mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-17 15:36:35 +00:00
Compare commits
8 Commits
v1.25.1322
...
dev/duhowe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0963bfe4c2 | ||
|
|
03afcfd7e8 | ||
|
|
2dac785e1a | ||
|
|
b67fb19f7c | ||
|
|
85c2628808 | ||
|
|
e89b17e562 | ||
|
|
2a58b001bf | ||
|
|
eec8dbd6d7 |
@@ -361,6 +361,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// and react accordingly.
|
||||
_updateFont();
|
||||
|
||||
const auto padding = StringToXamlThickness(_settings->Padding());
|
||||
auto padx = gsl::narrow_cast<til::CoordType>(lrint((padding.Left + padding.Right) * _compositionScale));
|
||||
auto pady = gsl::narrow_cast<til::CoordType>(lrint((padding.Top + padding.Bottom) * _compositionScale));
|
||||
|
||||
const til::size windowSize{ til::math::rounding, windowWidth, windowHeight };
|
||||
|
||||
// First set up the dx engine with the window size in pixels.
|
||||
@@ -369,7 +373,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, windowSize);
|
||||
LOG_IF_FAILED(_renderEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() }));
|
||||
|
||||
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
|
||||
const auto vp = _renderEngine->GetViewportInCharacters(Viewport::FromDimensions({ 0, 0 }, { viewInPixels.Width() - padx, viewInPixels.Height() - pady }));
|
||||
const auto width = vp.Width();
|
||||
const auto height = vp.Height();
|
||||
|
||||
@@ -399,6 +403,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_renderEngineSwapChainChanged(handle);
|
||||
});
|
||||
|
||||
_renderEngine->SetPadding(static_cast<float>(padding.Left),
|
||||
static_cast<float>(padding.Top),
|
||||
static_cast<float>(padding.Right),
|
||||
static_cast<float>(padding.Bottom));
|
||||
_renderEngine->SetRetroTerminalEffect(_settings->RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(_settings->PixelShaderPath());
|
||||
_renderEngine->SetPixelShaderImagePath(_settings->PixelShaderImagePath());
|
||||
@@ -900,6 +908,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Inform the renderer of our opacity
|
||||
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
|
||||
|
||||
const auto padding = StringToXamlThickness(_settings->Padding());
|
||||
_renderEngine->SetPadding(static_cast<float>(padding.Left),
|
||||
static_cast<float>(padding.Top),
|
||||
static_cast<float>(padding.Right),
|
||||
static_cast<float>(padding.Bottom));
|
||||
|
||||
// Trigger a redraw to repaint the window background and tab colors.
|
||||
_renderer->TriggerRedrawAll(true, true);
|
||||
|
||||
@@ -1115,6 +1129,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
auto cx = gsl::narrow_cast<til::CoordType>(lrint(_panelWidth * _compositionScale));
|
||||
auto cy = gsl::narrow_cast<til::CoordType>(lrint(_panelHeight * _compositionScale));
|
||||
const auto padding = StringToXamlThickness(_settings->Padding());
|
||||
auto padx = gsl::narrow_cast<til::CoordType>(lrint((padding.Left + padding.Right) * _compositionScale));
|
||||
auto pady = gsl::narrow_cast<til::CoordType>(lrint((padding.Top + padding.Bottom) * _compositionScale));
|
||||
|
||||
cx -= padx;
|
||||
cy -= pady;
|
||||
|
||||
// Don't actually resize so small that a single character wouldn't fit
|
||||
// in either dimension. The buffer really doesn't like being size 0.
|
||||
@@ -1128,7 +1148,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_terminal->ClearSelection();
|
||||
|
||||
// Tell the dx engine that our window is now the new size.
|
||||
THROW_IF_FAILED(_renderEngine->SetWindowSize({ cx, cy }));
|
||||
THROW_IF_FAILED(_renderEngine->SetWindowSize({ cx + padx, cy + pady }));
|
||||
|
||||
// Invalidate everything
|
||||
_renderer->TriggerRedrawAll();
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
const auto scaleFactor = static_cast<float>(DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel());
|
||||
const auto localOrigin = _termControl->TransformToVisual(nullptr).TransformPoint({});
|
||||
const auto padding = _termControl->GetPadding();
|
||||
const auto& padding = _termControl->_contentPadding;
|
||||
const auto cursorPosition = core->CursorPosition();
|
||||
const auto fontSize = core->FontSize();
|
||||
|
||||
@@ -928,9 +928,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// settings might be out-of-proc in the future
|
||||
auto settings{ _core.Settings() };
|
||||
|
||||
// Apply padding as swapChainPanel's margin
|
||||
const auto newMargin = StringToXamlThickness(settings.Padding());
|
||||
SwapChainPanel().Margin(newMargin);
|
||||
// Store the padding for UI calculations
|
||||
_contentPadding = StringToXamlThickness(settings.Padding());
|
||||
|
||||
// Apply settings for scrollbar
|
||||
if (settings.ScrollState() == ScrollbarState::Hidden)
|
||||
@@ -957,10 +956,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
if (_automationPeer)
|
||||
{
|
||||
_automationPeer.SetControlPadding(Core::Padding{
|
||||
static_cast<float>(newMargin.Left),
|
||||
static_cast<float>(newMargin.Top),
|
||||
static_cast<float>(newMargin.Right),
|
||||
static_cast<float>(newMargin.Bottom),
|
||||
static_cast<float>(_contentPadding.Left),
|
||||
static_cast<float>(_contentPadding.Top),
|
||||
static_cast<float>(_contentPadding.Right),
|
||||
static_cast<float>(_contentPadding.Bottom),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1234,12 +1233,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers)
|
||||
if (const auto& interactivityAutoPeer{ _interactivity.OnCreateAutomationPeer() })
|
||||
{
|
||||
const auto margins{ SwapChainPanel().Margin() };
|
||||
const Core::Padding padding{
|
||||
static_cast<float>(margins.Left),
|
||||
static_cast<float>(margins.Top),
|
||||
static_cast<float>(margins.Right),
|
||||
static_cast<float>(margins.Bottom),
|
||||
static_cast<float>(_contentPadding.Left),
|
||||
static_cast<float>(_contentPadding.Top),
|
||||
static_cast<float>(_contentPadding.Right),
|
||||
static_cast<float>(_contentPadding.Bottom),
|
||||
};
|
||||
_automationPeer = winrt::make<implementation::TermControlAutomationPeer>(get_strong(), padding, interactivityAutoPeer);
|
||||
return _automationPeer;
|
||||
@@ -1255,11 +1253,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.FontSize();
|
||||
}
|
||||
|
||||
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
||||
{
|
||||
return SwapChainPanel().Margin();
|
||||
}
|
||||
|
||||
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
||||
{
|
||||
return _core.ConnectionState();
|
||||
@@ -1452,12 +1445,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
if (_automationPeer)
|
||||
{
|
||||
_automationPeer.UpdateControlBounds();
|
||||
const auto margins{ GetPadding() };
|
||||
_automationPeer.SetControlPadding(Core::Padding{
|
||||
static_cast<float>(margins.Left),
|
||||
static_cast<float>(margins.Top),
|
||||
static_cast<float>(margins.Right),
|
||||
static_cast<float>(margins.Bottom),
|
||||
static_cast<float>(_contentPadding.Left),
|
||||
static_cast<float>(_contentPadding.Top),
|
||||
static_cast<float>(_contentPadding.Right),
|
||||
static_cast<float>(_contentPadding.Bottom),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2063,8 +2055,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// SwapChainPanel, not the entire control. If they drag out of
|
||||
// the bounds of the text, into the padding, we still what that
|
||||
// to auto-scroll
|
||||
const auto cursorBelowBottomDist = cursorPosition.Y - SwapChainPanel().Margin().Top - SwapChainPanel().ActualHeight();
|
||||
const auto cursorAboveTopDist = -1 * cursorPosition.Y + SwapChainPanel().Margin().Top;
|
||||
const auto cursorBelowBottomDist = cursorPosition.Y - _contentPadding.Top - SwapChainPanel().ActualHeight();
|
||||
const auto cursorAboveTopDist = -1 * cursorPosition.Y + _contentPadding.Top;
|
||||
|
||||
constexpr auto MinAutoScrollDist = 2.0; // Arbitrary value
|
||||
auto newAutoScrollVelocity = 0.0;
|
||||
@@ -2964,9 +2956,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// Account for the size of any padding
|
||||
const auto padding = GetPadding();
|
||||
width += static_cast<float>(padding.Left + padding.Right);
|
||||
height += static_cast<float>(padding.Top + padding.Bottom);
|
||||
width += static_cast<float>(_contentPadding.Left + _contentPadding.Right);
|
||||
height += static_cast<float>(_contentPadding.Top + _contentPadding.Bottom);
|
||||
|
||||
return { width, height };
|
||||
}
|
||||
@@ -2991,10 +2982,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto fontSize = _core.FontSizeInDips();
|
||||
const auto fontDimension = widthOrHeight ? fontSize.Width : fontSize.Height;
|
||||
|
||||
const auto padding = GetPadding();
|
||||
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
|
||||
padding.Left + padding.Right :
|
||||
padding.Top + padding.Bottom);
|
||||
_contentPadding.Left + _contentPadding.Right :
|
||||
_contentPadding.Top + _contentPadding.Bottom);
|
||||
|
||||
if (widthOrHeight && _core.Settings().ScrollState() != ScrollbarState::Hidden)
|
||||
{
|
||||
@@ -3088,12 +3078,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
winrt::Windows::Foundation::Point TermControl::_toControlOrigin(const til::point terminalPos)
|
||||
{
|
||||
const auto fontSize{ CharacterDimensions() };
|
||||
auto padding{ GetPadding() };
|
||||
|
||||
// Convert text buffer cursor position to client coordinate position within the window.
|
||||
return {
|
||||
terminalPos.x * fontSize.Width + static_cast<float>(padding.Left),
|
||||
terminalPos.y * fontSize.Height + static_cast<float>(padding.Top),
|
||||
terminalPos.x * fontSize.Width + static_cast<float>(_contentPadding.Left),
|
||||
terminalPos.y * fontSize.Height + static_cast<float>(_contentPadding.Top),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3107,12 +3096,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - the corresponding viewport terminal position (in pixels) for the given Point parameter
|
||||
Core::Point TermControl::_toTerminalOrigin(winrt::Windows::Foundation::Point cursorPosition)
|
||||
{
|
||||
// cursorPosition is DIPs, relative to SwapChainPanel origin
|
||||
const auto padding = GetPadding();
|
||||
|
||||
// This point is the location of the cursor within the actual grid of characters, in DIPs
|
||||
const auto relativeToMarginInDIPsX = cursorPosition.X - static_cast<float>(padding.Left);
|
||||
const auto relativeToMarginInDIPsY = cursorPosition.Y - static_cast<float>(padding.Top);
|
||||
const auto relativeToMarginInDIPsX = cursorPosition.X - static_cast<float>(_contentPadding.Left);
|
||||
const auto relativeToMarginInDIPsY = cursorPosition.Y - static_cast<float>(_contentPadding.Top);
|
||||
|
||||
// Convert it to pixels
|
||||
const auto scale = SwapChainPanel().CompositionScaleX();
|
||||
@@ -3668,11 +3654,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
winrt::Windows::Foundation::Point TermControl::_toPosInDips(const Core::Point terminalCellPos)
|
||||
{
|
||||
const auto marginsInDips{ GetPadding() };
|
||||
const auto fontSize{ _core.FontSizeInDips() };
|
||||
return {
|
||||
terminalCellPos.X * fontSize.Width + static_cast<float>(marginsInDips.Left),
|
||||
terminalCellPos.Y * fontSize.Height + static_cast<float>(marginsInDips.Top),
|
||||
terminalCellPos.X * fontSize.Width + static_cast<float>(_contentPadding.Left),
|
||||
terminalCellPos.Y * fontSize.Height + static_cast<float>(_contentPadding.Top),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3950,14 +3935,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// CharacterDimensions returns a font size in pixels.
|
||||
const auto fontSize{ CharacterDimensions() };
|
||||
|
||||
// Account for the margins, which are in DIPs
|
||||
auto padding{ GetPadding() };
|
||||
|
||||
// Convert text buffer cursor position to client coordinate position
|
||||
// within the window. This point is in _pixels_
|
||||
return {
|
||||
cursorPos.X * fontSize.Width + static_cast<float>(padding.Left),
|
||||
cursorPos.Y * fontSize.Height + static_cast<float>(padding.Top),
|
||||
cursorPos.X * fontSize.Width + static_cast<float>(_contentPadding.Left),
|
||||
cursorPos.Y * fontSize.Height + static_cast<float>(_contentPadding.Top),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3965,11 +3947,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::ContextMenuRequestedEventArgs args)
|
||||
{
|
||||
const auto inverseScale = 1.0f / static_cast<float>(XamlRoot().RasterizationScale());
|
||||
const auto padding = GetPadding();
|
||||
const auto pos = args.Position();
|
||||
_showContextMenuAt({
|
||||
pos.X * inverseScale + static_cast<float>(padding.Left),
|
||||
pos.Y * inverseScale + static_cast<float>(padding.Top),
|
||||
pos.X * inverseScale + static_cast<float>(_contentPadding.Left),
|
||||
pos.Y * inverseScale + static_cast<float>(_contentPadding.Top),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4012,7 +3993,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
double TermControl::QuickFixButtonWidth()
|
||||
{
|
||||
const auto leftPadding = GetPadding().Left;
|
||||
const auto leftPadding = _contentPadding.Left;
|
||||
if (_quickFixButtonCollapsible)
|
||||
{
|
||||
const auto cellWidth = CharacterDimensions().Width;
|
||||
@@ -4027,7 +4008,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
double TermControl::QuickFixButtonCollapsedWidth()
|
||||
{
|
||||
return std::max(CharacterDimensions().Width * 2.0 / 3.0, GetPadding().Left);
|
||||
return std::max(CharacterDimensions().Width * 2.0 / 3.0, _contentPadding.Left);
|
||||
}
|
||||
|
||||
bool TermControl::OpenQuickFixMenu()
|
||||
@@ -4064,10 +4045,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// If the gutter is narrow, display the collapsed version
|
||||
const auto& termPadding = GetPadding();
|
||||
|
||||
// Make sure to update _quickFixButtonCollapsible and QuickFix button widths BEFORE updating the VisualState
|
||||
_quickFixButtonCollapsible = termPadding.Left < CharacterDimensions().Width;
|
||||
_quickFixButtonCollapsible = _contentPadding.Left < CharacterDimensions().Width;
|
||||
PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"QuickFixButtonWidth" });
|
||||
PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"QuickFixButtonCollapsedWidth" });
|
||||
VisualStateManager::GoToState(*this, !_quickFixButtonCollapsible ? StateNormal : StateCollapsed, false);
|
||||
@@ -4084,8 +4063,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// draw the button in the gutter
|
||||
const auto& quickFixBtnPosInDips = _toPosInDips({ 0, _quickFixBufferPos });
|
||||
Controls::Canvas::SetLeft(quickFixBtn, -termPadding.Left);
|
||||
Controls::Canvas::SetTop(quickFixBtn, quickFixBtnPosInDips.Y - termPadding.Top);
|
||||
Controls::Canvas::SetLeft(quickFixBtn, -_contentPadding.Left);
|
||||
Controls::Canvas::SetTop(quickFixBtn, quickFixBtnPosInDips.Y - _contentPadding.Top);
|
||||
quickFixBtn.Visibility(Visibility::Visible);
|
||||
|
||||
if (auto automationPeer{ FrameworkElementAutomationPeer::FromElement(*this) })
|
||||
|
||||
@@ -152,7 +152,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
~TermControl();
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
const Windows::UI::Xaml::Thickness GetPadding();
|
||||
|
||||
static Windows::Foundation::Size GetProposedDimensions(const IControlSettings& settings,
|
||||
const uint32_t dpi,
|
||||
@@ -283,6 +282,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _quickFixButtonCollapsible{ false };
|
||||
bool _quickFixesAvailable{ false };
|
||||
til::CoordType _quickFixBufferPos{};
|
||||
Windows::UI::Xaml::Thickness _contentPadding{ 0.f };
|
||||
|
||||
std::shared_ptr<ThrottledFuncLeading> _playWarningBell;
|
||||
|
||||
|
||||
@@ -194,6 +194,12 @@ void AtlasEngine::_invalidateSpans(std::span<const til::point_span> spans, const
|
||||
if (_api.s->font->dpi != newDPI)
|
||||
{
|
||||
_api.s.write()->font.write()->dpi = newDPI;
|
||||
_api.s.write()->misc.write()->padding = {
|
||||
.x = _api.paddingInDip.x * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
.y = _api.paddingInDip.y * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
.z = _api.paddingInDip.z * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
.w = _api.paddingInDip.w * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
};
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@@ -900,3 +906,18 @@ void AtlasEngine::_resolveFontMetrics(const FontInfoDesired& fontInfoDesired, Fo
|
||||
_api.s.write()->font.write()->fontCollection = std::move(collection);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AtlasEngine::SetPadding(float left, float top, float right, float bottom) noexcept
|
||||
{
|
||||
f32x4 newPadding{ left, top, right, bottom };
|
||||
if (_api.paddingInDip != newPadding)
|
||||
{
|
||||
_api.paddingInDip = newPadding;
|
||||
_api.s.write()->misc.write()->padding = {
|
||||
.x = _api.paddingInDip.x * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
.y = _api.paddingInDip.y * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
.z = _api.paddingInDip.z * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
.w = _api.paddingInDip.w * (_api.s->font->dpi / USER_DEFAULT_SCREEN_DPI),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(std::wstring_view glyph, _Out_ bool* pResult) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateTitle(std::wstring_view newTitle) noexcept override;
|
||||
void UpdateHyperlinkHoveredId(uint16_t hoveredId) noexcept override;
|
||||
void SetPadding(float left, float top, float right, float bottom) noexcept override;
|
||||
|
||||
// getter
|
||||
[[nodiscard]] std::wstring_view GetPixelShaderPath() noexcept;
|
||||
@@ -181,6 +182,9 @@ namespace Microsoft::Console::Render::Atlas
|
||||
|
||||
// The position of the viewport inside the text buffer (in cells).
|
||||
u16x2 viewportOffset{ 0, 0 };
|
||||
|
||||
// SetPadding()
|
||||
f32x4 paddingInDip{ 0.f, 0.f, 0.f, 0.f };
|
||||
} _api;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ void BackendD2D::Render(RenderingPayload& p)
|
||||
_handleSettingsUpdate(p);
|
||||
}
|
||||
|
||||
const D2D1_MATRIX_3X2_F worldTransform{ _getDefaultTransform(p) };
|
||||
|
||||
_renderTarget->BeginDraw();
|
||||
try
|
||||
{
|
||||
@@ -48,6 +50,7 @@ void BackendD2D::Render(RenderingPayload& p)
|
||||
_renderTarget->Clear();
|
||||
#endif
|
||||
_drawBackground(p);
|
||||
_renderTarget->SetTransform(&worldTransform);
|
||||
_drawCursorPart1(p);
|
||||
_drawText(p);
|
||||
_drawCursorPart2(p);
|
||||
@@ -318,7 +321,7 @@ void BackendD2D::_drawText(RenderingPayload& p)
|
||||
|
||||
if (row->lineRendition != LineRendition::SingleWidth)
|
||||
{
|
||||
_drawTextResetLineRendition(row);
|
||||
_drawTextResetLineRendition(p, row);
|
||||
}
|
||||
|
||||
if (row->bitmap.revision != 0)
|
||||
@@ -505,17 +508,15 @@ void BackendD2D::_flushBuiltinGlyphs()
|
||||
f32 BackendD2D::_drawTextPrepareLineRendition(const RenderingPayload& p, const ShapedRow* row, f32 baselineY) const noexcept
|
||||
{
|
||||
const auto lineRendition = row->lineRendition;
|
||||
D2D1_MATRIX_3X2_F transform{
|
||||
.m11 = 2.0f,
|
||||
.m22 = 1.0f,
|
||||
};
|
||||
D2D1_MATRIX_3X2_F transform{ _getDefaultTransform(p) };
|
||||
transform.m11 = 2.0f; // scale horizontally by 2.0
|
||||
|
||||
if (lineRendition >= LineRendition::DoubleHeightTop)
|
||||
{
|
||||
D2D1_RECT_F clipRect{ 0, 0, static_cast<f32>(p.s->targetSize.x), static_cast<f32>(p.s->targetSize.y) };
|
||||
|
||||
transform.m22 = 2.0f;
|
||||
transform.dy = -1.0f * (baselineY + p.s->font->descender);
|
||||
transform.dy += -1.0f * (baselineY + p.s->font->descender);
|
||||
|
||||
// If you print the top half of a double height row (DECDHL), the expectation is that only
|
||||
// the top half is visible, which requires us to keep the clip rect at the bottom of the row.
|
||||
@@ -539,9 +540,9 @@ f32 BackendD2D::_drawTextPrepareLineRendition(const RenderingPayload& p, const S
|
||||
return baselineY;
|
||||
}
|
||||
|
||||
void BackendD2D::_drawTextResetLineRendition(const ShapedRow* row) const noexcept
|
||||
void BackendD2D::_drawTextResetLineRendition(const RenderingPayload& p, const ShapedRow* row) const noexcept
|
||||
{
|
||||
static constexpr D2D1_MATRIX_3X2_F identity{ .m11 = 1, .m22 = 1 };
|
||||
const auto identity{ _getDefaultTransform(p) };
|
||||
_renderTarget->SetTransform(&identity);
|
||||
|
||||
if (row->lineRendition >= LineRendition::DoubleHeightTop)
|
||||
@@ -1005,4 +1006,14 @@ void BackendD2D::_fillRectangle(const D2D1_RECT_F& rect, u32 color)
|
||||
_renderTarget->FillRectangle(&rect, brush);
|
||||
}
|
||||
|
||||
D2D_MATRIX_3X2_F BackendD2D::_getDefaultTransform(const RenderingPayload& p) const noexcept
|
||||
{
|
||||
return {
|
||||
.m11 = 1.f,
|
||||
.m22 = 1.f,
|
||||
.dx = p.s->misc->padding.x,
|
||||
.dy = p.s->misc->padding.y,
|
||||
};
|
||||
}
|
||||
|
||||
TIL_FAST_MATH_END
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
D2D1_RECT_U _prepareBuiltinGlyph(const RenderingPayload& p, char32_t ch, u32 off);
|
||||
void _flushBuiltinGlyphs();
|
||||
ATLAS_ATTR_COLD f32 _drawTextPrepareLineRendition(const RenderingPayload& p, const ShapedRow* row, f32 baselineY) const noexcept;
|
||||
ATLAS_ATTR_COLD void _drawTextResetLineRendition(const ShapedRow* row) const noexcept;
|
||||
ATLAS_ATTR_COLD void _drawTextResetLineRendition(const RenderingPayload& p, const ShapedRow* row) const noexcept;
|
||||
ATLAS_ATTR_COLD f32r _getGlyphRunDesignBounds(const DWRITE_GLYPH_RUN& glyphRun, f32 baselineX, f32 baselineY);
|
||||
ATLAS_ATTR_COLD void _drawGridlineRow(const RenderingPayload& p, const ShapedRow* row, u16 y);
|
||||
ATLAS_ATTR_COLD void _drawBitmap(const RenderingPayload& p, const ShapedRow* row, u16 y) const;
|
||||
@@ -40,6 +40,8 @@ namespace Microsoft::Console::Render::Atlas
|
||||
ATLAS_ATTR_COLD ID2D1SolidColorBrush* _brushWithColorUpdate(u32 color);
|
||||
void _fillRectangle(const D2D1_RECT_F& rect, u32 color);
|
||||
|
||||
D2D_MATRIX_3X2_F _getDefaultTransform(const RenderingPayload& p) const noexcept;
|
||||
|
||||
wil::com_ptr<ID2D1DeviceContext> _renderTarget;
|
||||
wil::com_ptr<ID2D1DeviceContext4> _renderTarget4; // Optional. Supported since Windows 10 14393.
|
||||
wil::com_ptr<ID2D1StrokeStyle> _dottedStrokeStyle;
|
||||
|
||||
@@ -571,18 +571,30 @@ void BackendD3D::_recreateBackgroundColorBitmap(const RenderingPayload& p)
|
||||
_backgroundBitmapGeneration = {};
|
||||
}
|
||||
|
||||
void BackendD3D::_recreateConstBuffer(const RenderingPayload& p) const
|
||||
void BackendD3D::_recreateConstBuffer(const RenderingPayload& p)
|
||||
{
|
||||
{
|
||||
VSConstBuffer data{};
|
||||
data.positionScale = { 2.0f / p.s->targetSize.x, -2.0f / p.s->targetSize.y };
|
||||
data.positionScale = {
|
||||
2.0f / p.s->targetSize.x,
|
||||
-2.0f / p.s->targetSize.y,
|
||||
};
|
||||
data.positionOffset = {
|
||||
data.positionScale.x * p.s->misc->padding.x - 1.0f,
|
||||
data.positionScale.y * p.s->misc->padding.y + 1.0f,
|
||||
};
|
||||
p.deviceContext->UpdateSubresource(_vsConstantBuffer.get(), 0, nullptr, &data, 0, 0);
|
||||
}
|
||||
{
|
||||
PSConstBuffer data{};
|
||||
data.backgroundColor = colorFromU32Premultiply<f32x4>(p.s->misc->backgroundColor);
|
||||
data.backgroundCellSize = { static_cast<f32>(p.s->font->cellSize.x), static_cast<f32>(p.s->font->cellSize.y) };
|
||||
data.backgroundCellCount = { static_cast<f32>(p.s->viewportCellCount.x), static_cast<f32>(p.s->viewportCellCount.y) };
|
||||
data.backgroundScale = {
|
||||
1.0f / (p.s->font->cellSize.x * p.s->viewportCellCount.x),
|
||||
1.0f / (p.s->font->cellSize.y * p.s->viewportCellCount.y),
|
||||
};
|
||||
data.backgroundOffset = {
|
||||
data.backgroundScale.x * -p.s->misc->padding.x,
|
||||
data.backgroundScale.y * -p.s->misc->padding.y,
|
||||
};
|
||||
DWrite_GetGammaRatios(_gamma, data.gammaRatios);
|
||||
data.enhancedContrast = p.s->font->antialiasingMode == AntialiasingMode::ClearType ? _cleartypeEnhancedContrast : _grayscaleEnhancedContrast;
|
||||
data.underlineWidth = p.s->font->underline.height;
|
||||
@@ -594,6 +606,23 @@ void BackendD3D::_recreateConstBuffer(const RenderingPayload& p) const
|
||||
data.shadedGlyphDotSize = std::max(1.0f, std::roundf(std::max(p.s->font->cellSize.x / 12.0f, p.s->font->cellSize.y / 24.0f)));
|
||||
p.deviceContext->UpdateSubresource(_psConstantBuffer.get(), 0, nullptr, &data, 0, 0);
|
||||
}
|
||||
{
|
||||
const auto color = colorFromU32Premultiply<f32x4>(p.s->misc->backgroundColor);
|
||||
const D3D11_SAMPLER_DESC desc{
|
||||
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
|
||||
.AddressU = D3D11_TEXTURE_ADDRESS_BORDER,
|
||||
.AddressV = D3D11_TEXTURE_ADDRESS_BORDER,
|
||||
.AddressW = D3D11_TEXTURE_ADDRESS_BORDER,
|
||||
.MipLODBias = 0,
|
||||
.MaxAnisotropy = 1,
|
||||
.ComparisonFunc = D3D11_COMPARISON_NEVER,
|
||||
.BorderColor = { color.x, color.y, color.z, color.w },
|
||||
//.BorderColor = { 1.0f, 0.2f, 0.2f, 1.0f },
|
||||
.MinLOD = -FLT_MAX,
|
||||
.MaxLOD = FLT_MAX,
|
||||
};
|
||||
THROW_IF_FAILED(p.device->CreateSamplerState(&desc, _backgroundSampler.put()));
|
||||
}
|
||||
}
|
||||
|
||||
void BackendD3D::_setupDeviceContextState(const RenderingPayload& p)
|
||||
@@ -622,6 +651,7 @@ void BackendD3D::_setupDeviceContextState(const RenderingPayload& p)
|
||||
p.deviceContext->PSSetShader(_pixelShader.get(), nullptr, 0);
|
||||
p.deviceContext->PSSetConstantBuffers(0, 1, _psConstantBuffer.addressof());
|
||||
p.deviceContext->PSSetShaderResources(0, 2, &resources[0]);
|
||||
p.deviceContext->PSSetSamplers(0, 1, _backgroundSampler.addressof());
|
||||
|
||||
// OM: Output Merger
|
||||
p.deviceContext->OMSetBlendState(_blendState.get(), nullptr, 0xffffffff);
|
||||
@@ -1072,6 +1102,10 @@ void BackendD3D::_drawBackground(const RenderingPayload& p)
|
||||
|
||||
_appendQuad() = {
|
||||
.shadingType = static_cast<u16>(ShadingType::Background),
|
||||
.position = {
|
||||
static_cast<i16>(lrintf(-p.s->misc->padding.x)),
|
||||
static_cast<i16>(lrintf(-p.s->misc->padding.x)),
|
||||
},
|
||||
.size = p.s->targetSize,
|
||||
};
|
||||
}
|
||||
@@ -2306,14 +2340,30 @@ void BackendD3D::_executeCustomShader(RenderingPayload& p)
|
||||
const auto now = queryPerfCount();
|
||||
const auto time = static_cast<int>(now % _customShaderPerfTickMod) * _customShaderSecsPerPerfTick;
|
||||
|
||||
const f32x2 scale = {
|
||||
1.0f / p.s->targetSize.x,
|
||||
1.0f / p.s->targetSize.y,
|
||||
};
|
||||
|
||||
const f32x2 physicalVpSize = {
|
||||
p.s->viewportCellCount.x * p.s->font->cellSize.x,
|
||||
p.s->viewportCellCount.y * p.s->font->cellSize.y,
|
||||
};
|
||||
|
||||
const CustomConstBuffer data{
|
||||
.time = time,
|
||||
.scale = static_cast<f32>(p.s->font->dpi) / static_cast<f32>(USER_DEFAULT_SCREEN_DPI),
|
||||
.resolution = {
|
||||
static_cast<f32>(_viewportCellCount.x * p.s->font->cellSize.x),
|
||||
static_cast<f32>(_viewportCellCount.y * p.s->font->cellSize.y),
|
||||
static_cast<f32>(p.s->targetSize.x),
|
||||
static_cast<f32>(p.s->targetSize.y),
|
||||
},
|
||||
.background = colorFromU32Premultiply<f32x4>(p.s->misc->backgroundColor),
|
||||
.viewport = {
|
||||
static_cast<f32>(p.s->misc->padding.x) * scale.x,
|
||||
static_cast<f32>(p.s->misc->padding.y) * scale.y,
|
||||
static_cast<f32>(p.s->misc->padding.x + physicalVpSize.x) * scale.x,
|
||||
static_cast<f32>(p.s->misc->padding.y + physicalVpSize.y) * scale.y,
|
||||
}
|
||||
};
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped{};
|
||||
@@ -2372,7 +2422,7 @@ void BackendD3D::_executeCustomShader(RenderingPayload& p)
|
||||
p.deviceContext->PSSetShader(_pixelShader.get(), nullptr, 0);
|
||||
p.deviceContext->PSSetConstantBuffers(0, 1, _psConstantBuffer.addressof());
|
||||
p.deviceContext->PSSetShaderResources(0, 2, &resources[0]);
|
||||
p.deviceContext->PSSetSamplers(0, 0, nullptr);
|
||||
p.deviceContext->PSSetSamplers(0, 1, _backgroundSampler.addressof());
|
||||
|
||||
// OM: Output Merger
|
||||
p.deviceContext->OMSetBlendState(_blendState.get(), nullptr, 0xffffffff);
|
||||
|
||||
@@ -30,15 +30,15 @@ namespace Microsoft::Console::Render::Atlas
|
||||
// * bool will probably not work the way you want it to,
|
||||
// because HLSL uses 32-bit bools and C++ doesn't.
|
||||
alignas(sizeof(f32x2)) f32x2 positionScale;
|
||||
alignas(sizeof(f32x2)) f32x2 positionOffset;
|
||||
#pragma warning(suppress : 4324) // 'VSConstBuffer': structure was padded due to alignment specifier
|
||||
};
|
||||
|
||||
// WARNING: Same rules as for VSConstBuffer above apply.
|
||||
struct alignas(16) PSConstBuffer
|
||||
{
|
||||
alignas(sizeof(f32x4)) f32x4 backgroundColor;
|
||||
alignas(sizeof(f32x2)) f32x2 backgroundCellSize;
|
||||
alignas(sizeof(f32x2)) f32x2 backgroundCellCount;
|
||||
alignas(sizeof(f32x2)) f32x2 backgroundScale;
|
||||
alignas(sizeof(f32x2)) f32x2 backgroundOffset;
|
||||
alignas(sizeof(f32x4)) f32 gammaRatios[4]{};
|
||||
alignas(sizeof(f32)) f32 enhancedContrast = 0;
|
||||
alignas(sizeof(f32)) f32 underlineWidth = 0;
|
||||
@@ -55,6 +55,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
alignas(sizeof(f32)) f32 scale = 0;
|
||||
alignas(sizeof(f32x2)) f32x2 resolution;
|
||||
alignas(sizeof(f32x4)) f32x4 background;
|
||||
alignas(sizeof(f32x4)) f32x4 viewport;
|
||||
#pragma warning(suppress : 4324) // 'CustomConstBuffer': structure was padded due to alignment specifier
|
||||
};
|
||||
|
||||
@@ -230,7 +231,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
void _recreateCustomShader(const RenderingPayload& p);
|
||||
void _recreateCustomRenderTargetView(const RenderingPayload& p);
|
||||
void _recreateBackgroundColorBitmap(const RenderingPayload& p);
|
||||
void _recreateConstBuffer(const RenderingPayload& p) const;
|
||||
void _recreateConstBuffer(const RenderingPayload& p);
|
||||
void _setupDeviceContextState(const RenderingPayload& p);
|
||||
void _debugUpdateShaders(const RenderingPayload& p) noexcept;
|
||||
void _debugShowDirty(const RenderingPayload& p);
|
||||
@@ -291,6 +292,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
|
||||
wil::com_ptr<ID3D11Texture2D> _backgroundBitmap;
|
||||
wil::com_ptr<ID3D11ShaderResourceView> _backgroundBitmapView;
|
||||
wil::com_ptr<ID3D11SamplerState> _backgroundSampler;
|
||||
til::generation_t _backgroundBitmapGeneration;
|
||||
|
||||
wil::com_ptr<ID3D11Texture2D> _glyphAtlas;
|
||||
|
||||
@@ -399,6 +399,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
std::wstring customPixelShaderPath;
|
||||
std::wstring customPixelShaderImagePath;
|
||||
bool useRetroTerminalEffect = false;
|
||||
f32x4 padding{ 0.f, 0.f, 0.f, 0.f };
|
||||
};
|
||||
|
||||
struct Settings
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
cbuffer ConstBuffer : register(b0)
|
||||
{
|
||||
float4 backgroundColor;
|
||||
float2 backgroundCellSize;
|
||||
float2 backgroundCellCount;
|
||||
float2 backgroundScale;
|
||||
float2 backgroundOffset;
|
||||
float4 gammaRatios;
|
||||
float enhancedContrast;
|
||||
float underlineWidth;
|
||||
@@ -17,6 +16,7 @@ cbuffer ConstBuffer : register(b0)
|
||||
float shadedGlyphDotSize;
|
||||
}
|
||||
|
||||
SamplerState backgroundSampler;
|
||||
Texture2D<float4> background : register(t0);
|
||||
Texture2D<float4> glyphAtlas : register(t1);
|
||||
|
||||
@@ -37,8 +37,7 @@ Output main(PSData data) : SV_Target
|
||||
{
|
||||
case SHADING_TYPE_TEXT_BACKGROUND:
|
||||
{
|
||||
float2 cell = data.position.xy / backgroundCellSize;
|
||||
color = all(cell < backgroundCellCount) ? background[cell] : backgroundColor;
|
||||
color = background.Sample(backgroundSampler, data.position.xy * backgroundScale + backgroundOffset);
|
||||
weights = float4(1, 1, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
cbuffer ConstBuffer : register(b0)
|
||||
{
|
||||
float2 positionScale;
|
||||
float2 positionOffset;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
@@ -18,8 +19,8 @@ PSData main(VSData data)
|
||||
output.renditionScale = data.renditionScale;
|
||||
// positionScale is expected to be float2(2.0f / sizeInPixel.x, -2.0f / sizeInPixel.y). Together with the
|
||||
// addition below this will transform our "position" from pixel into normalized device coordinate (NDC) space.
|
||||
output.position.xy = (data.position + data.vertex.xy * data.size) * positionScale + float2(-1.0f, 1.0f);
|
||||
output.position.xy = (data.vertex * data.size + data.position) * positionScale + positionOffset;
|
||||
output.position.zw = float2(0, 1);
|
||||
output.texcoord = data.texcoord + data.vertex.xy * data.size;
|
||||
output.texcoord = data.vertex * data.size + data.texcoord;
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -97,3 +97,7 @@ void RenderEngineBase::WaitUntilCanRender() noexcept
|
||||
void RenderEngineBase::UpdateHyperlinkHoveredId(const uint16_t /*hoveredId*/) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void RenderEngineBase::SetPadding(float, float, float, float) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace Microsoft::Console::Render
|
||||
[[nodiscard]] virtual HRESULT IsGlyphWideByFont(std::wstring_view glyph, _Out_ bool* pResult) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateTitle(std::wstring_view newTitle) noexcept = 0;
|
||||
virtual void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept = 0;
|
||||
virtual void SetPadding(float left, float top, float right, float bottom) noexcept = 0;
|
||||
};
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace Microsoft::Console::Render
|
||||
|
||||
void WaitUntilCanRender() noexcept override;
|
||||
void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept override;
|
||||
void SetPadding(float left, float top, float right, float bottom) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept = 0;
|
||||
|
||||
Reference in New Issue
Block a user