Compare commits

...

5 commits

Author SHA1 Message Date
Dustin L. Howett 343ff0913d Migrate spelling-0.0.19 changes from main 2020-03-30 09:39:17 -07:00
Michael Niksa 39d67e3859 Merge branch 'master' into dev/miniksa/dx_bitmap 2020-03-30 09:39:17 -07:00
Michael Niksa 78c1bc10f7 try to get present1 working and get mad because std::vector<bool> is bad. 2020-03-23 15:26:10 -07:00
Michael Niksa b46b5d0f6f it works! 2020-03-23 14:31:12 -07:00
Michael Niksa 7e8f0398c3 Start moving dx renderer onto bitmap. 2020-03-23 09:55:01 -07:00
38 changed files with 1171 additions and 480539 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
powf
sqrtf
isnan

View file

@ -1,7 +0,0 @@
mfcribbon
microsoft
microsoftonline
osgvsowi
powershell
tdbuildteamid
visualstudio

View file

@ -1,7 +0,0 @@
https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
(?:0[Xx]|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]?\b
\{[0-9A-FA-F]{8}-(?:[0-9A-FA-F]{4}-){3}[0-9A-FA-F]{12}\}
\d+x\d+Logo
Scro\&ll
# selectionInput.cpp
:\\windows\\syste\b

View file

@ -1,7 +0,0 @@
The contents of each `.txt` file in this directory are merged together.
* [alphabet](alphabet.txt) is a sample for alphabet related items
* [web](web.txt) is a sample for web/html related items
* [whitelist](whitelist.txt) is the main whitelist -- there is nothing
particularly special about the file name (beyond the extension which is
important).

View file

@ -1,3 +0,0 @@
http
td
www

50
.github/actions/spelling/advice.md vendored Normal file
View file

@ -0,0 +1,50 @@
<!-- markdownlint-disable MD033 MD041 -->
<details>
<summary>
:pencil2: Contributor please read this
</summary>
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
:warning: The command is written for posix shells. You can copy the contents of each `perl` command excluding the outer `'` marks and dropping any `'"`/`"'` quotation mark pairs into a file and then run `perl file.pl` from the root of the repository to run the code. Alternatively, you can manually insert the items...
If the listed items are:
* ... **misspelled**, then please *correct* them instead of using the command.
* ... *names*, please add them to `.github/actions/spelling/allow/names.txt`.
* ... APIs, you can add them to a file in `.github/actions/spelling/allow/`.
* ... just things you're using, please add them to an appropriate file in `.github/actions/spelling/expect/`.
* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spelling/patterns/`.
See the `README.md` in each directory for more information.
:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
<details><summary>:clamp: If you see a bunch of garbage</summary>
If it relates to a ...
<details><summary>well-formed pattern</summary>
See if there's a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it.
If not, try writing one and adding it to a `patterns/{file}.txt`.
Patterns are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
</details>
<details><summary>binary-ish string</summary>
Please add a file path to the `excludes.txt` file instead of just accepting the garbage.
File paths are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
../tree/HEAD/README.md) (on whichever branch you're using).
</details>
</details>
</details>

View file

@ -1,6 +1,6 @@
# Dictionaries are lists of words to accept unconditionally
# Allow files are lists of words to accept unconditionally
While check spelling will complain about a whitelisted word
While check spelling will complain about an expected word
which is no longer present, you can include things here even if
they are not otherwise present in the repository.
@ -8,13 +8,14 @@ E.g., you could include a list of system APIs here, or potential
contributors (so that if a future commit includes their name,
it'll be accepted).
### Files
## Files
| File | Description |
| ---- | ----------- |
| [Dictionary](dictionary.txt) | Primary US English dictionary |
| [Allow](allow.txt) | Supplements to the dictionary |
| [Chinese](chinese.txt) | Chinese words |
| [Japanese](japanese.txt) | Japanese words |
| [Microsoft](microsoft.txt) | Microsoft brand items |
| [Fonts](fonts.txt) | Font names |
| [Names](names.txt) | Names of people |
| [Colors](colors.txt) | Names of color |

View file

@ -0,0 +1,77 @@
apc
calt
ccmp
changelog
cybersecurity
Apc
clickable
clig
copyable
dalet
dcs
Dcs
dialytika
dje
downside
downsides
dze
dzhe
Enum'd
Fitt
formattings
ftp
fvar
geeksforgeeks
ghe
gje
hostname
hostnames
hyperlink
hyperlinking
hyperlinks
img
It'd
kje
liga
lje
locl
lorem
Llast
Lmid
Lorigin
maxed
mkmk
mru
noreply
nje
ogonek
ok'd
overlined
postmodern
ptys
qof
qps
rclt
reimplementation
reserialization
reserialize
reserializes
rlig
runtimes
shcha
slnt
Sos
timestamped
TLDR
tokenizes
tonos
tshe
uiatextrange
UIs
und
unregister
versioned
We'd
wildcards
yeru
zhe

194
.github/actions/spelling/allow/apis.txt vendored Normal file
View file

@ -0,0 +1,194 @@
ACCEPTFILES
ACCESSDENIED
alignas
alignof
APPLYTOSUBMENUS
bitfield
bitfields
BUILDBRANCH
BUILDMSG
BUILDNUMBER
BYPOSITION
charconv
CLASSNOTAVAILABLE
cmdletbinding
COLORPROPERTY
colspan
COMDLG
comparand
cstdint
CXICON
CYICON
dataobject
dcomp
DERR
dlldata
DONTADDTORECENT
DWORDLONG
enumset
environstrings
EXPCMDFLAGS
EXPCMDSTATE
filetime
FILTERSPEC
FORCEFILESYSTEM
FORCEMINIMIZE
frac
fullkbd
futex
GETDESKWALLPAPER
GETHIGHCONTRAST
Hashtable
HIGHCONTRASTON
HIGHCONTRASTW
hotkeys
href
hrgn
IActivation
IApp
IAppearance
IAsync
IBind
IBox
IClass
IComparable
IComparer
IConnection
ICustom
IDialog
IDirect
IExplorer
IFACEMETHOD
IFile
IInheritable
IMap
IObject
iosfwd
IPackage
IPeasant
isspace
ISetup
IStorage
istream
IStringable
ITab
ITaskbar
IUri
IVirtual
KEYSELECT
LCID
llabs
llu
localtime
lround
LSHIFT
MENUCOMMAND
MENUDATA
MENUINFO
memicmp
mptt
mov
msappx
MULTIPLEUSE
NCHITTEST
NCLBUTTONDBLCLK
NCRBUTTONDBLCLK
NIF
NIN
NOAGGREGATION
NOASYNC
NOCHANGEDIR
NOPROGRESS
NOREDIRECTIONBITMAP
NOREPEAT
NOTIFYBYPOS
NOTIFYICON
NOTIFYICONDATA
ntprivapi
oaidl
ocidl
ODR
offsetof
osver
OSVERSIONINFOEXW
otms
OUTLINETEXTMETRICW
overridable
PAGESCROLL
PICKFOLDERS
pmr
rcx
REGCLS
RETURNCMD
rfind
roundf
RSHIFT
schandle
semver
serializer
SETVERSION
SHELLEXECUTEINFOW
shobjidl
SHOWMINIMIZED
SHOWTIP
SINGLEUSE
SIZENS
smoothstep
snprintf
spsc
sregex
SRWLOC
SRWLOCK
STDCPP
STDMETHOD
strchr
strcpy
streambuf
strtoul
Stubless
Subheader
Subpage
syscall
TASKBARCREATED
TBPF
THEMECHANGED
tlg
tmp
tolower
toupper
TTask
TVal
UChar
UPDATEINIFILE
userenv
wcsstr
wcstoui
winmain
wmemcmp
wpc
wsregex
wwinmain
xchg
XDocument
XElement
xfacet
xhash
XIcon
xiosbase
xlocale
xlocbuf
xlocinfo
xlocmes
xlocmon
xlocnum
xloctime
XMax
xmemory
XParse
xpath
xstddef
xstring
xtree
xutility
YIcon
YMax

View file

@ -0,0 +1,117 @@
alice
aliceblue
antiquewhite
blanchedalmond
blueviolet
burlywood
cadetblue
cornflowerblue
cornsilk
cyan
darkblue
darkcyan
darkgoldenrod
darkgray
darkgreen
darkgrey
darkkhaki
darkmagenta
darkolivegreen
darkorange
darkorchid
darkred
darksalmon
darkseagreen
darkslateblue
darkslategray
darkslategrey
darkturquoise
darkviolet
deeppink
deepskyblue
dimgray
dimgrey
dodgerblue
firebrick
floralwhite
forestgreen
gainsboro
ghostwhite
greenyellow
hotpink
indian
indianred
lavenderblush
lawngreen
lemonchiffon
lightblue
lightcoral
lightcyan
lightgoldenrod
lightgoldenrodyellow
lightgray
lightgreen
lightgrey
lightpink
lightsalmon
lightseagreen
lightskyblue
lightslateblue
lightslategray
lightslategrey
lightsteelblue
lightyellow
limegreen
mediumaquamarine
mediumblue
mediumorchid
mediumpurple
mediumseagreen
mediumslateblue
mediumspringgreen
mediumturquoise
mediumvioletred
midnightblue
mintcream
mistyrose
navajo
navajowhite
navyblue
oldlace
olivedrab
orangered
palegoldenrod
palegreen
paleturquoise
palevioletred
papayawhip
peachpuff
peru
powderblue
rebecca
rebeccapurple
rosybrown
royalblue
saddlebrown
sandybrown
seagreen
sienna
skyblue
slateblue
slategray
slategrey
springgreen
steelblue
violetred
webgray
webgreen
webgrey
webmaroon
webpurple
whitesmoke
xaroon
xray
xreen
xrey
xurple
yellowgreen

View file

@ -1,8 +1,10 @@
Consolas
emoji
emojis
Extralight
Gabriola
Iosevka
MDL
Monofur
Segoe
wght

11
.github/actions/spelling/allow/math.txt vendored Normal file
View file

@ -0,0 +1,11 @@
atan
CPrime
HBar
HPrime
isnan
LPrime
LStep
powf
RSub
sqrtf
ULP

View file

@ -0,0 +1,78 @@
ACLs
ADMINS
advapi
altform
altforms
appendwttlogging
appx
appxbundle
appxerror
appxmanifest
ATL
backplating
bitmaps
BOMs
CPLs
cpptools
cppvsdbg
CPRs
cryptbase
DACL
DACLs
diffs
disposables
dotnetfeed
DTDs
DWINRT
enablewttlogging
Intelli
IVisual
LKG
LOCKFILE
Lxss
mfcribbon
microsoft
microsoftonline
MSAA
msixbundle
MSVC
muxc
netcore
osgvsowi
PFILETIME
pgc
pgo
pgosweep
powerrename
powershell
propkey
pscustomobject
QWORD
regedit
robocopy
SACLs
sdkddkver
Shobjidl
Skype
SRW
sxs
Sysinternals
sysnative
systemroot
taskkill
tasklist
tdbuildteamid
unvirtualized
VCRT
vcruntime
Virtualization
visualstudio
vscode
VSTHRD
winsdkver
wlk
wslpath
wtl
wtt
wttlog
Xamarin

View file

@ -3,53 +3,78 @@ austdi
Ballmer
bhoj
Bhojwani
carlos
dhowett
Diviness
dsafa
duhowett
ekg
ethanschoonover
Firefox
Gatta
glsl
Gravell
Grie
Griese
Hernan
Howett
Illhardt
iquilezles
jantari
jerrysh
Kaiyu
kimwalisch
KMehrain
KODELIFE
Kodelife
Kourosh
kowalczyk
leonmsft
Lepilleur
lhecker
lukesampson
Manandhar
mbadolato
Mehrain
menger
mgravell
michaelniksa
michkap
migrie
mikegr
mikemaccana
miloush
miniksa
niksa
nvaccess
nvda
oising
oldnewthing
opengl
osgwiki
pabhojwa
panos
paulcam
pauldotknopf
PGP
Pham
Rincewind
rprichard
Schoonover
shadertoy
Somuah
sonph
sonpham
stakx
thereses
Walisch
Wellons
Wirt
Wojciech
zadjii
Zamor
Zamora
zamora
Zoey
zorio
Zverovich

View file

@ -1,3 +1,4 @@
(?:(?i)\.png$)
(?:^|/)dirs$
(?:^|/)go\.mod$
(?:^|/)go\.sum$
@ -35,7 +36,6 @@ SUMS$
\.pbxproj$
\.pdf$
\.pem$
\.png$
\.psd$
\.runsettings$
\.sig$
@ -45,17 +45,35 @@ SUMS$
\.tar$
\.tgz$
\.ttf$
\.vsdx$
\.woff
\.xcf$
\.xls
\.xpm$
\.yml$
\.zip$
^consolegit2gitfilters\.json$
^dep/
^doc/reference/master-sequence-list.csv$
^doc/reference/UTF8-torture-test\.txt$
^oss/
^src/host/ft_uia/run\.bat$
^src/host/runft\.bat$
^src/host/runut\.bat$
^src/interactivity/onecore/BgfxEngine\.
^src/renderer/wddmcon/WddmConRenderer\.
^src/terminal/adapter/ut_adapter/run\.bat$
^src/terminal/parser/delfuzzpayload\.bat$
^src/terminal/parser/ft_fuzzer/run\.bat$
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
^src/terminal/parser/ut_parser/run\.bat$
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
^src/tools/lnkd/lnkd\.bat$
^src/tools/pixels/pixels\.bat$
^src/tools/texttests/fira\.txt$
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
^\.github/actions/spell-check/
^src/types/ut_types/UtilsTests.cpp$
^\.github/actions/spelling/
^\.gitignore$
^\XamlStyler.json$

View file

@ -0,0 +1,13 @@
The contents of each `.txt` file in this directory are merged together.
* [alphabet](alphabet.txt) is a sample for alphabet related items
* [web](web.txt) is a sample for web/html related items
* [expect](expect.txt) is the main list of expected items -- there is nothing
particularly special about the file name (beyond the extension which is
important).
These terms are things which temporarily exist in the project, but which
aren't necessarily words.
If something is a word that could come and go, it probably belongs in a
[dictionary](../dictionary/README.md).

View file

@ -1,3 +1,9 @@
AAAa
AAAAA
AAAAAAAAAAAAA
AAAAAABBBBBBCCC
AAAAABBBBBBCCC
abcd
abcd
abcde
abcdef
@ -5,12 +11,22 @@ ABCDEFG
ABCDEFGH
ABCDEFGHIJ
abcdefghijk
ABCDEFGHIJKLMNO
abcdefghijklmnop
ABCDEFGHIJKLMNOPQRST
abcdefghijklmnopqrstuvwxyz
QQQQQ
QQQQQQQQQ
QQQQQQQQQQ
ABCG
ABE
abf
BBBBB
BBBBBBBB
BBBBBBBBBBBBBBDDDD
BBBBBCCC
BBBBCCCCC
BBGGRR
CCE
EFG
EFGh
QQQQQQQQQQABCDEFGHIJ
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
@ -19,9 +35,7 @@ qrstuvwxyz
qwerty
QWERTYUIOP
qwertyuiopasdfg
TTTTTTTTTTTTTTTTTTTTTTTTTT
VVVVVVVVVVVVVVVV
yyyy
YYYYYYYDDDDDDDDDDD
ZAAZZ
ZABBZ
ZBAZZ

19
.github/actions/spelling/expect/web.txt vendored Normal file
View file

@ -0,0 +1,19 @@
http
www
easyrgb
php
ecma
rapidtables
WCAG
freedesktop
ycombinator
robertelder
kovidgoyal
leonerd
fixterms
winui
appshellintegration
mdtauk
cppreference
gfycat
Guake

View file

@ -0,0 +1,27 @@
https://(?:(?:[-a-zA-Z0-9?&=]*\.|)microsoft\.com)/[-a-zA-Z0-9?&=_#\/.]*
https://aka\.ms/[-a-zA-Z0-9?&=\/_]*
https://www\.itscj\.ipsj\.or\.jp/iso-ir/[-0-9]+\.pdf
https://www\.vt100\.net/docs/[-a-zA-Z0-9#_\/.]*
https://www.w3.org/[-a-zA-Z0-9?&=\/_#]*
https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
https://(?:[a-z-]+\.|)github(?:usercontent|)\.com/[-a-zA-Z0-9?%&=_\/.]*
https://www.xfree86.org/[-a-zA-Z0-9?&=\/_#]*
[Pp]ublicKeyToken="?[0-9a-fA-F]{16}"?
(?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]|</UniqueIdentifier)
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
microsoft/cascadia-code\@[0-9a-fA-F]{40}
\d+x\d+Logo
Scro\&ll
# selectionInput.cpp
:\\windows\\syste\b
TestUtils::VerifyExpectedString\(tb, L"[^"]+"
(?:hostSm|mach)\.ProcessString\(L"[^"]+"
\b([A-Za-z])\g{-1}{3,}\b
0x[0-9A-Za-z]+
Base64::s_(?:En|De)code\(L"[^"]+"
VERIFY_ARE_EQUAL\(L"[^"]+"
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+/"
std::memory_order_[\w]+
D2DERR_SHADER_COMPILE_FAILED
TIL_FEATURE_[0-9A-Z_]+
vcvars\w*

22
.github/actions/spelling/reject.txt vendored Normal file
View file

@ -0,0 +1,22 @@
^attache$
^attacher$
^attachers$
^spae$
^spaebook$
^spaecraft$
^spaed$
^spaedom$
^spaeing$
^spaeings$
^spae-man$
^spaeman$
^spaer$
^Spaerobee$
^spaes$
^spaewife$
^spaewoman$
^spaework$
^spaewright$
^wether$
^wethers$
^wetherteg$

View file

@ -1,20 +0,0 @@
name: Spell checking
on:
push:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '15 * * * *'
jobs:
build:
name: Spell checking
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.0.0
with:
fetch-depth: 5
- uses: check-spelling/check-spelling@0.0.12-alpha
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
bucket: .github/actions
project: spell-check

20
.github/workflows/spelling2.yml vendored Normal file
View file

@ -0,0 +1,20 @@
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
name: Spell checking
on:
pull_request_target:
push:
jobs:
spelling:
name: Spell checking
runs-on: ubuntu-latest
steps:
- name: checkout-merge
if: "contains(github.event_name, 'pull_request')"
uses: actions/checkout@v2
with:
ref: refs/pull/${{github.event.pull_request.number}}/merge
- name: checkout
if: "!contains(github.event_name, 'pull_request')"
uses: actions/checkout@v2
- uses: check-spelling/check-spelling@v0.0.19

View file

@ -701,6 +701,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
if (notifyScroll)
{
// TODO: don't do this, thanks migrie
_buffer->GetRenderTarget().TriggerRedrawAll();
_NotifyScrollEvent();
}

View file

@ -11,8 +11,8 @@
#include "til/some.h"
#include "til/size.h"
#include "til/point.h"
#include "til/rectangle.h"
#include "til/operators.h"
#include "til/rectangle.h"
#include "til/bitmap.h"
#include "til/u8u16convert.h"

View file

@ -285,7 +285,8 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
for (const auto pt : rc)
{
til::at(_bits, _rc.index_of(pt)) = true;
auto idx = _rc.index_of(pt);
til::at(_bits, idx) = true;
}
_dirty |= rc;

View file

@ -3,10 +3,6 @@
#pragma once
#include "rectangle.h"
#include "size.h"
#include "bitmap.h"
namespace til // Terminal Implementation Library. Also: "Today I Learned"
{
// Operators go here when they involve two headers that can't/don't include each other.

View file

@ -3,10 +3,6 @@
#pragma once
#include "point.h"
#include "size.h"
#include "some.h"
#ifdef UNIT_TESTING
class RectangleTests;
#endif
@ -636,6 +632,32 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
return *this;
}
// MUL will scale the entire rectangle up by the size factor
rectangle operator*(const size& size)
{
auto topLeft = _topLeft;
auto bottomRight = _bottomRight;
topLeft = topLeft * size;
bottomRight = bottomRight * size;
return til::rectangle{ topLeft, bottomRight };
}
// DIV will scale the entire rectangle down by the size factor,
// but rounds the bottom-right corner out.
rectangle operator/(const size& size)
{
auto topLeft = _topLeft;
auto bottomRight = _bottomRight;
topLeft = topLeft / size;
// Move bottom right point into a size
// Use size specialization of divide_ceil to round up against the size given.
// Add leading addition to point to convert it back into a point.
bottomRight = til::point{} + til::size{ right(), bottom() }.divide_ceil(size);
return til::rectangle{ topLeft, bottomRight };
}
#pragma endregion
constexpr ptrdiff_t top() const noexcept

View file

@ -65,9 +65,8 @@ using namespace Microsoft::Console::Types;
// TODO GH 2683: The default constructor should not throw.
DxEngine::DxEngine() :
RenderEngineBase(),
_isInvalidUsed{ false },
_invalidRect{ 0 },
_invalidScroll{ 0 },
_invalidMap{},
_invalidScroll{},
_presentParams{ 0 },
_presentReady{ false },
_presentScroll{ 0 },
@ -75,16 +74,16 @@ DxEngine::DxEngine() :
_presentOffset{ 0 },
_isEnabled{ false },
_isPainting{ false },
_displaySizePixels{ 0 },
_displaySizePixels{},
_foregroundColor{ 0 },
_backgroundColor{ 0 },
_selectionBackground{},
_glyphCell{ 0 },
_glyphCell{},
_haveDeviceResources{ false },
_retroTerminalEffects{ false },
_antialiasingMode{ D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE },
_hwndTarget{ static_cast<HWND>(INVALID_HANDLE_VALUE) },
_sizeTarget{ 0 },
_sizeTarget{},
_dpi{ USER_DEFAULT_SCREEN_DPI },
_scale{ 1.0f },
_chainMode{ SwapChainMode::ForComposition },
@ -238,8 +237,8 @@ HRESULT DxEngine::_SetupTerminalEffects()
// Setup the viewport.
D3D11_VIEWPORT vp;
vp.Width = static_cast<FLOAT>(_displaySizePixels.cx);
vp.Height = static_cast<FLOAT>(_displaySizePixels.cy);
vp.Width = _displaySizePixels.width<float>();
vp.Height = _displaySizePixels.height<float>();
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
@ -370,7 +369,7 @@ void DxEngine::_ComputePixelShaderSettings() noexcept
// You can find out how to install it here:
// https://docs.microsoft.com/en-us/windows/uwp/gaming/use-the-directx-runtime-and-visual-studio-graphics-diagnostic-features
// clang-format on
// D3D11_CREATE_DEVICE_DEBUG |
D3D11_CREATE_DEVICE_DEBUG |
D3D11_CREATE_DEVICE_SINGLETHREADED;
const std::array<D3D_FEATURE_LEVEL, 5> FeatureLevels{ D3D_FEATURE_LEVEL_11_1,
@ -424,8 +423,7 @@ void DxEngine::_ComputePixelShaderSettings() noexcept
{
switch (_chainMode)
{
case SwapChainMode::ForHwnd:
{
case SwapChainMode::ForHwnd: {
// use the HWND's dimensions for the swap chain dimensions.
RECT rect = { 0 };
RETURN_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &rect));
@ -454,11 +452,10 @@ void DxEngine::_ComputePixelShaderSettings() noexcept
break;
}
case SwapChainMode::ForComposition:
{
case SwapChainMode::ForComposition: {
// Use the given target size for compositions.
SwapChainDesc.Width = _displaySizePixels.cx;
SwapChainDesc.Height = _displaySizePixels.cy;
SwapChainDesc.Width = _displaySizePixels.width<UINT>();
SwapChainDesc.Height = _displaySizePixels.height<UINT>();
// We're doing advanced composition pretty much for the purpose of pretty alpha, so turn it on.
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
@ -633,8 +630,8 @@ void DxEngine::_ReleaseDeviceResources() noexcept
return _dwriteFactory->CreateTextLayout(string,
gsl::narrow<UINT32>(stringLength),
_dwriteTextFormat.Get(),
gsl::narrow<float>(_displaySizePixels.cx),
_glyphCell.cy != 0 ? _glyphCell.cy : gsl::narrow<float>(_displaySizePixels.cy),
_displaySizePixels.width<float>(),
_glyphCell.height() != 0 ? _glyphCell.height<float>() : _displaySizePixels.height<float>(),
ppTextLayout);
}
@ -655,9 +652,7 @@ void DxEngine::_ReleaseDeviceResources() noexcept
[[nodiscard]] HRESULT DxEngine::SetWindowSize(const SIZE Pixels) noexcept
{
_sizeTarget = Pixels;
RETURN_IF_FAILED(InvalidateAll());
_invalidMap.resize(_sizeTarget / _glyphCell, true);
return S_OK;
}
@ -691,7 +686,8 @@ Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
{
RETURN_HR_IF_NULL(E_INVALIDARG, psrRegion);
_InvalidOr(*psrRegion);
_invalidMap.set(Viewport::FromExclusive(*psrRegion).ToInclusive());
return S_OK;
}
@ -705,8 +701,9 @@ Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
{
RETURN_HR_IF_NULL(E_INVALIDARG, pcoordCursor);
const SMALL_RECT sr = Microsoft::Console::Types::Viewport::FromCoord(*pcoordCursor).ToInclusive();
return Invalidate(&sr);
_invalidMap.set(*pcoordCursor);
return S_OK;
}
// Routine Description:
@ -716,13 +713,17 @@ Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
// Return Value:
// - S_OK
[[nodiscard]] HRESULT DxEngine::InvalidateSystem(const RECT* const prcDirtyClient) noexcept
try
{
RETURN_HR_IF_NULL(E_INVALIDARG, prcDirtyClient);
_InvalidOr(*prcDirtyClient);
// Dirty client is in pixels. Use divide specialization against glyph factor to make conversion
// to cells.
_invalidMap.set(til::rectangle{ *prcDirtyClient } / _glyphCell);
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - Invalidates a series of character rectangles
@ -748,50 +749,24 @@ Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
// Return Value:
// - S_OK
[[nodiscard]] HRESULT DxEngine::InvalidateScroll(const COORD* const pcoordDelta) noexcept
try
{
if (pcoordDelta->X != 0 || pcoordDelta->Y != 0)
const til::point deltaCells{ *pcoordDelta };
if (deltaCells != til::point{ 0, 0 })
{
try
{
POINT delta = { 0 };
delta.x = pcoordDelta->X * _glyphCell.cx;
delta.y = pcoordDelta->Y * _glyphCell.cy;
const til::point deltaPixels = deltaCells * _glyphCell;
_InvalidOffset(delta);
// Shift the contents of the map and fill in revealed area.
_invalidMap.translate(deltaCells, true);
_invalidScroll.cx += delta.x;
_invalidScroll.cy += delta.y;
// Add the revealed portion of the screen from the scroll to the invalid area.
const RECT display = _GetDisplayRect();
RECT reveal = display;
// X delta first
OffsetRect(&reveal, delta.x, 0);
IntersectRect(&reveal, &reveal, &display);
SubtractRect(&reveal, &display, &reveal);
if (!IsRectEmpty(&reveal))
{
_InvalidOr(reveal);
}
// Y delta second (subtract rect won't work if you move both)
reveal = display;
OffsetRect(&reveal, 0, delta.y);
IntersectRect(&reveal, &reveal, &display);
SubtractRect(&reveal, &display, &reveal);
if (!IsRectEmpty(&reveal))
{
_InvalidOr(reveal);
}
}
CATCH_RETURN();
// TODO: should we just maintain it all in cells?
_invalidScroll += deltaPixels;
}
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - Invalidates the entire window area
@ -800,12 +775,12 @@ Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
// Return Value:
// - S_OK
[[nodiscard]] HRESULT DxEngine::InvalidateAll() noexcept
try
{
const RECT screen = _GetDisplayRect();
_InvalidOr(screen);
_invalidMap.set_all();
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - This currently has no effect in this renderer.
@ -827,23 +802,17 @@ Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
// - <none>
// Return Value:
// - X by Y area in pixels of the surface
[[nodiscard]] SIZE DxEngine::_GetClientSize() const noexcept
[[nodiscard]] til::size DxEngine::_GetClientSize() const noexcept
{
switch (_chainMode)
{
case SwapChainMode::ForHwnd:
{
case SwapChainMode::ForHwnd: {
RECT clientRect = { 0 };
LOG_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &clientRect));
SIZE clientSize = { 0 };
clientSize.cx = clientRect.right - clientRect.left;
clientSize.cy = clientRect.bottom - clientRect.top;
return clientSize;
return til::rectangle{ clientRect }.size();
}
case SwapChainMode::ForComposition:
{
case SwapChainMode::ForComposition: {
SIZE size = _sizeTarget;
size.cx = static_cast<LONG>(size.cx * _scale);
size.cy = static_cast<LONG>(size.cy * _scale);
@ -870,90 +839,6 @@ void _ScaleByFont(RECT& cellsToPixels, SIZE fontSize) noexcept
cellsToPixels.bottom *= fontSize.cy;
}
// Routine Description:
// - Retrieves a rectangle representation of the pixel size of the
// surface we are drawing on
// Arguments:
// - <none>
// Return Value;
// - Origin-placed rectangle representing the pixel size of the surface
[[nodiscard]] RECT DxEngine::_GetDisplayRect() const noexcept
{
return { 0, 0, _displaySizePixels.cx, _displaySizePixels.cy };
}
// Routine Description:
// - Helper to shift the existing dirty rectangle by a pixel offset
// and crop it to still be within the bounds of the display surface
// Arguments:
// - delta - Adjustment distance in pixels
// - -Y is up, Y is down, -X is left, X is right.
// Return Value:
// - <none>
void DxEngine::_InvalidOffset(POINT delta)
{
if (_isInvalidUsed)
{
// Copy the existing invalid rect
RECT invalidNew = _invalidRect;
// Offset it to the new position
THROW_IF_WIN32_BOOL_FALSE(OffsetRect(&invalidNew, delta.x, delta.y));
// Get the rect representing the display
const RECT rectScreen = _GetDisplayRect();
// Ensure that the new invalid rectangle is still on the display
IntersectRect(&invalidNew, &invalidNew, &rectScreen);
_invalidRect = invalidNew;
}
}
// Routine description:
// - Adds the given character rectangle to the total dirty region
// - Will scale internally to pixels based on the current font.
// Arguments:
// - sr - character rectangle
// Return Value:
// - <none>
void DxEngine::_InvalidOr(SMALL_RECT sr) noexcept
{
RECT region;
region.left = sr.Left;
region.top = sr.Top;
region.right = sr.Right;
region.bottom = sr.Bottom;
_ScaleByFont(region, _glyphCell);
region.right += _glyphCell.cx;
region.bottom += _glyphCell.cy;
_InvalidOr(region);
}
// Routine Description:
// - Adds the given pixel rectangle to the total dirty region
// Arguments:
// - rc - Dirty pixel rectangle
// Return Value:
// - <none>
void DxEngine::_InvalidOr(RECT rc) noexcept
{
if (_isInvalidUsed)
{
UnionRect(&_invalidRect, &_invalidRect, &rc);
const RECT rcScreen = _GetDisplayRect();
IntersectRect(&_invalidRect, &_invalidRect, &rcScreen);
}
else
{
_invalidRect = rc;
_isInvalidUsed = true;
}
}
// Routine Description:
// - This is unused by this renderer.
// Arguments:
@ -976,24 +861,19 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
// - Any DirectX error, a memory error, etc.
[[nodiscard]] HRESULT DxEngine::StartPaint() noexcept
{
FAIL_FAST_IF_FAILED(InvalidateAll());
RETURN_HR_IF(E_NOT_VALID_STATE, _isPainting); // invalid to start a paint while painting.
if (TraceLoggingProviderEnabled(g_hDxRenderProvider, WINEVENT_LEVEL_VERBOSE, 0))
{
const auto invalidatedStr = _invalidMap.to_string();
const auto invalidated = invalidatedStr.c_str();
#pragma warning(suppress : 26477 26485 26494 26482 26446 26447) // We don't control TraceLoggingWrite
TraceLoggingWrite(g_hDxRenderProvider,
"Invalid",
TraceLoggingInt32(_invalidRect.bottom - _invalidRect.top, "InvalidHeight"),
TraceLoggingInt32((_invalidRect.bottom - _invalidRect.top) / _glyphCell.cy, "InvalidHeightChars"),
TraceLoggingInt32(_invalidRect.right - _invalidRect.left, "InvalidWidth"),
TraceLoggingInt32((_invalidRect.right - _invalidRect.left) / _glyphCell.cx, "InvalidWidthChars"),
TraceLoggingInt32(_invalidRect.left, "InvalidX"),
TraceLoggingInt32(_invalidRect.left / _glyphCell.cx, "InvalidXChars"),
TraceLoggingInt32(_invalidRect.top, "InvalidY"),
TraceLoggingInt32(_invalidRect.top / _glyphCell.cy, "InvalidYChars"),
TraceLoggingInt32(_invalidScroll.cx, "ScrollWidth"),
TraceLoggingInt32(_invalidScroll.cx / _glyphCell.cx, "ScrollWidthChars"),
TraceLoggingInt32(_invalidScroll.cy, "ScrollHeight"),
TraceLoggingInt32(_invalidScroll.cy / _glyphCell.cy, "ScrollHeightChars"));
TraceLoggingWrite(g_hDxRenderProvider,
"Invalid",
TraceLoggingWideString(invalidated),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
}
if (_isEnabled)
{
@ -1004,8 +884,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
{
RETURN_IF_FAILED(_CreateDeviceResources(true));
}
else if (_displaySizePixels.cy != clientSize.cy ||
_displaySizePixels.cx != clientSize.cx)
else if (_displaySizePixels != clientSize)
{
// OK, we're going to play a dangerous game here for the sake of optimizing resize
// First, set up a complete clear of all device resources if something goes terribly wrong.
@ -1018,7 +897,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
_d2dRenderTarget.Reset();
// Change the buffer size and recreate the render target (and surface)
RETURN_IF_FAILED(_dxgiSwapChain->ResizeBuffers(2, clientSize.cx, clientSize.cy, DXGI_FORMAT_B8G8R8A8_UNORM, 0));
RETURN_IF_FAILED(_dxgiSwapChain->ResizeBuffers(2, clientSize.width<UINT>(), clientSize.height<UINT>(), DXGI_FORMAT_B8G8R8A8_UNORM, 0));
RETURN_IF_FAILED(_PrepareRenderTarget());
// OK we made it past the parts that can cause errors. We can release our failure handler.
@ -1044,6 +923,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
// Return Value:
// - Any DirectX error, a memory error, etc.
[[nodiscard]] HRESULT DxEngine::EndPaint() noexcept
try
{
RETURN_HR_IF(E_INVALIDARG, !_isPainting); // invalid to end paint when we're not painting
@ -1057,21 +937,33 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
if (SUCCEEDED(hr))
{
if (_invalidScroll.cy != 0 || _invalidScroll.cx != 0)
if (_invalidScroll != til::point{ 0, 0 })
{
_presentDirty = _invalidRect;
// Copy `til::rectangles` into RECT map.
_presentDirty.assign(_invalidMap.begin(), _invalidMap.end());
const RECT display = _GetDisplayRect();
SubtractRect(&_presentScroll, &display, &_presentDirty);
_presentOffset.x = _invalidScroll.cx;
_presentOffset.y = _invalidScroll.cy;
// The scroll rect is the entire screen minus the revealed areas.
// Get the entire screen into a rectangle.
til::rectangle scrollArea{ _displaySizePixels };
_presentParams.DirtyRectsCount = 1;
_presentParams.pDirtyRects = &_presentDirty;
// Reduce the size of the rectangle by the scroll.
scrollArea -= til::size{} - _invalidScroll;
// Assign the area to the present storage
_presentScroll = scrollArea;
// Pass the offset.
_presentOffset = _invalidScroll;
// Now fill up the parameters structure from the member variables.
_presentParams.DirtyRectsCount = gsl::narrow<UINT>(_presentDirty.size());
_presentParams.pDirtyRects = _presentDirty.data();
_presentParams.pScrollOffset = &_presentOffset;
_presentParams.pScrollRect = &_presentScroll;
// The scroll rect will be empty if we scrolled >= 1 full screen size.
// Present1 doesn't like that. So clear it out. Everything will be dirty anyway.
if (IsRectEmpty(&_presentScroll))
{
_presentParams.pScrollRect = nullptr;
@ -1088,13 +980,13 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
}
}
_invalidRect = { 0 };
_isInvalidUsed = false;
_invalidMap.reset_all();
_invalidScroll = { 0 };
_invalidScroll = {};
return hr;
}
CATCH_RETURN()
// Routine Description:
// - Copies the front surface of the swap chain (the one being displayed)
@ -1146,8 +1038,8 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
{
HRESULT hr = S_OK;
hr = _dxgiSwapChain->Present(1, 0);
/*hr = _dxgiSwapChain->Present1(1, 0, &_presentParams);*/
/*hr = _dxgiSwapChain->Present(1, 0);*/
hr = _dxgiSwapChain->Present1(1, 0, &_presentParams);
if (FAILED(hr))
{
@ -1166,7 +1058,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
RETURN_IF_FAILED(_CopyFrontToBack());
_presentReady = false;
_presentDirty = { 0 };
_presentDirty.clear();
_presentOffset = { 0 };
_presentScroll = { 0 };
_presentParams = { 0 };
@ -1196,21 +1088,19 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
// - S_OK
[[nodiscard]] HRESULT DxEngine::PaintBackground() noexcept
{
switch (_chainMode)
{
case SwapChainMode::ForHwnd:
_d2dRenderTarget->FillRectangle(D2D1::RectF(static_cast<float>(_invalidRect.left),
static_cast<float>(_invalidRect.top),
static_cast<float>(_invalidRect.right),
static_cast<float>(_invalidRect.bottom)),
_d2dBrushBackground.Get());
break;
case SwapChainMode::ForComposition:
D2D1_COLOR_F nothing = { 0 };
D2D1_COLOR_F nothing = { 0 };
// Runs are counts of cells.
// Use a transform by the size of one cell to convert cells-to-pixels
// as we clear.
_d2dRenderTarget->SetTransform(D2D1::Matrix3x2F::Scale(_glyphCell));
for (const auto rect : _invalidMap.runs())
{
_d2dRenderTarget->PushAxisAlignedClip(rect, D2D1_ANTIALIAS_MODE_ALIASED);
_d2dRenderTarget->Clear(nothing);
break;
_d2dRenderTarget->PopAxisAlignedClip();
}
_d2dRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
return S_OK;
}
@ -1231,9 +1121,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
try
{
// Calculate positioning of our origin.
D2D1_POINT_2F origin;
origin.x = static_cast<float>(coord.X * _glyphCell.cx);
origin.y = static_cast<float>(coord.Y * _glyphCell.cy);
D2D1_POINT_2F origin = til::point{ coord } * _glyphCell;
// Create the text layout
CustomTextLayout layout(_dwriteFactory.Get(),
@ -1241,7 +1129,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
_dwriteTextFormat.Get(),
_dwriteFontFace.Get(),
clusters,
_glyphCell.cx);
_glyphCell.width());
// Get the baseline for this font as that's where we draw from
DWRITE_LINE_SPACING spacing;
@ -1253,7 +1141,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
_d2dBrushBackground.Get(),
_dwriteFactory.Get(),
spacing,
D2D1::SizeF(gsl::narrow<FLOAT>(_glyphCell.cx), gsl::narrow<FLOAT>(_glyphCell.cy)),
_glyphCell,
D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
// Layout then render the text
@ -1284,10 +1172,8 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
_d2dBrushForeground->SetColor(_ColorFFromColorRef(color));
const auto font = _GetFontSize();
D2D_POINT_2F target;
target.x = static_cast<float>(coordTarget.X) * font.X;
target.y = static_cast<float>(coordTarget.Y) * font.Y;
const auto font = _glyphCell;
D2D_POINT_2F target = til::point{ coordTarget } * font;
D2D_POINT_2F start = { 0 };
D2D_POINT_2F end = { 0 };
@ -1300,7 +1186,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
if (lines & GridLines::Top)
{
end = start;
end.x += font.X;
end.x += font.width();
_d2dRenderTarget->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get());
}
@ -1308,7 +1194,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
if (lines & GridLines::Left)
{
end = start;
end.y += font.Y;
end.y += font.height();
_d2dRenderTarget->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get());
}
@ -1321,28 +1207,28 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
// The top right corner inclusive is at 7,0 which is X (0) + Font Height (8) - 1 = 7.
// 0.5 pixel offset for crisp lines; -0.5 on the Y to fit _in_ the cell, not outside it.
start = { target.x + 0.5f, target.y + font.Y - 0.5f };
start = { target.x + 0.5f, target.y + font.height() - 0.5f };
if (lines & GridLines::Bottom)
{
end = start;
end.x += font.X - 1.f;
end.x += font.width() - 1.f;
_d2dRenderTarget->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get());
}
start = { target.x + font.X - 0.5f, target.y + 0.5f };
start = { target.x + font.width() - 0.5f, target.y + 0.5f };
if (lines & GridLines::Right)
{
end = start;
end.y += font.Y - 1.f;
end.y += font.height() - 1.f;
_d2dRenderTarget->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get());
}
// Move to the next character in this run.
target.x += font.X;
target.x += font.width();
}
return S_OK;
@ -1361,17 +1247,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
_d2dBrushForeground->SetColor(_selectionBackground);
const auto resetColorOnExit = wil::scope_exit([&]() noexcept { _d2dBrushForeground->SetColor(existingColor); });
RECT pixels;
pixels.left = rect.Left * _glyphCell.cx;
pixels.top = rect.Top * _glyphCell.cy;
pixels.right = rect.Right * _glyphCell.cx;
pixels.bottom = rect.Bottom * _glyphCell.cy;
D2D1_RECT_F draw = { 0 };
draw.left = static_cast<float>(pixels.left);
draw.top = static_cast<float>(pixels.top);
draw.right = static_cast<float>(pixels.right);
draw.bottom = static_cast<float>(pixels.bottom);
const D2D1_RECT_F draw = til::rectangle{ rect } *_glyphCell;
_d2dRenderTarget->FillRectangle(draw, _d2dBrushForeground.Get());
@ -1399,52 +1275,42 @@ enum class CursorPaintType
{
return S_FALSE;
}
// Create rectangular block representing where the cursor can fill.
D2D1_RECT_F rect = { 0 };
rect.left = static_cast<float>(options.coordCursor.X * _glyphCell.cx);
rect.top = static_cast<float>(options.coordCursor.Y * _glyphCell.cy);
rect.right = static_cast<float>(rect.left + _glyphCell.cx);
rect.bottom = static_cast<float>(rect.top + _glyphCell.cy);
// Create rectangular block representing where the cursor can fill.s
D2D1_RECT_F rect = til::rectangle{ til::point{options.coordCursor} } *_glyphCell;
// If we're double-width, make it one extra glyph wider
if (options.fIsDoubleWidth)
{
rect.right += _glyphCell.cx;
rect.right += _glyphCell.width();
}
CursorPaintType paintType = CursorPaintType::Fill;
switch (options.cursorType)
{
case CursorType::Legacy:
{
case CursorType::Legacy: {
// Enforce min/max cursor height
ULONG ulHeight = std::clamp(options.ulCursorHeightPercent, s_ulMinCursorHeightPercent, s_ulMaxCursorHeightPercent);
ulHeight = gsl::narrow<ULONG>((_glyphCell.cy * ulHeight) / 100);
ulHeight = (_glyphCell.height<ULONG>() * ulHeight) / 100;
rect.top = rect.bottom - ulHeight;
break;
}
case CursorType::VerticalBar:
{
case CursorType::VerticalBar: {
// It can't be wider than one cell or we'll have problems in invalidation, so restrict here.
// It's either the left + the proposed width from the ease of access setting, or
// it's the right edge of the block cursor as a maximum.
rect.right = std::min(rect.right, rect.left + options.cursorPixelWidth);
break;
}
case CursorType::Underscore:
{
case CursorType::Underscore: {
rect.top = rect.bottom - 1;
break;
}
case CursorType::EmptyBox:
{
case CursorType::EmptyBox: {
paintType = CursorPaintType::Outline;
break;
}
case CursorType::FullBox:
{
case CursorType::FullBox: {
break;
}
default:
@ -1461,13 +1327,11 @@ enum class CursorPaintType
switch (paintType)
{
case CursorPaintType::Fill:
{
case CursorPaintType::Fill: {
_d2dRenderTarget->FillRectangle(rect, brush.Get());
break;
}
case CursorPaintType::Outline:
{
case CursorPaintType::Outline: {
// DrawRectangle in straddles physical pixels in an attempt to draw a line
// between them. To avoid this, bump the rectangle around by half the stroke width.
rect.top += 0.5f;
@ -1581,6 +1445,7 @@ CATCH_RETURN()
// Return Value:
// - S_OK or relevant DirectX error
[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo) noexcept
try
{
RETURN_IF_FAILED(_GetProposedFont(pfiFontInfoDesired,
fiFontInfo,
@ -1589,22 +1454,16 @@ CATCH_RETURN()
_dwriteTextAnalyzer,
_dwriteFontFace));
try
{
const auto size = fiFontInfo.GetSize();
_glyphCell.cx = size.X;
_glyphCell.cy = size.Y;
}
CATCH_RETURN();
_glyphCell = fiFontInfo.GetSize();
return S_OK;
}
CATCH_RETURN();
[[nodiscard]] Viewport DxEngine::GetViewportInCharacters(const Viewport& viewInPixels) noexcept
{
const short widthInChars = gsl::narrow_cast<short>(viewInPixels.Width() / _glyphCell.cx);
const short heightInChars = gsl::narrow_cast<short>(viewInPixels.Height() / _glyphCell.cy);
const short widthInChars = gsl::narrow_cast<short>(viewInPixels.Width() / _glyphCell.width());
const short heightInChars = gsl::narrow_cast<short>(viewInPixels.Height() / _glyphCell.height());
return Viewport::FromDimensions(viewInPixels.Origin(), { widthInChars, heightInChars });
}
@ -1693,29 +1552,7 @@ float DxEngine::GetScaling() const noexcept
// - Rectangle describing dirty area in characters.
[[nodiscard]] std::vector<til::rectangle> DxEngine::GetDirtyArea()
{
SMALL_RECT r;
r.Top = gsl::narrow<SHORT>(floor(_invalidRect.top / _glyphCell.cy));
r.Left = gsl::narrow<SHORT>(floor(_invalidRect.left / _glyphCell.cx));
r.Bottom = gsl::narrow<SHORT>(floor(_invalidRect.bottom / _glyphCell.cy));
r.Right = gsl::narrow<SHORT>(floor(_invalidRect.right / _glyphCell.cx));
// Exclusive to inclusive
r.Bottom--;
r.Right--;
return { r };
}
// Routine Description:
// - Gets COORD packed with shorts of each glyph (character) cell's
// height and width.
// Arguments:
// - <none>
// Return Value:
// - Nearest integer short x and y values for each cell.
[[nodiscard]] COORD DxEngine::_GetFontSize() const noexcept
{
return { gsl::narrow<SHORT>(_glyphCell.cx), gsl::narrow<SHORT>(_glyphCell.cy) };
return _invalidMap.runs();
}
// Routine Description:
@ -1725,10 +1562,12 @@ float DxEngine::GetScaling() const noexcept
// Return Value:
// - S_OK
[[nodiscard]] HRESULT DxEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
try
{
*pFontSize = _GetFontSize();
*pFontSize = _glyphCell;
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - Currently unused by this renderer.
@ -1738,30 +1577,28 @@ float DxEngine::GetScaling() const noexcept
// Return Value:
// - S_OK or relevant DirectWrite error.
[[nodiscard]] HRESULT DxEngine::IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept
try
{
RETURN_HR_IF_NULL(E_INVALIDARG, pResult);
try
{
const Cluster cluster(glyph, 0); // columns don't matter, we're doing analysis not layout.
const Cluster cluster(glyph, 0); // columns don't matter, we're doing analysis not layout.
// Create the text layout
CustomTextLayout layout(_dwriteFactory.Get(),
_dwriteTextAnalyzer.Get(),
_dwriteTextFormat.Get(),
_dwriteFontFace.Get(),
{ &cluster, 1 },
_glyphCell.cx);
// Create the text layout
CustomTextLayout layout(_dwriteFactory.Get(),
_dwriteTextAnalyzer.Get(),
_dwriteTextFormat.Get(),
_dwriteFontFace.Get(),
{ &cluster, 1 },
_glyphCell.width());
UINT32 columns = 0;
RETURN_IF_FAILED(layout.GetColumns(&columns));
UINT32 columns = 0;
RETURN_IF_FAILED(layout.GetColumns(&columns));
*pResult = columns != 1;
}
CATCH_RETURN();
*pResult = columns != 1;
return S_OK;
}
CATCH_RETURN();
// Method Description:
// - Updates the window's title string.
@ -2135,12 +1972,10 @@ float DxEngine::GetScaling() const noexcept
switch (_chainMode)
{
case SwapChainMode::ForHwnd:
{
case SwapChainMode::ForHwnd: {
return D2D1::ColorF(rgb);
}
case SwapChainMode::ForComposition:
{
case SwapChainMode::ForComposition: {
// Get the A value we've snuck into the highest byte
const BYTE a = ((color >> 24) & 0xFF);
const float aFloat = a / 255.0f;

View file

@ -121,7 +121,7 @@ namespace Microsoft::Console::Render
SwapChainMode _chainMode;
HWND _hwndTarget;
SIZE _sizeTarget;
til::size _sizeTarget;
int _dpi;
float _scale;
@ -130,8 +130,8 @@ namespace Microsoft::Console::Render
bool _isEnabled;
bool _isPainting;
SIZE _displaySizePixels;
SIZE _glyphCell;
til::size _displaySizePixels;
til::size _glyphCell;
D2D1_COLOR_F _defaultForegroundColor;
D2D1_COLOR_F _defaultBackgroundColor;
@ -140,19 +140,11 @@ namespace Microsoft::Console::Render
D2D1_COLOR_F _backgroundColor;
D2D1_COLOR_F _selectionBackground;
[[nodiscard]] RECT _GetDisplayRect() const noexcept;
bool _isInvalidUsed;
RECT _invalidRect;
SIZE _invalidScroll;
void _InvalidOr(SMALL_RECT sr) noexcept;
void _InvalidOr(RECT rc) noexcept;
void _InvalidOffset(POINT pt);
til::bitmap _invalidMap;
til::point _invalidScroll;
bool _presentReady;
RECT _presentDirty;
std::vector<RECT> _presentDirty;
RECT _presentScroll;
POINT _presentOffset;
DXGI_PRESENT_PARAMETERS _presentParams;
@ -244,9 +236,7 @@ namespace Microsoft::Console::Render
::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1>& textAnalyzer,
::Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFace) const noexcept;
[[nodiscard]] COORD _GetFontSize() const noexcept;
[[nodiscard]] SIZE _GetClientSize() const noexcept;
[[nodiscard]] til::size _GetClientSize() const noexcept;
[[nodiscard]] D2D1_COLOR_F _ColorFFromColorRef(const COLORREF color) noexcept;

View file

@ -4,9 +4,11 @@
#pragma once
// This includes support libraries from the CRT, STL, WIL, and GSL
#define BLOCK_TIL // We want to include it later, after DX.
#include "LibraryIncludes.h"
#include <windows.h>
#include <winmeta.h>
#include "..\host\conddkrefs.h"
#include <condrv.h>
@ -34,4 +36,7 @@
#include <dwrite_2.h>
#include <dwrite_3.h>
// Re-include TIL at the bottom to gain DX superpowers.
#include "til.h"
#pragma hdrstop