Reputation: 1779
I am writing a C# Direct2D application using SharpDX, however I can understand answers/examples that are provided in C++.
I want to render text and change the width of certain characters to look like the picture:
The letter B expanded to 200% and the letter D is reduced to 50%
In the code below I draw the geometry of the glyphs And so it is possible to change the width of geometry But that's not a good solution, because a geometry drawing comes out as blurred as you see in the picture.
In conclusion, there are two questions:
How I change the width of the characters?
How to draw geometries of letters without blurring. (it is possible to render geometry with 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();
}
Upvotes: 1
Views: 799
Reputation: 1779
Since some of the letters should be narrow and some are normal and some are wide, you can not use one GlyphRun
, but must create 3 different GlyphRun
.
To cause all letters of any GlyphRun
to be wide or narrow:
Transform
to RenderTarget
GlyphRun
Transform
Wide transform: RenderTarget2D.Transform = new SharpDX.Mathematics.Interop.RawMatrix3x2(1.5f, 0, 0, 1, 0, 0);
Narrow transform: RenderTarget2D.Transform = new SharpDX.Mathematics.Interop.RawMatrix3x2(0.5f, 0, 0, 1, 0, 0);
After this solution you do not need to convert GlyphRun
to geometry
and get mixed up with blurred letters.
Upvotes: 1
Reputation: 7385
Direct2D
text rendering functionality is offered in two parts:
1) DrawText
and DrawTextLayout
method, enables a caller to pass either a string and formatting parameters or a DWrite text layout object for multiple formats. This should be suitable for most callers.
2) The second way is to render text, exposed as the DrawGlyphRun
method, provides rasterization for customers who already know the position of the glyphs they want to render. The following two general rules can help improve text performance when drawing in Direct2D.
I now see that you are using the second approach, but in the first one, you can set the rendering to ClearType
:
RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Cleartype;
I am not sure how to include it in you example, but the Sharp DX example looks like this:
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"));
}
}
}
Sample taken from: https://github.com/sharpdx/SharpDX-Samples/blob/master/Desktop/Direct2D1/TextRenderingApp
Upvotes: 0