I am very new to Direct2D and DirectWrite and still looking into the possibilities that these APIs provide. For a potential graphics applications I was wondering whether it is possible to render text as a path so that individual points can be modified just like in a vector graphics editor. Is it possible to do something like that directly in Direct2D and DirectWrite or are there at least ways to retrieve the necessary information and construct a path object that resembles text manually?
Asked
Active
Viewed 1,759 times
1
-
Questions of this nature are generally discouraged as "too broad" here on SO, or as producing answers that will be "primarily opinion-based." That doesn't mean that it isn't a good question, though. Have you actually tried out Direct2D with respect to what you're trying to accomplish? – Feb 14 '15 at 20:49
-
Well I am still learning to use Direct2D/DirectWrite but I find it quite difficult to use even though it seems to be a very flexible API. This link might be what I am kind of looking for but maybe a more experienced developer can comment on this. http://www.codeproject.com/Articles/376597/Outline-Text-With-DirectWrite – Karim Jordan Feb 14 '15 at 21:04
-
You might want to post your question there, under that code project. Once you reach a point where you can actually show us some code, we can assist you here. And, yes, Direct2D is a bit daunting :). – Feb 14 '15 at 21:11
1 Answers
3
The article you reference in your comment is correct. The key is simply IDWriteFontFace::GetGlyphRunOutline. A bit more about the usage can be found here. And the function described in that CustomTextRenderer article from their sample code is the following (ugly as it is):
// Gets GlyphRun outlines via IDWriteFontFace::GetGlyphRunOutline
// and then draws and fills them using Direct2D path geometries
IFACEMETHODIMP CustomTextRenderer::DrawGlyphRun(
_In_opt_ void* clientDrawingContext,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
DWRITE_MEASURING_MODE measuringMode,
_In_ DWRITE_GLYPH_RUN const* glyphRun,
_In_ DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
IUnknown* clientDrawingEffect)
{
HRESULT hr = S_OK;
// Create the path geometry.
Microsoft::WRL::ComPtr<ID2D1PathGeometry> pathGeometry;
hr = D2DFactory->CreatePathGeometry(&pathGeometry);
// Write to the path geometry using the geometry sink.
Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink;
if (SUCCEEDED(hr))
{
hr = pathGeometry->Open(&sink);
}
// Get the glyph run outline geometries back from DirectWrite
// and place them within the geometry sink.
if (SUCCEEDED(hr))
{
hr = glyphRun->fontFace->GetGlyphRunOutline(
glyphRun->fontEmSize,
glyphRun->glyphIndices,
glyphRun->glyphAdvances,
glyphRun->glyphOffsets,
glyphRun->glyphCount,
glyphRun->isSideways,
glyphRun->bidiLevel % 2,
sink.Get());
}
// Close the geometry sink
if (SUCCEEDED(hr))
{
hr = sink.Get()->Close();
}
// Initialize a matrix to translate the origin of the glyph run.
D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
1.0f, 0.0f,
0.0f, 1.0f,
baselineOriginX, baselineOriginY);
// Create the transformed geometry
Microsoft::WRL::ComPtr<ID2D1TransformedGeometry> transformedGeometry;
if (SUCCEEDED(hr))
{
hr = D2DFactory.Get()->CreateTransformedGeometry(
pathGeometry.Get(),
&matrix,
&transformedGeometry);
}
// Draw the outline of the glyph run
D2DDeviceContext->DrawGeometry(
transformedGeometry.Get(),
outlineBrush.Get());
// Fill in the glyph run
D2DDeviceContext->FillGeometry(
transformedGeometry.Get(),
fillBrush.Get());
return hr;
}
In that example, after creating the path geometry from the text, they are simply moving to to location specified in the x and y parameters, then tracing and filling the geometry. I call the code ugly because of the logic, especially where the sink may not get closed if the outline call fails. But it is just sample code. Good luck.

Jeff
- 2,495
- 18
- 38