terminal/src/buffer/out/Row.hpp
Leonard Hecker a8e4bedae3
Introduce til::rle - a run length encoded vector (#10099)
## Summary of the Pull Request

Introduces `til::rle`, a vector-like container which stores elements of
type T in a run length encoded format. This allows efficient compaction
of repeated elements within the vector.

## References

* #8000 - Supports buffer rewrite work. A re-use of `til::rle` will be
  useful as a column counter as we pursue NxM storage and presentation.
* #3075 - The new iterators allow skipping forward by multiple units,
  which wasn't possible under `TextBuffer-/OutputCellIterator`.
  Additionally it also allows a bulk insertions.
* #8787 and #410 - High probability this should be `pmr`-ified
  like `bitmap` for things like `chafa` and `cacafire`
  which are changing the run length frequently.

## PR Checklist

* [x] Closes #8741
* [x] I work here.
* [x] Tests added.
* [x] Tests passed.

## Validation Steps Performed

* [x] Ran `cacafire` in `OpenConsole.exe` and it looked beautiful
* [x] Ran new suite of `RunLengthEncodingTests.cpp`

Co-authored-by: Michael Niksa <miniksa@microsoft.com>
2021-05-20 17:27:50 +00:00

94 lines
3 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- Row.hpp
Abstract:
- data structure for information associated with one row of screen buffer
Author(s):
- Michael Niksa (miniksa) 10-Apr-2014
- Paul Campbell (paulcam) 10-Apr-2014
Revision History:
- From components of output.h/.c
by Therese Stowell (ThereseS) 1990-1991
- Pulled into its own file from textBuffer.hpp/cpp (AustDi, 2017)
--*/
#pragma once
#include "AttrRow.hpp"
#include "LineRendition.hpp"
#include "OutputCell.hpp"
#include "OutputCellIterator.hpp"
#include "CharRow.hpp"
#include "UnicodeStorage.hpp"
class TextBuffer;
class ROW final
{
public:
ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
size_t size() const noexcept { return _rowWidth; }
void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
bool WasWrapForced() const noexcept { return _wrapForced; }
void SetDoubleBytePadded(const bool doubleBytePadded) noexcept { _doubleBytePadded = doubleBytePadded; }
bool WasDoubleBytePadded() const noexcept { return _doubleBytePadded; }
const CharRow& GetCharRow() const noexcept { return _charRow; }
CharRow& GetCharRow() noexcept { return _charRow; }
const ATTR_ROW& GetAttrRow() const noexcept { return _attrRow; }
ATTR_ROW& GetAttrRow() noexcept { return _attrRow; }
LineRendition GetLineRendition() const noexcept { return _lineRendition; }
void SetLineRendition(const LineRendition lineRendition) noexcept { _lineRendition = lineRendition; }
SHORT GetId() const noexcept { return _id; }
void SetId(const SHORT id) noexcept { _id = id; }
bool Reset(const TextAttribute Attr);
[[nodiscard]] HRESULT Resize(const unsigned short width);
void ClearColumn(const size_t column);
std::wstring GetText() const { return _charRow.GetText(); }
UnicodeStorage& GetUnicodeStorage() noexcept;
const UnicodeStorage& GetUnicodeStorage() const noexcept;
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap = std::nullopt, std::optional<size_t> limitRight = std::nullopt);
#ifdef UNIT_TESTING
friend constexpr bool operator==(const ROW& a, const ROW& b) noexcept;
friend class RowTests;
#endif
private:
CharRow _charRow;
ATTR_ROW _attrRow;
LineRendition _lineRendition;
SHORT _id;
unsigned short _rowWidth;
// Occurs when the user runs out of text in a given row and we're forced to wrap the cursor to the next line
bool _wrapForced;
// Occurs when the user runs out of text to support a double byte character and we're forced to the next line
bool _doubleBytePadded;
TextBuffer* _pParent; // non ownership pointer
};
#ifdef UNIT_TESTING
constexpr bool operator==(const ROW& a, const ROW& b) noexcept
{
// comparison is only used in the tests; this should suffice.
return (a._pParent == b._pParent &&
a._id == b._id);
}
#endif