From 6f8269c42e3d40f9c00c02f2c17a753924d95f5c Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Fri, 26 Jul 2024 17:15:04 -0500 Subject: [PATCH] atlas: render selection spans in white on blue atlas: get rid of SelectionFrom/SelectionTo and the selection quad atlas: support selection color --- src/renderer/atlas/AtlasEngine.api.cpp | 9 ++++-- src/renderer/atlas/AtlasEngine.cpp | 25 ++-------------- src/renderer/atlas/AtlasEngine.h | 1 + src/renderer/atlas/BackendD2D.cpp | 21 -------------- src/renderer/atlas/BackendD3D.cpp | 40 -------------------------- src/renderer/atlas/BackendD3D.h | 1 - src/renderer/atlas/common.h | 7 ++--- src/renderer/atlas/shader_common.hlsl | 1 - 8 files changed, 12 insertions(+), 93 deletions(-) diff --git a/src/renderer/atlas/AtlasEngine.api.cpp b/src/renderer/atlas/AtlasEngine.api.cpp index 32c172793aea..9f4c3c075e65 100644 --- a/src/renderer/atlas/AtlasEngine.api.cpp +++ b/src/renderer/atlas/AtlasEngine.api.cpp @@ -7,6 +7,7 @@ #include "Backend.h" #include "../../buffer/out/textBuffer.hpp" #include "../base/FontCache.h" +#include "../../types/inc/ColorFix.hpp" // #### NOTE #### // If you see any code in here that contains "_r." you might be seeing a race condition. @@ -423,12 +424,14 @@ void AtlasEngine::SetRetroTerminalEffect(bool enable) noexcept } } -void AtlasEngine::SetSelectionBackground(const COLORREF color, const float alpha) noexcept +void AtlasEngine::SetSelectionBackground(const COLORREF color, const float /*alpha*/) noexcept { - const u32 selectionColor = (color & 0xffffff) | gsl::narrow_cast(lrintf(alpha * 255.0f)) << 24; + const u32 selectionColor = (color & 0xffffff) | 0xff000000; if (_api.s->misc->selectionColor != selectionColor) { - _api.s.write()->misc.write()->selectionColor = selectionColor; + auto misc = _api.s.write()->misc.write(); + misc->selectionColor = selectionColor; + misc->selectionForeground = 0xff000000 | ColorFix::GetPerceivableColor(color, color, 0.5f * 0.5f); } } diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp index d10f3e8e785d..b841ec577f4a 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -311,6 +311,8 @@ CATCH_RETURN() _api.searchHighlightFocused = { info.searchHighlightFocused, 1 }; } } + + _api.selectionSpans = til::point_span_subspan_within_rect(info.selectionSpans, dr); } return S_OK; @@ -497,6 +499,7 @@ try // Apply the highlighting colors to the highlighted cells RETURN_IF_FAILED(_drawHighlighted(_api.searchHighlights, y, x, columnEnd, highlightFg, highlightBg)); RETURN_IF_FAILED(_drawHighlighted(_api.searchHighlightFocused, y, x, columnEnd, highlightFocusFg, highlightFocusBg)); + RETURN_IF_FAILED(_drawHighlighted(_api.selectionSpans, y, x, columnEnd, _api.s->misc->selectionForeground, _api.s->misc->selectionColor)); _api.lastPaintBufferLineCoord = { x, y }; return S_OK; @@ -563,31 +566,9 @@ try CATCH_RETURN() [[nodiscard]] HRESULT AtlasEngine::PaintSelection(std::span rects) noexcept -try { - // Unfortunately there's no step after Renderer::_PaintBufferOutput that - // would inform us that it's done with the last AtlasEngine::PaintBufferLine. - // As such we got to call _flushBufferLine() here just to be sure. - _flushBufferLine(); - - for (auto&& rect : rects) - { - const auto y = gsl::narrow_cast(clamp(rect.top, 0, _p.s->viewportCellCount.y - 1)); - const auto from = gsl::narrow_cast(clamp(rect.left, 0, _p.s->viewportCellCount.x - 1)); - const auto to = gsl::narrow_cast(clamp(rect.right, from, _p.s->viewportCellCount.x)); - - auto& row = *_p.rows[y]; - row.selectionFrom = from; - row.selectionTo = to; - - _p.dirtyRectInPx.left = std::min(_p.dirtyRectInPx.left, from * _p.s->font->cellSize.x); - _p.dirtyRectInPx.top = std::min(_p.dirtyRectInPx.top, y * _p.s->font->cellSize.y); - _p.dirtyRectInPx.right = std::max(_p.dirtyRectInPx.right, to * _p.s->font->cellSize.x); - _p.dirtyRectInPx.bottom = std::max(_p.dirtyRectInPx.bottom, _p.dirtyRectInPx.top + _p.s->font->cellSize.y); - } return S_OK; } -CATCH_RETURN() [[nodiscard]] HRESULT AtlasEngine::PaintCursor(const CursorOptions& options) noexcept try diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h index 1c0c76503873..8c5bdc0df702 100644 --- a/src/renderer/atlas/AtlasEngine.h +++ b/src/renderer/atlas/AtlasEngine.h @@ -171,6 +171,7 @@ namespace Microsoft::Console::Render::Atlas // These tracks the highlighted regions on the screen that are yet to be painted. std::span searchHighlights; std::span searchHighlightFocused; + std::span selectionSpans; // dirtyRect is a computed value based on invalidatedRows. til::rect dirtyRect; diff --git a/src/renderer/atlas/BackendD2D.cpp b/src/renderer/atlas/BackendD2D.cpp index 8a7861ecd9b3..c05dd1f21e33 100644 --- a/src/renderer/atlas/BackendD2D.cpp +++ b/src/renderer/atlas/BackendD2D.cpp @@ -51,7 +51,6 @@ void BackendD2D::Render(RenderingPayload& p) _drawCursorPart1(p); _drawText(p); _drawCursorPart2(p); - _drawSelection(p); #if ATLAS_DEBUG_SHOW_DIRTY _debugShowDirty(p); #endif @@ -938,26 +937,6 @@ void BackendD2D::_drawCursor(const RenderingPayload& p, ID2D1RenderTarget* rende } } -void BackendD2D::_drawSelection(const RenderingPayload& p) -{ - u16 y = 0; - for (const auto& row : p.rows) - { - if (row->selectionTo > row->selectionFrom) - { - const D2D1_RECT_F rect{ - static_cast(p.s->font->cellSize.x * row->selectionFrom), - static_cast(p.s->font->cellSize.y * y), - static_cast(p.s->font->cellSize.x * row->selectionTo), - static_cast(p.s->font->cellSize.y * (y + 1)), - }; - _fillRectangle(rect, p.s->misc->selectionColor); - } - - y++; - } -} - #if ATLAS_DEBUG_SHOW_DIRTY void BackendD2D::_debugShowDirty(const RenderingPayload& p) { diff --git a/src/renderer/atlas/BackendD3D.cpp b/src/renderer/atlas/BackendD3D.cpp index 2e02e342863f..de76593398e1 100644 --- a/src/renderer/atlas/BackendD3D.cpp +++ b/src/renderer/atlas/BackendD3D.cpp @@ -229,7 +229,6 @@ void BackendD3D::Render(RenderingPayload& p) _drawBackground(p); _drawCursorBackground(p); _drawText(p); - _drawSelection(p); _debugShowDirty(p); _flushQuads(p); @@ -2248,45 +2247,6 @@ size_t BackendD3D::_drawCursorForegroundSlowPath(const CursorRect& c, size_t off return addedInstances; } -void BackendD3D::_drawSelection(const RenderingPayload& p) -{ - u16 y = 0; - u16 lastFrom = 0; - u16 lastTo = 0; - - for (const auto& row : p.rows) - { - if (row->selectionTo > row->selectionFrom) - { - // If the current selection line matches the previous one, we can just extend the previous quad downwards. - // The way this is implemented isn't very smart, but we also don't have very many rows to iterate through. - if (row->selectionFrom == lastFrom && row->selectionTo == lastTo) - { - _getLastQuad().size.y += p.s->font->cellSize.y; - } - else - { - _appendQuad() = { - .shadingType = static_cast(ShadingType::Selection), - .position = { - static_cast(p.s->font->cellSize.x * row->selectionFrom), - static_cast(p.s->font->cellSize.y * y), - }, - .size = { - static_cast(p.s->font->cellSize.x * (row->selectionTo - row->selectionFrom)), - static_cast(p.s->font->cellSize.y), - }, - .color = p.s->misc->selectionColor, - }; - lastFrom = row->selectionFrom; - lastTo = row->selectionTo; - } - } - - y++; - } -} - void BackendD3D::_debugShowDirty(const RenderingPayload& p) { #if ATLAS_DEBUG_SHOW_DIRTY diff --git a/src/renderer/atlas/BackendD3D.h b/src/renderer/atlas/BackendD3D.h index cb1bfcccea4d..af5eb58248d4 100644 --- a/src/renderer/atlas/BackendD3D.h +++ b/src/renderer/atlas/BackendD3D.h @@ -76,7 +76,6 @@ namespace Microsoft::Console::Render::Atlas SolidLine, Cursor, - Selection, TextDrawingFirst = TextGrayscale, TextDrawingLast = SolidLine, diff --git a/src/renderer/atlas/common.h b/src/renderer/atlas/common.h index 56cc1fce1390..c2efd676560d 100644 --- a/src/renderer/atlas/common.h +++ b/src/renderer/atlas/common.h @@ -393,7 +393,8 @@ namespace Microsoft::Console::Render::Atlas struct MiscellaneousSettings { u32 backgroundColor = 0; - u32 selectionColor = 0x7fffffff; + u32 selectionColor = 0xffffffff; + u32 selectionForeground = 0xff000000; std::wstring customPixelShaderPath; std::wstring customPixelShaderImagePath; bool useRetroTerminalEffect = false; @@ -475,8 +476,6 @@ namespace Microsoft::Console::Render::Atlas bitmap.active = false; gridLineRanges.clear(); lineRendition = LineRendition::SingleWidth; - selectionFrom = 0; - selectionTo = 0; dirtyTop = y * cellHeight; dirtyBottom = dirtyTop + cellHeight; } @@ -496,8 +495,6 @@ namespace Microsoft::Console::Render::Atlas Bitmap bitmap; std::vector gridLineRanges; LineRendition lineRendition = LineRendition::SingleWidth; - u16 selectionFrom = 0; - u16 selectionTo = 0; til::CoordType dirtyTop = 0; til::CoordType dirtyBottom = 0; }; diff --git a/src/renderer/atlas/shader_common.hlsl b/src/renderer/atlas/shader_common.hlsl index 51eb524b86b1..de998313585c 100644 --- a/src/renderer/atlas/shader_common.hlsl +++ b/src/renderer/atlas/shader_common.hlsl @@ -16,7 +16,6 @@ #define SHADING_TYPE_CURLY_LINE 7 #define SHADING_TYPE_SOLID_LINE 8 #define SHADING_TYPE_CURSOR 9 -#define SHADING_TYPE_SELECTION 10 struct VSData {