Я пишу приложение C # Direct2D, используя SharpDX, однако я могу понять ответы / примеры, которые представлены в C ++.
Я хочу сделать текст и изменить ширину определенных символов, чтобы они выглядели как на картинке:
Буква B расширена до 200%, а буква D уменьшена до 50%
В приведенном ниже коде я рисую геометрию глифов
И так можно изменить ширину геометрии
Но это не очень хорошее решение, потому что геометрический рисунок получается размытым, как вы видите на картинке.
В заключение два вопроса:
Как мне изменить ширину символов?
Как нарисовать геометрию букв без размытия. (можно рендерить геометрию с 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();
}
Поскольку некоторые буквы должны быть узкими, а некоторые нормальными, а некоторые — широкими, вы не можете использовать одну из них. GlyphRun
, но должны создать 3 разных GlyphRun
,
Чтобы вызвать все буквы любого GlyphRun
быть широким или узким:
Transform
в RenderTarget
GlyphRun
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
и перепутать с размытыми буквами.
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