diff --git a/src/StaticAnalysis.ruleset b/src/StaticAnalysis.ruleset
index e9d2a69ed8d..114c0cc5c2f 100644
--- a/src/StaticAnalysis.ruleset
+++ b/src/StaticAnalysis.ruleset
@@ -1,11 +1,15 @@
-
+
-
-
-
+
+
+
+
+
+
+
diff --git a/src/buffer/out/AttrRow.cpp b/src/buffer/out/AttrRow.cpp
index e9efd8f6037..c97bcbba884 100644
--- a/src/buffer/out/AttrRow.cpp
+++ b/src/buffer/out/AttrRow.cpp
@@ -46,7 +46,7 @@ void ATTR_ROW::Resize(const size_t newWidth)
{
// Get the attribute that covers the final column of old width.
const auto runPos = FindAttrIndex(_cchRowWidth - 1, nullptr);
- auto& run = _list[runPos];
+ auto& run = _list.at(runPos);
// Extend its length by the additional columns we're adding.
run.SetLength(run.GetLength() + newWidth - _cchRowWidth);
@@ -60,7 +60,7 @@ void ATTR_ROW::Resize(const size_t newWidth)
// Get the attribute that covers the final column of the new width
size_t CountOfAttr = 0;
const auto runPos = FindAttrIndex(newWidth - 1, &CountOfAttr);
- auto& run = _list[runPos];
+ auto& run = _list.at(runPos);
// CountOfAttr was given to us as "how many columns left from this point forward are covered by the returned run"
// So if the original run was B5 covering a 5 size OldWidth and we have a NewWidth of 3
@@ -108,7 +108,7 @@ TextAttribute ATTR_ROW::GetAttrByColumn(const size_t column,
{
THROW_HR_IF(E_INVALIDARG, column >= _cchRowWidth);
const auto runPos = FindAttrIndex(column, pApplies);
- return _list[runPos].GetAttributes();
+ return _list.at(runPos).GetAttributes();
}
// Routine Description:
@@ -290,10 +290,10 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
// two elements in our internal list.
else if (_list.size() == 2 && newAttrs.at(0).GetLength() == 1)
{
- auto left = _list.begin();
+ const auto left = _list.begin();
if (iStart == left->GetLength() && NewAttr == left->GetAttributes())
{
- auto right = left + 1;
+ const auto right = left + 1;
left->IncrementLength();
right->DecrementLength();
diff --git a/src/buffer/out/AttrRowIterator.cpp b/src/buffer/out/AttrRowIterator.cpp
index 0462afa144c..c4e735d3e11 100644
--- a/src/buffer/out/AttrRowIterator.cpp
+++ b/src/buffer/out/AttrRowIterator.cpp
@@ -6,21 +6,21 @@
#include "AttrRowIterator.hpp"
#include "AttrRow.hpp"
-AttrRowIterator AttrRowIterator::CreateEndIterator(const ATTR_ROW* const attrRow)
+AttrRowIterator AttrRowIterator::CreateEndIterator(const ATTR_ROW* const attrRow) noexcept
{
AttrRowIterator it{ attrRow };
it._setToEnd();
return it;
}
-AttrRowIterator::AttrRowIterator(const ATTR_ROW* const attrRow) :
+AttrRowIterator::AttrRowIterator(const ATTR_ROW* const attrRow) noexcept :
_pAttrRow{ attrRow },
_run{ attrRow->_list.cbegin() },
_currentAttributeIndex{ 0 }
{
}
-AttrRowIterator::operator bool() const noexcept
+AttrRowIterator::operator bool() const
{
return _run < _pAttrRow->_list.cend();
}
@@ -139,7 +139,7 @@ void AttrRowIterator::_decrement(size_t count)
// Routine Description:
// - sets fields on the iterator to describe the end() state of the ATTR_ROW
-void AttrRowIterator::_setToEnd()
+void AttrRowIterator::_setToEnd() noexcept
{
_run = _pAttrRow->_list.cend();
_currentAttributeIndex = 0;
diff --git a/src/buffer/out/AttrRowIterator.hpp b/src/buffer/out/AttrRowIterator.hpp
index 5ca7f72c125..c9e053ea247 100644
--- a/src/buffer/out/AttrRowIterator.hpp
+++ b/src/buffer/out/AttrRowIterator.hpp
@@ -29,11 +29,11 @@ class AttrRowIterator final
using pointer = TextAttribute*;
using reference = TextAttribute&;
- static AttrRowIterator CreateEndIterator(const ATTR_ROW* const attrRow);
+ static AttrRowIterator CreateEndIterator(const ATTR_ROW* const attrRow) noexcept;
- AttrRowIterator(const ATTR_ROW* const attrRow);
+ AttrRowIterator(const ATTR_ROW* const attrRow) noexcept;
- operator bool() const noexcept;
+ operator bool() const;
bool operator==(const AttrRowIterator& it) const;
bool operator!=(const AttrRowIterator& it) const;
@@ -57,5 +57,5 @@ class AttrRowIterator final
void _increment(size_t count);
void _decrement(size_t count);
- void _setToEnd();
+ void _setToEnd() noexcept;
};
diff --git a/src/buffer/out/CharRow.cpp b/src/buffer/out/CharRow.cpp
index 60a7d0d144c..8ac4ea217da 100644
--- a/src/buffer/out/CharRow.cpp
+++ b/src/buffer/out/CharRow.cpp
@@ -84,7 +84,7 @@ size_t CharRow::size() const noexcept
// - sRowWidth - The width of the row.
// Return Value:
// -
-void CharRow::Reset()
+void CharRow::Reset() noexcept
{
for (auto& cell : _data)
{
@@ -209,7 +209,7 @@ const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
// Note: will throw exception if column is out of bounds
DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
{
- return const_cast(static_cast(this)->DbcsAttrAt(column));
+ return _data.at(column).DbcsAttr();
}
// Routine Description:
@@ -250,29 +250,6 @@ CharRow::reference CharRow::GlyphAt(const size_t column)
return { *this, column };
}
-// Routine Description:
-// - returns string containing text data exactly how it's stored internally, including doubling of
-// leading/trailing cells.
-// Arguments:
-// - none
-// Return Value:
-// - text stored in char row
-// - Note: will throw exception if out of memory
-std::wstring CharRow::GetTextRaw() const
-{
- std::wstring wstr;
- wstr.reserve(_data.size());
- for (size_t i = 0; i < _data.size(); ++i)
- {
- auto glyph = GlyphAt(i);
- for (auto it = glyph.begin(); it != glyph.end(); ++it)
- {
- wstr.push_back(*it);
- }
- }
- return wstr;
-}
-
std::wstring CharRow::GetText() const
{
std::wstring wstr;
@@ -280,24 +257,24 @@ std::wstring CharRow::GetText() const
for (size_t i = 0; i < _data.size(); ++i)
{
- auto glyph = GlyphAt(i);
+ const auto glyph = GlyphAt(i);
if (!DbcsAttrAt(i).IsTrailing())
{
- for (auto it = glyph.begin(); it != glyph.end(); ++it)
+ for (const auto wch : glyph)
{
- wstr.push_back(*it);
+ wstr.push_back(wch);
}
}
}
return wstr;
}
-UnicodeStorage& CharRow::GetUnicodeStorage()
+UnicodeStorage& CharRow::GetUnicodeStorage() noexcept
{
return _pParent->GetUnicodeStorage();
}
-const UnicodeStorage& CharRow::GetUnicodeStorage() const
+const UnicodeStorage& CharRow::GetUnicodeStorage() const noexcept
{
return _pParent->GetUnicodeStorage();
}
@@ -308,7 +285,7 @@ const UnicodeStorage& CharRow::GetUnicodeStorage() const
// - 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
+COORD CharRow::GetStorageKey(const size_t column) const noexcept
{
return { gsl::narrow(column), _pParent->GetId() };
}
diff --git a/src/buffer/out/CharRow.hpp b/src/buffer/out/CharRow.hpp
index c9ff3a0ae17..e1b802d065f 100644
--- a/src/buffer/out/CharRow.hpp
+++ b/src/buffer/out/CharRow.hpp
@@ -53,7 +53,7 @@ class CharRow final
void SetDoubleBytePadded(const bool doubleBytePadded) noexcept;
bool WasDoubleBytePadded() const noexcept;
size_t size() const noexcept;
- void Reset();
+ void Reset() noexcept;
[[nodiscard]] HRESULT Resize(const size_t newSize) noexcept;
size_t MeasureLeft() const;
size_t MeasureRight() const noexcept;
@@ -64,9 +64,6 @@ class CharRow final
void ClearGlyph(const size_t column);
std::wstring GetText() const;
- // other functions implemented at the template class level
- std::wstring GetTextRaw() const;
-
// working with glyphs
const reference GlyphAt(const size_t column) const;
reference GlyphAt(const size_t column);
@@ -78,9 +75,9 @@ class CharRow final
iterator end() noexcept;
const_iterator cend() const noexcept;
- UnicodeStorage& GetUnicodeStorage();
- const UnicodeStorage& GetUnicodeStorage() const;
- COORD GetStorageKey(const size_t column) const;
+ UnicodeStorage& GetUnicodeStorage() noexcept;
+ const UnicodeStorage& GetUnicodeStorage() const noexcept;
+ COORD GetStorageKey(const size_t column) const noexcept;
void UpdateParent(ROW* const pParent) noexcept;
diff --git a/src/buffer/out/CharRowCell.cpp b/src/buffer/out/CharRowCell.cpp
index a6c2d2fb66e..d8cdeff429c 100644
--- a/src/buffer/out/CharRowCell.cpp
+++ b/src/buffer/out/CharRowCell.cpp
@@ -8,13 +8,13 @@
// default glyph value, used for reseting the character data portion of a cell
static constexpr wchar_t DefaultValue = UNICODE_SPACE;
-CharRowCell::CharRowCell() :
+CharRowCell::CharRowCell() noexcept :
_wch{ DefaultValue },
_attr{}
{
}
-CharRowCell::CharRowCell(const wchar_t wch, const DbcsAttribute attr) :
+CharRowCell::CharRowCell(const wchar_t wch, const DbcsAttribute attr) noexcept :
_wch{ wch },
_attr{ attr }
{
@@ -22,7 +22,7 @@ CharRowCell::CharRowCell(const wchar_t wch, const DbcsAttribute attr) :
// Routine Description:
// - "erases" the glyph. really sets it back to the default "empty" value
-void CharRowCell::EraseChars()
+void CharRowCell::EraseChars() noexcept
{
if (_attr.IsGlyphStored())
{
diff --git a/src/buffer/out/CharRowCell.hpp b/src/buffer/out/CharRowCell.hpp
index fd8785bafd7..9ce8ee16b45 100644
--- a/src/buffer/out/CharRowCell.hpp
+++ b/src/buffer/out/CharRowCell.hpp
@@ -27,10 +27,10 @@ Author(s):
class CharRowCell final
{
public:
- CharRowCell();
- CharRowCell(const wchar_t wch, const DbcsAttribute attr);
+ CharRowCell() noexcept;
+ CharRowCell(const wchar_t wch, const DbcsAttribute attr) noexcept;
- void EraseChars();
+ void EraseChars() noexcept;
void Reset() noexcept;
bool IsSpace() const noexcept;
diff --git a/src/buffer/out/CharRowCellReference.cpp b/src/buffer/out/CharRowCellReference.cpp
index 1f320756bd0..0f8a2e1a574 100644
--- a/src/buffer/out/CharRowCellReference.cpp
+++ b/src/buffer/out/CharRowCellReference.cpp
@@ -91,6 +91,9 @@ CharRowCellReference::const_iterator CharRowCellReference::begin() const
// - get read-only iterator to the end of the glyph data
// Return Value:
// - end iterator of the glyph data
+#pragma warning(push)
+#pragma warning(disable : 26481)
+// TODO GH 2672: eliminate using pointers raw as begin/end markers in this class
CharRowCellReference::const_iterator CharRowCellReference::end() const
{
if (_cellData().DbcsAttr().IsGlyphStored())
@@ -103,6 +106,7 @@ CharRowCellReference::const_iterator CharRowCellReference::end() const
return &_cellData().Char() + 1;
}
}
+#pragma warning(pop)
bool operator==(const CharRowCellReference& ref, const std::vector& glyph)
{
diff --git a/src/buffer/out/CharRowCellReference.hpp b/src/buffer/out/CharRowCellReference.hpp
index 64a42a17710..24e2ae45fe9 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) :
+ CharRowCellReference(CharRow& parent, const size_t index) noexcept :
_parent{ parent },
_index{ index }
{
diff --git a/src/buffer/out/DbcsAttribute.hpp b/src/buffer/out/DbcsAttribute.hpp
index f92a707b167..442505052c3 100644
--- a/src/buffer/out/DbcsAttribute.hpp
+++ b/src/buffer/out/DbcsAttribute.hpp
@@ -63,7 +63,7 @@ class DbcsAttribute final
return _glyphStored;
}
- void SetGlyphStored(const bool stored)
+ void SetGlyphStored(const bool stored) noexcept
{
_glyphStored = stored;
}
diff --git a/src/buffer/out/OutputCell.cpp b/src/buffer/out/OutputCell.cpp
index 59dc1c1f8b2..ad30b996bdb 100644
--- a/src/buffer/out/OutputCell.cpp
+++ b/src/buffer/out/OutputCell.cpp
@@ -11,7 +11,7 @@
static constexpr TextAttribute InvalidTextAttribute{ INVALID_COLOR, INVALID_COLOR };
-OutputCell::OutputCell() :
+OutputCell::OutputCell() noexcept :
_text{},
_dbcsAttribute{},
_textAttribute{ InvalidTextAttribute },
@@ -111,7 +111,5 @@ void OutputCell::_setFromOutputCellView(const OutputCellView& cell)
_dbcsAttribute = cell.DbcsAttr();
_textAttribute = cell.TextAttr();
_behavior = cell.TextAttrBehavior();
-
- const auto& view = cell.Chars();
- _text = view;
+ _text = cell.Chars();
}
diff --git a/src/buffer/out/OutputCell.hpp b/src/buffer/out/OutputCell.hpp
index 8599ddf7cb3..df64e0b461e 100644
--- a/src/buffer/out/OutputCell.hpp
+++ b/src/buffer/out/OutputCell.hpp
@@ -25,7 +25,7 @@ Module Name:
class InvalidCharInfoConversionException : public std::exception
{
- const char* what() const noexcept
+ const char* what() const noexcept override
{
return "Cannot convert to CHAR_INFO without explicit TextAttribute";
}
@@ -34,7 +34,7 @@ class InvalidCharInfoConversionException : public std::exception
class OutputCell final
{
public:
- OutputCell();
+ OutputCell() noexcept;
OutputCell(const std::wstring_view charData,
const DbcsAttribute dbcsAttribute,
diff --git a/src/buffer/out/OutputCellIterator.cpp b/src/buffer/out/OutputCellIterator.cpp
index 2068e73af58..dbd9fb8bb7a 100644
--- a/src/buffer/out/OutputCellIterator.cpp
+++ b/src/buffer/out/OutputCellIterator.cpp
@@ -17,7 +17,7 @@ static constexpr TextAttribute InvalidTextAttribute{ INVALID_COLOR, INVALID_COLO
// Arguments:
// - wch - The character to use for filling
// - fillLimit - How many times to allow this value to be viewed/filled. Infinite if 0.
-OutputCellIterator::OutputCellIterator(const wchar_t& wch, const size_t fillLimit) :
+OutputCellIterator::OutputCellIterator(const wchar_t& wch, const size_t fillLimit) noexcept :
_mode(Mode::Fill),
_currentView(s_GenerateView(wch)),
_run(),
@@ -33,7 +33,7 @@ OutputCellIterator::OutputCellIterator(const wchar_t& wch, const size_t fillLimi
// Arguments:
// - attr - The color attribute to use for filling
// - fillLimit - How many times to allow this value to be viewed/filled. Infinite if 0.
-OutputCellIterator::OutputCellIterator(const TextAttribute& attr, const size_t fillLimit) :
+OutputCellIterator::OutputCellIterator(const TextAttribute& attr, const size_t fillLimit) noexcept :
_mode(Mode::Fill),
_currentView(s_GenerateView(attr)),
_run(),
@@ -50,7 +50,7 @@ OutputCellIterator::OutputCellIterator(const TextAttribute& attr, const size_t f
// - wch - The character to use for filling
// - attr - The color attribute to use for filling
// - fillLimit - How many times to allow this value to be viewed/filled. Infinite if 0.
-OutputCellIterator::OutputCellIterator(const wchar_t& wch, const TextAttribute& attr, const size_t fillLimit) :
+OutputCellIterator::OutputCellIterator(const wchar_t& wch, const TextAttribute& attr, const size_t fillLimit) noexcept :
_mode(Mode::Fill),
_currentView(s_GenerateView(wch, attr)),
_run(),
@@ -66,7 +66,7 @@ OutputCellIterator::OutputCellIterator(const wchar_t& wch, const TextAttribute&
// Arguments:
// - charInfo - The legacy character and color data to use for fililng (uses Unicode portion of text data)
// - fillLimit - How many times to allow this value to be viewed/filled. Infinite if 0.
-OutputCellIterator::OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit) :
+OutputCellIterator::OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit) noexcept :
_mode(Mode::Fill),
_currentView(s_GenerateView(charInfo)),
_run(),
@@ -116,7 +116,12 @@ OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text, const
// razzle cannot distinguish between a std::wstring_view and a std::basic_string_view
// NOTE: This one internally casts to wchar_t because Razzle sees WORD and wchar_t as the same type
// despite that Visual Studio build can tell the difference.
-OutputCellIterator::OutputCellIterator(const std::basic_string_view legacyAttrs, const bool /*unused*/) :
+#pragma warning(push)
+#pragma warning(suppress : 26490)
+// Suppresses reinterpret_cast. We're only doing this because Windows doesn't understand the type difference between wchar_t and DWORD.
+// It is not worth trying to separate that out further or risking performance over this particular warning here.
+// TODO GH 2673 - Investigate real wchar_t flag in Windows and resolve this audit issue
+OutputCellIterator::OutputCellIterator(const std::basic_string_view legacyAttrs, const bool /*unused*/) noexcept :
_mode(Mode::LegacyAttr),
_currentView(s_GenerateViewLegacyAttr(legacyAttrs.at(0))),
_run(std::wstring_view(reinterpret_cast(legacyAttrs.data()), legacyAttrs.size())),
@@ -126,12 +131,13 @@ OutputCellIterator::OutputCellIterator(const std::basic_string_view legacy
_fillLimit(0)
{
}
+#pragma warning(pop)
// Routine Description:
// - This is an iterator over legacy cell data. We will use the unicode text and the legacy color attribute.
// Arguments:
// - charInfos - Multiple cell with unicode text and legacy color data.
-OutputCellIterator::OutputCellIterator(const std::basic_string_view charInfos) :
+OutputCellIterator::OutputCellIterator(const std::basic_string_view charInfos) noexcept :
_mode(Mode::CharInfo),
_currentView(s_GenerateView(charInfos.at(0))),
_run(charInfos),
@@ -315,7 +321,7 @@ OutputCellIterator OutputCellIterator::operator++(int)
// - Reference the view to fully-formed output cell data representing the underlying data source.
// Return Value:
// - Reference to the view
-const OutputCellView& OutputCellIterator::operator*() const
+const OutputCellView& OutputCellIterator::operator*() const noexcept
{
return _currentView;
}
@@ -324,7 +330,7 @@ const OutputCellView& OutputCellIterator::operator*() const
// - Get pointer to the view to fully-formed output cell data representing the underlying data source.
// Return Value:
// - Pointer to the view
-const OutputCellView* OutputCellIterator::operator->() const
+const OutputCellView* OutputCellIterator::operator->() const noexcept
{
return &_currentView;
}
@@ -338,7 +344,7 @@ const OutputCellView* OutputCellIterator::operator->() const
// - True if we just turned a lead half into a trailing half (and caller doesn't
// need to further update the view).
// - False if this wasn't applicable and the caller should update the view.
-bool OutputCellIterator::_TryMoveTrailing()
+bool OutputCellIterator::_TryMoveTrailing() noexcept
{
if (_currentView.DbcsAttr().IsLeading())
{
@@ -421,7 +427,7 @@ OutputCellView OutputCellIterator::s_GenerateView(const std::wstring_view view,
// - wch - View representing a single UTF-16 character (that can be represented without surrogates)
// Return Value:
// - Object representing the view into this cell
-OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch)
+OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch) noexcept
{
const auto glyph = std::wstring_view(&wch, 1);
@@ -443,7 +449,7 @@ OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch)
// - attr - View representing a single color
// Return Value:
// - Object representing the view into this cell
-OutputCellView OutputCellIterator::s_GenerateView(const TextAttribute& attr)
+OutputCellView OutputCellIterator::s_GenerateView(const TextAttribute& attr) noexcept
{
return OutputCellView({}, {}, attr, TextAttributeBehavior::StoredOnly);
}
@@ -458,7 +464,7 @@ OutputCellView OutputCellIterator::s_GenerateView(const TextAttribute& attr)
// - attr - View representing a single color
// Return Value:
// - Object representing the view into this cell
-OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch, const TextAttribute& attr)
+OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch, const TextAttribute& attr) noexcept
{
const auto glyph = std::wstring_view(&wch, 1);
@@ -480,12 +486,12 @@ OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch, const Text
// - legacyAttr - View representing a single legacy color
// Return Value:
// - Object representing the view into this cell
-OutputCellView OutputCellIterator::s_GenerateViewLegacyAttr(const WORD& legacyAttr)
+OutputCellView OutputCellIterator::s_GenerateViewLegacyAttr(const WORD& legacyAttr) noexcept
{
WORD cleanAttr = legacyAttr;
WI_ClearAllFlags(cleanAttr, COMMON_LVB_SBCSDBCS); // don't use legacy lead/trailing byte flags for colors
- TextAttribute attr(cleanAttr);
+ const TextAttribute attr(cleanAttr);
return s_GenerateView(attr);
}
@@ -498,7 +504,7 @@ OutputCellView OutputCellIterator::s_GenerateViewLegacyAttr(const WORD& legacyAt
// - charInfo - character and attribute pair representing a single cell
// Return Value:
// - Object representing the view into this cell
-OutputCellView OutputCellIterator::s_GenerateView(const CHAR_INFO& charInfo)
+OutputCellView OutputCellIterator::s_GenerateView(const CHAR_INFO& charInfo) noexcept
{
const auto glyph = std::wstring_view(&charInfo.Char.UnicodeChar, 1);
diff --git a/src/buffer/out/OutputCellIterator.hpp b/src/buffer/out/OutputCellIterator.hpp
index b5b29050760..02f6aefa54e 100644
--- a/src/buffer/out/OutputCellIterator.hpp
+++ b/src/buffer/out/OutputCellIterator.hpp
@@ -33,14 +33,14 @@ class OutputCellIterator final
using pointer = OutputCellView*;
using reference = OutputCellView&;
- OutputCellIterator(const wchar_t& wch, const size_t fillLimit = 0);
- OutputCellIterator(const TextAttribute& attr, const size_t fillLimit = 0);
- OutputCellIterator(const wchar_t& wch, const TextAttribute& attr, const size_t fillLimit = 0);
- OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit = 0);
+ OutputCellIterator(const wchar_t& wch, const size_t fillLimit = 0) noexcept;
+ OutputCellIterator(const TextAttribute& attr, const size_t fillLimit = 0) noexcept;
+ OutputCellIterator(const wchar_t& wch, const TextAttribute& attr, const size_t fillLimit = 0) noexcept;
+ OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit = 0) noexcept;
OutputCellIterator(const std::wstring_view utf16Text);
OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute);
- OutputCellIterator(const std::basic_string_view legacyAttributes, const bool unused);
- OutputCellIterator(const std::basic_string_view charInfos);
+ OutputCellIterator(const std::basic_string_view legacyAttributes, const bool unused) noexcept;
+ OutputCellIterator(const std::basic_string_view charInfos) noexcept;
OutputCellIterator(const std::basic_string_view cells);
~OutputCellIterator() = default;
@@ -55,8 +55,8 @@ class OutputCellIterator final
OutputCellIterator& operator++();
OutputCellIterator operator++(int);
- const OutputCellView& operator*() const;
- const OutputCellView* operator->() const;
+ const OutputCellView& operator*() const noexcept;
+ const OutputCellView* operator->() const noexcept;
private:
enum class Mode
@@ -97,7 +97,7 @@ class OutputCellIterator final
TextAttribute _attr;
- bool _TryMoveTrailing();
+ bool _TryMoveTrailing() noexcept;
static OutputCellView s_GenerateView(const std::wstring_view view);
@@ -108,11 +108,11 @@ class OutputCellIterator final
const TextAttribute attr,
const TextAttributeBehavior behavior);
- static OutputCellView s_GenerateView(const wchar_t& wch);
- static OutputCellView s_GenerateViewLegacyAttr(const WORD& legacyAttr);
- static OutputCellView s_GenerateView(const TextAttribute& attr);
- static OutputCellView s_GenerateView(const wchar_t& wch, const TextAttribute& attr);
- static OutputCellView s_GenerateView(const CHAR_INFO& charInfo);
+ static OutputCellView s_GenerateView(const wchar_t& wch) noexcept;
+ static OutputCellView s_GenerateViewLegacyAttr(const WORD& legacyAttr) noexcept;
+ static OutputCellView s_GenerateView(const TextAttribute& attr) noexcept;
+ static OutputCellView s_GenerateView(const wchar_t& wch, const TextAttribute& attr) noexcept;
+ static OutputCellView s_GenerateView(const CHAR_INFO& charInfo) noexcept;
static OutputCellView s_GenerateView(const OutputCell& cell);
diff --git a/src/buffer/out/OutputCellRect.cpp b/src/buffer/out/OutputCellRect.cpp
index 37711c5343b..90385094465 100644
--- a/src/buffer/out/OutputCellRect.cpp
+++ b/src/buffer/out/OutputCellRect.cpp
@@ -7,7 +7,7 @@
// Routine Description:
// - Constucts an empty in-memory region for holding output buffer cell data.
-OutputCellRect::OutputCellRect() :
+OutputCellRect::OutputCellRect() noexcept :
_rows(0),
_cols(0)
{
@@ -64,7 +64,7 @@ OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
// - Pointer to the location in the rectangle that represents the start of the requested row.
OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
{
- return (_storage.data() + (row * _cols));
+ return &_storage.at(row * _cols);
}
// Routine Description:
@@ -76,7 +76,7 @@ OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
// - Pointer to the location in the rectangle that represents the start of the requested row.
const OutputCell* OutputCellRect::_FindRowOffset(const size_t row) const
{
- return (_storage.data() + (row * _cols));
+ return &_storage.at(row * _cols);
}
// Routine Description:
diff --git a/src/buffer/out/OutputCellRect.hpp b/src/buffer/out/OutputCellRect.hpp
index ae73232505d..ebdb4883e35 100644
--- a/src/buffer/out/OutputCellRect.hpp
+++ b/src/buffer/out/OutputCellRect.hpp
@@ -29,7 +29,7 @@ Revision History:
class OutputCellRect final
{
public:
- OutputCellRect();
+ OutputCellRect() noexcept;
OutputCellRect(const size_t rows, const size_t cols);
gsl::span GetRow(const size_t row);
diff --git a/src/buffer/out/OutputCellView.cpp b/src/buffer/out/OutputCellView.cpp
index 434333c030f..cd1f16a7646 100644
--- a/src/buffer/out/OutputCellView.cpp
+++ b/src/buffer/out/OutputCellView.cpp
@@ -15,7 +15,7 @@
OutputCellView::OutputCellView(const std::wstring_view view,
const DbcsAttribute dbcsAttr,
const TextAttribute textAttr,
- const TextAttributeBehavior behavior) :
+ const TextAttributeBehavior behavior) noexcept :
_view(view),
_dbcsAttr(dbcsAttr),
_textAttr(textAttr),
@@ -27,7 +27,9 @@ OutputCellView::OutputCellView(const std::wstring_view view,
// - Returns reference to view over text data
// Return Value:
// - Reference to UTF-16 character data
-const std::wstring_view& OutputCellView::Chars() const noexcept
+// C26445 - suppressed to enable the `TextBufferTextIterator::operator->` method which needs a non-temporary memory location holding the wstring_view.
+// TODO: GH 2681 - remove this suppression by reconciling the probably bad design of the iterators that leads to this being required.
+[[gsl::suppress(26445)]] const std::wstring_view& OutputCellView::Chars() const noexcept
{
return _view;
}
diff --git a/src/buffer/out/OutputCellView.hpp b/src/buffer/out/OutputCellView.hpp
index 2c425d8088a..06c9b86af21 100644
--- a/src/buffer/out/OutputCellView.hpp
+++ b/src/buffer/out/OutputCellView.hpp
@@ -28,7 +28,7 @@ class OutputCellView
OutputCellView(const std::wstring_view view,
const DbcsAttribute dbcsAttr,
const TextAttribute textAttr,
- const TextAttributeBehavior behavior);
+ const TextAttributeBehavior behavior) noexcept;
const std::wstring_view& Chars() const noexcept;
size_t Columns() const noexcept;
diff --git a/src/buffer/out/Row.cpp b/src/buffer/out/Row.cpp
index 44ffd941f04..4172374af6d 100644
--- a/src/buffer/out/Row.cpp
+++ b/src/buffer/out/Row.cpp
@@ -30,14 +30,14 @@ size_t ROW::size() const noexcept
return _rowWidth;
}
-const CharRow& ROW::GetCharRow() const
+const CharRow& ROW::GetCharRow() const noexcept
{
return _charRow;
}
-CharRow& ROW::GetCharRow()
+CharRow& ROW::GetCharRow() noexcept
{
- return const_cast(static_cast(this)->GetCharRow());
+ return _charRow;
}
const ATTR_ROW& ROW::GetAttrRow() const noexcept
@@ -47,7 +47,7 @@ const ATTR_ROW& ROW::GetAttrRow() const noexcept
ATTR_ROW& ROW::GetAttrRow() noexcept
{
- return const_cast(static_cast(this)->GetAttrRow());
+ return _attrRow;
}
SHORT ROW::GetId() const noexcept
@@ -132,12 +132,12 @@ RowCellIterator ROW::AsCellIter(const size_t startIndex, const size_t count) con
return RowCellIterator(*this, startIndex, count);
}
-UnicodeStorage& ROW::GetUnicodeStorage()
+UnicodeStorage& ROW::GetUnicodeStorage() noexcept
{
return _pParent->GetUnicodeStorage();
}
-const UnicodeStorage& ROW::GetUnicodeStorage() const
+const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
{
return _pParent->GetUnicodeStorage();
}
diff --git a/src/buffer/out/Row.hpp b/src/buffer/out/Row.hpp
index 5bf05c858f6..27d2a390928 100644
--- a/src/buffer/out/Row.hpp
+++ b/src/buffer/out/Row.hpp
@@ -36,8 +36,8 @@ class ROW final
size_t size() const noexcept;
- const CharRow& GetCharRow() const;
- CharRow& GetCharRow();
+ const CharRow& GetCharRow() const noexcept;
+ CharRow& GetCharRow() noexcept;
const ATTR_ROW& GetAttrRow() const noexcept;
ATTR_ROW& GetAttrRow() noexcept;
@@ -54,8 +54,8 @@ class ROW final
RowCellIterator AsCellIter(const size_t startIndex) const;
RowCellIterator AsCellIter(const size_t startIndex, const size_t count) const;
- UnicodeStorage& GetUnicodeStorage();
- const UnicodeStorage& GetUnicodeStorage() const;
+ UnicodeStorage& GetUnicodeStorage() noexcept;
+ const UnicodeStorage& GetUnicodeStorage() const noexcept;
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const bool setWrap, std::optional limitRight = std::nullopt);
diff --git a/src/buffer/out/RowCellIterator.cpp b/src/buffer/out/RowCellIterator.cpp
index 0381e4d933e..0dedc264a25 100644
--- a/src/buffer/out/RowCellIterator.cpp
+++ b/src/buffer/out/RowCellIterator.cpp
@@ -37,38 +37,38 @@ bool RowCellIterator::operator!=(const RowCellIterator& it) const noexcept
return !(*this == it);
}
-RowCellIterator& RowCellIterator::operator+=(const ptrdiff_t& movement)
+RowCellIterator& RowCellIterator::operator+=(const ptrdiff_t& movement) noexcept
{
_pos += movement;
return (*this);
}
-RowCellIterator& RowCellIterator::operator++()
+RowCellIterator& RowCellIterator::operator++() noexcept
{
return this->operator+=(1);
}
-RowCellIterator RowCellIterator::operator++(int)
+RowCellIterator RowCellIterator::operator++(int) noexcept
{
auto temp(*this);
operator++();
return temp;
}
-RowCellIterator RowCellIterator::operator+(const ptrdiff_t& movement)
+RowCellIterator RowCellIterator::operator+(const ptrdiff_t& movement) noexcept
{
auto temp(*this);
temp += movement;
return temp;
}
-const OutputCellView& RowCellIterator::operator*() const
+const OutputCellView& RowCellIterator::operator*() const noexcept
{
return _view;
}
-const OutputCellView* RowCellIterator::operator->() const
+const OutputCellView* RowCellIterator::operator->() const noexcept
{
return &_view;
}
diff --git a/src/buffer/out/RowCellIterator.hpp b/src/buffer/out/RowCellIterator.hpp
index c386bb6afa1..62d6ffc1c14 100644
--- a/src/buffer/out/RowCellIterator.hpp
+++ b/src/buffer/out/RowCellIterator.hpp
@@ -38,13 +38,13 @@ class RowCellIterator final
bool operator==(const RowCellIterator& it) const noexcept;
bool operator!=(const RowCellIterator& it) const noexcept;
- RowCellIterator& operator+=(const ptrdiff_t& movement);
- RowCellIterator& operator++();
- RowCellIterator operator++(int);
- RowCellIterator operator+(const ptrdiff_t& movement);
+ RowCellIterator& operator+=(const ptrdiff_t& movement) noexcept;
+ RowCellIterator& operator++() noexcept;
+ RowCellIterator operator++(int) noexcept;
+ RowCellIterator operator+(const ptrdiff_t& movement) noexcept;
- const OutputCellView& operator*() const;
- const OutputCellView* operator->() const;
+ const OutputCellView& operator*() const noexcept;
+ const OutputCellView* operator->() const noexcept;
private:
const ROW& _row;
diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp
index 84e100afa30..0c964b848e9 100644
--- a/src/buffer/out/TextAttribute.cpp
+++ b/src/buffer/out/TextAttribute.cpp
@@ -16,7 +16,7 @@ bool TextAttribute::IsLegacy() const noexcept
// - color that should be displayed as the foreground color
COLORREF TextAttribute::CalculateRgbForeground(std::basic_string_view colorTable,
COLORREF defaultFgColor,
- COLORREF defaultBgColor) const
+ COLORREF defaultBgColor) const noexcept
{
return _IsReverseVideo() ? _GetRgbBackground(colorTable, defaultBgColor) : _GetRgbForeground(colorTable, defaultFgColor);
}
@@ -29,7 +29,7 @@ COLORREF TextAttribute::CalculateRgbForeground(std::basic_string_view
// - color that should be displayed as the background color
COLORREF TextAttribute::CalculateRgbBackground(std::basic_string_view colorTable,
COLORREF defaultFgColor,
- COLORREF defaultBgColor) const
+ COLORREF defaultBgColor) const noexcept
{
return _IsReverseVideo() ? _GetRgbForeground(colorTable, defaultFgColor) : _GetRgbBackground(colorTable, defaultBgColor);
}
@@ -42,7 +42,7 @@ COLORREF TextAttribute::CalculateRgbBackground(std::basic_string_view
// Return Value:
// - color that is stored as the foreground color
COLORREF TextAttribute::_GetRgbForeground(std::basic_string_view colorTable,
- COLORREF defaultColor) const
+ COLORREF defaultColor) const noexcept
{
return _foreground.GetColor(colorTable, defaultColor, _isBold);
}
@@ -55,7 +55,7 @@ COLORREF TextAttribute::_GetRgbForeground(std::basic_string_view color
// Return Value:
// - color that is stored as the background color
COLORREF TextAttribute::_GetRgbBackground(std::basic_string_view colorTable,
- COLORREF defaultColor) const
+ COLORREF defaultColor) const noexcept
{
return _background.GetColor(colorTable, defaultColor, false);
}
@@ -75,22 +75,22 @@ WORD TextAttribute::GetMetaAttributes() const noexcept
return wMeta;
}
-void TextAttribute::SetForeground(const COLORREF rgbForeground)
+void TextAttribute::SetForeground(const COLORREF rgbForeground) noexcept
{
_foreground = TextColor(rgbForeground);
}
-void TextAttribute::SetBackground(const COLORREF rgbBackground)
+void TextAttribute::SetBackground(const COLORREF rgbBackground) noexcept
{
_background = TextColor(rgbBackground);
}
void TextAttribute::SetFromLegacy(const WORD wLegacy) noexcept
{
- _wAttrLegacy = static_cast(wLegacy & META_ATTRS);
+ _wAttrLegacy = gsl::narrow_cast(wLegacy & META_ATTRS);
WI_ClearAllFlags(_wAttrLegacy, COMMON_LVB_SBCSDBCS);
- BYTE fgIndex = static_cast(wLegacy & FG_ATTRS);
- BYTE bgIndex = static_cast(wLegacy & BG_ATTRS) >> 4;
+ const BYTE fgIndex = gsl::narrow_cast(wLegacy & FG_ATTRS);
+ const BYTE bgIndex = gsl::narrow_cast(wLegacy & BG_ATTRS) >> 4;
_foreground = TextColor(fgIndex);
_background = TextColor(bgIndex);
}
@@ -98,16 +98,16 @@ void TextAttribute::SetFromLegacy(const WORD wLegacy) noexcept
void TextAttribute::SetLegacyAttributes(const WORD attrs,
const bool setForeground,
const bool setBackground,
- const bool setMeta)
+ const bool setMeta) noexcept
{
if (setForeground)
{
- BYTE fgIndex = (BYTE)(attrs & FG_ATTRS);
+ const BYTE fgIndex = gsl::narrow_cast(attrs & FG_ATTRS);
_foreground = TextColor(fgIndex);
}
if (setBackground)
{
- BYTE bgIndex = (BYTE)(attrs & BG_ATTRS) >> 4;
+ const BYTE bgIndex = gsl::narrow_cast(attrs & BG_ATTRS) >> 4;
_background = TextColor(bgIndex);
}
if (setMeta)
@@ -133,17 +133,17 @@ void TextAttribute::SetIndexedAttributes(const std::optional foregro
{
if (foreground)
{
- BYTE fgIndex = (*foreground) & 0xFF;
+ const BYTE fgIndex = (*foreground) & 0xFF;
_foreground = TextColor(fgIndex);
}
if (background)
{
- BYTE bgIndex = (*background) & 0xFF;
+ const BYTE bgIndex = (*background) & 0xFF;
_background = TextColor(bgIndex);
}
}
-void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground)
+void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept
{
if (fIsForeground)
{
diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp
index 1a53bbb611e..eb8cc6111df 100644
--- a/src/buffer/out/TextAttribute.hpp
+++ b/src/buffer/out/TextAttribute.hpp
@@ -39,9 +39,9 @@ class TextAttribute final
}
constexpr TextAttribute(const WORD wLegacyAttr) noexcept :
- _wAttrLegacy{ static_cast(wLegacyAttr & META_ATTRS) },
- _foreground{ static_cast(wLegacyAttr & FG_ATTRS) },
- _background{ static_cast((wLegacyAttr & BG_ATTRS) >> 4) },
+ _wAttrLegacy{ gsl::narrow_cast(wLegacyAttr & META_ATTRS) },
+ _foreground{ gsl::narrow_cast(wLegacyAttr & FG_ATTRS) },
+ _background{ gsl::narrow_cast((wLegacyAttr & BG_ATTRS) >> 4) },
_isBold{ false }
{
// If we're given lead/trailing byte information with the legacy color, strip it.
@@ -59,9 +59,9 @@ class TextAttribute final
constexpr WORD GetLegacyAttributes() const noexcept
{
- BYTE fg = (_foreground.GetIndex() & FG_ATTRS);
- BYTE bg = (_background.GetIndex() << 4) & BG_ATTRS;
- WORD meta = (_wAttrLegacy & META_ATTRS);
+ const BYTE fg = (_foreground.GetIndex() & FG_ATTRS);
+ const BYTE bg = (_background.GetIndex() << 4) & BG_ATTRS;
+ const WORD meta = (_wAttrLegacy & META_ATTRS);
return (fg | bg | meta) | (_isBold ? FOREGROUND_INTENSITY : 0);
}
@@ -80,20 +80,20 @@ class TextAttribute final
constexpr WORD GetLegacyAttributes(const BYTE defaultFgIndex,
const BYTE defaultBgIndex) const noexcept
{
- BYTE fgIndex = _foreground.IsLegacy() ? _foreground.GetIndex() : defaultFgIndex;
- BYTE bgIndex = _background.IsLegacy() ? _background.GetIndex() : defaultBgIndex;
- BYTE fg = (fgIndex & FG_ATTRS);
- BYTE bg = (bgIndex << 4) & BG_ATTRS;
- WORD meta = (_wAttrLegacy & META_ATTRS);
+ const BYTE fgIndex = _foreground.IsLegacy() ? _foreground.GetIndex() : defaultFgIndex;
+ const BYTE bgIndex = _background.IsLegacy() ? _background.GetIndex() : defaultBgIndex;
+ const BYTE fg = (fgIndex & FG_ATTRS);
+ const BYTE bg = (bgIndex << 4) & BG_ATTRS;
+ const WORD meta = (_wAttrLegacy & META_ATTRS);
return (fg | bg | meta) | (_isBold ? FOREGROUND_INTENSITY : 0);
}
COLORREF CalculateRgbForeground(std::basic_string_view colorTable,
COLORREF defaultFgColor,
- COLORREF defaultBgColor) const;
+ COLORREF defaultBgColor) const noexcept;
COLORREF CalculateRgbBackground(std::basic_string_view colorTable,
COLORREF defaultFgColor,
- COLORREF defaultBgColor) const;
+ COLORREF defaultBgColor) const noexcept;
bool IsLeadingByte() const noexcept;
bool IsTrailingByte() const noexcept;
@@ -110,7 +110,7 @@ class TextAttribute final
void SetLegacyAttributes(const WORD attrs,
const bool setForeground,
const bool setBackground,
- const bool setMeta);
+ const bool setMeta) noexcept;
void SetIndexedAttributes(const std::optional foreground,
const std::optional background) noexcept;
@@ -133,9 +133,9 @@ class TextAttribute final
bool IsLegacy() const noexcept;
bool IsBold() const noexcept;
- void SetForeground(const COLORREF rgbForeground);
- void SetBackground(const COLORREF rgbBackground);
- void SetColor(const COLORREF rgbColor, const bool fIsForeground);
+ void SetForeground(const COLORREF rgbForeground) noexcept;
+ void SetBackground(const COLORREF rgbBackground) noexcept;
+ void SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept;
void SetDefaultForeground() noexcept;
void SetDefaultBackground() noexcept;
@@ -150,9 +150,9 @@ class TextAttribute final
private:
COLORREF _GetRgbForeground(std::basic_string_view colorTable,
- COLORREF defaultColor) const;
+ COLORREF defaultColor) const noexcept;
COLORREF _GetRgbBackground(std::basic_string_view colorTable,
- COLORREF defaultColor) const;
+ COLORREF defaultColor) const noexcept;
bool _IsReverseVideo() const noexcept;
void _SetBoldness(const bool isBold) noexcept;
diff --git a/src/buffer/out/TextColor.cpp b/src/buffer/out/TextColor.cpp
index 76778a8230b..606afdac148 100644
--- a/src/buffer/out/TextColor.cpp
+++ b/src/buffer/out/TextColor.cpp
@@ -11,7 +11,7 @@
// - rgbColor: the COLORREF containing the color information for this TextColor
// Return Value:
// -
-void TextColor::SetColor(const COLORREF rgbColor)
+void TextColor::SetColor(const COLORREF rgbColor) noexcept
{
_meta = ColorType::IsRgb;
_red = GetRValue(rgbColor);
@@ -25,7 +25,7 @@ void TextColor::SetColor(const COLORREF rgbColor)
// - index: the index of the colortable we should use for this TextColor.
// Return Value:
// -
-void TextColor::SetIndex(const BYTE index)
+void TextColor::SetIndex(const BYTE index) noexcept
{
_meta = ColorType::IsIndex;
_index = index;
@@ -38,7 +38,7 @@ void TextColor::SetIndex(const BYTE index)
// -
// Return Value:
// -
-void TextColor::SetDefault()
+void TextColor::SetDefault() noexcept
{
_meta = ColorType::IsDefault;
}
@@ -63,7 +63,7 @@ void TextColor::SetDefault()
// - a COLORREF containing the real value of this TextColor.
COLORREF TextColor::GetColor(std::basic_string_view colorTable,
const COLORREF defaultColor,
- bool brighten) const
+ bool brighten) const noexcept
{
if (IsDefault())
{
@@ -81,9 +81,9 @@ COLORREF TextColor::GetColor(std::basic_string_view colorTable,
// If we find a match, return instead the bright version of this color
for (size_t i = 0; i < 8; i++)
{
- if (colorTable[i] == defaultColor)
+ if (colorTable.at(i) == defaultColor)
{
- return colorTable[i + 8];
+ return colorTable.at(i + 8);
}
}
}
@@ -102,12 +102,12 @@ COLORREF TextColor::GetColor(std::basic_string_view colorTable,
if (brighten && _index < 8)
{
FAIL_FAST_IF(colorTable.size() < 16);
- FAIL_FAST_IF((size_t)(_index + 8) > (size_t)(colorTable.size()));
- return colorTable[_index + 8];
+ FAIL_FAST_IF(gsl::narrow_cast(_index) + 8 > colorTable.size());
+ return colorTable.at(gsl::narrow_cast(_index) + 8);
}
else
{
- return colorTable[_index];
+ return colorTable.at(_index);
}
}
}
@@ -119,7 +119,7 @@ COLORREF TextColor::GetColor(std::basic_string_view colorTable,
// -
// Return Value:
// - a COLORREF containing our stored value
-COLORREF TextColor::_GetRGB() const
+COLORREF TextColor::_GetRGB() const noexcept
{
return RGB(_red, _green, _blue);
}
diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h
index 6ba9284148c..f551f4e863a 100644
--- a/src/buffer/out/TextColor.h
+++ b/src/buffer/out/TextColor.h
@@ -91,13 +91,13 @@ struct TextColor
return _meta == ColorType::IsRgb;
}
- void SetColor(const COLORREF rgbColor);
- void SetIndex(const BYTE index);
- void SetDefault();
+ void SetColor(const COLORREF rgbColor) noexcept;
+ void SetIndex(const BYTE index) noexcept;
+ void SetDefault() noexcept;
COLORREF GetColor(std::basic_string_view colorTable,
const COLORREF defaultColor,
- const bool brighten) const;
+ const bool brighten) const noexcept;
constexpr BYTE GetIndex() const noexcept
{
@@ -113,7 +113,7 @@ struct TextColor
BYTE _green;
BYTE _blue;
- COLORREF _GetRGB() const;
+ COLORREF _GetRGB() const noexcept;
#ifdef UNIT_TESTING
friend class TextBufferTests;
diff --git a/src/buffer/out/UnicodeStorage.cpp b/src/buffer/out/UnicodeStorage.cpp
index db5dd318255..41f85adcff6 100644
--- a/src/buffer/out/UnicodeStorage.cpp
+++ b/src/buffer/out/UnicodeStorage.cpp
@@ -4,7 +4,7 @@
#include "precomp.h"
#include "UnicodeStorage.hpp"
-UnicodeStorage::UnicodeStorage() :
+UnicodeStorage::UnicodeStorage() noexcept :
_map{}
{
}
@@ -35,7 +35,7 @@ void UnicodeStorage::StoreGlyph(const key_type key, const mapped_type& glyph)
// - erases key and its associated data from the storage
// Arguments:
// - key - the key to remove
-void UnicodeStorage::Erase(const key_type key) noexcept
+void UnicodeStorage::Erase(const key_type key)
{
_map.erase(key);
}
diff --git a/src/buffer/out/UnicodeStorage.hpp b/src/buffer/out/UnicodeStorage.hpp
index 1b386da4792..0f2a629bd40 100644
--- a/src/buffer/out/UnicodeStorage.hpp
+++ b/src/buffer/out/UnicodeStorage.hpp
@@ -47,13 +47,13 @@ class UnicodeStorage final
using key_type = typename COORD;
using mapped_type = typename std::vector;
- UnicodeStorage();
+ UnicodeStorage() noexcept;
const mapped_type& GetText(const key_type key) const;
void StoreGlyph(const key_type key, const mapped_type& glyph);
- void Erase(const key_type key) noexcept;
+ void Erase(const key_type key);
void Remap(const std::map& rowMap, const std::optional width);
diff --git a/src/buffer/out/cursor.cpp b/src/buffer/out/cursor.cpp
index 6cb69597897..0b2f461be4d 100644
--- a/src/buffer/out/cursor.cpp
+++ b/src/buffer/out/cursor.cpp
@@ -11,7 +11,7 @@
// - Constructor to set default properties for Cursor
// Arguments:
// - ulSize - The height of the cursor within this buffer
-Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) :
+Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
_parentBuffer{ parentBuffer },
_cPosition{ 0 },
_fHasMoved(false),
@@ -87,36 +87,36 @@ ULONG Cursor::GetSize() const noexcept
return _ulSize;
}
-void Cursor::SetHasMoved(const bool fHasMoved)
+void Cursor::SetHasMoved(const bool fHasMoved) noexcept
{
_fHasMoved = fHasMoved;
}
-void Cursor::SetIsVisible(const bool fIsVisible)
+void Cursor::SetIsVisible(const bool fIsVisible) noexcept
{
_fIsVisible = fIsVisible;
_RedrawCursor();
}
-void Cursor::SetIsOn(const bool fIsOn)
+void Cursor::SetIsOn(const bool fIsOn) noexcept
{
_fIsOn = fIsOn;
_RedrawCursorAlways();
}
-void Cursor::SetBlinkingAllowed(const bool fBlinkingAllowed)
+void Cursor::SetBlinkingAllowed(const bool fBlinkingAllowed) noexcept
{
_fBlinkingAllowed = fBlinkingAllowed;
_RedrawCursorAlways();
}
-void Cursor::SetIsDouble(const bool fIsDouble)
+void Cursor::SetIsDouble(const bool fIsDouble) noexcept
{
_fIsDouble = fIsDouble;
_RedrawCursor();
}
-void Cursor::SetIsConversionArea(const bool fIsConversionArea)
+void Cursor::SetIsConversionArea(const bool fIsConversionArea) noexcept
{
// Functionally the same as "Hide cursor"
// Never called with TRUE, it's only used in the creation of a
@@ -125,19 +125,19 @@ void Cursor::SetIsConversionArea(const bool fIsConversionArea)
_RedrawCursorAlways();
}
-void Cursor::SetIsPopupShown(const bool fIsPopupShown)
+void Cursor::SetIsPopupShown(const bool fIsPopupShown) noexcept
{
// Functionally the same as "Hide cursor"
_fIsPopupShown = fIsPopupShown;
_RedrawCursorAlways();
}
-void Cursor::SetDelay(const bool fDelay)
+void Cursor::SetDelay(const bool fDelay) noexcept
{
_fDelay = fDelay;
}
-void Cursor::SetSize(const ULONG ulSize)
+void Cursor::SetSize(const ULONG ulSize) noexcept
{
_ulSize = ulSize;
_RedrawCursor();
@@ -195,7 +195,7 @@ void Cursor::_RedrawCursorAlways() noexcept
CATCH_LOG();
}
-void Cursor::SetPosition(const COORD cPosition)
+void Cursor::SetPosition(const COORD cPosition) noexcept
{
_RedrawCursor();
_cPosition.X = cPosition.X;
@@ -204,50 +204,50 @@ void Cursor::SetPosition(const COORD cPosition)
ResetDelayEOLWrap();
}
-void Cursor::SetXPosition(const int NewX)
+void Cursor::SetXPosition(const int NewX) noexcept
{
_RedrawCursor();
- _cPosition.X = (SHORT)NewX;
+ _cPosition.X = gsl::narrow(NewX);
_RedrawCursor();
ResetDelayEOLWrap();
}
-void Cursor::SetYPosition(const int NewY)
+void Cursor::SetYPosition(const int NewY) noexcept
{
_RedrawCursor();
- _cPosition.Y = (SHORT)NewY;
+ _cPosition.Y = gsl::narrow(NewY);
_RedrawCursor();
ResetDelayEOLWrap();
}
-void Cursor::IncrementXPosition(const int DeltaX)
+void Cursor::IncrementXPosition(const int DeltaX) noexcept
{
_RedrawCursor();
- _cPosition.X += (SHORT)DeltaX;
+ _cPosition.X += gsl::narrow(DeltaX);
_RedrawCursor();
ResetDelayEOLWrap();
}
-void Cursor::IncrementYPosition(const int DeltaY)
+void Cursor::IncrementYPosition(const int DeltaY) noexcept
{
_RedrawCursor();
- _cPosition.Y += (SHORT)DeltaY;
+ _cPosition.Y += gsl::narrow(DeltaY);
_RedrawCursor();
ResetDelayEOLWrap();
}
-void Cursor::DecrementXPosition(const int DeltaX)
+void Cursor::DecrementXPosition(const int DeltaX) noexcept
{
_RedrawCursor();
- _cPosition.X -= (SHORT)DeltaX;
+ _cPosition.X -= gsl::narrow(DeltaX);
_RedrawCursor();
ResetDelayEOLWrap();
}
-void Cursor::DecrementYPosition(const int DeltaY)
+void Cursor::DecrementYPosition(const int DeltaY) noexcept
{
_RedrawCursor();
- _cPosition.Y -= (SHORT)DeltaY;
+ _cPosition.Y -= gsl::narrow(DeltaY);
_RedrawCursor();
ResetDelayEOLWrap();
}
@@ -262,7 +262,7 @@ void Cursor::DecrementYPosition(const int DeltaY)
// - OtherCursor - The cursor to copy properties from
// Return Value:
// -
-void Cursor::CopyProperties(const Cursor& OtherCursor)
+void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept
{
// We shouldn't copy the position as it will be already rearranged by the resize operation.
//_cPosition = pOtherCursor->_cPosition;
@@ -288,34 +288,34 @@ void Cursor::CopyProperties(const Cursor& OtherCursor)
_color = OtherCursor._color;
}
-void Cursor::DelayEOLWrap(const COORD coordDelayedAt)
+void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
{
_coordDelayedAt = coordDelayedAt;
_fDelayedEolWrap = true;
}
-void Cursor::ResetDelayEOLWrap()
+void Cursor::ResetDelayEOLWrap() noexcept
{
_coordDelayedAt = { 0 };
_fDelayedEolWrap = false;
}
-COORD Cursor::GetDelayedAtPosition() const
+COORD Cursor::GetDelayedAtPosition() const noexcept
{
return _coordDelayedAt;
}
-bool Cursor::IsDelayedEOLWrap() const
+bool Cursor::IsDelayedEOLWrap() const noexcept
{
return _fDelayedEolWrap;
}
-void Cursor::StartDeferDrawing()
+void Cursor::StartDeferDrawing() noexcept
{
_fDeferCursorRedraw = true;
}
-void Cursor::EndDeferDrawing()
+void Cursor::EndDeferDrawing() noexcept
{
if (_fHaveDeferredCursorRedraw)
{
@@ -325,27 +325,27 @@ void Cursor::EndDeferDrawing()
_fDeferCursorRedraw = FALSE;
}
-const CursorType Cursor::GetType() const
+const CursorType Cursor::GetType() const noexcept
{
return _cursorType;
}
-const bool Cursor::IsUsingColor() const
+const bool Cursor::IsUsingColor() const noexcept
{
return GetColor() != INVALID_COLOR;
}
-const COLORREF Cursor::GetColor() const
+const COLORREF Cursor::GetColor() const noexcept
{
return _color;
}
-void Cursor::SetColor(const unsigned int color)
+void Cursor::SetColor(const unsigned int color) noexcept
{
- _color = (COLORREF)color;
+ _color = gsl::narrow_cast(color);
}
-void Cursor::SetType(const CursorType type)
+void Cursor::SetType(const CursorType type) noexcept
{
_cursorType = type;
}
diff --git a/src/buffer/out/cursor.h b/src/buffer/out/cursor.h
index 496e96f1ff2..140dcc9492a 100644
--- a/src/buffer/out/cursor.h
+++ b/src/buffer/out/cursor.h
@@ -28,7 +28,7 @@ class Cursor final
public:
static const unsigned int s_InvertCursorColor = INVALID_COLOR;
- Cursor(const ULONG ulSize, TextBuffer& parentBuffer);
+ Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept;
~Cursor();
@@ -50,41 +50,41 @@ class Cursor final
ULONG GetSize() const noexcept;
COORD GetPosition() const noexcept;
- const CursorType GetType() const;
- const bool IsUsingColor() const;
- const COLORREF GetColor() const;
-
- void StartDeferDrawing();
- void EndDeferDrawing();
-
- void SetHasMoved(const bool fHasMoved);
- void SetIsVisible(const bool fIsVisible);
- void SetIsOn(const bool fIsOn);
- void SetBlinkingAllowed(const bool fIsOn);
- void SetIsDouble(const bool fIsDouble);
- void SetIsConversionArea(const bool fIsConversionArea);
- void SetIsPopupShown(const bool fIsPopupShown);
- void SetDelay(const bool fDelay);
- void SetSize(const ULONG ulSize);
+ const CursorType GetType() const noexcept;
+ const bool IsUsingColor() const noexcept;
+ const COLORREF GetColor() const noexcept;
+
+ void StartDeferDrawing() noexcept;
+ void EndDeferDrawing() noexcept;
+
+ void SetHasMoved(const bool fHasMoved) noexcept;
+ void SetIsVisible(const bool fIsVisible) noexcept;
+ void SetIsOn(const bool fIsOn) noexcept;
+ void SetBlinkingAllowed(const bool fIsOn) noexcept;
+ void SetIsDouble(const bool fIsDouble) noexcept;
+ void SetIsConversionArea(const bool fIsConversionArea) noexcept;
+ void SetIsPopupShown(const bool fIsPopupShown) noexcept;
+ void SetDelay(const bool fDelay) noexcept;
+ void SetSize(const ULONG ulSize) noexcept;
void SetStyle(const ULONG ulSize, const COLORREF color, const CursorType type) noexcept;
- void SetPosition(const COORD cPosition);
- void SetXPosition(const int NewX);
- void SetYPosition(const int NewY);
- void IncrementXPosition(const int DeltaX);
- void IncrementYPosition(const int DeltaY);
- void DecrementXPosition(const int DeltaX);
- void DecrementYPosition(const int DeltaY);
+ 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 CopyProperties(const Cursor& OtherCursor);
+ void CopyProperties(const Cursor& OtherCursor) noexcept;
- void DelayEOLWrap(const COORD coordDelayedAt);
- void ResetDelayEOLWrap();
- COORD GetDelayedAtPosition() const;
- bool IsDelayedEOLWrap() const;
+ void DelayEOLWrap(const COORD coordDelayedAt) noexcept;
+ void ResetDelayEOLWrap() noexcept;
+ COORD GetDelayedAtPosition() const noexcept;
+ bool IsDelayedEOLWrap() const noexcept;
- void SetColor(const unsigned int color);
- void SetType(const CursorType type);
+ void SetColor(const unsigned int color) noexcept;
+ void SetType(const CursorType type) noexcept;
private:
TextBuffer& _parentBuffer;
diff --git a/src/buffer/out/textBuffer.cpp b/src/buffer/out/textBuffer.cpp
index 831c672a586..a64406f074b 100644
--- a/src/buffer/out/textBuffer.cpp
+++ b/src/buffer/out/textBuffer.cpp
@@ -49,7 +49,7 @@ TextBuffer::TextBuffer(const COORD screenBufferSize,
// - OtherBuffer - The text buffer to copy properties from
// Return Value:
// -
-void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer)
+void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer) noexcept
{
GetCursor().CopyProperties(OtherBuffer.GetCursor());
}
@@ -60,9 +60,9 @@ void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer)
// -
// Return Value:
// - Total number of rows in the buffer
-UINT TextBuffer::TotalRowCount() const
+UINT TextBuffer::TotalRowCount() const noexcept
{
- return static_cast(_storage.size());
+ return gsl::narrow(_storage.size());
}
// Routine Description:
@@ -78,7 +78,7 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
const size_t offsetIndex = (_firstRow + index) % totalRows;
- return _storage[offsetIndex];
+ return _storage.at(offsetIndex);
}
// Routine Description:
@@ -90,7 +90,11 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
// - reference to the requested row. Asserts if out of bounds.
ROW& TextBuffer::GetRowByOffset(const size_t index)
{
- return const_cast(static_cast(this)->GetRowByOffset(index));
+ const size_t totalRows = TotalRowCount();
+
+ // Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
+ const size_t offsetIndex = (_firstRow + index) % totalRows;
+ return _storage.at(offsetIndex);
}
// Routine Description:
@@ -542,7 +546,7 @@ bool TextBuffer::IncrementCircularBuffer()
_renderTarget.TriggerCircling();
// First, clean out the old "first row" as it will become the "last row" of the buffer after the circle is performed.
- bool fSuccess = _storage.at(_firstRow).Reset(_currentAttributes);
+ const bool fSuccess = _storage.at(_firstRow).Reset(_currentAttributes);
if (fSuccess)
{
// Now proceed to increment.
@@ -584,9 +588,9 @@ COORD TextBuffer::GetLastNonSpaceCharacter(const Microsoft::Console::Types::View
// Search the given viewport by starting at the bottom.
coordEndOfText.Y = viewport.BottomInclusive();
- const ROW* pCurrRow = &GetRowByOffset(coordEndOfText.Y);
+ 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 = static_cast(pCurrRow->GetCharRow().MeasureRight()) - 1;
+ coordEndOfText.X = gsl::narrow(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();
@@ -594,10 +598,10 @@ COORD TextBuffer::GetLastNonSpaceCharacter(const Microsoft::Console::Types::View
while (fDoBackUp)
{
coordEndOfText.Y--;
- pCurrRow = &GetRowByOffset(coordEndOfText.Y);
+ 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 = static_cast(pCurrRow->GetCharRow().MeasureRight()) - 1;
+ coordEndOfText.X = gsl::narrow(backupRow.GetCharRow().MeasureRight()) - 1;
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
}
@@ -640,7 +644,7 @@ COORD TextBuffer::_GetPreviousFromCursor() const
return coordPosition;
}
-const SHORT TextBuffer::GetFirstRowIndex() const
+const SHORT TextBuffer::GetFirstRowIndex() const noexcept
{
return _firstRow;
}
@@ -649,7 +653,7 @@ const Viewport TextBuffer::GetSize() const
return Viewport::FromDimensions({ 0, 0 }, { gsl::narrow(_storage.at(0).size()), gsl::narrow(_storage.size()) });
}
-void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex)
+void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex) noexcept
{
_firstRow = FirstRowIndex;
}
@@ -755,12 +759,12 @@ void TextBuffer::ScrollRows(const SHORT firstRow, const SHORT size, const SHORT
_RefreshRowIDs(std::nullopt);
}
-Cursor& TextBuffer::GetCursor()
+Cursor& TextBuffer::GetCursor() noexcept
{
return _cursor;
}
-const Cursor& TextBuffer::GetCursor() const
+const Cursor& TextBuffer::GetCursor() const noexcept
{
return _cursor;
}
@@ -795,7 +799,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 COORD newSize)
{
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
@@ -812,7 +816,7 @@ void TextBuffer::Reset()
// rotate rows until the top row is at index 0
try
{
- const ROW& newTopRow = _storage[TopRowIndex];
+ const ROW& newTopRow = _storage.at(TopRowIndex);
while (&newTopRow != &_storage.front())
{
_storage.push_back(std::move(_storage.front()));
@@ -843,12 +847,12 @@ void TextBuffer::Reset()
return S_OK;
}
-const UnicodeStorage& TextBuffer::GetUnicodeStorage() const
+const UnicodeStorage& TextBuffer::GetUnicodeStorage() const noexcept
{
return _unicodeStorage;
}
-UnicodeStorage& TextBuffer::GetUnicodeStorage()
+UnicodeStorage& TextBuffer::GetUnicodeStorage() noexcept
{
return _unicodeStorage;
}
@@ -923,7 +927,7 @@ ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
}
THROW_HR_IF(E_FAIL, Row.GetId() == _firstRow);
- return _storage[prevRowIndex];
+ return _storage.at(prevRowIndex);
}
// Method Description:
@@ -932,7 +936,7 @@ ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
// -
// Return Value:
// - This buffer's current render target.
-Microsoft::Console::Render::IRenderTarget& TextBuffer::GetRenderTarget()
+Microsoft::Console::Render::IRenderTarget& TextBuffer::GetRenderTarget() noexcept
{
return _renderTarget;
}
@@ -977,9 +981,9 @@ const TextBuffer::TextAndColor TextBuffer::GetTextForClipboard(const bool lineSe
std::vector selectionBkAttr;
// preallocate to avoid reallocs
- selectionText.reserve(highlight.Width() + 2); // + 2 for \r\n if we munged it
- selectionFgAttr.reserve(highlight.Width() + 2);
- selectionBkAttr.reserve(highlight.Width() + 2);
+ selectionText.reserve(gsl::narrow(highlight.Width()) + 2); // + 2 for \r\n if we munged it
+ selectionFgAttr.reserve(gsl::narrow(highlight.Width()) + 2);
+ selectionBkAttr.reserve(gsl::narrow(highlight.Width()) + 2);
// copy char data into the string buffer, skipping trailing bytes
while (it)
@@ -998,6 +1002,8 @@ const TextBuffer::TextAndColor TextBuffer::GetTextForClipboard(const bool lineSe
selectionBkAttr.push_back(CellBkAttr);
}
}
+#pragma warning(suppress : 26444)
+ // TODO GH 2675: figure out why there's custom construction/destruction happening here
it++;
}
@@ -1059,6 +1065,10 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPo
{
try
{
+ // TODO: GH 602 the font name needs to be passed and stored around as an actual bounded type, not an implicit bounds on LF_FACESIZE
+ const auto faceLength = wcsnlen_s(fontFaceName, LF_FACESIZE);
+ const std::wstring_view faceNameView{ fontFaceName, faceLength };
+
std::ostringstream htmlBuilder;
// First we have to add some standard
@@ -1084,12 +1094,9 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPo
htmlBuilder << ";";
htmlBuilder << "font-family:";
- if (fontFaceName[0] != '\0')
- {
- htmlBuilder << "'";
- htmlBuilder << ConvertToA(CP_UTF8, fontFaceName);
- htmlBuilder << "',";
- }
+ htmlBuilder << "'";
+ htmlBuilder << ConvertToA(CP_UTF8, faceNameView);
+ htmlBuilder << "',";
// even with different font, add monospace as fallback
htmlBuilder << "monospace;";
@@ -1109,7 +1116,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPo
bool hasWrittenAnyText = false;
std::optional fgColor = std::nullopt;
std::optional bkColor = std::nullopt;
- for (UINT row = 0; row < rows.text.size(); row++)
+ for (size_t row = 0; row < rows.text.size(); row++)
{
size_t startOffset = 0;
@@ -1118,25 +1125,25 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPo
htmlBuilder << "
";
}
- for (UINT col = 0; col < rows.text[row].length(); col++)
+ for (size_t col = 0; col < rows.text.at(row).length(); col++)
{
// do not include \r nor \n as they don't have attributes
// and are not HTML friendly. For line break use '
' instead.
- bool isLastCharInRow =
- col == rows.text[row].length() - 1 ||
- rows.text[row][col + 1] == '\r' ||
- rows.text[row][col + 1] == '\n';
+ const bool isLastCharInRow =
+ col == rows.text.at(row).length() - 1 ||
+ rows.text.at(row).at(col + 1) == '\r' ||
+ rows.text.at(row).at(col + 1) == '\n';
bool colorChanged = false;
- if (!fgColor.has_value() || rows.FgAttr[row][col] != fgColor.value())
+ if (!fgColor.has_value() || rows.FgAttr.at(row).at(col) != fgColor.value())
{
- fgColor = rows.FgAttr[row][col];
+ fgColor = rows.FgAttr.at(row).at(col);
colorChanged = true;
}
- if (!bkColor.has_value() || rows.BkAttr[row][col] != bkColor.value())
+ if (!bkColor.has_value() || rows.BkAttr.at(row).at(col) != bkColor.value())
{
- bkColor = rows.BkAttr[row][col];
+ bkColor = rows.BkAttr.at(row).at(col);
colorChanged = true;
}
@@ -1145,7 +1152,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPo
{
// note: this should be escaped (for '<', '>', and '&'),
// however MS Word doesn't appear to support HTML entities
- htmlBuilder << ConvertToA(CP_UTF8, std::wstring_view(rows.text[row].data() + startOffset, col - startOffset + includeCurrent));
+ htmlBuilder << ConvertToA(CP_UTF8, std::wstring_view(rows.text.at(row)).substr(startOffset, col - startOffset + includeCurrent));
startOffset = col;
}
};
diff --git a/src/buffer/out/textBuffer.hpp b/src/buffer/out/textBuffer.hpp
index 97b3375606d..beb477fbbd6 100644
--- a/src/buffer/out/textBuffer.hpp
+++ b/src/buffer/out/textBuffer.hpp
@@ -72,7 +72,7 @@ class TextBuffer final
~TextBuffer() = default;
// Used for duplicating properties to another text buffer
- void CopyProperties(const TextBuffer& OtherBuffer);
+ void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
// row manipulation
const ROW& GetRowByOffset(const size_t index) const;
@@ -107,16 +107,16 @@ class TextBuffer final
COORD GetLastNonSpaceCharacter() const;
COORD GetLastNonSpaceCharacter(const Microsoft::Console::Types::Viewport viewport) const;
- Cursor& GetCursor();
- const Cursor& GetCursor() const;
+ Cursor& GetCursor() noexcept;
+ const Cursor& GetCursor() const noexcept;
- const SHORT GetFirstRowIndex() const;
+ const SHORT GetFirstRowIndex() const noexcept;
const Microsoft::Console::Types::Viewport GetSize() const;
void ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta);
- UINT TotalRowCount() const;
+ UINT TotalRowCount() const noexcept;
[[nodiscard]] TextAttribute GetCurrentAttributes() const noexcept;
@@ -124,12 +124,12 @@ class TextBuffer final
void Reset();
- [[nodiscard]] HRESULT ResizeTraditional(const COORD newSize) noexcept;
+ [[nodiscard]] HRESULT ResizeTraditional(const COORD newSize);
- const UnicodeStorage& GetUnicodeStorage() const;
- UnicodeStorage& GetUnicodeStorage();
+ const UnicodeStorage& GetUnicodeStorage() const noexcept;
+ UnicodeStorage& GetUnicodeStorage() noexcept;
- Microsoft::Console::Render::IRenderTarget& GetRenderTarget();
+ Microsoft::Console::Render::IRenderTarget& GetRenderTarget() noexcept;
class TextAndColor
{
@@ -165,7 +165,7 @@ class TextBuffer final
Microsoft::Console::Render::IRenderTarget& _renderTarget;
- void _SetFirstRowIndex(const SHORT FirstRowIndex);
+ void _SetFirstRowIndex(const SHORT FirstRowIndex) noexcept;
COORD _GetPreviousFromCursor() const;
diff --git a/src/buffer/out/textBufferCellIterator.cpp b/src/buffer/out/textBufferCellIterator.cpp
index 50948ab6bbd..285a4ec2047 100644
--- a/src/buffer/out/textBufferCellIterator.cpp
+++ b/src/buffer/out/textBufferCellIterator.cpp
@@ -65,7 +65,7 @@ TextBufferCellIterator::operator bool() const noexcept
// - it - The other iterator to compare to this one.
// Return Value:
// - True if it's the same text buffer and same cell position. False otherwise.
-bool TextBufferCellIterator::operator==(const TextBufferCellIterator& it) const noexcept
+bool TextBufferCellIterator::operator==(const TextBufferCellIterator& it) const
{
return _pos == it._pos &&
&_buffer == &it._buffer &&
@@ -81,7 +81,7 @@ bool TextBufferCellIterator::operator==(const TextBufferCellIterator& it) const
// - it - The other iterator to compare to this one.
// Return Value:
// - True if it's the same text buffer and different cell position or if they're different buffers. False otherwise.
-bool TextBufferCellIterator::operator!=(const TextBufferCellIterator& it) const noexcept
+bool TextBufferCellIterator::operator!=(const TextBufferCellIterator& it) const
{
return !(*this == it);
}
@@ -212,7 +212,7 @@ void TextBufferCellIterator::_SetPos(const COORD newPos)
if (newPos.X != _pos.X)
{
- const ptrdiff_t diff = newPos.X - _pos.X;
+ const auto diff = gsl::narrow_cast(newPos.X) - gsl::narrow_cast(_pos.X);
_attrIter += diff;
}
diff --git a/src/buffer/out/textBufferCellIterator.hpp b/src/buffer/out/textBufferCellIterator.hpp
index 730154f28ab..d647bd70152 100644
--- a/src/buffer/out/textBufferCellIterator.hpp
+++ b/src/buffer/out/textBufferCellIterator.hpp
@@ -28,12 +28,10 @@ class TextBufferCellIterator
TextBufferCellIterator(const TextBuffer& buffer, COORD pos);
TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Microsoft::Console::Types::Viewport limits);
- ~TextBufferCellIterator() = default;
-
operator bool() const noexcept;
- bool operator==(const TextBufferCellIterator& it) const noexcept;
- bool operator!=(const TextBufferCellIterator& it) const noexcept;
+ bool operator==(const TextBufferCellIterator& it) const;
+ bool operator!=(const TextBufferCellIterator& it) const;
TextBufferCellIterator& operator+=(const ptrdiff_t& movement);
TextBufferCellIterator& operator-=(const ptrdiff_t& movement);
diff --git a/src/buffer/out/textBufferTextIterator.cpp b/src/buffer/out/textBufferTextIterator.cpp
index 05c6a4c997d..9687e317584 100644
--- a/src/buffer/out/textBufferTextIterator.cpp
+++ b/src/buffer/out/textBufferTextIterator.cpp
@@ -16,7 +16,7 @@ using namespace Microsoft::Console::Types;
// - Narrows the view of a cell iterator into a text only iterator.
// Arguments:
// - A cell iterator
-TextBufferTextIterator::TextBufferTextIterator(const TextBufferCellIterator& cellIt) :
+TextBufferTextIterator::TextBufferTextIterator(const TextBufferCellIterator& cellIt) noexcept :
TextBufferCellIterator(cellIt)
{
}
@@ -25,7 +25,8 @@ TextBufferTextIterator::TextBufferTextIterator(const TextBufferCellIterator& cel
// - Returns the text information from the text buffer position addressed by this iterator.
// Return Value:
// - Read only UTF-16 text data
-const std::wstring_view TextBufferTextIterator::operator*() const
+// TODO GH 2682, fix design so this doesn't have to be suppressed.
+[[gsl::suppress(26434)]] const std::wstring_view TextBufferTextIterator::operator*() const noexcept
{
return _view.Chars();
}
@@ -34,7 +35,8 @@ const std::wstring_view TextBufferTextIterator::operator*() const
// - Returns the text information from the text buffer position addressed by this iterator.
// Return Value:
// - Read only UTF-16 text data
-const std::wstring_view* TextBufferTextIterator::operator->() const
+// TODO GH 2682, fix design so this doesn't have to be suppressed.
+[[gsl::suppress(26434)]] const std::wstring_view* TextBufferTextIterator::operator->() const noexcept
{
return &_view.Chars();
}
diff --git a/src/buffer/out/textBufferTextIterator.hpp b/src/buffer/out/textBufferTextIterator.hpp
index 845e86e19c8..634745eec63 100644
--- a/src/buffer/out/textBufferTextIterator.hpp
+++ b/src/buffer/out/textBufferTextIterator.hpp
@@ -22,10 +22,10 @@ class SCREEN_INFORMATION;
class TextBufferTextIterator final : public TextBufferCellIterator
{
public:
- TextBufferTextIterator(const TextBufferCellIterator& cellIter);
+ TextBufferTextIterator(const TextBufferCellIterator& cellIter) noexcept;
- const std::wstring_view operator*() const;
- const std::wstring_view* operator->() const;
+ const std::wstring_view operator*() const noexcept;
+ const std::wstring_view* operator->() const noexcept;
protected:
#if UNIT_TESTING
diff --git a/src/cascadia/ut_app/TerminalApp.Unit.Tests.manifest b/src/cascadia/ut_app/TerminalApp.Unit.Tests.manifest
index ef9516047af..a447bc8fdc2 100644
--- a/src/cascadia/ut_app/TerminalApp.Unit.Tests.manifest
+++ b/src/cascadia/ut_app/TerminalApp.Unit.Tests.manifest
@@ -9,6 +9,7 @@
+
diff --git a/src/inc/DefaultSettings.h b/src/inc/DefaultSettings.h
index 678f4115b31..ed6d8f2a2f7 100644
--- a/src/inc/DefaultSettings.h
+++ b/src/inc/DefaultSettings.h
@@ -26,6 +26,10 @@ constexpr COLORREF DEFAULT_BACKGROUND_WITH_ALPHA = OPACITY_OPAQUE | DEFAULT_BACK
constexpr COLORREF POWERSHELL_BLUE = RGB(1, 36, 86);
constexpr short DEFAULT_HISTORY_SIZE = 9001;
+
+#pragma warning(push)
+#pragma warning(disable : 26426)
+// TODO GH 2674, don't disable this warning, move to std::wstring_view or something like that.
const std::wstring DEFAULT_FONT_FACE{ L"Consolas" };
constexpr int DEFAULT_FONT_SIZE = 12;
@@ -39,3 +43,4 @@ constexpr COLORREF DEFAULT_CURSOR_COLOR = COLOR_WHITE;
constexpr COLORREF DEFAULT_CURSOR_HEIGHT = 25;
const std::wstring DEFAULT_WORD_DELIMITERS{ L" ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?\u2502" };
+#pragma warning(pop)
diff --git a/src/renderer/base/lib/base.vcxproj b/src/renderer/base/lib/base.vcxproj
index 7ba34072f2a..03f238e9ad6 100644
--- a/src/renderer/base/lib/base.vcxproj
+++ b/src/renderer/base/lib/base.vcxproj
@@ -22,6 +22,7 @@
+
diff --git a/src/renderer/base/lib/base.vcxproj.filters b/src/renderer/base/lib/base.vcxproj.filters
index 00f0bb1e6dd..300c6dfc5d4 100644
--- a/src/renderer/base/lib/base.vcxproj.filters
+++ b/src/renderer/base/lib/base.vcxproj.filters
@@ -80,6 +80,9 @@
Header Files\inc
+
+ Header Files\inc
+
diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp
index 94cf4c8e47a..de883e84215 100644
--- a/src/renderer/dx/CustomTextLayout.cpp
+++ b/src/renderer/dx/CustomTextLayout.cpp
@@ -20,16 +20,16 @@ using namespace Microsoft::Console::Render;
// - font - The DirectWrite font face to use while calculating layout (by default, will fallback if necessary)
// - clusters - From the backing buffer, the text to be displayed clustered by the columns it should consume.
// - width - The count of pixels available per column (the expected pixel width of every column)
-CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
- IDWriteTextAnalyzer1* const analyzer,
- IDWriteTextFormat* const format,
- IDWriteFontFace1* const font,
+CustomTextLayout::CustomTextLayout(gsl::not_null const factory,
+ gsl::not_null const analyzer,
+ gsl::not_null const format,
+ gsl::not_null const font,
std::basic_string_view const clusters,
size_t const width) :
- _factory{ factory },
- _analyzer{ analyzer },
- _format{ format },
- _font{ font },
+ _factory{ factory.get() },
+ _analyzer{ analyzer.get() },
+ _format{ format.get() },
+ _font{ font.get() },
_localeName{},
_numberSubstitution{},
_readingDirection{ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT },
@@ -39,7 +39,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
_width{ width }
{
// Fetch the locale name out once now from the format
- _localeName.resize(format->GetLocaleNameLength() + 1); // +1 for null
+ _localeName.resize(gsl::narrow_cast(format->GetLocaleNameLength()) + 1); // +1 for null
THROW_IF_FAILED(format->GetLocaleName(_localeName.data(), gsl::narrow(_localeName.size())));
for (const auto& cluster : clusters)
@@ -58,6 +58,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// - S_OK or suitable DirectX/DirectWrite/Direct2D result code.
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::GetColumns(_Out_ UINT32* columns)
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, columns);
*columns = 0;
RETURN_IF_FAILED(_AnalyzeRuns());
@@ -88,7 +89,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::Draw(_In_opt_ void* clientDrawingContext,
_In_ IDWriteTextRenderer* renderer,
FLOAT originX,
- FLOAT originY)
+ FLOAT originY) noexcept
{
RETURN_IF_FAILED(_AnalyzeRuns());
RETURN_IF_FAILED(_ShapeGlyphRuns());
@@ -146,7 +147,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
}
// Resequence the resulting runs in order before returning to caller.
- size_t totalRuns = _runs.size();
+ const size_t totalRuns = _runs.size();
std::vector runs;
runs.resize(totalRuns);
@@ -178,7 +179,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
const auto textLength = gsl::narrow(_text.size());
// Estimate the maximum number of glyph indices needed to hold a string.
- UINT32 estimatedGlyphCount = _EstimateGlyphCount(textLength);
+ const UINT32 estimatedGlyphCount = _EstimateGlyphCount(textLength);
_glyphIndices.resize(estimatedGlyphCount);
_glyphOffsets.resize(estimatedGlyphCount);
@@ -230,9 +231,9 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// will shape as if the line is not broken.
Run& run = _runs.at(runIndex);
- UINT32 textStart = run.textStart;
- UINT32 textLength = run.textLength;
- UINT32 maxGlyphCount = static_cast(_glyphIndices.size() - glyphStart);
+ const UINT32 textStart = run.textStart;
+ const UINT32 textLength = run.textLength;
+ UINT32 maxGlyphCount = gsl::narrow(_glyphIndices.size() - glyphStart);
UINT32 actualGlyphCount = 0;
run.glyphStart = glyphStart;
@@ -268,7 +269,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
do
{
hr = _analyzer->GetGlyphs(
- &_text[textStart],
+ &_text.at(textStart),
textLength,
run.fontFace.Get(),
run.isSideways, // isSideways,
@@ -280,10 +281,10 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
nullptr, // featureLengths
0, // featureCount
maxGlyphCount, // maxGlyphCount
- &_glyphClusters[textStart],
- &textProps[0],
- &_glyphIndices[glyphStart],
- &glyphProps[0],
+ &_glyphClusters.at(textStart),
+ &textProps.at(0),
+ &_glyphIndices.at(glyphStart),
+ &glyphProps.at(0),
&actualGlyphCount);
tries++;
@@ -291,7 +292,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
{
// Try again using a larger buffer.
maxGlyphCount = _EstimateGlyphCount(maxGlyphCount);
- UINT32 totalGlyphsArrayCount = glyphStart + maxGlyphCount;
+ const UINT32 totalGlyphsArrayCount = glyphStart + maxGlyphCount;
glyphProps.resize(maxGlyphCount);
_glyphIndices.resize(totalGlyphsArrayCount);
@@ -306,19 +307,19 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// Get the placement of the all the glyphs.
- _glyphAdvances.resize(std::max(static_cast(glyphStart + actualGlyphCount), _glyphAdvances.size()));
- _glyphOffsets.resize(std::max(static_cast(glyphStart + actualGlyphCount), _glyphOffsets.size()));
+ _glyphAdvances.resize(std::max(gsl::narrow_cast(glyphStart) + gsl::narrow_cast(actualGlyphCount), _glyphAdvances.size()));
+ _glyphOffsets.resize(std::max(gsl::narrow_cast(glyphStart) + gsl::narrow_cast(actualGlyphCount), _glyphOffsets.size()));
const auto fontSizeFormat = _format->GetFontSize();
const auto fontSize = fontSizeFormat * run.fontScale;
hr = _analyzer->GetGlyphPlacements(
- &_text[textStart],
- &_glyphClusters[textStart],
- &textProps[0],
+ &_text.at(textStart),
+ &_glyphClusters.at(textStart),
+ &textProps.at(0),
textLength,
- &_glyphIndices[glyphStart],
- &glyphProps[0],
+ &_glyphIndices.at(glyphStart),
+ &glyphProps.at(0),
actualGlyphCount,
run.fontFace.Get(),
fontSize,
@@ -329,8 +330,8 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
NULL, // features
NULL, // featureRangeLengths
0, // featureRanges
- &_glyphAdvances[glyphStart],
- &_glyphOffsets[glyphStart]);
+ &_glyphAdvances.at(glyphStart),
+ &_glyphOffsets.at(glyphStart));
RETURN_IF_FAILED(hr);
@@ -391,13 +392,13 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
for (auto i = run.glyphStart; i < (run.glyphStart + run.glyphCount); i++)
{
// Advance is how wide in pixels the glyph is
- auto& advance = _glyphAdvances[i];
+ auto& advance = _glyphAdvances.at(i);
// Offsets is how far to move the origin (in pixels) from where it is
- auto& offset = _glyphOffsets[i];
+ auto& offset = _glyphOffsets.at(i);
// Get how many columns we expected the glyph to have and mutiply into pixels.
- const auto columns = _textClusterColumns[i];
+ const auto columns = _textClusterColumns.at(i);
const auto advanceExpected = static_cast(columns * _width);
// If what we expect is bigger than what we have... pad it out.
@@ -419,7 +420,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// We need to retrieve the design information for this specific glyph so we can figure out the appropriate
// height proportional to the width that we desire.
INT32 advanceInDesignUnits;
- RETURN_IF_FAILED(run.fontFace->GetDesignGlyphAdvances(1, &_glyphIndices[i], &advanceInDesignUnits));
+ RETURN_IF_FAILED(run.fontFace->GetDesignGlyphAdvances(1, &_glyphIndices.at(i), &advanceInDesignUnits));
// When things are drawn, we want the font size (as specified in the base font in the original format)
// to be scaled by some factor.
@@ -467,6 +468,8 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
IDWriteTextRenderer* renderer,
const D2D_POINT_2F origin) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, renderer);
+
try
{
// We're going to start from the origin given and walk to the right for each
@@ -477,21 +480,21 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
for (UINT32 runIndex = 0; runIndex < _runs.size(); ++runIndex)
{
// Get the run
- Run& run = _runs.at(runIndex);
+ const Run& run = _runs.at(runIndex);
// Prepare the glyph run and description objects by converting our
// internal storage representation into something that matches DWrite's structures.
- DWRITE_GLYPH_RUN glyphRun = { 0 };
+ DWRITE_GLYPH_RUN glyphRun;
glyphRun.bidiLevel = run.bidiLevel;
glyphRun.fontEmSize = _format->GetFontSize() * run.fontScale;
glyphRun.fontFace = run.fontFace.Get();
- glyphRun.glyphAdvances = _glyphAdvances.data() + run.glyphStart;
+ glyphRun.glyphAdvances = &_glyphAdvances.at(run.glyphStart);
glyphRun.glyphCount = run.glyphCount;
- glyphRun.glyphIndices = _glyphIndices.data() + run.glyphStart;
- glyphRun.glyphOffsets = _glyphOffsets.data() + run.glyphStart;
+ glyphRun.glyphIndices = &_glyphIndices.at(run.glyphStart);
+ glyphRun.glyphOffsets = &_glyphOffsets.at(run.glyphStart);
glyphRun.isSideways = false;
- DWRITE_GLYPH_RUN_DESCRIPTION glyphRunDescription = { 0 };
+ DWRITE_GLYPH_RUN_DESCRIPTION glyphRunDescription;
glyphRunDescription.clusterMap = _glyphClusters.data();
glyphRunDescription.localeName = _localeName.data();
glyphRunDescription.string = _text.data();
@@ -539,7 +542,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// Return Value:
// - An estimate of how many glyph spaces may be required in the shaping arrays
// to hold the data from a string of the given length.
-[[nodiscard]] UINT32 CustomTextLayout::_EstimateGlyphCount(const UINT32 textLength) noexcept
+[[nodiscard]] constexpr UINT32 CustomTextLayout::_EstimateGlyphCount(const UINT32 textLength) noexcept
{
// This formula is from https://docs.microsoft.com/en-us/windows/desktop/api/dwrite/nf-dwrite-idwritetextanalyzer-getglyphs
// and is the recommended formula for estimating buffer size for glyph count.
@@ -561,12 +564,15 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
_Outptr_result_buffer_(*textLength) WCHAR const** textString,
_Out_ UINT32* textLength)
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, textString);
+ RETURN_HR_IF_NULL(E_INVALIDARG, textLength);
+
*textString = nullptr;
*textLength = 0;
if (textPosition < _text.size())
{
- *textString = _text.data() + textPosition;
+ *textString = &_text.at(textPosition);
*textLength = gsl::narrow(_text.size()) - textPosition;
}
@@ -585,8 +591,11 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// - S_OK or appropriate STL/GSL failure code.
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::GetTextBeforePosition(UINT32 textPosition,
_Outptr_result_buffer_(*textLength) WCHAR const** textString,
- _Out_ UINT32* textLength)
+ _Out_ UINT32* textLength) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, textString);
+ RETURN_HR_IF_NULL(E_INVALIDARG, textLength);
+
*textString = nullptr;
*textLength = 0;
@@ -606,7 +615,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// -
// Return Value:
// - The reading direction held for this layout from construction
-[[nodiscard]] DWRITE_READING_DIRECTION STDMETHODCALLTYPE CustomTextLayout::GetParagraphReadingDirection()
+[[nodiscard]] DWRITE_READING_DIRECTION STDMETHODCALLTYPE CustomTextLayout::GetParagraphReadingDirection() noexcept
{
return _readingDirection;
}
@@ -622,8 +631,11 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// - S_OK or appropriate STL/GSL failure code.
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::GetLocaleName(UINT32 textPosition,
_Out_ UINT32* textLength,
- _Outptr_result_z_ WCHAR const** localeName)
+ _Outptr_result_z_ WCHAR const** localeName) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, textLength);
+ RETURN_HR_IF_NULL(E_INVALIDARG, localeName);
+
*localeName = _localeName.data();
*textLength = gsl::narrow(_text.size()) - textPosition;
@@ -641,8 +653,11 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// - S_OK or appropriate STL/GSL failure code.
[[nodiscard]] HRESULT STDMETHODCALLTYPE CustomTextLayout::GetNumberSubstitution(UINT32 textPosition,
_Out_ UINT32* textLength,
- _COM_Outptr_ IDWriteNumberSubstitution** numberSubstitution)
+ _COM_Outptr_ IDWriteNumberSubstitution** numberSubstitution) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, textLength);
+ RETURN_HR_IF_NULL(E_INVALIDARG, numberSubstitution);
+
*numberSubstitution = nullptr;
*textLength = gsl::narrow(_text.size()) - textPosition;
@@ -799,7 +814,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
RETURN_IF_FAILED(format1->GetFontCollection(&collection));
std::wstring familyName;
- familyName.resize(format1->GetFontFamilyNameLength() + 1);
+ familyName.resize(gsl::narrow_cast(format1->GetFontFamilyNameLength()) + 1);
RETURN_IF_FAILED(format1->GetFontFamilyName(familyName.data(), gsl::narrow(familyName.size())));
const auto weight = format1->GetFontWeight();
@@ -912,7 +927,7 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
if (textLength < runTextLength)
{
runTextLength = textLength; // Limit to what's actually left.
- UINT32 runTextStart = run.textStart;
+ const UINT32 runTextStart = run.textStart;
_SplitCurrentRun(runTextStart + runTextLength);
}
@@ -940,12 +955,12 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
// - - Updates internal state
void CustomTextLayout::_SetCurrentRun(const UINT32 textPosition)
{
- if (_runIndex < _runs.size() && _runs[_runIndex].ContainsTextPosition(textPosition))
+ if (_runIndex < _runs.size() && _runs.at(_runIndex).ContainsTextPosition(textPosition))
{
return;
}
- _runIndex = static_cast(
+ _runIndex = gsl::narrow(
std::find(_runs.begin(), _runs.end(), textPosition) - _runs.begin());
}
@@ -957,13 +972,13 @@ void CustomTextLayout::_SetCurrentRun(const UINT32 textPosition)
// - - Updates internal state, the back half will be selected after running
void CustomTextLayout::_SplitCurrentRun(const UINT32 splitPosition)
{
- UINT32 runTextStart = _runs.at(_runIndex).textStart;
+ const UINT32 runTextStart = _runs.at(_runIndex).textStart;
if (splitPosition <= runTextStart)
return; // no change
// Grow runs by one.
- size_t totalRuns = _runs.size();
+ const size_t totalRuns = _runs.size();
try
{
_runs.resize(totalRuns + 1);
@@ -974,16 +989,16 @@ void CustomTextLayout::_SplitCurrentRun(const UINT32 splitPosition)
}
// Copy the old run to the end.
- LinkedRun& frontHalf = _runs[_runIndex];
+ LinkedRun& frontHalf = _runs.at(_runIndex);
LinkedRun& backHalf = _runs.back();
backHalf = frontHalf;
// Adjust runs' text positions and lengths.
- UINT32 splitPoint = splitPosition - runTextStart;
+ const UINT32 splitPoint = splitPosition - runTextStart;
backHalf.textStart += splitPoint;
backHalf.textLength -= splitPoint;
frontHalf.textLength = splitPoint;
- frontHalf.nextRunIndex = static_cast(totalRuns);
- _runIndex = static_cast(totalRuns);
+ frontHalf.nextRunIndex = gsl::narrow(totalRuns);
+ _runIndex = gsl::narrow(totalRuns);
}
#pragma endregion
diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h
index 6e57dc5c986..598431b8b74 100644
--- a/src/renderer/dx/CustomTextLayout.h
+++ b/src/renderer/dx/CustomTextLayout.h
@@ -19,10 +19,10 @@ namespace Microsoft::Console::Render
public:
// Based on the Windows 7 SDK sample at https://github.com/pauldotknopf/WindowsSDK7-Samples/tree/master/multimedia/DirectWrite/CustomLayout
- CustomTextLayout(IDWriteFactory1* const factory,
- IDWriteTextAnalyzer1* const analyzer,
- IDWriteTextFormat* const format,
- IDWriteFontFace1* const font,
+ CustomTextLayout(gsl::not_null const factory,
+ gsl::not_null const analyzer,
+ gsl::not_null const format,
+ gsl::not_null const font,
const std::basic_string_view<::Microsoft::Console::Render::Cluster> clusters,
size_t const width);
@@ -32,43 +32,43 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT STDMETHODCALLTYPE Draw(_In_opt_ void* clientDrawingContext,
_In_ IDWriteTextRenderer* renderer,
FLOAT originX,
- FLOAT originY);
+ FLOAT originY) noexcept;
// IDWriteTextAnalysisSource methods
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE GetTextAtPosition(UINT32 textPosition,
- _Outptr_result_buffer_(*textLength) WCHAR const** textString,
- _Out_ UINT32* textLength) override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE GetTextBeforePosition(UINT32 textPosition,
- _Outptr_result_buffer_(*textLength) WCHAR const** textString,
- _Out_ UINT32* textLength) override;
- [[nodiscard]] virtual DWRITE_READING_DIRECTION STDMETHODCALLTYPE GetParagraphReadingDirection() override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE GetLocaleName(UINT32 textPosition,
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE GetTextAtPosition(UINT32 textPosition,
+ _Outptr_result_buffer_(*textLength) WCHAR const** textString,
+ _Out_ UINT32* textLength) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE GetTextBeforePosition(UINT32 textPosition,
+ _Outptr_result_buffer_(*textLength) WCHAR const** textString,
+ _Out_ UINT32* textLength) noexcept override;
+ [[nodiscard]] DWRITE_READING_DIRECTION STDMETHODCALLTYPE GetParagraphReadingDirection() noexcept override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE GetLocaleName(UINT32 textPosition,
+ _Out_ UINT32* textLength,
+ _Outptr_result_z_ WCHAR const** localeName) noexcept override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE GetNumberSubstitution(UINT32 textPosition,
_Out_ UINT32* textLength,
- _Outptr_result_z_ WCHAR const** localeName) override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE GetNumberSubstitution(UINT32 textPosition,
- _Out_ UINT32* textLength,
- _COM_Outptr_ IDWriteNumberSubstitution** numberSubstitution) override;
+ _COM_Outptr_ IDWriteNumberSubstitution** numberSubstitution) noexcept override;
// IDWriteTextAnalysisSink methods
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE SetScriptAnalysis(UINT32 textPosition,
- UINT32 textLength,
- _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE SetLineBreakpoints(UINT32 textPosition,
- UINT32 textLength,
- _In_reads_(textLength) DWRITE_LINE_BREAKPOINT const* lineBreakpoints) override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE SetBidiLevel(UINT32 textPosition,
- UINT32 textLength,
- UINT8 explicitLevel,
- UINT8 resolvedLevel) override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE SetNumberSubstitution(UINT32 textPosition,
- UINT32 textLength,
- _In_ IDWriteNumberSubstitution* numberSubstitution) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE SetScriptAnalysis(UINT32 textPosition,
+ UINT32 textLength,
+ _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE SetLineBreakpoints(UINT32 textPosition,
+ UINT32 textLength,
+ _In_reads_(textLength) DWRITE_LINE_BREAKPOINT const* lineBreakpoints) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE SetBidiLevel(UINT32 textPosition,
+ UINT32 textLength,
+ UINT8 explicitLevel,
+ UINT8 resolvedLevel) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE SetNumberSubstitution(UINT32 textPosition,
+ UINT32 textLength,
+ _In_ IDWriteNumberSubstitution* numberSubstitution) override;
protected:
// A single contiguous run of characters containing the same analysis results.
struct Run
{
- Run() :
+ Run() noexcept :
textStart(),
textLength(),
glyphStart(),
@@ -93,12 +93,12 @@ namespace Microsoft::Console::Render
::Microsoft::WRL::ComPtr fontFace;
FLOAT fontScale;
- inline bool ContainsTextPosition(UINT32 desiredTextPosition) const
+ inline bool ContainsTextPosition(UINT32 desiredTextPosition) const noexcept
{
return desiredTextPosition >= textStart && desiredTextPosition < textStart + textLength;
}
- inline bool operator==(UINT32 desiredTextPosition) const
+ inline bool operator==(UINT32 desiredTextPosition) const noexcept
{
// Search by text position using std::find
return ContainsTextPosition(desiredTextPosition);
@@ -108,7 +108,7 @@ namespace Microsoft::Console::Render
// Single text analysis run, which points to the next run.
struct LinkedRun : Run
{
- LinkedRun() :
+ LinkedRun() noexcept :
nextRunIndex(0)
{
}
@@ -132,7 +132,7 @@ namespace Microsoft::Console::Render
IDWriteTextRenderer* renderer,
const D2D_POINT_2F origin) noexcept;
- [[nodiscard]] static UINT32 _EstimateGlyphCount(const UINT32 textLength) noexcept;
+ [[nodiscard]] static constexpr UINT32 _EstimateGlyphCount(const UINT32 textLength) noexcept;
private:
const ::Microsoft::WRL::ComPtr _factory;
diff --git a/src/renderer/dx/CustomTextRenderer.cpp b/src/renderer/dx/CustomTextRenderer.cpp
index b99c263a635..c0e545faf20 100644
--- a/src/renderer/dx/CustomTextRenderer.cpp
+++ b/src/renderer/dx/CustomTextRenderer.cpp
@@ -21,8 +21,10 @@ using namespace Microsoft::Console::Render;
// Return Value:
// - S_OK
[[nodiscard]] HRESULT CustomTextRenderer::IsPixelSnappingDisabled(void* /*clientDrawingContext*/,
- _Out_ BOOL* isDisabled)
+ _Out_ BOOL* isDisabled) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, isDisabled);
+
*isDisabled = false;
return S_OK;
}
@@ -38,9 +40,12 @@ using namespace Microsoft::Console::Render;
// Return Value:
// - S_OK
[[nodiscard]] HRESULT CustomTextRenderer::GetPixelsPerDip(void* clientDrawingContext,
- _Out_ FLOAT* pixelsPerDip)
+ _Out_ FLOAT* pixelsPerDip) noexcept
{
- DrawingContext* drawingContext = static_cast(clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, pixelsPerDip);
+
+ const DrawingContext* drawingContext = static_cast(clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, drawingContext);
float dpiX, dpiY;
drawingContext->renderTarget->GetDpi(&dpiX, &dpiY);
@@ -58,12 +63,24 @@ using namespace Microsoft::Console::Render;
// Return Value:
// - S_OK
[[nodiscard]] HRESULT CustomTextRenderer::GetCurrentTransform(void* clientDrawingContext,
- DWRITE_MATRIX* transform)
+ DWRITE_MATRIX* transform) noexcept
{
- DrawingContext* drawingContext = static_cast(clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, transform);
+
+ const DrawingContext* drawingContext = static_cast(clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, drawingContext);
+
+ // Retrieve as D2D1 matrix then copy into DWRITE matrix.
+ D2D1_MATRIX_3X2_F d2d1Matrix{ 0 };
+ drawingContext->renderTarget->GetTransform(&d2d1Matrix);
+
+ transform->dx = d2d1Matrix.dx;
+ transform->dy = d2d1Matrix.dy;
+ transform->m11 = d2d1Matrix.m11;
+ transform->m12 = d2d1Matrix.m12;
+ transform->m21 = d2d1Matrix.m21;
+ transform->m22 = d2d1Matrix.m22;
- // Matrix structures are defined identically
- drawingContext->renderTarget->GetTransform((D2D1_MATRIX_3X2_F*)transform);
return S_OK;
}
#pragma endregion
@@ -88,17 +105,16 @@ using namespace Microsoft::Console::Render;
FLOAT baselineOriginX,
FLOAT baselineOriginY,
_In_ const DWRITE_UNDERLINE* underline,
- IUnknown* clientDrawingEffect)
+ IUnknown* clientDrawingEffect) noexcept
{
- _FillRectangle(clientDrawingContext,
- clientDrawingEffect,
- baselineOriginX,
- baselineOriginY + underline->offset,
- underline->width,
- underline->thickness,
- underline->readingDirection,
- underline->flowDirection);
- return S_OK;
+ return _FillRectangle(clientDrawingContext,
+ clientDrawingEffect,
+ baselineOriginX,
+ baselineOriginY + underline->offset,
+ underline->width,
+ underline->thickness,
+ underline->readingDirection,
+ underline->flowDirection);
}
// Routine Description:
@@ -120,17 +136,16 @@ using namespace Microsoft::Console::Render;
FLOAT baselineOriginX,
FLOAT baselineOriginY,
_In_ const DWRITE_STRIKETHROUGH* strikethrough,
- IUnknown* clientDrawingEffect)
+ IUnknown* clientDrawingEffect) noexcept
{
- _FillRectangle(clientDrawingContext,
- clientDrawingEffect,
- baselineOriginX,
- baselineOriginY + strikethrough->offset,
- strikethrough->width,
- strikethrough->thickness,
- strikethrough->readingDirection,
- strikethrough->flowDirection);
- return S_OK;
+ return _FillRectangle(clientDrawingContext,
+ clientDrawingEffect,
+ baselineOriginX,
+ baselineOriginY + strikethrough->offset,
+ strikethrough->width,
+ strikethrough->thickness,
+ strikethrough->readingDirection,
+ strikethrough->flowDirection);
}
// Routine Description:
@@ -146,16 +161,17 @@ using namespace Microsoft::Console::Render;
// - flowDirection - textual flow information that could affect the rectangle
// Return Value:
// - S_OK
-void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
- IUnknown* clientDrawingEffect,
- float x,
- float y,
- float width,
- float thickness,
- DWRITE_READING_DIRECTION /*readingDirection*/,
- DWRITE_FLOW_DIRECTION /*flowDirection*/)
+[[nodiscard]] HRESULT CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
+ IUnknown* clientDrawingEffect,
+ float x,
+ float y,
+ float width,
+ float thickness,
+ DWRITE_READING_DIRECTION /*readingDirection*/,
+ DWRITE_FLOW_DIRECTION /*flowDirection*/) noexcept
{
DrawingContext* drawingContext = static_cast(clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, drawingContext);
// Get brush
ID2D1Brush* brush = drawingContext->foregroundBrush;
@@ -165,8 +181,10 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
brush = static_cast(clientDrawingEffect);
}
- D2D1_RECT_F rect = D2D1::RectF(x, y, x + width, y + thickness);
+ const D2D1_RECT_F rect = D2D1::RectF(x, y, x + width, y + thickness);
drawingContext->renderTarget->FillRectangle(&rect, brush);
+
+ return S_OK;
}
// Routine Description:
@@ -189,8 +207,10 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
IDWriteInlineObject* inlineObject,
BOOL isSideways,
BOOL isRightToLeft,
- IUnknown* clientDrawingEffect)
+ IUnknown* clientDrawingEffect) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, inlineObject);
+
return inlineObject->Draw(clientDrawingContext,
this,
originX,
@@ -233,12 +253,11 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
// Since we've delegated the drawing of the background of the text into this function, the origin passed in isn't actually the baseline.
// It's the top left corner. Save that off first.
- D2D1_POINT_2F origin = D2D1::Point2F(baselineOriginX, baselineOriginY);
+ const D2D1_POINT_2F origin = D2D1::Point2F(baselineOriginX, baselineOriginY);
// Then make a copy for the baseline origin (which is part way down the left side of the text, not the top or bottom).
// We'll use this baseline Origin for drawing the actual text.
- D2D1_POINT_2F baselineOrigin = origin;
- baselineOrigin.y += drawingContext->spacing.baseline;
+ const D2D1_POINT_2F baselineOrigin{ origin.x, origin.y + drawingContext->spacing.baseline };
::Microsoft::WRL::ComPtr d2dContext;
RETURN_IF_FAILED(drawingContext->renderTarget->QueryInterface(d2dContext.GetAddressOf()));
@@ -249,11 +268,9 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
rect.bottom = rect.top + drawingContext->cellSize.height;
rect.left = origin.x;
rect.right = rect.left;
+ const auto advancesSpan = gsl::make_span(glyphRun->glyphAdvances, glyphRun->glyphCount);
- for (UINT32 i = 0; i < glyphRun->glyphCount; i++)
- {
- rect.right += glyphRun->glyphAdvances[i];
- }
+ rect.right = std::accumulate(advancesSpan.cbegin(), advancesSpan.cend(), rect.right);
d2dContext->FillRectangle(rect, drawingContext->backgroundBrush);
@@ -270,7 +287,7 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
RETURN_IF_FAILED(drawingContext->dwriteFactory->QueryInterface(dwriteFactory4.GetAddressOf()));
// The list of glyph image formats this renderer is prepared to support.
- DWRITE_GLYPH_IMAGE_FORMATS supportedFormats =
+ const DWRITE_GLYPH_IMAGE_FORMATS supportedFormats =
DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE |
DWRITE_GLYPH_IMAGE_FORMATS_CFF |
DWRITE_GLYPH_IMAGE_FORMATS_COLR |
@@ -283,14 +300,14 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
// Determine whether there are any color glyph runs within glyphRun. If
// there are, glyphRunEnumerator can be used to iterate through them.
::Microsoft::WRL::ComPtr glyphRunEnumerator;
- HRESULT hr = dwriteFactory4->TranslateColorGlyphRun(baselineOrigin,
- glyphRun,
- glyphRunDescription,
- supportedFormats,
- measuringMode,
- nullptr,
- 0,
- &glyphRunEnumerator);
+ const HRESULT hr = dwriteFactory4->TranslateColorGlyphRun(baselineOrigin,
+ glyphRun,
+ glyphRunDescription,
+ supportedFormats,
+ measuringMode,
+ nullptr,
+ 0,
+ &glyphRunEnumerator);
// If the analysis found no color glyphs in the run, just draw normally.
if (hr == DWRITE_E_NOCOLOR)
@@ -320,7 +337,7 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
DWRITE_COLOR_GLYPH_RUN1 const* colorRun;
RETURN_IF_FAILED(glyphRunEnumerator->GetCurrentRun(&colorRun));
- D2D1_POINT_2F currentBaselineOrigin = D2D1::Point2F(colorRun->baselineOriginX, colorRun->baselineOriginY);
+ const D2D1_POINT_2F currentBaselineOrigin = D2D1::Point2F(colorRun->baselineOriginX, colorRun->baselineOriginY);
switch (colorRun->glyphImageFormat)
{
@@ -357,7 +374,7 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
// This run is solid-color outlines, either from non-color
// glyphs or from COLR glyph layers. Use Direct2D to draw them.
- ID2D1Brush* layerBrush;
+ ID2D1Brush* layerBrush{ nullptr };
// The rule is "if 0xffff, use current brush." See:
// https://docs.microsoft.com/en-us/windows/desktop/api/dwrite_2/ns-dwrite_2-dwrite_color_glyph_run
if (colorRun->paletteIndex == 0xFFFF)
@@ -414,6 +431,11 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
_In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,
ID2D1Brush* brush)
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, glyphRun);
+ RETURN_HR_IF_NULL(E_INVALIDARG, glyphRunDescription);
+ RETURN_HR_IF_NULL(E_INVALIDARG, brush);
+
::Microsoft::WRL::ComPtr d2dContext;
RETURN_IF_FAILED(clientDrawingContext->renderTarget->QueryInterface(d2dContext.GetAddressOf()));
@@ -433,8 +455,11 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
D2D1_POINT_2F baselineOrigin,
DWRITE_MEASURING_MODE /*measuringMode*/,
_In_ const DWRITE_GLYPH_RUN* glyphRun,
- _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* /*glyphRunDescription*/)
+ _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* /*glyphRunDescription*/) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, glyphRun);
+
// This is regular text but manually
::Microsoft::WRL::ComPtr d2dFactory;
clientDrawingContext->renderTarget->GetFactory(d2dFactory.GetAddressOf());
@@ -473,8 +498,11 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
D2D1_POINT_2F baselineOrigin,
DWRITE_MEASURING_MODE /*measuringMode*/,
_In_ const DWRITE_GLYPH_RUN* glyphRun,
- _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* /*glyphRunDescription*/)
+ _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* /*glyphRunDescription*/) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, clientDrawingContext);
+ RETURN_HR_IF_NULL(E_INVALIDARG, glyphRun);
+
// This is glow text manually
::Microsoft::WRL::ComPtr d2dFactory;
clientDrawingContext->renderTarget->GetFactory(d2dFactory.GetAddressOf());
diff --git a/src/renderer/dx/CustomTextRenderer.h b/src/renderer/dx/CustomTextRenderer.h
index f64623c11e8..c3e2fc5219b 100644
--- a/src/renderer/dx/CustomTextRenderer.h
+++ b/src/renderer/dx/CustomTextRenderer.h
@@ -15,7 +15,7 @@ namespace Microsoft::Console::Render
IDWriteFactory* dwriteFactory,
const DWRITE_LINE_SPACING spacing,
const D2D_SIZE_F cellSize,
- const D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE)
+ const D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE) noexcept
{
this->renderTarget = renderTarget;
this->foregroundBrush = foregroundBrush;
@@ -42,53 +42,53 @@ namespace Microsoft::Console::Render
// https://docs.microsoft.com/en-us/windows/desktop/DirectWrite/how-to-implement-a-custom-text-renderer
// IDWritePixelSnapping methods
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE IsPixelSnappingDisabled(void* clientDrawingContext,
- _Out_ BOOL* isDisabled) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE IsPixelSnappingDisabled(void* clientDrawingContext,
+ _Out_ BOOL* isDisabled) noexcept override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE GetPixelsPerDip(void* clientDrawingContext,
- _Out_ FLOAT* pixelsPerDip) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE GetPixelsPerDip(void* clientDrawingContext,
+ _Out_ FLOAT* pixelsPerDip) noexcept override;
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE GetCurrentTransform(void* clientDrawingContext,
- _Out_ DWRITE_MATRIX* transform) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE GetCurrentTransform(void* clientDrawingContext,
+ _Out_ DWRITE_MATRIX* transform) noexcept override;
// IDWriteTextRenderer methods
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun(void* clientDrawingContext,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- _In_ const DWRITE_GLYPH_RUN* glyphRun,
- _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,
- IUnknown* clientDrawingEffect) override;
-
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE DrawUnderline(void* clientDrawingContext,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- _In_ const DWRITE_UNDERLINE* underline,
- IUnknown* clientDrawingEffect) override;
-
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE DrawStrikethrough(void* clientDrawingContext,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- _In_ const DWRITE_STRIKETHROUGH* strikethrough,
- IUnknown* clientDrawingEffect) override;
-
- [[nodiscard]] virtual HRESULT STDMETHODCALLTYPE DrawInlineObject(void* clientDrawingContext,
- FLOAT originX,
- FLOAT originY,
- IDWriteInlineObject* inlineObject,
- BOOL isSideways,
- BOOL isRightToLeft,
- IUnknown* clientDrawingEffect) override;
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE DrawGlyphRun(void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ _In_ const DWRITE_GLYPH_RUN* glyphRun,
+ _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,
+ IUnknown* clientDrawingEffect) override;
+
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE DrawUnderline(void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ _In_ const DWRITE_UNDERLINE* underline,
+ IUnknown* clientDrawingEffect) noexcept override;
+
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE DrawStrikethrough(void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ _In_ const DWRITE_STRIKETHROUGH* strikethrough,
+ IUnknown* clientDrawingEffect) noexcept override;
+
+ [[nodiscard]] HRESULT STDMETHODCALLTYPE DrawInlineObject(void* clientDrawingContext,
+ FLOAT originX,
+ FLOAT originY,
+ IDWriteInlineObject* inlineObject,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ IUnknown* clientDrawingEffect) noexcept override;
private:
- void _FillRectangle(void* clientDrawingContext,
- IUnknown* clientDrawingEffect,
- float x,
- float y,
- float width,
- float thickness,
- DWRITE_READING_DIRECTION readingDirection,
- DWRITE_FLOW_DIRECTION flowDirection);
+ [[nodiscard]] HRESULT _FillRectangle(void* clientDrawingContext,
+ IUnknown* clientDrawingEffect,
+ float x,
+ float y,
+ float width,
+ float thickness,
+ DWRITE_READING_DIRECTION readingDirection,
+ DWRITE_FLOW_DIRECTION flowDirection) noexcept;
[[nodiscard]] HRESULT _DrawBasicGlyphRun(DrawingContext* clientDrawingContext,
D2D1_POINT_2F baselineOrigin,
@@ -101,12 +101,12 @@ namespace Microsoft::Console::Render
D2D1_POINT_2F baselineOrigin,
DWRITE_MEASURING_MODE measuringMode,
_In_ const DWRITE_GLYPH_RUN* glyphRun,
- _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription);
+ _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription) noexcept;
[[nodiscard]] HRESULT _DrawGlowGlyphRun(DrawingContext* clientDrawingContext,
D2D1_POINT_2F baselineOrigin,
DWRITE_MEASURING_MODE measuringMode,
_In_ const DWRITE_GLYPH_RUN* glyphRun,
- _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription);
+ _In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription) noexcept;
};
}
diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp
index 33f8790470b..e8cb5589de6 100644
--- a/src/renderer/dx/DxRenderer.cpp
+++ b/src/renderer/dx/DxRenderer.cpp
@@ -15,7 +15,7 @@
#pragma hdrstop
static constexpr float POINTS_PER_INCH = 72.0f;
-static std::wstring FALLBACK_FONT_FACE = L"Consolas";
+static constexpr std::wstring_view FALLBACK_FONT_FACE = L"Consolas";
static constexpr std::wstring_view FALLBACK_LOCALE = L"en-us";
using namespace Microsoft::Console::Render;
@@ -24,6 +24,8 @@ using namespace Microsoft::Console::Types;
// Routine Description:
// - Constructs a DirectX-based renderer for console text
// which primarily uses DirectWrite on a Direct2D surface
+#pragma warning(suppress : 26455)
+// TODO GH 2683: The default constructor should not throw.
DxEngine::DxEngine() :
RenderEngineBase(),
_isInvalidUsed{ false },
@@ -129,7 +131,7 @@ DxEngine::~DxEngine()
_ReleaseDeviceResources();
}
- auto freeOnFail = wil::scope_exit([&] { _ReleaseDeviceResources(); });
+ auto freeOnFail = wil::scope_exit([&]() noexcept { _ReleaseDeviceResources(); });
RETURN_IF_FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&_dxgiFactory2)));
@@ -147,39 +149,37 @@ DxEngine::~DxEngine()
// D3D11_CREATE_DEVICE_DEBUG |
D3D11_CREATE_DEVICE_SINGLETHREADED;
- D3D_FEATURE_LEVEL FeatureLevels[] = {
- D3D_FEATURE_LEVEL_11_1,
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
- D3D_FEATURE_LEVEL_9_1,
- };
+ const std::array FeatureLevels{ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_1 };
// Trying hardware first for maximum performance, then trying WARP (software) renderer second
// in case we're running inside a downlevel VM where hardware passthrough isn't enabled like
// for Windows 7 in a VM.
- const auto hardwareResult = D3D11CreateDevice(NULL,
+ const auto hardwareResult = D3D11CreateDevice(nullptr,
D3D_DRIVER_TYPE_HARDWARE,
- NULL,
+ nullptr,
DeviceFlags,
- FeatureLevels,
- ARRAYSIZE(FeatureLevels),
+ FeatureLevels.data(),
+ gsl::narrow_cast(FeatureLevels.size()),
D3D11_SDK_VERSION,
&_d3dDevice,
- NULL,
+ nullptr,
&_d3dDeviceContext);
if (FAILED(hardwareResult))
{
- RETURN_IF_FAILED(D3D11CreateDevice(NULL,
+ RETURN_IF_FAILED(D3D11CreateDevice(nullptr,
D3D_DRIVER_TYPE_WARP,
- NULL,
+ nullptr,
DeviceFlags,
- FeatureLevels,
- ARRAYSIZE(FeatureLevels),
+ FeatureLevels.data(),
+ gsl::narrow_cast(FeatureLevels.size()),
D3D11_SDK_VERSION,
&_d3dDevice,
- NULL,
+ nullptr,
&_d3dDeviceContext));
}
@@ -196,58 +196,62 @@ DxEngine::~DxEngine()
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
SwapChainDesc.Scaling = DXGI_SCALING_NONE;
- switch (_chainMode)
+ try
{
- case SwapChainMode::ForHwnd:
- {
- // use the HWND's dimensions for the swap chain dimensions.
- RECT rect = { 0 };
- RETURN_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &rect));
-
- SwapChainDesc.Width = rect.right - rect.left;
- SwapChainDesc.Height = rect.bottom - rect.top;
-
- // We can't do alpha for HWNDs. Set to ignore. It will fail otherwise.
- SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
- const auto createSwapChainResult = _dxgiFactory2->CreateSwapChainForHwnd(_d3dDevice.Get(),
- _hwndTarget,
- &SwapChainDesc,
- nullptr,
- nullptr,
- &_dxgiSwapChain);
- if (FAILED(createSwapChainResult))
+ switch (_chainMode)
{
- SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
- RETURN_IF_FAILED(_dxgiFactory2->CreateSwapChainForHwnd(_d3dDevice.Get(),
- _hwndTarget,
- &SwapChainDesc,
- nullptr,
- nullptr,
- &_dxgiSwapChain));
+ case SwapChainMode::ForHwnd:
+ {
+ // use the HWND's dimensions for the swap chain dimensions.
+ RECT rect = { 0 };
+ RETURN_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &rect));
+
+ SwapChainDesc.Width = rect.right - rect.left;
+ SwapChainDesc.Height = rect.bottom - rect.top;
+
+ // We can't do alpha for HWNDs. Set to ignore. It will fail otherwise.
+ SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+ const auto createSwapChainResult = _dxgiFactory2->CreateSwapChainForHwnd(_d3dDevice.Get(),
+ _hwndTarget,
+ &SwapChainDesc,
+ nullptr,
+ nullptr,
+ &_dxgiSwapChain);
+ if (FAILED(createSwapChainResult))
+ {
+ SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ RETURN_IF_FAILED(_dxgiFactory2->CreateSwapChainForHwnd(_d3dDevice.Get(),
+ _hwndTarget,
+ &SwapChainDesc,
+ nullptr,
+ nullptr,
+ &_dxgiSwapChain));
+ }
+
+ break;
}
+ case SwapChainMode::ForComposition:
+ {
+ // Use the given target size for compositions.
+ SwapChainDesc.Width = _displaySizePixels.cx;
+ SwapChainDesc.Height = _displaySizePixels.cy;
- break;
- }
- case SwapChainMode::ForComposition:
- {
- // Use the given target size for compositions.
- SwapChainDesc.Width = _displaySizePixels.cx;
- SwapChainDesc.Height = _displaySizePixels.cy;
-
- // We're doing advanced composition pretty much for the purpose of pretty alpha, so turn it on.
- SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
- // It's 100% required to use scaling mode stretch for composition. There is no other choice.
- SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
-
- RETURN_IF_FAILED(_dxgiFactory2->CreateSwapChainForComposition(_d3dDevice.Get(),
- &SwapChainDesc,
- nullptr,
- &_dxgiSwapChain));
- break;
- }
- default:
- THROW_HR(E_NOTIMPL);
+ // We're doing advanced composition pretty much for the purpose of pretty alpha, so turn it on.
+ SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
+ // It's 100% required to use scaling mode stretch for composition. There is no other choice.
+ SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+
+ RETURN_IF_FAILED(_dxgiFactory2->CreateSwapChainForComposition(_d3dDevice.Get(),
+ &SwapChainDesc,
+ nullptr,
+ &_dxgiSwapChain));
+ break;
+ }
+ default:
+ THROW_HR(E_NOTIMPL);
+ }
}
+ CATCH_RETURN();
// With a new swap chain, mark the entire thing as invalid.
RETURN_IF_FAILED(InvalidateAll());
@@ -265,9 +269,14 @@ DxEngine::~DxEngine()
freeOnFail.release(); // don't need to release if we made it to the bottom and everything was good.
// Notify that swap chain changed.
+
if (_pfn)
{
- _pfn();
+ try
+ {
+ _pfn();
+ }
+ CATCH_LOG(); // A failure in the notification function isn't a failure to prepare, so just log it and go on.
}
return S_OK;
@@ -275,54 +284,57 @@ DxEngine::~DxEngine()
[[nodiscard]] HRESULT DxEngine::_PrepareRenderTarget() noexcept
{
- RETURN_IF_FAILED(_dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&_dxgiSurface)));
-
- D2D1_RENDER_TARGET_PROPERTIES props =
- D2D1::RenderTargetProperties(
- D2D1_RENDER_TARGET_TYPE_DEFAULT,
- D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
- 0.0f,
- 0.0f);
-
- RETURN_IF_FAILED(_d2dFactory->CreateDxgiSurfaceRenderTarget(_dxgiSurface.Get(),
- &props,
- &_d2dRenderTarget));
-
- _d2dRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
- RETURN_IF_FAILED(_d2dRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::DarkRed),
- &_d2dBrushBackground));
-
- RETURN_IF_FAILED(_d2dRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White),
- &_d2dBrushForeground));
-
- const D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties{
- D2D1_CAP_STYLE_SQUARE, // startCap
- D2D1_CAP_STYLE_SQUARE, // endCap
- D2D1_CAP_STYLE_SQUARE, // dashCap
- D2D1_LINE_JOIN_MITER, // lineJoin
- 0.f, // miterLimit
- D2D1_DASH_STYLE_SOLID, // dashStyle
- 0.f, // dashOffset
- };
- RETURN_IF_FAILED(_d2dFactory->CreateStrokeStyle(&strokeStyleProperties, nullptr, 0, &_strokeStyle));
-
- // If in composition mode, apply scaling factor matrix
- if (_chainMode == SwapChainMode::ForComposition)
+ try
{
- const auto fdpi = static_cast(_dpi);
- _d2dRenderTarget->SetDpi(fdpi, fdpi);
+ RETURN_IF_FAILED(_dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&_dxgiSurface)));
+
+ const D2D1_RENDER_TARGET_PROPERTIES props =
+ D2D1::RenderTargetProperties(
+ D2D1_RENDER_TARGET_TYPE_DEFAULT,
+ D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
+ 0.0f,
+ 0.0f);
+
+ RETURN_IF_FAILED(_d2dFactory->CreateDxgiSurfaceRenderTarget(_dxgiSurface.Get(),
+ &props,
+ &_d2dRenderTarget));
+
+ _d2dRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
+ RETURN_IF_FAILED(_d2dRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::DarkRed),
+ &_d2dBrushBackground));
+
+ RETURN_IF_FAILED(_d2dRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White),
+ &_d2dBrushForeground));
+
+ const D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties{
+ D2D1_CAP_STYLE_SQUARE, // startCap
+ D2D1_CAP_STYLE_SQUARE, // endCap
+ D2D1_CAP_STYLE_SQUARE, // dashCap
+ D2D1_LINE_JOIN_MITER, // lineJoin
+ 0.f, // miterLimit
+ D2D1_DASH_STYLE_SOLID, // dashStyle
+ 0.f, // dashOffset
+ };
+ RETURN_IF_FAILED(_d2dFactory->CreateStrokeStyle(&strokeStyleProperties, nullptr, 0, &_strokeStyle));
+
+ // If in composition mode, apply scaling factor matrix
+ if (_chainMode == SwapChainMode::ForComposition)
+ {
+ const auto fdpi = static_cast(_dpi);
+ _d2dRenderTarget->SetDpi(fdpi, fdpi);
- DXGI_MATRIX_3X2_F inverseScale = { 0 };
- inverseScale._11 = 1.0f / _scale;
- inverseScale._22 = inverseScale._11;
+ DXGI_MATRIX_3X2_F inverseScale = { 0 };
+ inverseScale._11 = 1.0f / _scale;
+ inverseScale._22 = inverseScale._11;
- ::Microsoft::WRL::ComPtr sc2;
- RETURN_IF_FAILED(_dxgiSwapChain.As(&sc2));
+ ::Microsoft::WRL::ComPtr sc2;
+ RETURN_IF_FAILED(_dxgiSwapChain.As(&sc2));
- RETURN_IF_FAILED(sc2->SetMatrixTransform(&inverseScale));
+ RETURN_IF_FAILED(sc2->SetMatrixTransform(&inverseScale));
+ }
+ return S_OK;
}
-
- return S_OK;
+ CATCH_RETURN();
}
// Routine Description:
@@ -333,31 +345,35 @@ DxEngine::~DxEngine()
// -
void DxEngine::_ReleaseDeviceResources() noexcept
{
- _haveDeviceResources = false;
- _d2dBrushForeground.Reset();
- _d2dBrushBackground.Reset();
-
- if (nullptr != _d2dRenderTarget.Get() && _isPainting)
+ try
{
- _d2dRenderTarget->EndDraw();
- }
+ _haveDeviceResources = false;
+ _d2dBrushForeground.Reset();
+ _d2dBrushBackground.Reset();
- _d2dRenderTarget.Reset();
+ if (nullptr != _d2dRenderTarget.Get() && _isPainting)
+ {
+ _d2dRenderTarget->EndDraw();
+ }
- _dxgiSurface.Reset();
- _dxgiSwapChain.Reset();
+ _d2dRenderTarget.Reset();
- if (nullptr != _d3dDeviceContext.Get())
- {
- // To ensure the swap chain goes away we must unbind any views from the
- // D3D pipeline
- _d3dDeviceContext->OMSetRenderTargets(0, nullptr, nullptr);
- }
- _d3dDeviceContext.Reset();
+ _dxgiSurface.Reset();
+ _dxgiSwapChain.Reset();
+
+ if (nullptr != _d3dDeviceContext.Get())
+ {
+ // To ensure the swap chain goes away we must unbind any views from the
+ // D3D pipeline
+ _d3dDeviceContext->OMSetRenderTargets(0, nullptr, nullptr);
+ }
+ _d3dDeviceContext.Reset();
- _d3dDevice.Reset();
+ _d3dDevice.Reset();
- _dxgiFactory2.Reset();
+ _dxgiFactory2.Reset();
+ }
+ CATCH_LOG();
}
// Routine Description:
@@ -375,10 +391,10 @@ void DxEngine::_ReleaseDeviceResources() noexcept
_Out_ IDWriteTextLayout** ppTextLayout) noexcept
{
return _dwriteFactory->CreateTextLayout(string,
- static_cast(stringLength),
+ gsl::narrow(stringLength),
_dwriteTextFormat.Get(),
- (float)_displaySizePixels.cx,
- _glyphCell.cy != 0 ? _glyphCell.cy : (float)_displaySizePixels.cy,
+ gsl::narrow(_displaySizePixels.cx),
+ _glyphCell.cy != 0 ? _glyphCell.cy : gsl::narrow(_displaySizePixels.cy),
ppTextLayout);
}
@@ -410,7 +426,7 @@ void DxEngine::SetCallback(std::function pfn)
_pfn = pfn;
}
-Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
+Microsoft::WRL::ComPtr DxEngine::GetSwapChain()
{
if (_dxgiSwapChain.Get() == nullptr)
{
@@ -428,6 +444,8 @@ Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
// - S_OK
[[nodiscard]] HRESULT DxEngine::Invalidate(const SMALL_RECT* const psrRegion) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, psrRegion);
+
_InvalidOr(*psrRegion);
return S_OK;
}
@@ -440,7 +458,9 @@ Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
// - S_OK
[[nodiscard]] HRESULT DxEngine::InvalidateCursor(const COORD* const pcoordCursor) noexcept
{
- SMALL_RECT sr = Microsoft::Console::Types::Viewport::FromCoord(*pcoordCursor).ToInclusive();
+ RETURN_HR_IF_NULL(E_INVALIDARG, pcoordCursor);
+
+ const SMALL_RECT sr = Microsoft::Console::Types::Viewport::FromCoord(*pcoordCursor).ToInclusive();
return Invalidate(&sr);
}
@@ -452,6 +472,8 @@ Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
// - S_OK
[[nodiscard]] HRESULT DxEngine::InvalidateSystem(const RECT* const prcDirtyClient) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, prcDirtyClient);
+
_InvalidOr(*prcDirtyClient);
return S_OK;
@@ -484,39 +506,43 @@ Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
{
if (pcoordDelta->X != 0 || pcoordDelta->Y != 0)
{
- POINT delta = { 0 };
- delta.x = pcoordDelta->X * _glyphCell.cx;
- delta.y = pcoordDelta->Y * _glyphCell.cy;
+ try
+ {
+ POINT delta = { 0 };
+ delta.x = pcoordDelta->X * _glyphCell.cx;
+ delta.y = pcoordDelta->Y * _glyphCell.cy;
- _InvalidOffset(delta);
+ _InvalidOffset(delta);
- _invalidScroll.cx += delta.x;
- _invalidScroll.cy += delta.y;
+ _invalidScroll.cx += delta.x;
+ _invalidScroll.cy += delta.y;
- // Add the revealed portion of the screen from the scroll to the invalid area.
- const RECT display = _GetDisplayRect();
- RECT reveal = display;
+ // Add the revealed portion of the screen from the scroll to the invalid area.
+ const RECT display = _GetDisplayRect();
+ RECT reveal = display;
- // X delta first
- OffsetRect(&reveal, delta.x, 0);
- IntersectRect(&reveal, &reveal, &display);
- SubtractRect(&reveal, &display, &reveal);
+ // X delta first
+ OffsetRect(&reveal, delta.x, 0);
+ IntersectRect(&reveal, &reveal, &display);
+ SubtractRect(&reveal, &display, &reveal);
- if (!IsRectEmpty(&reveal))
- {
- _InvalidOr(reveal);
- }
+ if (!IsRectEmpty(&reveal))
+ {
+ _InvalidOr(reveal);
+ }
- // Y delta second (subtract rect won't work if you move both)
- reveal = display;
- OffsetRect(&reveal, 0, delta.y);
- IntersectRect(&reveal, &reveal, &display);
- SubtractRect(&reveal, &display, &reveal);
+ // Y delta second (subtract rect won't work if you move both)
+ reveal = display;
+ OffsetRect(&reveal, 0, delta.y);
+ IntersectRect(&reveal, &reveal, &display);
+ SubtractRect(&reveal, &display, &reveal);
- if (!IsRectEmpty(&reveal))
- {
- _InvalidOr(reveal);
+ if (!IsRectEmpty(&reveal))
+ {
+ _InvalidOr(reveal);
+ }
}
+ CATCH_RETURN();
}
return S_OK;
@@ -544,6 +570,8 @@ Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
// - S_FALSE because we don't use this.
[[nodiscard]] HRESULT DxEngine::InvalidateCircling(_Out_ bool* const pForcePaint) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, pForcePaint);
+
*pForcePaint = false;
return S_FALSE;
}
@@ -577,7 +605,7 @@ Microsoft::WRL::ComPtr DxEngine::GetSwapChain() noexcept
return size;
}
default:
- THROW_HR(E_NOTIMPL);
+ FAIL_FAST_HR(E_NOTIMPL);
}
}
@@ -617,7 +645,7 @@ void _ScaleByFont(RECT& cellsToPixels, SIZE fontSize) noexcept
// - -Y is up, Y is down, -X is left, X is right.
// Return Value:
// -
-void DxEngine::_InvalidOffset(POINT delta) noexcept
+void DxEngine::_InvalidOffset(POINT delta)
{
if (_isInvalidUsed)
{
@@ -671,7 +699,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
{
UnionRect(&_invalidRect, &_invalidRect, &rc);
- RECT rcScreen = _GetDisplayRect();
+ const RECT rcScreen = _GetDisplayRect();
IntersectRect(&_invalidRect, &_invalidRect, &rcScreen);
}
else
@@ -689,6 +717,8 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
// - S_FALSE because this is unused.
[[nodiscard]] HRESULT DxEngine::PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, pForcePaint);
+
*pForcePaint = false;
return S_FALSE;
}
@@ -706,37 +736,41 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
if (_isEnabled)
{
- const auto clientSize = _GetClientSize();
- if (!_haveDeviceResources)
+ try
{
- RETURN_IF_FAILED(_CreateDeviceResources(true));
- }
- else if (_displaySizePixels.cy != clientSize.cy ||
- _displaySizePixels.cx != clientSize.cx)
- {
- // OK, we're going to play a dangerous game here for the sake of optimizing resize
- // First, set up a complete clear of all device resources if something goes terribly wrong.
- auto resetDeviceResourcesOnFailure = wil::scope_exit([&] {
- _ReleaseDeviceResources();
- });
+ const auto clientSize = _GetClientSize();
+ if (!_haveDeviceResources)
+ {
+ RETURN_IF_FAILED(_CreateDeviceResources(true));
+ }
+ else if (_displaySizePixels.cy != clientSize.cy ||
+ _displaySizePixels.cx != clientSize.cx)
+ {
+ // OK, we're going to play a dangerous game here for the sake of optimizing resize
+ // First, set up a complete clear of all device resources if something goes terribly wrong.
+ auto resetDeviceResourcesOnFailure = wil::scope_exit([&]() noexcept {
+ _ReleaseDeviceResources();
+ });
- // Now let go of a few of the device resources that get in the way of resizing buffers in the swap chain
- _dxgiSurface.Reset();
- _d2dRenderTarget.Reset();
+ // Now let go of a few of the device resources that get in the way of resizing buffers in the swap chain
+ _dxgiSurface.Reset();
+ _d2dRenderTarget.Reset();
- // Change the buffer size and recreate the render target (and surface)
- RETURN_IF_FAILED(_dxgiSwapChain->ResizeBuffers(2, clientSize.cx, clientSize.cy, DXGI_FORMAT_B8G8R8A8_UNORM, 0));
- RETURN_IF_FAILED(_PrepareRenderTarget());
+ // Change the buffer size and recreate the render target (and surface)
+ RETURN_IF_FAILED(_dxgiSwapChain->ResizeBuffers(2, clientSize.cx, clientSize.cy, DXGI_FORMAT_B8G8R8A8_UNORM, 0));
+ RETURN_IF_FAILED(_PrepareRenderTarget());
- // OK we made it past the parts that can cause errors. We can release our failure handler.
- resetDeviceResourcesOnFailure.release();
+ // OK we made it past the parts that can cause errors. We can release our failure handler.
+ resetDeviceResourcesOnFailure.release();
- // And persist the new size.
- _displaySizePixels = clientSize;
- }
+ // And persist the new size.
+ _displaySizePixels = clientSize;
+ }
- _d2dRenderTarget->BeginDraw();
- _isPainting = true;
+ _d2dRenderTarget->BeginDraw();
+ _isPainting = true;
+ }
+ CATCH_RETURN();
}
return S_OK;
@@ -766,7 +800,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
{
_presentDirty = _invalidRect;
- RECT display = _GetDisplayRect();
+ const RECT display = _GetDisplayRect();
SubtractRect(&_presentScroll, &display, &_presentDirty);
_presentOffset.x = _invalidScroll.cx;
_presentOffset.y = _invalidScroll.cy;
@@ -811,13 +845,17 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
// - Any DirectX error, a memory error, etc.
[[nodiscard]] HRESULT DxEngine::_CopyFrontToBack() noexcept
{
- Microsoft::WRL::ComPtr backBuffer;
- Microsoft::WRL::ComPtr frontBuffer;
+ try
+ {
+ Microsoft::WRL::ComPtr backBuffer;
+ Microsoft::WRL::ComPtr frontBuffer;
- RETURN_IF_FAILED(_dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)));
- RETURN_IF_FAILED(_dxgiSwapChain->GetBuffer(1, IID_PPV_ARGS(&frontBuffer)));
+ RETURN_IF_FAILED(_dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)));
+ RETURN_IF_FAILED(_dxgiSwapChain->GetBuffer(1, IID_PPV_ARGS(&frontBuffer)));
- _d3dDeviceContext->CopyResource(backBuffer.Get(), frontBuffer.Get());
+ _d3dDeviceContext->CopyResource(backBuffer.Get(), frontBuffer.Get());
+ }
+ CATCH_RETURN();
return S_OK;
}
@@ -833,16 +871,20 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
{
if (_presentReady)
{
- FAIL_FAST_IF_FAILED(_dxgiSwapChain->Present(1, 0));
- /*FAIL_FAST_IF_FAILED(_dxgiSwapChain->Present1(1, 0, &_presentParams));*/
+ try
+ {
+ FAIL_FAST_IF_FAILED(_dxgiSwapChain->Present(1, 0));
+ /*FAIL_FAST_IF_FAILED(_dxgiSwapChain->Present1(1, 0, &_presentParams));*/
- RETURN_IF_FAILED(_CopyFrontToBack());
- _presentReady = false;
+ RETURN_IF_FAILED(_CopyFrontToBack());
+ _presentReady = false;
- _presentDirty = { 0 };
- _presentOffset = { 0 };
- _presentScroll = { 0 };
- _presentParams = { 0 };
+ _presentDirty = { 0 };
+ _presentOffset = { 0 };
+ _presentScroll = { 0 };
+ _presentParams = { 0 };
+ }
+ CATCH_RETURN();
}
return S_OK;
@@ -945,7 +987,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
COORD const coordTarget) noexcept
{
const auto existingColor = _d2dBrushForeground->GetColor();
- const auto restoreBrushOnExit = wil::scope_exit([&] { _d2dBrushForeground->SetColor(existingColor); });
+ const auto restoreBrushOnExit = wil::scope_exit([&]() noexcept { _d2dBrushForeground->SetColor(existingColor); });
_d2dBrushForeground->SetColor(_ColorFFromColorRef(color));
@@ -1028,7 +1070,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
0.5f);
_d2dBrushForeground->SetColor(selectionColor);
- const auto resetColorOnExit = wil::scope_exit([&] { _d2dBrushForeground->SetColor(existingColor); });
+ const auto resetColorOnExit = wil::scope_exit([&]() noexcept { _d2dBrushForeground->SetColor(existingColor); });
RECT pixels;
pixels.left = rect.Left * _glyphCell.cx;
@@ -1089,7 +1131,8 @@ enum class CursorPaintType
{
// Enforce min/max cursor height
ULONG ulHeight = std::clamp(options.ulCursorHeightPercent, s_ulMinCursorHeightPercent, s_ulMaxCursorHeightPercent);
- ulHeight = (ULONG)((_glyphCell.cy * ulHeight) / 100);
+
+ ulHeight = gsl::narrow((_glyphCell.cy * ulHeight) / 100);
rect.top = rect.bottom - ulHeight;
break;
}
@@ -1202,25 +1245,29 @@ enum class CursorPaintType
// - S_OK or relevant DirectX error
[[nodiscard]] HRESULT DxEngine::UpdateFont(const FontInfoDesired& pfiFontInfoDesired, FontInfo& fiFontInfo) noexcept
{
- const auto hr = _GetProposedFont(pfiFontInfoDesired,
- fiFontInfo,
- _dpi,
- _dwriteTextFormat,
- _dwriteTextAnalyzer,
- _dwriteFontFace);
+ RETURN_IF_FAILED(_GetProposedFont(pfiFontInfoDesired,
+ fiFontInfo,
+ _dpi,
+ _dwriteTextFormat,
+ _dwriteTextAnalyzer,
+ _dwriteFontFace));
- const auto size = fiFontInfo.GetSize();
+ try
+ {
+ const auto size = fiFontInfo.GetSize();
- _glyphCell.cx = size.X;
- _glyphCell.cy = size.Y;
+ _glyphCell.cx = size.X;
+ _glyphCell.cy = size.Y;
+ }
+ CATCH_RETURN();
- return hr;
+ return S_OK;
}
[[nodiscard]] Viewport DxEngine::GetViewportInCharacters(const Viewport& viewInPixels) noexcept
{
- short widthInChars = static_cast(viewInPixels.Width() / _glyphCell.cx);
- short heightInChars = static_cast(viewInPixels.Height() / _glyphCell.cy);
+ const short widthInChars = gsl::narrow_cast(viewInPixels.Width() / _glyphCell.cx);
+ const short heightInChars = gsl::narrow_cast(viewInPixels.Height() / _glyphCell.cy);
return Viewport::FromDimensions(viewInPixels.Origin(), { widthInChars, heightInChars });
}
@@ -1297,13 +1344,13 @@ float DxEngine::GetScaling() const noexcept
// -
// Return Value:
// - Rectangle describing dirty area in characters.
-[[nodiscard]] SMALL_RECT DxEngine::GetDirtyRectInChars() noexcept
+[[nodiscard]] SMALL_RECT DxEngine::GetDirtyRectInChars()
{
SMALL_RECT r;
- r.Top = (SHORT)(floor(_invalidRect.top / _glyphCell.cy));
- r.Left = (SHORT)(floor(_invalidRect.left / _glyphCell.cx));
- r.Bottom = (SHORT)(floor(_invalidRect.bottom / _glyphCell.cy));
- r.Right = (SHORT)(floor(_invalidRect.right / _glyphCell.cx));
+ r.Top = gsl::narrow(floor(_invalidRect.top / _glyphCell.cy));
+ r.Left = gsl::narrow(floor(_invalidRect.left / _glyphCell.cx));
+ r.Bottom = gsl::narrow(floor(_invalidRect.bottom / _glyphCell.cy));
+ r.Right = gsl::narrow(floor(_invalidRect.right / _glyphCell.cx));
// Exclusive to inclusive
r.Bottom--;
@@ -1321,7 +1368,7 @@ float DxEngine::GetScaling() const noexcept
// - Nearest integer short x and y values for each cell.
[[nodiscard]] COORD DxEngine::_GetFontSize() const noexcept
{
- return { (SHORT)(_glyphCell.cx), (SHORT)(_glyphCell.cy) };
+ return { gsl::narrow(_glyphCell.cx), gsl::narrow(_glyphCell.cy) };
}
// Routine Description:
@@ -1345,20 +1392,26 @@ float DxEngine::GetScaling() const noexcept
// - S_OK or relevant DirectWrite error.
[[nodiscard]] HRESULT DxEngine::IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept
{
- Cluster cluster(glyph, 0); // columns don't matter, we're doing analysis not layout.
+ RETURN_HR_IF_NULL(E_INVALIDARG, pResult);
- // Create the text layout
- CustomTextLayout layout(_dwriteFactory.Get(),
- _dwriteTextAnalyzer.Get(),
- _dwriteTextFormat.Get(),
- _dwriteFontFace.Get(),
- { &cluster, 1 },
- _glyphCell.cx);
+ try
+ {
+ const Cluster cluster(glyph, 0); // columns don't matter, we're doing analysis not layout.
+
+ // Create the text layout
+ CustomTextLayout layout(_dwriteFactory.Get(),
+ _dwriteTextAnalyzer.Get(),
+ _dwriteTextFormat.Get(),
+ _dwriteFontFace.Get(),
+ { &cluster, 1 },
+ _glyphCell.cx);
- UINT32 columns = 0;
- RETURN_IF_FAILED(layout.GetColumns(&columns));
+ UINT32 columns = 0;
+ RETURN_IF_FAILED(layout.GetColumns(&columns));
- *pResult = columns != 1;
+ *pResult = columns != 1;
+ }
+ CATCH_RETURN();
return S_OK;
}
@@ -1371,7 +1424,7 @@ float DxEngine::GetScaling() const noexcept
// - S_OK
[[nodiscard]] HRESULT DxEngine::_DoUpdateTitle(_In_ const std::wstring& /*newTitle*/) noexcept
{
- return PostMessageW(_hwndTarget, CM_UPDATE_TITLE, 0, (LPARAM) nullptr) ? S_OK : E_FAIL;
+ return PostMessageW(_hwndTarget, CM_UPDATE_TITLE, 0, 0) ? S_OK : E_FAIL;
}
// Routine Description:
@@ -1451,6 +1504,11 @@ float DxEngine::GetScaling() const noexcept
THROW_IF_FAILED(fontFace0.As(&fontFace));
+ // Retrieve metrics in case the font we created was different than what was requested.
+ weight = font->GetWeight();
+ stretch = font->GetStretch();
+ style = font->GetStyle();
+
// Dig the family name out at the end to return it.
familyName = _GetFontFamilyName(fontFamily.Get(), localeName);
}
@@ -1488,7 +1546,7 @@ float DxEngine::GetScaling() const noexcept
// - If fallback occurred, this is updated to what we retrieved instead.
// Return Value:
// - Localized string name of the font family
-[[nodiscard]] std::wstring DxEngine::_GetFontFamilyName(IDWriteFontFamily* const fontFamily,
+[[nodiscard]] std::wstring DxEngine::_GetFontFamilyName(gsl::not_null const fontFamily,
std::wstring& localeName) const
{
// See: https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nn-dwrite-idwritefontcollection
@@ -1691,9 +1749,9 @@ float DxEngine::GetScaling() const noexcept
// 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
// or rounding or scaling manipulation.
- COORD unscaled = desired.GetEngineSize();
+ const COORD unscaled = desired.GetEngineSize();
- COORD scaled = coordSize;
+ const COORD scaled = coordSize;
actual.SetFromEngine(fontName.data(),
desired.GetFamily(),
@@ -1733,22 +1791,6 @@ float DxEngine::GetScaling() const noexcept
return D2D1::ColorF(rgb, aFloat);
}
default:
- THROW_HR(E_NOTIMPL);
+ FAIL_FAST_HR(E_NOTIMPL);
}
}
-
-// Routine Description:
-// - Helps convert a Direct2D ColorF into a DXGI RGBA
-// Arguments:
-// - color - Direct2D Color F
-// Return Value:
-// - DXGI RGBA
-[[nodiscard]] DXGI_RGBA DxEngine::s_RgbaFromColorF(const D2D1_COLOR_F color) noexcept
-{
- DXGI_RGBA rgba;
- rgba.a = color.a;
- rgba.b = color.b;
- rgba.g = color.g;
- rgba.r = color.r;
- return rgba;
-}
diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp
index bc25588d3f1..f0960120316 100644
--- a/src/renderer/dx/DxRenderer.hpp
+++ b/src/renderer/dx/DxRenderer.hpp
@@ -31,7 +31,11 @@ namespace Microsoft::Console::Render
{
public:
DxEngine();
- virtual ~DxEngine() override;
+ ~DxEngine();
+ DxEngine(const DxEngine&) = default;
+ DxEngine(DxEngine&&) = default;
+ DxEngine& operator=(const DxEngine&) = default;
+ DxEngine& operator=(DxEngine&&) = default;
// Used to release device resources so that another instance of
// conhost can render to the screen (i.e. only one DirectX
@@ -45,7 +49,7 @@ namespace Microsoft::Console::Render
void SetCallback(std::function pfn);
- ::Microsoft::WRL::ComPtr GetSwapChain() noexcept;
+ ::Microsoft::WRL::ComPtr GetSwapChain();
// IRenderEngine Members
[[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override;
@@ -84,7 +88,7 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override;
- [[nodiscard]] SMALL_RECT GetDirtyRectInChars() noexcept override;
+ [[nodiscard]] SMALL_RECT GetDirtyRectInChars() override;
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
@@ -133,7 +137,7 @@ namespace Microsoft::Console::Render
void _InvalidOr(SMALL_RECT sr) noexcept;
void _InvalidOr(RECT rc) noexcept;
- void _InvalidOffset(POINT pt) noexcept;
+ void _InvalidOffset(POINT pt);
bool _presentReady;
RECT _presentDirty;
@@ -193,7 +197,7 @@ namespace Microsoft::Console::Render
[[nodiscard]] std::wstring _GetLocaleName() const;
- [[nodiscard]] std::wstring _GetFontFamilyName(IDWriteFontFamily* const fontFamily,
+ [[nodiscard]] std::wstring _GetFontFamilyName(gsl::not_null const fontFamily,
std::wstring& localeName) const;
[[nodiscard]] HRESULT _GetProposedFont(const FontInfoDesired& desired,
@@ -209,6 +213,15 @@ namespace Microsoft::Console::Render
[[nodiscard]] D2D1_COLOR_F _ColorFFromColorRef(const COLORREF color) noexcept;
- [[nodiscard]] static DXGI_RGBA s_RgbaFromColorF(const D2D1_COLOR_F color) noexcept;
+ // Routine Description:
+ // - Helps convert a Direct2D ColorF into a DXGI RGBA
+ // Arguments:
+ // - color - Direct2D Color F
+ // Return Value:
+ // - DXGI RGBA
+ [[nodiscard]] constexpr DXGI_RGBA s_RgbaFromColorF(const D2D1_COLOR_F color) noexcept
+ {
+ return { color.r, color.g, color.b, color.a };
+ }
};
}
diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp
index 2399ab6a3f2..2d321381318 100644
--- a/src/renderer/inc/IRenderEngine.hpp
+++ b/src/renderer/inc/IRenderEngine.hpp
@@ -64,6 +64,14 @@ namespace Microsoft::Console::Render
virtual ~IRenderEngine() = 0;
+ protected:
+ IRenderEngine() = default;
+ IRenderEngine(const IRenderEngine&) = default;
+ IRenderEngine(IRenderEngine&&) = default;
+ IRenderEngine& operator=(const IRenderEngine&) = default;
+ IRenderEngine& operator=(IRenderEngine&&) = default;
+
+ public:
[[nodiscard]] virtual HRESULT StartPaint() noexcept = 0;
[[nodiscard]] virtual HRESULT EndPaint() noexcept = 0;
[[nodiscard]] virtual HRESULT Present() noexcept = 0;
diff --git a/src/renderer/inc/IRenderTarget.hpp b/src/renderer/inc/IRenderTarget.hpp
index 1d1223b12b1..4fbba7fad41 100644
--- a/src/renderer/inc/IRenderTarget.hpp
+++ b/src/renderer/inc/IRenderTarget.hpp
@@ -25,6 +25,14 @@ namespace Microsoft::Console::Render
public:
virtual ~IRenderTarget() = 0;
+ protected:
+ IRenderTarget() = default;
+ IRenderTarget(const IRenderTarget&) = default;
+ IRenderTarget(IRenderTarget&&) = default;
+ IRenderTarget& operator=(const IRenderTarget&) = default;
+ IRenderTarget& operator=(IRenderTarget&&) = default;
+
+ public:
virtual void TriggerRedraw(const Microsoft::Console::Types::Viewport& region) = 0;
virtual void TriggerRedraw(const COORD* const pcoord) = 0;
virtual void TriggerRedrawCursor(const COORD* const pcoord) = 0;
diff --git a/src/renderer/inc/RenderEngineBase.hpp b/src/renderer/inc/RenderEngineBase.hpp
index dad43c5c51a..eae934bc775 100644
--- a/src/renderer/inc/RenderEngineBase.hpp
+++ b/src/renderer/inc/RenderEngineBase.hpp
@@ -24,9 +24,16 @@ namespace Microsoft::Console::Render
class RenderEngineBase : public IRenderEngine
{
public:
+ ~RenderEngineBase() = 0;
+
+ protected:
RenderEngineBase();
- virtual ~RenderEngineBase() = 0;
+ RenderEngineBase(const RenderEngineBase&) = default;
+ RenderEngineBase(RenderEngineBase&&) = default;
+ RenderEngineBase& operator=(const RenderEngineBase&) = default;
+ RenderEngineBase& operator=(RenderEngineBase&&) = default;
+ public:
[[nodiscard]] HRESULT InvalidateTitle(const std::wstring& proposedTitle) noexcept override;
[[nodiscard]] HRESULT UpdateTitle(const std::wstring& newTitle) noexcept override;
diff --git a/src/types/CodepointWidthDetector.cpp b/src/types/CodepointWidthDetector.cpp
index c627a2b1fd8..eb29a8af488 100644
--- a/src/types/CodepointWidthDetector.cpp
+++ b/src/types/CodepointWidthDetector.cpp
@@ -14,7 +14,7 @@ namespace
CodepointWidth width;
};
- static bool operator<(const UnicodeRange& range, const unsigned int searchTerm)
+ static bool operator<(const UnicodeRange& range, const unsigned int searchTerm) noexcept
{
return range.upperBound < searchTerm;
}
@@ -310,13 +310,21 @@ namespace
};
}
+// Routine Description:
+// - Constructs an instance of the CodepointWidthDetector class
+CodepointWidthDetector::CodepointWidthDetector() noexcept :
+ _fallbackCache{},
+ _pfnFallbackMethod{}
+{
+}
+
// Routine Description:
// - returns the width type of codepoint by searching the map generated from the unicode spec
// Arguments:
// - glyph - the utf16 encoded codepoint to search for
// Return Value:
// - the width type of the codepoint
-CodepointWidth CodepointWidthDetector::GetWidth(const std::wstring_view glyph) const noexcept
+CodepointWidth CodepointWidthDetector::GetWidth(const std::wstring_view glyph) const
{
if (glyph.empty())
{
@@ -443,7 +451,7 @@ bool CodepointWidthDetector::_checkFallbackViaCache(const std::wstring_view glyp
const std::wstring findMe{ glyph };
// TODO: Cache needs to be emptied when font changes.
- auto it = _fallbackCache.find(findMe);
+ const auto it = _fallbackCache.find(findMe);
if (it == _fallbackCache.end())
{
auto result = _pfnFallbackMethod(glyph);
diff --git a/src/types/GlyphWidth.cpp b/src/types/GlyphWidth.cpp
index b92935c31b6..f90c79f9481 100644
--- a/src/types/GlyphWidth.cpp
+++ b/src/types/GlyphWidth.cpp
@@ -5,6 +5,8 @@
#include "inc/CodepointWidthDetector.hpp"
#include "inc/GlyphWidth.hpp"
+#pragma warning(suppress : 26426)
+// TODO GH 2676 - remove warning suppression and decide what to do re: singleton instance of CodepointWidthDetector
static CodepointWidthDetector widthDetector;
// Function Description:
@@ -18,7 +20,7 @@ bool IsGlyphFullWidth(const std::wstring_view glyph)
// Function Description:
// - determines if the glyph represented by the single character should be
// wide or not. See CodepointWidthDetector::IsWide
-bool IsGlyphFullWidth(const wchar_t wch)
+bool IsGlyphFullWidth(const wchar_t wch) noexcept
{
return widthDetector.IsWide(wch);
}
@@ -44,7 +46,7 @@ void SetGlyphWidthFallback(std::function pfnFallb
// -
// Return Value:
// -
-void NotifyGlyphWidthFontChanged()
+void NotifyGlyphWidthFontChanged() noexcept
{
widthDetector.NotifyFontChanged();
}
diff --git a/src/types/IBaseData.h b/src/types/IBaseData.h
index e82bfa8c170..453dbae7711 100644
--- a/src/types/IBaseData.h
+++ b/src/types/IBaseData.h
@@ -24,6 +24,15 @@ namespace Microsoft::Console::Types
{
public:
virtual ~IBaseData() = 0;
+
+ protected:
+ IBaseData() = default;
+ IBaseData(const IBaseData&) = default;
+ IBaseData(IBaseData&&) = default;
+ IBaseData& operator=(const IBaseData&) = default;
+ IBaseData& operator=(IBaseData&&) = default;
+
+ public:
virtual Microsoft::Console::Types::Viewport GetViewport() noexcept = 0;
virtual const TextBuffer& GetTextBuffer() noexcept = 0;
virtual const FontInfo& GetFontInfo() noexcept = 0;
diff --git a/src/types/IInputEvent.cpp b/src/types/IInputEvent.cpp
index f7a3a925a2a..5df614a6ca5 100644
--- a/src/types/IInputEvent.cpp
+++ b/src/types/IInputEvent.cpp
@@ -48,7 +48,7 @@ std::deque> IInputEvent::Create(const std::deque> outEvents;
for (size_t i = 0; i < records.size(); ++i)
{
- std::unique_ptr event = IInputEvent::Create(records[i]);
+ std::unique_ptr event = IInputEvent::Create(records.at(i));
outEvents.push_back(std::move(event));
}
return outEvents;
diff --git a/src/types/IUiaData.h b/src/types/IUiaData.h
index a087789172d..6fbb2f513ef 100644
--- a/src/types/IUiaData.h
+++ b/src/types/IUiaData.h
@@ -23,8 +23,16 @@ namespace Microsoft::Console::Types
class IUiaData : public IBaseData
{
public:
- virtual ~IUiaData() = 0;
+ ~IUiaData() = 0;
+ protected:
+ IUiaData() = default;
+ IUiaData(const IUiaData&) = default;
+ IUiaData(IUiaData&&) = default;
+ IUiaData& operator=(const IUiaData&) = default;
+ IUiaData& operator=(IUiaData&&) = default;
+
+ public:
virtual const bool IsSelectionActive() const = 0;
virtual void ClearSelection() = 0;
virtual void SelectNewRegion(const COORD coordStart, const COORD coordEnd) = 0;
diff --git a/src/types/KeyEvent.cpp b/src/types/KeyEvent.cpp
index c62a35c908b..869d302d5a4 100644
--- a/src/types/KeyEvent.cpp
+++ b/src/types/KeyEvent.cpp
@@ -68,7 +68,7 @@ void KeyEvent::ActivateModifierKey(const ModifierKeyState modifierKey) noexcept
WI_SetAllFlags(_activeModifierKeys, bitFlag);
}
-bool KeyEvent::DoActiveModifierKeysMatch(const std::unordered_set& consoleModifiers) const noexcept
+bool KeyEvent::DoActiveModifierKeysMatch(const std::unordered_set& consoleModifiers) const
{
DWORD consoleBits = 0;
for (const ModifierKeyState& mod : consoleModifiers)
diff --git a/src/types/ScreenInfoUiaProviderBase.cpp b/src/types/ScreenInfoUiaProviderBase.cpp
index aff23dde5cc..27cf40c14e0 100644
--- a/src/types/ScreenInfoUiaProviderBase.cpp
+++ b/src/types/ScreenInfoUiaProviderBase.cpp
@@ -10,14 +10,16 @@ using namespace Microsoft::Console::Types;
using namespace Microsoft::Console::Types::ScreenInfoUiaProviderTracing;
// A helper function to create a SafeArray Version of an int array of a specified length
-SAFEARRAY* BuildIntSafeArray(_In_reads_(length) const int* const data, const int length)
+SAFEARRAY* BuildIntSafeArray(std::basic_string_view data)
{
- SAFEARRAY* psa = SafeArrayCreateVector(VT_I4, 0, length);
+ SAFEARRAY* psa = SafeArrayCreateVector(VT_I4, 0, gsl::narrow(data.size()));
if (psa != nullptr)
{
- for (long i = 0; i < length; i++)
+ for (size_t i = 0; i < data.size(); i++)
{
- if (FAILED(SafeArrayPutElement(psa, &i, (void*)&(data[i]))))
+ LONG lIndex = 0;
+ if (FAILED(SizeTToLong(i, &lIndex) ||
+ FAILED(SafeArrayPutElement(psa, &lIndex, (void*)&(data.at(i))))))
{
SafeArrayDestroy(psa);
psa = nullptr;
@@ -38,10 +40,6 @@ ScreenInfoUiaProviderBase::ScreenInfoUiaProviderBase(_In_ IUiaData* pData) :
//Tracing::s_TraceUia(nullptr, ApiCall::Constructor, nullptr);
}
-ScreenInfoUiaProviderBase::~ScreenInfoUiaProviderBase()
-{
-}
-
[[nodiscard]] HRESULT ScreenInfoUiaProviderBase::Signal(_In_ EVENTID id)
{
HRESULT hr = S_OK;
@@ -58,7 +56,7 @@ ScreenInfoUiaProviderBase::~ScreenInfoUiaProviderBase()
}
CATCH_RETURN();
- IRawElementProviderSimple* pProvider = static_cast(this);
+ IRawElementProviderSimple* pProvider = this;
hr = UiaRaiseAutomationEvent(pProvider, id);
_signalFiringMapping[id] = false;
@@ -85,7 +83,7 @@ ScreenInfoUiaProviderBase::Release()
{
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::Release, nullptr);
- long val = InterlockedDecrement(&_cRefs);
+ const long val = InterlockedDecrement(&_cRefs);
if (val == 0)
{
delete this;
@@ -96,23 +94,16 @@ ScreenInfoUiaProviderBase::Release()
IFACEMETHODIMP ScreenInfoUiaProviderBase::QueryInterface(_In_ REFIID riid,
_COM_Outptr_result_maybenull_ void** ppInterface)
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, ppInterface);
+
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::QueryInterface, nullptr);
- if (riid == __uuidof(IUnknown))
- {
- *ppInterface = static_cast(this);
- }
- else if (riid == __uuidof(IRawElementProviderSimple))
+ if (riid == __uuidof(IUnknown) ||
+ riid == __uuidof(IRawElementProviderSimple) ||
+ riid == __uuidof(IRawElementProviderFragment) ||
+ riid == __uuidof(ITextProvider))
{
- *ppInterface = static_cast(this);
- }
- else if (riid == __uuidof(IRawElementProviderFragment))
- {
- *ppInterface = static_cast(this);
- }
- else if (riid == __uuidof(ITextProvider))
- {
- *ppInterface = static_cast(this);
+ *ppInterface = this;
}
else
{
@@ -120,7 +111,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::QueryInterface(_In_ REFIID riid,
return E_NOINTERFACE;
}
- (static_cast(*ppInterface))->AddRef();
+ AddRef();
return S_OK;
}
@@ -131,8 +122,10 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::QueryInterface(_In_ REFIID riid,
// Implementation of IRawElementProviderSimple::get_ProviderOptions.
// Gets UI Automation provider options.
-IFACEMETHODIMP ScreenInfoUiaProviderBase::get_ProviderOptions(_Out_ ProviderOptions* pOptions)
+IFACEMETHODIMP ScreenInfoUiaProviderBase::get_ProviderOptions(_Out_ ProviderOptions* pOptions) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, pOptions);
+
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetProviderOptions, nullptr);
*pOptions = ProviderOptions_ServerSideProvider;
@@ -155,7 +148,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetPatternProvider(_In_ PATTERNID patt
if (patternId == UIA_TextPatternId)
{
- hr = this->QueryInterface(__uuidof(ITextProvider), reinterpret_cast(ppInterface));
+ hr = this->QueryInterface(IID_PPV_ARGS(ppInterface));
if (FAILED(hr))
{
*ppInterface = nullptr;
@@ -167,7 +160,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetPatternProvider(_In_ PATTERNID patt
// Implementation of IRawElementProviderSimple::get_PropertyValue.
// Gets custom properties.
IFACEMETHODIMP ScreenInfoUiaProviderBase::GetPropertyValue(_In_ PROPERTYID propertyId,
- _Out_ VARIANT* pVariant)
+ _Out_ VARIANT* pVariant) noexcept
{
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetPropertyValue, nullptr);
@@ -237,7 +230,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetPropertyValue(_In_ PROPERTYID prope
return S_OK;
}
-IFACEMETHODIMP ScreenInfoUiaProviderBase::get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider)
+IFACEMETHODIMP ScreenInfoUiaProviderBase::get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider) noexcept
{
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetHostRawElementProvider, nullptr);
@@ -260,15 +253,17 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetRuntimeId(_Outptr_result_maybenull_
*ppRuntimeId = nullptr;
// AppendRuntimeId is a magic Number that tells UIAutomation to Append its own Runtime ID(From the HWND)
- int rId[] = { UiaAppendRuntimeId, -1 };
+ const std::array rId{ UiaAppendRuntimeId, -1 };
+
+ const std::basic_string_view span{ rId.data(), rId.size() };
// BuildIntSafeArray is a custom function to hide the SafeArray creation
- *ppRuntimeId = BuildIntSafeArray(rId, 2);
+ *ppRuntimeId = BuildIntSafeArray(span);
RETURN_IF_NULL_ALLOC(*ppRuntimeId);
return S_OK;
}
-IFACEMETHODIMP ScreenInfoUiaProviderBase::GetEmbeddedFragmentRoots(_Outptr_result_maybenull_ SAFEARRAY** ppRoots)
+IFACEMETHODIMP ScreenInfoUiaProviderBase::GetEmbeddedFragmentRoots(_Outptr_result_maybenull_ SAFEARRAY** ppRoots) noexcept
{
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetEmbeddedFragmentRoots, nullptr);
@@ -296,11 +291,11 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
//ApiMsgGetSelection apiMsg;
_LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_UnlockConsole();
});
- RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
+ RETURN_HR_IF_NULL(E_INVALIDARG, ppRetVal);
*ppRetVal = nullptr;
HRESULT hr = S_OK;
@@ -322,6 +317,11 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
IRawElementProviderSimple* pProvider;
hr = this->QueryInterface(IID_PPV_ARGS(&pProvider));
+ if (pProvider == nullptr)
+ {
+ hr = E_POINTER;
+ }
+
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
@@ -340,7 +340,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
range = nullptr;
hr = wil::ResultFromCaughtException();
}
- (static_cast(pProvider))->Release();
+ pProvider->Release();
if (range == nullptr)
{
SafeArrayDestroy(*ppRetVal);
@@ -349,7 +349,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
}
LONG currentIndex = 0;
- hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, reinterpret_cast(range));
+ hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range);
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
@@ -363,6 +363,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
std::deque ranges;
IRawElementProviderSimple* pProvider;
RETURN_IF_FAILED(QueryInterface(IID_PPV_ARGS(&pProvider)));
+ RETURN_HR_IF_NULL(E_POINTER, pProvider);
try
{
ranges = GetSelectionRanges(pProvider);
@@ -379,25 +380,28 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
//apiMsg.SelectionRowCount = static_cast(ranges.size());
// make a safe array
- *ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, static_cast(ranges.size()));
+ *ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, gsl::narrow(ranges.size()));
if (*ppRetVal == nullptr)
{
return E_OUTOFMEMORY;
}
// fill the safe array
- for (LONG i = 0; i < static_cast(ranges.size()); ++i)
+ for (LONG i = 0; i < gsl::narrow(ranges.size()); ++i)
{
- hr = SafeArrayPutElement(*ppRetVal, &i, reinterpret_cast(ranges[i]));
+ hr = SafeArrayPutElement(*ppRetVal, &i, ranges.at(i));
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
*ppRetVal = nullptr;
while (!ranges.empty())
{
- UiaTextRangeBase* pRange = ranges[0];
+ UiaTextRangeBase* pRange = ranges.at(0);
ranges.pop_front();
- pRange->Release();
+ if (pRange)
+ {
+ pRange->Release();
+ }
}
return hr;
}
@@ -415,11 +419,11 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
//Tracing::s_TraceUia(this, ApiCall::GetVisibleRanges, nullptr);
_LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_UnlockConsole();
});
- RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
+ RETURN_HR_IF_NULL(E_INVALIDARG, ppRetVal);
*ppRetVal = nullptr;
const auto viewport = _getViewport();
@@ -428,7 +432,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
// make a safe array
const size_t rowCount = viewport.Height();
- *ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, static_cast(rowCount));
+ *ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, gsl::narrow(rowCount));
if (*ppRetVal == nullptr)
{
return E_OUTOFMEMORY;
@@ -444,6 +448,11 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
IRawElementProviderSimple* pProvider;
HRESULT hr = this->QueryInterface(IID_PPV_ARGS(&pProvider));
+ if (pProvider == nullptr)
+ {
+ hr = E_POINTER;
+ }
+
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
@@ -464,7 +473,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
range = nullptr;
hr = wil::ResultFromCaughtException();
}
- (static_cast(pProvider))->Release();
+ pProvider->Release();
if (range == nullptr)
{
@@ -473,8 +482,8 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetVisibleRanges(_Outptr_result_mayben
return hr;
}
- LONG currentIndex = static_cast(i);
- hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, reinterpret_cast(range));
+ LONG currentIndex = gsl::narrow(i);
+ hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range);
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
@@ -491,11 +500,12 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::RangeFromChild(_In_ IRawElementProvide
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::RangeFromChild, nullptr);
- RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
+ RETURN_HR_IF_NULL(E_INVALIDARG, ppRetVal);
*ppRetVal = nullptr;
IRawElementProviderSimple* pProvider;
RETURN_IF_FAILED(this->QueryInterface(IID_PPV_ARGS(&pProvider)));
+ RETURN_HR_IF_NULL(E_POINTER, pProvider);
HRESULT hr = S_OK;
try
@@ -507,7 +517,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::RangeFromChild(_In_ IRawElementProvide
*ppRetVal = nullptr;
hr = wil::ResultFromCaughtException();
}
- (static_cast(pProvider))->Release();
+ pProvider->Release();
return hr;
}
@@ -518,11 +528,12 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::RangeFromPoint(_In_ UiaPoint point,
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::RangeFromPoint, nullptr);
- RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
+ RETURN_HR_IF_NULL(E_INVALIDARG, ppRetVal);
*ppRetVal = nullptr;
IRawElementProviderSimple* pProvider;
RETURN_IF_FAILED(this->QueryInterface(IID_PPV_ARGS(&pProvider)));
+ RETURN_HR_IF_NULL(E_POINTER, pProvider);
HRESULT hr = S_OK;
try
@@ -535,7 +546,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::RangeFromPoint(_In_ UiaPoint point,
*ppRetVal = nullptr;
hr = wil::ResultFromCaughtException();
}
- (static_cast(pProvider))->Release();
+ pProvider->Release();
return hr;
}
@@ -545,11 +556,12 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::get_DocumentRange(_COM_Outptr_result_m
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetDocumentRange, nullptr);
- RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
+ RETURN_HR_IF_NULL(E_INVALIDARG, ppRetVal);
*ppRetVal = nullptr;
IRawElementProviderSimple* pProvider;
RETURN_IF_FAILED(this->QueryInterface(IID_PPV_ARGS(&pProvider)));
+ RETURN_HR_IF_NULL(E_POINTER, pProvider);
HRESULT hr = S_OK;
try
@@ -561,7 +573,7 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::get_DocumentRange(_COM_Outptr_result_m
*ppRetVal = nullptr;
hr = wil::ResultFromCaughtException();
}
- (static_cast(pProvider))->Release();
+ pProvider->Release();
if (*ppRetVal)
{
@@ -571,8 +583,10 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::get_DocumentRange(_COM_Outptr_result_m
return hr;
}
-IFACEMETHODIMP ScreenInfoUiaProviderBase::get_SupportedTextSelection(_Out_ SupportedTextSelection* pRetVal)
+IFACEMETHODIMP ScreenInfoUiaProviderBase::get_SupportedTextSelection(_Out_ SupportedTextSelection* pRetVal) noexcept
{
+ RETURN_HR_IF_NULL(E_INVALIDARG, pRetVal);
+
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetSupportedTextSelection, nullptr);
@@ -587,12 +601,12 @@ const COORD ScreenInfoUiaProviderBase::_getScreenBufferCoords() const
return _getTextBuffer().GetSize().Dimensions();
}
-const TextBuffer& ScreenInfoUiaProviderBase::_getTextBuffer() const
+const TextBuffer& ScreenInfoUiaProviderBase::_getTextBuffer() const noexcept
{
return _pData->GetTextBuffer();
}
-const Viewport ScreenInfoUiaProviderBase::_getViewport() const
+const Viewport ScreenInfoUiaProviderBase::_getViewport() const noexcept
{
return _pData->GetViewport();
}
diff --git a/src/types/ScreenInfoUiaProviderBase.h b/src/types/ScreenInfoUiaProviderBase.h
index 0b47454eefa..5ffe24b5b01 100644
--- a/src/types/ScreenInfoUiaProviderBase.h
+++ b/src/types/ScreenInfoUiaProviderBase.h
@@ -38,44 +38,48 @@ namespace Microsoft::Console::Types
{
public:
ScreenInfoUiaProviderBase(_In_ IUiaData* pData);
- virtual ~ScreenInfoUiaProviderBase();
+ ScreenInfoUiaProviderBase(const ScreenInfoUiaProviderBase&) = default;
+ ScreenInfoUiaProviderBase(ScreenInfoUiaProviderBase&&) = default;
+ ScreenInfoUiaProviderBase& operator=(const ScreenInfoUiaProviderBase&) = default;
+ ScreenInfoUiaProviderBase& operator=(ScreenInfoUiaProviderBase&&) = default;
+ virtual ~ScreenInfoUiaProviderBase() = default;
[[nodiscard]] HRESULT Signal(_In_ EVENTID id);
// IUnknown methods
IFACEMETHODIMP_(ULONG)
- AddRef();
+ AddRef() override;
IFACEMETHODIMP_(ULONG)
- Release();
+ Release() override;
IFACEMETHODIMP QueryInterface(_In_ REFIID riid,
- _COM_Outptr_result_maybenull_ void** ppInterface);
+ _COM_Outptr_result_maybenull_ void** ppInterface) override;
// IRawElementProviderSimple methods
- IFACEMETHODIMP get_ProviderOptions(_Out_ ProviderOptions* pOptions);
+ IFACEMETHODIMP get_ProviderOptions(_Out_ ProviderOptions* pOptions) noexcept override;
IFACEMETHODIMP GetPatternProvider(_In_ PATTERNID iid,
- _COM_Outptr_result_maybenull_ IUnknown** ppInterface);
+ _COM_Outptr_result_maybenull_ IUnknown** ppInterface) override;
IFACEMETHODIMP GetPropertyValue(_In_ PROPERTYID idProp,
- _Out_ VARIANT* pVariant);
- IFACEMETHODIMP get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider);
+ _Out_ VARIANT* pVariant) noexcept override;
+ IFACEMETHODIMP get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider) noexcept override;
// IRawElementProviderFragment methods
virtual IFACEMETHODIMP Navigate(_In_ NavigateDirection direction,
_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider) = 0;
- IFACEMETHODIMP GetRuntimeId(_Outptr_result_maybenull_ SAFEARRAY** ppRuntimeId);
+ IFACEMETHODIMP GetRuntimeId(_Outptr_result_maybenull_ SAFEARRAY** ppRuntimeId) override;
virtual IFACEMETHODIMP get_BoundingRectangle(_Out_ UiaRect* pRect) = 0;
- IFACEMETHODIMP GetEmbeddedFragmentRoots(_Outptr_result_maybenull_ SAFEARRAY** ppRoots);
- IFACEMETHODIMP SetFocus();
+ IFACEMETHODIMP GetEmbeddedFragmentRoots(_Outptr_result_maybenull_ SAFEARRAY** ppRoots) noexcept override;
+ IFACEMETHODIMP SetFocus() override;
virtual IFACEMETHODIMP get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) = 0;
// ITextProvider
- IFACEMETHODIMP GetSelection(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal);
- IFACEMETHODIMP GetVisibleRanges(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal);
+ IFACEMETHODIMP GetSelection(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal) override;
+ IFACEMETHODIMP GetVisibleRanges(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal) override;
IFACEMETHODIMP RangeFromChild(_In_ IRawElementProviderSimple* childElement,
- _COM_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal);
+ _COM_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
IFACEMETHODIMP RangeFromPoint(_In_ UiaPoint point,
- _COM_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal);
- IFACEMETHODIMP get_DocumentRange(_COM_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal);
- IFACEMETHODIMP get_SupportedTextSelection(_Out_ SupportedTextSelection* pRetVal);
+ _COM_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
+ IFACEMETHODIMP get_DocumentRange(_COM_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
+ IFACEMETHODIMP get_SupportedTextSelection(_Out_ SupportedTextSelection* pRetVal) noexcept override;
protected:
virtual std::deque GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider) = 0;
@@ -118,8 +122,8 @@ namespace Microsoft::Console::Types
std::map _signalFiringMapping;
const COORD _getScreenBufferCoords() const;
- const TextBuffer& _getTextBuffer() const;
- const Viewport _getViewport() const;
+ const TextBuffer& _getTextBuffer() const noexcept;
+ const Viewport _getViewport() const noexcept;
void _LockConsole() noexcept;
void _UnlockConsole() noexcept;
};
diff --git a/src/types/UTF8OutPipeReader.cpp b/src/types/UTF8OutPipeReader.cpp
index 5c646bc2166..1e69046c675 100644
--- a/src/types/UTF8OutPipeReader.cpp
+++ b/src/types/UTF8OutPipeReader.cpp
@@ -6,8 +6,10 @@
#include
#include
-UTF8OutPipeReader::UTF8OutPipeReader(HANDLE outPipe) :
- _outPipe{ outPipe }
+UTF8OutPipeReader::UTF8OutPipeReader(HANDLE outPipe) noexcept :
+ _outPipe{ outPipe },
+ _buffer{ 0 },
+ _utf8Partials{ 0 }
{
}
@@ -30,24 +32,24 @@ UTF8OutPipeReader::UTF8OutPipeReader(HANDLE outPipe) :
bool fSuccess{};
// in case of early escaping
- *_buffer = 0;
- strView = std::string_view{ reinterpret_cast(_buffer), 0 };
+ _buffer.at(0) = 0;
+ strView = std::string_view{ _buffer.data(), 0 };
// copy UTF-8 code units that were remaining from the previously read chunk (if any)
if (_dwPartialsLen != 0)
{
- std::move(_utf8Partials, _utf8Partials + _dwPartialsLen, _buffer);
+ std::move(_utf8Partials.cbegin(), _utf8Partials.cbegin() + _dwPartialsLen, _buffer.begin());
}
// try to read data
- fSuccess = !!ReadFile(_outPipe, &_buffer[_dwPartialsLen], std::extent::value - _dwPartialsLen, &dwRead, nullptr);
+ fSuccess = !!ReadFile(_outPipe, &_buffer.at(_dwPartialsLen), gsl::narrow(_buffer.size()) - _dwPartialsLen, &dwRead, nullptr);
dwRead += _dwPartialsLen;
_dwPartialsLen = 0;
if (!fSuccess) // reading failed (we must check this first, because dwRead will also be 0.)
{
- auto lastError = GetLastError();
+ const auto lastError = GetLastError();
if (lastError == ERROR_BROKEN_PIPE)
{
// This is a successful, but detectable, exit.
@@ -65,13 +67,13 @@ UTF8OutPipeReader::UTF8OutPipeReader(HANDLE outPipe) :
return S_OK;
}
- const BYTE* const endPtr{ _buffer + dwRead };
- const BYTE* backIter{ endPtr - 1 };
+ const auto endPtr = _buffer.cbegin() + dwRead;
+ auto backIter = endPtr - 1;
// If the last byte in the buffer was a byte belonging to a UTF-8 multi-byte character
if ((*backIter & _Utf8BitMasks::MaskAsciiByte) > _Utf8BitMasks::IsAsciiByte)
{
// Check only up to 3 last bytes, if no Lead Byte was found then the byte before must be the Lead Byte and no partials are in the buffer
- for (DWORD dwSequenceLen{ 1UL }, stop{ dwRead < 4UL ? dwRead : 4UL }; dwSequenceLen < stop; ++dwSequenceLen, --backIter)
+ for (DWORD dwSequenceLen{ 1UL }; dwSequenceLen < std::min(dwRead, 4UL); ++dwSequenceLen, --backIter)
{
// If Lead Byte found
if ((*backIter & _Utf8BitMasks::MaskContinuationByte) > _Utf8BitMasks::IsContinuationByte)
@@ -80,9 +82,9 @@ UTF8OutPipeReader::UTF8OutPipeReader(HANDLE outPipe) :
// Use the bitmask at index `dwSequenceLen`. Compare the result with the operand having the same index. If they
// are not equal then the sequence has to be cached because it is a partial code point. Otherwise the
// sequence is a complete UTF-8 code point and the whole buffer is ready for the conversion to hstring.
- if ((*backIter & _cmpMasks[dwSequenceLen]) != _cmpOperands[dwSequenceLen])
+ if ((*backIter & _cmpMasks.at(dwSequenceLen)) != _cmpOperands.at(dwSequenceLen))
{
- std::move(backIter, endPtr, _utf8Partials);
+ std::move(backIter, endPtr, _utf8Partials.begin());
dwRead -= dwSequenceLen;
_dwPartialsLen = dwSequenceLen;
}
@@ -93,6 +95,6 @@ UTF8OutPipeReader::UTF8OutPipeReader(HANDLE outPipe) :
}
// give back a view of the part of the buffer that contains complete code points only
- strView = std::string_view{ reinterpret_cast(_buffer), dwRead };
+ strView = std::string_view{ &_buffer.at(0), dwRead };
return S_OK;
}
diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp
index 47e7d502f32..929a8c8e612 100644
--- a/src/types/UiaTextRangeBase.cpp
+++ b/src/types/UiaTextRangeBase.cpp
@@ -47,7 +47,7 @@ UiaTextRangeBase::MoveState::MoveState(const ScreenInfoRow startScreenInfoRow,
const Column firstColumnInRow,
const Column lastColumnInRow,
const MovementIncrement increment,
- const MovementDirection direction) :
+ const MovementDirection direction) noexcept :
StartScreenInfoRow{ startScreenInfoRow },
StartColumn{ startColumn },
EndScreenInfoRow{ endScreenInfoRow },
@@ -162,7 +162,7 @@ void UiaTextRangeBase::Initialize(_In_ const UiaPoint point)
// get row that point resides in
const RECT windowRect = _getTerminalRect();
const SMALL_RECT viewport = _pData->GetViewport().ToInclusive();
- ScreenInfoRow row;
+ ScreenInfoRow row = 0;
if (clientPoint.y <= windowRect.top)
{
row = viewport.Top;
@@ -184,7 +184,7 @@ void UiaTextRangeBase::Initialize(_In_ const UiaPoint point)
_degenerate = true;
}
-UiaTextRangeBase::UiaTextRangeBase(const UiaTextRangeBase& a) :
+UiaTextRangeBase::UiaTextRangeBase(const UiaTextRangeBase& a) noexcept :
_cRefs{ 1 },
_pProvider{ a._pProvider },
_start{ a._start },
@@ -201,17 +201,17 @@ UiaTextRangeBase::UiaTextRangeBase(const UiaTextRangeBase& a) :
#endif
}
-const IdType UiaTextRangeBase::GetId() const
+const IdType UiaTextRangeBase::GetId() const noexcept
{
return _id;
}
-const Endpoint UiaTextRangeBase::GetStart() const
+const Endpoint UiaTextRangeBase::GetStart() const noexcept
{
return _start;
}
-const Endpoint UiaTextRangeBase::GetEnd() const
+const Endpoint UiaTextRangeBase::GetEnd() const noexcept
{
return _end;
}
@@ -222,12 +222,12 @@ const Endpoint UiaTextRangeBase::GetEnd() const
// -
// Return Value:
// - true if range is degenerate, false otherwise.
-const bool UiaTextRangeBase::IsDegenerate() const
+const bool UiaTextRangeBase::IsDegenerate() const noexcept
{
return _degenerate;
}
-void UiaTextRangeBase::SetRangeValues(const Endpoint start, const Endpoint end, const bool isDegenerate)
+void UiaTextRangeBase::SetRangeValues(const Endpoint start, const Endpoint end, const bool isDegenerate) noexcept
{
_start = start;
_end = end;
@@ -266,13 +266,10 @@ IFACEMETHODIMP UiaTextRangeBase::QueryInterface(_In_ REFIID riid, _COM_Outptr_re
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::QueryInterface, nullptr);
- if (riid == __uuidof(IUnknown))
- {
- *ppInterface = static_cast(this);
- }
- else if (riid == __uuidof(ITextRangeProvider))
+ if (riid == __uuidof(IUnknown) ||
+ riid == __uuidof(ITextRangeProvider))
{
- *ppInterface = static_cast(this);
+ *ppInterface = this;
}
else
{
@@ -280,7 +277,7 @@ IFACEMETHODIMP UiaTextRangeBase::QueryInterface(_In_ REFIID riid, _COM_Outptr_re
return E_NOINTERFACE;
}
- (static_cast(*ppInterface))->AddRef();
+ AddRef();
return S_OK;
}
@@ -288,16 +285,16 @@ IFACEMETHODIMP UiaTextRangeBase::QueryInterface(_In_ REFIID riid, _COM_Outptr_re
#pragma region ITextRangeProvider
-IFACEMETHODIMP UiaTextRangeBase::Compare(_In_opt_ ITextRangeProvider* pRange, _Out_ BOOL* pRetVal)
+IFACEMETHODIMP UiaTextRangeBase::Compare(_In_opt_ ITextRangeProvider* pRange, _Out_ BOOL* pRetVal) noexcept
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
RETURN_HR_IF(E_INVALIDARG, pRetVal == nullptr);
*pRetVal = FALSE;
- UiaTextRangeBase* other = static_cast(pRange);
+ const UiaTextRangeBase* other = static_cast(pRange);
if (other)
{
*pRetVal = !!(_start == other->GetStart() &&
@@ -317,39 +314,23 @@ IFACEMETHODIMP UiaTextRangeBase::Compare(_In_opt_ ITextRangeProvider* pRange, _O
IFACEMETHODIMP UiaTextRangeBase::CompareEndpoints(_In_ TextPatternRangeEndpoint endpoint,
_In_ ITextRangeProvider* pTargetRange,
_In_ TextPatternRangeEndpoint targetEndpoint,
- _Out_ int* pRetVal)
+ _Out_ int* pRetVal) noexcept
{
RETURN_HR_IF(E_INVALIDARG, pRetVal == nullptr);
*pRetVal = 0;
// get the text range that we're comparing to
- UiaTextRangeBase* range = static_cast(pTargetRange);
+ const UiaTextRangeBase* range = static_cast(pTargetRange);
if (range == nullptr)
{
return E_INVALIDARG;
}
// get endpoint value that we're comparing to
- Endpoint theirValue;
- if (targetEndpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start)
- {
- theirValue = range->GetStart();
- }
- else
- {
- theirValue = range->GetEnd() + 1;
- }
+ const Endpoint theirValue = targetEndpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start ? range->GetStart() : range->GetEnd() + 1;
// get the values of our endpoint
- Endpoint ourValue;
- if (endpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start)
- {
- ourValue = _start;
- }
- else
- {
- ourValue = _end + 1;
- }
+ const Endpoint ourValue = endpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start ? _start : _end + 1;
// compare them
*pRetVal = std::clamp(static_cast(ourValue) - static_cast(theirValue), -1, 1);
@@ -369,7 +350,7 @@ IFACEMETHODIMP UiaTextRangeBase::CompareEndpoints(_In_ TextPatternRangeEndpoint
IFACEMETHODIMP UiaTextRangeBase::ExpandToEnclosingUnit(_In_ TextUnit unit)
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
@@ -415,7 +396,7 @@ IFACEMETHODIMP UiaTextRangeBase::ExpandToEnclosingUnit(_In_ TextUnit unit)
IFACEMETHODIMP UiaTextRangeBase::FindAttribute(_In_ TEXTATTRIBUTEID /*textAttributeId*/,
_In_ VARIANT /*val*/,
_In_ BOOL /*searchBackward*/,
- _Outptr_result_maybenull_ ITextRangeProvider** /*ppRetVal*/)
+ _Outptr_result_maybenull_ ITextRangeProvider** /*ppRetVal*/) noexcept
{
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::FindAttribute, nullptr);
@@ -423,7 +404,7 @@ IFACEMETHODIMP UiaTextRangeBase::FindAttribute(_In_ TEXTATTRIBUTEID /*textAttrib
}
IFACEMETHODIMP UiaTextRangeBase::GetAttributeValue(_In_ TEXTATTRIBUTEID textAttributeId,
- _Out_ VARIANT* pRetVal)
+ _Out_ VARIANT* pRetVal) noexcept
{
RETURN_HR_IF(E_INVALIDARG, pRetVal == nullptr);
@@ -445,7 +426,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetAttributeValue(_In_ TEXTATTRIBUTEID textAttr
IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal)
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
@@ -469,7 +450,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
const unsigned int totalRowsInRange = _rowCountInRange(_pData);
for (unsigned int i = 0; i < totalRowsInRange; ++i)
{
- ScreenInfoRow screenInfoRow = _textBufferRowToScreenInfoRow(_pData, startRow + i);
+ const ScreenInfoRow screenInfoRow = _textBufferRowToScreenInfoRow(_pData, startRow + i);
if (!_isScreenInfoRowInViewport(_pData, screenInfoRow))
{
continue;
@@ -479,15 +460,15 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
}
// convert to a safearray
- *ppRetVal = SafeArrayCreateVector(VT_R8, 0, static_cast(coords.size()));
+ *ppRetVal = SafeArrayCreateVector(VT_R8, 0, gsl::narrow(coords.size()));
if (*ppRetVal == nullptr)
{
return E_OUTOFMEMORY;
}
- HRESULT hr;
- for (LONG i = 0; i < static_cast(coords.size()); ++i)
+ HRESULT hr = E_UNEXPECTED;
+ for (LONG i = 0; i < gsl::narrow(coords.size()); ++i)
{
- hr = SafeArrayPutElement(*ppRetVal, &i, &coords[i]);
+ hr = SafeArrayPutElement(*ppRetVal, &i, &coords.at(i));
if (FAILED(hr))
{
SafeArrayDestroy(*ppRetVal);
@@ -516,7 +497,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetEnclosingElement(_Outptr_result_maybenull_ I
IFACEMETHODIMP UiaTextRangeBase::GetText(_In_ int maxLength, _Out_ BSTR* pRetVal)
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
@@ -552,7 +533,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetText(_In_ int maxLength, _Out_ BSTR* pRetVal
OutputDebugString(ss.str().c_str());
#endif
- ScreenInfoRow currentScreenInfoRow;
+ ScreenInfoRow currentScreenInfoRow = 0;
for (unsigned int i = 0; i < totalRowsInRange; ++i)
{
currentScreenInfoRow = startScreenInfoRow + i;
@@ -569,7 +550,7 @@ IFACEMETHODIMP UiaTextRangeBase::GetText(_In_ int maxLength, _Out_ BSTR* pRetVal
if (currentScreenInfoRow == endScreenInfoRow)
{
// prevent the end from going past the last non-whitespace char in the row
- endIndex = std::min(static_cast(endColumn + 1), rowRight);
+ endIndex = std::min(gsl::narrow_cast(endColumn) + 1, rowRight);
}
// if startIndex >= endIndex then _start is
@@ -619,7 +600,7 @@ IFACEMETHODIMP UiaTextRangeBase::Move(_In_ TextUnit unit,
_Out_ int* pRetVal)
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
@@ -657,12 +638,12 @@ IFACEMETHODIMP UiaTextRangeBase::Move(_In_ TextUnit unit,
moveFunc = &_moveByLine;
}
- MovementDirection moveDirection = (count > 0) ? MovementDirection::Forward : MovementDirection::Backward;
+ const MovementDirection moveDirection = (count > 0) ? MovementDirection::Forward : MovementDirection::Backward;
std::pair newEndpoints;
try
{
- MoveState moveState{ _pData, *this, moveDirection };
+ const MoveState moveState{ _pData, *this, moveDirection };
newEndpoints = moveFunc(_pData,
count,
moveState,
@@ -691,7 +672,7 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByUnit(_In_ TextPatternRangeEndpoin
_Out_ int* pRetVal)
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
@@ -721,7 +702,7 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByUnit(_In_ TextPatternRangeEndpoin
_outputRowConversions();
#endif
- MovementDirection moveDirection = (count > 0) ? MovementDirection::Forward : MovementDirection::Backward;
+ const MovementDirection moveDirection = (count > 0) ? MovementDirection::Forward : MovementDirection::Backward;
auto moveFunc = &_moveEndpointByUnitDocument;
if (unit == TextUnit::TextUnit_Character)
@@ -736,7 +717,7 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByUnit(_In_ TextPatternRangeEndpoin
std::tuple moveResults;
try
{
- MoveState moveState{ _pData, *this, moveDirection };
+ const MoveState moveState{ _pData, *this, moveDirection };
moveResults = moveFunc(_pData, count, endpoint, moveState, pRetVal);
}
CATCH_RETURN();
@@ -758,11 +739,11 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByRange(_In_ TextPatternRangeEndpoi
_In_ TextPatternRangeEndpoint targetEndpoint)
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
- UiaTextRangeBase* range = static_cast(pTargetRange);
+ const UiaTextRangeBase* range = static_cast(pTargetRange);
if (range == nullptr)
{
return E_INVALIDARG;
@@ -789,7 +770,7 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByRange(_In_ TextPatternRangeEndpoi
#endif
// get the value that we're updating to
- Endpoint targetEndpointValue;
+ Endpoint targetEndpointValue = 0;
if (targetEndpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start)
{
targetEndpointValue = range->GetStart();
@@ -816,47 +797,41 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByRange(_In_ TextPatternRangeEndpoi
}
}
- // convert then endpoints to screen info rows/columns
- ScreenInfoRow startScreenInfoRow;
- Column startColumn;
- ScreenInfoRow endScreenInfoRow;
- Column endColumn;
- ScreenInfoRow targetScreenInfoRow;
- Column targetColumn;
try
{
- startScreenInfoRow = _endpointToScreenInfoRow(_pData, _start);
- startColumn = _endpointToColumn(_pData, _start);
- endScreenInfoRow = _endpointToScreenInfoRow(_pData, _end);
- endColumn = _endpointToColumn(_pData, _end);
- targetScreenInfoRow = _endpointToScreenInfoRow(_pData, targetEndpointValue);
- targetColumn = _endpointToColumn(_pData, targetEndpointValue);
- }
- CATCH_RETURN();
+ // convert then endpoints to screen info rows/columns
+ const auto startScreenInfoRow = _endpointToScreenInfoRow(_pData, _start);
+ const auto startColumn = _endpointToColumn(_pData, _start);
+ const auto endScreenInfoRow = _endpointToScreenInfoRow(_pData, _end);
+ const auto endColumn = _endpointToColumn(_pData, _end);
+ const auto targetScreenInfoRow = _endpointToScreenInfoRow(_pData, targetEndpointValue);
+ const auto targetColumn = _endpointToColumn(_pData, targetEndpointValue);
- // set endpoint value and check for crossed endpoints
- bool crossedEndpoints = false;
- if (endpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start)
- {
- _start = targetEndpointValue;
- if (_compareScreenCoords(_pData, endScreenInfoRow, endColumn, targetScreenInfoRow, targetColumn) == -1)
+ // set endpoint value and check for crossed endpoints
+ bool crossedEndpoints = false;
+ if (endpoint == TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start)
{
- // endpoints were crossed
- _end = _start;
- crossedEndpoints = true;
+ _start = targetEndpointValue;
+ if (_compareScreenCoords(_pData, endScreenInfoRow, endColumn, targetScreenInfoRow, targetColumn) == -1)
+ {
+ // endpoints were crossed
+ _end = _start;
+ crossedEndpoints = true;
+ }
}
- }
- else
- {
- _end = targetEndpointValue;
- if (_compareScreenCoords(_pData, startScreenInfoRow, startColumn, targetScreenInfoRow, targetColumn) == 1)
+ else
{
- // endpoints were crossed
- _start = _end;
- crossedEndpoints = true;
+ _end = targetEndpointValue;
+ if (_compareScreenCoords(_pData, startScreenInfoRow, startColumn, targetScreenInfoRow, targetColumn) == 1)
+ {
+ // endpoints were crossed
+ _start = _end;
+ crossedEndpoints = true;
+ }
}
+ _degenerate = crossedEndpoints;
}
- _degenerate = crossedEndpoints;
+ CATCH_RETURN();
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::MoveEndpointByRange, &apiMsg);
@@ -866,7 +841,7 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByRange(_In_ TextPatternRangeEndpoi
IFACEMETHODIMP UiaTextRangeBase::Select()
{
_pData->LockConsole();
- auto Unlock = wil::scope_exit([&] {
+ auto Unlock = wil::scope_exit([&]() noexcept {
_pData->UnlockConsole();
});
@@ -877,14 +852,10 @@ IFACEMETHODIMP UiaTextRangeBase::Select()
}
else
{
- COORD coordStart;
- COORD coordEnd;
-
- coordStart.X = static_cast