wip
This commit is contained in:
parent
479ef264b2
commit
9cb4fc4373
9
.github/actions/spelling/allow/apis.txt
vendored
9
.github/actions/spelling/allow/apis.txt
vendored
|
@ -9,6 +9,7 @@ BUILDBRANCH
|
|||
BUILDMSG
|
||||
BUILDNUMBER
|
||||
BYPOSITION
|
||||
calloc
|
||||
charconv
|
||||
CLASSNOTAVAILABLE
|
||||
cmdletbinding
|
||||
|
@ -25,6 +26,8 @@ DERR
|
|||
dlldata
|
||||
DONTADDTORECENT
|
||||
DWORDLONG
|
||||
dxgidebug
|
||||
dxguid
|
||||
enumset
|
||||
environstrings
|
||||
EXPCMDFLAGS
|
||||
|
@ -66,8 +69,8 @@ IObject
|
|||
iosfwd
|
||||
IPackage
|
||||
IPeasant
|
||||
isspace
|
||||
ISetup
|
||||
isspace
|
||||
IStorage
|
||||
istream
|
||||
IStringable
|
||||
|
@ -82,12 +85,12 @@ llu
|
|||
localtime
|
||||
lround
|
||||
LSHIFT
|
||||
memicmp
|
||||
MENUCOMMAND
|
||||
MENUDATA
|
||||
MENUINFO
|
||||
memicmp
|
||||
mptt
|
||||
mov
|
||||
mptt
|
||||
msappx
|
||||
MULTIPLEUSE
|
||||
NCHITTEST
|
||||
|
|
5
.github/actions/spelling/allow/names.txt
vendored
5
.github/actions/spelling/allow/names.txt
vendored
|
@ -3,6 +3,7 @@ austdi
|
|||
Ballmer
|
||||
bhoj
|
||||
Bhojwani
|
||||
Bilodeau
|
||||
carlos
|
||||
dhowett
|
||||
Diviness
|
||||
|
@ -25,8 +26,8 @@ jerrysh
|
|||
Kaiyu
|
||||
kimwalisch
|
||||
KMehrain
|
||||
KODELIFE
|
||||
Kodelife
|
||||
KODELIFE
|
||||
Kourosh
|
||||
kowalczyk
|
||||
leonmsft
|
||||
|
@ -73,8 +74,8 @@ Wirt
|
|||
Wojciech
|
||||
zadjii
|
||||
Zamor
|
||||
Zamora
|
||||
zamora
|
||||
Zamora
|
||||
Zoey
|
||||
zorio
|
||||
Zverovich
|
||||
|
|
19
.github/actions/spelling/expect/expect.txt
vendored
19
.github/actions/spelling/expect/expect.txt
vendored
|
@ -312,6 +312,7 @@ commdlg
|
|||
COMMITID
|
||||
compat
|
||||
componentization
|
||||
COMPOSITIONSURFACE
|
||||
conapi
|
||||
conareainfo
|
||||
conattrs
|
||||
|
@ -426,6 +427,8 @@ cstring
|
|||
cstyle
|
||||
csv
|
||||
CSwitch
|
||||
csx
|
||||
csy
|
||||
CTerminal
|
||||
CText
|
||||
ctime
|
||||
|
@ -847,6 +850,7 @@ GAUSSIAN
|
|||
gci
|
||||
gcx
|
||||
gcy
|
||||
GDC
|
||||
gdi
|
||||
gdip
|
||||
gdirenderer
|
||||
|
@ -1344,6 +1348,7 @@ LPWINDOWPOS
|
|||
lpwpos
|
||||
lpwstr
|
||||
LRESULT
|
||||
lroundf
|
||||
lru
|
||||
lsb
|
||||
lsconfig
|
||||
|
@ -1445,6 +1450,7 @@ MOUSEMOVE
|
|||
mousewheel
|
||||
movemask
|
||||
MOVESTART
|
||||
movsb
|
||||
msb
|
||||
msbuild
|
||||
mscorlib
|
||||
|
@ -1623,6 +1629,7 @@ NVIDIA
|
|||
NVR
|
||||
OACR
|
||||
oauth
|
||||
obin
|
||||
objbase
|
||||
ocf
|
||||
ocolor
|
||||
|
@ -1746,6 +1753,7 @@ pdx
|
|||
peb
|
||||
PEMAGIC
|
||||
PENDTASKMSG
|
||||
Pentium
|
||||
pfa
|
||||
PFACENODE
|
||||
pfed
|
||||
|
@ -1910,6 +1918,7 @@ pythonw
|
|||
qos
|
||||
QRSTU
|
||||
qsort
|
||||
Qstrip
|
||||
queryable
|
||||
QUESTIONMARK
|
||||
quickedit
|
||||
|
@ -1917,6 +1926,7 @@ QWER
|
|||
qzmp
|
||||
RAII
|
||||
RALT
|
||||
rapi
|
||||
rasterbar
|
||||
rasterfont
|
||||
rasterization
|
||||
|
@ -2199,7 +2209,6 @@ somefile
|
|||
SOURCEBRANCH
|
||||
sourced
|
||||
SOURCESDIRECTORY
|
||||
SPACEBAR
|
||||
spammy
|
||||
spand
|
||||
sprintf
|
||||
|
@ -2309,6 +2318,7 @@ taskbar
|
|||
tbar
|
||||
TBase
|
||||
tbc
|
||||
TBDR
|
||||
tbi
|
||||
Tbl
|
||||
TBM
|
||||
|
@ -2421,6 +2431,7 @@ Trd
|
|||
TREX
|
||||
triaged
|
||||
triaging
|
||||
TRIANGLELIST
|
||||
TRIANGLESTRIP
|
||||
TRIMZEROHEADINGS
|
||||
truetype
|
||||
|
@ -2498,12 +2509,13 @@ unittesting
|
|||
universaltest
|
||||
unk
|
||||
unknwn
|
||||
Unmap
|
||||
unmark
|
||||
UNORM
|
||||
unparseable
|
||||
unpause
|
||||
Unregister
|
||||
unregistering
|
||||
unscoped
|
||||
untests
|
||||
untextured
|
||||
untimes
|
||||
|
@ -2568,6 +2580,7 @@ vectorized
|
|||
VERCTRL
|
||||
versioning
|
||||
VERTBAR
|
||||
VERTEXID
|
||||
VFT
|
||||
vga
|
||||
vgaoem
|
||||
|
@ -2575,6 +2588,7 @@ viewkind
|
|||
viewports
|
||||
Virt
|
||||
VIRTTERM
|
||||
virtualalloc
|
||||
Virtualizing
|
||||
vkey
|
||||
VKKEYSCAN
|
||||
|
@ -2851,6 +2865,7 @@ YDPI
|
|||
yIcon
|
||||
yml
|
||||
YOffset
|
||||
yolo
|
||||
YPosition
|
||||
YSize
|
||||
YSubstantial
|
||||
|
|
178
OpenConsole.sln
178
OpenConsole.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29001.49
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31410.414
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Terminal", "Terminal", "{59840756-302F-44DF-AA47-441A9D673202}"
|
||||
EndProject
|
||||
|
@ -131,6 +131,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Scratch", "src\tools\scratc
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InteractivityWin32", "src\interactivity\win32\lib\win32.LIB.vcxproj", "{06EC74CB-9A12-429C-B551-8532EC964726}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {8222900C-8B6C-452A-91AC-BE95DB04B95F}
|
||||
{1C959542-BAC2-4E55-9A6D-13251914CBB9} = {1C959542-BAC2-4E55-9A6D-13251914CBB9}
|
||||
{990F2657-8580-4828-943F-5DD657D11842} = {990F2657-8580-4828-943F-5DD657D11842}
|
||||
{AF0A096A-8B3A-4949-81EF-7DF8F0FEE91F} = {AF0A096A-8B3A-4949-81EF-7DF8F0FEE91F}
|
||||
|
@ -400,6 +401,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsTerminal.UIA.Tests",
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-ms-win-core-synch-l1-2-0", "src\api-ms-win-core-synch-l1-2-0\api-ms-win-core-synch-l1-2-0.vcxproj", "{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererAtlas", "src\renderer\atlas\atlas.vcxproj", "{8222900C-8B6C-452A-91AC-BE95DB04B95F}"
|
||||
EndProject
|
||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "HostPackage", "src\host\HostPackage\HostPackage.wapproj", "{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenConsoleShellExt", "src\host\ShellExtension\OpenConsoleShellExt.vcxproj", "{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
AuditMode|Any CPU = AuditMode|Any CPU
|
||||
|
@ -3339,6 +3346,170 @@ Global
|
|||
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x64.Build.0 = Release|x64
|
||||
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}.Release|x86.Build.0 = Release|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|x64.Build.0 = Debug|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x64.ActiveCfg = Release|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x64.Build.0 = Release|x64
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x86.Build.0 = Release|Win32
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|Any CPU.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|ARM.ActiveCfg = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|ARM.Build.0 = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|ARM.Deploy.0 = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|ARM64.ActiveCfg = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|ARM64.Build.0 = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|ARM64.Deploy.0 = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|DotNet_x64Test.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|DotNet_x64Test.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|DotNet_x64Test.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|DotNet_x86Test.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|DotNet_x86Test.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|DotNet_x86Test.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|x64.ActiveCfg = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|x64.Build.0 = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|x64.Deploy.0 = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|x86.ActiveCfg = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|x86.Build.0 = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.AuditMode|x86.Deploy.0 = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|DotNet_x64Test.ActiveCfg = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|DotNet_x64Test.Build.0 = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|DotNet_x64Test.Deploy.0 = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|DotNet_x86Test.ActiveCfg = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|DotNet_x86Test.Build.0 = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|DotNet_x86Test.Deploy.0 = Debug|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|x64.Build.0 = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|x86.Build.0 = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|Any CPU.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|ARM.ActiveCfg = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|ARM.Build.0 = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|ARM.Deploy.0 = Debug|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|ARM64.Build.0 = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|DotNet_x64Test.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|DotNet_x64Test.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|DotNet_x64Test.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|DotNet_x86Test.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|DotNet_x86Test.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|DotNet_x86Test.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|x64.ActiveCfg = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|x64.Build.0 = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|x64.Deploy.0 = Debug|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|x86.ActiveCfg = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|x86.Build.0 = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Fuzzing|x86.Deploy.0 = Debug|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|ARM.Build.0 = Release|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|DotNet_x64Test.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|DotNet_x64Test.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|DotNet_x64Test.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|DotNet_x86Test.ActiveCfg = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|DotNet_x86Test.Build.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|DotNet_x86Test.Deploy.0 = Release|Any CPU
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|x64.ActiveCfg = Release|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|x64.Build.0 = Release|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|x64.Deploy.0 = Release|x64
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|x86.ActiveCfg = Release|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|x86.Build.0 = Release|x86
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE}.Release|x86.Deploy.0 = Release|x86
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|x64.Build.0 = Debug|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|x64.Build.0 = Fuzzing|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Fuzzing|x86.Build.0 = Fuzzing|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|x64.ActiveCfg = Release|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|x64.Build.0 = Release|x64
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -3438,6 +3609,9 @@ Global
|
|||
{C323DAEE-B307-4C7B-ACE5-7293CBEFCB5B} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
|
||||
{F19DACD5-0C6E-40DC-B6E4-767A3200542C} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
|
||||
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {05500DEF-2294-41E3-AF9A-24E580B82836}
|
||||
{44D35904-4DC6-4EEC-86F2-6E3E341C95BE} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
||||
|
|
21
oss/robin-hood-hashing/LICENSE
Normal file
21
oss/robin-hood-hashing/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018-2021 Martin Ankerl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
9
oss/robin-hood-hashing/MAINTAINER_README.md
Normal file
9
oss/robin-hood-hashing/MAINTAINER_README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
### Notes for Future Maintainers
|
||||
|
||||
The provenance information (where it came from and which commit) is stored in the file `cgmanifest.json` in the same directory as this readme.
|
||||
Please update the provenance information in that file when ingesting an updated version of the dependent library.
|
||||
That provenance file is automatically read and inventoried by Microsoft systems to ensure compliance with appropiate governance standards.
|
||||
|
||||
## Updates
|
||||
|
||||
Get updates from here: https://github.com/martinus/robin-hood-hashing
|
14
oss/robin-hood-hashing/cgmanifest.json
Normal file
14
oss/robin-hood-hashing/cgmanifest.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"Registrations": [
|
||||
{
|
||||
"component": {
|
||||
"type": "git",
|
||||
"git": {
|
||||
"repositoryUrl": "https://github.com/martinus/robin-hood-hashing",
|
||||
"commitHash": "24b3f50f9532153edc23b29ae277dcccfd75a462"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Version": 1
|
||||
}
|
2529
oss/robin-hood-hashing/robin_hood.h
Normal file
2529
oss/robin-hood-hashing/robin_hood.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -17,8 +17,8 @@
|
|||
// Note: will through if unable to allocate char/attribute buffers
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26447) // small_vector's constructor says it can throw but it should not given how we use it. This suppresses this error for the AuditMode build.
|
||||
CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
|
||||
_data(rowWidth, value_type()),
|
||||
CharRow::CharRow(CharRowCell* buffer, size_t rowWidth, ROW* const pParent) noexcept :
|
||||
_data(buffer, rowWidth),
|
||||
_pParent{ FAIL_FAST_IF_NULL(pParent) }
|
||||
{
|
||||
}
|
||||
|
@ -53,38 +53,9 @@ void CharRow::Reset() noexcept
|
|||
// - resizes the width of the CharRowBase
|
||||
// Arguments:
|
||||
// - newSize - the new width of the character and attributes rows
|
||||
// Return Value:
|
||||
// - S_OK on success, otherwise relevant error code
|
||||
[[nodiscard]] HRESULT CharRow::Resize(const size_t newSize) noexcept
|
||||
void CharRow::Resize(CharRowCell* buffer, const size_t newSize) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
const value_type insertVals;
|
||||
_data.resize(newSize, insertVals);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
typename CharRow::iterator CharRow::begin() noexcept
|
||||
{
|
||||
return _data.begin();
|
||||
}
|
||||
|
||||
typename CharRow::const_iterator CharRow::cbegin() const noexcept
|
||||
{
|
||||
return _data.cbegin();
|
||||
}
|
||||
|
||||
typename CharRow::iterator CharRow::end() noexcept
|
||||
{
|
||||
return _data.end();
|
||||
}
|
||||
|
||||
typename CharRow::const_iterator CharRow::cend() const noexcept
|
||||
{
|
||||
return _data.cend();
|
||||
_data = { buffer, newSize };
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -95,12 +66,16 @@ typename CharRow::const_iterator CharRow::cend() const noexcept
|
|||
// - The calculated left boundary of the internal string.
|
||||
size_t CharRow::MeasureLeft() const noexcept
|
||||
{
|
||||
const_iterator it = _data.cbegin();
|
||||
while (it != _data.cend() && it->IsSpace())
|
||||
const auto beg = _data.begin();
|
||||
const auto end = _data.end();
|
||||
|
||||
auto it = beg;
|
||||
while (it != end && it->IsSpace())
|
||||
{
|
||||
++it;
|
||||
}
|
||||
return it - _data.cbegin();
|
||||
|
||||
return it - beg;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -111,17 +86,21 @@ size_t CharRow::MeasureLeft() const noexcept
|
|||
// - The calculated right boundary of the internal string.
|
||||
size_t CharRow::MeasureRight() const
|
||||
{
|
||||
const_reverse_iterator it = _data.crbegin();
|
||||
while (it != _data.crend() && it->IsSpace())
|
||||
const auto beg = _data.rbegin();
|
||||
const auto end = _data.rend();
|
||||
|
||||
auto it = beg;
|
||||
while (it != end && it->IsSpace())
|
||||
{
|
||||
++it;
|
||||
}
|
||||
return _data.crend() - it;
|
||||
|
||||
return end - it;
|
||||
}
|
||||
|
||||
void CharRow::ClearCell(const size_t column)
|
||||
{
|
||||
_data.at(column).Reset();
|
||||
_data[column].Reset();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -132,7 +111,7 @@ void CharRow::ClearCell(const size_t column)
|
|||
// - True if there is valid text in this row. False otherwise.
|
||||
bool CharRow::ContainsText() const noexcept
|
||||
{
|
||||
for (const value_type& cell : _data)
|
||||
for (const auto& cell : _data)
|
||||
{
|
||||
if (!cell.IsSpace())
|
||||
{
|
||||
|
@ -151,7 +130,7 @@ bool CharRow::ContainsText() const noexcept
|
|||
// Note: will throw exception if column is out of bounds
|
||||
const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
|
||||
{
|
||||
return _data.at(column).DbcsAttr();
|
||||
return _data[column].DbcsAttr();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -163,7 +142,7 @@ const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
|
|||
// Note: will throw exception if column is out of bounds
|
||||
DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
|
||||
{
|
||||
return _data.at(column).DbcsAttr();
|
||||
return _data[column].DbcsAttr();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -175,7 +154,7 @@ DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
|
|||
// Note: will throw exception if column is out of bounds
|
||||
void CharRow::ClearGlyph(const size_t column)
|
||||
{
|
||||
_data.at(column).EraseChars();
|
||||
_data[column].EraseChars();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
|
@ -49,15 +49,12 @@ class CharRow final
|
|||
public:
|
||||
using glyph_type = typename wchar_t;
|
||||
using value_type = typename CharRowCell;
|
||||
using iterator = typename boost::container::small_vector_base<value_type>::iterator;
|
||||
using const_iterator = typename boost::container::small_vector_base<value_type>::const_iterator;
|
||||
using const_reverse_iterator = typename boost::container::small_vector_base<value_type>::const_reverse_iterator;
|
||||
using reference = typename CharRowCellReference;
|
||||
|
||||
CharRow(size_t rowWidth, ROW* const pParent) noexcept;
|
||||
CharRow(CharRowCell* buffer, size_t rowWidth, ROW* const pParent) noexcept;
|
||||
|
||||
size_t size() const noexcept;
|
||||
[[nodiscard]] HRESULT Resize(const size_t newSize) noexcept;
|
||||
void Resize(CharRowCell* buffer, const size_t newSize) noexcept;
|
||||
size_t MeasureLeft() const noexcept;
|
||||
size_t MeasureRight() const;
|
||||
bool ContainsText() const noexcept;
|
||||
|
@ -71,14 +68,46 @@ public:
|
|||
const reference GlyphAt(const size_t column) const;
|
||||
reference GlyphAt(const size_t column);
|
||||
|
||||
// iterators
|
||||
iterator begin() noexcept;
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator begin() const noexcept { return cbegin(); }
|
||||
auto begin() noexcept
|
||||
{
|
||||
// gsl::span uses strict bounds checking even in Release mode.
|
||||
// While this can be useful, not even our STL is that strict.
|
||||
// --> Reduce iteration overhead in Release by returning pointers.
|
||||
#ifdef NDEBUG
|
||||
return _data.data();
|
||||
#else
|
||||
return _data.begin();
|
||||
#endif
|
||||
}
|
||||
|
||||
iterator end() noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
const_iterator end() const noexcept { return cend(); }
|
||||
auto begin() const noexcept
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
return _data.data();
|
||||
#else
|
||||
return _data.begin();
|
||||
#endif
|
||||
}
|
||||
|
||||
auto end() noexcept
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
#pragma warning(suppress : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
|
||||
return _data.data() + _data.size();
|
||||
#else
|
||||
return _data.end();
|
||||
#endif
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
#pragma warning(suppress : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
|
||||
return _data.data() + _data.size();
|
||||
#else
|
||||
return _data.end();
|
||||
#endif
|
||||
}
|
||||
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
|
@ -96,20 +125,21 @@ private:
|
|||
|
||||
protected:
|
||||
// storage for glyph data and dbcs attributes
|
||||
boost::container::small_vector<value_type, 120> _data;
|
||||
gsl::span<CharRowCell> _data;
|
||||
|
||||
// ROW that this CharRow belongs to
|
||||
ROW* _pParent;
|
||||
};
|
||||
|
||||
template<typename InputIt1, typename InputIt2>
|
||||
void OverwriteColumns(InputIt1 startChars, InputIt1 endChars, InputIt2 startAttrs, CharRow::iterator outIt)
|
||||
template<typename InputIt1, typename InputIt2, typename OutputIt>
|
||||
void OverwriteColumns(InputIt1 startChars, InputIt1 endChars, InputIt2 startAttrs, OutputIt outIt)
|
||||
{
|
||||
std::transform(startChars,
|
||||
endChars,
|
||||
startAttrs,
|
||||
outIt,
|
||||
[](const wchar_t wch, const DbcsAttribute attr) {
|
||||
return CharRow::value_type{ wch, attr };
|
||||
});
|
||||
std::transform(
|
||||
startChars,
|
||||
endChars,
|
||||
startAttrs,
|
||||
outIt,
|
||||
[](const wchar_t wch, const DbcsAttribute attr) {
|
||||
return CharRow::value_type{ wch, attr };
|
||||
});
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ void CharRowCell::Reset() noexcept
|
|||
// - true if cell contains a space glyph, false otherwise
|
||||
bool CharRowCell::IsSpace() const noexcept
|
||||
{
|
||||
return !_attr.IsGlyphStored() && _wch == UNICODE_SPACE;
|
||||
return !_attr.IsGlyphStored() && (_wch == 0 || _wch == UNICODE_SPACE);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
friend constexpr bool operator==(const CharRowCell& a, const CharRowCell& b) noexcept;
|
||||
|
||||
private:
|
||||
wchar_t _wch{ UNICODE_SPACE };
|
||||
wchar_t _wch{};
|
||||
DbcsAttribute _attr{};
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
#include "UnicodeStorage.hpp"
|
||||
#include "CharRow.hpp"
|
||||
|
||||
CharRowCellReference::CharRowCellReference(CharRow& parent, const size_t index) :
|
||||
_parent{ parent },
|
||||
_index{ index }
|
||||
{
|
||||
Expects(index < parent.size());
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - assignment operator. will store extended glyph data in a separate storage location
|
||||
// Arguments:
|
||||
|
@ -41,7 +48,7 @@ CharRowCellReference::operator std::wstring_view() const
|
|||
// - ref to the CharRowCell
|
||||
CharRowCell& CharRowCellReference::_cellData()
|
||||
{
|
||||
return _parent._data.at(_index);
|
||||
return til::at(_parent._data, _index);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -50,7 +57,7 @@ CharRowCell& CharRowCellReference::_cellData()
|
|||
// - ref to the CharRowCell
|
||||
const CharRowCell& CharRowCellReference::_cellData() const
|
||||
{
|
||||
return _parent._data.at(_index);
|
||||
return til::at(_parent._data, _index);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
|
@ -25,11 +25,7 @@ class CharRowCellReference final
|
|||
public:
|
||||
using const_iterator = const wchar_t*;
|
||||
|
||||
CharRowCellReference(CharRow& parent, const size_t index) noexcept :
|
||||
_parent{ parent },
|
||||
_index{ index }
|
||||
{
|
||||
}
|
||||
CharRowCellReference(CharRow& parent, const size_t index);
|
||||
|
||||
~CharRowCellReference() = default;
|
||||
CharRowCellReference(const CharRowCellReference&) noexcept = default;
|
||||
|
|
|
@ -81,7 +81,7 @@ OutputCellIterator::OutputCellIterator(const CHAR_INFO& charInfo, const size_t f
|
|||
// - This is an iterator over a range of text only. No color data will be modified as the text is inserted.
|
||||
// Arguments:
|
||||
// - utf16Text - UTF-16 text range
|
||||
OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text) :
|
||||
OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text) noexcept :
|
||||
_mode(Mode::LooseTextOnly),
|
||||
_currentView(s_GenerateView(utf16Text)),
|
||||
_run(utf16Text),
|
||||
|
@ -97,7 +97,7 @@ OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text) :
|
|||
// Arguments:
|
||||
// - utf16Text - UTF-16 text range
|
||||
// - attribute - Color to apply over the entire range
|
||||
OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute) :
|
||||
OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute) noexcept :
|
||||
_mode(Mode::Loose),
|
||||
_currentView(s_GenerateView(utf16Text, attribute)),
|
||||
_run(utf16Text),
|
||||
|
@ -362,7 +362,7 @@ bool OutputCellIterator::_TryMoveTrailing() noexcept
|
|||
// - view - View representing characters corresponding to a single glyph
|
||||
// Return Value:
|
||||
// - Object representing the view into this cell
|
||||
OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view)
|
||||
OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view) noexcept
|
||||
{
|
||||
return s_GenerateView(view, InvalidTextAttribute, TextAttributeBehavior::Current);
|
||||
}
|
||||
|
@ -377,8 +377,7 @@ OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view)
|
|||
// - attr - Color attributes to apply to the text
|
||||
// Return Value:
|
||||
// - Object representing the view into this cell
|
||||
OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view,
|
||||
const TextAttribute attr)
|
||||
OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view, const TextAttribute attr) noexcept
|
||||
{
|
||||
return s_GenerateView(view, attr, TextAttributeBehavior::Stored);
|
||||
}
|
||||
|
@ -394,9 +393,7 @@ OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view,
|
|||
// - behavior - Behavior of the given text attribute (used when writing)
|
||||
// Return Value:
|
||||
// - Object representing the view into this cell
|
||||
OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view,
|
||||
const TextAttribute attr,
|
||||
const TextAttributeBehavior behavior)
|
||||
OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view, const TextAttribute attr, const TextAttributeBehavior behavior) noexcept
|
||||
{
|
||||
const auto glyph = Utf16Parser::ParseNext(view);
|
||||
DbcsAttribute dbcsAttr;
|
||||
|
|
|
@ -37,8 +37,8 @@ public:
|
|||
OutputCellIterator(const TextAttribute& attr, const size_t fillLimit = 0) noexcept;
|
||||
OutputCellIterator(const wchar_t& wch, const TextAttribute& attr, const size_t fillLimit = 0) noexcept;
|
||||
OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit = 0) noexcept;
|
||||
OutputCellIterator(const std::wstring_view utf16Text);
|
||||
OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute);
|
||||
OutputCellIterator(const std::wstring_view utf16Text) noexcept;
|
||||
OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute) noexcept;
|
||||
OutputCellIterator(const gsl::span<const WORD> legacyAttributes) noexcept;
|
||||
OutputCellIterator(const gsl::span<const CHAR_INFO> charInfos) noexcept;
|
||||
OutputCellIterator(const gsl::span<const OutputCell> cells);
|
||||
|
@ -100,14 +100,9 @@ private:
|
|||
|
||||
bool _TryMoveTrailing() noexcept;
|
||||
|
||||
static OutputCellView s_GenerateView(const std::wstring_view view);
|
||||
|
||||
static OutputCellView s_GenerateView(const std::wstring_view view,
|
||||
const TextAttribute attr);
|
||||
|
||||
static OutputCellView s_GenerateView(const std::wstring_view view,
|
||||
const TextAttribute attr,
|
||||
const TextAttributeBehavior behavior);
|
||||
static OutputCellView s_GenerateView(const std::wstring_view view) noexcept;
|
||||
static OutputCellView s_GenerateView(const std::wstring_view view, const TextAttribute attr) noexcept;
|
||||
static OutputCellView s_GenerateView(const std::wstring_view view, const TextAttribute attr, const TextAttributeBehavior behavior) noexcept;
|
||||
|
||||
static OutputCellView s_GenerateView(const wchar_t& wch) noexcept;
|
||||
static OutputCellView s_GenerateViewLegacyAttr(const WORD& legacyAttr) noexcept;
|
||||
|
|
|
@ -31,7 +31,17 @@ OutputCellView::OutputCellView(const std::wstring_view view,
|
|||
// TODO: GH 2681 - remove this suppression by reconciling the probably bad design of the iterators that leads to this being required.
|
||||
[[gsl::suppress(26445)]] const std::wstring_view& OutputCellView::Chars() const noexcept
|
||||
{
|
||||
return _view;
|
||||
static constexpr std::wstring_view emptyBufferCell{ L"\0", 1 };
|
||||
static constexpr std::wstring_view spaceBufferCell{ L" ", 1 };
|
||||
|
||||
// The buffer uses virtual memory and rows might not be initialized yet.
|
||||
// To us they'll appear as if they contain \0, but we don't want to pass that to the renderer.
|
||||
if (_view != emptyBufferCell)
|
||||
{
|
||||
return _view;
|
||||
}
|
||||
|
||||
return spaceBufferCell;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
|
@ -16,10 +16,9 @@
|
|||
// - pParent - the text buffer that this row belongs to
|
||||
// Return Value:
|
||||
// - constructed object
|
||||
ROW::ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
|
||||
ROW::ROW(const SHORT rowId, CharRowCell* buffer, const unsigned short rowWidth, const TextAttribute& fillAttribute, TextBuffer* const pParent) :
|
||||
_id{ rowId },
|
||||
_rowWidth{ rowWidth },
|
||||
_charRow{ rowWidth, this },
|
||||
_charRow{ buffer, rowWidth, this },
|
||||
_attrRow{ rowWidth, fillAttribute },
|
||||
_lineRendition{ LineRendition::SingleWidth },
|
||||
_wrapForced{ false },
|
||||
|
@ -34,7 +33,7 @@ ROW::ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute f
|
|||
// - Attr - The default attribute (color) to fill
|
||||
// Return Value:
|
||||
// - <none>
|
||||
bool ROW::Reset(const TextAttribute Attr)
|
||||
bool ROW::Reset(const TextAttribute& Attr)
|
||||
{
|
||||
_lineRendition = LineRendition::SingleWidth;
|
||||
_wrapForced = false;
|
||||
|
@ -52,26 +51,6 @@ bool ROW::Reset(const TextAttribute Attr)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - resizes ROW to new width
|
||||
// Arguments:
|
||||
// - width - the new width, in cells
|
||||
// Return Value:
|
||||
// - S_OK if successful, otherwise relevant error
|
||||
[[nodiscard]] HRESULT ROW::Resize(const unsigned short width)
|
||||
{
|
||||
RETURN_IF_FAILED(_charRow.Resize(width));
|
||||
try
|
||||
{
|
||||
_attrRow.Resize(width);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
_rowWidth = width;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - clears char data in column in row
|
||||
// Arguments:
|
||||
|
|
|
@ -32,9 +32,9 @@ class TextBuffer;
|
|||
class ROW final
|
||||
{
|
||||
public:
|
||||
ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
|
||||
ROW(const SHORT rowId, CharRowCell* buffer, const unsigned short rowWidth, const TextAttribute& fillAttribute, TextBuffer* const pParent);
|
||||
|
||||
size_t size() const noexcept { return _rowWidth; }
|
||||
size_t size() const noexcept { return _charRow.size(); }
|
||||
|
||||
void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
|
||||
bool WasWrapForced() const noexcept { return _wrapForced; }
|
||||
|
@ -54,8 +54,7 @@ public:
|
|||
SHORT GetId() const noexcept { return _id; }
|
||||
void SetId(const SHORT id) noexcept { _id = id; }
|
||||
|
||||
bool Reset(const TextAttribute Attr);
|
||||
[[nodiscard]] HRESULT Resize(const unsigned short width);
|
||||
bool Reset(const TextAttribute& Attr);
|
||||
|
||||
void ClearColumn(const size_t column);
|
||||
std::wstring GetText() const { return _charRow.GetText(); }
|
||||
|
@ -74,13 +73,12 @@ private:
|
|||
CharRow _charRow;
|
||||
ATTR_ROW _attrRow;
|
||||
LineRendition _lineRendition;
|
||||
TextBuffer* _pParent; // non ownership pointer
|
||||
SHORT _id;
|
||||
unsigned short _rowWidth;
|
||||
// Occurs when the user runs out of text in a given row and we're forced to wrap the cursor to the next line
|
||||
bool _wrapForced;
|
||||
// Occurs when the user runs out of text to support a double byte character and we're forced to the next line
|
||||
bool _doubleBytePadded;
|
||||
TextBuffer* _pParent; // non ownership pointer
|
||||
};
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
|
|
|
@ -85,10 +85,6 @@ public:
|
|||
|
||||
friend constexpr bool operator==(const TextAttribute& a, const TextAttribute& b) noexcept;
|
||||
friend constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexcept;
|
||||
friend constexpr bool operator==(const TextAttribute& attr, const WORD& legacyAttr) noexcept;
|
||||
friend constexpr bool operator!=(const TextAttribute& attr, const WORD& legacyAttr) noexcept;
|
||||
friend constexpr bool operator==(const WORD& legacyAttr, const TextAttribute& attr) noexcept;
|
||||
friend constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept;
|
||||
|
||||
bool IsLegacy() const noexcept;
|
||||
bool IsBold() const noexcept;
|
||||
|
|
|
@ -47,7 +47,7 @@ void UnicodeStorage::Erase(const key_type key) noexcept
|
|||
// - rowMap - A map of the old row IDs to the new row IDs.
|
||||
// - width - The width of the new row. Remove any items that are beyond the row width.
|
||||
// - Use nullopt if we're not resizing the width of the row, just renumbering the rows.
|
||||
void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width)
|
||||
void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, SHORT width)
|
||||
{
|
||||
// Make a temporary map to hold all the new row positioning
|
||||
std::unordered_map<key_type, mapped_type> newMap;
|
||||
|
@ -58,18 +58,10 @@ void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const
|
|||
// Extract the old coordinate position
|
||||
const auto oldCoord = pair.first;
|
||||
|
||||
// Only try to short-circuit based on width if we were told it changed
|
||||
// by being given a new width value.
|
||||
if (width.has_value())
|
||||
// If the column index is at/beyond the row width, don't bother copying it to the new map.
|
||||
if (oldCoord.X >= width)
|
||||
{
|
||||
// Get the column ID
|
||||
const auto oldColId = oldCoord.X;
|
||||
|
||||
// If the column index is at/beyond the row width, don't bother copying it to the new map.
|
||||
if (oldColId >= width.value())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the row ID from the position as that's what we need to remap
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
void Erase(const key_type key) noexcept;
|
||||
|
||||
void Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width);
|
||||
void Remap(const std::unordered_map<SHORT, SHORT>& rowMap, SHORT width);
|
||||
|
||||
private:
|
||||
std::unordered_map<key_type, mapped_type> _map;
|
||||
|
|
|
@ -31,21 +31,19 @@ TextBuffer::TextBuffer(const COORD screenBufferSize,
|
|||
const TextAttribute defaultAttributes,
|
||||
const UINT cursorSize,
|
||||
Microsoft::Console::Render::IRenderTarget& renderTarget) :
|
||||
_firstRow{ 0 },
|
||||
_currentAttributes{ defaultAttributes },
|
||||
_cursor{ cursorSize, *this },
|
||||
_storage{},
|
||||
_unicodeStorage{},
|
||||
_renderTarget{ renderTarget },
|
||||
_size{},
|
||||
_currentHyperlinkId{ 1 },
|
||||
_currentPatternId{ 0 }
|
||||
_renderTarget{ renderTarget }
|
||||
{
|
||||
// initialize ROWs
|
||||
_charBuffer = _AllocateCharBuffer(screenBufferSize);
|
||||
_storage.reserve(static_cast<size_t>(screenBufferSize.Y));
|
||||
for (size_t i = 0; i < static_cast<size_t>(screenBufferSize.Y); ++i)
|
||||
|
||||
auto buffer = _charBuffer.get();
|
||||
|
||||
for (SHORT i = 0; i < screenBufferSize.Y; ++i)
|
||||
{
|
||||
_storage.emplace_back(static_cast<SHORT>(i), screenBufferSize.X, _currentAttributes, this);
|
||||
_storage.emplace_back(i, buffer, screenBufferSize.X, _currentAttributes, this);
|
||||
buffer += screenBufferSize.X;
|
||||
}
|
||||
|
||||
_UpdateSize();
|
||||
|
@ -83,11 +81,9 @@ UINT TextBuffer::TotalRowCount() const noexcept
|
|||
// - const reference to the requested row. Asserts if out of bounds.
|
||||
const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
||||
{
|
||||
const size_t totalRows = TotalRowCount();
|
||||
|
||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||
const size_t offsetIndex = (_firstRow + index) % totalRows;
|
||||
return _storage.at(offsetIndex);
|
||||
const size_t offsetIndex = (_firstRow + index) % _storage.size();
|
||||
return _storage[offsetIndex];
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -99,11 +95,9 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
|||
// - reference to the requested row. Asserts if out of bounds.
|
||||
ROW& TextBuffer::GetRowByOffset(const size_t index)
|
||||
{
|
||||
const size_t totalRows = TotalRowCount();
|
||||
|
||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||
const size_t offsetIndex = (_firstRow + index) % totalRows;
|
||||
return _storage.at(offsetIndex);
|
||||
const size_t offsetIndex = (_firstRow + index) % _storage.size();
|
||||
return _storage[offsetIndex];
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -400,7 +394,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
|||
//Return Value:
|
||||
// - true if we successfully inserted the character
|
||||
// - false otherwise (out of memory)
|
||||
bool TextBuffer::InsertCharacter(const std::wstring_view chars,
|
||||
bool TextBuffer::InsertCharacter(const std::wstring_view& chars,
|
||||
const DbcsAttribute dbcsAttribute,
|
||||
const TextAttribute attr)
|
||||
{
|
||||
|
@ -670,6 +664,15 @@ const Viewport TextBuffer::GetSize() const noexcept
|
|||
return _size;
|
||||
}
|
||||
|
||||
wil::unique_virtualalloc_ptr<CharRowCell> TextBuffer::_AllocateCharBuffer(const COORD size)
|
||||
{
|
||||
const auto dx = static_cast<size_t>(size.X);
|
||||
const auto dy = static_cast<size_t>(size.Y);
|
||||
const auto buffer = static_cast<CharRowCell*>(VirtualAlloc(nullptr, dx * dy * sizeof(CharRowCell), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
|
||||
THROW_IF_NULL_ALLOC(buffer);
|
||||
return wil::unique_virtualalloc_ptr<CharRowCell>{ buffer };
|
||||
}
|
||||
|
||||
void TextBuffer::_UpdateSize()
|
||||
{
|
||||
_size = Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
|
||||
|
@ -778,7 +781,7 @@ void TextBuffer::ScrollRows(const SHORT firstRow, const SHORT size, const SHORT
|
|||
|
||||
// Renumber the IDs now that we've rearranged where the rows sit within the buffer.
|
||||
// Refreshing should also delegate to the UnicodeStorage to re-key all the stored unicode sequences (where applicable).
|
||||
_RefreshRowIDs(std::nullopt);
|
||||
_RefreshRowIDs(_size.Width());
|
||||
}
|
||||
|
||||
Cursor& TextBuffer::GetCursor() noexcept
|
||||
|
@ -863,14 +866,14 @@ COORD TextBuffer::ScreenToBufferPosition(const COORD position) const
|
|||
{
|
||||
// Use shift right to quickly divide the X pos by 2 for double width lines.
|
||||
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||
return { position.X >> scale, position.Y };
|
||||
return { gsl::narrow_cast<SHORT>(position.X >> scale), position.Y };
|
||||
}
|
||||
|
||||
COORD TextBuffer::BufferToScreenPosition(const COORD position) const
|
||||
{
|
||||
// Use shift left to quickly multiply the X pos by 2 for double width lines.
|
||||
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||
return { position.X << scale, position.Y };
|
||||
return { gsl::narrow_cast<SHORT>(position.X << scale), position.Y };
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -896,49 +899,43 @@ void TextBuffer::Reset()
|
|||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
|
||||
|
||||
try
|
||||
auto charBuffer = _AllocateCharBuffer(newSize);
|
||||
const auto currentSize = GetSize().Dimensions();
|
||||
const auto attributes = GetCurrentAttributes();
|
||||
|
||||
SHORT TopRow = 0; // new top row of the screen buffer
|
||||
if (newSize.Y <= GetCursor().GetPosition().Y)
|
||||
{
|
||||
const auto currentSize = GetSize().Dimensions();
|
||||
const auto attributes = GetCurrentAttributes();
|
||||
|
||||
SHORT TopRow = 0; // new top row of the screen buffer
|
||||
if (newSize.Y <= GetCursor().GetPosition().Y)
|
||||
{
|
||||
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
|
||||
}
|
||||
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
|
||||
|
||||
// rotate rows until the top row is at index 0
|
||||
for (int i = 0; i < TopRowIndex; i++)
|
||||
{
|
||||
_storage.emplace_back(std::move(_storage.front()));
|
||||
_storage.erase(_storage.begin());
|
||||
}
|
||||
|
||||
_SetFirstRowIndex(0);
|
||||
|
||||
// realloc in the Y direction
|
||||
// remove rows if we're shrinking
|
||||
while (_storage.size() > static_cast<size_t>(newSize.Y))
|
||||
{
|
||||
_storage.pop_back();
|
||||
}
|
||||
// add rows if we're growing
|
||||
while (_storage.size() < static_cast<size_t>(newSize.Y))
|
||||
{
|
||||
_storage.emplace_back(static_cast<short>(_storage.size()), newSize.X, attributes, this);
|
||||
}
|
||||
|
||||
// Now that we've tampered with the row placement, refresh all the row IDs.
|
||||
// Also take advantage of the row ID refresh loop to resize the rows in the X dimension
|
||||
// and cleanup the UnicodeStorage characters that might fall outside the resized buffer.
|
||||
_RefreshRowIDs(newSize.X);
|
||||
|
||||
// Update the cached size value
|
||||
_UpdateSize();
|
||||
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
|
||||
|
||||
// rotate rows until the top row is at index 0
|
||||
std::rotate(_storage.begin(), _storage.begin() + TopRowIndex, _storage.end());
|
||||
_SetFirstRowIndex(0);
|
||||
|
||||
// realloc in the Y direction
|
||||
// remove rows if we're shrinking
|
||||
while (_storage.size() > static_cast<size_t>(newSize.Y))
|
||||
{
|
||||
_storage.pop_back();
|
||||
}
|
||||
// add rows if we're growing
|
||||
while (_storage.size() < static_cast<size_t>(newSize.Y))
|
||||
{
|
||||
_storage.emplace_back(static_cast<short>(_storage.size()), nullptr, newSize.X, attributes, this);
|
||||
}
|
||||
|
||||
// Now that we've tampered with the row placement, refresh all the row IDs.
|
||||
// Also take advantage of the row ID refresh loop to resize the rows in the X dimension
|
||||
// and cleanup the UnicodeStorage characters that might fall outside the resized buffer.
|
||||
_RefreshRowIDs(newSize.X);
|
||||
_RefreshRowWidth(charBuffer.get(), newSize.X);
|
||||
|
||||
// Update the cached size value
|
||||
_UpdateSize();
|
||||
|
||||
_charBuffer = std::move(charBuffer);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -961,7 +958,7 @@ UnicodeStorage& TextBuffer::GetUnicodeStorage() noexcept
|
|||
// any high unicode (UnicodeStorage) runs while we're already looping through the rows.
|
||||
// Arguments:
|
||||
// - newRowWidth - Optional new value for the row width.
|
||||
void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
|
||||
void TextBuffer::_RefreshRowIDs(SHORT width)
|
||||
{
|
||||
std::unordered_map<SHORT, SHORT> rowMap;
|
||||
SHORT i = 0;
|
||||
|
@ -975,17 +972,19 @@ void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
|
|||
|
||||
// Also update the char row parent pointers as they can get shuffled up in the rotates.
|
||||
it.GetCharRow().UpdateParent(&it);
|
||||
|
||||
// Resize the rows in the X dimension if we have a new width
|
||||
if (newRowWidth.has_value())
|
||||
{
|
||||
// Realloc in the X direction
|
||||
THROW_IF_FAILED(it.Resize(newRowWidth.value()));
|
||||
}
|
||||
}
|
||||
|
||||
// Give the new mapping to Unicode Storage
|
||||
_unicodeStorage.Remap(rowMap, newRowWidth);
|
||||
_unicodeStorage.Remap(rowMap, width);
|
||||
}
|
||||
|
||||
void TextBuffer::_RefreshRowWidth(CharRowCell* data, size_t width) noexcept
|
||||
{
|
||||
for (auto& it : _storage)
|
||||
{
|
||||
it.GetCharRow().Resize(data, width);
|
||||
data += width;
|
||||
}
|
||||
}
|
||||
|
||||
void TextBuffer::_NotifyPaint(const Viewport& viewport) const
|
||||
|
@ -1044,7 +1043,7 @@ Microsoft::Console::Render::IRenderTarget& TextBuffer::GetRenderTarget() noexcep
|
|||
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
||||
// Return Value:
|
||||
// - the delimiter class for the given char
|
||||
const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const
|
||||
const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std::wstring_view& wordDelimiters) const
|
||||
{
|
||||
return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
|
||||
}
|
||||
|
@ -1060,7 +1059,7 @@ const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std
|
|||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - The COORD for the first character on the "word" (inclusive)
|
||||
const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view& wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// Consider a buffer with this text in it:
|
||||
// " word other "
|
||||
|
@ -1110,7 +1109,7 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
|||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The COORD for the first character on the current/previous READABLE "word" (inclusive)
|
||||
const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const
|
||||
const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const std::wstring_view& wordDelimiters) const
|
||||
{
|
||||
COORD result = target;
|
||||
const auto bufferSize = GetSize();
|
||||
|
@ -1155,7 +1154,7 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
|
|||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The COORD for the first character on the current word or delimiter run (stopped by the left margin)
|
||||
const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const
|
||||
const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std::wstring_view& wordDelimiters) const
|
||||
{
|
||||
COORD result = target;
|
||||
const auto bufferSize = GetSize();
|
||||
|
@ -1188,7 +1187,7 @@ const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std:
|
|||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||
// Return Value:
|
||||
// - The COORD for the last character on the "word" (inclusive)
|
||||
const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view& wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// Consider a buffer with this text in it:
|
||||
// " word other "
|
||||
|
@ -1226,7 +1225,7 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
|||
// - limit - the last "valid" position in the text buffer (to improve performance)
|
||||
// Return Value:
|
||||
// - The COORD for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
||||
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const
|
||||
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view& wordDelimiters, const COORD limit) const
|
||||
{
|
||||
const auto bufferSize{ GetSize() };
|
||||
COORD result{ target };
|
||||
|
@ -1276,7 +1275,7 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
|
|||
// - wordDelimiters - what characters are we considering for the separation of words
|
||||
// Return Value:
|
||||
// - The COORD for the last character of the current word or delimiter run (stopped by right margin)
|
||||
const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const
|
||||
const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::wstring_view& wordDelimiters) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
|
||||
|
@ -1359,7 +1358,7 @@ void TextBuffer::_PruneHyperlinks()
|
|||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
|
||||
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view& wordDelimiters, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
// move to the beginning of the next word
|
||||
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
|
||||
|
@ -1385,7 +1384,7 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
|
|||
// Return Value:
|
||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
||||
bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters) const
|
||||
bool TextBuffer::MoveToPreviousWord(COORD& pos, const std::wstring_view& wordDelimiters) const
|
||||
{
|
||||
// move to the beginning of the current word
|
||||
auto copy{ GetWordStart(pos, wordDelimiters, true) };
|
||||
|
@ -1782,7 +1781,7 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
|
|||
// - string containing the generated HTML
|
||||
std::string TextBuffer::GenHTML(const TextAndColor& rows,
|
||||
const int fontHeightPoints,
|
||||
const std::wstring_view fontFaceName,
|
||||
const std::wstring_view& fontFaceName,
|
||||
const COLORREF backgroundColor)
|
||||
{
|
||||
try
|
||||
|
@ -1845,7 +1844,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows,
|
|||
const auto writeAccumulatedChars = [&](bool includeCurrent) {
|
||||
if (col >= startOffset)
|
||||
{
|
||||
const auto unescapedText = ConvertToA(CP_UTF8, std::wstring_view(rows.text.at(row)).substr(startOffset, col - startOffset + includeCurrent));
|
||||
const auto unescapedText = ConvertToA(CP_UTF8, rows.text.at(row).substr(startOffset, col - startOffset + includeCurrent));
|
||||
for (const auto c : unescapedText)
|
||||
{
|
||||
switch (c)
|
||||
|
@ -1971,7 +1970,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows,
|
|||
// - htmlTitle - value used in title tag of html header. Used to name the application
|
||||
// Return Value:
|
||||
// - string containing the generated RTF
|
||||
std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoints, const std::wstring_view fontFaceName, const COLORREF backgroundColor)
|
||||
std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoints, const std::wstring_view& fontFaceName, const COLORREF backgroundColor)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -2033,7 +2032,7 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
|
|||
const auto writeAccumulatedChars = [&](bool includeCurrent) {
|
||||
if (col >= startOffset)
|
||||
{
|
||||
const auto unescapedText = ConvertToA(CP_UTF8, std::wstring_view(rows.text.at(row)).substr(startOffset, col - startOffset + includeCurrent));
|
||||
const auto unescapedText = ConvertToA(CP_UTF8, rows.text.at(row).substr(startOffset, col - startOffset + includeCurrent));
|
||||
for (const auto c : unescapedText)
|
||||
{
|
||||
switch (c)
|
||||
|
@ -2411,9 +2410,9 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
|||
// - Adds or updates a hyperlink in our hyperlink table
|
||||
// Arguments:
|
||||
// - The hyperlink URI, the hyperlink id (could be new or old)
|
||||
void TextBuffer::AddHyperlinkToMap(std::wstring_view uri, uint16_t id)
|
||||
void TextBuffer::AddHyperlinkToMap(const std::wstring_view& uri, uint16_t id)
|
||||
{
|
||||
_hyperlinkMap[id] = uri;
|
||||
_hyperlinkMap.emplace(id, uri);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -2433,28 +2432,31 @@ std::wstring TextBuffer::GetHyperlinkUriFromId(uint16_t id) const
|
|||
// - The user-defined id
|
||||
// Return value:
|
||||
// - The internal hyperlink ID
|
||||
uint16_t TextBuffer::GetHyperlinkId(std::wstring_view uri, std::wstring_view id)
|
||||
uint16_t TextBuffer::GetHyperlinkId(const std::wstring_view& uri, const std::wstring_view& id)
|
||||
{
|
||||
uint16_t numericId = 0;
|
||||
if (id.empty())
|
||||
{
|
||||
// no custom id specified, return our internal count
|
||||
numericId = _currentHyperlinkId;
|
||||
++_currentHyperlinkId;
|
||||
numericId = _currentHyperlinkId++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// assign _currentHyperlinkId if the custom id does not already exist
|
||||
std::wstring newId{ id };
|
||||
// hash the URL and add it to the custom ID - GH#7698
|
||||
newId += L"%" + std::to_wstring(std::hash<std::wstring_view>{}(uri));
|
||||
const auto result = _hyperlinkCustomIdMap.emplace(newId, _currentHyperlinkId);
|
||||
// We need to use both uri and id for hashing. See GH#7698
|
||||
std::wstring key;
|
||||
key.reserve(uri.size() + id.size());
|
||||
key.append(uri);
|
||||
key.append(id);
|
||||
|
||||
const auto result = _hyperlinkCustomIdMap.emplace(key, _currentHyperlinkId);
|
||||
numericId = result.first->second;
|
||||
|
||||
if (result.second)
|
||||
{
|
||||
// the custom id did not already exist
|
||||
_hyperlinkCustomIdMapReverse.insert_or_assign(_currentHyperlinkId, key);
|
||||
++_currentHyperlinkId;
|
||||
}
|
||||
numericId = (*(result.first)).second;
|
||||
}
|
||||
// _currentHyperlinkId could overflow, make sure its not 0
|
||||
if (_currentHyperlinkId == 0)
|
||||
|
@ -2472,13 +2474,11 @@ uint16_t TextBuffer::GetHyperlinkId(std::wstring_view uri, std::wstring_view id)
|
|||
void TextBuffer::RemoveHyperlinkFromMap(uint16_t id) noexcept
|
||||
{
|
||||
_hyperlinkMap.erase(id);
|
||||
for (const auto& customIdPair : _hyperlinkCustomIdMap)
|
||||
|
||||
if (auto it = _hyperlinkCustomIdMapReverse.find(id); it != _hyperlinkCustomIdMapReverse.end())
|
||||
{
|
||||
if (customIdPair.second == id)
|
||||
{
|
||||
_hyperlinkCustomIdMap.erase(customIdPair.first);
|
||||
break;
|
||||
}
|
||||
_hyperlinkCustomIdMap.erase(it->second);
|
||||
_hyperlinkCustomIdMapReverse.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2491,12 +2491,9 @@ void TextBuffer::RemoveHyperlinkFromMap(uint16_t id) noexcept
|
|||
// - The custom ID if there was one, empty string otherwise
|
||||
std::wstring TextBuffer::GetCustomIdFromId(uint16_t id) const
|
||||
{
|
||||
for (auto customIdPair : _hyperlinkCustomIdMap)
|
||||
if (auto it = _hyperlinkCustomIdMapReverse.find(id); it != _hyperlinkCustomIdMapReverse.end())
|
||||
{
|
||||
if (customIdPair.second == id)
|
||||
{
|
||||
return customIdPair.first;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -2510,6 +2507,7 @@ void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
|
|||
{
|
||||
_hyperlinkMap = other._hyperlinkMap;
|
||||
_hyperlinkCustomIdMap = other._hyperlinkCustomIdMap;
|
||||
_hyperlinkCustomIdMapReverse = other._hyperlinkCustomIdMapReverse;
|
||||
_currentHyperlinkId = other._currentHyperlinkId;
|
||||
}
|
||||
|
||||
|
@ -2520,7 +2518,7 @@ void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
|
|||
// - The regex pattern
|
||||
// Return value:
|
||||
// - An ID that the caller should associate with the given pattern
|
||||
const size_t TextBuffer::AddPatternRecognizer(const std::wstring_view regexString)
|
||||
const size_t TextBuffer::AddPatternRecognizer(const std::wstring_view& regexString)
|
||||
{
|
||||
++_currentPatternId;
|
||||
_idsAndPatterns.emplace(std::make_pair(_currentPatternId, regexString));
|
||||
|
|
|
@ -98,7 +98,7 @@ public:
|
|||
const std::optional<size_t> limitRight = std::nullopt);
|
||||
|
||||
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
bool InsertCharacter(const std::wstring_view chars, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
bool InsertCharacter(const std::wstring_view& chars, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
bool IncrementCursor();
|
||||
bool NewlineCursor();
|
||||
|
||||
|
@ -141,10 +141,10 @@ public:
|
|||
|
||||
Microsoft::Console::Render::IRenderTarget& GetRenderTarget() noexcept;
|
||||
|
||||
const COORD GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
const COORD GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToPreviousWord(COORD& pos, const std::wstring_view wordDelimiters) const;
|
||||
const COORD GetWordStart(const COORD target, const std::wstring_view& wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
const COORD GetWordEnd(const COORD target, const std::wstring_view& wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToNextWord(COORD& pos, const std::wstring_view& wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
bool MoveToPreviousWord(COORD& pos, const std::wstring_view& wordDelimiters) const;
|
||||
|
||||
const til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
const til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||
|
@ -153,9 +153,9 @@ public:
|
|||
|
||||
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const;
|
||||
|
||||
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
||||
void AddHyperlinkToMap(const std::wstring_view& uri, uint16_t id);
|
||||
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
||||
uint16_t GetHyperlinkId(std::wstring_view uri, std::wstring_view id);
|
||||
uint16_t GetHyperlinkId(const std::wstring_view& uri, const std::wstring_view& id);
|
||||
void RemoveHyperlinkFromMap(uint16_t id) noexcept;
|
||||
std::wstring GetCustomIdFromId(uint16_t id) const;
|
||||
void CopyHyperlinkMaps(const TextBuffer& OtherBuffer);
|
||||
|
@ -176,12 +176,12 @@ public:
|
|||
|
||||
static std::string GenHTML(const TextAndColor& rows,
|
||||
const int fontHeightPoints,
|
||||
const std::wstring_view fontFaceName,
|
||||
const std::wstring_view& fontFaceName,
|
||||
const COLORREF backgroundColor);
|
||||
|
||||
static std::string GenRTF(const TextAndColor& rows,
|
||||
const int fontHeightPoints,
|
||||
const std::wstring_view fontFaceName,
|
||||
const std::wstring_view& fontFaceName,
|
||||
const COLORREF backgroundColor);
|
||||
|
||||
struct PositionInformation
|
||||
|
@ -195,60 +195,49 @@ public:
|
|||
const std::optional<Microsoft::Console::Types::Viewport> lastCharacterViewport,
|
||||
std::optional<std::reference_wrapper<PositionInformation>> positionInfo);
|
||||
|
||||
const size_t AddPatternRecognizer(const std::wstring_view regexString);
|
||||
const size_t AddPatternRecognizer(const std::wstring_view& regexString);
|
||||
void ClearPatternRecognizers() noexcept;
|
||||
void CopyPatterns(const TextBuffer& OtherBuffer);
|
||||
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const size_t firstRow, const size_t lastRow) const;
|
||||
|
||||
private:
|
||||
static wil::unique_virtualalloc_ptr<CharRowCell> _AllocateCharBuffer(const COORD size);
|
||||
|
||||
void _UpdateSize();
|
||||
Microsoft::Console::Types::Viewport _size;
|
||||
std::vector<ROW> _storage;
|
||||
Cursor _cursor;
|
||||
|
||||
SHORT _firstRow; // indexes top row (not necessarily 0)
|
||||
|
||||
TextAttribute _currentAttributes;
|
||||
|
||||
// storage location for glyphs that can't fit into the buffer normally
|
||||
UnicodeStorage _unicodeStorage;
|
||||
|
||||
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
|
||||
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
||||
uint16_t _currentHyperlinkId;
|
||||
|
||||
void _RefreshRowIDs(std::optional<SHORT> newRowWidth);
|
||||
|
||||
Microsoft::Console::Render::IRenderTarget& _renderTarget;
|
||||
|
||||
void _RefreshRowIDs(SHORT width);
|
||||
void _RefreshRowWidth(CharRowCell* data, size_t width) noexcept;
|
||||
void _SetFirstRowIndex(const SHORT FirstRowIndex) noexcept;
|
||||
|
||||
COORD _GetPreviousFromCursor() const;
|
||||
|
||||
void _SetWrapOnCurrentRow();
|
||||
void _AdjustWrapOnCurrentRow(const bool fSet);
|
||||
|
||||
void _NotifyPaint(const Microsoft::Console::Types::Viewport& viewport) const;
|
||||
|
||||
// Assist with maintaining proper buffer state for Double Byte character sequences
|
||||
bool _PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
||||
bool _AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
||||
|
||||
ROW& _GetFirstRow();
|
||||
ROW& _GetPrevRowNoWrap(const ROW& row);
|
||||
|
||||
void _ExpandTextRow(SMALL_RECT& selectionRow) const;
|
||||
|
||||
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
|
||||
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const;
|
||||
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||
|
||||
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view& wordDelimiters) const;
|
||||
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view& wordDelimiters) const;
|
||||
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view& wordDelimiters) const;
|
||||
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view& wordDelimiters, const COORD limit) const;
|
||||
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view& wordDelimiters) const;
|
||||
void _PruneHyperlinks();
|
||||
|
||||
Microsoft::Console::Render::IRenderTarget& _renderTarget;
|
||||
wil::unique_virtualalloc_ptr<CharRowCell> _charBuffer;
|
||||
std::vector<ROW> _storage;
|
||||
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
|
||||
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
||||
std::unordered_map<uint16_t, std::wstring> _hyperlinkCustomIdMapReverse;
|
||||
std::unordered_map<size_t, std::wstring> _idsAndPatterns;
|
||||
size_t _currentPatternId;
|
||||
TextAttribute _currentAttributes;
|
||||
UnicodeStorage _unicodeStorage;
|
||||
Cursor _cursor;
|
||||
Microsoft::Console::Types::Viewport _size;
|
||||
uint16_t _currentHyperlinkId{ 1 };
|
||||
size_t _currentPatternId{ 0 };
|
||||
SHORT _firstRow{ 0 }; // indexes top row (not necessarily 0)
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class TextBufferTests;
|
||||
|
|
|
@ -28,25 +28,6 @@ static constexpr bool _IsMouseMessage(UINT uMsg)
|
|||
uMsg == WM_MOUSEMOVE || uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL;
|
||||
}
|
||||
|
||||
// Helper static function to ensure that all ambiguous-width glyphs are reported as narrow.
|
||||
// See microsoft/terminal#2066 for more info.
|
||||
static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */) noexcept
|
||||
{
|
||||
return false; // glyph is not wide.
|
||||
}
|
||||
|
||||
static bool _EnsureStaticInitialization()
|
||||
{
|
||||
// use C++11 magic statics to make sure we only do this once.
|
||||
static bool initialized = []() {
|
||||
// *** THIS IS A SINGLETON ***
|
||||
SetGlyphWidthFallback(_IsGlyphWideForceNarrowFallback);
|
||||
|
||||
return true;
|
||||
}();
|
||||
return initialized;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc(
|
||||
HWND hwnd,
|
||||
UINT uMsg,
|
||||
|
@ -176,8 +157,6 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) :
|
|||
_pfnWriteCallback{ nullptr },
|
||||
_multiClickTime{ 500 } // this will be overwritten by the windows system double-click time
|
||||
{
|
||||
_EnsureStaticInitialization();
|
||||
|
||||
HINSTANCE hInstance = wil::GetModuleInstanceHandle();
|
||||
|
||||
if (RegisterTermClass(hInstance))
|
||||
|
@ -220,7 +199,6 @@ HRESULT HwndTerminal::Initialize()
|
|||
|
||||
auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>();
|
||||
RETURN_IF_FAILED(dxEngine->SetHwnd(_hwnd.get()));
|
||||
RETURN_IF_FAILED(dxEngine->Enable());
|
||||
_renderer->AddRenderEngine(dxEngine.get());
|
||||
|
||||
_UpdateFont(USER_DEFAULT_SCREEN_DPI);
|
||||
|
|
|
@ -35,25 +35,6 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(
|
|||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// Helper static function to ensure that all ambiguous-width glyphs are reported as narrow.
|
||||
// See microsoft/terminal#2066 for more info.
|
||||
static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */)
|
||||
{
|
||||
return false; // glyph is not wide.
|
||||
}
|
||||
|
||||
static bool _EnsureStaticInitialization()
|
||||
{
|
||||
// use C++11 magic statics to make sure we only do this once.
|
||||
static bool initialized = []() {
|
||||
// *** THIS IS A SINGLETON ***
|
||||
SetGlyphWidthFallback(_IsGlyphWideForceNarrowFallback);
|
||||
|
||||
return true;
|
||||
}();
|
||||
return initialized;
|
||||
}
|
||||
|
||||
ControlCore::ControlCore(IControlSettings settings,
|
||||
TerminalConnection::ITerminalConnection connection) :
|
||||
_connection{ connection },
|
||||
|
@ -61,8 +42,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
_desiredFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8 },
|
||||
_actualFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false }
|
||||
{
|
||||
_EnsureStaticInitialization();
|
||||
|
||||
_terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>();
|
||||
|
||||
// Subscribe to the connection's disconnected event and call our connection closed handlers.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "ControlCore.g.h"
|
||||
#include "../../renderer/base/Renderer.hpp"
|
||||
#include "../../renderer/dx/DxRenderer.hpp"
|
||||
#include "../../renderer/atlas/AtlasEngine.h"
|
||||
#include "../../renderer/uia/UiaRenderer.hpp"
|
||||
#include "../../cascadia/TerminalCore/Terminal.hpp"
|
||||
#include "../buffer/out/search.h"
|
||||
|
|
|
@ -147,6 +147,7 @@
|
|||
<ProjectReference Include="..\..\types\lib\types.vcxproj" />
|
||||
<ProjectReference Include="..\..\buffer\out\lib\bufferout.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\renderer\base\lib\base.vcxproj" />
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\renderer\atlas\atlas.vcxproj" />
|
||||
<ProjectReference Include="..\..\renderer\dx\lib\dx.vcxproj" />
|
||||
<ProjectReference Include="..\..\renderer\uia\lib\uia.vcxproj" />
|
||||
<ProjectReference Include="..\..\terminal\parser\lib\parser.vcxproj" />
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
|
||||
#include <winrt/Microsoft.Terminal.Core.h>
|
||||
|
||||
#include <d3d11_1.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <dcomp.h>
|
||||
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
#include <TraceLoggingProvider.h>
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
<ProjectReference Include="$(OpenConsoleDir)src\terminal\parser\lib\parser.vcxproj">
|
||||
<Project>{3ae13314-1939-4dfa-9c14-38ca0834050c}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\renderer\atlas\atlas.vcxproj">
|
||||
<Project>{21d07cec-24b8-458f-bc34-0866833c60b6}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\renderer\dx\lib\dx.vcxproj">
|
||||
<Project>{48d21369-3d7b-4431-9967-24e81292cf62}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\src\inc;$(SolutionDir)\dep;$(SolutionDir)\dep\Console;$(SolutionDir)\dep\gsl\include;$(SolutionDir)\dep\wil\include;$(SolutionDir)\dep\Win32K;$(SolutionDir)\oss\boost\boost_1_73_0;$(SolutionDir)\oss\chromium;$(SolutionDir)\oss\dynamic_bitset;$(SolutionDir)\oss\fmt\include;$(SolutionDir)\oss\interval_tree;$(SolutionDir)\oss\libpopcnt;$(SolutionDir)\oss\pcg\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\src\inc;$(SolutionDir)\dep;$(SolutionDir)\dep\Console;$(SolutionDir)\dep\gsl\include;$(SolutionDir)\dep\wil\include;$(SolutionDir)\dep\Win32K;$(SolutionDir)\oss\boost\boost_1_73_0;$(SolutionDir)\oss\chromium;$(SolutionDir)\oss\dynamic_bitset;$(SolutionDir)\oss\fmt\include;$(SolutionDir)\oss\interval_tree;$(SolutionDir)\oss\libpopcnt;$(SolutionDir)\oss\pcg\include;$(SolutionDir)\oss\robin-hood-hashing;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
|
@ -174,6 +174,11 @@
|
|||
<!-- For Win32 (x86) ONLY ... we use all defaults for AMD64. No def for those. -->
|
||||
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
|
||||
<ClCompile>
|
||||
<!--
|
||||
KB4103718 dropped support for x86 CPUs without SSE2 on Windows 7 in 2018.
|
||||
But this only affects Pentium III and older, which I'm sure can't even run VS 2019.
|
||||
-->
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
|
115
src/host/HostPackage/HostPackage.wapproj
Normal file
115
src/host/HostPackage/HostPackage.wapproj
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0'">
|
||||
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x86">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|AnyCPU">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|AnyCPU">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>44d35904-4dc6-4eec-86f2-6e3e341c95be</ProjectGuid>
|
||||
<TargetPlatformVersion>10.0.20348.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.20348.0</TargetPlatformMinVersion>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||
<EntryPointProjectUniqueName>..\exe\Host.EXE.vcxproj</EntryPointProjectUniqueName>
|
||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled>
|
||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundlePlatforms>x64</AppxBundlePlatforms>
|
||||
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
||||
<PackageCertificateKeyFile>HostPackage_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Images\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22414.2000-preview.rs-prerelease" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\exe\Host.EXE.vcxproj" />
|
||||
<ProjectReference Include="..\ShellExtension\OpenConsoleShellExt.vcxproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
BIN
src/host/HostPackage/Images/Square150x150Logo.scale-200.png
Normal file
BIN
src/host/HostPackage/Images/Square150x150Logo.scale-200.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
BIN
src/host/HostPackage/Images/Square44x44Logo.scale-200.png
Normal file
BIN
src/host/HostPackage/Images/Square44x44Logo.scale-200.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
68
src/host/HostPackage/Package.appxmanifest
Normal file
68
src/host/HostPackage/Package.appxmanifest
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
|
||||
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
|
||||
IgnorableNamespaces="uap rescap uap3">
|
||||
|
||||
<Identity
|
||||
Name="OpenConsole"
|
||||
Publisher="CN=lhecker"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>OpenConsole</DisplayName>
|
||||
<PublisherDisplayName>lhecker</PublisherDisplayName>
|
||||
<Logo></Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="OpenConsole"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="Images\Square150x150Logo.png"
|
||||
Square44x44Logo="Images\Square44x44Logo.png" Description="OpenConsole">
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="OpenConsoleShellExt">
|
||||
<com:Class Id="74cd627e-aad1-4ee4-9427-7c4db186ee59" Path="OpenConsoleShellExt\OpenConsoleShellExt.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
<desktop4:Extension Category="windows.fileExplorerContextMenus">
|
||||
<desktop4:FileExplorerContextMenus>
|
||||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="OpenTerminalHere" Clsid="74cd627e-aad1-4ee4-9427-7c4db186ee59" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="OpenTerminalHere" Clsid="74cd627e-aad1-4ee4-9427-7c4db186ee59" />
|
||||
</desktop5:ItemType>
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
</Capabilities>
|
||||
</Package>
|
4
src/host/ShellExtension/OpenConsoleShellExt.def
Normal file
4
src/host/ShellExtension/OpenConsoleShellExt.def
Normal file
|
@ -0,0 +1,4 @@
|
|||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetActivationFactory PRIVATE
|
||||
DllGetClassObject PRIVATE
|
69
src/host/ShellExtension/OpenConsoleShellExt.vcxproj
Normal file
69
src/host/ShellExtension/OpenConsoleShellExt.vcxproj
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B321ECD6-18E2-4F07-BFB0-B63750CE0CBD}</ProjectGuid>
|
||||
<ProjectName>OpenConsoleShellExt</ProjectName>
|
||||
<RootNamespace>OpenConsole.ShellExtension</RootNamespace>
|
||||
<!-- cppwinrt.build.pre.props depends on these settings: -->
|
||||
<!-- build a dll, not exe (Application) -->
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<!-- suppress a bunch of Windows Universal properties from cppwinrt.props -->
|
||||
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)src\cppwinrt.build.pre.props" />
|
||||
<ItemGroup>
|
||||
<ClInclude Include="OpenTerminalHere.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="OpenTerminalHere.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="$(ProjectName).def" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Project References ======================== -->
|
||||
<Import Project="$(SolutionDir)src\cppwinrt.build.post.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<!-- Override GetPackagingOutputs to roll up our DLL.
|
||||
This is a heavily stripped version of the one in Microsoft.*.AppxPackage.targets.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<_ContinueOnError Condition="'$(BuildingProject)' == 'true'">true</_ContinueOnError>
|
||||
<_ContinueOnError Condition="'$(BuildingProject)' != 'true'">false</_ContinueOnError>
|
||||
</PropertyGroup>
|
||||
<Target Name="GetPackagingOutputs" Returns="@(PackagingOutputs)">
|
||||
<CallTarget Targets="BuiltProjectOutputGroup">
|
||||
<Output TaskParameter="TargetOutputs" ItemName="_BuiltProjectOutputGroupOutput" />
|
||||
</CallTarget>
|
||||
<ItemGroup>
|
||||
<_PackagingOutputsUnexpanded Include="%(_BuiltProjectOutputGroupOutput.FinalOutputPath)">
|
||||
<TargetPath>%(_BuiltProjectOutputGroupOutput.TargetPath)</TargetPath>
|
||||
<OutputGroup>BuiltProjectOutputGroup</OutputGroup>
|
||||
<ProjectName>$(ProjectName)</ProjectName>
|
||||
</_PackagingOutputsUnexpanded>
|
||||
</ItemGroup>
|
||||
<CallTarget Targets="DebugSymbolsProjectOutputGroup">
|
||||
<Output TaskParameter="TargetOutputs" ItemName="_DebugSymbolsProjectOutputGroupOutput" />
|
||||
</CallTarget>
|
||||
<ItemGroup>
|
||||
<_PackagingOutputsUnexpanded Include="%(_DebugSymbolsProjectOutputGroupOutput.FinalOutputPath)">
|
||||
<OutputGroup>DebugSymbolsProjectOutputGroup</OutputGroup>
|
||||
<ProjectName>$(ProjectName)</ProjectName>
|
||||
</_PackagingOutputsUnexpanded>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackagingOutputs Include="@(_PackagingOutputsUnexpanded)">
|
||||
<TargetPath>%(Filename)%(Extension)</TargetPath>
|
||||
</PackagingOutputs>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
217
src/host/ShellExtension/OpenTerminalHere.cpp
Normal file
217
src/host/ShellExtension/OpenTerminalHere.cpp
Normal file
|
@ -0,0 +1,217 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "OpenTerminalHere.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <wil/common.h>
|
||||
#include <wil/stl.h>
|
||||
#include <wil/win32_helpers.h>
|
||||
|
||||
#include <ShlObj_core.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
|
||||
|
||||
HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray, IBindCtx* /*pBindContext*/)
|
||||
try
|
||||
{
|
||||
std::wstring path;
|
||||
|
||||
if (psiItemArray == nullptr)
|
||||
{
|
||||
path = _GetPathFromExplorer();
|
||||
if (path.empty())
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD count;
|
||||
psiItemArray->GetCount(&count);
|
||||
|
||||
winrt::com_ptr<IShellItem> psi;
|
||||
wil::unique_cotaskmem_string pszName;
|
||||
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
|
||||
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
|
||||
|
||||
path = std::wstring{ pszName.get() };
|
||||
}
|
||||
|
||||
// Append a "\." to the given path, so that this will work in "C:\"
|
||||
path.append(L"\\.");
|
||||
|
||||
std::filesystem::path applicationName{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
|
||||
applicationName.replace_filename(L"..\\Host.EXE\\OpenConsole.exe");
|
||||
|
||||
std::wstring commandLine;
|
||||
commandLine.push_back(L'"');
|
||||
commandLine.append(applicationName);
|
||||
commandLine.append(L"\" pwsh.exe");
|
||||
|
||||
wil::unique_process_information _piClient;
|
||||
STARTUPINFOEX siEx{ 0 };
|
||||
siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
|
||||
|
||||
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(
|
||||
applicationName.c_str(), // lpApplicationName
|
||||
commandLine.data(),
|
||||
nullptr, // lpProcessAttributes
|
||||
nullptr, // lpThreadAttributes
|
||||
false, // bInheritHandles
|
||||
EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, // dwCreationFlags
|
||||
nullptr, // lpEnvironment
|
||||
path.data(),
|
||||
&siEx.StartupInfo, // lpStartupInfo
|
||||
&_piClient // lpProcessInformation
|
||||
));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
HRESULT OpenTerminalHere::GetToolTip(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszInfoTip)
|
||||
{
|
||||
*ppszInfoTip = nullptr;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT OpenTerminalHere::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
|
||||
{
|
||||
return SHStrDupW(L"Open in OpenConsole", ppszName);
|
||||
}
|
||||
|
||||
HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/, BOOL /*fOkToBeSlow*/, EXPCMDSTATE* pCmdState)
|
||||
{
|
||||
*pCmdState = ECS_ENABLED;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OpenTerminalHere::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)
|
||||
try
|
||||
{
|
||||
std::filesystem::path path{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
|
||||
path.replace_filename(L"..\\Host.EXE\\OpenConsole.exe,0");
|
||||
return SHStrDupW(path.c_str(), ppszIcon);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
HRESULT OpenTerminalHere::GetFlags(EXPCMDFLAGS* pFlags)
|
||||
{
|
||||
*pFlags = ECF_DEFAULT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OpenTerminalHere::GetCanonicalName(GUID* pguidCommandName)
|
||||
{
|
||||
*pguidCommandName = __uuidof(this);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OpenTerminalHere::EnumSubCommands(IEnumExplorerCommand** ppEnum)
|
||||
{
|
||||
*ppEnum = nullptr;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
std::wstring OpenTerminalHere::_GetPathFromExplorer() const
|
||||
{
|
||||
using namespace std;
|
||||
using namespace winrt;
|
||||
|
||||
wstring path;
|
||||
HRESULT hr = NOERROR;
|
||||
|
||||
auto hwnd = ::GetForegroundWindow();
|
||||
if (hwnd == nullptr)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
TCHAR szName[MAX_PATH] = { 0 };
|
||||
::GetClassName(hwnd, szName, MAX_PATH);
|
||||
if (0 == StrCmp(szName, L"WorkerW") ||
|
||||
0 == StrCmp(szName, L"Progman"))
|
||||
{
|
||||
//special folder: desktop
|
||||
hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
path = szName;
|
||||
return path;
|
||||
}
|
||||
|
||||
if (0 != StrCmp(szName, L"CabinetWClass"))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
com_ptr<IShellWindows> shell;
|
||||
try
|
||||
{
|
||||
shell = create_instance<IShellWindows>(CLSID_ShellWindows, CLSCTX_ALL);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
//look like try_create_instance is not available no more
|
||||
}
|
||||
|
||||
if (shell == nullptr)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
com_ptr<IDispatch> disp;
|
||||
wil::unique_variant variant;
|
||||
variant.vt = VT_I4;
|
||||
|
||||
com_ptr<IWebBrowserApp> browser;
|
||||
// look for correct explorer window
|
||||
for (variant.intVal = 0;
|
||||
shell->Item(variant, disp.put()) == S_OK;
|
||||
variant.intVal++)
|
||||
{
|
||||
com_ptr<IWebBrowserApp> tmp;
|
||||
if (FAILED(disp->QueryInterface(tmp.put())))
|
||||
{
|
||||
disp = nullptr; // get rid of DEBUG non-nullptr warning
|
||||
continue;
|
||||
}
|
||||
|
||||
HWND tmpHWND = NULL;
|
||||
hr = tmp->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&tmpHWND));
|
||||
if (hwnd == tmpHWND)
|
||||
{
|
||||
browser = tmp;
|
||||
disp = nullptr; // get rid of DEBUG non-nullptr warning
|
||||
break; //found
|
||||
}
|
||||
|
||||
disp = nullptr; // get rid of DEBUG non-nullptr warning
|
||||
}
|
||||
|
||||
if (browser)
|
||||
{
|
||||
wil::unique_bstr url;
|
||||
hr = browser->get_LocationURL(&url);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
wstring sUrl(url.get(), SysStringLen(url.get()));
|
||||
DWORD size = MAX_PATH;
|
||||
hr = ::PathCreateFromUrl(sUrl.c_str(), szName, &size, NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
path = szName;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
28
src/host/ShellExtension/OpenTerminalHere.h
Normal file
28
src/host/ShellExtension/OpenTerminalHere.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <wrl.h>
|
||||
#include <ShlObj.h>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
struct __declspec(uuid("74cd627e-aad1-4ee4-9427-7c4db186ee59")) OpenTerminalHere : public RuntimeClass<RuntimeClassFlags<ClassicCom | InhibitFtmBase>, IExplorerCommand>
|
||||
{
|
||||
#pragma region IExplorerCommand
|
||||
STDMETHODIMP Invoke(IShellItemArray* psiItemArray, IBindCtx* pBindContext);
|
||||
STDMETHODIMP GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfoTip);
|
||||
STDMETHODIMP GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName);
|
||||
STDMETHODIMP GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState);
|
||||
STDMETHODIMP GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon);
|
||||
STDMETHODIMP GetFlags(EXPCMDFLAGS* pFlags);
|
||||
STDMETHODIMP GetCanonicalName(GUID* pguidCommandName);
|
||||
STDMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum);
|
||||
#pragma endregion
|
||||
|
||||
private:
|
||||
std::wstring _GetPathFromExplorer() const;
|
||||
};
|
||||
|
||||
CoCreatableClass(OpenTerminalHere);
|
31
src/host/ShellExtension/dllmain.cpp
Normal file
31
src/host/ShellExtension/dllmain.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include <wrl/module.h>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
__control_entrypoint(DllExport) STDAPI DllCanUnloadNow()
|
||||
{
|
||||
return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory)
|
||||
{
|
||||
return Module<InProc>::GetModule().GetActivationFactory(activatableClassId, factory);
|
||||
}
|
||||
|
||||
_Check_return_ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv)
|
||||
{
|
||||
return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
STDAPI_(BOOL)
|
||||
DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
DisableThreadLibraryCalls(hinst);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
4
src/host/ShellExtension/packages.config
Normal file
4
src/host/ShellExtension/packages.config
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210309.3" targetFramework="native" />
|
||||
</packages>
|
|
@ -46,6 +46,9 @@
|
|||
<ProjectReference Include="..\..\renderer\dx\lib\dx.vcxproj">
|
||||
<Project>{48d21369-3d7b-4431-9967-24e81292cf62}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\renderer\atlas\atlas.vcxproj">
|
||||
<Project>{8222900C-8B6C-452A-91AC-BE95DB04B95F}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\renderer\gdi\lib\gdi.vcxproj">
|
||||
<Project>{1c959542-bac2-4e55-9a6d-13251914cbb9}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -274,8 +274,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||
const FontInfo& fontInfo = activeScreenInfo.GetCurrentFont();
|
||||
consoleFontInfoEx.FontFamily = fontInfo.GetFamily();
|
||||
consoleFontInfoEx.FontWeight = fontInfo.GetWeight();
|
||||
|
||||
RETURN_IF_FAILED(fontInfo.FillLegacyNameBuffer(gsl::make_span(consoleFontInfoEx.FaceName)));
|
||||
fontInfo.FillLegacyNameBuffer(consoleFontInfoEx.FaceName);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,7 @@ Revision History:
|
|||
#include "ConsoleArguments.hpp"
|
||||
#include "ApiRoutines.h"
|
||||
|
||||
#include "../renderer/inc/IRenderData.hpp"
|
||||
#include "../renderer/inc/IRenderEngine.hpp"
|
||||
#include "../renderer/inc/IRenderer.hpp"
|
||||
#include "../renderer/inc/IFontDefaultList.hpp"
|
||||
#include "../renderer/base/Renderer.hpp"
|
||||
|
||||
#include "../server/DeviceComm.h"
|
||||
#include "../server/ConDrvDeviceComm.h"
|
||||
|
@ -62,7 +59,7 @@ public:
|
|||
|
||||
std::vector<wchar_t> WordDelimiters;
|
||||
|
||||
Microsoft::Console::Render::IRenderer* pRender;
|
||||
Microsoft::Console::Render::Renderer* pRender;
|
||||
|
||||
Microsoft::Console::Render::IFontDefaultList* pFontDefaultList;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ Settings::Settings() :
|
|||
_fInterceptCopyPaste(0),
|
||||
_DefaultForeground(INVALID_COLOR),
|
||||
_DefaultBackground(INVALID_COLOR),
|
||||
_fUseDx(false),
|
||||
_fUseDx(0),
|
||||
_fCopyColor(false)
|
||||
{
|
||||
_dwScreenBufferSize.X = 80;
|
||||
|
@ -816,7 +816,7 @@ void Settings::SetTerminalScrolling(const bool terminalScrollingEnabled) noexcep
|
|||
// - This is based on user preference and velocity hold back state.
|
||||
// Return Value:
|
||||
// - True means use DirectX renderer. False means use GDI renderer.
|
||||
bool Settings::GetUseDx() const noexcept
|
||||
DWORD Settings::GetUseDx() const noexcept
|
||||
{
|
||||
return _fUseDx;
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
bool IsTerminalScrolling() const noexcept;
|
||||
void SetTerminalScrolling(const bool terminalScrollingEnabled) noexcept;
|
||||
|
||||
bool GetUseDx() const noexcept;
|
||||
DWORD GetUseDx() const noexcept;
|
||||
bool GetCopyColor() const noexcept;
|
||||
|
||||
private:
|
||||
|
@ -230,7 +230,7 @@ private:
|
|||
bool _fAutoReturnOnNewline;
|
||||
bool _fRenderGridWorldwide;
|
||||
bool _fScreenReversed;
|
||||
bool _fUseDx;
|
||||
DWORD _fUseDx;
|
||||
bool _fCopyColor;
|
||||
|
||||
std::array<COLORREF, XTERM_COLOR_TABLE_SIZE> _colorTable;
|
||||
|
|
|
@ -771,8 +771,9 @@ PWSTR TranslateConsoleTitle(_In_ PCWSTR pwszConsoleTitle, const BOOL fUnexpand,
|
|||
|
||||
// Set up the renderer to be used to calculate the width of a glyph,
|
||||
// should we be unable to figure out its width another way.
|
||||
auto pfn = std::bind(&Renderer::IsGlyphWideByFont, static_cast<Renderer*>(g.pRender), std::placeholders::_1);
|
||||
SetGlyphWidthFallback(pfn);
|
||||
SetGlyphWidthFallback([renderer = g.pRender](const std::wstring_view& glyph) -> bool {
|
||||
return renderer->IsGlyphWideByFont(glyph);
|
||||
});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ class CodepointWidthDetectorTests
|
|||
}
|
||||
}
|
||||
|
||||
static bool FallbackMethod(const std::wstring_view glyph)
|
||||
static bool FallbackMethod(const std::wstring_view& glyph)
|
||||
{
|
||||
if (glyph.size() < 1)
|
||||
{
|
||||
|
|
|
@ -73,7 +73,8 @@
|
|||
|
||||
// Chromium Numerics (safe math)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100) // unreferenced parameter
|
||||
#pragma warning(disable : 4100) // '...': unreferenced formal parameter
|
||||
#pragma warning(disable : 26812) // The enum type '...' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
|
||||
#include <base/numerics/safe_math.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
|
@ -84,16 +85,15 @@
|
|||
#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
|
||||
#include <intsafe.h>
|
||||
|
||||
// LibPopCnt - Fast C/C++ bit population count library (on bits in an array)
|
||||
#include <libpopcnt.h>
|
||||
|
||||
// Dynamic Bitset (optional dependency on LibPopCnt for perf at bit counting)
|
||||
// Variable-size compressed-storage header-only bit flag storage library.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4702) // unreachable code
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
#include <dynamic_bitset.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <robin_hood.h>
|
||||
|
||||
// {fmt}, a C++20-compatible formatting library
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/compile.h>
|
||||
|
|
|
@ -15,11 +15,11 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
|||
class _bitmap_const_iterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = typename std::input_iterator_tag;
|
||||
using value_type = typename const til::rectangle;
|
||||
using difference_type = typename ptrdiff_t;
|
||||
using pointer = typename const til::rectangle*;
|
||||
using reference = typename const til::rectangle&;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = const til::rectangle;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = const til::rectangle*;
|
||||
using reference = const til::rectangle&;
|
||||
|
||||
_bitmap_const_iterator(const dynamic_bitset<unsigned long long, Allocator>& values, til::rectangle rc, ptrdiff_t pos) :
|
||||
_values(values),
|
||||
|
|
60
src/inc/til/pair.h
Normal file
60
src/inc/til/pair.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
{
|
||||
// pair is a simple clone of std::pair, with one difference:
|
||||
// copy and move constructors and operators are explicitly defaulted.
|
||||
// This allows pair to be std::is_trivially_copyable, if both T and S are.
|
||||
// --> pair can be used with memcpy(), unlike std::pair.
|
||||
template<typename T, typename S>
|
||||
struct pair
|
||||
{
|
||||
using first_type = T;
|
||||
using second_type = S;
|
||||
|
||||
pair() = default;
|
||||
|
||||
pair(const pair&) = default;
|
||||
pair& operator=(const pair&) = default;
|
||||
|
||||
pair(pair&&) = default;
|
||||
pair& operator=(pair&&) = default;
|
||||
|
||||
constexpr pair(const T& first, const S& second) noexcept(std::is_nothrow_copy_constructible_v<T>&& std::is_nothrow_copy_constructible_v<S>) :
|
||||
first(first), second(second)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr pair(T&& first, S&& second) noexcept(std::is_nothrow_constructible_v<T>&& std::is_nothrow_constructible_v<S>) :
|
||||
first(std::forward<T>(first)), second(std::forward<S>(second))
|
||||
{
|
||||
}
|
||||
|
||||
constexpr void swap(pair& other) noexcept(std::is_nothrow_swappable_v<T>&& std::is_nothrow_swappable_v<S>)
|
||||
{
|
||||
if (this != std::addressof(other))
|
||||
{
|
||||
std::swap(first, other.first);
|
||||
std::swap(second, other.second);
|
||||
}
|
||||
}
|
||||
|
||||
first_type first{};
|
||||
second_type second{};
|
||||
};
|
||||
|
||||
template<typename T, typename S>
|
||||
[[nodiscard]] constexpr bool operator==(const pair<T, S>& lhs, const pair<T, S>& rhs)
|
||||
{
|
||||
return lhs.first == rhs.first && lhs.second == rhs.second;
|
||||
}
|
||||
|
||||
template<typename T, typename S>
|
||||
[[nodiscard]] constexpr bool operator!=(const pair<T, S>& lhs, const pair<T, S>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
|
@ -253,12 +253,6 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT BgfxEngine::IsGlyphWideByFont(const std::wstring_view /*glyph*/, _Out_ bool* const pResult) noexcept
|
||||
{
|
||||
*pResult = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Updates the window's title string.
|
||||
// Does nothing for BGFX.
|
||||
|
|
|
@ -70,7 +70,6 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../../renderer/gdi/gdirenderer.hpp"
|
||||
|
||||
#if TIL_FEATURE_CONHOSTDXENGINE_ENABLED
|
||||
#include "../../renderer/atlas/AtlasEngine.h"
|
||||
#include "../../renderer/dx/DxRenderer.hpp"
|
||||
#endif
|
||||
|
||||
|
@ -209,16 +210,18 @@ void Window::_UpdateSystemMetrics() const
|
|||
// Ensure we have appropriate system metrics before we start constructing the window.
|
||||
_UpdateSystemMetrics();
|
||||
|
||||
const bool useDx = pSettings->GetUseDx();
|
||||
const auto useDx = pSettings->GetUseDx();
|
||||
GdiEngine* pGdiEngine = nullptr;
|
||||
#if TIL_FEATURE_CONHOSTDXENGINE_ENABLED
|
||||
[[maybe_unused]] DxEngine* pDxEngine = nullptr;
|
||||
DxEngine* pDxEngine = nullptr;
|
||||
AtlasEngine* pAtlasEngine = nullptr;
|
||||
#endif
|
||||
try
|
||||
{
|
||||
#if TIL_FEATURE_CONHOSTDXENGINE_ENABLED
|
||||
if (useDx)
|
||||
switch (useDx)
|
||||
{
|
||||
#if TIL_FEATURE_CONHOSTDXENGINE_ENABLED
|
||||
case 1:
|
||||
pDxEngine = new DxEngine();
|
||||
// TODO: MSFT:21255595 make this less gross
|
||||
// Manually set the Dx Engine to Hwnd mode. When we're trying to
|
||||
|
@ -227,12 +230,16 @@ void Window::_UpdateSystemMetrics() const
|
|||
// math in the hwnd mode, not the Composition mode.
|
||||
THROW_IF_FAILED(pDxEngine->SetHwnd(nullptr));
|
||||
g.pRender->AddRenderEngine(pDxEngine);
|
||||
}
|
||||
else
|
||||
break;
|
||||
case 2:
|
||||
pAtlasEngine = new AtlasEngine();
|
||||
g.pRender->AddRenderEngine(pAtlasEngine);
|
||||
break;
|
||||
#endif
|
||||
{
|
||||
default:
|
||||
pGdiEngine = new GdiEngine();
|
||||
g.pRender->AddRenderEngine(pGdiEngine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
|
@ -242,10 +249,6 @@ void Window::_UpdateSystemMetrics() const
|
|||
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
SCREEN_INFORMATION& siAttached = GetScreenInfo();
|
||||
|
||||
siAttached.RefreshFontWithRenderer();
|
||||
|
||||
// Save reference to settings
|
||||
_pSettings = pSettings;
|
||||
|
||||
|
@ -324,7 +327,7 @@ void Window::_UpdateSystemMetrics() const
|
|||
_hWnd = hWnd;
|
||||
|
||||
#if TIL_FEATURE_CONHOSTDXENGINE_ENABLED
|
||||
if (useDx)
|
||||
if (pDxEngine)
|
||||
{
|
||||
status = NTSTATUS_FROM_WIN32(HRESULT_CODE((pDxEngine->SetHwnd(hWnd))));
|
||||
|
||||
|
@ -333,6 +336,10 @@ void Window::_UpdateSystemMetrics() const
|
|||
status = NTSTATUS_FROM_WIN32(HRESULT_CODE((pDxEngine->Enable())));
|
||||
}
|
||||
}
|
||||
else if (pAtlasEngine)
|
||||
{
|
||||
status = NTSTATUS_FROM_WIN32(HRESULT_CODE((pAtlasEngine->SetHwnd(hWnd))));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
@ -362,6 +369,7 @@ void Window::_UpdateSystemMetrics() const
|
|||
// Post a window size update so that the new console window will size itself correctly once it's up and
|
||||
// running. This works around chicken & egg cases involving window size calculations having to do with font
|
||||
// sizes, DPI, and non-primary monitors (see MSFT #2367234).
|
||||
SCREEN_INFORMATION& siAttached = GetScreenInfo();
|
||||
siAttached.PostUpdateWindowSize();
|
||||
|
||||
// Locate window theming modules and try to set the dark mode.
|
||||
|
|
|
@ -28,6 +28,7 @@ USE_NATIVE_EH = 1
|
|||
# Compiler Settings
|
||||
# -------------------------------------
|
||||
|
||||
MSC_OPTIMIZATION = /O2
|
||||
MSC_WARNING_LEVEL = /W4 /WX
|
||||
USER_C_FLAGS = $(USER_C_FLAGS) /utf-8
|
||||
|
||||
|
@ -43,12 +44,13 @@ INCLUDES= \
|
|||
$(INCLUDES); \
|
||||
$(CONSOLE_SRC_PATH)\inc; \
|
||||
$(CONSOLE_SRC_PATH)\..\..\inc; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\dynamic_bitset; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\libpopcnt; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\boost\boost_1_73_0; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\chromium; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\dynamic_bitset; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\fmt\include; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\interval_tree; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\boost\boost_1_73_0; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\libpopcnt; \
|
||||
$(CONSOLE_SRC_PATH)\..\oss\robin-hood-hashing; \
|
||||
$(MINWIN_INTERNAL_PRIV_SDK_INC_PATH_L); \
|
||||
$(MINWIN_RESTRICTED_PRIV_SDK_INC_PATH_L); \
|
||||
$(MINCORE_INTERNAL_PRIV_SDK_INC_PATH_L); \
|
||||
|
|
|
@ -188,12 +188,13 @@ DWORD GetRegistryValues(
|
|||
|
||||
if (pStateInfo == nullptr)
|
||||
{
|
||||
Status = RegistrySerialization::s_QueryValue(hConsoleKey,
|
||||
CONSOLE_REGISTRY_CURRENTPAGE,
|
||||
sizeof(dwValue),
|
||||
REG_DWORD,
|
||||
(PBYTE)&dwValue,
|
||||
nullptr);
|
||||
Status = RegistrySerialization::s_QueryValue(
|
||||
hConsoleKey,
|
||||
CONSOLE_REGISTRY_CURRENTPAGE,
|
||||
sizeof(dwValue),
|
||||
REG_DWORD,
|
||||
(PBYTE)&dwValue,
|
||||
nullptr);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
dwRet = dwValue;
|
||||
|
@ -211,9 +212,10 @@ DWORD GetRegistryValues(
|
|||
}
|
||||
else
|
||||
{
|
||||
Status = RegistrySerialization::s_OpenKey(hConsoleKey,
|
||||
pStateInfo->OriginalTitle,
|
||||
&hTitleKey);
|
||||
Status = RegistrySerialization::s_OpenKey(
|
||||
hConsoleKey,
|
||||
pStateInfo->OriginalTitle,
|
||||
&hTitleKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RegCloseKey(hConsoleKey);
|
||||
|
@ -701,11 +703,12 @@ VOID SetRegistryValues(
|
|||
//
|
||||
// Save the current page.
|
||||
//
|
||||
LOG_IF_FAILED(RegistrySerialization::s_SetValue(hConsoleKey,
|
||||
CONSOLE_REGISTRY_CURRENTPAGE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwPage,
|
||||
sizeof(dwPage)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_SetValue(
|
||||
hConsoleKey,
|
||||
CONSOLE_REGISTRY_CURRENTPAGE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwPage,
|
||||
sizeof(dwPage)));
|
||||
|
||||
//
|
||||
// Open the console title subkey unless we're changing the defaults.
|
||||
|
@ -716,9 +719,10 @@ VOID SetRegistryValues(
|
|||
}
|
||||
else
|
||||
{
|
||||
Status = RegistrySerialization::s_CreateKey(hConsoleKey,
|
||||
pStateInfo->OriginalTitle,
|
||||
&hTitleKey);
|
||||
Status = RegistrySerialization::s_CreateKey(
|
||||
hConsoleKey,
|
||||
pStateInfo->OriginalTitle,
|
||||
&hTitleKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RegCloseKey(hConsoleKey);
|
||||
|
@ -732,30 +736,33 @@ VOID SetRegistryValues(
|
|||
//
|
||||
|
||||
dwValue = pStateInfo->ScreenAttributes;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FILLATTR,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FILLATTR,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->PopupAttributes;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_POPUPATTR,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_POPUPATTR,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
dwValue = pStateInfo->ColorTable[i];
|
||||
if (SUCCEEDED(StringCchPrintf(awchBuffer, ARRAYSIZE(awchBuffer), CONSOLE_REGISTRY_COLORTABLE, i)))
|
||||
{
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
awchBuffer,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
awchBuffer,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -764,30 +771,33 @@ VOID SetRegistryValues(
|
|||
//
|
||||
|
||||
dwValue = pStateInfo->InsertMode;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_INSERTMODE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_INSERTMODE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->QuickEdit;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_QUICKEDIT,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_QUICKEDIT,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
FAIL_FAST_IF(!(OEMCP != 0));
|
||||
if (g_fEastAsianSystem)
|
||||
{
|
||||
dwValue = (DWORD)pStateInfo->CodePage;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CODEPAGE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CODEPAGE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -796,12 +806,13 @@ VOID SetRegistryValues(
|
|||
|
||||
dwValue = MAKELONG(pStateInfo->ScreenBufferSize.X,
|
||||
pStateInfo->ScreenBufferSize.Y);
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_BUFFERSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_BUFFERSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
//
|
||||
// Save window size
|
||||
|
@ -809,12 +820,13 @@ VOID SetRegistryValues(
|
|||
|
||||
dwValue = MAKELONG(pStateInfo->WindowSize.X,
|
||||
pStateInfo->WindowSize.Y);
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_WINDOWSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_WINDOWSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
//
|
||||
// Save window position
|
||||
|
@ -822,18 +834,19 @@ VOID SetRegistryValues(
|
|||
|
||||
if (pStateInfo->AutoPosition)
|
||||
{
|
||||
LOG_IF_FAILED(RegistrySerialization::s_DeleteValue(hTitleKey, CONSOLE_REGISTRY_WINDOWPOS));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_DeleteValue(hTitleKey, CONSOLE_REGISTRY_WINDOWPOS));
|
||||
}
|
||||
else
|
||||
{
|
||||
dwValue = MAKELONG(pStateInfo->WindowPosX,
|
||||
pStateInfo->WindowPosY);
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_WINDOWPOS,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_WINDOWPOS,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -842,107 +855,120 @@ VOID SetRegistryValues(
|
|||
|
||||
dwValue = MAKELONG(pStateInfo->FontSize.X,
|
||||
pStateInfo->FontSize.Y);
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FONTSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FONTSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->FontFamily;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FONTFAMILY,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FONTFAMILY,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->FontWeight;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FONTWEIGHT,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FACENAME,
|
||||
REG_SZ,
|
||||
(BYTE*)(pStateInfo->FaceName),
|
||||
(DWORD)(wcslen(pStateInfo->FaceName) + 1) * sizeof(TCHAR)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FONTWEIGHT,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FACENAME,
|
||||
REG_SZ,
|
||||
(BYTE*)(pStateInfo->FaceName),
|
||||
(DWORD)(wcslen(pStateInfo->FaceName) + 1) * sizeof(TCHAR)));
|
||||
|
||||
//
|
||||
// Save cursor size
|
||||
//
|
||||
|
||||
dwValue = pStateInfo->CursorSize;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CURSORSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CURSORSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
//
|
||||
// Save history buffer size and number
|
||||
//
|
||||
|
||||
dwValue = pStateInfo->HistoryBufferSize;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_HISTORYSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_HISTORYSIZE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->NumberOfHistoryBuffers;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_HISTORYBUFS,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_HISTORYBUFS,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->HistoryNoDup;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_HISTORYNODUP,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_HISTORYNODUP,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
// Save per-title V2 console state
|
||||
dwValue = pStateInfo->fWrapText;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_LINEWRAP,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_LINEWRAP,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->fFilterOnPaste;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FILTERONPASTE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_FILTERONPASTE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->fCtrlKeyShortcutsDisabled;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CTRLKEYSHORTCUTS_DISABLED,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CTRLKEYSHORTCUTS_DISABLED,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->fLineSelection;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_LINESELECTION,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_LINESELECTION,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->bWindowTransparency;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_WINDOWALPHA,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_WINDOWALPHA,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
SetGlobalRegistryValues();
|
||||
|
||||
|
@ -954,50 +980,56 @@ VOID SetRegistryValues(
|
|||
{
|
||||
// Save cursor type and color
|
||||
dwValue = pStateInfo->CursorType;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CURSORTYPE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CURSORTYPE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
dwValue = pStateInfo->CursorColor;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CURSORCOLOR,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_CURSORCOLOR,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
dwValue = pStateInfo->InterceptCopyPaste;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_INTERCEPTCOPYPASTE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_INTERCEPTCOPYPASTE,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
|
||||
dwValue = pStateInfo->TerminalScrolling;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_TERMINALSCROLLING,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_TERMINALSCROLLING,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->DefaultForeground;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_DEFAULTFOREGROUND,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_DEFAULTFOREGROUND,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
dwValue = pStateInfo->DefaultBackground;
|
||||
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_DEFAULTBACKGROUND,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
LOG_IF_NTSTATUS_FAILED(RegistrySerialization::s_UpdateValue(
|
||||
hConsoleKey,
|
||||
hTitleKey,
|
||||
CONSOLE_REGISTRY_DEFAULTBACKGROUND,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwValue,
|
||||
sizeof(dwValue)));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -63,7 +63,7 @@ const RegistrySerialization::_RegPropertyMap RegistrySerialization::s_PropertyMa
|
|||
{ _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTFOREGROUND, SET_FIELD_AND_SIZE(_DefaultForeground) },
|
||||
{ _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTBACKGROUND, SET_FIELD_AND_SIZE(_DefaultBackground) },
|
||||
{ _RegPropertyType::Boolean, CONSOLE_REGISTRY_TERMINALSCROLLING, SET_FIELD_AND_SIZE(_TerminalScrolling) },
|
||||
{ _RegPropertyType::Boolean, CONSOLE_REGISTRY_USEDX, SET_FIELD_AND_SIZE(_fUseDx) },
|
||||
{ _RegPropertyType::Dword, CONSOLE_REGISTRY_USEDX, SET_FIELD_AND_SIZE(_fUseDx) },
|
||||
{ _RegPropertyType::Boolean, CONSOLE_REGISTRY_COPYCOLOR, SET_FIELD_AND_SIZE(_fCopyColor) }
|
||||
|
||||
};
|
||||
|
@ -251,7 +251,8 @@ NTSTATUS RegistrySerialization::s_OpenKey(_In_opt_ HKEY const hKey, _In_ PCWSTR
|
|||
[[nodiscard]]
|
||||
NTSTATUS RegistrySerialization::s_DeleteValue(const HKEY hKey, _In_ PCWSTR const pwszValueName)
|
||||
{
|
||||
return NTSTATUS_FROM_WIN32(RegDeleteKeyValueW(hKey, nullptr, pwszValueName));
|
||||
const auto result = RegDeleteKeyValueW(hKey, nullptr, pwszValueName);
|
||||
return result == ERROR_FILE_NOT_FOUND ? S_OK : NTSTATUS_FROM_WIN32(result);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
1128
src/renderer/atlas/AtlasEngine.cpp
Normal file
1128
src/renderer/atlas/AtlasEngine.cpp
Normal file
File diff suppressed because it is too large
Load diff
344
src/renderer/atlas/AtlasEngine.h
Normal file
344
src/renderer/atlas/AtlasEngine.h
Normal file
|
@ -0,0 +1,344 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d2d1.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <dwrite.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
#include <robin_hood.h>
|
||||
#include <til/pair.h>
|
||||
|
||||
#include "../../renderer/inc/IRenderEngine.hpp"
|
||||
|
||||
namespace Microsoft::Console::Render
|
||||
{
|
||||
class AtlasEngine final : public IRenderEngine
|
||||
{
|
||||
public:
|
||||
explicit AtlasEngine();
|
||||
|
||||
AtlasEngine(const AtlasEngine&) = delete;
|
||||
AtlasEngine& operator=(const AtlasEngine&) = delete;
|
||||
|
||||
// IRenderEngine
|
||||
[[nodiscard]] HRESULT StartPaint() noexcept override;
|
||||
[[nodiscard]] HRESULT EndPaint() noexcept override;
|
||||
[[nodiscard]] bool RequiresContinuousRedraw() noexcept override;
|
||||
void WaitUntilCanRender() noexcept override;
|
||||
[[nodiscard]] HRESULT Present() noexcept override;
|
||||
[[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override;
|
||||
[[nodiscard]] HRESULT ScrollFrame() noexcept override;
|
||||
[[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateSystem(const RECT* const prcDirtyClient) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateAll() noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateCircling(_Out_ bool* const pForcePaint) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateTitle() noexcept override;
|
||||
[[nodiscard]] HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept override;
|
||||
[[nodiscard]] HRESULT ResetLineTransform() noexcept override;
|
||||
[[nodiscard]] HRESULT PrepareLineTransform(const LineRendition lineRendition, const size_t targetRow, const size_t viewportLeft) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintBackground() noexcept override;
|
||||
[[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> const clusters, const COORD coord, const bool fTrimLeft, const bool lineWrapped) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintBufferGridLines(const GridLines lines, const COLORREF color, const size_t cchLine, const COORD coordTarget) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null<IRenderData*> pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const SIZE cellSize, const size_t centeringHint) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override;
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, const int iDpi) noexcept override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
// Just for compatibility with DxEngine, but can be removed at some point.
|
||||
HRESULT Enable()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// DxRenderer - getter
|
||||
[[nodiscard]] bool GetRetroTerminalEffect() const noexcept;
|
||||
[[nodiscard]] float GetScaling() const noexcept;
|
||||
[[nodiscard]] HANDLE GetSwapChainHandle();
|
||||
[[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInCharacters(const ::Microsoft::Console::Types::Viewport& viewInPixels) const noexcept;
|
||||
[[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInPixels(const ::Microsoft::Console::Types::Viewport& viewInCharacters) const noexcept;
|
||||
// DxRenderer - setter
|
||||
void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept;
|
||||
void SetCallback(std::function<void()> pfn);
|
||||
void SetDefaultTextBackgroundOpacity(const float opacity) noexcept;
|
||||
void SetForceFullRepaintRendering(bool enable) noexcept;
|
||||
[[nodiscard]] HRESULT SetHwnd(const HWND hwnd) noexcept;
|
||||
void SetPixelShaderPath(std::wstring_view value) noexcept;
|
||||
void SetRetroTerminalEffect(bool enable) noexcept;
|
||||
void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept;
|
||||
void SetSoftwareRendering(bool enable) noexcept;
|
||||
void SetWarningCallback(std::function<void(const HRESULT)> pfn);
|
||||
[[nodiscard]] HRESULT SetWindowSize(const SIZE pixels) noexcept;
|
||||
void ToggleShaderEffects();
|
||||
[[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo, const std::unordered_map<std::wstring_view, uint32_t>& features, const std::unordered_map<std::wstring_view, float>& axes) noexcept;
|
||||
void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept;
|
||||
|
||||
// Some helper classes for the implementation.
|
||||
// public because I don't want to sprinkle the code with friends.
|
||||
public:
|
||||
template<typename T>
|
||||
struct aligned_buffer
|
||||
{
|
||||
constexpr aligned_buffer() noexcept = default;
|
||||
|
||||
explicit aligned_buffer(size_t size, size_t alignment) :
|
||||
_data{ THROW_IF_NULL_ALLOC(static_cast<T*>(_aligned_malloc(size * sizeof(T), alignment))) },
|
||||
_size{ size }
|
||||
{
|
||||
}
|
||||
|
||||
~aligned_buffer()
|
||||
{
|
||||
_aligned_free(_data);
|
||||
}
|
||||
|
||||
aligned_buffer(aligned_buffer&& other) noexcept :
|
||||
_data{ std::exchange(other._data, nullptr) },
|
||||
_size{ std::exchange(other._size, 0) }
|
||||
{
|
||||
}
|
||||
|
||||
aligned_buffer& operator=(aligned_buffer&& other) noexcept
|
||||
{
|
||||
_aligned_free(_data);
|
||||
_data = std::exchange(other._data, nullptr);
|
||||
_size = std::exchange(other._size, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* data()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
private:
|
||||
T* _data = nullptr;
|
||||
size_t _size = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct vec2
|
||||
{
|
||||
T x{};
|
||||
T y{};
|
||||
|
||||
bool operator==(const vec2& other) const noexcept
|
||||
{
|
||||
return memcmp(this, &other, sizeof(vec2)) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const vec2& other) const noexcept
|
||||
{
|
||||
return memcmp(this, &other, sizeof(vec2)) != 0;
|
||||
}
|
||||
|
||||
vec2 operator*(const vec2& other) const noexcept
|
||||
{
|
||||
return { static_cast<T>(x * other.x), static_cast<T>(y * other.y) };
|
||||
}
|
||||
|
||||
vec2 operator/(const vec2& other) const noexcept
|
||||
{
|
||||
return { static_cast<T>(x / other.x), static_cast<T>(y / other.y) };
|
||||
}
|
||||
|
||||
template<typename U = T>
|
||||
U area() const noexcept
|
||||
{
|
||||
return static_cast<U>(x) * static_cast<U>(y);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct vec4
|
||||
{
|
||||
T x{};
|
||||
T y{};
|
||||
T z{};
|
||||
T w{};
|
||||
};
|
||||
|
||||
using u8 = uint8_t;
|
||||
using u16 = uint16_t;
|
||||
using u16x2 = vec2<u16>;
|
||||
using u32 = uint32_t;
|
||||
using u32x2 = vec2<u32>;
|
||||
using f32 = float;
|
||||
using f32x2 = vec2<f32>;
|
||||
using f32x4 = vec4<f32>;
|
||||
|
||||
union glyph_entry
|
||||
{
|
||||
uint32_t value;
|
||||
struct
|
||||
{
|
||||
uint32_t codepoint : 20;
|
||||
uint32_t wide : 1;
|
||||
uint32_t bold : 1;
|
||||
uint32_t italic : 1;
|
||||
};
|
||||
|
||||
constexpr bool operator==(const glyph_entry& other) const noexcept
|
||||
{
|
||||
return value == other.value;
|
||||
}
|
||||
};
|
||||
|
||||
struct glyph_entry_hasher
|
||||
{
|
||||
constexpr size_t operator()(glyph_entry entry) const noexcept
|
||||
{
|
||||
uint64_t x = entry.value;
|
||||
x ^= x >> 33;
|
||||
x *= UINT64_C(0xff51afd7ed558ccd);
|
||||
x ^= x >> 33;
|
||||
return static_cast<size_t>(x);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
// D3D constant buffers sizes must be a multiple of 16 bytes.
|
||||
struct alignas(16) const_buffer
|
||||
{
|
||||
f32x4 viewport;
|
||||
u32x2 cellSize;
|
||||
u32 cellCountX;
|
||||
u32 backgroundColor;
|
||||
u32 selectionColor;
|
||||
#pragma warning(suppress : 4324) // structure was padded due to alignment specifier
|
||||
};
|
||||
|
||||
struct cell
|
||||
{
|
||||
union
|
||||
{
|
||||
u32 glyphIndex;
|
||||
u16x2 glyphIndex16;
|
||||
};
|
||||
u32 flags;
|
||||
u32x2 color;
|
||||
};
|
||||
|
||||
enum class invalidation_flags : u8
|
||||
{
|
||||
none = 0,
|
||||
device = 1 << 0,
|
||||
size = 1 << 1,
|
||||
font = 1 << 2,
|
||||
cbuffer = 1 << 3,
|
||||
title = 1 << 4,
|
||||
};
|
||||
friend constexpr invalidation_flags operator~(invalidation_flags v) noexcept { return static_cast<invalidation_flags>(~static_cast<u8>(v)); }
|
||||
friend constexpr invalidation_flags operator|(invalidation_flags lhs, invalidation_flags rhs) noexcept { return static_cast<invalidation_flags>(static_cast<u8>(lhs) | static_cast<u8>(rhs)); }
|
||||
friend constexpr invalidation_flags operator&(invalidation_flags lhs, invalidation_flags rhs) noexcept { return static_cast<invalidation_flags>(static_cast<u8>(lhs) & static_cast<u8>(rhs)); }
|
||||
friend constexpr void operator|=(invalidation_flags& lhs, invalidation_flags rhs) noexcept { lhs = lhs | rhs; }
|
||||
friend constexpr void operator&=(invalidation_flags& lhs, invalidation_flags rhs) noexcept { lhs = lhs & rhs; }
|
||||
|
||||
// resource handling
|
||||
[[nodiscard]] HRESULT _handleException(const wil::ResultException& exception) noexcept;
|
||||
__declspec(noinline) void _createResources();
|
||||
__declspec(noinline) void _recreateSizeDependentResources();
|
||||
__declspec(noinline) void _recreateFontDependentResources();
|
||||
void _setShaderResources() const;
|
||||
void _updateConstantBuffer() const;
|
||||
|
||||
// text handling
|
||||
IDWriteTextFormat* _getTextFormat(bool bold, bool italic) const noexcept { return _r.textFormats[italic][bold].get(); }
|
||||
wil::com_ptr<IDWriteTextFormat> _createTextFormat(const wchar_t* fontFamilyName, DWRITE_FONT_WEIGHT fontWeight, DWRITE_FONT_STYLE fontStyle, float fontSize, const wchar_t* localeName) const;
|
||||
u16x2 _allocateAtlasCell() noexcept;
|
||||
void _drawGlyph(const til::pair<glyph_entry, std::array<u16x2, 2>>& pair) const;
|
||||
void _drawCursor() const;
|
||||
void _copyScratchpadCell(uint32_t scratchpadIndex, u16x2 target, uint32_t copyFlags = 0) const;
|
||||
|
||||
template<typename T1, typename T2>
|
||||
cell* _getCell(T1 x, T2 y) noexcept
|
||||
{
|
||||
return _r.cells.data() + static_cast<size_t>(_api.cellCount.x) * y + x;
|
||||
}
|
||||
|
||||
struct static_resources
|
||||
{
|
||||
wil::com_ptr<ID2D1Factory> d2dFactory;
|
||||
wil::com_ptr<IDWriteFactory> dwriteFactory;
|
||||
bool isWindows10OrGreater = true;
|
||||
} _sr;
|
||||
|
||||
struct resources
|
||||
{
|
||||
// D3D resources
|
||||
wil::com_ptr<ID3D11Device> device;
|
||||
wil::com_ptr<ID3D11DeviceContext1> deviceContext;
|
||||
wil::com_ptr<IDXGISwapChain1> swapChain;
|
||||
wil::unique_handle swapChainHandle;
|
||||
wil::unique_handle frameLatencyWaitableObject;
|
||||
wil::com_ptr<ID3D11RenderTargetView> renderTargetView;
|
||||
wil::com_ptr<ID3D11VertexShader> vertexShader;
|
||||
wil::com_ptr<ID3D11PixelShader> pixelShader;
|
||||
wil::com_ptr<ID3D11Buffer> constantBuffer;
|
||||
wil::com_ptr<ID3D11Buffer> cellBuffer;
|
||||
wil::com_ptr<ID3D11ShaderResourceView> cellView;
|
||||
|
||||
// D2D resources
|
||||
wil::com_ptr<ID3D11Texture2D> glyphBuffer;
|
||||
wil::com_ptr<ID3D11ShaderResourceView> glyphView;
|
||||
wil::com_ptr<ID3D11Texture2D> glyphScratchpad;
|
||||
wil::com_ptr<ID2D1RenderTarget> d2dRenderTarget;
|
||||
wil::com_ptr<ID2D1Brush> brush;
|
||||
wil::com_ptr<IDWriteTextFormat> textFormats[2][2];
|
||||
|
||||
// Resources dependent on _api.sizeInPixel
|
||||
aligned_buffer<cell> cells;
|
||||
// Resources dependent on _api.cellSize
|
||||
robin_hood::unordered_flat_map<glyph_entry, std::array<u16x2, 2>, glyph_entry_hasher> glyphs;
|
||||
std::vector<til::pair<glyph_entry, std::array<u16x2, 2>>> glyphQueue;
|
||||
u16x2 atlasSizeInPixel;
|
||||
u16x2 atlasPosition;
|
||||
} _r;
|
||||
|
||||
struct api_state
|
||||
{
|
||||
f32x2 cellSizeDIP; // invalidation_flags::font
|
||||
u16x2 cellSize; // invalidation_flags::size
|
||||
u16x2 cellCount; // caches `sizeInPixel / cellSize`
|
||||
u16x2 sizeInPixel; // invalidation_flags::size
|
||||
|
||||
std::wstring fontName; // invalidation_flags::font|size
|
||||
u16 fontSize = 0; // invalidation_flags::font|size
|
||||
u16 fontWeight = DWRITE_FONT_WEIGHT_NORMAL; // invalidation_flags::font
|
||||
u16 dpi = USER_DEFAULT_SCREEN_DPI; // invalidation_flags::font|size
|
||||
u16 antialiasingMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; // invalidation_flags::font
|
||||
|
||||
std::function<void()> swapChainChangedCallback;
|
||||
HWND hwnd = nullptr;
|
||||
} _api;
|
||||
|
||||
struct render_api_state
|
||||
{
|
||||
til::rectangle dirtyArea;
|
||||
u32x2 currentColor{};
|
||||
glyph_entry attributes{};
|
||||
u32 backgroundColor = ~u32(0);
|
||||
u32 selectionColor = 0x7fffffff;
|
||||
} _rapi;
|
||||
|
||||
invalidation_flags _invalidations = invalidation_flags::device;
|
||||
};
|
||||
}
|
49
src/renderer/atlas/atlas.vcxproj
Normal file
49
src/renderer/atlas/atlas.vcxproj
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{8222900C-8B6C-452A-91AC-BE95DB04B95F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>atlas</RootNamespace>
|
||||
<ProjectName>RendererAtlas</ProjectName>
|
||||
<TargetName>ConRenderAtlas</TargetName>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)src\common.build.pre.props" />
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AtlasEngine.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="AtlasEngine.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="shader_ps.hlsl">
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
<ShaderModel>4.1</ShaderModel>
|
||||
<VariableName>shader_ps</VariableName>
|
||||
<ObjectFileOutput />
|
||||
<HeaderFileOutput>$(OutDir)$(ProjectName)\%(Filename).h</HeaderFileOutput>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<AdditionalOptions Condition="'$(Configuration)'=='Release'">/Qstrip_debug /Qstrip_reflect %(AdditionalOptions)</AdditionalOptions>
|
||||
</FxCompile>
|
||||
<FxCompile Include="shader_vs.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<ShaderModel>4.1</ShaderModel>
|
||||
<VariableName>shader_vs</VariableName>
|
||||
<ObjectFileOutput />
|
||||
<HeaderFileOutput>$(OutDir)$(ProjectName)\%(Filename).h</HeaderFileOutput>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<AdditionalOptions Condition="'$(Configuration)'=='Release'">/Qstrip_debug /Qstrip_reflect %(AdditionalOptions)</AdditionalOptions>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(SolutionDir)src\common.build.post.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(OutDir)$(ProjectName)\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
4
src/renderer/atlas/pch.cpp
Normal file
4
src/renderer/atlas/pch.cpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
50
src/renderer/atlas/pch.h
Normal file
50
src/renderer/atlas/pch.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <array>
|
||||
#include <iomanip>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <d2d1.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <dwrite.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <dxgidebug.h>
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
#include <gsl/pointers>
|
||||
#include <gsl/span>
|
||||
#include <gsl/gsl_util>
|
||||
#include <wil/com.h>
|
||||
#include <wil/result_macros.h>
|
||||
#include <wil/stl.h>
|
||||
#include <wil/win32_helpers.h>
|
||||
|
||||
#include <robin_hood.h>
|
||||
|
||||
// Dynamic Bitset (optional dependency on LibPopCnt for perf at bit counting)
|
||||
// Variable-size compressed-storage header-only bit flag storage library.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
#include <dynamic_bitset.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
// Chromium Numerics (safe math)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100) // '...': unreferenced formal parameter
|
||||
#pragma warning(disable : 26812) // The enum type '...' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
|
||||
#include <base/numerics/safe_math.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include "til.h"
|
||||
#include <til/pair.h>
|
75
src/renderer/atlas/shader_ps.hlsl
Normal file
75
src/renderer/atlas/shader_ps.hlsl
Normal file
|
@ -0,0 +1,75 @@
|
|||
// According to Nvidia's "Understanding Structured Buffer Performance" guide
|
||||
// one should aim for structures with sizes divisible by 128 bits (16 bytes).
|
||||
// This prevents elements from spanning cache lines.
|
||||
struct Cell
|
||||
{
|
||||
uint glyphPos;
|
||||
uint flags;
|
||||
uint2 color;
|
||||
};
|
||||
|
||||
cbuffer ConstantBuffer : register(b0)
|
||||
{
|
||||
float4 viewport;
|
||||
uint2 cellSize;
|
||||
uint cellCountX;
|
||||
uint backgroundColor;
|
||||
uint selectionColor;
|
||||
};
|
||||
StructuredBuffer<Cell> cells : register(t0);
|
||||
Texture2D<float4> glyphs : register(t1);
|
||||
|
||||
float4 decodeRGB(uint i)
|
||||
{
|
||||
uint r = i & 0xff;
|
||||
uint g = (i >> 8) & 0xff;
|
||||
uint b = (i >> 16) & 0xff;
|
||||
uint a = i >> 24;
|
||||
return float4(r, g, b, a) / 255.0;
|
||||
}
|
||||
|
||||
uint2 decodeU16x2(uint i)
|
||||
{
|
||||
return uint2(i & 0xffff, i >> 16);
|
||||
}
|
||||
|
||||
float insideRect(float2 pos, float4 boundaries)
|
||||
{
|
||||
float2 v = step(boundaries.xy, pos) - step(boundaries.zw, pos);
|
||||
return v.x * v.y;
|
||||
}
|
||||
|
||||
float4 main(float4 pos: SV_Position): SV_Target
|
||||
{
|
||||
if (!insideRect(pos.xy, viewport))
|
||||
{
|
||||
return decodeRGB(backgroundColor);
|
||||
}
|
||||
|
||||
uint2 cellIndex = pos.xy / cellSize;
|
||||
uint2 cellPos = pos.xy % cellSize;
|
||||
|
||||
Cell cell = cells[cellIndex.y * cellCountX + cellIndex.x];
|
||||
|
||||
uint2 glyphPos = decodeU16x2(cell.glyphPos);
|
||||
uint2 pixelPos = glyphPos + cellPos;
|
||||
float4 alpha = glyphs[pixelPos];
|
||||
|
||||
float3 color = lerp(
|
||||
decodeRGB(cell.color.y).rgb,
|
||||
decodeRGB(cell.color.x).rgb,
|
||||
alpha.rgb
|
||||
);
|
||||
|
||||
if (cell.flags & 1)
|
||||
{
|
||||
color = abs(glyphs[cellPos].rgb - color);
|
||||
}
|
||||
if (cell.flags & 2)
|
||||
{
|
||||
float4 sc = decodeRGB(selectionColor);
|
||||
color = lerp(color, sc.rgb, sc.a);
|
||||
}
|
||||
|
||||
return float4(color, 1);
|
||||
}
|
12
src/renderer/atlas/shader_vs.hlsl
Normal file
12
src/renderer/atlas/shader_vs.hlsl
Normal file
|
@ -0,0 +1,12 @@
|
|||
float4 main(uint id : SV_VERTEXID) : SV_POSITION
|
||||
{
|
||||
// The algorithm below is a fast way to generate a full screen triangle,
|
||||
// published by Bill Bilodeau "Vertex Shader Tricks" at GDC14.
|
||||
// It covers the entire viewport and is faster for the GPU than a quad/rectangle.
|
||||
return float4(
|
||||
float(id / 2) * 4.0 - 1.0,
|
||||
float(id % 2) * 4.0 - 1.0,
|
||||
0.0,
|
||||
1.0
|
||||
);
|
||||
}
|
|
@ -7,20 +7,7 @@
|
|||
|
||||
#include "../inc/FontInfoBase.hpp"
|
||||
|
||||
bool operator==(const FontInfoBase& a, const FontInfoBase& b)
|
||||
{
|
||||
return a._faceName == b._faceName &&
|
||||
a._weight == b._weight &&
|
||||
a._family == b._family &&
|
||||
a._codePage == b._codePage &&
|
||||
a._fDefaultRasterSetFromEngine == b._fDefaultRasterSetFromEngine;
|
||||
}
|
||||
|
||||
FontInfoBase::FontInfoBase(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const bool fSetDefaultRasterFont,
|
||||
const unsigned int codePage) :
|
||||
FontInfoBase::FontInfoBase(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const bool fSetDefaultRasterFont, const unsigned int codePage) noexcept :
|
||||
_faceName(faceName),
|
||||
_family(family),
|
||||
_weight(weight),
|
||||
|
@ -30,20 +17,16 @@ FontInfoBase::FontInfoBase(const std::wstring_view faceName,
|
|||
ValidateFont();
|
||||
}
|
||||
|
||||
FontInfoBase::FontInfoBase(const FontInfoBase& fibFont) :
|
||||
FontInfoBase(fibFont.GetFaceName(),
|
||||
fibFont.GetFamily(),
|
||||
fibFont.GetWeight(),
|
||||
fibFont.WasDefaultRasterSetFromEngine(),
|
||||
fibFont.GetCodePage())
|
||||
bool FontInfoBase::operator==(const FontInfoBase& other) noexcept
|
||||
{
|
||||
return _faceName == other._faceName &&
|
||||
_weight == other._weight &&
|
||||
_family == other._family &&
|
||||
_codePage == other._codePage &&
|
||||
_fDefaultRasterSetFromEngine == other._fDefaultRasterSetFromEngine;
|
||||
}
|
||||
|
||||
FontInfoBase::~FontInfoBase()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char FontInfoBase::GetFamily() const
|
||||
unsigned char FontInfoBase::GetFamily() const noexcept
|
||||
{
|
||||
return _family;
|
||||
}
|
||||
|
@ -51,22 +34,22 @@ unsigned char FontInfoBase::GetFamily() const
|
|||
// When the default raster font is forced set from the engine, this is how we differentiate it from a simple apply.
|
||||
// Default raster font is internally represented as a blank face name and zeros for weight, family, and size. This is
|
||||
// the hint for the engine to use whatever comes back from GetStockObject(OEM_FIXED_FONT) (at least in the GDI world).
|
||||
bool FontInfoBase::WasDefaultRasterSetFromEngine() const
|
||||
bool FontInfoBase::WasDefaultRasterSetFromEngine() const noexcept
|
||||
{
|
||||
return _fDefaultRasterSetFromEngine;
|
||||
}
|
||||
|
||||
unsigned int FontInfoBase::GetWeight() const
|
||||
unsigned int FontInfoBase::GetWeight() const noexcept
|
||||
{
|
||||
return _weight;
|
||||
}
|
||||
|
||||
const std::wstring_view FontInfoBase::GetFaceName() const noexcept
|
||||
const std::wstring& FontInfoBase::GetFaceName() const noexcept
|
||||
{
|
||||
return _faceName;
|
||||
}
|
||||
|
||||
unsigned int FontInfoBase::GetCodePage() const
|
||||
unsigned int FontInfoBase::GetCodePage() const noexcept
|
||||
{
|
||||
return _codePage;
|
||||
}
|
||||
|
@ -77,21 +60,15 @@ unsigned int FontInfoBase::GetCodePage() const
|
|||
// Arguments:
|
||||
// - buffer: the buffer into which to copy characters
|
||||
// - size: the size of buffer
|
||||
HRESULT FontInfoBase::FillLegacyNameBuffer(gsl::span<wchar_t> buffer) const
|
||||
try
|
||||
void FontInfoBase::FillLegacyNameBuffer(wchar_t (&buffer)[LF_FACESIZE]) const noexcept
|
||||
{
|
||||
auto toCopy = std::min<size_t>(buffer.size() - 1, _faceName.size());
|
||||
auto last = std::copy(_faceName.cbegin(), _faceName.cbegin() + toCopy, buffer.begin());
|
||||
std::fill(last, buffer.end(), L'\0');
|
||||
return S_OK;
|
||||
const auto toCopy = std::min(std::size(buffer) - 1, _faceName.size());
|
||||
auto last = std::copy_n(_faceName.data(), toCopy, &buffer[0]);
|
||||
*last = L'\0';
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
// NOTE: this method is intended to only be used from the engine itself to respond what font it has chosen.
|
||||
void FontInfoBase::SetFromEngine(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const bool fSetDefaultRasterFont)
|
||||
void FontInfoBase::SetFromEngine(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const bool fSetDefaultRasterFont) noexcept
|
||||
{
|
||||
_faceName = faceName;
|
||||
_family = family;
|
||||
|
@ -101,12 +78,12 @@ void FontInfoBase::SetFromEngine(const std::wstring_view faceName,
|
|||
|
||||
// Internally, default raster font is represented by empty facename, and zeros for weight, family, and size. Since
|
||||
// FontInfoBase doesn't have sizing information, this helper checks everything else.
|
||||
bool FontInfoBase::IsDefaultRasterFontNoSize() const
|
||||
bool FontInfoBase::IsDefaultRasterFontNoSize() const noexcept
|
||||
{
|
||||
return (_weight == 0 && _family == 0 && _faceName.empty());
|
||||
}
|
||||
|
||||
void FontInfoBase::ValidateFont()
|
||||
void FontInfoBase::ValidateFont() noexcept
|
||||
{
|
||||
// If we were given a blank name, it meant raster fonts, which to us is always Terminal.
|
||||
if (!IsDefaultRasterFontNoSize() && s_pFontDefaultList != nullptr)
|
||||
|
@ -115,8 +92,7 @@ void FontInfoBase::ValidateFont()
|
|||
if (_faceName == DEFAULT_TT_FONT_FACENAME)
|
||||
{
|
||||
std::wstring defaultFontFace;
|
||||
if (SUCCEEDED(s_pFontDefaultList->RetrieveDefaultFontNameForCodepage(GetCodePage(),
|
||||
defaultFontFace)))
|
||||
if (SUCCEEDED(s_pFontDefaultList->RetrieveDefaultFontNameForCodepage(GetCodePage(), defaultFontFace)))
|
||||
{
|
||||
_faceName = defaultFontFace;
|
||||
|
||||
|
@ -128,14 +104,14 @@ void FontInfoBase::ValidateFont()
|
|||
}
|
||||
}
|
||||
|
||||
bool FontInfoBase::IsTrueTypeFont() const
|
||||
bool FontInfoBase::IsTrueTypeFont() const noexcept
|
||||
{
|
||||
return WI_IsFlagSet(_family, TMPF_TRUETYPE);
|
||||
}
|
||||
|
||||
Microsoft::Console::Render::IFontDefaultList* FontInfoBase::s_pFontDefaultList;
|
||||
|
||||
void FontInfoBase::s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList)
|
||||
void FontInfoBase::s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList) noexcept
|
||||
{
|
||||
s_pFontDefaultList = pFontDefaultList;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,25 @@
|
|||
|
||||
#include "../inc/FontInfoDesired.hpp"
|
||||
|
||||
bool operator==(const FontInfoDesired& a, const FontInfoDesired& b)
|
||||
FontInfoDesired::FontInfoDesired(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const COORD coordSizeDesired, const unsigned int codePage) noexcept :
|
||||
FontInfoBase(faceName, family, weight, false, codePage),
|
||||
_coordSizeDesired(coordSizeDesired)
|
||||
{
|
||||
return (static_cast<FontInfoBase>(a) == static_cast<FontInfoBase>(b) &&
|
||||
a._coordSizeDesired == b._coordSizeDesired);
|
||||
}
|
||||
|
||||
COORD FontInfoDesired::GetEngineSize() const
|
||||
FontInfoDesired::FontInfoDesired(const FontInfo& fiFont) noexcept :
|
||||
FontInfoBase(fiFont),
|
||||
_coordSizeDesired(fiFont.GetUnscaledSize())
|
||||
{
|
||||
}
|
||||
|
||||
bool FontInfoDesired::operator==(const FontInfoDesired& other) noexcept
|
||||
{
|
||||
return FontInfoBase::operator==(other) &&
|
||||
_coordSizeDesired == other._coordSizeDesired;
|
||||
}
|
||||
|
||||
COORD FontInfoDesired::GetEngineSize() const noexcept
|
||||
{
|
||||
COORD coordSize = _coordSizeDesired;
|
||||
if (IsTrueTypeFont())
|
||||
|
@ -22,30 +34,12 @@ COORD FontInfoDesired::GetEngineSize() const
|
|||
return coordSize;
|
||||
}
|
||||
|
||||
FontInfoDesired::FontInfoDesired(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const COORD coordSizeDesired,
|
||||
const unsigned int codePage) :
|
||||
FontInfoBase(faceName, family, weight, false, codePage),
|
||||
_coordSizeDesired(coordSizeDesired)
|
||||
{
|
||||
}
|
||||
|
||||
FontInfoDesired::FontInfoDesired(const FontInfo& fiFont) :
|
||||
FontInfoBase(fiFont),
|
||||
_coordSizeDesired(fiFont.GetUnscaledSize())
|
||||
{
|
||||
}
|
||||
|
||||
// This helper determines if this object represents the default raster font. This can either be because internally we're
|
||||
// using the empty facename and zeros for size, weight, and family, or it can be because we were given explicit
|
||||
// dimensions from the engine that were the result of loading the default raster font. See GdiEngine::_GetProposedFont().
|
||||
bool FontInfoDesired::IsDefaultRasterFont() const
|
||||
bool FontInfoDesired::IsDefaultRasterFont() const noexcept
|
||||
{
|
||||
// Either the raster was set from the engine...
|
||||
// OR the face name is empty with a size of 0x0 or 8x12.
|
||||
return WasDefaultRasterSetFromEngine() || (GetFaceName().empty() &&
|
||||
((_coordSizeDesired.X == 0 && _coordSizeDesired.Y == 0) ||
|
||||
(_coordSizeDesired.X == 8 && _coordSizeDesired.Y == 12)));
|
||||
return WasDefaultRasterSetFromEngine() || (GetFaceName().empty() && (_coordSizeDesired == COORD{ 0, 0 } || _coordSizeDesired == COORD{ 8, 12 }));
|
||||
}
|
||||
|
|
|
@ -7,38 +7,25 @@
|
|||
using namespace Microsoft::Console;
|
||||
using namespace Microsoft::Console::Render;
|
||||
|
||||
RenderEngineBase::RenderEngineBase() :
|
||||
_titleChanged(false),
|
||||
_lastFrameTitle(L"")
|
||||
HRESULT RenderEngineBase::InvalidateTitle() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT RenderEngineBase::InvalidateTitle(const std::wstring_view proposedTitle) noexcept
|
||||
{
|
||||
if (proposedTitle != _lastFrameTitle)
|
||||
{
|
||||
_titleChanged = true;
|
||||
}
|
||||
|
||||
_titleChanged = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderEngineBase::UpdateTitle(const std::wstring_view newTitle) noexcept
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
if (newTitle != _lastFrameTitle)
|
||||
if (!_titleChanged)
|
||||
{
|
||||
RETURN_IF_FAILED(_DoUpdateTitle(newTitle));
|
||||
_lastFrameTitle = newTitle;
|
||||
_titleChanged = false;
|
||||
hr = S_OK;
|
||||
return S_FALSE;
|
||||
}
|
||||
return hr;
|
||||
|
||||
RETURN_IF_FAILED(_DoUpdateTitle(newTitle));
|
||||
_titleChanged = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderEngineBase::UpdateSoftFont(const gsl::span<const uint16_t> /*bitPattern*/,
|
||||
const SIZE /*cellSize*/,
|
||||
const size_t /*centeringHint*/) noexcept
|
||||
HRESULT RenderEngineBase::UpdateSoftFont(const gsl::span<const uint16_t> /*bitPattern*/, const SIZE /*cellSize*/, const size_t /*centeringHint*/) noexcept
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
@ -53,9 +40,7 @@ HRESULT RenderEngineBase::ResetLineTransform() noexcept
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT RenderEngineBase::PrepareLineTransform(const LineRendition /*lineRendition*/,
|
||||
const size_t /*targetRow*/,
|
||||
const size_t /*viewportLeft*/) noexcept
|
||||
HRESULT RenderEngineBase::PrepareLineTransform(const LineRendition /*lineRendition*/, const size_t /*targetRow*/, const size_t /*viewportLeft*/) noexcept
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
@ -74,5 +59,13 @@ HRESULT RenderEngineBase::PrepareLineTransform(const LineRendition /*lineRenditi
|
|||
// - Blocks until the engine is able to render without blocking.
|
||||
void RenderEngineBase::WaitUntilCanRender() noexcept
|
||||
{
|
||||
// do nothing by default
|
||||
Sleep(8);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Uses the currently selected font to determine how wide the given character will be when rendered.
|
||||
[[nodiscard]] HRESULT RenderEngineBase::IsGlyphWideByFont(const std::wstring_view& /*glyph*/, _Out_ bool* const pResult) noexcept
|
||||
{
|
||||
*pResult = false;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
|
|
@ -5,19 +5,7 @@
|
|||
|
||||
#include "../inc/FontInfo.hpp"
|
||||
|
||||
bool operator==(const FontInfo& a, const FontInfo& b)
|
||||
{
|
||||
return (static_cast<FontInfoBase>(a) == static_cast<FontInfoBase>(b) &&
|
||||
a._coordSize == b._coordSize &&
|
||||
a._coordSizeUnscaled == b._coordSizeUnscaled);
|
||||
}
|
||||
|
||||
FontInfo::FontInfo(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const COORD coordSize,
|
||||
const unsigned int codePage,
|
||||
const bool fSetDefaultRasterFont /* = false */) :
|
||||
FontInfo::FontInfo(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const COORD coordSize, const unsigned int codePage, const bool fSetDefaultRasterFont) noexcept :
|
||||
FontInfoBase(faceName, family, weight, fSetDefaultRasterFont, codePage),
|
||||
_coordSize(coordSize),
|
||||
_coordSizeUnscaled(coordSize),
|
||||
|
@ -26,39 +14,29 @@ FontInfo::FontInfo(const std::wstring_view faceName,
|
|||
ValidateFont();
|
||||
}
|
||||
|
||||
FontInfo::FontInfo(const FontInfo& fiFont) :
|
||||
FontInfoBase(fiFont),
|
||||
_coordSize(fiFont.GetSize()),
|
||||
_coordSizeUnscaled(fiFont.GetUnscaledSize())
|
||||
bool FontInfo::operator==(const FontInfo& other) noexcept
|
||||
{
|
||||
return FontInfoBase::operator==(other) &&
|
||||
_coordSize == other._coordSize &&
|
||||
_coordSizeUnscaled == other._coordSizeUnscaled;
|
||||
}
|
||||
|
||||
COORD FontInfo::GetUnscaledSize() const
|
||||
COORD FontInfo::GetUnscaledSize() const noexcept
|
||||
{
|
||||
return _coordSizeUnscaled;
|
||||
}
|
||||
|
||||
COORD FontInfo::GetSize() const
|
||||
COORD FontInfo::GetSize() const noexcept
|
||||
{
|
||||
return _coordSize;
|
||||
}
|
||||
|
||||
void FontInfo::SetFromEngine(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const bool fSetDefaultRasterFont,
|
||||
const COORD coordSize,
|
||||
const COORD coordSizeUnscaled)
|
||||
void FontInfo::SetFromEngine(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const bool fSetDefaultRasterFont, const COORD coordSize, const COORD coordSizeUnscaled) noexcept
|
||||
{
|
||||
FontInfoBase::SetFromEngine(faceName,
|
||||
family,
|
||||
weight,
|
||||
fSetDefaultRasterFont);
|
||||
|
||||
FontInfoBase::SetFromEngine(faceName, family, weight, fSetDefaultRasterFont);
|
||||
_coordSize = coordSize;
|
||||
_coordSizeUnscaled = coordSizeUnscaled;
|
||||
|
||||
_ValidateCoordSize();
|
||||
ValidateFont();
|
||||
}
|
||||
|
||||
bool FontInfo::GetFallback() const noexcept
|
||||
|
@ -71,12 +49,7 @@ void FontInfo::SetFallback(const bool didFallback) noexcept
|
|||
_didFallback = didFallback;
|
||||
}
|
||||
|
||||
void FontInfo::ValidateFont()
|
||||
{
|
||||
_ValidateCoordSize();
|
||||
}
|
||||
|
||||
void FontInfo::_ValidateCoordSize()
|
||||
void FontInfo::ValidateFont() noexcept
|
||||
{
|
||||
// a (0,0) font is okay for the default raster font, as we will eventually set the dimensions based on the font GDI
|
||||
// passes back to us.
|
||||
|
|
|
@ -69,11 +69,6 @@ Renderer::~Renderer()
|
|||
auto tries = maxRetriesForRenderEngine;
|
||||
while (tries > 0)
|
||||
{
|
||||
if (_destructing)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
const auto hr = _PaintFrameForEngine(pEngine);
|
||||
if (E_PENDING == hr)
|
||||
{
|
||||
|
@ -487,7 +482,7 @@ void Renderer::TriggerTitleChange()
|
|||
const auto newTitle = _pData->GetConsoleTitle();
|
||||
FOREACH_ENGINE(pEngine)
|
||||
{
|
||||
LOG_IF_FAILED(pEngine->InvalidateTitle(newTitle));
|
||||
LOG_IF_FAILED(pEngine->InvalidateTitle());
|
||||
}
|
||||
_NotifyPaintFrame();
|
||||
}
|
||||
|
@ -593,7 +588,7 @@ bool Renderer::s_IsSoftFontChar(const std::wstring_view& v, const size_t firstSo
|
|||
// - glyph - the utf16 encoded codepoint to test
|
||||
// Return Value:
|
||||
// - True if the codepoint is full-width (two wide), false if it is half-width (one wide).
|
||||
bool Renderer::IsGlyphWideByFont(const std::wstring_view glyph)
|
||||
bool Renderer::IsGlyphWideByFont(const std::wstring_view& glyph)
|
||||
{
|
||||
bool fIsFullWidth = false;
|
||||
|
||||
|
@ -761,7 +756,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
|
|||
// Retrieve the first pattern id
|
||||
auto patternIds = _pData->GetPatternId(target);
|
||||
// Determine whether we're using a soft font.
|
||||
auto usingSoftFont = s_IsSoftFontChar(it->Chars(), _firstSoftFontChar, _lastSoftFontChar);
|
||||
auto usingSoftFont = _isSoftFontChar(it->Chars());
|
||||
|
||||
// And hold the point where we should start drawing.
|
||||
auto screenPoint = target;
|
||||
|
@ -808,7 +803,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
|
|||
{
|
||||
COORD thisPoint{ screenPoint.X + gsl::narrow<SHORT>(cols), screenPoint.Y };
|
||||
const auto thisPointPatterns = _pData->GetPatternId(thisPoint);
|
||||
const auto thisUsingSoftFont = s_IsSoftFontChar(it->Chars(), _firstSoftFontChar, _lastSoftFontChar);
|
||||
const auto thisUsingSoftFont = _isSoftFontChar(it->Chars());
|
||||
const auto changedPatternOrFont = patternIds != thisPointPatterns || usingSoftFont != thisUsingSoftFont;
|
||||
if (color != it->TextAttr() || changedPatternOrFont)
|
||||
{
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace Microsoft::Console::Render
|
|||
const FontInfoDesired& FontInfoDesired,
|
||||
_Out_ FontInfo& FontInfo) override;
|
||||
|
||||
bool IsGlyphWideByFont(const std::wstring_view glyph) override;
|
||||
bool IsGlyphWideByFont(const std::wstring_view& glyph) override;
|
||||
|
||||
void EnablePainting() override;
|
||||
void WaitForPaintCompletionAndDisable(const DWORD dwTimeoutMs) override;
|
||||
|
@ -108,6 +108,7 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] HRESULT _PaintTitle(IRenderEngine* const pEngine);
|
||||
[[nodiscard]] std::optional<CursorOptions> _GetCursorInfo();
|
||||
[[nodiscard]] HRESULT _PrepareRenderInfo(_In_ IRenderEngine* const pEngine);
|
||||
bool _isSoftFontChar(const std::wstring_view& v) const noexcept;
|
||||
|
||||
std::array<IRenderEngine*, 2> _engines{};
|
||||
IRenderData* _pData = nullptr; // Non-ownership pointer
|
||||
|
|
|
@ -61,7 +61,7 @@ RenderThread::~RenderThread()
|
|||
// Return Value:
|
||||
// - S_OK if we succeeded, else an HRESULT corresponding to a failure to create
|
||||
// an Event or Thread.
|
||||
[[nodiscard]] HRESULT RenderThread::Initialize(IRenderer* const pRendererParent) noexcept
|
||||
[[nodiscard]] HRESULT RenderThread::Initialize(_In_ IRenderer* const pRendererParent) noexcept
|
||||
{
|
||||
_pRenderer = pRendererParent;
|
||||
|
||||
|
@ -213,12 +213,6 @@ DWORD WINAPI RenderThread::_ThreadProc()
|
|||
LOG_IF_FAILED(_pRenderer->PaintFrame());
|
||||
|
||||
SetEvent(_hPaintCompletedEvent);
|
||||
|
||||
// extra check before we sleep since it's a "long" activity, relatively speaking.
|
||||
if (_fKeepRunning)
|
||||
{
|
||||
Sleep(s_FrameLimitMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
|
|
@ -37,8 +37,6 @@ namespace Microsoft::Console::Render
|
|||
static DWORD WINAPI s_ThreadProc(_In_ LPVOID lpParameter);
|
||||
DWORD WINAPI _ThreadProc();
|
||||
|
||||
static DWORD const s_FrameLimitMilliseconds = 8;
|
||||
|
||||
HANDLE _hThread;
|
||||
HANDLE _hEvent;
|
||||
|
||||
|
|
|
@ -1498,18 +1498,13 @@ CATCH_RETURN()
|
|||
// - See https://docs.microsoft.com/en-us/windows/uwp/gaming/reduce-latency-with-dxgi-1-3-swap-chains.
|
||||
void DxEngine::WaitUntilCanRender() noexcept
|
||||
{
|
||||
if (!_swapChainFrameLatencyWaitableObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// DxEngine isn't really performant and holds the console lock for at least 20ms per (full) frame.
|
||||
// Sleeping 8ms per frame thus increases throughput of the concurrently running VtEngine.
|
||||
Sleep(8);
|
||||
|
||||
const auto ret = WaitForSingleObjectEx(
|
||||
_swapChainFrameLatencyWaitableObject.get(),
|
||||
1000, // 1 second timeout (shouldn't ever occur)
|
||||
true);
|
||||
if (ret != WAIT_OBJECT_0)
|
||||
if (_swapChainFrameLatencyWaitableObject)
|
||||
{
|
||||
LOG_WIN32_MSG(ret, "Waiting for swap chain frame latency waitable object returned error or timeout.");
|
||||
WaitForSingleObjectEx(_swapChainFrameLatencyWaitableObject.get(), 1000, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2135,7 +2130,7 @@ CATCH_RETURN();
|
|||
// - pResult - True if it should take two columns. False if it should take one.
|
||||
// Return Value:
|
||||
// - S_OK or relevant DirectWrite error.
|
||||
[[nodiscard]] HRESULT DxEngine::IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept
|
||||
[[nodiscard]] HRESULT DxEngine::IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept
|
||||
try
|
||||
{
|
||||
RETURN_HR_IF_NULL(E_INVALIDARG, pResult);
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
[[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInCharacters(const ::Microsoft::Console::Types::Viewport& viewInPixels) noexcept;
|
||||
[[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInPixels(const ::Microsoft::Console::Types::Viewport& viewInCharacters) noexcept;
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
|
|
|
@ -38,7 +38,7 @@ using namespace Microsoft::Console::Render;
|
|||
// - pResult - receives return value, True if it is full-width (2 wide). False if it is half-width (1 wide).
|
||||
// Return Value:
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT GdiEngine::IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept
|
||||
[[nodiscard]] HRESULT GdiEngine::IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept
|
||||
{
|
||||
bool isFullWidth = false;
|
||||
|
||||
|
|
|
@ -610,7 +610,7 @@ GdiEngine::~GdiEngine()
|
|||
// NOTE: not using what GDI gave us because some fonts don't quite roundtrip (e.g. MS Gothic and VL Gothic)
|
||||
lf.lfPitchAndFamily = (FIXED_PITCH | FF_MODERN);
|
||||
|
||||
RETURN_IF_FAILED(FontDesired.FillLegacyNameBuffer(gsl::make_span(lf.lfFaceName)));
|
||||
FontDesired.FillLegacyNameBuffer(lf.lfFaceName);
|
||||
|
||||
// Create font.
|
||||
hFont.reset(CreateFontIndirectW(&lf));
|
||||
|
|
|
@ -28,40 +28,21 @@ Author(s):
|
|||
class FontInfo : public FontInfoBase
|
||||
{
|
||||
public:
|
||||
FontInfo(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const COORD coordSize,
|
||||
const unsigned int codePage,
|
||||
const bool fSetDefaultRasterFont = false);
|
||||
FontInfo(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const COORD coordSize, const unsigned int codePage, const bool fSetDefaultRasterFont = false) noexcept;
|
||||
|
||||
FontInfo(const FontInfo& fiFont);
|
||||
|
||||
COORD GetSize() const;
|
||||
COORD GetUnscaledSize() const;
|
||||
|
||||
void SetFromEngine(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const bool fSetDefaultRasterFont,
|
||||
const COORD coordSize,
|
||||
const COORD coordSizeUnscaled);
|
||||
bool operator==(const FontInfo& other) noexcept;
|
||||
|
||||
COORD GetSize() const noexcept;
|
||||
COORD GetUnscaledSize() const noexcept;
|
||||
void SetFromEngine(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const bool fSetDefaultRasterFont, const COORD coordSize, const COORD coordSizeUnscaled) noexcept;
|
||||
bool GetFallback() const noexcept;
|
||||
void SetFallback(const bool didFallback) noexcept;
|
||||
|
||||
void ValidateFont();
|
||||
|
||||
friend bool operator==(const FontInfo& a, const FontInfo& b);
|
||||
void ValidateFont() noexcept;
|
||||
|
||||
private:
|
||||
void _ValidateCoordSize();
|
||||
|
||||
COORD _coordSize;
|
||||
COORD _coordSizeUnscaled;
|
||||
bool _didFallback;
|
||||
};
|
||||
|
||||
bool operator==(const FontInfo& a, const FontInfo& b);
|
||||
|
||||
// SET AND UNSET CONSOLE_OEMFONT_DISPLAY unless we can get rid of the stupid recoding in the conhost side.
|
||||
|
|
|
@ -26,40 +26,25 @@ static constexpr wchar_t DEFAULT_RASTER_FONT_FACENAME[]{ L"Terminal" };
|
|||
class FontInfoBase
|
||||
{
|
||||
public:
|
||||
FontInfoBase(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const bool fSetDefaultRasterFont,
|
||||
const unsigned int uiCodePage);
|
||||
FontInfoBase(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const bool fSetDefaultRasterFont, const unsigned int uiCodePage) noexcept;
|
||||
|
||||
FontInfoBase(const FontInfoBase& fibFont);
|
||||
bool operator==(const FontInfoBase& other) noexcept;
|
||||
|
||||
~FontInfoBase();
|
||||
|
||||
unsigned char GetFamily() const;
|
||||
unsigned int GetWeight() const;
|
||||
const std::wstring_view GetFaceName() const noexcept;
|
||||
unsigned int GetCodePage() const;
|
||||
|
||||
HRESULT FillLegacyNameBuffer(gsl::span<wchar_t> buffer) const;
|
||||
|
||||
bool IsTrueTypeFont() const;
|
||||
|
||||
void SetFromEngine(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const bool fSetDefaultRasterFont);
|
||||
|
||||
bool WasDefaultRasterSetFromEngine() const;
|
||||
void ValidateFont();
|
||||
unsigned char GetFamily() const noexcept;
|
||||
unsigned int GetWeight() const noexcept;
|
||||
const std::wstring& GetFaceName() const noexcept;
|
||||
unsigned int GetCodePage() const noexcept;
|
||||
void FillLegacyNameBuffer(wchar_t (&buffer)[LF_FACESIZE]) const noexcept;
|
||||
bool IsTrueTypeFont() const noexcept;
|
||||
void SetFromEngine(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const bool fSetDefaultRasterFont) noexcept;
|
||||
bool WasDefaultRasterSetFromEngine() const noexcept;
|
||||
void ValidateFont() noexcept;
|
||||
|
||||
static Microsoft::Console::Render::IFontDefaultList* s_pFontDefaultList;
|
||||
static void s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList);
|
||||
|
||||
friend bool operator==(const FontInfoBase& a, const FontInfoBase& b);
|
||||
static void s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList) noexcept;
|
||||
|
||||
protected:
|
||||
bool IsDefaultRasterFontNoSize() const;
|
||||
bool IsDefaultRasterFontNoSize() const noexcept;
|
||||
|
||||
private:
|
||||
std::wstring _faceName;
|
||||
|
@ -68,5 +53,3 @@ private:
|
|||
unsigned int _codePage;
|
||||
bool _fDefaultRasterSetFromEngine;
|
||||
};
|
||||
|
||||
bool operator==(const FontInfoBase& a, const FontInfoBase& b);
|
||||
|
|
|
@ -24,21 +24,14 @@ Author(s):
|
|||
class FontInfoDesired : public FontInfoBase
|
||||
{
|
||||
public:
|
||||
FontInfoDesired(const std::wstring_view faceName,
|
||||
const unsigned char family,
|
||||
const unsigned int weight,
|
||||
const COORD coordSizeDesired,
|
||||
const unsigned int uiCodePage);
|
||||
FontInfoDesired(const std::wstring_view& faceName, const unsigned char family, const unsigned int weight, const COORD coordSizeDesired, const unsigned int uiCodePage) noexcept;
|
||||
FontInfoDesired(const FontInfo& fiFont) noexcept;
|
||||
|
||||
FontInfoDesired(const FontInfo& fiFont);
|
||||
bool operator==(const FontInfoDesired& other) noexcept;
|
||||
|
||||
COORD GetEngineSize() const;
|
||||
bool IsDefaultRasterFont() const;
|
||||
|
||||
friend bool operator==(const FontInfoDesired& a, const FontInfoDesired& b);
|
||||
COORD GetEngineSize() const noexcept;
|
||||
bool IsDefaultRasterFont() const noexcept;
|
||||
|
||||
private:
|
||||
COORD _coordSizeDesired;
|
||||
};
|
||||
|
||||
bool operator==(const FontInfoDesired& a, const FontInfoDesired& b);
|
||||
|
|
|
@ -44,27 +44,22 @@ namespace Microsoft::Console::Render
|
|||
};
|
||||
using GridLineSet = til::enumset<GridLines>;
|
||||
|
||||
virtual ~IRenderEngine() = 0;
|
||||
|
||||
protected:
|
||||
IRenderEngine() = default;
|
||||
IRenderEngine(const IRenderEngine&) = default;
|
||||
IRenderEngine(IRenderEngine&&) = default;
|
||||
|
||||
virtual ~IRenderEngine() = 0;
|
||||
|
||||
IRenderEngine& operator=(const IRenderEngine&) = default;
|
||||
IRenderEngine& operator=(IRenderEngine&&) = default;
|
||||
|
||||
public:
|
||||
[[nodiscard]] virtual HRESULT StartPaint() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT EndPaint() noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual bool RequiresContinuousRedraw() noexcept = 0;
|
||||
virtual void WaitUntilCanRender() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT Present() noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT ScrollFrame() noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT InvalidateSystem(const RECT* const prcDirtyClient) noexcept = 0;
|
||||
|
@ -72,48 +67,24 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] virtual HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT InvalidateAll() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT InvalidateCircling(_Out_ bool* const pForcePaint) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT InvalidateTitle(const std::wstring_view proposedTitle) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT InvalidateTitle() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT ResetLineTransform() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PrepareLineTransform(const LineRendition lineRendition,
|
||||
const size_t targetRow,
|
||||
const size_t viewportLeft) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT PrepareLineTransform(const LineRendition lineRendition, const size_t targetRow, const size_t viewportLeft) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PaintBackground() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PaintBufferLine(gsl::span<const Cluster> const clusters,
|
||||
const COORD coord,
|
||||
const bool fTrimLeft,
|
||||
const bool lineWrapped) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PaintBufferGridLines(const GridLineSet lines,
|
||||
const COLORREF color,
|
||||
const size_t cchLine,
|
||||
const COORD coordTarget) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PaintBufferLine(gsl::span<const Cluster> const clusters, const COORD coord, const bool fTrimLeft, const bool lineWrapped) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const COORD coordTarget) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT PaintSelection(const SMALL_RECT rect) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT PaintCursor(const CursorOptions& options) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes,
|
||||
const gsl::not_null<IRenderData*> pData,
|
||||
const bool usingSoftFont,
|
||||
const bool isSettingDefaultBrushes) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired,
|
||||
_Out_ FontInfo& FontInfo) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateSoftFont(const gsl::span<const uint16_t> bitPattern,
|
||||
const SIZE cellSize,
|
||||
const size_t centeringHint) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null<IRenderData*> pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const SIZE cellSize, const size_t centeringHint) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateDpi(const int iDpi) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired,
|
||||
_Out_ FontInfo& FontInfo,
|
||||
const int iDpi) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, const int iDpi) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace Microsoft::Console::Render
|
|||
const FontInfoDesired& FontInfoDesired,
|
||||
_Out_ FontInfo& FontInfo) = 0;
|
||||
|
||||
virtual bool IsGlyphWideByFont(const std::wstring_view glyph) = 0;
|
||||
virtual bool IsGlyphWideByFont(const std::wstring_view& glyph) = 0;
|
||||
|
||||
virtual void EnablePainting() = 0;
|
||||
virtual void WaitForPaintCompletionAndDisable(const DWORD dwTimeoutMs) = 0;
|
||||
|
|
|
@ -24,40 +24,27 @@ namespace Microsoft::Console::Render
|
|||
class RenderEngineBase : public IRenderEngine
|
||||
{
|
||||
public:
|
||||
RenderEngineBase() = default;
|
||||
~RenderEngineBase() = 0;
|
||||
|
||||
protected:
|
||||
RenderEngineBase();
|
||||
RenderEngineBase(const RenderEngineBase&) = default;
|
||||
RenderEngineBase(RenderEngineBase&&) = default;
|
||||
RenderEngineBase& operator=(const RenderEngineBase&) = default;
|
||||
RenderEngineBase& operator=(RenderEngineBase&&) = default;
|
||||
|
||||
public:
|
||||
[[nodiscard]] HRESULT InvalidateTitle(const std::wstring_view proposedTitle) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT InvalidateTitle() noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT UpdateSoftFont(const gsl::span<const uint16_t> bitPattern,
|
||||
const SIZE cellSize,
|
||||
const size_t centeringHint) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const SIZE cellSize, const size_t centeringHint) noexcept override;
|
||||
[[nodiscard]] HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT ResetLineTransform() noexcept override;
|
||||
[[nodiscard]] HRESULT PrepareLineTransform(const LineRendition lineRendition,
|
||||
const size_t targetRow,
|
||||
const size_t viewportLeft) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PrepareLineTransform(const LineRendition lineRendition, const size_t targetRow, const size_t viewportLeft) noexcept override;
|
||||
[[nodiscard]] virtual bool RequiresContinuousRedraw() noexcept override;
|
||||
|
||||
void WaitUntilCanRender() noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view& glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept = 0;
|
||||
|
||||
bool _titleChanged;
|
||||
std::wstring _lastFrameTitle;
|
||||
bool _titleChanged = false;
|
||||
};
|
||||
|
||||
inline Microsoft::Console::Render::RenderEngineBase::~RenderEngineBase() {}
|
||||
|
|
|
@ -261,6 +261,13 @@ CATCH_RETURN();
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
// RenderEngineBase defines a WaitUntilCanRender() that sleeps for 8ms to throttle rendering.
|
||||
// But UiaEngine is never the only the engine running. Overriding this function prevents
|
||||
// us from sleeping 16ms per frame, when the other engine also sleeps for 8ms.
|
||||
void UiaEngine::WaitUntilCanRender() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Used to perform longer running presentation steps outside the lock so the
|
||||
// other threads can continue.
|
||||
|
@ -453,18 +460,6 @@ CATCH_RETURN();
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Currently unused by this renderer.
|
||||
// Arguments:
|
||||
// - glyph - The glyph run to process for column width.
|
||||
// - pResult - True if it should take two columns. False if it should take one.
|
||||
// Return Value:
|
||||
// - S_OK or relevant DirectWrite error.
|
||||
[[nodiscard]] HRESULT UiaEngine::IsGlyphWideByFont(const std::wstring_view /*glyph*/, _Out_ bool* const /*pResult*/) noexcept
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Updates the window's title string.
|
||||
// - Currently unused by this renderer.
|
||||
|
|
|
@ -36,12 +36,10 @@ namespace Microsoft::Console::Render
|
|||
// IRenderEngine Members
|
||||
[[nodiscard]] HRESULT StartPaint() noexcept override;
|
||||
[[nodiscard]] HRESULT EndPaint() noexcept override;
|
||||
void WaitUntilCanRender() noexcept override;
|
||||
[[nodiscard]] HRESULT Present() noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT ScrollFrame() noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateSystem(const RECT* const prcDirtyClient) noexcept override;
|
||||
|
@ -49,30 +47,18 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateAll() noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateCircling(_Out_ bool* const pForcePaint) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PaintBackground() noexcept override;
|
||||
[[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> const clusters,
|
||||
COORD const coord,
|
||||
bool const fTrimLeft,
|
||||
const bool lineWrapped) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> const clusters, COORD const coord, bool const fTrimLeft, const bool lineWrapped) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet const lines, COLORREF const color, size_t const cchLine, COORD const coordTarget) noexcept override;
|
||||
[[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes,
|
||||
const gsl::not_null<IRenderData*> pData,
|
||||
const bool usingSoftFont,
|
||||
const bool isSettingDefaultBrushes) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const gsl::not_null<IRenderData*> pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, const int iDpi) noexcept override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
|
|
@ -23,20 +23,6 @@ using namespace Microsoft::Console::Types;
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Uses the currently selected font to determine how wide the given character will be when rendered.
|
||||
// - NOTE: Only supports determining half-width/full-width status for CJK-type languages (e.g. is it 1 character wide or 2. a.k.a. is it a rectangle or square.)
|
||||
// Arguments:
|
||||
// - glyph - utf16 encoded codepoint to check
|
||||
// - pResult - receives return value, True if it is full-width (2 wide). False if it is half-width (1 wide).
|
||||
// Return Value:
|
||||
// - S_FALSE: This is unsupported by the VT Renderer and should use another engine's value.
|
||||
[[nodiscard]] HRESULT VtEngine::IsGlyphWideByFont(const std::wstring_view /*glyph*/, _Out_ bool* const pResult) noexcept
|
||||
{
|
||||
*pResult = false;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Performs a "CombineRect" with the "OR" operation.
|
||||
// - Basically extends the existing rect outward to also encompass the passed-in region.
|
||||
|
|
|
@ -88,7 +88,6 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT SuppressResizeRepaint() noexcept;
|
||||
|
||||
|
|
|
@ -402,12 +402,6 @@ RECT WddmConEngine::GetDisplaySize()
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT WddmConEngine::IsGlyphWideByFont(const std::wstring_view /*glyph*/, _Out_ bool* const pResult) noexcept
|
||||
{
|
||||
*pResult = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Updates the window's title string.
|
||||
// Does nothing for WddmCon.
|
||||
|
|
|
@ -62,7 +62,6 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
|
|
|
@ -1325,7 +1325,8 @@ void StateMachine::_EventCsiParam(const wchar_t wch)
|
|||
// - wch - Character that triggered the event
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void StateMachine::_EventOscParam(const wchar_t wch) noexcept
|
||||
#pragma warning(suppress : 26440) // Function ... can be declared 'noexcept' (f.6).
|
||||
void StateMachine::_EventOscParam(const wchar_t wch)
|
||||
{
|
||||
_trace.TraceOnEvent(L"OscParam");
|
||||
if (_isOscTerminator(wch))
|
||||
|
@ -1577,7 +1578,8 @@ void StateMachine::_EventDcsEntry(const wchar_t wch)
|
|||
// - wch - Character that triggered the event
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void StateMachine::_EventDcsIgnore() noexcept
|
||||
#pragma warning(suppress : 26440) // Function ... can be declared 'noexcept' (f.6).
|
||||
void StateMachine::_EventDcsIgnore(const wchar_t /*wch*/)
|
||||
{
|
||||
_trace.TraceOnEvent(L"DcsIgnore");
|
||||
_ActionIgnore();
|
||||
|
@ -1697,7 +1699,8 @@ void StateMachine::_EventDcsPassThrough(const wchar_t wch)
|
|||
// - wch - Character that triggered the event
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void StateMachine::_EventSosPmApcString(const wchar_t /*wch*/) noexcept
|
||||
#pragma warning(suppress : 26440) // Function ... can be declared 'noexcept' (f.6).
|
||||
void StateMachine::_EventSosPmApcString(const wchar_t /*wch*/)
|
||||
{
|
||||
_trace.TraceOnEvent(L"SosPmApcString");
|
||||
_ActionIgnore();
|
||||
|
@ -1738,52 +1741,34 @@ void StateMachine::ProcessCharacter(const wchar_t wch)
|
|||
_ActionInterrupt();
|
||||
_EnterEscape();
|
||||
}
|
||||
else
|
||||
else if (_state < VTStates::TotalStates)
|
||||
{
|
||||
static constexpr alignas(64) void (StateMachine::*funcs[])(wchar_t) = {
|
||||
&StateMachine::_EventGround, // VTStates::Ground
|
||||
&StateMachine::_EventEscape, // VTStates::Escape
|
||||
&StateMachine::_EventEscapeIntermediate, // VTStates::EscapeIntermediate
|
||||
&StateMachine::_EventCsiEntry, // VTStates::CsiEntry
|
||||
&StateMachine::_EventCsiIntermediate, // VTStates::CsiIntermediate
|
||||
&StateMachine::_EventCsiIgnore, // VTStates::CsiIgnore
|
||||
&StateMachine::_EventCsiParam, // VTStates::CsiParam
|
||||
&StateMachine::_EventOscParam, // VTStates::OscParam
|
||||
&StateMachine::_EventOscString, // VTStates::OscString
|
||||
&StateMachine::_EventOscTermination, // VTStates::OscTermination
|
||||
&StateMachine::_EventSs3Entry, // VTStates::Ss3Entry
|
||||
&StateMachine::_EventSs3Param, // VTStates::Ss3Param
|
||||
&StateMachine::_EventVt52Param, // VTStates::Vt52Param
|
||||
&StateMachine::_EventDcsEntry, // VTStates::DcsEntry
|
||||
&StateMachine::_EventDcsIgnore, // VTStates::DcsIgnore
|
||||
&StateMachine::_EventDcsIntermediate, // VTStates::DcsIntermediate
|
||||
&StateMachine::_EventDcsParam, // VTStates::DcsParam
|
||||
&StateMachine::_EventDcsPassThrough, // VTStates::DcsPassThrough
|
||||
&StateMachine::_EventSosPmApcString, // VTStates::SosPmApcString
|
||||
};
|
||||
|
||||
// Then pass to the current state as an event
|
||||
switch (_state)
|
||||
{
|
||||
case VTStates::Ground:
|
||||
return _EventGround(wch);
|
||||
case VTStates::Escape:
|
||||
return _EventEscape(wch);
|
||||
case VTStates::EscapeIntermediate:
|
||||
return _EventEscapeIntermediate(wch);
|
||||
case VTStates::CsiEntry:
|
||||
return _EventCsiEntry(wch);
|
||||
case VTStates::CsiIntermediate:
|
||||
return _EventCsiIntermediate(wch);
|
||||
case VTStates::CsiIgnore:
|
||||
return _EventCsiIgnore(wch);
|
||||
case VTStates::CsiParam:
|
||||
return _EventCsiParam(wch);
|
||||
case VTStates::OscParam:
|
||||
return _EventOscParam(wch);
|
||||
case VTStates::OscString:
|
||||
return _EventOscString(wch);
|
||||
case VTStates::OscTermination:
|
||||
return _EventOscTermination(wch);
|
||||
case VTStates::Ss3Entry:
|
||||
return _EventSs3Entry(wch);
|
||||
case VTStates::Ss3Param:
|
||||
return _EventSs3Param(wch);
|
||||
case VTStates::Vt52Param:
|
||||
return _EventVt52Param(wch);
|
||||
case VTStates::DcsEntry:
|
||||
return _EventDcsEntry(wch);
|
||||
case VTStates::DcsIgnore:
|
||||
return _EventDcsIgnore();
|
||||
case VTStates::DcsIntermediate:
|
||||
return _EventDcsIntermediate(wch);
|
||||
case VTStates::DcsParam:
|
||||
return _EventDcsParam(wch);
|
||||
case VTStates::DcsPassThrough:
|
||||
return _EventDcsPassThrough(wch);
|
||||
case VTStates::SosPmApcString:
|
||||
return _EventSosPmApcString(wch);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
// Invalid _state values will jump to address 0, which is fine I guess.
|
||||
#pragma warning(suppress : 26482) // Only index into arrays using constant expressions (bounds.2).
|
||||
(this->*funcs[WI_EnumValue(_state)])(wch);
|
||||
}
|
||||
}
|
||||
// Method Description:
|
||||
|
|
|
@ -100,22 +100,22 @@ namespace Microsoft::Console::VirtualTerminal
|
|||
void _EventCsiIntermediate(const wchar_t wch);
|
||||
void _EventCsiIgnore(const wchar_t wch);
|
||||
void _EventCsiParam(const wchar_t wch);
|
||||
void _EventOscParam(const wchar_t wch) noexcept;
|
||||
void _EventOscParam(const wchar_t wch);
|
||||
void _EventOscString(const wchar_t wch);
|
||||
void _EventOscTermination(const wchar_t wch);
|
||||
void _EventSs3Entry(const wchar_t wch);
|
||||
void _EventSs3Param(const wchar_t wch);
|
||||
void _EventVt52Param(const wchar_t wch);
|
||||
void _EventDcsEntry(const wchar_t wch);
|
||||
void _EventDcsIgnore() noexcept;
|
||||
void _EventDcsIgnore(const wchar_t wch);
|
||||
void _EventDcsIntermediate(const wchar_t wch);
|
||||
void _EventDcsParam(const wchar_t wch);
|
||||
void _EventDcsPassThrough(const wchar_t wch);
|
||||
void _EventSosPmApcString(const wchar_t wch) noexcept;
|
||||
void _EventSosPmApcString(const wchar_t wch);
|
||||
|
||||
void _AccumulateTo(const wchar_t wch, size_t& value) noexcept;
|
||||
|
||||
enum class VTStates
|
||||
enum class VTStates : uint_fast8_t
|
||||
{
|
||||
Ground,
|
||||
Escape,
|
||||
|
@ -135,7 +135,8 @@ namespace Microsoft::Console::VirtualTerminal
|
|||
DcsIntermediate,
|
||||
DcsParam,
|
||||
DcsPassThrough,
|
||||
SosPmApcString
|
||||
SosPmApcString,
|
||||
TotalStates
|
||||
};
|
||||
|
||||
Microsoft::Console::VirtualTerminal::ParserTracing _trace;
|
||||
|
|
|
@ -9,12 +9,12 @@ namespace
|
|||
// used to store range data in CodepointWidthDetector's internal map
|
||||
struct UnicodeRange final
|
||||
{
|
||||
unsigned int lowerBound;
|
||||
unsigned int upperBound;
|
||||
uint32_t lowerBound;
|
||||
uint32_t upperBound;
|
||||
CodepointWidth width;
|
||||
};
|
||||
|
||||
static bool operator<(const UnicodeRange& range, const unsigned int searchTerm) noexcept
|
||||
static bool operator<(const UnicodeRange& range, const uint32_t searchTerm) noexcept
|
||||
{
|
||||
return range.upperBound < searchTerm;
|
||||
}
|
||||
|
@ -323,56 +323,46 @@ namespace
|
|||
};
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Constructs an instance of the CodepointWidthDetector class
|
||||
CodepointWidthDetector::CodepointWidthDetector() noexcept :
|
||||
_fallbackCache{},
|
||||
_pfnFallbackMethod{}
|
||||
{
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - returns the width type of codepoint as fast as we can by using quick lookup table and fallback cache.
|
||||
// Arguments:
|
||||
// - glyph - the utf16 encoded codepoint to search for
|
||||
// Return Value:
|
||||
// - the width type of the codepoint
|
||||
CodepointWidth CodepointWidthDetector::GetWidth(const std::wstring_view glyph) const
|
||||
CodepointWidth CodepointWidthDetector::GetWidth(const std::wstring_view& glyph) const noexcept
|
||||
try
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, glyph.empty());
|
||||
if (glyph.size() == 1)
|
||||
#pragma warning(suppress : 26494) // Variable 'codepoint' is uninitialized. Always initialize an object (type.5).
|
||||
uint32_t codepoint;
|
||||
switch (glyph.size())
|
||||
{
|
||||
// We first attempt to look at our custom quick lookup table of char width preferences.
|
||||
const auto width = GetQuickCharWidth(glyph.front());
|
||||
case 1:
|
||||
codepoint = til::at(glyph, 0);
|
||||
break;
|
||||
case 2:
|
||||
codepoint = (til::at(glyph, 0) & 0x3FF) << 10;
|
||||
codepoint |= til::at(glyph, 1) & 0x3FF;
|
||||
codepoint += 0x10000;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("invalid UTF16 scalar value pair");
|
||||
}
|
||||
|
||||
// If it's invalid, the quick width had no opinion, so go to the lookup table.
|
||||
if (width == CodepointWidth::Invalid)
|
||||
{
|
||||
return _lookupGlyphWidthWithCache(glyph);
|
||||
}
|
||||
// If it's ambiguous, the quick width wanted us to ask the font directly, try that if we can.
|
||||
// If not, go to the lookup table.
|
||||
else if (width == CodepointWidth::Ambiguous)
|
||||
{
|
||||
if (_pfnFallbackMethod)
|
||||
{
|
||||
return _checkFallbackViaCache(glyph) ? CodepointWidth::Wide : CodepointWidth::Ambiguous;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _lookupGlyphWidthWithCache(glyph);
|
||||
}
|
||||
}
|
||||
// Otherwise, return Width as it is.
|
||||
else
|
||||
{
|
||||
return width;
|
||||
}
|
||||
}
|
||||
else
|
||||
auto width = _lookupGlyphWidth(codepoint);
|
||||
|
||||
if (width == CodepointWidth::Ambiguous && _pfnFallbackMethod)
|
||||
{
|
||||
return _lookupGlyphWidthWithCache(glyph);
|
||||
width = _checkFallbackViaCache(codepoint, glyph) ? CodepointWidth::Wide : CodepointWidth::Ambiguous;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
// If we got this far, we couldn't figure it out.
|
||||
// It's better to be too wide than too narrow.
|
||||
return glyph.empty() ? CodepointWidth::Ambiguous : CodepointWidth::Wide;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -383,13 +373,7 @@ CodepointWidth CodepointWidthDetector::GetWidth(const std::wstring_view glyph) c
|
|||
// - true if wch is wide
|
||||
bool CodepointWidthDetector::IsWide(const wchar_t wch) const noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
return IsWide({ &wch, 1 });
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return true;
|
||||
return IsWide({ &wch, 1 });
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -398,7 +382,7 @@ bool CodepointWidthDetector::IsWide(const wchar_t wch) const noexcept
|
|||
// - glyph - the utf16 encoded codepoint to check width of
|
||||
// Return Value:
|
||||
// - true if codepoint is wide
|
||||
bool CodepointWidthDetector::IsWide(const std::wstring_view glyph) const
|
||||
bool CodepointWidthDetector::IsWide(const std::wstring_view& glyph) const noexcept
|
||||
{
|
||||
return GetWidth(glyph) == CodepointWidth::Wide;
|
||||
}
|
||||
|
@ -409,64 +393,24 @@ bool CodepointWidthDetector::IsWide(const std::wstring_view glyph) const
|
|||
// - glyph - the utf16 encoded codepoint to search for
|
||||
// Return Value:
|
||||
// - the width type of the codepoint
|
||||
CodepointWidth CodepointWidthDetector::_lookupGlyphWidth(const std::wstring_view glyph) const
|
||||
CodepointWidth CodepointWidthDetector::_lookupGlyphWidth(uint32_t codepoint) const
|
||||
{
|
||||
if (glyph.empty())
|
||||
// No need to check ASCII
|
||||
if (codepoint >= 0x80)
|
||||
{
|
||||
return CodepointWidth::Invalid;
|
||||
}
|
||||
const auto it = std::lower_bound(s_wideAndAmbiguousTable.begin(), s_wideAndAmbiguousTable.end(), codepoint);
|
||||
|
||||
const auto codepoint = _extractCodepoint(glyph);
|
||||
const auto it = std::lower_bound(s_wideAndAmbiguousTable.begin(), s_wideAndAmbiguousTable.end(), codepoint);
|
||||
|
||||
// For characters that are not _in_ the table, lower_bound will return the nearest item that is.
|
||||
// We must check its bounds to make sure that our hit was a true hit.
|
||||
if (it != s_wideAndAmbiguousTable.end() && codepoint >= it->lowerBound && codepoint <= it->upperBound)
|
||||
{
|
||||
return it->width;
|
||||
// For characters that are not _in_ the table, lower_bound will return the nearest item that is.
|
||||
// We must check its bounds to make sure that our hit was a true hit.
|
||||
if (it != s_wideAndAmbiguousTable.end() && codepoint >= it->lowerBound && codepoint <= it->upperBound)
|
||||
{
|
||||
return it->width;
|
||||
}
|
||||
}
|
||||
|
||||
return CodepointWidth::Narrow;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - returns the width type of codepoint using fallback methods.
|
||||
// Arguments:
|
||||
// - glyph - the utf16 encoded codepoint to check width of
|
||||
// Return Value:
|
||||
// - the width type of the codepoint
|
||||
CodepointWidth CodepointWidthDetector::_lookupGlyphWidthWithCache(const std::wstring_view glyph) const noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use our generated table to try to lookup the width based on the Unicode standard.
|
||||
const CodepointWidth width = _lookupGlyphWidth(glyph);
|
||||
|
||||
// If it's ambiguous, then ask the font if we can.
|
||||
if (width == CodepointWidth::Ambiguous)
|
||||
{
|
||||
if (_pfnFallbackMethod)
|
||||
{
|
||||
return _checkFallbackViaCache(glyph) ? CodepointWidth::Wide : CodepointWidth::Ambiguous;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CodepointWidth::Ambiguous;
|
||||
}
|
||||
}
|
||||
// If it's not ambiguous, it should say wide or narrow.
|
||||
else
|
||||
{
|
||||
return width;
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// If we got this far, we couldn't figure it out.
|
||||
// It's better to be too wide than too narrow.
|
||||
return CodepointWidth::Wide;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Checks the fallback function but caches the results until the font changes
|
||||
// because the lookup function is usually very expensive and will return the same results
|
||||
|
@ -474,47 +418,18 @@ CodepointWidth CodepointWidthDetector::_lookupGlyphWidthWithCache(const std::wst
|
|||
// Arguments:
|
||||
// - glyph - the utf16 encoded codepoint to check width of
|
||||
// - true if codepoint is wide or false if it is narrow
|
||||
bool CodepointWidthDetector::_checkFallbackViaCache(const std::wstring_view glyph) const
|
||||
bool CodepointWidthDetector::_checkFallbackViaCache(uint32_t codepoint, const std::wstring_view& glyph) const
|
||||
{
|
||||
const std::wstring findMe{ glyph };
|
||||
|
||||
// TODO: Cache needs to be emptied when font changes.
|
||||
const auto it = _fallbackCache.find(findMe);
|
||||
if (it == _fallbackCache.end())
|
||||
{
|
||||
auto result = _pfnFallbackMethod(glyph);
|
||||
_fallbackCache.insert_or_assign(findMe, result);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
const auto it = _fallbackCache.find(codepoint);
|
||||
if (it != _fallbackCache.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - extract unicode codepoint from utf16 encoding
|
||||
// Arguments:
|
||||
// - glyph - the utf16 encoded codepoint convert
|
||||
// Return Value:
|
||||
// - the codepoint being stored
|
||||
unsigned int CodepointWidthDetector::_extractCodepoint(const std::wstring_view glyph) noexcept
|
||||
{
|
||||
if (glyph.size() == 1)
|
||||
{
|
||||
return static_cast<unsigned int>(glyph.front());
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int mask = 0x3FF;
|
||||
// leading bits, shifted over to make space for trailing bits
|
||||
unsigned int codepoint = (glyph.at(0) & mask) << 10;
|
||||
// trailing bits
|
||||
codepoint |= (glyph.at(1) & mask);
|
||||
// 0x10000 is subtracted from the codepoint to encode a surrogate pair, add it back
|
||||
codepoint += 0x10000;
|
||||
return codepoint;
|
||||
}
|
||||
const auto result = _pfnFallbackMethod(glyph);
|
||||
_fallbackCache.insert_or_assign(codepoint, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -527,9 +442,9 @@ unsigned int CodepointWidthDetector::_extractCodepoint(const std::wstring_view g
|
|||
// - pfnFallback - the function to use as the fallback method.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CodepointWidthDetector::SetFallbackMethod(std::function<bool(const std::wstring_view)> pfnFallback)
|
||||
void CodepointWidthDetector::SetFallbackMethod(std::function<bool(const std::wstring_view&)> pfnFallback) noexcept
|
||||
{
|
||||
_pfnFallbackMethod = pfnFallback;
|
||||
_pfnFallbackMethod = std::move(pfnFallback);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -542,5 +457,6 @@ void CodepointWidthDetector::SetFallbackMethod(std::function<bool(const std::wst
|
|||
// - <none>
|
||||
void CodepointWidthDetector::NotifyFontChanged() const noexcept
|
||||
{
|
||||
#pragma warning(suppress : 26447) // The function is declared 'noexcept' but calls function 'clear()' which may throw exceptions (f.6).
|
||||
_fallbackCache.clear();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ static CodepointWidthDetector widthDetector;
|
|||
// Function Description:
|
||||
// - determines if the glyph represented by the string of characters should be
|
||||
// wide or not. See CodepointWidthDetector::IsWide
|
||||
bool IsGlyphFullWidth(const std::wstring_view glyph)
|
||||
bool IsGlyphFullWidth(const std::wstring_view& glyph) noexcept
|
||||
{
|
||||
return widthDetector.IsWide(glyph);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ bool IsGlyphFullWidth(const wchar_t wch) noexcept
|
|||
// - pfnFallback - the function to use as the fallback method.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void SetGlyphWidthFallback(std::function<bool(const std::wstring_view)> pfnFallback)
|
||||
void SetGlyphWidthFallback(std::function<bool(const std::wstring_view&)> pfnFallback)
|
||||
{
|
||||
widthDetector.SetFallbackMethod(pfnFallback);
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ void TermControlUiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) con
|
|||
screenPoint->y = includeOffsets(screenPoint->y, boundingRect.top, padding.top, scaleFactor);
|
||||
}
|
||||
|
||||
const COORD TermControlUiaTextRange::_getScreenFontSize() const
|
||||
const COORD TermControlUiaTextRange::_getScreenFontSize() const noexcept
|
||||
{
|
||||
// Do NOT get the font info from IRenderData. It is a dummy font info.
|
||||
// Instead, the font info is saved in the TermControl. So we have to
|
||||
|
|
|
@ -57,6 +57,6 @@ namespace Microsoft::Terminal
|
|||
protected:
|
||||
void _TranslatePointToScreen(LPPOINT clientPoint) const override;
|
||||
void _TranslatePointFromScreen(LPPOINT screenPoint) const override;
|
||||
const COORD _getScreenFontSize() const override;
|
||||
const COORD _getScreenFontSize() const noexcept override;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1313,7 +1313,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetChildren(_Outptr_result_maybenull_ SAFEARRAY
|
|||
|
||||
#pragma endregion
|
||||
|
||||
const COORD UiaTextRangeBase::_getScreenFontSize() const
|
||||
const COORD UiaTextRangeBase::_getScreenFontSize() const noexcept
|
||||
{
|
||||
COORD coordRet = _pData->GetFontInfo().GetSize();
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ namespace Microsoft::Console::Types
|
|||
|
||||
RECT _getTerminalRect() const;
|
||||
|
||||
virtual const COORD _getScreenFontSize() const;
|
||||
virtual const COORD _getScreenFontSize() const noexcept;
|
||||
|
||||
const unsigned int _getViewportHeight(const SMALL_RECT viewport) const noexcept;
|
||||
const Viewport _getOptimizedBufferSize() const noexcept;
|
||||
|
|
|
@ -16,24 +16,21 @@ Author:
|
|||
#include "convert.hpp"
|
||||
#include <functional>
|
||||
|
||||
static_assert(sizeof(unsigned int) == sizeof(wchar_t) * 2,
|
||||
"UnicodeRange expects to be able to store a unicode codepoint in an unsigned int");
|
||||
|
||||
// use to measure the width of a codepoint
|
||||
class CodepointWidthDetector final
|
||||
{
|
||||
public:
|
||||
CodepointWidthDetector() noexcept;
|
||||
CodepointWidthDetector() noexcept = default;
|
||||
|
||||
CodepointWidthDetector(const CodepointWidthDetector&) = delete;
|
||||
CodepointWidthDetector(CodepointWidthDetector&&) = delete;
|
||||
~CodepointWidthDetector() = default;
|
||||
CodepointWidthDetector& operator=(const CodepointWidthDetector&) = delete;
|
||||
CodepointWidthDetector& operator=(CodepointWidthDetector&&) = delete;
|
||||
|
||||
CodepointWidth GetWidth(const std::wstring_view glyph) const;
|
||||
bool IsWide(const std::wstring_view glyph) const;
|
||||
CodepointWidth GetWidth(const std::wstring_view& glyph) const noexcept;
|
||||
bool IsWide(const std::wstring_view& glyph) const noexcept;
|
||||
bool IsWide(const wchar_t wch) const noexcept;
|
||||
void SetFallbackMethod(std::function<bool(const std::wstring_view)> pfnFallback);
|
||||
void SetFallbackMethod(std::function<bool(const std::wstring_view&)> pfnFallback) noexcept;
|
||||
void NotifyFontChanged() const noexcept;
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
|
@ -41,11 +38,9 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
CodepointWidth _lookupGlyphWidth(const std::wstring_view glyph) const;
|
||||
CodepointWidth _lookupGlyphWidthWithCache(const std::wstring_view glyph) const noexcept;
|
||||
bool _checkFallbackViaCache(const std::wstring_view glyph) const;
|
||||
static unsigned int _extractCodepoint(const std::wstring_view glyph) noexcept;
|
||||
CodepointWidth _lookupGlyphWidth(uint32_t codepoint) const;
|
||||
bool _checkFallbackViaCache(uint32_t codepoint, const std::wstring_view& glyph) const;
|
||||
|
||||
mutable std::unordered_map<std::wstring, bool> _fallbackCache;
|
||||
std::function<bool(std::wstring_view)> _pfnFallbackMethod;
|
||||
mutable robin_hood::unordered_flat_map<uint32_t, bool> _fallbackCache;
|
||||
std::function<bool(const std::wstring_view&)> _pfnFallbackMethod;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ Abstract:
|
|||
#include <functional>
|
||||
#include <string_view>
|
||||
|
||||
bool IsGlyphFullWidth(const std::wstring_view glyph);
|
||||
bool IsGlyphFullWidth(const std::wstring_view& glyph) noexcept;
|
||||
bool IsGlyphFullWidth(const wchar_t wch) noexcept;
|
||||
void SetGlyphWidthFallback(std::function<bool(std::wstring_view)> pfnFallback);
|
||||
void SetGlyphWidthFallback(std::function<bool(const std::wstring_view&)> pfnFallback);
|
||||
void NotifyGlyphWidthFontChanged() noexcept;
|
||||
|
|
Loading…
Reference in a new issue