C# SharpDx:设置字符宽度 我使用SalpDX编写了一个C的直接T2D应用程序,但是我能理解C++中提供的答案/例子。

C# SharpDx:设置字符宽度 我使用SalpDX编写了一个C的直接T2D应用程序,但是我能理解C++中提供的答案/例子。,c#,c++,directx,sharpdx,directwrite,C#,C++,Directx,Sharpdx,Directwrite,我想渲染文本并更改某些字符的宽度,使其看起来像图片: 字母B扩展到200%,字母D减少到50% 在下面的代码中,我绘制了图示符的几何图形 所以可以改变几何体的宽度 但这不是一个好的解决方案,因为几何图形的模糊程度与您在图片中看到的一样 总之,有两个问题: 如何更改字符的宽度 如何在不模糊的情况下绘制字母的几何图形。(是否可以使用ClearType渲染几何体?) private void RenderGlyphRun1(FontFace1-fontFace) { var offset=新列表(

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

字母B扩展到200%,字母D减少到50%

在下面的代码中,我绘制了图示符的几何图形 所以可以改变几何体的宽度 但这不是一个好的解决方案,因为几何图形的模糊程度与您在图片中看到的一样

总之,有两个问题:

  • 如何更改字符的宽度

  • 如何在不模糊的情况下绘制字母的几何图形。(是否可以使用ClearType渲染几何体?)

    private void RenderGlyphRun1(FontFace1-fontFace)
    {
    var offset=新列表();
    var fontEmSize_=12;
    GlyphRun GlyphRun=新GlyphRun();
    glyphRun.FontFace=FontFace;
    glyphRun.FontSize=fontEmSize;
    glyphRun.BidiLevel=1;
    左var=650f;
    var-top=50f;
    变量基线=(浮动)(fontFace.Metrics.LineGap+fontFace.Metrics.Ascent)/
    fontFace.Metrics.DesignUnitsPrem*glyphRun.FontSize;
    字符串textToDraw=“ABCDE”;
    foreach(textToDraw中的字符)
    {
    添加(新glyphonoffset());
    }
    var charArr=textToDraw.Select(x=>(int)x.ToArray();
    glyphRun.index=fontFace.getGlyphIndex(charArr);
    var metrics=fontFace.getdesignglyphmmetrics(glyphRun.index,false);
    glyphRun.Advances=metrics.Select(x=>(float)x.advanceswidth/
    fontFace.Metrics.DesignUnitsPrem*glyphRun.FontSize).ToArray();
    glyphRun.Offsets=Offsets.ToArray();
    RenderTarget2D.BeginDraw();
    RenderTarget2D.Clear(SharpDX.Color.White);
    RenderTarget2D.DrawGlyphRun(新矢量2(左,上),
    glyphRun,新的SharpDX.Direct2D1.SolidColorBrush(RenderTarget2D,SharpDX.Color.Black),
    测量模式(自然);
    top+=基线;
    var pathGeometry=新的pathGeometry(Factory2D);
    var geometrySink=pathGeometry.Open();
    fontFace.GetGlyphRunOutline(glyphRun.FontSize、glyphRun.Index、,
    glyphRun.Advances、glyphRun.offset、glyphRun.IsSideways、,
    glyphRun.BidiLevel%2!=0,geometrySink);
    geometrySink.Close();
    geometrySink.Dispose();
    fontFace.Dispose();
    变量矩阵=新矩阵x3x2()
    {
    M11=1,
    M12=0,
    M21=0,
    M22=1,
    M31=左,
    M32=顶部
    };
    var transformedGeometry=新的transformedGeometry(Factory2D、路径几何、矩阵);
    var brushColor=(Color4)SharpDX.Color.Black;
    var brush=新的SolidColorBrush(RenderTarget2D,brushColor);
    RenderTarget2D.FillGeometry(transformedGeometry,笔刷);
    Dispose();
    transformedGeometry.Dispose();
    brush.Dispose();
    RenderTarget2D.EndDraw();
    }       
    

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

    1)
    DrawText
    DrawTextLayout
    方法使调用者能够为多种格式传递字符串和格式参数或DWrite文本布局对象。这应该适合大多数呼叫者

    2) 第二种方法是渲染文本,作为
    DrawGlyphRun
    方法公开,为已经知道要渲染的glyph位置的客户提供光栅化。在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"));
        }
      }
    }
    

    样本取自:

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

    要使任何
    字形的所有字母变宽或变窄,请执行以下操作:

  • 转换
    配置为
    渲染目标
  • 绘制
    GlyphRun
  • 返回原始的
    变换
  • 宽变换:
    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)


    使用此解决方案后,您不需要将
    GlyphRun
    转换为
    geometry
    并与模糊的字母混淆。

    我认为您需要分别渲染target2D.FillGeometry每个字符/glyph。您还可以在矩阵中指定每个字形的比例。@VuVirt
    您还可以在矩阵中指定每个字形的比例
    您的意思是什么?请举个例子。请向我解释你的答案如何回答我的问题<代码>如何更改字符的宽度?如何在不模糊的情况下绘制字母的几何图形。(是否可以使用ClearType渲染几何体?
    不幸的是,您的答案还不够
    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"));
        }
      }
    }