2

我正在使用 SharpDX 编写 C# Direct2D 应用程序,但是我可以理解 C++ 中提供的答案/示例。

我想渲染文本并更改某些字符的宽度,使其看起来像图片:

在此处输入图像描述

字母 B 扩大到 200%,字母 D 缩小到 50%

在下面的代码中,我绘制了字形的几何图形因此可以更改几何图形的宽度但这不是一个好的解决方案,因为几何图形绘制出来的效果就像您在图片中看到的那样模糊。

在此处输入图像描述

总之,有两个问题:

  1. 如何更改字符的宽度?

  2. 如何在不模糊的情况下绘制字母的几何形状。(可以用 ClearType 渲染几何图形吗?)

    private void RenderGlyphRun1(FontFace1 fontFace)
    {
        var Offsets = new List<GlyphOffset>();
        var fontEmSize_ = 12;
        GlyphRun glyphRun = new GlyphRun();
        glyphRun.FontFace = fontFace;
        glyphRun.FontSize = fontEmSize_;
        glyphRun.BidiLevel = 1;
        var left = 650f;
        var top = 50f;
    
        var baseLine = (float)(fontFace.Metrics.LineGap + fontFace.Metrics.Ascent) /
            fontFace.Metrics.DesignUnitsPerEm * glyphRun.FontSize;
    
        string textToDraw = "ABCDE";
        foreach (char letter in textToDraw)
        {
            Offsets.Add(new GlyphOffset());
        }
    
        var charArr = textToDraw.Select(x => (int)x).ToArray();
        glyphRun.Indices = fontFace.GetGlyphIndices(charArr);
    
        var metrics = fontFace.GetDesignGlyphMetrics(glyphRun.Indices, false);
        glyphRun.Advances = metrics.Select(x => (float)x.AdvanceWidth /
                 fontFace.Metrics.DesignUnitsPerEm * glyphRun.FontSize).ToArray();
    
        glyphRun.Offsets = Offsets.ToArray();
    
        RenderTarget2D.BeginDraw();
        RenderTarget2D.Clear(SharpDX.Color.White);
    
        RenderTarget2D.DrawGlyphRun(new Vector2(left, top),
            glyphRun, new SharpDX.Direct2D1.SolidColorBrush(RenderTarget2D, SharpDX.Color.Black),
            MeasuringMode.Natural);
    
        top += baseLine;
    
        var pathGeometry = new PathGeometry(Factory2D);
        var geometrySink = pathGeometry.Open();
    
        fontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices,
            glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways,
            glyphRun.BidiLevel % 2 != 0, geometrySink);
    
        geometrySink.Close();
        geometrySink.Dispose();
        fontFace.Dispose();
    
        var matrix = new Matrix3x2()
        {
            M11 = 1,
            M12 = 0,
            M21 = 0,
            M22 = 1,
            M31 = left,
            M32 = top
        };
    
        var transformedGeometry = new TransformedGeometry(Factory2D, pathGeometry, matrix);
        var brushColor = (Color4)SharpDX.Color.Black;
        var brush = new SolidColorBrush(RenderTarget2D, brushColor);
        RenderTarget2D.FillGeometry(transformedGeometry, brush);
    
        pathGeometry.Dispose();
        transformedGeometry.Dispose();
        brush.Dispose();
    
        RenderTarget2D.EndDraw();
    }       
    
4

2 回答 2

2

由于有些字母应该是窄的,有些是正常的,有些是宽的,所以你不能使用一个GlyphRun,而必须创建 3 个不同的GlyphRun

使 anyGlyphRun的所有字母变宽或变窄:

  1. 配置TransformRenderTarget
  2. 绘制GlyphRun
  3. 退回原件Transform

宽变换: RenderTarget2D.Transform = new SharpDX.Mathematics.Interop.RawMatrix3x2(1.5f, 0, 0, 1, 0, 0);

窄变换: RenderTarget2D.Transform = new SharpDX.Mathematics.Interop.RawMatrix3x2(0.5f, 0, 0, 1, 0, 0);

使用此解决方案后,您无需转换GlyphRungeometry模糊字母并与之混淆。

于 2018-10-07T16:52:21.543 回答
0

Direct2D文本呈现功能分两部分提供:

1)DrawTextDrawTextLayout方法,使调用者能够传递字符串和格式参数或用于多种格式的 DWrite 文本布局对象。这应该适合大多数来电者。

2)第二种方式是渲染文本,暴露为DrawGlyphRun方法,为已经知道要渲染的字形位置的客户提供光栅化。在 Direct2D 中绘图时,以下两个一般规则有助于提高文本性能。

我现在看到您使用的是第二种方法,但在第一种方法中,您可以将渲染设置为ClearType

RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Cleartype;

我不确定如何将它包含在您的示例中,但 Sharp DX 示例如下所示:

using System;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.DirectWrite;
using SharpDX.Samples;
using TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode;

namespace TextRenderingApp
{
  public class Program : Direct2D1DemoApp
  {        
    public TextFormat TextFormat { get; private set; }
    public TextLayout TextLayout { get; private set; }

    protected override void Initialize(DemoConfiguration demoConfiguration)
    {
        base.Initialize(demoConfiguration);

        // Initialize a TextFormat
        TextFormat = new TextFormat(FactoryDWrite, "Calibri", 128) {TextAlignment = TextAlignment.Center, ParagraphAlignment = ParagraphAlignment.Center};

        RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Cleartype;

        // Initialize a TextLayout
        TextLayout = new TextLayout(FactoryDWrite, "SharpDX D2D1 - DWrite", TextFormat, demoConfiguration.Width, demoConfiguration.Height);
    }


    protected override void Draw(DemoTime time)
    {
        base.Draw(time);

        // Draw the TextLayout
        RenderTarget2D.DrawTextLayout(new Vector2(0,0), TextLayout, SceneColorBrush, DrawTextOptions.None );
    }


    [STAThread]
    static void Main(string[] args)
    {
        Program program = new Program();
        program.Run(new DemoConfiguration("SharpDX DirectWrite Text Rendering Demo"));
    }
  }
}

样本取自:https ://github.com/sharpdx/SharpDX-Samples/blob/master/Desktop/Direct2D1/TextRenderingApp

于 2018-10-05T06:48:20.460 回答