Compare commits

...

4 Commits

Author SHA1 Message Date
Zoey Riordan
06001e4acc fix mouse events in the wpf control (#4720)
PR #4548 inadvertantly broke mouse button input in the WPF control. This happened due to the extra layer of HWND indirection. The fix is to move the mouse button handling down into the native control where the window messages are now being sent.

(cherry picked from commit 4393fefb71)
2020-02-28 14:49:42 -08:00
Dustin Howett
1d022aa816 Revert "Restrict DX run height adjustment to only relevant glyph AND Correct PTY rendering on trailing half of fullwidth glyphs (#4668)"
This reverts commit 4420950337.
2020-02-28 10:15:12 -08:00
Dustin Howett
f68bd09d7a Revert "Clip text to within the row we expect (#4671)"
This reverts commit 671110c88a.
2020-02-28 10:14:13 -08:00
Dustin Howett
8fb90dcea5 Revert "Don't split surrogate pairs when breaking runs for scaling. Affects emoji rendering. #4704 (#4731)"
This reverts commit d7ea526c3c.
2020-02-28 10:13:51 -08:00
16 changed files with 307 additions and 581 deletions

View File

@@ -294,8 +294,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{D3EF
build\scripts\Test-WindowsTerminalPackage.ps1 = build\scripts\Test-WindowsTerminalPackage.ps1
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dx.Unit.Tests", "src\renderer\dx\ut_dx\Dx.Unit.Tests.vcxproj", "{95B136F9-B238-490C-A7C5-5843C1FECAC4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winconpty.Tests.Feature", "src\winconpty\ft_pty\winconpty.FeatureTests.vcxproj", "{024052DE-83FB-4653-AEA4-90790D29D5BD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAzBridge", "src\cascadia\TerminalAzBridge\TerminalAzBridge.vcxproj", "{067F0A06-FCB7-472C-96E9-B03B54E8E18D}"
@@ -1425,32 +1423,6 @@ Global
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x64.Build.0 = Release|x64
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x86.ActiveCfg = Release|Win32
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x86.Build.0 = Release|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|x64.ActiveCfg = Release|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|x86.Build.0 = AuditMode|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|Any CPU.ActiveCfg = Debug|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|ARM64.Build.0 = Debug|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x64.ActiveCfg = Debug|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x64.Build.0 = Debug|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x86.ActiveCfg = Debug|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x86.Build.0 = Debug|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|Any CPU.ActiveCfg = Release|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|ARM64.ActiveCfg = Release|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|ARM64.Build.0 = Release|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x64.ActiveCfg = Release|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x64.Build.0 = Release|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x86.ActiveCfg = Release|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x86.Build.0 = Release|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|x64.ActiveCfg = Release|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|x86.Build.0 = AuditMode|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|Any CPU.ActiveCfg = Debug|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|ARM64.Build.0 = Debug|ARM64
@@ -1465,12 +1437,6 @@ Global
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x64.Build.0 = Release|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.ActiveCfg = Release|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.Build.0 = Release|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|x64.ActiveCfg = Release|x64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|x86.Build.0 = AuditMode|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|Any CPU.ActiveCfg = Debug|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|ARM64.Build.0 = Debug|ARM64
@@ -1559,7 +1525,6 @@ Global
{53DD5520-E64C-4C06-B472-7CE62CA539C9} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
{6B5A44ED-918D-4747-BFB1-2472A1FCA173} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
{D3EF7B96-CD5E-47C9-B9A9-136259563033} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
{95B136F9-B238-490C-A7C5-5843C1FECAC4} = {05500DEF-2294-41E3-AF9A-24E580B82836}
{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {59840756-302F-44DF-AA47-441A9D673202}
EndGlobalSection

View File

@@ -3,6 +3,7 @@
#include "pch.h"
#include "HwndTerminal.hpp"
#include <windowsx.h>
#include "../../types/TermControlUiaProvider.hpp"
#include <DefaultSettings.h>
#include "../../renderer/base/Renderer.hpp"
@@ -33,6 +34,33 @@ LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc(
{
return UiaReturnRawElementProvider(hwnd, wParam, lParam, terminal->_GetUiaProvider());
}
break;
case WM_LBUTTONDOWN:
LOG_IF_FAILED(terminal->_StartSelection(lParam));
return 0;
case WM_MOUSEMOVE:
if (WI_IsFlagSet(wParam, MK_LBUTTON))
{
LOG_IF_FAILED(terminal->_MoveSelection(lParam));
return 0;
}
break;
case WM_RBUTTONDOWN:
if (terminal->_terminal->IsSelectionActive())
{
try
{
const auto bufferData = terminal->_terminal->RetrieveSelectedTextFromBuffer(false);
LOG_IF_FAILED(terminal->_CopyTextToSystemClipboard(bufferData, true));
terminal->_terminal->ClearSelection();
}
CATCH_LOG();
}
else
{
terminal->_PasteTextFromClipboard();
}
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
@@ -65,7 +93,8 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) :
_actualFont{ DEFAULT_FONT_FACE, 0, 10, { 0, 14 }, CP_UTF8, false },
_uiaProvider{ nullptr },
_uiaProviderInitialized{ false },
_currentDpi{ USER_DEFAULT_SCREEN_DPI }
_currentDpi{ USER_DEFAULT_SCREEN_DPI },
_pfnWriteCallback{ nullptr }
{
HINSTANCE hInstance = wil::GetModuleInstanceHandle();
@@ -128,7 +157,7 @@ HRESULT HwndTerminal::Initialize()
_terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
_terminal->SetDefaultBackground(RGB(5, 27, 80));
_terminal->SetDefaultForeground(RGB(255, 255, 255));
_terminal->SetWriteInputCallback([=](std::wstring & input) noexcept { _WriteTextToConnection(input); });
localPointerToThread->EnablePainting();
return S_OK;
@@ -139,27 +168,24 @@ void HwndTerminal::RegisterScrollCallback(std::function<void(int, int, int)> cal
_terminal->SetScrollPositionChangedCallback(callback);
}
void HwndTerminal::_WriteTextToConnection(const std::wstring& input) noexcept
{
if (!_pfnWriteCallback)
{
return;
}
try
{
auto callingText{ wil::make_cotaskmem_string(input.data(), input.size()) };
_pfnWriteCallback(callingText.release());
}
CATCH_LOG();
}
void HwndTerminal::RegisterWriteCallback(const void _stdcall callback(wchar_t*))
{
_terminal->SetWriteInputCallback([=](std::wstring & input) noexcept {
const wchar_t* text = input.c_str();
const size_t textChars = wcslen(text) + 1;
const size_t textBytes = textChars * sizeof(wchar_t);
wchar_t* callingText = nullptr;
callingText = static_cast<wchar_t*>(::CoTaskMemAlloc(textBytes));
if (callingText == nullptr)
{
callback(nullptr);
}
else
{
wcscpy_s(callingText, textChars, text);
callback(callingText);
}
});
_pfnWriteCallback = callback;
}
::Microsoft::Console::Types::IUiaData* HwndTerminal::GetUiaData() const noexcept
@@ -320,45 +346,54 @@ void _stdcall TerminalUserScroll(void* terminal, int viewTop)
publicTerminal->_terminal->UserScrollViewport(viewTop);
}
HRESULT _stdcall TerminalStartSelection(void* terminal, COORD cursorPosition, bool altPressed)
HRESULT HwndTerminal::_StartSelection(LPARAM lParam) noexcept
try
{
COORD terminalPosition = { cursorPosition };
const bool altPressed = GetKeyState(VK_MENU) < 0;
COORD cursorPosition{
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam),
};
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto fontSize = publicTerminal->_actualFont.GetSize();
const auto fontSize = this->_actualFont.GetSize();
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.X == 0);
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.Y == 0);
terminalPosition.X /= fontSize.X;
terminalPosition.Y /= fontSize.Y;
cursorPosition.X /= fontSize.X;
cursorPosition.Y /= fontSize.Y;
publicTerminal->_terminal->SetSelectionAnchor(terminalPosition);
publicTerminal->_terminal->SetBlockSelection(altPressed);
this->_terminal->SetSelectionAnchor(cursorPosition);
this->_terminal->SetBlockSelection(altPressed);
publicTerminal->_renderer->TriggerSelection();
this->_renderer->TriggerSelection();
return S_OK;
}
CATCH_RETURN();
HRESULT _stdcall TerminalMoveSelection(void* terminal, COORD cursorPosition)
HRESULT HwndTerminal::_MoveSelection(LPARAM lParam) noexcept
try
{
COORD terminalPosition = { cursorPosition };
COORD cursorPosition{
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam),
};
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto fontSize = publicTerminal->_actualFont.GetSize();
const auto fontSize = this->_actualFont.GetSize();
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.X == 0);
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.Y == 0);
terminalPosition.X /= fontSize.X;
terminalPosition.Y /= fontSize.Y;
cursorPosition.X /= fontSize.X;
cursorPosition.Y /= fontSize.Y;
publicTerminal->_terminal->SetSelectionEnd(terminalPosition);
publicTerminal->_renderer->TriggerSelection();
this->_terminal->SetSelectionEnd(cursorPosition);
this->_renderer->TriggerSelection();
return S_OK;
}
CATCH_RETURN();
void _stdcall TerminalClearSelection(void* terminal)
{
@@ -501,6 +536,144 @@ void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible)
publicTerminal->_terminal->SetCursorVisible(visible);
}
// Routine Description:
// - Copies the text given onto the global system clipboard.
// Arguments:
// - rows - Rows of text data to copy
// - fAlsoCopyFormatting - true if the color and formatting should also be copied, false otherwise
HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting)
{
std::wstring finalString;
// Concatenate strings into one giant string to put onto the clipboard.
for (const auto& str : rows.text)
{
finalString += str;
}
// allocate the final clipboard data
const size_t cchNeeded = finalString.size() + 1;
const size_t cbNeeded = sizeof(wchar_t) * cchNeeded;
wil::unique_hglobal globalHandle(GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbNeeded));
RETURN_LAST_ERROR_IF_NULL(globalHandle.get());
PWSTR pwszClipboard = static_cast<PWSTR>(GlobalLock(globalHandle.get()));
RETURN_LAST_ERROR_IF_NULL(pwszClipboard);
// The pattern gets a bit strange here because there's no good wil built-in for global lock of this type.
// Try to copy then immediately unlock. Don't throw until after (so the hglobal won't be freed until we unlock).
const HRESULT hr = StringCchCopyW(pwszClipboard, cchNeeded, finalString.data());
GlobalUnlock(globalHandle.get());
RETURN_IF_FAILED(hr);
// Set global data to clipboard
RETURN_LAST_ERROR_IF(!OpenClipboard(_hwnd.get()));
{ // Clipboard Scope
auto clipboardCloser = wil::scope_exit([]() noexcept {
LOG_LAST_ERROR_IF(!CloseClipboard());
});
RETURN_LAST_ERROR_IF(!EmptyClipboard());
RETURN_LAST_ERROR_IF_NULL(SetClipboardData(CF_UNICODETEXT, globalHandle.get()));
if (fAlsoCopyFormatting)
{
const auto& fontData = _actualFont;
int const iFontHeightPoints = fontData.GetUnscaledSize().Y * 72 / this->_currentDpi;
const COLORREF bgColor = _terminal->GetBackgroundColor(_terminal->GetDefaultBrushColors());
std::string HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor, "Hwnd Console Host");
_CopyToSystemClipboard(HTMLToPlaceOnClip, L"HTML Format");
std::string RTFToPlaceOnClip = TextBuffer::GenRTF(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor);
_CopyToSystemClipboard(RTFToPlaceOnClip, L"Rich Text Format");
}
}
// only free if we failed.
// the memory has to remain allocated if we successfully placed it on the clipboard.
// Releasing the smart pointer will leave it allocated as we exit scope.
globalHandle.release();
return S_OK;
}
// Routine Description:
// - Copies the given string onto the global system clipboard in the specified format
// Arguments:
// - stringToCopy - The string to copy
// - lpszFormat - the name of the format
HRESULT HwndTerminal::_CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat)
{
const size_t cbData = stringToCopy.size() + 1; // +1 for '\0'
if (cbData)
{
wil::unique_hglobal globalHandleData(GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbData));
RETURN_LAST_ERROR_IF_NULL(globalHandleData.get());
PSTR pszClipboardHTML = static_cast<PSTR>(GlobalLock(globalHandleData.get()));
RETURN_LAST_ERROR_IF_NULL(pszClipboardHTML);
// The pattern gets a bit strange here because there's no good wil built-in for global lock of this type.
// Try to copy then immediately unlock. Don't throw until after (so the hglobal won't be freed until we unlock).
const HRESULT hr2 = StringCchCopyA(pszClipboardHTML, cbData, stringToCopy.data());
GlobalUnlock(globalHandleData.get());
RETURN_IF_FAILED(hr2);
UINT const CF_FORMAT = RegisterClipboardFormatW(lpszFormat);
RETURN_LAST_ERROR_IF(0 == CF_FORMAT);
RETURN_LAST_ERROR_IF_NULL(SetClipboardData(CF_FORMAT, globalHandleData.get()));
// only free if we failed.
// the memory has to remain allocated if we successfully placed it on the clipboard.
// Releasing the smart pointer will leave it allocated as we exit scope.
globalHandleData.release();
}
return S_OK;
}
void HwndTerminal::_PasteTextFromClipboard() noexcept
{
// Get paste data from clipboard
if (!OpenClipboard(_hwnd.get()))
{
return;
}
HANDLE ClipboardDataHandle = GetClipboardData(CF_UNICODETEXT);
if (ClipboardDataHandle == nullptr)
{
CloseClipboard();
return;
}
PCWCH pwstr = static_cast<PCWCH>(GlobalLock(ClipboardDataHandle));
_StringPaste(pwstr);
GlobalUnlock(ClipboardDataHandle);
CloseClipboard();
}
void HwndTerminal::_StringPaste(const wchar_t* const pData) noexcept
{
if (pData == nullptr)
{
return;
}
try
{
std::wstring text(pData);
_WriteTextToConnection(text);
}
CATCH_LOG();
}
COORD HwndTerminal::GetFontSize() const
{
return _actualFont.GetSize();

View File

@@ -28,8 +28,6 @@ __declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(void* terminal, dou
__declspec(dllexport) HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions);
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
__declspec(dllexport) HRESULT _stdcall TerminalStartSelection(void* terminal, COORD cursorPosition, bool altPressed);
__declspec(dllexport) HRESULT _stdcall TerminalMoveSelection(void* terminal, COORD cursorPosition);
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
__declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
__declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
@@ -69,7 +67,7 @@ private:
FontInfo _actualFont;
int _currentDpi;
bool _uiaProviderInitialized;
std::function<void(wchar_t*)> _pfnWriteCallback;
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal;
@@ -81,8 +79,6 @@ private:
friend HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions);
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
friend HRESULT _stdcall TerminalStartSelection(void* terminal, COORD cursorPosition, bool altPressed);
friend HRESULT _stdcall TerminalMoveSelection(void* terminal, COORD cursorPosition);
friend void _stdcall TerminalClearSelection(void* terminal);
friend const wchar_t* _stdcall TerminalGetSelection(void* terminal);
friend bool _stdcall TerminalIsSelectionActive(void* terminal);
@@ -91,7 +87,16 @@ private:
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
friend void _stdcall TerminalBlinkCursor(void* terminal);
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
void _UpdateFont(int newDpi);
void _WriteTextToConnection(const std::wstring& text) noexcept;
HRESULT _CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting);
HRESULT _CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat);
void _PasteTextFromClipboard() noexcept;
void _StringPaste(const wchar_t* const pData) noexcept;
HRESULT _StartSelection(LPARAM lParam) noexcept;
HRESULT _MoveSelection(LPARAM lParam) noexcept;
IRawElementProviderSimple* _GetUiaProvider() noexcept;
// Inherited via IControlAccessibilityInfo

View File

@@ -230,23 +230,6 @@ namespace Microsoft.Terminal.Wpf
this.Focus();
NativeMethods.SetFocus(this.hwnd);
break;
case NativeMethods.WindowMessage.WM_LBUTTONDOWN:
this.LeftClickHandler((int)lParam);
break;
case NativeMethods.WindowMessage.WM_RBUTTONDOWN:
if (NativeMethods.TerminalIsSelectionActive(this.terminal))
{
Clipboard.SetText(NativeMethods.TerminalGetSelection(this.terminal));
}
else
{
this.connection.WriteInput(Clipboard.GetText());
}
break;
case NativeMethods.WindowMessage.WM_MOUSEMOVE:
this.MouseMoveHandler((int)wParam, (int)lParam);
break;
case NativeMethods.WindowMessage.WM_KEYDOWN:
NativeMethods.TerminalSetCursorVisible(this.terminal, true);
NativeMethods.TerminalClearSelection(this.terminal);

View File

@@ -650,11 +650,6 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
// Ensure that our cluster vector is clear.
clusters.clear();
// Reset our flag to know when we're in the special circumstance
// of attempting to draw only the right-half of a two-column character
// as the first item in our run.
bool trimLeft = false;
// This inner loop will accumulate clusters until the color changes.
// When the color changes, it will save the new color off and break.
do
@@ -666,33 +661,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
}
// Walk through the text data and turn it into rendering clusters.
// If we're on the first cluster to be added and it's marked as "trailing"
// (a.k.a. the right half of a two column character), then we need some special handling.
if (clusters.empty() && it->DbcsAttr().IsTrailing())
{
// If we have room to move to the left to start drawing...
if (screenPoint.X > 0)
{
// Move left to the one so the whole character can be struck correctly.
--screenPoint.X;
// And tell the next function to trim off the left half of it.
trimLeft = true;
// And add one to the number of columns we expect it to take as we insert it.
clusters.emplace_back(it->Chars(), it->Columns() + 1);
}
else
{
// If we didn't have room, move to the right one and just skip this one.
screenPoint.X++;
continue;
}
}
// Otherwise if it's not a special case, just insert it as is.
else
{
clusters.emplace_back(it->Chars(), it->Columns());
}
clusters.emplace_back(it->Chars(), it->Columns());
// Advance the cluster and column counts.
const auto columnCount = clusters.back().GetColumns();
@@ -702,7 +671,8 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
} while (it);
// Do the painting.
THROW_IF_FAILED(pEngine->PaintBufferLine({ clusters.data(), clusters.size() }, screenPoint, trimLeft, lineWrapped));
// TODO: Calculate when trim left should be TRUE
THROW_IF_FAILED(pEngine->PaintBufferLine({ clusters.data(), clusters.size() }, screenPoint, false, lineWrapped));
// If we're allowed to do grid drawing, draw that now too (since it will be coupled with the color data)
if (_pData->IsGridLineDrawingAllowed())

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
@@ -154,7 +154,18 @@ CustomTextLayout::CustomTextLayout(gsl::not_null<IDWriteFactory1*> const factory
}
// Resequence the resulting runs in order before returning to caller.
_OrderRuns();
const size_t totalRuns = _runs.size();
std::vector<LinkedRun> runs;
runs.resize(totalRuns);
UINT32 nextRunIndex = 0;
for (size_t i = 0; i < totalRuns; ++i)
{
runs.at(i) = _runs.at(nextRunIndex);
nextRunIndex = _runs.at(nextRunIndex).nextRunIndex;
}
_runs.swap(runs);
}
CATCH_RETURN();
return S_OK;
@@ -357,31 +368,6 @@ CustomTextLayout::CustomTextLayout(gsl::not_null<IDWriteFactory1*> const factory
{
LOG_IF_FAILED(_CorrectGlyphRun(runIndex));
}
// If scale corrections were needed, we need to split the run.
for (auto [index, scale] : _glyphScaleCorrections)
{
// Don't split in the middle of a surrogate pair.
const auto after = IS_HIGH_SURROGATE(_text.at(index)) ? 2 : 1;
// Split after the adjustment first so it
// takes a copy of all the run properties before we modify them.
// GH 4665: This is the other half of the potential future perf item.
// If glyphs needing the same scale are coalesced, we could
// break fewer times and have fewer runs.
_SetCurrentRun(index + after);
_SplitCurrentRun(index + after);
// Now split just this glyph off.
_SetCurrentRun(index);
_SplitCurrentRun(index);
// Get the run with the one glyph and adjust the scale.
auto& run = _GetCurrentRun();
run.fontScale = scale;
}
_OrderRuns();
}
CATCH_RETURN();
return S_OK;
@@ -390,94 +376,90 @@ CustomTextLayout::CustomTextLayout(gsl::not_null<IDWriteFactory1*> const factory
// Routine Description:
// - Adjusts the advances for each glyph in the run so it fits within a fixed-column count of cells.
// Arguments:
// - runIndex - The ID number of the internal runs array to use while shaping.
// - runIndex - The ID number of the internal runs array to use while shaping
// Return Value:
// - S_OK or suitable DirectWrite or STL error code
[[nodiscard]] HRESULT CustomTextLayout::_CorrectGlyphRun(const UINT32 runIndex) noexcept
try
{
const Run& run = _runs.at(runIndex);
if (run.textLength == 0)
try
{
return S_FALSE; // Nothing to do..
}
Run& run = _runs.at(runIndex);
// We're going to walk through and check for advances that don't match the space that we expect to give out.
DWRITE_FONT_METRICS1 metrics;
run.fontFace->GetMetrics(&metrics);
// Walk through advances and space out characters that are too small to consume their box.
for (auto i = run.glyphStart; i < (run.glyphStart + run.glyphCount); i++)
{
// Advance is how wide in pixels the glyph is
auto& advance = _glyphAdvances.at(i);
// Offsets is how far to move the origin (in pixels) from where it is
auto& offset = _glyphOffsets.at(i);
// Get how many columns we expected the glyph to have and mutiply into pixels.
const auto columns = _textClusterColumns.at(i);
const auto advanceExpected = static_cast<float>(columns * _width);
// If what we expect is bigger than what we have... pad it out.
if (advanceExpected > advance)
if (run.textLength == 0)
{
// Get the amount of space we have leftover.
const auto diff = advanceExpected - advance;
// Move the X offset (pixels to the right from the left edge) by half the excess space
// so half of it will be left of the glyph and the other half on the right.
offset.advanceOffset += diff / 2;
// Set the advance to the perfect width we want.
advance = advanceExpected;
return S_FALSE; // Nothing to do..
}
// If what we expect is smaller than what we have... rescale the font size to get a smaller glyph to fit.
else if (advanceExpected < advance)
// We're going to walk through and check for advances that don't match the space that we expect to give out.
DWRITE_FONT_METRICS1 metrics;
run.fontFace->GetMetrics(&metrics);
// Walk through advances and space out characters that are too small to consume their box.
for (auto i = run.glyphStart; i < (run.glyphStart + run.glyphCount); i++)
{
// We need to retrieve the design information for this specific glyph so we can figure out the appropriate
// height proportional to the width that we desire.
INT32 advanceInDesignUnits;
RETURN_IF_FAILED(run.fontFace->GetDesignGlyphAdvances(1, &_glyphIndices.at(i), &advanceInDesignUnits));
// Advance is how wide in pixels the glyph is
auto& advance = _glyphAdvances.at(i);
// When things are drawn, we want the font size (as specified in the base font in the original format)
// to be scaled by some factor.
// i.e. if the original font size was 16, we might want to draw this glyph with a 15.2 size font so
// the width (and height) of the glyph will shrink to fit the monospace cell box.
// Offsets is how far to move the origin (in pixels) from where it is
auto& offset = _glyphOffsets.at(i);
// This pattern is copied from the DxRenderer's algorithm for figuring out the font height for a specific width
// and was advised by the DirectWrite team.
const float widthAdvance = static_cast<float>(advanceInDesignUnits) / metrics.designUnitsPerEm;
const auto fontSizeWant = advanceExpected / widthAdvance;
const auto scaleProposed = fontSizeWant / _format->GetFontSize();
// Get how many columns we expected the glyph to have and mutiply into pixels.
const auto columns = _textClusterColumns.at(i);
const auto advanceExpected = static_cast<float>(columns * _width);
// Store the glyph scale correction for future run breaking
// GH 4665: In theory, we could also store the length of the new run and coalesce
// in case two adjacent glyphs need the same scale factor.
_glyphScaleCorrections.push_back(std::tuple{ i, scaleProposed });
// If what we expect is bigger than what we have... pad it out.
if (advanceExpected > advance)
{
// Get the amount of space we have leftover.
const auto diff = advanceExpected - advance;
// Set the advance to the perfect width that we want before figuring out if the scale factor doesn't match this run
advance = advanceExpected;
// Move the X offset (pixels to the right from the left edge) by half the excess space
// so half of it will be left of the glyph and the other half on the right.
offset.advanceOffset += diff / 2;
// Set the advance to the perfect width we want.
advance = advanceExpected;
}
// If what we expect is smaller than what we have... rescale the font size to get a smaller glyph to fit.
else if (advanceExpected < advance)
{
// We need to retrieve the design information for this specific glyph so we can figure out the appropriate
// height proportional to the width that we desire.
INT32 advanceInDesignUnits;
RETURN_IF_FAILED(run.fontFace->GetDesignGlyphAdvances(1, &_glyphIndices.at(i), &advanceInDesignUnits));
// When things are drawn, we want the font size (as specified in the base font in the original format)
// to be scaled by some factor.
// i.e. if the original font size was 16, we might want to draw this glyph with a 15.2 size font so
// the width (and height) of the glyph will shrink to fit the monospace cell box.
// This pattern is copied from the DxRenderer's algorithm for figuring out the font height for a specific width
// and was advised by the DirectWrite team.
const float widthAdvance = static_cast<float>(advanceInDesignUnits) / metrics.designUnitsPerEm;
const auto fontSizeWant = advanceExpected / widthAdvance;
run.fontScale = fontSizeWant / _format->GetFontSize();
// Set the advance to the perfect width that we want.
advance = advanceExpected;
}
}
// Certain fonts, like Batang, contain glyphs for hidden control
// and formatting characters. So we'll want to explicitly force their
// advance to zero.
// I'm leaving this here for future reference, but I don't think we want invisible glyphs for this renderer.
//if (run.script.shapes & DWRITE_SCRIPT_SHAPES_NO_VISUAL)
//{
// std::fill(_glyphAdvances.begin() + glyphStart,
// _glyphAdvances.begin() + glyphStart + actualGlyphCount,
// 0.0f
// );
//}
}
// Certain fonts, like Batang, contain glyphs for hidden control
// and formatting characters. So we'll want to explicitly force their
// advance to zero.
// I'm leaving this here for future reference, but I don't think we want invisible glyphs for this renderer.
//if (run.script.shapes & DWRITE_SCRIPT_SHAPES_NO_VISUAL)
//{
// std::fill(_glyphAdvances.begin() + glyphStart,
// _glyphAdvances.begin() + glyphStart + actualGlyphCount,
// 0.0f
// );
//}
CATCH_RETURN();
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - Takes the analyzed and shaped textual information from the layout process and
@@ -969,18 +951,6 @@ CATCH_RETURN();
return _runs.at(originalRunIndex);
}
// Routine Description:
// - Retrieves the current run according to the internal
// positioning set by Set/Split Current Run methods.
// Arguments:
// - <none>
// Return Value:
// - Mutable reference ot the current run.
[[nodiscard]] CustomTextLayout::LinkedRun& CustomTextLayout::_GetCurrentRun()
{
return _runs.at(_runIndex);
}
// Routine Description:
// - Move the current run to the given position.
// Since the analyzers generally return results in a forward manner,
@@ -1037,126 +1007,5 @@ void CustomTextLayout::_SplitCurrentRun(const UINT32 splitPosition)
frontHalf.textLength = splitPoint;
frontHalf.nextRunIndex = gsl::narrow<UINT32>(totalRuns);
_runIndex = gsl::narrow<UINT32>(totalRuns);
// If there is already a glyph mapping in these runs,
// we need to correct it for the split as well.
// See also (for NxM):
// https://social.msdn.microsoft.com/Forums/en-US/993365bc-8689-45ff-a675-c5ed0c011788/dwriteglyphrundescriptionclustermap-explained
if (frontHalf.glyphCount > 0)
{
// Starting from this:
// TEXT (_text)
// f i ñ e
// CLUSTERMAP (_glyphClusters)
// 0 0 1 3
// GLYPH INDICIES (_glyphIndicies)
// 19 81 23 72
// With _runs length = 1
// _runs(0):
// - Text Index: 0
// - Text Length: 4
// - Glyph Index: 0
// - Glyph Length: 4
//
// If we split at text index = 2 (between i and ñ)...
// ... then this will be the state after the text splitting above:
//
// TEXT (_text)
// f i ñ e
// CLUSTERMAP (_glyphClusters)
// 0 0 1 3
// GLYPH INDICIES (_glyphIndicies)
// 19 81 23 72
// With _runs length = 2
// _runs(0):
// - Text Index: 0
// - Text Length: 2
// - Glyph Index: 0
// - Glyph Length: 4
// _runs(1):
// - Text Index: 2
// - Text Length: 2
// - Glyph Index: 0
// - Glyph Length: 4
//
// Notice that the text index/length values are correct,
// but we haven't fixed up the glyph index/lengths to match.
// We need it to say:
// With _runs length = 2
// _runs(0):
// - Text Index: 0
// - Text Length: 2
// - Glyph Index: 0
// - Glyph Length: 1
// _runs(1):
// - Text Index: 2
// - Text Length: 2
// - Glyph Index: 1
// - Glyph Length: 3
//
// Which means that the cluster map value under the beginning
// of the right-hand text range is our offset to fix all the values.
// In this case, that's 1 corresponding with the ñ.
const auto mapOffset = _glyphClusters.at(backHalf.textStart);
// The front half's glyph start index (position in _glyphIndicies)
// stays the same.
// The front half's glyph count (items in _glyphIndicies to consume)
// is the offset value as that's now one past the end of the front half.
// (and count is end index + 1)
frontHalf.glyphCount = mapOffset;
// The back half starts at the index that's one past the end of the front
backHalf.glyphStart = mapOffset;
// And the back half count (since it was copied from the front half above)
// now just needs to be subtracted by how many we gave the front half.
backHalf.glyphCount -= mapOffset;
// The CLUSTERMAP is also wrong given that it is relative
// to each run. And now there are two runs so the map
// value under the ñ and e need to updated to be relative
// to the text index "2" now instead of the original.
//
// For the entire range of the back half, we need to walk through and
// slide all the glyph mapping values to be relative to the new
// backHalf.glyphStart, or adjust it by the offset we just set it to.
const auto updateBegin = _glyphClusters.begin() + backHalf.textStart;
std::for_each_n(updateBegin, backHalf.textLength, [mapOffset](UINT16& n) {
n -= mapOffset;
});
}
}
// Routine Description:
// - Takes the linked runs stored in the state variable _runs
// and ensures that their vector/array indexes are in order in which they're drawn.
// - This is to be used after splitting and reordering them with the split/select functions
// as those manipulate the runs like a linked list (instead of an ordered array)
// while splitting to reduce copy overhead and just reorder them when complete with this func.
// Arguments:
// - <none> - Manipulates _runs variable.
// Return Value:
// - <none>
void CustomTextLayout::_OrderRuns()
{
const size_t totalRuns = _runs.size();
std::vector<LinkedRun> runs;
runs.resize(totalRuns);
UINT32 nextRunIndex = 0;
for (UINT32 i = 0; i < totalRuns; ++i)
{
runs.at(i) = _runs.at(nextRunIndex);
runs.at(i).nextRunIndex = i + 1;
nextRunIndex = _runs.at(nextRunIndex).nextRunIndex;
}
runs.back().nextRunIndex = 0;
_runs.swap(runs);
}
#pragma endregion

View File

@@ -117,10 +117,8 @@ namespace Microsoft::Console::Render
};
[[nodiscard]] LinkedRun& _FetchNextRun(UINT32& textLength);
[[nodiscard]] LinkedRun& _GetCurrentRun();
void _SetCurrentRun(const UINT32 textPosition);
void _SplitCurrentRun(const UINT32 splitPosition);
void _OrderRuns();
[[nodiscard]] HRESULT STDMETHODCALLTYPE _AnalyzeFontFallback(IDWriteTextAnalysisSource* const source, UINT32 textPosition, UINT32 textLength);
[[nodiscard]] HRESULT STDMETHODCALLTYPE _SetMappedFont(UINT32 textPosition, UINT32 textLength, IDWriteFont* const font, FLOAT const scale);
@@ -166,28 +164,9 @@ namespace Microsoft::Console::Render
UINT32 _runIndex;
// Glyph shaping results
std::vector<DWRITE_GLYPH_OFFSET> _glyphOffsets;
// Clusters are complicated. They're in respect to each individual run.
// The offsets listed here are in respect to the _text string, but from the beginning index of
// each run.
// That means if we have two runs, we will see 0 1 2 3 4 0 1 2 3 4 5 6 7... in this clusters count.
std::vector<UINT16> _glyphClusters;
// This appears to be the index of the glyph inside each font.
std::vector<UINT16> _glyphIndices;
std::vector<float> _glyphAdvances;
// These are used to further break the runs apart and adjust the font size so glyphs fit inside the cells.
std::vector<std::tuple<UINT32, float>> _glyphScaleCorrections;
#ifdef UNIT_TESTING
public:
CustomTextLayout() = default;
friend class CustomTextLayoutTests;
#endif
};
}

View File

@@ -272,13 +272,6 @@ using namespace Microsoft::Console::Render;
rect.right = std::accumulate(advancesSpan.cbegin(), advancesSpan.cend(), rect.right);
// Clip all drawing in this glyph run to where we expect.
d2dContext->PushAxisAlignedClip(rect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
// Ensure we pop it on the way out
auto popclip = wil::scope_exit([&d2dContext]() noexcept {
d2dContext->PopAxisAlignedClip();
});
d2dContext->FillRectangle(rect, drawingContext->backgroundBrush);
// Now go onto drawing the text.

View File

@@ -21,7 +21,7 @@
using namespace DirectX;
std::atomic<size_t> Microsoft::Console::Render::DxEngine::_tracelogCount{ 0 };
#pragma warning(suppress : 26477) // We don't control tracelogging macros
#pragma warning(suppress : 26477)
TRACELOGGING_DEFINE_PROVIDER(g_hDxRenderProvider,
"Microsoft.Windows.Terminal.Renderer.DirectX",
// {c93e739e-ae50-5a14-78e7-f171e947535d}

View File

@@ -1,3 +1,2 @@
DIRS= \
lib \
ut_dx \
lib

View File

@@ -1,100 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "WexTestClass.h"
#include "..\..\inc\consoletaeftemplates.hpp"
#include "..\CustomTextLayout.h"
using namespace WEX::Common;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace Microsoft::Console::Render;
class Microsoft::Console::Render::CustomTextLayoutTests
{
TEST_CLASS(CustomTextLayoutTests);
TEST_METHOD(OrderRuns)
{
CustomTextLayout layout;
// Create linked list runs where a --> c --> b
CustomTextLayout::LinkedRun a;
a.nextRunIndex = 2;
a.textStart = 0;
CustomTextLayout::LinkedRun b;
b.nextRunIndex = 0;
b.textStart = 20;
CustomTextLayout::LinkedRun c;
c.nextRunIndex = 1;
c.textStart = 10;
// but insert them into the runs as a, b, c
layout._runs.push_back(a);
layout._runs.push_back(b);
layout._runs.push_back(c);
// Now order them.
layout._OrderRuns();
// Validate that they've been reordered to a, c, b by index so they can be iterated to go in order.
// The text starts should be in order 0, 10, 20.
// The next run indexes should point at each other.
VERIFY_ARE_EQUAL(a.textStart, layout._runs.at(0).textStart);
VERIFY_ARE_EQUAL(1u, layout._runs.at(0).nextRunIndex);
VERIFY_ARE_EQUAL(c.textStart, layout._runs.at(1).textStart);
VERIFY_ARE_EQUAL(2u, layout._runs.at(1).nextRunIndex);
VERIFY_ARE_EQUAL(b.textStart, layout._runs.at(2).textStart);
VERIFY_ARE_EQUAL(0u, layout._runs.at(2).nextRunIndex);
}
TEST_METHOD(SplitCurrentRunIncludingGlyphs)
{
CustomTextLayout layout;
// Put glyph data into the layout as if we've already gone through analysis.
// This data matches the verbose comment from the CustomTextLayout.cpp file
// and is derived from
// https://social.msdn.microsoft.com/Forums/en-US/993365bc-8689-45ff-a675-c5ed0c011788/dwriteglyphrundescriptionclustermap-explained
layout._text = L"fiñe";
layout._glyphIndices.push_back(19);
layout._glyphIndices.push_back(81);
layout._glyphIndices.push_back(23);
layout._glyphIndices.push_back(72);
layout._glyphClusters.push_back(0);
layout._glyphClusters.push_back(0);
layout._glyphClusters.push_back(1);
layout._glyphClusters.push_back(3);
// Set up the layout to have a run that already has glyph data inside of it.
CustomTextLayout::LinkedRun run;
run.textStart = 0;
run.textLength = 4;
run.glyphStart = 0;
run.glyphCount = 4;
layout._runs.push_back(run);
// Now split it in the middle per the comment example
layout._SetCurrentRun(2);
layout._SplitCurrentRun(2);
// And validate that the split state matches what we expected.
VERIFY_ARE_EQUAL(0u, layout._runs.at(0).textStart);
VERIFY_ARE_EQUAL(2u, layout._runs.at(0).textLength);
VERIFY_ARE_EQUAL(0u, layout._runs.at(0).glyphStart);
VERIFY_ARE_EQUAL(1u, layout._runs.at(0).glyphCount);
VERIFY_ARE_EQUAL(2u, layout._runs.at(1).textStart);
VERIFY_ARE_EQUAL(2u, layout._runs.at(1).textLength);
VERIFY_ARE_EQUAL(1u, layout._runs.at(1).glyphStart);
VERIFY_ARE_EQUAL(3u, layout._runs.at(1).glyphCount);
}
};

View File

@@ -1,12 +0,0 @@
//Autogenerated file name + version resource file for Device Guard whitelisting effort
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_UNKNOWN
#define VER_FILESUBTYPE VFT2_UNKNOWN
#define VER_FILEDESCRIPTION_STR ___TARGETNAME
#define VER_INTERNALNAME_STR ___TARGETNAME
#define VER_ORIGINALFILENAME_STR ___TARGETNAME
#include "common.ver"

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{95B136F9-B238-490C-A7C5-5843C1FECAC4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>DxUnitTests</RootNamespace>
<ProjectName>Dx.Unit.Tests</ProjectName>
<TargetName>Dx.Unit.Tests</TargetName>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(SolutionDir)src\common.build.pre.props" />
<ItemGroup>
<ClCompile Include="CustomTextLayoutTests.cpp" />
<ClCompile Include="..\precomp.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\types\lib\types.vcxproj">
<Project>{18d09a24-8240-42d6-8cb6-236eee820263}</Project>
</ProjectReference>
<ProjectReference Include="..\..\base\lib\base.vcxproj">
<Project>{af0a096a-8b3a-4949-81ef-7df8f0fee91f}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\dx.vcxproj">
<Project>{48D21369-3D7B-4431-9967-24E81292CF62}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\precomp.h" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..;$(SolutionDir)src\inc;$(SolutionDir)src\inc\test;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(SolutionDir)src\common.build.post.props" />
<Import Project="$(SolutionDir)src\common.build.tests.props" />
</Project>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="ProductBuild" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(NTMAKEENV)\UniversalTest\Microsoft.TestInfrastructure.UniversalTest.props" />
</Project>

View File

@@ -1,34 +0,0 @@
!include ..\..\project.unittest.inc
# -------------------------------------
# Program Information
# -------------------------------------
TARGETNAME = Microsoft.Console.Renderer.Dx.UnitTests
TARGETTYPE = DYNLINK
DLLDEF =
# -------------------------------------
# Sources, Headers, and Libraries
# -------------------------------------
SOURCES = \
$(SOURCES) \
CustomTextLayoutTests.cpp \
DefaultResource.rc \
INCLUDES = \
.. \
$(INCLUDES) \
TARGETLIBS = \
$(WINCORE_OBJ_PATH)\console\open\src\renderer\dx\lib\$(O)\ConRenderDx.lib \
$(TARGETLIBS) \
# -------------------------------------
# Localization
# -------------------------------------
# Autogenerated. Sets file name for Device Guard whitelisting effort, used in RC.exe.
C_DEFINES = $(C_DEFINES) -D___TARGETNAME="""$(TARGETNAME).$(TARGETTYPE)"""
MUI_VERIFY_NO_LOC_RESOURCE = 1

View File

@@ -73,7 +73,7 @@ void RenderTracing::TraceString(const std::string_view& instr) const
const char* const seq = _seq.c_str();
TraceLoggingWrite(g_hConsoleVtRendererTraceProvider,
"VtEngine_TraceString",
TraceLoggingUtf8String(seq),
TraceLoggingString(seq),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
}
#else