mirror of
https://github.com/microsoft/terminal.git
synced 2026-02-04 05:35:20 +00:00
Another underline fix, but this time use the bitmap; consider moving underline production into PaintBufferLine itself
This commit is contained in:
@@ -203,7 +203,7 @@ try
|
||||
auto dst = _p.colorBitmap.data() + dstOffset;
|
||||
const auto bytes = count * sizeof(u32);
|
||||
|
||||
for (size_t i = 0; i < 2; ++i)
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
// Avoid bumping the colorBitmapGeneration unless necessary. This approx. further halves
|
||||
// the (already small) GPU load. This could easily be replaced with some custom SIMD
|
||||
@@ -353,7 +353,7 @@ CATCH_RETURN()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void AtlasEngine::_fillColorBitmap(const size_t y, const size_t x1, const size_t x2, const u32 fgColor, const u32 bgColor) noexcept
|
||||
void AtlasEngine::_fillColorBitmap(const size_t y, const size_t x1, const size_t x2, const u32 fgColor, const u32 bgColor, const u32 ulColor) noexcept
|
||||
{
|
||||
const auto bitmap = _p.colorBitmap.begin() + _p.colorBitmapRowStride * y;
|
||||
const auto shift = gsl::narrow_cast<u8>(_p.rows[y]->lineRendition != LineRendition::SingleWidth);
|
||||
@@ -363,10 +363,11 @@ void AtlasEngine::_fillColorBitmap(const size_t y, const size_t x1, const size_t
|
||||
const u32 colors[] = {
|
||||
u32ColorPremultiply(bgColor),
|
||||
fgColor,
|
||||
ulColor,
|
||||
};
|
||||
|
||||
// This fills the color in the background bitmap, and then in the foreground bitmap.
|
||||
for (size_t i = 0; i < 2; ++i)
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
const auto color = colors[i];
|
||||
|
||||
@@ -428,7 +429,7 @@ try
|
||||
{
|
||||
const auto isFinalRow = y == hiEnd.y;
|
||||
const auto end = isFinalRow ? std::min(hiEnd.x, x2) : x2;
|
||||
_fillColorBitmap(row, x1, end, fgColor, bgColor);
|
||||
_fillColorBitmap(row, x1, end, fgColor, bgColor, fgColor);
|
||||
|
||||
// Return early if we couldn't paint the whole region (either this was not the last row, or
|
||||
// it was the last row but the highlight ends outside of our x range.)
|
||||
@@ -451,7 +452,7 @@ try
|
||||
const auto isEndInside = y == hiEnd.y && hiEnd.x <= x2;
|
||||
if (isStartInside && isEndInside)
|
||||
{
|
||||
_fillColorBitmap(row, hiStart.x, static_cast<size_t>(hiEnd.x), fgColor, bgColor);
|
||||
_fillColorBitmap(row, hiStart.x, static_cast<size_t>(hiEnd.x), fgColor, bgColor, fgColor);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
@@ -460,7 +461,7 @@ try
|
||||
if (isStartInside)
|
||||
{
|
||||
const auto start = std::max(x1, hiStart.x);
|
||||
_fillColorBitmap(y, start, x2, fgColor, bgColor);
|
||||
_fillColorBitmap(y, start, x2, fgColor, bgColor, fgColor);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -517,7 +518,7 @@ try
|
||||
}
|
||||
|
||||
// Apply the current foreground and background colors to the cells
|
||||
_fillColorBitmap(y, x, columnEnd, _api.currentForeground, _api.currentBackground);
|
||||
_fillColorBitmap(y, x, columnEnd, _api.currentForeground, _api.currentBackground, 0xfffa7720u);
|
||||
|
||||
// Apply the highlighting colors to the highlighted cells
|
||||
RETURN_IF_FAILED(_drawHighlighted(_api.searchHighlights, y, x, columnEnd, highlightFg, highlightBg));
|
||||
@@ -532,13 +533,15 @@ CATCH_RETURN()
|
||||
[[nodiscard]] HRESULT AtlasEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept
|
||||
try
|
||||
{
|
||||
UNREFERENCED_PARAMETER(gridlineColor);
|
||||
UNREFERENCED_PARAMETER(underlineColor);
|
||||
const auto shift = gsl::narrow_cast<u8>(_api.lineRendition != LineRendition::SingleWidth);
|
||||
const auto x = std::max(0, coordTarget.x - (_api.viewportOffset.x >> shift));
|
||||
const auto y = gsl::narrow_cast<u16>(clamp<til::CoordType>(coordTarget.y, 0, _p.s->viewportCellCount.y - 1));
|
||||
const auto from = gsl::narrow_cast<u16>(clamp<til::CoordType>(x << shift, 0, _p.s->viewportCellCount.x - 1));
|
||||
const auto to = gsl::narrow_cast<u16>(clamp<size_t>((x + cchLine) << shift, from, _p.s->viewportCellCount.x));
|
||||
const auto glColor = gsl::narrow_cast<u32>(gridlineColor) | 0xff000000;
|
||||
const auto ulColor = gsl::narrow_cast<u32>(underlineColor) | 0xff000000;
|
||||
const auto glColor = 0xffff0000U; //gsl::narrow_cast<u32>(gridlineColor) | 0xff000000;
|
||||
const auto ulColor = 0xff00ff00U; //gsl::narrow_cast<u32>(underlineColor) | 0xff000000;
|
||||
_p.rows[y]->gridLineRanges.emplace_back(lines, glColor, ulColor, from, to);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -791,9 +794,10 @@ void AtlasEngine::_recreateCellCountDependentResources()
|
||||
// so we round up to multiple of 8 because 8 * sizeof(u32) == 32.
|
||||
_p.colorBitmapRowStride = alignForward<size_t>(_p.s->viewportCellCount.x, 8);
|
||||
_p.colorBitmapDepthStride = _p.colorBitmapRowStride * _p.s->viewportCellCount.y;
|
||||
_p.colorBitmap = Buffer<u32, 32>(_p.colorBitmapDepthStride * 2);
|
||||
_p.colorBitmap = Buffer<u32, 32>(_p.colorBitmapDepthStride * 3);
|
||||
_p.backgroundBitmap = { _p.colorBitmap.data(), _p.colorBitmapDepthStride };
|
||||
_p.foregroundBitmap = { _p.colorBitmap.data() + _p.colorBitmapDepthStride, _p.colorBitmapDepthStride };
|
||||
_p.underlineBitmap = { _p.colorBitmap.data() + (_p.colorBitmapDepthStride << 1), _p.colorBitmapDepthStride };
|
||||
|
||||
memset(_p.colorBitmap.data(), 0, _p.colorBitmap.size() * sizeof(u32));
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
void _mapCharacters(const wchar_t* text, u32 textLength, u32* mappedLength, IDWriteFontFace2** mappedFontFace) const;
|
||||
void _mapComplex(IDWriteFontFace2* mappedFontFace, u32 idx, u32 length, ShapedRow& row);
|
||||
ATLAS_ATTR_COLD void _mapReplacementCharacter(u32 from, u32 to, ShapedRow& row);
|
||||
void _fillColorBitmap(const size_t y, const size_t x1, const size_t x2, const u32 fgColor, const u32 bgColor) noexcept;
|
||||
void _fillColorBitmap(const size_t y, const size_t x1, const size_t x2, const u32 fgColor, const u32 bgColor, const u32 ulColor) noexcept;
|
||||
[[nodiscard]] HRESULT _drawHighlighted(std::span<const til::point_span>& highlights, const u16 row, const u16 begX, const u16 endX, const u32 fgColor, const u32 bgColor) noexcept;
|
||||
|
||||
// AtlasEngine.api.cpp
|
||||
|
||||
@@ -678,12 +678,12 @@ void BackendD3D::_debugUpdateShaders(const RenderingPayload& p) noexcept
|
||||
struct FileVS
|
||||
{
|
||||
std::wstring_view filename;
|
||||
wil::com_ptr<ID3D11VertexShader> BackendD3D::*target;
|
||||
wil::com_ptr<ID3D11VertexShader> BackendD3D::* target;
|
||||
};
|
||||
struct FilePS
|
||||
{
|
||||
std::wstring_view filename;
|
||||
wil::com_ptr<ID3D11PixelShader> BackendD3D::*target;
|
||||
wil::com_ptr<ID3D11PixelShader> BackendD3D::* target;
|
||||
};
|
||||
|
||||
static constexpr std::array filesVS{
|
||||
@@ -1784,37 +1784,51 @@ void BackendD3D::_drawGridlines(const RenderingPayload& p, u16 y)
|
||||
auto posX = r.from * cellSize.x + offset;
|
||||
const auto end = r.to * cellSize.x;
|
||||
|
||||
const auto colors = &p.foregroundBitmap[p.colorBitmapRowStride * y];
|
||||
|
||||
for (; posX < end; posX += textCellWidth)
|
||||
{
|
||||
_appendQuad() = {
|
||||
.shadingType = static_cast<u16>(ShadingType::SolidLine),
|
||||
.position = { static_cast<i16>(posX), rowTop },
|
||||
.size = { width, p.s->font->cellSize.y },
|
||||
.color = r.gridlineColor,
|
||||
.color = colors[r.from],
|
||||
};
|
||||
}
|
||||
};
|
||||
const auto appendHorizontalLine = [&](const GridLineRange& r, FontDecorationPosition pos, ShadingType shadingType, const u32 color) {
|
||||
const auto appendHorizontalLine = [&](const GridLineRange& r, FontDecorationPosition pos, ShadingType shadingType, const std::span<const u32>& colorBitmap) {
|
||||
const auto offset = pos.position << verticalShift;
|
||||
const auto height = static_cast<u16>(pos.height << verticalShift);
|
||||
|
||||
const auto left = static_cast<i16>(r.from * cellSize.x);
|
||||
const auto width = static_cast<u16>((r.to - r.from) * cellSize.x);
|
||||
|
||||
i32 rt = textCellTop + offset;
|
||||
i32 rb = rt + height;
|
||||
rt = clamp(rt, clipTop, clipBottom);
|
||||
rb = clamp(rb, clipTop, clipBottom);
|
||||
|
||||
const auto colors = &colorBitmap[p.colorBitmapRowStride * y];
|
||||
|
||||
if (rt < rb)
|
||||
{
|
||||
_appendQuad() = {
|
||||
.shadingType = static_cast<u16>(shadingType),
|
||||
.renditionScale = { static_cast<u8>(1 << horizontalShift), static_cast<u8>(1 << verticalShift) },
|
||||
.position = { left, static_cast<i16>(rt) },
|
||||
.size = { width, static_cast<u16>(rb - rt) },
|
||||
.color = color,
|
||||
};
|
||||
for (auto from = r.from; from < r.to;)
|
||||
{
|
||||
const auto start = colors[from];
|
||||
u16 w = 1u;
|
||||
for (; colors[from + w] == start && w < (r.to - r.from); ++w)
|
||||
;
|
||||
|
||||
const auto left = static_cast<i16>(from * cellSize.x);
|
||||
const auto width = static_cast<u16>(w * cellSize.x);
|
||||
|
||||
_appendQuad() = {
|
||||
.shadingType = static_cast<u16>(shadingType),
|
||||
.renditionScale = { static_cast<u8>(1 << horizontalShift), static_cast<u8>(1 << verticalShift) },
|
||||
.position = { left, static_cast<i16>(rt) },
|
||||
.size = { width, static_cast<u16>(rb - rt) },
|
||||
.color = start,
|
||||
};
|
||||
|
||||
from += w;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1833,38 +1847,38 @@ void BackendD3D::_drawGridlines(const RenderingPayload& p, u16 y)
|
||||
}
|
||||
if (r.lines.test(GridLines::Top))
|
||||
{
|
||||
appendHorizontalLine(r, p.s->font->gridTop, ShadingType::SolidLine, r.gridlineColor);
|
||||
appendHorizontalLine(r, p.s->font->gridTop, ShadingType::SolidLine, p.foregroundBitmap);
|
||||
}
|
||||
if (r.lines.test(GridLines::Bottom))
|
||||
{
|
||||
appendHorizontalLine(r, p.s->font->gridBottom, ShadingType::SolidLine, r.gridlineColor);
|
||||
appendHorizontalLine(r, p.s->font->gridBottom, ShadingType::SolidLine, p.foregroundBitmap);
|
||||
}
|
||||
if (r.lines.test(GridLines::Strikethrough))
|
||||
{
|
||||
appendHorizontalLine(r, p.s->font->strikethrough, ShadingType::SolidLine, r.gridlineColor);
|
||||
appendHorizontalLine(r, p.s->font->strikethrough, ShadingType::SolidLine, p.foregroundBitmap);
|
||||
}
|
||||
|
||||
if (r.lines.test(GridLines::Underline))
|
||||
{
|
||||
appendHorizontalLine(r, p.s->font->underline, ShadingType::SolidLine, r.underlineColor);
|
||||
appendHorizontalLine(r, p.s->font->underline, ShadingType::SolidLine, p.underlineBitmap);
|
||||
}
|
||||
else if (r.lines.any(GridLines::DottedUnderline, GridLines::HyperlinkUnderline))
|
||||
{
|
||||
appendHorizontalLine(r, p.s->font->underline, ShadingType::DottedLine, r.underlineColor);
|
||||
appendHorizontalLine(r, p.s->font->underline, ShadingType::DottedLine, p.underlineBitmap);
|
||||
}
|
||||
else if (r.lines.test(GridLines::DashedUnderline))
|
||||
{
|
||||
appendHorizontalLine(r, p.s->font->underline, ShadingType::DashedLine, r.underlineColor);
|
||||
appendHorizontalLine(r, p.s->font->underline, ShadingType::DashedLine, p.underlineBitmap);
|
||||
}
|
||||
else if (r.lines.test(GridLines::CurlyUnderline))
|
||||
{
|
||||
appendHorizontalLine(r, _curlyUnderline, ShadingType::CurlyLine, r.underlineColor);
|
||||
appendHorizontalLine(r, _curlyUnderline, ShadingType::CurlyLine, p.underlineBitmap);
|
||||
}
|
||||
else if (r.lines.test(GridLines::DoubleUnderline))
|
||||
{
|
||||
for (const auto pos : p.s->font->doubleUnderline)
|
||||
{
|
||||
appendHorizontalLine(r, pos, ShadingType::SolidLine, r.underlineColor);
|
||||
appendHorizontalLine(r, pos, ShadingType::SolidLine, p.underlineBitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,14 +562,17 @@ namespace Microsoft::Console::Render::Atlas
|
||||
// This exists as a convenience access to colorBitmap and
|
||||
// contains a view into the foreground color bitmap.
|
||||
std::span<u32> foregroundBitmap;
|
||||
// This exists as a convenience access to colorBitmap and
|
||||
// contains a view into the underline color bitmap.
|
||||
std::span<u32> underlineBitmap;
|
||||
// This stride of the colorBitmap is a "count" of u32 and not in bytes.
|
||||
size_t colorBitmapRowStride = 0;
|
||||
// FYI depth refers to the `colorBitmapRowStride * height` size of each bitmap contained
|
||||
// in colorBitmap. colorBitmap contains 2 bitmaps (background and foreground colors).
|
||||
// in colorBitmap. colorBitmap contains 3 bitmaps (background, foreground and underline colors).
|
||||
size_t colorBitmapDepthStride = 0;
|
||||
// A generation of 1 ensures that the backends redraw the background on the first Present().
|
||||
// The 1st entry in this array corresponds to the background and the 2nd to the foreground bitmap.
|
||||
std::array<til::generation_t, 2> colorBitmapGenerations{ 1, 1 };
|
||||
std::array<til::generation_t, 3> colorBitmapGenerations{ 1, 1, 1 };
|
||||
// In columns/rows.
|
||||
til::rect cursorRect;
|
||||
// The viewport/SwapChain area to be presented. In pixel.
|
||||
|
||||
Reference in New Issue
Block a user