Repository: microsoft/terminal
File: src/renderer/dx/CustomTextLayout.cpp (C++)

Code before:
// Routine Description:
// - Implements a drawing interface similarly to the default IDWriteTextLayout which will
//   take the string from construction, analyze it for complexity, shape up the glyphs,
//   and then draw the final product to the given renderer at the point and pass along
//   the context information.
// - This specific class does the layout calculations and complexity analysis, not the
//   final drawing. That's the renderer's job (passed in.)
// Arguments:
// - clientDrawingContext - Optional pointer to information that the renderer might need
//                          while attempting to graphically place the text onto the screen
// - renderer - The interface to be used for actually putting text onto the screen
// - originX - X pixel point of top left corner on final surface for drawing
// - originY - Y pixel point of top left corner on final surface for drawing
// Return Value:
// - S_OK or suitable DirectX/DirectWrite/Direct2D result code.
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::Draw(_In_opt_ void* clientDrawingContext,
                                                               _In_ IDWriteTextRenderer* renderer,
                                                               FLOAT originX,
                                                               FLOAT originY) noexcept
try
{
    const auto drawingContext = static_cast<const DrawingContext*>(clientDrawingContext);

    const DWRITE_FONT_WEIGHT weight = _fontRenderData->DefaultFontWeight();
    DWRITE_FONT_STYLE style = _fontRenderData->DefaultFontStyle();
    const DWRITE_FONT_STRETCH stretch = _fontRenderData->DefaultFontStretch();

    if (drawingContext->useItalicFont)
    {
        style = DWRITE_FONT_STYLE_ITALIC;
    }

    _formatInUse = _fontRenderData->TextFormatWithAttribute(weight, style, stretch).Get();
    _fontInUse = _fontRenderData->FontFaceWithAttribute(weight, style, stretch).Get();

    RETURN_IF_FAILED(_AnalyzeTextComplexity());
    RETURN_IF_FAILED(_AnalyzeRuns());
    RETURN_IF_FAILED(_ShapeGlyphRuns());
    RETURN_IF_FAILED(_CorrectGlyphRuns());
    // Correcting box drawing has to come after both font fallback and
    // the glyph run advance correction (which will apply a font size scaling factor).
    // We need to know all the proposed X and Y dimension metrics to get this right.
    RETURN_IF_FAILED(_CorrectBoxDrawing());

    RETURN_IF_FAILED(_DrawGlyphRuns(clientDrawingContext, renderer, { originX, originY }));

    return S_OK;
}
CATCH_RETURN()

// Routine Description:

Review comment (suggestion):
Is there anything that can change the `stretch` property? Is there a SGR sequence for this? Or this is just gonna sit here not being used.


Code after:
// Routine Description:
// - Implements a drawing interface similarly to the default IDWriteTextLayout which will
//   take the string from construction, analyze it for complexity, shape up the glyphs,
//   and then draw the final product to the given renderer at the point and pass along
//   the context information.
// - This specific class does the layout calculations and complexity analysis, not the
//   final drawing. That's the renderer's job (passed in.)
// Arguments:
// - clientDrawingContext - Optional pointer to information that the renderer might need
//                          while attempting to graphically place the text onto the screen
// - renderer - The interface to be used for actually putting text onto the screen
// - originX - X pixel point of top left corner on final surface for drawing
// - originY - Y pixel point of top left corner on final surface for drawing
// Return Value:
// - S_OK or suitable DirectX/DirectWrite/Direct2D result code.
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::Draw(_In_opt_ void* clientDrawingContext,
                                                               _In_ IDWriteTextRenderer* renderer,
                                                               FLOAT originX,
                                                               FLOAT originY) noexcept
try
{
    const auto drawingContext = static_cast<const DrawingContext*>(clientDrawingContext);

    DWRITE_FONT_WEIGHT weight = _fontRenderData->DefaultFontWeight();
    DWRITE_FONT_STYLE style = _fontRenderData->DefaultFontStyle();
    const DWRITE_FONT_STRETCH stretch = _fontRenderData->DefaultFontStretch();

    if (drawingContext->useBoldFont)
    {
        // TODO: "relative" bold?
        weight = DWRITE_FONT_WEIGHT_BOLD;
    }

    if (drawingContext->useItalicFont)
    {
        style = DWRITE_FONT_STYLE_ITALIC;
    }

    _formatInUse = _fontRenderData->TextFormatWithAttribute(weight, style, stretch).Get();
    _fontInUse = _fontRenderData->FontFaceWithAttribute(weight, style, stretch).Get();

    RETURN_IF_FAILED(_AnalyzeTextComplexity());
    RETURN_IF_FAILED(_AnalyzeRuns());
    RETURN_IF_FAILED(_ShapeGlyphRuns());
    RETURN_IF_FAILED(_CorrectGlyphRuns());
    // Correcting box drawing has to come after both font fallback and
    // the glyph run advance correction (which will apply a font size scaling factor).
    // We need to know all the proposed X and Y dimension metrics to get this right.
    RETURN_IF_FAILED(_CorrectBoxDrawing());

    RETURN_IF_FAILED(_DrawGlyphRuns(clientDrawingContext, renderer, { originX, originY }));