terminal/src/types/UiaTextRangeBase.hpp
Leonard Hecker 95cc7d9625
Add noexcept to all FontInfo structs (#11640)
FontInfoBase and it's descendents are missing noexcept annotations, which
virally forces other code to not be noexcept as well during AuditMode checks.
Apart from adding noexcept, this commit also
* Passes std::wstring_view by reference.
* Pass the FillLegacyNameBuffer argument as a simple pointer-to-array,
  allowing us to fill the buffer with a single memcpy.
  (gsl::span's iterators inhibit any internal STL optimizations.)
* Move operator== declarations inside the class to reduce code size.

All other changes are an effect of the virality of noexcept.

This is an offshoot from #11623.

## Validation Steps Performed
* It still compiles ✔️
2021-10-29 14:08:41 +00:00

195 lines
9.1 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- UiaTextRangeBase.hpp
Abstract:
- This module provides UI Automation access to the text of the console
window to support both automation tests and accessibility (screen
reading) applications.
- ConHost and Windows Terminal must implement their own virtual functions separately.
Author(s):
- Austin Diviness (AustDi) 2017
- Carlos Zamora (CaZamor) 2019
--*/
#pragma once
#include "inc/viewport.hpp"
#include "../buffer/out/textBuffer.hpp"
#include "IUiaData.h"
#include "unicode.hpp"
#include "IUiaTraceable.h"
#include <UIAutomationCore.h>
#include <deque>
#include <tuple>
#include <wrl/implements.h>
#ifdef UNIT_TESTING
class UiaTextRangeTests;
#endif
namespace Microsoft::Console::Types
{
class UiaTextRangeBase : public WRL::RuntimeClass<WRL::RuntimeClassFlags<WRL::ClassicCom | WRL::InhibitFtmBase>, ITextRangeProvider>, public IUiaTraceable
{
protected:
// indicates which direction a movement operation
// is going
enum class MovementDirection
{
Forward,
Backward
};
public:
// The default word delimiter for UiaTextRanges
static constexpr std::wstring_view DefaultWordDelimiter{ &UNICODE_SPACE, 1 };
// degenerate range
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
// degenerate range at cursor position
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const Cursor& cursor,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
// specific endpoint range
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const COORD start,
_In_ const COORD end,
_In_ bool blockRange = false,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
virtual HRESULT RuntimeClassInitialize(const UiaTextRangeBase& a) noexcept;
UiaTextRangeBase(const UiaTextRangeBase&) = delete;
UiaTextRangeBase(UiaTextRangeBase&&) = delete;
UiaTextRangeBase& operator=(const UiaTextRangeBase&) = delete;
UiaTextRangeBase& operator=(UiaTextRangeBase&&) = delete;
~UiaTextRangeBase() = default;
const COORD GetEndpoint(TextPatternRangeEndpoint endpoint) const noexcept;
bool SetEndpoint(TextPatternRangeEndpoint endpoint, const COORD val) noexcept;
const bool IsDegenerate() const noexcept;
// ITextRangeProvider methods
virtual IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) = 0;
IFACEMETHODIMP Compare(_In_opt_ ITextRangeProvider* pRange, _Out_ BOOL* pRetVal) noexcept override;
IFACEMETHODIMP CompareEndpoints(_In_ TextPatternRangeEndpoint endpoint,
_In_ ITextRangeProvider* pTargetRange,
_In_ TextPatternRangeEndpoint targetEndpoint,
_Out_ int* pRetVal) noexcept override;
IFACEMETHODIMP ExpandToEnclosingUnit(_In_ TextUnit unit) noexcept override;
IFACEMETHODIMP FindAttribute(_In_ TEXTATTRIBUTEID textAttributeId,
_In_ VARIANT val,
_In_ BOOL searchBackward,
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) noexcept override;
IFACEMETHODIMP FindText(_In_ BSTR text,
_In_ BOOL searchBackward,
_In_ BOOL ignoreCase,
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) noexcept override;
IFACEMETHODIMP GetAttributeValue(_In_ TEXTATTRIBUTEID textAttributeId,
_Out_ VARIANT* pRetVal) noexcept override;
IFACEMETHODIMP GetBoundingRectangles(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal) noexcept override;
IFACEMETHODIMP GetEnclosingElement(_Outptr_result_maybenull_ IRawElementProviderSimple** ppRetVal) noexcept override;
IFACEMETHODIMP GetText(_In_ int maxLength,
_Out_ BSTR* pRetVal) noexcept override;
IFACEMETHODIMP Move(_In_ TextUnit unit,
_In_ int count,
_Out_ int* pRetVal) noexcept override;
IFACEMETHODIMP MoveEndpointByUnit(_In_ TextPatternRangeEndpoint endpoint,
_In_ TextUnit unit,
_In_ int count,
_Out_ int* pRetVal) noexcept override;
IFACEMETHODIMP MoveEndpointByRange(_In_ TextPatternRangeEndpoint endpoint,
_In_ ITextRangeProvider* pTargetRange,
_In_ TextPatternRangeEndpoint targetEndpoint) noexcept override;
IFACEMETHODIMP Select() noexcept override;
IFACEMETHODIMP AddToSelection() noexcept override;
IFACEMETHODIMP RemoveFromSelection() noexcept override;
IFACEMETHODIMP ScrollIntoView(_In_ BOOL alignToTop) noexcept override;
IFACEMETHODIMP GetChildren(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal) noexcept override;
protected:
UiaTextRangeBase() = default;
IUiaData* _pData{ nullptr };
IRawElementProviderSimple* _pProvider{ nullptr };
std::wstring _wordDelimiters{};
virtual void _TranslatePointToScreen(LPPOINT clientPoint) const = 0;
virtual void _TranslatePointFromScreen(LPPOINT screenPoint) const = 0;
void Initialize(_In_ const UiaPoint point);
// measure units in the form [_start, _end).
// These are in the TextBuffer coordinate space.
// NOTE: _start is inclusive, but _end is exclusive
COORD _start{};
COORD _end{};
bool _blockRange{};
// This is used by tracing to extract the text value
// that the UiaTextRange currently encompasses.
// GetText() cannot be used as it's not const
std::wstring _getTextValue(std::optional<unsigned int> maxLength = std::nullopt) const;
RECT _getTerminalRect() const;
virtual const COORD _getScreenFontSize() const noexcept;
const unsigned int _getViewportHeight(const SMALL_RECT viewport) const noexcept;
const Viewport _getOptimizedBufferSize() const noexcept;
const til::point _getDocumentEnd() const;
void _getBoundingRect(const til::rectangle textRect, _Inout_ std::vector<double>& coords) const;
void _expandToEnclosingUnit(TextUnit unit);
void
_moveEndpointByUnitCharacter(_In_ const int moveCount,
_In_ const TextPatternRangeEndpoint endpoint,
gsl::not_null<int*> const pAmountMoved,
_In_ const bool preventBufferEnd = false);
void
_moveEndpointByUnitWord(_In_ const int moveCount,
_In_ const TextPatternRangeEndpoint endpoint,
gsl::not_null<int*> const pAmountMoved,
_In_ const bool preventBufferEnd = false);
void
_moveEndpointByUnitLine(_In_ const int moveCount,
_In_ const TextPatternRangeEndpoint endpoint,
gsl::not_null<int*> const pAmountMoved,
_In_ const bool preventBoundary = false) noexcept;
void
_moveEndpointByUnitDocument(_In_ const int moveCount,
_In_ const TextPatternRangeEndpoint endpoint,
gsl::not_null<int*> const pAmountMoved,
_In_ const bool preventBoundary = false) noexcept;
std::optional<bool> _verifyAttr(TEXTATTRIBUTEID attributeId, VARIANT val, const TextAttribute& attr) const;
bool _initializeAttrQuery(TEXTATTRIBUTEID attributeId, VARIANT* pRetVal, const TextAttribute& attr) const;
bool _tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, COORD& resultingPos) const;
COORD _getInclusiveEnd() noexcept;
#ifdef UNIT_TESTING
friend class ::UiaTextRangeTests;
#endif
friend class UiaTracing;
};
}