terminal/src/buffer/out/DbcsAttribute.hpp

144 lines
3.3 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- DbcsAttribute.hpp
Abstract:
- helper class for storing double byte character set information about a cell in the output buffer.
Author(s):
- Austin Diviness (AustDi) 26-Jan-2018
Revision History:
--*/
#pragma once
class DbcsAttribute final
{
public:
enum class Attribute : BYTE
{
Single = 0x00,
Leading = 0x01,
Trailing = 0x02
};
DbcsAttribute() noexcept :
_attribute{ Attribute::Single },
_glyphStored{ false }
{
}
DbcsAttribute(const Attribute attribute) noexcept :
_attribute{ attribute },
_glyphStored{ false }
{
}
constexpr bool IsSingle() const noexcept
{
return _attribute == Attribute::Single;
}
constexpr bool IsLeading() const noexcept
{
return _attribute == Attribute::Leading;
}
constexpr bool IsTrailing() const noexcept
{
return _attribute == Attribute::Trailing;
}
constexpr bool IsDbcs() const noexcept
{
return IsLeading() || IsTrailing();
}
constexpr bool IsGlyphStored() const noexcept
{
return _glyphStored;
}
void SetGlyphStored(const bool stored)
{
_glyphStored = stored;
}
void SetSingle() noexcept
{
_attribute = Attribute::Single;
}
void SetLeading() noexcept
{
_attribute = Attribute::Leading;
}
void SetTrailing() noexcept
{
_attribute = Attribute::Trailing;
}
void Reset() noexcept
{
SetSingle();
SetGlyphStored(false);
}
WORD GeneratePublicApiAttributeFormat() const noexcept
{
WORD publicAttribute = 0;
if (IsLeading())
{
WI_SetFlag(publicAttribute, COMMON_LVB_LEADING_BYTE);
}
if (IsTrailing())
{
WI_SetFlag(publicAttribute, COMMON_LVB_TRAILING_BYTE);
}
return publicAttribute;
}
static DbcsAttribute FromPublicApiAttributeFormat(WORD publicAttribute)
{
// it's not valid to be both a leading and trailing byte
if (WI_AreAllFlagsSet(publicAttribute, COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE))
{
THROW_HR(E_INVALIDARG);
}
DbcsAttribute attr;
if (WI_IsFlagSet(publicAttribute, COMMON_LVB_LEADING_BYTE))
{
attr.SetLeading();
}
else if (WI_IsFlagSet(publicAttribute, COMMON_LVB_TRAILING_BYTE))
{
attr.SetTrailing();
}
return attr;
}
friend constexpr bool operator==(const DbcsAttribute& a, const DbcsAttribute& b) noexcept;
private:
Attribute _attribute : 2;
bool _glyphStored : 1;
#ifdef UNIT_TESTING
friend class TextBufferTests;
#endif
};
constexpr bool operator==(const DbcsAttribute& a, const DbcsAttribute& b) noexcept
{
return a._attribute == b._attribute;
}
static_assert(sizeof(DbcsAttribute) == sizeof(BYTE), "DbcsAttribute should be one byte big. if this changes then it needs"
" either an implicit conversion to a BYTE or an update to all places that assume it's a byte big");