Repository: microsoft/terminal (language: cpp)

Issue:
Rectangle, Point, and Size need concerted structure
OK, as I'm refactoring, there's a few problems:
1. There's a lot of conversion on interface boundaries between `size_t`, `long`, and `SHORT` based versions of representations of rectangles, points, and sizes.
2. There's a bunch of places where we pass a line,column pair as two size_ts because there isn't a size_t version of `SIZE`. It should probably be passed as one sensible struct because the ordering of these parameters keeps getting reversed too.
3. Many of our conversions use an assorted mix of either C-cast, static_cast, gsl::narrow, gsl::narrow_cast, or intsafe.h.
4. We don't distinguish points from sizes in console code. They're both `COORD`. x is width and y is height for size usage.

We're also going to want to be able to expand most of our values to reach an "infinite" scrollback.

My proposal here would be:
- In the `types` library, we should create:
1. Point
- Contains `x` and `y` like Windows SDK 'POINT' but is `size_t`.
- Has conversions to Windows SDK `POINT` safely.
- Has conversions to Console's `COORD` safely.

2. Size
- Contains 'cx' and 'cy' like Windows SDK 'SIZE' but is `size_t`.
- Has conversions to Windows SDK `SIZE` safely.
- Has conversions to Console's `COORD` safely.

3. Rectangle
- Contains a `Point` and a `Size`. 
- Has conversions to Windows SDK `RECT` safely.
- Has conversions to Console's `SMALL_RECT` safely.

4. Viewport
- Update this guy to be happy with conversions in and out of the above 3.


Then walk through the code and update to use these things.



Discussion / hints:
Specific reference from UiaTextRange refactor (PR #4018):
https://github.com/microsoft/terminal/pull/4018/files#r372678719
`til::size` was implemented in #4850.
`til::point` was implemented in #4897.
`til::rectangle` was implemented in #4912.

To replace `Viewport`, we will still require...
- Translation of `til::rectangle` 
- Scaling of `til::rectangle`
- Iteration in "walk" directions
- Move helpers that will translate the contents of a buffer that is analogous to a `til::rectangle` representation and move it in-place using the "walk" directions for maximum efficiency. (For Scrolling data in storage or rendering buffers.)

This issue also stays open to track the replacements:
- Of `Viewport` usages with `til::rectangle` usages
- Of `RECT` and `SMALL_RECT` usages with `til::rectangle` except declarations on API boundaries
- Of `COORD` and `POINT` with `til::point` except declarations on API boundaries
- Of `COORD` and `SIZE` with `til::size` except declarations on API boundaries

Fix patch:
diff --git a/src/buffer/out/AttrRow.cpp b/src/buffer/out/AttrRow.cpp
index 16d338c0fba..25def986e1a 100644
--- a/src/buffer/out/AttrRow.cpp
+++ b/src/buffer/out/AttrRow.cpp
@@ -11,8 +11,8 @@
 // - attr - the default text attribute
 // Return Value:
 // - constructed object
-ATTR_ROW::ATTR_ROW(const uint16_t width, const TextAttribute attr) :
-    _data(width, attr) {}
+ATTR_ROW::ATTR_ROW(const til::CoordType width, const TextAttribute attr) :
+    _data(gsl::narrow_cast<uint16_t>(width), attr) {}
 
 // Routine Description:
 // - Sets all properties of the ATTR_ROW to default values
@@ -32,9 +32,9 @@ void ATTR_ROW::Reset(const TextAttribute attr)
 // - newWidth - The new width of the row.
 // Return Value:
 // - <none>, throws exceptions on failures.
-void ATTR_ROW::Resize(const uint16_t newWidth)
+void ATTR_ROW::Resize(const til::CoordType newWidth)
 {
-    _data.resize_trailing_extent(newWidth);
+    _data.resize_trailing_extent(gsl::narrow<uint16_t>(newWidth));
 }
 
 // Routine Description:
@@ -45,9 +45,9 @@ void ATTR_ROW::Resize(const uint16_t newWidth)
 // - the text attribute at column
 // Note:
 // - will throw on error
-TextAttribute ATTR_ROW::GetAttrByColumn(const uint16_t column) const
+TextAttribute ATTR_ROW::GetAttrByColumn(const til::CoordType column) const
 {
-    return _data.at(column);
+    return _data.at(gsl::narrow<uint16_t>(column));
 }
 
 // Routine Description:
@@ -74,7 +74,7 @@ std::vector<uint16_t> ATTR_ROW::GetHyperlinks() const
 // - attr - Attribute (color) to fill remaining characters with
 // Return Value:
 // - <none>
-bool ATTR_ROW::SetAttrToEnd(const uint16_t beginIndex, const TextAttribute attr)
+bool ATTR_ROW::SetAttrToEnd(const til::CoordType beginIndex, const TextAttribute attr)
 {
     _data.replace(gsl::narrow<uint16_t>(beginIndex), _data.size(), attr);
     return true;
@@ -103,9 +103,9 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
 // - newAttr: The attribute to merge into this row.
 // Return Value:
 // - <none>
-void ATTR_ROW::Replace(const uint16_t beginIndex, const uint16_t endIndex, const TextAttribute& newAttr)
+void ATTR_ROW::Replace(const til::CoordType beginIndex, const til::CoordType endIndex, const TextAttribute& newAttr)
 {
-    _data.replace(beginIndex, endIndex, newAttr);
+    _data.replace(gsl::narrow<uint16_t>(beginIndex), gsl::narrow<uint16_t>(endIndex), newAttr);
 }
 
 ATTR_ROW::const_iterator ATTR_ROW::begin() const noexcept
diff --git a/src/buffer/out/AttrRow.hpp b/src/buffer/out/AttrRow.hpp
index 49756f60805..5a6de23c4d6 100644
--- a/src/buffer/out/AttrRow.hpp
+++ b/src/buffer/out/AttrRow.hpp
@@ -30,7 +30,7 @@ class ATTR_ROW final
 public:
     using const_iterator = rle_vector::const_iterator;
 
-    ATTR_ROW(uint16_t width, TextAttribute attr);
+    ATTR_ROW(til::CoordType width, TextAttribute attr);
 
     ~ATTR_ROW() = default;
 
@@ -40,13 +40,13 @@ class ATTR_ROW final
     noexcept = default;
     ATTR_ROW& operator=(ATTR_ROW&&) noexcept = default;
 
-    TextAttribute GetAttrByColumn(uint16_t column) const;
+    TextAttribute GetAttrByColumn(til::CoordType column) const;
     std::vector<uint16_t> GetHyperlinks() const;
 
-    bool SetAttrToEnd(uint16_t beginIndex, TextAttribute attr);
+    bool SetAttrToEnd(til::CoordType beginIndex, TextAttribute attr);
     void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith);
-    void Resize(uint16_t newWidth);
-    void Replace(uint16_t beginIndex, uint16_t endIndex, const TextAttribute& newAttr);
+    void Resize(til::CoordType newWidth);
+    void Replace(til::CoordType beginIndex, til::CoordType endIndex, const TextAttribute& newAttr);
 
     const_iterator begin() const noexcept;
     const_iterator end() const noexcept;
diff --git a/src/buffer/out/CharRow.cpp b/src/buffer/out/CharRow.cpp
index 2466aa82c9c..704adacf218 100644
--- a/src/buffer/out/CharRow.cpp
+++ b/src/buffer/out/CharRow.cpp
@@ -17,7 +17,7 @@
 // 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 :
+CharRow::CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept :
     _data(rowWidth, value_type()),
     _pParent{ FAIL_FAST_IF_NULL(pParent) }
 {
@@ -30,9 +30,9 @@ CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
 // - <none>
 // Return Value:
 // - the size of the row
-size_t CharRow::size() const noexcept
+til::CoordType CharRow::size() const noexcept
 {
-    return _data.size();
+    return gsl::narrow_cast<til::CoordType>(_data.size());
 }
 
 // Routine Description:
@@ -55,7 +55,7 @@ void CharRow::Reset() noexcept
 // - 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
+[[nodiscard]] HRESULT CharRow::Resize(const til::CoordType newSize) noexcept
 {
     try
     {
@@ -93,14 +93,14 @@ typename CharRow::const_iterator CharRow::cend() const noexcept
 // - <none>
 // Return Value:
 // - The calculated left boundary of the internal string.
-size_t CharRow::MeasureLeft() const noexcept
+til::CoordType CharRow::MeasureLeft() const noexcept
 {
     auto it = _data.cbegin();
     while (it != _data.cend() && it->IsSpace())
     {
         ++it;
     }
-    return it - _data.cbegin();
+    return gsl::narrow_cast<til::CoordType>(it - _data.cbegin());
 }
 
 // Routine Description:
@@ -109,17 +109,17 @@ size_t CharRow::MeasureLeft() const noexcept
 // - <none>
 // Return Value:
 // - The calculated right boundary of the internal string.
-size_t CharRow::MeasureRight() const
+til::CoordType CharRow::MeasureRight() const
 {
     auto it = _data.crbegin();
     while (it != _data.crend() && it->IsSpace())
     {
         ++it;
     }
-    return _data.crend() - it;
+    return gsl::narrow_cast<til::CoordType>(_data.crend() - it);
 }
 
-void CharRow::ClearCell(const size_t column)
+void CharRow::ClearCell(const til::CoordType column)
 {
     _data.at(column).Reset();
 }
@@ -149,7 +149,7 @@ bool CharRow::ContainsText() const noexcept
 // Return Value:
 // - the attribute
 // Note: will throw exception if column is out of bounds
-const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
+const DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column) const
 {
     return _data.at(column).DbcsAttr();
 }
@@ -161,7 +161,7 @@ const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
 // Return Value:
 // - the attribute
 // Note: will throw exception if column is out of bounds
-DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
+DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column)
 {
     return _data.at(column).DbcsAttr();
 }
@@ -173,7 +173,7 @@ DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
 // Return Value:
 // - <none>
 // Note: will throw exception if column is out of bounds
-void CharRow::ClearGlyph(const size_t column)
+void CharRow::ClearGlyph(const til::CoordType column)
 {
     _data.at(column).EraseChars();
 }
@@ -185,9 +185,9 @@ void CharRow::ClearGlyph(const size_t column)
 // Return Value:
 // - text data at column
 // - Note: will throw exception if column is out of bounds
-const CharRow::reference CharRow::GlyphAt(const size_t column) const
+const CharRow::reference CharRow::GlyphAt(const til::CoordType column) const
 {
-    THROW_HR_IF(E_INVALIDARG, column >= _data.size());
+    THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
     return { const_cast<CharRow&>(*this), column };
 }
 
@@ -198,9 +198,9 @@ const CharRow::reference CharRow::GlyphAt(const size_t column) const
 // Return Value:
 // - text data at column
 // - Note: will throw exception if column is out of bounds
-CharRow::reference CharRow::GlyphAt(const size_t column)
+CharRow::reference CharRow::GlyphAt(const til::CoordType column)
 {
-    THROW_HR_IF(E_INVALIDARG, column >= _data.size());
+    THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
     return { *this, column };
 }
 
@@ -209,7 +209,7 @@ std::wstring CharRow::GetText() const
     std::wstring wstr;
     wstr.reserve(_data.size());
 
-    for (size_t i = 0; i < _data.size(); ++i)
+    for (til::CoordType i = 0; i < gsl::narrow_cast<til::CoordType>(_data.size()); ++i)
     {
         const auto glyph = GlyphAt(i);
         if (!DbcsAttrAt(i).IsTrailing())
@@ -231,9 +231,9 @@ std::wstring CharRow::GetText() const
 // - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
 // Return Value:
 // - the delimiter class for the given char
-const DelimiterClass CharRow::DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const
+const DelimiterClass CharRow::DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const
 {
-    THROW_HR_IF(E_INVALIDARG, column >= _data.size());
+    THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
 
     const auto glyph = *GlyphAt(column).begin();
     if (glyph <= UNICODE_SPACE)
@@ -265,10 +265,10 @@ const UnicodeStorage& CharRow::GetUnicodeStorage() const noexcept
 // Arguments:
 // - column - the column to generate the key for
 // Return Value:
-// - the COORD key for data access from UnicodeStorage for the column
-COORD CharRow::GetStorageKey(const size_t column) const noexcept
+// - the til::point key for data access from UnicodeStorage for the column
+til::point CharRow::GetStorageKey(const til::CoordType column) const noexcept
 {
-    return { gsl::narrow<SHORT>(column), _pParent->GetId() };
+    return { column, _pParent->GetId() };
 }
 
 // Routine Description:
diff --git a/src/buffer/out/CharRow.hpp b/src/buffer/out/CharRow.hpp
index 55d747e8735..7e18cb6fb3e 100644
--- a/src/buffer/out/CharRow.hpp
+++ b/src/buffer/out/CharRow.hpp
@@ -54,22 +54,22 @@ class CharRow final
     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(til::CoordType rowWidth, ROW* const pParent) noexcept;
 
-    size_t size() const noexcept;
-    [[nodiscard]] HRESULT Resize(const size_t newSize) noexcept;
-    size_t MeasureLeft() const noexcept;
-    size_t MeasureRight() const;
+    til::CoordType size() const noexcept;
+    [[nodiscard]] HRESULT Resize(const til::CoordType newSize) noexcept;
+    til::CoordType MeasureLeft() const noexcept;
+    til::CoordType MeasureRight() const;
     bool ContainsText() const noexcept;
-    const DbcsAttribute& DbcsAttrAt(const size_t column) const;
-    DbcsAttribute& DbcsAttrAt(const size_t column);
-    void ClearGlyph(const size_t column);
+    const DbcsAttribute& DbcsAttrAt(const til::CoordType column) const;
+    DbcsAttribute& DbcsAttrAt(const til::CoordType column);
+    void ClearGlyph(const til::CoordType column);
 
-    const DelimiterClass DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const;
+    const DelimiterClass DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const;
 
     // working with glyphs
-    const reference GlyphAt(const size_t column) const;
-    reference GlyphAt(const size_t column);
+    const reference GlyphAt(const til::CoordType column) const;
+    reference GlyphAt(const til::CoordType column);
 
     // iterators
     iterator begin() noexcept;
@@ -82,7 +82,7 @@ class CharRow final
 
     UnicodeStorage& GetUnicodeStorage() noexcept;
     const UnicodeStorage& GetUnicodeStorage() const noexcept;
-    COORD GetStorageKey(const size_t column) const noexcept;
+    til::point GetStorageKey(const til::CoordType column) const noexcept;
 
     void UpdateParent(ROW* const pParent);
 
@@ -91,7 +91,7 @@ class CharRow final
 
 private:
     void Reset() noexcept;
-    void ClearCell(const size_t column);
+    void ClearCell(const til::CoordType column);
     std::wstring GetText() const;
 
 protected:
diff --git a/src/buffer/out/CharRowCellReference.hpp b/src/buffer/out/CharRowCellReference.hpp
index 1d1d5966859..ecbae5809e5 100644
--- a/src/buffer/out/CharRowCellReference.hpp
+++ b/src/buffer/out/CharRowCellReference.hpp
@@ -25,7 +25,7 @@ class CharRowCellReference final
 public:
     using const_iterator = const wchar_t*;
 
-    CharRowCellReference(CharRow& parent, const size_t index) noexcept :
+    CharRowCellReference(CharRow& parent, const til::CoordType index) noexcept :
         _parent{ parent },
         _index{ index }
     {
@@ -51,7 +51,7 @@ class CharRowCellReference final
     // what char row the object belongs to
     CharRow& _parent;
     // the index of the cell in the parent char row
-    const size_t _index;
+    til::CoordType _index;
 
     CharRowCell& _cellData();
     const CharRowCell& _cellData() const;
diff --git a/src/buffer/out/LineRendition.hpp b/src/buffer/out/LineRendition.hpp
index 69643936705..db7a5489ca7 100644
--- a/src/buffer/out/LineRendition.hpp
+++ b/src/buffer/out/LineRendition.hpp
@@ -21,16 +21,16 @@ enum class LineRendition
     DoubleHeightBottom
 };
 
-constexpr SMALL_RECT ScreenToBufferLine(const SMALL_RECT& line, const LineRendition lineRendition)
+constexpr til::inclusive_rect ScreenToBufferLine(const til::inclusive_rect& line, const LineRendition lineRendition)
 {
     // Use shift right to quickly divide the Left and Right by 2 for double width lines.
-    const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
+    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
     return { line.Left >> scale, line.Top, line.Right >> scale, line.Bottom };
 }
 
-constexpr SMALL_RECT BufferToScreenLine(const SMALL_RECT& line, const LineRendition lineRendition)
+constexpr til::inclusive_rect BufferToScreenLine(const til::inclusive_rect& line, const LineRendition lineRendition)
 {
     // Use shift left to quickly multiply the Left and Right by 2 for double width lines.
-    const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
+    const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
     return { line.Left << scale, line.Top, (line.Right << scale) + scale, line.Bottom };
 }
diff --git a/src/buffer/out/OutputCellIterator.cpp b/src/buffer/out/OutputCellIterator.cpp
index ac2c37164f7..1b585cd28c5 100644
--- a/src/buffer/out/OutputCellIterator.cpp
+++ b/src/buffer/out/OutputCellIterator.cpp
@@ -531,16 +531,16 @@ OutputCellView OutputCellIterator::s_GenerateView(const OutputCell& cell)
 // - Gets the distance between two iterators relative to the input data given in.
 // Return Value:
 // - The number of items of the input run consumed between these two iterators.
-ptrdiff_t OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
+til::CoordType OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
 {
-    return _pos - other._pos;
+    return gsl::narrow_cast<til::CoordType>(_pos - other._pos);
 }
 
 // Routine Description:
 // - Gets the distance between two iterators relative to the number of cells inserted.
 // Return Value:
 // - The number of cells in the backing buffer filled between these two iterators.
-ptrdiff_t OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
+til::CoordType OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
 {
-    return _distance - other._distance;
+    return gsl::narrow_cast<til::CoordType>(_distance - other._distance);
 }
diff --git a/src/buffer/out/OutputCellIterator.hpp b/src/buffer/out/OutputCellIterator.hpp
index 6f05bb792cc..89447a51026 100644
--- a/src/buffer/out/OutputCellIterator.hpp
+++ b/src/buffer/out/OutputCellIterator.hpp
@@ -29,7 +29,7 @@ class OutputCellIterator final
 public:
     using iterator_category = std::input_iterator_tag;
     using value_type = OutputCellView;
-    using difference_type = ptrdiff_t;
+    using difference_type = til::CoordType;
     using pointer = OutputCellView*;
     using reference = OutputCellView&;
 
@@ -48,9 +48,9 @@ class OutputCellIterator final
 
     operator bool() const noexcept;
 
-    ptrdiff_t GetCellDistance(OutputCellIterator other) const noexcept;
-    ptrdiff_t GetInputDistance(OutputCellIterator other) const noexcept;
-    friend ptrdiff_t operator-(OutputCellIterator one, OutputCellIterator two) = delete;
+    til::CoordType GetCellDistance(OutputCellIterator other) const noexcept;
+    til::CoordType GetInputDistance(OutputCellIterator other) const noexcept;
+    friend til::CoordType operator-(OutputCellIterator one, OutputCellIterator two) = delete;
 
     OutputCellIterator& operator++();
     OutputCellIterator operator++(int);
diff --git a/src/buffer/out/OutputCellRect.cpp b/src/buffer/out/OutputCellRect.cpp
index 9dd0f74dfb9..6b789298d3a 100644
--- a/src/buffer/out/OutputCellRect.cpp
+++ b/src/buffer/out/OutputCellRect.cpp
@@ -21,14 +21,11 @@ OutputCellRect::OutputCellRect() noexcept :
 // Arguments:
 // - rows - Rows in the rectangle (height)
 // - cols - Columns in the rectangle (width)
-OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
+OutputCellRect::OutputCellRect(const til::CoordType rows, const til::CoordType cols) :
     _rows(rows),
     _cols(cols)
 {
-    size_t totalCells;
-    THROW_IF_FAILED(SizeTMult(rows, cols, &totalCells));
-
-    _storage.resize(totalCells);
+    _storage.resize(gsl::narrow<size_t>(rows * cols));
 }
 
 // Routine Description:
@@ -37,7 +34,7 @@ OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
 // - row - The Y position or row index in the buffer.
 // Return Value:
 // - Read/write span of OutputCells
-gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
+gsl::span<OutputCell> OutputCellRect::GetRow(const til::CoordType row)
 {
     return gsl::span<OutputCell>(_FindRowOffset(row), _cols);
 }
@@ -48,7 +45,7 @@ gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
 // - row - The Y position or row index in the buffer.
 // Return Value:
 // - Read-only iterator of OutputCells
-OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
+OutputCellIterator OutputCellRect::GetRowIter(const til::CoordType row) const
 {
     const gsl::span<const OutputCell> view(_FindRowOffset(row), _cols);
 
@@ -62,9 +59,9 @@ OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
 // - row - The Y position or row index in the buffer.
 // Return Value:
 // - Pointer to the location in the rectangle that represents the start of the requested row.
-OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
+OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row)
 {
-    return &_storage.at(row * _cols);
+    return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
 }
 
 // Routine Description:
@@ -74,16 +71,16 @@ OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
 // - row - The Y position or row index in the buffer.
 // Return Value:
 // - Pointer to the location in the rectangle that represents the start of the requested row.
-const OutputCell* OutputCellRect::_FindRowOffset(const size_t row) const
+const OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row) const
 {
-    return &_storage.at(row * _cols);
+    return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
 }
 
 // Routine Description:
 // - Gets the height of the rectangle
 // Return Value:
 // - Height
-size_t OutputCellRect::Height() const noexcept
+til::CoordType OutputCellRect::Height() const noexcept
 {
     return _rows;
 }
@@ -92,7 +89,7 @@ size_t OutputCellRect::Height() const noexcept
 // - Gets the width of the rectangle
 // Return Value:
 // - Width
-size_t OutputCellRect::Width() const noexcept
+til::CoordType OutputCellRect::Width() const noexcept
 {
     return _cols;
 }
diff --git a/src/buffer/out/OutputCellRect.hpp b/src/buffer/out/OutputCellRect.hpp
index ebdb4883e35..4e5d38cf813 100644
--- a/src/buffer/out/OutputCellRect.hpp
+++ b/src/buffer/out/OutputCellRect.hpp
@@ -30,20 +30,20 @@ class OutputCellRect final
 {
 public:
     OutputCellRect() noexcept;
-    OutputCellRect(const size_t rows, const size_t cols);
+    OutputCellRect(const til::CoordType rows, const til::CoordType cols);
 
-    gsl::span<OutputCell> GetRow(const size_t row);
-    OutputCellIterator GetRowIter(const size_t row) const;
+    gsl::span<OutputCell> GetRow(const til::CoordType row);
+    OutputCellIterator GetRowIter(const til::CoordType row) const;
 
-    size_t Height() const noexcept;
-    size_t Width() const noexcept;
+    til::CoordType Height() const noexcept;
+    til::CoordType Width() const noexcept;
 
 private:
     std::vector<OutputCell> _storage;
 
-    OutputCell* _FindRowOffset(const size_t row);
-    const OutputCell* _FindRowOffset(const size_t row) const;
+    OutputCell* _FindRowOffset(const til::CoordType row);
+    const OutputCell* _FindRowOffset(const til::CoordType row) const;
 
-    size_t _cols;
-    size_t _rows;
+    til::CoordType _cols;
+    til::CoordType _rows;
 };
diff --git a/src/buffer/out/OutputCellView.cpp b/src/buffer/out/OutputCellView.cpp
index cd1f16a7646..5b454fe396f 100644
--- a/src/buffer/out/OutputCellView.cpp
+++ b/src/buffer/out/OutputCellView.cpp
@@ -38,7 +38,7 @@ OutputCellView::OutputCellView(const std::wstring_view view,
 // - Reports how many columns we expect the Chars() text data to consume
 // Return Value:
 // - Count of column cells on the screen
-size_t OutputCellView::Columns() const noexcept
+til::CoordType OutputCellView::Columns() const noexcept
 {
     if (DbcsAttr().IsSingle())
     {
diff --git a/src/buffer/out/OutputCellView.hpp b/src/buffer/out/OutputCellView.hpp
index c2a7a6e3fe2..65d0ffac074 100644
--- a/src/buffer/out/OutputCellView.hpp
+++ b/src/buffer/out/OutputCellView.hpp
@@ -31,7 +31,7 @@ class OutputCellView
                    const TextAttributeBehavior behavior) noexcept;
 
     const std::wstring_view& Chars() const noexcept;
-    size_t Columns() const noexcept;
+    til::CoordType Columns() const noexcept;
     DbcsAttribute DbcsAttr() const noexcept;
     TextAttribute TextAttr() const noexcept;
     TextAttributeBehavior TextAttrBehavior() const noexcept;
diff --git a/src/buffer/out/Row.cpp b/src/buffer/out/Row.cpp
index db83900b8b1..362dffe9124 100644
--- a/src/buffer/out/Row.cpp
+++ b/src/buffer/out/Row.cpp
@@ -16,7 +16,7 @@
 // - 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 til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
     _id{ rowId },
     _rowWidth{ rowWidth },
     _charRow{ rowWidth, this },
@@ -58,7 +58,7 @@ bool ROW::Reset(const TextAttribute Attr)
 // - width - the new width, in cells
 // Return Value:
 // - S_OK if successful, otherwise relevant error
-[[nodiscard]] HRESULT ROW::Resize(const unsigned short width)
+[[nodiscard]] HRESULT ROW::Resize(const til::CoordType width)
 {
     RETURN_IF_FAILED(_charRow.Resize(width));
     try
@@ -78,7 +78,7 @@ bool ROW::Reset(const TextAttribute Attr)
 // - column - 0-indexed column index
 // Return Value:
 // - <none>
-void ROW::ClearColumn(const size_t column)
+void ROW::ClearColumn(const til::CoordType column)
 {
     THROW_HR_IF(E_INVALIDARG, column >= _charRow.size());
     _charRow.ClearCell(column);
@@ -103,7 +103,7 @@ const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
 // - limitRight - right inclusive column ID for the last write in this row. (optional, will just write to the end of row if nullopt)
 // Return Value:
 // - iterator to first cell that was not written to this row.
-OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap, std::optional<size_t> limitRight)
+OutputCellIterator ROW::WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap, std::optional<til::CoordType> limitRight)
 {
     THROW_HR_IF(E_INVALIDARG, index >= _charRow.size());
     THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= _charRow.size());
diff --git a/src/buffer/out/Row.hpp b/src/buffer/out/Row.hpp
index cee3b53bd88..5c2040078dd 100644
--- a/src/buffer/out/Row.hpp
+++ b/src/buffer/out/Row.hpp
@@ -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 til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
 
-    size_t size() const noexcept { return _rowWidth; }
+    til::CoordType size() const noexcept { return _rowWidth; }
 
     void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
     bool WasWrapForced() const noexcept { return _wrapForced; }
@@ -51,19 +51,19 @@ class ROW final
     LineRendition GetLineRendition() const noexcept { return _lineRendition; }
     void SetLineRendition(const LineRendition lineRendition) noexcept { _lineRendition = lineRendition; }
 
-    SHORT GetId() const noexcept { return _id; }
-    void SetId(const SHORT id) noexcept { _id = id; }
+    til::CoordType GetId() const noexcept { return _id; }
+    void SetId(const til::CoordType id) noexcept { _id = id; }
 
     bool Reset(const TextAttribute Attr);
-    [[nodiscard]] HRESULT Resize(const unsigned short width);
+    [[nodiscard]] HRESULT Resize(const til::CoordType width);
 
-    void ClearColumn(const size_t column);
+    void ClearColumn(const til::CoordType column);
     std::wstring GetText() const { return _charRow.GetText(); }
 
     UnicodeStorage& GetUnicodeStorage() noexcept;
     const UnicodeStorage& GetUnicodeStorage() const noexcept;
 
-    OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap = std::nullopt, std::optional<size_t> limitRight = std::nullopt);
+    OutputCellIterator WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap = std::nullopt, std::optional<til::CoordType> limitRight = std::nullopt);
 
 #ifdef UNIT_TESTING
     friend constexpr bool operator==(const ROW& a, const ROW& b) noexcept;
@@ -74,8 +74,8 @@ class ROW final
     CharRow _charRow;
     ATTR_ROW _attrRow;
     LineRendition _lineRendition;
-    SHORT _id;
-    unsigned short _rowWidth;
+    til::CoordType _id;
+    til::CoordType _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
diff --git a/src/buffer/out/UnicodeStorage.cpp b/src/buffer/out/UnicodeStorage.cpp
index 7de3c11025a..b7c63bfb41e 100644
--- a/src/buffer/out/UnicodeStorage.cpp
+++ b/src/buffer/out/UnicodeStorage.cpp
@@ -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<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width)
 {
     // Make a temporary map to hold all the new row positioning
     std::unordered_map<key_type, mapped_type> newMap;
@@ -87,7 +87,7 @@ void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const
         const auto newRowId = mapIter->second;
 
         // Generate a new coordinate with the same X as the old one, but a new Y value.
-        const auto newCoord = COORD{ oldCoord.X, newRowId };
+        const auto newCoord = til::point{ oldCoord.X, newRowId };
 
         // Put the adjusted coordinate into the map with the original value.
         newMap.emplace(newCoord, pair.second);
diff --git a/src/buffer/out/UnicodeStorage.hpp b/src/buffer/out/UnicodeStorage.hpp
index ac463f3ed5c..e7330131978 100644
--- a/src/buffer/out/UnicodeStorage.hpp
+++ b/src/buffer/out/UnicodeStorage.hpp
@@ -20,11 +20,11 @@ Author(s):
 #include <til/bit.h>
 #include <til/hash.h>
 
-// std::unordered_map needs help to know how to hash a COORD
+// std::unordered_map needs help to know how to hash a til::point
 namespace std
 {
     template<>
-    struct hash<COORD>
+    struct hash<til::point>
     {
         // Routine Description:
         // - hashes a coord. coord will be hashed by storing the x and y values consecutively in the lower
@@ -33,9 +33,9 @@ namespace std
         // - coord - the coord to hash
         // Return Value:
         // - the hashed coord
-        constexpr size_t operator()(const COORD& coord) const noexcept
+        constexpr size_t operator()(const til::point coord) const noexcept
         {
-            return til::hash(til::bit_cast<uint32_t>(coord));
+            return til::hash(til::bit_cast<uint64_t>(coord));
         }
     };
 }
@@ -43,7 +43,7 @@ namespace std
 class UnicodeStorage final
 {
 public:
-    using key_type = typename COORD;
+    using key_type = typename til::point;
     using mapped_type = typename std::vector<wchar_t>;
 
     UnicodeStorage() noexcept;
@@ -54,7 +54,7 @@ class UnicodeStorage final
 
     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<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width);
 
 private:
     std::unordered_map<key_type, mapped_type> _map;
diff --git a/src/buffer/out/cursor.cpp b/src/buffer/out/cursor.cpp
index b6d003a3b88..66f3050795c 100644
--- a/src/buffer/out/cursor.cpp
+++ b/src/buffer/out/cursor.cpp
@@ -13,7 +13,6 @@
 // - ulSize - The height of the cursor within this buffer
 Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
     _parentBuffer{ parentBuffer },
-    _cPosition{ 0 },
     _fHasMoved(false),
     _fIsVisible(true),
     _fIsOn(true),
@@ -23,7 +22,6 @@ Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
     _fIsConversionArea(false),
     _fIsPopupShown(false),
     _fDelayedEolWrap(false),
-    _coordDelayedAt{ 0 },
     _fDeferCursorRedraw(false),
     _fHaveDeferredCursorRedraw(false),
     _ulSize(ulSize),
@@ -35,7 +33,7 @@ Cursor::~Cursor()
 {
 }
 
-COORD Cursor::GetPosition() const noexcept
+til::point Cursor::GetPosition() const noexcept
 {
     return _cPosition;
 }
@@ -192,59 +190,58 @@ void Cursor::_RedrawCursorAlways() noexcept
     CATCH_LOG();
 }
 
-void Cursor::SetPosition(const COORD cPosition) noexcept
+void Cursor::SetPosition(const til::point cPosition) noexcept
 {
     _RedrawCursor();
-    _cPosition.X = cPosition.X;
-    _cPosition.Y = cPosition.Y;
+    _cPosition = cPosition;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
 
-void Cursor::SetXPosition(const int NewX) noexcept
+void Cursor::SetXPosition(const til::CoordType NewX) noexcept
 {
     _RedrawCursor();
-    _cPosition.X = gsl::narrow<SHORT>(NewX);
+    _cPosition.X = NewX;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
 
-void Cursor::SetYPosition(const int NewY) noexcept
+void Cursor::SetYPosition(const til::CoordType NewY) noexcept
 {
     _RedrawCursor();
-    _cPosition.Y = gsl::narrow<SHORT>(NewY);
+    _cPosition.Y = NewY;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
 
-void Cursor::IncrementXPosition(const int DeltaX) noexcept
+void Cursor::IncrementXPosition(const til::CoordType DeltaX) noexcept
 {
     _RedrawCursor();
-    _cPosition.X += gsl::narrow<SHORT>(DeltaX);
+    _cPosition.X += DeltaX;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
 
-void Cursor::IncrementYPosition(const int DeltaY) noexcept
+void Cursor::IncrementYPosition(const til::CoordType DeltaY) noexcept
 {
     _RedrawCursor();
-    _cPosition.Y += gsl::narrow<SHORT>(DeltaY);
+    _cPosition.Y += DeltaY;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
 
-void Cursor::DecrementXPosition(const int DeltaX) noexcept
+void Cursor::DecrementXPosition(const til::CoordType DeltaX) noexcept
 {
     _RedrawCursor();
-    _cPosition.X -= gsl::narrow<SHORT>(DeltaX);
+    _cPosition.X -= DeltaX;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
 
-void Cursor::DecrementYPosition(const int DeltaY) noexcept
+void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
 {
     _RedrawCursor();
-    _cPosition.Y -= gsl::narrow<SHORT>(DeltaY);
+    _cPosition.Y -= DeltaY;
     _RedrawCursor();
     ResetDelayEOLWrap();
 }
@@ -284,7 +281,7 @@ void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept
     _cursorType = OtherCursor._cursorType;
 }
 
-void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
+void Cursor::DelayEOLWrap(const til::point coordDelayedAt) noexcept
 {
     _coordDelayedAt = coordDelayedAt;
     _fDelayedEolWrap = true;
@@ -292,11 +289,11 @@ void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
 
 void Cursor::ResetDelayEOLWrap() noexcept
 {
-    _coordDelayedAt = { 0 };
+    _coordDelayedAt = {};
     _fDelayedEolWrap = false;
 }
 
-COORD Cursor::GetDelayedAtPosition() const noexcept
+til::point Cursor::GetDelayedAtPosition() const noexcept
 {
     return _coordDelayedAt;
 }
diff --git a/src/buffer/out/cursor.h b/src/buffer/out/cursor.h
index ec0caa01821..bbd908eb3e7 100644
--- a/src/buffer/out/cursor.h
+++ b/src/buffer/out/cursor.h
@@ -47,7 +47,7 @@ class Cursor final
     bool IsPopupShown() const noexcept;
     bool GetDelay() const noexcept;
     ULONG GetSize() const noexcept;
-    COORD GetPosition() const noexcept;
+    til::point GetPosition() const noexcept;
 
     const CursorType GetType() const noexcept;
 
@@ -66,19 +66,19 @@ class Cursor final
     void SetSize(const ULONG ulSize) noexcept;
     void SetStyle(const ULONG ulSize, const CursorType type) noexcept;
 
-    void SetPosition(const COORD cPosition) noexcept;
-    void SetXPosition(const int NewX) noexcept;
-    void SetYPosition(const int NewY) noexcept;
-    void IncrementXPosition(const int DeltaX) noexcept;
-    void IncrementYPosition(const int DeltaY) noexcept;
-    void DecrementXPosition(const int DeltaX) noexcept;
-    void DecrementYPosition(const int DeltaY) noexcept;
+    void SetPosition(const til::point cPosition) noexcept;
+    void SetXPosition(const til::CoordType NewX) noexcept;
+    void SetYPosition(const til::CoordType NewY) noexcept;
+    void IncrementXPosition(const til::CoordType DeltaX) noexcept;
+    void IncrementYPosition(const til::CoordType DeltaY) noexcept;
+    void DecrementXPosition(const til::CoordType DeltaX) noexcept;
+    void DecrementYPosition(const til::CoordType DeltaY) noexcept;
 
     void CopyProperties(const Cursor& OtherCursor) noexcept;
 
-    void DelayEOLWrap(const COORD coordDelayedAt) noexcept;
+    void DelayEOLWrap(const til::point coordDelayedAt) noexcept;
     void ResetDelayEOLWrap() noexcept;
-    COORD GetDelayedAtPosition() const noexcept;
+    til::point GetDelayedAtPosition() const noexcept;
     bool IsDelayedEOLWrap() const noexcept;
 
     void SetType(const CursorType type) noexcept;
@@ -90,7 +90,7 @@ class Cursor final
 
     // NOTE: If you are adding a property here, go add it to CopyProperties.
 
-    COORD _cPosition; // current position on screen (in screen buffer coords).
+    til::point _cPosition; // current position on screen (in screen buffer coords).
 
     bool _fHasMoved;
     bool _fIsVisible; // whether cursor is visible (set only through the API)
@@ -102,7 +102,7 @@ class Cursor final
     bool _fIsPopupShown; // if a popup is being shown, turn off, stop blinking.
 
     bool _fDelayedEolWrap; // don't wrap at EOL till the next char comes in.
-    COORD _coordDelayedAt; // coordinate the EOL wrap was delayed at.
+    til::point _coordDelayedAt; // coordinate the EOL wrap was delayed at.
 
     bool _fDeferCursorRedraw; // whether we should defer redrawing the cursor or not
     bool _fHaveDeferredCursorRedraw; // have we been asked to redraw the cursor while it was being deferred?
diff --git a/src/buffer/out/precomp.h b/src/buffer/out/precomp.h
index 9d4fc228da2..3ae7439f781 100644
--- a/src/buffer/out/precomp.h
+++ b/src/buffer/out/precomp.h
@@ -35,7 +35,6 @@ Module Name:
 #include <intsafe.h>
 
 // private dependencies
-#include "../inc/operators.hpp"
 #include "../inc/unicode.hpp"
 #pragma warning(pop)
 
diff --git a/src/buffer/out/search.cpp b/src/buffer/out/search.cpp
index a5b2b4d9e84..30731eec7cc 100644
--- a/src/buffer/out/search.cpp
+++ b/src/buffer/out/search.cpp
@@ -50,7 +50,7 @@ Search::Search(IUiaData& uiaData,
                const std::wstring& str,
                const Direction direction,
                const Sensitivity sensitivity,
-               const COORD anchor) :
+               const til::point anchor) :
     _direction(direction),
     _sensitivity(sensitivity),
     _needle(s_CreateNeedleFromString(str)),
@@ -124,7 +124,7 @@ void Search::Color(const TextAttribute attr) const
 // been called and returned true.
 // Return Value:
 // - pair containing [start, end] coord positions of text found by search
-std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
+std::pair<til::point, til::point> Search::GetFoundLocation() const noexcept
 {
     return { _coordSelStart, _coordSelEnd };
 }
@@ -140,7 +140,7 @@ std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
 // - direction - The intended direction of the search
 // Return Value:
 // - Coordinate to start the search from.
-COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
+til::point Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
 {
     const auto& textBuffer = uiaData.GetTextBuffer();
     const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
@@ -187,10 +187,10 @@ COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direct
 // - end - If we found it, this is filled with the coordinate of the last character of the needle.
 // Return Value:
 // - True if we found it. False if not.
-bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const
+bool Search::_FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const
 {
-    start = { 0 };
-    end = { 0 };
+    start = {};
+    end = {};
 
     auto bufferPos = pos;
 
@@ -269,7 +269,7 @@ wchar_t Search::_ApplySensitivity(const wchar_t wch) const noexcept
 // - Helper to increment a coordinate in respect to the associated screen buffer
 // Arguments
 // - coord - Updated by function to increment one position (will wrap X and Y direction)
-void Search::_IncrementCoord(COORD& coord) const noexcept
+void Search::_IncrementCoord(til::point& coord) const noexcept
 {
     _uiaData.GetTextBuffer().GetSize().IncrementInBoundsCircular(coord);
 }
@@ -278,7 +278,7 @@ void Search::_IncrementCoord(COORD& coord) const noexcept
 // - Helper to decrement a coordinate in respect to the associated screen buffer
 // Arguments
 // - coord - Updated by function to decrement one position (will wrap X and Y direction)
-void Search::_DecrementCoord(COORD& coord) const noexcept
+void Search::_DecrementCoord(til::point& coord) const noexcept
 {
     _uiaData.GetTextBuffer().GetSize().DecrementInBoundsCircular(coord);
 }
@@ -314,7 +314,7 @@ void Search::_UpdateNextPosition()
     {
         if (_direction == Direction::Forward)
         {
-            _coordNext = { 0 };
+            _coordNext = {};
         }
         else
         {
diff --git a/src/buffer/out/search.h b/src/buffer/out/search.h
index 38e5bb7885c..7f30245ec5b 100644
--- a/src/buffer/out/search.h
+++ b/src/buffer/out/search.h
@@ -49,33 +49,33 @@ class Search final
            const std::wstring& str,
            const Direction dir,
            const Sensitivity sensitivity,
-           const COORD anchor);
+           const til::point anchor);
 
     bool FindNext();
     void Select() const;
     void Color(const TextAttribute attr) const;
 
-    std::pair<COORD, COORD> GetFoundLocation() const noexcept;
+    std::pair<til::point, til::point> GetFoundLocation() const noexcept;
 
 private:
     wchar_t _ApplySensitivity(const wchar_t wch) const noexcept;
-    bool _FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const;
+    bool _FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const;
     bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept;
     void _UpdateNextPosition();
 
-    void _IncrementCoord(COORD& coord) const noexcept;
-    void _DecrementCoord(COORD& coord) const noexcept;
+    void _IncrementCoord(til::point& coord) const noexcept;
+    void _DecrementCoord(til::point& coord) const noexcept;
 
-    static COORD s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
+    static til::point s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
 
     static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);
 
     bool _reachedEnd = false;
-    COORD _coordNext = { 0 };
-    COORD _coordSelStart = { 0 };
-    COORD _coordSelEnd = { 0 };
+    til::point _coordNext;
+    til::point _coordSelStart;
+    til::point _coordSelEnd;
 
-    const COORD _coordAnchor;
+    const til::point _coordAnchor;
     const std::vector<std::vector<wchar_t>> _needle;
     const Direction _direction;
     const Sensitivity _sensitivity;
diff --git a/src/buffer/out/textBuffer.cpp b/src/buffer/out/textBuffer.cpp
index 7846e10138b..859bc5b231f 100644
--- a/src/buffer/out/textBuffer.cpp
+++ b/src/buffer/out/textBuffer.cpp
@@ -30,7 +30,7 @@ using PointTree = interval_tree::IntervalTree<til::point, size_t>;
 // Return Value:
 // - constructed object
 // Note: may throw exception
-TextBuffer::TextBuffer(const COORD screenBufferSize,
+TextBuffer::TextBuffer(const til::size screenBufferSize,
                        const TextAttribute defaultAttributes,
                        const UINT cursorSize,
                        const bool isActiveBuffer,
@@ -47,10 +47,10 @@ TextBuffer::TextBuffer(const COORD screenBufferSize,
     _currentPatternId{ 0 }
 {
     // initialize ROWs
-    _storage.reserve(static_cast<size_t>(screenBufferSize.Y));
-    for (size_t i = 0; i < static_cast<size_t>(screenBufferSize.Y); ++i)
+    _storage.reserve(gsl::narrow<size_t>(screenBufferSize.Y));
+    for (til::CoordType i = 0; i < screenBufferSize.Y; ++i)
     {
-        _storage.emplace_back(static_cast<SHORT>(i), screenBufferSize.X, _currentAttributes, this);
+        _storage.emplace_back(i, screenBufferSize.X, _currentAttributes, this);
     }
 
     _UpdateSize();
@@ -74,9 +74,9 @@ void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer) noexcept
 // - <none>
 // Return Value:
 // - Total number of rows in the buffer
-UINT TextBuffer::TotalRowCount() const noexcept
+til::CoordType TextBuffer::TotalRowCount() const noexcept
 {
-    return gsl::narrow<UINT>(_storage.size());
+    return gsl::narrow_cast<til::CoordType>(_storage.size());
 }
 
 // Routine Description:
@@ -86,13 +86,11 @@ UINT TextBuffer::TotalRowCount() const noexcept
 // - Number of rows down from the first row of the buffer.
 // Return Value:
 // - const reference to the requested row. Asserts if out of bounds.
-const ROW& TextBuffer::GetRowByOffset(const size_t index) const
+const ROW& TextBuffer::GetRowByOffset(const til::CoordType index) const noexcept
 {
-    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 auto offsetIndex = (_firstRow + index) % totalRows;
-    return _storage.at(offsetIndex);
+    const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
+    return til::at(_storage, offsetIndex);
 }
 
 // Routine Description:
@@ -102,13 +100,11 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
 // - Number of rows down from the first row of the buffer.
 // Return Value:
 // - reference to the requested row. Asserts if out of bounds.
-ROW& TextBuffer::GetRowByOffset(const size_t index)
+ROW& TextBuffer::GetRowByOffset(const til::CoordType index) noexcept
 {
-    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 auto offsetIndex = (_firstRow + index) % totalRows;
-    return _storage.at(offsetIndex);
+    const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
+    return til::at(_storage, offsetIndex);
 }
 
 // Routine Description:
@@ -117,7 +113,7 @@ ROW& TextBuffer::GetRowByOffset(const size_t index)
 // - at - X,Y position in buffer for iterator start position
 // Return Value:
 // - Read-only iterator of text data only.
-TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
+TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at) const
 {
     return TextBufferTextIterator(GetCellDataAt(at));
 }
@@ -128,7 +124,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
 // - at - X,Y position in buffer for iterator start position
 // Return Value:
 // - Read-only iterator of cell data.
-TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
+TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at) const
 {
     return TextBufferCellIterator(*this, at);
 }
@@ -140,7 +136,7 @@ TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
 // - at - X,Y position in buffer for iterator start position
 // Return Value:
 // - Read-only iterator of text data only.
-TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
+TextBufferTextIterator TextBuffer::GetTextLineDataAt(const til::point at) const
 {
     return TextBufferTextIterator(GetCellLineDataAt(at));
 }
@@ -152,9 +148,9 @@ TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
 // - at - X,Y position in buffer for iterator start position
 // Return Value:
 // - Read-only iterator of cell data.
-TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
+TextBufferCellIterator TextBuffer::GetCellLineDataAt(const til::point at) const
 {
-    SMALL_RECT limit;
+    til::inclusive_rect limit;
     limit.Top = at.Y;
     limit.Bottom = at.Y;
     limit.Left = 0;
@@ -171,7 +167,7 @@ TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
 // - limit - boundaries for the iterator to operate within
 // Return Value:
 // - Read-only iterator of text data only.
-TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport limit) const
+TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at, const Viewport limit) const
 {
     return TextBufferTextIterator(GetCellDataAt(at, limit));
 }
@@ -184,7 +180,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport
 // - limit - boundaries for the iterator to operate within
 // Return Value:
 // - Read-only iterator of cell data.
-TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at, const Viewport limit) const
+TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at, const Viewport limit) const
 {
     return TextBufferCellIterator(*this, at, limit);
 }
@@ -337,7 +333,7 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt)
 // Return Value:
 // - The final position of the iterator
 OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
-                                     const COORD target,
+                                     const til::point target,
                                      const std::optional<bool> wrap)
 {
     // Make mutable copy so we can walk.
@@ -374,9 +370,9 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
 // Return Value:
 // - The iterator, but advanced to where we stopped writing. Use to find input consumed length or cells written length.
 OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
-                                         const COORD target,
+                                         const til::point target,
                                          const std::optional<bool> wrap,
-                                         std::optional<size_t> limitRight)
+                                         std::optional<til::CoordType> limitRight)
 {
     // If we're not in bounds, exit early.
     if (!GetSize().IsInBounds(target))
@@ -390,7 +386,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
 
     // Take the cell distance written and notify that it needs to be repainted.
     const auto written = newIt.GetCellDistance(givenIt);
-    const auto paint = Viewport::FromDimensions(target, { gsl::narrow<SHORT>(written), 1 });
+    const auto paint = Viewport::FromDimensions(target, { written, 1 });
     TriggerRedraw(paint);
 
     return newIt;
@@ -467,7 +463,7 @@ bool TextBuffer::InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttr
 // - <none> - Always sets to wrap
 //Return Value:
 // - <none>
-void TextBuffer::_SetWrapOnCurrentRow()
+void TextBuffer::_SetWrapOnCurrentRow() noexcept
 {
     _AdjustWrapOnCurrentRow(true);
 }
@@ -479,10 +475,10 @@ void TextBuffer::_SetWrapOnCurrentRow()
 // - fSet - True if this row has a wrap. False otherwise.
 //Return Value:
 // - <none>
-void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet)
+void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet) noexcept
 {
     // The vertical position of the cursor represents the current row we're manipulating.
-    const UINT uiCurrentRowOffset = GetCursor().GetPosition().Y;
+    const auto uiCurrentRowOffset = GetCursor().GetPosition().Y;
 
     // Set the wrap status as appropriate
     GetRowByOffset(uiCurrentRowOffset).SetWrapForced(fSet);
@@ -501,7 +497,7 @@ bool TextBuffer::IncrementCursor()
     // Cursor position is stored as logical array indices (starts at 0) for the window
     // Buffer Size is specified as the "length" of the array. It would say 80 for valid values of 0-79.
     // So subtract 1 from buffer size in each direction to find the index of the final column in the buffer
-    const short iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
+    const auto iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
 
     // Move the cursor one position to the right
     GetCursor().IncrementXPosition(1);
@@ -604,17 +600,17 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
 // - The viewport
 //Return value:
 // - Coordinate position (relative to the text buffer)
-COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
+til::point TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
 {
     const auto viewport = viewOptional.has_value() ? viewOptional.value() : GetSize();
 
-    COORD coordEndOfText = { 0 };
+    til::point coordEndOfText;
     // Search the given viewport by starting at the bottom.
     coordEndOfText.Y = viewport.BottomInclusive();
 
     const auto& currRow = GetRowByOffset(coordEndOfText.Y);
     // The X position of the end of the valid text is the Right draw boundary (which is one beyond the final valid character)
-    coordEndOfText.X = gsl::narrow<short>(currRow.GetCharRow().MeasureRight()) - 1;
+    coordEndOfText.X = currRow.GetCharRow().MeasureRight() - 1;
 
     // If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
     const auto viewportTop = viewport.Top();
@@ -625,13 +621,13 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
         const auto& backupRow = GetRowByOffset(coordEndOfText.Y);
         // We need to back up to the previous row if this line is empty, AND there are more rows
 
-        coordEndOfText.X = gsl::narrow<short>(backupRow.GetCharRow().MeasureRight()) - 1;
+        coordEndOfText.X = backupRow.GetCharRow().MeasureRight() - 1;
         fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
     }
 
     // don't allow negative results
-    coordEndOfText.Y = std::max(coordEndOfText.Y, 0i16);
-    coordEndOfText.X = std::max(coordEndOfText.X, 0i16);
+    coordEndOfText.Y = std::max(coordEndOfText.Y, 0);
+    coordEndOfText.X = std::max(coordEndOfText.X, 0);
 
     return coordEndOfText;
 }
@@ -643,7 +639,7 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
 // Return Value:
 // - Coordinate position in screen coordinates of the character just before the cursor.
 // - NOTE: Will return 0,0 if already in the top left corner
-COORD TextBuffer::_GetPreviousFromCursor() const
+til::point TextBuffer::_GetPreviousFromCursor() const noexcept
 {
     auto coordPosition = GetCursor().GetPosition();
 
@@ -668,7 +664,7 @@ COORD TextBuffer::_GetPreviousFromCursor() const
     return coordPosition;
 }
 
-const SHORT TextBuffer::GetFirstRowIndex() const noexcept
+const til::CoordType TextBuffer::GetFirstRowIndex() const noexcept
 {
     return _firstRow;
 }
@@ -680,15 +676,15 @@ const Viewport TextBuffer::GetSize() const noexcept
 
 void TextBuffer::_UpdateSize()
 {
-    _size = Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
+    _size = Viewport::FromDimensions({ _storage.at(0).size(), gsl::narrow<til::CoordType>(_storage.size()) });
 }
 
-void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex) noexcept
+void TextBuffer::_SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept
 {
     _firstRow = FirstRowIndex;
 }
 
-void TextBuffer::ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta)
+void TextBuffer::ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta)
 {
     // If we don't have to move anything, leave early.
     if (delta == 0)
@@ -825,9 +821,9 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
             const auto fillChar = L' ';
             auto fillAttrs = GetCurrentAttributes();
             fillAttrs.SetStandardErase();
-            const size_t fillOffset = GetLineWidth(rowIndex);
-            const auto fillLength = GetSize().Width() - fillOffset;
-            const auto fillData = OutputCellIterator{ fillChar, fillAttrs, fillLength };
+            const auto fillOffset = GetLineWidth(rowIndex);
+            const auto fillLength = gsl::narrow<size_t>(GetSize().Width() - fillOffset);
+            const OutputCellIterator fillData{ fillChar, fillAttrs, fillLength };
             row.WriteCells(fillData, fillOffset, false);
             // We also need to make sure the cursor is clamped within the new width.
             GetCursor().SetPosition(ClampPositionWithinLine(cursorPosition));
@@ -836,7 +832,7 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
     }
 }
 
-void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t endRow)
+void TextBuffer::ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept
 {
     for (auto row = startRow; row < endRow; row++)
     {
@@ -844,40 +840,40 @@ void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t end
     }
 }
 
-LineRendition TextBuffer::GetLineRendition(const size_t row) const
+LineRendition TextBuffer::GetLineRendition(const til::CoordType row) const noexcept
 {
     return GetRowByOffset(row).GetLineRendition();
 }
 
-bool TextBuffer::IsDoubleWidthLine(const size_t row) const
+bool TextBuffer::IsDoubleWidthLine(const til::CoordType row) const noexcept
 {
     return GetLineRendition(row) != LineRendition::SingleWidth;
 }
 
-SHORT TextBuffer::GetLineWidth(const size_t row) const
+til::CoordType TextBuffer::GetLineWidth(const til::CoordType row) const noexcept
 {
     // Use shift right to quickly divide the width by 2 for double width lines.
-    const SHORT scale = IsDoubleWidthLine(row) ? 1 : 0;
+    const auto scale = IsDoubleWidthLine(row) ? 1 : 0;
     return GetSize().Width() >> scale;
 }
 
-COORD TextBuffer::ClampPositionWithinLine(const COORD position) const
+til::point TextBuffer::ClampPositionWithinLine(const til::point position) const noexcept
 {
-    const SHORT rightmostColumn = GetLineWidth(position.Y) - 1;
+    const auto rightmostColumn = GetLineWidth(position.Y) - 1;
     return { std::min(position.X, rightmostColumn), position.Y };
 }
 
-COORD TextBuffer::ScreenToBufferPosition(const COORD position) const
+til::point TextBuffer::ScreenToBufferPosition(const til::point position) const noexcept
 {
     // Use shift right to quickly divide the X pos by 2 for double width lines.
-    const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
+    const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
     return { position.X >> scale, position.Y };
 }
 
-COORD TextBuffer::BufferToScreenPosition(const COORD position) const
+til::point TextBuffer::BufferToScreenPosition(const til::point position) const noexcept
 {
     // Use shift left to quickly multiply the X pos by 2 for double width lines.
-    const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
+    const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
     return { position.X << scale, position.Y };
 }
 
@@ -900,7 +896,7 @@ void TextBuffer::Reset()
 // - newSize - new size of screen.
 // Return Value:
 // - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
-[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const COORD newSize) noexcept
+[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const til::size newSize) noexcept
 {
     RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
 
@@ -909,12 +905,12 @@ void TextBuffer::Reset()
         const auto currentSize = GetSize().Dimensions();
         const auto attributes = GetCurrentAttributes();
 
-        SHORT TopRow = 0; // new top row of the screen buffer
+        til::CoordType 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;
+        const auto TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
 
         // rotate rows until the top row is at index 0
         for (auto i = 0; i < TopRowIndex; i++)
@@ -934,7 +930,7 @@ void TextBuffer::Reset()
         // 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);
+            _storage.emplace_back(gsl::narrow_cast<til::CoordType>(_storage.size()), newSize.X, attributes, this);
         }
 
         // Now that we've tampered with the row placement, refresh all the row IDs.
@@ -983,7 +979,7 @@ void TextBuffer::TriggerRedraw(const Viewport& viewport)
     }
 }
 
-void TextBuffer::TriggerRedrawCursor(const COORD position)
+void TextBuffer::TriggerRedrawCursor(const til::point position)
 {
     if (_isActiveBuffer)
     {
@@ -1007,7 +1003,7 @@ void TextBuffer::TriggerScroll()
     }
 }
 
-void TextBuffer::TriggerScroll(const COORD delta)
+void TextBuffer::TriggerScroll(const til::point delta)
 {
     if (_isActiveBuffer)
     {
@@ -1032,10 +1028,10 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
 //   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(std::optional<til::CoordType> newRowWidth)
 {
-    std::unordered_map<SHORT, SHORT> rowMap;
-    SHORT i = 0;
+    std::unordered_map<til::CoordType, til::CoordType> rowMap;
+    til::CoordType i = 0;
     for (auto& it : _storage)
     {
         // Build a map so we can update Unicode Storage
@@ -1065,7 +1061,7 @@ void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
 // - <none>
 // Return Value:
 //  - reference to the first row.
-ROW& TextBuffer::_GetFirstRow()
+ROW& TextBuffer::_GetFirstRow() noexcept
 {
     return GetRowByOffset(0);
 }
@@ -1099,23 +1095,23 @@ ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
 // - 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
+DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const
 {
     return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
 }
 
 // Method Description:
-// - Get the COORD for the beginning of the word you are on
+// - Get the til::point for the beginning of the word you are on
 // Arguments:
-// - target - a COORD on the word you are currently on
+// - target - a til::point on the word you are currently on
 // - wordDelimiters - what characters are we considering for the separation of words
 // - accessibilityMode - when enabled, we continue expanding left until we are at the beginning of a readable word.
 //                        Otherwise, expand left until a character of a new delimiter class is found
 //                        (or a row boundary is encountered)
 // - 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
+// - The til::point for the first character on the "word" (inclusive)
+til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
 {
     // Consider a buffer with this text in it:
     // "  word   other  "
@@ -1130,7 +1126,7 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
 #pragma warning(suppress : 26496)
     auto copy{ target };
     const auto bufferSize{ GetSize() };
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
     if (target == bufferSize.Origin())
     {
         // can't expand left
@@ -1140,12 +1136,12 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
     {
         // GH#7664: Treat EndExclusive as EndInclusive so
         // that it actually points to a space in the buffer
-        copy = { bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
+        copy = bufferSize.BottomRightInclusive();
     }
-    else if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
+    else if (bufferSize.CompareInBounds(target, limit, true) >= 0)
     {
         // if at/past the limit --> clamp to limit
-        copy = limitOptional->to_win32_coord();
+        copy = limitOptional.value_or(bufferSize.BottomRightInclusive());
     }
 
     if (accessibilityMode)
@@ -1159,13 +1155,13 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
 }
 
 // Method Description:
-// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (accessibility definition) you are on
+// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (accessibility definition) you are on
 // Arguments:
-// - target - a COORD on the word you are currently on
+// - target - a til::point on the word you are currently on
 // - 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
+// - The til::point for the first character on the current/previous READABLE "word" (inclusive)
+til::point TextBuffer::_GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const
 {
     auto result = target;
     const auto bufferSize = GetSize();
@@ -1204,13 +1200,13 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
 }
 
 // Method Description:
-// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (selection definition) you are on
+// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (selection definition) you are on
 // Arguments:
-// - target - a COORD on the word you are currently on
+// - target - a til::point on the word you are currently on
 // - 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
+// - The til::point for the first character on the current word or delimiter run (stopped by the left margin)
+til::point TextBuffer::_GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const
 {
     auto result = target;
     const auto bufferSize = GetSize();
@@ -1233,17 +1229,17 @@ const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std:
 }
 
 // Method Description:
-// - Get the COORD for the beginning of the NEXT word
+// - Get the til::point for the beginning of the NEXT word
 // Arguments:
-// - target - a COORD on the word you are currently on
+// - target - a til::point on the word you are currently on
 // - wordDelimiters - what characters are we considering for the separation of words
 // - accessibilityMode - when enabled, we continue expanding right until we are at the beginning of the next READABLE word
 //                        Otherwise, expand right until a character of a new delimiter class is found
 //                        (or a row boundary is encountered)
 // - 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
+// - The til::point for the last character on the "word" (inclusive)
+til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
 {
     // Consider a buffer with this text in it:
     // "  word   other  "
@@ -1257,15 +1253,15 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
 
     // Already at/past the limit. Can't move forward.
     const auto bufferSize{ GetSize() };
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
-    if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
+    if (bufferSize.CompareInBounds(target, limit, true) >= 0)
     {
         return target;
     }
 
     if (accessibilityMode)
     {
-        return _GetWordEndForAccessibility(target, wordDelimiters, limit.to_win32_coord());
+        return _GetWordEndForAccessibility(target, wordDelimiters, limit);
     }
     else
     {
@@ -1274,14 +1270,14 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
 }
 
 // Method Description:
-// - Helper method for GetWordEnd(). Get the COORD for the beginning of the next READABLE word
+// - Helper method for GetWordEnd(). Get the til::point for the beginning of the next READABLE word
 // Arguments:
-// - target - a COORD on the word you are currently on
+// - target - a til::point on the word you are currently on
 // - wordDelimiters - what characters are we considering for the separation of words
 // - 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
+// - The til::point for the first character of the next readable "word". If no next word, return one past the end of the buffer
+til::point TextBuffer::_GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const
 {
     const auto bufferSize{ GetSize() };
     auto result{ target };
@@ -1325,13 +1321,13 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
 }
 
 // Method Description:
-// - Helper method for GetWordEnd(). Get the COORD for the beginning of the NEXT word
+// - Helper method for GetWordEnd(). Get the til::point for the beginning of the NEXT word
 // Arguments:
-// - target - a COORD on the word you are currently on
+// - target - a til::point on the word you are currently on
 // - 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
+// - The til::point for the last character of the current word or delimiter run (stopped by right margin)
+til::point TextBuffer::_GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const
 {
     const auto bufferSize = GetSize();
 
@@ -1380,7 +1376,7 @@ void TextBuffer::_PruneHyperlinks()
         // we have found all hyperlink references in the first row and put them in refs,
         // now we need to search the rest of the buffer (i.e. all the rows except the first)
         // to see if those references are anywhere else
-        for (size_t i = 1; i != total; ++i)
+        for (til::CoordType i = 1; i < total; ++i)
         {
             const auto nextRowRefs = GetRowByOffset(i).GetAttrRow().GetHyperlinks();
             for (auto id : nextRowRefs)
@@ -1408,22 +1404,22 @@ void TextBuffer::_PruneHyperlinks()
 // Method Description:
 // - Update pos to be the position of the first character of the next word. This is used for accessibility
 // Arguments:
-// - pos - a COORD on the word you are currently on
+// - pos - a til::point on the word you are currently on
 // - wordDelimiters - what characters are we considering for the separation of words
 // - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
 // 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
+// - pos - The til::point for the first character on the "word" (inclusive)
+bool TextBuffer::MoveToNextWord(til::point& 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"
     //       This is also the inclusive start of the next word.
     const auto bufferSize{ GetSize() };
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
-    const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit.to_win32_coord()) };
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
+    const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit) };
 
-    if (bufferSize.CompareInBounds(copy, limit.to_win32_coord(), true) >= 0)
+    if (bufferSize.CompareInBounds(copy, limit, true) >= 0)
     {
         return false;
     }
@@ -1435,12 +1431,12 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
 // Method Description:
 // - Update pos to be the position of the first character of the previous word. This is used for accessibility
 // Arguments:
-// - pos - a COORD on the word you are currently on
+// - pos - a til::point on the word you are currently on
 // - wordDelimiters - what characters are we considering for the separation of words
 // 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
+// - pos - The til::point for the first character on the "word" (inclusive)
+bool TextBuffer::MoveToPreviousWord(til::point& pos, std::wstring_view wordDelimiters) const
 {
     // move to the beginning of the current word
     auto copy{ GetWordStart(pos, wordDelimiters, true) };
@@ -1459,51 +1455,51 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
 // Method Description:
 // - Update pos to be the beginning of the current glyph/character. This is used for accessibility
 // Arguments:
-// - pos - a COORD on the word you are currently on
+// - pos - a til::point on the word you are currently on
 // - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
 // Return Value:
-// - pos - The COORD for the first cell of the current glyph (inclusive)
-const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
+// - pos - The til::point for the first cell of the current glyph (inclusive)
+til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
 {
-    auto resultPos = pos.to_win32_coord();
+    auto resultPos = pos;
     const auto bufferSize = GetSize();
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
 
     // Clamp pos to limit
-    if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
+    if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
     {
-        resultPos = limit.to_win32_coord();
+        resultPos = limit;
     }
 
     // limit is exclusive, so we need to move back to be within valid bounds
-    if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
+    if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
     {
         bufferSize.DecrementInBounds(resultPos, true);
     }
 
-    return til::point{ resultPos };
+    return resultPos;
 }
 
 // Method Description:
 // - Update pos to be the end of the current glyph/character.
 // Arguments:
-// - pos - a COORD on the word you are currently on
+// - pos - a til::point on the word you are currently on
 // - accessibilityMode - this is being used for accessibility; make the end exclusive.
 // Return Value:
-// - pos - The COORD for the last cell of the current glyph (exclusive)
-const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
+// - pos - The til::point for the last cell of the current glyph (exclusive)
+til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
 {
-    auto resultPos = pos.to_win32_coord();
+    auto resultPos = pos;
     const auto bufferSize = GetSize();
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
 
     // Clamp pos to limit
-    if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
+    if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
     {
-        resultPos = limit.to_win32_coord();
+        resultPos = limit;
     }
 
-    if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
+    if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
     {
         bufferSize.IncrementInBounds(resultPos, true);
     }
@@ -1513,24 +1509,24 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilit
     {
         bufferSize.IncrementInBounds(resultPos, true);
     }
-    return til::point{ resultPos };
+    return resultPos;
 }
 
 // Method Description:
 // - Update pos to be the beginning of the next glyph/character. This is used for accessibility
 // Arguments:
-// - pos - a COORD on the word you are currently on
+// - pos - a til::point on the word you are currently on
 // - allowExclusiveEnd - allow result to be the exclusive limit (one past limit)
 // - limit - boundaries for the iterator to operate within
 // 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 cell of the current glyph (inclusive)
+// - pos - The til::point for the first cell of the current glyph (inclusive)
 bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::optional<til::point> limitOptional) const
 {
     const auto bufferSize = GetSize();
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
 
-    const auto distanceToLimit{ bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) };
+    const auto distanceToLimit{ bufferSize.CompareInBounds(pos, limit, true) };
     if (distanceToLimit >= 0)
     {
         // Corner Case: we're on/past the limit
@@ -1547,7 +1543,7 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
     }
 
     // Try to move forward, but if we hit the buffer boundary, we fail to move.
-    auto iter{ GetCellDataAt(pos.to_win32_coord(), bufferSize) };
+    auto iter{ GetCellDataAt(pos, bufferSize) };
     const bool success{ ++iter };
 
     // Move again if we're on a wide glyph
@@ -1556,24 +1552,24 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
         ++iter;
     }
 
-    pos = til::point{ iter.Pos() };
+    pos = iter.Pos();
     return success;
 }
 
 // Method Description:
 // - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
 // Arguments:
-// - pos - a COORD on the word you are currently on
+// - pos - a til::point on the word you are currently on
 // 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 cell of the previous glyph (inclusive)
+// - pos - The til::point for the first cell of the previous glyph (inclusive)
 bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional) const
 {
-    auto resultPos = pos.to_win32_coord();
+    auto resultPos = pos;
     const auto bufferSize = GetSize();
-    const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
+    const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
 
-    if (bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) > 0)
+    if (bufferSize.CompareInBounds(pos, limit, true) > 0)
     {
         // we're past the end
         // clamp us to the limit
@@ -1588,7 +1584,7 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
         bufferSize.DecrementInBounds(resultPos, true);
     }
 
-    pos = til::point{ resultPos };
+    pos = resultPos;
     return success;
 }
 
@@ -1606,9 +1602,9 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
 //                      the buffer rather than the screen.
 // Return Value:
 // - the delimiter class for the given char
-const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const
+const std::vector<til::inclusive_rect> TextBuffer::GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const
 {
-    std::vector<SMALL_RECT> textRects;
+    std::vector<til::inclusive_rect> textRects;
 
     const auto bufferSize = GetSize();
 
@@ -1619,11 +1615,11 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
                                                std::make_tuple(start, end) :
                                                std::make_tuple(end, start);
 
-    const auto textRectSize = base::ClampedNumeric<short>(1) + lowerCoord.Y - higherCoord.Y;
+    const auto textRectSize = 1 + lowerCoord.Y - higherCoord.Y;
     textRects.reserve(textRectSize);
     for (auto row = higherCoord.Y; row <= lowerCoord.Y; row++)
     {
-        SMALL_RECT textRow;
+        til::inclusive_rect textRow;
 
         textRow.Top = row;
         textRow.Bottom = row;
@@ -1661,12 +1657,12 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
 // - selectionRow: the selection row to be expanded
 // Return Value:
 // - modifies selectionRow's Left and Right values to expand properly
-void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
+void TextBuffer::_ExpandTextRow(til::inclusive_rect& textRow) const
 {
     const auto bufferSize = GetSize();
 
     // expand left side of rect
-    COORD targetPoint{ textRow.Left, textRow.Top };
+    til::point targetPoint{ textRow.Left, textRow.Top };
     if (GetCellDataAt(targetPoint)->DbcsAttr().IsTrailing())
     {
         if (targetPoint.X == bufferSize.Left())
@@ -1708,7 +1704,7 @@ void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
 // - The text, background color, and foreground color data of the selected region of the text buffer.
 const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
                                                    const bool trimTrailingWhitespace,
-                                                   const std::vector<SMALL_RECT>& selectionRects,
+                                                   const std::vector<til::inclusive_rect>& selectionRects,
                                                    std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors,
                                                    const bool formatWrappedRows) const
 {
@@ -1725,9 +1721,9 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
     }
 
     // for each row in the selection
-    for (UINT i = 0; i < rows; i++)
+    for (size_t i = 0; i < rows; i++)
     {
-        const UINT iRow = selectionRects.at(i).Top;
+        const auto iRow = selectionRects.at(i).Top;
 
         const auto highlight = Viewport::FromInclusive(selectionRects.at(i));
 
@@ -2243,22 +2239,22 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
     const auto cOldCursorPos = oldCursor.GetPosition();
     const auto cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
 
-    const short cOldRowsTotal = cOldLastChar.Y + 1;
+    const auto cOldRowsTotal = cOldLastChar.Y + 1;
 
-    COORD cNewCursorPos = { 0 };
+    til::point cNewCursorPos;
     auto fFoundCursorPos = false;
     auto foundOldMutable = false;
     auto foundOldVisible = false;
     auto hr = S_OK;
     // Loop through all the rows of the old buffer and reprint them into the new buffer
-    short iOldRow = 0;
+    til::CoordType iOldRow = 0;
     for (; iOldRow < cOldRowsTotal; iOldRow++)
     {
         // Fetch the row and its "right" which is the last printable character.
         const auto& row = oldBuffer.GetRowByOffset(iOldRow);
         const auto cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
         const auto& charRow = row.GetCharRow();
-        auto iRight = gsl::narrow_cast<short>(charRow.MeasureRight());
+        auto iRight = charRow.MeasureRight();
 
         // If we're starting a new row, try and preserve the line rendition
         // from the row in the original buffer.
@@ -2296,7 +2292,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
         // Loop through every character in the current row (up to
         // the "right" boundary, which is one past the final valid
         // character)
-        short iOldCol = 0;
+        til::CoordType iOldCol = 0;
         const auto copyRight = iRight;
         for (; iOldCol < copyRight; iOldCol++)
         {
@@ -2439,7 +2435,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
                     const auto coordNewCursor = newCursor.GetPosition();
                     if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
                     {
-                        if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
+                        if (newBuffer.GetRowByOffset(coordNewCursor.Y - 1).WasWrapForced())
                         {
                             hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
                         }
@@ -2693,17 +2689,17 @@ void TextBuffer::CopyPatterns(const TextBuffer& OtherBuffer)
 // - The lastRow to search
 // Return value:
 // - An interval tree containing the patterns found
-PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) const
+PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const
 {
     PointTree::interval_vector intervals;
 
     std::wstring concatAll;
     const auto rowSize = GetRowByOffset(0).size();
-    concatAll.reserve(rowSize * (lastRow - firstRow + 1));
+    concatAll.reserve(gsl::narrow_cast<size_t>(rowSize) * gsl::narrow_cast<size_t>(lastRow - firstRow + 1));
 
     // to deal with text that spans multiple lines, we will first concatenate
     // all the text into one string and find the patterns in that string
-    for (auto i = firstRow; i <= lastRow; ++i)
+    for (til::CoordType i = firstRow; i <= lastRow; ++i)
     {
         auto& row = GetRowByOffset(i);
         concatAll += row.GetText();
@@ -2718,21 +2714,21 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
         auto words_begin = std::wsregex_iterator(concatAll.begin(), concatAll.end(), regexObj);
         auto words_end = std::wsregex_iterator();
 
-        size_t lenUpToThis = 0;
+        til::CoordType lenUpToThis = 0;
         for (auto i = words_begin; i != words_end; ++i)
         {
             // record the locations -
             // when we find a match, the prefix is text that is between this
             // match and the previous match, so we use the size of the prefix
             // along with the size of the match to determine the locations
-            size_t prefixSize = 0;
+            til::CoordType prefixSize = 0;
             for (const auto parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
             {
                 const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
                 prefixSize += IsGlyphFullWidth(glyph) ? 2 : 1;
             }
             const auto start = lenUpToThis + prefixSize;
-            size_t matchSize = 0;
+            til::CoordType matchSize = 0;
             for (const auto parsedGlyph : Utf16Parser::Parse(i->str()))
             {
                 const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
@@ -2741,8 +2737,8 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
             const auto end = start + matchSize;
             lenUpToThis = end;
 
-            const til::point startCoord{ gsl::narrow<SHORT>(start % rowSize), gsl::narrow<SHORT>(start / rowSize) };
-            const til::point endCoord{ gsl::narrow<SHORT>(end % rowSize), gsl::narrow<SHORT>(end / rowSize) };
+            const til::point startCoord{ start % rowSize, start / rowSize };
+            const til::point endCoord{ end % rowSize, end / rowSize };
 
             // store the intervals
             // NOTE: these intervals are relative to the VIEWPORT not the buffer
diff --git a/src/buffer/out/textBuffer.hpp b/src/buffer/out/textBuffer.hpp
index 6175d37d2db..61f82599acd 100644
--- a/src/buffer/out/textBuffer.hpp
+++ b/src/buffer/out/textBuffer.hpp
@@ -68,7 +68,7 @@ namespace Microsoft::Console::Render
 class TextBuffer final
 {
 public:
-    TextBuffer(const COORD screenBufferSize,
+    TextBuffer(const til::size screenBufferSize,
                const TextAttribute defaultAttributes,
                const UINT cursorSize,
                const bool isActiveBuffer,
@@ -79,27 +79,27 @@ class TextBuffer final
     void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
 
     // row manipulation
-    const ROW& GetRowByOffset(const size_t index) const;
-    ROW& GetRowByOffset(const size_t index);
+    const ROW& GetRowByOffset(const til::CoordType index) const noexcept;
+    ROW& GetRowByOffset(const til::CoordType index) noexcept;
 
-    TextBufferCellIterator GetCellDataAt(const COORD at) const;
-    TextBufferCellIterator GetCellLineDataAt(const COORD at) const;
-    TextBufferCellIterator GetCellDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
-    TextBufferTextIterator GetTextDataAt(const COORD at) const;
-    TextBufferTextIterator GetTextLineDataAt(const COORD at) const;
-    TextBufferTextIterator GetTextDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
+    TextBufferCellIterator GetCellDataAt(const til::point at) const;
+    TextBufferCellIterator GetCellLineDataAt(const til::point at) const;
+    TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
+    TextBufferTextIterator GetTextDataAt(const til::point at) const;
+    TextBufferTextIterator GetTextLineDataAt(const til::point at) const;
+    TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
 
     // Text insertion functions
     OutputCellIterator Write(const OutputCellIterator givenIt);
 
     OutputCellIterator Write(const OutputCellIterator givenIt,
-                             const COORD target,
+                             const til::point target,
                              const std::optional<bool> wrap = true);
 
     OutputCellIterator WriteLine(const OutputCellIterator givenIt,
-                                 const COORD target,
+                                 const til::point target,
                                  const std::optional<bool> setWrap = std::nullopt,
-                                 const std::optional<size_t> limitRight = std::nullopt);
+                                 const std::optional<til::CoordType> 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);
@@ -109,36 +109,36 @@ class TextBuffer final
     // Scroll needs access to this to quickly rotate around the buffer.
     bool IncrementCircularBuffer(const bool inVtMode = false);
 
-    COORD GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
+    til::point GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
 
     Cursor& GetCursor() noexcept;
     const Cursor& GetCursor() const noexcept;
 
-    const SHORT GetFirstRowIndex() const noexcept;
+    const til::CoordType GetFirstRowIndex() const noexcept;
 
     const Microsoft::Console::Types::Viewport GetSize() const noexcept;
 
-    void ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta);
+    void ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta);
 
-    UINT TotalRowCount() const noexcept;
+    til::CoordType TotalRowCount() const noexcept;
 
     [[nodiscard]] TextAttribute GetCurrentAttributes() const noexcept;
 
     void SetCurrentAttributes(const TextAttribute& currentAttributes) noexcept;
 
     void SetCurrentLineRendition(const LineRendition lineRendition);
-    void ResetLineRenditionRange(const size_t startRow, const size_t endRow);
-    LineRendition GetLineRendition(const size_t row) const;
-    bool IsDoubleWidthLine(const size_t row) const;
+    void ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept;
+    LineRendition GetLineRendition(const til::CoordType row) const noexcept;
+    bool IsDoubleWidthLine(const til::CoordType row) const noexcept;
 
-    SHORT GetLineWidth(const size_t row) const;
-    COORD ClampPositionWithinLine(const COORD position) const;
-    COORD ScreenToBufferPosition(const COORD position) const;
-    COORD BufferToScreenPosition(const COORD position) const;
+    til::CoordType GetLineWidth(const til::CoordType row) const noexcept;
+    til::point ClampPositionWithinLine(const til::point position) const noexcept;
+    til::point ScreenToBufferPosition(const til::point position) const noexcept;
+    til::point BufferToScreenPosition(const til::point position) const noexcept;
 
     void Reset();
 
-    [[nodiscard]] HRESULT ResizeTraditional(const COORD newSize) noexcept;
+    [[nodiscard]] HRESULT ResizeTraditional(const til::size newSize) noexcept;
 
     const UnicodeStorage& GetUnicodeStorage() const noexcept;
     UnicodeStorage& GetUnicodeStorage() noexcept;
@@ -149,23 +149,23 @@ class TextBuffer final
     Microsoft::Console::Render::Renderer& GetRenderer() noexcept;
 
     void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport);
-    void TriggerRedrawCursor(const COORD position);
+    void TriggerRedrawCursor(const til::point position);
     void TriggerRedrawAll();
     void TriggerScroll();
-    void TriggerScroll(const COORD delta);
+    void TriggerScroll(const til::point delta);
     void TriggerNewTextNotification(const std::wstring_view newText);
 
-    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;
+    til::point GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
+    til::point GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
+    bool MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
+    bool MoveToPreviousWord(til::point& 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;
+    til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
+    til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
     bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false, std::optional<til::point> limitOptional = std::nullopt) const;
     bool MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional = std::nullopt) const;
 
-    const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const;
+    const std::vector<til::inclusive_rect> GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const;
 
     void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
     std::wstring GetHyperlinkUriFromId(uint16_t id) const;
@@ -184,7 +184,7 @@ class TextBuffer final
 
     const TextAndColor GetText(const bool includeCRLF,
                                const bool trimTrailingWhitespace,
-                               const std::vector<SMALL_RECT>& textRects,
+                               const std::vector<til::inclusive_rect>& textRects,
                                std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors = nullptr,
                                const bool formatWrappedRows = false) const;
 
@@ -200,8 +200,8 @@ class TextBuffer final
 
     struct PositionInformation
     {
-        short mutableViewportTop{ 0 };
-        short visibleViewportTop{ 0 };
+        til::CoordType mutableViewportTop{ 0 };
+        til::CoordType visibleViewportTop{ 0 };
     };
 
     static HRESULT Reflow(TextBuffer& oldBuffer,
@@ -212,7 +212,7 @@ class TextBuffer final
     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;
+    interval_tree::IntervalTree<til::point, size_t> GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const;
 
 private:
     void _UpdateSize();
@@ -220,7 +220,7 @@ class TextBuffer final
     std::vector<ROW> _storage;
     Cursor _cursor;
 
-    SHORT _firstRow; // indexes top row (not necessarily 0)
+    til::CoordType _firstRow; // indexes top row (not necessarily 0)
 
     TextAttribute _currentAttributes;
 
@@ -234,29 +234,29 @@ class TextBuffer final
     std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
     uint16_t _currentHyperlinkId;
 
-    void _RefreshRowIDs(std::optional<SHORT> newRowWidth);
+    void _RefreshRowIDs(std::optional<til::CoordType> newRowWidth);
 
-    void _SetFirstRowIndex(const SHORT FirstRowIndex) noexcept;
+    void _SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept;
 
-    COORD _GetPreviousFromCursor() const;
+    til::point _GetPreviousFromCursor() const noexcept;
 
-    void _SetWrapOnCurrentRow();
-    void _AdjustWrapOnCurrentRow(const bool fSet);
+    void _SetWrapOnCurrentRow() noexcept;
+    void _AdjustWrapOnCurrentRow(const bool fSet) noexcept;
 
     // Assist with maintaining proper buffer state for Double Byte character sequences
     bool _PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute);
     bool _AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute);
 
-    ROW& _GetFirstRow();
+    ROW& _GetFirstRow() noexcept;
     ROW& _GetPrevRowNoWrap(const ROW& row);
 
-    void _ExpandTextRow(SMALL_RECT& selectionRow) const;
+    void _ExpandTextRow(til::inclusive_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;
+    DelimiterClass _GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const;
+    til::point _GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const;
+    til::point _GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
+    til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
+    til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
 
     void _PruneHyperlinks();
 
diff --git a/src/buffer/out/textBufferCellIterator.cpp b/src/buffer/out/textBufferCellIterator.cpp
index 000135fb111..a9343d74984 100644
--- a/src/buffer/out/textBufferCellIterator.cpp
+++ b/src/buffer/out/textBufferCellIterator.cpp
@@ -19,7 +19,7 @@ using namespace Microsoft::Console::Types;
 // Arguments:
 // - buffer - Text buffer to seek through
 // - pos - Starting position to retrieve text data from (within screen buffer bounds)
-TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos) :
+TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos) :
     TextBufferCellIterator(buffer, pos, buffer.GetSize())
 {
 }
@@ -30,7 +30,7 @@ TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD p
 // - buffer - Pointer to screen buffer to seek through
 // - pos - Starting position to retrieve text data from (within screen buffer bounds)
 // - limits - Viewport limits to restrict the iterator within the buffer bounds (smaller than the buffer itself)
-TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Viewport limits) :
+TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Viewport limits) :
     _buffer(buffer),
     _pos(pos),
     _pRow(s_GetRow(buffer, pos)),
@@ -126,7 +126,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
     const auto oldX = _pos.X;
     const auto oldY = _pos.Y;
 
-    // Under MSVC writing the individual members of a COORD generates worse assembly
+    // Under MSVC writing the individual members of a til::point generates worse assembly
     // compared to having them be local variables. This causes a performance impact.
     auto newX = oldX;
     auto newY = oldY;
@@ -289,7 +289,7 @@ ptrdiff_t TextBufferCellIterator::operator-(const TextBufferCellIterator& it)
 // - Sets the coordinate position that this iterator will inspect within the text buffer on dereference.
 // Arguments:
 // - newPos - The new coordinate position.
-void TextBufferCellIterator::_SetPos(const COORD newPos)
+void TextBufferCellIterator::_SetPos(const til::point newPos)
 {
     if (newPos.Y != _pos.Y)
     {
@@ -317,7 +317,7 @@ void TextBufferCellIterator::_SetPos(const COORD newPos)
 // - pos - Position inside screen buffer bounds to retrieve row
 // Return Value:
 // - Pointer to the underlying CharRow structure
-const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const COORD pos)
+const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept
 {
     return &buffer.GetRowByOffset(pos.Y);
 }
@@ -354,7 +354,7 @@ const OutputCellView* TextBufferCellIterator::operator->() const noexcept
     return &_view;
 }
 
-COORD TextBufferCellIterator::Pos() const noexcept
+til::point TextBufferCellIterator::Pos() const noexcept
 {
     return _pos;
 }
diff --git a/src/buffer/out/textBufferCellIterator.hpp b/src/buffer/out/textBufferCellIterator.hpp
index db8a3c89ce6..ffeb0378602 100644
--- a/src/buffer/out/textBufferCellIterator.hpp
+++ b/src/buffer/out/textBufferCellIterator.hpp
@@ -25,8 +25,8 @@ class TextBuffer;
 class TextBufferCellIterator
 {
 public:
-    TextBufferCellIterator(const TextBuffer& buffer, COORD pos);
-    TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Microsoft::Console::Types::Viewport limits);
+    TextBufferCellIterator(const TextBuffer& buffer, til::point pos);
+    TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Microsoft::Console::Types::Viewport limits);
 
     operator bool() const noexcept;
 
@@ -47,12 +47,12 @@ class TextBufferCellIterator
     const OutputCellView& operator*() const noexcept;
     const OutputCellView* operator->() const noexcept;
 
-    COORD Pos() const noexcept;
+    til::point Pos() const noexcept;
 
 protected:
-    void _SetPos(const COORD newPos);
+    void _SetPos(const til::point newPos);
     void _GenerateView();
-    static const ROW* s_GetRow(const TextBuffer& buffer, const COORD pos);
+    static const ROW* s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept;
 
     OutputCellView _view;
 
@@ -61,7 +61,7 @@ class TextBufferCellIterator
     const TextBuffer& _buffer;
     const Microsoft::Console::Types::Viewport _bounds;
     bool _exceeded;
-    COORD _pos;
+    til::point _pos;
 
 #if UNIT_TESTING
     friend class TextBufferIteratorTests;
diff --git a/src/buffer/out/ut_textbuffer/ReflowTests.cpp b/src/buffer/out/ut_textbuffer/ReflowTests.cpp
index 6c567ad017d..94183b703e2 100644
--- a/src/buffer/out/ut_textbuffer/ReflowTests.cpp
+++ b/src/buffer/out/ut_textbuffer/ReflowTests.cpp
@@ -36,9 +36,9 @@ namespace
 
     struct TestBuffer
     {
-        COORD size;
+        til::size size;
         std::vector<TestRow> rows;
-        COORD cursor;
+        til::point cursor;
     };
 
     struct TestCase
@@ -737,7 +737,7 @@ class ReflowTests
     {
         auto buffer = std::make_unique<TextBuffer>(testBuffer.size, TextAttribute{ 0x7 }, 0, false, renderer);
 
-        size_t i{};
+        til::CoordType i{};
         for (const auto& testRow : testBuffer.rows)
         {
             auto& row{ buffer->GetRowByOffset(i) };
@@ -745,7 +745,7 @@ class ReflowTests
             auto& charRow{ row.GetCharRow() };
             row.SetWrapForced(testRow.wrap);
 
-            size_t j{};
+            til::CoordType j{};
             for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
             {
                 // Yes, we're about to manually create a buffer. It is unpleasant.
@@ -771,7 +771,7 @@ class ReflowTests
         return buffer;
     }
 
-    static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const COORD newSize)
+    static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const til::size newSize)
     {
         auto buffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, renderer);
         TextBuffer::Reflow(originalBuffer, *buffer, std::nullopt, std::nullopt);
@@ -783,7 +783,7 @@ class ReflowTests
         VERIFY_ARE_EQUAL(testBuffer.cursor, buffer.GetCursor().GetPosition());
         VERIFY_ARE_EQUAL(testBuffer.size, buffer.GetSize().Dimensions());
 
-        size_t i{};
+        til::CoordType i{};
         for (const auto& testRow : testBuffer.rows)
         {
             NoThrowString indexString;
@@ -794,7 +794,7 @@ class ReflowTests
             indexString.Format(L"[Row %d]", i);
             VERIFY_ARE_EQUAL(testRow.wrap, row.WasWrapForced(), indexString);
 
-            size_t j{};
+            til::CoordType j{};
             for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
             {
                 indexString.Format(L"[Cell %d, %d; Text line index %d]", it - charRow.begin(), i, j);
diff --git a/src/buffer/out/ut_textbuffer/UnicodeStorageTests.cpp b/src/buffer/out/ut_textbuffer/UnicodeStorageTests.cpp
index 60fabd9e2ec..b2f9cf824a6 100644
--- a/src/buffer/out/ut_textbuffer/UnicodeStorageTests.cpp
+++ b/src/buffer/out/ut_textbuffer/UnicodeStorageTests.cpp
@@ -18,7 +18,7 @@ class UnicodeStorageTests
     TEST_METHOD(CanOverwriteEmoji)
     {
         UnicodeStorage storage;
-        const COORD coord{ 1, 3 };
+        const til::point coord{ 1, 3 };
         const std::vector<wchar_t> newMoon{ 0xD83C, 0xDF11 };
         const std::vector<wchar_t> fullMoon{ 0xD83C, 0xDF15 };
 
diff --git a/src/buffer/out/ut_textbuffer/precomp.h b/src/buffer/out/ut_textbuffer/precomp.h
index 981abbb1578..5a7d147d071 100644
--- a/src/buffer/out/ut_textbuffer/precomp.h
+++ b/src/buffer/out/ut_textbuffer/precomp.h
@@ -37,7 +37,6 @@ Module Name:
 
 // private dependencies
 #include "../host/conddkrefs.h"
-#include "../inc/operators.hpp"
 #include "../inc/unicode.hpp"
 #pragma warning(pop)
 
diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
index f25fd86aecc..373e9c55046 100644
--- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
+++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
@@ -230,7 +230,7 @@ HRESULT HwndTerminal::Initialize()
     RECT windowRect;
     GetWindowRect(_hwnd.get(), &windowRect);
 
-    const COORD windowSize{ gsl::narrow<short>(windowRect.right - windowRect.left), gsl::narrow<short>(windowRect.bottom - windowRect.top) };
+    const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
 
     // Fist set up the dx engine with the window size in pixels.
     // Then, using the font, get the number of characters that can fit.
@@ -239,7 +239,7 @@ HRESULT HwndTerminal::Initialize()
 
     _renderEngine = std::move(dxEngine);
 
-    _terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
+    _terminal->Create({ 80, 25 }, 1000, *_renderer);
     _terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
     localPointerToThread->EnablePainting();
 
@@ -343,7 +343,7 @@ IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
     return _uiaProvider.Get();
 }
 
-HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
+HRESULT HwndTerminal::Refresh(const til::size windowSize, _Out_ til::size* dimensions)
 {
     RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
 
@@ -357,8 +357,7 @@ HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
     _renderer->TriggerRedrawAll();
 
     // Convert our new dimensions to characters
-    const auto viewInPixels = Viewport::FromDimensions({ 0, 0 },
-                                                       { gsl::narrow<short>(windowSize.cx), gsl::narrow<short>(windowSize.cy) });
+    const auto viewInPixels = Viewport::FromDimensions(windowSize);
     const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
 
     // If this function succeeds with S_FALSE, then the terminal didn't
@@ -435,7 +434,7 @@ void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data)
 /// <param name="height">New height of the terminal in pixels</param>
 /// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
 /// <returns>HRESULT of the attempted resize.</returns>
-HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
+HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
 {
     const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
 
@@ -448,7 +447,7 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _I
         static_cast<int>(height),
         0));
 
-    const SIZE windowSize{ width, height };
+    const til::size windowSize{ width, height };
     return publicTerminal->Refresh(windowSize, dimensions);
 }
 
@@ -459,19 +458,19 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _I
 /// <param name="dimensionsInCharacters">New terminal size in row and column count.</param>
 /// <param name="dimensionsInPixels">Out parameter with the new size of the renderer.</param>
 /// <returns>HRESULT of the attempted resize.</returns>
-HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensionsInCharacters, _Out_ SIZE* dimensionsInPixels)
+HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensionsInCharacters, _Out_ til::size* dimensionsInPixels)
 {
     RETURN_HR_IF_NULL(E_INVALIDARG, dimensionsInPixels);
 
     const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
 
-    const auto viewInCharacters = Viewport::FromDimensions({ 0, 0 }, { (dimensionsInCharacters.X), (dimensionsInCharacters.Y) });
+    const auto viewInCharacters = Viewport::FromDimensions(dimensionsInCharacters);
     const auto viewInPixels = publicTerminal->_renderEngine->GetViewportInPixels(viewInCharacters);
 
     dimensionsInPixels->cx = viewInPixels.Width();
     dimensionsInPixels->cy = viewInPixels.Height();
 
-    COORD unused{ 0, 0 };
+    til::size unused;
 
     return TerminalTriggerResize(terminal, viewInPixels.Width(), viewInPixels.Height(), &unused);
 }
@@ -484,7 +483,7 @@ HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ CO
 /// <param name="height">Height of the terminal area to calculate.</param>
 /// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
 /// <returns>HRESULT of the calculation.</returns>
-HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
+HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
 {
     const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
 
@@ -548,11 +547,11 @@ try
 
     if (multiClickMapper == 3)
     {
-        _terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Line);
+        _terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Line);
     }
     else if (multiClickMapper == 2)
     {
-        _terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Word);
+        _terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Word);
     }
     else
     {
@@ -593,13 +592,13 @@ try
 
         if (distanceSquared >= maxDistanceSquared)
         {
-            _terminal->SetSelectionAnchor((touchdownPoint / fontSize).to_win32_coord());
+            _terminal->SetSelectionAnchor(touchdownPoint / fontSize);
             // stop tracking the touchdown point
             _singleClickTouchdownPos = std::nullopt;
         }
     }
 
-    this->_terminal->SetSelectionEnd((cursorPosition / fontSize).to_win32_coord());
+    this->_terminal->SetSelectionEnd(cursorPosition / fontSize);
     this->_renderer->TriggerSelection();
 
     return S_OK;
@@ -701,9 +700,7 @@ try
         wheelDelta = HIWORD(wParam);
 
         // If it's a *WHEEL event, it's in screen coordinates, not window (?!)
-        auto coordsToTransform = cursorPosition.to_win32_point();
-        ScreenToClient(_hwnd.get(), &coordsToTransform);
-        cursorPosition = til::point{ coordsToTransform };
+        ScreenToClient(_hwnd.get(), cursorPosition.as_win32_point());
     }
 
     const TerminalInput::MouseButtonState state{
@@ -712,7 +709,7 @@ try
         WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
     };
 
-    return _terminal->SendMouseEvent((cursorPosition / fontSize).to_win32_coord(), uMsg, getControlKeyState(), wheelDelta, state);
+    return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta, state);
 }
 catch (...)
 {
@@ -780,7 +777,7 @@ void _stdcall DestroyTerminal(void* terminal)
 }
 
 // Updates the terminal font type, size, color, as well as the background/foreground colors to a specified theme.
-void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi)
+void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi)
 {
     const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
     {
@@ -810,8 +807,8 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
     RECT windowRect;
     GetWindowRect(publicTerminal->_hwnd.get(), &windowRect);
 
-    COORD dimensions = {};
-    const SIZE windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
+    til::size dimensions;
+    const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
     publicTerminal->Refresh(windowSize, &dimensions);
 }
 
@@ -984,21 +981,21 @@ void HwndTerminal::_StringPaste(const wchar_t* const pData) noexcept
     CATCH_LOG();
 }
 
-COORD HwndTerminal::GetFontSize() const noexcept
+til::size HwndTerminal::GetFontSize() const noexcept
 {
     return _actualFont.GetSize();
 }
 
-RECT HwndTerminal::GetBounds() const noexcept
+til::rect HwndTerminal::GetBounds() const noexcept
 {
-    RECT windowRect;
-    GetWindowRect(_hwnd.get(), &windowRect);
+    til::rect windowRect;
+    GetWindowRect(_hwnd.get(), windowRect.as_win32_rect());
     return windowRect;
 }
 
-RECT HwndTerminal::GetPadding() const noexcept
+til::rect HwndTerminal::GetPadding() const noexcept
 {
-    return { 0 };
+    return {};
 }
 
 double HwndTerminal::GetScaleFactor() const noexcept
@@ -1006,7 +1003,7 @@ double HwndTerminal::GetScaleFactor() const noexcept
     return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
 }
 
-void HwndTerminal::ChangeViewport(const SMALL_RECT NewWindow)
+void HwndTerminal::ChangeViewport(const til::inclusive_rect& NewWindow)
 {
     _terminal->UserScrollViewport(NewWindow.Top);
 }
diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp
index 210010366be..48366c884c0 100644
--- a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp
+++ b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp
@@ -27,16 +27,16 @@ extern "C" {
 __declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
 __declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
 __declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
-__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
-__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
-__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
+__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
+__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
+__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
 __declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
 __declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
 __declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
 __declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
 __declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
 __declspec(dllexport) void _stdcall DestroyTerminal(void* terminal);
-__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
+__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
 __declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*));
 __declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
 __declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD flags, WORD scanCode);
@@ -60,7 +60,7 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
     HRESULT Initialize();
     void Teardown() noexcept;
     void SendOutput(std::wstring_view data);
-    HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions);
+    HRESULT Refresh(const til::size windowSize, _Out_ til::size* dimensions);
     void RegisterScrollCallback(std::function<void(int, int, int)> callback);
     void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
     ::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
@@ -91,9 +91,9 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
     std::optional<til::point> _singleClickTouchdownPos;
 
     friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
-    friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
-    friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
-    friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
+    friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
+    friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
+    friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
     friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
     friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
     friend void _stdcall TerminalClearSelection(void* terminal);
@@ -101,7 +101,7 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
     friend bool _stdcall TerminalIsSelectionActive(void* terminal);
     friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
     friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags);
-    friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
+    friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
     friend void _stdcall TerminalBlinkCursor(void* terminal);
     friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
     friend void _stdcall TerminalSetFocus(void* terminal);
@@ -128,10 +128,10 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
     void _SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept;
 
     // Inherited via IControlAccessibilityInfo
-    COORD GetFontSize() const noexcept override;
-    RECT GetBounds() const noexcept override;
+    til::size GetFontSize() const noexcept override;
+    til::rect GetBounds() const noexcept override;
     double GetScaleFactor() const noexcept override;
-    void ChangeViewport(const SMALL_RECT NewWindow) override;
+    void ChangeViewport(const til::inclusive_rect& NewWindow) override;
     HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
-    RECT GetPadding() const noexcept override;
+    til::rect GetPadding() const noexcept override;
 };
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index 5a7814ad604..46889b1db99 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -1084,8 +1084,8 @@ namespace winrt::TerminalApp::implementation
                                                                                  L".",
                                                                                  L"Azure",
                                                                                  nullptr,
-                                                                                 ::base::saturated_cast<uint32_t>(settings.InitialRows()),
-                                                                                 ::base::saturated_cast<uint32_t>(settings.InitialCols()),
+                                                                                 settings.InitialRows(),
+                                                                                 settings.InitialCols(),
                                                                                  winrt::guid());
 
             if constexpr (Feature_VtPassthroughMode::IsEnabled())
@@ -1135,8 +1135,8 @@ namespace winrt::TerminalApp::implementation
                                                                                  newWorkingDirectory,
                                                                                  settings.StartingTitle(),
                                                                                  envMap.GetView(),
-                                                                                 ::base::saturated_cast<uint32_t>(settings.InitialRows()),
-                                                                                 ::base::saturated_cast<uint32_t>(settings.InitialCols()),
+                                                                                 settings.InitialRows(),
+                                                                                 settings.InitialCols(),
                                                                                  winrt::guid());
 
             valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
diff --git a/src/cascadia/TerminalAzBridge/main.cpp b/src/cascadia/TerminalAzBridge/main.cpp
index 6a08d16b12b..c6dcc776bf0 100644
--- a/src/cascadia/TerminalAzBridge/main.cpp
+++ b/src/cascadia/TerminalAzBridge/main.cpp
@@ -9,7 +9,7 @@ using namespace winrt;
 using namespace winrt::Windows::Foundation;
 using namespace winrt::Microsoft::Terminal::TerminalConnection;
 
-static COORD GetConsoleScreenSize(HANDLE outputHandle)
+static til::point GetConsoleScreenSize(HANDLE outputHandle)
 {
     CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
     csbiex.cbSize = sizeof(csbiex);
diff --git a/src/cascadia/TerminalConnection/AzureConnection.cpp b/src/cascadia/TerminalConnection/AzureConnection.cpp
index 97482f93c32..21ec8639f6c 100644
--- a/src/cascadia/TerminalConnection/AzureConnection.cpp
+++ b/src/cascadia/TerminalConnection/AzureConnection.cpp
@@ -75,8 +75,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
     {
         if (settings)
         {
-            _initialRows = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows);
-            _initialCols = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols);
+            _initialRows = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows));
+            _initialCols = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols));
         }
     }
 
diff --git a/src/cascadia/TerminalConnection/AzureConnection.h b/src/cascadia/TerminalConnection/AzureConnection.h
index 7f018adcfbd..22c62699ca9 100644
--- a/src/cascadia/TerminalConnection/AzureConnection.h
+++ b/src/cascadia/TerminalConnection/AzureConnection.h
@@ -32,8 +32,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
         WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
 
     private:
-        uint32_t _initialRows{};
-        uint32_t _initialCols{};
+        til::CoordType _initialRows{};
+        til::CoordType _initialCols{};
 
         enum class AzureState
         {
diff --git a/src/cascadia/TerminalConnection/ConptyConnection.cpp b/src/cascadia/TerminalConnection/ConptyConnection.cpp
index 1d590367984..6fee6a797e0 100644
--- a/src/cascadia/TerminalConnection/ConptyConnection.cpp
+++ b/src/cascadia/TerminalConnection/ConptyConnection.cpp
@@ -293,7 +293,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
     {
         _transitionToState(ConnectionState::Connecting);
 
-        const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
+        const til::size dimensions{ gsl::narrow<til::CoordType>(_initialCols), gsl::narrow<til::CoordType>(_initialRows) };
 
         // If we do not have pipes already, then this is a fresh connection... not an inbound one that is a received
         // handoff from an already-started PTY process.
@@ -309,7 +309,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
                 }
             }
 
-            THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, flags, &_inPipe, &_outPipe, &_hPC));
+            THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(til::unwrap_coord_size(dimensions), flags, &_inPipe, &_outPipe, &_hPC));
 
             if (_initialParentHwnd != 0)
             {
@@ -338,7 +338,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
                 TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
                 TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
 
-            THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), dimensions));
+            THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), til::unwrap_coord_size(dimensions)));
             THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
 
             if (_initialVisibility)
diff --git a/src/cascadia/TerminalConnection/ConptyConnection.h b/src/cascadia/TerminalConnection/ConptyConnection.h
index 5e20b11d4bc..d54ad7e03a3 100644
--- a/src/cascadia/TerminalConnection/ConptyConnection.h
+++ b/src/cascadia/TerminalConnection/ConptyConnection.h
@@ -67,8 +67,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
         void _indicateExitWithStatus(unsigned int status) noexcept;
         void _ClientTerminated() noexcept;
 
-        uint32_t _initialRows{};
-        uint32_t _initialCols{};
+        til::CoordType _initialRows{};
+        til::CoordType _initialCols{};
         uint64_t _initialParentHwnd{ 0 };
         hstring _commandline{};
         hstring _startingDirectory{};
diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp
index a224ca22c4d..db37b510674 100644
--- a/src/cascadia/TerminalControl/ControlCore.cpp
+++ b/src/cascadia/TerminalControl/ControlCore.cpp
@@ -250,8 +250,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
             // and react accordingly.
             _updateFont(true);
 
-            const COORD windowSize{ static_cast<short>(windowWidth),
-                                    static_cast<short>(windowHeight) };
+            const til::size windowSize{ static_cast<til::CoordType>(windowWidth),
+                                        static_cast<til::CoordType>(windowHeight) };
 
             // First set up the dx engine with the window size in pixels.
             // Then, using the font, get the number of characters that can fit.
@@ -444,7 +444,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
                                      const short wheelDelta,
                                      const TerminalInput::MouseButtonState state)
     {
-        return _terminal->SendMouseEvent(viewportPos.to_win32_coord(), uiButton, states, wheelDelta, state);
+        return _terminal->SendMouseEvent(viewportPos, uiButton, states, wheelDelta, state);
     }
 
     void ControlCore::UserScrollViewport(const int viewTop)
@@ -568,12 +568,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         _lastHoveredCell = terminalPosition;
         uint16_t newId{ 0u };
         // we can't use auto here because we're pre-declaring newInterval.
-        decltype(_terminal->GetHyperlinkIntervalFromPosition(COORD{})) newInterval{ std::nullopt };
+        decltype(_terminal->GetHyperlinkIntervalFromPosition({})) newInterval{ std::nullopt };
         if (terminalPosition.has_value())
         {
             auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
-            newId = _terminal->GetHyperlinkIdAtPosition(terminalPosition->to_win32_coord());
-            newInterval = _terminal->GetHyperlinkIntervalFromPosition(terminalPosition->to_win32_coord());
+            newId = _terminal->GetHyperlinkIdAtPosition(*terminalPosition);
+            newInterval = _terminal->GetHyperlinkIntervalFromPosition(*terminalPosition);
         }
 
         // If the hyperlink ID changed or the interval changed, trigger a redraw all
@@ -603,7 +603,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
     {
         // Lock for the duration of our reads.
         auto lock = _terminal->LockForReading();
-        return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }.to_win32_coord()) };
+        return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }) };
     }
 
     winrt::hstring ControlCore::HoveredUriText() const
@@ -611,7 +611,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
         if (_lastHoveredCell.has_value())
         {
-            return winrt::hstring{ _terminal->GetHyperlinkAtPosition(_lastHoveredCell->to_win32_coord()) };
+            return winrt::hstring{ _terminal->GetHyperlinkAtPosition(*_lastHoveredCell) };
         }
         return {};
     }
@@ -781,7 +781,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
     bool ControlCore::_setFontSizeUnderLock(int fontSize)
     {
         // Make sure we have a non-zero font size
-        const auto newSize = std::max<short>(gsl::narrow_cast<short>(fontSize), 1);
+        const auto newSize = std::max(fontSize, 1);
         const auto fontFace = _settings->FontFace();
         const auto fontWeight = _settings->FontWeight();
         _actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
@@ -837,8 +837,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
     // - <none>
     void ControlCore::_refreshSizeUnderLock()
     {
-        auto cx = gsl::narrow_cast<short>(_panelWidth * _compositionScale);
-        auto cy = gsl::narrow_cast<short>(_panelHeight * _compositionScale);
+        auto cx = gsl::narrow_cast<til::CoordType>(_panelWidth * _compositionScale);
+        auto cy = gsl::narrow_cast<til::CoordType>(_panelHeight * _compositionScale);
 
         // Don't actually resize so small that a single character wouldn't fit
         // in either dimension. The buffer really doesn't like being size 0.
@@ -906,17 +906,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         _refreshSizeUnderLock();
     }
 
-    void ControlCore::SetSelectionAnchor(const til::point& position)
+    void ControlCore::SetSelectionAnchor(const til::point position)
     {
         auto lock = _terminal->LockForWriting();
-        _terminal->SetSelectionAnchor(position.to_win32_coord());
+        _terminal->SetSelectionAnchor(position);
     }
 
     // Method Description:
     // - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
     // Arguments:
     // - position: the point in terminal coordinates (in cells, not pixels)
-    void ControlCore::SetEndSelectionPoint(const til::point& position)
+    void ControlCore::SetEndSelectionPoint(const til::point position)
     {
         if (!_terminal->IsSelectionActive())
         {
@@ -933,7 +933,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         };
 
         // save location (for rendering) + render
-        _terminal->SetSelectionEnd(terminalPosition.to_win32_coord());
+        _terminal->SetSelectionEnd(terminalPosition);
         _renderer->TriggerSelection();
     }
 
@@ -1488,7 +1488,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         }
 
         auto lock = _terminal->LockForReading();
-        return til::point{ _terminal->GetCursorPosition() }.to_core_point();
+        return _terminal->GetCursorPosition().to_core_point();
     }
 
     // This one's really pushing the boundary of what counts as "encapsulation".
@@ -1540,7 +1540,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         {
             // If shift is pressed and there is a selection we extend it using
             // the selection mode (expand the "end" selection point)
-            _terminal->SetSelectionEnd(terminalPosition.to_win32_coord(), mode);
+            _terminal->SetSelectionEnd(terminalPosition, mode);
             selectionNeedsToBeCopied = true;
         }
         else if (mode != ::Terminal::SelectionExpansion::Char || shiftEnabled)
@@ -1548,7 +1548,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
             // If we are handling a double / triple-click or shift+single click
             // we establish selection using the selected mode
             // (expand both "start" and "end" selection points)
-            _terminal->MultiClickSelection(terminalPosition.to_win32_coord(), mode);
+            _terminal->MultiClickSelection(terminalPosition, mode);
             selectionNeedsToBeCopied = true;
         }
 
diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h
index 9cf4355a6ce..d06ebd46593 100644
--- a/src/cascadia/TerminalControl/ControlCore.h
+++ b/src/cascadia/TerminalControl/ControlCore.h
@@ -151,8 +151,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         bool HasSelection() const;
         bool CopyOnSelect() const;
         Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
-        void SetSelectionAnchor(const til::point& position);
-        void SetEndSelectionPoint(const til::point& position);
+        void SetSelectionAnchor(const til::point position);
+        void SetEndSelectionPoint(const til::point position);
 
         void Search(const winrt::hstring& text,
                     const bool goForward,
diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp
index f84c834fac4..85f92cba396 100644
--- a/src/cascadia/TerminalControl/ControlInteractivity.cpp
+++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp
@@ -615,7 +615,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         // Get the size of the font, which is in pixels
         const til::size fontSize{ _core->GetFont().GetSize() };
         // Convert the location in pixels to characters within the current viewport.
-        return til::point{ pixelPosition / fontSize };
+        return pixelPosition / fontSize;
     }
 
     bool ControlInteractivity::_sendMouseEventHelper(const til::point terminalPosition,
diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h
index 200498a37ab..3d47ad7c0c9 100644
--- a/src/cascadia/TerminalControl/ControlInteractivity.h
+++ b/src/cascadia/TerminalControl/ControlInteractivity.h
@@ -123,7 +123,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         // terminal.
         bool _selectionNeedsToBeCopied;
 
-        std::optional<COORD> _lastHoveredCell{ std::nullopt };
+        std::optional<til::point> _lastHoveredCell{ std::nullopt };
         // Track the last hyperlink ID we hovered over
         uint16_t _lastHoveredId{ 0 };
 
diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp
index 310633e0faa..fd86fdc5d28 100644
--- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp
+++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp
@@ -146,14 +146,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
 #pragma endregion
 
 #pragma region IControlAccessibilityInfo
-    COORD InteractivityAutomationPeer::GetFontSize() const noexcept
+    til::size InteractivityAutomationPeer::GetFontSize() const noexcept
     {
-        return til::size{ til::math::rounding, _interactivity->Core().FontSize() }.to_win32_coord();
+        return { til::math::rounding, _interactivity->Core().FontSize() };
     }
 
-    RECT InteractivityAutomationPeer::GetBounds() const noexcept
+    til::rect InteractivityAutomationPeer::GetBounds() const noexcept
     {
-        return _controlBounds.to_win32_rect();
+        return _controlBounds;
     }
 
     HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
@@ -164,9 +164,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         return S_OK;
     }
 
-    RECT InteractivityAutomationPeer::GetPadding() const noexcept
+    til::rect InteractivityAutomationPeer::GetPadding() const noexcept
     {
-        return _controlPadding.to_win32_rect();
+        return _controlPadding;
     }
 
     double InteractivityAutomationPeer::GetScaleFactor() const noexcept
@@ -174,7 +174,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
     }
 
-    void InteractivityAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow)
+    void InteractivityAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
     {
         _interactivity->UpdateScrollbar(NewWindow.Top);
     }
diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h
index 9f0d96fead5..863521a7fef 100644
--- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h
+++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h
@@ -63,11 +63,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
 
 #pragma region IControlAccessibilityInfo Pattern
         // Inherited via IControlAccessibilityInfo
-        virtual COORD GetFontSize() const noexcept override;
-        virtual RECT GetBounds() const noexcept override;
-        virtual RECT GetPadding() const noexcept override;
+        virtual til::size GetFontSize() const noexcept override;
+        virtual til::rect GetBounds() const noexcept override;
+        virtual til::rect GetPadding() const noexcept override;
         virtual double GetScaleFactor() const noexcept override;
-        virtual void ChangeViewport(SMALL_RECT NewWindow) override;
+        virtual void ChangeViewport(const til::inclusive_rect& NewWindow) override;
         virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
 #pragma endregion
 
diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp
index 37e4ad8096e..7acd4e30abc 100644
--- a/src/cascadia/TerminalControl/TermControl.cpp
+++ b/src/cascadia/TerminalControl/TermControl.cpp
@@ -637,7 +637,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
     // clever way around asking the core for this.
     til::point TermControl::GetFontSize() const
     {
-        return til::point{ til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
+        return { til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
     }
 
     const Windows::UI::Xaml::Thickness TermControl::GetPadding()
@@ -1969,7 +1969,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         //      The family is only used to determine if the font is truetype or
         //      not, but DX doesn't use that info at all.
         //      The Codepage is additionally not actually used by the DX engine at all.
-        FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, gsl::narrow_cast<short>(fontSize) }, CP_UTF8, false };
+        FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontSize }, CP_UTF8, false };
         FontInfoDesired desiredFont = { actualFont };
 
         // Create a DX engine and initialize it with our font and DPI. We'll
diff --git a/src/cascadia/TerminalCore/ITerminalInput.hpp b/src/cascadia/TerminalCore/ITerminalInput.hpp
index 1db443f51d6..480494de1f6 100644
--- a/src/cascadia/TerminalCore/ITerminalInput.hpp
+++ b/src/cascadia/TerminalCore/ITerminalInput.hpp
@@ -17,10 +17,10 @@ namespace Microsoft::Terminal::Core
         ITerminalInput& operator=(ITerminalInput&&) = default;
 
         virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
-        virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
+        virtual bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
         virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
 
-        [[nodiscard]] virtual HRESULT UserResize(const COORD size) noexcept = 0;
+        [[nodiscard]] virtual HRESULT UserResize(const til::size size) noexcept = 0;
         virtual void UserScrollViewport(const int viewTop) = 0;
         virtual int GetScrollOffset() = 0;
 
diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp
index fe0fbeab27c..bc4b01e608d 100644
--- a/src/cascadia/TerminalCore/Terminal.cpp
+++ b/src/cascadia/TerminalCore/Terminal.cpp
@@ -66,12 +66,12 @@ Terminal::Terminal() :
     _renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, RGB(0, 0, 0));
 }
 
-void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& renderer)
+void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Renderer& renderer)
 {
     _mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
     _scrollbackLines = scrollbackLines;
-    const COORD bufferSize{ viewportSize.X,
-                            Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
+    const til::size bufferSize{ viewportSize.X,
+                                Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
     const TextAttribute attr{};
     const UINT cursorSize = 12;
     _mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, renderer);
@@ -97,8 +97,8 @@ void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& rende
 void Terminal::CreateFromSettings(ICoreSettings settings,
                                   Renderer& renderer)
 {
-    const COORD viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
-                              Utils::ClampToShortMax(settings.InitialRows(), 1) };
+    const til::size viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
+                                  Utils::ClampToShortMax(settings.InitialRows(), 1) };
 
     // TODO:MSFT:20642297 - Support infinite scrollback here, if HistorySize is -1
     Create(viewportSize, Utils::ClampToShortMax(settings.HistorySize(), 0), renderer);
@@ -243,7 +243,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
 // - S_OK if we successfully resized the terminal, S_FALSE if there was
 //      nothing to do (the viewportSize is the same as our current size), or an
 //      appropriate HRESULT for failing to resize.
-[[nodiscard]] HRESULT Terminal::UserResize(const COORD viewportSize) noexcept
+[[nodiscard]] HRESULT Terminal::UserResize(const til::size viewportSize) noexcept
 {
     const auto oldDimensions = _GetMutableViewport().Dimensions();
     if (viewportSize == oldDimensions)
@@ -258,7 +258,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
     if (_inAltBuffer())
     {
         // stash this resize for the future.
-        _deferredResize = til::size{ viewportSize };
+        _deferredResize = viewportSize;
 
         _altBuffer->GetCursor().StartDeferDrawing();
         // we're capturing `this` here because when we exit, we want to EndDefer on the (newly created) active buffer.
@@ -273,19 +273,19 @@ std::wstring_view Terminal::GetWorkingDirectory()
         // Since the _mutableViewport is no longer the size of the actual
         // viewport, then update our _altBufferSize tracker we're using to help
         // us out here.
-        _altBufferSize = til::size{ viewportSize };
+        _altBufferSize = viewportSize;
         return S_OK;
     }
 
-    const auto dx = ::base::ClampSub(viewportSize.X, oldDimensions.X);
-    const short newBufferHeight = ::base::ClampAdd(viewportSize.Y, _scrollbackLines);
+    const auto dx = viewportSize.X - oldDimensions.X;
+    const auto newBufferHeight = std::clamp(viewportSize.Y + _scrollbackLines, 0, SHRT_MAX);
 
-    COORD bufferSize{ viewportSize.X, newBufferHeight };
+    til::size bufferSize{ viewportSize.X, newBufferHeight };
 
     // This will be used to determine where the viewport should be in the new buffer.
     const auto oldViewportTop = _mutableViewport.Top();
     auto newViewportTop = oldViewportTop;
-    auto newVisibleTop = ::base::saturated_cast<short>(_VisibleStartIndex());
+    auto newVisibleTop = _VisibleStartIndex();
 
     // If the original buffer had _no_ scroll offset, then we should be at the
     // bottom in the new buffer as well. Track that case now.
@@ -329,7 +329,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
         oldRows.mutableViewportTop = oldViewportTop;
         oldRows.visibleViewportTop = newVisibleTop;
 
-        const std::optional<short> oldViewStart{ oldViewportTop };
+        const std::optional oldViewStart{ oldViewportTop };
         RETURN_IF_FAILED(TextBuffer::Reflow(*_mainBuffer.get(),
                                             *newTextBuffer.get(),
                                             _mutableViewport,
@@ -383,7 +383,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
 
     const auto maxRow = std::max(newLastChar.Y, newCursorPos.Y);
 
-    const short proposedTopFromLastLine = ::base::ClampAdd(::base::ClampSub(maxRow, viewportSize.Y), 1);
+    const auto proposedTopFromLastLine = maxRow - viewportSize.Y + 1;
     const auto proposedTopFromScrollback = newViewportTop;
 
     auto proposedTop = std::max(proposedTopFromLastLine,
@@ -433,7 +433,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
 
     // Make sure the proposed viewport is within the bounds of the buffer.
     // First make sure the top is >=0
-    proposedTop = std::max(static_cast<short>(0), proposedTop);
+    proposedTop = std::max(0, proposedTop);
 
     // If the new bottom would be below the bottom of the buffer, then slide the
     // top up so that we'll still fit within the buffer.
@@ -452,7 +452,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
     // Make sure that we don't scroll past the mutableViewport at the bottom of the buffer
     newVisibleTop = std::min(newVisibleTop, _mutableViewport.Top());
     // Make sure we don't scroll past the top of the scrollback
-    newVisibleTop = std::max<short>(newVisibleTop, 0);
+    newVisibleTop = std::max(newVisibleTop, 0);
 
     // If the old scrolloffset was 0, then we weren't scrolled back at all
     // before, and shouldn't be now either.
@@ -555,7 +555,7 @@ bool Terminal::ShouldSendAlternateScroll(const unsigned int uiButton,
 // - Given a coord, get the URI at that location
 // Arguments:
 // - The position
-std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
+std::wstring Terminal::GetHyperlinkAtPosition(const til::point position)
 {
     auto attr = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr();
     if (attr.IsHyperlink())
@@ -571,8 +571,8 @@ std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
         const auto end = result->stop;
         std::wstring uri;
 
-        const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start.to_win32_coord()));
-        const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end.to_win32_coord()));
+        const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start));
+        const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end));
         for (auto iter = startIter; iter != endIter; ++iter)
         {
             uri += iter->Chars();
@@ -588,7 +588,7 @@ std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
 // - The position of the text
 // Return value:
 // - The hyperlink ID
-uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
+uint16_t Terminal::GetHyperlinkIdAtPosition(const til::point position)
 {
     return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr().GetHyperlinkId();
 }
@@ -599,9 +599,9 @@ uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
 // - The position
 // Return value:
 // - The interval representing the start and end coordinates
-std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const COORD position)
+std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const til::point position)
 {
-    const auto results = _patternIntervalTree.findOverlapping(til::point{ position.X + 1, position.Y }, til::point{ position });
+    const auto results = _patternIntervalTree.findOverlapping({ position.X + 1, position.Y }, position);
     if (results.size() > 0)
     {
         for (const auto& result : results)
@@ -716,16 +716,14 @@ bool Terminal::SendKeyEvent(const WORD vkey,
 // Return Value:
 // - true if we translated the key event, and it should not be processed any further.
 // - false if we did not translate the key, and it should be processed into a character.
-bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
+bool Terminal::SendMouseEvent(til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
 {
     // GH#6401: VT applications should be able to receive mouse events from outside the
     // terminal buffer. This is likely to happen when the user drags the cursor offscreen.
     // We shouldn't throw away perfectly good events when they're offscreen, so we just
     // clamp them to be within the range [(0, 0), (W, H)].
-#pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below
-    auto clampedPos{ viewportPos };
-    _GetMutableViewport().ToOrigin().Clamp(clampedPos);
-    return _terminalInput->HandleMouse(til::point{ clampedPos }, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
+    _GetMutableViewport().ToOrigin().Clamp(viewportPos);
+    return _terminalInput->HandleMouse(viewportPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
 }
 
 // Method Description:
@@ -784,8 +782,8 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
 {
     const auto vis = _VisibleStartIndex();
     auto invalidate = [=](const PointTree::interval& interval) {
-        COORD startCoord{ gsl::narrow<SHORT>(interval.start.x), gsl::narrow<SHORT>(interval.start.y + vis) };
-        COORD endCoord{ gsl::narrow<SHORT>(interval.stop.x), gsl::narrow<SHORT>(interval.stop.y + vis) };
+        til::point startCoord{ interval.start.x, interval.start.y + vis };
+        til::point endCoord{ interval.stop.x, interval.stop.y + vis };
         _InvalidateFromCoords(startCoord, endCoord);
     };
     tree.visit_all(invalidate);
@@ -795,30 +793,30 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
 // - Given start and end coords, invalidates all the regions between them
 // Arguments:
 // - The start and end coords
-void Terminal::_InvalidateFromCoords(const COORD start, const COORD end)
+void Terminal::_InvalidateFromCoords(const til::point start, const til::point end)
 {
     if (start.Y == end.Y)
     {
-        SMALL_RECT region{ start.X, start.Y, end.X, end.Y };
+        til::inclusive_rect region{ start.X, start.Y, end.X, end.Y };
         _activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
     }
     else
     {
-        const auto rowSize = gsl::narrow<SHORT>(_activeBuffer().GetRowByOffset(0).size());
+        const auto rowSize = _activeBuffer().GetRowByOffset(0).size();
 
         // invalidate the first line
-        SMALL_RECT region{ start.X, start.Y, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(start.Y) };
+        til::inclusive_rect region{ start.X, start.Y, rowSize - 1, start.Y };
         _activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
 
         if ((end.Y - start.Y) > 1)
         {
             // invalidate the lines in between the first and last line
-            region = SMALL_RECT{ 0, start.Y + 1, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(end.Y - 1) };
+            region = til::inclusive_rect{ 0, start.Y + 1, rowSize - 1, end.Y - 1 };
             _activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
         }
 
         // invalidate the last line
-        region = SMALL_RECT{ 0, end.Y, end.X, end.Y };
+        region = til::inclusive_rect{ 0, end.Y, end.X, end.Y };
         _activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
     }
 }
@@ -977,11 +975,11 @@ Viewport Terminal::_GetMutableViewport() const noexcept
     // GH#3493: if we're in the alt buffer, then it's possible that the mutable
     // viewport's size hasn't been updated yet. In that case, use the
     // temporarily stashed _altBufferSize instead.
-    return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize.to_win32_coord()) :
+    return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize) :
                             _mutableViewport;
 }
 
-short Terminal::GetBufferHeight() const noexcept
+til::CoordType Terminal::GetBufferHeight() const noexcept
 {
     return _GetMutableViewport().BottomExclusive();
 }
@@ -1015,8 +1013,8 @@ Viewport Terminal::_GetVisibleViewport() const noexcept
     // GH#3493: if we're in the alt buffer, then it's possible that the mutable
     // viewport's size hasn't been updated yet. In that case, use the
     // temporarily stashed _altBufferSize instead.
-    const COORD origin{ 0, gsl::narrow<short>(_VisibleStartIndex()) };
-    const auto size{ _inAltBuffer() ? _altBufferSize.to_win32_coord() :
+    const til::point origin{ 0, _VisibleStartIndex() };
+    const auto size{ _inAltBuffer() ? _altBufferSize :
                                       _mutableViewport.Dimensions() };
     return Viewport::FromDimensions(origin,
                                     size);
@@ -1060,7 +1058,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
         {
             // If "wch" was a surrogate character, we just consumed 2 code units above.
             // -> Increment "i" by 1 in that case and thus by 2 in total in this iteration.
-            proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance);
+            proposedCursorPosition.X += cellDistance;
             i += inputDistance - 1;
         }
         else
@@ -1099,7 +1097,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
     cursor.EndDeferDrawing();
 }
 
-void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
+void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
 {
 #pragma warning(suppress : 26496) // cpp core checks wants this const but it's modified below.
     auto proposedCursorPosition = proposedPosition;
@@ -1108,7 +1106,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
 
     // If we're about to scroll past the bottom of the buffer, instead cycle the
     // buffer.
-    SHORT rowsPushedOffTopOfBuffer = 0;
+    til::CoordType rowsPushedOffTopOfBuffer = 0;
     const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
     if (proposedCursorPosition.Y >= bufferSize.Height())
     {
@@ -1163,7 +1161,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
             // In the alt buffer, we never need to adjust _mutableViewport, which is the viewport of the main buffer.
             if (newViewTop != _mutableViewport.Top())
             {
-                _mutableViewport = Viewport::FromDimensions({ 0, gsl::narrow<short>(newViewTop) },
+                _mutableViewport = Viewport::FromDimensions({ 0, newViewTop },
                                                             _mutableViewport.Dimensions());
                 updatedViewport = true;
             }
@@ -1203,7 +1201,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
         // We have to report the delta here because we might have circled the text buffer.
         // That didn't change the viewport and therefore the TriggerScroll(void)
         // method can't detect the delta on its own.
-        COORD delta{ 0, gsl::narrow_cast<short>(-rowsPushedOffTopOfBuffer) };
+        til::point delta{ 0, -rowsPushedOffTopOfBuffer };
         _activeBuffer().TriggerScroll(delta);
     }
 }
diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp
index a042ec360f3..509f2c326c6 100644
--- a/src/cascadia/TerminalCore/Terminal.hpp
+++ b/src/cascadia/TerminalCore/Terminal.hpp
@@ -69,8 +69,8 @@ class Microsoft::Terminal::Core::Terminal final :
     Terminal& operator=(const Terminal&) = default;
     Terminal& operator=(Terminal&&) = default;
 
-    void Create(COORD viewportSize,
-                SHORT scrollbackLines,
+    void Create(til::size viewportSize,
+                til::CoordType scrollbackLines,
                 Microsoft::Console::Render::Renderer& renderer);
 
     void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
@@ -94,7 +94,7 @@ class Microsoft::Terminal::Core::Terminal final :
     [[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
     til::ticket_lock& GetReadWriteLock() noexcept;
 
-    short GetBufferHeight() const noexcept;
+    til::CoordType GetBufferHeight() const noexcept;
 
     int ViewStartIndex() const noexcept;
     int ViewEndIndex() const noexcept;
@@ -118,7 +118,7 @@ class Microsoft::Terminal::Core::Terminal final :
     void LineFeed(const bool withReturn) override;
     void SetWindowTitle(const std::wstring_view title) override;
     CursorType GetUserDefaultCursorStyle() const override;
-    bool ResizeWindow(const size_t width, const size_t height) override;
+    bool ResizeWindow(const til::CoordType width, const til::CoordType height) override;
     void SetConsoleOutputCP(const unsigned int codepage) override;
     unsigned int GetConsoleOutputCP() const override;
     void EnableXtermBracketedPasteMode(const bool enabled) override;
@@ -137,10 +137,10 @@ class Microsoft::Terminal::Core::Terminal final :
 #pragma region ITerminalInput
     // These methods are defined in Terminal.cpp
     bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
-    bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
+    bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
     bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
 
-    [[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
+    [[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept override;
     void UserScrollViewport(const int viewTop) override;
     int GetScrollOffset() noexcept override;
 
@@ -150,14 +150,14 @@ class Microsoft::Terminal::Core::Terminal final :
 
     void FocusChanged(const bool focused) noexcept override;
 
-    std::wstring GetHyperlinkAtPosition(const COORD position);
-    uint16_t GetHyperlinkIdAtPosition(const COORD position);
-    std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const COORD position);
+    std::wstring GetHyperlinkAtPosition(const til::point position);
+    uint16_t GetHyperlinkIdAtPosition(const til::point position);
+    std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const til::point position);
 #pragma endregion
 
 #pragma region IBaseData(base to IRenderData and IUiaData)
     Microsoft::Console::Types::Viewport GetViewport() noexcept override;
-    COORD GetTextBufferEndPosition() const noexcept override;
+    til::point GetTextBufferEndPosition() const noexcept override;
     const TextBuffer& GetTextBuffer() const noexcept override;
     const FontInfo& GetFontInfo() const noexcept override;
 
@@ -167,7 +167,7 @@ class Microsoft::Terminal::Core::Terminal final :
 
 #pragma region IRenderData
     // These methods are defined in TerminalRenderData.cpp
-    COORD GetCursorPosition() const noexcept override;
+    til::point GetCursorPosition() const noexcept override;
     bool IsCursorVisible() const noexcept override;
     bool IsCursorOn() const noexcept override;
     ULONG GetCursorHeight() const noexcept override;
@@ -178,7 +178,7 @@ class Microsoft::Terminal::Core::Terminal final :
     const bool IsGridLineDrawingAllowed() noexcept override;
     const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
     const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
-    const std::vector<size_t> GetPatternId(const COORD location) const noexcept override;
+    const std::vector<size_t> GetPatternId(const til::point location) const noexcept override;
 #pragma endregion
 
 #pragma region IUiaData
@@ -187,11 +187,11 @@ class Microsoft::Terminal::Core::Terminal final :
     const bool IsSelectionActive() const noexcept override;
     const bool IsBlockSelection() const noexcept override;
     void ClearSelection() override;
-    void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
-    const COORD GetSelectionAnchor() const noexcept override;
-    const COORD GetSelectionEnd() const noexcept override;
+    void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override;
+    const til::point GetSelectionAnchor() const noexcept override;
+    const til::point GetSelectionEnd() const noexcept override;
     const std::wstring_view GetConsoleTitle() const noexcept override;
-    void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
+    void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute) override;
     const bool IsUiaDataInitialized() const noexcept override;
 #pragma endregion
 
@@ -237,9 +237,9 @@ class Microsoft::Terminal::Core::Terminal final :
         Viewport,
         Buffer
     };
-    void MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode);
-    void SetSelectionAnchor(const COORD position);
-    void SetSelectionEnd(const COORD position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
+    void MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode);
+    void SetSelectionAnchor(const til::point position);
+    void SetSelectionEnd(const til::point position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
     void SetBlockSelection(const bool isEnabled) noexcept;
     void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
     void SelectAll();
@@ -303,14 +303,14 @@ class Microsoft::Terminal::Core::Terminal final :
     FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
 #pragma region Text Selection
     // a selection is represented as a range between two COORDs (start and end)
-    // the pivot is the COORD that remains selected when you extend a selection in any direction
+    // the pivot is the til::point that remains selected when you extend a selection in any direction
     //   this is particularly useful when a word selection is extended over its starting point
     //   see TerminalSelection.cpp for more information
     struct SelectionAnchors
     {
-        COORD start;
-        COORD end;
-        COORD pivot;
+        til::point start;
+        til::point end;
+        til::point pivot;
     };
     std::optional<SelectionAnchors> _selection;
     bool _blockSelection;
@@ -322,7 +322,7 @@ class Microsoft::Terminal::Core::Terminal final :
     std::unique_ptr<TextBuffer> _mainBuffer;
     std::unique_ptr<TextBuffer> _altBuffer;
     Microsoft::Console::Types::Viewport _mutableViewport;
-    SHORT _scrollbackLines;
+    til::CoordType _scrollbackLines;
     bool _detectURLs{ false };
 
     til::size _altBufferSize;
@@ -346,7 +346,7 @@ class Microsoft::Terminal::Core::Terminal final :
 
     interval_tree::IntervalTree<til::point, size_t> _patternIntervalTree;
     void _InvalidatePatternTree(interval_tree::IntervalTree<til::point, size_t>& tree);
-    void _InvalidateFromCoords(const COORD start, const COORD end);
+    void _InvalidateFromCoords(const til::point start, const til::point end);
 
     // Since virtual keys are non-zero, you assume that this field is empty/invalid if it is.
     struct KeyEventCodes
@@ -372,7 +372,7 @@ class Microsoft::Terminal::Core::Terminal final :
 
     void _WriteBuffer(const std::wstring_view& stringView);
 
-    void _AdjustCursorPosition(const COORD proposedPosition);
+    void _AdjustCursorPosition(const til::point proposedPosition);
 
     void _NotifyScrollEvent() noexcept;
 
@@ -384,14 +384,14 @@ class Microsoft::Terminal::Core::Terminal final :
 
 #pragma region TextSelection
     // These methods are defined in TerminalSelection.cpp
-    std::vector<SMALL_RECT> _GetSelectionRects() const noexcept;
-    std::pair<COORD, COORD> _PivotSelection(const COORD targetPos, bool& targetStart) const;
-    std::pair<COORD, COORD> _ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const;
-    COORD _ConvertToBufferCell(const COORD viewportPos) const;
-    void _MoveByChar(SelectionDirection direction, COORD& pos);
-    void _MoveByWord(SelectionDirection direction, COORD& pos);
-    void _MoveByViewport(SelectionDirection direction, COORD& pos);
-    void _MoveByBuffer(SelectionDirection direction, COORD& pos);
+    std::vector<til::inclusive_rect> _GetSelectionRects() const noexcept;
+    std::pair<til::point, til::point> _PivotSelection(const til::point targetPos, bool& targetStart) const;
+    std::pair<til::point, til::point> _ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const;
+    til::point _ConvertToBufferCell(const til::point viewportPos) const;
+    void _MoveByChar(SelectionDirection direction, til::point& pos);
+    void _MoveByWord(SelectionDirection direction, til::point& pos);
+    void _MoveByViewport(SelectionDirection direction, til::point& pos);
+    void _MoveByBuffer(SelectionDirection direction, til::point& pos);
 #pragma endregion
 
 #ifdef UNIT_TESTING
diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp
index 6899c7ba4a4..06df2d809ce 100644
--- a/src/cascadia/TerminalCore/TerminalApi.cpp
+++ b/src/cascadia/TerminalCore/TerminalApi.cpp
@@ -45,7 +45,7 @@ void Terminal::SetViewportPosition(const til::point position)
     if (!_inAltBuffer())
     {
         const auto dimensions = _GetMutableViewport().Dimensions();
-        _mutableViewport = Viewport::FromDimensions(position.to_win32_coord(), dimensions);
+        _mutableViewport = Viewport::FromDimensions(position, dimensions);
         Terminal::_NotifyScrollEvent();
     }
 }
@@ -106,7 +106,7 @@ CursorType Terminal::GetUserDefaultCursorStyle() const
     return _defaultCursorShape;
 }
 
-bool Terminal::ResizeWindow(const size_t /*width*/, const size_t /*height*/)
+bool Terminal::ResizeWindow(const til::CoordType /*width*/, const til::CoordType /*height*/)
 {
     // TODO: This will be needed to support various resizing sequences. See also GH#1860.
     return false;
@@ -196,7 +196,7 @@ void Terminal::PlayMidiNote(const int noteNumber, const int velocity, const std:
 void Terminal::UseAlternateScreenBuffer()
 {
     // the new alt buffer is exactly the size of the viewport.
-    _altBufferSize = til::size{ _mutableViewport.Dimensions() };
+    _altBufferSize = _mutableViewport.Dimensions();
 
     const auto cursorSize = _mainBuffer->GetCursor().GetSize();
 
@@ -204,7 +204,7 @@ void Terminal::UseAlternateScreenBuffer()
     _mainBuffer->ClearPatternRecognizers();
 
     // Create a new alt buffer
-    _altBuffer = std::make_unique<TextBuffer>(_altBufferSize.to_win32_coord(),
+    _altBuffer = std::make_unique<TextBuffer>(_altBufferSize,
                                               TextAttribute{},
                                               cursorSize,
                                               true,
@@ -275,7 +275,7 @@ void Terminal::UseMainScreenBuffer()
 
     if (_deferredResize.has_value())
     {
-        LOG_IF_FAILED(UserResize(_deferredResize.value().to_win32_coord()));
+        LOG_IF_FAILED(UserResize(_deferredResize.value()));
         _deferredResize = std::nullopt;
     }
 
diff --git a/src/cascadia/TerminalCore/TerminalSelection.cpp b/src/cascadia/TerminalCore/TerminalSelection.cpp
index 6d75d6d20c5..7f0ad40229d 100644
--- a/src/cascadia/TerminalCore/TerminalSelection.cpp
+++ b/src/cascadia/TerminalCore/TerminalSelection.cpp
@@ -43,9 +43,9 @@ using namespace Microsoft::Terminal::Core;
 // - Helper to determine the selected region of the buffer. Used for rendering.
 // Return Value:
 // - A vector of rectangles representing the regions to select, line by line. They are absolute coordinates relative to the buffer origin.
-std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
+std::vector<til::inclusive_rect> Terminal::_GetSelectionRects() const noexcept
 {
-    std::vector<SMALL_RECT> result;
+    std::vector<til::inclusive_rect> result;
 
     if (!IsSelectionActive())
     {
@@ -66,7 +66,7 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
 // - None
 // Return Value:
 // - None
-const COORD Terminal::GetSelectionAnchor() const noexcept
+const til::point Terminal::GetSelectionAnchor() const noexcept
 {
     return _selection->start;
 }
@@ -77,7 +77,7 @@ const COORD Terminal::GetSelectionAnchor() const noexcept
 // - None
 // Return Value:
 // - None
-const COORD Terminal::GetSelectionEnd() const noexcept
+const til::point Terminal::GetSelectionEnd() const noexcept
 {
     return _selection->end;
 }
@@ -101,7 +101,7 @@ const bool Terminal::IsBlockSelection() const noexcept
 // Arguments:
 // - viewportPos: the (x,y) coordinate on the visible viewport
 // - expansionMode: the SelectionExpansion to dictate the boundaries of the selection anchors
-void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode)
+void Terminal::MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode)
 {
     // set the selection pivot to expand the selection using SetSelectionEnd()
     _selection = SelectionAnchors{};
@@ -119,7 +119,7 @@ void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion e
 // - Record the position of the beginning of a selection
 // Arguments:
 // - position: the (x,y) coordinate on the visible viewport
-void Terminal::SetSelectionAnchor(const COORD viewportPos)
+void Terminal::SetSelectionAnchor(const til::point viewportPos)
 {
     _selection = SelectionAnchors{};
     _selection->pivot = _ConvertToBufferCell(viewportPos);
@@ -136,7 +136,7 @@ void Terminal::SetSelectionAnchor(const COORD viewportPos)
 // Arguments:
 // - viewportPos: the (x,y) coordinate on the visible viewport
 // - newExpansionMode: overwrites the _multiClickSelectionMode for this function call. Used for ShiftClick
-void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionExpansion> newExpansionMode)
+void Terminal::SetSelectionEnd(const til::point viewportPos, std::optional<SelectionExpansion> newExpansionMode)
 {
     if (!_selection.has_value())
     {
@@ -180,7 +180,7 @@ void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionE
 // - targetStart: if true, target will be the new start. Otherwise, target will be the new end.
 // Return Value:
 // - the new start/end for a selection
-std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& targetStart) const
+std::pair<til::point, til::point> Terminal::_PivotSelection(const til::point targetPos, bool& targetStart) const
 {
     if (targetStart = _activeBuffer().GetSize().CompareInBounds(targetPos, _selection->pivot) <= 0)
     {
@@ -202,7 +202,7 @@ std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& t
 // - anchors: a pair of selection anchors representing a desired selection
 // Return Value:
 // - the new start/end for a selection
-std::pair<COORD, COORD> Terminal::_ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const
+std::pair<til::point, til::point> Terminal::_ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const
 {
     auto start = anchors.first;
     auto end = anchors.second;
@@ -389,38 +389,39 @@ void Terminal::SelectAll()
     _selection->pivot = _selection->end;
 }
 
-void Terminal::_MoveByChar(SelectionDirection direction, COORD& pos)
+void Terminal::_MoveByChar(SelectionDirection direction, til::point& pos)
 {
     switch (direction)
     {
     case SelectionDirection::Left:
         _activeBuffer().GetSize().DecrementInBounds(pos);
-        pos = _activeBuffer().GetGlyphStart(til::point{ pos }).to_win32_coord();
+        pos = _activeBuffer().GetGlyphStart(pos);
         break;
     case SelectionDirection::Right:
         _activeBuffer().GetSize().IncrementInBounds(pos);
-        pos = _activeBuffer().GetGlyphEnd(til::point{ pos }).to_win32_coord();
+        pos = _activeBuffer().GetGlyphEnd(pos);
         break;
     case SelectionDirection::Up:
     {
         const auto bufferSize{ _activeBuffer().GetSize() };
-        pos = { pos.X, std::clamp(base::ClampSub<short, short>(pos.Y, 1).RawValue(), bufferSize.Top(), bufferSize.BottomInclusive()) };
+        pos = { pos.X, std::clamp(pos.Y - 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
         break;
     }
     case SelectionDirection::Down:
     {
         const auto bufferSize{ _activeBuffer().GetSize() };
-        pos = { pos.X, std::clamp(base::ClampAdd<short, short>(pos.Y, 1).RawValue(), bufferSize.Top(), bufferSize.BottomInclusive()) };
+        pos = { pos.X, std::clamp(pos.Y + 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
         break;
     }
     }
 }
 
-void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
+void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
 {
     switch (direction)
     {
     case SelectionDirection::Left:
+    {
         const auto wordStartPos{ _activeBuffer().GetWordStart(pos, _wordDelimiters) };
         if (_activeBuffer().GetSize().CompareInBounds(_selection->pivot, pos) < 0)
         {
@@ -441,7 +442,9 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
             pos = wordStartPos;
         }
         break;
+    }
     case SelectionDirection::Right:
+    {
         const auto wordEndPos{ _activeBuffer().GetWordEnd(pos, _wordDelimiters) };
         if (_activeBuffer().GetSize().CompareInBounds(pos, _selection->pivot) < 0)
         {
@@ -462,6 +465,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
             pos = wordEndPos;
         }
         break;
+    }
     case SelectionDirection::Up:
         _MoveByChar(direction, pos);
         pos = _activeBuffer().GetWordStart(pos, _wordDelimiters);
@@ -473,7 +477,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
     }
 }
 
-void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
+void Terminal::_MoveByViewport(SelectionDirection direction, til::point& pos)
 {
     const auto bufferSize{ _activeBuffer().GetSize() };
     switch (direction)
@@ -487,22 +491,22 @@ void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
     case SelectionDirection::Up:
     {
         const auto viewportHeight{ _GetMutableViewport().Height() };
-        const auto newY{ base::ClampSub<short, short>(pos.Y, viewportHeight) };
-        pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY };
+        const auto newY{ pos.Y - viewportHeight };
+        pos = newY < bufferSize.Top() ? bufferSize.Origin() : til::point{ pos.X, newY };
         break;
     }
     case SelectionDirection::Down:
     {
         const auto viewportHeight{ _GetMutableViewport().Height() };
         const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
-        const auto newY{ base::ClampAdd<short, short>(pos.Y, viewportHeight) };
-        pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY };
+        const auto newY{ pos.Y + viewportHeight };
+        pos = newY > mutableBottom ? til::point{ bufferSize.RightInclusive(), mutableBottom } : til::point{ pos.X, newY };
         break;
     }
     }
 }
 
-void Terminal::_MoveByBuffer(SelectionDirection direction, COORD& pos)
+void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos)
 {
     const auto bufferSize{ _activeBuffer().GetSize() };
     switch (direction)
@@ -559,10 +563,10 @@ const TextBuffer::TextAndColor Terminal::RetrieveSelectedTextFromBuffer(bool sin
 // - viewportPos: a coordinate on the viewport
 // Return Value:
 // - the corresponding location on the buffer
-COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
+til::point Terminal::_ConvertToBufferCell(const til::point viewportPos) const
 {
-    const auto yPos = base::ClampedNumeric<short>(_VisibleStartIndex()) + viewportPos.Y;
-    COORD bufferPos = { viewportPos.X, yPos };
+    const auto yPos = _VisibleStartIndex() + viewportPos.Y;
+    til::point bufferPos = { viewportPos.X, yPos };
     _activeBuffer().GetSize().Clamp(bufferPos);
     return bufferPos;
 }
@@ -574,7 +578,7 @@ COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
 // - coordSelectionStart - Not used
 // - coordSelectionEnd - Not used
 // - attr - Not used.
-void Terminal::ColorSelection(const COORD, const COORD, const TextAttribute)
+void Terminal::ColorSelection(const til::point, const til::point, const TextAttribute)
 {
     THROW_HR(E_NOTIMPL);
 }
diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp
index 56b6a058072..2e3e695498e 100644
--- a/src/cascadia/TerminalCore/terminalrenderdata.cpp
+++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp
@@ -14,13 +14,12 @@ Viewport Terminal::GetViewport() noexcept
     return _GetVisibleViewport();
 }
 
-COORD Terminal::GetTextBufferEndPosition() const noexcept
+til::point Terminal::GetTextBufferEndPosition() const noexcept
 {
     // We use the end line of mutableViewport as the end
     // of the text buffer, it always moves with the written
     // text
-    COORD endPosition{ _GetMutableViewport().Width() - 1, gsl::narrow<short>(ViewEndIndex()) };
-    return endPosition;
+    return { _GetMutableViewport().Width() - 1, ViewEndIndex() };
 }
 
 const TextBuffer& Terminal::GetTextBuffer() const noexcept
@@ -38,7 +37,7 @@ void Terminal::SetFontInfo(const FontInfo& fontInfo)
     _fontInfo = fontInfo;
 }
 
-COORD Terminal::GetCursorPosition() const noexcept
+til::point Terminal::GetCursorPosition() const noexcept
 {
     const auto& cursor = _activeBuffer().GetCursor();
     return cursor.GetPosition();
@@ -104,10 +103,10 @@ const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkCustomId(uin
 // - The location
 // Return value:
 // - The pattern IDs of the location
-const std::vector<size_t> Terminal::GetPatternId(const COORD location) const noexcept
+const std::vector<size_t> Terminal::GetPatternId(const til::point location) const noexcept
 {
     // Look through our interval tree for this location
-    const auto intervals = _patternIntervalTree.findOverlapping(til::point{ location.X + 1, location.Y }, til::point{ location });
+    const auto intervals = _patternIntervalTree.findOverlapping({ location.X + 1, location.Y }, location);
     if (intervals.size() == 0)
     {
         return {};
@@ -147,7 +146,7 @@ catch (...)
     return {};
 }
 
-void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
+void Terminal::SelectNewRegion(const til::point coordStart, const til::point coordEnd)
 {
 #pragma warning(push)
 #pragma warning(disable : 26496) // cpp core checks wants these const, but they're decremented below.
@@ -178,8 +177,8 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
         _NotifyScrollEvent();
     }
 
-    realCoordStart.Y -= gsl::narrow<short>(_VisibleStartIndex());
-    realCoordEnd.Y -= gsl::narrow<short>(_VisibleStartIndex());
+    realCoordStart.Y -= _VisibleStartIndex();
+    realCoordEnd.Y -= _VisibleStartIndex();
 
     SetSelectionAnchor(realCoordStart);
     SetSelectionEnd(realCoordEnd, SelectionExpansion::Char);
diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp
index f23c42b5b4c..1533614d12a 100644
--- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp
+++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp
@@ -440,7 +440,7 @@ namespace ControlUnitTests
         Log::Comment(L"Verify the location of the selection");
         // The viewport is on row 21, so the selection will be on:
         // {(5, 5)+(0, 21)} to {(5, 5)+(0, 21)}
-        COORD expectedAnchor{ 5, 26 };
+        til::point expectedAnchor{ 5, 26 };
         VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
         VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
 
@@ -453,7 +453,7 @@ namespace ControlUnitTests
         Log::Comment(L"Verify the location of the selection");
         // The viewport is now on row 20, so the selection will be on:
         // {(5, 5)+(0, 20)} to {(5, 5)+(0, 21)}
-        COORD newExpectedAnchor{ 5, 25 };
+        til::point newExpectedAnchor{ 5, 25 };
         // Remember, the anchor is always before the end in the buffer. So yes,
         // se started the selection on 5,26, but now that's the end.
         VERIFY_ARE_EQUAL(newExpectedAnchor, core->_terminal->GetSelectionAnchor());
@@ -586,7 +586,7 @@ namespace ControlUnitTests
         VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size());
 
         Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to");
-        COORD expectedAnchor{ 0, 0 };
+        til::point expectedAnchor{ 0, 0 };
         VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
     }
 
@@ -631,9 +631,9 @@ namespace ControlUnitTests
         VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size());
 
         Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to");
-        COORD expectedAnchor{ 0, 0 };
+        til::point expectedAnchor{ 0, 0 };
         VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
-        COORD expectedEnd{ 2, 0 };
+        til::point expectedEnd{ 2, 0 };
         VERIFY_ARE_EQUAL(expectedEnd, core->_terminal->GetSelectionEnd());
 
         interactivity->PointerReleased(noMouseDown,
@@ -801,7 +801,7 @@ namespace ControlUnitTests
         Log::Comment(L"Verify the location of the selection");
         // The viewport is on row (historySize + 5), so the selection will be on:
         // {(5, (historySize+5))+(0, 21)} to {(5, (historySize+5))+(0, 21)}
-        COORD expectedAnchor{ 5, gsl::narrow_cast<SHORT>(settings->HistorySize()) + 5 };
+        til::point expectedAnchor{ 5, settings->HistorySize() + 5 };
         VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
         VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
 
diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
index 60d8a725153..69f19e67eda 100644
--- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
@@ -52,8 +52,8 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final
     // !!! DANGER: Many tests in this class expect the Terminal and Host buffers
     // to be 80x32. If you change these, you'll probably inadvertently break a
     // bunch of tests !!!
-    static const SHORT TerminalViewWidth = 80;
-    static const SHORT TerminalViewHeight = 32;
+    static const til::CoordType TerminalViewWidth = 80;
+    static const til::CoordType TerminalViewHeight = 32;
 
     // This test class is for tests that are supposed to emit something in the PTY layer
     // and then check that they've been staged for presentation correctly inside
@@ -108,7 +108,7 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final
         // Make sure a test hasn't left us in the alt buffer on accident
         VERIFY_IS_FALSE(currentBuffer._IsAltBuffer());
         VERIFY_SUCCEEDED(currentBuffer.SetViewportOrigin(true, { 0, 0 }, true));
-        VERIFY_ARE_EQUAL(COORD({ 0, 0 }), currentBuffer.GetTextBuffer().GetCursor().GetPosition());
+        VERIFY_ARE_EQUAL(til::point{}, currentBuffer.GetTextBuffer().GetCursor().GetPosition());
 
         // Set up an xterm-256 renderer for conpty
         auto hFile = wil::unique_hfile(INVALID_HANDLE_VALUE);
@@ -230,7 +230,7 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final
 private:
     bool _writeCallback(const char* const pch, const size_t cch);
     void _flushFirstFrame();
-    void _resizeConpty(const unsigned short sx, const unsigned short sy);
+    void _resizeConpty(const til::CoordType sx, const til::CoordType sy);
     void _clearConpty();
 
     [[nodiscard]] std::tuple<TextBuffer*, TextBuffer*> _performResize(const til::size newSize);
@@ -295,8 +295,8 @@ void ConptyRoundtripTests::_flushFirstFrame()
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 }
 
-void ConptyRoundtripTests::_resizeConpty(const unsigned short sx,
-                                         const unsigned short sy)
+void ConptyRoundtripTests::_resizeConpty(const til::CoordType sx,
+                                         const til::CoordType sy)
 {
     // Largely taken from implementation in PtySignalInputThread::_InputThread
     if (_pConApi->ResizeWindow(sx, sy))
@@ -322,9 +322,9 @@ void ConptyRoundtripTests::_clearConpty()
 
     Log::Comment(L"========== Resize the Terminal and conpty ==========");
 
-    auto resizeResult = term->UserResize(newSize.to_win32_coord());
+    auto resizeResult = term->UserResize(newSize);
     VERIFY_SUCCEEDED(resizeResult);
-    _resizeConpty(newSize.narrow_width<unsigned short>(), newSize.narrow_height<unsigned short>());
+    _resizeConpty(newSize.width, newSize.height);
 
     // After we resize, make sure to get the new textBuffers
     return { &ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer().GetTextBuffer(),
@@ -456,7 +456,7 @@ void ConptyRoundtripTests::TestWrappingALongString()
 
     const auto initialTermView = term->GetViewport();
 
-    const auto charsToWrite = gsl::narrow_cast<short>(TestUtils::Test100CharsString.size());
+    const auto charsToWrite = gsl::narrow_cast<til::CoordType>(TestUtils::Test100CharsString.size());
     VERIFY_ARE_EQUAL(100, charsToWrite);
 
     VERIFY_ARE_EQUAL(0, initialTermView.Top());
@@ -505,7 +505,7 @@ void ConptyRoundtripTests::TestAdvancedWrapping()
 
     _flushFirstFrame();
 
-    const auto charsToWrite = gsl::narrow_cast<short>(TestUtils::Test100CharsString.size());
+    const auto charsToWrite = gsl::narrow_cast<til::CoordType>(TestUtils::Test100CharsString.size());
     VERIFY_ARE_EQUAL(100, charsToWrite);
 
     hostSm.ProcessString(TestUtils::Test100CharsString);
@@ -802,9 +802,7 @@ void ConptyRoundtripTests::TestResizeHeight()
     // If we've printed more lines than the height of the buffer, then we're
     // expecting the viewport to have moved down. Otherwise, the terminal's
     // viewport will stay at 0,0.
-    const auto expectedTerminalViewBottom = std::max(std::min(::base::saturated_cast<short>(printedRows + 1),
-                                                              term->GetBufferHeight()),
-                                                     term->GetViewport().Height());
+    const auto expectedTerminalViewBottom = std::max(std::min(printedRows + 1, term->GetBufferHeight()), term->GetViewport().Height());
 
     VERIFY_ARE_EQUAL(expectedTerminalViewBottom, secondTermView.BottomExclusive());
     VERIFY_ARE_EQUAL(expectedTerminalViewBottom - initialTermView.Height(), secondTermView.Top());
@@ -816,11 +814,9 @@ void ConptyRoundtripTests::TestResizeHeight()
         const auto numLostRows = std::max(0,
                                           printedRows - std::min(term->GetTextBuffer().GetSize().Height(), initialTerminalBufferHeight) + 1);
 
-        const auto rowsWithText = std::min(::base::saturated_cast<short>(printedRows),
-                                           expectedTerminalViewBottom) -
-                                  1 + std::min(resizeDy, 0);
+        const auto rowsWithText = std::min(printedRows, expectedTerminalViewBottom) - 1 + std::min(resizeDy, 0);
 
-        for (short row = 0; row < rowsWithText; row++)
+        for (til::CoordType row = 0; row < rowsWithText; row++)
         {
             SetVerifyOutput settings(VerifyOutputSettings::LogOnlyFailures);
             auto iter = termTb.GetCellDataAt({ 0, row });
@@ -854,9 +850,7 @@ void ConptyRoundtripTests::TestResizeHeight()
         //   characters, but then we'll want to look for more blank rows at the
         //   bottom. The characters in the initial viewport won't have moved.
 
-        const auto originalViewHeight = ::base::saturated_cast<short>(resizeDy < 0 ?
-                                                                          initialHostView.Height() + resizeDy :
-                                                                          initialHostView.Height());
+        const auto originalViewHeight = resizeDy < 0 ? initialHostView.Height() + resizeDy : initialHostView.Height();
         const auto rowsWithText = std::min(originalViewHeight - 1, printedRows);
         const auto scrolled = printedRows > initialHostView.Height();
         // The last row of the viewport should be empty
@@ -868,7 +862,7 @@ void ConptyRoundtripTests::TestResizeHeight()
                                                         (printedRows - originalViewHeight + 1) :
                                                         0);
 
-        short row = 0;
+        til::CoordType row = 0;
         // Don't include the last row of the viewport in this check, since it'll
         // be blank. We'll check it in the below loop.
         for (; row < rowsWithText; row++)
@@ -1029,7 +1023,7 @@ void ConptyRoundtripTests::PassthroughClearScrollback()
 
     // Verify that we've printed height*2 lines of X's to the Terminal
     const auto termFirstView = term->GetViewport();
-    for (short y = 0; y < 2 * termFirstView.Height(); y++)
+    for (til::CoordType y = 0; y < 2 * termFirstView.Height(); y++)
     {
         TestUtils::VerifyExpectedString(termTb, L"X  ", { 0, y });
     }
@@ -1046,7 +1040,7 @@ void ConptyRoundtripTests::PassthroughClearScrollback()
     VERIFY_ARE_EQUAL(0, termSecondView.Top());
 
     // Verify the top of the Terminal viewport contains the contents of the old viewport
-    for (short y = 0; y < termSecondView.BottomInclusive(); y++)
+    for (til::CoordType y = 0; y < termSecondView.BottomInclusive(); y++)
     {
         TestUtils::VerifyExpectedString(termTb, L"X  ", { 0, y });
     }
@@ -1094,15 +1088,15 @@ void ConptyRoundtripTests::PassthroughClearAll()
     }
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const bool afterClear = false) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
 
         // "~" rows
-        for (short row = 0; row < viewport.narrow_bottom<short>(); row++)
+        for (til::CoordType row = 0; row < viewport.bottom; row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
             VERIFY_IS_FALSE(tb.GetRowByOffset(row).WasWrapForced());
             auto iter = tb.GetCellDataAt({ 0, row });
-            if (afterClear && row >= viewport.narrow_top<short>())
+            if (afterClear && row >= viewport.top)
             {
                 TestUtils::VerifySpanOfText(L" ", iter, 0, width);
             }
@@ -1115,13 +1109,13 @@ void ConptyRoundtripTests::PassthroughClearAll()
     };
 
     Log::Comment(L"========== Checking the host buffer state (before) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (before) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 
     const til::rect originalTerminalView{ term->_mutableViewport.ToInclusive() };
 
@@ -1135,11 +1129,11 @@ void ConptyRoundtripTests::PassthroughClearAll()
     // Make sure that the terminal's new viewport is actually just lower than it
     // used to be.
     const til::rect newTerminalView{ term->_mutableViewport.ToInclusive() };
-    VERIFY_ARE_EQUAL(end, newTerminalView.narrow_top<short>());
+    VERIFY_ARE_EQUAL(end, newTerminalView.top);
     VERIFY_IS_GREATER_THAN(newTerminalView.top, originalTerminalView.top);
 
     Log::Comment(L"========== Checking the host buffer state (after) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
@@ -1193,7 +1187,7 @@ void ConptyRoundtripTests::PassthroughHardReset()
 
     // Verify that we've printed height*2 lines of X's to the Terminal
     const auto termFirstView = term->GetViewport();
-    for (short y = 0; y < 2 * termFirstView.Height(); y++)
+    for (til::CoordType y = 0; y < 2 * termFirstView.Height(); y++)
     {
         TestUtils::VerifyExpectedString(termTb, L"X  ", { 0, y });
     }
@@ -1206,7 +1200,7 @@ void ConptyRoundtripTests::PassthroughHardReset()
     VERIFY_ARE_EQUAL(0, termSecondView.Top());
 
     // Verify everything has been cleared out
-    for (short y = 0; y < termFirstView.BottomInclusive(); y++)
+    for (til::CoordType y = 0; y < termFirstView.BottomInclusive(); y++)
     {
         TestUtils::VerifyExpectedString(termTb, std::wstring(TerminalViewWidth, L' '), { 0, y });
     }
@@ -1359,7 +1353,7 @@ void ConptyRoundtripTests::OutputWrappedLinesAtBottomOfBuffer()
 
     hostSm.ProcessString(std::wstring(wrappedLineLength, L'A'));
 
-    auto verifyBuffer = [](const TextBuffer& tb, const short wrappedRow) {
+    auto verifyBuffer = [](const TextBuffer& tb, const til::CoordType wrappedRow) {
         // Buffer contents should look like the following: (80 wide)
         // (w) means we hard wrapped the line
         // (b) means the line is _not_ wrapped (it's broken, the default state.)
@@ -1377,9 +1371,9 @@ void ConptyRoundtripTests::OutputWrappedLinesAtBottomOfBuffer()
 
         auto iter0 = tb.GetCellDataAt({ 0, wrappedRow });
         TestUtils::VerifySpanOfText(L"A", iter0, 0, TerminalViewWidth);
-        auto iter1 = tb.GetCellDataAt({ 0, gsl::narrow<short>(wrappedRow + 1) });
+        auto iter1 = tb.GetCellDataAt({ 0, wrappedRow + 1 });
         TestUtils::VerifySpanOfText(L"A", iter1, 0, 20);
-        auto iter2 = tb.GetCellDataAt({ 20, gsl::narrow<short>(wrappedRow + 1) });
+        auto iter2 = tb.GetCellDataAt({ 20, wrappedRow + 1 });
         TestUtils::VerifySpanOfText(L" ", iter2, 0, TerminalViewWidth - 20);
     };
 
@@ -1465,8 +1459,8 @@ void ConptyRoundtripTests::ScrollWithChangesInMiddle()
     hostSm.ProcessString(std::wstring(wrappedLineLength, L'A')); // Print 100 'A's
 
     auto verifyBuffer = [](const TextBuffer& tb, const til::rect& viewport) {
-        const auto wrappedRow = gsl::narrow<short>(viewport.bottom - 2);
-        const auto start = viewport.narrow_top<short>();
+        const auto wrappedRow = viewport.bottom - 2;
+        const auto start = viewport.top;
         for (auto i = start; i < wrappedRow; i++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", i));
@@ -1479,20 +1473,20 @@ void ConptyRoundtripTests::ScrollWithChangesInMiddle()
         auto iter0 = tb.GetCellDataAt({ 0, wrappedRow });
         TestUtils::VerifySpanOfText(L"A", iter0, 0, TerminalViewWidth);
 
-        auto iter1 = tb.GetCellDataAt({ 0, gsl::narrow<short>(wrappedRow + 1) });
+        auto iter1 = tb.GetCellDataAt({ 0, wrappedRow + 1 });
         TestUtils::VerifySpanOfText(L"A", iter1, 0, 20);
-        auto iter2 = tb.GetCellDataAt({ 20, gsl::narrow<short>(wrappedRow + 1) });
+        auto iter2 = tb.GetCellDataAt({ 20, wrappedRow + 1 });
         TestUtils::VerifySpanOfText(L" ", iter2, 0, TerminalViewWidth - 20);
     };
 
     Log::Comment(NoThrowString().Format(L"Checking the host buffer..."));
-    verifyBuffer(hostTb, til::rect{ hostView.ToInclusive() });
+    verifyBuffer(hostTb, hostView.ToExclusive());
     Log::Comment(NoThrowString().Format(L"... Done"));
 
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(NoThrowString().Format(L"Checking the terminal buffer..."));
-    verifyBuffer(termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(termTb, term->_mutableViewport.ToExclusive());
     Log::Comment(NoThrowString().Format(L"... Done"));
 }
 
@@ -1558,13 +1552,13 @@ void ConptyRoundtripTests::ScrollWithMargins()
         for (auto i = 0; i < rowsToWrite; ++i)
         {
             const std::wstring expectedString(4, static_cast<wchar_t>(L'A' + i));
-            const COORD expectedPos{ 0, gsl::narrow<SHORT>(i) };
+            const til::point expectedPos{ 0, i };
             TestUtils::VerifyExpectedString(tb, expectedString, expectedPos);
         }
 
         // For the last row, verify we have an entire row of asterisks for the mode line.
         const std::wstring expectedModeLine(initialTermView.Width() - 1, L'*');
-        const COORD expectedPos{ 0, gsl::narrow<SHORT>(rowsToWrite) };
+        const til::point expectedPos{ 0, rowsToWrite };
         TestUtils::VerifyExpectedString(tb, expectedModeLine, expectedPos);
     };
 
@@ -1675,21 +1669,21 @@ void ConptyRoundtripTests::ScrollWithMargins()
         {
             // Start with B this time because the A line got scrolled off the top.
             const std::wstring expectedString(4, static_cast<wchar_t>(L'B' + i));
-            const COORD expectedPos{ 0, gsl::narrow<SHORT>(i) };
+            const til::point expectedPos{ 0, i };
             TestUtils::VerifyExpectedString(tb, expectedString, expectedPos);
         }
 
         // For the second to last row, verify that it is blank.
         {
             const std::wstring expectedBlankLine(initialTermView.Width(), L' ');
-            const COORD blankLinePos{ 0, gsl::narrow<SHORT>(rowsToWrite - 1) };
+            const til::point blankLinePos{ 0, rowsToWrite - 1 };
             TestUtils::VerifyExpectedString(tb, expectedBlankLine, blankLinePos);
         }
 
         // For the last row, verify we have an entire row of asterisks for the mode line.
         {
             const std::wstring expectedModeLine(initialTermView.Width() - 1, L'*');
-            const COORD modeLinePos{ 0, gsl::narrow<SHORT>(rowsToWrite) };
+            const til::point modeLinePos{ 0, rowsToWrite };
             TestUtils::VerifyExpectedString(tb, expectedModeLine, modeLinePos);
         }
     };
@@ -1757,7 +1751,7 @@ void ConptyRoundtripTests::DontWrapMoveCursorInSingleFrame()
         // Simple verification: Make sure the cursor is in the correct place,
         // and that it's visible. We don't care so much about the buffer
         // contents in this test.
-        const COORD expectedCursor{ 8, 3 };
+        const til::point expectedCursor{ 8, 3 };
         VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         VERIFY_IS_TRUE(tb.GetCursor().IsVisible());
     };
@@ -1851,11 +1845,11 @@ void ConptyRoundtripTests::ClearHostTrickeryTest()
         // We _would_ expect the Terminal's cursor to be on { 8, 0 }, but this
         // is currently broken due to #381/#4676. So we'll use the viewport
         // provided to find the actual Y position of the cursor.
-        const auto viewTop = viewport.origin().narrow_y<short>();
-        const short cursorRow = viewTop + (cursorOnNextLine ? 1 : 0);
-        const short cursorCol = (cursorOnNextLine ? 5 :
-                                                    (10 + (useLongSpaces ? 5 : 0) + (printTextAfterSpaces ? 5 : 0)));
-        const COORD expectedCursor{ cursorCol, cursorRow };
+        const auto viewTop = viewport.origin().y;
+        const auto cursorRow = viewTop + (cursorOnNextLine ? 1 : 0);
+        const auto cursorCol = (cursorOnNextLine ? 5 :
+                                                   (10 + (useLongSpaces ? 5 : 0) + (printTextAfterSpaces ? 5 : 0)));
+        const til::point expectedCursor{ cursorCol, cursorRow };
 
         VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         VERIFY_IS_TRUE(tb.GetCursor().IsVisible());
@@ -1928,13 +1922,13 @@ void ConptyRoundtripTests::ClearHostTrickeryTest()
     hostSm.ProcessString(L"\x1b[?1049l");
 
     Log::Comment(L"Checking the host buffer state");
-    verifyBuffer(hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"Checking the terminal buffer state");
-    verifyBuffer(termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::OverstrikeAtBottomOfBuffer()
@@ -1958,12 +1952,12 @@ void ConptyRoundtripTests::OverstrikeAtBottomOfBuffer()
                            const til::rect viewport) {
         const auto lastRow = viewport.bottom - 1;
         const til::point expectedCursor{ 0, lastRow - 1 };
-        VERIFY_ARE_EQUAL(expectedCursor, til::point{ tb.GetCursor().GetPosition() });
+        VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         VERIFY_IS_TRUE(tb.GetCursor().IsVisible());
 
-        TestUtils::VerifyExpectedString(tb, L"AAAAAAAAAA          DDDDDDDDDD", COORD{ 0, gsl::narrow<short>(lastRow - 2) });
-        TestUtils::VerifyExpectedString(tb, L"BBBBBBBBBB", COORD{ 0, gsl::narrow<short>(lastRow - 1) });
-        TestUtils::VerifyExpectedString(tb, L"FFFFFFFFFE", COORD{ 0, gsl::narrow<short>(lastRow) });
+        TestUtils::VerifyExpectedString(tb, L"AAAAAAAAAA          DDDDDDDDDD", { 0, lastRow - 2 });
+        TestUtils::VerifyExpectedString(tb, L"BBBBBBBBBB", { 0, lastRow - 1 });
+        TestUtils::VerifyExpectedString(tb, L"FFFFFFFFFE", { 0, lastRow });
     };
 
     _logConpty = true;
@@ -2000,14 +1994,14 @@ void ConptyRoundtripTests::OverstrikeAtBottomOfBuffer()
     hostSm.ProcessString(L"\n");
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state ==========");
 
-    verifyBuffer(termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::MarginsWithStatusLine()
@@ -2034,16 +2028,16 @@ void ConptyRoundtripTests::MarginsWithStatusLine()
 
     auto verifyBuffer = [](const TextBuffer& tb,
                            const til::rect viewport) {
-        const auto lastRow = gsl::narrow<short>(viewport.bottom - 1);
+        const auto lastRow = viewport.bottom - 1;
         const til::point expectedCursor{ 1, lastRow };
-        VERIFY_ARE_EQUAL(expectedCursor, til::point{ tb.GetCursor().GetPosition() });
+        VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         VERIFY_IS_TRUE(tb.GetCursor().IsVisible());
 
-        TestUtils::VerifyExpectedString(tb, L"EEEEEEEEEE", COORD{ 0, gsl::narrow<short>(lastRow - 4) });
-        TestUtils::VerifyExpectedString(tb, L"AAAAAAAAAA", COORD{ 0, gsl::narrow<short>(lastRow - 3) });
-        TestUtils::VerifyExpectedString(tb, L"          ", COORD{ 0, gsl::narrow<short>(lastRow - 2) });
-        TestUtils::VerifyExpectedString(tb, L"XBBBBBBBBB", COORD{ 0, gsl::narrow<short>(lastRow - 1) });
-        TestUtils::VerifyExpectedString(tb, L"YCCCCCCCCC", COORD{ 0, lastRow });
+        TestUtils::VerifyExpectedString(tb, L"EEEEEEEEEE", { 0, lastRow - 4 });
+        TestUtils::VerifyExpectedString(tb, L"AAAAAAAAAA", { 0, lastRow - 3 });
+        TestUtils::VerifyExpectedString(tb, L"          ", { 0, lastRow - 2 });
+        TestUtils::VerifyExpectedString(tb, L"XBBBBBBBBB", { 0, lastRow - 1 });
+        TestUtils::VerifyExpectedString(tb, L"YCCCCCCCCC", { 0, lastRow });
     };
 
     // We're _not_ checking the conpty output during this test, only the side effects.
@@ -2078,12 +2072,12 @@ void ConptyRoundtripTests::MarginsWithStatusLine()
     {
         // Emulate calling ScrollConsoleScreenBuffer to scroll the B and C lines
         // down one line.
-        SMALL_RECT src;
+        til::inclusive_rect src;
         src.Top = newBottom - 2;
         src.Left = 0;
         src.Right = si.GetViewport().Width();
         src.Bottom = originalBottom;
-        COORD tgt{ 0, gsl::narrow<short>(newBottom - 1) };
+        til::point tgt{ 0, newBottom - 1 };
         TextAttribute useThisAttr(0x07); // We don't terribly care about the attributes so this is arbitrary
         ScrollRegion(si, src, std::nullopt, tgt, L' ', useThisAttr);
     }
@@ -2097,14 +2091,14 @@ void ConptyRoundtripTests::MarginsWithStatusLine()
     hostSm.ProcessString(L"Y");
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state ==========");
 
-    verifyBuffer(termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::OutputWrappedLineWithSpace()
@@ -2289,7 +2283,7 @@ void ConptyRoundtripTests::OutputWrappedLineWithSpaceAtBottomOfBuffer()
         // | B_ ...    | (b) (cursor is on the '_')
         // |    ...    | (b)
 
-        const auto wrappedRow = gsl::narrow<short>(viewport.bottom - 2);
+        const auto wrappedRow = viewport.bottom - 2;
         VERIFY_IS_TRUE(tb.GetRowByOffset(wrappedRow).WasWrapForced());
         VERIFY_IS_FALSE(tb.GetRowByOffset(wrappedRow + 1).WasWrapForced());
 
@@ -2299,20 +2293,20 @@ void ConptyRoundtripTests::OutputWrappedLineWithSpaceAtBottomOfBuffer()
         TestUtils::VerifySpanOfText(L" ", iter0, 0, 2);
 
         // Second row
-        auto iter1 = tb.GetCellDataAt({ 0, gsl::narrow<short>(wrappedRow + 1) });
+        auto iter1 = tb.GetCellDataAt({ 0, wrappedRow + 1 });
         TestUtils::VerifySpanOfText(L" ", iter1, 0, 1);
-        auto iter2 = tb.GetCellDataAt({ 1, gsl::narrow<short>(wrappedRow + 1) });
+        auto iter2 = tb.GetCellDataAt({ 1, wrappedRow + 1 });
         TestUtils::VerifySpanOfText(L"B", iter2, 0, secondTextLength);
     };
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(hostTb, til::rect{ hostView.ToInclusive() });
+    verifyBuffer(hostTb, hostView.ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state ==========");
-    verifyBuffer(termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::BreakLinesOnCursorMovement()
@@ -2350,21 +2344,21 @@ void ConptyRoundtripTests::BreakLinesOnCursorMovement()
 
     auto verifyBuffer = [&](const TextBuffer& tb,
                             const til::rect viewport) {
-        const auto lastRow = gsl::narrow<short>(viewport.bottom - 1);
+        const auto lastRow = viewport.bottom - 1;
         const til::point expectedCursor{ 5, lastRow };
-        VERIFY_ARE_EQUAL(expectedCursor, til::point{ tb.GetCursor().GetPosition() });
+        VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         VERIFY_IS_TRUE(tb.GetCursor().IsVisible());
 
-        for (auto y = viewport.narrow_top<short>(); y < lastRow; y++)
+        for (auto y = viewport.top; y < lastRow; y++)
         {
             // We're using CUP to move onto the status line _always_, so the
             // second-last row will always be marked as wrapped.
             const auto rowWrapped = (!expectHardBreak) || (y == lastRow - 1);
             VERIFY_ARE_EQUAL(rowWrapped, tb.GetRowByOffset(y).WasWrapForced());
-            TestUtils::VerifyExpectedString(tb, L"~    ", COORD{ 0, y });
+            TestUtils::VerifyExpectedString(tb, L"~    ", { 0, y });
         }
 
-        TestUtils::VerifyExpectedString(tb, L"AAAAA", COORD{ 0, lastRow });
+        TestUtils::VerifyExpectedString(tb, L"AAAAA", { 0, lastRow });
     };
 
     // We're _not_ checking the conpty output during this test, only the side effects.
@@ -2473,7 +2467,7 @@ void ConptyRoundtripTests::BreakLinesOnCursorMovement()
     hostSm.ProcessString(L"AAAAA");
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(altTextBuffer, til::rect{ altBuffer.GetViewport().ToInclusive() });
+    verifyBuffer(altTextBuffer, altBuffer.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
@@ -2481,7 +2475,7 @@ void ConptyRoundtripTests::BreakLinesOnCursorMovement()
     Log::Comment(L"========== Checking the terminal buffer state ==========");
     // GH#3492: Now that we support the alt buffer, make sure to validate the
     // _alt buffer's_ contents.
-    verifyBuffer(*term->_altBuffer, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*term->_altBuffer, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::TestCursorInDeferredEOLPositionOnNewLineWithSpaces()
@@ -2504,7 +2498,7 @@ void ConptyRoundtripTests::TestCursorInDeferredEOLPositionOnNewLineWithSpaces()
     // fill width-1 with "A", then add one space and another character..
     hostSm.ProcessString(std::wstring(gsl::narrow_cast<size_t>(TerminalViewWidth) - 1, L'A') + L" B");
 
-    auto verifyBuffer = [&](const TextBuffer& tb, SHORT bottomRow) {
+    auto verifyBuffer = [&](const TextBuffer& tb, til::CoordType bottomRow) {
         // Buffer contents should look like the following: (80 wide)
         // (w) means we hard wrapped the line
         // (b) means the line is _not_ wrapped (it's broken, the default state.)
@@ -2517,7 +2511,7 @@ void ConptyRoundtripTests::TestCursorInDeferredEOLPositionOnNewLineWithSpaces()
 
         til::point cursorPos{ tb.GetCursor().GetPosition() };
         // The cursor should be on the second char of the last line
-        VERIFY_ARE_EQUAL((til::point{ 1, bottomRow }), cursorPos);
+        VERIFY_ARE_EQUAL(til::point(1, bottomRow), cursorPos);
 
         const auto& secondToLastRow = tb.GetRowByOffset(bottomRow - 1);
         const auto& lastRow = tb.GetRowByOffset(bottomRow);
@@ -2525,7 +2519,7 @@ void ConptyRoundtripTests::TestCursorInDeferredEOLPositionOnNewLineWithSpaces()
         VERIFY_IS_FALSE(lastRow.WasWrapForced());
 
         auto expectedStringSecondToLastRow{ std::wstring(gsl::narrow_cast<size_t>(tb.GetSize().Width()) - 1, L'A') + L" " };
-        TestUtils::VerifyExpectedString(tb, expectedStringSecondToLastRow, { 0, gsl::narrow<short>(bottomRow - 1) });
+        TestUtils::VerifyExpectedString(tb, expectedStringSecondToLastRow, { 0, bottomRow - 1 });
         TestUtils::VerifyExpectedString(tb, L"B", { 0, bottomRow });
     };
 
@@ -2595,8 +2589,8 @@ void ConptyRoundtripTests::ResizeRepaintVimExeBuffer()
     drawVim();
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport) {
-        const auto firstRow = viewport.narrow_top<short>();
-        const auto width = viewport.narrow_width<short>();
+        const auto firstRow = viewport.top;
+        const auto width = viewport.width();
 
         // First row
         VERIFY_IS_FALSE(tb.GetRowByOffset(firstRow).WasWrapForced());
@@ -2606,12 +2600,12 @@ void ConptyRoundtripTests::ResizeRepaintVimExeBuffer()
 
         // Second row
         VERIFY_IS_FALSE(tb.GetRowByOffset(firstRow + 1).WasWrapForced());
-        auto iter1 = tb.GetCellDataAt({ 0, gsl::narrow<short>(firstRow + 1) });
+        auto iter1 = tb.GetCellDataAt({ 0, firstRow + 1 });
         TestUtils::VerifySpanOfText(L"B", iter1, 0, 3);
         TestUtils::VerifySpanOfText(L" ", iter1, 0, width - 3);
 
         // "~" rows
-        for (short row = firstRow + 2; row < viewport.bottom - 1; row++)
+        for (auto row = firstRow + 2; row < viewport.bottom - 1; row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
             VERIFY_IS_TRUE(tb.GetRowByOffset(row).WasWrapForced());
@@ -2622,7 +2616,7 @@ void ConptyRoundtripTests::ResizeRepaintVimExeBuffer()
 
         // Last row
         {
-            const auto row = gsl::narrow<short>(viewport.bottom - 1);
+            const auto row = viewport.bottom - 1;
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
             VERIFY_IS_TRUE(tb.GetRowByOffset(row).WasWrapForced());
             auto iter = tb.GetCellDataAt({ 0, row });
@@ -2632,13 +2626,13 @@ void ConptyRoundtripTests::ResizeRepaintVimExeBuffer()
     };
 
     Log::Comment(L"========== Checking the host buffer state (before) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (before) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 
     // After we resize, make sure to get the new textBuffers
     std::tie(hostTb, termTb) = _performResize({ TerminalViewWidth - 1,
@@ -2652,13 +2646,13 @@ void ConptyRoundtripTests::ResizeRepaintVimExeBuffer()
     drawVim();
 
     Log::Comment(L"========== Checking the host buffer state (after) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (after) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::ClsAndClearHostClearsScrollbackTest()
@@ -2705,10 +2699,10 @@ void ConptyRoundtripTests::ClsAndClearHostClearsScrollbackTest()
     }
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const bool afterClear = false) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
 
         // "~" rows
-        for (short row = 0; row < viewport.narrow_bottom<short>(); row++)
+        for (til::CoordType row = 0; row < viewport.bottom; row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
             VERIFY_IS_FALSE(tb.GetRowByOffset(row).WasWrapForced());
@@ -2726,13 +2720,13 @@ void ConptyRoundtripTests::ClsAndClearHostClearsScrollbackTest()
     };
 
     Log::Comment(L"========== Checking the host buffer state (before) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (before) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 
     VERIFY_ARE_EQUAL(si.GetViewport().Dimensions(), si.GetBufferSize().Dimensions());
     VERIFY_ARE_EQUAL(si.GetViewport(), si.GetBufferSize());
@@ -2745,13 +2739,13 @@ void ConptyRoundtripTests::ClsAndClearHostClearsScrollbackTest()
         csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
         _apiRoutines.GetConsoleScreenBufferInfoExImpl(si, csbiex);
 
-        SMALL_RECT src{ 0 };
+        til::inclusive_rect src{ 0 };
         src.Top = 0;
         src.Left = 0;
         src.Right = csbiex.dwSize.X;
         src.Bottom = csbiex.dwSize.Y;
 
-        COORD tgt{ 0, -csbiex.dwSize.Y };
+        til::point tgt{ 0, -csbiex.dwSize.Y };
         VERIFY_SUCCEEDED(_apiRoutines.ScrollConsoleScreenBufferWImpl(si,
                                                                      src,
                                                                      tgt,
@@ -2796,12 +2790,12 @@ void ConptyRoundtripTests::ClsAndClearHostClearsScrollbackTest()
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the host buffer state (after) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (after) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, true);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), true);
 }
 
 void ConptyRoundtripTests::TestResizeWithCookedRead()
@@ -2941,12 +2935,12 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs()
     }
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const bool isTerminal, const bool afterResize) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
 
         // Conhost and Terminal attributes are potentially different.
         const auto greenAttrs = isTerminal ? terminalGreenAttrs : conhostGreenAttrs;
 
-        for (short row = 0; row < tb.GetSize().Height(); row++)
+        for (til::CoordType row = 0; row < tb.GetSize().Height(); row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d...", row));
 
@@ -2979,13 +2973,13 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs()
     };
 
     Log::Comment(L"========== Checking the host buffer state (before) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, false, false);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), false, false);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (before) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, true, false);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), true, false);
 
     // After we resize, make sure to get the new textBuffers
     std::tie(hostTb, termTb) = _performResize({ TerminalViewWidth + dx,
@@ -2995,13 +2989,13 @@ void ConptyRoundtripTests::ResizeInitializeBufferWithDefaultAttrs()
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the host buffer state (after) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, false, true);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), false, true);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (after) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, true, true);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), true, true);
 }
 
 void ConptyRoundtripTests::NewLinesAtBottomWithBackground()
@@ -3079,13 +3073,13 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground()
     }
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
         const auto isTerminal = viewport.top != 0;
 
         // Conhost and Terminal attributes are potentially different.
         const auto blueAttrs = isTerminal ? terminalBlueAttrs : conhostBlueAttrs;
 
-        for (short row = 0; row < viewport.bottom - 2; row++)
+        for (til::CoordType row = 0; row < viewport.bottom - 2; row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
             VERIFY_IS_FALSE(tb.GetRowByOffset(row).WasWrapForced());
@@ -3115,13 +3109,13 @@ void ConptyRoundtripTests::NewLinesAtBottomWithBackground()
     };
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 }
 
 void doWriteCharsLegacy(SCREEN_INFORMATION& screenInfo, const std::wstring_view string, DWORD flags = 0)
@@ -3279,10 +3273,10 @@ void ConptyRoundtripTests::WrapNewLineAtBottom()
     // row[5]: |~~~~~~             | <break>
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
         const auto isTerminal = viewport.top != 0;
 
-        for (short row = 0; row < viewport.narrow_bottom<short>(); row++)
+        for (til::CoordType row = 0; row < viewport.bottom; row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
 
@@ -3296,25 +3290,25 @@ void ConptyRoundtripTests::WrapNewLineAtBottom()
             VERIFY_ARE_EQUAL(isWrapped, tb.GetRowByOffset(row).WasWrapForced());
             if (isWrapped)
             {
-                TestUtils::VerifyExpectedString(tb, std::wstring(charsInFirstLine, L'~'), COORD{ 0, row });
+                TestUtils::VerifyExpectedString(tb, std::wstring(charsInFirstLine, L'~'), { 0, row });
             }
             else
             {
-                auto iter = TestUtils::VerifyExpectedString(tb, std::wstring(charsInSecondLine, L'~'), COORD{ 0, row });
+                auto iter = TestUtils::VerifyExpectedString(tb, std::wstring(charsInSecondLine, L'~'), { 0, row });
                 TestUtils::VerifyExpectedString(std::wstring(width - charsInSecondLine, L' '), iter);
             }
         }
     };
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state ==========");
     VERIFY_ARE_EQUAL(circledRows, term->_mutableViewport.Top());
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::WrapNewLineAtBottomLikeMSYS()
@@ -3481,10 +3475,10 @@ void ConptyRoundtripTests::WrapNewLineAtBottomLikeMSYS()
     }
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
         const auto isTerminal = viewport.top != 0;
-        auto lastRow = gsl::narrow<short>(viewport.bottom - 1);
-        for (short row = 0; row < lastRow; row++)
+        auto lastRow = viewport.bottom - 1;
+        for (til::CoordType row = 0; row < lastRow; row++)
         {
             Log::Comment(NoThrowString().Format(L"Checking row %d", row));
 
@@ -3503,28 +3497,28 @@ void ConptyRoundtripTests::WrapNewLineAtBottomLikeMSYS()
             VERIFY_ARE_EQUAL(isWrapped, tb.GetRowByOffset(row).WasWrapForced());
             if (isWrapped)
             {
-                TestUtils::VerifyExpectedString(tb, std::wstring(charsInFirstLine, L'~'), COORD{ 0, row });
+                TestUtils::VerifyExpectedString(tb, std::wstring(charsInFirstLine, L'~'), { 0, row });
             }
             else
             {
-                auto iter = TestUtils::VerifyExpectedString(tb, std::wstring(charsInSecondLine, L'~'), COORD{ 0, row });
+                auto iter = TestUtils::VerifyExpectedString(tb, std::wstring(charsInSecondLine, L'~'), { 0, row });
                 TestUtils::VerifyExpectedString(std::wstring(width - charsInSecondLine, L' '), iter);
             }
         }
         VERIFY_IS_FALSE(tb.GetRowByOffset(lastRow).WasWrapForced());
-        auto iter = TestUtils::VerifyExpectedString(tb, std::wstring(1, L':'), COORD{ 0, lastRow });
+        auto iter = TestUtils::VerifyExpectedString(tb, std::wstring(1, L':'), { 0, lastRow });
         TestUtils::VerifyExpectedString(std::wstring(width - 1, L' '), iter);
     };
 
     Log::Comment(L"========== Checking the host buffer state ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() });
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive());
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state ==========");
     VERIFY_ARE_EQUAL(circledRows + 1, term->_mutableViewport.Top());
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() });
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive());
 }
 
 void ConptyRoundtripTests::DeleteWrappedWord()
@@ -3557,7 +3551,7 @@ void ConptyRoundtripTests::DeleteWrappedWord()
     sm.ProcessString(L"\x1b[?25h");
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const bool after) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
 
         auto iter1 = tb.GetCellDataAt({ 0, 0 });
         TestUtils::VerifySpanOfText(L"A", iter1, 0, 50);
@@ -3580,12 +3574,12 @@ void ConptyRoundtripTests::DeleteWrappedWord()
     };
 
     Log::Comment(L"========== Checking the host buffer state (before) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, false);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), false);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (before) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, false);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), false);
 
     // Now, go back and erase all the 'B's, as if the user executed a
     // backward-kill-word in PowerShell. Afterwards, the buffer will look like:
@@ -3609,12 +3603,12 @@ void ConptyRoundtripTests::DeleteWrappedWord()
     sm.ProcessString(L"\x1b[?25h");
 
     Log::Comment(L"========== Checking the host buffer state (after) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (after) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, true);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), true);
 }
 
 // This test checks that upon conpty rendering again, terminal still maintains
@@ -3718,43 +3712,43 @@ void ConptyRoundtripTests::ClearBufferSignal()
     sm.ProcessString(L"\x1b[?25h");
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const bool before) {
-        const auto width = viewport.narrow_width<short>();
-        const short numCharsOnSecondLine = 50 - (width - 51);
+        const auto width = viewport.width();
+        const auto numCharsOnSecondLine = 50 - (width - 51);
         auto iter1 = tb.GetCellDataAt({ 0, 0 });
         if (before)
         {
             TestUtils::VerifySpanOfText(L"A", iter1, 0, 50);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, 1);
             TestUtils::VerifySpanOfText(L"B", iter1, 0, 50);
-            COORD expectedCursor{ numCharsOnSecondLine, 1 };
+            til::point expectedCursor{ numCharsOnSecondLine, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         }
         else
         {
             TestUtils::VerifySpanOfText(L"B", iter1, 0, numCharsOnSecondLine);
-            COORD expectedCursor{ numCharsOnSecondLine, 0 };
+            til::point expectedCursor{ numCharsOnSecondLine, 0 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
         }
     };
 
     Log::Comment(L"========== Checking the host buffer state (before) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (before) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, true);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), true);
 
     Log::Comment(L"========== Clear the ConPTY buffer with the signal ==========");
     _clearConpty();
 
     Log::Comment(L"========== Checking the host buffer state (after) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, false);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), false);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (after) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_mutableViewport.ToInclusive() }, false);
+    verifyBuffer(*termTb, term->_mutableViewport.ToExclusive(), false);
 }
 
 void ConptyRoundtripTests::SimpleAltBufferTest()
@@ -3812,7 +3806,7 @@ void ConptyRoundtripTests::SimpleAltBufferTest()
     };
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const Frame frame) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
         auto iter0 = tb.GetCellDataAt({ 0, 0 });
         auto iter1 = tb.GetCellDataAt({ 0, 1 });
         switch (frame)
@@ -3825,7 +3819,7 @@ void ConptyRoundtripTests::SimpleAltBufferTest()
 
             TestUtils::VerifySpanOfText(L"B", iter1, 0, 50);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, static_cast<size_t>(width - 50));
-            COORD expectedCursor{ 50, 1 };
+            til::point expectedCursor{ 50, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -3834,7 +3828,7 @@ void ConptyRoundtripTests::SimpleAltBufferTest()
             TestUtils::VerifySpanOfText(L" ", iter0, 0, width);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, width);
 
-            COORD expectedCursor{ 50, 1 };
+            til::point expectedCursor{ 50, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -3845,7 +3839,7 @@ void ConptyRoundtripTests::SimpleAltBufferTest()
             TestUtils::VerifySpanOfText(L"C", iter1, 0, 5u);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, static_cast<size_t>(width - 55));
 
-            COORD expectedCursor{ 55, 1 };
+            til::point expectedCursor{ 55, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -3853,13 +3847,13 @@ void ConptyRoundtripTests::SimpleAltBufferTest()
     };
 
     Log::Comment(L"========== Checking the host buffer state (InMainBufferBefore) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, Frame::InMainBufferBefore);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), Frame::InMainBufferBefore);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (InMainBufferBefore) ==========");
     VERIFY_ARE_EQUAL(0, term->_GetMutableViewport().Top());
-    verifyBuffer(*termTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InMainBufferBefore);
+    verifyBuffer(*termTb, term->_GetMutableViewport().ToExclusive(), Frame::InMainBufferBefore);
 
     Log::Comment(L"========== Switch to the alt buffer ==========");
 
@@ -3880,37 +3874,37 @@ void ConptyRoundtripTests::SimpleAltBufferTest()
     VERIFY_ARE_NOT_EQUAL(termAltTb, termTb);
 
     Log::Comment(L"========== Checking the host buffer state (InAltBufferBefore) ==========");
-    verifyBuffer(*hostAltTb, til::rect{ siAlt.GetViewport().ToInclusive() }, Frame::InAltBufferBefore);
+    verifyBuffer(*hostAltTb, siAlt.GetViewport().ToExclusive(), Frame::InAltBufferBefore);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (InAltBufferBefore) ==========");
     VERIFY_ARE_EQUAL(0, term->_GetMutableViewport().Top());
-    verifyBuffer(*termAltTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InAltBufferBefore);
+    verifyBuffer(*termAltTb, term->_GetMutableViewport().ToExclusive(), Frame::InAltBufferBefore);
 
     Log::Comment(L"========== Add some text to the alt buffer ==========");
 
     sm.ProcessString(L"CCCCC");
     Log::Comment(L"========== Checking the host buffer state (InAltBufferAfter) ==========");
-    verifyBuffer(*hostAltTb, til::rect{ siAlt.GetViewport().ToInclusive() }, Frame::InAltBufferAfter);
+    verifyBuffer(*hostAltTb, siAlt.GetViewport().ToExclusive(), Frame::InAltBufferAfter);
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (InAltBufferAfter) ==========");
     VERIFY_ARE_EQUAL(0, term->_GetMutableViewport().Top());
-    verifyBuffer(*termAltTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InAltBufferAfter);
+    verifyBuffer(*termAltTb, term->_GetMutableViewport().ToExclusive(), Frame::InAltBufferAfter);
 
     Log::Comment(L"========== Back to the main buffer ==========");
 
     sm.ProcessString(L"\x1b[?1049l");
     Log::Comment(L"========== Checking the host buffer state (InMainBufferAfter) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, Frame::InMainBufferAfter);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), Frame::InMainBufferAfter);
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (InMainBufferAfter) ==========");
     VERIFY_ARE_EQUAL(0, term->_GetMutableViewport().Top());
-    verifyBuffer(*termTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InMainBufferAfter);
+    verifyBuffer(*termTb, term->_GetMutableViewport().ToExclusive(), Frame::InMainBufferAfter);
 }
 
 void ConptyRoundtripTests::AltBufferToAltBufferTest()
@@ -3966,7 +3960,7 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
     };
 
     auto verifyBuffer = [&](const TextBuffer& tb, const til::rect& viewport, const Frame frame) {
-        const auto width = viewport.narrow_width<short>();
+        const auto width = viewport.width();
         auto iter0 = tb.GetCellDataAt({ 0, 0 });
         auto iter1 = tb.GetCellDataAt({ 0, 1 });
         switch (frame)
@@ -3978,7 +3972,7 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
 
             TestUtils::VerifySpanOfText(L"B", iter1, 0, 50);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, static_cast<size_t>(width - 50));
-            COORD expectedCursor{ 50, 1 };
+            til::point expectedCursor{ 50, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -3987,7 +3981,7 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
             TestUtils::VerifySpanOfText(L" ", iter0, 0, width);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, width);
 
-            COORD expectedCursor{ 50, 1 };
+            til::point expectedCursor{ 50, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -3998,7 +3992,7 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
             TestUtils::VerifySpanOfText(L"C", iter1, 0, 5u);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, static_cast<size_t>(width - 55));
 
-            COORD expectedCursor{ 55, 1 };
+            til::point expectedCursor{ 55, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -4007,7 +4001,7 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
             TestUtils::VerifySpanOfText(L" ", iter0, 0, width);
             TestUtils::VerifySpanOfText(L" ", iter1, 0, width);
 
-            COORD expectedCursor{ 55, 1 };
+            til::point expectedCursor{ 55, 1 };
             VERIFY_ARE_EQUAL(expectedCursor, tb.GetCursor().GetPosition());
             break;
         }
@@ -4015,12 +4009,12 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
     };
 
     Log::Comment(L"========== Checking the host buffer state (InMainBufferBefore) ==========");
-    verifyBuffer(*hostTb, til::rect{ si.GetViewport().ToInclusive() }, Frame::InMainBufferBefore);
+    verifyBuffer(*hostTb, si.GetViewport().ToExclusive(), Frame::InMainBufferBefore);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (InMainBufferBefore) ==========");
-    verifyBuffer(*termTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InMainBufferBefore);
+    verifyBuffer(*termTb, term->_GetMutableViewport().ToExclusive(), Frame::InMainBufferBefore);
 
     Log::Comment(L"========== Switch to the alt buffer ==========");
 
@@ -4041,23 +4035,23 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
     VERIFY_ARE_NOT_EQUAL(termAltTb, termTb);
 
     Log::Comment(L"========== Checking the host buffer state (InAltBufferBefore) ==========");
-    verifyBuffer(*hostAltTb, til::rect{ siAlt->GetViewport().ToInclusive() }, Frame::InAltBufferBefore);
+    verifyBuffer(*hostAltTb, siAlt->GetViewport().ToExclusive(), Frame::InAltBufferBefore);
 
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
     Log::Comment(L"========== Checking the terminal buffer state (InAltBufferBefore) ==========");
-    verifyBuffer(*termAltTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InAltBufferBefore);
+    verifyBuffer(*termAltTb, term->_GetMutableViewport().ToExclusive(), Frame::InAltBufferBefore);
 
     Log::Comment(L"========== Add some text to the alt buffer ==========");
 
     sm.ProcessString(L"CCCCC");
     Log::Comment(L"========== Checking the host buffer state (InAltBufferAfter) ==========");
-    verifyBuffer(*hostAltTb, til::rect{ siAlt->GetViewport().ToInclusive() }, Frame::InAltBufferAfter);
+    verifyBuffer(*hostAltTb, siAlt->GetViewport().ToExclusive(), Frame::InAltBufferAfter);
     Log::Comment(L"Painting the frame");
     VERIFY_SUCCEEDED(renderer.PaintFrame());
 
     Log::Comment(L"========== Checking the terminal buffer state (InAltBufferAfter) ==========");
-    verifyBuffer(*termAltTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::InAltBufferAfter);
+    verifyBuffer(*termAltTb, term->_GetMutableViewport().ToExclusive(), Frame::InAltBufferAfter);
 
     Log::Comment(L"========== Stay in the alt buffer, what happens? ==========");
 
@@ -4070,10 +4064,10 @@ void ConptyRoundtripTests::AltBufferToAltBufferTest()
     termAltTb = &term->_activeBuffer();
 
     Log::Comment(L"========== Checking the host buffer state (StillInAltBuffer) ==========");
-    verifyBuffer(*hostAltTb, til::rect{ siAlt->GetViewport().ToInclusive() }, Frame::StillInAltBuffer);
+    verifyBuffer(*hostAltTb, siAlt->GetViewport().ToExclusive(), Frame::StillInAltBuffer);
 
     Log::Comment(L"========== Checking the terminal buffer state (StillInAltBuffer) ==========");
-    verifyBuffer(*termAltTb, til::rect{ term->_GetMutableViewport().ToInclusive() }, Frame::StillInAltBuffer);
+    verifyBuffer(*termAltTb, term->_GetMutableViewport().ToExclusive(), Frame::StillInAltBuffer);
 }
 
 void ConptyRoundtripTests::AltBufferResizeCrash()
diff --git a/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp
index bd38e005a30..671fb167e28 100644
--- a/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp
@@ -60,7 +60,7 @@ void ScreenSizeLimitsTest::ScrollbackHistorySizeIsClampedToBounds()
     // which is the *sum* of the history size plus the number of rows
     // actually visible on screen at the moment.
 
-    const unsigned int visibleRowCount = 100;
+    static constexpr til::CoordType visibleRowCount = 100;
 
     // Zero history size is acceptable.
     auto noHistorySettings = winrt::make<MockTermSettings>(0, visibleRowCount, 100);
@@ -79,19 +79,19 @@ void ScreenSizeLimitsTest::ScrollbackHistorySizeIsClampedToBounds()
     auto maxHistorySizeSettings = winrt::make<MockTermSettings>(SHRT_MAX - visibleRowCount, visibleRowCount, 100);
     Terminal maxHistorySizeTerminal;
     maxHistorySizeTerminal.CreateFromSettings(maxHistorySizeSettings, renderer);
-    VERIFY_ARE_EQUAL(maxHistorySizeTerminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX), L"History size == SHRT_MAX - initial row count is accepted");
+    VERIFY_ARE_EQUAL(maxHistorySizeTerminal.GetTextBuffer().TotalRowCount(), SHRT_MAX, L"History size == SHRT_MAX - initial row count is accepted");
 
     // History size + initial visible rows == SHRT_MAX + 1 will be clamped slightly.
     auto justTooBigHistorySizeSettings = winrt::make<MockTermSettings>(SHRT_MAX - visibleRowCount + 1, visibleRowCount, 100);
     Terminal justTooBigHistorySizeTerminal;
     justTooBigHistorySizeTerminal.CreateFromSettings(justTooBigHistorySizeSettings, renderer);
-    VERIFY_ARE_EQUAL(justTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX), L"History size == 1 + SHRT_MAX - initial row count is clamped to SHRT_MAX - initial row count");
+    VERIFY_ARE_EQUAL(justTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), SHRT_MAX, L"History size == 1 + SHRT_MAX - initial row count is clamped to SHRT_MAX - initial row count");
 
     // Ridiculously large history sizes are also clamped.
     auto farTooBigHistorySizeSettings = winrt::make<MockTermSettings>(99999999, visibleRowCount, 100);
     Terminal farTooBigHistorySizeTerminal;
     farTooBigHistorySizeTerminal.CreateFromSettings(farTooBigHistorySizeSettings, renderer);
-    VERIFY_ARE_EQUAL(farTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX), L"History size that is far too large is clamped to SHRT_MAX - initial row count");
+    VERIFY_ARE_EQUAL(farTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), SHRT_MAX, L"History size that is far too large is clamped to SHRT_MAX - initial row count");
 }
 
 void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
@@ -102,8 +102,8 @@ void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
     //
     // This is a test for GH#2630, GH#2815.
 
-    const unsigned int initialVisibleColCount = 50;
-    const unsigned int initialVisibleRowCount = 50;
+    static constexpr til::CoordType initialVisibleColCount = 50;
+    static constexpr til::CoordType initialVisibleRowCount = 50;
     const auto historySize = SHRT_MAX - (initialVisibleRowCount * 2);
 
     Log::Comment(L"Watch out - this test takes a while on debug, because "
@@ -114,18 +114,18 @@ void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
     Terminal terminal;
     DummyRenderer renderer{ &terminal };
     terminal.CreateFromSettings(settings, renderer);
-    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(historySize + initialVisibleRowCount));
+    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), historySize + initialVisibleRowCount);
 
     Log::Comment(L"Resize the terminal to have exactly SHRT_MAX lines");
     VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount * 2 }));
 
-    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX));
+    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), SHRT_MAX);
 
     Log::Comment(L"Resize the terminal to have MORE than SHRT_MAX lines - we should clamp to SHRT_MAX");
     VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount * 3 }));
-    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX));
+    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), SHRT_MAX);
 
     Log::Comment(L"Resize back down to the original size");
     VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount }));
-    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(historySize + initialVisibleRowCount));
+    VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), historySize + initialVisibleRowCount);
 }
diff --git a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp
index 9fa6b928caa..f3f5db07e47 100644
--- a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp
@@ -29,7 +29,7 @@ namespace
     class MockScrollRenderEngine final : public RenderEngineBase
     {
     public:
-        std::optional<COORD> TriggerScrollDelta() const
+        std::optional<til::point> TriggerScrollDelta() const
         {
             return _triggerScrollDelta;
         }
@@ -44,36 +44,36 @@ namespace
         HRESULT Present() noexcept { return S_OK; }
         HRESULT PrepareForTeardown(_Out_ bool* /*pForcePaint*/) noexcept { return S_OK; }
         HRESULT ScrollFrame() noexcept { return S_OK; }
-        HRESULT Invalidate(const SMALL_RECT* /*psrRegion*/) noexcept { return S_OK; }
-        HRESULT InvalidateCursor(const SMALL_RECT* /*psrRegion*/) noexcept { return S_OK; }
-        HRESULT InvalidateSystem(const RECT* /*prcDirtyClient*/) noexcept { return S_OK; }
-        HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& /*rectangles*/) noexcept { return S_OK; }
-        HRESULT InvalidateScroll(const COORD* pcoordDelta) noexcept
+        HRESULT Invalidate(const til::rect* /*psrRegion*/) noexcept { return S_OK; }
+        HRESULT InvalidateCursor(const til::rect* /*psrRegion*/) noexcept { return S_OK; }
+        HRESULT InvalidateSystem(const til::rect* /*prcDirtyClient*/) noexcept { return S_OK; }
+        HRESULT InvalidateSelection(const std::vector<til::rect>& /*rectangles*/) noexcept { return S_OK; }
+        HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept
         {
-            _triggerScrollDelta = { *pcoordDelta };
+            _triggerScrollDelta = *pcoordDelta;
             return S_OK;
         }
         HRESULT InvalidateAll() noexcept { return S_OK; }
         HRESULT InvalidateCircling(_Out_ bool* /*pForcePaint*/) noexcept { return S_OK; }
         HRESULT PaintBackground() noexcept { return S_OK; }
-        HRESULT PaintBufferLine(gsl::span<const Cluster> /*clusters*/, COORD /*coord*/, bool /*fTrimLeft*/, bool /*lineWrapped*/) noexcept { return S_OK; }
-        HRESULT PaintBufferGridLines(GridLineSet /*lines*/, COLORREF /*color*/, size_t /*cchLine*/, COORD /*coordTarget*/) noexcept { return S_OK; }
-        HRESULT PaintSelection(SMALL_RECT /*rect*/) noexcept { return S_OK; }
+        HRESULT PaintBufferLine(gsl::span<const Cluster> /*clusters*/, til::point /*coord*/, bool /*fTrimLeft*/, bool /*lineWrapped*/) noexcept { return S_OK; }
+        HRESULT PaintBufferGridLines(GridLineSet /*lines*/, COLORREF /*color*/, size_t /*cchLine*/, til::point /*coordTarget*/) noexcept { return S_OK; }
+        HRESULT PaintSelection(const til::rect& /*rect*/) noexcept { return S_OK; }
         HRESULT PaintCursor(const CursorOptions& /*options*/) noexcept { return S_OK; }
         HRESULT UpdateDrawingBrushes(const TextAttribute& /*textAttributes*/, const RenderSettings& /*renderSettings*/, gsl::not_null<IRenderData*> /*pData*/, bool /*usingSoftFont*/, bool /*isSettingDefaultBrushes*/) noexcept { return S_OK; }
         HRESULT UpdateFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/) noexcept { return S_OK; }
         HRESULT UpdateDpi(int /*iDpi*/) noexcept { return S_OK; }
-        HRESULT UpdateViewport(SMALL_RECT /*srNewViewport*/) noexcept { return S_OK; }
+        HRESULT UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept { return S_OK; }
         HRESULT GetProposedFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/, int /*iDpi*/) noexcept { return S_OK; }
         HRESULT GetDirtyArea(gsl::span<const til::rect>& /*area*/) noexcept { return S_OK; }
-        HRESULT GetFontSize(_Out_ COORD* /*pFontSize*/) noexcept { return S_OK; }
+        HRESULT GetFontSize(_Out_ til::size* /*pFontSize*/) noexcept { return S_OK; }
         HRESULT IsGlyphWideByFont(std::wstring_view /*glyph*/, _Out_ bool* /*pResult*/) noexcept { return S_OK; }
 
     protected:
         HRESULT _DoUpdateTitle(const std::wstring_view /*newTitle*/) noexcept { return S_OK; }
 
     private:
-        std::optional<COORD> _triggerScrollDelta;
+        std::optional<til::point> _triggerScrollDelta;
     };
 
     struct ScrollBarNotification
@@ -95,11 +95,11 @@ class TerminalCoreUnitTests::ScrollTest final
     // !!! DANGER: Many tests in this class expect the Terminal buffer
     // to be 80x32. If you change these, you'll probably inadvertently break a
     // bunch of tests !!!
-    static const SHORT TerminalViewWidth = 80;
-    static const SHORT TerminalViewHeight = 32;
+    static const til::CoordType TerminalViewWidth = 80;
+    static const til::CoordType TerminalViewHeight = 32;
     // For TestNotifyScrolling, it's important that this value is ~=9000.
     // Something smaller like 100 won't cause the test to fail.
-    static const SHORT TerminalHistoryLength = 9001;
+    static const til::CoordType TerminalHistoryLength = 9001;
 
     TEST_CLASS(ScrollTest);
 
@@ -203,7 +203,7 @@ void ScrollTest::TestNotifyScrolling()
             VERIFY_IS_TRUE(_renderEngine->TriggerScrollDelta().has_value(),
                            fmt::format(L"Expected a 'trigger scroll' notification in Render Engine for row {}", currentRow).c_str());
 
-            COORD expectedDelta;
+            til::point expectedDelta;
             expectedDelta.X = 0;
             expectedDelta.Y = -1;
             VERIFY_ARE_EQUAL(expectedDelta, _renderEngine->TriggerScrollDelta().value(), fmt::format(L"Wrong value in 'trigger scroll' notification in Render Engine for row {}", currentRow).c_str());
diff --git a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp
index 7b458aa06a7..894c5b7764f 100644
--- a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp
@@ -32,7 +32,7 @@ namespace TerminalCoreUnitTests
         // - expected: the expected value of the selection rect
         // Return Value:
         // - N/A
-        void ValidateSingleRowSelection(Terminal& term, SMALL_RECT expected)
+        void ValidateSingleRowSelection(Terminal& term, const til::inclusive_rect& expected)
         {
             // Simulate renderer calling TriggerSelection and acquiring selection area
             auto selectionRects = term.GetSelectionRects();
@@ -51,7 +51,7 @@ namespace TerminalCoreUnitTests
             term.Create({ 100, 100 }, 0, renderer);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.SetSelectionAnchor(clickPos);
 
             ValidateSingleRowSelection(term, { 5, 10, 5, 10 });
@@ -66,7 +66,7 @@ namespace TerminalCoreUnitTests
             // Used for two things:
             //    - click y-pos
             //    - keep track of row we're verifying
-            SHORT rowValue = 10;
+            til::CoordType rowValue = 10;
 
             // Simulate click at (x,y) = (5,10)
             term.SetSelectionAnchor({ 5, rowValue });
@@ -89,17 +89,17 @@ namespace TerminalCoreUnitTests
                 if (rowValue == 10)
                 {
                     // Verify top line
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, 10, rightBoundary, 10 }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, 10, rightBoundary, 10 }));
                 }
                 else if (rowValue == 20)
                 {
                     // Verify bottom line
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 20, 15, 20 }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 20, 15, 20 }));
                 }
                 else
                 {
                     // Verify other lines (full)
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, rowValue, rightBoundary, rowValue }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, rowValue, rightBoundary, rowValue }));
                 }
 
                 rowValue++;
@@ -108,16 +108,16 @@ namespace TerminalCoreUnitTests
 
         TEST_METHOD(OverflowTests)
         {
-            const COORD maxCoord = { SHRT_MAX, SHRT_MAX };
+            const til::point maxCoord = { SHRT_MAX, SHRT_MAX };
 
-            // Test SetSelectionAnchor(COORD) and SetSelectionEnd(COORD)
+            // Test SetSelectionAnchor(til::point) and SetSelectionEnd(til::point)
             // Behavior: clamp coord to viewport.
-            auto ValidateSingleClickSelection = [&](SHORT scrollback, SMALL_RECT expected) {
+            auto ValidateSingleClickSelection = [&](til::CoordType scrollback, const til::inclusive_rect& expected) {
                 Terminal term;
                 DummyRenderer renderer{ &term };
                 term.Create({ 10, 10 }, scrollback, renderer);
 
-                // NOTE: SetSelectionEnd(COORD) is called within SetSelectionAnchor(COORD)
+                // NOTE: SetSelectionEnd(til::point) is called within SetSelectionAnchor(til::point)
                 term.SetSelectionAnchor(maxCoord);
                 ValidateSingleRowSelection(term, expected);
             };
@@ -125,7 +125,7 @@ namespace TerminalCoreUnitTests
             // Test a Double Click Selection
             // Behavior: clamp coord to viewport.
             //           Then, do double click selection.
-            auto ValidateDoubleClickSelection = [&](SHORT scrollback, SMALL_RECT expected) {
+            auto ValidateDoubleClickSelection = [&](til::CoordType scrollback, const til::inclusive_rect& expected) {
                 Terminal term;
                 DummyRenderer renderer{ &term };
                 term.Create({ 10, 10 }, scrollback, renderer);
@@ -137,7 +137,7 @@ namespace TerminalCoreUnitTests
             // Test a Triple Click Selection
             // Behavior: clamp coord to viewport.
             //           Then, do triple click selection.
-            auto ValidateTripleClickSelection = [&](SHORT scrollback, SMALL_RECT expected) {
+            auto ValidateTripleClickSelection = [&](til::CoordType scrollback, const til::inclusive_rect& expected) {
                 Terminal term;
                 DummyRenderer renderer{ &term };
                 term.Create({ 10, 10 }, scrollback, renderer);
@@ -155,7 +155,7 @@ namespace TerminalCoreUnitTests
             ValidateTripleClickSelection(0, { 0, 9, 9, 9 });
 
             // Test with max scrollback
-            const SHORT expected_row = SHRT_MAX - 1;
+            const til::CoordType expected_row = SHRT_MAX - 1;
             Log::Comment(L"Single click selection with MAXIMUM scrollback value");
             ValidateSingleClickSelection(SHRT_MAX, { 9, expected_row, 9, expected_row });
             Log::Comment(L"Double click selection with MAXIMUM scrollback value");
@@ -218,7 +218,7 @@ namespace TerminalCoreUnitTests
             term.Create({ 10, 10 }, 0, renderer);
 
             auto viewport = term.GetViewport();
-            const SHORT leftBoundary = 0;
+            const til::CoordType leftBoundary = 0;
             const auto rightBoundary = viewport.RightInclusive();
 
             // Simulate click at (x,y) = (5,5)
@@ -227,7 +227,7 @@ namespace TerminalCoreUnitTests
             // Case 1: Move out of right boundary
             Log::Comment(L"Out of bounds: X-value too large");
             term.SetSelectionEnd({ 20, 5 });
-            ValidateSingleRowSelection(term, SMALL_RECT({ 5, 5, rightBoundary, 5 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 5, 5, rightBoundary, 5 }));
 
             // Case 2: Move out of left boundary
             Log::Comment(L"Out of bounds: X-value negative");
@@ -250,17 +250,17 @@ namespace TerminalCoreUnitTests
                     if (rowValue == 0)
                     {
                         // Verify top line
-                        VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, rightBoundary, rowValue }));
+                        VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, rightBoundary, rowValue }));
                     }
                     else if (rowValue == 5)
                     {
                         // Verify last line
-                        VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, 5, rowValue }));
+                        VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, 5, rowValue }));
                     }
                     else
                     {
                         // Verify other lines (full)
-                        VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, rightBoundary, rowValue }));
+                        VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, rightBoundary, rowValue }));
                     }
                 }
             }
@@ -281,17 +281,17 @@ namespace TerminalCoreUnitTests
                     if (rowValue == 5)
                     {
                         // Verify top line
-                        VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, 5, rightBoundary, 5 }));
+                        VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, 5, rightBoundary, 5 }));
                     }
                     else if (rowValue == 9)
                     {
                         // Verify bottom line
-                        VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, 5, rowValue }));
+                        VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, 5, rowValue }));
                     }
                     else
                     {
                         // Verify other lines (full)
-                        VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, rightBoundary, rowValue }));
+                        VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, rightBoundary, rowValue }));
                     }
                 }
             }
@@ -306,7 +306,7 @@ namespace TerminalCoreUnitTests
             // Used for two things:
             //    - click y-pos
             //    - keep track of row we're verifying
-            SHORT rowValue = 10;
+            til::CoordType rowValue = 10;
 
             // Simulate ALT + click at (x,y) = (5,10)
             term.SetSelectionAnchor({ 5, rowValue });
@@ -327,7 +327,7 @@ namespace TerminalCoreUnitTests
                 auto selection = viewport.ConvertToOrigin(selectionRect).ToInclusive();
 
                 // Verify all lines
-                VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, 15, rowValue }));
+                VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, 15, rowValue }));
 
                 rowValue++;
             }
@@ -337,13 +337,13 @@ namespace TerminalCoreUnitTests
         {
             Terminal term;
             DummyRenderer renderer{ &term };
-            SHORT scrollbackLines = 5;
+            til::CoordType scrollbackLines = 5;
             term.Create({ 100, 100 }, scrollbackLines, renderer);
 
             // Used for two things:
             //    - click y-pos
             //    - keep track of row we're verifying
-            SHORT rowValue = 10;
+            til::CoordType rowValue = 10;
 
             // Simulate click at (x,y) = (5,10)
             term.SetSelectionAnchor({ 5, rowValue });
@@ -366,17 +366,17 @@ namespace TerminalCoreUnitTests
                 if (rowValue == 10)
                 {
                     // Verify top line
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, 10, rightBoundary, 10 }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, 10, rightBoundary, 10 }));
                 }
                 else if (rowValue == 20)
                 {
                     // Verify bottom line
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 20, 15, 20 }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 20, 15, 20 }));
                 }
                 else
                 {
                     // Verify other lines (full)
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, rowValue, rightBoundary, rowValue }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, rowValue, rightBoundary, rowValue }));
                 }
 
                 rowValue++;
@@ -398,7 +398,7 @@ namespace TerminalCoreUnitTests
             term.Write(burrito);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.SetSelectionAnchor(clickPos);
 
             // Validate selection area
@@ -421,7 +421,7 @@ namespace TerminalCoreUnitTests
             term.Write(burrito);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 4, 10 };
+            auto clickPos = til::point{ 4, 10 };
             term.SetSelectionAnchor(clickPos);
 
             // Validate selection area
@@ -461,23 +461,23 @@ namespace TerminalCoreUnitTests
             VERIFY_ARE_EQUAL(selectionRects.size(), static_cast<size_t>(5));
 
             auto viewport = term.GetViewport();
-            SHORT rowValue = 8;
+            til::CoordType rowValue = 8;
             for (auto selectionRect : selectionRects)
             {
                 auto selection = viewport.ConvertToOrigin(selectionRect).ToInclusive();
 
                 if (rowValue == 10)
                 {
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 4, rowValue, 7, rowValue }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 4, rowValue, 7, rowValue }));
                 }
                 else if (rowValue == 11)
                 {
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, 8, rowValue }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, 8, rowValue }));
                 }
                 else
                 {
                     // Verify all lines
-                    VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, 7, rowValue }));
+                    VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, 7, rowValue }));
                 }
 
                 rowValue++;
@@ -500,11 +500,11 @@ namespace TerminalCoreUnitTests
             term.Write(text);
 
             // Simulate double click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
 
             // Validate selection area
-            ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, (4 + gsl::narrow<SHORT>(text.size()) - 1), 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect{ 4, 10, gsl::narrow<til::CoordType>(4 + text.size() - 1), 10 });
         }
 
         TEST_METHOD(DoubleClick_Delimiter)
@@ -518,14 +518,14 @@ namespace TerminalCoreUnitTests
             term.UpdateSettings(settings);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
 
             // Simulate renderer calling TriggerSelection and acquiring selection area
             auto selectionRects = term.GetSelectionRects();
 
             // Validate selection area
-            ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 0, 10, 99, 10 }));
         }
 
         TEST_METHOD(DoubleClick_DelimiterClass)
@@ -545,7 +545,7 @@ namespace TerminalCoreUnitTests
 
             // Simulate click at (x,y) = (15,10)
             // this is over the '>' char
-            auto clickPos = COORD{ 15, 10 };
+            auto clickPos = til::point{ 15, 10 };
             term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
 
             // ---Validate selection area---
@@ -553,7 +553,7 @@ namespace TerminalCoreUnitTests
             // ">" is in class 1
             // the white space to the right of the ">" is in class 0
             // Double-clicking the ">" should only highlight that cell
-            ValidateSingleRowSelection(term, SMALL_RECT({ 15, 10, 15, 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 15, 10, 15, 10 }));
         }
 
         TEST_METHOD(DoubleClickDrag_Right)
@@ -582,7 +582,7 @@ namespace TerminalCoreUnitTests
             term.SetSelectionEnd({ 21, 10 });
 
             // Validate selection area
-            ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
         }
 
         TEST_METHOD(DoubleClickDrag_Left)
@@ -611,7 +611,7 @@ namespace TerminalCoreUnitTests
             term.SetSelectionEnd({ 5, 10 });
 
             // Validate selection area
-            ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
         }
 
         TEST_METHOD(TripleClick_GeneralCase)
@@ -621,11 +621,11 @@ namespace TerminalCoreUnitTests
             term.Create({ 100, 100 }, 0, renderer);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
 
             // Validate selection area
-            ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 0, 10, 99, 10 }));
         }
 
         TEST_METHOD(TripleClickDrag_Horizontal)
@@ -635,14 +635,14 @@ namespace TerminalCoreUnitTests
             term.Create({ 100, 100 }, 0, renderer);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
 
             // Simulate move to (x,y) = (7,10)
             term.SetSelectionEnd({ 7, 10 });
 
             // Validate selection area
-            ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 }));
+            ValidateSingleRowSelection(term, til::inclusive_rect({ 0, 10, 99, 10 }));
         }
 
         TEST_METHOD(TripleClickDrag_Vertical)
@@ -652,7 +652,7 @@ namespace TerminalCoreUnitTests
             term.Create({ 100, 100 }, 0, renderer);
 
             // Simulate click at (x,y) = (5,10)
-            auto clickPos = COORD{ 5, 10 };
+            auto clickPos = til::point{ 5, 10 };
             term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
 
             // Simulate move to (x,y) = (5,11)
@@ -666,11 +666,11 @@ namespace TerminalCoreUnitTests
 
             // verify first selection rect
             auto selection = term.GetViewport().ConvertToOrigin(selectionRects.at(0)).ToInclusive();
-            VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 10, 99, 10 }));
+            VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 10, 99, 10 }));
 
             // verify second selection rect
             selection = term.GetViewport().ConvertToOrigin(selectionRects.at(1)).ToInclusive();
-            VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 11, 99, 11 }));
+            VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 11, 99, 11 }));
         }
 
         TEST_METHOD(ShiftClick)
@@ -694,7 +694,7 @@ namespace TerminalCoreUnitTests
                 term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansion::Word);
 
                 // Validate selection area: "doubleClickMe" selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 16, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 16, 10 }));
             }
 
             // Step 2: Shift+Click to "dragThroughHere"
@@ -707,7 +707,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Char);
 
                 // Validate selection area: "doubleClickMe drag" selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 21, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 21, 10 }));
             }
 
             // Step 3: Shift+Double-Click at "dragThroughHere"
@@ -720,7 +720,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word);
 
                 // Validate selection area: "doubleClickMe dragThroughHere" selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
             }
 
             // Step 4: Shift+Triple-Click at "dragThroughHere"
@@ -733,7 +733,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Line);
 
                 // Validate selection area: "doubleClickMe dragThroughHere..." selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 99, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 99, 10 }));
             }
 
             // Step 5: Shift+Double-Click at "dragThroughHere"
@@ -746,7 +746,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word);
 
                 // Validate selection area: "doubleClickMe dragThroughHere" selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
             }
 
             // Step 6: Drag past "dragThroughHere"
@@ -760,7 +760,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 35, 10 });
 
                 // Validate selection area: "doubleClickMe dragThroughHere..." selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 99, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 99, 10 }));
             }
 
             // Step 6: Drag back to "dragThroughHere"
@@ -773,7 +773,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 21, 10 });
 
                 // Validate selection area: "doubleClickMe dragThroughHere" selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
             }
 
             // Step 7: Drag within "dragThroughHere"
@@ -786,7 +786,7 @@ namespace TerminalCoreUnitTests
                 term.SetSelectionEnd({ 25, 10 });
 
                 // Validate selection area: "doubleClickMe dragThroughHere" still selected
-                ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
             }
         }
 
@@ -802,7 +802,7 @@ namespace TerminalCoreUnitTests
                 term.SelectNewRegion({ 10, 10 }, { 20, 10 });
 
                 // Validate selection area
-                ValidateSingleRowSelection(term, SMALL_RECT({ 10, 10, 20, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 10, 10, 20, 10 }));
             }
 
             // Step 2: Drag to (5,10)
@@ -811,7 +811,7 @@ namespace TerminalCoreUnitTests
 
                 // Validate selection area
                 // NOTE: Pivot should be (10, 10)
-                ValidateSingleRowSelection(term, SMALL_RECT({ 5, 10, 10, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 5, 10, 10, 10 }));
             }
 
             // Step 3: Drag back to (20,10)
@@ -820,7 +820,7 @@ namespace TerminalCoreUnitTests
 
                 // Validate selection area
                 // NOTE: Pivot should still be (10, 10)
-                ValidateSingleRowSelection(term, SMALL_RECT({ 10, 10, 20, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 10, 10, 20, 10 }));
             }
 
             // Step 4: Shift+Click at (5,10)
@@ -829,7 +829,7 @@ namespace TerminalCoreUnitTests
 
                 // Validate selection area
                 // NOTE: Pivot should still be (10, 10)
-                ValidateSingleRowSelection(term, SMALL_RECT({ 5, 10, 10, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 5, 10, 10, 10 }));
             }
 
             // Step 5: Shift+Click back at (20,10)
@@ -838,7 +838,7 @@ namespace TerminalCoreUnitTests
 
                 // Validate selection area
                 // NOTE: Pivot should still be (10, 10)
-                ValidateSingleRowSelection(term, SMALL_RECT({ 10, 10, 20, 10 }));
+                ValidateSingleRowSelection(term, til::inclusive_rect({ 10, 10, 20, 10 }));
             }
         }
     };
diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp
index 345288de8dd..808ce3cbd8e 100644
--- a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp
@@ -28,9 +28,9 @@ class TerminalCoreUnitTests::TerminalBufferTests final
     // !!! DANGER: Many tests in this class expect the Terminal buffer
     // to be 80x32. If you change these, you'll probably inadvertently break a
     // bunch of tests !!!
-    static const SHORT TerminalViewWidth = 80;
-    static const SHORT TerminalViewHeight = 32;
-    static const SHORT TerminalHistoryLength = 100;
+    static const til::CoordType TerminalViewWidth = 80;
+    static const til::CoordType TerminalViewHeight = 32;
+    static const til::CoordType TerminalHistoryLength = 100;
 
     TEST_CLASS(TerminalBufferTests);
 
@@ -70,8 +70,8 @@ class TerminalCoreUnitTests::TerminalBufferTests final
     }
 
 private:
-    void _SetTabStops(std::list<short> columns, bool replace);
-    std::list<short> _GetTabStops();
+    void _SetTabStops(std::list<til::CoordType> columns, bool replace);
+    std::list<til::CoordType> _GetTabStops();
 
     std::unique_ptr<DummyRenderer> emptyRenderer;
     std::unique_ptr<Terminal> term;
@@ -103,7 +103,7 @@ void TerminalBufferTests::TestWrappingCharByChar()
     const auto initialView = term->GetViewport();
     auto& cursor = termTb.GetCursor();
 
-    const auto charsToWrite = gsl::narrow_cast<short>(TestUtils::Test100CharsString.size());
+    const auto charsToWrite = gsl::narrow_cast<til::CoordType>(TestUtils::Test100CharsString.size());
 
     VERIFY_ARE_EQUAL(0, initialView.Top());
     VERIFY_ARE_EQUAL(32, initialView.BottomExclusive());
@@ -142,7 +142,7 @@ void TerminalBufferTests::TestWrappingALongString()
     const auto initialView = term->GetViewport();
     auto& cursor = termTb.GetCursor();
 
-    const auto charsToWrite = gsl::narrow_cast<short>(TestUtils::Test100CharsString.size());
+    const auto charsToWrite = gsl::narrow_cast<til::CoordType>(TestUtils::Test100CharsString.size());
     VERIFY_ARE_EQUAL(100, charsToWrite);
 
     VERIFY_ARE_EQUAL(0, initialView.Top());
@@ -251,7 +251,7 @@ void TerminalBufferTests::DontSnapToOutputTest()
     VERIFY_ARE_EQUAL(TerminalHistoryLength, term->_scrollOffset);
 }
 
-void TerminalBufferTests::_SetTabStops(std::list<short> columns, bool replace)
+void TerminalBufferTests::_SetTabStops(std::list<til::CoordType> columns, bool replace)
 {
     auto& termTb = *term->_mainBuffer;
     auto& termSm = *term->_stateMachine;
@@ -272,9 +272,9 @@ void TerminalBufferTests::_SetTabStops(std::list<short> columns, bool replace)
     }
 }
 
-std::list<short> TerminalBufferTests::_GetTabStops()
+std::list<til::CoordType> TerminalBufferTests::_GetTabStops()
 {
-    std::list<short> columns;
+    std::list<til::CoordType> columns;
     auto& termTb = *term->_mainBuffer;
     auto& termSm = *term->_stateMachine;
     const auto initialView = term->GetViewport();
@@ -305,7 +305,7 @@ void TerminalBufferTests::TestResetClearTabStops()
     const auto resetToInitialState = L"\033c";
 
     Log::Comment(L"Default tabs every 8 columns.");
-    std::list<short> expectedStops{ 8, 16, 24, 32, 40, 48, 56, 64, 72 };
+    std::list<til::CoordType> expectedStops{ 8, 16, 24, 32, 40, 48, 56, 64, 72 };
     VERIFY_ARE_EQUAL(expectedStops, _GetTabStops());
 
     Log::Comment(L"Clear all tabs.");
@@ -330,7 +330,7 @@ void TerminalBufferTests::TestAddTabStop()
 
     Log::Comment(L"Clear all tabs.");
     termSm.ProcessString(clearTabStops);
-    std::list<short> expectedStops{};
+    std::list<til::CoordType> expectedStops{};
     VERIFY_ARE_EQUAL(expectedStops, _GetTabStops());
 
     Log::Comment(L"Add tab to empty list.");
@@ -419,7 +419,7 @@ void TerminalBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear head.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(inputData, false);
         cursor.SetXPosition(inputData.front());
         termSm.ProcessString(clearTabStop);
@@ -433,7 +433,7 @@ void TerminalBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear middle.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(inputData, false);
         cursor.SetXPosition(*std::next(inputData.begin()));
         termSm.ProcessString(clearTabStop);
@@ -447,7 +447,7 @@ void TerminalBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear tail.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(inputData, false);
         cursor.SetXPosition(inputData.back());
         termSm.ProcessString(clearTabStop);
@@ -461,7 +461,7 @@ void TerminalBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear nonexistent item.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(inputData, false);
         cursor.SetXPosition(0);
         termSm.ProcessString(clearTabStop);
@@ -482,7 +482,7 @@ void TerminalBufferTests::TestGetForwardTab()
 
     const auto nextForwardTab = L"\033[I";
 
-    std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+    std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
     _SetTabStops(inputData, true);
 
     const auto coordScreenBufferSize = initialView.Dimensions();
@@ -551,7 +551,7 @@ void TerminalBufferTests::TestGetReverseTab()
 
     const auto nextReverseTab = L"\033[Z";
 
-    std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+    std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
     _SetTabStops(inputData, true);
 
     Log::Comment(L"Find previous tab from before front.");
diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp
index 91428816843..ab496e7be4a 100644
--- a/src/cascadia/WindowsTerminal/AppHost.cpp
+++ b/src/cascadia/WindowsTerminal/AppHost.cpp
@@ -549,21 +549,21 @@ LaunchPosition AppHost::_GetWindowLaunchPosition()
 // - launchMode: A LaunchMode enum reference that indicates the launch mode
 // Return Value:
 // - None
-void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode)
+void AppHost::_HandleCreateWindow(const HWND hwnd, til::rect proposedRect, LaunchMode& launchMode)
 {
     launchMode = _logic.GetLaunchMode();
 
     // Acquire the actual initial position
     auto initialPos = _logic.GetInitialPosition(proposedRect.left, proposedRect.top);
     const auto centerOnLaunch = _logic.CenterOnLaunch();
-    proposedRect.left = static_cast<long>(initialPos.X);
-    proposedRect.top = static_cast<long>(initialPos.Y);
+    proposedRect.left = gsl::narrow<til::CoordType>(initialPos.X);
+    proposedRect.top = gsl::narrow<til::CoordType>(initialPos.Y);
 
     long adjustedHeight = 0;
     long adjustedWidth = 0;
 
     // Find nearest monitor.
-    auto hmon = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
+    auto hmon = MonitorFromRect(proposedRect.as_win32_rect(), MONITOR_DEFAULTTONEAREST);
 
     // Get nearest monitor information
     MONITORINFO monitorInfo;
@@ -620,13 +620,13 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
                           Utils::ClampToShortMax(adjustedHeight, 1) };
 
     // Find nearest monitor for the position that we've actually settled on
-    auto hMonNearest = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
+    auto hMonNearest = MonitorFromRect(proposedRect.as_win32_rect(), MONITOR_DEFAULTTONEAREST);
     MONITORINFO nearestMonitorInfo;
     nearestMonitorInfo.cbSize = sizeof(MONITORINFO);
     // Get monitor dimensions:
     GetMonitorInfo(hMonNearest, &nearestMonitorInfo);
-    const til::size desktopDimensions{ gsl::narrow<short>(nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left),
-                                       gsl::narrow<short>(nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top) };
+    const til::size desktopDimensions{ nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left,
+                                       nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top };
 
     // GH#10583 - Adjust the position of the rectangle to account for the size
     // of the invisible borders on the left/right. We DON'T want to adjust this
@@ -642,11 +642,11 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
         // space reserved for the resize handles. So retrieve that size here.
         const auto availableSpace = desktopDimensions + nonClientSize;
 
-        origin = til::point{
-            ::base::ClampSub(nearestMonitorInfo.rcWork.left, (nonClientSize.width / 2)),
+        origin = {
+            (nearestMonitorInfo.rcWork.left - (nonClientSize.width / 2)),
             (nearestMonitorInfo.rcWork.top)
         };
-        dimensions = til::size{
+        dimensions = {
             availableSpace.width,
             availableSpace.height / 2
         };
@@ -655,7 +655,7 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
     else if (centerOnLaunch)
     {
         // Move our proposed location into the center of that specific monitor.
-        origin = til::point{
+        origin = {
             (nearestMonitorInfo.rcWork.left + ((desktopDimensions.width / 2) - (dimensions.width / 2))),
             (nearestMonitorInfo.rcWork.top + ((desktopDimensions.height / 2) - (dimensions.height / 2)))
         };
diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h
index f65bb103fd0..a3ae4edd2ba 100644
--- a/src/cascadia/WindowsTerminal/AppHost.h
+++ b/src/cascadia/WindowsTerminal/AppHost.h
@@ -40,7 +40,7 @@ class AppHost
     void _HandleCommandlineArgs();
     winrt::Microsoft::Terminal::Settings::Model::LaunchPosition _GetWindowLaunchPosition();
 
-    void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
+    void _HandleCreateWindow(const HWND hwnd, til::rect proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
     void _UpdateTitleBarContent(const winrt::Windows::Foundation::IInspectable& sender,
                                 const winrt::Windows::UI::Xaml::UIElement& arg);
     void _UpdateTheme(const winrt::Windows::Foundation::IInspectable&,
diff --git a/src/cascadia/WindowsTerminal/BaseWindow.h b/src/cascadia/WindowsTerminal/BaseWindow.h
index f74e22791b1..98538c82b78 100644
--- a/src/cascadia/WindowsTerminal/BaseWindow.h
+++ b/src/cascadia/WindowsTerminal/BaseWindow.h
@@ -146,13 +146,13 @@ class BaseWindow
     }
 
     //// Gets the physical size of the client area of the HWND in _window
-    SIZE GetPhysicalSize() const noexcept
+    til::size GetPhysicalSize() const noexcept
     {
         RECT rect = {};
         GetClientRect(_window.get(), &rect);
         const auto windowsWidth = rect.right - rect.left;
         const auto windowsHeight = rect.bottom - rect.top;
-        return SIZE{ windowsWidth, windowsHeight };
+        return { windowsWidth, windowsHeight };
     }
 
     //// Gets the logical (in DIPs) size of a physical size specified by the parameter physicalSize
@@ -164,7 +164,7 @@ class BaseWindow
     //// See also:
     ////   https://docs.microsoft.com/en-us/windows/desktop/LearnWin32/dpi-and-device-independent-pixels
     ////   https://docs.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness
-    winrt::Windows::Foundation::Size GetLogicalSize(const SIZE physicalSize) const noexcept
+    winrt::Windows::Foundation::Size GetLogicalSize(const til::size physicalSize) const noexcept
     {
         const auto scale = GetCurrentDpiScale();
         // 0.5 is to ensure that we pixel snap correctly at the edges, this is necessary with odd DPIs like 1.25, 1.5, 1, .75
diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp
index a1a79a30d7c..3b54950ec00 100644
--- a/src/cascadia/WindowsTerminal/IslandWindow.cpp
+++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp
@@ -108,11 +108,11 @@ void IslandWindow::Close()
 // - pfn: a function to be called during the handling of WM_CREATE. It takes two
 //   parameters:
 //      * HWND: the HWND of the window that's being created.
-//      * RECT: The position on the screen that the system has proposed for our
+//      * til::rect: The position on the screen that the system has proposed for our
 //        window.
 // Return Value:
 // - <none>
-void IslandWindow::SetCreateCallback(std::function<void(const HWND, const RECT, LaunchMode& launchMode)> pfn) noexcept
+void IslandWindow::SetCreateCallback(std::function<void(const HWND, const til::rect&, LaunchMode& launchMode)> pfn) noexcept
 {
     _pfnCreateCallback = pfn;
 }
@@ -148,7 +148,7 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
 {
     // Get proposed window rect from create structure
     auto pcs = reinterpret_cast<CREATESTRUCTW*>(lParam);
-    RECT rc;
+    til::rect rc;
     rc.left = pcs->x;
     rc.top = pcs->y;
     rc.right = rc.left + pcs->cx;
@@ -713,9 +713,9 @@ void IslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content)
 // Arguments:
 // - dpi: the scaling that we should use to calculate the border sizes.
 // Return Value:
-// - a RECT whose components represent the margins of the nonclient area,
+// - a til::rect whose components represent the margins of the nonclient area,
 //   relative to the client area.
-RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
+til::rect IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
 {
     const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
     RECT islandFrame{};
@@ -724,7 +724,7 @@ RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
     // the error and go on. We'll use whatever the control proposed as the
     // size of our window, which will be at least close.
     LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
-    return islandFrame;
+    return til::rect{ islandFrame };
 }
 
 // Method Description:
@@ -733,7 +733,7 @@ RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
 // - dpi: dpi of a monitor on which the window is placed
 // Return Value
 // - The size difference
-SIZE IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
+til::size IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
 {
     const auto islandFrame{ GetNonClientFrame(dpi) };
     return {
@@ -1015,7 +1015,7 @@ void IslandWindow::_SetIsBorderless(const bool borderlessEnabled)
 // - Called when entering fullscreen, with the window's current monitor rect and work area.
 // - The current window position, dpi, work area, and maximized state are stored, and the
 //   window is positioned to the monitor rect.
-void IslandWindow::_SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork)
+void IslandWindow::_SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork)
 {
     const auto hWnd = GetHandle();
 
@@ -1039,7 +1039,7 @@ void IslandWindow::_SetFullscreenPosition(const RECT rcMonitor, const RECT rcWor
 //   window's current monitor (if the current work area or window DPI have changed).
 // - A fullscreen window's monitor can be changed by win+shift+left/right hotkeys or monitor
 //   topology changes (for example unplugging a monitor or disconnecting a remote session).
-void IslandWindow::_RestoreFullscreenPosition(const RECT rcWork)
+void IslandWindow::_RestoreFullscreenPosition(const RECT& rcWork)
 {
     const auto hWnd = GetHandle();
 
@@ -1698,7 +1698,7 @@ til::rect IslandWindow::_getQuakeModeSize(HMONITOR hmon)
         availableSpace.height / 2
     };
 
-    return til::rect{ origin, dimensions };
+    return { origin, dimensions };
 }
 
 void IslandWindow::HideWindow()
diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h
index dcd805dc52f..64e16d9397c 100644
--- a/src/cascadia/WindowsTerminal/IslandWindow.h
+++ b/src/cascadia/WindowsTerminal/IslandWindow.h
@@ -32,12 +32,12 @@ class IslandWindow :
     virtual void OnAppInitialized();
     virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
     virtual void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
-    virtual RECT GetNonClientFrame(const UINT dpi) const noexcept;
-    virtual SIZE GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept;
+    virtual til::rect GetNonClientFrame(const UINT dpi) const noexcept;
+    virtual til::size GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept;
 
     virtual void Initialize();
 
-    void SetCreateCallback(std::function<void(const HWND, const RECT, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> pfn) noexcept;
+    void SetCreateCallback(std::function<void(const HWND, const til::rect&, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> pfn) noexcept;
     void SetSnapDimensionCallback(std::function<float(bool widthOrHeight, float dimension)> pfn) noexcept;
 
     void FocusModeChanged(const bool focusMode);
@@ -94,7 +94,7 @@ class IslandWindow :
     winrt::Windows::UI::Xaml::Controls::Grid _rootGrid;
     wil::com_ptr<ITaskbarList3> _taskbar;
 
-    std::function<void(const HWND, const RECT, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> _pfnCreateCallback;
+    std::function<void(const HWND, const til::rect&, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> _pfnCreateCallback;
     std::function<float(bool, float)> _pfnSnapDimensionCallback;
 
     void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept;
@@ -111,8 +111,8 @@ class IslandWindow :
 
     virtual void _SetIsBorderless(const bool borderlessEnabled);
     virtual void _SetIsFullscreen(const bool fullscreenEnabled);
-    void _RestoreFullscreenPosition(const RECT rcWork);
-    void _SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork);
+    void _RestoreFullscreenPosition(const RECT& rcWork);
+    void _SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork);
 
     LONG _getDesiredWindowStyle() const;
 
diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
index 97094434746..01b0bd66346 100644
--- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
+++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp
@@ -154,7 +154,7 @@ LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message,
     {
         // Try to determine what part of the window is being hovered here. This
         // is absolutely critical to making sure Snap Layouts (GH#9443) works!
-        return _dragBarNcHitTest(til::point{ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) });
+        return _dragBarNcHitTest({ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) });
     }
     break;
 
@@ -425,7 +425,7 @@ int NonClientIslandWindow::_GetTopBorderHeight() const noexcept
     return topBorderVisibleHeight;
 }
 
-RECT NonClientIslandWindow::_GetDragAreaRect() const noexcept
+til::rect NonClientIslandWindow::_GetDragAreaRect() const noexcept
 {
     if (_dragBar && _dragBar.Visibility() == Visibility::Visible)
     {
@@ -445,16 +445,15 @@ RECT NonClientIslandWindow::_GetDragAreaRect() const noexcept
             static_cast<float>(_dragBar.ActualHeight())
         };
         const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);
-        RECT dragBarRect = {
-            static_cast<LONG>(clientDragBarRect.X * scale),
-            static_cast<LONG>(clientDragBarRect.Y * scale),
-            static_cast<LONG>((clientDragBarRect.Width + clientDragBarRect.X) * scale),
-            static_cast<LONG>((clientDragBarRect.Height + clientDragBarRect.Y) * scale),
+        return {
+            gsl::narrow_cast<til::CoordType>(clientDragBarRect.X * scale),
+            gsl::narrow_cast<til::CoordType>(clientDragBarRect.Y * scale),
+            gsl::narrow_cast<til::CoordType>((clientDragBarRect.Width + clientDragBarRect.X) * scale),
+            gsl::narrow_cast<til::CoordType>((clientDragBarRect.Height + clientDragBarRect.Y) * scale),
         };
-        return dragBarRect;
     }
 
-    return RECT{};
+    return {};
 }
 
 // Method Description:
@@ -539,9 +538,9 @@ void NonClientIslandWindow::_UpdateIslandPosition(const UINT windowWidth, const
     // buttons, which will make them clickable. It's perhaps not the right fix,
     // but it works.
     // _GetTopBorderHeight() returns 0 when we're maximized.
-    const auto topBorderHeight = ::base::saturated_cast<short>((originalTopHeight == 0) ? -1 : originalTopHeight);
+    const auto topBorderHeight = (originalTopHeight == 0) ? -1 : originalTopHeight;
 
-    const COORD newIslandPos = { 0, topBorderHeight };
+    const til::point newIslandPos = { 0, topBorderHeight };
 
     winrt::check_bool(SetWindowPos(_interopWindowHandle,
                                    HWND_BOTTOM,
@@ -807,17 +806,17 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
 // Arguments:
 // - dpi: the scaling that we should use to calculate the border sizes.
 // Return Value:
-// - a RECT whose components represent the margins of the nonclient area,
+// - a til::rect whose components represent the margins of the nonclient area,
 //   relative to the client area.
-RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
+til::rect NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
 {
     const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
-    RECT islandFrame{};
+    til::rect islandFrame;
 
     // If we failed to get the correct window size for whatever reason, log
     // the error and go on. We'll use whatever the control proposed as the
     // size of our window, which will be at least close.
-    LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
+    LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(islandFrame.as_win32_rect(), windowStyle, false, 0, dpi));
 
     islandFrame.top = -topBorderVisibleHeight;
     return islandFrame;
@@ -829,7 +828,7 @@ RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
 // - dpi: dpi of a monitor on which the window is placed
 // Return Value
 // - The size difference
-SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
+til::size NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
 {
     const auto islandFrame{ GetNonClientFrame(dpi) };
 
diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h
index 7f5cfb36b35..0b54ec92db3 100644
--- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h
+++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h
@@ -37,8 +37,8 @@ class NonClientIslandWindow : public IslandWindow
 
     [[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
 
-    virtual RECT GetNonClientFrame(UINT dpi) const noexcept override;
-    virtual SIZE GetTotalNonClientExclusiveSize(UINT dpi) const noexcept override;
+    virtual til::rect GetNonClientFrame(UINT dpi) const noexcept override;
+    virtual til::size GetTotalNonClientExclusiveSize(UINT dpi) const noexcept override;
 
     void Initialize() override;
 
@@ -48,7 +48,7 @@ class NonClientIslandWindow : public IslandWindow
     void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) override;
 
 private:
-    std::optional<COORD> _oldIslandPos;
+    std::optional<til::point> _oldIslandPos;
 
     winrt::TerminalApp::TitlebarControl _titlebar{ nullptr };
     winrt::Windows::UI::Xaml::UIElement _clientContent{ nullptr };
@@ -70,7 +70,7 @@ class NonClientIslandWindow : public IslandWindow
     void _ResizeDragBarWindow() noexcept;
 
     int _GetResizeHandleHeight() const noexcept;
-    RECT _GetDragAreaRect() const noexcept;
+    til::rect _GetDragAreaRect() const noexcept;
     int _GetTopBorderHeight() const noexcept;
     LRESULT _dragBarNcHitTest(const til::point pointer);
 
diff --git a/src/cascadia/WpfTerminalControl/NativeMethods.cs b/src/cascadia/WpfTerminalControl/NativeMethods.cs
index eb0b4de4110..e22f40bdf0b 100644
--- a/src/cascadia/WpfTerminalControl/NativeMethods.cs
+++ b/src/cascadia/WpfTerminalControl/NativeMethods.cs
@@ -186,31 +186,31 @@ public enum SetWindowPosFlags : uint
         public static extern void TerminalSendOutput(IntPtr terminal, string lpdata);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern uint TerminalTriggerResize(IntPtr terminal, short width, short height, out COORD dimensions);
+        public static extern uint TerminalTriggerResize(IntPtr terminal, int width, int height, out TilSize dimensions);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern uint TerminalTriggerResizeWithDimension(IntPtr terminal, [MarshalAs(UnmanagedType.Struct)] COORD dimensions, out SIZE dimensionsInPixels);
+        public static extern uint TerminalTriggerResizeWithDimension(IntPtr terminal, TilSize dimensions, out TilSize dimensionsInPixels);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern uint TerminalCalculateResize(IntPtr terminal, short width, short height, out COORD dimensions);
+        public static extern uint TerminalCalculateResize(IntPtr terminal, int width, int height, out TilSize dimensions);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
         public static extern void TerminalDpiChanged(IntPtr terminal, int newDpi);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern void TerminalRegisterScrollCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)]ScrollCallback callback);
+        public static extern void TerminalRegisterScrollCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)] ScrollCallback callback);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern void TerminalRegisterWriteCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)]WriteCallback callback);
+        public static extern void TerminalRegisterWriteCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)] WriteCallback callback);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
         public static extern void TerminalUserScroll(IntPtr terminal, int viewTop);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern uint TerminalStartSelection(IntPtr terminal, COORD cursorPosition, bool altPressed);
+        public static extern uint TerminalStartSelection(IntPtr terminal, TilPoint cursorPosition, bool altPressed);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
-        public static extern uint TerminalMoveSelection(IntPtr terminal, COORD cursorPosition);
+        public static extern uint TerminalMoveSelection(IntPtr terminal, TilPoint cursorPosition);
 
         [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
         public static extern void TerminalClearSelection(IntPtr terminal);
@@ -272,31 +272,31 @@ public struct WINDOWPOS
         }
 
         [StructLayout(LayoutKind.Sequential)]
-        public struct COORD
+        public struct TilPoint
         {
             /// <summary>
             ///  The x-coordinate of the point.
             /// </summary>
-            public short X;
+            public int X;
 
             /// <summary>
             /// The y-coordinate of the point.
             /// </summary>
-            public short Y;
+            public int Y;
         }
 
         [StructLayout(LayoutKind.Sequential)]
-        public struct SIZE
+        public struct TilSize
         {
             /// <summary>
             ///  The x size.
             /// </summary>
-            public int cx;
+            public int X;
 
             /// <summary>
             /// The y size.
             /// </summary>
-            public int cy;
+            public int Y;
         }
     }
 #pragma warning restore SA1600 // Elements should be documented
diff --git a/src/cascadia/WpfTerminalControl/TerminalContainer.cs b/src/cascadia/WpfTerminalControl/TerminalContainer.cs
index fc4c4039a41..960fa4fd1c9 100644
--- a/src/cascadia/WpfTerminalControl/TerminalContainer.cs
+++ b/src/cascadia/WpfTerminalControl/TerminalContainer.cs
@@ -173,9 +173,9 @@ internal void Resize(Size renderSize)
 
             NativeMethods.TerminalTriggerResize(
                 this.terminal,
-                Convert.ToInt16(renderSize.Width),
-                Convert.ToInt16(renderSize.Height),
-                out NativeMethods.COORD dimensions);
+                (int)renderSize.Width,
+                (int)renderSize.Height,
+                out NativeMethods.TilSize dimensions);
 
             this.Rows = dimensions.Y;
             this.Columns = dimensions.X;
@@ -200,11 +200,11 @@ internal void Resize(uint rows, uint columns)
                 throw new ArgumentException("Terminal column count cannot be 0.", nameof(columns));
             }
 
-            NativeMethods.SIZE dimensionsInPixels;
-            NativeMethods.COORD dimensions = new NativeMethods.COORD
+            NativeMethods.TilSize dimensionsInPixels;
+            NativeMethods.TilSize dimensions = new NativeMethods.TilSize
             {
-                X = (short)columns,
-                Y = (short)rows,
+                X = (int)columns,
+                Y = (int)rows,
             };
 
             NativeMethods.TerminalTriggerResizeWithDimension(this.terminal, dimensions, out dimensionsInPixels);
@@ -214,8 +214,8 @@ internal void Resize(uint rows, uint columns)
 
             this.TerminalRendererSize = new Size()
             {
-                Width = dimensionsInPixels.cx,
-                Height = dimensionsInPixels.cy,
+                Width = dimensionsInPixels.X,
+                Height = dimensionsInPixels.Y,
             };
 
             this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
@@ -226,11 +226,11 @@ internal void Resize(uint rows, uint columns)
         /// </summary>
         /// <param name="size">DPI scaled size.</param>
         /// <returns>Amount of rows and columns that would fit the given size.</returns>
-        internal (uint columns, uint rows) CalculateRowsAndColumns(Size size)
+        internal (int columns, int rows) CalculateRowsAndColumns(Size size)
         {
-            NativeMethods.TerminalCalculateResize(this.terminal, (short)size.Width, (short)size.Height, out NativeMethods.COORD dimensions);
+            NativeMethods.TerminalCalculateResize(this.terminal, (int)size.Width, (int)size.Height, out NativeMethods.TilSize dimensions);
 
-            return ((uint)dimensions.X, (uint)dimensions.Y);
+            return (dimensions.X, dimensions.Y);
         }
 
         /// <summary>
@@ -242,7 +242,7 @@ internal void RaiseResizedIfDrawSpaceIncreased()
 
             if (this.Columns < columns || this.Rows < rows)
             {
-                this.connection?.Resize(rows, columns);
+                this.connection?.Resize((uint)rows, (uint)columns);
             }
         }
 
@@ -368,11 +368,11 @@ private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam
                             break;
                         }
 
-                        NativeMethods.COORD dimensions;
+                        NativeMethods.TilSize dimensions;
 
                         if (this.AutoResize)
                         {
-                            NativeMethods.TerminalTriggerResize(this.terminal, (short)windowpos.cx, (short)windowpos.cy, out dimensions);
+                            NativeMethods.TerminalTriggerResize(this.terminal, windowpos.cx, windowpos.cy, out dimensions);
 
                             this.Columns = dimensions.X;
                             this.Rows = dimensions.Y;
@@ -386,7 +386,7 @@ private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam
                         else
                         {
                             // Calculate the new columns and rows that fit the total control size and alert the control to redraw the margins.
-                            NativeMethods.TerminalCalculateResize(this.terminal, (short)this.TerminalControlSize.Width, (short)this.TerminalControlSize.Height, out dimensions);
+                            NativeMethods.TerminalCalculateResize(this.terminal, (int)this.TerminalControlSize.Width, (int)this.TerminalControlSize.Height, out dimensions);
                         }
 
                         this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
@@ -405,9 +405,9 @@ private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam
         private void LeftClickHandler(int lParam)
         {
             var altPressed = NativeMethods.GetKeyState((int)NativeMethods.VirtualKey.VK_MENU) < 0;
-            var x = (short)(((int)lParam << 16) >> 16);
-            var y = (short)((int)lParam >> 16);
-            NativeMethods.COORD cursorPosition = new NativeMethods.COORD()
+            var x = lParam & 0xffff;
+            var y = lParam >> 16;
+            var cursorPosition = new NativeMethods.TilPoint()
             {
                 X = x,
                 Y = y,
@@ -418,11 +418,11 @@ private void LeftClickHandler(int lParam)
 
         private void MouseMoveHandler(int wParam, int lParam)
         {
-            if (((int)wParam & 0x0001) == 1)
+            if ((wParam & 0x0001) == 1)
             {
-                var x = (short)(((int)lParam << 16) >> 16);
-                var y = (short)((int)lParam >> 16);
-                NativeMethods.COORD cursorPosition = new NativeMethods.COORD()
+                var x = lParam & 0xffff;
+                var y = lParam >> 16;
+                var cursorPosition = new NativeMethods.TilPoint()
                 {
                     X = x,
                     Y = y,
diff --git a/src/host/ApiRoutines.h b/src/host/ApiRoutines.h
index 107cc687806..457aaee9f00 100644
--- a/src/host/ApiRoutines.h
+++ b/src/host/ApiRoutines.h
@@ -118,19 +118,19 @@ class ApiRoutines : public IApiRoutines
     [[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                          const WORD attribute,
                                                          const size_t lengthToWrite,
-                                                         const COORD startingCoordinate,
+                                                         const til::point startingCoordinate,
                                                          size_t& cellsModified) noexcept override;
 
     [[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                           const char character,
                                                           const size_t lengthToWrite,
-                                                          const COORD startingCoordinate,
+                                                          const til::point startingCoordinate,
                                                           size_t& cellsModified) noexcept override;
 
     [[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                           const wchar_t character,
                                                           const size_t lengthToWrite,
-                                                          const COORD startingCoordinate,
+                                                          const til::point startingCoordinate,
                                                           size_t& cellsModified,
                                                           const bool enablePowershellShim = false) noexcept override;
 
@@ -162,25 +162,25 @@ class ApiRoutines : public IApiRoutines
                                                            const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override;
 
     [[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
-                                                         const COORD size) noexcept override;
+                                                         const til::size size) noexcept override;
 
     [[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
-                                                       const COORD position) noexcept override;
+                                                       const til::point position) noexcept override;
 
     void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
-                                         COORD& size) noexcept override;
+                                         til::size& size) noexcept override;
 
     [[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
-                                                         const SMALL_RECT& source,
-                                                         const COORD target,
-                                                         std::optional<SMALL_RECT> clip,
+                                                         const til::inclusive_rect& source,
+                                                         const til::point target,
+                                                         std::optional<til::inclusive_rect> clip,
                                                          const char fillCharacter,
                                                          const WORD fillAttribute) noexcept override;
 
     [[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
-                                                         const SMALL_RECT& source,
-                                                         const COORD target,
-                                                         std::optional<SMALL_RECT> clip,
+                                                         const til::inclusive_rect& source,
+                                                         const til::point target,
+                                                         std::optional<til::inclusive_rect> clip,
                                                          const wchar_t fillCharacter,
                                                          const WORD fillAttribute,
                                                          const bool enableCmdShim = false) noexcept override;
@@ -190,20 +190,20 @@ class ApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
                                                    const bool isAbsolute,
-                                                   const SMALL_RECT& windowRect) noexcept override;
+                                                   const til::inclusive_rect& windowRect) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
-                                                         const COORD origin,
+                                                         const til::point origin,
                                                          gsl::span<WORD> buffer,
                                                          size_t& written) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
-                                                          const COORD origin,
+                                                          const til::point origin,
                                                           gsl::span<char> buffer,
                                                           size_t& written) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
-                                                          const COORD origin,
+                                                          const til::point origin,
                                                           gsl::span<wchar_t> buffer,
                                                           size_t& written) noexcept override;
 
@@ -229,17 +229,17 @@ class ApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                           const gsl::span<const WORD> attrs,
-                                                          const COORD target,
+                                                          const til::point target,
                                                           size_t& used) noexcept override;
 
     [[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                            const std::string_view text,
-                                                           const COORD target,
+                                                           const til::point target,
                                                            size_t& used) noexcept override;
 
     [[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                            const std::wstring_view text,
-                                                           const COORD target,
+                                                           const til::point target,
                                                            size_t& used) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context,
@@ -279,7 +279,7 @@ class ApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
                                                  const DWORD index,
-                                                 COORD& size) noexcept override;
+                                                 til::size& size) noexcept override;
 
     //// driver will pare down for non-Ex method
     [[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
@@ -288,7 +288,7 @@ class ApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
                                                     const ULONG flags,
-                                                    COORD& newSize) noexcept override;
+                                                    til::size& newSize) noexcept override;
 
     void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override;
 
diff --git a/src/host/CommandListPopup.cpp b/src/host/CommandListPopup.cpp
index dea942a7431..2539990d328 100644
--- a/src/host/CommandListPopup.cpp
+++ b/src/host/CommandListPopup.cpp
@@ -22,10 +22,10 @@ static constexpr size_t COMMAND_NUMBER_SIZE = 8; // size of command number buffe
 // - history - the history to look through to measure command sizes
 // Return Value:
 // - the proposed size of the popup with the history list taken into account
-static COORD calculatePopupSize(const CommandHistory& history)
+static til::size calculatePopupSize(const CommandHistory& history)
 {
     // this is the historical size of the popup, so it is now used as a minimum
-    const COORD minSize = { 40, 10 };
+    const til::size minSize = { 40, 10 };
 
     // padding is for the command number listing before a command is printed to the window.
     // ex: |10: echo blah
@@ -45,9 +45,9 @@ static COORD calculatePopupSize(const CommandHistory& history)
     }
 
     // calculate height, it can range up to 20 rows
-    auto height = std::clamp(gsl::narrow<short>(history.GetNumberOfCommands()), minSize.Y, 20i16);
+    auto height = std::clamp(gsl::narrow<til::CoordType>(history.GetNumberOfCommands()), minSize.Y, 20);
 
-    return { gsl::narrow<short>(width), height };
+    return { gsl::narrow_cast<til::CoordType>(width), height };
 }
 
 CommandListPopup::CommandListPopup(SCREEN_INFORMATION& screenInfo, const CommandHistory& history) :
@@ -139,7 +139,7 @@ void CommandListPopup::_setBottomIndex()
 {
     if (_currentCommand < (SHORT)(_history.GetNumberOfCommands() - Height()))
     {
-        _bottomIndex = std::max(_currentCommand, gsl::narrow<SHORT>(Height() - 1i16));
+        _bottomIndex = std::max(_currentCommand, gsl::narrow<SHORT>(Height() - 1));
     }
     else
     {
@@ -204,7 +204,7 @@ void CommandListPopup::_setBottomIndex()
     {
         auto& history = cookedReadData.History();
 
-        if (history.GetNumberOfCommands() <= 1 || _currentCommand == gsl::narrow<short>(history.GetNumberOfCommands()) - 1i16)
+        if (history.GetNumberOfCommands() <= 1 || _currentCommand == gsl::narrow<short>(history.GetNumberOfCommands()) - 1)
         {
             return STATUS_SUCCESS;
         }
@@ -330,22 +330,22 @@ void CommandListPopup::_DrawContent()
 void CommandListPopup::_drawList()
 {
     // draw empty popup
-    COORD WriteCoord;
-    WriteCoord.X = _region.Left + 1i16;
-    WriteCoord.Y = _region.Top + 1i16;
+    til::point WriteCoord;
+    WriteCoord.X = _region.Left + 1;
+    WriteCoord.Y = _region.Top + 1;
     size_t lStringLength = Width();
-    for (SHORT i = 0; i < Height(); ++i)
+    for (til::CoordType i = 0; i < Height(); ++i)
     {
         const OutputCellIterator spaces(UNICODE_SPACE, _attributes, lStringLength);
         const auto result = _screenInfo.Write(spaces, WriteCoord);
         lStringLength = result.GetCellDistance(spaces);
-        WriteCoord.Y += 1i16;
+        WriteCoord.Y += 1;
     }
 
     auto api = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().api;
 
-    WriteCoord.Y = _region.Top + 1i16;
-    auto i = std::max(gsl::narrow<SHORT>(_bottomIndex - Height() + 1), 0i16);
+    WriteCoord.Y = _region.Top + 1;
+    auto i = gsl::narrow<SHORT>(std::max(_bottomIndex - Height() + 1, 0));
     for (; i <= _bottomIndex; i++)
     {
         CHAR CommandNumber[COMMAND_NUMBER_SIZE];
@@ -377,7 +377,7 @@ void CommandListPopup::_drawList()
             CommandNumberLength = static_cast<ULONG>(Width());
         }
 
-        WriteCoord.X = _region.Left + 1i16;
+        WriteCoord.X = _region.Left + 1;
 
         LOG_IF_FAILED(api->WriteConsoleOutputCharacterAImpl(_screenInfo,
                                                             { CommandNumberPtr, CommandNumberLength },
@@ -415,7 +415,7 @@ void CommandListPopup::_drawList()
             }
         }
 
-        WriteCoord.X = gsl::narrow<SHORT>(WriteCoord.X + CommandNumberLength);
+        WriteCoord.X = gsl::narrow<til::CoordType>(WriteCoord.X + CommandNumberLength);
         size_t used;
         LOG_IF_FAILED(api->WriteConsoleOutputCharacterWImpl(_screenInfo,
                                                             { command.data(), lStringLength },
@@ -425,7 +425,7 @@ void CommandListPopup::_drawList()
         // write attributes to screen
         if (i == _currentCommand)
         {
-            WriteCoord.X = _region.Left + 1i16;
+            WriteCoord.X = _region.Left + 1;
             // inverted attributes
             lStringLength = Width();
             auto inverted = _attributes;
@@ -468,7 +468,7 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
     {
         if (NewCmdNum >= gsl::narrow<SHORT>(_history.GetNumberOfCommands()))
         {
-            NewCmdNum = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1i16;
+            NewCmdNum = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1;
         }
         else if (NewCmdNum < 0)
         {
@@ -482,9 +482,9 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
     if (NewCmdNum <= _bottomIndex - Size)
     {
         _bottomIndex += delta;
-        if (_bottomIndex < Size - 1i16)
+        if (_bottomIndex < Size - 1)
         {
-            _bottomIndex = Size - 1i16;
+            _bottomIndex = gsl::narrow<SHORT>(Size - 1);
         }
         Scroll = true;
     }
@@ -493,7 +493,7 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
         _bottomIndex += delta;
         if (_bottomIndex >= gsl::narrow<SHORT>(_history.GetNumberOfCommands()))
         {
-            _bottomIndex = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1i16;
+            _bottomIndex = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1;
         }
         Scroll = true;
     }
@@ -518,27 +518,27 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
 // - NewCurrentCommand - The new command to be highlighted.
 void CommandListPopup::_updateHighlight(const SHORT OldCurrentCommand, const SHORT NewCurrentCommand)
 {
-    SHORT TopIndex;
+    til::CoordType TopIndex;
     if (_bottomIndex < Height())
     {
         TopIndex = 0;
     }
     else
     {
-        TopIndex = _bottomIndex - Height() + 1i16;
+        TopIndex = _bottomIndex - Height() + 1;
     }
-    COORD WriteCoord;
-    WriteCoord.X = _region.Left + 1i16;
+    til::point WriteCoord;
+    WriteCoord.X = _region.Left + 1;
     size_t lStringLength = Width();
 
-    WriteCoord.Y = _region.Top + 1i16 + OldCurrentCommand - TopIndex;
+    WriteCoord.Y = _region.Top + 1 + OldCurrentCommand - TopIndex;
 
     const OutputCellIterator it(_attributes, lStringLength);
     const auto done = _screenInfo.Write(it, WriteCoord);
     lStringLength = done.GetCellDistance(it);
 
     // highlight new command
-    WriteCoord.Y = _region.Top + 1i16 + NewCurrentCommand - TopIndex;
+    WriteCoord.Y = _region.Top + 1 + NewCurrentCommand - TopIndex;
 
     // inverted attributes
     auto inverted = _attributes;
diff --git a/src/host/CursorBlinker.cpp b/src/host/CursorBlinker.cpp
index 91107d1c813..f9a809fd072 100644
--- a/src/host/CursorBlinker.cpp
+++ b/src/host/CursorBlinker.cpp
@@ -101,7 +101,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo) const noexcept
         const auto fontSize = ScreenInfo.GetScreenFontSize();
         cursor.SetHasMoved(false);
 
-        RECT rc;
+        til::rect rc;
         rc.left = (position.X - viewport.Left()) * fontSize.X;
         rc.top = (position.Y - viewport.Top()) * fontSize.Y;
         rc.right = rc.left + fontSize.X;
diff --git a/src/host/VtApiRoutines.cpp b/src/host/VtApiRoutines.cpp
index f2b007a2ffb..e01696e3848 100644
--- a/src/host/VtApiRoutines.cpp
+++ b/src/host/VtApiRoutines.cpp
@@ -237,7 +237,7 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
 [[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                                     const WORD attribute,
                                                                     const size_t lengthToWrite,
-                                                                    const COORD startingCoordinate,
+                                                                    const til::point startingCoordinate,
                                                                     size_t& cellsModified) noexcept
 {
     (void)m_pVtEngine->_CursorPosition(startingCoordinate);
@@ -252,7 +252,7 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
 [[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                                      const char character,
                                                                      const size_t lengthToWrite,
-                                                                     const COORD startingCoordinate,
+                                                                     const til::point startingCoordinate,
                                                                      size_t& cellsModified) noexcept
 {
     // I mean... if you get your jollies by using UTF8 for single byte codepoints...
@@ -275,7 +275,7 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
 [[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                                      const wchar_t character,
                                                                      const size_t lengthToWrite,
-                                                                     const COORD startingCoordinate,
+                                                                     const til::point startingCoordinate,
                                                                      size_t& cellsModified,
                                                                      const bool enablePowershellShim) noexcept
 {
@@ -350,7 +350,7 @@ void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& c
                                                                       const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept
 {
     (void)m_pVtEngine->_ResizeWindow(data.srWindow.Right - data.srWindow.Left, data.srWindow.Bottom - data.srWindow.Top);
-    (void)m_pVtEngine->_CursorPosition(data.dwCursorPosition);
+    (void)m_pVtEngine->_CursorPosition(til::wrap_coord(data.dwCursorPosition));
     (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast<BYTE>(data.wAttributes), true);
     (void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast<BYTE>(data.wAttributes >> 4), false);
     //color table?
@@ -361,14 +361,14 @@ void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& c
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
-                                                                    const COORD size) noexcept
+                                                                    const til::size size) noexcept
 {
     // Don't transmit. The terminal figures out its own buffer size.
     return S_OK;
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
-                                                                  const COORD position) noexcept
+                                                                  const til::point position) noexcept
 {
     if (m_listeningForDSR)
     {
@@ -384,16 +384,16 @@ void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& c
 }
 
 void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
-                                                    COORD& size) noexcept
+                                                    til::size& size) noexcept
 {
     m_pUsualRoutines->GetLargestConsoleWindowSizeImpl(context, size); // This is likely super weird but not weirder than existing ConPTY answers.
     return;
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
-                                                                    const SMALL_RECT& source,
-                                                                    const COORD target,
-                                                                    std::optional<SMALL_RECT> clip,
+                                                                    const til::inclusive_rect& source,
+                                                                    const til::point target,
+                                                                    std::optional<til::inclusive_rect> clip,
                                                                     const char fillCharacter,
                                                                     const WORD fillAttribute) noexcept
 {
@@ -402,9 +402,9 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
-                                                                    const SMALL_RECT& source,
-                                                                    const COORD target,
-                                                                    std::optional<SMALL_RECT> clip,
+                                                                    const til::inclusive_rect& source,
+                                                                    const til::point target,
+                                                                    std::optional<til::inclusive_rect> clip,
                                                                     const wchar_t fillCharacter,
                                                                     const WORD fillAttribute,
                                                                     const bool enableCmdShim) noexcept
@@ -424,15 +424,15 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
 
 [[nodiscard]] HRESULT VtApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
                                                               const bool isAbsolute,
-                                                              const SMALL_RECT& windowRect) noexcept
+                                                              const til::inclusive_rect& windowRect) noexcept
 {
-    (void)m_pVtEngine->_ResizeWindow(windowRect.Right - windowRect.Left, windowRect.Bottom - windowRect.Top);
+    (void)m_pVtEngine->_ResizeWindow(windowRect.Right - windowRect.Left + 1, windowRect.Bottom - windowRect.Top + 1);
     (void)m_pVtEngine->_Flush();
     return S_OK;
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
-                                                                    const COORD origin,
+                                                                    const til::point origin,
                                                                     gsl::span<WORD> buffer,
                                                                     size_t& written) noexcept
 {
@@ -442,7 +442,7 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
-                                                                     const COORD origin,
+                                                                     const til::point origin,
                                                                      gsl::span<char> buffer,
                                                                      size_t& written) noexcept
 {
@@ -452,7 +452,7 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
 }
 
 [[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
-                                                                     const COORD origin,
+                                                                     const til::point origin,
                                                                      gsl::span<wchar_t> buffer,
                                                                      size_t& written) noexcept
 {
@@ -498,7 +498,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
                                                              const Microsoft::Console::Types::Viewport& requestRectangle,
                                                              Microsoft::Console::Types::Viewport& writtenRectangle) noexcept
 {
-    COORD cursor{ requestRectangle.Left(), requestRectangle.Top() };
+    auto cursor = requestRectangle.Origin();
 
     const size_t width = requestRectangle.Width();
     size_t pos = 0;
@@ -529,7 +529,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
 
 [[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                                      const gsl::span<const WORD> attrs,
-                                                                     const COORD target,
+                                                                     const til::point target,
                                                                      size_t& used) noexcept
 {
     (void)m_pVtEngine->_CursorPosition(target);
@@ -549,7 +549,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
 
 [[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                                       const std::string_view text,
-                                                                      const COORD target,
+                                                                      const til::point target,
                                                                       size_t& used) noexcept
 {
     if (m_outputCodepage == CP_UTF8)
@@ -567,7 +567,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
 
 [[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                                       const std::wstring_view text,
-                                                                      const COORD target,
+                                                                      const til::point target,
                                                                       size_t& used) noexcept
 {
     (void)m_pVtEngine->_CursorPosition(target);
@@ -676,7 +676,7 @@ void VtApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
 
 [[nodiscard]] HRESULT VtApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
                                                             const DWORD index,
-                                                            COORD& size) noexcept
+                                                            til::size& size) noexcept
 {
     size.X = 8;
     size.Y = 12;
@@ -693,7 +693,7 @@ void VtApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
 
 [[nodiscard]] HRESULT VtApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
                                                                const ULONG flags,
-                                                               COORD& newSize) noexcept
+                                                               til::size& newSize) noexcept
 {
     return S_OK;
 }
diff --git a/src/host/VtApiRoutines.h b/src/host/VtApiRoutines.h
index ef6dd351e80..79962bc989a 100644
--- a/src/host/VtApiRoutines.h
+++ b/src/host/VtApiRoutines.h
@@ -121,19 +121,19 @@ class VtApiRoutines : public IApiRoutines
     [[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                          const WORD attribute,
                                                          const size_t lengthToWrite,
-                                                         const COORD startingCoordinate,
+                                                         const til::point startingCoordinate,
                                                          size_t& cellsModified) noexcept override;
 
     [[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                           const char character,
                                                           const size_t lengthToWrite,
-                                                          const COORD startingCoordinate,
+                                                          const til::point startingCoordinate,
                                                           size_t& cellsModified) noexcept override;
 
     [[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                           const wchar_t character,
                                                           const size_t lengthToWrite,
-                                                          const COORD startingCoordinate,
+                                                          const til::point startingCoordinate,
                                                           size_t& cellsModified,
                                                           const bool enablePowershellShim = false) noexcept override;
 
@@ -165,25 +165,25 @@ class VtApiRoutines : public IApiRoutines
                                                            const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override;
 
     [[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
-                                                         const COORD size) noexcept override;
+                                                         const til::size size) noexcept override;
 
     [[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
-                                                       const COORD position) noexcept override;
+                                                       const til::point position) noexcept override;
 
     void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
-                                         COORD& size) noexcept override;
+                                         til::size& size) noexcept override;
 
     [[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
-                                                         const SMALL_RECT& source,
-                                                         const COORD target,
-                                                         std::optional<SMALL_RECT> clip,
+                                                         const til::inclusive_rect& source,
+                                                         const til::point target,
+                                                         std::optional<til::inclusive_rect> clip,
                                                          const char fillCharacter,
                                                          const WORD fillAttribute) noexcept override;
 
     [[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
-                                                         const SMALL_RECT& source,
-                                                         const COORD target,
-                                                         std::optional<SMALL_RECT> clip,
+                                                         const til::inclusive_rect& source,
+                                                         const til::point target,
+                                                         std::optional<til::inclusive_rect> clip,
                                                          const wchar_t fillCharacter,
                                                          const WORD fillAttribute,
                                                          const bool enableCmdShim = false) noexcept override;
@@ -193,20 +193,20 @@ class VtApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
                                                    const bool isAbsolute,
-                                                   const SMALL_RECT& windowRect) noexcept override;
+                                                   const til::inclusive_rect& windowRect) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
-                                                         const COORD origin,
+                                                         const til::point origin,
                                                          gsl::span<WORD> buffer,
                                                          size_t& written) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
-                                                          const COORD origin,
+                                                          const til::point origin,
                                                           gsl::span<char> buffer,
                                                           size_t& written) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
-                                                          const COORD origin,
+                                                          const til::point origin,
                                                           gsl::span<wchar_t> buffer,
                                                           size_t& written) noexcept override;
 
@@ -232,17 +232,17 @@ class VtApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                           const gsl::span<const WORD> attrs,
-                                                          const COORD target,
+                                                          const til::point target,
                                                           size_t& used) noexcept override;
 
     [[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                            const std::string_view text,
-                                                           const COORD target,
+                                                           const til::point target,
                                                            size_t& used) noexcept override;
 
     [[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                            const std::wstring_view text,
-                                                           const COORD target,
+                                                           const til::point target,
                                                            size_t& used) noexcept override;
 
     [[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context,
@@ -282,7 +282,7 @@ class VtApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
                                                  const DWORD index,
-                                                 COORD& size) noexcept override;
+                                                 til::size& size) noexcept override;
 
     //// driver will pare down for non-Ex method
     [[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
@@ -291,7 +291,7 @@ class VtApiRoutines : public IApiRoutines
 
     [[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
                                                     const ULONG flags,
-                                                    COORD& newSize) noexcept override;
+                                                    til::size& newSize) noexcept override;
 
     void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override;
 
diff --git a/src/host/VtIo.cpp b/src/host/VtIo.cpp
index adae77d3faa..b8d817d34fb 100644
--- a/src/host/VtIo.cpp
+++ b/src/host/VtIo.cpp
@@ -390,7 +390,7 @@ void VtIo::CreatePseudoWindow()
 // Return Value:
 // - S_OK if we successfully inherited the cursor or did nothing, else an
 //      appropriate HRESULT
-[[nodiscard]] HRESULT VtIo::SetCursorPosition(const COORD coordCursor)
+[[nodiscard]] HRESULT VtIo::SetCursorPosition(const til::point coordCursor)
 {
     auto hr = S_OK;
     if (_lookingForCursorPosition)
diff --git a/src/host/VtIo.hpp b/src/host/VtIo.hpp
index 39af4466bb3..7a13565a8da 100644
--- a/src/host/VtIo.hpp
+++ b/src/host/VtIo.hpp
@@ -34,7 +34,7 @@ namespace Microsoft::Console::VirtualTerminal
         [[nodiscard]] static HRESULT ParseIoMode(const std::wstring& VtMode, _Out_ VtIoMode& ioMode);
 
         [[nodiscard]] HRESULT SuppressResizeRepaint();
-        [[nodiscard]] HRESULT SetCursorPosition(const COORD coordCursor);
+        [[nodiscard]] HRESULT SetCursorPosition(const til::point coordCursor);
 
         [[nodiscard]] HRESULT SwitchScreenBuffer(const bool useAltBuffer);
 
diff --git a/src/host/_output.cpp b/src/host/_output.cpp
index 2e5f81f2a00..cba5626219a 100644
--- a/src/host/_output.cpp
+++ b/src/host/_output.cpp
@@ -70,7 +70,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
 // - S_OK, E_INVALIDARG or similar HRESULT error.
 [[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                                    const gsl::span<const WORD> attrs,
-                                                                   const COORD target,
+                                                                   const til::point target,
                                                                    size_t& used) noexcept
 {
     // Set used to 0 from the beginning in case we exit early.
@@ -110,7 +110,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
 // - S_OK, E_INVALIDARG or similar HRESULT error.
 [[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                                     const std::wstring_view chars,
-                                                                    const COORD target,
+                                                                    const til::point target,
                                                                     size_t& used) noexcept
 {
     // Set used to 0 from the beginning in case we exit early.
@@ -153,7 +153,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
 // - S_OK, E_INVALIDARG or similar HRESULT error.
 [[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                                     const std::string_view chars,
-                                                                    const COORD target,
+                                                                    const til::point target,
                                                                     size_t& used) noexcept
 {
     // Set used to 0 from the beginning in case we exit early.
@@ -195,7 +195,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
 [[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                                   const WORD attribute,
                                                                   const size_t lengthToWrite,
-                                                                  const COORD startingCoordinate,
+                                                                  const til::point startingCoordinate,
                                                                   size_t& cellsModified) noexcept
 {
     // Set modified cells to 0 from the beginning.
@@ -221,14 +221,15 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
         TextAttribute useThisAttr(attribute);
         const OutputCellIterator it(useThisAttr, lengthToWrite);
         const auto done = screenBuffer.Write(it, startingCoordinate);
+        const auto cellsModifiedCoord = done.GetCellDistance(it);
 
-        cellsModified = done.GetCellDistance(it);
+        cellsModified = cellsModifiedCoord;
 
         if (screenBuffer.HasAccessibilityEventing())
         {
             // Notify accessibility
             auto endingCoordinate = startingCoordinate;
-            bufferSize.MoveInBounds(cellsModified, endingCoordinate);
+            bufferSize.MoveInBounds(cellsModifiedCoord, endingCoordinate);
             screenBuffer.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
         }
     }
@@ -253,7 +254,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
 [[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                                    const wchar_t character,
                                                                    const size_t lengthToWrite,
-                                                                   const COORD startingCoordinate,
+                                                                   const til::point startingCoordinate,
                                                                    size_t& cellsModified,
                                                                    const bool enablePowershellShim) noexcept
 {
@@ -284,13 +285,15 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
         // when writing to the buffer, specifically unset wrap if we get to the last column.
         // a fill operation should UNSET wrap in that scenario. See GH #1126 for more details.
         const auto done = screenInfo.Write(it, startingCoordinate, false);
-        cellsModified = done.GetInputDistance(it);
+        const auto cellsModifiedCoord = done.GetInputDistance(it);
+
+        cellsModified = cellsModifiedCoord;
 
         // Notify accessibility
         if (screenInfo.HasAccessibilityEventing())
         {
             auto endingCoordinate = startingCoordinate;
-            bufferSize.MoveInBounds(cellsModified, endingCoordinate);
+            bufferSize.MoveInBounds(cellsModifiedCoord, endingCoordinate);
             screenInfo.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
         }
 
@@ -304,10 +307,10 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
         if (enablePowershellShim && gci.IsInVtIoMode())
         {
-            const til::size currentBufferDimensions{ screenInfo.GetBufferSize().Dimensions() };
+            const auto currentBufferDimensions{ screenInfo.GetBufferSize().Dimensions() };
 
             const auto wroteWholeBuffer = lengthToWrite == (currentBufferDimensions.area<size_t>());
-            const auto startedAtOrigin = startingCoordinate == COORD{ 0, 0 };
+            const auto startedAtOrigin = startingCoordinate == til::point{ 0, 0 };
             const auto wroteSpaces = character == UNICODE_SPACE;
 
             if (wroteWholeBuffer && startedAtOrigin && wroteSpaces)
@@ -334,7 +337,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
 [[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                                    const char character,
                                                                    const size_t lengthToWrite,
-                                                                   const COORD startingCoordinate,
+                                                                   const til::point startingCoordinate,
                                                                    size_t& cellsModified) noexcept
 try
 {
diff --git a/src/host/_stream.cpp b/src/host/_stream.cpp
index d507c57221e..899228a9dcf 100644
--- a/src/host/_stream.cpp
+++ b/src/host/_stream.cpp
@@ -40,9 +40,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
 // - fKeepCursorVisible - TRUE if changing window origin desirable when hit right edge
 // Return Value:
 [[nodiscard]] NTSTATUS AdjustCursorPosition(SCREEN_INFORMATION& screenInfo,
-                                            _In_ COORD coordCursor,
+                                            _In_ til::point coordCursor,
                                             const BOOL fKeepCursorVisible,
-                                            _Inout_opt_ PSHORT psScrollY)
+                                            _Inout_opt_ til::CoordType* psScrollY)
 {
     const auto inVtMode = WI_IsFlagSet(screenInfo.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
     const auto bufferSize = screenInfo.GetBufferSize().Dimensions();
@@ -50,8 +50,8 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
     {
         if (coordCursor.Y > 0)
         {
-            coordCursor.X = (SHORT)(bufferSize.X + coordCursor.X);
-            coordCursor.Y = (SHORT)(coordCursor.Y - 1);
+            coordCursor.X = bufferSize.X + coordCursor.X;
+            coordCursor.Y = coordCursor.Y - 1;
         }
         else
         {
@@ -91,7 +91,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
     auto srMargins = screenInfo.GetAbsoluteScrollMargins().ToInclusive();
     const auto fMarginsSet = srMargins.Bottom > srMargins.Top;
     auto currentCursor = screenInfo.GetTextBuffer().GetCursor().GetPosition();
-    const int iCurrentCursorY = currentCursor.Y;
+    const auto iCurrentCursorY = currentCursor.Y;
 
     const auto fCursorInMargins = iCurrentCursorY <= srMargins.Bottom && iCurrentCursorY >= srMargins.Top;
     const auto cursorAboveViewport = coordCursor.Y < 0 && inVtMode;
@@ -119,22 +119,22 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
         // To do this, we're going to scroll everything starting at the bottom
         //  margin down, then move the viewport down.
 
-        const SHORT delta = coordCursor.Y - srMargins.Bottom;
-        SMALL_RECT scrollRect{ 0 };
+        const auto delta = coordCursor.Y - srMargins.Bottom;
+        til::inclusive_rect scrollRect;
         scrollRect.Left = 0;
         scrollRect.Top = srMargins.Bottom + 1; // One below margins
         scrollRect.Bottom = bufferSize.Y - 1; // -1, otherwise this would be an exclusive rect.
         scrollRect.Right = bufferSize.X - 1; // -1, otherwise this would be an exclusive rect.
 
         // This is the Y position we're moving the contents below the bottom margin to.
-        SHORT moveToYPosition = scrollRect.Top + delta;
+        auto moveToYPosition = scrollRect.Top + delta;
 
         // This is where the viewport will need to be to give the effect of
         //      scrolling the contents in the margins.
-        SHORT newViewTop = viewport.Top() + delta;
+        auto newViewTop = viewport.Top() + delta;
 
         // This is how many new lines need to be added to the buffer to support this operation.
-        const SHORT newRows = (viewport.BottomExclusive() + delta) - bufferSize.Y;
+        const auto newRows = (viewport.BottomExclusive() + delta) - bufferSize.Y;
 
         // If we're near the bottom of the buffer, we might need to insert some
         //      new rows at the bottom.
@@ -148,8 +148,8 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
             scrollRect.Top--;
         }
 
-        const COORD newPostMarginsOrigin = { 0, moveToYPosition };
-        const COORD newViewOrigin = { 0, newViewTop };
+        const til::point newPostMarginsOrigin{ 0, moveToYPosition };
+        const til::point newViewOrigin{ 0, newViewTop };
 
         try
         {
@@ -195,7 +195,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
             // And now we need to report that only the bottom line didn't "move" as we put the EEEE
             // back where it started, but everything else moved.
             // In this case, delta was 1. So the amount that moved is the entire viewport height minus the delta.
-            Viewport invalid = Viewport::FromDimensions(viewport.Origin(), { viewport.Width(), viewport.Height() - delta });
+            auto invalid = Viewport::FromDimensions(viewport.Origin(), { viewport.Width(), viewport.Height() - delta });
             screenInfo.GetTextBuffer().TriggerRedraw(invalid);
         }
 
@@ -214,15 +214,15 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
     //      the margins content, and we can skip this.
     if (fScrollUp || (fScrollDown && !scrollDownAtTop))
     {
-        SHORT diff = coordCursor.Y - (fScrollUp ? srMargins.Top : srMargins.Bottom);
+        auto diff = coordCursor.Y - (fScrollUp ? srMargins.Top : srMargins.Bottom);
 
-        SMALL_RECT scrollRect = { 0 };
+        til::inclusive_rect scrollRect;
         scrollRect.Top = srMargins.Top;
         scrollRect.Bottom = srMargins.Bottom;
         scrollRect.Left = 0; // NOTE: Left/Right Scroll margins don't do anything currently.
         scrollRect.Right = bufferSize.X - 1; // -1, otherwise this would be an exclusive rect.
 
-        COORD dest;
+        til::point dest;
         dest.X = scrollRect.Left;
         dest.Y = scrollRect.Top - diff;
 
@@ -257,9 +257,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
 
         if (nullptr != psScrollY)
         {
-            *psScrollY += (SHORT)(bufferSize.Y - coordCursor.Y - 1);
+            *psScrollY += bufferSize.Y - coordCursor.Y - 1;
         }
-        coordCursor.Y += (SHORT)(bufferSize.Y - coordCursor.Y - 1);
+        coordCursor.Y += bufferSize.Y - coordCursor.Y - 1;
     }
 
     const auto cursorMovedPastViewport = coordCursor.Y > screenInfo.GetViewport().BottomInclusive();
@@ -269,7 +269,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
         // if at right or bottom edge of window, scroll right or down one char.
         if (cursorMovedPastViewport)
         {
-            COORD WindowOrigin;
+            til::point WindowOrigin;
             WindowOrigin.X = 0;
             WindowOrigin.Y = coordCursor.Y - screenInfo.GetViewport().BottomInclusive();
             Status = screenInfo.SetViewportOrigin(false, WindowOrigin, true);
@@ -327,16 +327,16 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                                         _In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
                                         _Inout_ size_t* const pcb,
                                         _Out_opt_ size_t* const pcSpaces,
-                                        const SHORT sOriginalXPosition,
+                                        const til::CoordType sOriginalXPosition,
                                         const DWORD dwFlags,
-                                        _Inout_opt_ PSHORT const psScrollY)
+                                        _Inout_opt_ til::CoordType* const psScrollY)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& textBuffer = screenInfo.GetTextBuffer();
     auto& cursor = textBuffer.GetCursor();
     auto CursorPosition = cursor.GetPosition();
     auto Status = STATUS_SUCCESS;
-    SHORT XPosition;
+    til::CoordType XPosition;
     size_t TempNumSpaces = 0;
     const auto fUnprocessed = WI_IsFlagClear(screenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT);
     const auto fWrapAtEOL = WI_IsFlagSet(screenInfo.OutputMode, ENABLE_WRAP_AT_EOL_OUTPUT);
@@ -357,7 +357,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
         coordScreenBufferSize.X = textBuffer.GetLineWidth(CursorPosition.Y);
     }
 
-    static constexpr unsigned int LOCAL_BUFFER_SIZE = 1024;
+    static constexpr til::CoordType LOCAL_BUFFER_SIZE = 1024;
     WCHAR LocalBuffer[LOCAL_BUFFER_SIZE];
 
     while (*pcb < BufferSize)
@@ -386,7 +386,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
 
         // As an optimization, collect characters in buffer and print out all at once.
         XPosition = cursor.GetPosition().X;
-        size_t i = 0;
+        til::CoordType i = 0;
         auto LocalBufPtr = LocalBuffer;
         while (*pcb < BufferSize && i < LOCAL_BUFFER_SIZE && XPosition < coordScreenBufferSize.X)
         {
@@ -452,14 +452,14 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                     break;
                 case UNICODE_TAB:
                 {
-                    const ULONG TabSize = NUMBER_OF_SPACES_IN_TAB(XPosition);
-                    XPosition = (SHORT)(XPosition + TabSize);
+                    const auto TabSize = NUMBER_OF_SPACES_IN_TAB(XPosition);
+                    XPosition = XPosition + TabSize;
                     if (XPosition >= coordScreenBufferSize.X)
                     {
                         goto EndWhile;
                     }
 
-                    for (ULONG j = 0; j < TabSize && i < LOCAL_BUFFER_SIZE; j++, i++)
+                    for (til::CoordType j = 0; j < TabSize && i < LOCAL_BUFFER_SIZE; j++, i++)
                     {
                         *LocalBufPtr = UNICODE_SPACE;
                         LocalBufPtr++;
@@ -547,9 +547,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
 
             // Make sure we don't write past the end of the buffer.
             // WCL-NOTE: This check uses a code unit count instead of a column count. That is incorrect.
-            if (i > gsl::narrow_cast<size_t>(coordScreenBufferSize.X) - CursorPosition.X)
+            if (i > coordScreenBufferSize.X - CursorPosition.X)
             {
-                i = gsl::narrow_cast<size_t>(coordScreenBufferSize.X) - CursorPosition.X;
+                i = coordScreenBufferSize.X - CursorPosition.X;
             }
 
             // line was wrapped if we're writing up to the end of the current row
@@ -559,7 +559,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
             // Notify accessibility
             if (screenInfo.HasAccessibilityEventing())
             {
-                screenInfo.NotifyAccessibilityEventing(CursorPosition.X, CursorPosition.Y, CursorPosition.X + gsl::narrow<SHORT>(i - 1), CursorPosition.Y);
+                screenInfo.NotifyAccessibilityEventing(CursorPosition.X, CursorPosition.Y, CursorPosition.X + i - 1, CursorPosition.Y);
             }
 
             // The number of "spaces" or "cells" we have consumed needs to be reported and stored for later
@@ -633,7 +633,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                 wchar_t* Tmp2 = nullptr;
                 WCHAR LastChar;
 
-                const size_t bufferSize = pwchBuffer - pwchBufferBackupLimit;
+                const auto bufferSize = pwchBuffer - pwchBufferBackupLimit;
                 std::unique_ptr<wchar_t[]> buffer;
                 try
                 {
@@ -677,9 +677,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
 
                 if (LastChar == UNICODE_TAB)
                 {
-                    CursorPosition.X -= (SHORT)(RetrieveNumberOfSpaces(sOriginalXPosition,
-                                                                       pwchBufferBackupLimit,
-                                                                       (ULONG)(pwchBuffer - pwchBufferBackupLimit - 1)));
+                    CursorPosition.X -= RetrieveNumberOfSpaces(sOriginalXPosition,
+                                                               pwchBufferBackupLimit,
+                                                               pwchBuffer - pwchBufferBackupLimit - 1);
                     if (CursorPosition.X < 0)
                     {
                         CursorPosition.X = (coordScreenBufferSize.X - 1) / TAB_SIZE;
@@ -756,7 +756,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                                         dwFlags & WC_PRINTABLE_CONTROL_CHARS))
                 {
                     CursorPosition.X = coordScreenBufferSize.X - 1;
-                    CursorPosition.Y = (SHORT)(cursor.GetPosition().Y - 1);
+                    CursorPosition.Y = cursor.GetPosition().Y - 1;
 
                     // since you just backspaced yourself back up into the previous row, unset the wrap flag
                     // on the prev row if it was set
@@ -778,8 +778,8 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
         }
         case UNICODE_TAB:
         {
-            const auto TabSize = gsl::narrow_cast<size_t>(NUMBER_OF_SPACES_IN_TAB(cursor.GetPosition().X));
-            CursorPosition.X = (SHORT)(cursor.GetPosition().X + TabSize);
+            const auto TabSize = NUMBER_OF_SPACES_IN_TAB(cursor.GetPosition().X);
+            CursorPosition.X = cursor.GetPosition().X + TabSize;
 
             // move cursor forward to next tab stop.  fill space with blanks.
             // we get here when the tab extends beyond the right edge of the
@@ -839,7 +839,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                 CursorPosition.X = 0;
             }
 
-            CursorPosition.Y = (SHORT)(cursor.GetPosition().Y + 1);
+            CursorPosition.Y = cursor.GetPosition().Y + 1;
 
             {
                 // since we explicitly just moved down a row, clear the wrap status on the row we just came from
@@ -883,7 +883,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                 }
 
                 CursorPosition.X = 0;
-                CursorPosition.Y = (SHORT)(TargetPoint.Y + 1);
+                CursorPosition.Y = TargetPoint.Y + 1;
 
                 // since you just moved yourself down onto the next row with 1 character, that sounds like a
                 // forced wrap so set the flag
@@ -942,9 +942,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
                                   _In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
                                   _Inout_ size_t* const pcb,
                                   _Out_opt_ size_t* const pcSpaces,
-                                  const SHORT sOriginalXPosition,
+                                  const til::CoordType sOriginalXPosition,
                                   const DWORD dwFlags,
-                                  _Inout_opt_ PSHORT const psScrollY)
+                                  _Inout_opt_ til::CoordType* const psScrollY)
 {
     if (!WI_IsFlagSet(screenInfo.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING) ||
         !WI_IsFlagSet(screenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT))
diff --git a/src/host/_stream.h b/src/host/_stream.h
index 2f9656c7bd2..149482f1ff1 100644
--- a/src/host/_stream.h
+++ b/src/host/_stream.h
@@ -36,9 +36,9 @@ Routine Description:
 Return Value:
 --*/
 [[nodiscard]] NTSTATUS AdjustCursorPosition(SCREEN_INFORMATION& screenInfo,
-                                            _In_ COORD coordCursor,
+                                            _In_ til::point coordCursor,
                                             const BOOL fKeepCursorVisible,
-                                            _Inout_opt_ PSHORT psScrollY);
+                                            _Inout_opt_ til::CoordType* psScrollY);
 
 /*++
 Routine Description:
@@ -73,9 +73,9 @@ Return Value:
                                         _In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
                                         _Inout_ size_t* const pcb,
                                         _Out_opt_ size_t* const pcSpaces,
-                                        const SHORT sOriginalXPosition,
+                                        const til::CoordType sOriginalXPosition,
                                         const DWORD dwFlags,
-                                        _Inout_opt_ PSHORT const psScrollY);
+                                        _Inout_opt_ til::CoordType* const psScrollY);
 
 // The new entry point for WriteChars to act as an intercept in case we place a Virtual Terminal processor in the way.
 [[nodiscard]] NTSTATUS WriteChars(SCREEN_INFORMATION& screenInfo,
@@ -84,9 +84,9 @@ Return Value:
                                   _In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
                                   _Inout_ size_t* const pcb,
                                   _Out_opt_ size_t* const pcSpaces,
-                                  const SHORT sOriginalXPosition,
+                                  const til::CoordType sOriginalXPosition,
                                   const DWORD dwFlags,
-                                  _Inout_opt_ PSHORT const psScrollY);
+                                  _Inout_opt_ til::CoordType* const psScrollY);
 
 // NOTE: console lock must be held when calling this routine
 // String has been translated to unicode at this point.
diff --git a/src/host/cmdline.cpp b/src/host/cmdline.cpp
index 83223906197..fc49f5371ae 100644
--- a/src/host/cmdline.cpp
+++ b/src/host/cmdline.cpp
@@ -247,7 +247,7 @@ void RedrawCommandLine(COOKED_READ_DATA& cookedReadData)
         // Draw the command line
         cookedReadData.OriginalCursorPosition() = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
 
-        SHORT ScrollY = 0;
+        til::CoordType ScrollY = 0;
 #pragma prefast(suppress : 28931, "Status is not unused. It's used in debug assertions.")
         auto Status = WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                        cookedReadData.BufferStartPtr(),
@@ -264,9 +264,9 @@ void RedrawCommandLine(COOKED_READ_DATA& cookedReadData)
 
         // Move the cursor back to the right position
         auto CursorPosition = cookedReadData.OriginalCursorPosition();
-        CursorPosition.X += (SHORT)RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
-                                                               cookedReadData.BufferStartPtr(),
-                                                               cookedReadData.InsertionPoint());
+        CursorPosition.X += RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
+                                                        cookedReadData.BufferStartPtr(),
+                                                        cookedReadData.InsertionPoint());
         if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
                                cookedReadData.InsertionPoint(),
                                cookedReadData.ScreenInfo().GetBufferSize().Width() - cookedReadData.OriginalCursorPosition().X))
@@ -289,7 +289,7 @@ void SetCurrentCommandLine(COOKED_READ_DATA& cookedReadData, _In_ SHORT Index) /
     FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
     if (cookedReadData.IsEchoInput())
     {
-        SHORT ScrollY = 0;
+        til::CoordType ScrollY = 0;
         FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                       cookedReadData.BufferStartPtr(),
                                                       cookedReadData.BufferCurrentPtr(),
@@ -453,7 +453,7 @@ void CommandLine::_processHistoryCycling(COOKED_READ_DATA& cookedReadData,
     FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
     if (cookedReadData.IsEchoInput())
     {
-        short ScrollY = 0;
+        til::CoordType ScrollY = 0;
         FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                       cookedReadData.BufferStartPtr(),
                                                       cookedReadData.BufferCurrentPtr(),
@@ -488,7 +488,7 @@ void CommandLine::_setPromptToOldestCommand(COOKED_READ_DATA& cookedReadData)
         FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
         if (cookedReadData.IsEchoInput())
         {
-            short ScrollY = 0;
+            til::CoordType ScrollY = 0;
             FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                           cookedReadData.BufferStartPtr(),
                                                           cookedReadData.BufferCurrentPtr(),
@@ -524,7 +524,7 @@ void CommandLine::_setPromptToNewestCommand(COOKED_READ_DATA& cookedReadData)
         FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
         if (cookedReadData.IsEchoInput())
         {
-            short ScrollY = 0;
+            til::CoordType ScrollY = 0;
             FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                           cookedReadData.BufferStartPtr(),
                                                           cookedReadData.BufferCurrentPtr(),
@@ -570,7 +570,7 @@ void CommandLine::DeletePromptAfterCursor(COOKED_READ_DATA& cookedReadData) noex
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::_deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::_deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept
 {
     DeleteCommandLine(cookedReadData, false);
     cookedReadData.BytesRead() -= cookedReadData.InsertionPoint() * sizeof(WCHAR);
@@ -598,12 +598,12 @@ COORD CommandLine::_deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) n
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::_moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::_moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
 {
     cookedReadData.InsertionPoint() = cookedReadData.BytesRead() / sizeof(WCHAR);
     cookedReadData.SetBufferCurrentPtr(cookedReadData.BufferStartPtr() + cookedReadData.InsertionPoint());
-    COORD cursorPosition{ 0, 0 };
-    cursorPosition.X = (SHORT)(cookedReadData.OriginalCursorPosition().X + cookedReadData.VisibleCharCount());
+    til::point cursorPosition;
+    cursorPosition.X = gsl::narrow<til::CoordType>(cookedReadData.OriginalCursorPosition().X + cookedReadData.VisibleCharCount());
     cursorPosition.Y = cookedReadData.OriginalCursorPosition().Y;
 
     const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
@@ -625,7 +625,7 @@ COORD CommandLine::_moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) no
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::_moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::_moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
 {
     cookedReadData.InsertionPoint() = 0;
     cookedReadData.SetBufferCurrentPtr(cookedReadData.BufferStartPtr());
@@ -638,7 +638,7 @@ COORD CommandLine::_moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData)
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - New cursor position
-COORD CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept
 {
     PWCHAR LastWord;
     auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
@@ -699,12 +699,12 @@ COORD CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexc
             }
             cookedReadData.SetBufferCurrentPtr(LastWord);
         }
-        cookedReadData.InsertionPoint() = (ULONG)(cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
+        cookedReadData.InsertionPoint() = (cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
         cursorPosition = cookedReadData.OriginalCursorPosition();
-        cursorPosition.X = (SHORT)(cursorPosition.X +
-                                   RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
-                                                               cookedReadData.BufferStartPtr(),
-                                                               cookedReadData.InsertionPoint()));
+        cursorPosition.X = cursorPosition.X +
+                           RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
+                                                       cookedReadData.BufferStartPtr(),
+                                                       cookedReadData.InsertionPoint());
         const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
         if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
                                cookedReadData.InsertionPoint() + 1,
@@ -722,7 +722,7 @@ COORD CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexc
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - New cursor position
-COORD CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
+til::point CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
 {
     auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
     if (cookedReadData.BufferCurrentPtr() != cookedReadData.BufferStartPtr())
@@ -731,10 +731,10 @@ COORD CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
         cookedReadData.InsertionPoint()--;
         cursorPosition.X = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition().X;
         cursorPosition.Y = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition().Y;
-        cursorPosition.X = (SHORT)(cursorPosition.X -
-                                   RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
-                                                          cookedReadData.BufferStartPtr(),
-                                                          cookedReadData.InsertionPoint()));
+        cursorPosition.X = cursorPosition.X -
+                           RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
+                                                  cookedReadData.BufferStartPtr(),
+                                                  cookedReadData.InsertionPoint());
         const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
         if (CheckBisectProcessW(cookedReadData.ScreenInfo(),
                                 cookedReadData.BufferStartPtr(),
@@ -758,7 +758,7 @@ COORD CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept
 {
     auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
     if (cookedReadData.InsertionPoint() < (cookedReadData.BytesRead() / sizeof(WCHAR)))
@@ -810,10 +810,10 @@ COORD CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noex
         cookedReadData.SetBufferCurrentPtr(NextWord);
         cookedReadData.InsertionPoint() = (ULONG)(cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
         cursorPosition = cookedReadData.OriginalCursorPosition();
-        cursorPosition.X = (SHORT)(cursorPosition.X +
-                                   RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
-                                                               cookedReadData.BufferStartPtr(),
-                                                               cookedReadData.InsertionPoint()));
+        cursorPosition.X = cursorPosition.X +
+                           RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
+                                                       cookedReadData.BufferStartPtr(),
+                                                       cookedReadData.InsertionPoint());
         const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
         if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
                                cookedReadData.InsertionPoint() + 1,
@@ -831,7 +831,7 @@ COORD CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noex
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
 {
     auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
     const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
@@ -839,10 +839,10 @@ COORD CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
     if (cookedReadData.InsertionPoint() < (cookedReadData.BytesRead() / sizeof(WCHAR)))
     {
         cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
-        cursorPosition.X = (SHORT)(cursorPosition.X +
-                                   RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
-                                                          cookedReadData.BufferStartPtr(),
-                                                          cookedReadData.InsertionPoint()));
+        cursorPosition.X = cursorPosition.X +
+                           RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
+                                                  cookedReadData.BufferStartPtr(),
+                                                  cookedReadData.InsertionPoint());
         if (CheckBisectProcessW(cookedReadData.ScreenInfo(),
                                 cookedReadData.BufferStartPtr(),
                                 cookedReadData.InsertionPoint() + 2,
@@ -869,7 +869,7 @@ COORD CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
             cookedReadData.InsertionPoint()++;
             if (cookedReadData.IsEchoInput())
             {
-                short ScrollY = 0;
+                til::CoordType ScrollY = 0;
                 auto CharsToWrite = sizeof(WCHAR);
                 FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                               cookedReadData.BufferStartPtr(),
@@ -912,7 +912,7 @@ void CommandLine::_insertCtrlZ(COOKED_READ_DATA& cookedReadData) noexcept
     cookedReadData.InsertionPoint()++;
     if (cookedReadData.IsEchoInput())
     {
-        short ScrollY = 0;
+        til::CoordType ScrollY = 0;
         auto CharsToWrite = sizeof(WCHAR);
         FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                       cookedReadData.BufferStartPtr(),
@@ -963,7 +963,7 @@ void CommandLine::_fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cooke
             cookedReadData.BytesRead() = std::max(LastCommand.size() * sizeof(wchar_t), cookedReadData.BytesRead());
             if (cookedReadData.IsEchoInput())
             {
-                short ScrollY = 0;
+                til::CoordType ScrollY = 0;
                 FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                               cookedReadData.BufferStartPtr(),
                                                               cookedReadData.BufferCurrentPtr(),
@@ -987,7 +987,7 @@ void CommandLine::_fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cooke
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData)
+til::point CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData)
 {
     auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
     if (cookedReadData.HasHistory())
@@ -998,10 +998,8 @@ COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cooked
                                                          index,
                                                          CommandHistory::MatchOptions::None))
         {
-            SHORT CurrentPos;
-
             // save cursor position
-            CurrentPos = (SHORT)cookedReadData.InsertionPoint();
+            const auto CurrentPos = cookedReadData.InsertionPoint();
 
             DeleteCommandLine(cookedReadData, true);
             THROW_IF_FAILED(cookedReadData.History().RetrieveNth((SHORT)index,
@@ -1010,7 +1008,7 @@ COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cooked
             FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
             if (cookedReadData.IsEchoInput())
             {
-                short ScrollY = 0;
+                til::CoordType ScrollY = 0;
                 FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
                                                               cookedReadData.BufferStartPtr(),
                                                               cookedReadData.BufferCurrentPtr(),
@@ -1039,7 +1037,7 @@ COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cooked
 // - cookedReadData - The cooked read data to operate on
 // Return Value:
 // - The new cursor position
-COORD CommandLine::DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept
+til::point CommandLine::DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept
 {
     // save cursor position
     auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
diff --git a/src/host/cmdline.h b/src/host/cmdline.h
index ffa2a16dca6..b178466f1fa 100644
--- a/src/host/cmdline.h
+++ b/src/host/cmdline.h
@@ -88,7 +88,7 @@ class CommandLine
     void EndAllPopups();
 
     void DeletePromptAfterCursor(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept;
 
 protected:
     CommandLine();
@@ -104,17 +104,17 @@ class CommandLine
     void _processHistoryCycling(COOKED_READ_DATA& cookedReadData, const CommandHistory::SearchDirection searchDirection);
     void _setPromptToOldestCommand(COOKED_READ_DATA& cookedReadData);
     void _setPromptToNewestCommand(COOKED_READ_DATA& cookedReadData);
-    COORD _deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD _moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD _moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD _moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD _moveCursorLeft(COOKED_READ_DATA& cookedReadData);
-    COORD _moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD _moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point _deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point _moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point _moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point _moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point _moveCursorLeft(COOKED_READ_DATA& cookedReadData);
+    til::point _moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept;
+    til::point _moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept;
     void _insertCtrlZ(COOKED_READ_DATA& cookedReadData) noexcept;
     void _deleteCommandHistory(COOKED_READ_DATA& cookedReadData) noexcept;
     void _fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cookedReadData) noexcept;
-    COORD _cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData);
+    til::point _cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData);
 
 #ifdef UNIT_TESTING
     friend class CommandLineTests;
diff --git a/src/host/conareainfo.cpp b/src/host/conareainfo.cpp
index 1f13a962ffe..868e36ede00 100644
--- a/src/host/conareainfo.cpp
+++ b/src/host/conareainfo.cpp
@@ -15,15 +15,13 @@
 using namespace Microsoft::Console::Types;
 using Microsoft::Console::Interactivity::ServiceLocator;
 
-ConversionAreaBufferInfo::ConversionAreaBufferInfo(const COORD coordBufferSize) :
-    coordCaBuffer(coordBufferSize),
-    rcViewCaWindow({ 0 }),
-    coordConView({ 0 })
+ConversionAreaBufferInfo::ConversionAreaBufferInfo(const til::size coordBufferSize) :
+    coordCaBuffer(coordBufferSize)
 {
 }
 
-ConversionAreaInfo::ConversionAreaInfo(const COORD bufferSize,
-                                       const COORD windowSize,
+ConversionAreaInfo::ConversionAreaInfo(const til::size bufferSize,
+                                       const til::size windowSize,
                                        const TextAttribute& fill,
                                        const TextAttribute& popupFill,
                                        const FontInfo fontInfo) :
@@ -110,7 +108,7 @@ void ConversionAreaInfo::SetAttributes(const TextAttribute& attr)
 // - text - Text to insert into the conversion area buffer
 // - column - Column to start at (X position)
 void ConversionAreaInfo::WriteText(const std::vector<OutputCell>& text,
-                                   const SHORT column)
+                                   const til::CoordType column)
 {
     gsl::span<const OutputCell> view(text.data(), text.size());
     _screenBuffer->Write(view, { column, 0 });
@@ -131,7 +129,7 @@ void ConversionAreaInfo::ClearArea() noexcept
     Paint();
 }
 
-[[nodiscard]] HRESULT ConversionAreaInfo::Resize(const COORD newSize) noexcept
+[[nodiscard]] HRESULT ConversionAreaInfo::Resize(const til::size newSize) noexcept
 {
     // attempt to resize underlying buffers
     RETURN_IF_NTSTATUS_FAILED(_screenBuffer->ResizeScreenBuffer(newSize, FALSE));
@@ -140,7 +138,7 @@ void ConversionAreaInfo::ClearArea() noexcept
     _caInfo.coordCaBuffer = newSize;
 
     // restrict viewport to buffer size.
-    const COORD restriction = { newSize.X - 1i16, newSize.Y - 1i16 };
+    const til::point restriction = { newSize.X - 1, newSize.Y - 1 };
     _caInfo.rcViewCaWindow.Left = std::min(_caInfo.rcViewCaWindow.Left, restriction.X);
     _caInfo.rcViewCaWindow.Right = std::min(_caInfo.rcViewCaWindow.Right, restriction.X);
     _caInfo.rcViewCaWindow.Top = std::min(_caInfo.rcViewCaWindow.Top, restriction.Y);
@@ -149,7 +147,7 @@ void ConversionAreaInfo::ClearArea() noexcept
     return S_OK;
 }
 
-void ConversionAreaInfo::SetWindowInfo(const SMALL_RECT view) noexcept
+void ConversionAreaInfo::SetWindowInfo(const til::inclusive_rect& view) noexcept
 {
     if (view.Left != _caInfo.rcViewCaWindow.Left ||
         view.Top != _caInfo.rcViewCaWindow.Top ||
@@ -172,7 +170,7 @@ void ConversionAreaInfo::SetWindowInfo(const SMALL_RECT view) noexcept
     }
 }
 
-void ConversionAreaInfo::SetViewPos(const COORD pos) noexcept
+void ConversionAreaInfo::SetViewPos(const til::point pos) noexcept
 {
     if (IsHidden())
     {
@@ -206,7 +204,7 @@ void ConversionAreaInfo::Paint() const noexcept
     auto& ScreenInfo = gci.GetActiveOutputBuffer();
     const auto viewport = ScreenInfo.GetViewport();
 
-    SMALL_RECT WriteRegion;
+    til::inclusive_rect WriteRegion;
     WriteRegion.Left = viewport.Left() + _caInfo.coordConView.X + _caInfo.rcViewCaWindow.Left;
     WriteRegion.Right = WriteRegion.Left + (_caInfo.rcViewCaWindow.Right - _caInfo.rcViewCaWindow.Left);
     WriteRegion.Top = viewport.Top() + _caInfo.coordConView.Y + _caInfo.rcViewCaWindow.Top;
diff --git a/src/host/conareainfo.h b/src/host/conareainfo.h
index 4808da09fe5..f334cbac813 100644
--- a/src/host/conareainfo.h
+++ b/src/host/conareainfo.h
@@ -30,18 +30,18 @@ class TextBuffer;
 class ConversionAreaBufferInfo final
 {
 public:
-    COORD coordCaBuffer;
-    SMALL_RECT rcViewCaWindow;
-    COORD coordConView;
+    til::size coordCaBuffer;
+    til::inclusive_rect rcViewCaWindow;
+    til::point coordConView;
 
-    explicit ConversionAreaBufferInfo(const COORD coordBufferSize);
+    explicit ConversionAreaBufferInfo(const til::size coordBufferSize);
 };
 
 class ConversionAreaInfo final
 {
 public:
-    ConversionAreaInfo(const COORD bufferSize,
-                       const COORD windowSize,
+    ConversionAreaInfo(const til::size bufferSize,
+                       const til::size windowSize,
                        const TextAttribute& fill,
                        const TextAttribute& popupFill,
                        const FontInfo fontInfo);
@@ -55,13 +55,13 @@ class ConversionAreaInfo final
     void SetHidden(const bool fIsHidden) noexcept;
     void ClearArea() noexcept;
 
-    [[nodiscard]] HRESULT Resize(const COORD newSize) noexcept;
+    [[nodiscard]] HRESULT Resize(const til::size newSize) noexcept;
 
-    void SetViewPos(const COORD pos) noexcept;
-    void SetWindowInfo(const SMALL_RECT view) noexcept;
+    void SetViewPos(const til::point pos) noexcept;
+    void SetWindowInfo(const til::inclusive_rect& view) noexcept;
     void Paint() const noexcept;
 
-    void WriteText(const std::vector<OutputCell>& text, const SHORT column);
+    void WriteText(const std::vector<OutputCell>& text, const til::CoordType column);
     void SetAttributes(const TextAttribute& attr);
 
     const TextBuffer& GetTextBuffer() const noexcept;
diff --git a/src/host/conimeinfo.cpp b/src/host/conimeinfo.cpp
index 697a176018b..fbe226ea25d 100644
--- a/src/host/conimeinfo.cpp
+++ b/src/host/conimeinfo.cpp
@@ -119,7 +119,7 @@ void ConsoleImeInfo::ClearAllAreas()
 // - newSize - New size for conversion areas
 // Return Value:
 // - S_OK or appropriate failure HRESULT.
-[[nodiscard]] HRESULT ConsoleImeInfo::ResizeAllAreas(const COORD newSize)
+[[nodiscard]] HRESULT ConsoleImeInfo::ResizeAllAreas(const til::size newSize)
 {
     for (auto& area : ConvAreaCompStr)
     {
@@ -310,7 +310,7 @@ std::vector<OutputCell> ConsoleImeInfo::s_ConvertToCells(const std::wstring_view
 //   If the viewport is deemed too small, we'll skip past it and advance begin past the entire full-width character.
 std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(const std::vector<OutputCell>::const_iterator begin,
                                                                              const std::vector<OutputCell>::const_iterator end,
-                                                                             COORD& pos,
+                                                                             til::point& pos,
                                                                              const Microsoft::Console::Types::Viewport view,
                                                                              SCREEN_INFORMATION& screenInfo)
 {
@@ -372,7 +372,7 @@ std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(con
 
     // Set the viewport and positioning parameters for the conversion area to describe to the renderer
     // the appropriate location to overlay this conversion area on top of the main screen buffer inside the viewport.
-    const SMALL_RECT region{ insertionPos.X, 0, gsl::narrow<SHORT>(insertionPos.X + lineVec.size() - 1), 0 };
+    const til::inclusive_rect region{ insertionPos.X, 0, gsl::narrow<til::CoordType>(insertionPos.X + lineVec.size() - 1), 0 };
     area.SetWindowInfo(region);
     area.SetViewPos({ 0 - view.Left(), insertionPos.Y - view.Top() });
 
@@ -383,7 +383,7 @@ std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(con
     // Notify accessibility that we have updated the text in this display region within the viewport.
     if (screenInfo.HasAccessibilityEventing())
     {
-        screenInfo.NotifyAccessibilityEventing(insertionPos.X, insertionPos.Y, gsl::narrow<SHORT>(insertionPos.X + lineVec.size() - 1), insertionPos.Y);
+        screenInfo.NotifyAccessibilityEventing(region.left, insertionPos.Y, region.right, insertionPos.Y);
     }
 
     // Hand back the iterator representing the end of what we used to be fed into the beginning of the next call.
diff --git a/src/host/conimeinfo.h b/src/host/conimeinfo.h
index 2a3016ff0f6..3d84f232caf 100644
--- a/src/host/conimeinfo.h
+++ b/src/host/conimeinfo.h
@@ -45,7 +45,7 @@ class ConsoleImeInfo final
     void RefreshAreaAttributes();
     void ClearAllAreas();
 
-    [[nodiscard]] HRESULT ResizeAllAreas(const COORD newSize);
+    [[nodiscard]] HRESULT ResizeAllAreas(const til::size newSize);
 
     void WriteCompMessage(const std::wstring_view text,
                           const gsl::span<const BYTE> attributes,
@@ -79,7 +79,7 @@ class ConsoleImeInfo final
 
     std::vector<OutputCell>::const_iterator _WriteConversionArea(const std::vector<OutputCell>::const_iterator begin,
                                                                  const std::vector<OutputCell>::const_iterator end,
-                                                                 COORD& pos,
+                                                                 til::point& pos,
                                                                  const Microsoft::Console::Types::Viewport view,
                                                                  SCREEN_INFORMATION& screenInfo);
 
diff --git a/src/host/conv.h b/src/host/conv.h
index b9f7c753aad..fb1a02395e4 100644
--- a/src/host/conv.h
+++ b/src/host/conv.h
@@ -26,4 +26,4 @@ void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
                              const Microsoft::Console::Types::Viewport& convRegion);
 
 [[nodiscard]] HRESULT ConsoleImeResizeCompStrView();
-[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const COORD coordNewScreenSize);
+[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const til::size coordNewScreenSize);
diff --git a/src/host/convarea.cpp b/src/host/convarea.cpp
index 4db24143e91..70f6a3e2457 100644
--- a/src/host/convarea.cpp
+++ b/src/host/convarea.cpp
@@ -12,11 +12,6 @@
 using namespace Microsoft::Console::Types;
 using Microsoft::Console::Interactivity::ServiceLocator;
 
-bool IsValidSmallRect(_In_ PSMALL_RECT const Rect)
-{
-    return (Rect->Right >= Rect->Left && Rect->Bottom >= Rect->Top);
-}
-
 void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
                              const Viewport& convRegion)
 {
@@ -38,38 +33,31 @@ void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
             const auto areaInfo = ConvAreaInfo.GetAreaBufferInfo();
 
             // Do clipping region
-            SMALL_RECT Region;
+            til::inclusive_rect Region;
             Region.Left = currentViewport.Left + areaInfo.rcViewCaWindow.Left + areaInfo.coordConView.X;
             Region.Right = Region.Left + (areaInfo.rcViewCaWindow.Right - areaInfo.rcViewCaWindow.Left);
             Region.Top = currentViewport.Top + areaInfo.rcViewCaWindow.Top + areaInfo.coordConView.Y;
             Region.Bottom = Region.Top + (areaInfo.rcViewCaWindow.Bottom - areaInfo.rcViewCaWindow.Top);
 
-            SMALL_RECT ClippedRegion;
-            ClippedRegion.Left = std::max(Region.Left, currentViewport.Left);
-            ClippedRegion.Top = std::max(Region.Top, currentViewport.Top);
-            ClippedRegion.Right = std::min(Region.Right, currentViewport.Right);
-            ClippedRegion.Bottom = std::min(Region.Bottom, currentViewport.Bottom);
+            Region.Left = std::max(Region.Left, currentViewport.Left);
+            Region.Top = std::max(Region.Top, currentViewport.Top);
+            Region.Right = std::min(Region.Right, currentViewport.Right);
+            Region.Bottom = std::min(Region.Bottom, currentViewport.Bottom);
 
-            if (IsValidSmallRect(&ClippedRegion))
+            if (Region)
             {
-                Region = ClippedRegion;
-                ClippedRegion.Left = std::max(Region.Left, convRegion.Left());
-                ClippedRegion.Top = std::max(Region.Top, convRegion.Top());
-                ClippedRegion.Right = std::min(Region.Right, convRegion.RightInclusive());
-                ClippedRegion.Bottom = std::min(Region.Bottom, convRegion.BottomInclusive());
-                if (IsValidSmallRect(&ClippedRegion))
+                Region.Left = std::max(Region.Left, convRegion.Left());
+                Region.Top = std::max(Region.Top, convRegion.Top());
+                Region.Right = std::min(Region.Right, convRegion.RightInclusive());
+                Region.Bottom = std::min(Region.Bottom, convRegion.BottomInclusive());
+                if (Region)
                 {
                     // if we have a renderer, we need to update.
                     // we've already confirmed (above with an early return) that we're on conversion areas that are a part of the active (visible/rendered) screen
                     // so send invalidates to those regions such that we're queried for data on the next frame and repainted.
                     if (ServiceLocator::LocateGlobals().pRender != nullptr)
                     {
-                        // convert inclusive rectangle to exclusive rectangle
-                        auto srExclusive = ClippedRegion;
-                        srExclusive.Right++;
-                        srExclusive.Bottom++;
-
-                        ServiceLocator::LocateGlobals().pRender->TriggerRedraw(Viewport::FromExclusive(srExclusive));
+                        ServiceLocator::LocateGlobals().pRender->TriggerRedraw(Viewport::FromInclusive(Region));
                     }
                 }
             }
@@ -90,7 +78,7 @@ void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
     return S_OK;
 }
 
-[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const COORD coordNewScreenSize)
+[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const til::size coordNewScreenSize)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto pIme = &gci.ConsoleIme;
diff --git a/src/host/directio.cpp b/src/host/directio.cpp
index 0b4cc422212..4933aec9ab5 100644
--- a/src/host/directio.cpp
+++ b/src/host/directio.cpp
@@ -537,9 +537,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
         auto tempIter = tempBuffer.cbegin();
         auto outIter = buffer.begin();
 
-        for (auto i = 0; i < size.Y; i++)
+        for (til::CoordType i = 0; i < size.Y; i++)
         {
-            for (auto j = 0; j < size.X; j++)
+            for (til::CoordType j = 0; j < size.X; j++)
             {
                 // Any time we see the lead flag, we presume there will be a trailing one following it.
                 // Giving us two bytes of space (one per cell in the ascii part of the character union)
@@ -615,9 +615,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
         const auto size = rectangle.Dimensions();
         auto outIter = buffer.begin();
 
-        for (auto i = 0; i < size.Y; i++)
+        for (til::CoordType i = 0; i < size.Y; i++)
         {
-            for (auto j = 0; j < size.X; j++)
+            for (til::CoordType j = 0; j < size.X; j++)
             {
                 // Clear lead/trailing flags. We'll determine it for ourselves versus the given codepage.
                 WI_ClearAllFlags(outIter->Attributes, COMMON_LVB_SBCSDBCS);
@@ -684,9 +684,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
     const auto size = rectangle.Dimensions();
     auto bufferIter = buffer.begin();
 
-    for (SHORT i = 0; i < size.Y; i++)
+    for (til::CoordType i = 0; i < size.Y; i++)
     {
-        for (SHORT j = 0; j < size.X; j++)
+        for (til::CoordType j = 0; j < size.X; j++)
         {
             // Prepare a candidate charinfo on the output side copying the colors but not the lead/trail information.
             CHAR_INFO candidate;
@@ -756,8 +756,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
         }
 
         // The buffer given should be big enough to hold the dimensions of the request.
-        size_t targetArea;
-        RETURN_IF_FAILED(SizeTMult(targetSize.X, targetSize.Y, &targetArea));
+        const auto targetArea = targetSize.area<size_t>();
         RETURN_HR_IF(E_INVALIDARG, targetArea < targetBuffer.size());
 
         // Clip the request rectangle to the size of the storage buffer
@@ -767,13 +766,13 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
 
         // Find the target point (where to write the user's buffer)
         // It will either be 0,0 or offset into the buffer by the inverse of the negative values.
-        COORD targetPoint;
+        til::point targetPoint;
         targetPoint.X = clip.Left < 0 ? -clip.Left : 0;
         targetPoint.Y = clip.Top < 0 ? -clip.Top : 0;
 
         // The clipped rect must be inside the buffer size, so it has a minimum value of 0. (max of itself and 0)
-        clip.Left = std::max(clip.Left, 0i16);
-        clip.Top = std::max(clip.Top, 0i16);
+        clip.Left = std::max(clip.Left, 0);
+        clip.Top = std::max(clip.Top, 0);
 
         // The final "request rectangle" or the area inside the buffer we want to read, is the clipped dimensions.
         const auto clippedRequestRectangle = Viewport::FromExclusive(clip);
@@ -784,7 +783,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
         // Get an iterator to the beginning of the return buffer
         // We might have to seek this forward or skip around if we clipped the request.
         auto targetIter = targetBuffer.begin();
-        COORD targetPos = { 0 };
+        til::point targetPos;
         const auto targetLimit = Viewport::FromDimensions(targetPoint, clippedRequestRectangle.Dimensions());
 
         // Get an iterator to the beginning of the request inside the screen buffer
@@ -902,7 +901,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
 
         // Do clipping according to the legacy patterns.
         auto writeRegion = requestRectangle.ToInclusive();
-        SMALL_RECT sourceRect;
+        til::inclusive_rect sourceRect;
         if (writeRegion.Right > storageSize.X - 1)
         {
             writeRegion.Right = storageSize.X - 1;
@@ -949,15 +948,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
         for (; target.Y < writeRectangle.BottomExclusive(); target.Y++)
         {
             // We find the offset into the original buffer by the dimensions of the original request rectangle.
-            ptrdiff_t rowOffset = 0;
-            RETURN_IF_FAILED(PtrdiffTSub(target.Y, requestRectangle.Top(), &rowOffset));
-            RETURN_IF_FAILED(PtrdiffTMult(rowOffset, requestRectangle.Width(), &rowOffset));
-
-            ptrdiff_t colOffset = 0;
-            RETURN_IF_FAILED(PtrdiffTSub(target.X, requestRectangle.Left(), &colOffset));
-
-            ptrdiff_t totalOffset = 0;
-            RETURN_IF_FAILED(PtrdiffTAdd(rowOffset, colOffset, &totalOffset));
+            const auto rowOffset = (target.Y - requestRectangle.Top()) * requestRectangle.Width();
+            const auto colOffset = target.X - requestRectangle.Left();
+            const auto totalOffset = rowOffset + colOffset;
 
             // Now we make a subspan starting from that offset for as much of the original request as would fit
             const auto subspan = buffer.subspan(totalOffset, writeRectangle.Width());
@@ -1027,7 +1020,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
 }
 
 [[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
-                                                                  const COORD origin,
+                                                                  const til::point origin,
                                                                   gsl::span<WORD> buffer,
                                                                   size_t& written) noexcept
 {
@@ -1048,7 +1041,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
 }
 
 [[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
-                                                                   const COORD origin,
+                                                                   const til::point origin,
                                                                    gsl::span<char> buffer,
                                                                    size_t& written) noexcept
 {
@@ -1077,7 +1070,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
 }
 
 [[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
-                                                                   const COORD origin,
+                                                                   const til::point origin,
                                                                    gsl::span<wchar_t> buffer,
                                                                    size_t& written) noexcept
 {
diff --git a/src/host/exe/exemain.cpp b/src/host/exe/exemain.cpp
index b0c77ee5fc1..0c2e6260723 100644
--- a/src/host/exe/exemain.cpp
+++ b/src/host/exe/exemain.cpp
@@ -194,6 +194,15 @@ static void _releaseNotifier() noexcept
     _comServerExitEvent.SetEvent();
 }
 
+// This method has the same behavior as gsl::narrow<T>, but instead of throwing an
+// exception on narrowing failure it'll return false. On success it returns true.
+template<typename T, typename U>
+constexpr bool narrow_maybe(U u, T& out) noexcept
+{
+    out = gsl::narrow_cast<T>(u);
+    return static_cast<U>(out) == u && (std::is_signed_v<T> == std::is_signed_v<U> || (out < T{}) == (u < U{}));
+}
+
 // Routine Description:
 // - Main entry point for EXE version of console launching.
 //   This can be used as a debugging/diagnostics tool as well as a method of testing the console without
diff --git a/src/host/ft_fuzzer/fuzzmain.cpp b/src/host/ft_fuzzer/fuzzmain.cpp
index 89db26f7b80..27763ebf211 100644
--- a/src/host/ft_fuzzer/fuzzmain.cpp
+++ b/src/host/ft_fuzzer/fuzzmain.cpp
@@ -82,8 +82,8 @@ struct NullDeviceComm : public IDeviceComm
 
     CONSOLE_API_CONNECTINFO fakeConnectInfo{};
     fakeConnectInfo.ConsoleInfo.SetShowWindow(SW_NORMAL);
-    fakeConnectInfo.ConsoleInfo.SetScreenBufferSize(til::size{ 80, 25 }.to_win32_coord());
-    fakeConnectInfo.ConsoleInfo.SetWindowSize(til::size{ 80, 25 }.to_win32_coord());
+    fakeConnectInfo.ConsoleInfo.SetScreenBufferSize({ 80, 25 });
+    fakeConnectInfo.ConsoleInfo.SetWindowSize({ 80, 25 });
     fakeConnectInfo.ConsoleInfo.SetStartupFlags(STARTF_USECOUNTCHARS);
     wcscpy_s(fakeConnectInfo.Title, fakeTitle.data());
     fakeConnectInfo.TitleLength = gsl::narrow_cast<DWORD>(fakeTitle.size() * sizeof(wchar_t)); // bytes, not wchars
@@ -132,7 +132,7 @@ extern "C" __declspec(dllexport) int LLVMFuzzerTestOneInput(const uint8_t* data,
     auto& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation();
 
     const auto u16String{ til::u8u16(std::string_view{ reinterpret_cast<const char*>(data), size }) };
-    SHORT scrollY{};
+    til::CoordType scrollY{};
     auto sizeInBytes{ u16String.size() * 2 };
     gci.LockConsole();
     auto u = wil::scope_exit([&]() { gci.UnlockConsole(); });
diff --git a/src/host/ft_host/API_OutputTests.cpp b/src/host/ft_host/API_OutputTests.cpp
index f175d85518b..baa539c22e9 100644
--- a/src/host/ft_host/API_OutputTests.cpp
+++ b/src/host/ft_host/API_OutputTests.cpp
@@ -769,7 +769,7 @@ void OutputTests::ReadConsoleOutputWWithClipping()
     VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputW(consoleOutputHandle, buffer.data(), regionDimensions, regionOrigin, &affected));
     VERIFY_ARE_EQUAL(expectedRegion, affected);
 
-    const auto affectedViewport = Viewport::FromInclusive(affected);
+    const auto affectedViewport = Viewport::FromInclusive(til::wrap_small_rect(affected));
     const auto filledBuffer = Viewport::FromDimensions({ 0, 0 }, affectedViewport.Dimensions());
 
     for (SHORT row = 0; row < regionDimensions.Y; row++)
@@ -865,7 +865,7 @@ void OutputTests::ReadConsoleOutputWNegativePositions()
     VERIFY_ARE_EQUAL(expectedRegion, affected);
 
     // Verify the data read affected only the expected area
-    const auto affectedViewport = Viewport::FromInclusive(affected);
+    const auto affectedViewport = Viewport::FromInclusive(til::wrap_small_rect(affected));
 
     // Because of the negative origin, the API will report that it filled starting at the 0 coordinate, but it believed
     // the original buffer's origin was at -3, -10. This means we have to read at that offset into the buffer we provided
@@ -955,7 +955,7 @@ void OutputTests::ReadConsoleOutputWPartialUserBuffer()
     expected.Top = regionOrigin.Y;
     expected.Bottom = regionDimensions.Y - 1;
 
-    const auto filledExpected = Viewport::FromInclusive(expected);
+    const auto filledExpected = Viewport::FromInclusive(til::wrap_small_rect(expected));
 
     // translate the expected region into the origin at 0,0 because that's what the API will report.
     expected.Right -= expected.Left;
diff --git a/src/host/ft_integrity/IntegrityTest.cpp b/src/host/ft_integrity/IntegrityTest.cpp
index be3db377fe1..8fc8a5f351e 100644
--- a/src/host/ft_integrity/IntegrityTest.cpp
+++ b/src/host/ft_integrity/IntegrityTest.cpp
@@ -220,7 +220,7 @@ void IntegrityTest::_TestValidationHelper(const bool fIsBlockExpected,
     wistd::unique_ptr<wchar_t[]> stringData = wil::make_unique_nothrow<wchar_t[]>(cch);
     THROW_IF_NULL_ALLOC(stringData);
 
-    COORD coordRead = { 0 };
+    til::point coordRead;
     for (coordRead.Y = 0; coordRead.Y < 8; coordRead.Y++)
     {
         ZeroMemory(stringData.get(), sizeof(wchar_t) * cch);
diff --git a/src/host/getset.cpp b/src/host/getset.cpp
index 0b3356242ca..b72259da01f 100644
--- a/src/host/getset.cpp
+++ b/src/host/getset.cpp
@@ -120,11 +120,16 @@ void ApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& con
         // If they're in the alt buffer, then when they query in that way, the
         //      value they'll get is the main buffer's size, which isn't updated
         //      until we switch back to it.
-        context.GetActiveBuffer().GetScreenBufferInformation(&data.dwSize,
-                                                             &data.dwCursorPosition,
-                                                             &data.srWindow,
+        til::size dwSize;
+        til::point dwCursorPosition;
+        til::inclusive_rect srWindow;
+        til::size dwMaximumWindowSize;
+
+        context.GetActiveBuffer().GetScreenBufferInformation(&dwSize,
+                                                             &dwCursorPosition,
+                                                             &srWindow,
                                                              &data.wAttributes,
-                                                             &data.dwMaximumWindowSize,
+                                                             &dwMaximumWindowSize,
                                                              &data.wPopupAttributes,
                                                              data.ColorTable);
 
@@ -134,8 +139,13 @@ void ApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& con
         //   to return an inclusive rect.
         // - For GetConsoleScreenBufferInfo, it will leave these values
         //   untouched, returning an exclusive rect.
-        data.srWindow.Right += 1;
-        data.srWindow.Bottom += 1;
+        srWindow.Right += 1;
+        srWindow.Bottom += 1;
+
+        data.dwSize = til::unwrap_coord_size(dwSize);
+        data.dwCursorPosition = til::unwrap_coord(dwCursorPosition);
+        data.srWindow = til::unwrap_small_rect(srWindow);
+        data.dwMaximumWindowSize = til::unwrap_coord_size(dwMaximumWindowSize);
     }
     CATCH_LOG();
 }
@@ -179,8 +189,8 @@ void ApiRoutines::GetConsoleSelectionInfoImpl(CONSOLE_SELECTION_INFO& consoleSel
 
             WI_SetFlag(consoleSelectionInfo.dwFlags, CONSOLE_SELECTION_IN_PROGRESS);
 
-            consoleSelectionInfo.dwSelectionAnchor = selection.GetSelectionAnchor();
-            consoleSelectionInfo.srSelection = selection.GetSelectionRectangle();
+            consoleSelectionInfo.dwSelectionAnchor = til::unwrap_coord(selection.GetSelectionAnchor());
+            consoleSelectionInfo.srSelection = til::unwrap_small_rect(selection.GetSelectionRectangle());
         }
         else
         {
@@ -216,7 +226,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
 // - S_OK, E_INVALIDARG or code from thrown exception
 [[nodiscard]] HRESULT ApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
                                                           const DWORD index,
-                                                          COORD& size) noexcept
+                                                          til::size& size) noexcept
 {
     try
     {
@@ -232,7 +242,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
         else
         {
             // Invalid font is 0,0 with STATUS_INVALID_PARAMETER
-            size = { 0 };
+            size = {};
             return E_INVALIDARG;
         }
     }
@@ -258,7 +268,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
 
         const auto& activeScreenInfo = context.GetActiveBuffer();
 
-        COORD WindowSize;
+        til::size WindowSize;
         if (isForMaximumWindowSize)
         {
             WindowSize = activeScreenInfo.GetMaxWindowSizeInCharacters();
@@ -267,7 +277,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
         {
             WindowSize = activeScreenInfo.GetCurrentFont().GetUnscaledSize();
         }
-        consoleFontInfoEx.dwFontSize = WindowSize;
+        consoleFontInfoEx.dwFontSize = til::unwrap_coord_size(WindowSize);
 
         consoleFontInfoEx.nFont = 0;
 
@@ -307,7 +317,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
         FontInfo fi(FaceName,
                     gsl::narrow_cast<unsigned char>(consoleFontInfoEx.FontFamily),
                     consoleFontInfoEx.FontWeight,
-                    consoleFontInfoEx.dwFontSize,
+                    til::wrap_coord_size(consoleFontInfoEx.dwFontSize),
                     gci.OutputCP);
 
         // TODO: MSFT: 9574827 - should this have a failure case?
@@ -486,7 +496,7 @@ void ApiRoutines::FlushConsoleInputBuffer(InputBuffer& context) noexcept
 // - context - The output buffer concerned
 // - size - receives the size in character count (rows/columns)
 void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
-                                                  COORD& size) noexcept
+                                                  til::size& size) noexcept
 {
     try
     {
@@ -508,7 +518,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 // Return Value:
 // - S_OK, E_INVALIDARG, or failure code from thrown exception
 [[nodiscard]] HRESULT ApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
-                                                                  const COORD size) noexcept
+                                                                  const til::size size) noexcept
 {
     try
     {
@@ -545,8 +555,8 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
         auto overflow = screenInfo.GetViewport().BottomRightExclusive() - screenInfo.GetBufferSize().Dimensions();
         if (overflow.X > 0 || overflow.Y > 0)
         {
-            overflow = { std::max<SHORT>(overflow.X, 0), std::max<SHORT>(overflow.Y, 0) };
-            RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, -overflow, false));
+            overflow = { -std::max(overflow.X, 0), -std::max(overflow.Y, 0) };
+            RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, overflow, false));
         }
 
         // And also that the cursor position is clamped within the buffer boundaries.
@@ -597,7 +607,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 
             commandLine.Hide(FALSE);
 
-            LOG_IF_FAILED(context.ResizeScreenBuffer(data.dwSize, TRUE));
+            LOG_IF_FAILED(context.ResizeScreenBuffer(til::wrap_coord_size(data.dwSize), TRUE));
 
             commandLine.Show();
         }
@@ -631,14 +641,14 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 
         context.SetDefaultAttributes(TextAttribute{ data.wAttributes }, TextAttribute{ data.wPopupAttributes });
 
-        const auto requestedViewport = Viewport::FromExclusive(data.srWindow);
+        const auto requestedViewport = Viewport::FromExclusive(til::wrap_exclusive_small_rect(data.srWindow));
 
         auto NewSize = requestedViewport.Dimensions();
         // If we have a window, clamp the requested viewport to the max window size
         if (!ServiceLocator::LocateGlobals().IsHeadless())
         {
-            NewSize.X = std::min(NewSize.X, data.dwMaximumWindowSize.X);
-            NewSize.Y = std::min(NewSize.Y, data.dwMaximumWindowSize.Y);
+            NewSize.X = std::min<til::CoordType>(NewSize.X, data.dwMaximumWindowSize.X);
+            NewSize.Y = std::min<til::CoordType>(NewSize.Y, data.dwMaximumWindowSize.Y);
         }
 
         // If wrap text is on, then the window width must be the same size as the buffer width
@@ -676,8 +686,8 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
         auto overflow = context.GetViewport().BottomRightExclusive() - context.GetBufferSize().Dimensions();
         if (overflow.X > 0 || overflow.Y > 0)
         {
-            overflow = { std::max<SHORT>(overflow.X, 0), std::max<SHORT>(overflow.Y, 0) };
-            RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, -overflow, false));
+            overflow = { -std::max(overflow.X, 0), -std::max(overflow.Y, 0) };
+            RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, overflow, false));
         }
 
         // And also that the cursor position is clamped within the buffer boundaries.
@@ -702,7 +712,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 // Return Value:
 // - S_OK, E_INVALIDARG, or failure code from thrown exception
 [[nodiscard]] HRESULT ApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
-                                                                const COORD position) noexcept
+                                                                const til::point position) noexcept
 {
     try
     {
@@ -733,7 +743,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
         // GH#1222 and GH#9754 - Use the "virtual" viewport here, so that the
         // viewport snaps back to the virtual viewport's location.
         const auto currentViewport = buffer.GetVirtualViewport().ToInclusive();
-        COORD delta{ 0 };
+        til::point delta;
         {
             // When evaluating the X offset, we must convert the buffer position to
             // equivalent screen coordinates, taking line rendition into account.
@@ -759,7 +769,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
             }
         }
 
-        COORD newWindowOrigin{ 0 };
+        til::point newWindowOrigin;
         newWindowOrigin.X = currentViewport.Left + delta.X;
         newWindowOrigin.Y = currentViewport.Top + delta.Y;
         // SetViewportOrigin will worry about clamping these values to the
@@ -815,7 +825,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 // - S_OK, E_INVALIDARG, or failure code from thrown exception
 [[nodiscard]] HRESULT ApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
                                                             const bool isAbsolute,
-                                                            const SMALL_RECT& windowRect) noexcept
+                                                            const til::inclusive_rect& windowRect) noexcept
 {
     try
     {
@@ -836,9 +846,9 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 
         RETURN_HR_IF(E_INVALIDARG, (Window.Right < Window.Left || Window.Bottom < Window.Top));
 
-        COORD NewWindowSize;
-        NewWindowSize.X = (SHORT)(CalcWindowSizeX(Window));
-        NewWindowSize.Y = (SHORT)(CalcWindowSizeY(Window));
+        til::point NewWindowSize;
+        NewWindowSize.X = CalcWindowSizeX(Window);
+        NewWindowSize.Y = CalcWindowSizeY(Window);
 
         // see MSFT:17415266
         // If we have a actual head, we care about the maximum size the window can be.
@@ -889,9 +899,9 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 // Return Value:
 // - S_OK, E_INVALIDARG, or failure code from thrown exception
 [[nodiscard]] HRESULT ApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
-                                                                  const SMALL_RECT& source,
-                                                                  const COORD target,
-                                                                  std::optional<SMALL_RECT> clip,
+                                                                  const til::inclusive_rect& source,
+                                                                  const til::point target,
+                                                                  std::optional<til::inclusive_rect> clip,
                                                                   const char fillCharacter,
                                                                   const WORD fillAttribute) noexcept
 {
@@ -919,9 +929,9 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
 // Return Value:
 // - S_OK, E_INVALIDARG, or failure code from thrown exception
 [[nodiscard]] HRESULT ApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
-                                                                  const SMALL_RECT& source,
-                                                                  const COORD target,
-                                                                  std::optional<SMALL_RECT> clip,
+                                                                  const til::inclusive_rect& source,
+                                                                  const til::point target,
+                                                                  std::optional<til::inclusive_rect> clip,
                                                                   const wchar_t fillCharacter,
                                                                   const WORD fillAttribute,
                                                                   const bool enableCmdShim) noexcept
@@ -1221,7 +1231,7 @@ void ApiRoutines::GetConsoleDisplayModeImpl(ULONG& flags) noexcept
 // - See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686028(v=vs.85).aspx
 [[nodiscard]] HRESULT ApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
                                                              const ULONG flags,
-                                                             COORD& newSize) noexcept
+                                                             til::size& newSize) noexcept
 {
     try
     {
diff --git a/src/host/globals.h b/src/host/globals.h
index 50e42c82d5c..f557d3c8b8e 100644
--- a/src/host/globals.h
+++ b/src/host/globals.h
@@ -49,8 +49,8 @@ class Globals
 
     wil::unique_event_nothrow hInputEvent;
 
-    SHORT sVerticalScrollSize;
-    SHORT sHorizontalScrollSize;
+    int sVerticalScrollSize;
+    int sHorizontalScrollSize;
 
     int dpi = USER_DEFAULT_SCREEN_DPI;
     ULONG cursorPixelWidth = 1;
diff --git a/src/host/misc.cpp b/src/host/misc.cpp
index 021e5562471..f30fb7d3acd 100644
--- a/src/host/misc.cpp
+++ b/src/host/misc.cpp
@@ -102,7 +102,7 @@ BOOL CheckBisectProcessW(const SCREEN_INFORMATION& ScreenInfo,
                          _In_reads_bytes_(cBytes) const WCHAR* pwchBuffer,
                          _In_ size_t cWords,
                          _In_ size_t cBytes,
-                         _In_ SHORT sOriginalXPosition,
+                         _In_ til::CoordType sOriginalXPosition,
                          _In_ BOOL fPrintableControlChars)
 {
     if (WI_IsFlagSet(ScreenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT))
@@ -151,7 +151,7 @@ BOOL CheckBisectProcessW(const SCREEN_INFORMATION& ScreenInfo,
                 case UNICODE_TAB:
                 {
                     size_t TabSize = NUMBER_OF_SPACES_IN_TAB(sOriginalXPosition);
-                    sOriginalXPosition = (SHORT)(sOriginalXPosition + TabSize);
+                    sOriginalXPosition = (til::CoordType)(sOriginalXPosition + TabSize);
                     if (cBytes < TabSize)
                         return TRUE;
                     cBytes -= TabSize;
diff --git a/src/host/misc.h b/src/host/misc.h
index 11eefe92ebb..6269353f5c0 100644
--- a/src/host/misc.h
+++ b/src/host/misc.h
@@ -35,7 +35,7 @@ BOOL CheckBisectProcessW(const SCREEN_INFORMATION& ScreenInfo,
                          _In_reads_bytes_(cBytes) const WCHAR* pwchBuffer,
                          _In_ size_t cWords,
                          _In_ size_t cBytes,
-                         _In_ SHORT sOriginalXPosition,
+                         _In_ til::CoordType sOriginalXPosition,
                          _In_ BOOL fPrintableControlChars);
 
 int ConvertToOem(const UINT uiCodePage,
diff --git a/src/host/output.cpp b/src/host/output.cpp
index e2138963d5c..0a9fceb03c1 100644
--- a/src/host/output.cpp
+++ b/src/host/output.cpp
@@ -65,7 +65,7 @@ using namespace Microsoft::Console::Interactivity;
 // - targetOrigin - upper left coordinates of new location rectangle
 static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
                            const Viewport& source,
-                           const COORD targetOrigin)
+                           const til::point targetOrigin)
 {
     const auto sourceOrigin = source.Origin();
 
@@ -86,7 +86,7 @@ static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
         {
             const auto delta = targetOrigin.Y - source.Top();
 
-            screenInfo.GetTextBuffer().ScrollRows(source.Top(), source.Height(), gsl::narrow<SHORT>(delta));
+            screenInfo.GetTextBuffer().ScrollRows(source.Top(), source.Height(), delta);
 
             return;
         }
@@ -121,7 +121,7 @@ static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
 // Return Value:
 // - vector of attribute data
 std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
-                                       const COORD coordRead,
+                                       const til::point coordRead,
                                        const size_t amountToRead)
 {
     // Short circuit. If nothing to read, leave early.
@@ -178,7 +178,7 @@ std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
 // Return Value:
 // - wstring
 std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
-                               const COORD coordRead,
+                               const til::point coordRead,
                                const size_t amountToRead)
 {
     // Short circuit. If nothing to read, leave early.
@@ -238,7 +238,7 @@ std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
 // Return Value:
 // - string of char data
 std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
-                              const COORD coordRead,
+                              const til::point coordRead,
                               const size_t amountToRead)
 {
     const auto wstr = ReadOutputStringW(screenInfo, coordRead, amountToRead);
@@ -247,7 +247,7 @@ std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
     return ConvertToA(gci.OutputCP, wstr);
 }
 
-void ScreenBufferSizeChange(const COORD coordNewSize)
+void ScreenBufferSizeChange(const til::size coordNewSize)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
@@ -305,7 +305,7 @@ bool StreamScrollRegion(SCREEN_INFORMATION& screenInfo)
         // Trigger a graphical update if we're active.
         if (screenInfo.IsActiveScreenBuffer())
         {
-            COORD coordDelta = { 0 };
+            til::point coordDelta;
             coordDelta.Y = -1;
 
             auto pNotifier = ServiceLocator::LocateAccessibilityNotifier();
@@ -336,9 +336,9 @@ bool StreamScrollRegion(SCREEN_INFORMATION& screenInfo)
 // - fillAttrsGiven - Attribute to fill source region with.
 // NOTE: Throws exceptions
 void ScrollRegion(SCREEN_INFORMATION& screenInfo,
-                  const SMALL_RECT scrollRectGiven,
-                  const std::optional<SMALL_RECT> clipRectGiven,
-                  const COORD destinationOriginGiven,
+                  const til::inclusive_rect scrollRectGiven,
+                  const std::optional<til::inclusive_rect> clipRectGiven,
+                  const til::point destinationOriginGiven,
                   const wchar_t fillCharGiven,
                   const TextAttribute fillAttrsGiven)
 {
diff --git a/src/host/output.h b/src/host/output.h
index 8c0a46517ac..849ba505596 100644
--- a/src/host/output.h
+++ b/src/host/output.h
@@ -22,26 +22,26 @@ Revision History:
 #include "../buffer/out/OutputCell.hpp"
 #include "../buffer/out/OutputCellRect.hpp"
 
-void ScreenBufferSizeChange(const COORD coordNewSize);
+void ScreenBufferSizeChange(const til::size coordNewSize);
 
 [[nodiscard]] NTSTATUS DoCreateScreenBuffer();
 
 std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
-                                       const COORD coordRead,
+                                       const til::point coordRead,
                                        const size_t amountToRead);
 
 std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
-                               const COORD coordRead,
+                               const til::point coordRead,
                                const size_t amountToRead);
 
 std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
-                              const COORD coordRead,
+                              const til::point coordRead,
                               const size_t amountToRead);
 
 void ScrollRegion(SCREEN_INFORMATION& screenInfo,
-                  const SMALL_RECT scrollRect,
-                  const std::optional<SMALL_RECT> clipRect,
-                  const COORD destinationOrigin,
+                  const til::inclusive_rect scrollRect,
+                  const std::optional<til::inclusive_rect> clipRect,
+                  const til::point destinationOrigin,
                   const wchar_t fillCharGiven,
                   const TextAttribute fillAttrsGiven);
 
diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp
index e355248d52d..e91241336d3 100644
--- a/src/host/outputStream.cpp
+++ b/src/host/outputStream.cpp
@@ -117,7 +117,7 @@ TextBuffer& ConhostInternalGetSet::GetTextBuffer()
 // - the exclusive coordinates of the viewport.
 til::rect ConhostInternalGetSet::GetViewport() const
 {
-    return til::rect{ _io.GetActiveOutputBuffer().GetVirtualViewport().ToInclusive() };
+    return _io.GetActiveOutputBuffer().GetVirtualViewport().ToExclusive();
 }
 
 // Routine Description:
@@ -129,8 +129,8 @@ til::rect ConhostInternalGetSet::GetViewport() const
 void ConhostInternalGetSet::SetViewportPosition(const til::point position)
 {
     auto& info = _io.GetActiveOutputBuffer();
-    const auto dimensions = til::size{ info.GetViewport().Dimensions() };
-    const auto windowRect = til::rect{ position, dimensions }.to_small_rect();
+    const auto dimensions = info.GetViewport().Dimensions();
+    const auto windowRect = til::rect{ position, dimensions }.to_inclusive_rect();
     THROW_IF_FAILED(ServiceLocator::LocateGlobals().api->SetConsoleWindowInfoImpl(info, true, windowRect));
 }
 
@@ -174,8 +174,8 @@ void ConhostInternalGetSet::SetScrollingRegion(const til::inclusive_rect& scroll
 {
     auto& screenInfo = _io.GetActiveOutputBuffer();
     auto srScrollMargins = screenInfo.GetRelativeScrollMargins().ToInclusive();
-    srScrollMargins.Top = gsl::narrow<short>(scrollMargins.Top);
-    srScrollMargins.Bottom = gsl::narrow<short>(scrollMargins.Bottom);
+    srScrollMargins.Top = scrollMargins.Top;
+    srScrollMargins.Bottom = scrollMargins.Bottom;
     screenInfo.SetScrollMargins(Viewport::FromInclusive(srScrollMargins));
 }
 
@@ -391,15 +391,13 @@ void ConhostInternalGetSet::PlayMidiNote(const int noteNumber, const int velocit
 // - height: The new height of the window, in rows
 // Return Value:
 // - True if handled successfully. False otherwise.
-bool ConhostInternalGetSet::ResizeWindow(const size_t width, const size_t height)
+bool ConhostInternalGetSet::ResizeWindow(const til::CoordType sColumns, const til::CoordType sRows)
 {
-    SHORT sColumns = 0;
-    SHORT sRows = 0;
-
-    THROW_IF_FAILED(SizeTToShort(width, &sColumns));
-    THROW_IF_FAILED(SizeTToShort(height, &sRows));
-    // We should do nothing if 0 is passed in for a size.
-    RETURN_BOOL_IF_FALSE(width > 0 && height > 0);
+    // Ensure we can safely use gsl::narrow_cast<short>(...).
+    if (sColumns <= 0 || sRows <= 0 || sColumns > SHRT_MAX || sRows > SHRT_MAX)
+    {
+        return false;
+    }
 
     auto api = ServiceLocator::LocateGlobals().api;
     auto& screenInfo = _io.GetActiveOutputBuffer();
@@ -411,19 +409,19 @@ bool ConhostInternalGetSet::ResizeWindow(const size_t width, const size_t height
     const auto oldViewport = screenInfo.GetVirtualViewport();
     auto newViewport = Viewport::FromDimensions(oldViewport.Origin(), sColumns, sRows);
     // Always resize the width of the console
-    csbiex.dwSize.X = sColumns;
+    csbiex.dwSize.X = gsl::narrow_cast<short>(sColumns);
     // Only set the screen buffer's height if it's currently less than
     //  what we're requesting.
     if (sRows > csbiex.dwSize.Y)
     {
-        csbiex.dwSize.Y = sRows;
+        csbiex.dwSize.Y = gsl::narrow_cast<short>(sRows);
     }
 
     // If the cursor row is now past the bottom of the viewport, we'll have to
     // move the viewport down to bring it back into view. However, we don't want
     // to do this in pty mode, because the conpty resize operation is dependent
     // on the viewport *not* being adjusted.
-    const short cursorOverflow = csbiex.dwCursorPosition.Y - newViewport.BottomInclusive();
+    const auto cursorOverflow = csbiex.dwCursorPosition.Y - newViewport.BottomInclusive();
     if (cursorOverflow > 0 && !IsConsolePty())
     {
         newViewport = Viewport::Offset(newViewport, { 0, cursorOverflow });
@@ -434,7 +432,7 @@ bool ConhostInternalGetSet::ResizeWindow(const size_t width, const size_t height
 
     // SetConsoleScreenBufferInfoEx however expects exclusive rects
     const auto sre = newViewport.ToExclusive();
-    csbiex.srWindow = sre;
+    csbiex.srWindow = til::unwrap_exclusive_small_rect(sre);
 
     THROW_IF_FAILED(api->SetConsoleScreenBufferInfoExImpl(screenInfo, csbiex));
     THROW_IF_FAILED(api->SetConsoleWindowInfoImpl(screenInfo, true, sri));
@@ -477,9 +475,9 @@ void ConhostInternalGetSet::NotifyAccessibilityChange(const til::rect& changedRe
     if (screenInfo.HasAccessibilityEventing())
     {
         screenInfo.NotifyAccessibilityEventing(
-            gsl::narrow_cast<short>(changedRect.left),
-            gsl::narrow_cast<short>(changedRect.top),
-            gsl::narrow_cast<short>(changedRect.right - 1),
-            gsl::narrow_cast<short>(changedRect.bottom - 1));
+            changedRect.left,
+            changedRect.top,
+            changedRect.right - 1,
+            changedRect.bottom - 1);
     }
 }
diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp
index 0bb642caeac..9a3bc2a0bdd 100644
--- a/src/host/outputStream.hpp
+++ b/src/host/outputStream.hpp
@@ -58,7 +58,7 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::
 
     void ShowWindow(bool showOrHide) override;
 
-    bool ResizeWindow(const size_t width, const size_t height) override;
+    bool ResizeWindow(const til::CoordType width, const til::CoordType height) override;
 
     void SetConsoleOutputCP(const unsigned int codepage) override;
     unsigned int GetConsoleOutputCP() const override;
diff --git a/src/host/popup.cpp b/src/host/popup.cpp
index 313cc612026..74c2a9c66ed 100644
--- a/src/host/popup.cpp
+++ b/src/host/popup.cpp
@@ -28,7 +28,7 @@ using Microsoft::Console::Interactivity::ServiceLocator;
 // Arguments:
 // - screenInfo - Reference to screen on which the popup should be drawn/overlaid.
 // - proposedSize - Suggested size of the popup. May be adjusted based on screen size.
-Popup::Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize) :
+Popup::Popup(SCREEN_INFORMATION& screenInfo, const til::size proposedSize) :
     _screenInfo(screenInfo),
     _userInputFunction(&Popup::_getUserInputInternal)
 {
@@ -39,12 +39,12 @@ Popup::Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize) :
 
     _region.Left = origin.X;
     _region.Top = origin.Y;
-    _region.Right = gsl::narrow<SHORT>(origin.X + size.X - 1i16);
-    _region.Bottom = gsl::narrow<SHORT>(origin.Y + size.Y - 1i16);
+    _region.Right = origin.X + size.X - 1;
+    _region.Bottom = origin.Y + size.Y - 1;
 
     _oldScreenSize = screenInfo.GetBufferSize().Dimensions();
 
-    SMALL_RECT TargetRect;
+    til::inclusive_rect TargetRect;
     TargetRect.Left = 0;
     TargetRect.Top = _region.Top;
     TargetRect.Right = _oldScreenSize.X - 1;
@@ -68,7 +68,7 @@ Popup::Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize) :
 Popup::~Popup()
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
-    const auto countWas = gci.PopupCount.fetch_sub(1i16);
+    const auto countWas = gci.PopupCount.fetch_sub(1);
     if (1 == countWas)
     {
         // Notify we're done showing popups.
@@ -87,7 +87,7 @@ void Popup::Draw()
 void Popup::_DrawBorder()
 {
     // fill attributes of top line
-    COORD WriteCoord;
+    til::point WriteCoord;
     WriteCoord.X = _region.Left;
     WriteCoord.Y = _region.Top;
     _screenInfo.Write(OutputCellIterator(_attributes, Width() + 2), WriteCoord);
@@ -103,7 +103,7 @@ void Popup::_DrawBorder()
     WriteCoord.X = _region.Right;
     _screenInfo.Write(OutputCellIterator(UNICODE_BOX_DRAW_LIGHT_DOWN_AND_LEFT, 1), WriteCoord);
 
-    for (SHORT i = 0; i < Height(); i++)
+    for (til::CoordType i = 0; i < Height(); i++)
     {
         WriteCoord.Y += 1;
         WriteCoord.X = _region.Left;
@@ -145,11 +145,11 @@ void Popup::_DrawPrompt(const UINT id)
     auto text = _LoadString(id);
 
     // Draw empty popup.
-    COORD WriteCoord;
-    WriteCoord.X = _region.Left + 1i16;
-    WriteCoord.Y = _region.Top + 1i16;
-    size_t lStringLength = Width();
-    for (SHORT i = 0; i < Height(); i++)
+    til::point WriteCoord;
+    WriteCoord.X = _region.Left + 1;
+    WriteCoord.Y = _region.Top + 1;
+    auto lStringLength = Width();
+    for (til::CoordType i = 0; i < Height(); i++)
     {
         const OutputCellIterator it(UNICODE_SPACE, _attributes, lStringLength);
         const auto done = _screenInfo.Write(it, WriteCoord);
@@ -158,12 +158,12 @@ void Popup::_DrawPrompt(const UINT id)
         WriteCoord.Y += 1;
     }
 
-    WriteCoord.X = _region.Left + 1i16;
-    WriteCoord.Y = _region.Top + 1i16;
+    WriteCoord.X = _region.Left + 1;
+    WriteCoord.Y = _region.Top + 1;
 
     // write prompt to screen
-    lStringLength = text.size();
-    if (lStringLength > (ULONG)Width())
+    lStringLength = gsl::narrow<til::CoordType>(text.size());
+    if (lStringLength > Width())
     {
         text = text.substr(0, Width());
     }
@@ -182,10 +182,10 @@ void Popup::End()
 {
     // restore previous contents to screen
 
-    SMALL_RECT SourceRect;
-    SourceRect.Left = 0i16;
+    til::inclusive_rect SourceRect;
+    SourceRect.Left = 0;
     SourceRect.Top = _region.Top;
-    SourceRect.Right = _oldScreenSize.X - 1i16;
+    SourceRect.Right = _oldScreenSize.X - 1;
     SourceRect.Bottom = _region.Bottom;
 
     const auto sourceViewport = Viewport::FromInclusive(SourceRect);
@@ -200,7 +200,7 @@ void Popup::End()
 // - proposedSize - The suggested size of the popup that may need to be adjusted to fit
 // Return Value:
 // - Coordinate size that the popup should consume in the screen buffer
-COORD Popup::_CalculateSize(const SCREEN_INFORMATION& screenInfo, const COORD proposedSize)
+til::size Popup::_CalculateSize(const SCREEN_INFORMATION& screenInfo, const til::size proposedSize)
 {
     // determine popup dimensions
     auto size = proposedSize;
@@ -225,14 +225,14 @@ COORD Popup::_CalculateSize(const SCREEN_INFORMATION& screenInfo, const COORD pr
 // - size - The size that the popup will consume
 // Return Value:
 // - Coordinate position of the origin point of the popup
-COORD Popup::_CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const COORD size)
+til::point Popup::_CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const til::size size)
 {
     const auto viewport = screenInfo.GetViewport();
 
     // determine origin.  center popup on window
-    COORD origin;
-    origin.X = gsl::narrow<SHORT>((viewport.Width() - size.X) / 2 + viewport.Left());
-    origin.Y = gsl::narrow<SHORT>((viewport.Height() - size.Y) / 2 + viewport.Top());
+    til::point origin;
+    origin.X = (viewport.Width() - size.X) / 2 + viewport.Left();
+    origin.Y = (viewport.Height() - size.Y) / 2 + viewport.Top();
     return origin;
 }
 
@@ -240,18 +240,18 @@ COORD Popup::_CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const COORD
 // - Helper to return the width of the popup in columns
 // Return Value:
 // - Width of popup inside attached screen buffer.
-SHORT Popup::Width() const noexcept
+til::CoordType Popup::Width() const noexcept
 {
-    return _region.Right - _region.Left - 1i16;
+    return _region.Right - _region.Left - 1;
 }
 
 // Routine Description:
 // - Helper to return the height of the popup in columns
 // Return Value:
 // - Height of popup inside attached screen buffer.
-SHORT Popup::Height() const noexcept
+til::CoordType Popup::Height() const noexcept
 {
-    return _region.Bottom - _region.Top - 1i16;
+    return _region.Bottom - _region.Top - 1;
 }
 
 // Routine Description:
@@ -259,11 +259,11 @@ SHORT Popup::Height() const noexcept
 //   we should overlay the cursor for user input.
 // Return Value:
 // - Coordinate location on the popup where the cursor should be placed.
-COORD Popup::GetCursorPosition() const noexcept
+til::point Popup::GetCursorPosition() const noexcept
 {
-    COORD CursorPosition;
-    CursorPosition.X = _region.Right - static_cast<SHORT>(MINIMUM_COMMAND_PROMPT_SIZE);
-    CursorPosition.Y = _region.Top + 1i16;
+    til::point CursorPosition;
+    CursorPosition.X = _region.Right - MINIMUM_COMMAND_PROMPT_SIZE;
+    CursorPosition.Y = _region.Top + 1;
     return CursorPosition;
 }
 
diff --git a/src/host/popup.h b/src/host/popup.h
index a9c67b3e1cf..73a91bafe27 100644
--- a/src/host/popup.h
+++ b/src/host/popup.h
@@ -29,11 +29,11 @@ class CommandHistory;
 class Popup
 {
 public:
-    static constexpr unsigned int MINIMUM_COMMAND_PROMPT_SIZE = 5;
+    static constexpr til::CoordType MINIMUM_COMMAND_PROMPT_SIZE = 5;
 
     using UserInputFunction = std::function<NTSTATUS(COOKED_READ_DATA&, bool&, DWORD&, wchar_t&)>;
 
-    Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize);
+    Popup(SCREEN_INFORMATION& screenInfo, const til::size proposedSize);
     virtual ~Popup();
     [[nodiscard]] virtual NTSTATUS Process(COOKED_READ_DATA& cookedReadData) noexcept = 0;
 
@@ -41,10 +41,10 @@ class Popup
 
     void End();
 
-    SHORT Width() const noexcept;
-    SHORT Height() const noexcept;
+    til::CoordType Width() const noexcept;
+    til::CoordType Height() const noexcept;
 
-    COORD GetCursorPosition() const noexcept;
+    til::point GetCursorPosition() const noexcept;
 
 protected:
     // used in test code to alter how the popup fetches use input
@@ -61,13 +61,13 @@ class Popup
     void _DrawPrompt(const UINT id);
     virtual void _DrawContent() = 0;
 
-    SMALL_RECT _region; // region popup occupies
+    til::inclusive_rect _region; // region popup occupies
     SCREEN_INFORMATION& _screenInfo;
     TextAttribute _attributes; // text attributes
 
 private:
-    COORD _CalculateSize(const SCREEN_INFORMATION& screenInfo, const COORD proposedSize);
-    COORD _CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const COORD size);
+    til::size _CalculateSize(const SCREEN_INFORMATION& screenInfo, const til::size proposedSize);
+    til::point _CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const til::size size);
 
     void _DrawBorder();
 
@@ -77,6 +77,6 @@ class Popup
                                                         wchar_t& wch) noexcept;
 
     OutputCellRect _oldContents; // contains data under popup
-    COORD _oldScreenSize;
+    til::size _oldScreenSize;
     UserInputFunction _userInputFunction;
 };
diff --git a/src/host/precomp.h b/src/host/precomp.h
index 507262a6f8a..f319e291cee 100644
--- a/src/host/precomp.h
+++ b/src/host/precomp.h
@@ -85,7 +85,6 @@ TRACELOGGING_DECLARE_PROVIDER(g_hConhostV2EventTraceProvider);
 #endif
 
 #include "../inc/contsf.h"
-#include "../inc/operators.hpp"
 #include "../inc/conattrs.hpp"
 
 // TODO: MSFT 9355094 Find a better way of doing this. http://osgvsowi/9355094
diff --git a/src/host/readDataCooked.cpp b/src/host/readDataCooked.cpp
index ac83589598d..154e537a696 100644
--- a/src/host/readDataCooked.cpp
+++ b/src/host/readDataCooked.cpp
@@ -107,7 +107,7 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
         _currentPosition = cchInitialData;
 
         OriginalCursorPosition() = screenInfo.GetTextBuffer().GetCursor().GetPosition();
-        OriginalCursorPosition().X -= (SHORT)_currentPosition;
+        OriginalCursorPosition().X -= (til::CoordType)_currentPosition;
 
         const auto sScreenBufferSizeX = screenInfo.GetBufferSize().Width();
         while (OriginalCursorPosition().X < 0)
@@ -164,17 +164,17 @@ SCREEN_INFORMATION& COOKED_READ_DATA::ScreenInfo() noexcept
     return _screenInfo;
 }
 
-const COORD& COOKED_READ_DATA::OriginalCursorPosition() const noexcept
+til::point COOKED_READ_DATA::OriginalCursorPosition() const noexcept
 {
     return _originalCursorPosition;
 }
 
-COORD& COOKED_READ_DATA::OriginalCursorPosition() noexcept
+til::point& COOKED_READ_DATA::OriginalCursorPosition() noexcept
 {
     return _originalCursorPosition;
 }
 
-COORD& COOKED_READ_DATA::BeforeDialogCursorPosition() noexcept
+til::point& COOKED_READ_DATA::BeforeDialogCursorPosition() noexcept
 {
     return _beforeDialogCursorPosition;
 }
@@ -482,7 +482,7 @@ bool COOKED_READ_DATA::ProcessInput(const wchar_t wchOrig,
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     size_t NumSpaces = 0;
-    SHORT ScrollY = 0;
+    til::CoordType ScrollY = 0;
     size_t NumToWrite;
     auto wch = wchOrig;
     bool fStartFromDelim;
@@ -702,11 +702,11 @@ bool COOKED_READ_DATA::ProcessInput(const wchar_t wchOrig,
 
         if (_echoInput && CallWrite)
         {
-            COORD CursorPosition;
+            til::point CursorPosition;
 
             // save cursor position
             CursorPosition = _screenInfo.GetTextBuffer().GetCursor().GetPosition();
-            CursorPosition.X = (SHORT)(CursorPosition.X + NumSpaces);
+            CursorPosition.X = (til::CoordType)(CursorPosition.X + NumSpaces);
 
             // clear the current command line from the screen
             // clang-format off
@@ -840,7 +840,7 @@ size_t COOKED_READ_DATA::Write(const std::wstring_view wstr)
     if (IsEchoInput())
     {
         size_t NumSpaces = 0;
-        SHORT ScrollY = 0;
+        til::CoordType ScrollY = 0;
 
         FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(ScreenInfo(),
                                                       _backupLimit,
diff --git a/src/host/readDataCooked.hpp b/src/host/readDataCooked.hpp
index 4eccee7f513..a60b8ca87ba 100644
--- a/src/host/readDataCooked.hpp
+++ b/src/host/readDataCooked.hpp
@@ -80,10 +80,10 @@ class COOKED_READ_DATA final : public ReadData
 
     SCREEN_INFORMATION& ScreenInfo() noexcept;
 
-    const COORD& OriginalCursorPosition() const noexcept;
-    COORD& OriginalCursorPosition() noexcept;
+    til::point OriginalCursorPosition() const noexcept;
+    til::point& OriginalCursorPosition() noexcept;
 
-    COORD& BeforeDialogCursorPosition() noexcept;
+    til::point& BeforeDialogCursorPosition() noexcept;
 
     bool IsEchoInput() const noexcept;
     bool IsInsertMode() const noexcept;
@@ -147,8 +147,8 @@ class COOKED_READ_DATA final : public ReadData
     SCREEN_INFORMATION& _screenInfo;
 
     // Note that cookedReadData's _originalCursorPosition is the position before ANY text was entered on the edit line.
-    COORD _originalCursorPosition;
-    COORD _beforeDialogCursorPosition; // Currently only used for F9 (ProcessCommandNumberInput) since it's the only pop-up to move the cursor when it starts.
+    til::point _originalCursorPosition;
+    til::point _beforeDialogCursorPosition; // Currently only used for F9 (ProcessCommandNumberInput) since it's the only pop-up to move the cursor when it starts.
 
     const bool _echoInput;
     const bool _lineInput;
diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp
index bb7f7135720..b7a5f7d5e4d 100644
--- a/src/host/renderData.cpp
+++ b/src/host/renderData.cpp
@@ -30,13 +30,12 @@ Microsoft::Console::Types::Viewport RenderData::GetViewport() noexcept
 // - Retrieves the end position of the text buffer. We use
 //   the cursor position as the text buffer end position
 // Return Value:
-// - COORD of the end position of the text buffer
-COORD RenderData::GetTextBufferEndPosition() const noexcept
+// - til::point of the end position of the text buffer
+til::point RenderData::GetTextBufferEndPosition() const noexcept
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto bufferSize = gci.GetActiveOutputBuffer().GetBufferSize();
-    COORD endPosition{ bufferSize.Width() - 1, bufferSize.BottomInclusive() };
-    return endPosition;
+    return { bufferSize.Width() - 1, bufferSize.BottomInclusive() };
 }
 
 // Routine Description:
@@ -108,7 +107,7 @@ void RenderData::UnlockConsole() noexcept
 // - <none>
 // Return Value:
 // - the cursor's position in the buffer relative to the buffer origin.
-COORD RenderData::GetCursorPosition() const noexcept
+til::point RenderData::GetCursorPosition() const noexcept
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto& cursor = gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor();
@@ -324,7 +323,7 @@ const std::wstring RenderData::GetHyperlinkCustomId(uint16_t id) const noexcept
 }
 
 // For now, we ignore regex patterns in conhost
-const std::vector<size_t> RenderData::GetPatternId(const COORD /*location*/) const noexcept
+const std::vector<size_t> RenderData::GetPatternId(const til::point /*location*/) const noexcept
 {
     return {};
 }
@@ -377,7 +376,7 @@ void RenderData::ClearSelection()
 // - coordEnd - Position to select up to
 // Return Value:
 // - <none>
-void RenderData::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
+void RenderData::SelectNewRegion(const til::point coordStart, const til::point coordEnd)
 {
     Selection::Instance().SelectNewRegion(coordStart, coordEnd);
 }
@@ -388,7 +387,7 @@ void RenderData::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
 // - none
 // Return Value:
 // - current selection anchor
-const COORD RenderData::GetSelectionAnchor() const noexcept
+const til::point RenderData::GetSelectionAnchor() const noexcept
 {
     return Selection::Instance().GetSelectionAnchor();
 }
@@ -399,7 +398,7 @@ const COORD RenderData::GetSelectionAnchor() const noexcept
 // - none
 // Return Value:
 // - current selection anchor
-const COORD RenderData::GetSelectionEnd() const noexcept
+const til::point RenderData::GetSelectionEnd() const noexcept
 {
     // The selection area in ConHost is encoded as two things...
     //  - SelectionAnchor: the initial position where the selection was started
@@ -440,7 +439,7 @@ const COORD RenderData::GetSelectionEnd() const noexcept
 // - coordSelectionStart - Anchor point (start of selection) for the region to be colored
 // - coordSelectionEnd - Other point referencing the rectangle inscribing the selection area
 // - attr - Color to apply to region.
-void RenderData::ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr)
+void RenderData::ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute attr)
 {
     Selection::Instance().ColorSelection(coordSelectionStart, coordSelectionEnd, attr);
 }
diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp
index bdceed55f8a..235bdc924b6 100644
--- a/src/host/renderData.hpp
+++ b/src/host/renderData.hpp
@@ -25,7 +25,7 @@ class RenderData final :
 public:
 #pragma region BaseData
     Microsoft::Console::Types::Viewport GetViewport() noexcept override;
-    COORD GetTextBufferEndPosition() const noexcept override;
+    til::point GetTextBufferEndPosition() const noexcept override;
     const TextBuffer& GetTextBuffer() const noexcept override;
     const FontInfo& GetFontInfo() const noexcept override;
 
@@ -36,7 +36,7 @@ class RenderData final :
 #pragma endregion
 
 #pragma region IRenderData
-    COORD GetCursorPosition() const noexcept override;
+    til::point GetCursorPosition() const noexcept override;
     bool IsCursorVisible() const noexcept override;
     bool IsCursorOn() const noexcept override;
     ULONG GetCursorHeight() const noexcept override;
@@ -53,7 +53,7 @@ class RenderData final :
     const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
     const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
 
-    const std::vector<size_t> GetPatternId(const COORD location) const noexcept override;
+    const std::vector<size_t> GetPatternId(const til::point location) const noexcept override;
 #pragma endregion
 
 #pragma region IUiaData
@@ -61,10 +61,10 @@ class RenderData final :
     const bool IsSelectionActive() const override;
     const bool IsBlockSelection() const noexcept override;
     void ClearSelection() override;
-    void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
-    const COORD GetSelectionAnchor() const noexcept;
-    const COORD GetSelectionEnd() const noexcept;
-    void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
+    void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override;
+    const til::point GetSelectionAnchor() const noexcept;
+    const til::point GetSelectionEnd() const noexcept;
+    void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute attr);
     const bool IsUiaDataInitialized() const noexcept override { return true; }
 #pragma endregion
 };
diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp
index af96a392cc0..e0631290026 100644
--- a/src/host/screenInfo.cpp
+++ b/src/host/screenInfo.cpp
@@ -48,12 +48,10 @@ SCREEN_INFORMATION::SCREEN_INFORMATION(
     _pAccessibilityNotifier{ pNotifier },
     _api{ *this },
     _stateMachine{ nullptr },
-    _scrollMargins{ Viewport::FromCoord({ 0 }) },
+    _scrollMargins{ Viewport::Empty() },
     _viewport(Viewport::Empty()),
     _psiAlternateBuffer{ nullptr },
     _psiMainBuffer{ nullptr },
-    _rcAltSavedClientNew{ 0 },
-    _rcAltSavedClientOld{ 0 },
     _fAltWindowChanged{ false },
     _PopupAttributes{ popupAttributes },
     _virtualBottom{ 0 },
@@ -90,9 +88,9 @@ SCREEN_INFORMATION::~SCREEN_INFORMATION()
 // - nFont - the initial font to generate text with.
 // - dwScreenBufferSize - the initial size of the screen buffer (in rows/columns).
 // Return Value:
-[[nodiscard]] NTSTATUS SCREEN_INFORMATION::CreateInstance(_In_ COORD coordWindowSize,
+[[nodiscard]] NTSTATUS SCREEN_INFORMATION::CreateInstance(_In_ til::size coordWindowSize,
                                                           const FontInfo fontInfo,
-                                                          _In_ COORD coordScreenBufferSize,
+                                                          _In_ til::size coordScreenBufferSize,
                                                           const TextAttribute defaultAttributes,
                                                           const TextAttribute popupAttributes,
                                                           const UINT uiCursorSize,
@@ -346,11 +344,11 @@ bool SCREEN_INFORMATION::IsActiveScreenBuffer() const
 // - MaximumWindowSize - Pointer to location in which to store maximum window size.
 // Return Value:
 // - None
-void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ PCOORD pcoordSize,
-                                                    _Out_ PCOORD pcoordCursorPosition,
-                                                    _Out_ PSMALL_RECT psrWindow,
+void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ til::size* pcoordSize,
+                                                    _Out_ til::point* pcoordCursorPosition,
+                                                    _Out_ til::inclusive_rect* psrWindow,
                                                     _Out_ PWORD pwAttributes,
-                                                    _Out_ PCOORD pcoordMaximumWindowSize,
+                                                    _Out_ til::size* pcoordMaximumWindowSize,
                                                     _Out_ PWORD pwPopupAttributes,
                                                     _Out_writes_(COLOR_TABLE_SIZE) LPCOLORREF lpColorTable) const
 {
@@ -378,8 +376,8 @@ void SCREEN_INFORMATION::GetScreenBufferInformation(_Out_ PCOORD pcoordSize,
 // Arguments:
 // - coordFontSize - The font size to use for calculation if a screen buffer is not yet attached.
 // Return Value:
-// - COORD containing the width and height representing the minimum character grid that can be rendered in the window.
-COORD SCREEN_INFORMATION::GetMinWindowSizeInCharacters(const COORD coordFontSize /*= { 1, 1 }*/) const
+// - til::size containing the width and height representing the minimum character grid that can be rendered in the window.
+til::size SCREEN_INFORMATION::GetMinWindowSizeInCharacters(const til::size coordFontSize /*= { 1, 1 }*/) const
 {
     FAIL_FAST_IF(coordFontSize.X == 0);
     FAIL_FAST_IF(coordFontSize.Y == 0);
@@ -388,9 +386,9 @@ COORD SCREEN_INFORMATION::GetMinWindowSizeInCharacters(const COORD coordFontSize
     const auto rcWindowInPixels = _pConsoleWindowMetrics->GetMinClientRectInPixels();
 
     // assign the pixel widths and heights to the final output
-    COORD coordClientAreaSize;
-    coordClientAreaSize.X = (SHORT)RECT_WIDTH(&rcWindowInPixels);
-    coordClientAreaSize.Y = (SHORT)RECT_HEIGHT(&rcWindowInPixels);
+    til::size coordClientAreaSize;
+    coordClientAreaSize.X = rcWindowInPixels.width();
+    coordClientAreaSize.Y = rcWindowInPixels.height();
 
     // now retrieve the font size and divide the pixel counts into character counts
     auto coordFont = coordFontSize; // by default, use the size we were given
@@ -416,9 +414,9 @@ COORD SCREEN_INFORMATION::GetMinWindowSizeInCharacters(const COORD coordFontSize
 // Arguments:
 // - coordFontSize - The font size to use for calculation if a screen buffer is not yet attached.
 // Return Value:
-// - COORD containing the width and height representing the largest character
+// - til::size containing the width and height representing the largest character
 //      grid that can be rendered on the current monitor and/or from the current buffer size.
-COORD SCREEN_INFORMATION::GetMaxWindowSizeInCharacters(const COORD coordFontSize /*= { 1, 1 }*/) const
+til::size SCREEN_INFORMATION::GetMaxWindowSizeInCharacters(const til::size coordFontSize /*= { 1, 1 }*/) const
 {
     FAIL_FAST_IF(coordFontSize.X == 0);
     FAIL_FAST_IF(coordFontSize.Y == 0);
@@ -448,9 +446,9 @@ COORD SCREEN_INFORMATION::GetMaxWindowSizeInCharacters(const COORD coordFontSize
 // Arguments:
 // - coordFontSize - The font size to use for calculation if a screen buffer is not yet attached.
 // Return Value:
-// - COORD containing the width and height representing the largest character
+// - til::size containing the width and height representing the largest character
 //      grid that can be rendered on the current monitor with the maximum size window.
-COORD SCREEN_INFORMATION::GetLargestWindowSizeInCharacters(const COORD coordFontSize /*= { 1, 1 }*/) const
+til::size SCREEN_INFORMATION::GetLargestWindowSizeInCharacters(const til::size coordFontSize /*= { 1, 1 }*/) const
 {
     FAIL_FAST_IF(coordFontSize.X == 0);
     FAIL_FAST_IF(coordFontSize.Y == 0);
@@ -458,9 +456,9 @@ COORD SCREEN_INFORMATION::GetLargestWindowSizeInCharacters(const COORD coordFont
     const auto rcClientInPixels = _pConsoleWindowMetrics->GetMaxClientRectInPixels();
 
     // first assign the pixel widths and heights to the final output
-    COORD coordClientAreaSize;
-    coordClientAreaSize.X = (SHORT)RECT_WIDTH(&rcClientInPixels);
-    coordClientAreaSize.Y = (SHORT)RECT_HEIGHT(&rcClientInPixels);
+    til::size coordClientAreaSize;
+    coordClientAreaSize.X = rcClientInPixels.width();
+    coordClientAreaSize.Y = rcClientInPixels.height();
 
     // now retrieve the font size and divide the pixel counts into character counts
     auto coordFont = coordFontSize; // by default, use the size we were given
@@ -480,21 +478,21 @@ COORD SCREEN_INFORMATION::GetLargestWindowSizeInCharacters(const COORD coordFont
     return coordClientAreaSize;
 }
 
-COORD SCREEN_INFORMATION::GetScrollBarSizesInCharacters() const
+til::size SCREEN_INFORMATION::GetScrollBarSizesInCharacters() const
 {
     auto coordFont = GetScreenFontSize();
 
     auto vScrollSize = ServiceLocator::LocateGlobals().sVerticalScrollSize;
     auto hScrollSize = ServiceLocator::LocateGlobals().sHorizontalScrollSize;
 
-    COORD coordBarSizes;
+    til::size coordBarSizes;
     coordBarSizes.X = (vScrollSize / coordFont.X) + ((vScrollSize % coordFont.X) != 0 ? 1 : 0);
     coordBarSizes.Y = (hScrollSize / coordFont.Y) + ((hScrollSize % coordFont.Y) != 0 ? 1 : 0);
 
     return coordBarSizes;
 }
 
-void SCREEN_INFORMATION::GetRequiredConsoleSizeInPixels(_Out_ PSIZE const pRequiredSize) const
+void SCREEN_INFORMATION::GetRequiredConsoleSizeInPixels(_Out_ til::size* const pRequiredSize) const
 {
     const auto coordFontSize = GetCurrentFont().GetSize();
 
@@ -503,20 +501,20 @@ void SCREEN_INFORMATION::GetRequiredConsoleSizeInPixels(_Out_ PSIZE const pRequi
     pRequiredSize->cy = GetViewport().Height() * coordFontSize.Y;
 }
 
-COORD SCREEN_INFORMATION::GetScreenFontSize() const
+til::size SCREEN_INFORMATION::GetScreenFontSize() const
 {
     // If we have no renderer, then we don't really need any sort of pixel math. so the "font size" for the scale factor
     // (which is used almost everywhere around the code as * and / calls) should just be 1,1 so those operations will do
     // effectively nothing.
-    COORD coordRet = { 1, 1 };
+    til::size coordRet = { 1, 1 };
     if (ServiceLocator::LocateGlobals().pRender != nullptr)
     {
         coordRet = GetCurrentFont().GetSize();
     }
 
     // For sanity's sake, make sure not to leak 0 out as a possible value. These values are used in division operations.
-    coordRet.X = std::max(coordRet.X, 1i16);
-    coordRet.Y = std::max(coordRet.Y, 1i16);
+    coordRet.X = std::max(coordRet.X, 1);
+    coordRet.Y = std::max(coordRet.Y, 1);
 
     return coordRet;
 }
@@ -585,10 +583,10 @@ bool SCREEN_INFORMATION::HasAccessibilityEventing() const noexcept
 // to aggregate drawing metadata to determine whether or not to use PolyTextOut.
 // After the Nov 2015 graphics refactor, the metadata drawing flag calculation is no longer necessary.
 // This now only notifies accessibility apps of a change.
-void SCREEN_INFORMATION::NotifyAccessibilityEventing(const short sStartX,
-                                                     const short sStartY,
-                                                     const short sEndX,
-                                                     const short sEndY)
+void SCREEN_INFORMATION::NotifyAccessibilityEventing(const til::CoordType sStartX,
+                                                     const til::CoordType sStartY,
+                                                     const til::CoordType sEndX,
+                                                     const til::CoordType sEndY)
 {
     if (!_pAccessibilityNotifier)
     {
@@ -711,7 +709,7 @@ VOID SCREEN_INFORMATION::InternalUpdateScrollBars()
 // - pcoordSize - Requested viewport width/heights in characters
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::SetViewportSize(const COORD* const pcoordSize)
+void SCREEN_INFORMATION::SetViewportSize(const til::size* const pcoordSize)
 {
     // If this is the alt buffer or a VT I/O buffer:
     //      first resize ourselves to match the new viewport
@@ -724,7 +722,7 @@ void SCREEN_INFORMATION::SetViewportSize(const COORD* const pcoordSize)
         if (_psiMainBuffer)
         {
             _psiMainBuffer->_fAltWindowChanged = false;
-            _psiMainBuffer->_deferredPtyResize = til::size{ GetBufferSize().Dimensions() };
+            _psiMainBuffer->_deferredPtyResize = GetBufferSize().Dimensions();
         }
     }
     _InternalSetViewportSize(pcoordSize, false, false);
@@ -749,13 +747,13 @@ void SCREEN_INFORMATION::SetViewportSize(const COORD* const pcoordSize)
 // - STATUS_INVALID_PARAMETER if the new viewport would be outside the buffer,
 //      else STATUS_SUCCESS
 [[nodiscard]] NTSTATUS SCREEN_INFORMATION::SetViewportOrigin(const bool fAbsolute,
-                                                             const COORD coordWindowOrigin,
+                                                             const til::point coordWindowOrigin,
                                                              const bool updateBottom)
 {
     // calculate window size
     auto WindowSize = _viewport.Dimensions();
 
-    SMALL_RECT NewWindow;
+    til::inclusive_rect NewWindow;
     // if relative coordinates, figure out absolute coords.
     if (!fAbsolute)
     {
@@ -775,8 +773,8 @@ void SCREEN_INFORMATION::SetViewportSize(const COORD* const pcoordSize)
         NewWindow.Left = coordWindowOrigin.X;
         NewWindow.Top = coordWindowOrigin.Y;
     }
-    NewWindow.Right = (SHORT)(NewWindow.Left + WindowSize.X - 1);
-    NewWindow.Bottom = (SHORT)(NewWindow.Top + WindowSize.Y - 1);
+    NewWindow.Right = NewWindow.Left + WindowSize.X - 1;
+    NewWindow.Bottom = NewWindow.Top + WindowSize.Y - 1;
 
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
@@ -786,7 +784,7 @@ void SCREEN_INFORMATION::SetViewportSize(const COORD* const pcoordSize)
     //  Instead move us to the bottom of the logical viewport.
     if (gci.IsTerminalScrolling() && !updateBottom && NewWindow.Bottom > _virtualBottom)
     {
-        const short delta = _virtualBottom - NewWindow.Bottom;
+        const auto delta = _virtualBottom - NewWindow.Bottom;
         NewWindow.Top += delta;
         NewWindow.Bottom += delta;
     }
@@ -862,8 +860,8 @@ bool SCREEN_INFORMATION::PostUpdateWindowSize() const
 // - prcClientOld - Client rectangle in pixels before this update
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
-                                             const RECT* const prcClientOld)
+void SCREEN_INFORMATION::ProcessResizeWindow(const til::rect* const prcClientNew,
+                                             const til::rect* const prcClientOld)
 {
     if (_IsAltBuffer())
     {
@@ -884,7 +882,7 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
     LOG_IF_FAILED(adjustBufferSizeResult);
 
     // 2. Now calculate how large the new viewport should be
-    COORD coordViewportSize;
+    til::size coordViewportSize;
     _CalculateViewportSize(prcClientNew, &coordViewportSize);
 
     // 3. And adjust the existing viewport to match the same dimensions.
@@ -922,9 +920,9 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
 // - pcoordClientNewCharacters - The maximum number of characters X by Y that can be displayed in the window with the given backing buffer.
 // Return Value:
 // - S_OK if math was successful. Check with SUCCEEDED/FAILED macro.
-[[nodiscard]] HRESULT SCREEN_INFORMATION::_AdjustScreenBufferHelper(const RECT* const prcClientNew,
-                                                                    const COORD coordBufferOld,
-                                                                    _Out_ COORD* const pcoordClientNewCharacters)
+[[nodiscard]] HRESULT SCREEN_INFORMATION::_AdjustScreenBufferHelper(const til::rect* const prcClientNew,
+                                                                    const til::size coordBufferOld,
+                                                                    _Out_ til::size* const pcoordClientNewCharacters)
 {
     // Get the font size ready.
     const auto coordFontSize = GetScreenFontSize();
@@ -933,9 +931,9 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
     RETURN_HR_IF(E_NOT_VALID_STATE, 0 == coordFontSize.X || 0 == coordFontSize.Y);
 
     // Find out how much client space we have to work with in the new area.
-    SIZE sizeClientNewPixels = { 0 };
-    sizeClientNewPixels.cx = RECT_WIDTH(prcClientNew);
-    sizeClientNewPixels.cy = RECT_HEIGHT(prcClientNew);
+    til::size sizeClientNewPixels;
+    sizeClientNewPixels.cx = prcClientNew->width();
+    sizeClientNewPixels.cy = prcClientNew->height();
 
     // Subtract out scroll bar space if scroll bars will be necessary.
     auto fIsHorizontalVisible = false;
@@ -953,12 +951,11 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
     }
 
     // Now with the scroll bars removed, calculate how many characters could fit into the new window area.
-    pcoordClientNewCharacters->X = (SHORT)(sizeClientNewPixels.cx / coordFontSize.X);
-    pcoordClientNewCharacters->Y = (SHORT)(sizeClientNewPixels.cy / coordFontSize.Y);
+    *pcoordClientNewCharacters = sizeClientNewPixels / coordFontSize;
 
     // If the new client is too tiny, our viewport will be 1x1.
-    pcoordClientNewCharacters->X = std::max(pcoordClientNewCharacters->X, 1i16);
-    pcoordClientNewCharacters->Y = std::max(pcoordClientNewCharacters->Y, 1i16);
+    pcoordClientNewCharacters->X = std::max(pcoordClientNewCharacters->X, 1);
+    pcoordClientNewCharacters->Y = std::max(pcoordClientNewCharacters->Y, 1);
     return S_OK;
 }
 
@@ -970,7 +967,7 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
 // - prcClientNew - Client rectangle in pixels after this update
 // Return Value:
 // - appropriate HRESULT
-[[nodiscard]] HRESULT SCREEN_INFORMATION::_AdjustScreenBuffer(const RECT* const prcClientNew)
+[[nodiscard]] HRESULT SCREEN_INFORMATION::_AdjustScreenBuffer(const til::rect* const prcClientNew)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     // Prepare the buffer sizes.
@@ -979,7 +976,7 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
     auto coordBufferSizeNew = coordBufferSizeOld;
 
     // First figure out how many characters we could fit into the new window given the old buffer size
-    COORD coordClientNewCharacters;
+    til::size coordClientNewCharacters;
 
     RETURN_IF_FAILED(_AdjustScreenBufferHelper(prcClientNew, coordBufferSizeOld, &coordClientNewCharacters));
 
@@ -1000,8 +997,8 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
         // The alt buffer always wants to be exactly the size of the screen, never more or less.
         // This prevents scrollbars when you increase the alt buffer size, then decrease it.
         // Can't have a buffer dimension of 0 - that'll cause divide by zeros in the future.
-        coordBufferSizeNew.X = std::max(coordClientNewCharacters.X, 1i16);
-        coordBufferSizeNew.Y = std::max(coordClientNewCharacters.Y, 1i16);
+        coordBufferSizeNew.X = std::max(coordClientNewCharacters.X, 1);
+        coordBufferSizeNew.Y = std::max(coordClientNewCharacters.Y, 1);
     }
     else
     {
@@ -1018,8 +1015,7 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
     auto hr = S_FALSE;
 
     // Only attempt to modify the buffer if something changed. Expensive operation.
-    if (coordBufferSizeOld.X != coordBufferSizeNew.X ||
-        coordBufferSizeOld.Y != coordBufferSizeNew.Y)
+    if (coordBufferSizeOld != coordBufferSizeNew)
     {
         auto& commandLine = CommandLine::Instance();
 
@@ -1053,14 +1049,14 @@ void SCREEN_INFORMATION::ProcessResizeWindow(const RECT* const prcClientNew,
 // - pcoordSize - Filled with the width/height to which the viewport should be set.
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::_CalculateViewportSize(const RECT* const prcClientArea, _Out_ COORD* const pcoordSize)
+void SCREEN_INFORMATION::_CalculateViewportSize(const til::rect* const prcClientArea, _Out_ til::size* const pcoordSize)
 {
     const auto coordBufferSize = GetBufferSize().Dimensions();
     const auto coordFontSize = GetScreenFontSize();
 
-    SIZE sizeClientPixels = { 0 };
-    sizeClientPixels.cx = RECT_WIDTH(prcClientArea);
-    sizeClientPixels.cy = RECT_HEIGHT(prcClientArea);
+    til::size sizeClientPixels;
+    sizeClientPixels.cx = prcClientArea->width();
+    sizeClientPixels.cy = prcClientArea->height();
 
     bool fIsHorizontalVisible;
     bool fIsVerticalVisible;
@@ -1080,8 +1076,8 @@ void SCREEN_INFORMATION::_CalculateViewportSize(const RECT* const prcClientArea,
         sizeClientPixels.cx -= ServiceLocator::LocateGlobals().sVerticalScrollSize;
     }
 
-    pcoordSize->X = (SHORT)(sizeClientPixels.cx / coordFontSize.X);
-    pcoordSize->Y = (SHORT)(sizeClientPixels.cy / coordFontSize.Y);
+    pcoordSize->X = (til::CoordType)(sizeClientPixels.cx / coordFontSize.X);
+    pcoordSize->Y = (til::CoordType)(sizeClientPixels.cy / coordFontSize.Y);
 }
 
 // Routine Description:
@@ -1093,12 +1089,12 @@ void SCREEN_INFORMATION::_CalculateViewportSize(const RECT* const prcClientArea,
 // - fResizeFromBottom - If false, will trim/add to top of viewport first. If true, will trim/add to left.
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
+void SCREEN_INFORMATION::_InternalSetViewportSize(const til::size* const pcoordSize,
                                                   const bool fResizeFromTop,
                                                   const bool fResizeFromLeft)
 {
-    const short DeltaX = pcoordSize->X - _viewport.Width();
-    const short DeltaY = pcoordSize->Y - _viewport.Height();
+    const auto DeltaX = pcoordSize->X - _viewport.Width();
+    const auto DeltaY = pcoordSize->Y - _viewport.Height();
     const auto coordScreenBufferSize = GetBufferSize().Dimensions();
 
     // do adjustments on a copy that's easily manipulated.
@@ -1109,7 +1105,7 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
     if (fResizeFromLeft)
     {
         // we're being horizontally sized from the left border
-        const SHORT sLeftProposed = (srNewViewport.Left - DeltaX);
+        const auto sLeftProposed = srNewViewport.Left - DeltaX;
         if (sLeftProposed >= 0)
         {
             // there's enough room in the backlog to just expand left
@@ -1121,13 +1117,13 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
             // content above as we can, but we can't show more
             // than the left of the window
             srNewViewport.Left = 0;
-            srNewViewport.Right += (SHORT)abs(sLeftProposed);
+            srNewViewport.Right += abs(sLeftProposed);
         }
     }
     else
     {
         // we're being horizontally sized from the right border
-        const SHORT sRightProposed = (srNewViewport.Right + DeltaX);
+        const auto sRightProposed = (srNewViewport.Right + DeltaX);
         if (sRightProposed <= (coordScreenBufferSize.X - 1))
         {
             srNewViewport.Right += DeltaX;
@@ -1141,7 +1137,7 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
 
     if (fResizeFromTop)
     {
-        const SHORT sTopProposed = (srNewViewport.Top - DeltaY);
+        const auto sTopProposed = (srNewViewport.Top - DeltaY);
         // we're being vertically sized from the top border
         if (sTopProposed >= 0)
         {
@@ -1172,13 +1168,13 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
             // content above as we can, but we can't show more
             // than the top of the window
             srNewViewport.Top = 0;
-            srNewViewport.Bottom += (SHORT)abs(sTopProposed);
+            srNewViewport.Bottom += abs(sTopProposed);
         }
     }
     else
     {
         // we're being vertically sized from the bottom border
-        const SHORT sBottomProposed = (srNewViewport.Bottom + DeltaY);
+        const auto sBottomProposed = (srNewViewport.Bottom + DeltaY);
         if (sBottomProposed <= (coordScreenBufferSize.Y - 1))
         {
             // If the new bottom is supposed to be before the final line of the buffer
@@ -1187,7 +1183,7 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
             // The final valid end position will be the coordinates of
             // the last character displayed (including any characters
             // in the input line)
-            COORD coordValidEnd;
+            til::point coordValidEnd;
             Selection::Instance().GetValidAreaBoundaries(nullptr, &coordValidEnd);
 
             // If the bottom of the window when adjusted would be
@@ -1225,21 +1221,21 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
     }
 
     // Bottom and right cannot pass the final characters in the array.
-    const SHORT offRightDelta = srNewViewport.Right - (coordScreenBufferSize.X - 1);
+    const auto offRightDelta = srNewViewport.Right - (coordScreenBufferSize.X - 1);
     if (offRightDelta > 0) // the viewport was off the right of the buffer...
     {
         // ...so slide both left/right back into the buffer. This will prevent us
         // from having a negative width later.
         srNewViewport.Right -= offRightDelta;
-        srNewViewport.Left = std::max<SHORT>(0, srNewViewport.Left - offRightDelta);
+        srNewViewport.Left = std::max(0, srNewViewport.Left - offRightDelta);
     }
-    const SHORT offBottomDelta = srNewViewport.Bottom - (coordScreenBufferSize.Y - 1);
+    const auto offBottomDelta = srNewViewport.Bottom - (coordScreenBufferSize.Y - 1);
     if (offBottomDelta > 0) // the viewport was off the right of the buffer...
     {
         // ...so slide both top/bottom back into the buffer. This will prevent us
         // from having a negative width later.
         srNewViewport.Bottom -= offBottomDelta;
-        srNewViewport.Top = std::max<SHORT>(0, srNewViewport.Top - offBottomDelta);
+        srNewViewport.Top = std::max(0, srNewViewport.Top - offBottomDelta);
     }
 
     // In general we want to avoid moving the virtual bottom unless it's aligned with
@@ -1284,9 +1280,9 @@ void SCREEN_INFORMATION::_InternalSetViewportSize(const COORD* const pcoordSize,
 // - pcoordSize - Requested viewport width/heights in characters
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::_AdjustViewportSize(const RECT* const prcClientNew,
-                                             const RECT* const prcClientOld,
-                                             const COORD* const pcoordSize)
+void SCREEN_INFORMATION::_AdjustViewportSize(const til::rect* const prcClientNew,
+                                             const til::rect* const prcClientOld,
+                                             const til::size* const pcoordSize)
 {
     // If the left is the only one that changed (and not the right
     // also), then adjust from the left. Otherwise if the right
@@ -1341,9 +1337,9 @@ void SCREEN_INFORMATION::_AdjustViewportSize(const RECT* const prcClientNew,
 //   (consuming horizontal space) will need to be visible
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::s_CalculateScrollbarVisibility(const RECT* const prcClientArea,
-                                                        const COORD* const pcoordBufferSize,
-                                                        const COORD* const pcoordFontSize,
+void SCREEN_INFORMATION::s_CalculateScrollbarVisibility(const til::rect* const prcClientArea,
+                                                        const til::size* const pcoordBufferSize,
+                                                        const til::size* const pcoordFontSize,
                                                         _Out_ bool* const pfIsHorizontalVisible,
                                                         _Out_ bool* const pfIsVerticalVisible)
 {
@@ -1352,12 +1348,12 @@ void SCREEN_INFORMATION::s_CalculateScrollbarVisibility(const RECT* const prcCli
     *pfIsVerticalVisible = false;
 
     // Set up the client area in pixels
-    SIZE sizeClientPixels = { 0 };
-    sizeClientPixels.cx = RECT_WIDTH(prcClientArea);
-    sizeClientPixels.cy = RECT_HEIGHT(prcClientArea);
+    til::size sizeClientPixels;
+    sizeClientPixels.cx = prcClientArea->width();
+    sizeClientPixels.cy = prcClientArea->height();
 
     // Set up the buffer area in pixels by multiplying the size by the font size scale factor
-    SIZE sizeBufferPixels = { 0 };
+    til::size sizeBufferPixels;
     sizeBufferPixels.cx = pcoordBufferSize->X * pcoordFontSize->X;
     sizeBufferPixels.cy = pcoordBufferSize->Y * pcoordFontSize->Y;
 
@@ -1422,7 +1418,7 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
 // - <in> Coordinates of the new screen size
 // Return Value:
 // - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
-[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeWithReflow(const COORD coordNewScreenSize)
+[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeWithReflow(const til::size coordNewScreenSize)
 {
     if ((USHORT)coordNewScreenSize.X >= SHORT_MAX || (USHORT)coordNewScreenSize.Y >= SHORT_MAX)
     {
@@ -1474,8 +1470,8 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
         // otherwise the top of the virtual viewport would end up negative.
         const auto cursorRow = newTextBuffer->GetCursor().GetPosition().Y;
         const auto lastNonSpaceRow = newTextBuffer->GetLastNonSpaceCharacter().Y;
-        const auto estimatedBottom = gsl::narrow_cast<short>(cursorRow + cursorDistanceFromBottom);
-        const auto viewportBottom = gsl::narrow_cast<short>(_viewport.Height() - 1);
+        const auto estimatedBottom = cursorRow + cursorDistanceFromBottom;
+        const auto viewportBottom = _viewport.Height() - 1;
         _virtualBottom = std::max({ lastNonSpaceRow, estimatedBottom, viewportBottom });
 
         // We can't let it extend past the bottom of the buffer either.
@@ -1483,8 +1479,8 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
 
         // Adjust the viewport so the cursor doesn't wildly fly off up or down.
         const auto sCursorHeightInViewportAfter = cursorRow - _viewport.Top();
-        COORD coordCursorHeightDiff = { 0 };
-        coordCursorHeightDiff.Y = gsl::narrow_cast<short>(sCursorHeightInViewportAfter - sCursorHeightInViewportBefore);
+        til::point coordCursorHeightDiff;
+        coordCursorHeightDiff.Y = sCursorHeightInViewportAfter - sCursorHeightInViewportBefore;
         LOG_IF_FAILED(SetViewportOrigin(false, coordCursorHeightDiff, false));
 
         newTextBuffer->SetCurrentAttributes(oldPrimaryAttributes);
@@ -1502,7 +1498,7 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
 // - coordNewScreenSize - new size of screen.
 // Return Value:
 // - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
-[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeTraditional(const COORD coordNewScreenSize)
+[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeTraditional(const til::size coordNewScreenSize)
 {
     _textBuffer->GetCursor().StartDeferDrawing();
     auto endDefer = wil::scope_exit([&]() noexcept { _textBuffer->GetCursor().EndDeferDrawing(); });
@@ -1517,7 +1513,7 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
 // - DoScrollBarUpdate - indicates whether to update scroll bars at the end
 // Return Value:
 // - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
-[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeScreenBuffer(const COORD coordNewScreenSize,
+[[nodiscard]] NTSTATUS SCREEN_INFORMATION::ResizeScreenBuffer(const til::size coordNewScreenSize,
                                                               const bool fDoScrollBarUpdate)
 {
     // If the size hasn't actually changed, do nothing.
@@ -1570,7 +1566,7 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
     {
         if (HasAccessibilityEventing())
         {
-            NotifyAccessibilityEventing(0, 0, (SHORT)(coordNewScreenSize.X - 1), (SHORT)(coordNewScreenSize.Y - 1));
+            NotifyAccessibilityEventing(0, 0, coordNewScreenSize.X - 1, coordNewScreenSize.Y - 1);
         }
 
         if ((!ConvScreenInfo))
@@ -1607,7 +1603,7 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
 // - psrRect - Pointer to rectangle holding data to be trimmed
 // Return Value:
 // - <none>
-void SCREEN_INFORMATION::ClipToScreenBuffer(_Inout_ SMALL_RECT* const psrClip) const
+void SCREEN_INFORMATION::ClipToScreenBuffer(_Inout_ til::inclusive_rect* const psrClip) const
 {
     const auto bufferSize = GetBufferSize();
 
@@ -1713,7 +1709,7 @@ void SCREEN_INFORMATION::SetCursorDBMode(const bool DoubleCursor)
 // - TurnOn - true if cursor should be left on, false if should be left off
 // Return Value:
 // - Status
-[[nodiscard]] NTSTATUS SCREEN_INFORMATION::SetCursorPosition(const COORD Position, const bool TurnOn)
+[[nodiscard]] NTSTATUS SCREEN_INFORMATION::SetCursorPosition(const til::point Position, const bool TurnOn)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& cursor = _textBuffer->GetCursor();
@@ -1767,9 +1763,9 @@ void SCREEN_INFORMATION::SetCursorDBMode(const bool DoubleCursor)
     return STATUS_SUCCESS;
 }
 
-void SCREEN_INFORMATION::MakeCursorVisible(const COORD CursorPosition)
+void SCREEN_INFORMATION::MakeCursorVisible(const til::point CursorPosition)
 {
-    COORD WindowOrigin;
+    til::point WindowOrigin;
 
     if (CursorPosition.X > _viewport.RightInclusive())
     {
@@ -1949,7 +1945,7 @@ void SCREEN_INFORMATION::_handleDeferredResize(SCREEN_INFORMATION& siMain)
     }
     else if (siMain._deferredPtyResize.has_value())
     {
-        const auto newViewSize = siMain._deferredPtyResize.value().to_win32_coord();
+        const auto newViewSize = siMain._deferredPtyResize.value();
         // Tricky! We want to make sure to resize the actual main buffer
         // here, not just change the size of the viewport. When they resized
         // the alt buffer, the dimensions of the alt buffer changed. We
@@ -1973,8 +1969,7 @@ void SCREEN_INFORMATION::_handleDeferredResize(SCREEN_INFORMATION& siMain)
         // From ApiRoutines::SetConsoleScreenBufferInfoExImpl. We don't need
         // the whole call to SetConsoleScreenBufferInfoEx here, that's
         // too much work.
-        if (newBufferSize.X != oldScreenBufferSize.X ||
-            newBufferSize.Y != oldScreenBufferSize.Y)
+        if (newBufferSize != oldScreenBufferSize)
         {
             auto& commandLine = CommandLine::Instance();
             commandLine.Hide(FALSE);
@@ -2303,16 +2298,15 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport,
 {
     const auto oldCursorPos = _textBuffer->GetCursor().GetPosition();
     auto sNewTop = oldCursorPos.Y;
-    const auto oldViewport = _viewport;
 
-    short delta = (sNewTop + _viewport.Height()) - (GetBufferSize().Height());
+    auto delta = (sNewTop + _viewport.Height()) - (GetBufferSize().Height());
     for (auto i = 0; i < delta; i++)
     {
         _textBuffer->IncrementCircularBuffer();
         sNewTop--;
     }
 
-    const COORD coordNewOrigin = { 0, sNewTop };
+    const til::point coordNewOrigin{ 0, sNewTop };
     RETURN_IF_FAILED(SetViewportOrigin(true, coordNewOrigin, true));
 
     // SetViewportOrigin will only move the virtual bottom down, but in this
@@ -2320,7 +2314,7 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport,
     UpdateBottom();
 
     // Place the cursor at the same x coord, on the row that's now the top
-    RETURN_IF_FAILED(SetCursorPosition(COORD{ oldCursorPos.X, sNewTop }, false));
+    RETURN_IF_FAILED(SetCursorPosition({ oldCursorPos.X, sNewTop }, false));
 
     // Update all the rows in the current viewport with the standard erase attributes,
     // i.e. the current background color, but with no meta attributes set.
@@ -2329,8 +2323,8 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport,
 
     // +1 on the y coord because we don't want to clear the attributes of the
     // cursor row, the one we saved.
-    auto fillPosition = COORD{ 0, _viewport.Top() + 1 };
-    auto fillLength = gsl::narrow_cast<size_t>(_viewport.Height() * GetBufferSize().Width());
+    til::point fillPosition{ 0, _viewport.Top() + 1 };
+    auto fillLength = gsl::narrow<size_t>(_viewport.Height() * GetBufferSize().Width());
     auto fillData = OutputCellIterator{ fillAttributes, fillLength };
     Write(fillData, fillPosition, false);
 
@@ -2380,10 +2374,10 @@ OutputCellRect SCREEN_INFORMATION::ReadRect(const Viewport viewport) const
 
     OutputCellRect result(viewport.Height(), viewport.Width());
     const OutputCell paddingCell{ std::wstring_view{ &UNICODE_SPACE, 1 }, {}, GetAttributes() };
-    for (size_t rowIndex = 0; rowIndex < gsl::narrow<size_t>(viewport.Height()); ++rowIndex)
+    for (til::CoordType rowIndex = 0, height = viewport.Height(); rowIndex < height; ++rowIndex)
     {
         auto location = viewport.Origin();
-        location.Y += (SHORT)rowIndex;
+        location.Y += rowIndex;
 
         auto data = GetCellLineDataAt(location);
         const auto span = result.GetRow(rowIndex);
@@ -2439,7 +2433,7 @@ OutputCellIterator SCREEN_INFORMATION::Write(const OutputCellIterator it)
 // Note:
 // - will throw exception on error.
 OutputCellIterator SCREEN_INFORMATION::Write(const OutputCellIterator it,
-                                             const COORD target,
+                                             const til::point target,
                                              const std::optional<bool> wrap)
 {
     // NOTE: if wrap = true/false, we want to set the line's wrap to true/false (respectively) if we reach the end of the line
@@ -2480,15 +2474,15 @@ OutputCellIterator SCREEN_INFORMATION::WriteRect(const OutputCellIterator it,
 // Note:
 // - will throw exception on error.
 void SCREEN_INFORMATION::WriteRect(const OutputCellRect& data,
-                                   const COORD location)
+                                   const til::point location)
 {
-    for (size_t i = 0; i < data.Height(); i++)
+    for (til::CoordType i = 0; i < data.Height(); i++)
     {
         const auto iter = data.GetRowIter(i);
 
-        COORD point;
+        til::point point;
         point.X = location.X;
-        point.Y = location.Y + static_cast<short>(i);
+        point.Y = location.Y + i;
 
         _textBuffer->WriteLine(iter, point);
     }
@@ -2509,7 +2503,7 @@ void SCREEN_INFORMATION::ClearTextData()
 // - position - location on the screen to get the word boundary for
 // Return Value:
 // - word boundary positions
-std::pair<COORD, COORD> SCREEN_INFORMATION::GetWordBoundary(const COORD position) const
+std::pair<til::point, til::point> SCREEN_INFORMATION::GetWordBoundary(const til::point position) const
 {
     // The position argument is in screen coordinates, but we need the
     // equivalent buffer position, taking line rendition into account.
@@ -2601,32 +2595,32 @@ const TextBuffer& SCREEN_INFORMATION::GetTextBuffer() const noexcept
     return *_textBuffer;
 }
 
-TextBufferTextIterator SCREEN_INFORMATION::GetTextDataAt(const COORD at) const
+TextBufferTextIterator SCREEN_INFORMATION::GetTextDataAt(const til::point at) const
 {
     return _textBuffer->GetTextDataAt(at);
 }
 
-TextBufferCellIterator SCREEN_INFORMATION::GetCellDataAt(const COORD at) const
+TextBufferCellIterator SCREEN_INFORMATION::GetCellDataAt(const til::point at) const
 {
     return _textBuffer->GetCellDataAt(at);
 }
 
-TextBufferTextIterator SCREEN_INFORMATION::GetTextLineDataAt(const COORD at) const
+TextBufferTextIterator SCREEN_INFORMATION::GetTextLineDataAt(const til::point at) const
 {
     return _textBuffer->GetTextLineDataAt(at);
 }
 
-TextBufferCellIterator SCREEN_INFORMATION::GetCellLineDataAt(const COORD at) const
+TextBufferCellIterator SCREEN_INFORMATION::GetCellLineDataAt(const til::point at) const
 {
     return _textBuffer->GetCellLineDataAt(at);
 }
 
-TextBufferTextIterator SCREEN_INFORMATION::GetTextDataAt(const COORD at, const Viewport limit) const
+TextBufferTextIterator SCREEN_INFORMATION::GetTextDataAt(const til::point at, const Viewport limit) const
 {
     return _textBuffer->GetTextDataAt(at, limit);
 }
 
-TextBufferCellIterator SCREEN_INFORMATION::GetCellDataAt(const COORD at, const Viewport limit) const
+TextBufferCellIterator SCREEN_INFORMATION::GetCellDataAt(const til::point at, const Viewport limit) const
 {
     return _textBuffer->GetCellDataAt(at, limit);
 }
@@ -2680,7 +2674,7 @@ void SCREEN_INFORMATION::InitializeCursorRowAttributes()
 // - the virtual terminal viewport
 Viewport SCREEN_INFORMATION::GetVirtualViewport() const noexcept
 {
-    const short newTop = _virtualBottom - _viewport.Height() + 1;
+    const auto newTop = _virtualBottom - _viewport.Height() + 1;
     return Viewport::FromDimensions({ _viewport.Left(), newTop }, _viewport.Dimensions());
 }
 
diff --git a/src/host/screenInfo.hpp b/src/host/screenInfo.hpp
index a9d344a3a4f..02043c5884f 100644
--- a/src/host/screenInfo.hpp
+++ b/src/host/screenInfo.hpp
@@ -58,9 +58,9 @@ namespace TerminalCoreUnitTests
 class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console::IIoProvider
 {
 public:
-    [[nodiscard]] static NTSTATUS CreateInstance(_In_ COORD coordWindowSize,
+    [[nodiscard]] static NTSTATUS CreateInstance(_In_ til::size coordWindowSize,
                                                  const FontInfo fontInfo,
-                                                 _In_ COORD coordScreenBufferSize,
+                                                 _In_ til::size coordScreenBufferSize,
                                                  const TextAttribute defaultAttributes,
                                                  const TextAttribute popupAttributes,
                                                  const UINT uiCursorSize,
@@ -68,36 +68,36 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
 
     ~SCREEN_INFORMATION();
 
-    void GetScreenBufferInformation(_Out_ PCOORD pcoordSize,
-                                    _Out_ PCOORD pcoordCursorPosition,
-                                    _Out_ PSMALL_RECT psrWindow,
+    void GetScreenBufferInformation(_Out_ til::size* pcoordSize,
+                                    _Out_ til::point* pcoordCursorPosition,
+                                    _Out_ til::inclusive_rect* psrWindow,
                                     _Out_ PWORD pwAttributes,
-                                    _Out_ PCOORD pcoordMaximumWindowSize,
+                                    _Out_ til::size* pcoordMaximumWindowSize,
                                     _Out_ PWORD pwPopupAttributes,
                                     _Out_writes_(COLOR_TABLE_SIZE) LPCOLORREF lpColorTable) const;
 
-    void GetRequiredConsoleSizeInPixels(_Out_ PSIZE const pRequiredSize) const;
+    void GetRequiredConsoleSizeInPixels(_Out_ til::size* const pRequiredSize) const;
 
     void MakeCurrentCursorVisible();
 
-    void ClipToScreenBuffer(_Inout_ SMALL_RECT* const psrClip) const;
+    void ClipToScreenBuffer(_Inout_ til::inclusive_rect* const psrClip) const;
 
-    COORD GetMinWindowSizeInCharacters(const COORD coordFontSize = { 1, 1 }) const;
-    COORD GetMaxWindowSizeInCharacters(const COORD coordFontSize = { 1, 1 }) const;
-    COORD GetLargestWindowSizeInCharacters(const COORD coordFontSize = { 1, 1 }) const;
-    COORD GetScrollBarSizesInCharacters() const;
+    til::size GetMinWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const;
+    til::size GetMaxWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const;
+    til::size GetLargestWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const;
+    til::size GetScrollBarSizesInCharacters() const;
 
     Microsoft::Console::Types::Viewport GetBufferSize() const;
     Microsoft::Console::Types::Viewport GetTerminalBufferSize() const;
 
-    COORD GetScreenFontSize() const;
+    til::size GetScreenFontSize() const;
     void UpdateFont(const FontInfo* const pfiNewFont);
     void RefreshFontWithRenderer();
 
-    [[nodiscard]] NTSTATUS ResizeScreenBuffer(const COORD coordNewScreenSize, const bool fDoScrollBarUpdate);
+    [[nodiscard]] NTSTATUS ResizeScreenBuffer(const til::size coordNewScreenSize, const bool fDoScrollBarUpdate);
 
     bool HasAccessibilityEventing() const noexcept;
-    void NotifyAccessibilityEventing(const short sStartX, const short sStartY, const short sEndX, const short sEndY);
+    void NotifyAccessibilityEventing(const til::CoordType sStartX, const til::CoordType sStartY, const til::CoordType sEndX, const til::CoordType sEndY);
 
     void UpdateScrollBars();
     void InternalUpdateScrollBars();
@@ -110,11 +110,11 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
     void SetViewport(const Microsoft::Console::Types::Viewport& newViewport, const bool updateBottom);
     Microsoft::Console::Types::Viewport GetVirtualViewport() const noexcept;
 
-    void ProcessResizeWindow(const RECT* const prcClientNew, const RECT* const prcClientOld);
-    void SetViewportSize(const COORD* const pcoordSize);
+    void ProcessResizeWindow(const til::rect* const prcClientNew, const til::rect* const prcClientOld);
+    void SetViewportSize(const til::size* const pcoordSize);
 
     // Forwarders to Window if we're the active buffer.
-    [[nodiscard]] NTSTATUS SetViewportOrigin(const bool fAbsolute, const COORD coordWindowOrigin, const bool updateBottom);
+    [[nodiscard]] NTSTATUS SetViewportOrigin(const bool fAbsolute, const til::point coordWindowOrigin, const bool updateBottom);
 
     bool SendNotifyBeep() const;
     bool PostUpdateWindowSize() const;
@@ -125,28 +125,28 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
 
     OutputCellRect ReadRect(const Microsoft::Console::Types::Viewport location) const;
 
-    TextBufferCellIterator GetCellDataAt(const COORD at) const;
-    TextBufferCellIterator GetCellLineDataAt(const COORD at) const;
-    TextBufferCellIterator GetCellDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
-    TextBufferTextIterator GetTextDataAt(const COORD at) const;
-    TextBufferTextIterator GetTextLineDataAt(const COORD at) const;
-    TextBufferTextIterator GetTextDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
+    TextBufferCellIterator GetCellDataAt(const til::point at) const;
+    TextBufferCellIterator GetCellLineDataAt(const til::point at) const;
+    TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
+    TextBufferTextIterator GetTextDataAt(const til::point at) const;
+    TextBufferTextIterator GetTextLineDataAt(const til::point at) const;
+    TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
 
     OutputCellIterator Write(const OutputCellIterator it);
 
     OutputCellIterator Write(const OutputCellIterator it,
-                             const COORD target,
+                             const til::point target,
                              const std::optional<bool> wrap = true);
 
     OutputCellIterator WriteRect(const OutputCellIterator it,
                                  const Microsoft::Console::Types::Viewport viewport);
 
     void WriteRect(const OutputCellRect& data,
-                   const COORD location);
+                   const til::point location);
 
     void ClearTextData();
 
-    std::pair<COORD, COORD> GetWordBoundary(const COORD position) const;
+    std::pair<til::point, til::point> GetWordBoundary(const til::point position) const;
 
     TextBuffer& GetTextBuffer() noexcept;
     const TextBuffer& GetTextBuffer() const noexcept;
@@ -189,9 +189,9 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
     void SetCursorType(const CursorType Type, const bool setMain = false) noexcept;
 
     void SetCursorDBMode(const bool DoubleCursor);
-    [[nodiscard]] NTSTATUS SetCursorPosition(const COORD Position, const bool TurnOn);
+    [[nodiscard]] NTSTATUS SetCursorPosition(const til::point Position, const bool TurnOn);
 
-    void MakeCursorVisible(const COORD CursorPosition);
+    void MakeCursorVisible(const til::point CursorPosition);
 
     Microsoft::Console::Types::Viewport GetRelativeScrollMargins() const;
     Microsoft::Console::Types::Viewport GetAbsoluteScrollMargins() const;
@@ -240,22 +240,22 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
     Microsoft::Console::Interactivity::IWindowMetrics* _pConsoleWindowMetrics;
     Microsoft::Console::Interactivity::IAccessibilityNotifier* _pAccessibilityNotifier;
 
-    [[nodiscard]] HRESULT _AdjustScreenBufferHelper(const RECT* const prcClientNew,
-                                                    const COORD coordBufferOld,
-                                                    _Out_ COORD* const pcoordClientNewCharacters);
-    [[nodiscard]] HRESULT _AdjustScreenBuffer(const RECT* const prcClientNew);
-    void _CalculateViewportSize(const RECT* const prcClientArea, _Out_ COORD* const pcoordSize);
-    void _AdjustViewportSize(const RECT* const prcClientNew, const RECT* const prcClientOld, const COORD* const pcoordSize);
-    void _InternalSetViewportSize(const COORD* const pcoordSize, const bool fResizeFromTop, const bool fResizeFromLeft);
-
-    static void s_CalculateScrollbarVisibility(const RECT* const prcClientArea,
-                                               const COORD* const pcoordBufferSize,
-                                               const COORD* const pcoordFontSize,
+    [[nodiscard]] HRESULT _AdjustScreenBufferHelper(const til::rect* const prcClientNew,
+                                                    const til::size coordBufferOld,
+                                                    _Out_ til::size* const pcoordClientNewCharacters);
+    [[nodiscard]] HRESULT _AdjustScreenBuffer(const til::rect* const prcClientNew);
+    void _CalculateViewportSize(const til::rect* const prcClientArea, _Out_ til::size* const pcoordSize);
+    void _AdjustViewportSize(const til::rect* const prcClientNew, const til::rect* const prcClientOld, const til::size* const pcoordSize);
+    void _InternalSetViewportSize(const til::size* pcoordSize, const bool fResizeFromTop, const bool fResizeFromLeft);
+
+    static void s_CalculateScrollbarVisibility(const til::rect* const prcClientArea,
+                                               const til::size* const pcoordBufferSize,
+                                               const til::size* const pcoordFontSize,
                                                _Out_ bool* const pfIsHorizontalVisible,
                                                _Out_ bool* const pfIsVerticalVisible);
 
-    [[nodiscard]] NTSTATUS ResizeWithReflow(const COORD coordnewScreenSize);
-    [[nodiscard]] NTSTATUS ResizeTraditional(const COORD coordNewScreenSize);
+    [[nodiscard]] NTSTATUS ResizeWithReflow(const til::size coordnewScreenSize);
+    [[nodiscard]] NTSTATUS ResizeTraditional(const til::size coordNewScreenSize);
 
     [[nodiscard]] NTSTATUS _InitializeOutputStateMachine();
     void _FreeOutputStateMachine();
@@ -279,8 +279,8 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
     SCREEN_INFORMATION* _psiAlternateBuffer; // The VT "Alternate" screen buffer.
     SCREEN_INFORMATION* _psiMainBuffer; // A pointer to the main buffer, if this is the alternate buffer.
 
-    RECT _rcAltSavedClientNew;
-    RECT _rcAltSavedClientOld;
+    til::rect _rcAltSavedClientNew;
+    til::rect _rcAltSavedClientOld;
     bool _fAltWindowChanged;
 
     TextAttribute _PopupAttributes;
@@ -291,7 +291,7 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
     // Tracks the last virtual position the viewport was at. This is not
     //  affected by the user scrolling the viewport, only when API calls cause
     //  the viewport to move (SetBufferInfo, WriteConsole, etc)
-    short _virtualBottom;
+    til::CoordType _virtualBottom;
 
     bool _ignoreLegacyEquivalentVTAttributes;
 
diff --git a/src/host/scrolling.cpp b/src/host/scrolling.cpp
index f3e01537fae..6d211a0fd3d 100644
--- a/src/host/scrolling.cpp
+++ b/src/host/scrolling.cpp
@@ -66,26 +66,26 @@ void Scrolling::s_ScrollIfNecessary(const SCREEN_INFORMATION& ScreenInfo)
 
     if (pSelection->IsInSelectingState() && pSelection->IsMouseButtonDown())
     {
-        POINT CursorPos;
+        til::point CursorPos;
         if (!pWindow->GetCursorPosition(&CursorPos))
         {
             return;
         }
 
-        RECT ClientRect;
+        til::rect ClientRect;
         if (!pWindow->GetClientRectangle(&ClientRect))
         {
             return;
         }
 
-        pWindow->MapPoints((LPPOINT)&ClientRect, 2);
+        pWindow->MapRect(&ClientRect);
         if (!(s_IsPointInRectangle(&ClientRect, CursorPos)))
         {
             pWindow->ConvertScreenToClient(&CursorPos);
 
-            COORD MousePosition;
-            MousePosition.X = (SHORT)CursorPos.x;
-            MousePosition.Y = (SHORT)CursorPos.y;
+            til::point MousePosition;
+            MousePosition.X = CursorPos.x;
+            MousePosition.Y = CursorPos.y;
 
             auto coordFontSize = ScreenInfo.GetScreenFontSize();
 
@@ -131,10 +131,10 @@ void Scrolling::s_HandleMouseWheel(_In_ bool isMouseWheel,
             * screen size. A ScrollScale of 1 indicates 1/2 the screen
             * size. This value can be modified in the registry.
             */
-            SHORT delta = 1;
+            til::CoordType delta = 1;
             if (hasShift)
             {
-                delta = gsl::narrow<SHORT>(std::max((ScreenInfo.GetViewport().Height() * ScreenInfo.ScrollScale) / 2, 1u));
+                delta = std::max((ScreenInfo.GetViewport().Height() * ScreenInfo.ScrollScale) / 2, 1u);
 
                 // Account for scroll direction changes by adjusting delta if there was a direction change.
                 delta *= (ScreenInfo.WheelDelta < 0 ? -1 : 1);
@@ -142,7 +142,7 @@ void Scrolling::s_HandleMouseWheel(_In_ bool isMouseWheel,
             }
             else
             {
-                delta *= (ScreenInfo.WheelDelta / (short)ulActualDelta);
+                delta *= (ScreenInfo.WheelDelta / ulActualDelta);
                 ScreenInfo.WheelDelta %= ulActualDelta;
             }
 
@@ -174,14 +174,14 @@ void Scrolling::s_HandleMouseWheel(_In_ bool isMouseWheel,
 
         if ((ULONG)abs(ScreenInfo.HWheelDelta) >= ulActualDelta)
         {
-            SHORT delta = 1;
+            til::CoordType delta = 1;
 
             if (hasShift)
             {
-                delta = std::max(ScreenInfo.GetViewport().RightInclusive(), 1i16);
+                delta = std::max(ScreenInfo.GetViewport().RightInclusive(), 1);
             }
 
-            delta *= (ScreenInfo.HWheelDelta / (short)ulActualDelta);
+            delta *= (ScreenInfo.HWheelDelta / ulActualDelta);
             ScreenInfo.HWheelDelta %= ulActualDelta;
 
             NewOrigin.X += delta;
@@ -326,7 +326,7 @@ bool Scrolling::s_HandleKeyScrollingEvent(const INPUT_KEY_INFO* const pKeyInfo)
     return true;
 }
 
-BOOL Scrolling::s_IsPointInRectangle(const RECT* const prc, const POINT pt)
+BOOL Scrolling::s_IsPointInRectangle(const til::rect* prc, const til::point pt)
 {
     return ((pt.x >= prc->left) && (pt.x < prc->right) &&
             (pt.y >= prc->top) && (pt.y < prc->bottom));
diff --git a/src/host/scrolling.hpp b/src/host/scrolling.hpp
index 71b10cc42e9..a082fa21a15 100644
--- a/src/host/scrolling.hpp
+++ b/src/host/scrolling.hpp
@@ -39,7 +39,7 @@ class Scrolling
     static bool s_HandleKeyScrollingEvent(const INPUT_KEY_INFO* const pKeyInfo);
 
 private:
-    static BOOL s_IsPointInRectangle(const RECT* const prc, const POINT pt);
+    static BOOL s_IsPointInRectangle(const til::rect* prc, const til::point pt);
 
     static ULONG s_ucWheelScrollLines;
     static ULONG s_ucWheelScrollChars;
diff --git a/src/host/selection.cpp b/src/host/selection.cpp
index 70ec0336f46..d528d0e49e3 100644
--- a/src/host/selection.cpp
+++ b/src/host/selection.cpp
@@ -38,14 +38,14 @@ Selection& Selection::Instance()
 // Arguments:
 // - <none> - Uses internal state to know what area is selected already.
 // Return Value:
-// - Returns a vector where each SMALL_RECT is one Row worth of the area to be selected.
+// - Returns a vector where each til::inclusive_rect is one Row worth of the area to be selected.
 // - Returns empty vector if no rows are selected.
 // - Throws exceptions for out of memory issues
-std::vector<SMALL_RECT> Selection::GetSelectionRects() const
+std::vector<til::inclusive_rect> Selection::GetSelectionRects() const
 {
     if (!_fSelectionVisible)
     {
-        return std::vector<SMALL_RECT>();
+        return std::vector<til::inclusive_rect>();
     }
 
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
@@ -53,7 +53,7 @@ std::vector<SMALL_RECT> Selection::GetSelectionRects() const
 
     // _coordSelectionAnchor is at one of the corners of _srSelectionRects
     // endSelectionAnchor is at the exact opposite corner
-    COORD endSelectionAnchor;
+    til::point endSelectionAnchor;
     endSelectionAnchor.X = (_coordSelectionAnchor.X == _srSelectionRect.Left) ? _srSelectionRect.Right : _srSelectionRect.Left;
     endSelectionAnchor.Y = (_coordSelectionAnchor.Y == _srSelectionRect.Top) ? _srSelectionRect.Bottom : _srSelectionRect.Top;
 
@@ -129,7 +129,7 @@ void Selection::_PaintSelection() const
 // - coordBufferPos - Position in which user started a selection
 // Return Value:
 // - <none>
-void Selection::InitializeMouseSelection(const COORD coordBufferPos)
+void Selection::InitializeMouseSelection(const til::point coordBufferPos)
 {
     Scrolling::s_ClearScroll();
 
@@ -174,7 +174,7 @@ void Selection::InitializeMouseSelection(const COORD coordBufferPos)
 // - coordSelectionEnd - The linear final position or opposite corner of the anchor to represent the complete selection area.
 // Return Value:
 // - <none>
-void Selection::AdjustSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd)
+void Selection::AdjustSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd)
 {
     // modify the anchor and then just use extend to adjust the other portion of the selection rectangle
     _coordSelectionAnchor = coordSelectionStart;
@@ -189,7 +189,7 @@ void Selection::AdjustSelection(const COORD coordSelectionStart, const COORD coo
 // - coordBufferPos - Position to extend/contract the current selection up to.
 // Return Value:
 // - <none>
-void Selection::ExtendSelection(_In_ COORD coordBufferPos)
+void Selection::ExtendSelection(_In_ til::point coordBufferPos)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& screenInfo = gci.GetActiveOutputBuffer();
@@ -388,18 +388,18 @@ void Selection::ClearSelection(const bool fStartingNewSelection)
 // Arguments:
 // - psrRect - Rectangular area to fill with color
 // - attr - The color attributes to apply
-void Selection::ColorSelection(const SMALL_RECT& srRect, const TextAttribute attr)
+void Selection::ColorSelection(const til::inclusive_rect& srRect, const TextAttribute attr)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
     // Read selection rectangle, assumed already clipped to buffer.
     auto& screenInfo = gci.GetActiveOutputBuffer();
 
-    COORD coordTargetSize;
+    til::point coordTargetSize;
     coordTargetSize.X = CalcWindowSizeX(srRect);
     coordTargetSize.Y = CalcWindowSizeY(srRect);
 
-    COORD coordTarget;
+    til::point coordTarget;
     coordTarget.X = srRect.Left;
     coordTarget.Y = srRect.Top;
 
@@ -424,7 +424,7 @@ void Selection::ColorSelection(const SMALL_RECT& srRect, const TextAttribute att
 // - coordSelectionStart - Anchor point (start of selection) for the region to be colored
 // - coordSelectionEnd - Other point referencing the rectangle inscribing the selection area
 // - attr - Color to apply to region.
-void Selection::ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr)
+void Selection::ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute attr)
 {
     // Extract row-by-row selection rectangles for the selection area.
     try
@@ -489,7 +489,7 @@ void Selection::InitializeMarkSelection()
 // - coordEnd - Position to select up to
 // Return Value:
 // - <none>
-void Selection::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
+void Selection::SelectNewRegion(const til::point coordStart, const til::point coordEnd)
 {
     // clear existing selection if applicable
     ClearSelection();
@@ -525,13 +525,13 @@ void Selection::SelectAll()
     const auto coordOldAnchor = _coordSelectionAnchor;
 
     // Attempt to get the boundaries of the current input line.
-    COORD coordInputStart;
-    COORD coordInputEnd;
+    til::point coordInputStart;
+    til::point coordInputEnd;
     const auto fHasInputArea = s_GetInputLineBoundaries(&coordInputStart, &coordInputEnd);
 
     // These variables will be used to specify the new selection area when we're done
-    COORD coordNewSelStart;
-    COORD coordNewSelEnd;
+    til::point coordNewSelStart;
+    til::point coordNewSelEnd;
 
     // Now evaluate conditions and attempt to assign a new selection area.
     if (!fHasInputArea)
diff --git a/src/host/selection.hpp b/src/host/selection.hpp
index 9993454e15f..5edb37cd4d8 100644
--- a/src/host/selection.hpp
+++ b/src/host/selection.hpp
@@ -28,7 +28,7 @@ class Selection
 public:
     ~Selection() = default;
 
-    std::vector<SMALL_RECT> GetSelectionRects() const;
+    std::vector<til::inclusive_rect> GetSelectionRects() const;
 
     void ShowSelection();
     void HideSelection();
@@ -47,18 +47,18 @@ class Selection
     // navigation.
 
     void InitializeMarkSelection();
-    void InitializeMouseSelection(const COORD coordBufferPos);
+    void InitializeMouseSelection(const til::point coordBufferPos);
 
-    void SelectNewRegion(const COORD coordStart, const COORD coordEnd);
+    void SelectNewRegion(const til::point coordStart, const til::point coordEnd);
     void SelectAll();
 
-    void ExtendSelection(_In_ COORD coordBufferPos);
-    void AdjustSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd);
+    void ExtendSelection(_In_ til::point coordBufferPos);
+    void AdjustSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd);
 
     void ClearSelection();
     void ClearSelection(const bool fStartingNewSelection);
-    void ColorSelection(const SMALL_RECT& srRect, const TextAttribute attr);
-    void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
+    void ColorSelection(const til::inclusive_rect& srRect, const TextAttribute attr);
+    void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute attr);
 
     // delete these or we can accidentally get copies of the singleton
     Selection(const Selection&) = delete;
@@ -98,18 +98,18 @@ class Selection
     void CheckAndSetAlternateSelection();
 
     // calculation functions
-    [[nodiscard]] static bool s_GetInputLineBoundaries(_Out_opt_ COORD* const pcoordInputStart, _Out_opt_ COORD* const pcoordInputEnd);
-    void GetValidAreaBoundaries(_Out_opt_ COORD* const pcoordValidStart, _Out_opt_ COORD* const pcoordValidEnd) const;
-    static bool s_IsWithinBoundaries(const COORD coordPosition, const COORD coordStart, const COORD coordEnd);
+    [[nodiscard]] static bool s_GetInputLineBoundaries(_Out_opt_ til::point* const pcoordInputStart, _Out_opt_ til::point* const pcoordInputEnd);
+    void GetValidAreaBoundaries(_Out_opt_ til::point* const pcoordValidStart, _Out_opt_ til::point* const pcoordValidEnd) const;
+    static bool s_IsWithinBoundaries(const til::point coordPosition, const til::point coordStart, const til::point coordEnd);
 
 private:
     // key handling
     bool _HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo);
     bool _HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKeyInfo);
-    COORD WordByWordSelection(const bool fPrevious,
-                              const Microsoft::Console::Types::Viewport& bufferSize,
-                              const COORD coordAnchor,
-                              const COORD coordSelPoint) const;
+    til::point WordByWordSelection(const bool fPrevious,
+                                   const Microsoft::Console::Types::Viewport& bufferSize,
+                                   const til::point coordAnchor,
+                                   const til::point coordSelPoint) const;
 
     // -------------------------------------------------------------------------------------------------------
     // selection state (selectionState.cpp)
@@ -126,12 +126,12 @@ class Selection
     bool IsMouseButtonDown() const;
 
     DWORD GetPublicSelectionFlags() const noexcept;
-    COORD GetSelectionAnchor() const noexcept;
-    SMALL_RECT GetSelectionRectangle() const noexcept;
+    til::point GetSelectionAnchor() const noexcept;
+    til::inclusive_rect GetSelectionRectangle() const noexcept;
 
     void SetLineSelection(const bool fLineSelectionOn);
 
-    bool ShouldAllowMouseDragSelection(const COORD mousePosition) const noexcept;
+    bool ShouldAllowMouseDragSelection(const til::point mousePosition) const noexcept;
 
     // TODO: these states likely belong somewhere else
     void MouseDown();
@@ -165,13 +165,13 @@ class Selection
 
     // -- Current Selection Data --
     // Anchor is the point the selection was started from (and will be one of the corners of the rectangle).
-    COORD _coordSelectionAnchor;
+    til::point _coordSelectionAnchor;
     // Rectangle is the area inscribing the selection. It is extended to screen edges in a particular way for line selection.
-    SMALL_RECT _srSelectionRect;
+    til::inclusive_rect _srSelectionRect;
 
     // -- Saved Cursor Data --
     // Saved when a selection is started for restoration later. Position is in character coordinates, not pixels.
-    COORD _coordSavedCursorPosition;
+    til::point _coordSavedCursorPosition;
     ULONG _ulSavedCursorSize;
     bool _fSavedCursorVisible;
     CursorType _savedCursorType;
diff --git a/src/host/selectionInput.cpp b/src/host/selectionInput.cpp
index 490718d7255..115911eb84d 100644
--- a/src/host/selectionInput.cpp
+++ b/src/host/selectionInput.cpp
@@ -140,10 +140,10 @@ bool Selection::s_IsValidKeyboardLineSelection(const INPUT_KEY_INFO* const pInpu
 // - coordSelPoint: Defines selection region from coordAnchor to this point. Modified to define the new selection region.
 // Return Value:
 // - <none>
-COORD Selection::WordByWordSelection(const bool fReverse,
-                                     const Viewport& bufferSize,
-                                     const COORD coordAnchor,
-                                     const COORD coordSelPoint) const
+til::point Selection::WordByWordSelection(const bool fReverse,
+                                          const Viewport& bufferSize,
+                                          const til::point coordAnchor,
+                                          const til::point coordSelPoint) const
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto& screenInfo = gci.GetActiveOutputBuffer();
@@ -167,8 +167,8 @@ COORD Selection::WordByWordSelection(const bool fReverse,
     bool fPrevIsDelim;
 
     // find the edit-line boundaries that we can highlight
-    COORD coordMaxLeft;
-    COORD coordMaxRight;
+    til::point coordMaxLeft;
+    til::point coordMaxRight;
     const auto fSuccess = s_GetInputLineBoundaries(&coordMaxLeft, &coordMaxRight);
 
     // if line boundaries fail, then set them to the buffer corners so they don't restrict anything.
@@ -324,7 +324,7 @@ bool Selection::HandleKeyboardLineSelectionEvent(const INPUT_KEY_INFO* const pIn
     const auto rectSelection = _srSelectionRect;
 
     // the selection point is the other corner of the rectangle from the anchor that we're about to manipulate
-    COORD coordSelPoint;
+    til::point coordSelPoint;
     coordSelPoint.X = coordAnchor.X == rectSelection.Left ? rectSelection.Right : rectSelection.Left;
     coordSelPoint.Y = coordAnchor.Y == rectSelection.Top ? rectSelection.Bottom : rectSelection.Top;
 
@@ -338,8 +338,8 @@ bool Selection::HandleKeyboardLineSelectionEvent(const INPUT_KEY_INFO* const pIn
     // retrieve input line information. If we are selecting from within the input line, we need
     // to bound ourselves within the input data first and not move into the back buffer.
 
-    COORD coordInputLineStart;
-    COORD coordInputLineEnd;
+    til::point coordInputLineStart;
+    til::point coordInputLineEnd;
     auto fHaveInputLine = s_GetInputLineBoundaries(&coordInputLineStart, &coordInputLineEnd);
 
     if (pInputKeyInfo->IsShiftOnly())
@@ -499,7 +499,7 @@ bool Selection::HandleKeyboardLineSelectionEvent(const INPUT_KEY_INFO* const pIn
                     if (coordInputLineStart.Y == coordSelPoint.Y)
                     {
                         // calculate the end of the outside/output buffer position
-                        const short sEndOfOutputPos = coordInputLineStart.X - 1;
+                        const auto sEndOfOutputPos = coordInputLineStart.X - 1;
 
                         // if we're not already on the very last character...
                         if (coordSelPoint.X < sEndOfOutputPos)
@@ -564,14 +564,14 @@ bool Selection::HandleKeyboardLineSelectionEvent(const INPUT_KEY_INFO* const pIn
             // shift + ctrl + home/end extends selection to top or bottom of buffer from selection
         case VK_HOME:
         {
-            COORD coordValidStart;
+            til::point coordValidStart;
             GetValidAreaBoundaries(&coordValidStart, nullptr);
             coordSelPoint = coordValidStart;
             break;
         }
         case VK_END:
         {
-            COORD coordValidEnd;
+            til::point coordValidEnd;
             GetValidAreaBoundaries(nullptr, &coordValidEnd);
             coordSelPoint = coordValidEnd;
             break;
@@ -693,12 +693,12 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo)
                     std::wstring str;
                     for (const auto& selectRect : selectionRects)
                     {
-                        auto it = screenInfo.GetCellDataAt(COORD{ selectRect.Left, selectRect.Top });
+                        auto it = screenInfo.GetCellDataAt({ selectRect.Left, selectRect.Top });
 
-                        for (SHORT i = 0; i < (selectRect.Right - selectRect.Left + 1);)
+                        for (til::CoordType i = 0; i < (selectRect.Right - selectRect.Left + 1);)
                         {
                             str.append(it->Chars());
-                            i += gsl::narrow_cast<SHORT>(it->Columns());
+                            i += it->Columns();
                             it += it->Columns();
                         }
                     }
@@ -756,8 +756,8 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
     {
         auto& ScreenInfo = gci.GetActiveOutputBuffer();
         auto& textBuffer = ScreenInfo.GetTextBuffer();
-        SHORT iNextRightX = 0;
-        SHORT iNextLeftX = 0;
+        til::CoordType iNextRightX = 0;
+        til::CoordType iNextLeftX = 0;
 
         const auto cursorPos = textBuffer.GetCursor().GetPosition();
 
@@ -877,7 +877,7 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
 
             if (pInputKeyInfo->IsCtrlPressed())
             {
-                COORD coordValidEnd;
+                til::point coordValidEnd;
                 GetValidAreaBoundaries(nullptr, &coordValidEnd);
 
                 // Adjust Y position of cursor to the final line with valid text
@@ -946,7 +946,7 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
 // - pcoordInputEnd - Position of the last character in the input line
 // Return Value:
 // - If true, the boundaries returned are valid. If false, they should be discarded.
-[[nodiscard]] bool Selection::s_GetInputLineBoundaries(_Out_opt_ COORD* const pcoordInputStart, _Out_opt_ COORD* const pcoordInputEnd)
+[[nodiscard]] bool Selection::s_GetInputLineBoundaries(_Out_opt_ til::point* const pcoordInputStart, _Out_opt_ til::point* const pcoordInputEnd)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto bufferSize = gci.GetActiveOutputBuffer().GetBufferSize();
@@ -974,7 +974,7 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
     else
     {
         // otherwise, we need to add the number of characters in the input line to the original cursor position
-        bufferSize.MoveInBounds(cookedRead.VisibleCharCount(), coordEnd);
+        bufferSize.MoveInBounds(gsl::narrow<til::CoordType>(cookedRead.VisibleCharCount()), coordEnd);
     }
 
     // - 1 so the coordinate is on top of the last position of the text, not one past it.
@@ -988,8 +988,7 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
 
     if (pcoordInputEnd != nullptr)
     {
-        pcoordInputEnd->X = coordEnd.X;
-        pcoordInputEnd->Y = coordEnd.Y;
+        *pcoordInputEnd = coordEnd;
     }
 
     return true;
@@ -1003,10 +1002,10 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
 // - pcoordInputEnd - Position of the last character in the buffer
 // Return Value:
 // - If true, the boundaries returned are valid. If false, they should be discarded.
-void Selection::GetValidAreaBoundaries(_Out_opt_ COORD* const pcoordValidStart, _Out_opt_ COORD* const pcoordValidEnd) const
+void Selection::GetValidAreaBoundaries(_Out_opt_ til::point* const pcoordValidStart, _Out_opt_ til::point* const pcoordValidEnd) const
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
-    COORD coordEnd;
+    til::point coordEnd;
     coordEnd.X = 0;
     coordEnd.Y = 0;
 
@@ -1047,7 +1046,7 @@ void Selection::GetValidAreaBoundaries(_Out_opt_ COORD* const pcoordValidStart,
 // - coordSecond - The end or right most edge of the regional boundary.
 // Return Value:
 // - True if it's within the bounds (inclusive). False otherwise.
-bool Selection::s_IsWithinBoundaries(const COORD coordPosition, const COORD coordStart, const COORD coordEnd)
+bool Selection::s_IsWithinBoundaries(const til::point coordPosition, const til::point coordStart, const til::point coordEnd)
 {
     auto fInBoundaries = false;
 
diff --git a/src/host/selectionState.cpp b/src/host/selectionState.cpp
index 0bf11b61e57..a630b490e14 100644
--- a/src/host/selectionState.cpp
+++ b/src/host/selectionState.cpp
@@ -192,7 +192,7 @@ void Selection::_RestoreDataToCursor(Cursor& cursor) noexcept
 // - none
 // Return Value:
 // - current selection anchor
-COORD Selection::GetSelectionAnchor() const noexcept
+til::point Selection::GetSelectionAnchor() const noexcept
 {
     return _coordSelectionAnchor;
 }
@@ -203,7 +203,7 @@ COORD Selection::GetSelectionAnchor() const noexcept
 // - none
 // Return Value:
 // - The rectangle to fill with selection data.
-SMALL_RECT Selection::GetSelectionRectangle() const noexcept
+til::inclusive_rect Selection::GetSelectionRectangle() const noexcept
 {
     return _srSelectionRect;
 }
@@ -248,7 +248,7 @@ void Selection::SetLineSelection(const bool fLineSelectionOn)
 // - mousePosition - current mouse position
 // Return Value:
 // - true if the selection can be changed by a mouse drag
-bool Selection::ShouldAllowMouseDragSelection(const COORD mousePosition) const noexcept
+bool Selection::ShouldAllowMouseDragSelection(const til::point mousePosition) const noexcept
 {
     const auto viewport = Viewport::FromInclusive(_srSelectionRect);
     const auto selectionContainsMouse = viewport.IsInBounds(mousePosition);
diff --git a/src/host/settings.cpp b/src/host/settings.cpp
index a5a03542dca..863b3786e3e 100644
--- a/src/host/settings.cpp
+++ b/src/host/settings.cpp
@@ -558,44 +558,44 @@ void Settings::SetReserved(const WORD wReserved)
     _wReserved = wReserved;
 }
 
-COORD Settings::GetScreenBufferSize() const
+til::size Settings::GetScreenBufferSize() const
 {
-    return _dwScreenBufferSize;
+    return til::wrap_coord_size(_dwScreenBufferSize);
 }
-void Settings::SetScreenBufferSize(const COORD dwScreenBufferSize)
+void Settings::SetScreenBufferSize(const til::size dwScreenBufferSize)
 {
-    _dwScreenBufferSize = dwScreenBufferSize;
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(dwScreenBufferSize, _dwScreenBufferSize));
 }
 
-COORD Settings::GetWindowSize() const
+til::size Settings::GetWindowSize() const
 {
-    return _dwWindowSize;
+    return til::wrap_coord_size(_dwWindowSize);
 }
-void Settings::SetWindowSize(const COORD dwWindowSize)
+void Settings::SetWindowSize(const til::size dwWindowSize)
 {
-    _dwWindowSize = dwWindowSize;
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(dwWindowSize, _dwWindowSize));
 }
 
 bool Settings::IsWindowSizePixelsValid() const
 {
     return _fUseWindowSizePixels;
 }
-COORD Settings::GetWindowSizePixels() const
+til::size Settings::GetWindowSizePixels() const
 {
-    return _dwWindowSizePixels;
+    return til::wrap_coord_size(_dwWindowSizePixels);
 }
-void Settings::SetWindowSizePixels(const COORD dwWindowSizePixels)
+void Settings::SetWindowSizePixels(const til::size dwWindowSizePixels)
 {
-    _dwWindowSizePixels = dwWindowSizePixels;
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(dwWindowSizePixels, _dwWindowSizePixels));
 }
 
-COORD Settings::GetWindowOrigin() const
+til::size Settings::GetWindowOrigin() const
 {
-    return _dwWindowOrigin;
+    return til::wrap_coord_size(_dwWindowOrigin);
 }
-void Settings::SetWindowOrigin(const COORD dwWindowOrigin)
+void Settings::SetWindowOrigin(const til::size dwWindowOrigin)
 {
-    _dwWindowOrigin = dwWindowOrigin;
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(dwWindowOrigin, _dwWindowOrigin));
 }
 
 DWORD Settings::GetFont() const
@@ -607,13 +607,13 @@ void Settings::SetFont(const DWORD nFont)
     _nFont = nFont;
 }
 
-COORD Settings::GetFontSize() const
+til::size Settings::GetFontSize() const
 {
-    return _dwFontSize;
+    return til::wrap_coord_size(_dwFontSize);
 }
-void Settings::SetFontSize(const COORD dwFontSize)
+void Settings::SetFontSize(const til::size dwFontSize)
 {
-    _dwFontSize = dwFontSize;
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(dwFontSize, _dwFontSize));
 }
 
 UINT Settings::GetFontFamily() const
diff --git a/src/host/settings.hpp b/src/host/settings.hpp
index e8c4d0b61bf..bb79bfcf951 100644
--- a/src/host/settings.hpp
+++ b/src/host/settings.hpp
@@ -113,24 +113,24 @@ class Settings
     WORD GetReserved() const;
     void SetReserved(const WORD wReserved);
 
-    COORD GetScreenBufferSize() const;
-    void SetScreenBufferSize(const COORD dwScreenBufferSize);
+    til::size GetScreenBufferSize() const;
+    void SetScreenBufferSize(const til::size dwScreenBufferSize);
 
-    COORD GetWindowSize() const;
-    void SetWindowSize(const COORD dwWindowSize);
+    til::size GetWindowSize() const;
+    void SetWindowSize(const til::size dwWindowSize);
 
     bool IsWindowSizePixelsValid() const;
-    COORD GetWindowSizePixels() const;
-    void SetWindowSizePixels(const COORD dwWindowSizePixels);
+    til::size GetWindowSizePixels() const;
+    void SetWindowSizePixels(const til::size dwWindowSizePixels);
 
-    COORD GetWindowOrigin() const;
-    void SetWindowOrigin(const COORD dwWindowOrigin);
+    til::size GetWindowOrigin() const;
+    void SetWindowOrigin(const til::size dwWindowOrigin);
 
     DWORD GetFont() const;
     void SetFont(const DWORD dwFont);
 
-    COORD GetFontSize() const;
-    void SetFontSize(const COORD dwFontSize);
+    til::size GetFontSize() const;
+    void SetFontSize(const til::size dwFontSize);
 
     UINT GetFontFamily() const;
     void SetFontFamily(const UINT uFontFamily);
diff --git a/src/host/srvinit.cpp b/src/host/srvinit.cpp
index f963999341a..c7a84116a5e 100644
--- a/src/host/srvinit.cpp
+++ b/src/host/srvinit.cpp
@@ -763,9 +763,9 @@ PWSTR TranslateConsoleTitle(_In_ PCWSTR pwszConsoleTitle, const BOOL fUnexpand,
     Cac->ConsoleInfo.SetStartupFlags(Data.StartupFlags);
     Cac->ConsoleInfo.SetFillAttribute(Data.FillAttribute);
     Cac->ConsoleInfo.SetShowWindow(Data.ShowWindow);
-    Cac->ConsoleInfo.SetScreenBufferSize(Data.ScreenBufferSize);
-    Cac->ConsoleInfo.SetWindowSize(Data.WindowSize);
-    Cac->ConsoleInfo.SetWindowOrigin(Data.WindowOrigin);
+    Cac->ConsoleInfo.SetScreenBufferSize(til::wrap_coord_size(Data.ScreenBufferSize));
+    Cac->ConsoleInfo.SetWindowSize(til::wrap_coord_size(Data.WindowSize));
+    Cac->ConsoleInfo.SetWindowOrigin(til::wrap_coord_size(Data.WindowOrigin));
     Cac->ProcessGroupId = Data.ProcessGroupId;
     Cac->ConsoleApp = Data.ConsoleApp;
     Cac->WindowVisible = Data.WindowVisible;
diff --git a/src/host/stream.cpp b/src/host/stream.cpp
index ab6030f96b0..3091c7a1fd4 100644
--- a/src/host/stream.cpp
+++ b/src/host/stream.cpp
@@ -182,18 +182,18 @@ using Microsoft::Console::Interactivity::ServiceLocator;
 
 // Routine Description:
 // - This routine returns the total number of screen spaces the characters up to the specified character take up.
-size_t RetrieveTotalNumberOfSpaces(const SHORT sOriginalCursorPositionX,
-                                   _In_reads_(ulCurrentPosition) const WCHAR* const pwchBuffer,
-                                   _In_ size_t ulCurrentPosition)
+til::CoordType RetrieveTotalNumberOfSpaces(const til::CoordType sOriginalCursorPositionX,
+                                           _In_reads_(ulCurrentPosition) const WCHAR* const pwchBuffer,
+                                           _In_ size_t ulCurrentPosition)
 {
     auto XPosition = sOriginalCursorPositionX;
-    size_t NumSpaces = 0;
+    til::CoordType NumSpaces = 0;
 
     for (size_t i = 0; i < ulCurrentPosition; i++)
     {
         const auto Char = pwchBuffer[i];
 
-        size_t NumSpacesForChar;
+        til::CoordType NumSpacesForChar;
         if (Char == UNICODE_TAB)
         {
             NumSpacesForChar = NUMBER_OF_SPACES_IN_TAB(XPosition);
@@ -210,7 +210,7 @@ size_t RetrieveTotalNumberOfSpaces(const SHORT sOriginalCursorPositionX,
         {
             NumSpacesForChar = 1;
         }
-        XPosition = (SHORT)(XPosition + NumSpacesForChar);
+        XPosition += NumSpacesForChar;
         NumSpaces += NumSpacesForChar;
     }
 
@@ -219,14 +219,14 @@ size_t RetrieveTotalNumberOfSpaces(const SHORT sOriginalCursorPositionX,
 
 // Routine Description:
 // - This routine returns the number of screen spaces the specified character takes up.
-size_t RetrieveNumberOfSpaces(_In_ SHORT sOriginalCursorPositionX,
-                              _In_reads_(ulCurrentPosition + 1) const WCHAR* const pwchBuffer,
-                              _In_ size_t ulCurrentPosition)
+til::CoordType RetrieveNumberOfSpaces(_In_ til::CoordType sOriginalCursorPositionX,
+                                      _In_reads_(ulCurrentPosition + 1) const WCHAR* const pwchBuffer,
+                                      _In_ size_t ulCurrentPosition)
 {
     auto Char = pwchBuffer[ulCurrentPosition];
     if (Char == UNICODE_TAB)
     {
-        size_t NumSpaces = 0;
+        til::CoordType NumSpaces = 0;
         auto XPosition = sOriginalCursorPositionX;
 
         for (size_t i = 0; i <= ulCurrentPosition; i++)
@@ -248,7 +248,7 @@ size_t RetrieveNumberOfSpaces(_In_ SHORT sOriginalCursorPositionX,
             {
                 NumSpaces = 1;
             }
-            XPosition = (SHORT)(XPosition + NumSpaces);
+            XPosition += NumSpaces;
         }
 
         return NumSpaces;
diff --git a/src/host/stream.h b/src/host/stream.h
index d65622c8b4d..7ecc0595f23 100644
--- a/src/host/stream.h
+++ b/src/host/stream.h
@@ -31,14 +31,14 @@ Revision History:
 
 // Routine Description:
 // - This routine returns the total number of screen spaces the characters up to the specified character take up.
-size_t RetrieveTotalNumberOfSpaces(const SHORT sOriginalCursorPositionX,
-                                   _In_reads_(ulCurrentPosition) const WCHAR* const pwchBuffer,
-                                   const size_t ulCurrentPosition);
+til::CoordType RetrieveTotalNumberOfSpaces(const til::CoordType sOriginalCursorPositionX,
+                                           _In_reads_(ulCurrentPosition) const WCHAR* const pwchBuffer,
+                                           const size_t ulCurrentPosition);
 
 // Routine Description:
 // - This routine returns the number of screen spaces the specified character takes up.
-size_t RetrieveNumberOfSpaces(_In_ SHORT sOriginalCursorPositionX,
-                              _In_reads_(ulCurrentPosition + 1) const WCHAR* const pwchBuffer,
-                              _In_ size_t ulCurrentPosition);
+til::CoordType RetrieveNumberOfSpaces(_In_ til::CoordType sOriginalCursorPositionX,
+                                      _In_reads_(ulCurrentPosition + 1) const WCHAR* const pwchBuffer,
+                                      _In_ size_t ulCurrentPosition);
 
 VOID UnblockWriteConsole(const DWORD dwReason);
diff --git a/src/host/ut_host/ApiRoutinesTests.cpp b/src/host/ut_host/ApiRoutinesTests.cpp
index 160ba995e37..d83c9f8ba27 100644
--- a/src/host/ut_host/ApiRoutinesTests.cpp
+++ b/src/host/ut_host/ApiRoutinesTests.cpp
@@ -476,7 +476,7 @@ class ApiRoutinesTests
     void ValidateScreen(SCREEN_INFORMATION& si,
                         const CHAR_INFO background,
                         const CHAR_INFO fill,
-                        const COORD delta,
+                        const til::point delta,
                         const std::optional<Viewport> clip)
     {
         const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
@@ -510,7 +510,7 @@ class ApiRoutinesTests
                                const CHAR_INFO fill,
                                const CHAR_INFO scroll,
                                const Viewport scrollArea,
-                               const COORD destPoint,
+                               const til::point destPoint,
                                const std::optional<Viewport> clip)
     {
         const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
@@ -518,7 +518,7 @@ class ApiRoutinesTests
         auto bufferSize = activeSi.GetBufferSize();
 
         // Find the delta by comparing the scroll area to the destination point
-        COORD delta;
+        til::point delta;
         delta.X = destPoint.X - scrollArea.Left();
         delta.Y = destPoint.Y - scrollArea.Top();
 
@@ -626,12 +626,12 @@ class ApiRoutinesTests
         // By default, we're going to use a nullopt clip rectangle.
         // If this instance of the test is checking clipping, we'll assign a clip value
         // prior to each call variation.
-        std::optional<SMALL_RECT> clipRectangle = std::nullopt;
+        std::optional<til::inclusive_rect> clipRectangle = std::nullopt;
         std::optional<Viewport> clipViewport = std::nullopt;
         const auto bufferSize = si.GetBufferSize();
 
         auto scroll = bufferSize.ToInclusive();
-        COORD destination{ 0, -2 }; // scroll up.
+        til::point destination{ 0, -2 }; // scroll up.
 
         Log::Comment(L"Fill screen with green Zs. Scroll all up by two, backfilling with red As. Confirm every cell.");
         si.GetActiveBuffer().ClearTextData(); // Clean out screen
diff --git a/src/host/ut_host/ClipboardTests.cpp b/src/host/ut_host/ClipboardTests.cpp
index c00b907138a..21314875279 100644
--- a/src/host/ut_host/ClipboardTests.cpp
+++ b/src/host/ut_host/ClipboardTests.cpp
@@ -65,7 +65,7 @@ class ClipboardTests
 
     const UINT cRectsSelected = 4;
 
-    std::vector<std::wstring> SetupRetrieveFromBuffers(bool fLineSelection, std::vector<SMALL_RECT>& selection)
+    std::vector<std::wstring> SetupRetrieveFromBuffers(bool fLineSelection, std::vector<til::inclusive_rect>& selection)
     {
         const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
         // NOTE: This test requires innate knowledge of how the common buffer text is emitted in order to test all cases
@@ -75,10 +75,10 @@ class ClipboardTests
         const auto& screenInfo = gci.GetActiveOutputBuffer();
 
         selection.clear();
-        selection.emplace_back(SMALL_RECT{ 0, 0, 8, 0 });
-        selection.emplace_back(SMALL_RECT{ 0, 1, 14, 1 });
-        selection.emplace_back(SMALL_RECT{ 0, 2, 14, 2 });
-        selection.emplace_back(SMALL_RECT{ 0, 3, 8, 3 });
+        selection.emplace_back(til::inclusive_rect{ 0, 0, 8, 0 });
+        selection.emplace_back(til::inclusive_rect{ 0, 1, 14, 1 });
+        selection.emplace_back(til::inclusive_rect{ 0, 2, 14, 2 });
+        selection.emplace_back(til::inclusive_rect{ 0, 3, 8, 3 });
 
         const auto& buffer = screenInfo.GetTextBuffer();
         return buffer.GetText(true, fLineSelection, selection).text;
@@ -91,13 +91,13 @@ class ClipboardTests
         // NOTE: This test requires innate knowledge of how the common buffer text is emitted in order to test all cases
         // Please see CommonState.hpp for information on the buffer state per row, the row contents, etc.
 
-        std::vector<SMALL_RECT> selection;
+        std::vector<til::inclusive_rect> selection;
         const auto text = SetupRetrieveFromBuffers(false, selection);
 
         // verify trailing bytes were trimmed
         // there are 2 double-byte characters in our sample string (see CommonState.hpp for sample)
         // the width is right - left
-        VERIFY_ARE_EQUAL((short)wcslen(text[0].data()), selection[0].Right - selection[0].Left + 1);
+        VERIFY_ARE_EQUAL((til::CoordType)wcslen(text[0].data()), selection[0].Right - selection[0].Left + 1);
 
         // since we're not in line selection, the line should be \r\n terminated
         auto tempPtr = text[0].data();
@@ -124,7 +124,7 @@ class ClipboardTests
         // NOTE: This test requires innate knowledge of how the common buffer text is emitted in order to test all cases
         // Please see CommonState.hpp for information on the buffer state per row, the row contents, etc.
 
-        std::vector<SMALL_RECT> selection;
+        std::vector<til::inclusive_rect> selection;
         const auto text = SetupRetrieveFromBuffers(true, selection);
 
         // row 2, no wrap
diff --git a/src/host/ut_host/CommandLineTests.cpp b/src/host/ut_host/CommandLineTests.cpp
index 9e41767b5e6..511ee2db820 100644
--- a/src/host/ut_host/CommandLineTests.cpp
+++ b/src/host/ut_host/CommandLineTests.cpp
@@ -255,7 +255,7 @@ class CommandLineTests
 
         auto& commandLine = CommandLine::Instance();
         const auto cursorPos = commandLine._moveCursorToEndOfPrompt(cookedReadData);
-        VERIFY_ARE_EQUAL(cursorPos.X, gsl::narrow<short>(expectedCursorPos));
+        VERIFY_ARE_EQUAL(cursorPos.X, gsl::narrow<til::CoordType>(expectedCursorPos));
         VERIFY_ARE_EQUAL(cookedReadData._currentPosition, expectedCursorPos);
         VERIFY_ARE_EQUAL(cookedReadData._bufPtr, expectedBufferPos);
     }
@@ -297,7 +297,7 @@ class CommandLineTests
 
         auto& commandLine = CommandLine::Instance();
         // cursor position at beginning of "blah"
-        short expectedPos = 10;
+        til::CoordType expectedPos = 10;
         auto cursorPos = commandLine._moveCursorLeftByWord(cookedReadData);
         VERIFY_ARE_EQUAL(cursorPos.X, expectedPos);
         VERIFY_ARE_EQUAL(cookedReadData._currentPosition, gsl::narrow<size_t>(expectedPos));
@@ -374,8 +374,8 @@ class CommandLineTests
         // NOTE: need to initialize the actually cursor and keep it up to date with the changes here. remove
         once functions are fixed
         // try to move right, nothing should happen
-        short expectedPos = gsl::narrow<short>(endCursorPos);
-        COORD cursorPos = MoveCursorRightByWord(cookedReadData);
+        auto expectedPos = endCursorPos;
+        auto cursorPos = MoveCursorRightByWord(cookedReadData);
         VERIFY_ARE_EQUAL(cursorPos.X, expectedPos);
         VERIFY_ARE_EQUAL(cookedReadData._currentPosition, expectedPos);
         VERIFY_ARE_EQUAL(cookedReadData._bufPtr, endBufferPos);
diff --git a/src/host/ut_host/CommandListPopupTests.cpp b/src/host/ut_host/CommandListPopupTests.cpp
index c048e83534b..d47f3bbfa31 100644
--- a/src/host/ut_host/CommandListPopupTests.cpp
+++ b/src/host/ut_host/CommandListPopupTests.cpp
@@ -311,7 +311,7 @@ class CommandListPopupTests
 
         VERIFY_ARE_EQUAL(popup.Process(cookedReadData), static_cast<NTSTATUS>(CONSOLE_STATUS_WAIT_NO_BLOCK));
         // selection should have moved up a page
-        VERIFY_ARE_EQUAL(static_cast<short>(m_pHistory->GetNumberOfCommands()) - popup.Height() - 1, popup._currentCommand);
+        VERIFY_ARE_EQUAL(static_cast<til::CoordType>(m_pHistory->GetNumberOfCommands()) - popup.Height() - 1, popup._currentCommand);
     }
 
     TEST_METHOD(PageDownMovesSelection)
diff --git a/src/host/ut_host/ConptyOutputTests.cpp b/src/host/ut_host/ConptyOutputTests.cpp
index 9683aaee803..29e0e28f20f 100644
--- a/src/host/ut_host/ConptyOutputTests.cpp
+++ b/src/host/ut_host/ConptyOutputTests.cpp
@@ -29,8 +29,8 @@ class ConptyOutputTests
     // !!! DANGER: Many tests in this class expect the Terminal and Host buffers
     // to be 80x32. If you change these, you'll probably inadvertently break a
     // bunch of tests !!!
-    static const SHORT TerminalViewWidth = 80;
-    static const SHORT TerminalViewHeight = 32;
+    static const til::CoordType TerminalViewWidth = 80;
+    static const til::CoordType TerminalViewHeight = 32;
 
     // This test class is to write some things into the PTY and then check that
     // the rendering that is coming out of the VT-sequence generator is exactly
@@ -79,7 +79,7 @@ class ConptyOutputTests
         // Make sure a test hasn't left us in the alt buffer on accident
         VERIFY_IS_FALSE(currentBuffer._IsAltBuffer());
         VERIFY_SUCCEEDED(currentBuffer.SetViewportOrigin(true, { 0, 0 }, true));
-        VERIFY_ARE_EQUAL(COORD({ 0, 0 }), currentBuffer.GetTextBuffer().GetCursor().GetPosition());
+        VERIFY_ARE_EQUAL(til::point{}, currentBuffer.GetTextBuffer().GetCursor().GetPosition());
 
         // Set up an xterm-256 renderer for conpty
         auto hFile = wil::unique_hfile(INVALID_HANDLE_VALUE);
diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp
index 75bc3eb00c6..41ab22e9d67 100644
--- a/src/host/ut_host/ScreenBufferTests.cpp
+++ b/src/host/ut_host/ScreenBufferTests.cpp
@@ -77,9 +77,9 @@ class ScreenBufferTests
         VERIFY_IS_FALSE(currentBuffer._IsAltBuffer());
         VERIFY_SUCCEEDED(currentBuffer.SetViewportOrigin(true, { 0, 0 }, true));
         // Make sure the viewport always starts off at the default size.
-        auto defaultSize = COORD{ CommonState::s_csWindowWidth, CommonState::s_csWindowHeight };
+        auto defaultSize = til::size{ CommonState::s_csWindowWidth, CommonState::s_csWindowHeight };
         currentBuffer.SetViewport(Viewport::FromDimensions(defaultSize), true);
-        VERIFY_ARE_EQUAL(COORD({ 0, 0 }), currentBuffer.GetTextBuffer().GetCursor().GetPosition());
+        VERIFY_ARE_EQUAL(til::point(0, 0), currentBuffer.GetTextBuffer().GetCursor().GetPosition());
         // Make sure the virtual bottom is correctly positioned.
         currentBuffer.UpdateBottom();
 
@@ -381,7 +381,7 @@ void ScreenBufferTests::AlternateBufferCursorInheritanceTest()
     auto& mainCursor = mainBuffer.GetTextBuffer().GetCursor();
 
     Log::Comment(L"Set the cursor attributes in the main buffer.");
-    auto mainCursorPos = COORD{ 3, 5 };
+    auto mainCursorPos = til::point{ 3, 5 };
     auto mainCursorVisible = false;
     auto mainCursorSize = 33u;
     auto mainCursorType = CursorType::DoubleUnderscore;
@@ -407,7 +407,7 @@ void ScreenBufferTests::AlternateBufferCursorInheritanceTest()
     VERIFY_ARE_EQUAL(mainCursorBlinking, altCursor.IsBlinkingAllowed());
 
     Log::Comment(L"Set the cursor attributes in the alt buffer.");
-    auto altCursorPos = COORD{ 5, 3 };
+    auto altCursorPos = til::point{ 5, 3 };
     auto altCursorVisible = true;
     auto altCursorSize = 66u;
     auto altCursorType = CursorType::EmptyBox;
@@ -513,7 +513,7 @@ void ScreenBufferTests::TestReverseLineFeed()
     VERIFY_ARE_EQUAL(c.Y, 6);
 }
 
-void _SetTabStops(SCREEN_INFORMATION& screenInfo, std::list<short> columns, bool replace)
+void _SetTabStops(SCREEN_INFORMATION& screenInfo, std::list<til::CoordType> columns, bool replace)
 {
     auto& stateMachine = screenInfo.GetStateMachine();
     auto& cursor = screenInfo.GetTextBuffer().GetCursor();
@@ -532,9 +532,9 @@ void _SetTabStops(SCREEN_INFORMATION& screenInfo, std::list<short> columns, bool
     }
 }
 
-std::list<short> _GetTabStops(SCREEN_INFORMATION& screenInfo)
+std::list<til::CoordType> _GetTabStops(SCREEN_INFORMATION& screenInfo)
 {
-    std::list<short> columns;
+    std::list<til::CoordType> columns;
 
     const auto lastColumn = screenInfo.GetBufferSize().RightInclusive();
     auto& stateMachine = screenInfo.GetStateMachine();
@@ -573,7 +573,7 @@ void ScreenBufferTests::TestResetClearTabStops()
     const auto resetToInitialState = L"\033c";
 
     Log::Comment(L"Default tabs every 8 columns.");
-    std::list<short> expectedStops{ 8, 16, 24, 32, 40, 48, 56, 64, 72 };
+    std::list<til::CoordType> expectedStops{ 8, 16, 24, 32, 40, 48, 56, 64, 72 };
     VERIFY_ARE_EQUAL(expectedStops, _GetTabStops(screenInfo));
 
     Log::Comment(L"Clear all tabs.");
@@ -599,7 +599,7 @@ void ScreenBufferTests::TestAddTabStop()
 
     Log::Comment(L"Clear all tabs.");
     stateMachine.ProcessString(clearTabStops);
-    std::list<short> expectedStops{};
+    std::list<til::CoordType> expectedStops{};
     VERIFY_ARE_EQUAL(expectedStops, _GetTabStops(screenInfo));
 
     Log::Comment(L"Add tab to empty list.");
@@ -689,7 +689,7 @@ void ScreenBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear head.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(screenInfo, inputData, false);
         cursor.SetXPosition(inputData.front());
         stateMachine.ProcessString(clearTabStop);
@@ -703,7 +703,7 @@ void ScreenBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear middle.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(screenInfo, inputData, false);
         cursor.SetXPosition(*std::next(inputData.begin()));
         stateMachine.ProcessString(clearTabStop);
@@ -717,7 +717,7 @@ void ScreenBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear tail.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(screenInfo, inputData, false);
         cursor.SetXPosition(inputData.back());
         stateMachine.ProcessString(clearTabStop);
@@ -731,7 +731,7 @@ void ScreenBufferTests::TestClearTabStop()
 
     Log::Comment(L"Allocate many (5) list items and clear nonexistent item.");
     {
-        std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+        std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
         _SetTabStops(screenInfo, inputData, false);
         cursor.SetXPosition(0);
         stateMachine.ProcessString(clearTabStop);
@@ -752,7 +752,7 @@ void ScreenBufferTests::TestGetForwardTab()
 
     const auto nextForwardTab = L"\033[I";
 
-    std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+    std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
     _SetTabStops(si, inputData, true);
 
     const auto coordScreenBufferSize = si.GetBufferSize().Dimensions();
@@ -822,7 +822,7 @@ void ScreenBufferTests::TestGetReverseTab()
 
     const auto nextReverseTab = L"\033[Z";
 
-    std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
+    std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
     _SetTabStops(si, inputData, true);
 
     Log::Comment(L"Find previous tab from before front.");
@@ -880,7 +880,7 @@ void ScreenBufferTests::TestAltBufferTabStops()
     VERIFY_IS_TRUE(WI_IsFlagSet(mainBuffer.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING));
 
     Log::Comment(L"Add an initial set of tab in the main buffer.");
-    std::list<short> expectedStops = { 3, 5, 6, 10, 15, 17 };
+    std::list<til::CoordType> expectedStops = { 3, 5, 6, 10, 15, 17 };
     _SetTabStops(mainBuffer, expectedStops, true);
     VERIFY_ARE_EQUAL(expectedStops, _GetTabStops(mainBuffer));
 
@@ -924,7 +924,7 @@ void ScreenBufferTests::EraseAllTests()
     Log::Comment(L"Case 1: Erase a single line of text in the buffer\n");
 
     stateMachine.ProcessString(L"foo");
-    COORD originalRelativePosition = { 3, 0 };
+    til::point originalRelativePosition = { 3, 0 };
     VERIFY_ARE_EQUAL(si.GetViewport().Top(), 0);
     VERIFY_ARE_EQUAL(cursor.GetPosition(), originalRelativePosition);
 
@@ -1293,7 +1293,7 @@ void ScreenBufferTests::VtResizeDECCOLM()
     newViewWidth = si.GetViewport().Width();
 
     VERIFY_IS_FALSE(areMarginsSet());
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), getRelativeCursorPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), getRelativeCursorPosition());
     VERIFY_ARE_EQUAL(initialSbHeight, newSbHeight);
     VERIFY_ARE_EQUAL(initialViewHeight, newViewHeight);
     VERIFY_ARE_EQUAL(132, newSbWidth);
@@ -1347,7 +1347,7 @@ void ScreenBufferTests::VtResizeDECCOLM()
     newViewWidth = si.GetViewport().Width();
 
     VERIFY_IS_FALSE(areMarginsSet());
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), getRelativeCursorPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), getRelativeCursorPosition());
     VERIFY_ARE_EQUAL(initialSbHeight, newSbHeight);
     VERIFY_ARE_EQUAL(initialViewHeight, newViewHeight);
     VERIFY_ARE_EQUAL(80, newSbWidth);
@@ -1363,31 +1363,31 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
     const auto& cursor = tbi.GetCursor();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(NoThrowString().Format(
         L"Move the cursor to 2,2, then execute a soft reset.\n"
         L"The cursor should not move."));
 
     stateMachine.ProcessString(L"\x1b[2;2H");
-    VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
 
     stateMachine.ProcessString(L"\x1b[!p");
-    VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
 
     Log::Comment(NoThrowString().Format(
         L"Set some margins. The cursor should move home."));
 
     stateMachine.ProcessString(L"\x1b[2;10r");
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
 
     Log::Comment(NoThrowString().Format(
         L"Move the cursor to 2,2, then execute a soft reset.\n"
         L"The cursor should not move, even though there are margins."));
     stateMachine.ProcessString(L"\x1b[2;2H");
-    VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
     stateMachine.ProcessString(L"\x1b[!p");
-    VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
 
     Log::Comment(
         L"Set the origin mode, some margins, and move the cursor to 2,2.\n"
@@ -1395,7 +1395,7 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
     stateMachine.ProcessString(L"\x1b[?6h");
     stateMachine.ProcessString(L"\x1b[5;10r");
     stateMachine.ProcessString(L"\x1b[2;2H");
-    VERIFY_ARE_EQUAL(COORD({ 1, 5 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 5), cursor.GetPosition());
 
     Log::Comment(
         L"Execute a soft reset, reapply the margins, and move the cursor to 2,2.\n"
@@ -1403,7 +1403,7 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
     stateMachine.ProcessString(L"\x1b[!p");
     stateMachine.ProcessString(L"\x1b[5;10r");
     stateMachine.ProcessString(L"\x1b[2;2H");
-    VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
 }
 
 void ScreenBufferTests::VtScrollMarginsNewlineColor()
@@ -1416,8 +1416,8 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor()
     auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
-    cursor.SetPosition(COORD({ 0, 0 }));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
+    cursor.SetPosition(til::point(0, 0));
 
     const auto yellow = RGB(255, 255, 0);
     const auto magenta = RGB(255, 0, 255);
@@ -1450,11 +1450,11 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor()
 
         Log::Comment(NoThrowString().Format(
             L"Cursor=%s",
-            VerifyOutputTraits<COORD>::ToString(cursorPos).GetBuffer()));
+            VerifyOutputTraits<til::point>::ToString(cursorPos).GetBuffer()));
         const auto viewport = si.GetViewport();
         Log::Comment(NoThrowString().Format(
             L"Viewport=%s",
-            VerifyOutputTraits<SMALL_RECT>::ToString(viewport.ToInclusive()).GetBuffer()));
+            VerifyOutputTraits<til::inclusive_rect>::ToString(viewport.ToInclusive()).GetBuffer()));
         const auto viewTop = viewport.Top();
         for (int y = viewTop; y < viewTop + 10; y++)
         {
@@ -1486,8 +1486,8 @@ void ScreenBufferTests::VtNewlinePastViewport()
     VERIFY_IS_TRUE(WI_IsFlagSet(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING));
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
-    cursor.SetPosition(COORD({ 0, 0 }));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
+    cursor.SetPosition(til::point(0, 0));
 
     stateMachine.ProcessString(L"\x1b[m");
     stateMachine.ProcessString(L"\x1b[2J");
@@ -1500,9 +1500,9 @@ void ScreenBufferTests::VtNewlinePastViewport()
     const auto initialViewport = si.GetViewport();
     Log::Comment(NoThrowString().Format(
         L"initialViewport=%s",
-        VerifyOutputTraits<SMALL_RECT>::ToString(initialViewport.ToInclusive()).GetBuffer()));
+        VerifyOutputTraits<til::inclusive_rect>::ToString(initialViewport.ToInclusive()).GetBuffer()));
 
-    cursor.SetPosition(COORD({ 0, initialViewport.BottomInclusive() }));
+    cursor.SetPosition({ 0, initialViewport.BottomInclusive() });
 
     // Set the attributes that will be used to initialize new rows.
     auto fillAttr = TextAttribute{ RGB(12, 34, 56), RGB(78, 90, 12) };
@@ -1519,7 +1519,7 @@ void ScreenBufferTests::VtNewlinePastViewport()
     const auto viewport = si.GetViewport();
     Log::Comment(NoThrowString().Format(
         L"viewport=%s",
-        VerifyOutputTraits<SMALL_RECT>::ToString(viewport.ToInclusive()).GetBuffer()));
+        VerifyOutputTraits<til::inclusive_rect>::ToString(viewport.ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(viewport.BottomInclusive(), cursor.GetPosition().Y);
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
@@ -1560,8 +1560,8 @@ void ScreenBufferTests::VtNewlinePastEndOfBuffer()
     VERIFY_IS_TRUE(WI_IsFlagSet(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING));
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
-    cursor.SetPosition(COORD({ 0, 0 }));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
+    cursor.SetPosition(til::point(0, 0));
 
     stateMachine.ProcessString(L"\x1b[m");
     stateMachine.ProcessString(L"\x1b[2J");
@@ -1577,9 +1577,9 @@ void ScreenBufferTests::VtNewlinePastEndOfBuffer()
     const auto initialViewport = si.GetViewport();
     Log::Comment(NoThrowString().Format(
         L"initialViewport=%s",
-        VerifyOutputTraits<SMALL_RECT>::ToString(initialViewport.ToInclusive()).GetBuffer()));
+        VerifyOutputTraits<til::inclusive_rect>::ToString(initialViewport.ToInclusive()).GetBuffer()));
 
-    cursor.SetPosition(COORD({ 0, initialViewport.BottomInclusive() }));
+    cursor.SetPosition({ 0, initialViewport.BottomInclusive() });
 
     // Set the attributes that will be used to initialize new rows.
     auto fillAttr = TextAttribute{ RGB(12, 34, 56), RGB(78, 90, 12) };
@@ -1596,7 +1596,7 @@ void ScreenBufferTests::VtNewlinePastEndOfBuffer()
     const auto viewport = si.GetViewport();
     Log::Comment(NoThrowString().Format(
         L"viewport=%s",
-        VerifyOutputTraits<SMALL_RECT>::ToString(viewport.ToInclusive()).GetBuffer()));
+        VerifyOutputTraits<til::inclusive_rect>::ToString(viewport.ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(viewport.BottomInclusive(), cursor.GetPosition().Y);
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
@@ -1639,11 +1639,11 @@ void ScreenBufferTests::VtNewlineOutsideMargins()
     Log::Comment(L"LF at bottom of viewport scrolls the viewport");
     cursor.SetPosition({ 0, viewportBottom });
     stateMachine.ProcessString(L"\n");
-    VERIFY_ARE_EQUAL(COORD({ 0, viewportBottom + 1 }), cursor.GetPosition());
-    VERIFY_ARE_EQUAL(COORD({ 0, viewportTop + 1 }), si.GetViewport().Origin());
+    VERIFY_ARE_EQUAL(til::point(0, viewportBottom + 1), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, viewportTop + 1), si.GetViewport().Origin());
 
     Log::Comment(L"Reset viewport and apply DECSTBM margins");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, viewportTop }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, { 0, viewportTop }, true));
     stateMachine.ProcessString(L"\x1b[1;5r");
     // Make sure we clear the margins on exit so they can't break other tests.
     auto clearMargins = wil::scope_exit([&] { stateMachine.ProcessString(L"\x1b[r"); });
@@ -1651,8 +1651,8 @@ void ScreenBufferTests::VtNewlineOutsideMargins()
     Log::Comment(L"LF no longer scrolls the viewport when below bottom margin");
     cursor.SetPosition({ 0, viewportBottom });
     stateMachine.ProcessString(L"\n");
-    VERIFY_ARE_EQUAL(COORD({ 0, viewportBottom }), cursor.GetPosition());
-    VERIFY_ARE_EQUAL(COORD({ 0, viewportTop }), si.GetViewport().Origin());
+    VERIFY_ARE_EQUAL(til::point(0, viewportBottom), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, viewportTop), si.GetViewport().Origin());
 }
 
 void ScreenBufferTests::VtSetColorTable()
@@ -1781,8 +1781,8 @@ void ScreenBufferTests::ResizeCursorUnchanged()
     gci.SetWrapText(useResizeWithReflow);
 
     auto newBufferSize = si.GetBufferSize().Dimensions();
-    newBufferSize.X += static_cast<short>(dx);
-    newBufferSize.Y += static_cast<short>(dy);
+    newBufferSize.X += dx;
+    newBufferSize.Y += dy;
 
     VERIFY_SUCCEEDED(si.ResizeScreenBuffer(newBufferSize, false));
 
@@ -1872,8 +1872,8 @@ void ScreenBufferTests::ResizeAltBufferGetScreenBufferInfo()
     auto useMain = wil::scope_exit([&] { altBuffer.UseMainScreenBuffer(); });
 
     auto newBufferSize = originalMainSize.Dimensions();
-    newBufferSize.X += static_cast<short>(dx);
-    newBufferSize.Y += static_cast<short>(dy);
+    newBufferSize.X += dx;
+    newBufferSize.Y += dy;
 
     const auto originalAltSize = Viewport(altBuffer._viewport);
 
@@ -1887,7 +1887,7 @@ void ScreenBufferTests::ResizeAltBufferGetScreenBufferInfo()
     const auto newActualMainView = mainBuffer.GetViewport();
     const auto newActualAltView = altBuffer.GetViewport();
 
-    const auto newApiViewport = Viewport::FromExclusive(csbiex.srWindow);
+    const auto newApiViewport = Viewport::FromExclusive(til::wrap_exclusive_small_rect(csbiex.srWindow));
 
     VERIFY_ARE_NOT_EQUAL(originalAltSize.Width(), newActualAltView.Width());
     VERIFY_ARE_NOT_EQUAL(originalAltSize.Height(), newActualAltView.Height());
@@ -1909,19 +1909,19 @@ void ScreenBufferTests::VtEraseAllPersistCursor()
 
     Log::Comment(NoThrowString().Format(
         L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(NoThrowString().Format(
         L"Move the cursor to 2,2, then execute a Erase All.\n"
         L"The cursor should not move relative to the viewport."));
 
     stateMachine.ProcessString(L"\x1b[2;2H");
-    VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
 
     stateMachine.ProcessString(L"\x1b[2J");
 
     auto newViewport = si._viewport;
-    COORD expectedCursor = { 1, 1 };
+    til::point expectedCursor = { 1, 1 };
     newViewport.ConvertFromOrigin(&expectedCursor);
 
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
@@ -1936,7 +1936,7 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor()
 
     Log::Comment(NoThrowString().Format(
         L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(NoThrowString().Format(
         L"Change the colors to dark_red on bright_blue, then execute a Erase All.\n"
@@ -1956,10 +1956,10 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor()
     auto newViewport = si._viewport;
     Log::Comment(NoThrowString().Format(
         L"new Viewport: %s",
-        VerifyOutputTraits<SMALL_RECT>::ToString(newViewport.ToInclusive()).GetBuffer()));
+        VerifyOutputTraits<til::inclusive_rect>::ToString(newViewport.ToInclusive()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
         L"Buffer Size: %s",
-        VerifyOutputTraits<SMALL_RECT>::ToString(si.GetBufferSize().ToInclusive()).GetBuffer()));
+        VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetBufferSize().ToInclusive()).GetBuffer()));
 
     auto iter = tbi.GetCellDataAt(newViewport.Origin());
     auto height = newViewport.Height();
@@ -1983,7 +1983,7 @@ void ScreenBufferTests::GetWordBoundary()
     const auto length = wcslen(text);
 
     // Make the buffer as big as our test text.
-    const COORD newBufferSize = { gsl::narrow<SHORT>(length), 10 };
+    const til::size newBufferSize = { gsl::narrow<til::CoordType>(length), 10 };
     VERIFY_SUCCEEDED(si.GetTextBuffer().ResizeTraditional(newBufferSize));
 
     const OutputCellIterator it(text, si.GetAttributes());
@@ -1991,8 +1991,8 @@ void ScreenBufferTests::GetWordBoundary()
 
     // Now find some words in it.
     Log::Comment(L"Find first word from its front.");
-    COORD expectedFirst = { 0, 0 };
-    COORD expectedSecond = { 4, 0 };
+    til::point expectedFirst = { 0, 0 };
+    til::point expectedSecond = { 4, 0 };
 
     auto boundary = si.GetWordBoundary({ 0, 0 });
     VERIFY_ARE_EQUAL(expectedFirst, boundary.first);
@@ -2059,7 +2059,7 @@ void ScreenBufferTests::GetWordBoundaryTrimZeros(const bool on)
     const auto length = wcslen(text);
 
     // Make the buffer as big as our test text.
-    const COORD newBufferSize = { gsl::narrow<SHORT>(length), 10 };
+    const til::size newBufferSize = { gsl::narrow<til::CoordType>(length), 10 };
     VERIFY_SUCCEEDED(si.GetTextBuffer().ResizeTraditional(newBufferSize));
 
     const OutputCellIterator it(text, si.GetAttributes());
@@ -2067,41 +2067,41 @@ void ScreenBufferTests::GetWordBoundaryTrimZeros(const bool on)
 
     gci.SetTrimLeadingZeros(on);
 
-    COORD expectedFirst;
-    COORD expectedSecond;
-    std::pair<COORD, COORD> boundary;
+    til::point expectedFirst;
+    til::point expectedSecond;
+    std::pair<til::point, til::point> boundary;
 
     Log::Comment(L"Find lead with 000");
-    expectedFirst = on ? COORD{ 3, 0 } : COORD{ 0, 0 };
-    expectedSecond = COORD{ 7, 0 };
+    expectedFirst = on ? til::point{ 3, 0 } : til::point{ 0, 0 };
+    expectedSecond = { 7, 0 };
     boundary = si.GetWordBoundary({ 0, 0 });
     VERIFY_ARE_EQUAL(expectedFirst, boundary.first);
     VERIFY_ARE_EQUAL(expectedSecond, boundary.second);
 
     Log::Comment(L"Find lead with 0x");
-    expectedFirst = COORD{ 8, 0 };
-    expectedSecond = COORD{ 14, 0 };
+    expectedFirst = { 8, 0 };
+    expectedSecond = { 14, 0 };
     boundary = si.GetWordBoundary({ 8, 0 });
     VERIFY_ARE_EQUAL(expectedFirst, boundary.first);
     VERIFY_ARE_EQUAL(expectedSecond, boundary.second);
 
     Log::Comment(L"Find lead with 0X");
-    expectedFirst = COORD{ 15, 0 };
-    expectedSecond = COORD{ 21, 0 };
+    expectedFirst = { 15, 0 };
+    expectedSecond = { 21, 0 };
     boundary = si.GetWordBoundary({ 15, 0 });
     VERIFY_ARE_EQUAL(expectedFirst, boundary.first);
     VERIFY_ARE_EQUAL(expectedSecond, boundary.second);
 
     Log::Comment(L"Find lead with 0n");
-    expectedFirst = COORD{ 22, 0 };
-    expectedSecond = COORD{ 28, 0 };
+    expectedFirst = { 22, 0 };
+    expectedSecond = { 28, 0 };
     boundary = si.GetWordBoundary({ 22, 0 });
     VERIFY_ARE_EQUAL(expectedFirst, boundary.first);
     VERIFY_ARE_EQUAL(expectedSecond, boundary.second);
 
     Log::Comment(L"Find lead with 0N");
-    expectedFirst = on ? COORD{ 30, 0 } : COORD{ 29, 0 };
-    expectedSecond = COORD{ 35, 0 };
+    expectedFirst = on ? til::point{ 30, 0 } : til::point{ 29, 0 };
+    expectedSecond = { 35, 0 };
     boundary = si.GetWordBoundary({ 29, 0 });
     VERIFY_ARE_EQUAL(expectedFirst, boundary.first);
     VERIFY_ARE_EQUAL(expectedSecond, boundary.second);
@@ -2197,7 +2197,7 @@ void ScreenBufferTests::TestAltBufferVtDispatching()
         auto& mainCursor = mainBuffer.GetTextBuffer().GetCursor();
         auto& altCursor = alternate.GetTextBuffer().GetCursor();
 
-        const COORD origin = { 0, 0 };
+        const til::point origin;
         mainCursor.SetPosition(origin);
         altCursor.SetPosition(origin);
         Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
@@ -2214,9 +2214,9 @@ void ScreenBufferTests::TestAltBufferVtDispatching()
         auto seqCb = 2 * seq.size();
         VERIFY_SUCCEEDED(DoWriteConsole(&seq[0], &seqCb, mainBuffer, false, waiter));
 
-        VERIFY_ARE_EQUAL(COORD({ 0, 0 }), mainCursor.GetPosition());
+        VERIFY_ARE_EQUAL(til::point(0, 0), mainCursor.GetPosition());
         // recall: vt coordinates are (row, column), 1-indexed
-        VERIFY_ARE_EQUAL(COORD({ 5, 4 }), altCursor.GetPosition());
+        VERIFY_ARE_EQUAL(til::point(5, 4), altCursor.GetPosition());
 
         const TextAttribute expectedDefaults = {};
         auto expectedRgb = expectedDefaults;
@@ -2236,8 +2236,8 @@ void ScreenBufferTests::TestAltBufferVtDispatching()
         seqCb = 2 * seq.size();
         VERIFY_SUCCEEDED(DoWriteConsole(&seq[0], &seqCb, mainBuffer, false, waiter));
 
-        VERIFY_ARE_EQUAL(COORD({ 0, 0 }), mainCursor.GetPosition());
-        VERIFY_ARE_EQUAL(COORD({ 6, 4 }), altCursor.GetPosition());
+        VERIFY_ARE_EQUAL(til::point(0, 0), mainCursor.GetPosition());
+        VERIFY_ARE_EQUAL(til::point(6, 4), altCursor.GetPosition());
 
         // Recall we didn't print an 'X' to the main buffer, so there's no
         //      char to inspect the attributes of.
@@ -2282,7 +2282,7 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault()
     auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
     cursor.SetPosition({ 0, 0 });
 
     auto magenta = RGB(255, 0, 255);
@@ -2333,7 +2333,7 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault()
     auto expectedSix = expectedTwo;
     expectedSix.SetDefaultBackground();
 
-    COORD expectedCursor{ 6, 0 };
+    til::point expectedCursor{ 6, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const auto& row = tbi.GetRowByOffset(0);
@@ -2387,7 +2387,7 @@ void ScreenBufferTests::SetDefaultsTogether()
     auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
     cursor.SetPosition({ 0, 0 });
 
     auto magenta = RGB(255, 0, 255);
@@ -2424,7 +2424,7 @@ void ScreenBufferTests::SetDefaultsTogether()
     TextAttribute expectedTwo{};
     expectedTwo.SetIndexedBackground256(250);
 
-    COORD expectedCursor{ 3, 0 };
+    til::point expectedCursor{ 3, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const auto& row = tbi.GetRowByOffset(0);
@@ -2462,7 +2462,7 @@ void ScreenBufferTests::ReverseResetWithDefaultBackground()
     auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
     cursor.SetPosition({ 0, 0 });
 
     auto magenta = RGB(255, 0, 255);
@@ -2488,7 +2488,7 @@ void ScreenBufferTests::ReverseResetWithDefaultBackground()
     auto expectedReversed = expectedDefaults;
     expectedReversed.Invert();
 
-    COORD expectedCursor{ 3, 0 };
+    til::point expectedCursor{ 3, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const auto& row = tbi.GetRowByOffset(0);
@@ -2533,7 +2533,7 @@ void ScreenBufferTests::BackspaceDefaultAttrs()
     auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
     cursor.SetPosition({ 0, 0 });
 
     auto magenta = RGB(255, 0, 255);
@@ -2551,7 +2551,7 @@ void ScreenBufferTests::BackspaceDefaultAttrs()
     TextAttribute expectedDefaults{};
     expectedDefaults.SetDefaultBackground();
 
-    COORD expectedCursor{ 1, 0 };
+    til::point expectedCursor{ 1, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const auto& row = tbi.GetRowByOffset(0);
@@ -2598,7 +2598,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy()
     auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
     cursor.SetPosition({ 0, 0 });
 
     auto magenta = RGB(255, 0, 255);
@@ -2630,7 +2630,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy()
     TextAttribute expectedDefaults{};
     expectedDefaults.SetDefaultBackground();
 
-    COORD expectedCursor{ 1, 0 };
+    til::point expectedCursor{ 1, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const auto& row = tbi.GetRowByOffset(0);
@@ -2668,7 +2668,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt()
     VERIFY_IS_TRUE(WI_IsFlagSet(si.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING));
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
     cursor.SetPosition({ 0, 0 });
 
     auto magenta = RGB(255, 0, 255);
@@ -2710,7 +2710,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt()
     stateMachine.ProcessString(L"\x1b[2D");
     stateMachine.ProcessString(L"\x1b[P");
 
-    COORD expectedCursor{ 1, 0 };
+    til::point expectedCursor{ 1, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const std::vector<TextAttribute> attrs{ attrRow->begin(), attrRow->end() };
@@ -2744,7 +2744,7 @@ void ScreenBufferTests::SetGlobalColorTable()
     const auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, til::point(0, 0), true));
     mainCursor.SetPosition({ 0, 0 });
 
     const auto originalRed = gci.GetColorTableEntry(TextColor::DARK_RED);
@@ -2753,7 +2753,7 @@ void ScreenBufferTests::SetGlobalColorTable()
 
     stateMachine.ProcessString(L"\x1b[41m");
     stateMachine.ProcessString(L"X");
-    COORD expectedCursor{ 1, 0 };
+    til::point expectedCursor{ 1, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, mainCursor.GetPosition());
     {
         const auto& row = mainBuffer.GetTextBuffer().GetRowByOffset(mainCursor.GetPosition().Y);
@@ -2795,7 +2795,7 @@ void ScreenBufferTests::SetGlobalColorTable()
     Log::Comment(NoThrowString().Format(
         L"Print another X, both should be the new \"red\" color"));
     stateMachine.ProcessString(L"X");
-    VERIFY_ARE_EQUAL(COORD({ 2, 0 }), altCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(2, 0), altCursor.GetPosition());
     {
         const auto& row = altBuffer.GetTextBuffer().GetRowByOffset(altCursor.GetPosition().Y);
         const auto attrRow = &row.GetAttrRow();
@@ -2818,7 +2818,7 @@ void ScreenBufferTests::SetGlobalColorTable()
     Log::Comment(NoThrowString().Format(
         L"Print another X, both should be the new \"red\" color"));
     stateMachine.ProcessString(L"X");
-    VERIFY_ARE_EQUAL(COORD({ 2, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(2, 0), mainCursor.GetPosition());
     {
         const auto& row = mainBuffer.GetTextBuffer().GetRowByOffset(mainCursor.GetPosition().Y);
         const auto attrRow = &row.GetAttrRow();
@@ -2851,7 +2851,7 @@ void ScreenBufferTests::SetColorTableThreeDigits()
     const auto& renderSettings = gci.GetRenderSettings();
 
     Log::Comment(NoThrowString().Format(L"Make sure the viewport is at 0,0"));
-    VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(mainBuffer.SetViewportOrigin(true, til::point(0, 0), true));
     mainCursor.SetPosition({ 0, 0 });
 
     const auto originalRed = gci.GetColorTableEntry(123);
@@ -2860,7 +2860,7 @@ void ScreenBufferTests::SetColorTableThreeDigits()
 
     stateMachine.ProcessString(L"\x1b[48;5;123m");
     stateMachine.ProcessString(L"X");
-    COORD expectedCursor{ 1, 0 };
+    til::point expectedCursor{ 1, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, mainCursor.GetPosition());
     {
         const auto& row = mainBuffer.GetTextBuffer().GetRowByOffset(mainCursor.GetPosition().Y);
@@ -2905,7 +2905,7 @@ void ScreenBufferTests::SetColorTableThreeDigits()
     // You shouldn't need to manually update the attributes again.
     stateMachine.ProcessString(L"\x1b[48;5;123m");
     stateMachine.ProcessString(L"X");
-    VERIFY_ARE_EQUAL(COORD({ 2, 0 }), altCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(2, 0), altCursor.GetPosition());
     {
         const auto& row = altBuffer.GetTextBuffer().GetRowByOffset(altCursor.GetPosition().Y);
         const auto attrRow = &row.GetAttrRow();
@@ -3100,7 +3100,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLine()
     auto& mainCursor = tbi.GetCursor();
     auto& mainView = mainBuffer.GetViewport();
 
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), mainCursor.GetPosition());
     VERIFY_ARE_EQUAL(mainBuffer.GetBufferSize().Width(), mainView.Width());
     VERIFY_IS_GREATER_THAN(mainView.Width(), (dx + numCharsToDelete));
 
@@ -3109,13 +3109,13 @@ void ScreenBufferTests::DeleteCharsNearEndOfLine()
         stateMachine.ProcessString(L"X");
     }
 
-    VERIFY_ARE_EQUAL(COORD({ mainView.Width() - 1, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(mainView.Width() - 1, 0), mainCursor.GetPosition());
 
     Log::Comment(NoThrowString().Format(
         L"row_i=[%s]",
         tbi.GetRowByOffset(0).GetText().c_str()));
 
-    mainCursor.SetPosition({ mainView.Width() - static_cast<short>(dx), 0 });
+    mainCursor.SetPosition({ mainView.Width() - static_cast<til::CoordType>(dx), 0 });
     std::wstringstream ss;
     ss << L"\x1b[" << numCharsToDelete << L"P"; // Delete N chars
     stateMachine.ProcessString(ss.str());
@@ -3123,7 +3123,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLine()
     Log::Comment(NoThrowString().Format(
         L"row_f=[%s]",
         tbi.GetRowByOffset(0).GetText().c_str()));
-    VERIFY_ARE_EQUAL(COORD({ mainView.Width() - static_cast<short>(dx), 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(mainView.Width() - static_cast<til::CoordType>(dx), 0), mainCursor.GetPosition());
     auto iter = tbi.GetCellDataAt({ 0, 0 });
     auto expectedNumSpaces = std::min(dx, numCharsToDelete);
     for (auto x = 0; x < mainView.Width() - expectedNumSpaces; x++)
@@ -3163,19 +3163,19 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleFirstCase()
     VERIFY_SUCCEEDED(si.ResizeScreenBuffer({ newBufferWidth, si.GetBufferSize().Height() }, false));
     auto& mainBuffer = gci.GetActiveOutputBuffer();
 
-    const COORD newViewSize{ newBufferWidth, mainBuffer.GetViewport().Height() };
+    const til::size newViewSize{ newBufferWidth, mainBuffer.GetViewport().Height() };
     mainBuffer.SetViewportSize(&newViewSize);
     auto& tbi = mainBuffer.GetTextBuffer();
     auto& mainView = mainBuffer.GetViewport();
     auto& mainCursor = tbi.GetCursor();
 
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), mainCursor.GetPosition());
     VERIFY_ARE_EQUAL(newBufferWidth, mainView.Width());
     VERIFY_ARE_EQUAL(mainBuffer.GetBufferSize().Width(), mainView.Width());
 
     stateMachine.ProcessString(L"ABCDEFG");
 
-    VERIFY_ARE_EQUAL(COORD({ 7, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(7, 0), mainCursor.GetPosition());
     // Place the cursor on the 'D'
     mainCursor.SetPosition({ 3, 0 });
 
@@ -3188,7 +3188,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleFirstCase()
     Log::Comment(NoThrowString().Format(L"after =[%s]", tbi.GetRowByOffset(0).GetText().c_str()));
 
     // Cursor shouldn't have moved
-    VERIFY_ARE_EQUAL(COORD({ 3, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(3, 0), mainCursor.GetPosition());
 
     auto iter = tbi.GetCellDataAt({ 0, 0 });
     VERIFY_ARE_EQUAL(L"A", iter->Chars());
@@ -3223,19 +3223,19 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleSecondCase()
     VERIFY_SUCCEEDED(si.ResizeScreenBuffer({ newBufferWidth, si.GetBufferSize().Height() }, false));
     auto& mainBuffer = gci.GetActiveOutputBuffer();
 
-    const COORD newViewSize{ newBufferWidth, mainBuffer.GetViewport().Height() };
+    const til::size newViewSize{ newBufferWidth, mainBuffer.GetViewport().Height() };
     mainBuffer.SetViewportSize(&newViewSize);
     auto& tbi = mainBuffer.GetTextBuffer();
     auto& mainView = mainBuffer.GetViewport();
     auto& mainCursor = tbi.GetCursor();
 
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), mainCursor.GetPosition());
     VERIFY_ARE_EQUAL(newBufferWidth, mainView.Width());
     VERIFY_ARE_EQUAL(mainBuffer.GetBufferSize().Width(), mainView.Width());
 
     stateMachine.ProcessString(L"ABCDEFG");
 
-    VERIFY_ARE_EQUAL(COORD({ 7, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(7, 0), mainCursor.GetPosition());
 
     // Place the cursor on the 'C'
     mainCursor.SetPosition({ 2, 0 });
@@ -3249,7 +3249,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleSecondCase()
 
     Log::Comment(NoThrowString().Format(L"after =[%s]", tbi.GetRowByOffset(0).GetText().c_str()));
 
-    VERIFY_ARE_EQUAL(COORD({ 2, 0 }), mainCursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(2, 0), mainCursor.GetPosition());
 
     auto iter = tbi.GetCellDataAt({ 0, 0 });
     VERIFY_ARE_EQUAL(L"A", iter->Chars());
@@ -3286,9 +3286,9 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom()
     VERIFY_SUCCESS_NTSTATUS(si.SetViewportOrigin(true, { 0, 1 }, true));
     cursor.SetPosition({ 0, si.GetViewport().BottomInclusive() });
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
     const auto darkRed = gci.GetColorTableEntry(TextColor::DARK_RED);
     const auto darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE);
     const auto darkBlack = gci.GetColorTableEntry(TextColor::DARK_BLACK);
@@ -3299,9 +3299,9 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom()
     stateMachine.ProcessString(L"X");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
     VERIFY_ARE_EQUAL(2, cursor.GetPosition().X);
     {
         const auto& row = tbi.GetRowByOffset(cursor.GetPosition().Y);
@@ -3320,18 +3320,18 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom()
     VERIFY_SUCCESS_NTSTATUS(si.SetViewportOrigin(true, { 0, 0 }, false));
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_IS_GREATER_THAN(cursor.GetPosition().Y, si.GetViewport().BottomInclusive());
 
     stateMachine.ProcessString(L"X");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(3, cursor.GetPosition().X);
     {
@@ -3353,7 +3353,7 @@ void ScreenBufferTests::DontResetColorsAboveVirtualBottom()
 }
 
 template<class T>
-void _FillLine(COORD position, T fillContent, TextAttribute fillAttr)
+void _FillLine(til::point position, T fillContent, TextAttribute fillAttr)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& si = gci.GetActiveOutputBuffer().GetActiveBuffer();
@@ -3364,7 +3364,7 @@ void _FillLine(COORD position, T fillContent, TextAttribute fillAttr)
 template<class T>
 void _FillLine(int line, T fillContent, TextAttribute fillAttr)
 {
-    _FillLine({ 0, gsl::narrow<SHORT>(line) }, fillContent, fillAttr);
+    _FillLine({ 0, line }, fillContent, fillAttr);
 }
 
 template<class T>
@@ -3377,7 +3377,7 @@ void _FillLines(int startLine, int endLine, T fillContent, TextAttribute fillAtt
 }
 
 template<class... T>
-bool _ValidateLineContains(COORD position, T&&... expectedContent)
+bool _ValidateLineContains(til::point position, T&&... expectedContent)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& si = gci.GetActiveOutputBuffer().GetActiveBuffer();
@@ -3398,7 +3398,7 @@ bool _ValidateLineContains(COORD position, T&&... expectedContent)
 template<class T>
 bool _ValidateLineContains(int line, T expectedContent, TextAttribute expectedAttr)
 {
-    return _ValidateLineContains({ 0, gsl::narrow<SHORT>(line) }, expectedContent, expectedAttr);
+    return _ValidateLineContains({ 0, line }, expectedContent, expectedAttr);
 }
 
 template<class T>
@@ -3517,7 +3517,7 @@ void ScreenBufferTests::ScrollOperations()
     expectedFillAttr.SetStandardErase();
 
     // Place the cursor in the center.
-    auto cursorPos = COORD{ bufferWidth / 2, (viewportStart + viewportEnd) / 2 };
+    auto cursorPos = til::point{ bufferWidth / 2, (viewportStart + viewportEnd) / 2 };
     // Unless this is reverse index, which has to be be at the top of the viewport.
     if (scrollType == ReverseIndex)
     {
@@ -3562,7 +3562,7 @@ void ScreenBufferTests::ScrollOperations()
 
     Log::Comment(L"Scrolled area should have moved up/down by given magnitude.");
     viewportChar += gsl::narrow<wchar_t>(deletedLines); // Characters dropped when deleting
-    viewportLine += gsl::narrow<SHORT>(insertedLines); // Lines skipped when inserting
+    viewportLine += insertedLines; // Lines skipped when inserting
     while (viewportLine < viewportEnd - deletedLines)
     {
         VERIFY_IS_TRUE(_ValidateLineContains(viewportLine++, viewportChar++, viewportAttr));
@@ -3607,8 +3607,8 @@ void ScreenBufferTests::InsertChars()
         L"Then insert 5 spaces at the cursor. Watch spaces get inserted, text slides right "
         L"out of the viewport, pushing some of the Qs out of the buffer.");
 
-    const auto insertLine = SHORT{ 10 };
-    auto insertPos = SHORT{ 20 };
+    const auto insertLine = til::CoordType{ 10 };
+    auto insertPos = til::CoordType{ 20 };
 
     // Place the cursor in the center of the line.
     VERIFY_SUCCEEDED(si.SetCursorPosition({ insertPos, insertLine }, true));
@@ -3767,8 +3767,8 @@ void ScreenBufferTests::DeleteChars()
         L"Then delete 5 characters at the cursor. Watch the rest of the line slide left, "
         L"replacing the deleted characters, with spaces inserted at the end of the line.");
 
-    const auto deleteLine = SHORT{ 10 };
-    auto deletePos = SHORT{ 20 };
+    const auto deleteLine = til::CoordType{ 10 };
+    auto deletePos = til::CoordType{ 20 };
 
     // Place the cursor in the center of the line.
     VERIFY_SUCCEEDED(si.SetCursorPosition({ deletePos, deleteLine }, true));
@@ -3927,9 +3927,9 @@ void ScreenBufferTests::EraseScrollbackTests()
     si.SetAttributes(TextAttribute{ FOREGROUND_GREEN | BACKGROUND_RED });
 
     // Place the cursor in the center.
-    const short centerX = bufferWidth / 2;
-    const short centerY = (si.GetViewport().Top() + si.GetViewport().BottomExclusive()) / 2;
-    const auto cursorPos = COORD{ centerX, centerY };
+    const auto centerX = bufferWidth / 2;
+    const auto centerY = (si.GetViewport().Top() + si.GetViewport().BottomExclusive()) / 2;
+    const auto cursorPos = til::point{ centerX, centerY };
 
     Log::Comment(L"Set the cursor position and erase the scrollback.");
     VERIFY_SUCCEEDED(si.SetCursorPosition(cursorPos, true));
@@ -3937,9 +3937,9 @@ void ScreenBufferTests::EraseScrollbackTests()
 
     // The viewport should move to the top of the buffer, while the cursor
     // maintains the same relative position.
-    const auto expectedOffset = COORD{ 0, -viewport.Top() };
+    const auto expectedOffset = til::point{ 0, -viewport.Top() };
     const auto expectedViewport = Viewport::Offset(viewport, expectedOffset);
-    const auto expectedCursorPos = COORD{ cursorPos.X, cursorPos.Y + expectedOffset.Y };
+    const auto expectedCursorPos = til::point{ cursorPos.X, cursorPos.Y + expectedOffset.Y };
 
     Log::Comment(L"Verify expected viewport.");
     VERIFY_ARE_EQUAL(expectedViewport, si.GetViewport());
@@ -4032,8 +4032,8 @@ void ScreenBufferTests::EraseTests()
     expectedFillAttr.SetStandardErase();
 
     // Place the cursor in the center.
-    const short centerX = bufferWidth / 2;
-    const short centerY = (si.GetViewport().Top() + si.GetViewport().BottomExclusive()) / 2;
+    const auto centerX = bufferWidth / 2;
+    const auto centerY = (si.GetViewport().Top() + si.GetViewport().BottomExclusive()) / 2;
 
     Log::Comment(L"Set the cursor position and perform the operation.");
     VERIFY_SUCCEEDED(si.SetCursorPosition({ centerX, centerY }, true));
@@ -4063,7 +4063,7 @@ void ScreenBufferTests::EraseTests()
     }
 
     // 2. Cursor Line
-    auto prefixPos = COORD{ 0, cursorPos.Y };
+    auto prefixPos = til::point{ 0, cursorPos.Y };
     auto suffixPos = cursorPos;
     // When erasing from the beginning, the cursor column is included in the range.
     suffixPos.X += (eraseType == DispatchTypes::EraseType::FromBeginning);
@@ -4143,9 +4143,9 @@ void _CommonScrollingSetup()
     stateMachine.ProcessString(L"1\n2\n3\n4");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(1, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(4, cursor.GetPosition().Y);
@@ -4167,9 +4167,9 @@ void _CommonScrollingSetup()
     stateMachine.ProcessString(L"\n5\n6\n7\n");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(4, cursor.GetPosition().Y);
@@ -4207,9 +4207,9 @@ void ScreenBufferTests::ScrollUpInMargins()
     stateMachine.ProcessString(L"\x1b[S");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(4, cursor.GetPosition().Y);
@@ -4246,9 +4246,9 @@ void ScreenBufferTests::ScrollDownInMargins()
     stateMachine.ProcessString(L"\x1b[T");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(4, cursor.GetPosition().Y);
@@ -4287,9 +4287,9 @@ void ScreenBufferTests::InsertLinesInMargins()
     stateMachine.ProcessString(L"\x1b[2L");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     // Verify cursor moved to left margin.
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
@@ -4322,9 +4322,9 @@ void ScreenBufferTests::InsertLinesInMargins()
     stateMachine.ProcessString(L"\x1b[L");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     // Verify cursor moved to left margin.
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
@@ -4364,9 +4364,9 @@ void ScreenBufferTests::DeleteLinesInMargins()
     stateMachine.ProcessString(L"\x1b[2M");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     // Verify cursor moved to left margin.
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
@@ -4399,9 +4399,9 @@ void ScreenBufferTests::DeleteLinesInMargins()
     stateMachine.ProcessString(L"\x1b[M");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     // Verify cursor moved to left margin.
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
@@ -4441,9 +4441,9 @@ void ScreenBufferTests::ReverseLineFeedInMargins()
     stateMachine.ProcessString(L"\x1bM");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(4, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(1, cursor.GetPosition().Y);
@@ -4478,9 +4478,9 @@ void ScreenBufferTests::ReverseLineFeedInMargins()
     stateMachine.ProcessString(L"\x1bM");
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(4, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y);
@@ -4533,15 +4533,15 @@ void ScreenBufferTests::LineFeedEscapeSequences()
     // We'll place the cursor in the center of the line.
     // If we are performing a line feed with carriage return,
     // the cursor should move to the leftmost column.
-    const short initialX = view.Width() / 2;
-    const short expectedX = withReturn ? 0 : initialX;
+    const auto initialX = view.Width() / 2;
+    const auto expectedX = withReturn ? 0 : initialX;
 
     {
         Log::Comment(L"Starting at the top of viewport");
-        const short initialY = 0;
-        const short expectedY = initialY + 1;
+        const auto initialY = 0;
+        const auto expectedY = initialY + 1;
         const auto expectedViewportTop = si.GetViewport().Top();
-        cursor.SetPosition(COORD{ initialX, initialY });
+        cursor.SetPosition({ initialX, initialY });
         stateMachine.ProcessString(escapeSequence);
 
         VERIFY_ARE_EQUAL(expectedX, cursor.GetPosition().X);
@@ -4552,9 +4552,9 @@ void ScreenBufferTests::LineFeedEscapeSequences()
     {
         Log::Comment(L"Starting at the bottom of viewport");
         const auto initialY = si.GetViewport().BottomInclusive();
-        const short expectedY = initialY + 1;
-        const short expectedViewportTop = si.GetViewport().Top() + 1;
-        cursor.SetPosition(COORD{ initialX, initialY });
+        const auto expectedY = initialY + 1;
+        const auto expectedViewportTop = si.GetViewport().Top() + 1;
+        cursor.SetPosition({ initialX, initialY });
         stateMachine.ProcessString(escapeSequence);
 
         VERIFY_ARE_EQUAL(expectedX, cursor.GetPosition().X);
@@ -4569,11 +4569,11 @@ void ScreenBufferTests::LineFeedEscapeSequences()
         // Make sure we clear the margins on exit so they can't break other tests.
         auto clearMargins = wil::scope_exit([&] { stateMachine.ProcessString(L"\x1b[r"); });
 
-        const short initialY = si.GetViewport().Top() + 9;
+        const auto initialY = si.GetViewport().Top() + 9;
         const auto expectedY = initialY;
         const auto expectedViewportTop = si.GetViewport().Top();
         _FillLine(initialY, L'Q', {});
-        cursor.SetPosition(COORD{ initialX, initialY });
+        cursor.SetPosition({ initialX, initialY });
         stateMachine.ProcessString(escapeSequence);
 
         VERIFY_ARE_EQUAL(expectedX, cursor.GetPosition().X);
@@ -4667,16 +4667,16 @@ void ScreenBufferTests::ScrollLines256Colors()
     stateMachine.ProcessString(scrollSeq);
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"viewport=%s", VerifyOutputTraits<SMALL_RECT>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
+        L"viewport=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(si.GetViewport().ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y);
 
     stateMachine.ProcessString(L"foo");
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     VERIFY_ARE_EQUAL(3, cursor.GetPosition().X);
     VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y);
     {
@@ -4742,55 +4742,55 @@ void ScreenBufferTests::SetOriginMode()
     Log::Comment(L"By default, setting a margin moves the cursor to the top-left of the screen.");
     cursor.SetPosition({ 40, 12 });
     stateMachine.ProcessString(L"\x1B[6;20r");
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     Log::Comment(L"Cursor addressing is relative to the top-left of the screen.");
     stateMachine.ProcessString(L"\x1B[13;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 12 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 12), cursor.GetPosition());
     Log::Comment(L"The cursor can be moved below the bottom margin.");
     stateMachine.ProcessString(L"\x1B[23;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 22 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 22), cursor.GetPosition());
 
     // Testing the effects of DECOM being set (relative cursor addressing)
     Log::Comment(L"Setting DECOM moves the cursor to the top-left of the margin area.");
     cursor.SetPosition({ 40, 12 });
     stateMachine.ProcessString(L"\x1B[?6h");
-    VERIFY_ARE_EQUAL(COORD({ 0, 5 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 5), cursor.GetPosition());
     Log::Comment(L"Setting a margin moves the cursor to the top-left of the margin area.");
     cursor.SetPosition({ 40, 12 });
     stateMachine.ProcessString(L"\x1B[6;20r");
-    VERIFY_ARE_EQUAL(COORD({ 0, 5 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 5), cursor.GetPosition());
     Log::Comment(L"Cursor addressing is relative to the top-left of the margin area.");
     stateMachine.ProcessString(L"\x1B[8;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 12 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 12), cursor.GetPosition());
     Log::Comment(L"The cursor cannot be moved below the bottom margin.");
     stateMachine.ProcessString(L"\x1B[100;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 19 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 19), cursor.GetPosition());
 
     // Testing the effects of DECOM being reset (absolute cursor addressing)
     Log::Comment(L"Resetting DECOM moves the cursor to the top-left of the screen.");
     cursor.SetPosition({ 40, 12 });
     stateMachine.ProcessString(L"\x1B[?6l");
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     Log::Comment(L"Setting a margin moves the cursor to the top-left of the screen.");
     cursor.SetPosition({ 40, 12 });
     stateMachine.ProcessString(L"\x1B[6;20r");
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     Log::Comment(L"Cursor addressing is relative to the top-left of the screen.");
     stateMachine.ProcessString(L"\x1B[13;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 12 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 12), cursor.GetPosition());
     Log::Comment(L"The cursor can be moved below the bottom margin.");
     stateMachine.ProcessString(L"\x1B[23;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 22 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 22), cursor.GetPosition());
 
     // Testing the effects of DECOM being set with no margins
     Log::Comment(L"With no margins, setting DECOM moves the cursor to the top-left of the screen.");
     stateMachine.ProcessString(L"\x1B[r");
     cursor.SetPosition({ 40, 12 });
     stateMachine.ProcessString(L"\x1B[?6h");
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     Log::Comment(L"Cursor addressing is still relative to the top-left of the screen.");
     stateMachine.ProcessString(L"\x1B[13;41H");
-    VERIFY_ARE_EQUAL(COORD({ 40, 12 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(40, 12), cursor.GetPosition());
 
     // Reset DECOM so we don't affect future tests
     stateMachine.ProcessString(L"\x1B[?6l");
@@ -4810,13 +4810,13 @@ void ScreenBufferTests::SetAutoWrapMode()
 
     Log::Comment(L"By default, output should wrap onto the next line.");
     // Output 6 characters, 3 spaces from the end of the line.
-    short startLine = 0;
+    auto startLine = 0;
     cursor.SetPosition({ 80 - 3, startLine });
     stateMachine.ProcessString(L"abcdef");
     // Half of the content should wrap onto the next line.
     VERIFY_IS_TRUE(_ValidateLineContains({ 80 - 3, startLine }, L"abc", attributes));
     VERIFY_IS_TRUE(_ValidateLineContains({ 0, startLine + 1 }, L"def", attributes));
-    VERIFY_ARE_EQUAL(COORD({ 3, startLine + 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(3, startLine + 1), cursor.GetPosition());
 
     Log::Comment(L"When DECAWM is reset, output is clamped to the line width.");
     stateMachine.ProcessString(L"\x1b[?7l");
@@ -4826,7 +4826,7 @@ void ScreenBufferTests::SetAutoWrapMode()
     stateMachine.ProcessString(L"abcdef");
     // Content should be clamped to the line width, overwriting the last char.
     VERIFY_IS_TRUE(_ValidateLineContains({ 80 - 3, startLine }, L"abf", attributes));
-    VERIFY_ARE_EQUAL(COORD({ 79, startLine }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(79, startLine), cursor.GetPosition());
 
     Log::Comment(L"When DECAWM is set, output is wrapped again.");
     stateMachine.ProcessString(L"\x1b[?7h");
@@ -4837,7 +4837,7 @@ void ScreenBufferTests::SetAutoWrapMode()
     // Half of the content should wrap onto the next line.
     VERIFY_IS_TRUE(_ValidateLineContains({ 80 - 3, startLine }, L"abc", attributes));
     VERIFY_IS_TRUE(_ValidateLineContains({ 0, startLine + 1 }, L"def", attributes));
-    VERIFY_ARE_EQUAL(COORD({ 3, startLine + 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(3, startLine + 1), cursor.GetPosition());
 }
 
 void ScreenBufferTests::HardResetBuffer()
@@ -4878,12 +4878,12 @@ void ScreenBufferTests::HardResetBuffer()
     Log::Comment(L"Write a single line of text to the buffer");
     stateMachine.ProcessString(L"Hello World!\n");
     VERIFY_IS_FALSE(isBufferClear());
-    VERIFY_ARE_EQUAL(COORD({ 0, 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 1), cursor.GetPosition());
 
     Log::Comment(L"After a reset, buffer should be clear, with cursor at 0,0");
     stateMachine.ProcessString(resetToInitialState);
     VERIFY_IS_TRUE(isBufferClear());
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
 
     Log::Comment(L"Set the background color to red");
     stateMachine.ProcessString(L"\x1b[41m");
@@ -4899,8 +4899,8 @@ void ScreenBufferTests::HardResetBuffer()
     Log::Comment(L"After a reset, buffer should be clear, with viewport and cursor at 0,0");
     stateMachine.ProcessString(resetToInitialState);
     VERIFY_IS_TRUE(isBufferClear());
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), viewport.Origin());
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), viewport.Origin());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     VERIFY_ARE_EQUAL(TextAttribute{}, si.GetAttributes());
 }
 
@@ -4915,7 +4915,7 @@ void ScreenBufferTests::RestoreDownAltBufferWithTerminalScrolling()
     auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); });
 
     auto& siMain = gci.GetActiveOutputBuffer();
-    const auto coordFontSize = siMain.GetScreenFontSize();
+    auto coordFontSize = siMain.GetScreenFontSize();
     siMain._virtualBottom = siMain._viewport.BottomInclusive();
 
     auto originalView = siMain._viewport;
@@ -4934,12 +4934,12 @@ void ScreenBufferTests::RestoreDownAltBufferWithTerminalScrolling()
         auto useMain = wil::scope_exit([&] { altBuffer.UseMainScreenBuffer(); });
 
         const auto originalSize = originalView.Dimensions();
-        const COORD doubledSize = { originalSize.X * 2, originalSize.Y * 2 };
+        const til::size doubledSize{ originalSize.X * 2, originalSize.Y * 2 };
 
         // Create some RECTs, which are dimensions in pixels, because
         // ProcessResizeWindow needs to work on rects in screen _pixel_
         // dimensions, not character sizes.
-        RECT originalClientRect{ 0 }, maximizedClientRect{ 0 };
+        til::rect originalClientRect, maximizedClientRect;
 
         originalClientRect.right = originalSize.X * coordFontSize.X;
         originalClientRect.bottom = originalSize.Y * coordFontSize.Y;
@@ -4987,24 +4987,24 @@ void ScreenBufferTests::SnapCursorWithTerminalScrolling()
     si._virtualBottom = originalView.BottomInclusive();
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"originalView=%s", VerifyOutputTraits<SMALL_RECT>::ToString(originalView.ToInclusive()).GetBuffer()));
+        L"originalView=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(originalView.ToInclusive()).GetBuffer()));
 
     Log::Comment(NoThrowString().Format(
         L"First set the viewport somewhere lower in the buffer, as if the text "
         L"was output there. Manually move the cursor there as well, so the "
         L"cursor is within that viewport."));
-    const COORD secondWindowOrigin{ 0, 10 };
+    const til::point secondWindowOrigin{ 0, 10 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, secondWindowOrigin, true));
     si.GetTextBuffer().GetCursor().SetPosition(secondWindowOrigin);
 
     const auto secondView = si._viewport;
     const auto secondVirtualBottom = si._virtualBottom;
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"secondView=%s", VerifyOutputTraits<SMALL_RECT>::ToString(secondView.ToInclusive()).GetBuffer()));
+        L"secondView=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(secondView.ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(10, secondView.Top());
     VERIFY_ARE_EQUAL(originalView.Height() + 10, secondView.BottomExclusive());
@@ -5013,16 +5013,16 @@ void ScreenBufferTests::SnapCursorWithTerminalScrolling()
     Log::Comment(NoThrowString().Format(
         L"Emulate scrolling upwards with the mouse (not moving the virtual view)"));
 
-    const COORD thirdWindowOrigin{ 0, 2 };
+    const til::point thirdWindowOrigin{ 0, 2 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, thirdWindowOrigin, false));
 
     const auto thirdView = si._viewport;
     const auto thirdVirtualBottom = si._virtualBottom;
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"thirdView=%s", VerifyOutputTraits<SMALL_RECT>::ToString(thirdView.ToInclusive()).GetBuffer()));
+        L"thirdView=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(thirdView.ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(2, thirdView.Top());
     VERIFY_ARE_EQUAL(originalView.Height() + 2, thirdView.BottomExclusive());
@@ -5036,9 +5036,9 @@ void ScreenBufferTests::SnapCursorWithTerminalScrolling()
     const auto fourthVirtualBottom = si._virtualBottom;
 
     Log::Comment(NoThrowString().Format(
-        L"cursor=%s", VerifyOutputTraits<COORD>::ToString(cursor.GetPosition()).GetBuffer()));
+        L"cursor=%s", VerifyOutputTraits<til::point>::ToString(cursor.GetPosition()).GetBuffer()));
     Log::Comment(NoThrowString().Format(
-        L"thirdView=%s", VerifyOutputTraits<SMALL_RECT>::ToString(fourthView.ToInclusive()).GetBuffer()));
+        L"thirdView=%s", VerifyOutputTraits<til::inclusive_rect>::ToString(fourthView.ToInclusive()).GetBuffer()));
 
     VERIFY_ARE_EQUAL(10, fourthView.Top());
     VERIFY_ARE_EQUAL(originalView.Height() + 10, fourthView.BottomExclusive());
@@ -5119,7 +5119,7 @@ void ScreenBufferTests::ClearAlternateBuffer()
 
 #pragma region Test SetConsoleCursorPositionImpl()
         // Reset cursor position as we do with CLS command (same params as in CMD)
-        VERIFY_SUCCEEDED(g.api->SetConsoleCursorPositionImpl(siMain, { 0 }));
+        VERIFY_SUCCEEDED(g.api->SetConsoleCursorPositionImpl(siMain, {}));
 
         // Verify state of alt buffer
         auto& altBufferCursor = altBuffer.GetTextBuffer().GetCursor();
@@ -5693,23 +5693,23 @@ void ScreenBufferTests::CursorNextPreviousLine()
     auto& cursor = si.GetTextBuffer().GetCursor();
 
     Log::Comment(L"Make sure the viewport is at 0,0");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(L"CNL without margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move down 5 lines (CNL).
     stateMachine.ProcessString(L"\x1b[5E");
     // We should end up in column 0 of line 15.
-    VERIFY_ARE_EQUAL(COORD({ 0, 15 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 15), cursor.GetPosition());
 
     Log::Comment(L"CPL without margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move up 5 lines (CPL).
     stateMachine.ProcessString(L"\x1b[5F");
     // We should end up in column 0 of line 5.
-    VERIFY_ARE_EQUAL(COORD({ 0, 5 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 5), cursor.GetPosition());
 
     // Set the margins to 8:12 (9:13 in VT coordinates).
     stateMachine.ProcessString(L"\x1b[9;13r");
@@ -5718,35 +5718,35 @@ void ScreenBufferTests::CursorNextPreviousLine()
 
     Log::Comment(L"CNL inside margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move down 5 lines (CNL).
     stateMachine.ProcessString(L"\x1b[5E");
     // We should stop on line 12, the bottom margin.
-    VERIFY_ARE_EQUAL(COORD({ 0, 12 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 12), cursor.GetPosition());
 
     Log::Comment(L"CPL inside margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move up 5 lines (CPL).
     stateMachine.ProcessString(L"\x1b[5F");
     // We should stop on line 8, the top margin.
-    VERIFY_ARE_EQUAL(COORD({ 0, 8 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 8), cursor.GetPosition());
 
     Log::Comment(L"CNL below bottom");
     // Starting from column 20 of line 13 (1 below bottom margin).
-    cursor.SetPosition(COORD{ 20, 13 });
+    cursor.SetPosition({ 20, 13 });
     // Move down 5 lines (CNL).
     stateMachine.ProcessString(L"\x1b[5E");
     // We should end up in column 0 of line 18.
-    VERIFY_ARE_EQUAL(COORD({ 0, 18 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 18), cursor.GetPosition());
 
     Log::Comment(L"CPL above top margin");
     // Starting from column 20 of line 7 (1 above top margin).
-    cursor.SetPosition(COORD{ 20, 7 });
+    cursor.SetPosition({ 20, 7 });
     // Move up 5 lines (CPL).
     stateMachine.ProcessString(L"\x1b[5F");
     // We should end up in column 0 of line 2.
-    VERIFY_ARE_EQUAL(COORD({ 0, 2 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 2), cursor.GetPosition());
 }
 
 void ScreenBufferTests::CursorPositionRelative()
@@ -5757,23 +5757,23 @@ void ScreenBufferTests::CursorPositionRelative()
     auto& cursor = si.GetTextBuffer().GetCursor();
 
     Log::Comment(L"Make sure the viewport is at 0,0");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(L"HPR without margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move forward 5 columns (HPR).
     stateMachine.ProcessString(L"\x1b[5a");
     // We should end up in column 25.
-    VERIFY_ARE_EQUAL(COORD({ 25, 10 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(25, 10), cursor.GetPosition());
 
     Log::Comment(L"VPR without margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move down 5 lines (VPR).
     stateMachine.ProcessString(L"\x1b[5e");
     // We should end up on line 15.
-    VERIFY_ARE_EQUAL(COORD({ 20, 15 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(20, 15), cursor.GetPosition());
 
     // Enable DECLRMM margin mode (future proofing for when we support it)
     stateMachine.ProcessString(L"\x1b[?69h");
@@ -5790,37 +5790,37 @@ void ScreenBufferTests::CursorPositionRelative()
 
     Log::Comment(L"HPR inside margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move forward 5 columns (HPR).
     stateMachine.ProcessString(L"\x1b[5a");
     // We should end up in column 25 (outside the right margin).
-    VERIFY_ARE_EQUAL(COORD({ 25, 10 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(25, 10), cursor.GetPosition());
 
     Log::Comment(L"VPR inside margins");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move down 5 lines (VPR).
     stateMachine.ProcessString(L"\x1b[5e");
     // We should end up on line 15 (outside the bottom margin).
-    VERIFY_ARE_EQUAL(COORD({ 20, 15 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(20, 15), cursor.GetPosition());
 
     Log::Comment(L"HPR to end of line");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move forward 9999 columns (HPR).
     stateMachine.ProcessString(L"\x1b[9999a");
     // We should end up in the rightmost column.
     const auto screenWidth = si.GetBufferSize().Width();
-    VERIFY_ARE_EQUAL(COORD({ screenWidth - 1, 10 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(screenWidth - 1, 10), cursor.GetPosition());
 
     Log::Comment(L"VPR to bottom of screen");
     // Starting from column 20 of line 10.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     // Move down 9999 lines (VPR).
     stateMachine.ProcessString(L"\x1b[9999e");
     // We should end up on the last line.
     const auto screenHeight = si.GetViewport().Height();
-    VERIFY_ARE_EQUAL(COORD({ 20, screenHeight - 1 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(20, screenHeight - 1), cursor.GetPosition());
 }
 
 void ScreenBufferTests::CursorSaveRestore()
@@ -5844,97 +5844,97 @@ void ScreenBufferTests::CursorSaveRestore()
     const auto resetDECOM = L"\x1b[?6l";
 
     Log::Comment(L"Make sure the viewport is at 0,0");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(L"Restore after save.");
     // Set the cursor position, attributes, and character set.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     si.SetAttributes(colorAttrs);
     stateMachine.ProcessString(selectGraphicsChars);
     // Save state.
     stateMachine.ProcessString(saveCursor);
     // Reset the cursor position, attributes, and character set.
-    cursor.SetPosition(COORD{ 0, 0 });
+    cursor.SetPosition({ 0, 0 });
     si.SetAttributes(defaultAttrs);
     stateMachine.ProcessString(selectAsciiChars);
     // Restore state.
     stateMachine.ProcessString(restoreCursor);
     // Verify initial position, colors, and graphic character set.
-    VERIFY_ARE_EQUAL(COORD({ 20, 10 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(20, 10), cursor.GetPosition());
     VERIFY_ARE_EQUAL(colorAttrs, si.GetAttributes());
     stateMachine.ProcessString(asciiText);
-    VERIFY_IS_TRUE(_ValidateLineContains(COORD({ 20, 10 }), graphicText, colorAttrs));
+    VERIFY_IS_TRUE(_ValidateLineContains({ 20, 10 }, graphicText, colorAttrs));
 
     Log::Comment(L"Restore again without save.");
     // Reset the cursor position, attributes, and character set.
-    cursor.SetPosition(COORD{ 0, 0 });
+    cursor.SetPosition({ 0, 0 });
     si.SetAttributes(defaultAttrs);
     stateMachine.ProcessString(selectAsciiChars);
     // Restore state.
     stateMachine.ProcessString(restoreCursor);
     // Verify initial saved position, colors, and graphic character set.
-    VERIFY_ARE_EQUAL(COORD({ 20, 10 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(20, 10), cursor.GetPosition());
     VERIFY_ARE_EQUAL(colorAttrs, si.GetAttributes());
     stateMachine.ProcessString(asciiText);
-    VERIFY_IS_TRUE(_ValidateLineContains(COORD({ 20, 10 }), graphicText, colorAttrs));
+    VERIFY_IS_TRUE(_ValidateLineContains({ 20, 10 }, graphicText, colorAttrs));
 
     Log::Comment(L"Restore after reset.");
     // Soft reset.
     stateMachine.ProcessString(L"\x1b[!p");
     // Set the cursor position, attributes, and character set.
-    cursor.SetPosition(COORD{ 20, 10 });
+    cursor.SetPosition({ 20, 10 });
     si.SetAttributes(colorAttrs);
     stateMachine.ProcessString(selectGraphicsChars);
     // Restore state.
     stateMachine.ProcessString(restoreCursor);
     // Verify home position, default attributes, and ascii character set.
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     VERIFY_ARE_EQUAL(defaultAttrs, si.GetAttributes());
     stateMachine.ProcessString(asciiText);
-    VERIFY_IS_TRUE(_ValidateLineContains(COORD({ 0, 0 }), asciiText, defaultAttrs));
+    VERIFY_IS_TRUE(_ValidateLineContains(til::point(0, 0), asciiText, defaultAttrs));
 
     Log::Comment(L"Restore origin mode.");
     // Set margins and origin mode to relative.
     stateMachine.ProcessString(L"\x1b[10;20r");
     stateMachine.ProcessString(setDECOM);
     // Verify home position inside margins.
-    VERIFY_ARE_EQUAL(COORD({ 0, 9 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 9), cursor.GetPosition());
     // Save state and reset origin mode to absolute.
     stateMachine.ProcessString(saveCursor);
     stateMachine.ProcessString(resetDECOM);
     // Verify home position at origin.
-    VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 0), cursor.GetPosition());
     // Restore state and move to home position.
     stateMachine.ProcessString(restoreCursor);
     stateMachine.ProcessString(L"\x1b[H");
     // Verify home position inside margins, i.e. relative origin mode restored.
-    VERIFY_ARE_EQUAL(COORD({ 0, 9 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(0, 9), cursor.GetPosition());
 
     Log::Comment(L"Clamp inside top margin.");
     // Reset margins, with absolute origin, and set cursor position.
     stateMachine.ProcessString(L"\x1b[r");
     stateMachine.ProcessString(setDECOM);
-    cursor.SetPosition(COORD{ 5, 15 });
+    cursor.SetPosition({ 5, 15 });
     // Save state.
     stateMachine.ProcessString(saveCursor);
     // Set margins and restore state.
     stateMachine.ProcessString(L"\x1b[20;25r");
     stateMachine.ProcessString(restoreCursor);
     // Verify Y position is clamped inside the top margin
-    VERIFY_ARE_EQUAL(COORD({ 5, 19 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(5, 19), cursor.GetPosition());
 
     Log::Comment(L"Clamp inside bottom margin.");
     // Reset margins, with absolute origin, and set cursor position.
     stateMachine.ProcessString(L"\x1b[r");
     stateMachine.ProcessString(setDECOM);
-    cursor.SetPosition(COORD{ 5, 15 });
+    cursor.SetPosition({ 5, 15 });
     // Save state.
     stateMachine.ProcessString(saveCursor);
     // Set margins and restore state.
     stateMachine.ProcessString(L"\x1b[1;10r");
     stateMachine.ProcessString(restoreCursor);
     // Verify Y position is clamped inside the top margin
-    VERIFY_ARE_EQUAL(COORD({ 5, 9 }), cursor.GetPosition());
+    VERIFY_ARE_EQUAL(til::point(5, 9), cursor.GetPosition());
 
     // Reset origin mode and margins.
     stateMachine.ProcessString(resetDECOM);
@@ -5979,7 +5979,7 @@ void ScreenBufferTests::ScreenAlignmentPattern()
     VERIFY_IS_TRUE(areMarginsSet());
 
     // Place the cursor in the center.
-    auto cursorPos = COORD{ bufferWidth / 2, (viewportStart + viewportEnd) / 2 };
+    auto cursorPos = til::point{ bufferWidth / 2, (viewportStart + viewportEnd) / 2 };
     VERIFY_SUCCEEDED(si.SetCursorPosition(cursorPos, true));
 
     Log::Comment(L"Execute the DECALN escape sequence.");
@@ -5997,7 +5997,7 @@ void ScreenBufferTests::ScreenAlignmentPattern()
     VERIFY_IS_FALSE(areMarginsSet());
 
     Log::Comment(L"Cursor position should be moved to home.");
-    auto homePosition = COORD{ 0, viewportStart };
+    auto homePosition = til::point{ 0, viewportStart };
     VERIFY_ARE_EQUAL(homePosition, cursor.GetPosition());
 
     Log::Comment(L"Meta/rendition attributes should be reset.");
@@ -6145,12 +6145,12 @@ void ScreenBufferTests::UpdateVirtualBottomWhenCursorMovesBelowIt()
     VERIFY_ARE_EQUAL(initialVirtualBottom, si._virtualBottom);
 
     Log::Comment(L"Set the initial cursor position on that virtual bottom line");
-    const auto initialCursorPos = COORD{ 0, initialVirtualBottom };
+    const auto initialCursorPos = til::point{ 0, initialVirtualBottom };
     cursor.SetPosition(initialCursorPos);
     VERIFY_ARE_EQUAL(initialCursorPos, cursor.GetPosition());
 
     Log::Comment(L"Pan down so the initial viewport has the cursor in the middle");
-    const auto initialOrigin = COORD{ 0, si.GetViewport().Top() + si.GetViewport().Height() / 2 };
+    const auto initialOrigin = til::point{ 0, si.GetViewport().Top() + si.GetViewport().Height() / 2 };
     gci.SetTerminalScrolling(false);
     VERIFY_SUCCEEDED(si.SetViewportOrigin(false, initialOrigin, false));
     VERIFY_ARE_EQUAL(initialOrigin, si.GetViewport().Origin());
@@ -6164,7 +6164,7 @@ void ScreenBufferTests::UpdateVirtualBottomWhenCursorMovesBelowIt()
     VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, content, content, content, &numBytes, nullptr, 0, 0, nullptr));
 
     Log::Comment(L"Confirm that the cursor position has moved down 10 lines");
-    const auto newCursorPos = COORD{ initialCursorPos.X, initialCursorPos.Y + 10 };
+    const auto newCursorPos = til::point{ initialCursorPos.X, initialCursorPos.Y + 10 };
     VERIFY_ARE_EQUAL(newCursorPos, cursor.GetPosition());
 
     Log::Comment(L"Confirm that the virtual bottom matches that new cursor position");
@@ -6187,7 +6187,7 @@ void ScreenBufferTests::UpdateVirtualBottomWithSetConsoleCursorPosition()
     auto& cursor = si.GetTextBuffer().GetCursor();
 
     Log::Comment(L"Pan down so the initial viewport is a couple of pages down");
-    const auto initialOrigin = COORD{ 0, si.GetViewport().Height() * 2 };
+    const auto initialOrigin = til::point{ 0, si.GetViewport().Height() * 2 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, initialOrigin, true));
     VERIFY_ARE_EQUAL(initialOrigin, si.GetViewport().Origin());
 
@@ -6210,12 +6210,12 @@ void ScreenBufferTests::UpdateVirtualBottomWithSetConsoleCursorPosition()
     VERIFY_ARE_EQUAL(initialVirtualBottom, si._virtualBottom);
 
     Log::Comment(L"Pan further down so the viewport is below the cursor");
-    const auto belowCursor = COORD{ 0, cursor.GetPosition().Y + 10 };
+    const auto belowCursor = til::point{ 0, cursor.GetPosition().Y + 10 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, belowCursor, false));
     VERIFY_ARE_EQUAL(belowCursor, si.GetViewport().Origin());
 
     Log::Comment(L"Set the cursor position one line down, still inside the virtual viewport");
-    const auto oneLineDown = COORD{ 0, cursor.GetPosition().Y + 1 };
+    const auto oneLineDown = til::point{ 0, cursor.GetPosition().Y + 1 };
     VERIFY_SUCCEEDED(g.api->SetConsoleCursorPositionImpl(si, oneLineDown));
     VERIFY_ARE_EQUAL(oneLineDown, cursor.GetPosition());
 
@@ -6226,7 +6226,7 @@ void ScreenBufferTests::UpdateVirtualBottomWithSetConsoleCursorPosition()
     VERIFY_ARE_EQUAL(initialVirtualBottom, si._virtualBottom);
 
     Log::Comment(L"Set the cursor position to the top of the buffer");
-    const auto topOfBuffer = COORD{ 0, 0 };
+    const auto topOfBuffer = til::point{ 0, 0 };
     VERIFY_SUCCEEDED(g.api->SetConsoleCursorPositionImpl(si, topOfBuffer));
     VERIFY_ARE_EQUAL(topOfBuffer, cursor.GetPosition());
 
@@ -6246,7 +6246,7 @@ void ScreenBufferTests::UpdateVirtualBottomAfterInternalSetViewportSize()
     auto& stateMachine = si.GetStateMachine();
 
     Log::Comment(L"Pan down so the initial viewport is a couple of pages down");
-    const auto initialOrigin = COORD{ 0, si.GetViewport().Height() * 2 };
+    const auto initialOrigin = til::point{ 0, si.GetViewport().Height() * 2 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, initialOrigin, true));
     VERIFY_ARE_EQUAL(initialOrigin, si.GetViewport().Origin());
 
@@ -6272,7 +6272,7 @@ void ScreenBufferTests::UpdateVirtualBottomAfterInternalSetViewportSize()
     VERIFY_ARE_EQUAL(initialVirtualBottom, si._virtualBottom);
 
     Log::Comment(L"Position the viewport just above the virtual bottom");
-    short viewportTop = si._virtualBottom - viewportSize.Y;
+    auto viewportTop = si._virtualBottom - viewportSize.Y;
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, { 0, viewportTop }, false));
     VERIFY_ARE_EQUAL(si._virtualBottom - 1, si.GetViewport().BottomInclusive());
 
@@ -6352,7 +6352,7 @@ void ScreenBufferTests::DontShrinkVirtualBottomDuringResizeWithReflowAtTop()
     auto& stateMachine = si.GetStateMachine();
 
     Log::Comment(L"Make sure the viewport is at the top of the buffer");
-    const auto bufferTop = COORD{ 0, 0 };
+    const auto bufferTop = til::point{ 0, 0 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, bufferTop, true));
     VERIFY_ARE_EQUAL(bufferTop, si.GetViewport().Origin());
 
@@ -6381,7 +6381,7 @@ void ScreenBufferTests::DontChangeVirtualBottomWithOffscreenLinefeed()
     auto& stateMachine = si.GetStateMachine();
 
     Log::Comment(L"Pan down so the initial viewport is a couple of pages down");
-    const auto initialOrigin = COORD{ 0, si.GetViewport().Height() * 2 };
+    const auto initialOrigin = til::point{ 0, si.GetViewport().Height() * 2 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, initialOrigin, true));
     VERIFY_ARE_EQUAL(initialOrigin, si.GetViewport().Origin());
 
@@ -6413,7 +6413,7 @@ void ScreenBufferTests::DontChangeVirtualBottomAfterResizeWindow()
     auto& stateMachine = si.GetStateMachine();
 
     Log::Comment(L"Pan down so the initial viewport is a couple of pages down");
-    const auto initialOrigin = COORD{ 0, si.GetViewport().Height() * 2 };
+    const auto initialOrigin = til::point{ 0, si.GetViewport().Height() * 2 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, initialOrigin, true));
     VERIFY_ARE_EQUAL(initialOrigin, si.GetViewport().Origin());
 
@@ -6450,7 +6450,7 @@ void ScreenBufferTests::DontChangeVirtualBottomWithMakeCursorVisible()
     auto& stateMachine = si.GetStateMachine();
 
     Log::Comment(L"Pan down so the initial viewport is a couple of pages down");
-    const auto initialOrigin = COORD{ 0, si.GetViewport().Height() * 2 };
+    const auto initialOrigin = til::point{ 0, si.GetViewport().Height() * 2 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, initialOrigin, true));
     VERIFY_ARE_EQUAL(initialOrigin, si.GetViewport().Origin());
 
@@ -6474,7 +6474,7 @@ void ScreenBufferTests::DontChangeVirtualBottomWithMakeCursorVisible()
     VERIFY_ARE_EQUAL(initialVirtualBottom, si._virtualBottom);
 
     Log::Comment(L"Pan further down so the viewport is below the cursor");
-    const auto belowCursor = COORD{ 0, cursor.GetPosition().Y + 10 };
+    const auto belowCursor = til::point{ 0, cursor.GetPosition().Y + 10 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, belowCursor, false));
     VERIFY_ARE_EQUAL(belowCursor, si.GetViewport().Origin());
 
@@ -6494,11 +6494,11 @@ void ScreenBufferTests::RetainHorizontalOffsetWhenMovingToBottom()
     auto& cursor = si.GetTextBuffer().GetCursor();
 
     Log::Comment(L"Make the viewport half the default width");
-    auto initialSize = COORD{ CommonState::s_csWindowWidth / 2, CommonState::s_csWindowHeight };
+    auto initialSize = til::size{ CommonState::s_csWindowWidth / 2, CommonState::s_csWindowHeight };
     si.SetViewportSize(&initialSize);
 
     Log::Comment(L"Offset the viewport both vertically and horizontally");
-    auto initialOrigin = COORD{ 10, 20 };
+    auto initialOrigin = til::point{ 10, 20 };
     VERIFY_SUCCEEDED(si.SetViewportOrigin(true, initialOrigin, true));
 
     Log::Comment(L"Verify that the virtual viewport is where it's expected to be");
@@ -6673,7 +6673,7 @@ void ScreenBufferTests::TestReflowEndOfLineColor()
     yellow.SetIndexedBackground(TextColor::DARK_YELLOW);
 
     Log::Comment(L"Make sure the viewport is at 0,0");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(L"Fill buffer with some data");
     stateMachine.ProcessString(L"\x1b[H");
@@ -6714,16 +6714,16 @@ void ScreenBufferTests::TestReflowEndOfLineColor()
     };
 
     Log::Comment(L"========== Checking the buffer state (before) ==========");
-    verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(si.GetTextBuffer(), si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"========== resize buffer ==========");
     const til::point delta{ dx, dy };
-    const til::point oldSize{ si.GetBufferSize().Dimensions() };
+    const auto oldSize = si.GetBufferSize().Dimensions();
     const auto newSize{ oldSize + delta };
-    VERIFY_SUCCEEDED(si.ResizeWithReflow(newSize.to_win32_coord()));
+    VERIFY_SUCCEEDED(si.ResizeWithReflow(newSize));
 
     Log::Comment(L"========== Checking the buffer state (after) ==========");
-    verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, false);
+    verifyBuffer(si.GetTextBuffer(), si.GetViewport().ToExclusive(), false);
 }
 
 void ScreenBufferTests::TestReflowSmallerLongLineWithColor()
@@ -6749,7 +6749,7 @@ void ScreenBufferTests::TestReflowSmallerLongLineWithColor()
     yellow.SetIndexedBackground(TextColor::DARK_YELLOW);
 
     Log::Comment(L"Make sure the viewport is at 0,0");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(L"Fill buffer with some data");
     stateMachine.ProcessString(L"\x1b[H");
@@ -6792,18 +6792,18 @@ void ScreenBufferTests::TestReflowSmallerLongLineWithColor()
     };
 
     Log::Comment(L"========== Checking the buffer state (before) ==========");
-    verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(si.GetTextBuffer(), si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"========== resize buffer ==========");
     const til::point delta{ -15, 0 };
-    const til::point oldSize{ si.GetBufferSize().Dimensions() };
+    const auto oldSize = si.GetBufferSize().Dimensions();
     const auto newSize{ oldSize + delta };
-    VERIFY_SUCCEEDED(si.ResizeWithReflow(newSize.to_win32_coord()));
+    VERIFY_SUCCEEDED(si.ResizeWithReflow(newSize));
 
     // Buffer is now 65 wide. 65 A's that wrapped onto the next row, where there
     // are also 3 B's wrapped in spaces.
     Log::Comment(L"========== Checking the buffer state (after) ==========");
-    verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, false);
+    verifyBuffer(si.GetTextBuffer(), si.GetViewport().ToExclusive(), false);
 }
 
 void ScreenBufferTests::TestReflowBiggerLongLineWithColor()
@@ -6827,7 +6827,7 @@ void ScreenBufferTests::TestReflowBiggerLongLineWithColor()
     yellow.SetIndexedBackground(TextColor::DARK_YELLOW);
 
     Log::Comment(L"Make sure the viewport is at 0,0");
-    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true));
+    VERIFY_SUCCEEDED(si.SetViewportOrigin(true, til::point(0, 0), true));
 
     Log::Comment(L"Fill buffer with some data");
     stateMachine.ProcessString(L"\x1b[H");
@@ -6873,18 +6873,18 @@ void ScreenBufferTests::TestReflowBiggerLongLineWithColor()
     };
 
     Log::Comment(L"========== Checking the buffer state (before) ==========");
-    verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, true);
+    verifyBuffer(si.GetTextBuffer(), si.GetViewport().ToExclusive(), true);
 
     Log::Comment(L"========== resize buffer ==========");
     const til::point delta{ 15, 0 };
-    const til::point oldSize{ si.GetBufferSize().Dimensions() };
+    const auto oldSize = si.GetBufferSize().Dimensions();
     const auto newSize{ oldSize + delta };
-    VERIFY_SUCCEEDED(si.ResizeWithReflow(newSize.to_win32_coord()));
+    VERIFY_SUCCEEDED(si.ResizeWithReflow(newSize));
 
     // Buffer is now 95 wide. 85 A's that de-flowed onto the first row, where
     // there are also 3 B's wrapped in spaces, and finally 5 trailing spaces.
     Log::Comment(L"========== Checking the buffer state (after) ==========");
-    verifyBuffer(si.GetTextBuffer(), til::rect{ si.GetViewport().ToInclusive() }, false);
+    verifyBuffer(si.GetTextBuffer(), si.GetViewport().ToExclusive(), false);
 }
 
 void ScreenBufferTests::TestDeferredMainBufferResize()
@@ -6917,7 +6917,7 @@ void ScreenBufferTests::TestDeferredMainBufferResize()
 
         auto& currentBuffer = gci.GetActiveOutputBuffer();
         // Set up an xterm-256 renderer for conpty
-        auto hFile = wil::unique_hfile(INVALID_HANDLE_VALUE);
+        wil::unique_hfile hFile = wil::unique_hfile(INVALID_HANDLE_VALUE);
         auto initialViewport = currentBuffer.GetViewport();
         auto vtRenderEngine = std::make_unique<Microsoft::Console::Render::Xterm256Engine>(std::move(hFile),
                                                                                            initialViewport);
@@ -6935,8 +6935,8 @@ void ScreenBufferTests::TestDeferredMainBufferResize()
 
     const til::size oldSize{ siMain->GetBufferSize().Dimensions() };
     const til::size oldView{ siMain->GetViewport().Dimensions() };
-    Log::Comment(NoThrowString().Format(L"Original buffer size: %dx%d", oldSize.width, oldSize.height));
-    Log::Comment(NoThrowString().Format(L"Original viewport: %dx%d", oldView.width, oldView.height));
+    Log::Comment(NoThrowString().Format(L"Original buffer size: %dx%d", oldSize.X, oldSize.Y));
+    Log::Comment(NoThrowString().Format(L"Original viewport: %dx%d", oldView.X, oldView.Y));
     VERIFY_ARE_NOT_EQUAL(oldSize, oldView);
 
     // printf "\x1b[?1049h" ; sleep 1 ; printf "\x1b[8;24;60t" ; sleep 1 ; printf "\x1b[?1049l" ; sleep 1 ; printf "\n"
diff --git a/src/host/ut_host/SearchTests.cpp b/src/host/ut_host/SearchTests.cpp
index 2c901cd4f4f..4e784349c49 100644
--- a/src/host/ut_host/SearchTests.cpp
+++ b/src/host/ut_host/SearchTests.cpp
@@ -57,7 +57,7 @@ class SearchTests
         return true;
     }
 
-    void DoFoundChecks(Search& s, COORD& coordStartExpected, SHORT lineDelta)
+    void DoFoundChecks(Search& s, til::point& coordStartExpected, til::CoordType lineDelta)
     {
         auto coordEndExpected = coordStartExpected;
         coordEndExpected.X += 1;
@@ -91,7 +91,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 0 };
+        til::point coordStartExpected;
         Search s(gci.renderData, L"AB", Search::Direction::Forward, Search::Sensitivity::CaseSensitive);
         DoFoundChecks(s, coordStartExpected, 1);
     }
@@ -100,7 +100,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 2, 0 };
+        til::point coordStartExpected = { 2, 0 };
         Search s(gci.renderData, L"\x304b", Search::Direction::Forward, Search::Sensitivity::CaseSensitive);
         DoFoundChecks(s, coordStartExpected, 1);
     }
@@ -109,7 +109,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 0 };
+        til::point coordStartExpected;
         Search s(gci.renderData, L"ab", Search::Direction::Forward, Search::Sensitivity::CaseInsensitive);
         DoFoundChecks(s, coordStartExpected, 1);
     }
@@ -118,7 +118,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 2, 0 };
+        til::point coordStartExpected = { 2, 0 };
         Search s(gci.renderData, L"\x304b", Search::Direction::Forward, Search::Sensitivity::CaseInsensitive);
         DoFoundChecks(s, coordStartExpected, 1);
     }
@@ -127,7 +127,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 0, 3 };
+        til::point coordStartExpected = { 0, 3 };
         Search s(gci.renderData, L"AB", Search::Direction::Backward, Search::Sensitivity::CaseSensitive);
         DoFoundChecks(s, coordStartExpected, -1);
     }
@@ -136,7 +136,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 2, 3 };
+        til::point coordStartExpected = { 2, 3 };
         Search s(gci.renderData, L"\x304b", Search::Direction::Backward, Search::Sensitivity::CaseSensitive);
         DoFoundChecks(s, coordStartExpected, -1);
     }
@@ -145,7 +145,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 0, 3 };
+        til::point coordStartExpected = { 0, 3 };
         Search s(gci.renderData, L"ab", Search::Direction::Backward, Search::Sensitivity::CaseInsensitive);
         DoFoundChecks(s, coordStartExpected, -1);
     }
@@ -154,7 +154,7 @@ class SearchTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
-        COORD coordStartExpected = { 2, 3 };
+        til::point coordStartExpected = { 2, 3 };
         Search s(gci.renderData, L"\x304b", Search::Direction::Backward, Search::Sensitivity::CaseInsensitive);
         DoFoundChecks(s, coordStartExpected, -1);
     }
diff --git a/src/host/ut_host/SelectionTests.cpp b/src/host/ut_host/SelectionTests.cpp
index 1185de27023..d8d7a6aaf8a 100644
--- a/src/host/ut_host/SelectionTests.cpp
+++ b/src/host/ut_host/SelectionTests.cpp
@@ -71,7 +71,7 @@ class SelectionTests
                 // ensure each rectangle is exactly the width requested (block selection)
                 const auto psrRect = &selectionRects[iRect];
 
-                const short sRectangleLineNumber = (short)iRect + m_pSelection->_srSelectionRect.Top;
+                const auto sRectangleLineNumber = (til::CoordType)iRect + m_pSelection->_srSelectionRect.Top;
 
                 VERIFY_ARE_EQUAL(psrRect->Top, sRectangleLineNumber);
                 VERIFY_ARE_EQUAL(psrRect->Bottom, sRectangleLineNumber);
@@ -170,7 +170,7 @@ class SelectionTests
                     // ensure each rectangle is exactly the width requested (block selection)
                     const auto psrRect = &selectionRects[iRect];
 
-                    const short sRectangleLineNumber = (short)iRect + m_pSelection->_srSelectionRect.Top;
+                    const auto sRectangleLineNumber = (til::CoordType)iRect + m_pSelection->_srSelectionRect.Top;
 
                     VERIFY_ARE_EQUAL(psrRect->Top, sRectangleLineNumber);
                     VERIFY_ARE_EQUAL(psrRect->Bottom, sRectangleLineNumber);
@@ -304,15 +304,15 @@ class SelectionTests
         VerifyGetSelectionRects_LineMode();
     }
 
-    void TestBisectSelectionDelta(SHORT sTargetX, SHORT sTargetY, SHORT sLength, SHORT sDeltaLeft, SHORT sDeltaRight)
+    void TestBisectSelectionDelta(til::CoordType sTargetX, til::CoordType sTargetY, til::CoordType sLength, til::CoordType sDeltaLeft, til::CoordType sDeltaRight)
     {
         const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
         const auto& screenInfo = gci.GetActiveOutputBuffer();
 
-        short sStringLength;
-        COORD coordTargetPoint;
-        SMALL_RECT srSelection;
-        SMALL_RECT srOriginal;
+        til::CoordType sStringLength;
+        til::point coordTargetPoint;
+        til::inclusive_rect srSelection;
+        til::inclusive_rect srOriginal;
 
         sStringLength = sLength;
         coordTargetPoint.X = sTargetX;
@@ -331,8 +331,8 @@ class SelectionTests
         srOriginal.Left = srSelection.Left;
         srOriginal.Right = srSelection.Right;
 
-        COORD startPos{ sTargetX, sTargetY };
-        COORD endPos{ base::ClampAdd(sTargetX, sLength), sTargetY };
+        til::point startPos{ sTargetX, sTargetY };
+        til::point endPos{ sTargetX + sLength, sTargetY };
         const auto selectionRects = screenInfo.GetTextBuffer().GetTextRects(startPos, endPos, false, false);
 
         VERIFY_ARE_EQUAL(static_cast<size_t>(1), selectionRects.size());
@@ -448,9 +448,9 @@ class SelectionInputTests
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
         // 80x80 box
-        const SHORT sRowWidth = 80;
+        const til::CoordType sRowWidth = 80;
 
-        SMALL_RECT srectEdges;
+        til::inclusive_rect srectEdges;
         srectEdges.Left = srectEdges.Top = 0;
         srectEdges.Right = srectEdges.Bottom = sRowWidth - 1;
 
@@ -472,7 +472,7 @@ class SelectionInputTests
 
         // backup text info position over remainder of text execution duration
         auto& textBuffer = gci.GetActiveOutputBuffer().GetTextBuffer();
-        COORD coordOldTextInfoPos;
+        til::point coordOldTextInfoPos;
         coordOldTextInfoPos.X = textBuffer.GetCursor().GetPosition().X;
         coordOldTextInfoPos.Y = textBuffer.GetCursor().GetPosition().Y;
 
@@ -490,8 +490,8 @@ class SelectionInputTests
         VERIFY_IS_TRUE(fResult);
 
         // now let's get some actual data
-        COORD coordStart;
-        COORD coordEnd;
+        til::point coordStart;
+        til::point coordEnd;
 
         fResult = Selection::s_GetInputLineBoundaries(&coordStart, &coordEnd);
         VERIFY_IS_TRUE(fResult);
@@ -502,9 +502,9 @@ class SelectionInputTests
 
         // ending position can vary. it's in one of two spots
         // 1. If the original cooked cursor was valid (which it was this first time), it's NumberOfVisibleChars ahead.
-        COORD coordFinalPos;
+        til::point coordFinalPos;
 
-        const short cCharsToAdjust = ((short)readData.VisibleCharCount() - 1); // then -1 to be on the last piece of text, not past it
+        const auto cCharsToAdjust = ((til::CoordType)readData.VisibleCharCount() - 1); // then -1 to be on the last piece of text, not past it
 
         coordFinalPos.X = (readData.OriginalCursorPosition().X + cCharsToAdjust) % sRowWidth;
         coordFinalPos.Y = readData.OriginalCursorPosition().Y + ((readData.OriginalCursorPosition().X + cCharsToAdjust) / sRowWidth);
@@ -540,8 +540,8 @@ class SelectionInputTests
         screenInfo.Write(OutputCellIterator(text));
 
         // Get the left and right side of the text we inserted (right is one past the end)
-        const COORD left = { 0, 0 };
-        const COORD right = { gsl::narrow<SHORT>(text.length()), 0 };
+        const til::point left;
+        const til::point right{ gsl::narrow<til::CoordType>(text.length()), 0 };
 
         // Get the selection instance and buffer size
         auto& sel = Selection::Instance();
@@ -587,8 +587,8 @@ class SelectionInputTests
         screenInfo.Write(OutputCellIterator(text));
 
         // Get the left and right side of the text we inserted (right is one past the end)
-        const COORD left = { 0, 0 };
-        const COORD right = { gsl::narrow<SHORT>(text.length()), 0 };
+        const til::point left;
+        const til::point right = { gsl::narrow<til::CoordType>(text.length()), 0 };
 
         // Get the selection instance and buffer size
         auto& sel = Selection::Instance();
diff --git a/src/host/ut_host/TextBufferIteratorTests.cpp b/src/host/ut_host/TextBufferIteratorTests.cpp
index 52ae10833da..e7e9a149d26 100644
--- a/src/host/ut_host/TextBufferIteratorTests.cpp
+++ b/src/host/ut_host/TextBufferIteratorTests.cpp
@@ -26,13 +26,13 @@ template<typename T>
 T GetIterator();
 
 template<typename T>
-T GetIteratorAt(COORD at);
+T GetIteratorAt(til::point at);
 
 template<typename T>
 T GetIteratorWithAdvance();
 
 template<>
-TextBufferCellIterator GetIteratorAt<TextBufferCellIterator>(COORD at)
+TextBufferCellIterator GetIteratorAt<TextBufferCellIterator>(til::point at)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto& outputBuffer = gci.GetActiveOutputBuffer();
@@ -42,7 +42,7 @@ TextBufferCellIterator GetIteratorAt<TextBufferCellIterator>(COORD at)
 template<>
 TextBufferCellIterator GetIterator<TextBufferCellIterator>()
 {
-    return GetIteratorAt<TextBufferCellIterator>({ 0 });
+    return GetIteratorAt<TextBufferCellIterator>({});
 }
 
 template<>
@@ -52,7 +52,7 @@ TextBufferCellIterator GetIteratorWithAdvance<TextBufferCellIterator>()
 }
 
 template<>
-TextBufferTextIterator GetIteratorAt<TextBufferTextIterator>(COORD at)
+TextBufferTextIterator GetIteratorAt<TextBufferTextIterator>(til::point at)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto& outputBuffer = gci.GetActiveOutputBuffer();
@@ -62,7 +62,7 @@ TextBufferTextIterator GetIteratorAt<TextBufferTextIterator>(COORD at)
 template<>
 TextBufferTextIterator GetIterator<TextBufferTextIterator>()
 {
-    return GetIteratorAt<TextBufferTextIterator>({ 0 });
+    return GetIteratorAt<TextBufferTextIterator>({});
 }
 
 template<>
@@ -144,7 +144,7 @@ class TextBufferIteratorTests
     {
         const auto it = GetIterator<T>();
 
-        COORD oneOff = it._pos;
+        auto oneOff = it._pos;
         oneOff.X++;
         const auto it2 = GetIteratorAt<T>(oneOff);
 
@@ -160,8 +160,8 @@ class TextBufferIteratorTests
         auto it = GetIterator<T>();
 
         ptrdiff_t diffUnit = 3;
-        COORD expectedPos = it._pos;
-        expectedPos.X += gsl::narrow<SHORT>(diffUnit);
+        auto expectedPos = it._pos;
+        expectedPos.X += gsl::narrow<til::CoordType>(diffUnit);
         const auto itExpected = GetIteratorAt<T>(expectedPos);
 
         it += diffUnit;
@@ -178,8 +178,8 @@ class TextBufferIteratorTests
         auto itExpected = GetIteratorWithAdvance<T>();
 
         ptrdiff_t diffUnit = 3;
-        COORD pos = itExpected._pos;
-        pos.X += gsl::narrow<SHORT>(diffUnit);
+        til::point pos = itExpected._pos;
+        pos.X += gsl::narrow<til::CoordType>(diffUnit);
         auto itOffset = GetIteratorAt<T>(pos);
 
         itOffset -= diffUnit;
@@ -195,7 +195,7 @@ class TextBufferIteratorTests
     {
         auto itActual = GetIterator<T>();
 
-        COORD expectedPos = itActual._pos;
+        til::point expectedPos = itActual._pos;
         expectedPos.X++;
         const auto itExpected = GetIteratorAt<T>(expectedPos);
 
@@ -212,7 +212,7 @@ class TextBufferIteratorTests
     {
         const auto itExpected = GetIteratorWithAdvance<T>();
 
-        COORD pos = itExpected._pos;
+        til::point pos = itExpected._pos;
         pos.X++;
         auto itActual = GetIteratorAt<T>(pos);
 
@@ -229,7 +229,7 @@ class TextBufferIteratorTests
     {
         auto it = GetIterator<T>();
 
-        COORD expectedPos = it._pos;
+        auto expectedPos = it._pos;
         expectedPos.X++;
         const auto itExpected = GetIteratorAt<T>(expectedPos);
 
@@ -246,7 +246,7 @@ class TextBufferIteratorTests
     {
         const auto itExpected = GetIteratorWithAdvance<T>();
 
-        COORD pos = itExpected._pos;
+        til::point pos = itExpected._pos;
         pos.X++;
         auto itActual = GetIteratorAt<T>(pos);
 
@@ -264,8 +264,8 @@ class TextBufferIteratorTests
         auto it = GetIterator<T>();
 
         ptrdiff_t diffUnit = 3;
-        COORD expectedPos = it._pos;
-        expectedPos.X += gsl::narrow<SHORT>(diffUnit);
+        auto expectedPos = it._pos;
+        expectedPos.X += gsl::narrow<til::CoordType>(diffUnit);
         const auto itExpected = GetIteratorAt<T>(expectedPos);
 
         const auto itActual = it + diffUnit;
@@ -282,8 +282,8 @@ class TextBufferIteratorTests
         auto itExpected = GetIteratorWithAdvance<T>();
 
         ptrdiff_t diffUnit = 3;
-        COORD pos = itExpected._pos;
-        pos.X += gsl::narrow<SHORT>(diffUnit);
+        til::point pos = itExpected._pos;
+        pos.X += gsl::narrow<til::CoordType>(diffUnit);
         auto itOffset = GetIteratorAt<T>(pos);
 
         const auto itActual = itOffset - diffUnit;
@@ -513,7 +513,7 @@ void TextBufferIteratorTests::ConstructedNoLimit()
     const auto& textBuffer = outputBuffer.GetTextBuffer();
     const auto& bufferSize = textBuffer.GetSize();
 
-    TextBufferCellIterator it(textBuffer, { 0 });
+    TextBufferCellIterator it(textBuffer, {});
 
     VERIFY_IS_TRUE(it, L"Iterator is valid.");
     VERIFY_ARE_EQUAL(bufferSize, it._bounds, L"Bounds match the bounds of the text buffer.");
@@ -540,14 +540,14 @@ void TextBufferIteratorTests::ConstructedLimits()
     const auto& outputBuffer = gci.GetActiveOutputBuffer();
     const auto& textBuffer = outputBuffer.GetTextBuffer();
 
-    SMALL_RECT limits;
+    til::inclusive_rect limits;
     limits.Top = 1;
     limits.Bottom = 1;
     limits.Left = 3;
     limits.Right = 5;
     const auto viewport = Microsoft::Console::Types::Viewport::FromInclusive(limits);
 
-    COORD pos;
+    til::point pos;
     pos.X = limits.Left;
     pos.Y = limits.Top;
 
@@ -568,16 +568,17 @@ void TextBufferIteratorTests::ConstructedLimits()
 
     // Verify throws for out of range.
     VERIFY_THROWS_SPECIFIC(TextBufferCellIterator(textBuffer,
-                                                  { 0 },
+                                                  {},
                                                   viewport),
                            wil::ResultException,
                            [](wil::ResultException& e) { return e.GetErrorCode() == E_INVALIDARG; });
 
     // Verify throws for limit not inside buffer
     const auto bufferSize = textBuffer.GetSize();
+    const auto invalidViewport = Viewport::FromInclusive({ bufferSize.Left(), bufferSize.Top(), bufferSize.RightInclusive() + 1, bufferSize.BottomInclusive() + 1 });
     VERIFY_THROWS_SPECIFIC(TextBufferCellIterator(textBuffer,
                                                   pos,
-                                                  Microsoft::Console::Types::Viewport::FromInclusive(bufferSize.ToExclusive())),
+                                                  invalidViewport),
                            wil::ResultException,
                            [](wil::ResultException& e) { return e.GetErrorCode() == E_INVALIDARG; });
 }
diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp
index 8494959274a..eae3b069659 100644
--- a/src/host/ut_host/TextBufferTests.cpp
+++ b/src/host/ut_host/TextBufferTests.cpp
@@ -69,9 +69,9 @@ class TextBufferTests
 
     TextBuffer& GetTbi();
 
-    SHORT GetBufferWidth();
+    til::CoordType GetBufferWidth();
 
-    SHORT GetBufferHeight();
+    til::CoordType GetBufferHeight();
 
     TEST_METHOD(TestBufferRowByOffset);
 
@@ -82,10 +82,10 @@ class TextBufferTests
     TEST_METHOD(TestDoubleBytePadFlag);
 
     void DoBoundaryTest(PCWCHAR const pwszInputString,
-                        const short cLength,
-                        const short cMax,
-                        const short cLeft,
-                        const short cRight);
+                        const til::CoordType cLength,
+                        const til::CoordType cMax,
+                        const til::CoordType cLeft,
+                        const til::CoordType cRight);
 
     TEST_METHOD(TestBoundaryMeasuresRegularString);
 
@@ -99,7 +99,7 @@ class TextBufferTests
 
     TEST_METHOD(TestNewlineCursor);
 
-    void TestLastNonSpace(const short cursorPosY);
+    void TestLastNonSpace(const til::CoordType cursorPosY);
 
     TEST_METHOD(TestGetLastNonSpaceCharacter);
 
@@ -171,12 +171,12 @@ TextBuffer& TextBufferTests::GetTbi()
     return gci.GetActiveOutputBuffer().GetTextBuffer();
 }
 
-SHORT TextBufferTests::GetBufferWidth()
+til::CoordType TextBufferTests::GetBufferWidth()
 {
     return GetTbi().GetSize().Width();
 }
 
-SHORT TextBufferTests::GetBufferHeight()
+til::CoordType TextBufferTests::GetBufferHeight()
 {
     return GetTbi().GetSize().Height();
 }
@@ -188,7 +188,7 @@ void TextBufferTests::TestBufferRowByOffset()
 
     VERIFY_IS_TRUE(csBufferHeight > 20);
 
-    short sId = csBufferHeight / 2 - 5;
+    auto sId = csBufferHeight / 2 - 5;
 
     const auto& row = textBuffer.GetRowByOffset(sId);
     VERIFY_ARE_EQUAL(row.GetId(), sId);
@@ -303,17 +303,17 @@ void TextBufferTests::TestDoubleBytePadFlag()
 }
 
 void TextBufferTests::DoBoundaryTest(PCWCHAR const pwszInputString,
-                                     const short cLength,
-                                     const short cMax,
-                                     const short cLeft,
-                                     const short cRight)
+                                     const til::CoordType cLength,
+                                     const til::CoordType cMax,
+                                     const til::CoordType cLeft,
+                                     const til::CoordType cRight)
 {
     auto& textBuffer = GetTbi();
 
     auto& charRow = textBuffer._GetFirstRow().GetCharRow();
 
     // copy string into buffer
-    for (size_t i = 0; i < static_cast<size_t>(cLength); ++i)
+    for (til::CoordType i = 0; i < cLength; ++i)
     {
         charRow.GlyphAt(i) = { &pwszInputString[i], 1 };
     }
@@ -328,9 +328,9 @@ void TextBufferTests::DoBoundaryTest(PCWCHAR const pwszInputString,
     }
 
     // left edge should be 0 since there are no leading spaces
-    VERIFY_ARE_EQUAL(charRow.MeasureLeft(), static_cast<size_t>(cLeft));
+    VERIFY_ARE_EQUAL(charRow.MeasureLeft(), cLeft);
     // right edge should be one past the index of the last character or the string length
-    VERIFY_ARE_EQUAL(charRow.MeasureRight(), static_cast<size_t>(cRight));
+    VERIFY_ARE_EQUAL(charRow.MeasureRight(), cRight);
 }
 
 void TextBufferTests::TestBoundaryMeasuresRegularString()
@@ -515,7 +515,7 @@ void TextBufferTests::TestNewlineCursor()
     // This is okay because the backing circular buffer changes, not the logical screen position (final visible line of the buffer)
 }
 
-void TextBufferTests::TestLastNonSpace(const short cursorPosY)
+void TextBufferTests::TestLastNonSpace(const til::CoordType cursorPosY)
 {
     auto& textBuffer = GetTbi();
     textBuffer.GetCursor().SetYPosition(cursorPosY);
@@ -531,7 +531,7 @@ void TextBufferTests::TestLastNonSpace(const short cursorPosY)
     auto coordExpected = textBuffer.GetCursor().GetPosition();
 
     // Try to get the X position from the current cursor position.
-    coordExpected.X = static_cast<short>(textBuffer.GetRowByOffset(coordExpected.Y).GetCharRow().MeasureRight()) - 1;
+    coordExpected.X = static_cast<til::CoordType>(textBuffer.GetRowByOffset(coordExpected.Y).GetCharRow().MeasureRight()) - 1;
 
     // If we went negative, this row was empty and we need to continue seeking upward...
     // - As long as X is negative (empty rows)
@@ -539,7 +539,7 @@ void TextBufferTests::TestLastNonSpace(const short cursorPosY)
     while (coordExpected.X < 0 && coordExpected.Y > 0)
     {
         coordExpected.Y--;
-        coordExpected.X = static_cast<short>(textBuffer.GetRowByOffset(coordExpected.Y).GetCharRow().MeasureRight()) - 1;
+        coordExpected.X = static_cast<til::CoordType>(textBuffer.GetRowByOffset(coordExpected.Y).GetCharRow().MeasureRight()) - 1;
     }
 
     VERIFY_ARE_EQUAL(coordLastNonSpace.X, coordExpected.X);
@@ -601,13 +601,13 @@ void TextBufferTests::TestIncrementCircularBuffer()
 
     Log::Comment(L"Test 1 = FirstRow of circular buffer is not the final row of the buffer");
     Log::Comment(L"Test 2 = FirstRow of circular buffer IS THE FINAL ROW of the buffer (and therefore circles)");
-    short rgRowsToTest[] = { 2, sBufferHeight - 1 };
+    til::CoordType rgRowsToTest[] = { 2, sBufferHeight - 1 };
 
     for (UINT iTestIndex = 0; iTestIndex < ARRAYSIZE(rgRowsToTest); iTestIndex++)
     {
         const auto iRowToTestIndex = rgRowsToTest[iTestIndex];
 
-        short iNextRowIndex = iRowToTestIndex + 1;
+        auto iNextRowIndex = iRowToTestIndex + 1;
         // if we're at or crossing the height, loop back to 0 (circular buffer)
         if (iNextRowIndex >= sBufferHeight)
         {
@@ -1750,7 +1750,7 @@ void TextBufferTests::ResizeTraditional()
     bool shrinkY;
     VERIFY_SUCCEEDED(TestData::TryGetValue(L"shrinkY", shrinkY), L"Shrink Y = true, Grow Y = false");
 
-    const COORD smallSize = { 5, 5 };
+    const til::size smallSize = { 5, 5 };
     const TextAttribute defaultAttr(0);
 
     TextBuffer buffer(smallSize, defaultAttr, 12, false, _renderer);
@@ -1846,13 +1846,13 @@ void TextBufferTests::ResizeTraditional()
 void TextBufferTests::ResizeTraditionalRotationPreservesHighUnicode()
 {
     // Set up a text buffer for us
-    const COORD bufferSize{ 80, 10 };
+    const til::size bufferSize{ 80, 10 };
     const UINT cursorSize = 12;
     const TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
 
     // Get a position inside the buffer
-    const COORD pos{ 2, 1 };
+    const til::point pos{ 2, 1 };
     auto position = _buffer->_storage[pos.Y].GetCharRow().GlyphAt(pos.X);
 
     // Fill it up with a sequence that will have to hit the high unicode storage.
@@ -1867,8 +1867,8 @@ void TextBufferTests::ResizeTraditionalRotationPreservesHighUnicode()
     VERIFY_ARE_EQUAL(String(bButton), String(readBackText.data(), gsl::narrow<int>(readBackText.size())));
 
     // Make it the first row in the buffer so it will rotate around when we resize and cause renumbering
-    const SHORT delta = _buffer->GetFirstRowIndex() - pos.Y;
-    const COORD newPos{ pos.X, pos.Y + delta };
+    const auto delta = _buffer->GetFirstRowIndex() - pos.Y;
+    const til::point newPos{ pos.X, pos.Y + delta };
 
     _buffer->_SetFirstRowIndex(pos.Y);
 
@@ -1888,13 +1888,13 @@ void TextBufferTests::ResizeTraditionalRotationPreservesHighUnicode()
 void TextBufferTests::ScrollBufferRotationPreservesHighUnicode()
 {
     // Set up a text buffer for us
-    const COORD bufferSize{ 80, 10 };
+    const til::size bufferSize{ 80, 10 };
     const UINT cursorSize = 12;
     const TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
 
     // Get a position inside the buffer
-    const COORD pos{ 2, 1 };
+    const til::point pos{ 2, 1 };
     auto position = _buffer->_storage[pos.Y].GetCharRow().GlyphAt(pos.X);
 
     // Fill it up with a sequence that will have to hit the high unicode storage.
@@ -1909,8 +1909,8 @@ void TextBufferTests::ScrollBufferRotationPreservesHighUnicode()
     VERIFY_ARE_EQUAL(String(fire), String(readBackText.data(), gsl::narrow<int>(readBackText.size())));
 
     // Prepare a delta and the new position we expect the symbol to be moved into.
-    const SHORT delta = 5;
-    const COORD newPos{ pos.X, pos.Y + delta };
+    const auto delta = 5;
+    const til::point newPos{ pos.X, pos.Y + delta };
 
     // Scroll the row with our data by delta.
     _buffer->ScrollRows(pos.Y, 1, delta);
@@ -1928,13 +1928,13 @@ void TextBufferTests::ScrollBufferRotationPreservesHighUnicode()
 void TextBufferTests::ResizeTraditionalHighUnicodeRowRemoval()
 {
     // Set up a text buffer for us
-    const COORD bufferSize{ 80, 10 };
+    const til::size bufferSize{ 80, 10 };
     const UINT cursorSize = 12;
     const TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
 
     // Get a position inside the buffer in the bottom row
-    const COORD pos{ 0, bufferSize.Y - 1 };
+    const til::point pos{ 0, bufferSize.Y - 1 };
     auto position = _buffer->_storage[pos.Y].GetCharRow().GlyphAt(pos.X);
 
     // Fill it up with a sequence that will have to hit the high unicode storage.
@@ -1951,7 +1951,7 @@ void TextBufferTests::ResizeTraditionalHighUnicodeRowRemoval()
     VERIFY_ARE_EQUAL(1u, _buffer->GetUnicodeStorage()._map.size(), L"There should be one item in the map.");
 
     // Perform resize to trim off the row of the buffer that included the emoji
-    COORD trimmedBufferSize{ bufferSize.X, bufferSize.Y - 1 };
+    til::size trimmedBufferSize{ bufferSize.X, bufferSize.Y - 1 };
 
     VERIFY_NT_SUCCESS(_buffer->ResizeTraditional(trimmedBufferSize));
 
@@ -1963,13 +1963,13 @@ void TextBufferTests::ResizeTraditionalHighUnicodeRowRemoval()
 void TextBufferTests::ResizeTraditionalHighUnicodeColumnRemoval()
 {
     // Set up a text buffer for us
-    const COORD bufferSize{ 80, 10 };
+    const til::size bufferSize{ 80, 10 };
     const UINT cursorSize = 12;
     const TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
 
     // Get a position inside the buffer in the last column
-    const COORD pos{ bufferSize.X - 1, 0 };
+    const til::point pos{ bufferSize.X - 1, 0 };
     auto position = _buffer->_storage[pos.Y].GetCharRow().GlyphAt(pos.X);
 
     // Fill it up with a sequence that will have to hit the high unicode storage.
@@ -1986,7 +1986,7 @@ void TextBufferTests::ResizeTraditionalHighUnicodeColumnRemoval()
     VERIFY_ARE_EQUAL(1u, _buffer->GetUnicodeStorage()._map.size(), L"There should be one item in the map.");
 
     // Perform resize to trim off the column of the buffer that included the emoji
-    COORD trimmedBufferSize{ bufferSize.X - 1, bufferSize.Y };
+    til::size trimmedBufferSize{ bufferSize.X - 1, bufferSize.Y };
 
     VERIFY_NT_SUCCESS(_buffer->ResizeTraditional(trimmedBufferSize));
 
@@ -1995,7 +1995,7 @@ void TextBufferTests::ResizeTraditionalHighUnicodeColumnRemoval()
 
 void TextBufferTests::TestBurrito()
 {
-    COORD bufferSize{ 80, 9001 };
+    til::size bufferSize{ 80, 9001 };
     UINT cursorSize = 12;
     TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2063,14 +2063,14 @@ void TextBufferTests::WriteLinesToBuffer(const std::vector<std::wstring>& text,
             }
 
             OutputCellIterator iter{ line };
-            buffer.Write(iter, { 0, gsl::narrow<SHORT>(row) }, wrap);
+            buffer.Write(iter, { 0, gsl::narrow<til::CoordType>(row) }, wrap);
         }
     }
 }
 
 void TextBufferTests::GetWordBoundaries()
 {
-    COORD bufferSize{ 80, 9001 };
+    til::size bufferSize{ 80, 9001 };
     UINT cursorSize = 12;
     TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2081,18 +2081,18 @@ void TextBufferTests::GetWordBoundaries()
     WriteLinesToBuffer(text, *_buffer);
 
     // Test Data:
-    // - COORD - starting position
-    // - COORD - expected result (accessibilityMode = false)
-    // - COORD - expected result (accessibilityMode = true)
+    // - til::point - starting position
+    // - til::point - expected result (accessibilityMode = false)
+    // - til::point - expected result (accessibilityMode = true)
     struct ExpectedResult
     {
-        COORD accessibilityModeDisabled;
-        COORD accessibilityModeEnabled;
+        til::point accessibilityModeDisabled;
+        til::point accessibilityModeEnabled;
     };
 
     struct Test
     {
-        COORD startPos;
+        til::point startPos;
         ExpectedResult expected;
     };
 
@@ -2134,7 +2134,7 @@ void TextBufferTests::GetWordBoundaries()
     const std::wstring_view delimiters = L" ";
     for (const auto& test : testData)
     {
-        Log::Comment(NoThrowString().Format(L"COORD (%hd, %hd)", test.startPos.X, test.startPos.Y));
+        Log::Comment(NoThrowString().Format(L"til::point (%hd, %hd)", test.startPos.X, test.startPos.Y));
         const auto result = _buffer->GetWordStart(test.startPos, delimiters, accessibilityMode);
         const auto expected = accessibilityMode ? test.expected.accessibilityModeEnabled : test.expected.accessibilityModeDisabled;
         VERIFY_ARE_EQUAL(expected, result);
@@ -2170,7 +2170,7 @@ void TextBufferTests::GetWordBoundaries()
 
     for (const auto& test : testData)
     {
-        Log::Comment(NoThrowString().Format(L"COORD (%hd, %hd)", test.startPos.X, test.startPos.Y));
+        Log::Comment(NoThrowString().Format(L"til::point (%hd, %hd)", test.startPos.X, test.startPos.Y));
         auto result = _buffer->GetWordEnd(test.startPos, delimiters, accessibilityMode);
         const auto expected = accessibilityMode ? test.expected.accessibilityModeEnabled : test.expected.accessibilityModeDisabled;
         VERIFY_ARE_EQUAL(expected, result);
@@ -2179,7 +2179,7 @@ void TextBufferTests::GetWordBoundaries()
 
 void TextBufferTests::MoveByWord()
 {
-    COORD bufferSize{ 80, 9001 };
+    til::size bufferSize{ 80, 9001 };
     UINT cursorSize = 12;
     TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2190,18 +2190,18 @@ void TextBufferTests::MoveByWord()
     WriteLinesToBuffer(text, *_buffer);
 
     // Test Data:
-    // - COORD - starting position
-    // - COORD - expected result (moving forwards)
-    // - COORD - expected result (moving backwards)
+    // - til::point - starting position
+    // - til::point - expected result (moving forwards)
+    // - til::point - expected result (moving backwards)
     struct ExpectedResult
     {
-        COORD moveForwards;
-        COORD moveBackwards;
+        til::point moveForwards;
+        til::point moveBackwards;
     };
 
     struct Test
     {
-        COORD startPos;
+        til::point startPos;
         ExpectedResult expected;
     };
 
@@ -2247,7 +2247,7 @@ void TextBufferTests::MoveByWord()
         Log::Comment(NoThrowString().Format(L"COORD (%hd, %hd)", test.startPos.X, test.startPos.Y));
         auto pos{ test.startPos };
         const auto result = movingForwards ?
-                                _buffer->MoveToNextWord(pos, delimiters, til::point{ lastCharPos }) :
+                                _buffer->MoveToNextWord(pos, delimiters, lastCharPos) :
                                 _buffer->MoveToPreviousWord(pos, delimiters);
         const auto expected = movingForwards ? test.expected.moveForwards : test.expected.moveBackwards;
         VERIFY_ARE_EQUAL(expected, pos);
@@ -2285,7 +2285,7 @@ void TextBufferTests::GetGlyphBoundaries()
     bool wideGlyph;
     VERIFY_SUCCEEDED(TestData::TryGetValue(L"wideGlyph", wideGlyph), L"Get wide glyph variant");
 
-    COORD bufferSize{ 10, 10 };
+    til::size bufferSize{ 10, 10 };
     UINT cursorSize = 12;
     TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2301,7 +2301,7 @@ void TextBufferTests::GetGlyphBoundaries()
     {
         Log::Comment(test.name.c_str());
         auto target = test.start;
-        _buffer->Write(iter, target.to_win32_coord());
+        _buffer->Write(iter, target);
 
         auto start = _buffer->GetGlyphStart(target);
         auto end = _buffer->GetGlyphEnd(target, true);
@@ -2321,7 +2321,7 @@ void TextBufferTests::GetTextRects()
     // It's encoded in UTF-16, as needed by the buffer.
     const auto burrito = std::wstring(L"\xD83C\xDF2F");
 
-    COORD bufferSize{ 20, 50 };
+    til::size bufferSize{ 20, 50 };
     UINT cursorSize = 12;
     TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2348,7 +2348,7 @@ void TextBufferTests::GetTextRects()
     bool blockSelection;
     VERIFY_SUCCEEDED(TestData::TryGetValue(L"blockSelection", blockSelection), L"Get 'blockSelection' variant");
 
-    std::vector<SMALL_RECT> expected{};
+    std::vector<til::inclusive_rect> expected{};
     if (blockSelection)
     {
         expected.push_back({ 1, 0, 7, 0 });
@@ -2366,8 +2366,8 @@ void TextBufferTests::GetTextRects()
         expected.push_back({ 0, 4, 7, 4 });
     }
 
-    COORD start{ 1, 0 };
-    COORD end{ 7, 4 };
+    til::point start{ 1, 0 };
+    til::point end{ 7, 4 };
     const auto result = _buffer->GetTextRects(start, end, blockSelection, false);
     VERIFY_ARE_EQUAL(expected.size(), result.size());
     for (size_t i = 0; i < expected.size(); ++i)
@@ -2401,7 +2401,7 @@ void TextBufferTests::GetText()
 
     if (!wrappedText)
     {
-        COORD bufferSize{ 10, 20 };
+        til::size bufferSize{ 10, 20 };
         UINT cursorSize = 12;
         TextAttribute attr{ 0x7f };
         auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2493,7 +2493,7 @@ void TextBufferTests::GetText()
     else
     {
         // Case 2: Wrapped Text
-        COORD bufferSize{ 5, 20 };
+        til::size bufferSize{ 5, 20 };
         UINT cursorSize = 12;
         TextAttribute attr{ 0x7f };
         auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2629,7 +2629,7 @@ void TextBufferTests::GetText()
 void TextBufferTests::HyperlinkTrim()
 {
     // Set up a text buffer for us
-    const COORD bufferSize{ 80, 10 };
+    const til::size bufferSize{ 80, 10 };
     const UINT cursorSize = 12;
     const TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2640,7 +2640,7 @@ void TextBufferTests::HyperlinkTrim()
     static constexpr std::wstring_view otherCustomId{ L"OtherCustomId" };
 
     // Set a hyperlink id in the first row and add a hyperlink to our map
-    const COORD pos{ 70, 0 };
+    const til::point pos{ 70, 0 };
     const auto id = _buffer->GetHyperlinkId(url, customId);
     TextAttribute newAttr{ 0x7f };
     newAttr.SetHyperlinkId(id);
@@ -2648,7 +2648,7 @@ void TextBufferTests::HyperlinkTrim()
     _buffer->AddHyperlinkToMap(url, id);
 
     // Set a different hyperlink id somewhere else in the buffer
-    const COORD otherPos{ 70, 5 };
+    const til::point otherPos{ 70, 5 };
     const auto otherId = _buffer->GetHyperlinkId(otherUrl, otherCustomId);
     newAttr.SetHyperlinkId(otherId);
     _buffer->GetRowByOffset(otherPos.Y).GetAttrRow().SetAttrToEnd(otherPos.X, newAttr);
@@ -2675,7 +2675,7 @@ void TextBufferTests::HyperlinkTrim()
 void TextBufferTests::NoHyperlinkTrim()
 {
     // Set up a text buffer for us
-    const COORD bufferSize{ 80, 10 };
+    const til::size bufferSize{ 80, 10 };
     const UINT cursorSize = 12;
     const TextAttribute attr{ 0x7f };
     auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer);
@@ -2684,7 +2684,7 @@ void TextBufferTests::NoHyperlinkTrim()
     static constexpr std::wstring_view customId{ L"CustomId" };
 
     // Set a hyperlink id in the first row and add a hyperlink to our map
-    const COORD pos{ 70, 0 };
+    const til::point pos{ 70, 0 };
     const auto id = _buffer->GetHyperlinkId(url, customId);
     TextAttribute newAttr{ 0x7f };
     newAttr.SetHyperlinkId(id);
@@ -2692,7 +2692,7 @@ void TextBufferTests::NoHyperlinkTrim()
     _buffer->AddHyperlinkToMap(url, id);
 
     // Set the same hyperlink id somewhere else in the buffer
-    const COORD otherPos{ 70, 5 };
+    const til::point otherPos{ 70, 5 };
     _buffer->GetRowByOffset(otherPos.Y).GetAttrRow().SetAttrToEnd(otherPos.X, newAttr);
 
     // Increment the circular buffer
diff --git a/src/host/ut_host/UtilsTests.cpp b/src/host/ut_host/UtilsTests.cpp
index 4929c4c5520..0ed977a6c12 100644
--- a/src/host/ut_host/UtilsTests.cpp
+++ b/src/host/ut_host/UtilsTests.cpp
@@ -49,43 +49,43 @@ class UtilsTests
         return true;
     }
 
-    SHORT RandomShort()
+    til::CoordType RandomCoord()
     {
-        SHORT s;
+        til::CoordType s;
 
         do
         {
-            s = (SHORT)rand() % SHORT_MAX;
-        } while (s == 0i16);
+            s = (til::CoordType)rand() % SHORT_MAX;
+        } while (s == 0);
 
         return s;
     }
 
-    void FillBothCoordsSameRandom(COORD* pcoordA, COORD* pcoordB)
+    void FillBothCoordsSameRandom(til::point* pcoordA, til::point* pcoordB)
     {
-        pcoordA->X = pcoordB->X = RandomShort();
-        pcoordA->Y = pcoordB->Y = RandomShort();
+        pcoordA->X = pcoordB->X = RandomCoord();
+        pcoordA->Y = pcoordB->Y = RandomCoord();
     }
 
-    void LogCoordinates(const COORD coordA, const COORD coordB)
+    void LogCoordinates(const til::point coordA, const til::point coordB)
     {
         Log::Comment(String().Format(L"Coordinates - A: (%d, %d) B: (%d, %d)", coordA.X, coordA.Y, coordB.X, coordB.Y));
     }
 
-    void SubtractRandom(short& psValue)
+    void SubtractRandom(til::CoordType& psValue)
     {
-        const auto sRand = RandomShort();
-        psValue -= gsl::narrow<SHORT>(std::max(sRand % psValue, 1));
+        const auto sRand = RandomCoord();
+        psValue -= std::max(sRand % psValue, 1);
     }
 
     TEST_METHOD(TestCompareCoords)
     {
         auto result = 5; // not 1, 0, or -1
-        COORD coordA;
-        COORD coordB;
+        til::point coordA;
+        til::point coordB;
 
         // Set the buffer size to be able to accommodate large values.
-        COORD coordMaxBuffer;
+        til::size coordMaxBuffer;
         coordMaxBuffer.X = SHORT_MAX;
         coordMaxBuffer.Y = SHORT_MAX;
 
diff --git a/src/host/ut_host/ViewportTests.cpp b/src/host/ut_host/ViewportTests.cpp
index 245839b08d1..9e8905d6494 100644
--- a/src/host/ut_host/ViewportTests.cpp
+++ b/src/host/ut_host/ViewportTests.cpp
@@ -13,8 +13,6 @@ using namespace WEX::Common;
 using namespace WEX::Logging;
 using namespace WEX::TestExecution;
 
-using Viewport = Microsoft::Console::Types::Viewport;
-
 class ViewportTests
 {
     TEST_CLASS(ViewportTests);
@@ -31,23 +29,23 @@ class ViewportTests
         VERIFY_ARE_EQUAL(0, v.BottomExclusive());
         VERIFY_ARE_EQUAL(0, v.Height());
         VERIFY_ARE_EQUAL(0, v.Width());
-        VERIFY_ARE_EQUAL(COORD({ 0 }), v.Origin());
-        VERIFY_ARE_EQUAL(COORD({ 0 }), v.Dimensions());
+        VERIFY_ARE_EQUAL(til::point{}, v.Origin());
+        VERIFY_ARE_EQUAL(til::size{}, v.Dimensions());
     }
 
     TEST_METHOD(CreateFromInclusive)
     {
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
         rect.Right = 20;
 
-        COORD origin;
+        til::point origin;
         origin.X = rect.Left;
         origin.Y = rect.Top;
 
-        COORD dimensions;
+        til::size dimensions;
         dimensions.X = rect.Right - rect.Left + 1;
         dimensions.Y = rect.Bottom - rect.Top + 1;
 
@@ -67,17 +65,17 @@ class ViewportTests
 
     TEST_METHOD(CreateFromExclusive)
     {
-        SMALL_RECT rect;
+        til::rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
         rect.Right = 20;
 
-        COORD origin;
+        til::point origin;
         origin.X = rect.Left;
         origin.Y = rect.Top;
 
-        COORD dimensions;
+        til::size dimensions;
         dimensions.X = rect.Right - rect.Left;
         dimensions.Y = rect.Bottom - rect.Top;
 
@@ -97,17 +95,17 @@ class ViewportTests
 
     TEST_METHOD(CreateFromDimensionsWidthHeight)
     {
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
         rect.Right = 20;
 
-        COORD origin;
+        til::point origin;
         origin.X = rect.Left;
         origin.Y = rect.Top;
 
-        COORD dimensions;
+        til::size dimensions;
         dimensions.X = rect.Right - rect.Left + 1;
         dimensions.Y = rect.Bottom - rect.Top + 1;
 
@@ -127,17 +125,17 @@ class ViewportTests
 
     TEST_METHOD(CreateFromDimensions)
     {
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
         rect.Right = 20;
 
-        COORD origin;
+        til::point origin;
         origin.X = rect.Left;
         origin.Y = rect.Top;
 
-        COORD dimensions;
+        til::size dimensions;
         dimensions.X = rect.Right - rect.Left + 1;
         dimensions.Y = rect.Bottom - rect.Top + 1;
 
@@ -157,17 +155,17 @@ class ViewportTests
 
     TEST_METHOD(CreateFromDimensionsNoOrigin)
     {
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 0;
         rect.Left = 0;
         rect.Bottom = 5;
         rect.Right = 20;
 
-        COORD origin;
+        til::point origin;
         origin.X = rect.Left;
         origin.Y = rect.Top;
 
-        COORD dimensions;
+        til::size dimensions;
         dimensions.X = rect.Right - rect.Left + 1;
         dimensions.Y = rect.Bottom - rect.Top + 1;
 
@@ -187,7 +185,7 @@ class ViewportTests
 
     TEST_METHOD(CreateFromCoord)
     {
-        COORD origin;
+        til::point origin;
         origin.X = 12;
         origin.Y = 24;
 
@@ -203,41 +201,13 @@ class ViewportTests
         VERIFY_ARE_EQUAL(1, v.Width());
         VERIFY_ARE_EQUAL(origin, v.Origin());
         // clang-format off
-        VERIFY_ARE_EQUAL(COORD({ 1, 1, }), v.Dimensions());
+        VERIFY_ARE_EQUAL(til::size(1, 1), v.Dimensions());
         // clang-format on
     }
 
-    TEST_METHOD(ToRect)
-    {
-        COORD origin;
-        origin.X = 2;
-        origin.Y = 4;
-
-        COORD dimensions;
-        dimensions.X = 10;
-        dimensions.Y = 20;
-
-        const auto v = Viewport::FromDimensions(origin, dimensions);
-
-        const RECT rc = v.ToRect();
-        const SMALL_RECT exclusive = v.ToExclusive();
-
-        VERIFY_ARE_EQUAL(exclusive.Left, v.Left());
-        VERIFY_ARE_EQUAL(rc.left, v.Left());
-
-        VERIFY_ARE_EQUAL(exclusive.Top, v.Top());
-        VERIFY_ARE_EQUAL(rc.top, v.Top());
-
-        VERIFY_ARE_EQUAL(exclusive.Right, v.RightExclusive());
-        VERIFY_ARE_EQUAL(rc.right, v.RightExclusive());
-
-        VERIFY_ARE_EQUAL(exclusive.Bottom, v.BottomExclusive());
-        VERIFY_ARE_EQUAL(rc.bottom, v.BottomExclusive());
-    }
-
     TEST_METHOD(IsInBoundsCoord)
     {
-        SMALL_RECT r;
+        til::inclusive_rect r;
         r.Top = 3;
         r.Bottom = 5;
         r.Left = 10;
@@ -245,7 +215,7 @@ class ViewportTests
 
         const auto v = Viewport::FromInclusive(r);
 
-        COORD c;
+        til::point c;
         c.X = r.Left;
         c.Y = r.Top;
         VERIFY_IS_TRUE(v.IsInBounds(c), L"Top left corner in bounds.");
@@ -296,7 +266,7 @@ class ViewportTests
 
     TEST_METHOD(IsInBoundsViewport)
     {
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
@@ -347,7 +317,7 @@ class ViewportTests
 
     TEST_METHOD(ClampCoord)
     {
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
@@ -355,7 +325,7 @@ class ViewportTests
 
         const auto view = Viewport::FromInclusive(rect);
 
-        COORD pos;
+        til::point pos;
         pos.X = rect.Left;
         pos.Y = rect.Top;
 
@@ -381,7 +351,7 @@ class ViewportTests
         view.Clamp(pos);
         VERIFY_ARE_EQUAL(before, pos, L"Verify clamp did nothing for position in top right corner.");
 
-        COORD expected;
+        til::point expected;
         expected.X = rect.Right;
         expected.Y = rect.Top;
 
@@ -430,7 +400,7 @@ class ViewportTests
         VERIFY_ARE_NOT_EQUAL(before, pos, L"Verify clamp modified position out the bottom right corner back.");
         VERIFY_ARE_EQUAL(expected, pos, L"Verify position was clamped into the bottom right corner.");
 
-        Viewport invalidView = Viewport::Empty();
+        auto invalidView = Viewport::Empty();
         VERIFY_THROWS_SPECIFIC(invalidView.Clamp(pos),
                                wil::ResultException,
                                [](wil::ResultException& e) { return e.GetErrorCode() == E_NOT_VALID_STATE; });
@@ -439,7 +409,7 @@ class ViewportTests
     TEST_METHOD(ClampViewport)
     {
         // Create the rectangle/view we will clamp to.
-        SMALL_RECT rect;
+        til::inclusive_rect rect;
         rect.Top = 3;
         rect.Bottom = 5;
         rect.Left = 10;
@@ -448,7 +418,7 @@ class ViewportTests
         const auto view = Viewport::FromInclusive(rect);
 
         Log::Comment(L"Make a rectangle that is larger than and fully encompasses our clamping rectangle.");
-        SMALL_RECT testRect;
+        til::inclusive_rect testRect;
         testRect.Top = rect.Top - 3;
         testRect.Bottom = rect.Bottom + 3;
         testRect.Left = rect.Left - 3;
@@ -477,7 +447,7 @@ class ViewportTests
         testView = Viewport::FromInclusive(testRect);
 
         Log::Comment(L"We expect it to be pulled back so each coordinate is in bounds, but the rectangle is still invalid (since left will be > right).");
-        SMALL_RECT expected;
+        til::inclusive_rect expected;
         expected.Top = rect.Bottom;
         expected.Bottom = rect.Top;
         expected.Left = rect.Right;
@@ -492,15 +462,15 @@ class ViewportTests
     {
         auto success = false;
 
-        SMALL_RECT edges;
+        til::inclusive_rect edges;
         edges.Left = 10;
         edges.Right = 19;
         edges.Top = 20;
         edges.Bottom = 29;
 
         const auto v = Viewport::FromInclusive(edges);
-        COORD original;
-        COORD screen;
+        til::point original;
+        til::point screen;
 
         // #1 coord inside region
         original.X = screen.X = 15;
@@ -537,15 +507,15 @@ class ViewportTests
     {
         auto success = false;
 
-        SMALL_RECT edges;
+        til::inclusive_rect edges;
         edges.Left = 10;
         edges.Right = 19;
         edges.Top = 20;
         edges.Bottom = 29;
 
         const auto v = Viewport::FromInclusive(edges);
-        COORD original;
-        COORD screen;
+        til::point original;
+        til::point screen;
 
         // #1 coord inside region
         original.X = screen.X = 15;
@@ -582,15 +552,15 @@ class ViewportTests
     {
         auto success = false;
 
-        SMALL_RECT edges;
+        til::inclusive_rect edges;
         edges.Left = 10;
         edges.Right = 19;
         edges.Top = 20;
         edges.Bottom = 29;
 
         const auto v = Viewport::FromInclusive(edges);
-        COORD original;
-        COORD screen;
+        til::point original;
+        til::point screen;
 
         // #1 coord inside region
         original.X = screen.X = 15;
@@ -627,15 +597,15 @@ class ViewportTests
     {
         auto success = false;
 
-        SMALL_RECT edges;
+        til::inclusive_rect edges;
         edges.Left = 10;
         edges.Right = 19;
         edges.Top = 20;
         edges.Bottom = 29;
 
         const auto v = Viewport::FromInclusive(edges);
-        COORD original;
-        COORD screen;
+        til::point original;
+        til::point screen;
 
         // #1 coord inside region
         original.X = screen.X = 15;
@@ -668,27 +638,27 @@ class ViewportTests
         VERIFY_ARE_EQUAL(screen.Y, edges.Bottom);
     }
 
-    SHORT RandomShort()
+    til::CoordType RandomCoord()
     {
-        SHORT s;
+        til::CoordType s;
 
         do
         {
-            s = (SHORT)rand() % SHORT_MAX;
-        } while (s == 0i16);
+            s = (til::CoordType)rand() % SHORT_MAX;
+        } while (s == 0);
 
         return s;
     }
 
     TEST_METHOD(MoveInBounds)
     {
-        const UINT cTestLoopInstances = 100;
+        const auto cTestLoopInstances = 100;
 
-        const SHORT sRowWidth = 20;
+        const auto sRowWidth = 20;
         VERIFY_IS_TRUE(sRowWidth > 0);
 
         // 20x20 box
-        SMALL_RECT srectEdges;
+        til::inclusive_rect srectEdges;
         srectEdges.Top = srectEdges.Left = 0;
         srectEdges.Bottom = srectEdges.Right = sRowWidth - 1;
 
@@ -697,13 +667,13 @@ class ViewportTests
         // repeat test
         for (UINT i = 0; i < cTestLoopInstances; i++)
         {
-            COORD coordPos;
-            coordPos.X = RandomShort() % 20;
-            coordPos.Y = RandomShort() % 20;
+            til::point coordPos;
+            coordPos.X = RandomCoord() % 20;
+            coordPos.Y = RandomCoord() % 20;
 
-            SHORT sAddAmount = RandomShort() % (sRowWidth * sRowWidth);
+            auto sAddAmount = RandomCoord() % (sRowWidth * sRowWidth);
 
-            COORD coordFinal;
+            til::point coordFinal;
             coordFinal.X = (coordPos.X + sAddAmount) % sRowWidth;
             coordFinal.Y = coordPos.Y + ((coordPos.X + sAddAmount) / sRowWidth);
 
@@ -731,7 +701,7 @@ class ViewportTests
 
     TEST_METHOD(CompareInBounds)
     {
-        SMALL_RECT edges;
+        til::inclusive_rect edges;
         edges.Left = 10;
         edges.Right = 19;
         edges.Top = 20;
@@ -739,7 +709,7 @@ class ViewportTests
 
         const auto v = Viewport::FromInclusive(edges);
 
-        COORD first, second;
+        til::point first, second;
         first.X = 12;
         first.Y = 24;
         second = first;
@@ -760,7 +730,7 @@ class ViewportTests
 
     TEST_METHOD(Offset)
     {
-        SMALL_RECT edges;
+        til::inclusive_rect edges;
         edges.Top = 0;
         edges.Left = 0;
         edges.Right = 10;
@@ -769,16 +739,16 @@ class ViewportTests
         const auto original = Viewport::FromInclusive(edges);
 
         Log::Comment(L"Move down and to the right first.");
-        COORD adjust = { 7, 2 };
-        SMALL_RECT expectedEdges;
+        til::point adjust{ 7, 2 };
+        til::inclusive_rect expectedEdges;
         expectedEdges.Top = edges.Top + adjust.Y;
         expectedEdges.Bottom = edges.Bottom + adjust.Y;
         expectedEdges.Left = edges.Left + adjust.X;
         expectedEdges.Right = edges.Right + adjust.X;
 
-        Viewport expected = Viewport::FromInclusive(expectedEdges);
+        auto expected = Viewport::FromInclusive(expectedEdges);
 
-        Viewport actual = Viewport::Offset(original, adjust);
+        auto actual = Viewport::Offset(original, adjust);
         VERIFY_ARE_EQUAL(expected, actual);
 
         Log::Comment(L"Now try moving up and to the left.");
@@ -792,32 +762,25 @@ class ViewportTests
         expected = Viewport::FromInclusive(expectedEdges);
         actual = Viewport::Offset(original, adjust);
         VERIFY_ARE_EQUAL(expected, actual);
-
-        Log::Comment(L"Now try adding way too much to cause an overflow.");
-        adjust = { SHORT_MAX, SHORT_MAX };
-
-        VERIFY_THROWS_SPECIFIC(const auto vp = Viewport::Offset(original, adjust),
-                               wil::ResultException,
-                               [](wil::ResultException& e) { return e.GetErrorCode() == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); });
     }
 
     TEST_METHOD(Union)
     {
-        SMALL_RECT srOne;
+        til::inclusive_rect srOne;
         srOne.Left = 4;
         srOne.Right = 10;
         srOne.Top = 6;
         srOne.Bottom = 14;
         const auto one = Viewport::FromInclusive(srOne);
 
-        SMALL_RECT srTwo;
+        til::inclusive_rect srTwo;
         srTwo.Left = 5;
         srTwo.Right = 13;
         srTwo.Top = 2;
         srTwo.Bottom = 10;
         const auto two = Viewport::FromInclusive(srTwo);
 
-        SMALL_RECT srExpected;
+        til::inclusive_rect srExpected;
         srExpected.Left = srOne.Left < srTwo.Left ? srOne.Left : srTwo.Left;
         srExpected.Right = srOne.Right > srTwo.Right ? srOne.Right : srTwo.Right;
         srExpected.Top = srOne.Top < srTwo.Top ? srOne.Top : srTwo.Top;
@@ -831,21 +794,21 @@ class ViewportTests
 
     TEST_METHOD(Intersect)
     {
-        SMALL_RECT srOne;
+        til::inclusive_rect srOne;
         srOne.Left = 4;
         srOne.Right = 10;
         srOne.Top = 6;
         srOne.Bottom = 14;
         const auto one = Viewport::FromInclusive(srOne);
 
-        SMALL_RECT srTwo;
+        til::inclusive_rect srTwo;
         srTwo.Left = 5;
         srTwo.Right = 13;
         srTwo.Top = 2;
         srTwo.Bottom = 10;
         const auto two = Viewport::FromInclusive(srTwo);
 
-        SMALL_RECT srExpected;
+        til::inclusive_rect srExpected;
         srExpected.Left = srOne.Left > srTwo.Left ? srOne.Left : srTwo.Left;
         srExpected.Right = srOne.Right < srTwo.Right ? srOne.Right : srTwo.Right;
         srExpected.Top = srOne.Top > srTwo.Top ? srOne.Top : srTwo.Top;
@@ -859,14 +822,14 @@ class ViewportTests
 
     TEST_METHOD(SubtractFour)
     {
-        SMALL_RECT srOriginal;
+        til::inclusive_rect srOriginal;
         srOriginal.Top = 0;
         srOriginal.Left = 0;
         srOriginal.Bottom = 10;
         srOriginal.Right = 10;
         const auto original = Viewport::FromInclusive(srOriginal);
 
-        SMALL_RECT srRemove;
+        til::inclusive_rect srRemove;
         srRemove.Top = 3;
         srRemove.Left = 3;
         srRemove.Bottom = 6;
@@ -874,7 +837,7 @@ class ViewportTests
         const auto remove = Viewport::FromInclusive(srRemove);
 
         std::vector<Viewport> expected;
-        // SMALL_RECT constructed as: Left, Top, Right, Bottom
+        // til::inclusive_rect constructed as: Left, Top, Right, Bottom
         // Top View
         expected.emplace_back(Viewport::FromInclusive({ srOriginal.Left, srOriginal.Top, srOriginal.Right, srRemove.Top - 1 }));
         // Bottom View
@@ -898,14 +861,14 @@ class ViewportTests
 
     TEST_METHOD(SubtractThree)
     {
-        SMALL_RECT srOriginal;
+        til::inclusive_rect srOriginal;
         srOriginal.Top = 0;
         srOriginal.Left = 0;
         srOriginal.Bottom = 10;
         srOriginal.Right = 10;
         const auto original = Viewport::FromInclusive(srOriginal);
 
-        SMALL_RECT srRemove;
+        til::inclusive_rect srRemove;
         srRemove.Top = 3;
         srRemove.Left = 3;
         srRemove.Bottom = 6;
@@ -913,7 +876,7 @@ class ViewportTests
         const auto remove = Viewport::FromInclusive(srRemove);
 
         std::vector<Viewport> expected;
-        // SMALL_RECT constructed as: Left, Top, Right, Bottom
+        // til::inclusive_rect constructed as: Left, Top, Right, Bottom
         // Top View
         expected.emplace_back(Viewport::FromInclusive({ srOriginal.Left, srOriginal.Top, srOriginal.Right, srRemove.Top - 1 }));
         // Bottom View
@@ -935,14 +898,14 @@ class ViewportTests
 
     TEST_METHOD(SubtractTwo)
     {
-        SMALL_RECT srOriginal;
+        til::inclusive_rect srOriginal;
         srOriginal.Top = 0;
         srOriginal.Left = 0;
         srOriginal.Bottom = 10;
         srOriginal.Right = 10;
         const auto original = Viewport::FromInclusive(srOriginal);
 
-        SMALL_RECT srRemove;
+        til::inclusive_rect srRemove;
         srRemove.Top = 3;
         srRemove.Left = 3;
         srRemove.Bottom = 15;
@@ -950,7 +913,7 @@ class ViewportTests
         const auto remove = Viewport::FromInclusive(srRemove);
 
         std::vector<Viewport> expected;
-        // SMALL_RECT constructed as: Left, Top, Right, Bottom
+        // til::inclusive_rect constructed as: Left, Top, Right, Bottom
         // Top View
         expected.emplace_back(Viewport::FromInclusive({ srOriginal.Left, srOriginal.Top, srOriginal.Right, srRemove.Top - 1 }));
         // Left View
@@ -970,14 +933,14 @@ class ViewportTests
 
     TEST_METHOD(SubtractOne)
     {
-        SMALL_RECT srOriginal;
+        til::inclusive_rect srOriginal;
         srOriginal.Top = 0;
         srOriginal.Left = 0;
         srOriginal.Bottom = 10;
         srOriginal.Right = 10;
         const auto original = Viewport::FromInclusive(srOriginal);
 
-        SMALL_RECT srRemove;
+        til::inclusive_rect srRemove;
         srRemove.Top = 3;
         srRemove.Left = -12;
         srRemove.Bottom = 15;
@@ -985,7 +948,7 @@ class ViewportTests
         const auto remove = Viewport::FromInclusive(srRemove);
 
         std::vector<Viewport> expected;
-        // SMALL_RECT constructed as: Left, Top, Right, Bottom
+        // til::inclusive_rect constructed as: Left, Top, Right, Bottom
         // Top View
         expected.emplace_back(Viewport::FromInclusive({ srOriginal.Left, srOriginal.Top, srOriginal.Right, srRemove.Top - 1 }));
 
@@ -1005,14 +968,14 @@ class ViewportTests
 
     TEST_METHOD(SubtractZero)
     {
-        SMALL_RECT srOriginal;
+        til::inclusive_rect srOriginal;
         srOriginal.Top = 0;
         srOriginal.Left = 0;
         srOriginal.Bottom = 10;
         srOriginal.Right = 10;
         const auto original = Viewport::FromInclusive(srOriginal);
 
-        SMALL_RECT srRemove;
+        til::inclusive_rect srRemove;
         srRemove.Top = 12;
         srRemove.Left = 12;
         srRemove.Bottom = 15;
@@ -1036,7 +999,7 @@ class ViewportTests
 
     TEST_METHOD(SubtractSame)
     {
-        SMALL_RECT srOriginal;
+        til::inclusive_rect srOriginal;
         srOriginal.Top = 0;
         srOriginal.Left = 0;
         srOriginal.Bottom = 10;
diff --git a/src/host/ut_host/VtIoTests.cpp b/src/host/ut_host/VtIoTests.cpp
index dc464dc1fc0..693c8985267 100644
--- a/src/host/ut_host/VtIoTests.cpp
+++ b/src/host/ut_host/VtIoTests.cpp
@@ -80,7 +80,7 @@ void VtIoTests::ModeParsingTest()
 
 Viewport SetUpViewport()
 {
-    SMALL_RECT view = {};
+    til::inclusive_rect view;
     view.Top = view.Left = 0;
     view.Bottom = 31;
     view.Right = 79;
@@ -262,9 +262,9 @@ class MockRenderData : public IRenderData, IUiaData
         return Microsoft::Console::Types::Viewport{};
     }
 
-    COORD GetTextBufferEndPosition() const noexcept override
+    til::point GetTextBufferEndPosition() const noexcept override
     {
-        return COORD{};
+        return {};
     }
 
     const TextBuffer& GetTextBuffer() const noexcept override
@@ -295,9 +295,9 @@ class MockRenderData : public IRenderData, IUiaData
         return std::make_pair(COLORREF{}, COLORREF{});
     }
 
-    COORD GetCursorPosition() const noexcept override
+    til::point GetCursorPosition() const noexcept override
     {
-        return COORD{};
+        return {};
     }
 
     bool IsCursorVisible() const noexcept override
@@ -359,21 +359,21 @@ class MockRenderData : public IRenderData, IUiaData
     {
     }
 
-    void SelectNewRegion(const COORD /*coordStart*/, const COORD /*coordEnd*/) override
+    void SelectNewRegion(const til::point /*coordStart*/, const til::point /*coordEnd*/) override
     {
     }
 
-    const COORD GetSelectionAnchor() const noexcept
+    const til::point GetSelectionAnchor() const noexcept
     {
-        return COORD{};
+        return {};
     }
 
-    const COORD GetSelectionEnd() const noexcept
+    const til::point GetSelectionEnd() const noexcept
     {
-        return COORD{};
+        return {};
     }
 
-    void ColorSelection(const COORD /*coordSelectionStart*/, const COORD /*coordSelectionEnd*/, const TextAttribute /*attr*/)
+    void ColorSelection(const til::point /*coordSelectionStart*/, const til::point /*coordSelectionEnd*/, const TextAttribute /*attr*/)
     {
     }
 
@@ -392,7 +392,7 @@ class MockRenderData : public IRenderData, IUiaData
         return {};
     }
 
-    const std::vector<size_t> GetPatternId(const COORD /*location*/) const noexcept
+    const std::vector<size_t> GetPatternId(const til::point /*location*/) const noexcept
     {
         return {};
     }
diff --git a/src/host/ut_host/VtRendererTests.cpp b/src/host/ut_host/VtRendererTests.cpp
index 1d47d4177ff..5f2331d6491 100644
--- a/src/host/ut_host/VtRendererTests.cpp
+++ b/src/host/ut_host/VtRendererTests.cpp
@@ -117,7 +117,7 @@ class Microsoft::Console::Render::VtRendererTest
 
 Viewport VtRendererTest::SetUpViewport()
 {
-    SMALL_RECT view = {};
+    til::inclusive_rect view;
     view.Top = view.Left = 0;
     view.Bottom = 31;
     view.Right = 79;
@@ -235,16 +235,16 @@ void VtRendererTest::Xterm256TestInvalidate()
 
     Log::Comment(NoThrowString().Format(
         L"Make sure that invalidating anything only invalidates that portion"));
-    SMALL_RECT invalid = { 1, 1, 2, 2 };
+    til::rect invalid = { 1, 1, 2, 2 };
     VERIFY_SUCCEEDED(engine->Invalidate(&invalid));
     TestPaint(*engine, [&]() {
         VERIFY_IS_TRUE(engine->_invalidMap.one());
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, *(engine->_invalidMap.begin()));
+        VERIFY_ARE_EQUAL(invalid, *(engine->_invalidMap.begin()));
     });
 
     Log::Comment(NoThrowString().Format(
         L"Make sure that scrolling only invalidates part of the viewport, and sends the right sequences"));
-    COORD scrollDelta = { 0, 1 };
+    til::point scrollDelta = { 0, 1 };
     VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
     TestPaint(*engine, [&]() {
         Log::Comment(NoThrowString().Format(
@@ -254,7 +254,7 @@ void VtRendererTest::Xterm256TestInvalidate()
 
         const auto runs = engine->_invalidMap.runs();
         VERIFY_ARE_EQUAL(1u, runs.size());
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, runs.front());
+        VERIFY_ARE_EQUAL(invalid, runs.front());
         qExpectedInput.push_back("\x1b[H"); // Go Home
         qExpectedInput.push_back("\x1b[L"); // insert a line
 
@@ -280,7 +280,7 @@ void VtRendererTest::Xterm256TestInvalidate()
         }
 
         // verify the rect matches the invalid one.
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, invalidRect);
+        VERIFY_ARE_EQUAL(invalid, invalidRect);
         // We would expect a CUP here, but the cursor is already at the home position
         qExpectedInput.push_back("\x1b[3L"); // insert 3 lines
         VERIFY_SUCCEEDED(engine->ScrollFrame());
@@ -296,7 +296,7 @@ void VtRendererTest::Xterm256TestInvalidate()
 
         const auto runs = engine->_invalidMap.runs();
         VERIFY_ARE_EQUAL(1u, runs.size());
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, runs.front());
+        VERIFY_ARE_EQUAL(invalid, runs.front());
 
         qExpectedInput.push_back("\x1b[32;1H"); // Bottom of buffer
         qExpectedInput.push_back("\n"); // Scroll down once
@@ -321,7 +321,7 @@ void VtRendererTest::Xterm256TestInvalidate()
         }
 
         // verify the rect matches the invalid one.
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, invalidRect);
+        VERIFY_ARE_EQUAL(invalid, invalidRect);
 
         // We would expect a CUP here, but we're already at the bottom from the last call.
         qExpectedInput.push_back("\n\n\n"); // Scroll down three times
@@ -351,7 +351,7 @@ void VtRendererTest::Xterm256TestInvalidate()
         }
 
         // verify the rect matches the invalid one.
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, invalidRect);
+        VERIFY_ARE_EQUAL(invalid, invalidRect);
 
         qExpectedInput.push_back("\x1b[H"); // Go to home
         qExpectedInput.push_back("\x1b[3L"); // insert 3 lines
@@ -661,7 +661,7 @@ void VtRendererTest::Xterm256TestCursor()
         std::vector<Cluster> clusters;
         for (size_t i = 0; i < wcslen(line); i++)
         {
-            clusters.emplace_back(std::wstring_view{ &line[i], 1 }, static_cast<size_t>(rgWidths[i]));
+            clusters.emplace_back(std::wstring_view{ &line[i], 1 }, static_cast<til::CoordType>(rgWidths[i]));
         }
 
         VERIFY_SUCCEEDED(engine->PaintBufferLine({ clusters.data(), clusters.size() }, { 1, 1 }, false, false));
@@ -910,16 +910,16 @@ void VtRendererTest::XtermTestInvalidate()
 
     Log::Comment(NoThrowString().Format(
         L"Make sure that invalidating anything only invalidates that portion"));
-    SMALL_RECT invalid = { 1, 1, 2, 2 };
+    til::rect invalid = { 1, 1, 2, 2 };
     VERIFY_SUCCEEDED(engine->Invalidate(&invalid));
     TestPaint(*engine, [&]() {
         VERIFY_IS_TRUE(engine->_invalidMap.one());
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, *(engine->_invalidMap.begin()));
+        VERIFY_ARE_EQUAL(invalid, *(engine->_invalidMap.begin()));
     });
 
     Log::Comment(NoThrowString().Format(
         L"Make sure that scrolling only invalidates part of the viewport, and sends the right sequences"));
-    COORD scrollDelta = { 0, 1 };
+    til::point scrollDelta = { 0, 1 };
     VERIFY_SUCCEEDED(engine->InvalidateScroll(&scrollDelta));
     TestPaint(*engine, [&]() {
         Log::Comment(NoThrowString().Format(
@@ -929,7 +929,7 @@ void VtRendererTest::XtermTestInvalidate()
 
         const auto runs = engine->_invalidMap.runs();
         VERIFY_ARE_EQUAL(1u, runs.size());
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, runs.front());
+        VERIFY_ARE_EQUAL(invalid, runs.front());
 
         qExpectedInput.push_back("\x1b[H"); // Go Home
         qExpectedInput.push_back("\x1b[L"); // insert a line
@@ -954,7 +954,7 @@ void VtRendererTest::XtermTestInvalidate()
         }
 
         // verify the rect matches the invalid one.
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, invalidRect);
+        VERIFY_ARE_EQUAL(invalid, invalidRect);
         // We would expect a CUP here, but the cursor is already at the home position
         qExpectedInput.push_back("\x1b[3L"); // insert 3 lines
         VERIFY_SUCCEEDED(engine->ScrollFrame());
@@ -970,7 +970,7 @@ void VtRendererTest::XtermTestInvalidate()
 
         const auto runs = engine->_invalidMap.runs();
         VERIFY_ARE_EQUAL(1u, runs.size());
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, runs.front());
+        VERIFY_ARE_EQUAL(invalid, runs.front());
 
         qExpectedInput.push_back("\x1b[32;1H"); // Bottom of buffer
         qExpectedInput.push_back("\n"); // Scroll down once
@@ -995,7 +995,7 @@ void VtRendererTest::XtermTestInvalidate()
         }
 
         // verify the rect matches the invalid one.
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, invalidRect);
+        VERIFY_ARE_EQUAL(invalid, invalidRect);
 
         // We would expect a CUP here, but we're already at the bottom from the last call.
         qExpectedInput.push_back("\n\n\n"); // Scroll down three times
@@ -1025,7 +1025,7 @@ void VtRendererTest::XtermTestInvalidate()
         }
 
         // verify the rect matches the invalid one.
-        VERIFY_ARE_EQUAL(til::rect{ Viewport::FromExclusive(invalid).ToInclusive() }, invalidRect);
+        VERIFY_ARE_EQUAL(invalid, invalidRect);
 
         qExpectedInput.push_back("\x1b[H"); // Go to home
         qExpectedInput.push_back("\x1b[3L"); // insert 3 lines
@@ -1290,7 +1290,7 @@ void VtRendererTest::XtermTestCursor()
         std::vector<Cluster> clusters;
         for (size_t i = 0; i < wcslen(line); i++)
         {
-            clusters.emplace_back(std::wstring_view{ &line[i], 1 }, static_cast<size_t>(rgWidths[i]));
+            clusters.emplace_back(std::wstring_view{ &line[i], 1 }, static_cast<til::CoordType>(rgWidths[i]));
         }
 
         VERIFY_SUCCEEDED(engine->PaintBufferLine({ clusters.data(), clusters.size() }, { 1, 1 }, false, false));
@@ -1414,12 +1414,12 @@ void VtRendererTest::TestWrapping()
         std::vector<Cluster> clusters1;
         for (size_t i = 0; i < wcslen(line1); i++)
         {
-            clusters1.emplace_back(std::wstring_view{ &line1[i], 1 }, static_cast<size_t>(rgWidths[i]));
+            clusters1.emplace_back(std::wstring_view{ &line1[i], 1 }, static_cast<til::CoordType>(rgWidths[i]));
         }
         std::vector<Cluster> clusters2;
         for (size_t i = 0; i < wcslen(line2); i++)
         {
-            clusters2.emplace_back(std::wstring_view{ &line2[i], 1 }, static_cast<size_t>(rgWidths[i]));
+            clusters2.emplace_back(std::wstring_view{ &line2[i], 1 }, static_cast<til::CoordType>(rgWidths[i]));
         }
 
         VERIFY_SUCCEEDED(engine->PaintBufferLine({ clusters1.data(), clusters1.size() }, { 0, 0 }, false, false));
@@ -1474,7 +1474,7 @@ void VtRendererTest::TestCursorVisibility()
     auto pfn = std::bind(&VtRendererTest::WriteCallback, this, std::placeholders::_1, std::placeholders::_2);
     engine->SetTestCallback(pfn);
 
-    COORD origin{ 0, 0 };
+    til::point origin{ 0, 0 };
 
     VERIFY_ARE_NOT_EQUAL(origin, engine->_lastText);
 
diff --git a/src/host/utils.cpp b/src/host/utils.cpp
index 463b3f8b94f..c451122cb37 100644
--- a/src/host/utils.cpp
+++ b/src/host/utils.cpp
@@ -11,21 +11,21 @@
 
 using Microsoft::Console::Interactivity::ServiceLocator;
 
-short CalcWindowSizeX(const SMALL_RECT& rect) noexcept
+til::CoordType CalcWindowSizeX(const til::inclusive_rect& rect) noexcept
 {
     return rect.Right - rect.Left + 1;
 }
 
-short CalcWindowSizeY(const SMALL_RECT& rect) noexcept
+til::CoordType CalcWindowSizeY(const til::inclusive_rect& rect) noexcept
 {
     return rect.Bottom - rect.Top + 1;
 }
 
-short CalcCursorYOffsetInPixels(const short sFontSizeY, const ULONG ulSize) noexcept
+til::CoordType CalcCursorYOffsetInPixels(const til::CoordType sFontSizeY, const ULONG ulSize) noexcept
 {
     // TODO: MSFT 10229700 - Note, we want to likely enforce that this isn't negative.
     // Pretty sure there's not a valid case for negative offsets here.
-    return (short)((sFontSizeY) - (ulSize));
+    return (til::CoordType)((sFontSizeY) - (ulSize));
 }
 
 WORD ConvertStringToDec(_In_ PCWSTR pwchToConvert, _Out_opt_ PCWSTR* const ppwchEnd) noexcept
@@ -167,7 +167,7 @@ UINT s_LoadStringEx(_In_ HINSTANCE hModule, _In_ UINT wID, _Out_writes_(cchBuffe
 // -  This is so you can do s_CompareCoords(first, second) <= 0 for "first is left or the same as second".
 //    (the < looks like a left arrow :D)
 // -  The magnitude of the result is the distance between the two coordinates when typing characters into the buffer (left to right, top to bottom)
-int Utils::s_CompareCoords(const COORD bufferSize, const COORD coordFirst, const COORD coordSecond) noexcept
+int Utils::s_CompareCoords(const til::size bufferSize, const til::point coordFirst, const til::point coordSecond) noexcept
 {
     const auto cRowWidth = bufferSize.X;
 
@@ -209,7 +209,7 @@ int Utils::s_CompareCoords(const COORD bufferSize, const COORD coordFirst, const
 // -  This is so you can do s_CompareCoords(first, second) <= 0 for "first is left or the same as second".
 //    (the < looks like a left arrow :D)
 // -  The magnitude of the result is the distance between the two coordinates when typing characters into the buffer (left to right, top to bottom)
-int Utils::s_CompareCoords(const COORD coordFirst, const COORD coordSecond) noexcept
+int Utils::s_CompareCoords(const til::point coordFirst, const til::point coordSecond) noexcept
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     // find the width of one row
@@ -225,7 +225,7 @@ int Utils::s_CompareCoords(const COORD coordFirst, const COORD coordSecond) noex
 // - coordCorner - One of the corners of the given rectangle
 // Return Value:
 // - The opposite corner of the one given.
-COORD Utils::s_GetOppositeCorner(const SMALL_RECT srRectangle, const COORD coordCorner) noexcept
+til::point Utils::s_GetOppositeCorner(const til::inclusive_rect& srRectangle, const til::point coordCorner) noexcept
 {
     // Assert we were given coordinates that are indeed one of the corners of the rectangle.
     FAIL_FAST_IF(!(coordCorner.X == srRectangle.Left || coordCorner.X == srRectangle.Right));
diff --git a/src/host/utils.hpp b/src/host/utils.hpp
index 86f3baff9f0..e0b6f62e916 100644
--- a/src/host/utils.hpp
+++ b/src/host/utils.hpp
@@ -22,9 +22,9 @@ Author(s):
 #define RECT_WIDTH(x) ((x)->right - (x)->left)
 #define RECT_HEIGHT(x) ((x)->bottom - (x)->top)
 
-short CalcWindowSizeX(const SMALL_RECT& rect) noexcept;
-short CalcWindowSizeY(const SMALL_RECT& rect) noexcept;
-short CalcCursorYOffsetInPixels(const short sFontSizeY, const ULONG ulSize) noexcept;
+til::CoordType CalcWindowSizeX(const til::inclusive_rect& rect) noexcept;
+til::CoordType CalcWindowSizeY(const til::inclusive_rect& rect) noexcept;
+til::CoordType CalcCursorYOffsetInPixels(const til::CoordType sFontSizeY, const ULONG ulSize) noexcept;
 WORD ConvertStringToDec(_In_ PCWSTR pwchToConvert, _Out_opt_ PCWSTR* const ppwchEnd) noexcept;
 
 std::wstring _LoadString(const UINT id);
@@ -37,8 +37,8 @@ static UINT s_LoadStringEx(_In_ HINSTANCE hModule,
 class Utils
 {
 public:
-    static int s_CompareCoords(const COORD bufferSize, const COORD first, const COORD second) noexcept;
-    static int s_CompareCoords(const COORD coordFirst, const COORD coordSecond) noexcept;
+    static int s_CompareCoords(const til::size bufferSize, const til::point first, const til::point second) noexcept;
+    static int s_CompareCoords(const til::point coordFirst, const til::point coordSecond) noexcept;
 
-    static COORD s_GetOppositeCorner(const SMALL_RECT srRectangle, const COORD coordCorner) noexcept;
+    static til::point s_GetOppositeCorner(const til::inclusive_rect& srRectangle, const til::point coordCorner) noexcept;
 };
diff --git a/src/inc/TestUtils.h b/src/inc/TestUtils.h
index 922a8d24de0..de8a94f35e8 100644
--- a/src/inc/TestUtils.h
+++ b/src/inc/TestUtils.h
@@ -102,7 +102,7 @@ class TerminalCoreUnitTests::TestUtils
     // - an iterator on the first character after the expectedString.
     static TextBufferCellIterator VerifyExpectedString(const TextBuffer& tb,
                                                        std::wstring_view expectedString,
-                                                       const COORD pos)
+                                                       const til::point pos)
     {
         auto iter = tb.GetCellDataAt(pos);
         VerifyExpectedString(expectedString, iter);
@@ -192,7 +192,7 @@ class TerminalCoreUnitTests::TestUtils
     };
 
     template<class... T>
-    static TextBufferCellIterator VerifyLineContains(const TextBuffer& tb, COORD position, T&&... expectedContent)
+    static TextBufferCellIterator VerifyLineContains(const TextBuffer& tb, til::point position, T&&... expectedContent)
     {
         auto actual = tb.GetCellLineDataAt(position);
         VerifyLineContains(actual, std::forward<T>(expectedContent)...);
diff --git a/src/inc/operators.hpp b/src/inc/operators.hpp
deleted file mode 100644
index a58c75180b9..00000000000
--- a/src/inc/operators.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*++
-Copyright (c) Microsoft Corporation.
-Licensed under the MIT license.
-
-Module Name:
-- operators.hpp
-
-Abstract:
-- This file contains helpful operator overloading for some older data structures.
-
-Author(s):
-- Austin Diviness (AustDi) Mar 2017
---*/
-
-#pragma once
-
-constexpr bool operator==(const COORD& a, const COORD& b) noexcept
-{
-    return (a.X == b.X &&
-            a.Y == b.Y);
-}
-
-constexpr bool operator!=(const COORD& a, const COORD& b) noexcept
-{
-    return !(a == b);
-}
-
-constexpr bool operator==(const SMALL_RECT& a, const SMALL_RECT& b) noexcept
-{
-    return (a.Top == b.Top &&
-            a.Left == b.Left &&
-            a.Bottom == b.Bottom &&
-            a.Right == b.Right);
-}
-
-constexpr bool operator!=(const SMALL_RECT& a, const SMALL_RECT& b) noexcept
-{
-    return !(a == b);
-}
diff --git a/src/inc/til/hash.h b/src/inc/til/hash.h
index a96f26dcf1b..7b7c9c4b53c 100644
--- a/src/inc/til/hash.h
+++ b/src/inc/til/hash.h
@@ -126,40 +126,41 @@ namespace til
         }
     };
 
-    template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>>
-    constexpr size_t hash(const T v) noexcept
+    template<typename T>
+    constexpr size_t hash(const T& v) noexcept
     {
-        // This runs murmurhash3's finalizer (fmix32/fmix64) on a single integer.
-        // It's fast, public domain and produces good results.
-        //
-        // Using til::as_unsigned here allows the compiler to drop the first
-        // `>> 33` mix for all Ts which are >= 32 bits.
-        // The existence of sign extension shouldn't change hash quality.
-        size_t h = til::as_unsigned(v);
-        if constexpr (sizeof(size_t) == 4)
+        if constexpr (sizeof(T) <= sizeof(size_t) && (std::is_integral_v<T> || std::is_enum_v<T>))
         {
-            h ^= h >> 16;
-            h *= UINT32_C(0x85ebca6b);
-            h ^= h >> 13;
-            h *= UINT32_C(0xc2b2ae35);
-            h ^= h >> 16;
+            // This runs murmurhash3's finalizer (fmix32/fmix64) on a single integer.
+            // It's fast, public domain and produces good results.
+            //
+            // Using til::as_unsigned here allows the compiler to drop the first
+            // `>> 33` mix for all Ts which are >= 32 bits.
+            // The existence of sign extension shouldn't change hash quality.
+            size_t h = til::as_unsigned(v);
+            if constexpr (sizeof(size_t) == 4)
+            {
+                h ^= h >> 16;
+                h *= UINT32_C(0x85ebca6b);
+                h ^= h >> 13;
+                h *= UINT32_C(0xc2b2ae35);
+                h ^= h >> 16;
+            }
+            else
+            {
+                h ^= h >> 33;
+                h *= UINT64_C(0xff51afd7ed558ccd);
+                h ^= h >> 33;
+                h *= UINT64_C(0xc4ceb9fe1a85ec53);
+                h ^= h >> 33;
+            }
+            return h;
         }
         else
         {
-            h ^= h >> 33;
-            h *= UINT64_C(0xff51afd7ed558ccd);
-            h ^= h >> 33;
-            h *= UINT64_C(0xc4ceb9fe1a85ec53);
-            h ^= h >> 33;
+            hasher h;
+            h.write(v);
+            return h.finalize();
         }
-        return h;
-    }
-
-    template<typename T, typename = std::enable_if_t<!(std::is_integral_v<T> || std::is_enum_v<T>)>>
-    constexpr size_t hash(const T& v) noexcept
-    {
-        hasher h;
-        h.write(v);
-        return h.finalize();
     }
 }
diff --git a/src/inc/til/math.h b/src/inc/til/math.h
index 59f80c2cc6e..8f9a51e439d 100644
--- a/src/inc/til/math.h
+++ b/src/inc/til/math.h
@@ -77,4 +77,13 @@ namespace til
         static constexpr details::flooring_t flooring; // positives become less positive, negatives become more negative
         static constexpr details::rounding_t rounding; // it's rounding, from math class
     }
+
+    // This method has the same behavior as gsl::narrow<T>, but instead of throwing an
+    // exception on narrowing failure it'll return false. On success it returns true.
+    template<typename T, typename U>
+    constexpr bool narrow_maybe(U u, T& out) noexcept
+    {
+        out = gsl::narrow_cast<T>(u);
+        return static_cast<U>(out) == u && (std::is_signed_v<T> == std::is_signed_v<U> || (out < T{}) == (u < U{}));
+    }
 }
diff --git a/src/inc/til/point.h b/src/inc/til/point.h
index ea0d9a4416d..4177e448a0a 100644
--- a/src/inc/til/point.h
+++ b/src/inc/til/point.h
@@ -174,18 +174,6 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
             return gsl::narrow<T>(y);
         }
 
-#ifdef _WINCONTYPES_
-        explicit constexpr point(const COORD other) noexcept :
-            x{ other.X }, y{ other.Y }
-        {
-        }
-
-        constexpr COORD to_win32_coord() const
-        {
-            return { narrow_x<short>(), narrow_y<short>() };
-        }
-#endif
-
 #ifdef _WINDEF_
         explicit constexpr point(const POINT other) noexcept :
             x{ other.x }, y{ other.y }
@@ -257,18 +245,31 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
         }
     };
 
-    constexpr point wrap_coord(const COORD rect) noexcept
+    constexpr point wrap_coord(const COORD pt) noexcept
     {
-        return { rect.X, rect.Y };
+        return { pt.X, pt.Y };
     }
 
-    constexpr COORD unwrap_coord(const point rect)
+    constexpr COORD unwrap_coord(const point pt)
     {
         return {
-            gsl::narrow<short>(rect.X),
-            gsl::narrow<short>(rect.Y),
+            gsl::narrow<short>(pt.x),
+            gsl::narrow<short>(pt.y),
         };
     }
+
+    constexpr HRESULT unwrap_coord_hr(const point pt, COORD& out) noexcept
+    {
+        short x = 0;
+        short y = 0;
+        if (narrow_maybe(pt.x, x) && narrow_maybe(pt.y, y))
+        {
+            out.X = x;
+            out.Y = y;
+            return S_OK;
+        }
+        RETURN_WIN32(ERROR_UNHANDLED_EXCEPTION);
+    }
 }
 
 #ifdef __WEX_COMMON_H__
diff --git a/src/inc/til/rect.h b/src/inc/til/rect.h
index 4d1fca122e9..d6d4f9d019f 100644
--- a/src/inc/til/rect.h
+++ b/src/inc/til/rect.h
@@ -70,6 +70,23 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
         };
     }
 
+    constexpr HRESULT unwrap_small_rect_hr(const inclusive_rect& rect, SMALL_RECT& out) noexcept
+    {
+        short l = 0;
+        short t = 0;
+        short r = 0;
+        short b = 0;
+        if (narrow_maybe(rect.left, l) && narrow_maybe(rect.top, t) && narrow_maybe(rect.right, r) && narrow_maybe(rect.bottom, b))
+        {
+            out.Left = l;
+            out.Top = t;
+            out.Right = r;
+            out.Bottom = b;
+            return S_OK;
+        }
+        RETURN_WIN32(ERROR_UNHANDLED_EXCEPTION);
+    }
+
     namespace details
     {
         class _rectangle_const_iterator
@@ -632,29 +649,6 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
         }
 
 #ifdef _WINCONTYPES_
-        // NOTE: This will convert from INCLUSIVE on the way in because
-        // that is generally how SMALL_RECTs are handled in console code and via the APIs.
-        explicit constexpr rect(const SMALL_RECT other) noexcept :
-            rect{ other.Left, other.Top, other.Right + 1, other.Bottom + 1 }
-        {
-        }
-
-        // NOTE: This will convert back to INCLUSIVE on the way out because
-        // that is generally how SMALL_RECTs are handled in console code and via the APIs.
-        constexpr SMALL_RECT to_small_rect() const
-        {
-            // The two -1 operations below are technically UB if they underflow.
-            // But practically speaking no hardware without two's complement for
-            // signed integers is supported by Windows. If they do underflow, they'll
-            // result in INT_MAX which will throw in gsl::narrow just like INT_MAX does.
-            return {
-                gsl::narrow<short>(left),
-                gsl::narrow<short>(top),
-                gsl::narrow<short>(right - 1),
-                gsl::narrow<short>(bottom - 1),
-            };
-        }
-
         // NOTE: This will convert from INCLUSIVE on the way in because
         // that is generally how SMALL_RECTs are handled in console code and via the APIs.
         explicit constexpr rect(const inclusive_rect other) noexcept :
@@ -782,6 +776,23 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
             gsl::narrow<short>(rect.bottom),
         };
     }
+
+    constexpr HRESULT unwrap_exclusive_small_rect_hr(const rect& rect, SMALL_RECT& out) noexcept
+    {
+        short l = 0;
+        short t = 0;
+        short r = 0;
+        short b = 0;
+        if (narrow_maybe(rect.left, l) && narrow_maybe(rect.top, t) && narrow_maybe(rect.right, r) && narrow_maybe(rect.bottom, b))
+        {
+            out.Left = l;
+            out.Top = t;
+            out.Right = r;
+            out.Bottom = b;
+            return S_OK;
+        }
+        RETURN_WIN32(ERROR_UNHANDLED_EXCEPTION);
+    }
 }
 
 #ifdef __WEX_COMMON_H__
diff --git a/src/inc/til/size.h b/src/inc/til/size.h
index 2b21abd41de..2db967f6fd7 100644
--- a/src/inc/til/size.h
+++ b/src/inc/til/size.h
@@ -133,18 +133,6 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
             return gsl::narrow<T>(static_cast<int64_t>(width) * static_cast<int64_t>(height));
         }
 
-#ifdef _WINCONTYPES_
-        explicit constexpr size(const COORD other) noexcept :
-            width{ other.X }, height{ other.Y }
-        {
-        }
-
-        constexpr COORD to_win32_coord() const
-        {
-            return { gsl::narrow<short>(width), gsl::narrow<short>(height) };
-        }
-#endif
-
 #ifdef _WINDEF_
         explicit constexpr size(const SIZE other) noexcept :
             width{ other.cx }, height{ other.cy }
@@ -204,18 +192,31 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
         }
     };
 
-    constexpr size wrap_coord_size(const COORD rect) noexcept
+    constexpr size wrap_coord_size(const COORD sz) noexcept
     {
-        return { rect.X, rect.Y };
+        return { sz.X, sz.Y };
     }
 
-    constexpr COORD unwrap_coord_size(const size rect)
+    constexpr COORD unwrap_coord_size(const size sz)
     {
         return {
-            gsl::narrow<short>(rect.width),
-            gsl::narrow<short>(rect.height),
+            gsl::narrow<short>(sz.width),
+            gsl::narrow<short>(sz.height),
         };
     }
+
+    constexpr HRESULT unwrap_coord_size_hr(const size sz, COORD& out) noexcept
+    {
+        short x = 0;
+        short y = 0;
+        if (narrow_maybe(sz.width, x) && narrow_maybe(sz.height, y))
+        {
+            out.X = x;
+            out.Y = y;
+            return S_OK;
+        }
+        RETURN_WIN32(ERROR_UNHANDLED_EXCEPTION);
+    }
 };
 
 #ifdef __WEX_COMMON_H__
diff --git a/src/interactivity/inc/IAccessibilityNotifier.hpp b/src/interactivity/inc/IAccessibilityNotifier.hpp
index 3e88b4dad2b..786893dd656 100644
--- a/src/interactivity/inc/IAccessibilityNotifier.hpp
+++ b/src/interactivity/inc/IAccessibilityNotifier.hpp
@@ -29,7 +29,7 @@ namespace Microsoft::Console::Interactivity
 
         virtual ~IAccessibilityNotifier() = default;
 
-        virtual void NotifyConsoleCaretEvent(_In_ RECT rectangle) = 0;
+        virtual void NotifyConsoleCaretEvent(_In_ const til::rect& rectangle) = 0;
         virtual void NotifyConsoleCaretEvent(_In_ ConsoleCaretEventFlags flags, _In_ LONG position) = 0;
         virtual void NotifyConsoleUpdateScrollEvent(_In_ LONG x, _In_ LONG y) = 0;
         virtual void NotifyConsoleUpdateSimpleEvent(_In_ LONG start, _In_ LONG charAndAttribute) = 0;
diff --git a/src/interactivity/inc/IConsoleWindow.hpp b/src/interactivity/inc/IConsoleWindow.hpp
index 75f7d893da4..232957ffb6c 100644
--- a/src/interactivity/inc/IConsoleWindow.hpp
+++ b/src/interactivity/inc/IConsoleWindow.hpp
@@ -36,7 +36,7 @@ namespace Microsoft::Console::Types
 
         virtual void SetIsFullscreen(const bool fFullscreenEnabled) = 0;
 
-        virtual void ChangeViewport(const SMALL_RECT NewWindow) = 0;
+        virtual void ChangeViewport(const til::inclusive_rect& NewWindow) = 0;
 
         virtual void CaptureMouse() = 0;
         virtual BOOL ReleaseMouse() = 0;
@@ -46,10 +46,10 @@ namespace Microsoft::Console::Types
         // Pass null.
         virtual void SetOwner() = 0;
 
-        virtual BOOL GetCursorPosition(_Out_ LPPOINT lpPoint) = 0;
-        virtual BOOL GetClientRectangle(_Out_ LPRECT lpRect) = 0;
-        virtual int MapPoints(_Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints) = 0;
-        virtual BOOL ConvertScreenToClient(_Inout_ LPPOINT lpPoint) = 0;
+        virtual BOOL GetCursorPosition(_Out_ til::point* lpPoint) = 0;
+        virtual BOOL GetClientRectangle(_Out_ til::rect* lpRect) = 0;
+        virtual BOOL MapRect(_Inout_ til::rect* lpRect) = 0;
+        virtual BOOL ConvertScreenToClient(_Inout_ til::point* lpPoint) = 0;
 
         virtual BOOL SendNotifyBeep() const = 0;
 
@@ -57,7 +57,7 @@ namespace Microsoft::Console::Types
 
         virtual BOOL PostUpdateWindowSize() const = 0;
 
-        virtual void UpdateWindowSize(const COORD coordSizeInChars) = 0;
+        virtual void UpdateWindowSize(const til::size coordSizeInChars) = 0;
         virtual void UpdateWindowText() = 0;
 
         virtual void HorizontalScroll(const WORD wScrollCommand,
@@ -67,6 +67,6 @@ namespace Microsoft::Console::Types
 
         [[nodiscard]] virtual HRESULT SignalUia(_In_ EVENTID id) = 0;
         [[nodiscard]] virtual HRESULT UiaSetTextAreaFocus() = 0;
-        virtual RECT GetWindowRect() const noexcept = 0;
+        virtual til::rect GetWindowRect() const noexcept = 0;
     };
 }
diff --git a/src/interactivity/inc/IWindowMetrics.hpp b/src/interactivity/inc/IWindowMetrics.hpp
index 04381dac7ae..7caf13f426f 100644
--- a/src/interactivity/inc/IWindowMetrics.hpp
+++ b/src/interactivity/inc/IWindowMetrics.hpp
@@ -21,7 +21,7 @@ namespace Microsoft::Console::Interactivity
     {
     public:
         virtual ~IWindowMetrics() = default;
-        virtual RECT GetMinClientRectInPixels() = 0;
-        virtual RECT GetMaxClientRectInPixels() = 0;
+        virtual til::rect GetMinClientRectInPixels() = 0;
+        virtual til::rect GetMaxClientRectInPixels() = 0;
     };
 }
diff --git a/src/interactivity/onecore/AccessibilityNotifier.cpp b/src/interactivity/onecore/AccessibilityNotifier.cpp
index ed823c4e2b9..743bd03e309 100644
--- a/src/interactivity/onecore/AccessibilityNotifier.cpp
+++ b/src/interactivity/onecore/AccessibilityNotifier.cpp
@@ -7,7 +7,7 @@
 
 using namespace Microsoft::Console::Interactivity::OneCore;
 
-void AccessibilityNotifier::NotifyConsoleCaretEvent(_In_ RECT /*rectangle*/) noexcept
+void AccessibilityNotifier::NotifyConsoleCaretEvent(_In_ const til::rect& /*rectangle*/) noexcept
 {
 }
 
diff --git a/src/interactivity/onecore/AccessibilityNotifier.hpp b/src/interactivity/onecore/AccessibilityNotifier.hpp
index 4e2f772b92d..90c044427f2 100644
--- a/src/interactivity/onecore/AccessibilityNotifier.hpp
+++ b/src/interactivity/onecore/AccessibilityNotifier.hpp
@@ -23,7 +23,7 @@ namespace Microsoft::Console::Interactivity::OneCore
     class AccessibilityNotifier : public IAccessibilityNotifier
     {
     public:
-        void NotifyConsoleCaretEvent(_In_ RECT rectangle) noexcept override;
+        void NotifyConsoleCaretEvent(_In_ const til::rect& rectangle) noexcept override;
         void NotifyConsoleCaretEvent(_In_ ConsoleCaretEventFlags flags, _In_ LONG position) noexcept override;
         void NotifyConsoleUpdateScrollEvent(_In_ LONG x, _In_ LONG y) noexcept override;
         void NotifyConsoleUpdateSimpleEvent(_In_ LONG start, _In_ LONG charAndAttribute) noexcept override;
diff --git a/src/interactivity/onecore/BgfxEngine.cpp b/src/interactivity/onecore/BgfxEngine.cpp
index bf5f40fe295..5ba1a0a1850 100644
--- a/src/interactivity/onecore/BgfxEngine.cpp
+++ b/src/interactivity/onecore/BgfxEngine.cpp
@@ -29,31 +29,31 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid
 {
     _runLength = sizeof(CD_IO_CHARACTER) * DisplayWidth;
 
-    _fontSize.X = FontWidth > SHORT_MAX ? SHORT_MAX : gsl::narrow_cast<SHORT>(FontWidth);
-    _fontSize.Y = FontHeight > SHORT_MAX ? SHORT_MAX : gsl::narrow_cast<SHORT>(FontHeight);
+    _fontSize.X = FontWidth > SHORT_MAX ? SHORT_MAX : gsl::narrow_cast<til::CoordType>(FontWidth);
+    _fontSize.Y = FontHeight > SHORT_MAX ? SHORT_MAX : gsl::narrow_cast<til::CoordType>(FontHeight);
 }
 
-[[nodiscard]] HRESULT BgfxEngine::Invalidate(const SMALL_RECT* const /*psrRegion*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::Invalidate(const til::rect* /*psrRegion*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT BgfxEngine::InvalidateCursor(const SMALL_RECT* const /*psrRegion*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::InvalidateCursor(const til::rect* /*psrRegion*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT BgfxEngine::InvalidateSystem(const RECT* const /*prcDirtyClient*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::InvalidateSystem(const til::rect* /*prcDirtyClient*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT BgfxEngine::InvalidateSelection(const std::vector<SMALL_RECT>& /*rectangles*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::InvalidateSelection(const std::vector<til::rect>& /*rectangles*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT BgfxEngine::InvalidateScroll(const COORD* const /*pcoordDelta*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::InvalidateScroll(const til::point* /*pcoordDelta*/) noexcept
 {
     return S_OK;
 }
@@ -127,7 +127,7 @@ CATCH_RETURN()
 }
 
 [[nodiscard]] HRESULT BgfxEngine::PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                                  const COORD coord,
+                                                  const til::point coord,
                                                   const bool /*trimLeft*/,
                                                   const bool /*lineWrapped*/) noexcept
 {
@@ -150,12 +150,12 @@ CATCH_RETURN()
 [[nodiscard]] HRESULT BgfxEngine::PaintBufferGridLines(GridLineSet const /*lines*/,
                                                        COLORREF const /*color*/,
                                                        size_t const /*cchLine*/,
-                                                       const COORD /*coordTarget*/) noexcept
+                                                       const til::point /*coordTarget*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT BgfxEngine::PaintSelection(const SMALL_RECT /*rect*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::PaintSelection(const til::rect& /*rect*/) noexcept
 {
     return S_OK;
 }
@@ -166,8 +166,8 @@ try
     // TODO: MSFT: 11448021 - Modify BGFX to support rendering full-width
     // characters and a full-width cursor.
     CD_IO_CURSOR_INFORMATION CursorInfo;
-    CursorInfo.Row = options.coordCursor.Y;
-    CursorInfo.Column = options.coordCursor.X;
+    CursorInfo.Row = gsl::narrow<USHORT>(options.coordCursor.Y);
+    CursorInfo.Column = gsl::narrow<USHORT>(options.coordCursor.X);
     CursorInfo.Height = options.ulCursorHeightPercent;
     CursorInfo.IsVisible = TRUE;
 
@@ -205,7 +205,7 @@ CATCH_RETURN()
 // - srNewViewport - The bounds of the new viewport.
 // Return Value:
 // - HRESULT S_OK
-[[nodiscard]] HRESULT BgfxEngine::UpdateViewport(const SMALL_RECT /*srNewViewport*/) noexcept
+[[nodiscard]] HRESULT BgfxEngine::UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept
 {
     return S_OK;
 }
@@ -226,7 +226,7 @@ CATCH_RETURN()
     return S_OK;
 }
 
-[[nodiscard]] HRESULT BgfxEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
+[[nodiscard]] HRESULT BgfxEngine::GetFontSize(_Out_ til::size* pFontSize) noexcept
 {
     *pFontSize = _fontSize;
     return S_OK;
diff --git a/src/interactivity/onecore/BgfxEngine.hpp b/src/interactivity/onecore/BgfxEngine.hpp
index bd35d0efe11..00476d805f1 100644
--- a/src/interactivity/onecore/BgfxEngine.hpp
+++ b/src/interactivity/onecore/BgfxEngine.hpp
@@ -32,11 +32,11 @@ namespace Microsoft::Console::Render
         BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWidth, LONG FontWidth, LONG FontHeight) noexcept;
 
         // IRenderEngine Members
-        [[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 Invalidate(const til::rect* psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override;
 
@@ -48,11 +48,11 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
         [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                              const COORD coord,
+                                              const til::point coord,
                                               const bool trimLeft,
                                               const bool lineWrapped) noexcept override;
-        [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, COLORREF const color, const size_t cchLine, const COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet const lines, COLORREF const color, size_t const cchLine, til::point const coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
 
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
 
@@ -63,12 +63,12 @@ namespace Microsoft::Console::Render
                                                    const bool isSettingDefaultBrushes) noexcept override;
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override;
         [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override;
-        [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override;
+        [[nodiscard]] HRESULT UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept override;
 
         [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, const int iDpi) noexcept override;
 
         [[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept override;
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* pFontSize) noexcept override;
         [[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
 
     protected:
@@ -82,7 +82,7 @@ namespace Microsoft::Console::Render
         SIZE_T _displayWidth;
         til::rect _dirtyArea;
 
-        COORD _fontSize;
+        til::size _fontSize;
 
         WORD _currentLegacyColorAttribute;
     };
diff --git a/src/interactivity/onecore/ConIoSrvComm.cpp b/src/interactivity/onecore/ConIoSrvComm.cpp
index b37993b6d00..e62aa67475e 100644
--- a/src/interactivity/onecore/ConIoSrvComm.cpp
+++ b/src/interactivity/onecore/ConIoSrvComm.cpp
@@ -356,13 +356,13 @@ VOID ConIoSrvComm::HandleFocusEvent(const CIS_EVENT* const Event)
                 // Right after we initialize, synchronize the screen/viewport states with the WddmCon surface dimensions
                 if (SUCCEEDED(hr))
                 {
-                    const RECT rcOld{};
+                    const til::rect rcOld;
 
                     // WddmEngine reports display size in characters, adjust to pixels for resize window calc.
                     auto rcDisplay = pWddmConEngine->GetDisplaySize();
 
                     // Get font to adjust char to pixels.
-                    COORD coordFont{};
+                    til::size coordFont;
                     LOG_IF_FAILED(pWddmConEngine->GetFontSize(&coordFont));
 
                     rcDisplay.right *= coordFont.X;
@@ -503,11 +503,11 @@ VOID ConIoSrvComm::CleanupForHeadless(const NTSTATUS status)
     return Status;
 }
 
-[[nodiscard]] NTSTATUS ConIoSrvComm::RequestUpdateDisplay(_In_ SHORT RowIndex) const
+[[nodiscard]] NTSTATUS ConIoSrvComm::RequestUpdateDisplay(_In_ til::CoordType RowIndex) const
 {
     CIS_MSG Message{};
     Message.Type = CIS_MSG_TYPE_UPDATEDISPLAY;
-    Message.UpdateDisplayParams.RowIndex = RowIndex;
+    Message.UpdateDisplayParams.RowIndex = gsl::narrow<SHORT>(RowIndex);
 
     auto Status = SendRequestReceiveReply(&Message);
     if (NT_SUCCESS(Status))
diff --git a/src/interactivity/onecore/ConIoSrvComm.hpp b/src/interactivity/onecore/ConIoSrvComm.hpp
index a12f11626e6..630a2badaf3 100644
--- a/src/interactivity/onecore/ConIoSrvComm.hpp
+++ b/src/interactivity/onecore/ConIoSrvComm.hpp
@@ -39,7 +39,7 @@ namespace Microsoft::Console::Interactivity::OneCore
         [[nodiscard]] NTSTATUS RequestGetDisplaySize(_Inout_ PCD_IO_DISPLAY_SIZE pCdDisplaySize) const;
         [[nodiscard]] NTSTATUS RequestGetFontSize(_Inout_ PCD_IO_FONT_SIZE pCdFontSize) const;
         [[nodiscard]] NTSTATUS RequestSetCursor(_In_ const CD_IO_CURSOR_INFORMATION* const pCdCursorInformation) const;
-        [[nodiscard]] NTSTATUS RequestUpdateDisplay(_In_ SHORT RowIndex) const;
+        [[nodiscard]] NTSTATUS RequestUpdateDisplay(_In_ til::CoordType RowIndex) const;
 
         [[nodiscard]] USHORT GetDisplayMode() const noexcept;
 
diff --git a/src/interactivity/onecore/ConsoleWindow.cpp b/src/interactivity/onecore/ConsoleWindow.cpp
index 03727ba83ab..f6b7fac3c89 100644
--- a/src/interactivity/onecore/ConsoleWindow.cpp
+++ b/src/interactivity/onecore/ConsoleWindow.cpp
@@ -34,7 +34,7 @@ void ConsoleWindow::SetIsFullscreen(const bool /*fFullscreenEnabled*/) noexcept
 {
 }
 
-void ConsoleWindow::ChangeViewport(const SMALL_RECT NewWindow)
+void ConsoleWindow::ChangeViewport(const til::inclusive_rect& NewWindow)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
 
@@ -74,22 +74,22 @@ void ConsoleWindow::SetOwner() noexcept
 {
 }
 
-BOOL ConsoleWindow::GetCursorPosition(LPPOINT /*lpPoint*/) noexcept
+BOOL ConsoleWindow::GetCursorPosition(til::point* /*lpPoint*/) noexcept
 {
     return FALSE;
 }
 
-BOOL ConsoleWindow::GetClientRectangle(LPRECT /*lpRect*/) noexcept
+BOOL ConsoleWindow::GetClientRectangle(til::rect* /*lpRect*/) noexcept
 {
     return FALSE;
 }
 
-int ConsoleWindow::MapPoints(LPPOINT /*lpPoints*/, UINT /*cPoints*/) noexcept
+BOOL ConsoleWindow::MapRect(til::rect* /*lpRect*/) noexcept
 {
     return 0;
 }
 
-BOOL ConsoleWindow::ConvertScreenToClient(LPPOINT /*lpPoint*/) noexcept
+BOOL ConsoleWindow::ConvertScreenToClient(til::point* /*lpPoint*/) noexcept
 {
     return 0;
 }
@@ -109,7 +109,7 @@ BOOL ConsoleWindow::PostUpdateWindowSize() const noexcept
     return FALSE;
 }
 
-void ConsoleWindow::UpdateWindowSize(const COORD /*coordSizeInChars*/) noexcept
+void ConsoleWindow::UpdateWindowSize(const til::size /*coordSizeInChars*/) noexcept
 {
 }
 
@@ -135,7 +135,7 @@ void ConsoleWindow::VerticalScroll(const WORD /*wScrollCommand*/, const WORD /*w
     return E_NOTIMPL;
 }
 
-RECT ConsoleWindow::GetWindowRect() const noexcept
+til::rect ConsoleWindow::GetWindowRect() const noexcept
 {
     return {};
 }
diff --git a/src/interactivity/onecore/ConsoleWindow.hpp b/src/interactivity/onecore/ConsoleWindow.hpp
index 680409d7080..4ab28d8626d 100644
--- a/src/interactivity/onecore/ConsoleWindow.hpp
+++ b/src/interactivity/onecore/ConsoleWindow.hpp
@@ -29,7 +29,7 @@ namespace Microsoft::Console::Interactivity::OneCore
 
         bool IsInFullscreen() const noexcept override;
         void SetIsFullscreen(const bool fFullscreenEnabled) noexcept override;
-        void ChangeViewport(const SMALL_RECT NewWindow) override;
+        void ChangeViewport(const til::inclusive_rect& NewWindow) override;
 
         void CaptureMouse() noexcept override;
         BOOL ReleaseMouse() noexcept override;
@@ -38,17 +38,17 @@ namespace Microsoft::Console::Interactivity::OneCore
 
         void SetOwner() noexcept override;
 
-        BOOL GetCursorPosition(LPPOINT lpPoint) noexcept override;
-        BOOL GetClientRectangle(LPRECT lpRect) noexcept override;
-        int MapPoints(LPPOINT lpPoints, UINT cPoints) noexcept override;
-        BOOL ConvertScreenToClient(LPPOINT lpPoint) noexcept override;
+        BOOL GetCursorPosition(til::point* lpPoint) noexcept override;
+        BOOL GetClientRectangle(til::rect* lpRect) noexcept override;
+        BOOL MapRect(_Inout_ til::rect* lpRect) noexcept override;
+        BOOL ConvertScreenToClient(til::point* lpPoint) noexcept override;
 
         BOOL SendNotifyBeep() const noexcept override;
 
         BOOL PostUpdateScrollBars() const noexcept override;
         BOOL PostUpdateWindowSize() const noexcept override;
 
-        void UpdateWindowSize(const COORD coordSizeInChars) noexcept override;
+        void UpdateWindowSize(const til::size coordSizeInChars) noexcept override;
         void UpdateWindowText() noexcept override;
 
         void HorizontalScroll(const WORD wScrollCommand, const WORD wAbsoluteChange) noexcept override;
@@ -56,6 +56,6 @@ namespace Microsoft::Console::Interactivity::OneCore
 
         [[nodiscard]] HRESULT SignalUia(_In_ EVENTID id) noexcept override;
         [[nodiscard]] HRESULT UiaSetTextAreaFocus() noexcept override;
-        RECT GetWindowRect() const noexcept override;
+        til::rect GetWindowRect() const noexcept override;
     };
 }
diff --git a/src/interactivity/onecore/WindowMetrics.cpp b/src/interactivity/onecore/WindowMetrics.cpp
index 277a66865c5..3be88cd0eb1 100644
--- a/src/interactivity/onecore/WindowMetrics.cpp
+++ b/src/interactivity/onecore/WindowMetrics.cpp
@@ -20,7 +20,7 @@
 
 using namespace Microsoft::Console::Interactivity::OneCore;
 
-RECT WindowMetrics::GetMinClientRectInPixels()
+til::rect WindowMetrics::GetMinClientRectInPixels()
 {
     // We need to always return something viable for this call,
     // so by default, set the font and display size to our headless
@@ -28,11 +28,11 @@ RECT WindowMetrics::GetMinClientRectInPixels()
     // If we get information from the Server, great. We'll calculate
     // the values for that at the end.
     // If we don't... then at least we have a non-zero rectangle.
-    COORD FontSize{};
+    til::size FontSize;
     FontSize.X = HEADLESS_FONT_SIZE_WIDTH;
     FontSize.Y = HEADLESS_FONT_SIZE_HEIGHT;
 
-    RECT DisplaySize{};
+    til::rect DisplaySize;
     DisplaySize.right = HEADLESS_DISPLAY_SIZE_WIDTH;
     DisplaySize.bottom = HEADLESS_DISPLAY_SIZE_HEIGHT;
 
@@ -112,7 +112,7 @@ RECT WindowMetrics::GetMinClientRectInPixels()
     return DisplaySize;
 }
 
-RECT WindowMetrics::GetMaxClientRectInPixels()
+til::rect WindowMetrics::GetMaxClientRectInPixels()
 {
     // OneCore consoles only have one size and cannot be resized.
     return GetMinClientRectInPixels();
diff --git a/src/interactivity/onecore/WindowMetrics.hpp b/src/interactivity/onecore/WindowMetrics.hpp
index aaa6e3ac70b..bbdc4c8407b 100644
--- a/src/interactivity/onecore/WindowMetrics.hpp
+++ b/src/interactivity/onecore/WindowMetrics.hpp
@@ -23,7 +23,7 @@ namespace Microsoft::Console::Interactivity::OneCore
     class WindowMetrics : public IWindowMetrics
     {
     public:
-        RECT GetMinClientRectInPixels() override;
-        RECT GetMaxClientRectInPixels() override;
+        til::rect GetMinClientRectInPixels() override;
+        til::rect GetMaxClientRectInPixels() override;
     };
 }
diff --git a/src/interactivity/win32/AccessibilityNotifier.cpp b/src/interactivity/win32/AccessibilityNotifier.cpp
index 7d0b57d93ad..015627b953b 100644
--- a/src/interactivity/win32/AccessibilityNotifier.cpp
+++ b/src/interactivity/win32/AccessibilityNotifier.cpp
@@ -11,14 +11,14 @@
 using namespace Microsoft::Console::Types;
 using namespace Microsoft::Console::Interactivity::Win32;
 
-void AccessibilityNotifier::NotifyConsoleCaretEvent(_In_ RECT rectangle)
+void AccessibilityNotifier::NotifyConsoleCaretEvent(_In_ const til::rect& rectangle)
 {
     const auto pWindow = ServiceLocator::LocateConsoleWindow();
     if (pWindow != nullptr)
     {
         CONSOLE_CARET_INFO caretInfo;
         caretInfo.hwnd = pWindow->GetWindowHandle();
-        caretInfo.rc = rectangle;
+        caretInfo.rc = rectangle.to_win32_rect();
 
         LOG_IF_FAILED(ServiceLocator::LocateConsoleControl<ConsoleControl>()->Control(ConsoleControl::ControlType::ConsoleSetCaretInfo,
                                                                                       &caretInfo,
@@ -41,7 +41,7 @@ void AccessibilityNotifier::NotifyConsoleCaretEvent(_In_ ConsoleCaretEventFlags
     }
 
     // UIA event notification
-    static COORD previousCursorLocation = { 0, 0 };
+    static til::point previousCursorLocation;
     const auto pWindow = ServiceLocator::LocateConsoleWindow();
 
     if (pWindow != nullptr)
diff --git a/src/interactivity/win32/AccessibilityNotifier.hpp b/src/interactivity/win32/AccessibilityNotifier.hpp
index 5bbad10b10d..115633c511e 100644
--- a/src/interactivity/win32/AccessibilityNotifier.hpp
+++ b/src/interactivity/win32/AccessibilityNotifier.hpp
@@ -27,7 +27,7 @@ namespace Microsoft::Console::Interactivity::Win32
     public:
         ~AccessibilityNotifier() = default;
 
-        void NotifyConsoleCaretEvent(_In_ RECT rectangle);
+        void NotifyConsoleCaretEvent(_In_ const til::rect& rectangle);
         void NotifyConsoleCaretEvent(_In_ ConsoleCaretEventFlags flags, _In_ LONG position);
         void NotifyConsoleUpdateScrollEvent(_In_ LONG x, _In_ LONG y);
         void NotifyConsoleUpdateSimpleEvent(_In_ LONG start, _In_ LONG charAndAttribute);
diff --git a/src/interactivity/win32/WindowIme.cpp b/src/interactivity/win32/WindowIme.cpp
index 3bf56068187..3fbfb6e5225 100644
--- a/src/interactivity/win32/WindowIme.cpp
+++ b/src/interactivity/win32/WindowIme.cpp
@@ -42,7 +42,7 @@ RECT GetImeSuggestionWindowPos()
     ClientToScreen(ServiceLocator::LocateConsoleWindow()->GetWindowHandle(), &ptSuggestion);
 
     // Move into suggestion rectangle.
-    RECT rcSuggestion = { 0 };
+    RECT rcSuggestion;
     rcSuggestion.top = rcSuggestion.bottom = ptSuggestion.y;
     rcSuggestion.left = rcSuggestion.right = ptSuggestion.x;
 
@@ -64,5 +64,5 @@ RECT GetImeSuggestionWindowPos()
 // - Rectangle specifying current text box area.
 RECT GetTextBoxArea()
 {
-    return Microsoft::Console::Interactivity::ServiceLocator::LocateConsoleWindow()->GetWindowRect();
+    return Microsoft::Console::Interactivity::ServiceLocator::LocateConsoleWindow()->GetWindowRect().to_win32_rect();
 }
diff --git a/src/interactivity/win32/WindowMetrics.cpp b/src/interactivity/win32/WindowMetrics.cpp
index 6bda2a804a4..637a08feba0 100644
--- a/src/interactivity/win32/WindowMetrics.cpp
+++ b/src/interactivity/win32/WindowMetrics.cpp
@@ -22,12 +22,11 @@ using namespace Microsoft::Console::Interactivity::Win32;
 // Arguments:
 // - <none>
 // Return Value:
-// - RECT of client area positions in pixels.
-RECT WindowMetrics::GetMinClientRectInPixels()
+// - til::rect of client area positions in pixels.
+til::rect WindowMetrics::GetMinClientRectInPixels()
 {
     // prepare rectangle
-    RECT rc;
-    SetRectEmpty(&rc);
+    til::rect rc;
 
     // set bottom/right dimensions to represent minimum window width/height
     rc.right = GetSystemMetrics(SM_CXMIN);
@@ -48,8 +47,8 @@ RECT WindowMetrics::GetMinClientRectInPixels()
 // Arguments:
 // - <none>
 // Return Value:
-// - RECT of client area positions in pixels.
-RECT WindowMetrics::GetMaxClientRectInPixels()
+// - til::rect of client area positions in pixels.
+til::rect WindowMetrics::GetMaxClientRectInPixels()
 {
     // This will retrieve the outer window rect. We need the client area to calculate characters.
     auto rc = GetMaxWindowRectInPixels();
@@ -65,11 +64,10 @@ RECT WindowMetrics::GetMaxClientRectInPixels()
 // Arguments:
 // - <none>
 // Return Value:
-// - RECT containing the left, right, top, and bottom positions from the desktop origin in pixels. Measures the outer edges of the potential window.
-RECT WindowMetrics::GetMaxWindowRectInPixels()
+// - til::rect containing the left, right, top, and bottom positions from the desktop origin in pixels. Measures the outer edges of the potential window.
+til::rect WindowMetrics::GetMaxWindowRectInPixels()
 {
-    RECT rc;
-    SetRectEmpty(&rc);
+    til::rect rc;
     return GetMaxWindowRectInPixels(&rc, nullptr);
 }
 
@@ -81,26 +79,22 @@ RECT WindowMetrics::GetMaxWindowRectInPixels()
 // - pDpiSuggested - The dpi that matches the suggested rect. We will attempt to compute this during the function, but if we fail for some reason,
 //                 - the original value passed in will be left untouched.
 // Return Value:
-// - RECT containing the left, right, top, and bottom positions from the desktop origin in pixels. Measures the outer edges of the potential window.
-RECT WindowMetrics::GetMaxWindowRectInPixels(const RECT* const prcSuggested, _Out_opt_ UINT* pDpiSuggested)
+// - til::rect containing the left, right, top, and bottom positions from the desktop origin in pixels. Measures the outer edges of the potential window.
+til::rect WindowMetrics::GetMaxWindowRectInPixels(const til::rect* const prcSuggested, _Out_opt_ UINT* pDpiSuggested)
 {
     // prepare rectangle
     auto rc = *prcSuggested;
 
-    // use zero rect to compare.
-    RECT rcZero;
-    SetRectEmpty(&rcZero);
-
     // First get the monitor pointer from either the active window or the default location (0,0,0,0)
     HMONITOR hMonitor = nullptr;
 
     // NOTE: We must use the nearest monitor because sometimes the system moves the window around into strange spots while performing snap and Win+D operations.
     // Those operations won't work correctly if we use MONITOR_DEFAULTTOPRIMARY.
     auto pWindow = ServiceLocator::LocateConsoleWindow();
-    if (pWindow == nullptr || (TRUE != EqualRect(&rc, &rcZero)))
+    if (pWindow == nullptr || rc != til::rect{})
     {
         // For invalid window handles or when we were passed a non-zero suggestion rectangle, get the monitor from the rect.
-        hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
+        hMonitor = MonitorFromRect(rc.as_win32_rect(), MONITOR_DEFAULTTONEAREST);
     }
     else
     {
@@ -131,12 +125,12 @@ RECT WindowMetrics::GetMaxWindowRectInPixels(const RECT* const prcSuggested, _Ou
     if (pWindow != nullptr && pWindow->IsInFullscreen())
     {
         // In full screen mode, we will consume the whole monitor with no chrome.
-        rc = MonitorInfo.rcMonitor;
+        rc = til::rect{ MonitorInfo.rcMonitor };
     }
     else
     {
         // In non-full screen, we want to only use the work area (avoiding the task bar space)
-        rc = MonitorInfo.rcWork;
+        rc = til::rect{ MonitorInfo.rcWork };
         rc.top -= wi.cyWindowBorders;
         rc.bottom += wi.cyWindowBorders;
         rc.left -= wi.cxWindowBorders;
@@ -170,9 +164,9 @@ RECT WindowMetrics::GetMaxWindowRectInPixels(const RECT* const prcSuggested, _Ou
 // - dwExStyle - Extended Style flags
 // Return Value:
 // - BOOL if adjustment was successful. (See AdjustWindowRectEx definition for details).
-BOOL WindowMetrics::AdjustWindowRectEx(_Inout_ LPRECT prc, const DWORD dwStyle, const BOOL fMenu, const DWORD dwExStyle)
+BOOL WindowMetrics::AdjustWindowRectEx(_Inout_ til::rect* prc, const DWORD dwStyle, const BOOL fMenu, const DWORD dwExStyle)
 {
-    return ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->AdjustWindowRectExForDpi(prc, dwStyle, fMenu, dwExStyle, ServiceLocator::LocateGlobals().dpi);
+    return AdjustWindowRectEx(prc, dwStyle, fMenu, dwExStyle, ServiceLocator::LocateGlobals().dpi);
 }
 
 // Routine Description:
@@ -185,9 +179,9 @@ BOOL WindowMetrics::AdjustWindowRectEx(_Inout_ LPRECT prc, const DWORD dwStyle,
 // - iDpi - The DPI to use for scaling.
 // Return Value:
 // - BOOL if adjustment was successful. (See AdjustWindowRectEx definition for details).
-BOOL WindowMetrics::AdjustWindowRectEx(_Inout_ LPRECT prc, const DWORD dwStyle, const BOOL fMenu, const DWORD dwExStyle, const int iDpi)
+BOOL WindowMetrics::AdjustWindowRectEx(_Inout_ til::rect* prc, const DWORD dwStyle, const BOOL fMenu, const DWORD dwExStyle, const int iDpi)
 {
-    return ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->AdjustWindowRectExForDpi(prc, dwStyle, fMenu, dwExStyle, iDpi);
+    return ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->AdjustWindowRectExForDpi(prc->as_win32_rect(), dwStyle, fMenu, dwExStyle, iDpi);
 }
 
 // Routine Description:
@@ -199,7 +193,7 @@ BOOL WindowMetrics::AdjustWindowRectEx(_Inout_ LPRECT prc, const DWORD dwStyle,
 // - prc - Pointer to rectangle to be adjusted from client to window positions.
 // Return Value:
 // - <none>
-void WindowMetrics::ConvertClientRectToWindowRect(_Inout_ RECT* const prc)
+void WindowMetrics::ConvertClientRectToWindowRect(_Inout_ til::rect* const prc)
 {
     ConvertRect(prc, ConvertRectangle::CLIENT_TO_WINDOW);
 }
@@ -213,7 +207,7 @@ void WindowMetrics::ConvertClientRectToWindowRect(_Inout_ RECT* const prc)
 // - prc - Pointer to rectangle to be adjusted from window to client positions.
 // Return Value:
 // - <none>
-void WindowMetrics::ConvertWindowRectToClientRect(_Inout_ RECT* const prc)
+void WindowMetrics::ConvertWindowRectToClientRect(_Inout_ til::rect* const prc)
 {
     ConvertRect(prc, ConvertRectangle::WINDOW_TO_CLIENT);
 }
@@ -229,10 +223,9 @@ void WindowMetrics::ConvertWindowRectToClientRect(_Inout_ RECT* const prc)
 // - dwExStyle - Extended Style flags
 // Return Value:
 // - BOOL if adjustment was successful. (See AdjustWindowRectEx definition for details).
-BOOL WindowMetrics::UnadjustWindowRectEx(_Inout_ LPRECT prc, const DWORD dwStyle, const BOOL fMenu, const DWORD dwExStyle)
+BOOL WindowMetrics::UnadjustWindowRectEx(_Inout_ til::rect* prc, const DWORD dwStyle, const BOOL fMenu, const DWORD dwExStyle)
 {
-    RECT rc;
-    SetRectEmpty(&rc);
+    til::rect rc;
     auto fRc = AdjustWindowRectEx(&rc, dwStyle, fMenu, dwExStyle);
     if (fRc)
     {
@@ -252,7 +245,7 @@ BOOL WindowMetrics::UnadjustWindowRectEx(_Inout_ LPRECT prc, const DWORD dwStyle
 // - crDirection - specifies which conversion to perform
 // Return Value:
 // - <none>
-void WindowMetrics::ConvertRect(_Inout_ RECT* const prc, const ConvertRectangle crDirection)
+void WindowMetrics::ConvertRect(_Inout_ til::rect* const prc, const ConvertRectangle crDirection)
 {
     // collect up current window style (if available) for adjustment
     DWORD dwStyle = 0;
diff --git a/src/interactivity/win32/WindowMetrics.hpp b/src/interactivity/win32/WindowMetrics.hpp
index 04f0afbcb94..8f4b9c40475 100644
--- a/src/interactivity/win32/WindowMetrics.hpp
+++ b/src/interactivity/win32/WindowMetrics.hpp
@@ -21,25 +21,25 @@ namespace Microsoft::Console::Interactivity::Win32
     public:
         // IWindowMetrics Members
         ~WindowMetrics() = default;
-        RECT GetMinClientRectInPixels();
-        RECT GetMaxClientRectInPixels();
+        til::rect GetMinClientRectInPixels();
+        til::rect GetMaxClientRectInPixels();
 
         // Public Members
-        RECT GetMaxWindowRectInPixels();
-        RECT GetMaxWindowRectInPixels(const RECT* const prcSuggested, _Out_opt_ UINT* pDpiSuggested);
+        til::rect GetMaxWindowRectInPixels();
+        til::rect GetMaxWindowRectInPixels(const til::rect* const prcSuggested, _Out_opt_ UINT* pDpiSuggested);
 
-        BOOL AdjustWindowRectEx(_Inout_ LPRECT prc,
+        BOOL AdjustWindowRectEx(_Inout_ til::rect* prc,
                                 const DWORD dwStyle,
                                 const BOOL fMenu,
                                 const DWORD dwExStyle);
-        BOOL AdjustWindowRectEx(_Inout_ LPRECT prc,
+        BOOL AdjustWindowRectEx(_Inout_ til::rect* prc,
                                 const DWORD dwStyle,
                                 const BOOL fMenu,
                                 const DWORD dwExStyle,
                                 const int iDpi);
 
-        void ConvertClientRectToWindowRect(_Inout_ RECT* const prc);
-        void ConvertWindowRectToClientRect(_Inout_ RECT* const prc);
+        void ConvertClientRectToWindowRect(_Inout_ til::rect* const prc);
+        void ConvertWindowRectToClientRect(_Inout_ til::rect* const prc);
 
     private:
         enum ConvertRectangle
@@ -48,11 +48,11 @@ namespace Microsoft::Console::Interactivity::Win32
             WINDOW_TO_CLIENT
         };
 
-        BOOL UnadjustWindowRectEx(_Inout_ LPRECT prc,
+        BOOL UnadjustWindowRectEx(_Inout_ til::rect* prc,
                                   const DWORD dwStyle,
                                   const BOOL fMenu,
                                   const DWORD dwExStyle);
 
-        void ConvertRect(_Inout_ RECT* const prc, const ConvertRectangle crDirection);
+        void ConvertRect(_Inout_ til::rect* const prc, const ConvertRectangle crDirection);
     };
 }
diff --git a/src/interactivity/win32/menu.cpp b/src/interactivity/win32/menu.cpp
index 1e72ffd33cf..beb5f680237 100644
--- a/src/interactivity/win32/menu.cpp
+++ b/src/interactivity/win32/menu.cpp
@@ -300,8 +300,8 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto& ScreenInfo = gci.GetActiveOutputBuffer();
-    pStateInfo->ScreenBufferSize = ScreenInfo.GetBufferSize().Dimensions();
-    pStateInfo->WindowSize = ScreenInfo.GetViewport().Dimensions();
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(ScreenInfo.GetBufferSize().Dimensions(), pStateInfo->ScreenBufferSize));
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(ScreenInfo.GetViewport().Dimensions(), pStateInfo->WindowSize));
 
     const auto rcWindow = ServiceLocator::LocateConsoleWindow<Window>()->GetWindowRect();
     pStateInfo->WindowPosX = rcWindow.left;
@@ -309,7 +309,7 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults)
 
     const auto& currentFont = ScreenInfo.GetCurrentFont();
     pStateInfo->FontFamily = currentFont.GetFamily();
-    pStateInfo->FontSize = currentFont.GetUnscaledSize();
+    LOG_IF_FAILED(til::unwrap_coord_size_hr(currentFont.GetUnscaledSize(), pStateInfo->FontSize));
     pStateInfo->FontWeight = currentFont.GetWeight();
     LOG_IF_FAILED(StringCchCopyW(pStateInfo->FaceName, ARRAYSIZE(pStateInfo->FaceName), currentFont.GetFaceName().data()));
 
@@ -447,7 +447,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
     // end V2 console properties
 
     // Apply font information (must come before all character calculations for window/buffer size).
-    FontInfo fiNewFont(pStateInfo->FaceName, gsl::narrow_cast<unsigned char>(pStateInfo->FontFamily), pStateInfo->FontWeight, pStateInfo->FontSize, pStateInfo->CodePage);
+    FontInfo fiNewFont(pStateInfo->FaceName, gsl::narrow_cast<unsigned char>(pStateInfo->FontFamily), pStateInfo->FontWeight, til::wrap_coord_size(pStateInfo->FontSize), pStateInfo->CodePage);
 
     ScreenInfo.UpdateFont(&fiNewFont);
 
@@ -473,10 +473,10 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
 
     {
         // Requested window in characters
-        auto coordWindow = pStateInfo->WindowSize;
+        auto coordWindow = til::wrap_coord_size(pStateInfo->WindowSize);
 
         // Requested buffer in characters.
-        auto coordBuffer = pStateInfo->ScreenBufferSize;
+        auto coordBuffer = til::wrap_coord_size(pStateInfo->ScreenBufferSize);
 
         // First limit the window so it cannot be bigger than the monitor.
         // Maximum number of characters we could fit on the given monitor.
@@ -498,7 +498,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
                 // Since we need a scroll bar in the Y direction, clamp the buffer width to make sure that
                 // it is leaving appropriate space for a scroll bar.
                 const auto coordScrollBars = ScreenInfo.GetScrollBarSizesInCharacters();
-                const auto sMaxBufferWidthWithScroll = gsl::narrow_cast<short>(coordLargest.X - coordScrollBars.X);
+                const auto sMaxBufferWidthWithScroll = coordLargest.X - coordScrollBars.X;
 
                 coordBuffer.X = std::min(coordBuffer.X, sMaxBufferWidthWithScroll);
             }
@@ -546,7 +546,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
     {
         gci.Flags &= ~CONSOLE_AUTO_POSITION;
 
-        POINT pt;
+        til::point pt;
         pt.x = pStateInfo->WindowPosX;
         pt.y = pStateInfo->WindowPosY;
 
diff --git a/src/interactivity/win32/screenInfoUiaProvider.cpp b/src/interactivity/win32/screenInfoUiaProvider.cpp
index bc9ebcdd8b5..80e3785040a 100644
--- a/src/interactivity/win32/screenInfoUiaProvider.cpp
+++ b/src/interactivity/win32/screenInfoUiaProvider.cpp
@@ -92,7 +92,7 @@ HWND ScreenInfoUiaProvider::GetWindowHandle() const
     return _pUiaParent->GetWindowHandle();
 }
 
-void ScreenInfoUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
+void ScreenInfoUiaProvider::ChangeViewport(const til::inclusive_rect& NewWindow)
 {
     _pUiaParent->ChangeViewport(NewWindow);
 }
@@ -139,8 +139,8 @@ HRESULT ScreenInfoUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* c
 }
 
 HRESULT ScreenInfoUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* const pProvider,
-                                               const COORD start,
-                                               const COORD end,
+                                               const til::point start,
+                                               const til::point end,
                                                const std::wstring_view wordDelimiters,
                                                _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr)
 {
diff --git a/src/interactivity/win32/screenInfoUiaProvider.hpp b/src/interactivity/win32/screenInfoUiaProvider.hpp
index 2050eb35421..1e38c51d6bb 100644
--- a/src/interactivity/win32/screenInfoUiaProvider.hpp
+++ b/src/interactivity/win32/screenInfoUiaProvider.hpp
@@ -43,7 +43,7 @@ namespace Microsoft::Console::Interactivity::Win32
         IFACEMETHODIMP get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) override;
 
         HWND GetWindowHandle() const;
-        void ChangeViewport(const SMALL_RECT NewWindow) override;
+        void ChangeViewport(const til::inclusive_rect& NewWindow) override;
 
     protected:
         HRESULT GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
@@ -59,8 +59,8 @@ namespace Microsoft::Console::Interactivity::Win32
 
         // specific endpoint range
         HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const pProvider,
-                                const COORD start,
-                                const COORD end,
+                                const til::point start,
+                                const til::point end,
                                 const std::wstring_view wordDelimiters,
                                 _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
 
diff --git a/src/interactivity/win32/uiaTextRange.cpp b/src/interactivity/win32/uiaTextRange.cpp
index e2831b70cc8..68734446748 100644
--- a/src/interactivity/win32/uiaTextRange.cpp
+++ b/src/interactivity/win32/uiaTextRange.cpp
@@ -30,8 +30,8 @@ HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
 // specific endpoint range
 HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
                                              _In_ IRawElementProviderSimple* const pProvider,
-                                             const COORD start,
-                                             const COORD end,
+                                             const til::point start,
+                                             const til::point end,
                                              bool blockRange,
                                              const std::wstring_view wordDelimiters) noexcept
 {
@@ -77,14 +77,14 @@ IFACEMETHODIMP UiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider*
     return S_OK;
 }
 
-void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
+void UiaTextRange::_TranslatePointToScreen(til::point* clientPoint) const
 {
-    ClientToScreen(_getWindowHandle(), clientPoint);
+    ClientToScreen(_getWindowHandle(), clientPoint->as_win32_point());
 }
 
-void UiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) const
+void UiaTextRange::_TranslatePointFromScreen(til::point* screenPoint) const
 {
-    ScreenToClient(_getWindowHandle(), screenPoint);
+    ScreenToClient(_getWindowHandle(), screenPoint->as_win32_point());
 }
 
 HWND UiaTextRange::_getWindowHandle() const
diff --git a/src/interactivity/win32/uiaTextRange.hpp b/src/interactivity/win32/uiaTextRange.hpp
index b97652e15a6..1d3fc3478fb 100644
--- a/src/interactivity/win32/uiaTextRange.hpp
+++ b/src/interactivity/win32/uiaTextRange.hpp
@@ -40,8 +40,8 @@ namespace Microsoft::Console::Interactivity::Win32
         // specific endpoint range
         HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
                                        _In_ IRawElementProviderSimple* const pProvider,
-                                       _In_ const COORD start,
-                                       _In_ const COORD end,
+                                       _In_ const til::point start,
+                                       _In_ const til::point end,
                                        _In_ bool blockRange = false,
                                        _In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
 
@@ -56,8 +56,8 @@ namespace Microsoft::Console::Interactivity::Win32
         IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
 
     protected:
-        void _TranslatePointToScreen(LPPOINT clientPoint) const override;
-        void _TranslatePointFromScreen(LPPOINT screenPoint) const override;
+        void _TranslatePointToScreen(til::point* clientPoint) const override;
+        void _TranslatePointFromScreen(til::point* screenPoint) const override;
 
     private:
         HWND _getWindowHandle() const;
diff --git a/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp b/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp
index 535d7822971..89b8bb45d2a 100644
--- a/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp
+++ b/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp
@@ -6,14 +6,14 @@
 // Read tools\TestTableWriter\README.md for more details
 // Define a few helpful variables
 constexpr til::rect bufferSize{ 0, 0, 80, 300 };
-constexpr short midX{ 40 };
-constexpr short midY{ 150 };
-constexpr short midPopulatedY{ 75 };
-constexpr short segment0{ 0 };
-constexpr short segment1{ 16 };
-constexpr short segment2{ 32 };
-constexpr short segment3{ 48 };
-constexpr short segment4{ 64 };
+constexpr til::CoordType midX{ 40 };
+constexpr til::CoordType midY{ 150 };
+constexpr til::CoordType midPopulatedY{ 75 };
+constexpr til::CoordType segment0{ 0 };
+constexpr til::CoordType segment1{ 16 };
+constexpr til::CoordType segment2{ 32 };
+constexpr til::CoordType segment3{ 48 };
+constexpr til::CoordType segment4{ 64 };
 constexpr til::point origin{ 0, 0 };
 constexpr til::point midTop{ midX, 0 };
 constexpr til::point midHistory{ midX, midPopulatedY };
diff --git a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp
index e3ccd2e7af4..90e0302861a 100644
--- a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp
+++ b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp
@@ -227,7 +227,7 @@ class DummyElementProvider final : public ScreenInfoUiaProviderBase
         return E_NOTIMPL;
     }
 
-    void ChangeViewport(const SMALL_RECT /*NewWindow*/)
+    void ChangeViewport(const til::inclusive_rect& /*NewWindow*/)
     {
         return;
     }
@@ -254,8 +254,8 @@ class DummyElementProvider final : public ScreenInfoUiaProviderBase
 
     // specific endpoint range
     HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const /*pProvider*/,
-                            const COORD /*start*/,
-                            const COORD /*end*/,
+                            const til::point /*start*/,
+                            const til::point /*end*/,
                             const std::wstring_view /*wordDelimiters*/,
                             _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** /*ppUtr*/) override
     {
@@ -286,15 +286,15 @@ class UiaTextRangeTests
     struct ExpectedResult
     {
         int moveAmt;
-        COORD start;
-        COORD end;
+        til::point start;
+        til::point end;
     };
 
     struct MoveTest
     {
         std::wstring comment;
-        COORD start;
-        COORD end;
+        til::point start;
+        til::point end;
         int moveAmt;
         ExpectedResult expected;
     };
@@ -302,8 +302,8 @@ class UiaTextRangeTests
     struct MoveEndpointTest
     {
         std::wstring comment;
-        COORD start;
-        COORD end;
+        til::point start;
+        til::point end;
         int moveAmt;
         TextPatternRangeEndpoint endpoint;
         ExpectedResult expected;
@@ -312,7 +312,7 @@ class UiaTextRangeTests
     struct ScrollTest
     {
         std::wstring comment;
-        short yPos;
+        til::CoordType yPos;
     };
 
     static constexpr const wchar_t* toString(TextUnit unit) noexcept
@@ -358,7 +358,7 @@ class UiaTextRangeTests
         // the variables from the generated tests.
 
         // fill first half of text buffer with text
-        for (UINT i = 0; i < _pTextBuffer->TotalRowCount() / 2; ++i)
+        for (auto i = 0; i < _pTextBuffer->TotalRowCount() / 2; ++i)
         {
             auto& row = _pTextBuffer->GetRowByOffset(i);
             auto& charRow = row.GetCharRow();
@@ -399,8 +399,8 @@ class UiaTextRangeTests
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&degenerate,
                                                                         _pUiaData,
                                                                         &_dummyProvider,
-                                                                        origin.to_win32_coord(),
-                                                                        origin.to_win32_coord()));
+                                                                        origin,
+                                                                        origin));
         VERIFY_IS_TRUE(degenerate->IsDegenerate());
         VERIFY_ARE_EQUAL(degenerate->_start, degenerate->_end);
 
@@ -410,8 +410,8 @@ class UiaTextRangeTests
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&notDegenerate,
                                                                         _pUiaData,
                                                                         &_dummyProvider,
-                                                                        origin.to_win32_coord(),
-                                                                        end.to_win32_coord()));
+                                                                        origin,
+                                                                        end));
         VERIFY_IS_FALSE(notDegenerate->IsDegenerate());
         VERIFY_ARE_NOT_EQUAL(notDegenerate->_start, notDegenerate->_end);
     }
@@ -422,8 +422,8 @@ class UiaTextRangeTests
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr1,
                                                                         _pUiaData,
                                                                         &_dummyProvider,
-                                                                        origin.to_win32_coord(),
-                                                                        origin.to_win32_coord()));
+                                                                        origin,
+                                                                        origin));
 
         // utr2 initialized to have the same start/end as utr1
         Microsoft::WRL::ComPtr<ITextRangeProvider> utr2;
@@ -439,8 +439,8 @@ class UiaTextRangeTests
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr2,
                                                                         _pUiaData,
                                                                         &_dummyProvider,
-                                                                        origin.to_win32_coord(),
-                                                                        end.to_win32_coord()));
+                                                                        origin,
+                                                                        end));
 
         Log::Comment(L"_end is different");
         THROW_IF_FAILED(utr1->Compare(utr2.Get(), &comparison));
@@ -453,8 +453,8 @@ class UiaTextRangeTests
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr1,
                                                                         _pUiaData,
                                                                         &_dummyProvider,
-                                                                        origin.to_win32_coord(),
-                                                                        origin.to_win32_coord()));
+                                                                        origin,
+                                                                        origin));
 
         Microsoft::WRL::ComPtr<ITextRangeProvider> utr2;
         THROW_IF_FAILED(utr1->Clone(&utr2));
@@ -475,8 +475,8 @@ class UiaTextRangeTests
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr2,
                                                                         _pUiaData,
                                                                         &_dummyProvider,
-                                                                        origin.to_win32_coord(),
-                                                                        end.to_win32_coord()));
+                                                                        origin,
+                                                                        end));
 
         Log::Comment(L"_start should match");
         THROW_IF_FAILED(utr1->CompareEndpoints(TextPatternRangeEndpoint_Start, utr2.Get(), TextPatternRangeEndpoint_Start, &comparison));
@@ -492,11 +492,11 @@ class UiaTextRangeTests
     TEST_METHOD(ExpandToEnclosingUnit)
     {
         // Let's start by filling the text buffer with something useful:
-        for (UINT i = 0; i < _pTextBuffer->TotalRowCount(); ++i)
+        for (auto i = 0; i < _pTextBuffer->TotalRowCount(); ++i)
         {
             auto& row = _pTextBuffer->GetRowByOffset(i);
             auto& charRow = row.GetCharRow();
-            for (size_t j = 0; j < charRow.size(); ++j)
+            for (auto j = 0; j < charRow.size(); ++j)
             {
                 // every 5th cell is a space, otherwise a letter
                 // this is used to simulate words
@@ -541,8 +541,8 @@ class UiaTextRangeTests
 
         struct TextUnitBoundaries
         {
-            COORD start;
-            COORD end;
+            til::point start;
+            til::point end;
         };
 
         const std::map<TextUnit, TextUnitBoundaries> textUnitBoundaries = {
@@ -565,7 +565,7 @@ class UiaTextRangeTests
         };
 
         Microsoft::WRL::ComPtr<UiaTextRange> utr;
-        auto verifyExpansion = [&](TextUnit textUnit, COORD utrStart, COORD utrEnd) {
+        auto verifyExpansion = [&](TextUnit textUnit, til::point utrStart, til::point utrEnd) {
             THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr,
                                                                             _pUiaData,
                                                                             &_dummyProvider,
@@ -590,7 +590,7 @@ class UiaTextRangeTests
             if (textUnit != TextUnit_Character)
             {
                 Log::Comment(NoThrowString().Format(L"%s - Test 2", toString(textUnit)));
-                const COORD end = { boundaries.start.X + 1, boundaries.start.Y };
+                const til::point end = { boundaries.start.X + 1, boundaries.start.Y };
                 verifyExpansion(textUnit, boundaries.start, end);
             }
 
@@ -602,7 +602,7 @@ class UiaTextRangeTests
             if (textUnit != TextUnit_Character && textUnit != TextUnit_Document)
             {
                 Log::Comment(NoThrowString().Format(L"%s - Test 4", toString(textUnit)));
-                const COORD end = { boundaries.end.X + 1, boundaries.end.Y };
+                const til::point end = { boundaries.end.X + 1, boundaries.end.Y };
                 verifyExpansion(textUnit, boundaries.start, end);
             }
 
@@ -610,7 +610,7 @@ class UiaTextRangeTests
             if (textUnit != TextUnit_Character)
             {
                 Log::Comment(NoThrowString().Format(L"%s - Test 5", toString(textUnit)));
-                const COORD start = { boundaries.start.X + 1, boundaries.start.Y };
+                const til::point start = { boundaries.start.X + 1, boundaries.start.Y };
                 verifyExpansion(textUnit, start, start);
             }
 
@@ -618,8 +618,8 @@ class UiaTextRangeTests
             if (textUnit != TextUnit_Character)
             {
                 Log::Comment(NoThrowString().Format(L"%s - Test 6", toString(textUnit)));
-                const COORD start = { boundaries.start.X + 1, boundaries.start.Y };
-                const COORD end = { start.X + 1, start.Y };
+                const til::point start = { boundaries.start.X + 1, boundaries.start.Y };
+                const til::point end = { start.X + 1, start.Y };
                 verifyExpansion(textUnit, start, end);
             }
 
@@ -627,7 +627,7 @@ class UiaTextRangeTests
             if (textUnit != TextUnit_Character)
             {
                 Log::Comment(NoThrowString().Format(L"%s - Test 7", toString(textUnit)));
-                const COORD start = { boundaries.start.X + 1, boundaries.start.Y };
+                const til::point start = { boundaries.start.X + 1, boundaries.start.Y };
                 verifyExpansion(textUnit, start, boundaries.end);
             }
 
@@ -635,8 +635,8 @@ class UiaTextRangeTests
             if (textUnit != TextUnit_Character && textUnit != TextUnit_Document)
             {
                 Log::Comment(NoThrowString().Format(L"%s - Test 8", toString(textUnit)));
-                const COORD start = { boundaries.start.X + 1, boundaries.start.Y };
-                const COORD end = { boundaries.end.X + 1, boundaries.end.Y };
+                const til::point start = { boundaries.start.X + 1, boundaries.start.Y };
+                const til::point end = { boundaries.end.X + 1, boundaries.end.Y };
                 verifyExpansion(textUnit, start, end);
             }
         }
@@ -644,8 +644,8 @@ class UiaTextRangeTests
 
     TEST_METHOD(MoveEndpointByRange)
     {
-        const COORD start{ 0, 1 };
-        const COORD end{ 1, 2 };
+        const til::point start{ 0, 1 };
+        const til::point end{ 1, 2 };
         Microsoft::WRL::ComPtr<UiaTextRange> utr;
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr,
                                                                         _pUiaData,
@@ -659,8 +659,8 @@ class UiaTextRangeTests
             THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&target,
                                                                             _pUiaData,
                                                                             &_dummyProvider,
-                                                                            origin.to_win32_coord(),
-                                                                            origin.to_win32_coord()));
+                                                                            origin,
+                                                                            origin));
         };
 
         Log::Comment(L"Move target's end to utr1's start");
@@ -669,7 +669,7 @@ class UiaTextRangeTests
             THROW_IF_FAILED(target->MoveEndpointByRange(TextPatternRangeEndpoint_End,
                                                         utr.Get(),
                                                         TextPatternRangeEndpoint_Start));
-            VERIFY_ARE_EQUAL(target->GetEndpoint(TextPatternRangeEndpoint_Start), origin.to_win32_coord());
+            VERIFY_ARE_EQUAL(target->GetEndpoint(TextPatternRangeEndpoint_Start), origin);
             VERIFY_ARE_EQUAL(target->GetEndpoint(TextPatternRangeEndpoint_End), utr->GetEndpoint(TextPatternRangeEndpoint_Start));
         }
 
@@ -679,7 +679,7 @@ class UiaTextRangeTests
             THROW_IF_FAILED(target->MoveEndpointByRange(TextPatternRangeEndpoint_End,
                                                         utr.Get(),
                                                         TextPatternRangeEndpoint_End));
-            VERIFY_ARE_EQUAL(target->GetEndpoint(TextPatternRangeEndpoint_Start), origin.to_win32_coord());
+            VERIFY_ARE_EQUAL(target->GetEndpoint(TextPatternRangeEndpoint_Start), origin);
             VERIFY_ARE_EQUAL(target->GetEndpoint(TextPatternRangeEndpoint_End), utr->GetEndpoint(TextPatternRangeEndpoint_End));
 
             THROW_IF_FAILED(target->MoveEndpointByRange(TextPatternRangeEndpoint_Start,
@@ -738,7 +738,7 @@ class UiaTextRangeTests
 
         // GH#6986: This is used as the "end of the buffer" to help screen readers run faster
         //          instead of parsing through thousands of empty lines of text.
-        const COORD documentEnd{ _pTextBuffer->GetSize().Left(), gsl::narrow<short>(_pTextBuffer->GetLastNonSpaceCharacter().Y + 1) };
+        const til::point documentEnd{ _pTextBuffer->GetSize().Left(), _pTextBuffer->GetLastNonSpaceCharacter().Y + 1 };
 
         // clang-format off
         const std::vector<MoveTest> testData
@@ -798,8 +798,8 @@ class UiaTextRangeTests
                 -5,
                 {
                     -5,
-                    {gsl::narrow<short>(lastColumnIndex - 4), 0},
-                    {gsl::narrow<short>(lastColumnIndex - 3), 0}
+                    {lastColumnIndex - 4, 0},
+                    {lastColumnIndex - 3, 0}
                 }
             }
         };
@@ -822,11 +822,11 @@ class UiaTextRangeTests
 
     TEST_METHOD(CanMoveByLine)
     {
-        const SHORT lastColumnIndex = _pScreenInfo->GetBufferSize().Width() - 1;
+        const auto lastColumnIndex = _pScreenInfo->GetBufferSize().Width() - 1;
 
         // GH#6986: This is used as the "end of the buffer" to help screen readers run faster
         //          instead of parsing through thousands of empty lines of text.
-        const COORD documentEnd{ _pTextBuffer->GetSize().Left(), gsl::narrow<short>(_pTextBuffer->GetLastNonSpaceCharacter().Y + 1) };
+        const til::point documentEnd{ _pTextBuffer->GetSize().Left(), _pTextBuffer->GetLastNonSpaceCharacter().Y + 1 };
 
         // clang-format off
         const std::vector<MoveTest> testData
@@ -862,8 +862,8 @@ class UiaTextRangeTests
                 -3,
                 {
                     -3,
-                    {0, base::ClampSub(documentEnd.Y, 3)},
-                    {0, base::ClampSub(documentEnd.Y, 3)}
+                    {0, documentEnd.Y - 3},
+                    {0, documentEnd.Y - 3}
                 }
             },
 
@@ -910,14 +910,14 @@ class UiaTextRangeTests
 
     TEST_METHOD(CanMoveEndpointByUnitCharacter)
     {
-        const SHORT lastColumnIndex = _pScreenInfo->GetBufferSize().Width() - 1;
+        const auto lastColumnIndex = _pScreenInfo->GetBufferSize().Width() - 1;
 
         // GH#6986: This is used as the "end of the buffer" to help screen readers run faster
         //          instead of parsing through thousands of empty lines of text.
-        const COORD documentEnd{ _pTextBuffer->GetSize().RightInclusive(), _pTextBuffer->GetLastNonSpaceCharacter().Y };
+        const til::point documentEnd{ _pTextBuffer->GetSize().RightInclusive(), _pTextBuffer->GetLastNonSpaceCharacter().Y };
 
         // clang-format off
-        const std::vector<MoveEndpointTest> testData
+        const std::array testData
         {
             MoveEndpointTest{
                 L"can't move _start past the beginning of the document when _start is positioned at the beginning",
@@ -967,7 +967,7 @@ class UiaTextRangeTests
                 {
                     1,
                     {0,0},
-                    {0, base::ClampAdd(documentEnd.Y,1)}
+                    {0, documentEnd.Y + 1}
                 }
             },
 
@@ -987,39 +987,39 @@ class UiaTextRangeTests
             MoveEndpointTest{
                 L"can't move _end past the beginning of the document when _end is positioned at the end",
                 {0, documentEnd.Y},
-                {0, base::ClampAdd(documentEnd.Y,1)},
+                {0, documentEnd.Y + 1},
                 1,
                 TextPatternRangeEndpoint_End,
                 {
                     0,
                     {0, documentEnd.Y},
-                    {0, base::ClampAdd(documentEnd.Y,1)},
+                    {0, documentEnd.Y + 1},
                 }
             },
 
             MoveEndpointTest{
                 L"can partially move _end to the end of the document when it is closer than the move count requested",
                 {0, 0},
-                {base::ClampSub(lastColumnIndex, 3), documentEnd.Y},
+                {lastColumnIndex - 3, documentEnd.Y},
                 5,
                 TextPatternRangeEndpoint_End,
                 {
                     4,
                     {0, 0},
-                    {0, base::ClampAdd(documentEnd.Y,1)},
+                    {0, documentEnd.Y + 1},
                 }
             },
 
             MoveEndpointTest{
                 L"can't move _start past the end of the document",
-                {base::ClampSub(lastColumnIndex, 4), documentEnd.Y},
-                {0, base::ClampAdd(documentEnd.Y,1)},
+                {lastColumnIndex - 4, documentEnd.Y},
+                {0, documentEnd.Y + 1},
                 5,
                 TextPatternRangeEndpoint_Start,
                 {
                     5,
-                    {0, base::ClampAdd(documentEnd.Y,1)},
-                    {0, base::ClampAdd(documentEnd.Y,1)},
+                    {0, documentEnd.Y + 1},
+                    {0, documentEnd.Y + 1},
                 }
             },
 
@@ -1055,12 +1055,12 @@ class UiaTextRangeTests
 
     TEST_METHOD(CanMoveEndpointByUnitLine)
     {
-        const SHORT lastColumnIndex = _pScreenInfo->GetBufferSize().Width() - 1;
-        const auto bottomRow = gsl::narrow<SHORT>(_pTextBuffer->TotalRowCount() - 1);
+        const auto lastColumnIndex = _pScreenInfo->GetBufferSize().Width() - 1;
+        const auto bottomRow = _pTextBuffer->TotalRowCount() - 1;
 
         // GH#6986: This is used as the "end of the buffer" to help screen readers run faster
         //          instead of parsing through thousands of empty lines of text.
-        const COORD documentEnd{ _pTextBuffer->GetSize().Left(), gsl::narrow<short>(_pTextBuffer->GetLastNonSpaceCharacter().Y + 1) };
+        const til::point documentEnd{ _pTextBuffer->GetSize().Left(), _pTextBuffer->GetLastNonSpaceCharacter().Y + 1 };
 
         // clang-format off
         const std::vector<MoveEndpointTest> testData
@@ -1134,7 +1134,7 @@ class UiaTextRangeTests
             MoveEndpointTest{
                 L"can't move _end forwards when it's on the bottom row (past doc end)",
                 {0, 0},
-                {gsl::narrow<short>(lastColumnIndex - 3), bottomRow},
+                {lastColumnIndex - 3, bottomRow},
                 1,
                 TextPatternRangeEndpoint_End,
                 0,
@@ -1145,7 +1145,7 @@ class UiaTextRangeTests
             MoveEndpointTest{
                 L"can't move _end forwards when it's at the end of the buffer already (past doc end)",
                 {0, 0},
-                {0, gsl::narrow<short>(bottomRow + 1)},
+                {0, bottomRow + 1},
                 1,
                 TextPatternRangeEndpoint_End,
                 0,
@@ -1167,7 +1167,7 @@ class UiaTextRangeTests
             MoveEndpointTest{
                 L"moving _end backward when it's already on the top row creates a degenerate range at the document start",
                 {4, 0},
-                {gsl::narrow<short>(lastColumnIndex - 5), 0},
+                {lastColumnIndex - 5, 0},
                 -1,
                 TextPatternRangeEndpoint_End,
                 -1,
@@ -1194,11 +1194,11 @@ class UiaTextRangeTests
 
     TEST_METHOD(CanMoveEndpointByUnitDocument)
     {
-        const auto bottomRow = gsl::narrow<SHORT>(_pTextBuffer->TotalRowCount() - 1);
+        const auto bottomRow = _pTextBuffer->TotalRowCount() - 1;
 
         // GH#6986: This is used as the "end of the buffer" to help screen readers run faster
         //          instead of parsing through thousands of empty lines of text.
-        const COORD documentEnd{ _pTextBuffer->GetSize().Left(), gsl::narrow<short>(_pTextBuffer->GetLastNonSpaceCharacter().Y + 1) };
+        const til::point documentEnd{ _pTextBuffer->GetSize().Left(), _pTextBuffer->GetLastNonSpaceCharacter().Y + 1 };
 
         // clang-format off
         const std::vector<MoveEndpointTest> testData =
@@ -1232,7 +1232,7 @@ class UiaTextRangeTests
             MoveEndpointTest{
                 L"can't move _end forward when it's already at the end of the buffer (past doc end)",
                 {3, 2},
-                {0, gsl::narrow<short>(bottomRow + 1)},
+                {0, bottomRow + 1},
                 1,
                 TextPatternRangeEndpoint_End,
                 {
@@ -1304,7 +1304,7 @@ class UiaTextRangeTests
         // at the end exclusive, the UTR should refuse to move past
         // the end.
         const auto lastNonspaceCharPos{ _pTextBuffer->GetLastNonSpaceCharacter() };
-        const COORD documentEnd{ 0, lastNonspaceCharPos.Y + 1 };
+        const til::point documentEnd{ 0, lastNonspaceCharPos.Y + 1 };
 
         // Iterate over each TextUnit. If we don't support
         // the given TextUnit, we're supposed to fallback
@@ -1320,7 +1320,7 @@ class UiaTextRangeTests
         Log::Comment(NoThrowString().Format(L"%s", toString(static_cast<TextUnit>(textUnit))));
 
         // Create a degenerate UTR at EndExclusive
-        THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, bufferEnd.to_win32_coord(), endExclusive.to_win32_coord()));
+        THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, bufferEnd, endExclusive));
         THROW_IF_FAILED(utr->ExpandToEnclosingUnit(static_cast<TextUnit>(textUnit)));
 
         VERIFY_ARE_EQUAL(documentEnd, utr->_end);
@@ -1335,15 +1335,15 @@ class UiaTextRangeTests
         // write "temp" at (2,2)
         _pTextBuffer->Reset();
         const til::point writeTarget{ 2, 2 };
-        _pTextBuffer->Write({ L"temp" }, writeTarget.to_win32_coord());
+        _pTextBuffer->Write({ L"temp" }, writeTarget);
 
         // GH#6986: This is used as the "end of the buffer" to help screen readers run faster
         //          instead of parsing through thousands of empty lines of text.
-        const til::point documentEndInclusive{ base::ClampSub<short, short>(static_cast<short>(bufferSize.right), 1), _pTextBuffer->GetLastNonSpaceCharacter().Y };
-        const til::point documentEndExclusive{ static_cast<short>(bufferSize.left), base::ClampAdd(documentEndInclusive.y, 1) };
+        const til::point documentEndInclusive{ bufferSize.right - 1, _pTextBuffer->GetLastNonSpaceCharacter().Y };
+        const til::point documentEndExclusive{ bufferSize.left, documentEndInclusive.y + 1 };
 
-        const til::point lastLineStart{ static_cast<short>(bufferSize.left), documentEndInclusive.y };
-        const auto secondToLastLinePos{ point_offset_by_line(til::point{ lastLineStart }, bufferSize, -1) };
+        const til::point lastLineStart{ bufferSize.left, documentEndInclusive.y };
+        const auto secondToLastLinePos{ point_offset_by_line(lastLineStart, bufferSize, -1) };
         const til::point secondToLastCharacterPos{ documentEndInclusive.x - 1, documentEndInclusive.y };
 
         // Iterate over each TextUnit. If we don't support
@@ -1368,22 +1368,22 @@ class UiaTextRangeTests
         Log::Comment(NoThrowString().Format(L"Forward by %s", toString(textUnit)));
 
         // Create an UTR at EndExclusive
-        const auto utrEnd{ atDocumentEnd ? documentEndExclusive : til::point{ endExclusive } };
+        const auto utrEnd{ atDocumentEnd ? documentEndExclusive : endExclusive };
         if (degenerate)
         {
             // UTR: (exclusive, exclusive) range
             const auto utrStart{ atDocumentEnd ? documentEndExclusive : endExclusive };
-            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart.to_win32_coord(), utrEnd.to_win32_coord()));
+            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd));
         }
         else
         {
             // UTR: (inclusive, exclusive) range
             const auto utrStart{ atDocumentEnd ? documentEndInclusive : endInclusive };
-            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart.to_win32_coord(), utrEnd.to_win32_coord()));
+            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd));
         }
         THROW_IF_FAILED(utr->Move(textUnit, 1, &moveAmt));
 
-        VERIFY_ARE_EQUAL(documentEndExclusive.to_win32_coord(), utr->_end);
+        VERIFY_ARE_EQUAL(documentEndExclusive, utr->_end);
         VERIFY_ARE_EQUAL(0, moveAmt);
 
         // Verify expansion works properly
@@ -1391,23 +1391,23 @@ class UiaTextRangeTests
         THROW_IF_FAILED(utr->ExpandToEnclosingUnit(textUnit));
         if (textUnit <= TextUnit::TextUnit_Character)
         {
-            VERIFY_ARE_EQUAL(documentEndInclusive.to_win32_coord(), utr->_start);
-            VERIFY_ARE_EQUAL(documentEndExclusive.to_win32_coord(), utr->_end);
+            VERIFY_ARE_EQUAL(documentEndInclusive, utr->_start);
+            VERIFY_ARE_EQUAL(documentEndExclusive, utr->_end);
         }
         else if (textUnit <= TextUnit::TextUnit_Word)
         {
-            VERIFY_ARE_EQUAL(writeTarget.to_win32_coord(), utr->_start);
-            VERIFY_ARE_EQUAL(documentEndExclusive.to_win32_coord(), utr->_end);
+            VERIFY_ARE_EQUAL(writeTarget, utr->_start);
+            VERIFY_ARE_EQUAL(documentEndExclusive, utr->_end);
         }
         else if (textUnit <= TextUnit::TextUnit_Line)
         {
-            VERIFY_ARE_EQUAL(lastLineStart.to_win32_coord(), utr->_start);
-            VERIFY_ARE_EQUAL(documentEndExclusive.to_win32_coord(), utr->_end);
+            VERIFY_ARE_EQUAL(lastLineStart, utr->_start);
+            VERIFY_ARE_EQUAL(documentEndExclusive, utr->_end);
         }
         else // textUnit <= TextUnit::TextUnit_Document:
         {
-            VERIFY_ARE_EQUAL(origin.to_win32_coord(), utr->_start);
-            VERIFY_ARE_EQUAL(documentEndExclusive.to_win32_coord(), utr->_end);
+            VERIFY_ARE_EQUAL(origin, utr->_start);
+            VERIFY_ARE_EQUAL(documentEndExclusive, utr->_end);
         }
 
         // reset the UTR
@@ -1415,13 +1415,13 @@ class UiaTextRangeTests
         {
             // UTR: (exclusive, exclusive) range
             const auto utrStart{ atDocumentEnd ? documentEndExclusive : endExclusive };
-            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart.to_win32_coord(), utrEnd.to_win32_coord()));
+            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd));
         }
         else
         {
             // UTR: (inclusive, exclusive) range
             const auto utrStart{ atDocumentEnd ? documentEndInclusive : endInclusive };
-            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart.to_win32_coord(), utrEnd.to_win32_coord()));
+            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd));
         }
 
         // Verify that moving backwards still works properly
@@ -1435,26 +1435,26 @@ class UiaTextRangeTests
             // -  degenerate --> it moves with _start to stay degenerate
             // - !degenerate --> it excludes the last char, to select the second to last char
             VERIFY_ARE_EQUAL(-1, moveAmt);
-            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? documentEndInclusive : secondToLastCharacterPos, til::point{ utr->_start });
-            VERIFY_ARE_EQUAL(documentEndInclusive, til::point{ utr->_end });
+            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? documentEndInclusive : secondToLastCharacterPos, utr->_start);
+            VERIFY_ARE_EQUAL(documentEndInclusive, utr->_end);
         }
         else if (textUnit <= TextUnit::TextUnit_Word)
         {
             VERIFY_ARE_EQUAL(-1, moveAmt);
-            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? writeTarget : origin, til::point{ utr->_start });
-            VERIFY_ARE_EQUAL(writeTarget, til::point{ utr->_end });
+            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? writeTarget : origin, utr->_start);
+            VERIFY_ARE_EQUAL(writeTarget, utr->_end);
         }
         else if (textUnit <= TextUnit::TextUnit_Line)
         {
             VERIFY_ARE_EQUAL(-1, moveAmt);
-            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? til::point{ lastLineStart } : secondToLastLinePos, til::point{ utr->_start });
-            VERIFY_ARE_EQUAL(lastLineStart, til::point{ utr->_end });
+            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? lastLineStart : secondToLastLinePos, utr->_start);
+            VERIFY_ARE_EQUAL(lastLineStart, utr->_end);
         }
         else // textUnit <= TextUnit::TextUnit_Document:
         {
             VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? -1 : 0, moveAmt);
-            VERIFY_ARE_EQUAL(origin, til::point{ utr->_start });
-            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? origin : til::point{ documentEndExclusive }, til::point{ utr->_end });
+            VERIFY_ARE_EQUAL(origin, utr->_start);
+            VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? origin : documentEndExclusive, utr->_end);
         }
     }
 
@@ -1464,11 +1464,11 @@ class UiaTextRangeTests
 
         const auto originExclusive{ point_offset_by_char(origin, bufferSize, 1) };
 
-        _pTextBuffer->Write({ L"My name is Carlos" }, origin.to_win32_coord());
+        _pTextBuffer->Write({ L"My name is Carlos" }, origin);
 
         // Create degenerate UTR at origin
         Microsoft::WRL::ComPtr<UiaTextRange> utr;
-        THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, origin.to_win32_coord(), origin.to_win32_coord()));
+        THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, origin, origin));
 
         // move forward by a word
         int moveAmt;
@@ -1483,7 +1483,7 @@ class UiaTextRangeTests
         VERIFY_ARE_EQUAL(L"name ", std::wstring_view{ text });
 
         // Collapse utr (move end to start)
-        const COORD expectedStart{ 3, 0 };
+        const til::point expectedStart{ 3, 0 };
         THROW_IF_FAILED(utr->MoveEndpointByRange(TextPatternRangeEndpoint::TextPatternRangeEndpoint_End, utr.Get(), TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start));
         VERIFY_ARE_EQUAL(expectedStart, utr->_start);
         VERIFY_IS_TRUE(utr->IsDegenerate());
@@ -1503,17 +1503,17 @@ class UiaTextRangeTests
         const auto viewportSize{ _pUiaData->GetViewport() };
 
         const std::vector<ScrollTest> testData{
-            { L"Origin", gsl::narrow<short>(bufferSize.top) },
-            { L"ViewportHeight From Top - 1", base::ClampedNumeric<short>(bufferSize.top) + viewportSize.Height() - 1 },
-            { L"ViewportHeight From Top", base::ClampedNumeric<short>(bufferSize.top) + viewportSize.Height() },
-            { L"ViewportHeight From Top + 1", base::ClampedNumeric<short>(bufferSize.top) + viewportSize.Height() + 1 },
-            { L"ViewportHeight From Bottom - 1", base::ClampedNumeric<short>(bufferSize.bottom) - viewportSize.Height() - 2 },
-            { L"ViewportHeight From Bottom", base::ClampedNumeric<short>(bufferSize.bottom) - viewportSize.Height() - 1 },
-            { L"ViewportHeight From Bottom + 1", base::ClampedNumeric<short>(bufferSize.bottom) - viewportSize.Height() + 1 },
+            { L"Origin", bufferSize.top },
+            { L"ViewportHeight From Top - 1", bufferSize.top + viewportSize.Height() - 1 },
+            { L"ViewportHeight From Top", bufferSize.top + viewportSize.Height() },
+            { L"ViewportHeight From Top + 1", bufferSize.top + viewportSize.Height() + 1 },
+            { L"ViewportHeight From Bottom - 1", bufferSize.bottom - viewportSize.Height() - 2 },
+            { L"ViewportHeight From Bottom", bufferSize.bottom - viewportSize.Height() - 1 },
+            { L"ViewportHeight From Bottom + 1", bufferSize.bottom - viewportSize.Height() + 1 },
 
             // GH#7839: ExclusiveEnd is a non-existent space,
             // so scrolling to it when !alignToTop used to crash
-            { L"Exclusive End", gsl::narrow<short>(bufferSize.bottom) }
+            { L"Exclusive End", bufferSize.bottom }
         };
 
         BEGIN_TEST_METHOD_PROPERTIES()
@@ -1528,7 +1528,7 @@ class UiaTextRangeTests
         {
             Log::Comment(test.comment.c_str());
             const til::point pos{ bufferSize.left, test.yPos };
-            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, pos.to_win32_coord(), pos.to_win32_coord()));
+            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, pos, pos));
             VERIFY_SUCCEEDED(utr->ScrollIntoView(alignToTop));
         }
     }
@@ -1726,8 +1726,8 @@ class UiaTextRangeTests
     TEST_METHOD(FindAttribute)
     {
         Microsoft::WRL::ComPtr<UiaTextRange> utr;
-        const COORD startPos{ 0, 0 };
-        const COORD endPos{ 0, 2 };
+        const til::point startPos{ 0, 0 };
+        const til::point endPos{ 0, 2 };
         THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, startPos, endPos));
         {
             Log::Comment(L"Test Font Name (special)");
@@ -1856,7 +1856,7 @@ class UiaTextRangeTests
         const auto secondChar{ point_offset_by_char(origin, bufferSize, 2) };
         const auto fifthChar{ point_offset_by_char(origin, bufferSize, 5) };
         const auto sixthChar{ point_offset_by_char(origin, bufferSize, 6) };
-        const til::point documentEnd{ bufferSize.left, (bufferSize.height() / 2) + 1 };
+        const til::point documentEnd{ bufferSize.left, bufferSize.height() / 2 + 1 };
 
         // Populate buffer
         //   Split the line into 5 segments alternating between "X" and whitespace
@@ -1867,10 +1867,10 @@ class UiaTextRangeTests
         //   |XXX   XXX   XXX|
         //   |_______________|
         {
-            short i = 0;
-            auto iter{ _pTextBuffer->GetCellDataAt(origin.to_win32_coord()) };
+            auto i = 0;
+            auto iter{ _pTextBuffer->GetCellDataAt(origin) };
             const auto segment{ bufferSize.width() / 5 };
-            while (iter.Pos() != documentEnd.to_win32_coord())
+            while (iter.Pos() != documentEnd)
             {
                 auto fill{ true };
                 if (i % segment == 0)
@@ -1935,11 +1935,11 @@ class UiaTextRangeTests
         // |                              |
         // +------------------------------+
         {
-            short i = 0;
-            auto iter{ _pTextBuffer->GetCellDataAt(bufferSize.origin().to_win32_coord()) };
+            auto i = 0;
+            auto iter{ _pTextBuffer->GetCellDataAt(bufferSize.origin()) };
             const auto segment{ bufferSize.width() / 10 };
             auto fill{ true };
-            while (iter.Pos() != docEnd.to_win32_coord())
+            while (iter.Pos() != docEnd)
             {
                 if (iter.Pos().X == bufferSize.left)
                 {
@@ -1977,12 +1977,12 @@ class UiaTextRangeTests
         {
             Microsoft::WRL::ComPtr<UiaTextRange> utr;
             int amountMoved;
-            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, testCase.input.start.to_win32_coord(), testCase.input.end.to_win32_coord()));
+            THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<UiaTextRange>(&utr, _pUiaData, &_dummyProvider, testCase.input.start, testCase.input.end));
             THROW_IF_FAILED(utr->Move(testCase.input.unit, testCase.input.moveAmount, &amountMoved));
 
             VERIFY_ARE_EQUAL(testCase.expected.moveAmount, amountMoved);
-            VERIFY_ARE_EQUAL(testCase.expected.start, til::point{ utr->_start });
-            VERIFY_ARE_EQUAL(testCase.expected.end, til::point{ utr->_end });
+            VERIFY_ARE_EQUAL(testCase.expected.start, utr->_start);
+            VERIFY_ARE_EQUAL(testCase.expected.end, utr->_end);
         }
     }
 };
diff --git a/src/interactivity/win32/window.cpp b/src/interactivity/win32/window.cpp
index 4f610d09d51..b6c025b33b1 100644
--- a/src/interactivity/win32/window.cpp
+++ b/src/interactivity/win32/window.cpp
@@ -173,8 +173,8 @@ void Window::_UpdateSystemMetrics() const
 
     Scrolling::s_UpdateSystemMetrics();
 
-    g.sVerticalScrollSize = (SHORT)dpiApi->GetSystemMetricsForDpi(SM_CXVSCROLL, g.dpi);
-    g.sHorizontalScrollSize = (SHORT)dpiApi->GetSystemMetricsForDpi(SM_CYHSCROLL, g.dpi);
+    g.sVerticalScrollSize = dpiApi->GetSystemMetricsForDpi(SM_CXVSCROLL, g.dpi);
+    g.sHorizontalScrollSize = dpiApi->GetSystemMetricsForDpi(SM_CYHSCROLL, g.dpi);
 
     gci.GetCursorBlinker().UpdateSystemMetrics();
 
@@ -256,7 +256,7 @@ void Window::_UpdateSystemMetrics() const
 
         // Figure out coordinates and how big to make the window from the desired client viewport size
         // Put left, top, right and bottom into rectProposed for checking against monitor screens below
-        RECT rectProposed = { pSettings->GetWindowOrigin().X, pSettings->GetWindowOrigin().Y, 0, 0 };
+        til::rect rectProposed = { pSettings->GetWindowOrigin().X, pSettings->GetWindowOrigin().Y, 0, 0 };
         _CalculateWindowRect(pSettings->GetWindowSize(), &rectProposed); //returns with rectangle filled out
 
         if (!WI_IsFlagSet(gci.Flags, CONSOLE_AUTO_POSITION))
@@ -271,10 +271,10 @@ void Window::_UpdateSystemMetrics() const
                 // When the user reconnects the other monitor, the
                 // window will be where he left it. Great for take
                 // home laptop scenario.
-                if (!MonitorFromRect(&rectProposed, MONITOR_DEFAULTTONULL))
+                if (!MonitorFromRect(rectProposed.as_win32_rect(), MONITOR_DEFAULTTONULL))
                 {
                     //Monitor we'll move to
-                    auto hMon = MonitorFromRect(&rectProposed, MONITOR_DEFAULTTONEAREST);
+                    auto hMon = MonitorFromRect(rectProposed.as_win32_rect(), MONITOR_DEFAULTTONEAREST);
                     MONITORINFO mi = { 0 };
 
                     //get origin of monitor's workarea
@@ -283,8 +283,8 @@ void Window::_UpdateSystemMetrics() const
 
                     //Adjust right and bottom to new positions, relative to monitor workarea's origin
                     //Need to do this before adjusting left/top so RECT_* calculations are correct
-                    rectProposed.right = mi.rcWork.left + RECT_WIDTH(&rectProposed);
-                    rectProposed.bottom = mi.rcWork.top + RECT_HEIGHT(&rectProposed);
+                    rectProposed.right = mi.rcWork.left + rectProposed.width();
+                    rectProposed.bottom = mi.rcWork.top + rectProposed.height();
 
                     // Move origin to top left of nearest
                     // monitor's WORKAREA (accounting for taskbar
@@ -309,8 +309,8 @@ void Window::_UpdateSystemMetrics() const
             CONSOLE_WINDOW_FLAGS,
             WI_IsFlagSet(gci.Flags, CONSOLE_AUTO_POSITION) ? CW_USEDEFAULT : rectProposed.left,
             rectProposed.top, // field is ignored if CW_USEDEFAULT was chosen above
-            RECT_WIDTH(&rectProposed),
-            RECT_HEIGHT(&rectProposed),
+            rectProposed.width(),
+            rectProposed.height(),
             HWND_DESKTOP,
             nullptr,
             nullptr,
@@ -443,7 +443,7 @@ void Window::_CloseWindow() const
 // - NewWindow: the inclusive rect to use as the new viewport in the buffer
 // Return Value:
 // <none>
-void Window::ChangeViewport(const SMALL_RECT NewWindow)
+void Window::ChangeViewport(const til::inclusive_rect& NewWindow)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& ScreenInfo = GetScreenInfo();
@@ -492,7 +492,7 @@ void Window::ChangeViewport(const SMALL_RECT NewWindow)
 // - Size of the window in characters (relative to the current font)
 // Return Value:
 // - <none>
-void Window::UpdateWindowSize(const COORD coordSizeInChars)
+void Window::UpdateWindowSize(const til::size coordSizeInChars)
 {
     GetScreenInfo().SetViewportSize(&coordSizeInChars);
 
@@ -502,7 +502,7 @@ void Window::UpdateWindowSize(const COORD coordSizeInChars)
 // Routine Description:
 // Arguments:
 // Return Value:
-void Window::UpdateWindowPosition(_In_ POINT const ptNewPos) const
+void Window::UpdateWindowPosition(_In_ const til::point ptNewPos) const
 {
     SetWindowPos(GetWindowHandle(),
                  nullptr,
@@ -577,7 +577,7 @@ BOOL Window::ReleaseMouse()
 // - sizeNew - The X and Y dimensions
 // Return Value:
 // - <none>
-void Window::_UpdateWindowSize(const SIZE sizeNew)
+void Window::_UpdateWindowSize(const til::size sizeNew)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     auto& ScreenInfo = GetScreenInfo();
@@ -623,20 +623,20 @@ void Window::_UpdateWindowSize(const SIZE sizeNew)
         const auto ScreenFontSize = siAttached.GetScreenFontSize();
 
         // Now do the multiplication of characters times pixels per char. This is the client area pixel size.
-        SIZE WindowSize;
+        til::size WindowSize;
         WindowSize.cx = WindowDimensions.X * ScreenFontSize.X;
         WindowSize.cy = WindowDimensions.Y * ScreenFontSize.Y;
 
         // Fill a rectangle to call the system to adjust the client rect into a window rect
-        RECT rectSizeTemp = { 0 };
+        til::rect rectSizeTemp;
         rectSizeTemp.right = WindowSize.cx;
         rectSizeTemp.bottom = WindowSize.cy;
         FAIL_FAST_IF(!(rectSizeTemp.top == 0 && rectSizeTemp.left == 0));
         ServiceLocator::LocateWindowMetrics<WindowMetrics>()->ConvertClientRectToWindowRect(&rectSizeTemp);
 
         // Measure the adjusted rectangle dimensions and fill up the size variable
-        WindowSize.cx = RECT_WIDTH(&rectSizeTemp);
-        WindowSize.cy = RECT_HEIGHT(&rectSizeTemp);
+        WindowSize.cx = rectSizeTemp.width();
+        WindowSize.cy = rectSizeTemp.height();
 
         if (WindowDimensions.Y != 0)
         {
@@ -660,15 +660,15 @@ void Window::_UpdateWindowSize(const SIZE sizeNew)
         // such that there isn't leftover space around the window when snapping.
 
         // To figure out if it's substantial, calculate what the window size would be if it were one character larger than what we just proposed
-        SIZE WindowSizeMax;
+        til::size WindowSizeMax;
         WindowSizeMax.cx = WindowSize.cx + ScreenFontSize.X;
         WindowSizeMax.cy = WindowSize.cy + ScreenFontSize.Y;
 
         // And figure out the current window size as well.
         const auto rcWindowCurrent = GetWindowRect();
-        SIZE WindowSizeCurrent;
-        WindowSizeCurrent.cx = RECT_WIDTH(&rcWindowCurrent);
-        WindowSizeCurrent.cy = RECT_HEIGHT(&rcWindowCurrent);
+        til::size WindowSizeCurrent;
+        WindowSizeCurrent.cx = rcWindowCurrent.width();
+        WindowSizeCurrent.cy = rcWindowCurrent.height();
 
         // If the current window has a few extra sub-character pixels between the proposed size (WindowSize) and the next size up (WindowSizeMax), then don't change anything.
         const auto fDeltaXSubstantial = !(WindowSizeCurrent.cx >= WindowSize.cx && WindowSizeCurrent.cx < WindowSizeMax.cx);
@@ -727,7 +727,7 @@ void Window::_UpdateWindowSize(const SIZE sizeNew)
 void Window::VerticalScroll(const WORD wScrollCommand, const WORD wAbsoluteChange)
 {
     auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
-    COORD NewOrigin;
+    til::point NewOrigin;
     auto& ScreenInfo = GetScreenInfo();
 
     // Log a telemetry event saying the user interacted with the Console
@@ -797,7 +797,7 @@ void Window::VerticalScroll(const WORD wScrollCommand, const WORD wAbsoluteChang
     }
     }
 
-    NewOrigin.Y = std::clamp(NewOrigin.Y, 0i16, gsl::narrow<SHORT>(sScreenBufferSizeY - viewport.Height()));
+    NewOrigin.Y = std::clamp(NewOrigin.Y, 0, sScreenBufferSizeY - viewport.Height());
     LOG_IF_FAILED(ScreenInfo.SetViewportOrigin(true, NewOrigin, false));
 }
 
@@ -868,7 +868,7 @@ void Window::HorizontalScroll(const WORD wScrollCommand, const WORD wAbsoluteCha
         return;
     }
     }
-    NewOrigin.X = std::clamp(NewOrigin.X, 0i16, gsl::narrow<SHORT>(sScreenBufferSizeX - viewport.Width()));
+    NewOrigin.X = std::clamp(NewOrigin.X, 0, sScreenBufferSizeX - viewport.Width());
     LOG_IF_FAILED(ScreenInfo.SetViewportOrigin(true, NewOrigin, false));
 }
 
@@ -901,7 +901,7 @@ int Window::UpdateScrollBar(bool isVertical,
 // - prc - rectangle to fill
 // Return Value:
 // - <none>
-void Window::s_ConvertWindowPosToWindowRect(const LPWINDOWPOS lpWindowPos, _Out_ RECT* const prc)
+void Window::s_ConvertWindowPosToWindowRect(const LPWINDOWPOS lpWindowPos, _Out_ til::rect* prc)
 {
     prc->left = lpWindowPos->x;
     prc->top = lpWindowPos->y;
@@ -916,7 +916,7 @@ void Window::s_ConvertWindowPosToWindowRect(const LPWINDOWPOS lpWindowPos, _Out_
 // - prectWindow - rectangle to fill with pixel positions of the outer edge rectangle for this window
 // Return Value:
 // - <none>
-void Window::_CalculateWindowRect(const COORD coordWindowInChars, _Inout_ RECT* const prectWindow) const
+void Window::_CalculateWindowRect(const til::size coordWindowInChars, _Inout_ til::rect* prectWindow) const
 {
     auto& g = ServiceLocator::LocateGlobals();
     const auto& siAttached = GetScreenInfo();
@@ -944,21 +944,21 @@ void Window::_CalculateWindowRect(const COORD coordWindowInChars, _Inout_ RECT*
 //      rectangle for this window
 // Return Value:
 // - <none>
-void Window::s_CalculateWindowRect(const COORD coordWindowInChars,
+void Window::s_CalculateWindowRect(const til::size coordWindowInChars,
                                    const int iDpi,
-                                   const COORD coordFontSize,
-                                   const COORD coordBufferSize,
+                                   const til::size coordFontSize,
+                                   const til::size coordBufferSize,
                                    _In_opt_ HWND const hWnd,
-                                   _Inout_ RECT* const prectWindow)
+                                   _Inout_ til::rect* const prectWindow)
 {
-    SIZE sizeWindow;
+    til::size sizeWindow;
 
     // Initially use the given size in characters * font size to get client area pixel size
     sizeWindow.cx = coordWindowInChars.X * coordFontSize.X;
     sizeWindow.cy = coordWindowInChars.Y * coordFontSize.Y;
 
     // Create a proposed rectangle
-    RECT rectProposed = { prectWindow->left, prectWindow->top, prectWindow->left + sizeWindow.cx, prectWindow->top + sizeWindow.cy };
+    til::rect rectProposed = { prectWindow->left, prectWindow->top, prectWindow->left + sizeWindow.cx, prectWindow->top + sizeWindow.cy };
 
     // Now adjust the client area into a window size
     // 1. Start with default window style
@@ -982,26 +982,26 @@ void Window::s_CalculateWindowRect(const COORD coordWindowInChars,
     // If the window is smaller than the buffer in width, add space at the bottom for a horizontal scroll bar
     if (coordWindowInChars.X < coordBufferSize.X)
     {
-        rectProposed.bottom += (SHORT)ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->GetSystemMetricsForDpi(SM_CYHSCROLL, iDpi);
+        rectProposed.bottom += ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->GetSystemMetricsForDpi(SM_CYHSCROLL, iDpi);
     }
 
     // If the window is smaller than the buffer in height, add space at the right for a vertical scroll bar
     if (coordWindowInChars.Y < coordBufferSize.Y)
     {
-        rectProposed.right += (SHORT)ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->GetSystemMetricsForDpi(SM_CXVSCROLL, iDpi);
+        rectProposed.right += ServiceLocator::LocateHighDpiApi<WindowDpiApi>()->GetSystemMetricsForDpi(SM_CXVSCROLL, iDpi);
     }
 
     // Apply the calculated sizes to the existing window pointer
     // We do this at the end so we can preserve the positioning of the window and just change the size.
-    prectWindow->right = prectWindow->left + RECT_WIDTH(&rectProposed);
-    prectWindow->bottom = prectWindow->top + RECT_HEIGHT(&rectProposed);
+    prectWindow->right = prectWindow->left + rectProposed.width();
+    prectWindow->bottom = prectWindow->top + rectProposed.height();
 }
 
-RECT Window::GetWindowRect() const noexcept
+til::rect Window::GetWindowRect() const noexcept
 {
-    RECT rc = { 0 };
+    RECT rc;
     ::GetWindowRect(GetWindowHandle(), &rc);
-    return rc;
+    return til::rect{ rc };
 }
 
 HWND Window::GetWindowHandle() const
@@ -1112,7 +1112,7 @@ bool Window::IsInFullscreen() const
 // - Called when entering fullscreen, with the window's current monitor rect and work area.
 // - The current window position, dpi, work area, and maximized state are stored, and the
 //   window is positioned to the monitor rect.
-void Window::_SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork)
+void Window::_SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork)
 {
     ::GetWindowRect(GetWindowHandle(), &_rcWindowBeforeFullscreen);
     _dpiBeforeFullscreen = GetDpiForWindow(GetWindowHandle());
@@ -1134,7 +1134,7 @@ void Window::_SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork)
 //   window's current monitor (if the current work area or window DPI have changed).
 // - A fullscreen window's monitor can be changed by win+shift+left/right hotkeys or monitor
 //   topology changes (for example unplugging a monitor or disconnecting a remote session).
-void Window::_RestoreFullscreenPosition(const RECT rcWork)
+void Window::_RestoreFullscreenPosition(const RECT& rcWork)
 {
     // If the window was previously maximized, re-maximize the window.
     if (_fWasMaximizedBeforeFullscreen)
@@ -1394,22 +1394,22 @@ void Window::SetOwner()
     SetConsoleWindowOwner(_hWnd, nullptr);
 }
 
-BOOL Window::GetCursorPosition(_Out_ LPPOINT lpPoint)
+BOOL Window::GetCursorPosition(_Out_ til::point* lpPoint)
 {
-    return GetCursorPos(lpPoint);
+    return GetCursorPos(lpPoint->as_win32_point());
 }
 
-BOOL Window::GetClientRectangle(_Out_ LPRECT lpRect)
+BOOL Window::GetClientRectangle(_Out_ til::rect* lpRect)
 {
-    return GetClientRect(_hWnd, lpRect);
+    return GetClientRect(_hWnd, lpRect->as_win32_rect());
 }
 
-int Window::MapPoints(_Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
+BOOL Window::MapRect(_Inout_ til::rect* lpRect)
 {
-    return MapWindowPoints(_hWnd, nullptr, lpPoints, cPoints);
+    return MapWindowPoints(_hWnd, nullptr, lpRect->as_win32_points(), 2) != 0;
 }
 
-BOOL Window::ConvertScreenToClient(_Inout_ LPPOINT lpPoint)
+BOOL Window::ConvertScreenToClient(_Inout_ til::point* lpPoint)
 {
-    return ScreenToClient(_hWnd, lpPoint);
+    return ScreenToClient(_hWnd, lpPoint->as_win32_point());
 }
diff --git a/src/interactivity/win32/window.hpp b/src/interactivity/win32/window.hpp
index 09f32064492..ba00662cd1a 100644
--- a/src/interactivity/win32/window.hpp
+++ b/src/interactivity/win32/window.hpp
@@ -37,7 +37,7 @@ namespace Microsoft::Console::Interactivity::Win32
 
         ~Window();
 
-        RECT GetWindowRect() const noexcept;
+        til::rect GetWindowRect() const noexcept;
         HWND GetWindowHandle() const;
         SCREEN_INFORMATION& GetScreenInfo();
         const SCREEN_INFORMATION& GetScreenInfo() const;
@@ -53,7 +53,7 @@ namespace Microsoft::Console::Interactivity::Win32
         void SetIsFullscreen(const bool fFullscreenEnabled);
         void ToggleFullscreen();
 
-        void ChangeViewport(const SMALL_RECT NewWindow);
+        void ChangeViewport(const til::inclusive_rect& NewWindow);
 
         void VerticalScroll(const WORD wScrollCommand,
                             const WORD wAbsoluteChange);
@@ -67,8 +67,8 @@ namespace Microsoft::Console::Interactivity::Win32
                             int maxSize,
                             int viewportPosition);
 
-        void UpdateWindowSize(const COORD coordSizeInChars);
-        void UpdateWindowPosition(_In_ POINT const ptNewPos) const;
+        void UpdateWindowSize(const til::size coordSizeInChars);
+        void UpdateWindowPosition(_In_ const til::point ptNewPos) const;
         void UpdateWindowText();
 
         void CaptureMouse();
@@ -86,11 +86,10 @@ namespace Microsoft::Console::Interactivity::Win32
         [[nodiscard]] HRESULT SignalUia(_In_ EVENTID id);
 
         void SetOwner();
-        BOOL GetCursorPosition(_Out_ LPPOINT lpPoint);
-        BOOL GetClientRectangle(_Out_ LPRECT lpRect);
-        int MapPoints(_Inout_updates_(cPoints) LPPOINT lpPoints,
-                      _In_ UINT cPoints);
-        BOOL ConvertScreenToClient(_Inout_ LPPOINT lpPoint);
+        BOOL GetCursorPosition(_Out_ til::point* lpPoint);
+        BOOL GetClientRectangle(_Out_ til::rect* lpRect);
+        BOOL MapRect(_Inout_ til::rect* lpRect);
+        BOOL ConvertScreenToClient(_Inout_ til::point* lpPoint);
 
         [[nodiscard]] HRESULT UiaSetTextAreaFocus();
 
@@ -122,7 +121,7 @@ namespace Microsoft::Console::Interactivity::Win32
 #endif
 
         [[nodiscard]] NTSTATUS _InternalSetWindowSize();
-        void _UpdateWindowSize(const SIZE sizeNew);
+        void _UpdateWindowSize(const til::size sizeNew);
 
         void _UpdateSystemMetrics() const;
 
@@ -158,11 +157,11 @@ namespace Microsoft::Console::Interactivity::Win32
         // The size/position of the window on the most recent update.
         // This is remembered so we can figure out which
         // size the client was resized from.
-        RECT _rcClientLast;
+        til::rect _rcClientLast;
 
         // Full screen
-        void _RestoreFullscreenPosition(const RECT rcWork);
-        void _SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork);
+        void _RestoreFullscreenPosition(const RECT& rcWork);
+        void _SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork);
         bool _fIsInFullscreen;
         bool _fWasMaximizedBeforeFullscreen;
         RECT _rcWindowBeforeFullscreen;
@@ -170,20 +169,20 @@ namespace Microsoft::Console::Interactivity::Win32
         UINT _dpiBeforeFullscreen;
 
         // math helpers
-        void _CalculateWindowRect(const COORD coordWindowInChars,
-                                  _Inout_ RECT* const prectWindow) const;
-        static void s_CalculateWindowRect(const COORD coordWindowInChars,
+        void _CalculateWindowRect(const til::size coordWindowInChars,
+                                  _Inout_ til::rect* const prectWindow) const;
+        static void s_CalculateWindowRect(const til::size coordWindowInChars,
                                           const int iDpi,
-                                          const COORD coordFontSize,
-                                          const COORD coordBufferSize,
+                                          const til::size coordFontSize,
+                                          const til::size coordBufferSize,
                                           _In_opt_ HWND const hWnd,
-                                          _Inout_ RECT* const prectWindow);
+                                          _Inout_ til::rect* const prectWindow);
 
         static void s_ReinitializeFontsForDPIChange();
 
         bool _fInDPIChange = false;
 
         static void s_ConvertWindowPosToWindowRect(const LPWINDOWPOS lpWindowPos,
-                                                   _Out_ RECT* const prc);
+                                                   _Out_ til::rect* const prc);
     };
 }
diff --git a/src/interactivity/win32/windowUiaProvider.cpp b/src/interactivity/win32/windowUiaProvider.cpp
index 4dc7464be67..744f566d021 100644
--- a/src/interactivity/win32/windowUiaProvider.cpp
+++ b/src/interactivity/win32/windowUiaProvider.cpp
@@ -299,12 +299,12 @@ HWND WindowUiaProvider::GetWindowHandle() const
     return S_OK;
 }
 
-void WindowUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
+void WindowUiaProvider::ChangeViewport(const til::inclusive_rect& NewWindow)
 {
     _baseWindow->ChangeViewport(NewWindow);
 }
 
-RECT WindowUiaProvider::GetWindowRect() const noexcept
+til::rect WindowUiaProvider::GetWindowRect() const noexcept
 {
     return _baseWindow->GetWindowRect();
 }
diff --git a/src/interactivity/win32/windowUiaProvider.hpp b/src/interactivity/win32/windowUiaProvider.hpp
index 9eea94ead33..97a35aa5535 100644
--- a/src/interactivity/win32/windowUiaProvider.hpp
+++ b/src/interactivity/win32/windowUiaProvider.hpp
@@ -73,9 +73,9 @@ namespace Microsoft::Console::Interactivity::Win32
                                                         _COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider);
         virtual IFACEMETHODIMP GetFocus(_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider);
 
-        RECT GetWindowRect() const noexcept;
+        til::rect GetWindowRect() const noexcept;
         HWND GetWindowHandle() const;
-        void ChangeViewport(const SMALL_RECT NewWindow);
+        void ChangeViewport(const til::inclusive_rect& NewWindow);
 
     protected:
         // this is used to prevent the object from
diff --git a/src/interactivity/win32/windowio.cpp b/src/interactivity/win32/windowio.cpp
index 7816d8ff398..c0f9902e82e 100644
--- a/src/interactivity/win32/windowio.cpp
+++ b/src/interactivity/win32/windowio.cpp
@@ -116,7 +116,7 @@ VOID SetConsoleWindowOwner(const HWND hwnd, _Inout_opt_ ConsoleProcessHandle* pP
 // - pInputRecord - Input record event from the general input event handler
 // Return Value:
 // - True if the modes were appropriate for converting to a terminal sequence AND there was a matching terminal sequence for this key. False otherwise.
-bool HandleTerminalMouseEvent(const COORD cMousePosition,
+bool HandleTerminalMouseEvent(const til::point cMousePosition,
                               const unsigned int uiButton,
                               const short sModifierKeystate,
                               const short sWheelDelta)
@@ -141,7 +141,7 @@ bool HandleTerminalMouseEvent(const COORD cMousePosition,
         auto clampedPosition{ cMousePosition };
         const auto clampViewport{ gci.GetActiveOutputBuffer().GetViewport().ToOrigin() };
         clampViewport.Clamp(clampedPosition);
-        fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(til::wrap_coord(clampedPosition), uiButton, sModifierKeystate, sWheelDelta, state);
+        fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(clampedPosition, uiButton, sModifierKeystate, sWheelDelta, state);
     }
 
     return fWasHandled;
@@ -612,16 +612,16 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo,
     //  results on systems with multiple monitors. Systems with multiple monitors
     //  can have negative x- and y- coordinates, and LOWORD and HIWORD treat the
     //  coordinates as unsigned quantities.
-    short x = GET_X_LPARAM(lParam);
-    short y = GET_Y_LPARAM(lParam);
+    const auto x = GET_X_LPARAM(lParam);
+    const auto y = GET_Y_LPARAM(lParam);
 
-    COORD MousePosition;
+    til::point MousePosition;
     // If it's a *WHEEL event, it's in screen coordinates, not window
     if (Message == WM_MOUSEWHEEL || Message == WM_MOUSEHWHEEL)
     {
         POINT coords = { x, y };
         ScreenToClient(ServiceLocator::LocateConsoleWindow()->GetWindowHandle(), &coords);
-        MousePosition = { (SHORT)coords.x, (SHORT)coords.y };
+        MousePosition = { coords.x, coords.y };
     }
     else
     {
diff --git a/src/interactivity/win32/windowproc.cpp b/src/interactivity/win32/windowproc.cpp
index c011d34044f..8b173e1eac3 100644
--- a/src/interactivity/win32/windowproc.cpp
+++ b/src/interactivity/win32/windowproc.cpp
@@ -128,10 +128,10 @@ using namespace Microsoft::Console::Types;
         s_ReinitializeFontsForDPIChange(); // font sizes.
 
         // Now re-propose the window size with the same origin.
-        RECT rectProposed = { rc.left, rc.top, 0, 0 };
+        til::rect rectProposed = { rc.left, rc.top, 0, 0 };
         _CalculateWindowRect(_pSettings->GetWindowSize(), &rectProposed);
 
-        SetWindowPos(hWnd, nullptr, rectProposed.left, rectProposed.top, RECT_WIDTH(&rectProposed), RECT_HEIGHT(&rectProposed), SWP_NOACTIVATE | SWP_NOZORDER);
+        SetWindowPos(hWnd, nullptr, rectProposed.left, rectProposed.top, rectProposed.width(), rectProposed.height(), SWP_NOACTIVATE | SWP_NOZORDER);
 
         // Save the proposed window rect dimensions here so we can adjust if the system comes back and changes them on what we asked for.
         ServiceLocator::LocateWindowMetrics<WindowMetrics>()->ConvertWindowRectToClientRect(&rectProposed);
@@ -192,7 +192,7 @@ using namespace Microsoft::Console::Types;
         // GetProposedFont can fail if there's no render engine yet.
         // This can happen if we're headless.
         // Just assume that the font is 1x1 in that case.
-        const auto coordFontProposed = SUCCEEDED(hr) ? fiProposed.GetSize() : COORD({ 1, 1 });
+        const auto coordFontProposed = SUCCEEDED(hr) ? fiProposed.GetSize() : til::size{ 1, 1 };
 
         // Then from that font size, we need to calculate the client area.
         // Then from the client area we need to calculate the window area (using the proposed DPI scalar here as well.)
@@ -204,14 +204,14 @@ using namespace Microsoft::Console::Types;
         const auto coordBufferSize = ScreenInfo.GetTextBuffer().GetSize().Dimensions();
 
         // Now call the math calculation for our proposed size.
-        RECT rectProposed = { 0 };
+        til::rect rectProposed;
         s_CalculateWindowRect(coordWindowInChars, dpiProposed, coordFontProposed, coordBufferSize, hWnd, &rectProposed);
 
         // Prepare where we're going to keep our final suggestion.
         const auto pSuggestionSize = (SIZE*)lParam;
 
-        pSuggestionSize->cx = RECT_WIDTH(&rectProposed);
-        pSuggestionSize->cy = RECT_HEIGHT(&rectProposed);
+        pSuggestionSize->cx = rectProposed.width();
+        pSuggestionSize->cy = rectProposed.height();
 
         // Format our final suggestion for consumption.
         UnlockConsole();
@@ -356,14 +356,14 @@ using namespace Microsoft::Console::Types;
         if (!WI_IsFlagSet(lpwpos->flags, SWP_NOSIZE))
         {
             // Figure out the suggested dimensions
-            RECT rcSuggested;
+            til::rect rcSuggested;
             rcSuggested.left = lpwpos->x;
             rcSuggested.top = lpwpos->y;
             rcSuggested.right = rcSuggested.left + lpwpos->cx;
             rcSuggested.bottom = rcSuggested.top + lpwpos->cy;
-            SIZE szSuggested;
-            szSuggested.cx = RECT_WIDTH(&rcSuggested);
-            szSuggested.cy = RECT_HEIGHT(&rcSuggested);
+            til::size szSuggested;
+            szSuggested.cx = rcSuggested.width();
+            szSuggested.cy = rcSuggested.height();
 
             // Figure out the current dimensions for comparison.
             auto rcCurrent = GetWindowRect();
@@ -372,7 +372,7 @@ using namespace Microsoft::Console::Types;
             auto fIsEdgeResize = false;
             {
                 // We can only be edge resizing if our existing rectangle wasn't empty. If it was empty, we're doing the initial create.
-                if (!IsRectEmpty(&rcCurrent))
+                if (rcCurrent)
                 {
                     // If one or two sides are changing, we're being edge resized.
                     unsigned int cSidesChanging = 0;
@@ -407,7 +407,7 @@ using namespace Microsoft::Console::Types;
                 // Find the related monitor, the maximum pixel size,
                 // and the dpi for the suggested rect.
                 UINT dpiOfMaximum;
-                RECT rcMaximum;
+                til::rect rcMaximum;
 
                 if (fIsEdgeResize)
                 {
@@ -429,10 +429,10 @@ using namespace Microsoft::Console::Types;
                 // or worse yet, keep it from moving entirely. We'll get a WM_DPICHANGED,
                 // resize the window, and then process the restriction in a few window messages.
                 if (((int)dpiOfMaximum == g.dpi) &&
-                    ((szSuggested.cx > RECT_WIDTH(&rcMaximum)) || (szSuggested.cy > RECT_HEIGHT(&rcMaximum))))
+                    ((szSuggested.cx > rcMaximum.width()) || (szSuggested.cy > rcMaximum.height())))
                 {
-                    lpwpos->cx = std::min(RECT_WIDTH(&rcMaximum), szSuggested.cx);
-                    lpwpos->cy = std::min(RECT_HEIGHT(&rcMaximum), szSuggested.cy);
+                    lpwpos->cx = std::min(rcMaximum.width(), szSuggested.cx);
+                    lpwpos->cy = std::min(rcMaximum.height(), szSuggested.cy);
 
                     // We usually add SWP_NOMOVE so that if the user is dragging the left or top edge
                     // and hits the restriction, then the window just stops growing, it doesn't
@@ -795,7 +795,7 @@ void Window::_HandleWindowPosChanged(const LPARAM lParam)
     if (!ScreenInfo.ResizingWindow && (lpWindowPos->cx || lpWindowPos->cy) && !IsIconic(hWnd))
     {
         // calculate the dimensions for the newly proposed window rectangle
-        RECT rcNew;
+        til::rect rcNew;
         s_ConvertWindowPosToWindowRect(lpWindowPos, &rcNew);
         ServiceLocator::LocateWindowMetrics<WindowMetrics>()->ConvertWindowRectToClientRect(&rcNew);
 
@@ -840,7 +840,7 @@ void Window::_HandleWindowPosChanged(const LPARAM lParam)
     {
         // In lieu of actually painting right now, we're just going to aggregate this information in the renderer
         // and let it paint whenever it feels appropriate.
-        const auto rcUpdate = ps.rcPaint;
+        const auto rcUpdate = til::rect{ ps.rcPaint };
         ServiceLocator::LocateGlobals().pRender->TriggerSystemRedraw(&rcUpdate);
     }
 
diff --git a/src/renderer/atlas/AtlasEngine.api.cpp b/src/renderer/atlas/AtlasEngine.api.cpp
index 78ba30aaf74..900ac44100f 100644
--- a/src/renderer/atlas/AtlasEngine.api.cpp
+++ b/src/renderer/atlas/AtlasEngine.api.cpp
@@ -40,7 +40,7 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
 
 #pragma region IRenderEngine
 
-[[nodiscard]] HRESULT AtlasEngine::Invalidate(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT AtlasEngine::Invalidate(const til::rect* const psrRegion) noexcept
 {
     //assert(psrRegion->Top < psrRegion->Bottom && psrRegion->Top >= 0 && psrRegion->Bottom <= _api.cellCount.y);
 
@@ -50,7 +50,7 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
     return S_OK;
 }
 
-[[nodiscard]] HRESULT AtlasEngine::InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT AtlasEngine::InvalidateCursor(const til::rect* const psrRegion) noexcept
 {
     //assert(psrRegion->Left <= psrRegion->Right && psrRegion->Left >= 0 && psrRegion->Right <= _api.cellCount.x);
     //assert(psrRegion->Top <= psrRegion->Bottom && psrRegion->Top >= 0 && psrRegion->Bottom <= _api.cellCount.y);
@@ -68,19 +68,19 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
     return S_OK;
 }
 
-[[nodiscard]] HRESULT AtlasEngine::InvalidateSystem(const RECT* const prcDirtyClient) noexcept
+[[nodiscard]] HRESULT AtlasEngine::InvalidateSystem(const til::rect* const prcDirtyClient) noexcept
 {
     const auto top = prcDirtyClient->top / _api.fontMetrics.cellSize.y;
     const auto bottom = prcDirtyClient->bottom / _api.fontMetrics.cellSize.y;
 
     // BeginPaint() protects against invalid out of bounds numbers.
-    SMALL_RECT rect;
-    rect.Top = gsl::narrow_cast<SHORT>(top);
-    rect.Bottom = gsl::narrow_cast<SHORT>(bottom);
+    til::rect rect;
+    rect.Top = top;
+    rect.Bottom = bottom;
     return Invalidate(&rect);
 }
 
-[[nodiscard]] HRESULT AtlasEngine::InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept
+[[nodiscard]] HRESULT AtlasEngine::InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept
 {
     for (const auto& rect : rectangles)
     {
@@ -93,7 +93,7 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
     return S_OK;
 }
 
-[[nodiscard]] HRESULT AtlasEngine::InvalidateScroll(const COORD* const pcoordDelta) noexcept
+[[nodiscard]] HRESULT AtlasEngine::InvalidateScroll(const til::point* const pcoordDelta) noexcept
 {
     const auto delta = pcoordDelta->Y;
     if (delta == 0)
@@ -153,7 +153,7 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
     return UpdateFont(fontInfoDesired, fontInfo, {}, {});
 }
 
-[[nodiscard]] HRESULT AtlasEngine::UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const SIZE cellSize, const size_t centeringHint) noexcept
+[[nodiscard]] HRESULT AtlasEngine::UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const til::size cellSize, const size_t centeringHint) noexcept
 {
     return S_OK;
 }
@@ -172,7 +172,7 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
     return S_OK;
 }
 
-[[nodiscard]] HRESULT AtlasEngine::UpdateViewport(const SMALL_RECT srNewViewport) noexcept
+[[nodiscard]] HRESULT AtlasEngine::UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept
 {
     const u16x2 cellCount{
         gsl::narrow_cast<u16>(srNewViewport.Right - srNewViewport.Left + 1),
@@ -236,10 +236,10 @@ try
 
         DeleteObject(SelectObject(hdc.get(), hfont.get()));
 
-        SIZE sz;
+        til::size sz;
         RETURN_HR_IF(E_FAIL, !GetTextExtentPoint32W(hdc.get(), L"M", 1, &sz));
-        resultingCellSize.X = gsl::narrow<SHORT>(sz.cx);
-        resultingCellSize.Y = gsl::narrow<SHORT>(sz.cy);
+        resultingCellSize.X = sz.cx;
+        resultingCellSize.Y = sz.cy;
     }
 #endif
 
@@ -254,11 +254,11 @@ CATCH_RETURN()
     return S_OK;
 }
 
-[[nodiscard]] HRESULT AtlasEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
+[[nodiscard]] HRESULT AtlasEngine::GetFontSize(_Out_ til::size* pFontSize) noexcept
 {
     RETURN_HR_IF_NULL(E_INVALIDARG, pFontSize);
-    pFontSize->X = gsl::narrow_cast<SHORT>(_api.fontMetrics.cellSize.x);
-    pFontSize->Y = gsl::narrow_cast<SHORT>(_api.fontMetrics.cellSize.y);
+    pFontSize->X = _api.fontMetrics.cellSize.x;
+    pFontSize->Y = _api.fontMetrics.cellSize.y;
     return S_OK;
 }
 
@@ -315,14 +315,14 @@ HRESULT AtlasEngine::Enable() noexcept
 {
     assert(_api.fontMetrics.cellSize.x != 0);
     assert(_api.fontMetrics.cellSize.y != 0);
-    return Types::Viewport::FromDimensions(viewInPixels.Origin(), COORD{ gsl::narrow_cast<short>(viewInPixels.Width() / _api.fontMetrics.cellSize.x), gsl::narrow_cast<short>(viewInPixels.Height() / _api.fontMetrics.cellSize.y) });
+    return Types::Viewport::FromDimensions(viewInPixels.Origin(), { viewInPixels.Width() / _api.fontMetrics.cellSize.x, viewInPixels.Height() / _api.fontMetrics.cellSize.y });
 }
 
 [[nodiscard]] Microsoft::Console::Types::Viewport AtlasEngine::GetViewportInPixels(const Types::Viewport& viewInCharacters) const noexcept
 {
     assert(_api.fontMetrics.cellSize.x != 0);
     assert(_api.fontMetrics.cellSize.y != 0);
-    return Types::Viewport::FromDimensions(viewInCharacters.Origin(), COORD{ gsl::narrow_cast<short>(viewInCharacters.Width() * _api.fontMetrics.cellSize.x), gsl::narrow_cast<short>(viewInCharacters.Height() * _api.fontMetrics.cellSize.y) });
+    return Types::Viewport::FromDimensions(viewInCharacters.Origin(), { viewInCharacters.Width() * _api.fontMetrics.cellSize.x, viewInCharacters.Height() * _api.fontMetrics.cellSize.y });
 }
 
 void AtlasEngine::SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept
@@ -393,7 +393,7 @@ void AtlasEngine::SetWarningCallback(std::function<void(HRESULT)> pfn) noexcept
     _api.warningCallback = std::move(pfn);
 }
 
-[[nodiscard]] HRESULT AtlasEngine::SetWindowSize(const SIZE pixels) noexcept
+[[nodiscard]] HRESULT AtlasEngine::SetWindowSize(const til::size pixels) noexcept
 {
     u16x2 newSize;
     RETURN_IF_FAILED(vec2_narrow(pixels.cx, pixels.cy, newSize));
@@ -619,10 +619,15 @@ void AtlasEngine::_resolveFontMetrics(const wchar_t* requestedFaceName, const Fo
     const auto cellHeight = gsl::narrow<u16>(std::ceil(baseline + descentInPx + halfGapInPx));
 
     {
-        COORD resultingCellSize;
-        resultingCellSize.X = gsl::narrow<SHORT>(cellWidth);
-        resultingCellSize.Y = gsl::narrow<SHORT>(cellHeight);
-        fontInfo.SetFromEngine(requestedFaceName, requestedFamily, requestedWeight, false, resultingCellSize, requestedSize);
+        til::size coordSize;
+        coordSize.X = cellWidth;
+        coordSize.Y = cellHeight;
+
+        til::size coordSizeUnscaled;
+        coordSizeUnscaled.X = coordSize.X * USER_DEFAULT_SCREEN_DPI / _api.dpi;
+        coordSizeUnscaled.Y = coordSize.Y * USER_DEFAULT_SCREEN_DPI / _api.dpi;
+
+        fontInfo.SetFromEngine(requestedFaceName, requestedFamily, requestedWeight, false, coordSize, coordSizeUnscaled);
     }
 
     if (fontMetrics)
diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp
index ded8fd7effa..6357b3b52ec 100644
--- a/src/renderer/atlas/AtlasEngine.cpp
+++ b/src/renderer/atlas/AtlasEngine.cpp
@@ -447,7 +447,7 @@ void AtlasEngine::WaitUntilCanRender() noexcept
     return S_OK;
 }
 
-[[nodiscard]] HRESULT AtlasEngine::PaintBufferLine(const gsl::span<const Cluster> clusters, const COORD coord, const bool fTrimLeft, const bool lineWrapped) noexcept
+[[nodiscard]] HRESULT AtlasEngine::PaintBufferLine(const gsl::span<const Cluster> clusters, const til::point coord, const bool fTrimLeft, const bool lineWrapped) noexcept
 try
 {
     const auto x = gsl::narrow_cast<u16>(clamp<int>(coord.X, 0, _api.cellCount.x));
@@ -491,7 +491,7 @@ try
 }
 CATCH_RETURN()
 
-[[nodiscard]] HRESULT AtlasEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const COORD coordTarget) noexcept
+[[nodiscard]] HRESULT AtlasEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const til::point coordTarget) noexcept
 try
 {
     if (!_api.bufferLineWasHyperlinked && lines.test(GridLines::Underline) && WI_IsFlagClear(_api.flags, CellFlags::Underline))
@@ -508,14 +508,21 @@ try
 }
 CATCH_RETURN()
 
-[[nodiscard]] HRESULT AtlasEngine::PaintSelection(SMALL_RECT rect) noexcept
+[[nodiscard]] HRESULT AtlasEngine::PaintSelection(const til::rect& rect) noexcept
 try
 {
     // Unfortunately there's no step after Renderer::_PaintBufferOutput that
     // would inform us that it's done with the last AtlasEngine::PaintBufferLine.
     // As such we got to call _flushBufferLine() here just to be sure.
     _flushBufferLine();
-    _setCellFlags(rect, CellFlags::Selected, CellFlags::Selected);
+
+    const u16r u16rect{
+        rect.narrow_left<u16>(),
+        rect.narrow_top<u16>(),
+        rect.narrow_right<u16>(),
+        rect.narrow_bottom<u16>(),
+    };
+    _setCellFlags(u16rect, CellFlags::Selected, CellFlags::Selected);
     return S_OK;
 }
 CATCH_RETURN()
@@ -544,7 +551,7 @@ try
     // Clear the previous cursor
     if (_api.invalidatedCursorArea.non_empty())
     {
-        _setCellFlags(til::bit_cast<SMALL_RECT>(_api.invalidatedCursorArea), CellFlags::Cursor, CellFlags::None);
+        _setCellFlags(_api.invalidatedCursorArea, CellFlags::Cursor, CellFlags::None);
     }
 
     if (options.isOn)
@@ -552,10 +559,10 @@ try
         const auto point = options.coordCursor;
         // TODO: options.coordCursor can contain invalid out of bounds coordinates when
         // the window is being resized and the cursor is on the last line of the viewport.
-        const auto x = gsl::narrow_cast<SHORT>(std::min<int>(point.X, _r.cellCount.x - 1));
-        const auto y = gsl::narrow_cast<SHORT>(std::min<int>(point.Y, _r.cellCount.y - 1));
-        const SHORT right = x + 1 + (options.fIsDoubleWidth & (options.cursorType != CursorType::VerticalBar));
-        const SHORT bottom = y + 1;
+        const auto x = gsl::narrow_cast<uint16_t>(clamp<int>(point.X, 0, _r.cellCount.x - 1));
+        const auto y = gsl::narrow_cast<uint16_t>(clamp<int>(point.Y, 0, _r.cellCount.y - 1));
+        const auto right = gsl::narrow_cast<uint16_t>(x + 1 + (options.fIsDoubleWidth & (options.cursorType != CursorType::VerticalBar)));
+        const auto bottom = gsl::narrow_cast<uint16_t>(y + 1);
         _setCellFlags({ x, y, right, bottom }, CellFlags::Cursor, CellFlags::Cursor);
     }
 
@@ -1086,18 +1093,18 @@ AtlasEngine::Cell* AtlasEngine::_getCell(u16 x, u16 y) noexcept
     return _r.cells.data() + static_cast<size_t>(_r.cellCount.x) * y + x;
 }
 
-void AtlasEngine::_setCellFlags(SMALL_RECT coords, CellFlags mask, CellFlags bits) noexcept
+void AtlasEngine::_setCellFlags(u16r coords, CellFlags mask, CellFlags bits) noexcept
 {
-    assert(coords.Left <= coords.Right);
-    assert(coords.Top <= coords.Bottom);
-    assert(coords.Right <= _r.cellCount.x);
-    assert(coords.Bottom <= _r.cellCount.y);
+    assert(coords.left <= coords.right);
+    assert(coords.top <= coords.bottom);
+    assert(coords.right <= _r.cellCount.x);
+    assert(coords.bottom <= _r.cellCount.y);
 
     const auto filter = ~mask;
-    const auto width = static_cast<size_t>(coords.Right) - coords.Left;
-    const auto height = static_cast<size_t>(coords.Bottom) - coords.Top;
+    const auto width = static_cast<size_t>(coords.right) - coords.left;
+    const auto height = static_cast<size_t>(coords.bottom) - coords.top;
     const auto stride = static_cast<size_t>(_r.cellCount.x);
-    auto row = _r.cells.data() + static_cast<size_t>(_r.cellCount.x) * coords.Top + coords.Left;
+    auto row = _r.cells.data() + static_cast<size_t>(_r.cellCount.x) * coords.top + coords.left;
     const auto end = row + height * stride;
 
     for (; row != end; row += stride)
diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h
index ad3cc244184..92a22c0a086 100644
--- a/src/renderer/atlas/AtlasEngine.h
+++ b/src/renderer/atlas/AtlasEngine.h
@@ -27,11 +27,11 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT Present() noexcept override;
         [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* pForcePaint) noexcept override;
         [[nodiscard]] HRESULT ScrollFrame() noexcept override;
-        [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* psrRegion) noexcept override;
-        [[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* psrRegion) noexcept override;
-        [[nodiscard]] HRESULT InvalidateSystem(const RECT* prcDirtyClient) noexcept override;
-        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept override;
-        [[nodiscard]] HRESULT InvalidateScroll(const COORD* pcoordDelta) noexcept override;
+        [[nodiscard]] HRESULT Invalidate(const til::rect* psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT InvalidateFlush(_In_ const bool circled, _Out_ bool* const pForcePaint) noexcept override;
         [[nodiscard]] HRESULT InvalidateTitle(std::wstring_view proposedTitle) noexcept override;
@@ -40,18 +40,18 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT ResetLineTransform() noexcept override;
         [[nodiscard]] HRESULT PrepareLineTransform(LineRendition lineRendition, size_t targetRow, size_t viewportLeft) noexcept override;
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
-        [[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> clusters, COORD coord, bool fTrimLeft, bool lineWrapped) noexcept override;
-        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(SMALL_RECT rect) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> clusters, til::point coord, bool fTrimLeft, bool lineWrapped) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, til::point coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
         [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null<IRenderData*> pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept override;
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override;
-        [[nodiscard]] HRESULT UpdateSoftFont(gsl::span<const uint16_t> bitPattern, SIZE cellSize, size_t centeringHint) noexcept override;
+        [[nodiscard]] HRESULT UpdateSoftFont(gsl::span<const uint16_t> bitPattern, til::size cellSize, size_t centeringHint) noexcept override;
         [[nodiscard]] HRESULT UpdateDpi(int iDpi) noexcept override;
-        [[nodiscard]] HRESULT UpdateViewport(SMALL_RECT srNewViewport) noexcept override;
+        [[nodiscard]] HRESULT UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept override;
         [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, int iDpi) noexcept override;
         [[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept override;
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* pFontSize) noexcept override;
         [[nodiscard]] HRESULT IsGlyphWideByFont(std::wstring_view glyph, _Out_ bool* pResult) noexcept override;
         [[nodiscard]] HRESULT UpdateTitle(std::wstring_view newTitle) noexcept override;
 
@@ -73,7 +73,7 @@ namespace Microsoft::Console::Render
         void SetSelectionBackground(COLORREF color, float alpha = 0.5f) noexcept override;
         void SetSoftwareRendering(bool enable) noexcept override;
         void SetWarningCallback(std::function<void(HRESULT)> pfn) noexcept override;
-        [[nodiscard]] HRESULT SetWindowSize(SIZE pixels) noexcept override;
+        [[nodiscard]] HRESULT SetWindowSize(til::size pixels) noexcept override;
         void ToggleShaderEffects() noexcept override;
         [[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 override;
         void UpdateHyperlinkHoveredId(uint16_t hoveredId) noexcept override;
@@ -612,7 +612,7 @@ namespace Microsoft::Console::Render
         IDWriteTextFormat* _getTextFormat(bool bold, bool italic) const noexcept;
         const Buffer<DWRITE_FONT_AXIS_VALUE>& _getTextFormatAxis(bool bold, bool italic) const noexcept;
         Cell* _getCell(u16 x, u16 y) noexcept;
-        void _setCellFlags(SMALL_RECT coords, CellFlags mask, CellFlags bits) noexcept;
+        void _setCellFlags(u16r coords, CellFlags mask, CellFlags bits) noexcept;
         u16x2 _allocateAtlasTile() noexcept;
         void _flushBufferLine();
         void _emplaceGlyph(IDWriteFontFace* fontFace, size_t bufferPos1, size_t bufferPos2);
diff --git a/src/renderer/base/FontInfoDesired.cpp b/src/renderer/base/FontInfoDesired.cpp
index b1944dbfd2a..aa6648d0dbe 100644
--- a/src/renderer/base/FontInfoDesired.cpp
+++ b/src/renderer/base/FontInfoDesired.cpp
@@ -8,7 +8,7 @@
 FontInfoDesired::FontInfoDesired(const std::wstring_view& faceName,
                                  const unsigned char family,
                                  const unsigned int weight,
-                                 const COORD coordSizeDesired,
+                                 const til::size coordSizeDesired,
                                  const unsigned int codePage) noexcept :
     FontInfoBase(faceName, family, weight, false, codePage),
     _coordSizeDesired(coordSizeDesired)
@@ -27,7 +27,7 @@ bool FontInfoDesired::operator==(const FontInfoDesired& other) noexcept
            _coordSizeDesired == other._coordSizeDesired;
 }
 
-COORD FontInfoDesired::GetEngineSize() const noexcept
+til::size FontInfoDesired::GetEngineSize() const noexcept
 {
     auto coordSize = _coordSizeDesired;
     if (IsTrueTypeFont())
@@ -46,6 +46,6 @@ 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 == COORD{ 0, 0 } ||
-                                                _coordSizeDesired == COORD{ 8, 12 }));
+                                               (_coordSizeDesired == til::size{ 0, 0 } ||
+                                                _coordSizeDesired == til::size{ 8, 12 }));
 }
diff --git a/src/renderer/base/RenderEngineBase.cpp b/src/renderer/base/RenderEngineBase.cpp
index b3912c32cec..1bff8739162 100644
--- a/src/renderer/base/RenderEngineBase.cpp
+++ b/src/renderer/base/RenderEngineBase.cpp
@@ -36,7 +36,7 @@ HRESULT RenderEngineBase::NotifyNewText(const std::wstring_view /*newText*/) noe
 }
 
 HRESULT RenderEngineBase::UpdateSoftFont(const gsl::span<const uint16_t> /*bitPattern*/,
-                                         const SIZE /*cellSize*/,
+                                         const til::size /*cellSize*/,
                                          const size_t /*centeringHint*/) noexcept
 {
     return S_FALSE;
diff --git a/src/renderer/base/fontinfo.cpp b/src/renderer/base/fontinfo.cpp
index c73326c0852..8ef6d0b2c7a 100644
--- a/src/renderer/base/fontinfo.cpp
+++ b/src/renderer/base/fontinfo.cpp
@@ -8,7 +8,7 @@
 FontInfo::FontInfo(const std::wstring_view& faceName,
                    const unsigned char family,
                    const unsigned int weight,
-                   const COORD coordSize,
+                   const til::size coordSize,
                    const unsigned int codePage,
                    const bool fSetDefaultRasterFont /* = false */) noexcept :
     FontInfoBase(faceName, family, weight, fSetDefaultRasterFont, codePage),
@@ -26,12 +26,12 @@ bool FontInfo::operator==(const FontInfo& other) noexcept
            _coordSizeUnscaled == other._coordSizeUnscaled;
 }
 
-COORD FontInfo::GetUnscaledSize() const noexcept
+til::size FontInfo::GetUnscaledSize() const noexcept
 {
     return _coordSizeUnscaled;
 }
 
-COORD FontInfo::GetSize() const noexcept
+til::size FontInfo::GetSize() const noexcept
 {
     return _coordSize;
 }
@@ -40,8 +40,8 @@ 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
+                             const til::size coordSize,
+                             const til::size coordSizeUnscaled) noexcept
 {
     FontInfoBase::SetFromEngine(faceName,
                                 family,
diff --git a/src/renderer/base/precomp.h b/src/renderer/base/precomp.h
index 4b0c259334f..e05716224a5 100644
--- a/src/renderer/base/precomp.h
+++ b/src/renderer/base/precomp.h
@@ -22,7 +22,6 @@ Module Name:
 #include <wincon.h>
 
 #include "../../types/inc/viewport.hpp"
-#include "../../inc/operators.hpp"
 
 #ifndef _NTSTATUS_DEFINED
 #define _NTSTATUS_DEFINED
diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp
index b75b55de0ba..f686f4cc0a3 100644
--- a/src/renderer/base/renderer.cpp
+++ b/src/renderer/base/renderer.cpp
@@ -198,7 +198,7 @@ void Renderer::NotifyPaintFrame() noexcept
 // - <none>
 // Return Value:
 // - <none>
-void Renderer::TriggerSystemRedraw(const RECT* const prcDirtyClient)
+void Renderer::TriggerSystemRedraw(const til::rect* const prcDirtyClient)
 {
     FOREACH_ENGINE(pEngine)
     {
@@ -249,7 +249,7 @@ void Renderer::TriggerRedraw(const Viewport& region)
 // - pcoord: The buffer-space coordinate that has changed.
 // Return Value:
 // - <none>
-void Renderer::TriggerRedraw(const COORD* const pcoord)
+void Renderer::TriggerRedraw(const til::point* const pcoord)
 {
     TriggerRedraw(Viewport::FromCoord(*pcoord)); // this will notify to paint if we need it.
 }
@@ -263,7 +263,7 @@ void Renderer::TriggerRedraw(const COORD* const pcoord)
 // - pcoord: The buffer-space position of the cursor.
 // Return Value:
 // - <none>
-void Renderer::TriggerRedrawCursor(const COORD* const pcoord)
+void Renderer::TriggerRedrawCursor(const til::point* const pcoord)
 {
     // We first need to make sure the cursor position is within the buffer,
     // otherwise testing for a double width character can throw an exception.
@@ -274,8 +274,8 @@ void Renderer::TriggerRedrawCursor(const COORD* const pcoord)
         // converting the buffer coordinates to an equivalent range of screen
         // cells for the cursor, taking line rendition into account.
         const auto lineRendition = buffer.GetLineRendition(pcoord->Y);
-        const SHORT cursorWidth = _pData->IsCursorDoubleWidth() ? 2 : 1;
-        const SMALL_RECT cursorRect = { pcoord->X, pcoord->Y, pcoord->X + cursorWidth - 1, pcoord->Y };
+        const auto cursorWidth = _pData->IsCursorDoubleWidth() ? 2 : 1;
+        const til::inclusive_rect cursorRect = { pcoord->X, pcoord->Y, pcoord->X + cursorWidth - 1, pcoord->Y };
         auto cursorView = Viewport::FromInclusive(BufferToScreenLine(cursorRect, lineRendition));
 
         // The region is clamped within the viewport boundaries and we only
@@ -361,20 +361,13 @@ void Renderer::TriggerSelection()
         // Get selection rectangles
         auto rects = _GetSelectionRects();
 
+        // Make a viewport representing the coordinates that are currently presentable.
+        const til::rect viewport{ _pData->GetViewport().Dimensions() };
+
         // Restrict all previous selection rectangles to inside the current viewport bounds
         for (auto& sr : _previousSelection)
         {
-            // Make the exclusive SMALL_RECT into a til::rect.
-            til::rect rc{ Viewport::FromExclusive(sr).ToInclusive() };
-
-            // Make a viewport representing the coordinates that are currently presentable.
-            const til::rect viewport{ til::size{ _pData->GetViewport().Dimensions() } };
-
-            // Intersect them so we only invalidate things that are still visible.
-            rc &= viewport;
-
-            // Convert back into the exclusive SMALL_RECT and store in the vector.
-            sr = Viewport::FromInclusive(rc.to_small_rect()).ToExclusive();
+            sr &= viewport;
         }
 
         FOREACH_ENGINE(pEngine)
@@ -409,7 +402,7 @@ bool Renderer::_CheckViewportAndScroll()
     _viewport = Viewport::FromInclusive(srNewViewport);
     _forceUpdateViewport = false;
 
-    COORD coordDelta;
+    til::point coordDelta;
     coordDelta.X = srOldViewport.Left - srNewViewport.Left;
     coordDelta.Y = srOldViewport.Top - srNewViewport.Top;
 
@@ -419,7 +412,7 @@ bool Renderer::_CheckViewportAndScroll()
         LOG_IF_FAILED(engine->InvalidateScroll(&coordDelta));
     }
 
-    _ScrollPreviousSelection(til::point{ coordDelta });
+    _ScrollPreviousSelection(coordDelta);
     return true;
 }
 
@@ -447,14 +440,14 @@ void Renderer::TriggerScroll()
 // - <none>
 // Return Value:
 // - <none>
-void Renderer::TriggerScroll(const COORD* const pcoordDelta)
+void Renderer::TriggerScroll(const til::point* const pcoordDelta)
 {
     FOREACH_ENGINE(pEngine)
     {
         LOG_IF_FAILED(pEngine->InvalidateScroll(pcoordDelta));
     }
 
-    _ScrollPreviousSelection(til::point{ *pcoordDelta });
+    _ScrollPreviousSelection(*pcoordDelta);
 
     NotifyPaintFrame();
 }
@@ -549,7 +542,7 @@ void Renderer::TriggerFontChange(const int iDpi, const FontInfoDesired& FontInfo
 // - centeringHint - The horizontal extent that glyphs are offset from center.
 // Return Value:
 // - <none>
-void Renderer::UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const SIZE cellSize, const size_t centeringHint)
+void Renderer::UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const til::size cellSize, const size_t centeringHint)
 {
     // We reserve PUA code points U+EF20 to U+EF7F for soft fonts, but the range
     // that we test for in _IsSoftFontChar will depend on the size of the active
@@ -707,7 +700,7 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine)
             continue;
         }
 
-        auto dirty = Viewport::FromInclusive(dirtyRect.to_small_rect());
+        auto dirty = Viewport::FromExclusive(dirtyRect);
 
         // Shift the origin of the dirty region to match the underlying buffer so we can
         // compare the two regions directly for intersection.
@@ -726,7 +719,7 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine)
         {
             // Calculate the boundaries of a single line. This is from the left to right edge of the dirty
             // area in width and exactly 1 tall.
-            const auto screenLine = SMALL_RECT{ redraw.Left(), row, redraw.RightInclusive(), row };
+            const auto screenLine = til::inclusive_rect{ redraw.Left(), row, redraw.RightInclusive(), row };
 
             // Convert the screen coordinates of the line to an equivalent
             // range of buffer cells, taking line rendition into account.
@@ -738,7 +731,7 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine)
             // For example, the screen might say we need to paint line 1 because it is dirty but the viewport
             // is actually looking at line 26 relative to the buffer. This means that we need line 27 out
             // of the backing buffer to fill in line 1 of the screen.
-            const auto screenPosition = bufferLine.Origin() - COORD{ 0, view.Top() };
+            const auto screenPosition = bufferLine.Origin() - til::point{ 0, view.Top() };
 
             // Retrieve the cell information iterator limited to just this line we want to redraw.
             auto it = buffer.GetCellDataAt(bufferLine.Origin(), bufferLine);
@@ -767,7 +760,7 @@ static bool _IsAllSpaces(const std::wstring_view v)
 
 void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
                                         TextBufferCellIterator it,
-                                        const COORD target,
+                                        const til::point target,
                                         const bool lineWrapped)
 {
     auto globalInvert{ _renderSettings.GetRenderMode(RenderSettings::Mode::ScreenReversed) };
@@ -779,7 +772,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
         // we should have an iterator/view adapter for the rendering.
         // That would probably also eliminate the RenderData needing to give us the entire TextBuffer as well...
         // Retrieve the iterator for one line of information.
-        size_t cols = 0;
+        til::CoordType cols = 0;
 
         // Retrieve the first color.
         auto color = it->TextAttr();
@@ -807,7 +800,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
             THROW_IF_FAILED(_UpdateDrawingBrushes(pEngine, currentRunColor, usingSoftFont, false));
 
             // Advance the point by however many columns we've just outputted and reset the accumulator.
-            screenPoint.X += gsl::narrow<SHORT>(cols);
+            screenPoint.X += cols;
             cols = 0;
 
             // Hold onto the start of this run iterator and the target location where we started
@@ -831,7 +824,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
             // We also accumulate clusters according to regex patterns
             do
             {
-                COORD thisPoint{ gsl::narrow<SHORT>(screenPoint.X + cols), screenPoint.Y };
+                til::point thisPoint{ screenPoint.X + cols, screenPoint.Y };
                 const auto thisPointPatterns = _pData->GetPatternId(thisPoint);
                 const auto thisUsingSoftFont = s_IsSoftFontChar(it->Chars(), _firstSoftFontChar, _lastSoftFontChar);
                 const auto changedPatternOrFont = patternIds != thisPointPatterns || usingSoftFont != thisUsingSoftFont;
@@ -872,7 +865,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
 
                 // Advance the cluster and column counts.
                 _clusterBuffer.emplace_back(it->Chars(), columnCount);
-                it += std::max<size_t>(it->Columns(), 1); // prevent infinite loop for no visible columns
+                it += std::max(it->Columns(), 1); // prevent infinite loop for no visible columns
                 cols += columnCount;
 
             } while (it);
@@ -901,7 +894,7 @@ void Renderer::_PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine,
                     // We could theoretically pre-pass for this in the loop above to be more efficient about walking
                     // the iterator, but I fear it would make the code even more confusing than it already is.
                     // Do that in the future if some WPR trace points you to this spot as super bad.
-                    for (auto colsPainted = 0u; colsPainted < cols; ++colsPainted, ++lineIt, ++lineTarget.X)
+                    for (til::CoordType colsPainted = 0; colsPainted < cols; ++colsPainted, ++lineIt, ++lineTarget.X)
                     {
                         auto lines = lineIt->TextAttr();
                         _PaintBufferOutputGridLineHelper(pEngine, lines, 1, lineTarget);
@@ -984,7 +977,7 @@ IRenderEngine::GridLineSet Renderer::s_GetGridlines(const TextAttribute& textAtt
 void Renderer::_PaintBufferOutputGridLineHelper(_In_ IRenderEngine* const pEngine,
                                                 const TextAttribute textAttribute,
                                                 const size_t cchLine,
-                                                const COORD coordTarget)
+                                                const til::point coordTarget)
 {
     // Convert console grid line representations into rendering engine enum representations.
     auto lines = Renderer::s_GetGridlines(textAttribute);
@@ -1125,37 +1118,23 @@ void Renderer::_PaintOverlay(IRenderEngine& engine,
 {
     try
     {
-        // First get the screen buffer's viewport.
-        auto view = _pData->GetViewport();
-
         // Now get the overlay's viewport and adjust it to where it is supposed to be relative to the window.
-
-        auto srCaView = overlay.region.ToInclusive();
+        auto srCaView = overlay.region.ToExclusive();
         srCaView.Top += overlay.origin.Y;
         srCaView.Bottom += overlay.origin.Y;
         srCaView.Left += overlay.origin.X;
         srCaView.Right += overlay.origin.X;
 
-        // Set it up in a Viewport helper structure and trim it the IME viewport to be within the full console viewport.
-        auto viewConv = Viewport::FromInclusive(srCaView);
-
         gsl::span<const til::rect> dirtyAreas;
         LOG_IF_FAILED(engine.GetDirtyArea(dirtyAreas));
 
         for (const auto& rect : dirtyAreas)
         {
-            // Dirty is an inclusive rectangle, but oddly enough the IME was an exclusive one, so correct it.
-            auto srDirty = rect.to_small_rect();
-            srDirty.Bottom++;
-            srDirty.Right++;
-
-            if (viewConv.TrimToViewport(&srDirty))
+            if (const auto viewDirty = rect & srCaView)
             {
-                auto viewDirty = Viewport::FromInclusive(srDirty);
-
-                for (auto iRow = viewDirty.Top(); iRow < viewDirty.BottomInclusive(); iRow++)
+                for (auto iRow = viewDirty.Top; iRow < viewDirty.Bottom; iRow++)
                 {
-                    const COORD target{ viewDirty.Left(), iRow };
+                    const til::point target{ viewDirty.Left, iRow };
                     const auto source = target - overlay.origin;
 
                     auto it = overlay.buffer.GetCellLineDataAt(source);
@@ -1205,15 +1184,11 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine)
 
         // Get selection rectangles
         const auto rectangles = _GetSelectionRects();
-        for (auto rect : rectangles)
+        for (const auto& rect : rectangles)
         {
             for (auto& dirtyRect : dirtyAreas)
             {
-                // Make a copy as `TrimToViewport` will manipulate it and
-                // can destroy it for the next dirtyRect to test against.
-                auto rectCopy = rect;
-                auto dirtyView = Viewport::FromInclusive(dirtyRect.to_small_rect());
-                if (dirtyView.TrimToViewport(&rectCopy))
+                if (const auto rectCopy = rect & dirtyRect)
                 {
                     LOG_IF_FAILED(pEngine->PaintSelection(rectCopy));
                 }
@@ -1262,14 +1237,14 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine)
 // - Helper to determine the selected region of the buffer.
 // Return Value:
 // - A vector of rectangles representing the regions to select, line by line.
-std::vector<SMALL_RECT> Renderer::_GetSelectionRects() const
+std::vector<til::rect> Renderer::_GetSelectionRects() const
 {
     const auto& buffer = _pData->GetTextBuffer();
     auto rects = _pData->GetSelectionRects();
     // Adjust rectangles to viewport
     auto view = _pData->GetViewport();
 
-    std::vector<SMALL_RECT> result;
+    std::vector<til::rect> result;
     result.reserve(rects.size());
 
     for (auto rect : rects)
@@ -1278,14 +1253,7 @@ std::vector<SMALL_RECT> Renderer::_GetSelectionRects() const
         // expected by callers, taking line rendition into account.
         const auto lineRendition = buffer.GetLineRendition(rect.Top());
         rect = Viewport::FromInclusive(BufferToScreenLine(rect.ToInclusive(), lineRendition));
-
-        auto sr = view.ConvertToOrigin(rect).ToInclusive();
-
-        // hopefully temporary, we should be receiving the right selection sizes without correction.
-        sr.Right++;
-        sr.Bottom++;
-
-        result.emplace_back(sr);
+        result.emplace_back(view.ConvertToOrigin(rect).ToExclusive());
     }
 
     return result;
@@ -1304,16 +1272,9 @@ void Renderer::_ScrollPreviousSelection(const til::point delta)
 {
     if (delta != til::point{ 0, 0 })
     {
-        for (auto& sr : _previousSelection)
+        for (auto& rc : _previousSelection)
         {
-            // Get a rectangle representing this piece of the selection.
-            til::rect rc{ Viewport::FromExclusive(sr).ToInclusive() };
-
-            // Offset the entire existing rectangle by the delta.
             rc += delta;
-
-            // Store it back into the vector.
-            sr = Viewport::FromInclusive(rc.to_small_rect()).ToExclusive();
         }
     }
 }
diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp
index 009f3a954f9..b6b051199b6 100644
--- a/src/renderer/base/renderer.hpp
+++ b/src/renderer/base/renderer.hpp
@@ -48,16 +48,16 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT PaintFrame();
 
         void NotifyPaintFrame() noexcept;
-        void TriggerSystemRedraw(const RECT* const prcDirtyClient);
+        void TriggerSystemRedraw(const til::rect* const prcDirtyClient);
         void TriggerRedraw(const Microsoft::Console::Types::Viewport& region);
-        void TriggerRedraw(const COORD* const pcoord);
-        void TriggerRedrawCursor(const COORD* const pcoord);
+        void TriggerRedraw(const til::point* const pcoord);
+        void TriggerRedrawCursor(const til::point* const pcoord);
         void TriggerRedrawAll(const bool backgroundChanged = false, const bool frameChanged = false);
         void TriggerTeardown() noexcept;
 
         void TriggerSelection();
         void TriggerScroll();
-        void TriggerScroll(const COORD* const pcoordDelta);
+        void TriggerScroll(const til::point* const pcoordDelta);
 
         void TriggerFlush(const bool circling);
         void TriggerTitleChange();
@@ -69,7 +69,7 @@ namespace Microsoft::Console::Render
                                _Out_ FontInfo& FontInfo);
 
         void UpdateSoftFont(const gsl::span<const uint16_t> bitPattern,
-                            const SIZE cellSize,
+                            const til::size cellSize,
                             const size_t centeringHint);
 
         [[nodiscard]] HRESULT GetProposedFont(const int iDpi,
@@ -99,15 +99,15 @@ namespace Microsoft::Console::Render
         bool _CheckViewportAndScroll();
         [[nodiscard]] HRESULT _PaintBackground(_In_ IRenderEngine* const pEngine);
         void _PaintBufferOutput(_In_ IRenderEngine* const pEngine);
-        void _PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine, TextBufferCellIterator it, const COORD target, const bool lineWrapped);
-        void _PaintBufferOutputGridLineHelper(_In_ IRenderEngine* const pEngine, const TextAttribute textAttribute, const size_t cchLine, const COORD coordTarget);
+        void _PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine, TextBufferCellIterator it, const til::point target, const bool lineWrapped);
+        void _PaintBufferOutputGridLineHelper(_In_ IRenderEngine* const pEngine, const TextAttribute textAttribute, const size_t cchLine, const til::point coordTarget);
         void _PaintSelection(_In_ IRenderEngine* const pEngine);
         void _PaintCursor(_In_ IRenderEngine* const pEngine);
         void _PaintOverlays(_In_ IRenderEngine* const pEngine);
         void _PaintOverlay(IRenderEngine& engine, const RenderOverlay& overlay);
         [[nodiscard]] HRESULT _UpdateDrawingBrushes(_In_ IRenderEngine* const pEngine, const TextAttribute attr, const bool usingSoftFont, const bool isSettingDefaultBrushes);
         [[nodiscard]] HRESULT _PerformScrolling(_In_ IRenderEngine* const pEngine);
-        std::vector<SMALL_RECT> _GetSelectionRects() const;
+        std::vector<til::rect> _GetSelectionRects() const;
         void _ScrollPreviousSelection(const til::point delta);
         [[nodiscard]] HRESULT _PaintTitle(IRenderEngine* const pEngine);
         [[nodiscard]] std::optional<CursorOptions> _GetCursorInfo();
@@ -122,7 +122,7 @@ namespace Microsoft::Console::Render
         std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> _hoveredInterval;
         Microsoft::Console::Types::Viewport _viewport;
         std::vector<Cluster> _clusterBuffer;
-        std::vector<SMALL_RECT> _previousSelection;
+        std::vector<til::rect> _previousSelection;
         std::function<void()> _pfnBackgroundColorChanged;
         std::function<void()> _pfnFrameColorChanged;
         std::function<void()> _pfnRendererEnteredErrorState;
diff --git a/src/renderer/dx/DxFontRenderData.cpp b/src/renderer/dx/DxFontRenderData.cpp
index 868391f4466..c5e1ddcfbed 100644
--- a/src/renderer/dx/DxFontRenderData.cpp
+++ b/src/renderer/dx/DxFontRenderData.cpp
@@ -820,9 +820,9 @@ void DxFontRenderData::_BuildFontRenderData(const FontInfoDesired& desired, Font
 
     // The scaled size needs to represent the pixel box that each character will fit within for the purposes
     // of hit testing math and other such multiplication/division.
-    COORD coordSize = { 0 };
-    coordSize.X = gsl::narrow<SHORT>(widthExact);
-    coordSize.Y = gsl::narrow_cast<SHORT>(lineSpacing.height);
+    til::size coordSize;
+    coordSize.X = static_cast<til::CoordType>(widthExact);
+    coordSize.Y = static_cast<til::CoordType>(lineSpacing.height);
 
     // Unscaled is for the purposes of re-communicating this font back to the renderer again later.
     // As such, we need to give the same original size parameter back here without padding
@@ -890,7 +890,7 @@ void DxFontRenderData::_BuildFontRenderData(const FontInfoDesired& desired, Font
 
     _lineMetrics = lineMetrics;
 
-    _glyphCell = til::size{ actual.GetSize() };
+    _glyphCell = actual.GetSize();
 }
 
 Microsoft::WRL::ComPtr<IDWriteTextFormat> DxFontRenderData::_BuildTextFormat(const DxFontInfo& fontInfo, const std::wstring_view localeName)
diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp
index 141968dd579..46749162d3c 100644
--- a/src/renderer/dx/DxRenderer.cpp
+++ b/src/renderer/dx/DxRenderer.cpp
@@ -640,7 +640,7 @@ try
         case SwapChainMode::ForHwnd:
         {
             // use the HWND's dimensions for the swap chain dimensions.
-            RECT rect = { 0 };
+            RECT rect;
             RETURN_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &rect));
 
             _swapChainDesc.Width = rect.right - rect.left;
@@ -986,10 +986,10 @@ CATCH_RETURN()
     return S_OK;
 }
 
-[[nodiscard]] HRESULT DxEngine::SetWindowSize(const SIZE Pixels) noexcept
+[[nodiscard]] HRESULT DxEngine::SetWindowSize(const til::size Pixels) noexcept
 try
 {
-    _sizeTarget = til::size{ Pixels };
+    _sizeTarget = Pixels;
     return S_OK;
 }
 CATCH_RETURN();
@@ -1076,7 +1076,7 @@ void DxEngine::_InvalidateRectangle(const til::rect& rc)
     const auto size = _invalidMap.size();
     const auto topLeft = til::point{ 0, std::clamp(rc.top, 0, size.height) };
     const auto bottomRight = til::point{ size.width, std::clamp(rc.bottom, 0, size.height) };
-    _invalidMap.set(til::rect{ topLeft, bottomRight });
+    _invalidMap.set({ topLeft, bottomRight });
 }
 
 bool DxEngine::_IsAllInvalid() const noexcept
@@ -1090,14 +1090,14 @@ bool DxEngine::_IsAllInvalid() const noexcept
 // - psrRegion - Character rectangle
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT DxEngine::Invalidate(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT DxEngine::Invalidate(const til::rect* const psrRegion) noexcept
 try
 {
     RETURN_HR_IF_NULL(E_INVALIDARG, psrRegion);
 
     if (!_allInvalid)
     {
-        _InvalidateRectangle(til::rect{ Viewport::FromExclusive(*psrRegion).ToInclusive() });
+        _InvalidateRectangle(*psrRegion);
     }
 
     return S_OK;
@@ -1110,7 +1110,7 @@ CATCH_RETURN()
 // - psrRegion - the region covered by the cursor
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT DxEngine::InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT DxEngine::InvalidateCursor(const til::rect* const psrRegion) noexcept
 {
     return Invalidate(psrRegion);
 }
@@ -1121,7 +1121,7 @@ CATCH_RETURN()
 // - prcDirtyClient - pixel rectangle
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT DxEngine::InvalidateSystem(const RECT* const prcDirtyClient) noexcept
+[[nodiscard]] HRESULT DxEngine::InvalidateSystem(const til::rect* const prcDirtyClient) noexcept
 try
 {
     RETURN_HR_IF_NULL(E_INVALIDARG, prcDirtyClient);
@@ -1130,7 +1130,7 @@ try
     {
         // Dirty client is in pixels. Use divide specialization against glyph factor to make conversion
         // to cells.
-        _InvalidateRectangle(til::rect{ *prcDirtyClient }.scale_down(_fontRenderData->GlyphCell()));
+        _InvalidateRectangle(prcDirtyClient->scale_down(_fontRenderData->GlyphCell()));
     }
 
     return S_OK;
@@ -1143,7 +1143,7 @@ CATCH_RETURN();
 // - rectangles - One or more rectangles describing character positions on the grid
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT DxEngine::InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept
+[[nodiscard]] HRESULT DxEngine::InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept
 {
     if (!_allInvalid)
     {
@@ -1163,12 +1163,12 @@ CATCH_RETURN();
 //               - -Y is up, Y is down, -X is left, X is right.
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT DxEngine::InvalidateScroll(const COORD* const pcoordDelta) noexcept
+[[nodiscard]] HRESULT DxEngine::InvalidateScroll(const til::point* const pcoordDelta) noexcept
 try
 {
     RETURN_HR_IF(E_INVALIDARG, !pcoordDelta);
 
-    const til::point deltaCells{ *pcoordDelta };
+    const auto deltaCells{ *pcoordDelta };
 
     if (!_allInvalid)
     {
@@ -1222,7 +1222,7 @@ CATCH_RETURN();
     {
     case SwapChainMode::ForHwnd:
     {
-        RECT clientRect = { 0 };
+        RECT clientRect;
         LOG_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &clientRect));
 
         return til::rect{ clientRect }.size();
@@ -1244,7 +1244,7 @@ CATCH_RETURN();
 // - fontSize - scaling factors
 // Return Value:
 // - <none> - Updates reference
-void _ScaleByFont(RECT& cellsToPixels, SIZE fontSize) noexcept
+void _ScaleByFont(til::rect& cellsToPixels, til::size fontSize) noexcept
 {
     cellsToPixels.left *= fontSize.cx;
     cellsToPixels.right *= fontSize.cx;
@@ -1681,13 +1681,13 @@ CATCH_RETURN()
 // Return Value:
 // - S_OK or relevant DirectX error
 [[nodiscard]] HRESULT DxEngine::PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                                const COORD coord,
+                                                const til::point coord,
                                                 const bool /*trimLeft*/,
                                                 const bool /*lineWrapped*/) noexcept
 try
 {
     // Calculate positioning of our origin.
-    const auto origin = (til::point{ coord } * _fontRenderData->GlyphCell()).to_d2d_point();
+    const auto origin = (coord * _fontRenderData->GlyphCell()).to_d2d_point();
 
     // Create the text layout
     RETURN_IF_FAILED(_customLayout->Reset());
@@ -1713,7 +1713,7 @@ CATCH_RETURN()
 [[nodiscard]] HRESULT DxEngine::PaintBufferGridLines(const GridLineSet lines,
                                                      COLORREF const color,
                                                      const size_t cchLine,
-                                                     const COORD coordTarget) noexcept
+                                                     const til::point coordTarget) noexcept
 try
 {
     const auto existingColor = _d2dBrushForeground->GetColor();
@@ -1829,7 +1829,7 @@ CATCH_RETURN()
 //  - rect - Rectangle to invert or highlight to make the selection area
 // Return Value:
 // - S_OK or relevant DirectX error.
-[[nodiscard]] HRESULT DxEngine::PaintSelection(const SMALL_RECT rect) noexcept
+[[nodiscard]] HRESULT DxEngine::PaintSelection(const til::rect& rect) noexcept
 try
 {
     // If a clip rectangle is in place from drawing the text layer, remove it here.
@@ -1840,7 +1840,7 @@ try
     _d2dBrushForeground->SetColor(_selectionBackground);
     const auto resetColorOnExit = wil::scope_exit([&]() noexcept { _d2dBrushForeground->SetColor(existingColor); });
 
-    const auto draw = til::rect{ Viewport::FromExclusive(rect).ToInclusive() }.scale_up(_fontRenderData->GlyphCell()).to_d2d_rect();
+    const D2D1_RECT_F draw = rect.scale_up(_fontRenderData->GlyphCell()).to_d2d_rect();
 
     _d2dDeviceContext->FillRectangle(draw, _d2dBrushForeground.Get());
 
@@ -2027,16 +2027,16 @@ CATCH_RETURN();
 
 [[nodiscard]] Viewport DxEngine::GetViewportInCharacters(const Viewport& viewInPixels) const noexcept
 {
-    const auto widthInChars = base::saturated_cast<short>(viewInPixels.Width() / _fontRenderData->GlyphCell().width);
-    const auto heightInChars = base::saturated_cast<short>(viewInPixels.Height() / _fontRenderData->GlyphCell().height);
+    const auto widthInChars = viewInPixels.Width() / _fontRenderData->GlyphCell().width;
+    const auto heightInChars = viewInPixels.Height() / _fontRenderData->GlyphCell().height;
 
     return Viewport::FromDimensions(viewInPixels.Origin(), { widthInChars, heightInChars });
 }
 
 [[nodiscard]] Viewport DxEngine::GetViewportInPixels(const Viewport& viewInCharacters) const noexcept
 {
-    const auto widthInPixels = base::saturated_cast<short>(viewInCharacters.Width() * _fontRenderData->GlyphCell().width);
-    const auto heightInPixels = base::saturated_cast<short>(viewInCharacters.Height() * _fontRenderData->GlyphCell().height);
+    const auto widthInPixels = viewInCharacters.Width() * _fontRenderData->GlyphCell().width;
+    const auto heightInPixels = viewInCharacters.Height() * _fontRenderData->GlyphCell().height;
 
     return Viewport::FromDimensions(viewInCharacters.Origin(), { widthInPixels, heightInPixels });
 }
@@ -2081,7 +2081,7 @@ float DxEngine::GetScaling() const noexcept
 // - srNewViewport - The bounds of the new viewport.
 // Return Value:
 // - HRESULT S_OK
-[[nodiscard]] HRESULT DxEngine::UpdateViewport(const SMALL_RECT /*srNewViewport*/) noexcept
+[[nodiscard]] HRESULT DxEngine::UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept
 {
     return S_OK;
 }
@@ -2124,12 +2124,10 @@ CATCH_RETURN();
 // - pFontSize - Filled with the font size.
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT DxEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
+[[nodiscard]] HRESULT DxEngine::GetFontSize(_Out_ til::size* const pFontSize) noexcept
 try
 {
-    const auto size = _fontRenderData->GlyphCell();
-    pFontSize->X = size.narrow_width<short>();
-    pFontSize->Y = size.narrow_height<short>();
+    *pFontSize = _fontRenderData->GlyphCell();
     return S_OK;
 }
 CATCH_RETURN();
diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp
index 7fa74402099..fb1e4618d77 100644
--- a/src/renderer/dx/DxRenderer.hpp
+++ b/src/renderer/dx/DxRenderer.hpp
@@ -54,7 +54,7 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT SetHwnd(const HWND hwnd) noexcept override;
 
-        [[nodiscard]] HRESULT SetWindowSize(const SIZE pixels) noexcept override;
+        [[nodiscard]] HRESULT SetWindowSize(const til::size pixels) noexcept override;
 
         void SetCallback(std::function<void()> pfn) noexcept override;
         void SetWarningCallback(std::function<void(const HRESULT)> pfn) noexcept override;
@@ -73,11 +73,11 @@ namespace Microsoft::Console::Render
         HANDLE GetSwapChainHandle() noexcept override;
 
         // IRenderEngine Members
-        [[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 Invalidate(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* const prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* const pcoordDelta) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override;
 
@@ -100,12 +100,12 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
         [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                              const COORD coord,
+                                              const til::point coord,
                                               const bool fTrimLeft,
                                               const bool lineWrapped) noexcept override;
 
-        [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, COLORREF const color, const size_t cchLine, const COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet const lines, COLORREF const color, size_t const cchLine, til::point const coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
 
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
 
@@ -117,13 +117,13 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override;
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, const std::unordered_map<std::wstring_view, uint32_t>& features, const std::unordered_map<std::wstring_view, float>& axes) noexcept override;
         [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override;
-        [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override;
+        [[nodiscard]] HRESULT UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept override;
 
         [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, const int iDpi) noexcept override;
 
         [[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept override;
 
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* pFontSize) 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) const noexcept override;
diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp
index 365d5bdeba7..5800055ef4b 100644
--- a/src/renderer/gdi/gdirenderer.hpp
+++ b/src/renderer/gdi/gdirenderer.hpp
@@ -27,11 +27,11 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT SetHwnd(const HWND hwnd) noexcept;
 
-        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept override;
-        [[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override;
-        [[nodiscard]] HRESULT InvalidateSystem(const RECT* const prcDirtyClient) noexcept override;
-        [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override;
-        [[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* const pcoordDelta) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* const prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT Invalidate(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* const psrRegion) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override;
 
@@ -48,14 +48,14 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
         [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                              const COORD coord,
+                                              const til::point coord,
                                               const bool trimLeft,
                                               const bool lineWrapped) noexcept override;
         [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines,
                                                    const COLORREF color,
                                                    const size_t cchLine,
-                                                   const COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
+                                                   const til::point coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
 
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
 
@@ -67,17 +67,17 @@ namespace Microsoft::Console::Render
         [[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 til::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 UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept override;
 
         [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& FontDesired,
                                               _Out_ FontInfo& Font,
                                               const int iDpi) noexcept override;
 
         [[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept override;
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* const pFontSize) noexcept override;
         [[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
 
     protected:
@@ -123,17 +123,17 @@ namespace Microsoft::Console::Render
         };
 
         LineMetrics _lineMetrics;
-        COORD _coordFontLast;
+        til::size _coordFontLast;
         int _iCurrentDpi;
 
         static const int s_iBaseDpi = USER_DEFAULT_SCREEN_DPI;
 
-        SIZE _szMemorySurface;
+        til::size _szMemorySurface;
         HBITMAP _hbitmapMemorySurface;
         [[nodiscard]] HRESULT _PrepareMemoryBitmap(const HWND hwnd) noexcept;
 
-        SIZE _szInvalidScroll;
-        RECT _rcInvalid;
+        til::size _szInvalidScroll;
+        til::rect _rcInvalid;
         bool _fInvalidRectUsed;
 
         COLORREF _lastFg;
@@ -159,29 +159,25 @@ namespace Microsoft::Console::Render
         std::pmr::vector<std::pmr::wstring> _polyStrings;
         std::pmr::vector<std::pmr::basic_string<int>> _polyWidths;
 
-        [[nodiscard]] HRESULT _InvalidCombine(const RECT* const prc) noexcept;
-        [[nodiscard]] HRESULT _InvalidOffset(const POINT* const ppt) noexcept;
+        [[nodiscard]] HRESULT _InvalidCombine(const til::rect* const prc) noexcept;
+        [[nodiscard]] HRESULT _InvalidOffset(const til::point* const ppt) noexcept;
         [[nodiscard]] HRESULT _InvalidRestrict() noexcept;
 
-        [[nodiscard]] HRESULT _InvalidateRect(const RECT* const prc) noexcept;
+        [[nodiscard]] HRESULT _InvalidateRect(const til::rect* const prc) noexcept;
 
         [[nodiscard]] HRESULT _PaintBackgroundColor(const RECT* const prc) noexcept;
 
         static const ULONG s_ulMinCursorHeightPercent = 25;
         static const ULONG s_ulMaxCursorHeightPercent = 100;
 
-        [[nodiscard]] HRESULT _ScaleByFont(const COORD* const pcoord, _Out_ POINT* const pPoint) const noexcept;
-        [[nodiscard]] HRESULT _ScaleByFont(const SMALL_RECT* const psr, _Out_ RECT* const prc) const noexcept;
-        [[nodiscard]] HRESULT _ScaleByFont(const RECT* const prc, _Out_ SMALL_RECT* const psr) const noexcept;
-
         static int s_ScaleByDpi(const int iPx, const int iDpi);
         static int s_ShrinkByDpi(const int iPx, const int iDpi);
 
-        POINT _GetInvalidRectPoint() const;
-        SIZE _GetInvalidRectSize() const;
-        SIZE _GetRectSize(const RECT* const pRect) const;
+        til::point _GetInvalidRectPoint() const;
+        til::size _GetInvalidRectSize() const;
+        til::size _GetRectSize(const RECT* const pRect) const;
 
-        void _OrRect(_In_ RECT* const pRectExisting, const RECT* const pRectToOr) const;
+        void _OrRect(_In_ til::rect* const pRectExisting, const til::rect* const pRectToOr) const;
 
         bool _IsFontTrueType() const;
 
@@ -191,7 +187,7 @@ namespace Microsoft::Console::Render
                                                _Inout_ wil::unique_hfont& hFont,
                                                _Inout_ wil::unique_hfont& hFontItalic) noexcept;
 
-        COORD _GetFontSize() const;
+        til::size _GetFontSize() const;
         bool _IsMinimized() const;
         bool _IsWindowValid() const;
 
diff --git a/src/renderer/gdi/invalidate.cpp b/src/renderer/gdi/invalidate.cpp
index c55e21d2144..b8b32d58328 100644
--- a/src/renderer/gdi/invalidate.cpp
+++ b/src/renderer/gdi/invalidate.cpp
@@ -14,10 +14,10 @@ using namespace Microsoft::Console::Render;
 // Routine Description:
 // - Notifies us that the system has requested a particular pixel area of the client rectangle should be redrawn. (On WM_PAINT)
 // Arguments:
-// - prcDirtyClient - Pointer to pixel area (RECT) of client region the system believes is dirty
+// - prcDirtyClient - Pointer to pixel area (til::rect) of client region the system believes is dirty
 // Return Value:
 // - HRESULT S_OK, GDI-based error code, or safemath error
-HRESULT GdiEngine::InvalidateSystem(const RECT* const prcDirtyClient) noexcept
+HRESULT GdiEngine::InvalidateSystem(const til::rect* const prcDirtyClient) noexcept
 {
     RETURN_HR(_InvalidCombine(prcDirtyClient));
 }
@@ -25,24 +25,16 @@ HRESULT GdiEngine::InvalidateSystem(const RECT* const prcDirtyClient) noexcept
 // Routine Description:
 // - Notifies us that the console is attempting to scroll the existing screen area
 // Arguments:
-// - pcoordDelta - Pointer to character dimension (COORD) of the distance the console would like us to move while scrolling.
+// - pcoordDelta - Pointer to character dimension (til::point) of the distance the console would like us to move while scrolling.
 // Return Value:
 // - HRESULT S_OK, GDI-based error code, or safemath error
-HRESULT GdiEngine::InvalidateScroll(const COORD* const pcoordDelta) noexcept
+HRESULT GdiEngine::InvalidateScroll(const til::point* const pcoordDelta) noexcept
 {
     if (pcoordDelta->X != 0 || pcoordDelta->Y != 0)
     {
-        POINT ptDelta = { 0 };
-        RETURN_IF_FAILED(_ScaleByFont(pcoordDelta, &ptDelta));
-
+        const auto ptDelta = *pcoordDelta * _GetFontSize();
         RETURN_IF_FAILED(_InvalidOffset(&ptDelta));
-
-        SIZE szInvalidScrollNew;
-        RETURN_IF_FAILED(LongAdd(_szInvalidScroll.cx, ptDelta.x, &szInvalidScrollNew.cx));
-        RETURN_IF_FAILED(LongAdd(_szInvalidScroll.cy, ptDelta.y, &szInvalidScrollNew.cy));
-
-        // Store if safemath succeeded
-        _szInvalidScroll = szInvalidScrollNew;
+        _szInvalidScroll = _szInvalidScroll + ptDelta;
     }
 
     return S_OK;
@@ -54,7 +46,7 @@ HRESULT GdiEngine::InvalidateScroll(const COORD* const pcoordDelta) noexcept
 // - rectangles - Vector of rectangles to draw, line by line
 // Return Value:
 // - HRESULT S_OK or GDI-based error code
-HRESULT GdiEngine::InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept
+HRESULT GdiEngine::InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept
 {
     for (const auto& rect : rectangles)
     {
@@ -68,13 +60,12 @@ HRESULT GdiEngine::InvalidateSelection(const std::vector<SMALL_RECT>& rectangles
 // - Notifies us that the console has changed the character region specified.
 // - NOTE: This typically triggers on cursor or text buffer changes
 // Arguments:
-// - psrRegion - Character region (SMALL_RECT) that has been changed
+// - psrRegion - Character region (til::rect) that has been changed
 // Return Value:
 // - S_OK, GDI related failure, or safemath failure.
-HRESULT GdiEngine::Invalidate(const SMALL_RECT* const psrRegion) noexcept
+HRESULT GdiEngine::Invalidate(const til::rect* const psrRegion) noexcept
 {
-    RECT rcRegion = { 0 };
-    RETURN_IF_FAILED(_ScaleByFont(psrRegion, &rcRegion));
+    const auto rcRegion = psrRegion->scale_up(_GetFontSize());
     RETURN_HR(_InvalidateRect(&rcRegion));
 }
 
@@ -84,7 +75,7 @@ HRESULT GdiEngine::Invalidate(const SMALL_RECT* const psrRegion) noexcept
 // - psrRegion - the region covered by the cursor
 // Return Value:
 // - S_OK, else an appropriate HRESULT for failing to allocate or write.
-HRESULT GdiEngine::InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept
+HRESULT GdiEngine::InvalidateCursor(const til::rect* const psrRegion) noexcept
 {
     return this->Invalidate(psrRegion);
 }
@@ -104,8 +95,8 @@ HRESULT GdiEngine::InvalidateAll() noexcept
         return S_FALSE;
     }
 
-    RECT rc;
-    RETURN_HR_IF(E_FAIL, !(GetClientRect(_hwndTargetWindow, &rc)));
+    til::rect rc;
+    RETURN_HR_IF(E_FAIL, !(GetClientRect(_hwndTargetWindow, rc.as_win32_rect())));
     RETURN_HR(InvalidateSystem(&rc));
 }
 
@@ -127,10 +118,10 @@ HRESULT GdiEngine::PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept
 // Routine Description:
 // - Helper to combine the given rectangle into the invalid region to be updated on the next paint
 // Arguments:
-// - prc - Pixel region (RECT) that should be repainted on the next frame
+// - prc - Pixel region (til::rect) that should be repainted on the next frame
 // Return Value:
 // - S_OK, GDI related failure, or safemath failure.
-HRESULT GdiEngine::_InvalidCombine(const RECT* const prc) noexcept
+HRESULT GdiEngine::_InvalidCombine(const til::rect* const prc) noexcept
 {
     if (!_fInvalidRectUsed)
     {
@@ -154,20 +145,19 @@ HRESULT GdiEngine::_InvalidCombine(const RECT* const prc) noexcept
 // - ppt - Distances by which we should move the invalid region in response to a scroll
 // Return Value:
 // - S_OK, GDI related failure, or safemath failure.
-HRESULT GdiEngine::_InvalidOffset(const POINT* const ppt) noexcept
+HRESULT GdiEngine::_InvalidOffset(const til::point* ppt) noexcept
 {
     if (_fInvalidRectUsed)
     {
-        RECT rcInvalidNew;
-
-        RETURN_IF_FAILED(LongAdd(_rcInvalid.left, ppt->x, &rcInvalidNew.left));
-        RETURN_IF_FAILED(LongAdd(_rcInvalid.right, ppt->x, &rcInvalidNew.right));
-        RETURN_IF_FAILED(LongAdd(_rcInvalid.top, ppt->y, &rcInvalidNew.top));
-        RETURN_IF_FAILED(LongAdd(_rcInvalid.bottom, ppt->y, &rcInvalidNew.bottom));
+        til::rect rcInvalidNew;
+        rcInvalidNew.left = _rcInvalid.left + ppt->x;
+        rcInvalidNew.right = _rcInvalid.right + ppt->x;
+        rcInvalidNew.top = _rcInvalid.top + ppt->y;
+        rcInvalidNew.bottom = _rcInvalid.bottom + ppt->y;
 
         // Add the scrolled invalid rectangle to what was left behind to get the new invalid area.
         // This is the equivalent of adding in the "update rectangle" that we would get out of ScrollWindowEx/ScrollDC.
-        UnionRect(&_rcInvalid, &_rcInvalid, &rcInvalidNew);
+        _rcInvalid |= rcInvalidNew;
 
         // Ensure invalid areas remain within bounds of window.
         RETURN_IF_FAILED(_InvalidRestrict());
@@ -185,10 +175,10 @@ HRESULT GdiEngine::_InvalidOffset(const POINT* const ppt) noexcept
 HRESULT GdiEngine::_InvalidRestrict() noexcept
 {
     // Ensure that the invalid area remains within the bounds of the client area
-    RECT rcClient;
+    til::rect rcClient;
 
     // Do restriction only if retrieving the client rect was successful.
-    RETURN_HR_IF(E_FAIL, !(GetClientRect(_hwndTargetWindow, &rcClient)));
+    RETURN_HR_IF(E_FAIL, !(GetClientRect(_hwndTargetWindow, rcClient.as_win32_rect())));
 
     _rcInvalid.left = std::clamp(_rcInvalid.left, rcClient.left, rcClient.right);
     _rcInvalid.right = std::clamp(_rcInvalid.right, rcClient.left, rcClient.right);
@@ -204,7 +194,7 @@ HRESULT GdiEngine::_InvalidRestrict() noexcept
 // - prc - Pointer to pixel rectangle representing invalid area to add to next paint frame
 // Return Value:
 // - S_OK, GDI related failure, or safemath failure.
-HRESULT GdiEngine::_InvalidateRect(const RECT* const prc) noexcept
+HRESULT GdiEngine::_InvalidateRect(const til::rect* const prc) noexcept
 {
     RETURN_HR(_InvalidCombine(prc));
 }
diff --git a/src/renderer/gdi/math.cpp b/src/renderer/gdi/math.cpp
index 0a5d8f5333d..16824c0d2ef 100644
--- a/src/renderer/gdi/math.cpp
+++ b/src/renderer/gdi/math.cpp
@@ -18,12 +18,7 @@ using namespace Microsoft::Console::Render;
 // - S_OK or math failure
 [[nodiscard]] HRESULT GdiEngine::GetDirtyArea(gsl::span<const til::rect>& area) noexcept
 {
-    auto rc = _psInvalidData.rcPaint;
-
-    SMALL_RECT sr = { 0 };
-    RETURN_IF_FAILED(_ScaleByFont(&rc, &sr));
-
-    _invalidCharacters = til::rect{ sr };
+    _invalidCharacters = til::rect{ _psInvalidData.rcPaint }.scale_down(_GetFontSize());
 
     area = { &_invalidCharacters, 1 };
 
@@ -75,115 +70,6 @@ using namespace Microsoft::Console::Render;
     return S_OK;
 }
 
-// Routine Description:
-// - Scales a character region (SMALL_RECT) into a pixel region (RECT) by the current font size.
-// Arguments:
-// - psr = Character region (SMALL_RECT) from the console text buffer.
-// - prc - Pixel region (RECT) for drawing to the client surface.
-// Return Value:
-// - S_OK or safe math failure value.
-[[nodiscard]] HRESULT GdiEngine::_ScaleByFont(const SMALL_RECT* const psr, _Out_ RECT* const prc) const noexcept
-{
-    const auto coordFontSize = _GetFontSize();
-    RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), coordFontSize.X == 0 || coordFontSize.Y == 0);
-
-    RECT rc;
-    RETURN_IF_FAILED(LongMult(psr->Left, coordFontSize.X, &rc.left));
-    RETURN_IF_FAILED(LongMult(psr->Right, coordFontSize.X, &rc.right));
-    RETURN_IF_FAILED(LongMult(psr->Top, coordFontSize.Y, &rc.top));
-    RETURN_IF_FAILED(LongMult(psr->Bottom, coordFontSize.Y, &rc.bottom));
-
-    *prc = rc;
-
-    return S_OK;
-}
-
-// Routine Description:
-// - Scales a character coordinate (COORD) into a pixel coordinate (POINT) by the current font size.
-// Arguments:
-// - pcoord - Character coordinate (COORD) from the console text buffer.
-// - ppt - Pixel coordinate (POINT) for drawing to the client surface.
-// Return Value:
-// - S_OK or safe math failure value.
-[[nodiscard]] HRESULT GdiEngine::_ScaleByFont(const COORD* const pcoord, _Out_ POINT* const pPoint) const noexcept
-{
-    const auto coordFontSize = _GetFontSize();
-    RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), coordFontSize.X == 0 || coordFontSize.Y == 0);
-
-    POINT pt;
-    RETURN_IF_FAILED(LongMult(pcoord->X, coordFontSize.X, &pt.x));
-    RETURN_IF_FAILED(LongMult(pcoord->Y, coordFontSize.Y, &pt.y));
-
-    *pPoint = pt;
-
-    return S_OK;
-}
-
-// Routine Description:
-// - Scales a pixel region (RECT) into a character region (SMALL_RECT) by the current font size.
-// Arguments:
-// - prc - Pixel region (RECT) from drawing to the client surface.
-// - psr - Character region (SMALL_RECT) from the console text buffer.
-// Return Value:
-// - S_OK or safe math failure value.
-[[nodiscard]] HRESULT GdiEngine::_ScaleByFont(const RECT* const prc, _Out_ SMALL_RECT* const psr) const noexcept
-{
-    const auto coordFontSize = _GetFontSize();
-    RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), coordFontSize.X == 0 || coordFontSize.Y == 0);
-
-    SMALL_RECT sr;
-    sr.Left = static_cast<SHORT>(prc->left / coordFontSize.X);
-    sr.Top = static_cast<SHORT>(prc->top / coordFontSize.Y);
-
-    // We're dividing integers so we're always going to round down to the next whole number on division.
-    // To make sure that when we round down, we remain an exclusive rectangle, we need to add the width (or height) - 1 before
-    // dividing such that a 1 px size rectangle will become a 1 ch size character.
-    // For example:
-    // L = 1px, R = 2px. Font Width = 8. What we want to see is a character rect that will only draw the 0th character (0 to 1).
-    // A. Simple divide
-    // 1px / 8px = 0ch for the Left measurement.
-    // 2px / 8px = 0ch for the Right which would be inclusive not exclusive.
-    // A Conclusion = doesn't work.
-    // B. Add a character
-    // 1px / 8px = 0ch for the Left measurement.
-    // (2px + 8px) / 8px = 1ch for the Right which seems alright.
-    // B Conclusion = plausible, but see C for why not.
-    // C. Add one pixel less than a full character, but this time R = 8px (which in exclusive terms still only addresses 1 character of pixels.)
-    // 1px / 8px = 0ch for the Left measurement.
-    // (8px + 8px) / 8px = 2ch for the Right measurement. Now we're redrawing 2 chars when we only needed to do one because this caused us to effectively round up.
-    // C Conclusion = this works because our addition can never completely push us over to adding an additional ch to the rectangle.
-    // So the algorithm below is using the C conclusion's math.
-
-    // Do math as long and fit to short at the end.
-    auto lRight = prc->right;
-    auto lBottom = prc->bottom;
-
-    // Add the width of a font (in pixels) to the rect
-    RETURN_IF_FAILED(LongAdd(lRight, coordFontSize.X, &lRight));
-    RETURN_IF_FAILED(LongAdd(lBottom, coordFontSize.Y, &lBottom));
-
-    // Subtract 1 to ensure that we round down.
-    RETURN_IF_FAILED(LongSub(lRight, 1, &lRight));
-    RETURN_IF_FAILED(LongSub(lBottom, 1, &lBottom));
-
-    // Divide by font size to see how many rows/columns
-    // note: no safe math for div.
-    lRight /= coordFontSize.X;
-    lBottom /= coordFontSize.Y;
-
-    // Attempt to fit into SMALL_RECT's short variable.
-    RETURN_IF_FAILED(LongToShort(lRight, &sr.Right));
-    RETURN_IF_FAILED(LongToShort(lBottom, &sr.Bottom));
-
-    // Pixels are exclusive and character rects are inclusive. Subtract 1 to go from exclusive to inclusive rect.
-    RETURN_IF_FAILED(ShortSub(sr.Right, 1, &sr.Right));
-    RETURN_IF_FAILED(ShortSub(sr.Bottom, 1, &sr.Bottom));
-
-    *psr = sr;
-
-    return S_OK;
-}
-
 // Routine Description:
 // - Scales the given pixel measurement up from the typical system DPI (generally 96) to whatever the given DPI is.
 // Arguments:
@@ -214,9 +100,9 @@ int GdiEngine::s_ShrinkByDpi(const int iPx, const int iDpi)
 // - <none>
 // Return Value:
 // - Top left corner in pixels of where to start repainting the frame.
-POINT GdiEngine::_GetInvalidRectPoint() const
+til::point GdiEngine::_GetInvalidRectPoint() const
 {
-    POINT pt;
+    til::point pt;
     pt.x = _psInvalidData.rcPaint.left;
     pt.y = _psInvalidData.rcPaint.top;
 
@@ -229,20 +115,20 @@ POINT GdiEngine::_GetInvalidRectPoint() const
 // - <none>
 // Return Value:
 // - Width and height in pixels of the invalid area of the frame.
-SIZE GdiEngine::_GetInvalidRectSize() const
+til::size GdiEngine::_GetInvalidRectSize() const
 {
     return _GetRectSize(&_psInvalidData.rcPaint);
 }
 
 // Routine Description:
-// - Converts a pixel region (RECT) into its width/height (SIZE)
+// - Converts a pixel region (til::rect) into its width/height (til::size)
 // Arguments:
-// - Pixel region (RECT)
+// - Pixel region (til::rect)
 // Return Value:
-// - Pixel dimensions (SIZE)
-SIZE GdiEngine::_GetRectSize(const RECT* const pRect) const
+// - Pixel dimensions (til::size)
+til::size GdiEngine::_GetRectSize(const RECT* const pRect) const
 {
-    SIZE sz;
+    til::size sz;
     sz.cx = pRect->right - pRect->left;
     sz.cy = pRect->bottom - pRect->top;
 
@@ -257,7 +143,7 @@ SIZE GdiEngine::_GetRectSize(const RECT* const pRect) const
 // - pRectToOr - Add this rectangle to the existing one.
 // Return Value:
 // - <none>
-void GdiEngine::_OrRect(_In_ RECT* const pRectExisting, const RECT* const pRectToOr) const
+void GdiEngine::_OrRect(_In_ til::rect* pRectExisting, const til::rect* pRectToOr) const
 {
     pRectExisting->left = std::min(pRectExisting->left, pRectToOr->left);
     pRectExisting->top = std::min(pRectExisting->top, pRectToOr->top);
diff --git a/src/renderer/gdi/paint.cpp b/src/renderer/gdi/paint.cpp
index a3fe90780f9..ab4a38383fa 100644
--- a/src/renderer/gdi/paint.cpp
+++ b/src/renderer/gdi/paint.cpp
@@ -57,7 +57,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
     _fPaintStarted = true;
 
     _psInvalidData.fErase = TRUE;
-    _psInvalidData.rcPaint = _rcInvalid;
+    _psInvalidData.rcPaint = _rcInvalid.to_win32_rect();
 
 #if DBG
     _debugContext = GetDC(_debugWindow);
@@ -95,7 +95,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
             LOG_HR_IF(E_FAIL, !SetWorldTransform(_psInvalidData.hdc, &cursorInvertTransform));
         }
 
-        for (auto r : cursorInvertRects)
+        for (const auto& r : cursorInvertRects)
         {
             // Clean both the in-memory and actual window context.
             LOG_HR_IF(E_FAIL, !(InvertRect(_hdcMemoryContext, &r)));
@@ -117,11 +117,11 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
     const auto coordFontSize = _GetFontSize();
     RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), coordFontSize.X == 0 || coordFontSize.Y == 0);
 
-    SIZE szGutter;
+    til::size szGutter;
     szGutter.cx = _szMemorySurface.cx % coordFontSize.X;
     szGutter.cy = _szMemorySurface.cy % coordFontSize.Y;
 
-    RECT rcScrollLimit = { 0 };
+    RECT rcScrollLimit;
     RETURN_IF_FAILED(LongSub(_szMemorySurface.cx, szGutter.cx, &rcScrollLimit.right));
     RETURN_IF_FAILED(LongSub(_szMemorySurface.cy, szGutter.cy, &rcScrollLimit.bottom));
 
@@ -135,13 +135,13 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
                                       nullptr,
                                       0));
 
-    RECT rcUpdate = { 0 };
-    LOG_HR_IF(E_FAIL, !(ScrollDC(_hdcMemoryContext, _szInvalidScroll.cx, _szInvalidScroll.cy, &rcScrollLimit, &rcScrollLimit, nullptr, &rcUpdate)));
+    til::rect rcUpdate;
+    LOG_HR_IF(E_FAIL, !(ScrollDC(_hdcMemoryContext, _szInvalidScroll.cx, _szInvalidScroll.cy, &rcScrollLimit, &rcScrollLimit, nullptr, rcUpdate.as_win32_rect())));
 
     LOG_IF_FAILED(_InvalidCombine(&rcUpdate));
 
     // update invalid rect for the remainder of paint functions
-    _psInvalidData.rcPaint = _rcInvalid;
+    _psInvalidData.rcPaint = _rcInvalid.to_win32_rect();
 
     return S_OK;
 }
@@ -231,9 +231,9 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
     LOG_HR_IF(E_FAIL, !(BitBlt(_psInvalidData.hdc, pt.x, pt.y, sz.cx, sz.cy, _hdcMemoryContext, pt.x, pt.y, SRCCOPY)));
     WHEN_DBG(_DebugBltAll());
 
-    _rcInvalid = { 0 };
+    _rcInvalid = {};
     _fInvalidRectUsed = false;
-    _szInvalidScroll = { 0 };
+    _szInvalidScroll = {};
 
     LOG_HR_IF(E_FAIL, !(GdiFlush()));
     LOG_HR_IF(E_FAIL, !(ReleaseDC(_hwndTargetWindow, _psInvalidData.hdc)));
@@ -323,7 +323,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
 //#define CONSOLE_EXTTEXTOUT_FLAGS ETO_OPAQUE | ETO_CLIPPED
 //#define MAX_POLY_LINES 80
 [[nodiscard]] HRESULT GdiEngine::PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                                 const COORD coord,
+                                                 const til::point coord,
                                                  const bool trimLeft,
                                                  const bool /*lineWrapped*/) noexcept
 {
@@ -334,8 +334,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
         // Exit early if there are no lines to draw.
         RETURN_HR_IF(S_OK, 0 == cchLine);
 
-        POINT ptDraw = { 0 };
-        RETURN_IF_FAILED(_ScaleByFont(&coord, &ptDraw));
+        const auto ptDraw = coord * _GetFontSize();
 
         const auto pPolyTextLine = &_pPolyText[_cPolyText];
 
@@ -419,7 +418,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
         pPolyTextLine->uiFlags = ETO_OPAQUE | ETO_CLIPPED;
         pPolyTextLine->rcl.left = pPolyTextLine->x;
         pPolyTextLine->rcl.top = pPolyTextLine->y + topOffset;
-        pPolyTextLine->rcl.right = pPolyTextLine->rcl.left + (SHORT)cchCharWidths;
+        pPolyTextLine->rcl.right = pPolyTextLine->rcl.left + (til::CoordType)cchCharWidths;
         pPolyTextLine->rcl.bottom = pPolyTextLine->y + coordFontSize.Y - bottomOffset;
         pPolyTextLine->pdx = polyWidth.data();
 
@@ -515,13 +514,12 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
 // - coordTarget - The starting X/Y position of the first character to draw on.
 // Return Value:
 // - S_OK or suitable GDI HRESULT error or E_FAIL for GDI errors in functions that don't reliably return a specific error code.
-[[nodiscard]] HRESULT GdiEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const COORD coordTarget) noexcept
+[[nodiscard]] HRESULT GdiEngine::PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const til::point coordTarget) noexcept
 {
     LOG_IF_FAILED(_FlushBufferLines());
 
     // Convert the target from characters to pixels.
-    POINT ptTarget;
-    RETURN_IF_FAILED(_ScaleByFont(&coordTarget, &ptTarget));
+    const auto ptTarget = coordTarget * _GetFontSize();
     // Set the brush color as requested and save the previous brush to restore at the end.
     wil::unique_hbrush hbr(CreateSolidBrush(color));
     RETURN_HR_IF_NULL(E_FAIL, hbr.get());
@@ -617,15 +615,15 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
 
     // First set up a block cursor the size of the font.
     RECT rcBoundaries;
-    RETURN_IF_FAILED(LongMult(options.coordCursor.X, coordFontSize.X, &rcBoundaries.left));
-    RETURN_IF_FAILED(LongMult(options.coordCursor.Y, coordFontSize.Y, &rcBoundaries.top));
-    RETURN_IF_FAILED(LongAdd(rcBoundaries.left, coordFontSize.X, &rcBoundaries.right));
-    RETURN_IF_FAILED(LongAdd(rcBoundaries.top, coordFontSize.Y, &rcBoundaries.bottom));
+    rcBoundaries.left = options.coordCursor.X * coordFontSize.X;
+    rcBoundaries.top = options.coordCursor.Y * coordFontSize.Y;
+    rcBoundaries.right = rcBoundaries.left + coordFontSize.X;
+    rcBoundaries.bottom = rcBoundaries.top + coordFontSize.Y;
 
     // If we're double-width cursor, make it an extra font wider.
     if (options.fIsDoubleWidth)
     {
-        RETURN_IF_FAILED(LongAdd(rcBoundaries.right, coordFontSize.X, &rcBoundaries.right));
+        rcBoundaries.right = rcBoundaries.right + coordFontSize.X;
     }
 
     // Make a set of RECTs to paint.
@@ -646,7 +644,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
         ulHeight = MulDiv(coordFontSize.Y, ulHeight, 100); // divide by 100 because percent.
 
         // Reduce the height of the top to be relative to the bottom by the height we want.
-        RETURN_IF_FAILED(LongSub(rcInvert.bottom, ulHeight, &rcInvert.top));
+        rcInvert.top = rcInvert.bottom - ulHeight;
 
         cursorInvertRects.push_back(rcInvert);
     }
@@ -654,7 +652,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
 
     case CursorType::VerticalBar:
         LONG proposedWidth;
-        RETURN_IF_FAILED(LongAdd(rcInvert.left, options.cursorPixelWidth, &proposedWidth));
+        proposedWidth = rcInvert.left + options.cursorPixelWidth;
         // 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.
@@ -663,7 +661,7 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
         break;
 
     case CursorType::Underscore:
-        RETURN_IF_FAILED(LongAdd(rcInvert.bottom, -1, &rcInvert.top));
+        rcInvert.top = rcInvert.bottom + -1;
         cursorInvertRects.push_back(rcInvert);
         break;
 
@@ -671,9 +669,9 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
     {
         RECT top, bottom;
         top = bottom = rcBoundaries;
-        RETURN_IF_FAILED(LongAdd(bottom.bottom, -1, &bottom.top));
-        RETURN_IF_FAILED(LongAdd(top.bottom, -3, &top.top));
-        RETURN_IF_FAILED(LongAdd(top.top, 1, &top.bottom));
+        bottom.top = bottom.bottom + -1;
+        top.top = top.bottom + -3;
+        top.bottom = top.top + 1;
 
         cursorInvertRects.push_back(top);
         cursorInvertRects.push_back(bottom);
@@ -684,15 +682,15 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
     {
         RECT top, left, right, bottom;
         top = left = right = bottom = rcBoundaries;
-        RETURN_IF_FAILED(LongAdd(top.top, 1, &top.bottom));
-        RETURN_IF_FAILED(LongAdd(bottom.bottom, -1, &bottom.top));
-        RETURN_IF_FAILED(LongAdd(left.left, 1, &left.right));
-        RETURN_IF_FAILED(LongAdd(right.right, -1, &right.left));
+        top.bottom = top.top + 1;
+        bottom.top = bottom.bottom + -1;
+        left.right = left.left + 1;
+        right.left = right.right + -1;
 
-        RETURN_IF_FAILED(LongAdd(top.left, 1, &top.left));
-        RETURN_IF_FAILED(LongAdd(bottom.left, 1, &bottom.left));
-        RETURN_IF_FAILED(LongAdd(top.right, -1, &top.right));
-        RETURN_IF_FAILED(LongAdd(bottom.right, -1, &bottom.right));
+        top.left = top.left + 1;
+        bottom.left = bottom.left + 1;
+        top.right = top.right + -1;
+        bottom.right = bottom.right + -1;
 
         cursorInvertRects.push_back(top);
         cursorInvertRects.push_back(left);
@@ -750,12 +748,11 @@ bool GdiEngine::FontHasWesternScript(HDC hdc)
 //  - rect - Rectangle to invert or highlight to make the selection area
 // Return Value:
 // - S_OK or suitable GDI HRESULT error.
-[[nodiscard]] HRESULT GdiEngine::PaintSelection(const SMALL_RECT rect) noexcept
+[[nodiscard]] HRESULT GdiEngine::PaintSelection(const til::rect& rect) noexcept
 {
     LOG_IF_FAILED(_FlushBufferLines());
 
-    RECT pixelRect = { 0 };
-    RETURN_IF_FAILED(_ScaleByFont(&rect, &pixelRect));
+    const auto pixelRect = rect.scale_up(_GetFontSize()).to_win32_rect();
 
     RETURN_HR_IF(E_FAIL, !InvertRect(_hdcMemoryContext, &pixelRect));
 
diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp
index 166a95e0a3f..ced04328a0d 100644
--- a/src/renderer/gdi/state.cpp
+++ b/src/renderer/gdi/state.cpp
@@ -41,9 +41,6 @@ GdiEngine::GdiEngine() :
     _polyWidths{ &_pool }
 {
     ZeroMemory(_pPolyText, sizeof(POLYTEXTW) * s_cPolyTextCache);
-    _rcInvalid = { 0 };
-    _szInvalidScroll = { 0 };
-    _szMemorySurface = { 0 };
 
     _hdcMemoryContext = CreateCompatibleDC(nullptr);
     THROW_HR_IF_NULL(E_FAIL, _hdcMemoryContext);
@@ -150,7 +147,7 @@ GdiEngine::~GdiEngine()
 #if DBG
     if (_debugWindow != INVALID_HANDLE_VALUE && _debugWindow != nullptr)
     {
-        RECT rc = { 0 };
+        RECT rc;
         THROW_IF_WIN32_BOOL_FALSE(GetWindowRect(_hwndTargetWindow, &rc));
 
         THROW_IF_WIN32_BOOL_FALSE(SetWindowPos(_debugWindow, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE));
@@ -428,7 +425,7 @@ GdiEngine::~GdiEngine()
     _fontCodepage = Font.GetCodePage();
 
     // Inform the soft font of the change in size.
-    _softFont.SetTargetSize(til::size{ _GetFontSize() });
+    _softFont.SetTargetSize(_GetFontSize());
 
     LOG_IF_FAILED(InvalidateAll());
 
@@ -444,7 +441,7 @@ GdiEngine::~GdiEngine()
 // Return Value:
 // - S_OK if successful. E_FAIL if there was an error.
 [[nodiscard]] HRESULT GdiEngine::UpdateSoftFont(const gsl::span<const uint16_t> bitPattern,
-                                                const SIZE cellSize,
+                                                const til::size cellSize,
                                                 const size_t centeringHint) noexcept
 {
     // If we previously called SelectFont(_hdcMemoryContext, _softFont), it will
@@ -457,7 +454,7 @@ GdiEngine::~GdiEngine()
     }
 
     // Create a new font resource with the updated pattern, or delete if empty.
-    _softFont = FontResource{ bitPattern, til::size{ cellSize }, til::size{ _GetFontSize() }, centeringHint };
+    _softFont = FontResource{ bitPattern, cellSize, _GetFontSize(), centeringHint };
 
     return S_OK;
 }
@@ -481,7 +478,7 @@ GdiEngine::~GdiEngine()
 // - srNewViewport - The bounds of the new viewport.
 // Return Value:
 // - HRESULT S_OK
-[[nodiscard]] HRESULT GdiEngine::UpdateViewport(const SMALL_RECT /*srNewViewport*/) noexcept
+[[nodiscard]] HRESULT GdiEngine::UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept
 {
     return S_OK;
 }
@@ -629,9 +626,9 @@ GdiEngine::~GdiEngine()
     SIZE sz;
     RETURN_HR_IF(E_FAIL, !(GetTextExtentPoint32W(hdcTemp.get(), L"0", 1, &sz)));
 
-    COORD coordFont;
-    coordFont.X = static_cast<SHORT>(sz.cx);
-    coordFont.Y = static_cast<SHORT>(sz.cy);
+    til::size coordFont;
+    coordFont.X = sz.cx;
+    coordFont.Y = sz.cy;
 
     // The extent point won't necessarily be perfect for the width, so get the ABC metrics for the 0 if possible to improve the measurement.
     // This will fail for non-TrueType fonts and we'll fall back to what GetTextExtentPoint said.
@@ -639,12 +636,12 @@ GdiEngine::~GdiEngine()
         ABC abc;
         if (0 != GetCharABCWidthsW(hdcTemp.get(), '0', '0', &abc))
         {
-            const int abcTotal = abc.abcA + abc.abcB + abc.abcC;
+            const auto abcTotal = abc.abcA + abc.abcB + abc.abcC;
 
             // No negatives or zeros or we'll have bad character-to-pixel math later.
             if (abcTotal > 0)
             {
-                coordFont.X = static_cast<SHORT>(abcTotal);
+                coordFont.X = abcTotal;
             }
         }
     }
@@ -667,7 +664,7 @@ GdiEngine::~GdiEngine()
         }
         else if (coordFontRequested.X == 0)
         {
-            coordFontRequested.X = (SHORT)s_ShrinkByDpi(coordFont.X, iDpi);
+            coordFontRequested.X = s_ShrinkByDpi(coordFont.X, iDpi);
         }
 
         Font.SetFromEngine(currentFaceName,
@@ -687,7 +684,7 @@ GdiEngine::~GdiEngine()
 // - pFontSize - receives the current X by Y size of the font.
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT GdiEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
+[[nodiscard]] HRESULT GdiEngine::GetFontSize(_Out_ til::size* pFontSize) noexcept
 {
     *pFontSize = _GetFontSize();
     return S_OK;
@@ -699,7 +696,7 @@ GdiEngine::~GdiEngine()
 // - <none>
 // Return Value:
 // - X by Y size of the font.
-COORD GdiEngine::_GetFontSize() const
+til::size GdiEngine::_GetFontSize() const
 {
     return _coordFontLast;
 }
diff --git a/src/renderer/inc/Cluster.hpp b/src/renderer/inc/Cluster.hpp
index 094aadc0c21..52ff70f95d3 100644
--- a/src/renderer/inc/Cluster.hpp
+++ b/src/renderer/inc/Cluster.hpp
@@ -24,7 +24,7 @@ namespace Microsoft::Console::Render
     {
     public:
         constexpr Cluster() noexcept = default;
-        constexpr Cluster(const std::wstring_view text, const size_t columns) noexcept :
+        constexpr Cluster(const std::wstring_view text, const til::CoordType columns) noexcept :
             _text{ text },
             _columns{ columns }
         {
@@ -52,7 +52,7 @@ namespace Microsoft::Console::Render
 
         // Gets the number of columns in the grid that this character should consume
         // visually when rendered onto a line.
-        constexpr size_t GetColumns() const noexcept
+        constexpr til::CoordType GetColumns() const noexcept
         {
             return _columns;
         }
@@ -62,6 +62,6 @@ namespace Microsoft::Console::Render
         std::wstring_view _text;
 
         // This is how many columns we're expecting this cluster to take in the display grid
-        size_t _columns = 0;
+        til::CoordType _columns = 0;
     };
 }
diff --git a/src/renderer/inc/CursorOptions.h b/src/renderer/inc/CursorOptions.h
index 4fa5c6b899b..d3c766c7b54 100644
--- a/src/renderer/inc/CursorOptions.h
+++ b/src/renderer/inc/CursorOptions.h
@@ -23,10 +23,10 @@ namespace Microsoft::Console::Render
     {
         // Character cell in the grid to draw at
         // This is relative to the top of the viewport, not the buffer
-        COORD coordCursor;
+        til::point coordCursor;
 
         // Left offset of the viewport, which may alter the horizontal position
-        SHORT viewportLeft;
+        til::CoordType viewportLeft;
 
         // Line rendition of the current row, which can affect the cursor width
         LineRendition lineRendition;
diff --git a/src/renderer/inc/FontInfo.hpp b/src/renderer/inc/FontInfo.hpp
index 2b5ee35640a..8986c04284b 100644
--- a/src/renderer/inc/FontInfo.hpp
+++ b/src/renderer/inc/FontInfo.hpp
@@ -31,20 +31,20 @@ class FontInfo : public FontInfoBase
     FontInfo(const std::wstring_view& faceName,
              const unsigned char family,
              const unsigned int weight,
-             const COORD coordSize,
+             const til::size coordSize,
              const unsigned int codePage,
              const bool fSetDefaultRasterFont = false) noexcept;
 
     bool operator==(const FontInfo& other) noexcept;
 
-    COORD GetSize() const noexcept;
-    COORD GetUnscaledSize() const noexcept;
+    til::size GetSize() const noexcept;
+    til::size 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;
+                       const til::size coordSize,
+                       const til::size coordSizeUnscaled) noexcept;
     bool GetFallback() const noexcept;
     void SetFallback(const bool didFallback) noexcept;
     void ValidateFont() noexcept;
@@ -52,7 +52,7 @@ class FontInfo : public FontInfoBase
 private:
     void _ValidateCoordSize() noexcept;
 
-    COORD _coordSize;
-    COORD _coordSizeUnscaled;
+    til::size _coordSize;
+    til::size _coordSizeUnscaled;
     bool _didFallback;
 };
diff --git a/src/renderer/inc/FontInfoDesired.hpp b/src/renderer/inc/FontInfoDesired.hpp
index 44e5858192e..f4085629202 100644
--- a/src/renderer/inc/FontInfoDesired.hpp
+++ b/src/renderer/inc/FontInfoDesired.hpp
@@ -27,15 +27,15 @@ class FontInfoDesired : public FontInfoBase
     FontInfoDesired(const std::wstring_view& faceName,
                     const unsigned char family,
                     const unsigned int weight,
-                    const COORD coordSizeDesired,
+                    const til::size coordSizeDesired,
                     const unsigned int uiCodePage) noexcept;
     FontInfoDesired(const FontInfo& fiFont) noexcept;
 
     bool operator==(const FontInfoDesired& other) noexcept;
 
-    COORD GetEngineSize() const noexcept;
+    til::size GetEngineSize() const noexcept;
     bool IsDefaultRasterFont() const noexcept;
 
 private:
-    COORD _coordSizeDesired;
+    til::size _coordSizeDesired;
 };
diff --git a/src/renderer/inc/IRenderData.hpp b/src/renderer/inc/IRenderData.hpp
index 722c31528ff..d86b3cf1788 100644
--- a/src/renderer/inc/IRenderData.hpp
+++ b/src/renderer/inc/IRenderData.hpp
@@ -29,7 +29,7 @@ namespace Microsoft::Console::Render
 
         // This is where the top left of the stored buffer should be overlaid on the screen
         // (relative to the current visible viewport)
-        const COORD origin;
+        const til::point origin;
 
         // This is the area of the buffer that is actually used for overlay.
         // Anything outside of this is considered empty by the overlay and shouldn't be used
@@ -46,7 +46,7 @@ namespace Microsoft::Console::Render
         IRenderData& operator=(const IRenderData&) = default;
         IRenderData& operator=(IRenderData&&) = default;
 
-        virtual COORD GetCursorPosition() const noexcept = 0;
+        virtual til::point GetCursorPosition() const noexcept = 0;
         virtual bool IsCursorVisible() const noexcept = 0;
         virtual bool IsCursorOn() const noexcept = 0;
         virtual ULONG GetCursorHeight() const noexcept = 0;
@@ -62,7 +62,7 @@ namespace Microsoft::Console::Render
         virtual const std::wstring GetHyperlinkUri(uint16_t id) const noexcept = 0;
         virtual const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept = 0;
 
-        virtual const std::vector<size_t> GetPatternId(const COORD location) const noexcept = 0;
+        virtual const std::vector<size_t> GetPatternId(const til::point location) const noexcept = 0;
 
     protected:
         IRenderData() = default;
diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp
index 3bd45e7e734..259b432594f 100644
--- a/src/renderer/inc/IRenderEngine.hpp
+++ b/src/renderer/inc/IRenderEngine.hpp
@@ -61,11 +61,11 @@ namespace Microsoft::Console::Render
         [[nodiscard]] virtual HRESULT Present() noexcept = 0;
         [[nodiscard]] virtual HRESULT PrepareForTeardown(_Out_ bool* pForcePaint) noexcept = 0;
         [[nodiscard]] virtual HRESULT ScrollFrame() noexcept = 0;
-        [[nodiscard]] virtual HRESULT Invalidate(const SMALL_RECT* psrRegion) noexcept = 0;
-        [[nodiscard]] virtual HRESULT InvalidateCursor(const SMALL_RECT* psrRegion) noexcept = 0;
-        [[nodiscard]] virtual HRESULT InvalidateSystem(const RECT* prcDirtyClient) noexcept = 0;
-        [[nodiscard]] virtual HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept = 0;
-        [[nodiscard]] virtual HRESULT InvalidateScroll(const COORD* pcoordDelta) noexcept = 0;
+        [[nodiscard]] virtual HRESULT Invalidate(const til::rect* psrRegion) noexcept = 0;
+        [[nodiscard]] virtual HRESULT InvalidateCursor(const til::rect* psrRegion) noexcept = 0;
+        [[nodiscard]] virtual HRESULT InvalidateSystem(const til::rect* prcDirtyClient) noexcept = 0;
+        [[nodiscard]] virtual HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept = 0;
+        [[nodiscard]] virtual HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept = 0;
         [[nodiscard]] virtual HRESULT InvalidateAll() noexcept = 0;
         [[nodiscard]] virtual HRESULT InvalidateFlush(_In_ const bool circled, _Out_ bool* const pForcePaint) noexcept = 0;
         [[nodiscard]] virtual HRESULT InvalidateTitle(std::wstring_view proposedTitle) noexcept = 0;
@@ -74,18 +74,18 @@ namespace Microsoft::Console::Render
         [[nodiscard]] virtual HRESULT ResetLineTransform() noexcept = 0;
         [[nodiscard]] virtual HRESULT PrepareLineTransform(LineRendition lineRendition, size_t targetRow, size_t viewportLeft) noexcept = 0;
         [[nodiscard]] virtual HRESULT PaintBackground() noexcept = 0;
-        [[nodiscard]] virtual HRESULT PaintBufferLine(gsl::span<const Cluster> clusters, COORD coord, bool fTrimLeft, bool lineWrapped) noexcept = 0;
-        [[nodiscard]] virtual HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, COORD coordTarget) noexcept = 0;
-        [[nodiscard]] virtual HRESULT PaintSelection(SMALL_RECT rect) noexcept = 0;
+        [[nodiscard]] virtual HRESULT PaintBufferLine(gsl::span<const Cluster> clusters, til::point coord, bool fTrimLeft, bool lineWrapped) noexcept = 0;
+        [[nodiscard]] virtual HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, til::point coordTarget) noexcept = 0;
+        [[nodiscard]] virtual HRESULT PaintSelection(const til::rect& rect) noexcept = 0;
         [[nodiscard]] virtual HRESULT PaintCursor(const CursorOptions& options) noexcept = 0;
         [[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null<IRenderData*> pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept = 0;
         [[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept = 0;
-        [[nodiscard]] virtual HRESULT UpdateSoftFont(gsl::span<const uint16_t> bitPattern, SIZE cellSize, size_t centeringHint) noexcept = 0;
+        [[nodiscard]] virtual HRESULT UpdateSoftFont(gsl::span<const uint16_t> bitPattern, til::size cellSize, size_t centeringHint) noexcept = 0;
         [[nodiscard]] virtual HRESULT UpdateDpi(int iDpi) noexcept = 0;
-        [[nodiscard]] virtual HRESULT UpdateViewport(SMALL_RECT srNewViewport) noexcept = 0;
+        [[nodiscard]] virtual HRESULT UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept = 0;
         [[nodiscard]] virtual HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, int iDpi) noexcept = 0;
         [[nodiscard]] virtual HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept = 0;
-        [[nodiscard]] virtual HRESULT GetFontSize(_Out_ COORD* pFontSize) noexcept = 0;
+        [[nodiscard]] virtual HRESULT GetFontSize(_Out_ til::size* pFontSize) noexcept = 0;
         [[nodiscard]] virtual HRESULT IsGlyphWideByFont(std::wstring_view glyph, _Out_ bool* pResult) noexcept = 0;
         [[nodiscard]] virtual HRESULT UpdateTitle(std::wstring_view newTitle) noexcept = 0;
 
@@ -114,7 +114,7 @@ namespace Microsoft::Console::Render
         virtual void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept {}
         virtual void SetSoftwareRendering(bool enable) noexcept {}
         virtual void SetWarningCallback(std::function<void(HRESULT)> pfn) noexcept {}
-        virtual [[nodiscard]] HRESULT SetWindowSize(const SIZE pixels) noexcept { return E_NOTIMPL; }
+        virtual [[nodiscard]] HRESULT SetWindowSize(const til::size pixels) noexcept { return E_NOTIMPL; }
         virtual void ToggleShaderEffects() noexcept {}
         virtual [[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 { return E_NOTIMPL; }
         virtual void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept {}
diff --git a/src/renderer/inc/RenderEngineBase.hpp b/src/renderer/inc/RenderEngineBase.hpp
index da493207c63..28a29a5a721 100644
--- a/src/renderer/inc/RenderEngineBase.hpp
+++ b/src/renderer/inc/RenderEngineBase.hpp
@@ -31,7 +31,7 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT NotifyNewText(const std::wstring_view newText) noexcept override;
 
         [[nodiscard]] HRESULT UpdateSoftFont(const gsl::span<const uint16_t> bitPattern,
-                                             const SIZE cellSize,
+                                             const til::size cellSize,
                                              const size_t centeringHint) noexcept override;
 
         [[nodiscard]] HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept override;
diff --git a/src/renderer/uia/UiaRenderer.cpp b/src/renderer/uia/UiaRenderer.cpp
index 2eae4586374..2ac51ffccc6 100644
--- a/src/renderer/uia/UiaRenderer.cpp
+++ b/src/renderer/uia/UiaRenderer.cpp
@@ -54,10 +54,10 @@ UiaEngine::UiaEngine(IUiaEventDispatcher* dispatcher) :
 // - Notifies us that the console has changed the character region specified.
 // - NOTE: This typically triggers on cursor or text buffer changes
 // Arguments:
-// - psrRegion - Character region (SMALL_RECT) that has been changed
+// - psrRegion - Character region (til::rect) that has been changed
 // Return Value:
 // - S_OK, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT UiaEngine::Invalidate(const SMALL_RECT* const /*psrRegion*/) noexcept
+[[nodiscard]] HRESULT UiaEngine::Invalidate(const til::rect* const /*psrRegion*/) noexcept
 {
     _textBufferChanged = true;
     return S_OK;
@@ -70,7 +70,7 @@ UiaEngine::UiaEngine(IUiaEventDispatcher* dispatcher) :
 // - psrRegion - the region covered by the cursor
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT UiaEngine::InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT UiaEngine::InvalidateCursor(const til::rect* const psrRegion) noexcept
 try
 {
     RETURN_HR_IF_NULL(E_INVALIDARG, psrRegion);
@@ -92,7 +92,7 @@ CATCH_RETURN();
 // - prcDirtyClient - pixel rectangle
 // Return Value:
 // - S_FALSE
-[[nodiscard]] HRESULT UiaEngine::InvalidateSystem(const RECT* const /*prcDirtyClient*/) noexcept
+[[nodiscard]] HRESULT UiaEngine::InvalidateSystem(const til::rect* const /*prcDirtyClient*/) noexcept
 {
     return S_FALSE;
 }
@@ -104,7 +104,7 @@ CATCH_RETURN();
 // - rectangles - One or more rectangles describing character positions on the grid
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT UiaEngine::InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept
+[[nodiscard]] HRESULT UiaEngine::InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept
 {
     // early exit: different number of rows
     if (_prevSelection.size() != rectangles.size())
@@ -149,7 +149,7 @@ CATCH_RETURN();
 //               - -Y is up, Y is down, -X is left, X is right.
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT UiaEngine::InvalidateScroll(const COORD* const /*pcoordDelta*/) noexcept
+[[nodiscard]] HRESULT UiaEngine::InvalidateScroll(const til::point* const /*pcoordDelta*/) noexcept
 {
     return S_FALSE;
 }
@@ -334,7 +334,7 @@ void UiaEngine::WaitUntilCanRender() noexcept
 // Return Value:
 // - S_FALSE
 [[nodiscard]] HRESULT UiaEngine::PaintBufferLine(const gsl::span<const Cluster> /*clusters*/,
-                                                 const COORD /*coord*/,
+                                                 const til::point /*coord*/,
                                                  const bool /*trimLeft*/,
                                                  const bool /*lineWrapped*/) noexcept
 {
@@ -354,7 +354,7 @@ void UiaEngine::WaitUntilCanRender() noexcept
 [[nodiscard]] HRESULT UiaEngine::PaintBufferGridLines(GridLineSet const /*lines*/,
                                                       COLORREF const /*color*/,
                                                       size_t const /*cchLine*/,
-                                                      const COORD /*coordTarget*/) noexcept
+                                                      const til::point /*coordTarget*/) noexcept
 {
     return S_FALSE;
 }
@@ -368,7 +368,7 @@ void UiaEngine::WaitUntilCanRender() noexcept
 //  - rect - Rectangle to invert or highlight to make the selection area
 // Return Value:
 // - S_FALSE
-[[nodiscard]] HRESULT UiaEngine::PaintSelection(const SMALL_RECT /*rect*/) noexcept
+[[nodiscard]] HRESULT UiaEngine::PaintSelection(const til::rect& /*rect*/) noexcept
 {
     return S_FALSE;
 }
@@ -435,7 +435,7 @@ void UiaEngine::WaitUntilCanRender() noexcept
 // - srNewViewport - The bounds of the new viewport.
 // Return Value:
 // - HRESULT S_OK
-[[nodiscard]] HRESULT UiaEngine::UpdateViewport(const SMALL_RECT /*srNewViewport*/) noexcept
+[[nodiscard]] HRESULT UiaEngine::UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept
 {
     return S_FALSE;
 }
@@ -477,7 +477,7 @@ void UiaEngine::WaitUntilCanRender() noexcept
 // - pFontSize - Filled with the font size.
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT UiaEngine::GetFontSize(_Out_ COORD* const /*pFontSize*/) noexcept
+[[nodiscard]] HRESULT UiaEngine::GetFontSize(_Out_ til::size* const /*pFontSize*/) noexcept
 {
     return S_FALSE;
 }
diff --git a/src/renderer/uia/UiaRenderer.hpp b/src/renderer/uia/UiaRenderer.hpp
index aab0268f95a..16a6ae6630c 100644
--- a/src/renderer/uia/UiaRenderer.hpp
+++ b/src/renderer/uia/UiaRenderer.hpp
@@ -40,25 +40,25 @@ namespace Microsoft::Console::Render
         [[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 Invalidate(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* const prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* const pcoordDelta) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT NotifyNewText(const std::wstring_view newText) noexcept override;
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
-        [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters, const COORD coord, const bool fTrimLeft, const bool lineWrapped) noexcept override;
-        [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters, const til::point coord, const bool fTrimLeft, const bool lineWrapped) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF color, const size_t cchLine, const til::point coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
         [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, 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 UpdateViewport(const til::inclusive_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::rect>& area) noexcept override;
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* const pFontSize) noexcept override;
         [[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
 
     protected:
@@ -75,7 +75,7 @@ namespace Microsoft::Console::Render
 
         Microsoft::Console::Types::IUiaEventDispatcher* _dispatcher;
 
-        std::vector<SMALL_RECT> _prevSelection;
-        SMALL_RECT _prevCursorRegion;
+        std::vector<til::rect> _prevSelection;
+        til::rect _prevCursorRegion;
     };
 }
diff --git a/src/renderer/vt/VtSequences.cpp b/src/renderer/vt/VtSequences.cpp
index cb91f57f03f..d5d45a07d8b 100644
--- a/src/renderer/vt/VtSequences.cpp
+++ b/src/renderer/vt/VtSequences.cpp
@@ -81,7 +81,7 @@ using namespace Microsoft::Console::Render;
 // - chars: a number of characters to erase (by overwriting with space)
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_EraseCharacter(const short chars) noexcept
+[[nodiscard]] HRESULT VtEngine::_EraseCharacter(const til::CoordType chars) noexcept
 {
     return _WriteFormatted(FMT_COMPILE("\x1b[{}X"), chars);
 }
@@ -92,7 +92,7 @@ using namespace Microsoft::Console::Render;
 // - chars: a number of characters to move cursor right by.
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_CursorForward(const short chars) noexcept
+[[nodiscard]] HRESULT VtEngine::_CursorForward(const til::CoordType chars) noexcept
 {
     return _WriteFormatted(FMT_COMPILE("\x1b[{}C"), chars);
 }
@@ -122,7 +122,7 @@ using namespace Microsoft::Console::Render;
 // - fInsertLine: true iff we should insert the lines, false to delete them.
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_InsertDeleteLine(const short sLines, const bool fInsertLine) noexcept
+[[nodiscard]] HRESULT VtEngine::_InsertDeleteLine(const til::CoordType sLines, const bool fInsertLine) noexcept
 {
     if (sLines <= 0)
     {
@@ -143,7 +143,7 @@ using namespace Microsoft::Console::Render;
 // - sLines: a number of lines to insert
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_DeleteLine(const short sLines) noexcept
+[[nodiscard]] HRESULT VtEngine::_DeleteLine(const til::CoordType sLines) noexcept
 {
     return _InsertDeleteLine(sLines, false);
 }
@@ -155,7 +155,7 @@ using namespace Microsoft::Console::Render;
 // - sLines: a number of lines to insert
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_InsertLine(const short sLines) noexcept
+[[nodiscard]] HRESULT VtEngine::_InsertLine(const til::CoordType sLines) noexcept
 {
     return _InsertDeleteLine(sLines, true);
 }
@@ -168,7 +168,7 @@ using namespace Microsoft::Console::Render;
 // - coord: Console coordinates to move the cursor to.
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_CursorPosition(const COORD coord) noexcept
+[[nodiscard]] HRESULT VtEngine::_CursorPosition(const til::point coord) noexcept
 {
     // VT coords start at 1,1
     auto coordVt = coord;
@@ -277,7 +277,7 @@ using namespace Microsoft::Console::Render;
 // - sHeight: number of rows the terminal should display
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::_ResizeWindow(const short sWidth, const short sHeight) noexcept
+[[nodiscard]] HRESULT VtEngine::_ResizeWindow(const til::CoordType sWidth, const til::CoordType sHeight) noexcept
 {
     if (sWidth < 0 || sHeight < 0)
     {
diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp
index 5826d564f0a..6852706aa7c 100644
--- a/src/renderer/vt/XtermEngine.cpp
+++ b/src/renderer/vt/XtermEngine.cpp
@@ -39,7 +39,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
 {
     RETURN_IF_FAILED(VtEngine::StartPaint());
 
-    _trace.TraceLastText(til::point{ _lastText });
+    _trace.TraceLastText(_lastText);
 
     // Prep us to think that the cursor is not visible this frame. If it _is_
     // visible, then PaintCursor will be called, and we'll set this to true
@@ -73,12 +73,12 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
         RETURN_IF_FAILED(GetDirtyArea(dirty));
 
         // If we have 0 or 1 dirty pieces in the area, set as appropriate.
-        auto dirtyView = dirty.empty() ? Viewport::Empty() : Viewport::FromInclusive(til::at(dirty, 0).to_small_rect());
+        auto dirtyView = dirty.empty() ? Viewport::Empty() : Viewport::FromExclusive(til::at(dirty, 0));
 
         // If there's more than 1, union them all up with the 1 we already have.
         for (size_t i = 1; i < dirty.size(); ++i)
         {
-            dirtyView = Viewport::Union(dirtyView, Viewport::FromInclusive(til::at(dirty, i).to_small_rect()));
+            dirtyView = Viewport::Union(dirtyView, Viewport::FromExclusive(til::at(dirty, i)));
         }
     }
 
@@ -236,11 +236,11 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
 // - coord: location to move the cursor to.
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT XtermEngine::_MoveCursor(const COORD coord) noexcept
+[[nodiscard]] HRESULT XtermEngine::_MoveCursor(const til::point coord) noexcept
 {
     auto hr = S_OK;
     const auto originalPos = _lastText;
-    _trace.TraceMoveCursor(til::point{ _lastText }, til::point{ coord });
+    _trace.TraceMoveCursor(_lastText, coord);
     auto performedSoftWrap = false;
     if (coord.X != _lastText.X || coord.Y != _lastText.Y)
     {
@@ -312,7 +312,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
         else if (coord.Y == _lastText.Y && coord.X > _lastText.X)
         {
             // Same line, forward some distance
-            short distance = coord.X - _lastText.X;
+            auto distance = coord.X - _lastText.X;
             hr = _CursorForward(distance);
         }
         else
@@ -362,8 +362,8 @@ try
         return S_OK;
     }
 
-    const auto dy = _scrollDelta.narrow_y<short>();
-    const auto absDy = static_cast<short>(abs(dy));
+    const auto dy = _scrollDelta.y;
+    const auto absDy = abs(dy);
 
     // Save the old wrap state here. We're going to clear it so that
     // _MoveCursor will definitely move us to the right position. We'll
@@ -414,7 +414,7 @@ try
     // position we think we left the cursor.
     //
     // See GH#5113
-    _trace.TraceLastText(til::point{ _lastText });
+    _trace.TraceLastText(_lastText);
     if (_wrappedRow.has_value())
     {
         _wrappedRow.value() += dy;
@@ -466,14 +466,14 @@ CATCH_RETURN();
 //      area. Add the top or bottom rows to the invalid region, and update the
 //      total scroll delta accumulated this frame.
 // Arguments:
-// - pcoordDelta - Pointer to character dimension (COORD) of the distance the
+// - pcoordDelta - Pointer to character dimension (til::point) of the distance the
 //      console would like us to move while scrolling.
 // Return Value:
 // - S_OK if we succeeded, else an appropriate HRESULT for safemath failure
-[[nodiscard]] HRESULT XtermEngine::InvalidateScroll(const COORD* const pcoordDelta) noexcept
+[[nodiscard]] HRESULT XtermEngine::InvalidateScroll(const til::point* const pcoordDelta) noexcept
 try
 {
-    const til::point delta{ *pcoordDelta };
+    const auto delta{ *pcoordDelta };
 
     if (delta != til::point{ 0, 0 })
     {
@@ -505,7 +505,7 @@ CATCH_RETURN();
 // Return Value:
 // - S_OK or suitable HRESULT error from writing pipe.
 [[nodiscard]] HRESULT XtermEngine::PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                                   const COORD coord,
+                                                   const til::point coord,
                                                    const bool /*trimLeft*/,
                                                    const bool lineWrapped) noexcept
 {
diff --git a/src/renderer/vt/XtermEngine.hpp b/src/renderer/vt/XtermEngine.hpp
index 680851e57e0..c3a1af5f8b4 100644
--- a/src/renderer/vt/XtermEngine.hpp
+++ b/src/renderer/vt/XtermEngine.hpp
@@ -44,12 +44,12 @@ namespace Microsoft::Console::Render
                                                            const bool usingSoftFont,
                                                            const bool isSettingDefaultBrushes) noexcept override;
         [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                              const COORD coord,
+                                              const til::point coord,
                                               const bool trimLeft,
                                               const bool lineWrapped) noexcept override;
         [[nodiscard]] HRESULT ScrollFrame() noexcept override;
 
-        [[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* const pcoordDelta) noexcept override;
 
         [[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view str) noexcept override;
 
@@ -70,7 +70,7 @@ namespace Microsoft::Console::Render
         Tribool _lastCursorIsVisible;
         bool _nextCursorIsVisible;
 
-        [[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept override;
+        [[nodiscard]] HRESULT _MoveCursor(const til::point coord) noexcept override;
 
         [[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept override;
 
diff --git a/src/renderer/vt/invalidate.cpp b/src/renderer/vt/invalidate.cpp
index 86e21637845..08d2cf06f3e 100644
--- a/src/renderer/vt/invalidate.cpp
+++ b/src/renderer/vt/invalidate.cpp
@@ -15,11 +15,11 @@ using namespace Microsoft::Console::Render;
 //      client rectangle should be redrawn. (On WM_PAINT)
 //  For VT, this doesn't mean anything. So do nothing.
 // Arguments:
-// - prcDirtyClient - Pointer to pixel area (RECT) of client region the system
+// - prcDirtyClient - Pointer to pixel area (til::rect) of client region the system
 //      believes is dirty
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT VtEngine::InvalidateSystem(const RECT* const /*prcDirtyClient*/) noexcept
+[[nodiscard]] HRESULT VtEngine::InvalidateSystem(const til::rect* const /*prcDirtyClient*/) noexcept
 {
     return S_OK;
 }
@@ -31,7 +31,7 @@ using namespace Microsoft::Console::Render;
 // - rectangles - Vector of rectangles to draw, line by line
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT VtEngine::InvalidateSelection(const std::vector<SMALL_RECT>& /*rectangles*/) noexcept
+[[nodiscard]] HRESULT VtEngine::InvalidateSelection(const std::vector<til::rect>& /*rectangles*/) noexcept
 {
     // Selection shouldn't be handled bt the VT Renderer Host, it should be
     //      handled by the client.
@@ -43,15 +43,14 @@ using namespace Microsoft::Console::Render;
 // - Notifies us that the console has changed the character region specified.
 // - NOTE: This typically triggers on cursor or text buffer changes
 // Arguments:
-// - psrRegion - Character region (SMALL_RECT) that has been changed
+// - psrRegion - Character region (til::rect) that has been changed
 // Return Value:
 // - S_OK, else an appropriate HRESULT for failing to allocate or write.
-[[nodiscard]] HRESULT VtEngine::Invalidate(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT VtEngine::Invalidate(const til::rect* const psrRegion) noexcept
 try
 {
-    const til::rect rect{ Viewport::FromExclusive(*psrRegion).ToInclusive() };
-    _trace.TraceInvalidate(rect);
-    _invalidMap.set(rect);
+    _trace.TraceInvalidate(*psrRegion);
+    _invalidMap.set(*psrRegion);
     return S_OK;
 }
 CATCH_RETURN();
@@ -62,7 +61,7 @@ CATCH_RETURN();
 // - psrRegion - the region covered by the cursor
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT VtEngine::InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept
+[[nodiscard]] HRESULT VtEngine::InvalidateCursor(const til::rect* const psrRegion) noexcept
 {
     // If we just inherited the cursor, we're going to get an InvalidateCursor
     //      for both where the old cursor was, and where the new cursor is
@@ -91,7 +90,7 @@ CATCH_RETURN();
 [[nodiscard]] HRESULT VtEngine::InvalidateAll() noexcept
 try
 {
-    _trace.TraceInvalidateAll(til::rect{ _lastViewport.ToOrigin().ToInclusive() });
+    _trace.TraceInvalidateAll(_lastViewport.ToOrigin().ToExclusive());
     _invalidMap.set_all();
     return S_OK;
 }
diff --git a/src/renderer/vt/math.cpp b/src/renderer/vt/math.cpp
index 382953e3797..c608ad8fdda 100644
--- a/src/renderer/vt/math.cpp
+++ b/src/renderer/vt/math.cpp
@@ -45,7 +45,7 @@ using namespace Microsoft::Console::Types;
 // - pRectToOr - Add this rectangle to the existing one.
 // Return Value:
 // - <none>
-void VtEngine::_OrRect(_Inout_ SMALL_RECT* const pRectExisting, const SMALL_RECT* const pRectToOr) const
+void VtEngine::_OrRect(_Inout_ til::inclusive_rect* const pRectExisting, const til::inclusive_rect* const pRectToOr) const
 {
     pRectExisting->Left = std::min(pRectExisting->Left, pRectToOr->Left);
     pRectExisting->Top = std::min(pRectExisting->Top, pRectToOr->Top);
@@ -82,7 +82,7 @@ bool VtEngine::_WillWriteSingleChar() const
     // Either the next character to the right or the immediately previous
     //      character should follow this code path
     //      (The immediate previous character would suggest a backspace)
-    auto invalidIsNext = invalidPoint == til::point{ _lastText };
+    auto invalidIsNext = invalidPoint == _lastText;
     auto invalidIsLast = invalidPoint == til::point{ _lastText.X - 1, _lastText.Y };
 
     return invalidIsNext || invalidIsLast;
diff --git a/src/renderer/vt/paint.cpp b/src/renderer/vt/paint.cpp
index 1e026e356af..fade9487eb8 100644
--- a/src/renderer/vt/paint.cpp
+++ b/src/renderer/vt/paint.cpp
@@ -34,7 +34,7 @@ using namespace Microsoft::Console::Types;
     _quickReturn = !somethingToDo;
     _trace.TraceStartPaint(_quickReturn,
                            _invalidMap,
-                           til::rect{ _lastViewport.ToInclusive() },
+                           _lastViewport.ToExclusive(),
                            _scrollDelta,
                            _cursorMoved,
                            _wrappedRow);
@@ -126,7 +126,7 @@ using namespace Microsoft::Console::Types;
 // Return Value:
 // - S_OK or suitable HRESULT error from writing pipe.
 [[nodiscard]] HRESULT VtEngine::PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                                const COORD coord,
+                                                const til::point coord,
                                                 const bool /*trimLeft*/,
                                                 const bool /*lineWrapped*/) noexcept
 {
@@ -145,7 +145,7 @@ using namespace Microsoft::Console::Types;
 [[nodiscard]] HRESULT VtEngine::PaintBufferGridLines(const GridLineSet /*lines*/,
                                                      const COLORREF /*color*/,
                                                      const size_t /*cchLine*/,
-                                                     const COORD /*coordTarget*/) noexcept
+                                                     const til::point /*coordTarget*/) noexcept
 {
     return S_OK;
 }
@@ -158,7 +158,7 @@ using namespace Microsoft::Console::Types;
 // - S_OK or suitable HRESULT error from writing pipe.
 [[nodiscard]] HRESULT VtEngine::PaintCursor(const CursorOptions& options) noexcept
 {
-    _trace.TracePaintCursor(til::point{ options.coordCursor });
+    _trace.TracePaintCursor(options.coordCursor);
 
     // MSFT:15933349 - Send the terminal the updated cursor information, if it's changed.
     LOG_IF_FAILED(_MoveCursor(options.coordCursor));
@@ -176,7 +176,7 @@ using namespace Microsoft::Console::Types;
 //  - rect - Rectangle to invert or highlight to make the selection area
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT VtEngine::PaintSelection(const SMALL_RECT /*rect*/) noexcept
+[[nodiscard]] HRESULT VtEngine::PaintSelection(const til::rect& /*rect*/) noexcept
 {
     return S_OK;
 }
@@ -339,7 +339,7 @@ using namespace Microsoft::Console::Types;
 // Return Value:
 // - S_OK or suitable HRESULT error from writing pipe.
 [[nodiscard]] HRESULT VtEngine::_PaintAsciiBufferLine(const gsl::span<const Cluster> clusters,
-                                                      const COORD coord) noexcept
+                                                      const til::point coord) noexcept
 {
     try
     {
@@ -348,7 +348,7 @@ using namespace Microsoft::Console::Types;
         _bufferLine.clear();
         _bufferLine.reserve(clusters.size());
 
-        size_t totalWidth = 0;
+        til::CoordType totalWidth = 0;
         for (const auto& cluster : clusters)
         {
             _bufferLine.append(cluster.GetText());
@@ -358,7 +358,7 @@ using namespace Microsoft::Console::Types;
         RETURN_IF_FAILED(VtEngine::_WriteTerminalAscii(_bufferLine));
 
         // Update our internal tracker of the cursor's position
-        _lastText.X += gsl::narrow<short>(totalWidth);
+        _lastText.X += totalWidth;
 
         return S_OK;
     }
@@ -374,7 +374,7 @@ using namespace Microsoft::Console::Types;
 // Return Value:
 // - S_OK or suitable HRESULT error from writing pipe.
 [[nodiscard]] HRESULT VtEngine::_PaintUtf8BufferLine(const gsl::span<const Cluster> clusters,
-                                                     const COORD coord,
+                                                     const til::point coord,
                                                      const bool lineWrapped) noexcept
 {
     if (coord.Y < _virtualTop)
@@ -384,7 +384,7 @@ using namespace Microsoft::Console::Types;
 
     _bufferLine.clear();
     _bufferLine.reserve(clusters.size());
-    size_t totalWidth = 0;
+    til::CoordType totalWidth = 0;
     for (const auto& cluster : clusters)
     {
         _bufferLine.append(cluster.GetText());
@@ -406,7 +406,7 @@ using namespace Microsoft::Console::Types;
     // - "AA"
     //      cch = 2, spaceIndex = 1, foundNonSpace = true
     //      cch-nonSpaceLength = 0
-    const auto numSpaces = cchLine - nonSpaceLength;
+    const auto numSpaces = gsl::narrow_cast<til::CoordType>(cchLine - nonSpaceLength);
 
     // Optimizations:
     // If there are lots of spaces at the end of the line, we can try to Erase
@@ -511,7 +511,7 @@ using namespace Microsoft::Console::Types;
     // character of the row.
     if (_lastText.X < _lastViewport.RightExclusive())
     {
-        _lastText.X += static_cast<short>(columnsActual);
+        _lastText.X += columnsActual;
     }
     // GH#1245: If we wrote the exactly last char of the row, then we're in the
     // "delayed EOL wrap" state. Different terminals (conhost, gnome-terminal,
@@ -524,13 +524,6 @@ using namespace Microsoft::Console::Types;
         _delayedEolWrap = true;
     }
 
-    short sNumSpaces;
-    try
-    {
-        sNumSpaces = gsl::narrow<short>(numSpaces);
-    }
-    CATCH_RETURN();
-
     if (useEraseChar)
     {
         // ECH doesn't actually move the cursor itself. However, we think that
@@ -539,11 +532,11 @@ using namespace Microsoft::Console::Types;
         //   cursor somewhere else before the end of the frame, we'll move the
         //   cursor to the deferred position at the end of the frame, or right
         //   before we need to print new text.
-        _deferredCursorPos = { _lastText.X + sNumSpaces, _lastText.Y };
+        _deferredCursorPos = { _lastText.X + numSpaces, _lastText.Y };
 
         if (_deferredCursorPos.X <= _lastViewport.RightInclusive())
         {
-            RETURN_IF_FAILED(_EraseCharacter(sNumSpaces));
+            RETURN_IF_FAILED(_EraseCharacter(numSpaces));
         }
         else
         {
@@ -556,7 +549,7 @@ using namespace Microsoft::Console::Types;
         //      line is already empty.
         if (optimalToUseECH)
         {
-            _deferredCursorPos = { _lastText.X + sNumSpaces, _lastText.Y };
+            _deferredCursorPos = { _lastText.X + numSpaces, _lastText.Y };
         }
         else if (numSpaces > 0 && removeSpaces) // if we deleted the spaces... re-add them
         {
@@ -564,7 +557,7 @@ using namespace Microsoft::Console::Types;
             auto spaces = std::wstring(numSpaces, L' ');
             RETURN_IF_FAILED(VtEngine::_WriteTerminalUtf8(spaces));
 
-            _lastText.X += static_cast<short>(numSpaces);
+            _lastText.X += numSpaces;
         }
     }
 
diff --git a/src/renderer/vt/state.cpp b/src/renderer/vt/state.cpp
index c40f3c84241..f00d34a7efe 100644
--- a/src/renderer/vt/state.cpp
+++ b/src/renderer/vt/state.cpp
@@ -16,7 +16,7 @@ using namespace Microsoft::Console;
 using namespace Microsoft::Console::Render;
 using namespace Microsoft::Console::Types;
 
-const COORD VtEngine::INVALID_COORDS = { -1, -1 };
+constexpr til::point VtEngine::INVALID_COORDS = { -1, -1 };
 
 // Routine Description:
 // - Creates a new VT-based rendering engine
@@ -32,8 +32,7 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe,
     _lastTextAttributes(INVALID_COLOR, INVALID_COLOR),
     _lastViewport(initialViewport),
     _pool(til::pmr::get_default_resource()),
-    _invalidMap(til::size{ initialViewport.Dimensions() }, false, &_pool),
-    _lastText({ 0 }),
+    _invalidMap(initialViewport.Dimensions(), false, &_pool),
     _scrollDelta(0, 0),
     _quickReturn(false),
     _clearedAllThisFrame(false),
@@ -243,7 +242,7 @@ CATCH_RETURN();
 // - srNewViewport - The bounds of the new viewport.
 // Return Value:
 // - HRESULT S_OK
-[[nodiscard]] HRESULT VtEngine::UpdateViewport(const SMALL_RECT srNewViewport) noexcept
+[[nodiscard]] HRESULT VtEngine::UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept
 {
     auto hr = S_OK;
     const auto newView = Viewport::FromInclusive(srNewViewport);
@@ -265,13 +264,13 @@ CATCH_RETURN();
             // buffer will have triggered it's own invalidations for what it knows is
             // invalid. Previously, we'd invalidate everything if the width changed,
             // because we couldn't be sure if lines were reflowed.
-            _invalidMap.resize(til::size{ newSize });
+            _invalidMap.resize(newSize);
         }
         else
         {
             if (SUCCEEDED(hr))
             {
-                _invalidMap.resize(til::size{ newSize }, true); // resize while filling in new space with repaint requests.
+                _invalidMap.resize(newSize, true); // resize while filling in new space with repaint requests.
 
                 // Viewport is smaller now - just update it all.
                 if (oldSize.Y > newSize.Y || oldSize.X > newSize.X)
@@ -322,9 +321,9 @@ CATCH_RETURN();
 // - pFontSize - receives the current X by Y size of the font.
 // Return Value:
 // - S_FALSE: This is unsupported by the VT Renderer and should use another engine's value.
-[[nodiscard]] HRESULT VtEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
+[[nodiscard]] HRESULT VtEngine::GetFontSize(_Out_ til::size* const pFontSize) noexcept
 {
-    *pFontSize = COORD({ 1, 1 });
+    *pFontSize = { 1, 1 };
     return S_FALSE;
 }
 
@@ -382,7 +381,7 @@ bool VtEngine::_AllIsInvalid() const
 // - coordCursor: The cursor position to inherit from.
 // Return Value:
 // - S_OK
-[[nodiscard]] HRESULT VtEngine::InheritCursor(const COORD coordCursor) noexcept
+[[nodiscard]] HRESULT VtEngine::InheritCursor(const til::point coordCursor) noexcept
 {
     _virtualTop = coordCursor.Y;
     _lastText = coordCursor;
@@ -491,7 +490,7 @@ void VtEngine::SetLookingForDSRCallback(std::function<void(bool)> pfnLooking) no
     _pfnSetLookingForDSR = pfnLooking;
 }
 
-void VtEngine::SetTerminalCursorTextPosition(const COORD cursor) noexcept
+void VtEngine::SetTerminalCursorTextPosition(const til::point cursor) noexcept
 {
     _lastText = cursor;
 }
diff --git a/src/renderer/vt/tracing.cpp b/src/renderer/vt/tracing.cpp
index 8d9e460e68e..99a8b85ddaa 100644
--- a/src/renderer/vt/tracing.cpp
+++ b/src/renderer/vt/tracing.cpp
@@ -171,7 +171,7 @@ void RenderTracing::TraceStartPaint(const bool quickReturn,
                                     const til::rect& lastViewport,
                                     const til::point scrollDelt,
                                     const bool cursorMoved,
-                                    const std::optional<short>& wrappedRow) const
+                                    const std::optional<til::CoordType>& wrappedRow) const
 {
 #ifndef UNIT_TESTING
     if (TraceLoggingProviderEnabled(g_hConsoleVtRendererTraceProvider, WINEVENT_LEVEL_VERBOSE, TIL_KEYWORD_TRACE))
@@ -305,7 +305,7 @@ void RenderTracing::TraceWrapped() const
 #endif UNIT_TESTING
 }
 
-void RenderTracing::TraceSetWrapped(const short wrappedRow) const
+void RenderTracing::TraceSetWrapped(const til::CoordType wrappedRow) const
 {
 #ifndef UNIT_TESTING
     if (TraceLoggingProviderEnabled(g_hConsoleVtRendererTraceProvider, WINEVENT_LEVEL_VERBOSE, TIL_KEYWORD_TRACE))
diff --git a/src/renderer/vt/tracing.hpp b/src/renderer/vt/tracing.hpp
index 973605a19e7..78515df7d48 100644
--- a/src/renderer/vt/tracing.hpp
+++ b/src/renderer/vt/tracing.hpp
@@ -32,7 +32,7 @@ namespace Microsoft::Console::VirtualTerminal
         void TraceLastText(const til::point lastText) const;
         void TraceScrollFrame(const til::point scrollDelta) const;
         void TraceMoveCursor(const til::point lastText, const til::point cursor) const;
-        void TraceSetWrapped(const short wrappedRow) const;
+        void TraceSetWrapped(const til::CoordType wrappedRow) const;
         void TraceClearWrapped() const;
         void TraceWrapped() const;
         void TracePaintCursor(const til::point coordCursor) const;
@@ -44,7 +44,7 @@ namespace Microsoft::Console::VirtualTerminal
                              const til::rect& lastViewport,
                              const til::point scrollDelta,
                              const bool cursorMoved,
-                             const std::optional<short>& wrappedRow) const;
+                             const std::optional<til::CoordType>& wrappedRow) const;
         void TraceEndPaint() const;
     };
 }
diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp
index 38c3638af9e..4d9e624e919 100644
--- a/src/renderer/vt/vtrenderer.hpp
+++ b/src/renderer/vt/vtrenderer.hpp
@@ -42,7 +42,7 @@ namespace Microsoft::Console::Render
     public:
         // See _PaintUtf8BufferLine for explanation of this value.
         static const size_t ERASE_CHARACTER_STRING_LENGTH = 8;
-        static const COORD INVALID_COORDS;
+        static const til::point INVALID_COORDS;
 
         VtEngine(_In_ wil::unique_hfile hPipe,
                  const Microsoft::Console::Types::Viewport initialViewport);
@@ -52,29 +52,29 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT EndPaint() noexcept override;
         [[nodiscard]] HRESULT Present() noexcept override;
         [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* pForcePaint) noexcept override;
-        [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* psrRegion) noexcept override;
-        [[nodiscard]] HRESULT InvalidateCursor(const SMALL_RECT* psrRegion) noexcept override;
-        [[nodiscard]] HRESULT InvalidateSystem(const RECT* prcDirtyClient) noexcept override;
-        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT Invalidate(const til::rect* psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT InvalidateFlush(_In_ const bool circled, _Out_ bool* const pForcePaint) noexcept override;
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
-        [[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> clusters, COORD coord, bool fTrimLeft, bool lineWrapped) noexcept override;
-        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(SMALL_RECT rect) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferLine(gsl::span<const Cluster> clusters, til::point coord, bool fTrimLeft, bool lineWrapped) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF color, size_t cchLine, til::point coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override;
         [[nodiscard]] HRESULT UpdateDpi(int iDpi) noexcept override;
-        [[nodiscard]] HRESULT UpdateViewport(SMALL_RECT srNewViewport) noexcept override;
+        [[nodiscard]] HRESULT UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept override;
         [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo, int iDpi) noexcept override;
         [[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept override;
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* pFontSize) noexcept override;
         [[nodiscard]] HRESULT IsGlyphWideByFont(std::wstring_view glyph, _Out_ bool* pResult) noexcept override;
 
         // VtEngine
         [[nodiscard]] HRESULT SuppressResizeRepaint() noexcept;
         [[nodiscard]] HRESULT RequestCursor() noexcept;
-        [[nodiscard]] HRESULT InheritCursor(const COORD coordCursor) noexcept;
+        [[nodiscard]] HRESULT InheritCursor(const til::point coordCursor) noexcept;
         [[nodiscard]] HRESULT WriteTerminalUtf8(const std::string_view str) noexcept;
         [[nodiscard]] virtual HRESULT WriteTerminalW(const std::wstring_view str) noexcept = 0;
         void SetTerminalOwner(Microsoft::Console::VirtualTerminal::VtIo* const terminalOwner);
@@ -83,7 +83,7 @@ namespace Microsoft::Console::Render
         void SetResizeQuirk(const bool resizeQuirk);
         void SetPassthroughMode(const bool passthrough) noexcept;
         void SetLookingForDSRCallback(std::function<void(bool)> pfnLooking) noexcept;
-        void SetTerminalCursorTextPosition(const COORD coordCursor) noexcept;
+        void SetTerminalCursorTextPosition(const til::point coordCursor) noexcept;
         [[nodiscard]] virtual HRESULT ManuallyClearScrollback() noexcept;
         [[nodiscard]] HRESULT RequestWin32Input() noexcept;
         [[nodiscard]] virtual HRESULT SetWindowVisibility(const bool showOrHide) noexcept = 0;
@@ -105,7 +105,7 @@ namespace Microsoft::Console::Render
         std::pmr::unsynchronized_pool_resource _pool;
         til::pmr::bitmap _invalidMap;
 
-        COORD _lastText;
+        til::point _lastText;
         til::point _scrollDelta;
 
         bool _quickReturn;
@@ -115,12 +115,12 @@ namespace Microsoft::Console::Render
 
         bool _suppressResizeRepaint;
 
-        SHORT _virtualTop;
+        til::CoordType _virtualTop;
         bool _circled;
         bool _firstPaint;
         bool _skipCursor;
         bool _newBottomLine;
-        COORD _deferredCursorPos;
+        til::point _deferredCursorPos;
 
         bool _pipeBroken;
         HRESULT _exitResult;
@@ -129,7 +129,7 @@ namespace Microsoft::Console::Render
         Microsoft::Console::VirtualTerminal::RenderTracing _trace;
         bool _inResizeRequest{ false };
 
-        std::optional<short> _wrappedRow{ std::nullopt };
+        std::optional<til::CoordType> _wrappedRow{ std::nullopt };
 
         bool _delayedEolWrap{ false };
 
@@ -151,7 +151,7 @@ namespace Microsoft::Console::Render
         }
         CATCH_RETURN()
 
-        void _OrRect(_Inout_ SMALL_RECT* const pRectExisting, const SMALL_RECT* const pRectToOr) const;
+        void _OrRect(_Inout_ til::inclusive_rect* const pRectExisting, const til::inclusive_rect* const pRectToOr) const;
         bool _AllIsInvalid() const;
 
         [[nodiscard]] HRESULT _StopCursorBlinking() noexcept;
@@ -159,12 +159,12 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT _HideCursor() noexcept;
         [[nodiscard]] HRESULT _ShowCursor() noexcept;
         [[nodiscard]] HRESULT _EraseLine() noexcept;
-        [[nodiscard]] HRESULT _InsertDeleteLine(const short sLines, const bool fInsertLine) noexcept;
-        [[nodiscard]] HRESULT _DeleteLine(const short sLines) noexcept;
-        [[nodiscard]] HRESULT _InsertLine(const short sLines) noexcept;
-        [[nodiscard]] HRESULT _CursorForward(const short chars) noexcept;
-        [[nodiscard]] HRESULT _EraseCharacter(const short chars) noexcept;
-        [[nodiscard]] HRESULT _CursorPosition(const COORD coord) noexcept;
+        [[nodiscard]] HRESULT _InsertDeleteLine(const til::CoordType sLines, const bool fInsertLine) noexcept;
+        [[nodiscard]] HRESULT _DeleteLine(const til::CoordType sLines) noexcept;
+        [[nodiscard]] HRESULT _InsertLine(const til::CoordType sLines) noexcept;
+        [[nodiscard]] HRESULT _CursorForward(const til::CoordType chars) noexcept;
+        [[nodiscard]] HRESULT _EraseCharacter(const til::CoordType chars) noexcept;
+        [[nodiscard]] HRESULT _CursorPosition(const til::point coord) noexcept;
         [[nodiscard]] HRESULT _CursorHome() noexcept;
         [[nodiscard]] HRESULT _ClearScreen() noexcept;
         [[nodiscard]] HRESULT _ClearScrollback() noexcept;
@@ -179,7 +179,7 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT _SetGraphicsDefault() noexcept;
 
-        [[nodiscard]] HRESULT _ResizeWindow(const short sWidth, const short sHeight) noexcept;
+        [[nodiscard]] HRESULT _ResizeWindow(const til::CoordType sWidth, const til::CoordType sHeight) noexcept;
 
         [[nodiscard]] HRESULT _SetIntense(const bool isIntense) noexcept;
         [[nodiscard]] HRESULT _SetFaint(const bool isFaint) noexcept;
@@ -203,7 +203,7 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT _RequestFocusEventMode() noexcept;
 
-        [[nodiscard]] virtual HRESULT _MoveCursor(const COORD coord) noexcept = 0;
+        [[nodiscard]] virtual HRESULT _MoveCursor(const til::point coord) noexcept = 0;
         [[nodiscard]] HRESULT _RgbUpdateDrawingBrushes(const TextAttribute& textAttributes) noexcept;
         [[nodiscard]] HRESULT _16ColorUpdateDrawingBrushes(const TextAttribute& textAttributes) noexcept;
 
@@ -213,11 +213,11 @@ namespace Microsoft::Console::Render
         // so they don't have to alloc/free in a tight loop
         std::wstring _bufferLine;
         [[nodiscard]] HRESULT _PaintUtf8BufferLine(const gsl::span<const Cluster> clusters,
-                                                   const COORD coord,
+                                                   const til::point coord,
                                                    const bool lineWrapped) noexcept;
 
         [[nodiscard]] HRESULT _PaintAsciiBufferLine(const gsl::span<const Cluster> clusters,
-                                                    const COORD coord) noexcept;
+                                                    const til::point coord) noexcept;
 
         [[nodiscard]] HRESULT _WriteTerminalUtf8(const std::wstring_view str) noexcept;
         [[nodiscard]] HRESULT _WriteTerminalAscii(const std::wstring_view str) noexcept;
diff --git a/src/renderer/wddmcon/WddmConRenderer.cpp b/src/renderer/wddmcon/WddmConRenderer.cpp
index 11dce06fa8c..eb246b8128d 100644
--- a/src/renderer/wddmcon/WddmConRenderer.cpp
+++ b/src/renderer/wddmcon/WddmConRenderer.cpp
@@ -166,27 +166,27 @@ try
 }
 CATCH_RETURN()
 
-[[nodiscard]] HRESULT WddmConEngine::Invalidate(const SMALL_RECT* const /*psrRegion*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::Invalidate(const til::rect* const /*psrRegion*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT WddmConEngine::InvalidateCursor(const SMALL_RECT* const /*psrRegion*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::InvalidateCursor(const til::rect* const /*psrRegion*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT WddmConEngine::InvalidateSystem(const RECT* const /*prcDirtyClient*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::InvalidateSystem(const til::rect* const /*prcDirtyClient*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT WddmConEngine::InvalidateSelection(const std::vector<SMALL_RECT>& /*rectangles*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::InvalidateSelection(const std::vector<til::rect>& /*rectangles*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT WddmConEngine::InvalidateScroll(const COORD* const /*pcoordDelta*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::InvalidateScroll(const til::point* const /*pcoordDelta*/) noexcept
 {
     return S_OK;
 }
@@ -259,7 +259,7 @@ CATCH_RETURN()
 }
 
 [[nodiscard]] HRESULT WddmConEngine::PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                                     const COORD coord,
+                                                     const til::point coord,
                                                      const bool /*trimLeft*/,
                                                      const bool /*lineWrapped*/) noexcept
 {
@@ -287,12 +287,12 @@ CATCH_RETURN()
 [[nodiscard]] HRESULT WddmConEngine::PaintBufferGridLines(GridLineSet const /*lines*/,
                                                           COLORREF const /*color*/,
                                                           size_t const /*cchLine*/,
-                                                          const COORD /*coordTarget*/) noexcept
+                                                          const til::point /*coordTarget*/) noexcept
 {
     return S_OK;
 }
 
-[[nodiscard]] HRESULT WddmConEngine::PaintSelection(const SMALL_RECT /*rect*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::PaintSelection(const til::rect& /*rect*/) noexcept
 {
     return S_OK;
 }
@@ -330,7 +330,7 @@ CATCH_RETURN()
 // - srNewViewport - The bounds of the new viewport.
 // Return Value:
 // - HRESULT S_OK
-[[nodiscard]] HRESULT WddmConEngine::UpdateViewport(const SMALL_RECT /*srNewViewport*/) noexcept
+[[nodiscard]] HRESULT WddmConEngine::UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept
 {
     return S_OK;
 }
@@ -339,7 +339,7 @@ CATCH_RETURN()
                                                      FontInfo& fiFontInfo,
                                                      const int /*iDpi*/) noexcept
 {
-    COORD coordSize = { 0 };
+    til::size coordSize;
 #pragma warning(suppress : 26447)
     LOG_IF_FAILED(GetFontSize(&coordSize));
 
@@ -364,9 +364,9 @@ CATCH_RETURN()
     return S_OK;
 }
 
-RECT WddmConEngine::GetDisplaySize() noexcept
+til::rect WddmConEngine::GetDisplaySize() noexcept
 {
-    RECT r;
+    til::rect r;
     r.top = 0;
     r.left = 0;
     r.bottom = _displayHeight;
@@ -375,7 +375,7 @@ RECT WddmConEngine::GetDisplaySize() noexcept
     return r;
 }
 
-[[nodiscard]] HRESULT WddmConEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
+[[nodiscard]] HRESULT WddmConEngine::GetFontSize(_Out_ til::size* const pFontSize) noexcept
 {
     // In order to retrieve the font size being used by DirectX, it is necessary
     // to modify the API set that defines the contract for WddmCon. However, the
@@ -388,11 +388,7 @@ RECT WddmConEngine::GetDisplaySize() noexcept
     //
     // TODO: MSFT 11851921 - Subsume WddmCon into ConhostV2 and remove the API
     //       set extension.
-    COORD c;
-    c.X = DEFAULT_FONT_WIDTH;
-    c.Y = DEFAULT_FONT_HEIGHT;
-
-    *pFontSize = c;
+    *pFontSize = { DEFAULT_FONT_WIDTH, DEFAULT_FONT_HEIGHT };
     return S_OK;
 }
 
diff --git a/src/renderer/wddmcon/WddmConRenderer.hpp b/src/renderer/wddmcon/WddmConRenderer.hpp
index 0468489b9a5..87c3a799bd8 100644
--- a/src/renderer/wddmcon/WddmConRenderer.hpp
+++ b/src/renderer/wddmcon/WddmConRenderer.hpp
@@ -22,14 +22,14 @@ namespace Microsoft::Console::Render
         [[nodiscard]] HRESULT Enable() noexcept override;
         [[nodiscard]] HRESULT Disable() noexcept;
 
-        RECT GetDisplaySize() noexcept;
+        til::rect GetDisplaySize() noexcept;
 
         // IRenderEngine Members
-        [[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 Invalidate(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateCursor(const til::rect* const psrRegion) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSystem(const til::rect* const prcDirtyClient) noexcept override;
+        [[nodiscard]] HRESULT InvalidateSelection(const std::vector<til::rect>& rectangles) noexcept override;
+        [[nodiscard]] HRESULT InvalidateScroll(const til::point* const pcoordDelta) noexcept override;
         [[nodiscard]] HRESULT InvalidateAll() noexcept override;
         [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override;
 
@@ -41,11 +41,11 @@ namespace Microsoft::Console::Render
 
         [[nodiscard]] HRESULT PaintBackground() noexcept override;
         [[nodiscard]] HRESULT PaintBufferLine(const gsl::span<const Cluster> clusters,
-                                              const COORD coord,
+                                              const til::point coord,
                                               const bool trimLeft,
                                               const bool lineWrapped) noexcept override;
-        [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, COLORREF const color, const size_t cchLine, const COORD coordTarget) noexcept override;
-        [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override;
+        [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet const lines, COLORREF const color, size_t const cchLine, til::point const coordTarget) noexcept override;
+        [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override;
 
         [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;
 
@@ -56,12 +56,12 @@ namespace Microsoft::Console::Render
                                                    const bool isSettingDefaultBrushes) noexcept override;
         [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override;
         [[nodiscard]] HRESULT UpdateDpi(const int iDpi) noexcept override;
-        [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override;
+        [[nodiscard]] HRESULT UpdateViewport(const til::inclusive_rect& srNewViewport) noexcept override;
 
         [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, const int iDpi) noexcept override;
 
         [[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rect>& area) noexcept override;
-        [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
+        [[nodiscard]] HRESULT GetFontSize(_Out_ til::size* const pFontSize) noexcept override;
         [[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
 
     protected:
diff --git a/src/server/ApiDispatchers.cpp b/src/server/ApiDispatchers.cpp
index fd5b9f3c0f4..b6dbe3b8af2 100644
--- a/src/server/ApiDispatchers.cpp
+++ b/src/server/ApiDispatchers.cpp
@@ -499,7 +499,7 @@
         hr = m->_pApiRoutines->FillConsoleOutputAttributeImpl(*pScreenInfo,
                                                               a->Element,
                                                               fill,
-                                                              a->WriteCoord,
+                                                              til::wrap_coord(a->WriteCoord),
                                                               amountWritten);
         break;
     }
@@ -511,7 +511,7 @@
         hr = m->_pApiRoutines->FillConsoleOutputCharacterWImpl(*pScreenInfo,
                                                                a->Element,
                                                                fill,
-                                                               a->WriteCoord,
+                                                               til::wrap_coord(a->WriteCoord),
                                                                amountWritten,
                                                                m->GetProcessHandle()->GetShimPolicy().IsPowershellExe());
         break;
@@ -521,7 +521,7 @@
         hr = m->_pApiRoutines->FillConsoleOutputCharacterAImpl(*pScreenInfo,
                                                                static_cast<char>(a->Element),
                                                                fill,
-                                                               a->WriteCoord,
+                                                               til::wrap_coord(a->WriteCoord),
                                                                amountWritten);
         break;
     }
@@ -692,7 +692,7 @@
     SCREEN_INFORMATION* pObj;
     RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj));
 
-    return m->_pApiRoutines->SetConsoleScreenBufferSizeImpl(*pObj, a->Size);
+    return m->_pApiRoutines->SetConsoleScreenBufferSizeImpl(*pObj, til::wrap_coord_size(a->Size));
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerSetConsoleCursorPosition(_Inout_ CONSOLE_API_MSG* const m,
@@ -707,7 +707,7 @@
     SCREEN_INFORMATION* pObj;
     RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj));
 
-    return m->_pApiRoutines->SetConsoleCursorPositionImpl(*pObj, a->CursorPosition);
+    return m->_pApiRoutines->SetConsoleCursorPositionImpl(*pObj, til::wrap_coord(a->CursorPosition));
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerGetLargestConsoleWindowSize(_Inout_ CONSOLE_API_MSG* const m,
@@ -722,8 +722,9 @@
     SCREEN_INFORMATION* pObj;
     RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj));
 
-    m->_pApiRoutines->GetLargestConsoleWindowSizeImpl(*pObj, a->Size);
-    return S_OK;
+    auto size = til::wrap_coord_size(a->Size);
+    m->_pApiRoutines->GetLargestConsoleWindowSizeImpl(*pObj, size);
+    return til::unwrap_coord_size_hr(size, a->Size);
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerScrollConsoleScreenBuffer(_Inout_ CONSOLE_API_MSG* const m,
@@ -743,9 +744,9 @@
         // GH#3126 if the client application is cmd.exe, then we might need to
         // enable a compatibility shim.
         return m->_pApiRoutines->ScrollConsoleScreenBufferWImpl(*pObj,
-                                                                a->ScrollRectangle,
-                                                                a->DestinationOrigin,
-                                                                a->Clip ? std::optional<SMALL_RECT>(a->ClipRectangle) : std::nullopt,
+                                                                til::wrap_small_rect(a->ScrollRectangle),
+                                                                til::wrap_coord(a->DestinationOrigin),
+                                                                a->Clip ? std::optional{ til::wrap_small_rect(a->ClipRectangle) } : std::nullopt,
                                                                 a->Fill.Char.UnicodeChar,
                                                                 a->Fill.Attributes,
                                                                 m->GetProcessHandle()->GetShimPolicy().IsCmdExe());
@@ -753,9 +754,9 @@
     else
     {
         return m->_pApiRoutines->ScrollConsoleScreenBufferAImpl(*pObj,
-                                                                a->ScrollRectangle,
-                                                                a->DestinationOrigin,
-                                                                a->Clip ? std::optional<SMALL_RECT>(a->ClipRectangle) : std::nullopt,
+                                                                til::wrap_small_rect(a->ScrollRectangle),
+                                                                til::wrap_coord(a->DestinationOrigin),
+                                                                a->Clip ? std::optional{ til::wrap_small_rect(a->ClipRectangle) } : std::nullopt,
                                                                 a->Fill.Char.AsciiChar,
                                                                 a->Fill.Attributes);
     }
@@ -791,7 +792,7 @@
     SCREEN_INFORMATION* pObj;
     RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj));
 
-    return m->_pApiRoutines->SetConsoleWindowInfoImpl(*pObj, a->Absolute, a->Window);
+    return m->_pApiRoutines->SetConsoleWindowInfoImpl(*pObj, a->Absolute, til::wrap_small_rect(a->Window));
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerReadConsoleOutputString(_Inout_ CONSOLE_API_MSG* const m,
@@ -833,20 +834,20 @@
     case CONSOLE_ATTRIBUTE:
     {
         const gsl::span<WORD> buffer(reinterpret_cast<WORD*>(pvBuffer), cbBuffer / sizeof(WORD));
-        RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputAttributeImpl(*pScreenInfo, a->ReadCoord, buffer, written));
+        RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputAttributeImpl(*pScreenInfo, til::wrap_coord(a->ReadCoord), buffer, written));
         break;
     }
     case CONSOLE_REAL_UNICODE:
     case CONSOLE_FALSE_UNICODE:
     {
         const gsl::span<wchar_t> buffer(reinterpret_cast<wchar_t*>(pvBuffer), cbBuffer / sizeof(wchar_t));
-        RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputCharacterWImpl(*pScreenInfo, a->ReadCoord, buffer, written));
+        RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputCharacterWImpl(*pScreenInfo, til::wrap_coord(a->ReadCoord), buffer, written));
         break;
     }
     case CONSOLE_ASCII:
     {
         const gsl::span<char> buffer(reinterpret_cast<char*>(pvBuffer), cbBuffer);
-        RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputCharacterAImpl(*pScreenInfo, a->ReadCoord, buffer, written));
+        RETURN_IF_FAILED(m->_pApiRoutines->ReadConsoleOutputCharacterAImpl(*pScreenInfo, til::wrap_coord(a->ReadCoord), buffer, written));
         break;
     }
     default:
@@ -906,9 +907,9 @@
     Telemetry::Instance().LogApiCall(Telemetry::ApiCall::WriteConsoleOutput, a->Unicode);
 
     // Backup originalRegion and set the written area to a 0 size rectangle in case of failures.
-    const auto originalRegion = Microsoft::Console::Types::Viewport::FromInclusive(a->CharRegion);
+    const auto originalRegion = Microsoft::Console::Types::Viewport::FromInclusive(til::wrap_small_rect(a->CharRegion));
     auto writtenRegion = Microsoft::Console::Types::Viewport::FromDimensions(originalRegion.Origin(), { 0, 0 });
-    a->CharRegion = writtenRegion.ToInclusive();
+    RETURN_IF_FAILED(til::unwrap_small_rect_hr(writtenRegion.ToInclusive(), a->CharRegion));
 
     // Get input parameter buffer
     PVOID pvBuffer;
@@ -939,9 +940,7 @@
     }
 
     // Update the written region if we were successful
-    a->CharRegion = writtenRegion.ToInclusive();
-
-    return S_OK;
+    return til::unwrap_small_rect_hr(writtenRegion.ToInclusive(), a->CharRegion);
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerWriteConsoleOutputString(_Inout_ CONSOLE_API_MSG* const m,
@@ -991,7 +990,7 @@
 
         hr = m->_pApiRoutines->WriteConsoleOutputCharacterAImpl(*pScreenInfo,
                                                                 text,
-                                                                a->WriteCoord,
+                                                                til::wrap_coord(a->WriteCoord),
                                                                 used);
 
         break;
@@ -1003,7 +1002,7 @@
 
         hr = m->_pApiRoutines->WriteConsoleOutputCharacterWImpl(*pScreenInfo,
                                                                 text,
-                                                                a->WriteCoord,
+                                                                til::wrap_coord(a->WriteCoord),
                                                                 used);
 
         break;
@@ -1014,7 +1013,7 @@
 
         hr = m->_pApiRoutines->WriteConsoleOutputAttributeImpl(*pScreenInfo,
                                                                text,
-                                                               a->WriteCoord,
+                                                               til::wrap_coord(a->WriteCoord),
                                                                used);
 
         break;
@@ -1039,9 +1038,9 @@
     Telemetry::Instance().LogApiCall(Telemetry::ApiCall::ReadConsoleOutput, a->Unicode);
 
     // Backup data region passed and set it to a zero size region in case we exit early for failures.
-    const auto originalRegion = Microsoft::Console::Types::Viewport::FromInclusive(a->CharRegion);
+    const auto originalRegion = Microsoft::Console::Types::Viewport::FromInclusive(til::wrap_small_rect(a->CharRegion));
     const auto zeroRegion = Microsoft::Console::Types::Viewport::FromDimensions(originalRegion.Origin(), { 0, 0 });
-    a->CharRegion = zeroRegion.ToInclusive();
+    RETURN_IF_FAILED(til::unwrap_small_rect_hr(zeroRegion.ToInclusive(), a->CharRegion));
 
     PVOID pvBuffer;
     ULONG cbBuffer;
@@ -1077,7 +1076,7 @@
                                                                   finalRegion));
     }
 
-    a->CharRegion = finalRegion.ToInclusive();
+    RETURN_IF_FAILED(til::unwrap_small_rect_hr(finalRegion.ToInclusive(), a->CharRegion));
 
     // We have to reply back with the entire buffer length. The client side in kernelbase will trim out
     // the correct region of the buffer for return to the original caller.
@@ -1188,7 +1187,9 @@
     SCREEN_INFORMATION* pObj;
     RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_READ, &pObj));
 
-    return m->_pApiRoutines->GetConsoleFontSizeImpl(*pObj, a->FontIndex, a->FontSize);
+    auto size = til::wrap_coord_size(a->FontSize);
+    RETURN_IF_FAILED(m->_pApiRoutines->GetConsoleFontSizeImpl(*pObj, a->FontIndex, size));
+    return til::unwrap_coord_size_hr(size, a->FontSize);
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerGetConsoleCurrentFont(_Inout_ CONSOLE_API_MSG* const m,
@@ -1229,7 +1230,9 @@
     SCREEN_INFORMATION* pObj;
     RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_WRITE, &pObj));
 
-    return m->_pApiRoutines->SetConsoleDisplayModeImpl(*pObj, a->dwFlags, a->ScreenBufferDimensions);
+    auto size = til::wrap_coord_size(a->ScreenBufferDimensions);
+    RETURN_IF_FAILED(m->_pApiRoutines->SetConsoleDisplayModeImpl(*pObj, a->dwFlags, size));
+    return til::unwrap_coord_size_hr(size, a->ScreenBufferDimensions);
 }
 
 [[nodiscard]] HRESULT ApiDispatchers::ServerGetConsoleDisplayMode(_Inout_ CONSOLE_API_MSG* const m,
diff --git a/src/server/IApiRoutines.h b/src/server/IApiRoutines.h
index 04151b9af1b..9621b895d23 100644
--- a/src/server/IApiRoutines.h
+++ b/src/server/IApiRoutines.h
@@ -135,19 +135,19 @@ class IApiRoutines
     [[nodiscard]] virtual HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                                  const WORD attribute,
                                                                  const size_t lengthToWrite,
-                                                                 const COORD startingCoordinate,
+                                                                 const til::point startingCoordinate,
                                                                  size_t& cellsModified) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                                   const char character,
                                                                   const size_t lengthToWrite,
-                                                                  const COORD startingCoordinate,
+                                                                  const til::point startingCoordinate,
                                                                   size_t& cellsModified) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                                   const wchar_t character,
                                                                   const size_t lengthToWrite,
-                                                                  const COORD startingCoordinate,
+                                                                  const til::point startingCoordinate,
                                                                   size_t& cellsModified,
                                                                   const bool enablePowershellShim = false) noexcept = 0;
 
@@ -175,25 +175,25 @@ class IApiRoutines
                                                                    const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT SetConsoleScreenBufferSizeImpl(IConsoleOutputObject& context,
-                                                                 const COORD size) noexcept = 0;
+                                                                 const til::size size) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT SetConsoleCursorPositionImpl(IConsoleOutputObject& context,
-                                                               const COORD position) noexcept = 0;
+                                                               const til::point position) noexcept = 0;
 
     virtual void GetLargestConsoleWindowSizeImpl(const IConsoleOutputObject& context,
-                                                 COORD& size) noexcept = 0;
+                                                 til::size& size) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT ScrollConsoleScreenBufferAImpl(IConsoleOutputObject& context,
-                                                                 const SMALL_RECT& source,
-                                                                 const COORD target,
-                                                                 std::optional<SMALL_RECT> clip,
+                                                                 const til::inclusive_rect& source,
+                                                                 const til::point target,
+                                                                 std::optional<til::inclusive_rect> clip,
                                                                  const char fillCharacter,
                                                                  const WORD fillAttribute) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT ScrollConsoleScreenBufferWImpl(IConsoleOutputObject& context,
-                                                                 const SMALL_RECT& source,
-                                                                 const COORD target,
-                                                                 std::optional<SMALL_RECT> clip,
+                                                                 const til::inclusive_rect& source,
+                                                                 const til::point target,
+                                                                 std::optional<til::inclusive_rect> clip,
                                                                  const wchar_t fillCharacter,
                                                                  const WORD fillAttribute,
                                                                  const bool enableCmdShim = false) noexcept = 0;
@@ -203,20 +203,20 @@ class IApiRoutines
 
     [[nodiscard]] virtual HRESULT SetConsoleWindowInfoImpl(IConsoleOutputObject& context,
                                                            const bool isAbsolute,
-                                                           const SMALL_RECT& windowRect) noexcept = 0;
+                                                           const til::inclusive_rect& windowRect) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT ReadConsoleOutputAttributeImpl(const IConsoleOutputObject& context,
-                                                                 const COORD origin,
+                                                                 const til::point origin,
                                                                  gsl::span<WORD> buffer,
                                                                  size_t& written) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT ReadConsoleOutputCharacterAImpl(const IConsoleOutputObject& context,
-                                                                  const COORD origin,
+                                                                  const til::point origin,
                                                                   gsl::span<char> buffer,
                                                                   size_t& written) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT ReadConsoleOutputCharacterWImpl(const IConsoleOutputObject& context,
-                                                                  const COORD origin,
+                                                                  const til::point origin,
                                                                   gsl::span<wchar_t> buffer,
                                                                   size_t& written) noexcept = 0;
 
@@ -242,17 +242,17 @@ class IApiRoutines
 
     [[nodiscard]] virtual HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
                                                                   const gsl::span<const WORD> attrs,
-                                                                  const COORD target,
+                                                                  const til::point target,
                                                                   size_t& used) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
                                                                    const std::string_view text,
-                                                                   const COORD target,
+                                                                   const til::point target,
                                                                    size_t& used) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
                                                                    const std::wstring_view text,
-                                                                   const COORD target,
+                                                                   const til::point target,
                                                                    size_t& used) noexcept = 0;
 
     [[nodiscard]] virtual HRESULT ReadConsoleOutputAImpl(const IConsoleOutputObject& context,
@@ -292,7 +292,7 @@ class IApiRoutines
 
     [[nodiscard]] virtual HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
                                                          const DWORD index,
-                                                         COORD& size) noexcept = 0;
+                                                         til::size& size) noexcept = 0;
 
     // driver will pare down for non-Ex method
     [[nodiscard]] virtual HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
@@ -301,7 +301,7 @@ class IApiRoutines
 
     [[nodiscard]] virtual HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
                                                             const ULONG flags,
-                                                            COORD& newSize) noexcept = 0;
+                                                            til::size& newSize) noexcept = 0;
 
     virtual void GetConsoleDisplayModeImpl(ULONG& flags) noexcept = 0;
 
diff --git a/src/terminal/adapter/FontBuffer.cpp b/src/terminal/adapter/FontBuffer.cpp
index 98d13d78319..8bac5d3f9d4 100644
--- a/src/terminal/adapter/FontBuffer.cpp
+++ b/src/terminal/adapter/FontBuffer.cpp
@@ -130,7 +130,7 @@ bool FontBuffer::SetAttributes(const DispatchTypes::DrcsCellMatrix cellMatrix,
             // 0 width is treated as unknown (we'll try and estimate the expected
             // width), and the height parameter can still give us the height.
             _sizeDeclaredAsMatrix = false;
-            _declaredWidth = static_cast<size_t>(cellMatrix);
+            _declaredWidth = static_cast<VTInt>(cellMatrix);
             _declaredHeight = cellHeight.value_or(0);
             valid = (_declaredWidth <= MAX_WIDTH && _declaredHeight <= MAX_HEIGHT);
             break;
@@ -219,17 +219,17 @@ bool FontBuffer::FinalizeSixelData()
 
 gsl::span<const uint16_t> FontBuffer::GetBitPattern() const noexcept
 {
-    return { _buffer.data(), MAX_CHARS * _fullHeight };
+    return { _buffer.data(), gsl::narrow_cast<size_t>(MAX_CHARS * _fullHeight) };
 }
 
 til::size FontBuffer::GetCellSize() const noexcept
 {
-    return { gsl::narrow_cast<til::CoordType>(_fullWidth), gsl::narrow_cast<til::CoordType>(_fullHeight) };
+    return { _fullWidth, _fullHeight };
 }
 
 size_t FontBuffer::GetTextCenteringHint() const noexcept
 {
-    return _textCenteringHint;
+    return gsl::narrow_cast<size_t>(_textCenteringHint);
 }
 
 VTID FontBuffer::GetDesignation() const noexcept
@@ -297,7 +297,7 @@ void FontBuffer::_prepareCharacterBuffer()
 void FontBuffer::_prepareNextCharacter()
 {
     _lastChar = _currentChar;
-    _currentCharBuffer = std::next(_buffer.begin(), _currentChar * _fullHeight);
+    _currentCharBuffer = std::next(_buffer.begin(), gsl::narrow_cast<size_t>(_currentChar * _fullHeight));
     _sixelColumn = 0;
     _sixelRow = 0;
 
@@ -309,7 +309,7 @@ void FontBuffer::_prepareNextCharacter()
     }
 }
 
-void FontBuffer::_addSixelValue(const size_t value) noexcept
+void FontBuffer::_addSixelValue(const VTInt value) noexcept
 {
     if (_currentChar < MAX_CHARS && _sixelColumn < _textWidth)
     {
@@ -319,10 +319,10 @@ void FontBuffer::_addSixelValue(const size_t value) noexcept
         const auto outputColumnBit = (0x8000 >> (_sixelColumn + _textOffset));
         auto outputIterator = _currentCharBuffer;
         auto inputValueMask = 1;
-        for (size_t i = 0; i < 6 && _sixelRow + i < _fullHeight; i++)
+        for (VTInt i = 0; i < 6 && _sixelRow + i < _fullHeight; i++)
         {
             *outputIterator |= (value & inputValueMask) ? outputColumnBit : 0;
-            outputIterator++;
+            ++outputIterator;
             inputValueMask <<= 1;
         }
     }
@@ -350,7 +350,7 @@ void FontBuffer::_endOfCharacter()
     _prepareNextCharacter();
 }
 
-std::tuple<size_t, size_t, size_t> FontBuffer::_calculateDimensions() const
+std::tuple<VTInt, VTInt, VTInt> FontBuffer::_calculateDimensions() const
 {
     // If the size is declared as a matrix, this is most likely a VT2xx font,
     // typically with a cell size of 10x10. However, in 132-column mode, the
@@ -398,7 +398,7 @@ std::tuple<size_t, size_t, size_t> FontBuffer::_calculateDimensions() const
     // estimate the size from the used sixel values. If comparing a sixel-based
     // height, though, we need to round up the target cell height to account for
     // the fact that our used height will always be a multiple of six.
-    const auto inRange = [=](const size_t cellWidth, const size_t cellHeight) {
+    const auto inRange = [=](const VTInt cellWidth, const VTInt cellHeight) {
         const auto sixelHeight = (cellHeight + 5) / 6 * 6;
         const auto heightInRange = _declaredHeight ? _declaredHeight <= cellHeight : _usedHeight <= sixelHeight;
         const auto widthInRange = _declaredWidth ? _declaredWidth <= cellWidth : _usedWidth <= cellWidth;
@@ -499,7 +499,7 @@ void FontBuffer::_packAndCenterBitPatterns() noexcept
     // that are required.
     for (size_t srcLine = 0, dstLine = 0; srcLine < _buffer.size(); srcLine++)
     {
-        if ((srcLine % MAX_HEIGHT) < _fullHeight)
+        if (gsl::narrow_cast<VTInt>(srcLine % MAX_HEIGHT) < _fullHeight)
         {
             auto characterScanline = til::at(_buffer, srcLine);
             characterScanline &= textClippingMask;
@@ -515,11 +515,11 @@ void FontBuffer::_fillUnusedCharacters()
     // with an error glyph (a reverse question mark). This includes every
     // character prior to the start char, or after the last char.
     const auto errorPattern = _generateErrorGlyph();
-    for (size_t ch = 0; ch < MAX_CHARS; ch++)
+    for (VTInt ch = 0; ch < MAX_CHARS; ch++)
     {
         if (ch < _startChar || ch > _lastChar)
         {
-            auto charBuffer = std::next(_buffer.begin(), ch * _fullHeight);
+            auto charBuffer = std::next(_buffer.begin(), gsl::narrow_cast<size_t>(ch * _fullHeight));
             std::copy_n(errorPattern.begin(), _fullHeight, charBuffer);
         }
     }
diff --git a/src/terminal/adapter/FontBuffer.hpp b/src/terminal/adapter/FontBuffer.hpp
index 4b5ddbef220..a945f9a75ef 100644
--- a/src/terminal/adapter/FontBuffer.hpp
+++ b/src/terminal/adapter/FontBuffer.hpp
@@ -36,18 +36,18 @@ namespace Microsoft::Console::VirtualTerminal
         VTID GetDesignation() const noexcept;
 
     private:
-        static constexpr size_t MAX_WIDTH = 16;
-        static constexpr size_t MAX_HEIGHT = 32;
-        static constexpr size_t MAX_CHARS = 96;
+        static constexpr VTInt MAX_WIDTH = 16;
+        static constexpr VTInt MAX_HEIGHT = 32;
+        static constexpr VTInt MAX_CHARS = 96;
 
         void _buildCharsetId(const wchar_t ch);
         void _prepareCharacterBuffer();
         void _prepareNextCharacter();
-        void _addSixelValue(const size_t value) noexcept;
+        void _addSixelValue(const VTInt value) noexcept;
         void _endOfSixelLine();
         void _endOfCharacter();
 
-        std::tuple<size_t, size_t, size_t> _calculateDimensions() const;
+        std::tuple<VTInt, VTInt, VTInt> _calculateDimensions() const;
         void _packAndCenterBitPatterns() noexcept;
         void _fillUnusedCharacters();
         std::array<uint16_t, MAX_HEIGHT> _generateErrorGlyph();
@@ -57,22 +57,22 @@ namespace Microsoft::Console::VirtualTerminal
         VTInt _cellHeight;
         VTInt _pendingCellHeight;
         bool _sizeDeclaredAsMatrix;
-        size_t _declaredWidth;
-        size_t _declaredHeight;
-        size_t _usedWidth;
-        size_t _usedHeight;
-        size_t _fullWidth;
-        size_t _fullHeight;
-        size_t _textWidth;
-        size_t _textOffset;
+        VTInt _declaredWidth;
+        VTInt _declaredHeight;
+        VTInt _usedWidth;
+        VTInt _usedHeight;
+        VTInt _fullWidth;
+        VTInt _fullHeight;
+        VTInt _textWidth;
+        VTInt _textOffset;
         size_t _textCenteringHint;
 
         DispatchTypes::DrcsFontSet _fontSet;
         DispatchTypes::DrcsFontSet _pendingFontSet;
         DispatchTypes::DrcsFontUsage _fontUsage;
         DispatchTypes::DrcsFontUsage _pendingFontUsage;
-        size_t _linesPerPage;
-        size_t _columnsPerPage;
+        VTInt _linesPerPage;
+        VTInt _columnsPerPage;
         bool _isTextFont;
 
         DispatchTypes::DrcsCharsetSize _charsetSize;
@@ -81,15 +81,15 @@ namespace Microsoft::Console::VirtualTerminal
         VTID _pendingCharsetId{ 0 };
         bool _charsetIdInitialized;
         VTIDBuilder _charsetIdBuilder;
-        size_t _startChar;
-        size_t _lastChar;
-        size_t _currentChar;
+        VTInt _startChar;
+        VTInt _lastChar;
+        VTInt _currentChar;
 
         using buffer_type = std::array<uint16_t, MAX_HEIGHT * MAX_CHARS>;
         buffer_type _buffer;
         buffer_type::iterator _currentCharBuffer;
         bool _bufferCleared;
-        size_t _sixelColumn;
-        size_t _sixelRow;
+        VTInt _sixelColumn;
+        VTInt _sixelRow;
     };
 }
diff --git a/src/terminal/adapter/ITerminalApi.hpp b/src/terminal/adapter/ITerminalApi.hpp
index c805ec6e128..277a07fafdc 100644
--- a/src/terminal/adapter/ITerminalApi.hpp
+++ b/src/terminal/adapter/ITerminalApi.hpp
@@ -72,7 +72,7 @@ namespace Microsoft::Console::VirtualTerminal
         virtual void SetWorkingDirectory(const std::wstring_view uri) = 0;
         virtual void PlayMidiNote(const int noteNumber, const int velocity, const std::chrono::microseconds duration) = 0;
 
-        virtual bool ResizeWindow(const size_t width, const size_t height) = 0;
+        virtual bool ResizeWindow(const til::CoordType width, const til::CoordType height) = 0;
         virtual bool IsConsolePty() const = 0;
 
         virtual void NotifyAccessibilityChange(const til::rect& changedRect) = 0;
diff --git a/src/terminal/adapter/InteractDispatch.cpp b/src/terminal/adapter/InteractDispatch.cpp
index 303f8145d15..721f2652bc4 100644
--- a/src/terminal/adapter/InteractDispatch.cpp
+++ b/src/terminal/adapter/InteractDispatch.cpp
@@ -148,12 +148,10 @@ bool InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
     coordCursor.Y = std::clamp(coordCursor.Y, viewport.Top, viewport.Bottom);
     coordCursor.X = std::clamp(coordCursor.X, viewport.Left, viewport.Right);
 
-    const auto coordCursorShort = til::unwrap_coord(coordCursor);
-
     // Finally, attempt to set the adjusted cursor position back into the console.
     const auto api = gsl::not_null{ ServiceLocator::LocateGlobals().api };
     auto& info = ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer();
-    return SUCCEEDED(api->SetConsoleCursorPositionImpl(info, coordCursorShort));
+    return SUCCEEDED(api->SetConsoleCursorPositionImpl(info, coordCursor));
 }
 
 // Routine Description:
diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp
index 4d63b29338a..15cdb6e40c7 100644
--- a/src/terminal/adapter/adaptDispatch.cpp
+++ b/src/terminal/adapter/adaptDispatch.cpp
@@ -24,7 +24,6 @@ AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer& renderer, RenderSettin
     _isDECCOLMAllowed(false), // by default, DECCOLM is not allowed.
     _termOutput()
 {
-    _scrollMargins = { 0 }; // initially, there are no scroll margins.
 }
 
 // Routine Description:
@@ -198,8 +197,8 @@ bool AdaptDispatch::_CursorMovePosition(const Offset rowOffset, const Offset col
 
     // For relative movement, the given offsets will be relative to
     // the current cursor position.
-    int row = cursorPosition.Y;
-    int col = cursorPosition.X;
+    auto row = cursorPosition.Y;
+    auto col = cursorPosition.X;
 
     // But if the row is absolute, it will be relative to the top of the
     // viewport, or the top margin, depending on the origin mode.
@@ -218,8 +217,8 @@ bool AdaptDispatch::_CursorMovePosition(const Offset rowOffset, const Offset col
     // Adjust the base position by the given offsets and clamp the results.
     // The row is constrained within the viewport's vertical boundaries,
     // while the column is constrained by the buffer width.
-    row = std::clamp<int>(row + rowOffset.Value, viewport.top, viewport.bottom - 1);
-    col = std::clamp<int>(col + colOffset.Value, 0, textBuffer.GetSize().Width() - 1);
+    row = std::clamp(row + rowOffset.Value, viewport.top, viewport.bottom - 1);
+    col = std::clamp(col + colOffset.Value, 0, textBuffer.GetSize().Width() - 1);
 
     // If the operation needs to be clamped inside the margins, or the origin
     // mode is relative (which always requires margin clamping), then the row
@@ -245,8 +244,7 @@ bool AdaptDispatch::_CursorMovePosition(const Offset rowOffset, const Offset col
     }
 
     // Finally, attempt to set the adjusted cursor position back into the console.
-    const COORD newPos = { gsl::narrow_cast<SHORT>(col), gsl::narrow_cast<SHORT>(row) };
-    cursor.SetPosition(textBuffer.ClampPositionWithinLine(newPos));
+    cursor.SetPosition(textBuffer.ClampPositionWithinLine({ col, row }));
     _ApplyCursorMovementFlags(cursor);
 
     return true;
@@ -345,7 +343,7 @@ bool AdaptDispatch::CursorSaveState()
     // The cursor is given to us by the API as relative to the whole buffer.
     // But in VT speak, the cursor row should be relative to the current viewport top.
     auto cursorPosition = textBuffer.GetCursor().GetPosition();
-    cursorPosition.Y -= gsl::narrow_cast<short>(viewport.top);
+    cursorPosition.Y -= viewport.top;
 
     // VT is also 1 based, not 0 based, so correct by 1.
     auto& savedCursorState = _savedCursorState.at(_usingAltBuffer);
@@ -438,11 +436,11 @@ void AdaptDispatch::_ScrollRectVertically(TextBuffer& textBuffer, const til::rec
         // For now we're assuming the scrollRect is always the full width of the
         // buffer, but this will likely need to be extended to support scrolling
         // of arbitrary widths at some point in the future.
-        const auto top = gsl::narrow_cast<short>(delta > 0 ? scrollRect.top : (scrollRect.top + absoluteDelta));
-        const auto height = gsl::narrow_cast<short>(scrollRect.height() - absoluteDelta);
-        const auto actualDelta = gsl::narrow_cast<short>(delta > 0 ? absoluteDelta : -absoluteDelta);
+        const auto top = delta > 0 ? scrollRect.top : scrollRect.top + absoluteDelta;
+        const auto height = scrollRect.height() - absoluteDelta;
+        const auto actualDelta = delta > 0 ? absoluteDelta : -absoluteDelta;
         textBuffer.ScrollRows(top, height, actualDelta);
-        textBuffer.TriggerRedraw(Viewport::FromInclusive(scrollRect.to_small_rect()));
+        textBuffer.TriggerRedraw(Viewport::FromExclusive(scrollRect));
     }
 
     // Rows revealed by the scroll are filled with standard erase attributes.
@@ -470,11 +468,11 @@ void AdaptDispatch::_ScrollRectHorizontally(TextBuffer& textBuffer, const til::r
     const auto absoluteDelta = std::min(std::abs(delta), scrollRect.width());
     if (absoluteDelta < scrollRect.width())
     {
-        const auto left = gsl::narrow_cast<short>(delta > 0 ? scrollRect.left : (scrollRect.left + absoluteDelta));
-        const auto top = gsl::narrow_cast<short>(scrollRect.top);
-        const auto width = gsl::narrow_cast<short>(scrollRect.width() - absoluteDelta);
-        const auto height = gsl::narrow_cast<short>(scrollRect.height());
-        const auto actualDelta = gsl::narrow_cast<short>(delta > 0 ? absoluteDelta : -absoluteDelta);
+        const auto left = delta > 0 ? scrollRect.left : (scrollRect.left + absoluteDelta);
+        const auto top = scrollRect.top;
+        const auto width = scrollRect.width() - absoluteDelta;
+        const auto height = scrollRect.height();
+        const auto actualDelta = delta > 0 ? absoluteDelta : -absoluteDelta;
 
         const auto source = Viewport::FromDimensions({ left, top }, width, height);
         const auto target = Viewport::Offset(source, { actualDelta, 0 });
@@ -555,10 +553,10 @@ void AdaptDispatch::_FillRect(TextBuffer& textBuffer, const til::rect& fillRect,
     {
         const auto fillWidth = gsl::narrow_cast<size_t>(fillRect.right - fillRect.left);
         const auto fillData = OutputCellIterator{ fillChar, fillAttrs, fillWidth };
-        const auto col = gsl::narrow_cast<short>(fillRect.left);
-        for (auto row = gsl::narrow_cast<short>(fillRect.top); row < fillRect.bottom; row++)
+        const auto col = fillRect.left;
+        for (auto row = fillRect.top; row < fillRect.bottom; row++)
         {
-            textBuffer.WriteLine(fillData, COORD{ col, row }, false);
+            textBuffer.WriteLine(fillData, { col, row }, false);
         }
         _api.NotifyAccessibilityChange(fillRect);
     }
@@ -1298,13 +1296,11 @@ void AdaptDispatch::_DoSetTopBottomScrollingMargins(const VTInt topMargin,
     // having only a bottom param is legal      ([;3r   -> 0,3   -> 1,3  -> 1,3,true)
     // having neither uses the defaults         ([;r [r -> 0,0   -> 0,0  -> 0,0,false)
     // an illegal combo (eg, 3;2r) is ignored
-    SHORT actualTop = 0;
-    SHORT actualBottom = 0;
-    THROW_IF_FAILED(SizeTToShort(topMargin, &actualTop));
-    THROW_IF_FAILED(SizeTToShort(bottomMargin, &actualBottom));
+    til::CoordType actualTop = topMargin;
+    til::CoordType actualBottom = bottomMargin;
 
     const auto viewport = _api.GetViewport();
-    const auto screenHeight = gsl::narrow_cast<short>(viewport.bottom - viewport.top);
+    const auto screenHeight = viewport.bottom - viewport.top;
     // The default top margin is line 1
     if (actualTop == 0)
     {
@@ -1435,8 +1431,7 @@ bool AdaptDispatch::ReverseLineFeed()
     else if (cursorPosition.Y > viewport.top)
     {
         // Otherwise we move the cursor up, but not past the top of the viewport.
-        const COORD newCursorPosition{ cursorPosition.X, cursorPosition.Y - 1 };
-        cursor.SetPosition(textBuffer.ClampPositionWithinLine(newCursorPosition));
+        cursor.SetPosition(textBuffer.ClampPositionWithinLine({ cursorPosition.X, cursorPosition.Y - 1 }));
         _ApplyCursorMovementFlags(cursor);
     }
     return true;
@@ -1940,8 +1935,8 @@ bool AdaptDispatch::ScreenAlignmentPattern()
 void AdaptDispatch::_EraseScrollback()
 {
     const auto viewport = _api.GetViewport();
-    const auto top = gsl::narrow_cast<short>(viewport.top);
-    const auto height = gsl::narrow_cast<short>(viewport.bottom - viewport.top);
+    const auto top = viewport.top;
+    const auto height = viewport.bottom - viewport.top;
     auto& textBuffer = _api.GetTextBuffer();
     const auto bufferSize = textBuffer.GetSize().Dimensions();
     auto& cursor = textBuffer.GetCursor();
@@ -1975,7 +1970,7 @@ void AdaptDispatch::_EraseScrollback()
 void AdaptDispatch::_EraseAll()
 {
     const auto viewport = _api.GetViewport();
-    const auto viewportHeight = gsl::narrow_cast<short>(viewport.bottom - viewport.top);
+    const auto viewportHeight = viewport.bottom - viewport.top;
     auto& textBuffer = _api.GetTextBuffer();
     const auto bufferSize = textBuffer.GetSize();
 
@@ -1988,7 +1983,7 @@ void AdaptDispatch::_EraseAll()
     // Calculate new viewport position. Typically we want to move one line below
     // the last non-space row, but if the last non-space character is the very
     // start of the buffer, then we shouldn't move down at all.
-    const til::point lastChar{ textBuffer.GetLastNonSpaceCharacter() };
+    const auto lastChar = textBuffer.GetLastNonSpaceCharacter();
     auto newViewportTop = lastChar == til::point{} ? 0 : lastChar.Y + 1;
     const auto newViewportBottom = newViewportTop + viewportHeight;
     const auto delta = newViewportBottom - (bufferSize.Height());
@@ -2546,7 +2541,7 @@ ITermDispatch::StringHandler AdaptDispatch::DownloadDRCS(const VTInt fontNumber,
             const auto bitPattern = _fontBuffer->GetBitPattern();
             const auto cellSize = _fontBuffer->GetCellSize();
             const auto centeringHint = _fontBuffer->GetTextCenteringHint();
-            _renderer.UpdateSoftFont(bitPattern, cellSize.to_win32_size(), centeringHint);
+            _renderer.UpdateSoftFont(bitPattern, cellSize, centeringHint);
         }
         return true;
     };
diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp
index 9519de3a1a7..8475f181542 100644
--- a/src/terminal/adapter/ut_adapter/adapterTest.cpp
+++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp
@@ -92,7 +92,7 @@ class TestGetSet final : public ITerminalApi
 
     til::rect GetViewport() const override
     {
-        return til::rect{ _viewport.Left, _viewport.Top, _viewport.Right, _viewport.Bottom };
+        return { _viewport.Left, _viewport.Top, _viewport.Right, _viewport.Bottom };
     }
 
     void SetViewportPosition(const til::point /*position*/) override
@@ -182,7 +182,7 @@ class TestGetSet final : public ITerminalApi
         VERIFY_ARE_EQUAL(_expectedShowWindow, showOrHide);
     }
 
-    bool ResizeWindow(const size_t /*width*/, const size_t /*height*/) override
+    bool ResizeWindow(const til::CoordType /*width*/, const til::CoordType /*height*/) override
     {
         Log::Comment(L"ResizeWindow MOCK called...");
         return true;
@@ -269,7 +269,7 @@ class TestGetSet final : public ITerminalApi
         _setTextAttributesResult = TRUE;
         _returnResponseResult = TRUE;
 
-        _textBuffer = std::make_unique<TextBuffer>(COORD{ 100, 600 }, TextAttribute{}, 0, false, _renderer);
+        _textBuffer = std::make_unique<TextBuffer>(til::size{ 100, 600 }, TextAttribute{}, 0, false, _renderer);
 
         // Viewport sitting in the "middle" of the buffer somewhere (so all sides have excess buffer around them)
         _viewport.Top = 20;
@@ -327,13 +327,13 @@ class TestGetSet final : public ITerminalApi
             break;
         }
 
-        _textBuffer->GetCursor().SetPosition(til::unwrap_coord(cursorPos));
+        _textBuffer->GetCursor().SetPosition(cursorPos);
         _expectedCursorPos = cursorPos;
     }
 
     void ValidateExpectedCursorPos()
     {
-        VERIFY_ARE_EQUAL(_expectedCursorPos, til::point{ _textBuffer->GetCursor().GetPosition() });
+        VERIFY_ARE_EQUAL(_expectedCursorPos, _textBuffer->GetCursor().GetPosition());
     }
 
     void ValidateInputEvent(_In_ PCWSTR pwszExpectedResponse)
@@ -375,9 +375,9 @@ class TestGetSet final : public ITerminalApi
     StateMachine* _stateMachine;
     DummyRenderer _renderer;
     std::unique_ptr<TextBuffer> _textBuffer;
-    til::inclusive_rect _viewport = { 0, 0, 0, 0 };
-    til::inclusive_rect _expectedScrollRegion = { 0, 0, 0, 0 };
-    til::inclusive_rect _activeScrollRegion = { 0, 0, 0, 0 };
+    til::inclusive_rect _viewport;
+    til::inclusive_rect _expectedScrollRegion;
+    til::inclusive_rect _activeScrollRegion;
 
     til::point _expectedCursorPos;
 
@@ -1696,7 +1696,7 @@ class AdapterTest
         Log::Comment(L"Starting test...");
 
         til::inclusive_rect srTestMargins;
-        _testGetSet->_textBuffer = std::make_unique<TextBuffer>(COORD{ 100, 600 }, TextAttribute{}, 0, false, _testGetSet->_renderer);
+        _testGetSet->_textBuffer = std::make_unique<TextBuffer>(til::size{ 100, 600 }, TextAttribute{}, 0, false, _testGetSet->_renderer);
         _testGetSet->_viewport.Right = 8;
         _testGetSet->_viewport.Bottom = 8;
         auto sScreenHeight = _testGetSet->_viewport.Bottom - _testGetSet->_viewport.Top;
@@ -1998,7 +1998,7 @@ class AdapterTest
         using FontUsage = DispatchTypes::DrcsFontUsage;
 
         FontBuffer fontBuffer;
-        SIZE expectedCellSize;
+        til::size expectedCellSize;
 
         const auto decdld = [&](const auto cmw, const auto cmh, const auto ss, const auto u, const std::wstring_view data = {}) {
             const auto cellMatrix = static_cast<DispatchTypes::DrcsCellMatrix>(cmw);
@@ -2013,7 +2013,7 @@ class AdapterTest
             }
             RETURN_BOOL_IF_FALSE(fontBuffer.FinalizeSixelData());
 
-            const auto cellSize = fontBuffer.GetCellSize().to_win32_size();
+            const auto cellSize = fontBuffer.GetCellSize();
             Log::Comment(NoThrowString().Format(L"Cell size: %dx%d", cellSize.cx, cellSize.cy));
             VERIFY_ARE_EQUAL(expectedCellSize.cx, cellSize.cx);
             VERIFY_ARE_EQUAL(expectedCellSize.cy, cellSize.cy);
diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp
index 6c7bdf5e612..3b381aa5073 100644
--- a/src/terminal/parser/InputStateMachineEngine.cpp
+++ b/src/terminal/parser/InputStateMachineEngine.cpp
@@ -735,7 +735,8 @@ bool InputStateMachineEngine::_WriteMouseEvent(const til::point uiPos, const DWO
 {
     INPUT_RECORD rgInput;
     rgInput.EventType = MOUSE_EVENT;
-    rgInput.Event.MouseEvent.dwMousePosition = til::unwrap_coord(uiPos);
+    rgInput.Event.MouseEvent.dwMousePosition.X = ::base::saturated_cast<short>(uiPos.x);
+    rgInput.Event.MouseEvent.dwMousePosition.Y = ::base::saturated_cast<short>(uiPos.y);
     rgInput.Event.MouseEvent.dwButtonState = buttonState;
     rgInput.Event.MouseEvent.dwControlKeyState = controlKeyState;
     rgInput.Event.MouseEvent.dwEventFlags = eventFlags;
diff --git a/src/til/ut_til/PointTests.cpp b/src/til/ut_til/PointTests.cpp
index fca594abf13..cd069153c77 100644
--- a/src/til/ut_til/PointTests.cpp
+++ b/src/til/ut_til/PointTests.cpp
@@ -55,7 +55,7 @@ class PointTests
     {
         COORD coord{ -5, 10 };
 
-        const til::point pt{ coord };
+        const auto pt = til::wrap_coord(coord);
         VERIFY_ARE_EQUAL(coord.X, pt.x);
         VERIFY_ARE_EQUAL(coord.Y, pt.y);
     }
diff --git a/src/til/ut_til/RectangleTests.cpp b/src/til/ut_til/RectangleTests.cpp
index b59862db5a6..8709d1f8d66 100644
--- a/src/til/ut_til/RectangleTests.cpp
+++ b/src/til/ut_til/RectangleTests.cpp
@@ -130,7 +130,7 @@ class RectangleTests
         sr.Right = 14;
         sr.Bottom = 19;
 
-        const til::rect rc{ sr };
+        const til::rect rc{ til::wrap_small_rect(sr) };
         VERIFY_ARE_EQUAL(5, rc.left);
         VERIFY_ARE_EQUAL(10, rc.top);
         VERIFY_ARE_EQUAL(15, rc.right);
@@ -829,7 +829,7 @@ class RectangleTests
         Log::Comment(L"Typical situation.");
         {
             const til::rect rc{ 5, 10, 15, 20 };
-            const auto val = rc.to_small_rect();
+            const auto val = til::unwrap_small_rect(rc.to_inclusive_rect());
             VERIFY_ARE_EQUAL(5, val.Left);
             VERIFY_ARE_EQUAL(10, val.Top);
             VERIFY_ARE_EQUAL(14, val.Right);
@@ -845,7 +845,7 @@ class RectangleTests
             const til::rect rc{ l, t, r, b };
 
             auto fn = [&]() {
-                const auto val = rc.to_small_rect();
+                const auto val = til::unwrap_small_rect(rc.to_inclusive_rect());
             };
 
             VERIFY_THROWS(fn(), gsl::narrowing_error);
@@ -860,7 +860,7 @@ class RectangleTests
             const til::rect rc{ l, t, r, b };
 
             auto fn = [&]() {
-                const auto val = rc.to_small_rect();
+                const auto val = til::unwrap_small_rect(rc.to_inclusive_rect());
             };
 
             VERIFY_THROWS(fn(), gsl::narrowing_error);
@@ -875,7 +875,7 @@ class RectangleTests
             const til::rect rc{ l, t, r, b };
 
             auto fn = [&]() {
-                const auto val = rc.to_small_rect();
+                const auto val = til::unwrap_small_rect(rc.to_inclusive_rect());
             };
 
             VERIFY_THROWS(fn(), gsl::narrowing_error);
@@ -890,7 +890,7 @@ class RectangleTests
             const til::rect rc{ l, t, r, b };
 
             auto fn = [&]() {
-                const auto val = rc.to_small_rect();
+                const auto val = til::unwrap_small_rect(rc.to_inclusive_rect());
             };
 
             VERIFY_THROWS(fn(), gsl::narrowing_error);
diff --git a/src/til/ut_til/SizeTests.cpp b/src/til/ut_til/SizeTests.cpp
index 34122c69bc9..c2da636def5 100644
--- a/src/til/ut_til/SizeTests.cpp
+++ b/src/til/ut_til/SizeTests.cpp
@@ -55,7 +55,7 @@ class SizeTests
     {
         COORD coord{ -5, 10 };
 
-        const til::size sz{ coord };
+        const auto sz = til::wrap_coord_size(coord);
         VERIFY_ARE_EQUAL(coord.X, sz.width);
         VERIFY_ARE_EQUAL(coord.Y, sz.height);
     }
diff --git a/src/types/IBaseData.h b/src/types/IBaseData.h
index 676994cab57..7434f718baf 100644
--- a/src/types/IBaseData.h
+++ b/src/types/IBaseData.h
@@ -35,7 +35,7 @@ namespace Microsoft::Console::Types
 
     public:
         virtual Microsoft::Console::Types::Viewport GetViewport() noexcept = 0;
-        virtual COORD GetTextBufferEndPosition() const noexcept = 0;
+        virtual til::point GetTextBufferEndPosition() const noexcept = 0;
         virtual const TextBuffer& GetTextBuffer() const noexcept = 0;
         virtual const FontInfo& GetFontInfo() const noexcept = 0;
 
diff --git a/src/types/IControlAccessibilityInfo.h b/src/types/IControlAccessibilityInfo.h
index de3a3eeecf5..0b75be989ba 100644
--- a/src/types/IControlAccessibilityInfo.h
+++ b/src/types/IControlAccessibilityInfo.h
@@ -24,11 +24,11 @@ namespace Microsoft::Console::Types
     public:
         virtual ~IControlAccessibilityInfo() = 0;
 
-        virtual COORD GetFontSize() const noexcept = 0;
-        virtual RECT GetBounds() const noexcept = 0;
-        virtual RECT GetPadding() const noexcept = 0;
+        virtual til::size GetFontSize() const noexcept = 0;
+        virtual til::rect GetBounds() const noexcept = 0;
+        virtual til::rect GetPadding() const noexcept = 0;
         virtual double GetScaleFactor() const noexcept = 0;
-        virtual void ChangeViewport(const SMALL_RECT NewWindow) = 0;
+        virtual void ChangeViewport(const til::inclusive_rect& NewWindow) = 0;
         virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) = 0;
 
     protected:
diff --git a/src/types/IUiaData.h b/src/types/IUiaData.h
index de89520c72f..b453d87209b 100644
--- a/src/types/IUiaData.h
+++ b/src/types/IUiaData.h
@@ -37,10 +37,10 @@ namespace Microsoft::Console::Types
         virtual const bool IsSelectionActive() const = 0;
         virtual const bool IsBlockSelection() const = 0;
         virtual void ClearSelection() = 0;
-        virtual void SelectNewRegion(const COORD coordStart, const COORD coordEnd) = 0;
-        virtual const COORD GetSelectionAnchor() const noexcept = 0;
-        virtual const COORD GetSelectionEnd() const noexcept = 0;
-        virtual void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr) = 0;
+        virtual void SelectNewRegion(const til::point coordStart, const til::point coordEnd) = 0;
+        virtual const til::point GetSelectionAnchor() const noexcept = 0;
+        virtual const til::point GetSelectionEnd() const noexcept = 0;
+        virtual void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute attr) = 0;
         virtual const bool IsUiaDataInitialized() const noexcept = 0;
     };
 
diff --git a/src/types/MouseEvent.cpp b/src/types/MouseEvent.cpp
index d763111a901..39a6c720032 100644
--- a/src/types/MouseEvent.cpp
+++ b/src/types/MouseEvent.cpp
@@ -12,7 +12,8 @@ INPUT_RECORD MouseEvent::ToInputRecord() const noexcept
 {
     INPUT_RECORD record{ 0 };
     record.EventType = MOUSE_EVENT;
-    record.Event.MouseEvent.dwMousePosition = _position;
+    record.Event.MouseEvent.dwMousePosition.X = ::base::saturated_cast<short>(_position.x);
+    record.Event.MouseEvent.dwMousePosition.Y = ::base::saturated_cast<short>(_position.y);
     record.Event.MouseEvent.dwButtonState = _buttonState;
     record.Event.MouseEvent.dwControlKeyState = _activeModifierKeys;
     record.Event.MouseEvent.dwEventFlags = _eventFlags;
@@ -24,7 +25,7 @@ InputEventType MouseEvent::EventType() const noexcept
     return InputEventType::MouseEvent;
 }
 
-void MouseEvent::SetPosition(const COORD position) noexcept
+void MouseEvent::SetPosition(const til::point position) noexcept
 {
     _position = position;
 }
diff --git a/src/types/ScreenInfoUiaProviderBase.cpp b/src/types/ScreenInfoUiaProviderBase.cpp
index fab48df6e29..6c9a8f42e7b 100644
--- a/src/types/ScreenInfoUiaProviderBase.cpp
+++ b/src/types/ScreenInfoUiaProviderBase.cpp
@@ -287,8 +287,8 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
     const auto bufferSize = _pData->GetTextBuffer().GetSize();
     const auto viewport = bufferSize.ConvertToOrigin(_getViewport());
 
-    const COORD start{ viewport.Left(), viewport.Top() };
-    const COORD end{ viewport.Left(), viewport.BottomExclusive() };
+    const til::point start{ viewport.Left(), viewport.Top() };
+    const til::point end{ viewport.Left(), viewport.BottomExclusive() };
 
     auto hr = CreateTextRange(this, start, end, _wordDelimiters, &range);
     if (FAILED(hr))
@@ -365,7 +365,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::get_SupportedTextSelection(_Out_ Suppo
 
 #pragma endregion
 
-const COORD ScreenInfoUiaProviderBase::_getScreenBufferCoords() const noexcept
+til::size ScreenInfoUiaProviderBase::_getScreenBufferCoords() const noexcept
 {
     return _getTextBuffer().GetSize().Dimensions();
 }
@@ -375,7 +375,7 @@ const TextBuffer& ScreenInfoUiaProviderBase::_getTextBuffer() const noexcept
     return _pData->GetTextBuffer();
 }
 
-const Viewport ScreenInfoUiaProviderBase::_getViewport() const noexcept
+Viewport ScreenInfoUiaProviderBase::_getViewport() const noexcept
 {
     return _pData->GetViewport();
 }
diff --git a/src/types/ScreenInfoUiaProviderBase.h b/src/types/ScreenInfoUiaProviderBase.h
index eda5bf4d921..0ca1394cdd4 100644
--- a/src/types/ScreenInfoUiaProviderBase.h
+++ b/src/types/ScreenInfoUiaProviderBase.h
@@ -48,7 +48,7 @@ namespace Microsoft::Console::Types
         ~ScreenInfoUiaProviderBase() = default;
 
         [[nodiscard]] HRESULT Signal(_In_ EVENTID id);
-        virtual void ChangeViewport(const SMALL_RECT NewWindow) = 0;
+        virtual void ChangeViewport(const til::inclusive_rect& NewWindow) = 0;
 
         // IRawElementProviderSimple methods
         IFACEMETHODIMP get_ProviderOptions(_Out_ ProviderOptions* pOptions) noexcept override;
@@ -93,8 +93,8 @@ namespace Microsoft::Console::Types
 
         // specific endpoint range
         virtual HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const pProvider,
-                                        const COORD start,
-                                        const COORD end,
+                                        const til::point start,
+                                        const til::point end,
                                         const std::wstring_view wordDelimiters,
                                         _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr) = 0;
 
@@ -123,9 +123,9 @@ namespace Microsoft::Console::Types
         // mechanism for multi-threaded code.
         std::unordered_map<EVENTID, bool> _signalFiringMapping{};
 
-        const COORD _getScreenBufferCoords() const noexcept;
+        til::size _getScreenBufferCoords() const noexcept;
         const TextBuffer& _getTextBuffer() const noexcept;
-        const Viewport _getViewport() const noexcept;
+        Viewport _getViewport() const noexcept;
         void _LockConsole() noexcept;
         void _UnlockConsole() noexcept;
     };
diff --git a/src/types/TermControlUiaProvider.cpp b/src/types/TermControlUiaProvider.cpp
index 39c0e13fff0..01f8864b122 100644
--- a/src/types/TermControlUiaProvider.cpp
+++ b/src/types/TermControlUiaProvider.cpp
@@ -89,12 +89,12 @@ IFACEMETHODIMP TermControlUiaProvider::get_FragmentRoot(_COM_Outptr_result_maybe
     return S_OK;
 }
 
-const COORD TermControlUiaProvider::GetFontSize() const noexcept
+const til::size TermControlUiaProvider::GetFontSize() const noexcept
 {
     return _controlInfo->GetFontSize();
 }
 
-const RECT TermControlUiaProvider::GetPadding() const noexcept
+const til::rect TermControlUiaProvider::GetPadding() const noexcept
 {
     return _controlInfo->GetPadding();
 }
@@ -104,7 +104,7 @@ const double TermControlUiaProvider::GetScaleFactor() const noexcept
     return _controlInfo->GetScaleFactor();
 }
 
-void TermControlUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
+void TermControlUiaProvider::ChangeViewport(const til::inclusive_rect& NewWindow)
 {
     _controlInfo->ChangeViewport(NewWindow);
 }
@@ -150,8 +150,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple*
 }
 
 HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* const pProvider,
-                                                const COORD start,
-                                                const COORD end,
+                                                const til::point start,
+                                                const til::point end,
                                                 const std::wstring_view wordDelimiters,
                                                 _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr)
 {
diff --git a/src/types/TermControlUiaProvider.hpp b/src/types/TermControlUiaProvider.hpp
index 4e2131267da..8b6f80a40fb 100644
--- a/src/types/TermControlUiaProvider.hpp
+++ b/src/types/TermControlUiaProvider.hpp
@@ -39,10 +39,10 @@ namespace Microsoft::Terminal
         IFACEMETHODIMP get_BoundingRectangle(_Out_ UiaRect* pRect) noexcept override;
         IFACEMETHODIMP get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) noexcept override;
 
-        const COORD GetFontSize() const noexcept;
-        const RECT GetPadding() const noexcept;
+        const til::size GetFontSize() const noexcept;
+        const til::rect GetPadding() const noexcept;
         const double GetScaleFactor() const noexcept;
-        void ChangeViewport(const SMALL_RECT NewWindow) override;
+        void ChangeViewport(const til::inclusive_rect& NewWindow) override;
 
     protected:
         HRESULT GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
@@ -58,8 +58,8 @@ namespace Microsoft::Terminal
 
         // specific endpoint range
         HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const pProvider,
-                                const COORD start,
-                                const COORD end,
+                                const til::point start,
+                                const til::point end,
                                 const std::wstring_view wordDelimiters,
                                 _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
 
diff --git a/src/types/TermControlUiaTextRange.cpp b/src/types/TermControlUiaTextRange.cpp
index 97a5ca41f04..d200cad6bd9 100644
--- a/src/types/TermControlUiaTextRange.cpp
+++ b/src/types/TermControlUiaTextRange.cpp
@@ -25,8 +25,8 @@ HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
 
 HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
                                                         _In_ IRawElementProviderSimple* const pProvider,
-                                                        const COORD start,
-                                                        const COORD end,
+                                                        const til::point start,
+                                                        const til::point end,
                                                         bool blockRange,
                                                         const std::wstring_view wordDelimiters) noexcept
 {
@@ -73,7 +73,7 @@ IFACEMETHODIMP TermControlUiaTextRange::Clone(_Outptr_result_maybenull_ ITextRan
 //                (0,0) is the top-left of the app window
 // Return Value:
 // - <none>
-void TermControlUiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
+void TermControlUiaTextRange::_TranslatePointToScreen(til::point* clientPoint) const
 {
     const gsl::not_null<TermControlUiaProvider*> provider = static_cast<TermControlUiaProvider*>(_pProvider);
 
@@ -107,7 +107,7 @@ void TermControlUiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
 //                (0,0) is the top-left of the screen
 // Return Value:
 // - <none>
-void TermControlUiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) const
+void TermControlUiaTextRange::_TranslatePointFromScreen(til::point* screenPoint) const
 {
     const gsl::not_null<TermControlUiaProvider*> provider = static_cast<TermControlUiaProvider*>(_pProvider);
 
@@ -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 noexcept
+til::size 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
diff --git a/src/types/TermControlUiaTextRange.hpp b/src/types/TermControlUiaTextRange.hpp
index 42afc210b77..ce2cf7ecc0d 100644
--- a/src/types/TermControlUiaTextRange.hpp
+++ b/src/types/TermControlUiaTextRange.hpp
@@ -39,8 +39,8 @@ namespace Microsoft::Terminal
         // specific endpoint range
         HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
                                        _In_ IRawElementProviderSimple* const pProvider,
-                                       const COORD start,
-                                       const COORD end,
+                                       const til::point start,
+                                       const til::point end,
                                        bool blockRange = false,
                                        const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
 
@@ -55,8 +55,8 @@ namespace Microsoft::Terminal
         IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
 
     protected:
-        void _TranslatePointToScreen(LPPOINT clientPoint) const override;
-        void _TranslatePointFromScreen(LPPOINT screenPoint) const override;
-        const COORD _getScreenFontSize() const noexcept override;
+        void _TranslatePointToScreen(til::point* clientPoint) const override;
+        void _TranslatePointFromScreen(til::point* screenPoint) const override;
+        til::size _getScreenFontSize() const noexcept override;
     };
 }
diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp
index e9dd19912ce..1202b7a34da 100644
--- a/src/types/UiaTextRangeBase.cpp
+++ b/src/types/UiaTextRangeBase.cpp
@@ -61,8 +61,8 @@ CATCH_RETURN();
 #pragma warning(suppress : 26434) // WRL RuntimeClassInitialize base is a no-op and we need this for MakeAndInitialize
 HRESULT UiaTextRangeBase::RuntimeClassInitialize(_In_ IUiaData* pData,
                                                  _In_ IRawElementProviderSimple* const pProvider,
-                                                 _In_ const COORD start,
-                                                 _In_ const COORD end,
+                                                 _In_ const til::point start,
+                                                 _In_ const til::point end,
                                                  _In_ bool blockRange,
                                                  _In_ std::wstring_view wordDelimiters) noexcept
 try
@@ -93,13 +93,13 @@ CATCH_RETURN();
 
 void UiaTextRangeBase::Initialize(_In_ const UiaPoint point)
 {
-    POINT clientPoint;
+    til::point clientPoint;
     clientPoint.x = static_cast<LONG>(point.x);
     clientPoint.y = static_cast<LONG>(point.y);
     // get row that point resides in
     const auto windowRect = _getTerminalRect();
     const auto viewport = _pData->GetViewport().ToInclusive();
-    short row = 0;
+    til::CoordType row = 0;
     if (clientPoint.y <= windowRect.top)
     {
         row = viewport.Top;
@@ -114,7 +114,7 @@ void UiaTextRangeBase::Initialize(_In_ const UiaPoint point)
         _TranslatePointFromScreen(&clientPoint);
 
         const auto currentFontSize = _getScreenFontSize();
-        row = gsl::narrow<SHORT>(clientPoint.y / static_cast<LONG>(currentFontSize.Y)) + viewport.Top;
+        row = clientPoint.y / currentFontSize.Y + viewport.Top;
     }
     _start = { 0, row };
     _end = _start;
@@ -136,7 +136,7 @@ try
 }
 CATCH_RETURN();
 
-const COORD UiaTextRangeBase::GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept
+til::point UiaTextRangeBase::GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept
 {
     switch (endpoint)
     {
@@ -149,14 +149,14 @@ const COORD UiaTextRangeBase::GetEndpoint(TextPatternRangeEndpoint endpoint) con
 }
 
 // Routine Description:
-// - sets the target endpoint to the given COORD value
+// - sets the target endpoint to the given til::point value
 // - if the target endpoint crosses the other endpoint, become a degenerate range
 // Arguments:
 // - endpoint - the target endpoint (start or end)
 // - val - the value that it will be set to
 // Return Value:
 // - true if range is degenerate, false otherwise.
-bool UiaTextRangeBase::SetEndpoint(TextPatternRangeEndpoint endpoint, const COORD val) noexcept
+bool UiaTextRangeBase::SetEndpoint(TextPatternRangeEndpoint endpoint, const til::point val) noexcept
 {
     // GH#6402: Get the actual buffer size here, instead of the one
     //          constrained by the virtual bottom.
@@ -193,7 +193,7 @@ bool UiaTextRangeBase::SetEndpoint(TextPatternRangeEndpoint endpoint, const COOR
 // - <none>
 // Return Value:
 // - true if range is degenerate, false otherwise.
-const bool UiaTextRangeBase::IsDegenerate() const noexcept
+bool UiaTextRangeBase::IsDegenerate() const noexcept
 {
     return _start == _end;
 }
@@ -293,16 +293,16 @@ void UiaTextRangeBase::_expandToEnclosingUnit(TextUnit unit)
     // If we're past document end,
     // set us to ONE BEFORE the document end.
     // This allows us to expand properly.
-    if (bufferSize.CompareInBounds(_start, documentEnd.to_win32_coord(), true) >= 0)
+    if (bufferSize.CompareInBounds(_start, documentEnd, true) >= 0)
     {
-        _start = documentEnd.to_win32_coord();
+        _start = documentEnd;
         bufferSize.DecrementInBounds(_start, true);
     }
 
     if (unit == TextUnit_Character)
     {
-        _start = buffer.GetGlyphStart(til::point{ _start }, documentEnd).to_win32_coord();
-        _end = buffer.GetGlyphEnd(til::point{ _start }, true, documentEnd).to_win32_coord();
+        _start = buffer.GetGlyphStart(_start, documentEnd);
+        _end = buffer.GetGlyphEnd(_start, true, documentEnd);
     }
     else if (unit <= TextUnit_Word)
     {
@@ -317,20 +317,20 @@ void UiaTextRangeBase::_expandToEnclosingUnit(TextUnit unit)
         if (_start.Y == documentEnd.y)
         {
             // we're on the last line
-            _end = documentEnd.to_win32_coord();
+            _end = documentEnd;
             bufferSize.IncrementInBounds(_end, true);
         }
         else
         {
             _end.X = 0;
-            _end.Y = base::ClampAdd(_start.Y, 1);
+            _end.Y = _start.Y + 1;
         }
     }
     else
     {
         // expand to document
         _start = bufferSize.Origin();
-        _end = documentEnd.to_win32_coord();
+        _end = documentEnd;
     }
 }
 
@@ -515,8 +515,8 @@ try
     // NOTE: we store these as "first" and "second" anchor because,
     //       we just want to know what the inclusive range is.
     //       We'll do some post-processing to fix this on the way out.
-    std::optional<COORD> resultFirstAnchor;
-    std::optional<COORD> resultSecondAnchor;
+    std::optional<til::point> resultFirstAnchor;
+    std::optional<til::point> resultSecondAnchor;
     const auto attemptUpdateAnchors = [=, &resultFirstAnchor, &resultSecondAnchor](const TextBufferCellIterator iter) {
         const auto attrFound{ _verifyAttr(attributeId, val, iter->TextAttr()).value() };
         if (attrFound)
@@ -554,13 +554,14 @@ try
 
     // Iterate from searchStart to searchEnd in the buffer.
     // If we find the attribute we're looking for, we update resultFirstAnchor/SecondAnchor appropriately.
+#pragma warning(suppress : 26496) // TRANSITIONAL: false positive in VS 16.11
     auto viewportRange{ bufferSize };
     if (_blockRange)
     {
         const auto originX{ std::min(_start.X, inclusiveEnd.X) };
         const auto originY{ std::min(_start.Y, inclusiveEnd.Y) };
-        const auto width{ gsl::narrow_cast<short>(std::abs(inclusiveEnd.X - _start.X + 1)) };
-        const auto height{ gsl::narrow_cast<short>(std::abs(inclusiveEnd.Y - _start.Y + 1)) };
+        const auto width{ std::abs(inclusiveEnd.X - _start.X + 1) };
+        const auto height{ std::abs(inclusiveEnd.Y - _start.Y + 1) };
         viewportRange = Viewport::FromDimensions({ originX, originY }, width, height);
     }
     auto iter{ buffer.GetCellDataAt(searchStart, viewportRange) };
@@ -635,7 +636,7 @@ try
         searchDirection = Search::Direction::Backward;
 
         // we need to convert the end to inclusive
-        // because Search operates with an inclusive COORD
+        // because Search operates with an inclusive til::point
         searchAnchor = _end;
         bufferSize.DecrementInBounds(searchAnchor, true);
     }
@@ -812,13 +813,14 @@ try
     const auto inclusiveEnd{ _getInclusiveEnd() };
 
     // Check if the entire text range has that text attribute
+#pragma warning(suppress : 26496) // TRANSITIONAL: false positive in VS 16.11
     auto viewportRange{ bufferSize };
     if (_blockRange)
     {
         const auto originX{ std::min(_start.X, inclusiveEnd.X) };
         const auto originY{ std::min(_start.Y, inclusiveEnd.Y) };
-        const auto width{ gsl::narrow_cast<short>(std::abs(inclusiveEnd.X - _start.X + 1)) };
-        const auto height{ gsl::narrow_cast<short>(std::abs(inclusiveEnd.Y - _start.Y + 1)) };
+        const auto width{ std::abs(inclusiveEnd.X - _start.X + 1) };
+        const auto height{ std::abs(inclusiveEnd.Y - _start.Y + 1) };
         viewportRange = Viewport::FromDimensions({ originX, originY }, width, height);
     }
     auto iter{ buffer.GetCellDataAt(_start, viewportRange) };
@@ -868,7 +870,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
         const auto viewportOrigin = viewport.Origin();
         const auto viewportEnd = viewport.EndExclusive();
 
-        // startAnchor: the earliest COORD we will get a bounding rect for
+        // startAnchor: the earliest til::point we will get a bounding rect for
         auto startAnchor = GetEndpoint(TextPatternRangeEndpoint_Start);
         if (bufferSize.CompareInBounds(startAnchor, viewportOrigin, true) < 0)
         {
@@ -876,7 +878,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
             startAnchor = viewportOrigin;
         }
 
-        // endAnchor: the latest COORD we will get a bounding rect for
+        // endAnchor: the latest til::point we will get a bounding rect for
         auto endAnchor = GetEndpoint(TextPatternRangeEndpoint_End);
         if (bufferSize.CompareInBounds(endAnchor, viewportEnd, true) > 0)
         {
@@ -907,7 +909,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
                 // screen cells, taking line rendition into account.
                 const auto lineRendition = buffer.GetLineRendition(rect.Top);
                 til::rect r{ BufferToScreenLine(rect, lineRendition) };
-                r -= til::point{ viewportOrigin };
+                r -= viewportOrigin;
                 _getBoundingRect(r, coords);
             }
         }
@@ -919,7 +921,8 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
             return E_OUTOFMEMORY;
         }
         auto hr = E_UNEXPECTED;
-        for (LONG i = 0; i < gsl::narrow<LONG>(coords.size()); ++i)
+        const auto l = gsl::narrow<LONG>(coords.size());
+        for (LONG i = 0; i < l; ++i)
         {
             hr = SafeArrayPutElement(*ppRetVal, &i, &coords.at(i));
             if (FAILED(hr))
@@ -961,10 +964,7 @@ try
     });
     RETURN_HR_IF(E_FAIL, !_pData->IsUiaDataInitialized());
 
-    const auto maxLengthOpt = (maxLength == -1) ?
-                                  std::nullopt :
-                                  std::optional<unsigned int>{ maxLength };
-    const auto text = _getTextValue(maxLengthOpt);
+    const auto text = _getTextValue(maxLength);
     Unlock.reset();
 
     *pRetVal = SysAllocString(text.c_str());
@@ -983,7 +983,7 @@ CATCH_RETURN();
 // - the text that the UiaTextRange encompasses
 #pragma warning(push)
 #pragma warning(disable : 26447) // compiler isn't filtering throws inside the try/catch
-std::wstring UiaTextRangeBase::_getTextValue(std::optional<unsigned int> maxLength) const
+std::wstring UiaTextRangeBase::_getTextValue(til::CoordType maxLength) const
 {
     std::wstring textData{};
     if (!IsDegenerate())
@@ -1008,7 +1008,7 @@ std::wstring UiaTextRangeBase::_getTextValue(std::optional<unsigned int> maxLeng
                                                false,
                                                textRects);
 
-        const size_t textDataSize = base::ClampMul(bufferData.text.size(), bufferSize.Width());
+        const size_t textDataSize = bufferData.text.size() * bufferSize.Width();
         textData.reserve(textDataSize);
         for (const auto& text : bufferData.text)
         {
@@ -1016,9 +1016,9 @@ std::wstring UiaTextRangeBase::_getTextValue(std::optional<unsigned int> maxLeng
         }
     }
 
-    if (maxLength.has_value())
+    if (maxLength >= 0)
     {
-        textData.resize(*maxLength);
+        textData.resize(maxLength);
     }
 
     return textData;
@@ -1044,7 +1044,7 @@ try
     // If so, clamp each endpoint to the end of the document.
     constexpr auto endpoint = TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start;
     const auto bufferSize{ _pData->GetTextBuffer().GetSize() };
-    const auto documentEnd = _getDocumentEnd().to_win32_coord();
+    const auto documentEnd = _getDocumentEnd();
     if (bufferSize.CompareInBounds(_start, documentEnd, true) > 0)
     {
         _start = documentEnd;
@@ -1115,7 +1115,7 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByUnit(_In_ TextPatternRangeEndpoin
     auto documentEnd = bufferSize.EndExclusive();
     try
     {
-        documentEnd = _getDocumentEnd().to_win32_coord();
+        documentEnd = _getDocumentEnd();
     }
     CATCH_LOG();
 
@@ -1239,11 +1239,11 @@ try
     const auto oldViewport = _pData->GetViewport().ToInclusive();
     const auto viewportHeight = _getViewportHeight(oldViewport);
     // range rows
-    const base::ClampedNumeric<short> startScreenInfoRow = _start.Y;
-    const base::ClampedNumeric<short> endScreenInfoRow = _end.Y;
+    const auto startScreenInfoRow = _start.Y;
+    const auto endScreenInfoRow = _end.Y;
     // screen buffer rows
-    const base::ClampedNumeric<short> topRow = 0;
-    const base::ClampedNumeric<short> bottomRow = _pData->GetTextBuffer().TotalRowCount() - 1;
+    const til::CoordType topRow = 0;
+    const auto bottomRow = _pData->GetTextBuffer().TotalRowCount() - 1;
 
     auto newViewport = oldViewport;
 
@@ -1270,7 +1270,7 @@ try
     {
         // we need to align to the bottom
         // check if we can align to the bottom
-        if (static_cast<unsigned int>(endScreenInfoRow) >= viewportHeight)
+        if (endScreenInfoRow >= viewportHeight)
         {
             // GH#7839: endScreenInfoRow may be ExclusiveEnd
             //          ExclusiveEnd is past the bottomRow
@@ -1278,7 +1278,7 @@ try
 
             // we can align to bottom
             newViewport.Bottom = std::min(endScreenInfoRow, bottomRow);
-            newViewport.Top = base::ClampedNumeric<short>(newViewport.Bottom) - viewportHeight + 1;
+            newViewport.Top = newViewport.Bottom - viewportHeight + 1;
         }
         else
         {
@@ -1319,13 +1319,13 @@ IFACEMETHODIMP UiaTextRangeBase::GetChildren(_Outptr_result_maybenull_ SAFEARRAY
 
 #pragma endregion
 
-const COORD UiaTextRangeBase::_getScreenFontSize() const noexcept
+til::size UiaTextRangeBase::_getScreenFontSize() const noexcept
 {
     auto coordRet = _pData->GetFontInfo().GetSize();
 
     // For sanity's sake, make sure not to leak 0 out as a possible value. These values are used in division operations.
-    coordRet.X = std::max(coordRet.X, 1i16);
-    coordRet.Y = std::max(coordRet.Y, 1i16);
+    coordRet.X = std::max(coordRet.X, 1);
+    coordRet.Y = std::max(coordRet.Y, 1);
 
     return coordRet;
 }
@@ -1336,10 +1336,10 @@ const COORD UiaTextRangeBase::_getScreenFontSize() const noexcept
 // - viewport - The viewport to measure
 // Return Value:
 // - The viewport height
-const unsigned int UiaTextRangeBase::_getViewportHeight(const SMALL_RECT viewport) const noexcept
+til::CoordType UiaTextRangeBase::_getViewportHeight(const til::inclusive_rect& viewport) const noexcept
 {
     FAIL_FAST_IF(!(viewport.Bottom >= viewport.Top));
-    // + 1 because COORD is inclusive on both sides so subtracting top
+    // + 1 because til::inclusive_rect is inclusive on both sides so subtracting top
     // and bottom gets rid of 1 more then it should.
     return viewport.Bottom - viewport.Top + 1;
 }
@@ -1352,13 +1352,13 @@ const unsigned int UiaTextRangeBase::_getViewportHeight(const SMALL_RECT viewpor
 // - <none>
 // Return Value:
 // - A viewport representing the portion of the TextBuffer that has valid text
-const Viewport UiaTextRangeBase::_getOptimizedBufferSize() const noexcept
+Viewport UiaTextRangeBase::_getOptimizedBufferSize() const noexcept
 {
     // we need to add 1 to the X/Y of textBufferEnd
-    // because we want the returned viewport to include this COORD
+    // because we want the returned viewport to include this til::point
     const auto textBufferEnd = _pData->GetTextBufferEndPosition();
-    const auto width = base::ClampAdd<short>(1, textBufferEnd.X);
-    const auto height = base::ClampAdd<short>(1, textBufferEnd.Y);
+    const auto width = textBufferEnd.X + 1;
+    const auto height = textBufferEnd.Y + 1;
 
     return Viewport::FromDimensions({ 0, 0 }, width, height);
 }
@@ -1368,7 +1368,7 @@ const Viewport UiaTextRangeBase::_getOptimizedBufferSize() const noexcept
 // the last legible character is on the last line of the buffer,
 // we use the "end exclusive" position (left-most point on a line one past the end of the buffer).
 // NOTE: "end exclusive" is naturally computed using the heuristic above.
-const til::point UiaTextRangeBase::_getDocumentEnd() const
+til::point UiaTextRangeBase::_getDocumentEnd() const
 {
     const auto optimizedBufferSize{ _getOptimizedBufferSize() };
     const auto& buffer{ _pData->GetTextBuffer() };
@@ -1389,26 +1389,26 @@ const til::point UiaTextRangeBase::_getDocumentEnd() const
 // - <none>
 void UiaTextRangeBase::_getBoundingRect(const til::rect& textRect, _Inout_ std::vector<double>& coords) const
 {
-    const til::size currentFontSize{ _getScreenFontSize() };
+    const auto currentFontSize = _getScreenFontSize();
 
-    POINT topLeft{ 0 };
-    POINT bottomRight{ 0 };
+    til::point topLeft;
+    til::point bottomRight;
 
     // we want to clamp to a long (output type), not a short (input type)
     // so we need to explicitly say <long,long>
-    topLeft.x = base::ClampMul(textRect.left, currentFontSize.width);
-    topLeft.y = base::ClampMul(textRect.top, currentFontSize.height);
+    topLeft.x = textRect.left * currentFontSize.X;
+    topLeft.y = textRect.top * currentFontSize.Y;
 
-    bottomRight.x = base::ClampMul(textRect.right, currentFontSize.width);
-    bottomRight.y = base::ClampMul(textRect.bottom, currentFontSize.height);
+    bottomRight.x = textRect.right * currentFontSize.X;
+    bottomRight.y = textRect.bottom * currentFontSize.Y;
 
     // convert the coords to be relative to the screen instead of
     // the client window
     _TranslatePointToScreen(&topLeft);
     _TranslatePointToScreen(&bottomRight);
 
-    const long width = base::ClampSub(bottomRight.x, topLeft.x);
-    const long height = base::ClampSub(bottomRight.y, topLeft.y);
+    const long width = bottomRight.x - topLeft.x;
+    const long height = bottomRight.y - topLeft.y;
 
     // insert the coords
     coords.push_back(topLeft.x);
@@ -1471,7 +1471,7 @@ void UiaTextRangeBase::_moveEndpointByUnitCharacter(_In_ const int moveCount,
         }
     }
 
-    SetEndpoint(endpoint, target.to_win32_coord());
+    SetEndpoint(endpoint, target);
 }
 
 // Routine Description:
@@ -1516,7 +1516,7 @@ void UiaTextRangeBase::_moveEndpointByUnitWord(_In_ const int moveCount,
         {
         case MovementDirection::Forward:
         {
-            if (bufferSize.CompareInBounds(nextPos, documentEnd.to_win32_coord(), true) >= 0)
+            if (bufferSize.CompareInBounds(nextPos, documentEnd, true) >= 0)
             {
                 success = false;
             }
@@ -1527,7 +1527,7 @@ void UiaTextRangeBase::_moveEndpointByUnitWord(_In_ const int moveCount,
             }
             else if (allowBottomExclusive)
             {
-                resultPos = documentEnd.to_win32_coord();
+                resultPos = documentEnd;
                 (*pAmountMoved)++;
             }
             else
@@ -1578,7 +1578,7 @@ void UiaTextRangeBase::_moveEndpointByUnitWord(_In_ const int moveCount,
 // Return Value:
 // - true --> we were not at the beginning of the word, and we updated resultingPos to be so
 // - false --> otherwise (we're already at the beginning of the word)
-bool UiaTextRangeBase::_tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, COORD& resultingPos) const
+bool UiaTextRangeBase::_tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, til::point& resultingPos) const
 {
     const auto wordStart{ buffer.GetWordStart(resultingPos, _wordDelimiters, true, documentEnd) };
     if (resultingPos != wordStart)
@@ -1621,7 +1621,7 @@ void UiaTextRangeBase::_moveEndpointByUnitLine(_In_ const int moveCount,
     auto documentEnd{ bufferSize.EndExclusive() };
     try
     {
-        documentEnd = _getDocumentEnd().to_win32_coord();
+        documentEnd = _getDocumentEnd();
     }
     CATCH_LOG();
 
@@ -1642,7 +1642,7 @@ void UiaTextRangeBase::_moveEndpointByUnitLine(_In_ const int moveCount,
                 resultPos = documentEnd;
                 success = false;
             }
-            else if (preventBoundary && nextPos.Y == base::ClampSub(documentEnd.Y, 1))
+            else if (preventBoundary && nextPos.Y == documentEnd.Y - 1)
             {
                 // Corner Case: we're just before the limit
                 // and we're not allowed onto the exclusive end.
@@ -1733,7 +1733,7 @@ void UiaTextRangeBase::_moveEndpointByUnitDocument(_In_ const int moveCount,
         auto documentEnd{ bufferSize.EndExclusive() };
         try
         {
-            documentEnd = _getDocumentEnd().to_win32_coord();
+            documentEnd = _getDocumentEnd();
         }
         CATCH_LOG();
 
@@ -1767,9 +1767,9 @@ void UiaTextRangeBase::_moveEndpointByUnitDocument(_In_ const int moveCount,
     }
 }
 
-RECT UiaTextRangeBase::_getTerminalRect() const
+til::rect UiaTextRangeBase::_getTerminalRect() const
 {
-    UiaRect result{ 0 };
+    UiaRect result{};
 
     IRawElementProviderFragment* pRawElementProviderFragment;
     THROW_IF_FAILED(_pProvider->QueryInterface<IRawElementProviderFragment>(&pRawElementProviderFragment));
@@ -1779,14 +1779,14 @@ RECT UiaTextRangeBase::_getTerminalRect() const
     }
 
     return {
-        gsl::narrow<LONG>(result.left),
-        gsl::narrow<LONG>(result.top),
-        gsl::narrow<LONG>(result.left + result.width),
-        gsl::narrow<LONG>(result.top + result.height)
+        gsl::narrow_cast<til::CoordType>(result.left),
+        gsl::narrow_cast<til::CoordType>(result.top),
+        gsl::narrow_cast<til::CoordType>(result.left + result.width),
+        gsl::narrow_cast<til::CoordType>(result.top + result.height),
     };
 }
 
-COORD UiaTextRangeBase::_getInclusiveEnd() noexcept
+til::point UiaTextRangeBase::_getInclusiveEnd() const noexcept
 {
     auto result{ _end };
     _pData->GetTextBuffer().GetSize().DecrementInBounds(result, true);
diff --git a/src/types/UiaTextRangeBase.hpp b/src/types/UiaTextRangeBase.hpp
index eeed63669c6..16f395170fc 100644
--- a/src/types/UiaTextRangeBase.hpp
+++ b/src/types/UiaTextRangeBase.hpp
@@ -64,8 +64,8 @@ namespace Microsoft::Console::Types
         // specific endpoint range
         virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
                                                _In_ IRawElementProviderSimple* const pProvider,
-                                               _In_ const COORD start,
-                                               _In_ const COORD end,
+                                               _In_ const til::point start,
+                                               _In_ const til::point end,
                                                _In_ bool blockRange = false,
                                                _In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
 
@@ -77,9 +77,9 @@ namespace Microsoft::Console::Types
         UiaTextRangeBase& operator=(UiaTextRangeBase&&) = delete;
         ~UiaTextRangeBase() = default;
 
-        const COORD GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept;
-        bool SetEndpoint(TextPatternRangeEndpoint endpoint, const COORD val) noexcept;
-        const bool IsDegenerate() const noexcept;
+        til::point GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept;
+        bool SetEndpoint(TextPatternRangeEndpoint endpoint, const til::point val) noexcept;
+        bool IsDegenerate() const noexcept;
 
         // ITextRangeProvider methods
         virtual IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) = 0;
@@ -127,30 +127,30 @@ namespace Microsoft::Console::Types
 
         std::wstring _wordDelimiters{};
 
-        virtual void _TranslatePointToScreen(LPPOINT clientPoint) const = 0;
-        virtual void _TranslatePointFromScreen(LPPOINT screenPoint) const = 0;
+        virtual void _TranslatePointToScreen(til::point* clientPoint) const = 0;
+        virtual void _TranslatePointFromScreen(til::point* screenPoint) const = 0;
 
         void Initialize(_In_ const UiaPoint point);
 
         // measure units in the form [_start, _end).
         // These are in the TextBuffer coordinate space.
         // NOTE: _start is inclusive, but _end is exclusive
-        COORD _start{};
-        COORD _end{};
+        til::point _start{};
+        til::point _end{};
         bool _blockRange{};
 
         // This is used by tracing to extract the text value
         // that the UiaTextRange currently encompasses.
         // GetText() cannot be used as it's not const
-        std::wstring _getTextValue(std::optional<unsigned int> maxLength = std::nullopt) const;
+        std::wstring _getTextValue(til::CoordType maxLength = -1) const;
 
-        RECT _getTerminalRect() const;
+        til::rect _getTerminalRect() const;
 
-        virtual const COORD _getScreenFontSize() const noexcept;
+        virtual til::size _getScreenFontSize() const noexcept;
 
-        const unsigned int _getViewportHeight(const SMALL_RECT viewport) const noexcept;
-        const Viewport _getOptimizedBufferSize() const noexcept;
-        const til::point _getDocumentEnd() const;
+        til::CoordType _getViewportHeight(const til::inclusive_rect& viewport) const noexcept;
+        Viewport _getOptimizedBufferSize() const noexcept;
+        til::point _getDocumentEnd() const;
 
         void _getBoundingRect(const til::rect& textRect, _Inout_ std::vector<double>& coords) const;
 
@@ -182,9 +182,9 @@ namespace Microsoft::Console::Types
 
         std::optional<bool> _verifyAttr(TEXTATTRIBUTEID attributeId, VARIANT val, const TextAttribute& attr) const;
         bool _initializeAttrQuery(TEXTATTRIBUTEID attributeId, VARIANT* pRetVal, const TextAttribute& attr) const;
-        bool _tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, COORD& resultingPos) const;
+        bool _tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, til::point& resultingPos) const;
 
-        COORD _getInclusiveEnd() noexcept;
+        til::point _getInclusiveEnd() const noexcept;
 
 #ifdef UNIT_TESTING
         friend class ::UiaTextRangeTests;
diff --git a/src/types/WindowBufferSizeEvent.cpp b/src/types/WindowBufferSizeEvent.cpp
index 550a1435654..d68e71ce14b 100644
--- a/src/types/WindowBufferSizeEvent.cpp
+++ b/src/types/WindowBufferSizeEvent.cpp
@@ -12,7 +12,8 @@ INPUT_RECORD WindowBufferSizeEvent::ToInputRecord() const noexcept
 {
     INPUT_RECORD record{ 0 };
     record.EventType = WINDOW_BUFFER_SIZE_EVENT;
-    record.Event.WindowBufferSizeEvent.dwSize = _size;
+    record.Event.WindowBufferSizeEvent.dwSize.X = ::base::saturated_cast<short>(_size.width);
+    record.Event.WindowBufferSizeEvent.dwSize.Y = ::base::saturated_cast<short>(_size.height);
     return record;
 }
 
@@ -21,7 +22,7 @@ InputEventType WindowBufferSizeEvent::EventType() const noexcept
     return InputEventType::WindowBufferSizeEvent;
 }
 
-void WindowBufferSizeEvent::SetSize(const COORD size) noexcept
+void WindowBufferSizeEvent::SetSize(const til::size size) noexcept
 {
     _size = size;
 }
diff --git a/src/types/inc/IInputEvent.hpp b/src/types/inc/IInputEvent.hpp
index 6ebda3d7615..d98f176795a 100644
--- a/src/types/inc/IInputEvent.hpp
+++ b/src/types/inc/IInputEvent.hpp
@@ -356,14 +356,14 @@ class MouseEvent : public IInputEvent
 {
 public:
     constexpr MouseEvent(const MOUSE_EVENT_RECORD& record) :
-        _position{ record.dwMousePosition },
+        _position{ til::wrap_coord(record.dwMousePosition) },
         _buttonState{ record.dwButtonState },
         _activeModifierKeys{ record.dwControlKeyState },
         _eventFlags{ record.dwEventFlags }
     {
     }
 
-    constexpr MouseEvent(const COORD position,
+    constexpr MouseEvent(const til::point position,
                          const DWORD buttonState,
                          const DWORD activeModifierKeys,
                          const DWORD eventFlags) :
@@ -388,7 +388,7 @@ class MouseEvent : public IInputEvent
         return _eventFlags == MOUSE_MOVED;
     }
 
-    constexpr COORD GetPosition() const noexcept
+    constexpr til::point GetPosition() const noexcept
     {
         return _position;
     }
@@ -408,13 +408,13 @@ class MouseEvent : public IInputEvent
         return _eventFlags;
     }
 
-    void SetPosition(const COORD position) noexcept;
+    void SetPosition(const til::point position) noexcept;
     void SetButtonState(const DWORD buttonState) noexcept;
     void SetActiveModifierKeys(const DWORD activeModifierKeys) noexcept;
     void SetEventFlags(const DWORD eventFlags) noexcept;
 
 private:
-    COORD _position;
+    til::point _position;
     DWORD _buttonState;
     DWORD _activeModifierKeys;
     DWORD _eventFlags;
@@ -432,11 +432,11 @@ class WindowBufferSizeEvent : public IInputEvent
 {
 public:
     constexpr WindowBufferSizeEvent(const WINDOW_BUFFER_SIZE_RECORD& record) :
-        _size{ record.dwSize }
+        _size{ til::wrap_coord_size(record.dwSize) }
     {
     }
 
-    constexpr WindowBufferSizeEvent(const COORD size) :
+    constexpr WindowBufferSizeEvent(const til::size size) :
         _size{ size }
     {
     }
@@ -450,15 +450,15 @@ class WindowBufferSizeEvent : public IInputEvent
     INPUT_RECORD ToInputRecord() const noexcept override;
     InputEventType EventType() const noexcept override;
 
-    constexpr COORD GetSize() const noexcept
+    constexpr til::size GetSize() const noexcept
     {
         return _size;
     }
 
-    void SetSize(const COORD size) noexcept;
+    void SetSize(const til::size size) noexcept;
 
 private:
-    COORD _size;
+    til::size _size;
 
 #ifdef UNIT_TESTING
     friend std::wostream& operator<<(std::wostream& stream, const WindowBufferSizeEvent* const pEvent);
diff --git a/src/types/inc/viewport.hpp b/src/types/inc/viewport.hpp
index 6c23d491879..d762f64348f 100644
--- a/src/types/inc/viewport.hpp
+++ b/src/types/inc/viewport.hpp
@@ -12,7 +12,6 @@ Author(s):
 --*/
 
 #pragma once
-#include "../../inc/operators.hpp"
 
 namespace Microsoft::Console::Types
 {
@@ -23,56 +22,50 @@ namespace Microsoft::Console::Types
     class Viewport final
     {
     public:
-        ~Viewport() {}
-        constexpr Viewport() noexcept :
-            _sr({ 0, 0, -1, -1 }){};
-        Viewport(const Viewport& other) noexcept;
-        Viewport(Viewport&&) = default;
-        Viewport& operator=(const Viewport&) & = default;
-        Viewport& operator=(Viewport&&) & = default;
+        Viewport() = default;
 
         static Viewport Empty() noexcept;
 
-        static Viewport FromInclusive(const SMALL_RECT sr) noexcept;
+        static Viewport FromInclusive(const til::inclusive_rect& sr) noexcept;
+        static Viewport FromExclusive(const til::rect& sr) noexcept;
 
-        static Viewport FromExclusive(const SMALL_RECT sr) noexcept;
+        static Viewport FromDimensions(const til::point origin,
+                                       const til::CoordType width,
+                                       const til::CoordType height) noexcept;
 
-        static Viewport FromDimensions(const COORD origin,
-                                       const short width,
-                                       const short height) noexcept;
+        static Viewport FromDimensions(const til::point origin,
+                                       const til::size dimensions) noexcept;
 
-        static Viewport FromDimensions(const COORD origin,
-                                       const COORD dimensions) noexcept;
+        static Viewport FromDimensions(const til::size dimensions) noexcept;
 
-        static Viewport FromDimensions(const COORD dimensions) noexcept;
+        static Viewport FromCoord(const til::point origin) noexcept;
 
-        static Viewport FromCoord(const COORD origin) noexcept;
-
-        SHORT Left() const noexcept;
-        SHORT RightInclusive() const noexcept;
-        SHORT RightExclusive() const noexcept;
-        SHORT Top() const noexcept;
-        SHORT BottomInclusive() const noexcept;
-        SHORT BottomExclusive() const noexcept;
-        SHORT Height() const noexcept;
-        SHORT Width() const noexcept;
-        COORD Origin() const noexcept;
-        COORD BottomRightExclusive() const noexcept;
-        COORD EndExclusive() const noexcept;
-        COORD Dimensions() const noexcept;
+        til::CoordType Left() const noexcept;
+        til::CoordType RightInclusive() const noexcept;
+        til::CoordType RightExclusive() const noexcept;
+        til::CoordType Top() const noexcept;
+        til::CoordType BottomInclusive() const noexcept;
+        til::CoordType BottomExclusive() const noexcept;
+        til::CoordType Height() const noexcept;
+        til::CoordType Width() const noexcept;
+        til::point Origin() const noexcept;
+        til::point BottomRightInclusive() const noexcept;
+        til::point BottomRightExclusive() const noexcept;
+        til::point EndExclusive() const noexcept;
+        til::size Dimensions() const noexcept;
 
         bool IsInBounds(const Viewport& other) const noexcept;
-        bool IsInBounds(const COORD& pos, bool allowEndExclusive = false) const noexcept;
+        bool IsInBounds(const til::point pos, bool allowEndExclusive = false) const noexcept;
 
-        void Clamp(COORD& pos) const;
+        void Clamp(til::point& pos) const;
         Viewport Clamp(const Viewport& other) const noexcept;
 
-        bool MoveInBounds(const ptrdiff_t move, COORD& pos) const noexcept;
-        bool IncrementInBounds(COORD& pos, bool allowEndExclusive = false) const noexcept;
-        bool IncrementInBoundsCircular(COORD& pos) const noexcept;
-        bool DecrementInBounds(COORD& pos, bool allowEndExclusive = false) const noexcept;
-        bool DecrementInBoundsCircular(COORD& pos) const noexcept;
-        int CompareInBounds(const COORD& first, const COORD& second, bool allowEndExclusive = false) const noexcept;
+        bool MoveInBounds(const til::CoordType move, til::point& pos) const noexcept;
+        bool IncrementInBounds(til::point& pos, bool allowEndExclusive = false) const noexcept;
+        bool IncrementInBoundsCircular(til::point& pos) const noexcept;
+        bool DecrementInBounds(til::point& pos, bool allowEndExclusive = false) const noexcept;
+        bool DecrementInBoundsCircular(til::point& pos) const noexcept;
+        int CompareInBounds(const til::point first, const til::point second, bool allowEndExclusive = false) const noexcept;
 
         enum class XWalk
         {
@@ -92,28 +85,28 @@ namespace Microsoft::Console::Types
             const YWalk y;
         };
 
-        bool WalkInBounds(COORD& pos, const WalkDir dir, bool allowEndExclusive = false) const noexcept;
-        bool WalkInBoundsCircular(COORD& pos, const WalkDir dir, bool allowEndExclusive = false) const noexcept;
-        COORD GetWalkOrigin(const WalkDir dir) const noexcept;
+        bool WalkInBounds(til::point& pos, const WalkDir dir, bool allowEndExclusive = false) const noexcept;
+        bool WalkInBoundsCircular(til::point& pos, const WalkDir dir, bool allowEndExclusive = false) const noexcept;
+        til::point GetWalkOrigin(const WalkDir dir) const noexcept;
         static WalkDir DetermineWalkDirection(const Viewport& source, const Viewport& target) noexcept;
 
-        bool TrimToViewport(_Inout_ SMALL_RECT* const psr) const noexcept;
-        void ConvertToOrigin(_Inout_ SMALL_RECT* const psr) const noexcept;
-        void ConvertToOrigin(_Inout_ COORD* const pcoord) const noexcept;
+        bool TrimToViewport(_Inout_ til::rect* psr) const noexcept;
+        void ConvertToOrigin(_Inout_ til::rect* psr) const noexcept;
+        void ConvertToOrigin(_Inout_ til::inclusive_rect* const psr) const noexcept;
+        void ConvertToOrigin(_Inout_ til::point* const pcoord) const noexcept;
         [[nodiscard]] Viewport ConvertToOrigin(const Viewport& other) const noexcept;
-        void ConvertFromOrigin(_Inout_ SMALL_RECT* const psr) const noexcept;
-        void ConvertFromOrigin(_Inout_ COORD* const pcoord) const noexcept;
+        void ConvertFromOrigin(_Inout_ til::inclusive_rect* const psr) const noexcept;
+        void ConvertFromOrigin(_Inout_ til::point* const pcoord) const noexcept;
         [[nodiscard]] Viewport ConvertFromOrigin(const Viewport& other) const noexcept;
 
-        SMALL_RECT ToExclusive() const noexcept;
-        SMALL_RECT ToInclusive() const noexcept;
-        RECT ToRect() const noexcept;
+        til::rect ToExclusive() const noexcept;
+        til::inclusive_rect ToInclusive() const noexcept;
 
         Viewport ToOrigin() const noexcept;
 
         bool IsValid() const noexcept;
 
-        [[nodiscard]] static Viewport Offset(const Viewport& original, const COORD delta);
+        [[nodiscard]] static Viewport Offset(const Viewport& original, const til::point delta) noexcept;
 
         [[nodiscard]] static Viewport Union(const Viewport& lhs, const Viewport& rhs) noexcept;
 
@@ -132,23 +125,13 @@ namespace Microsoft::Console::Types
         }
 
     private:
-        Viewport(const SMALL_RECT sr) noexcept;
+        Viewport(const til::inclusive_rect& sr) noexcept;
 
         // This is always stored as a Inclusive rect.
-        SMALL_RECT _sr;
+        til::inclusive_rect _sr{ 0, 0, -1, -1 };
 
 #if UNIT_TESTING
         friend class ViewportTests;
 #endif
     };
 }
-
-inline COORD operator-(const COORD& a, const COORD& b) noexcept
-{
-    return { a.X - b.X, a.Y - b.Y };
-}
-
-inline COORD operator-(const COORD& c) noexcept
-{
-    return { -c.X, -c.Y };
-}
diff --git a/src/types/viewport.cpp b/src/types/viewport.cpp
index b71c3d3d892..45e1728887b 100644
--- a/src/types/viewport.cpp
+++ b/src/types/viewport.cpp
@@ -6,32 +6,24 @@
 
 using namespace Microsoft::Console::Types;
 
-Viewport::Viewport(const SMALL_RECT sr) noexcept :
+Viewport::Viewport(const til::inclusive_rect& sr) noexcept :
     _sr(sr)
 {
 }
 
-Viewport::Viewport(const Viewport& other) noexcept :
-    _sr(other._sr)
-{
-}
-
 Viewport Viewport::Empty() noexcept
 {
     return Viewport();
 }
 
-Viewport Viewport::FromInclusive(const SMALL_RECT sr) noexcept
+Viewport Viewport::FromInclusive(const til::inclusive_rect& sr) noexcept
 {
     return Viewport(sr);
 }
 
-Viewport Viewport::FromExclusive(const SMALL_RECT sr) noexcept
+Viewport Viewport::FromExclusive(const til::rect& sr) noexcept
 {
-    auto _sr = sr;
-    _sr.Bottom -= 1;
-    _sr.Right -= 1;
-    return Viewport::FromInclusive(_sr);
+    return FromInclusive(sr.to_inclusive_rect());
 }
 
 // Function Description:
@@ -42,15 +34,15 @@ Viewport Viewport::FromExclusive(const SMALL_RECT sr) noexcept
 // - height: The height of the new viewport
 // Return Value:
 // - a new Viewport at the given origin, with the given dimensions.
-Viewport Viewport::FromDimensions(const COORD origin,
-                                  const short width,
-                                  const short height) noexcept
+Viewport Viewport::FromDimensions(const til::point origin,
+                                  const til::CoordType width,
+                                  const til::CoordType height) noexcept
 {
-    return Viewport::FromInclusive({
+    return Viewport(til::inclusive_rect{
         origin.X,
         origin.Y,
-        base::saturated_cast<short>(origin.X + width - 1),
-        base::saturated_cast<short>(origin.Y + height - 1),
+        origin.X + width - 1,
+        origin.Y + height - 1,
     });
 }
 
@@ -62,14 +54,14 @@ Viewport Viewport::FromDimensions(const COORD origin,
 //      in the x and y coordinates respectively.
 // Return Value:
 // - a new Viewport at the given origin, with the given dimensions.
-Viewport Viewport::FromDimensions(const COORD origin,
-                                  const COORD dimensions) noexcept
+Viewport Viewport::FromDimensions(const til::point origin,
+                                  const til::size dimensions) noexcept
 {
-    return Viewport::FromInclusive({
+    return Viewport(til::inclusive_rect{
         origin.X,
         origin.Y,
-        base::saturated_cast<short>(origin.X + dimensions.X - 1),
-        base::saturated_cast<short>(origin.Y + dimensions.Y - 1),
+        origin.X + dimensions.X - 1,
+        origin.Y + dimensions.Y - 1,
     });
 }
 
@@ -80,9 +72,9 @@ Viewport Viewport::FromDimensions(const COORD origin,
 //      in the x and y coordinates respectively.
 // Return Value:
 // - a new Viewport at the origin, with the given dimensions.
-Viewport Viewport::FromDimensions(const COORD dimensions) noexcept
+Viewport Viewport::FromDimensions(const til::size dimensions) noexcept
 {
-    return Viewport::FromDimensions({ 0 }, dimensions);
+    return FromDimensions({}, dimensions);
 }
 
 // Method Description:
@@ -91,47 +83,47 @@ Viewport Viewport::FromDimensions(const COORD dimensions) noexcept
 // - origin: origin of the rectangle to create.
 // Return Value:
 // - a 1x1 Viewport at the given coordinate
-Viewport Viewport::FromCoord(const COORD origin) noexcept
+Viewport Viewport::FromCoord(const til::point origin) noexcept
 {
-    return Viewport::FromInclusive({ origin.X, origin.Y, origin.X, origin.Y });
+    return FromInclusive(til::inclusive_rect{ origin.X, origin.Y, origin.X, origin.Y });
 }
 
-SHORT Viewport::Left() const noexcept
+til::CoordType Viewport::Left() const noexcept
 {
     return _sr.Left;
 }
 
-SHORT Viewport::RightInclusive() const noexcept
+til::CoordType Viewport::RightInclusive() const noexcept
 {
     return _sr.Right;
 }
 
-SHORT Viewport::RightExclusive() const noexcept
+til::CoordType Viewport::RightExclusive() const noexcept
 {
     return _sr.Right + 1;
 }
 
-SHORT Viewport::Top() const noexcept
+til::CoordType Viewport::Top() const noexcept
 {
     return _sr.Top;
 }
 
-SHORT Viewport::BottomInclusive() const noexcept
+til::CoordType Viewport::BottomInclusive() const noexcept
 {
     return _sr.Bottom;
 }
 
-SHORT Viewport::BottomExclusive() const noexcept
+til::CoordType Viewport::BottomExclusive() const noexcept
 {
     return _sr.Bottom + 1;
 }
 
-SHORT Viewport::Height() const noexcept
+til::CoordType Viewport::Height() const noexcept
 {
     return BottomExclusive() - Top();
 }
 
-SHORT Viewport::Width() const noexcept
+til::CoordType Viewport::Width() const noexcept
 {
     return RightExclusive() - Left();
 }
@@ -142,31 +134,42 @@ SHORT Viewport::Width() const noexcept
 // - <none>
 // Return Value:
 // - the coordinates of this viewport's origin.
-COORD Viewport::Origin() const noexcept
+til::point Viewport::Origin() const noexcept
 {
     return { Left(), Top() };
 }
 
+// Method Description:
+// - Get a coord representing the bottom right of the viewport in inclusive terms.
+// Arguments:
+// - <none>
+// Return Value:
+// - the inclusive bottom right coordinates of this viewport.
+til::point Viewport::BottomRightInclusive() const noexcept
+{
+    return { RightInclusive(), BottomInclusive() };
+}
+
 // Method Description:
 // - Get a coord representing the bottom right of the viewport in exclusive terms.
 // Arguments:
 // - <none>
 // Return Value:
 // - the exclusive bottom right coordinates of this viewport.
-COORD Viewport::BottomRightExclusive() const noexcept
+til::point Viewport::BottomRightExclusive() const noexcept
 {
     return { RightExclusive(), BottomExclusive() };
 }
 
 // Method Description:
-// - For Accessibility, get a COORD representing the end of this viewport in exclusive terms.
+// - For Accessibility, get a til::point representing the end of this viewport in exclusive terms.
 // - This is needed to represent an exclusive endpoint in UiaTextRange that includes the last
-//    COORD's text in the buffer at (RightInclusive(), BottomInclusive())
+//    til::point's text in the buffer at (RightInclusive(), BottomInclusive())
 // Arguments:
 // - <none>
 // Return Value:
 // - the coordinates of this viewport's end.
-COORD Viewport::EndExclusive() const noexcept
+til::point Viewport::EndExclusive() const noexcept
 {
     return { Left(), BottomExclusive() };
 }
@@ -177,7 +180,7 @@ COORD Viewport::EndExclusive() const noexcept
 // - <none>
 // Return Value:
 // - the dimensions of this viewport.
-COORD Viewport::Dimensions() const noexcept
+til::size Viewport::Dimensions() const noexcept
 {
     return { Width(), Height() };
 }
@@ -200,12 +203,12 @@ bool Viewport::IsInBounds(const Viewport& other) const noexcept
 // - Determines if the given coordinate position lies within this viewport.
 // Arguments:
 // - pos - Coordinate position
-// - allowEndExclusive - if true, allow the EndExclusive COORD as a valid position.
+// - allowEndExclusive - if true, allow the EndExclusive til::point as a valid position.
 //                        Used in accessibility to signify that the exclusive end
-//                        includes the last COORD in a given viewport.
+//                        includes the last til::point in a given viewport.
 // Return Value:
 // - True if it lies inside the viewport. False otherwise.
-bool Viewport::IsInBounds(const COORD& pos, bool allowEndExclusive) const noexcept
+bool Viewport::IsInBounds(const til::point pos, bool allowEndExclusive) const noexcept
 {
     if (allowEndExclusive && pos == EndExclusive())
     {
@@ -222,7 +225,7 @@ bool Viewport::IsInBounds(const COORD& pos, bool allowEndExclusive) const noexce
 // - pos - coordinate to update/clamp
 // Return Value:
 // - <none>
-void Viewport::Clamp(COORD& pos) const
+void Viewport::Clamp(til::point& pos) const
 {
     THROW_HR_IF(E_NOT_VALID_STATE, !IsValid()); // we can't clamp to an invalid viewport.
 
@@ -257,12 +260,12 @@ Viewport Viewport::Clamp(const Viewport& other) const noexcept
 // Return Value:
 // - True if we successfully moved the requested distance. False if we had to stop early.
 // - If False, we will restore the original position to the given coordinate.
-bool Viewport::MoveInBounds(const ptrdiff_t move, COORD& pos) const noexcept
+bool Viewport::MoveInBounds(const til::CoordType move, til::point& pos) const noexcept
 {
     const auto backup = pos;
     auto success = true; // If nothing happens, we're still successful (e.g. add = 0)
 
-    for (auto i = 0; i < move; i++)
+    for (til::CoordType i = 0; i < move; i++)
     {
         success = IncrementInBounds(pos);
 
@@ -273,7 +276,7 @@ bool Viewport::MoveInBounds(const ptrdiff_t move, COORD& pos) const noexcept
         }
     }
 
-    for (auto i = 0; i > move; i--)
+    for (til::CoordType i = 0; i > move; i--)
     {
         success = DecrementInBounds(pos);
 
@@ -297,12 +300,12 @@ bool Viewport::MoveInBounds(const ptrdiff_t move, COORD& pos) const noexcept
 // - Increments the given coordinate within the bounds of this viewport.
 // Arguments:
 // - pos - Coordinate position that will be incremented, if it can be.
-// - allowEndExclusive - if true, allow the EndExclusive COORD as a valid position.
+// - allowEndExclusive - if true, allow the EndExclusive til::point as a valid position.
 //                        Used in accessibility to signify that the exclusive end
-//                        includes the last COORD in a given viewport.
+//                        includes the last til::point in a given viewport.
 // Return Value:
 // - True if it could be incremented. False if it would move outside.
-bool Viewport::IncrementInBounds(COORD& pos, bool allowEndExclusive) const noexcept
+bool Viewport::IncrementInBounds(til::point& pos, bool allowEndExclusive) const noexcept
 {
     return WalkInBounds(pos, { XWalk::LeftToRight, YWalk::TopToBottom }, allowEndExclusive);
 }
@@ -315,7 +318,7 @@ bool Viewport::IncrementInBounds(COORD& pos, bool allowEndExclusive) const noexc
 // Return Value:
 // - True if it could be incremented inside the viewport.
 // - False if it rolled over from the bottom right corner back to the top.
-bool Viewport::IncrementInBoundsCircular(COORD& pos) const noexcept
+bool Viewport::IncrementInBoundsCircular(til::point& pos) const noexcept
 {
     return WalkInBoundsCircular(pos, { XWalk::LeftToRight, YWalk::TopToBottom });
 }
@@ -324,12 +327,12 @@ bool Viewport::IncrementInBoundsCircular(COORD& pos) const noexcept
 // - Decrements the given coordinate within the bounds of this viewport.
 // Arguments:
 // - pos - Coordinate position that will be incremented, if it can be.
-// - allowEndExclusive - if true, allow the EndExclusive COORD as a valid position.
+// - allowEndExclusive - if true, allow the EndExclusive til::point as a valid position.
 //                        Used in accessibility to signify that the exclusive end
-//                        includes the last COORD in a given viewport.
+//                        includes the last til::point in a given viewport.
 // Return Value:
 // - True if it could be incremented. False if it would move outside.
-bool Viewport::DecrementInBounds(COORD& pos, bool allowEndExclusive) const noexcept
+bool Viewport::DecrementInBounds(til::point& pos, bool allowEndExclusive) const noexcept
 {
     return WalkInBounds(pos, { XWalk::RightToLeft, YWalk::BottomToTop }, allowEndExclusive);
 }
@@ -342,7 +345,7 @@ bool Viewport::DecrementInBounds(COORD& pos, bool allowEndExclusive) const noexc
 // Return Value:
 // - True if it could be decremented inside the viewport.
 // - False if it rolled over from the top left corner back to the bottom right.
-bool Viewport::DecrementInBoundsCircular(COORD& pos) const noexcept
+bool Viewport::DecrementInBoundsCircular(til::point& pos) const noexcept
 {
     return WalkInBoundsCircular(pos, { XWalk::RightToLeft, YWalk::BottomToTop });
 }
@@ -352,9 +355,9 @@ bool Viewport::DecrementInBoundsCircular(COORD& pos) const noexcept
 // Arguments:
 // - first- The first coordinate position
 // - second - The second coordinate position
-// - allowEndExclusive - if true, allow the EndExclusive COORD as a valid position.
+// - allowEndExclusive - if true, allow the EndExclusive til::point as a valid position.
 //                        Used in accessibility to signify that the exclusive end
-//                        includes the last COORD in a given viewport.
+//                        includes the last til::point in a given viewport.
 // Return Value:
 // -  Negative if First is to the left of the Second.
 // -  0 if First and Second are the same coordinate.
@@ -362,7 +365,7 @@ bool Viewport::DecrementInBoundsCircular(COORD& pos) const noexcept
 // -  This is so you can do s_CompareCoords(first, second) <= 0 for "first is left or the same as second".
 //    (the < looks like a left arrow :D)
 // -  The magnitude of the result is the distance between the two coordinates when typing characters into the buffer (left to right, top to bottom)
-int Viewport::CompareInBounds(const COORD& first, const COORD& second, bool allowEndExclusive) const noexcept
+int Viewport::CompareInBounds(const til::point first, const til::point second, bool allowEndExclusive) const noexcept
 {
     // Assert that our coordinates are within the expected boundaries
     FAIL_FAST_IF(!IsInBounds(first, allowEndExclusive));
@@ -393,12 +396,12 @@ int Viewport::CompareInBounds(const COORD& first, const COORD& second, bool allo
 // Arguments:
 // - pos - Coordinate position that will be adjusted, if it can be.
 // - dir - Walking direction specifying which direction to go when reaching the end of a row/column
-// - allowEndExclusive - if true, allow the EndExclusive COORD as a valid position.
+// - allowEndExclusive - if true, allow the EndExclusive til::point as a valid position.
 //                        Used in accessibility to signify that the exclusive end
-//                        includes the last COORD in a given viewport.
+//                        includes the last til::point in a given viewport.
 // Return Value:
 // - True if it could be adjusted as specified and remain in bounds. False if it would move outside.
-bool Viewport::WalkInBounds(COORD& pos, const WalkDir dir, bool allowEndExclusive) const noexcept
+bool Viewport::WalkInBounds(til::point& pos, const WalkDir dir, bool allowEndExclusive) const noexcept
 {
     auto copy = pos;
     if (WalkInBoundsCircular(copy, dir, allowEndExclusive))
@@ -419,14 +422,14 @@ bool Viewport::WalkInBounds(COORD& pos, const WalkDir dir, bool allowEndExclusiv
 // Arguments:
 // - pos - Coordinate position that will be adjusted.
 // - dir - Walking direction specifying which direction to go when reaching the end of a row/column
-// - allowEndExclusive - if true, allow the EndExclusive COORD as a valid position.
+// - allowEndExclusive - if true, allow the EndExclusive til::point as a valid position.
 //                        Used in accessibility to signify that the exclusive end
-//                        includes the last COORD in a given viewport.
+//                        includes the last til::point in a given viewport.
 // Return Value:
 // - True if it could be adjusted inside the viewport.
 // - False if it rolled over from the final corner back to the initial corner
 //   for the specified walk direction.
-bool Viewport::WalkInBoundsCircular(COORD& pos, const WalkDir dir, bool allowEndExclusive) const noexcept
+bool Viewport::WalkInBoundsCircular(til::point& pos, const WalkDir dir, bool allowEndExclusive) const noexcept
 {
     // Assert that the position given fits inside this viewport.
     FAIL_FAST_IF(!IsInBounds(pos, allowEndExclusive));
@@ -514,9 +517,9 @@ bool Viewport::WalkInBoundsCircular(COORD& pos, const WalkDir dir, bool allowEnd
 // Return Value:
 // - The origin for the walk to reach every position without circling
 //   if using this same viewport with the `WalkInBounds` methods.
-COORD Viewport::GetWalkOrigin(const WalkDir dir) const noexcept
+til::point Viewport::GetWalkOrigin(const WalkDir dir) const noexcept
 {
-    COORD origin{ 0 };
+    til::point origin;
     origin.X = dir.x == XWalk::LeftToRight ? Left() : RightInclusive();
     origin.Y = dir.y == YWalk::TopToBottom ? Top() : BottomInclusive();
     return origin;
@@ -689,7 +692,7 @@ Viewport::WalkDir Viewport::DetermineWalkDirection(const Viewport& source, const
 // - psr: a pointer to an exclusive rect to clip.
 // Return Value:
 // - true iff the clipped rectangle is valid (with a width and height both >0)
-bool Viewport::TrimToViewport(_Inout_ SMALL_RECT* const psr) const noexcept
+bool Viewport::TrimToViewport(_Inout_ til::rect* psr) const noexcept
 {
     psr->Left = std::max(psr->Left, Left());
     psr->Right = std::min(psr->Right, RightExclusive());
@@ -700,13 +703,30 @@ bool Viewport::TrimToViewport(_Inout_ SMALL_RECT* const psr) const noexcept
 }
 
 // Method Description:
-// - Translates the input SMALL_RECT out of our coordinate space, whose origin is
+// - Translates the input til::rect out of our coordinate space, whose origin is
+//      at (this.Left, this.Right)
+// Arguments:
+// - psr: a pointer to a til::rect the translate into our coordinate space.
+// Return Value:
+// - <none>
+void Viewport::ConvertToOrigin(_Inout_ til::rect* psr) const noexcept
+{
+    const auto dx = Left();
+    const auto dy = Top();
+    psr->Left -= dx;
+    psr->Right -= dx;
+    psr->Top -= dy;
+    psr->Bottom -= dy;
+}
+
+// Method Description:
+// - Translates the input til::inclusive_rect out of our coordinate space, whose origin is
 //      at (this.Left, this.Right)
 // Arguments:
-// - psr: a pointer to a SMALL_RECT the translate into our coordinate space.
+// - psr: a pointer to a til::inclusive_rect the translate into our coordinate space.
 // Return Value:
 // - <none>
-void Viewport::ConvertToOrigin(_Inout_ SMALL_RECT* const psr) const noexcept
+void Viewport::ConvertToOrigin(_Inout_ til::inclusive_rect* const psr) const noexcept
 {
     const auto dx = Left();
     const auto dy = Top();
@@ -723,20 +743,20 @@ void Viewport::ConvertToOrigin(_Inout_ SMALL_RECT* const psr) const noexcept
 // - pcoord: a pointer to a coordinate the translate into our coordinate space.
 // Return Value:
 // - <none>
-void Viewport::ConvertToOrigin(_Inout_ COORD* const pcoord) const noexcept
+void Viewport::ConvertToOrigin(_Inout_ til::point* const pcoord) const noexcept
 {
     pcoord->X -= Left();
     pcoord->Y -= Top();
 }
 
 // Method Description:
-// - Translates the input SMALL_RECT to our coordinate space, whose origin is
+// - Translates the input til::inclusive_rect to our coordinate space, whose origin is
 //      at (this.Left, this.Right)
 // Arguments:
-// - psr: a pointer to a SMALL_RECT the translate into our coordinate space.
+// - psr: a pointer to a til::inclusive_rect the translate into our coordinate space.
 // Return Value:
 // - <none>
-void Viewport::ConvertFromOrigin(_Inout_ SMALL_RECT* const psr) const noexcept
+void Viewport::ConvertFromOrigin(_Inout_ til::inclusive_rect* const psr) const noexcept
 {
     const auto dx = Left();
     const auto dy = Top();
@@ -753,46 +773,30 @@ void Viewport::ConvertFromOrigin(_Inout_ SMALL_RECT* const psr) const noexcept
 // - pcoord: a pointer to a coordinate the translate into our coordinate space.
 // Return Value:
 // - <none>
-void Viewport::ConvertFromOrigin(_Inout_ COORD* const pcoord) const noexcept
+void Viewport::ConvertFromOrigin(_Inout_ til::point* const pcoord) const noexcept
 {
     pcoord->X += Left();
     pcoord->Y += Top();
 }
 
 // Method Description:
-// - Returns an exclusive SMALL_RECT equivalent to this viewport.
+// - Returns an exclusive til::rect equivalent to this viewport.
 // Arguments:
 // - <none>
 // Return Value:
-// - an exclusive SMALL_RECT equivalent to this viewport.
-SMALL_RECT Viewport::ToExclusive() const noexcept
+// - an exclusive til::rect equivalent to this viewport.
+til::rect Viewport::ToExclusive() const noexcept
 {
     return { Left(), Top(), RightExclusive(), BottomExclusive() };
 }
 
 // Method Description:
-// - Returns an exclusive RECT equivalent to this viewport.
-// Arguments:
-// - <none>
-// Return Value:
-// - an exclusive RECT equivalent to this viewport.
-RECT Viewport::ToRect() const noexcept
-{
-    RECT r{ 0 };
-    r.left = Left();
-    r.top = Top();
-    r.right = RightExclusive();
-    r.bottom = BottomExclusive();
-    return r;
-}
-
-// Method Description:
-// - Returns an inclusive SMALL_RECT equivalent to this viewport.
+// - Returns an inclusive til::inclusive_rect equivalent to this viewport.
 // Arguments:
 // - <none>
 // Return Value:
-// - an inclusive SMALL_RECT equivalent to this viewport.
-SMALL_RECT Viewport::ToInclusive() const noexcept
+// - an inclusive til::inclusive_rect equivalent to this viewport.
+til::inclusive_rect Viewport::ToInclusive() const noexcept
 {
     return { Left(), Top(), RightInclusive(), BottomInclusive() };
 }
@@ -856,24 +860,12 @@ Viewport Viewport::ToOrigin() const noexcept
 // Return Value:
 // - The offset viewport by the given delta.
 // - NOTE: Throws on safe math failure.
-[[nodiscard]] Viewport Viewport::Offset(const Viewport& original, const COORD delta)
+[[nodiscard]] Viewport Viewport::Offset(const Viewport& original, const til::point delta) noexcept
 {
-    // If there's no delta, do nothing.
-    if (delta.X == 0 && delta.Y == 0)
-    {
-        return original;
-    }
-
-    auto newTop = original._sr.Top;
-    auto newLeft = original._sr.Left;
-    auto newRight = original._sr.Right;
-    auto newBottom = original._sr.Bottom;
-
-    THROW_IF_FAILED(ShortAdd(newLeft, delta.X, &newLeft));
-    THROW_IF_FAILED(ShortAdd(newRight, delta.X, &newRight));
-    THROW_IF_FAILED(ShortAdd(newTop, delta.Y, &newTop));
-    THROW_IF_FAILED(ShortAdd(newBottom, delta.Y, &newBottom));
-
+    const auto newLeft = original._sr.Left + delta.X;
+    const auto newTop = original._sr.Top + delta.Y;
+    const auto newRight = original._sr.Right + delta.X;
+    const auto newBottom = original._sr.Bottom + delta.Y;
     return Viewport({ newLeft, newTop, newRight, newBottom });
 }
 
@@ -1063,10 +1055,10 @@ try
         // We generate these rectangles by the original and intersection points, but some of them might be empty when the intersection
         // lines up with the edge of the original. That's OK. That just means that the subtraction didn't leave anything behind.
         // We will filter those out below when adding them to the result.
-        const auto top = Viewport({ original.Left(), original.Top(), original.RightInclusive(), intersection.Top() - 1 });
-        const auto bottom = Viewport({ original.Left(), intersection.BottomExclusive(), original.RightInclusive(), original.BottomInclusive() });
-        const auto left = Viewport({ original.Left(), intersection.Top(), intersection.Left() - 1, intersection.BottomInclusive() });
-        const auto right = Viewport({ intersection.RightExclusive(), intersection.Top(), original.RightInclusive(), intersection.BottomInclusive() });
+        const Viewport top{ til::inclusive_rect{ original.Left(), original.Top(), original.RightInclusive(), intersection.Top() - 1 } };
+        const Viewport bottom{ til::inclusive_rect{ original.Left(), intersection.BottomExclusive(), original.RightInclusive(), original.BottomInclusive() } };
+        const Viewport left{ til::inclusive_rect{ original.Left(), intersection.Top(), intersection.Left() - 1, intersection.BottomInclusive() } };
+        const Viewport right{ til::inclusive_rect{ intersection.RightExclusive(), intersection.Top(), original.RightInclusive(), intersection.BottomInclusive() } };
 
         if (top.IsValid())
         {
@@ -1098,5 +1090,5 @@ CATCH_FAIL_FAST()
 // - i.e. it has a positive, non-zero height and width.
 bool Viewport::IsValid() const noexcept
 {
-    return Height() > 0 && Width() > 0;
+    return static_cast<bool>(_sr);
 }
diff --git a/tools/TestTableWriter/GenerateTests.ps1 b/tools/TestTableWriter/GenerateTests.ps1
index 3f3d05e1b76..d0c674d628d 100644
--- a/tools/TestTableWriter/GenerateTests.ps1
+++ b/tools/TestTableWriter/GenerateTests.ps1
@@ -25,14 +25,14 @@ $result = "// Copyright (c) Microsoft Corporation.
 $result += "
 // Define a few helpful variables
 constexpr til::rect bufferSize{ 0, 0, 80, 300 };
-constexpr short midX{ 40 };
-constexpr short midY{ 150 };
-constexpr short midPopulatedY{ 75 };
-constexpr short segment0{ 0 };
-constexpr short segment1{ 16 };
-constexpr short segment2{ 32 };
-constexpr short segment3{ 48 };
-constexpr short segment4{ 64 };
+constexpr til::CoordType midX{ 40 };
+constexpr til::CoordType midY{ 150 };
+constexpr til::CoordType midPopulatedY{ 75 };
+constexpr til::CoordType segment0{ 0 };
+constexpr til::CoordType segment1{ 16 };
+constexpr til::CoordType segment2{ 32 };
+constexpr til::CoordType segment3{ 48 };
+constexpr til::CoordType segment4{ 64 };
 constexpr til::point origin{ 0, 0 };
 constexpr til::point midTop{ midX, 0 };
 constexpr til::point midHistory{ midX, midPopulatedY };


Test patch:
diff --git a/src/inc/test/CommonState.hpp b/src/inc/test/CommonState.hpp
index 791782cce98..15a773473ca 100644
--- a/src/inc/test/CommonState.hpp
+++ b/src/inc/test/CommonState.hpp
@@ -30,10 +30,10 @@ unit testing projects in the codebase without a bunch of overhead.
 class CommonState
 {
 public:
-    static const SHORT s_csWindowWidth = 80;
-    static const SHORT s_csWindowHeight = 80;
-    static const SHORT s_csBufferWidth = 80;
-    static const SHORT s_csBufferHeight = 300;
+    static const til::CoordType s_csWindowWidth = 80;
+    static const til::CoordType s_csWindowHeight = 80;
+    static const til::CoordType s_csBufferWidth = 80;
+    static const til::CoordType s_csBufferHeight = 300;
 
     CommonState() :
         m_heap(GetProcessHeap()),
@@ -64,7 +64,7 @@ class CommonState
         m_readHandle.reset(nullptr);
     }
 
-    void PrepareGlobalFont(const COORD coordFontSize = { 8, 12 })
+    void PrepareGlobalFont(const til::size coordFontSize = { 8, 12 })
     {
         m_pFontInfo = new FontInfo(L"Consolas", 0, 0, coordFontSize, 0);
     }
@@ -91,18 +91,18 @@ class CommonState
         g.pRender = nullptr;
     }
 
-    void PrepareGlobalScreenBuffer(const short viewWidth = s_csWindowWidth,
-                                   const short viewHeight = s_csWindowHeight,
-                                   const short bufferWidth = s_csBufferWidth,
-                                   const short bufferHeight = s_csBufferHeight)
+    void PrepareGlobalScreenBuffer(const til::CoordType viewWidth = s_csWindowWidth,
+                                   const til::CoordType viewHeight = s_csWindowHeight,
+                                   const til::CoordType bufferWidth = s_csBufferWidth,
+                                   const til::CoordType bufferHeight = s_csBufferHeight)
     {
         Globals& g = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals();
         CONSOLE_INFORMATION& gci = g.getConsoleInformation();
-        COORD coordWindowSize;
+        til::size coordWindowSize;
         coordWindowSize.X = viewWidth;
         coordWindowSize.Y = viewHeight;
 
-        COORD coordScreenBufferSize;
+        til::size coordScreenBufferSize;
         coordScreenBufferSize.X = bufferWidth;
         coordScreenBufferSize.Y = bufferHeight;
 
@@ -170,12 +170,12 @@ class CommonState
     }
 
     void PrepareNewTextBufferInfo(const bool useDefaultAttributes = false,
-                                  const short bufferWidth = s_csBufferWidth,
-                                  const short bufferHeight = s_csBufferHeight)
+                                  const til::CoordType bufferWidth = s_csBufferWidth,
+                                  const til::CoordType bufferHeight = s_csBufferHeight)
     {
         Globals& g = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals();
         CONSOLE_INFORMATION& gci = g.getConsoleInformation();
-        COORD coordScreenBufferSize;
+        til::size coordScreenBufferSize;
         coordScreenBufferSize.X = bufferWidth;
         coordScreenBufferSize.Y = bufferHeight;
 
@@ -232,13 +232,13 @@ class CommonState
     {
         CONSOLE_INFORMATION& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation();
         // fill with some assorted text that doesn't consume the whole row
-        const SHORT cRowsToFill = 4;
+        const til::CoordType cRowsToFill = 4;
 
         VERIFY_IS_TRUE(gci.HasActiveOutputBuffer());
 
         TextBuffer& textBuffer = gci.GetActiveOutputBuffer().GetTextBuffer();
 
-        for (SHORT iRow = 0; iRow < cRowsToFill; iRow++)
+        for (til::CoordType iRow = 0; iRow < cRowsToFill; iRow++)
         {
             ROW& row = textBuffer.GetRowByOffset(iRow);
             FillRow(&row);
@@ -251,13 +251,13 @@ class CommonState
     {
         CONSOLE_INFORMATION& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation();
         // fill with some text that fills the whole row and has bisecting double byte characters
-        const SHORT cRowsToFill = s_csBufferHeight;
+        const auto cRowsToFill = s_csBufferHeight;
 
         VERIFY_IS_TRUE(gci.HasActiveOutputBuffer());
 
         TextBuffer& textBuffer = gci.GetActiveOutputBuffer().GetTextBuffer();
 
-        for (SHORT iRow = 0; iRow < cRowsToFill; iRow++)
+        for (til::CoordType iRow = 0; iRow < cRowsToFill; iRow++)
         {
             ROW& row = textBuffer.GetRowByOffset(iRow);
             FillBisect(&row);