#pragma once
#include "TextDirection.h"
#include <array>
namespace WebCore {
enum class WritingMode : uint8_t {
TopToBottom = 0, BottomToTop = 1, LeftToRight = 2, RightToLeft = 3, };
constexpr unsigned makeTextFlowInitalizer(WritingMode writingMode, TextDirection direction)
{
return static_cast<unsigned>(writingMode) << 1 | static_cast<unsigned>(direction);
}
enum TextFlow {
InlineEastBlockSouth = makeTextFlowInitalizer(WritingMode::TopToBottom, TextDirection::LTR),
InlineWestBlockSouth = makeTextFlowInitalizer(WritingMode::TopToBottom, TextDirection::RTL),
InlineEastBlockNorth = makeTextFlowInitalizer(WritingMode::BottomToTop, TextDirection::LTR),
InlineWestBlockNorth = makeTextFlowInitalizer(WritingMode::BottomToTop, TextDirection::RTL),
InlineSouthBlockEast = makeTextFlowInitalizer(WritingMode::LeftToRight, TextDirection::LTR),
InlineSouthBlockWest = makeTextFlowInitalizer(WritingMode::LeftToRight, TextDirection::RTL),
InlineNorthBlockEast = makeTextFlowInitalizer(WritingMode::RightToLeft, TextDirection::LTR),
InlineNorthBlockWest = makeTextFlowInitalizer(WritingMode::RightToLeft, TextDirection::RTL)
};
constexpr inline TextFlow makeTextFlow(WritingMode writingMode, TextDirection direction)
{
return static_cast<TextFlow>(makeTextFlowInitalizer(writingMode, direction));
}
constexpr unsigned TextFlowReversedMask = 1;
constexpr unsigned TextFlowFlippedMask = 2;
constexpr unsigned TextFlowVerticalMask = 4;
constexpr inline bool isReversedTextFlow(TextFlow textflow)
{
return textflow & TextFlowReversedMask;
}
constexpr inline bool isFlippedTextFlow(TextFlow textflow)
{
return textflow & TextFlowFlippedMask;
}
constexpr inline bool isVerticalTextFlow(TextFlow textflow)
{
return textflow & TextFlowVerticalMask;
}
constexpr inline bool isVerticalWritingMode(WritingMode writingMode)
{
return isVerticalTextFlow(makeTextFlow(writingMode, TextDirection::LTR));
}
constexpr inline bool isFlippedWritingMode(WritingMode writingMode)
{
return isFlippedTextFlow(makeTextFlow(writingMode, TextDirection::LTR));
}
constexpr inline bool isHorizontalWritingMode(WritingMode writingMode)
{
return !isVerticalWritingMode(writingMode);
}
constexpr inline bool isFlippedLinesWritingMode(WritingMode writingMode)
{
return isVerticalWritingMode(writingMode) != isFlippedWritingMode(writingMode);
}
enum class LogicalBoxSide : uint8_t {
Before,
End,
After,
Start
};
enum class BoxSide : uint8_t {
Top,
Right,
Bottom,
Left
};
constexpr std::array<BoxSide, 4> allBoxSides = { BoxSide::Top, BoxSide::Right, BoxSide::Bottom, BoxSide::Left };
constexpr inline bool isHorizontalPhysicalSide(BoxSide physicalSide)
{
return physicalSide == BoxSide::Left || physicalSide == BoxSide::Right;
}
constexpr inline BoxSide mirrorPhysicalSide(BoxSide physicalSide)
{
return static_cast<BoxSide>((static_cast<int>(physicalSide) + 2) % 4);
}
constexpr inline BoxSide rotatePhysicalSide(BoxSide physicalSide)
{
bool horizontalSide = isHorizontalPhysicalSide(physicalSide);
return static_cast<BoxSide>((static_cast<int>(physicalSide) + (horizontalSide ? 1 : 3)) % 4);
}
constexpr inline BoxSide mapLogicalSideToPhysicalSide(TextFlow textflow, LogicalBoxSide logicalSide)
{
BoxSide physicalSide = static_cast<BoxSide>(logicalSide);
bool horizontalSide = isHorizontalPhysicalSide(physicalSide);
if (isVerticalTextFlow(textflow))
physicalSide = rotatePhysicalSide(physicalSide);
if ((horizontalSide && isReversedTextFlow(textflow)) || (!horizontalSide && isFlippedTextFlow(textflow)))
physicalSide = mirrorPhysicalSide(physicalSide);
return physicalSide;
}
constexpr inline BoxSide mapLogicalSideToPhysicalSide(WritingMode writingMode, LogicalBoxSide logicalSide)
{
TextDirection direction = isFlippedWritingMode(writingMode) ? TextDirection::RTL : TextDirection::LTR;
return mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), logicalSide);
}
}