c # — SharpDx: установка ширины символов

Я пишу приложение C # Direct2D, используя SharpDX, однако я могу понять ответы / примеры, которые представлены в 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();
    }
    

2

Решение

Поскольку некоторые буквы должны быть узкими, а некоторые нормальными, а некоторые — широкими, вы не можете использовать одну из них. GlyphRun, но должны создать 3 разных GlyphRun,

Чтобы вызвать все буквы любого GlyphRun быть широким или узким:

  1. конфигурировать Transform в RenderTarget
  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);

После этого решения вам не нужно конвертировать GlyphRun в geometry и перепутать с размытыми буквами.

2

Другие решения

Direct2D Функциональность рендеринга текста предлагается в двух частях:

1) DrawText а также DrawTextLayout Этот метод позволяет вызывающей стороне передавать либо строку и параметры форматирования, либо объект макета текста 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

0

По вопросам рекламы [email protected]