简体   繁体   English

Direct2D:将文本转换为路径

[英]Direct2D: Convert text to path

I am very new to Direct2D and DirectWrite and still looking into the possibilities that these APIs provide. 我对Direct2D和DirectWrite还是陌生的,仍然在研究这些API提供的可能性。 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? 是否可以直接在Direct2D和DirectWrite中做类似的事情,或者至少有其他方法来检索必要的信息并构造一个类似于文本的路径对象?

The article you reference in your comment is correct. 您在评论中引用的文章是正确的。 The key is simply IDWriteFontFace::GetGlyphRunOutline . 密钥只是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): 该CustomTextRenderer文章中的示例代码中描述的功能如下(实际上是很丑陋的):

//  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. 在该示例中,从文本创建路径几何之后,它们只是移动到x和y参数中指定的位置,然后跟踪并填充该几何。 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. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM