#include "monoformat_structured.hpp" namespace monoformat { MemoryOneBitBuffer::MemoryOneBitBuffer(std::span buffer, std::uint16_t width, std::uint16_t height) : m_width{width} , m_height{height} , m_buffer{buffer} { std::size_t expectedSize = (m_width * m_height + 8 - 1) / 8; if (m_buffer.size() < expectedSize) { m_width = 0; m_height = 0; } } MemoryOneBitBuffer::~MemoryOneBitBuffer() { } bool MemoryOneBitBuffer::isPixelSet(std::uint16_t x, std::uint16_t y) const { if (x >= m_width || y >= m_height) { return false; } std::size_t pxIndex = static_cast(y) * m_width + x; std::size_t byteIndex = pxIndex / 8; std::size_t bitIndex = pxIndex % 8; return ((static_cast(m_buffer[byteIndex]) >> bitIndex) & 0x01) == 0x01; } void MemoryOneBitBuffer::setPixel(std::uint16_t x, std::uint16_t y, bool value) { if (x >= m_width || y >= m_height) { return; } std::size_t pxIndex = static_cast(y) * m_width + x; std::size_t byteIndex = pxIndex / 8; std::size_t bitIndex = pxIndex % 8; if (value) { m_buffer[byteIndex] = static_cast(static_cast(m_buffer[byteIndex]) | (1u << bitIndex)); } else { m_buffer[byteIndex] = static_cast(static_cast(m_buffer[byteIndex]) & ~(1u << bitIndex)); } } ConstMemoryOneBitBuffer::ConstMemoryOneBitBuffer(std::span buffer, std::uint16_t width, std::uint16_t height) : m_width{width} , m_height{height} , m_buffer{buffer} { std::size_t expectedSize = (m_width * m_height + 8 - 1) / 8; if (m_buffer.size() < expectedSize) { m_width = 0; m_height = 0; } } ConstMemoryOneBitBuffer::~ConstMemoryOneBitBuffer() { } bool ConstMemoryOneBitBuffer::isPixelSet(std::uint16_t x, std::uint16_t y) const { if (x >= m_width || y >= m_height) { return false; } std::size_t pxIndex = static_cast(y) * m_width + x; std::size_t byteIndex = pxIndex / 8; std::size_t bitIndex = pxIndex % 8; return ((static_cast(m_buffer[byteIndex]) >> bitIndex) & 0x01) == 0x01; } void ConstMemoryOneBitBuffer::setPixel(std::uint16_t x, std::uint16_t y, bool value) { std::ignore = x; std::ignore = y; std::ignore = value; } ImageElement::ImageElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height) : m_x{x} , m_y{y} , m_width{width} , m_height{height} { std::size_t const bufferSize = (m_width * m_height + 8 - 1) / 8;\ m_buffer.resize(bufferSize); } std::uint16_t ImageElement::x() const noexcept { return m_x; } std::uint16_t ImageElement::y() const noexcept { return m_y; } std::uint16_t ImageElement::width() const noexcept { return m_width; } std::uint16_t ImageElement::height() const noexcept { return m_height; } std::span ImageElement::buffer() noexcept { return m_buffer; } std::span ImageElement::buffer() const noexcept { return m_buffer; } MemoryOneBitBuffer ImageElement::image() noexcept { return MemoryOneBitBuffer{m_buffer, m_width, m_height}; } ConstMemoryOneBitBuffer ImageElement::image() const noexcept { return ConstMemoryOneBitBuffer{m_buffer, m_width, m_height}; } ImageElement::~ImageElement() { } ElementType ImageElement::elementType() const { return ElementType::Image; } std::size_t ImageElement::serializeTo(std::span target) const { // FIXME: serialize } void ImageElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) { // FIXME: draw } std::expected, ParseError> ImageElement::parse(std::span& buffer) { // FIXME: parse } AnimationElement::AnimationElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t numberOfFrames, std::uint16_t updateInterval) : m_x{x} , m_y{y} , m_width{width} , m_height{height} , m_numberOfFrames{numberOfFrames} , m_updateInterval{updateInterval} { std::size_t const imageBufferSize = (m_width * m_height + 8 - 1) / 8;\ m_buffer.resize(imageBufferSize * numberOfFrames); } std::uint16_t AnimationElement::x() const noexcept { return m_x; } std::uint16_t AnimationElement::y() const noexcept { return m_y; } std::uint16_t AnimationElement::width() const noexcept { return m_width; } std::uint16_t AnimationElement::height() const noexcept { return m_height; } std::uint16_t AnimationElement::numberOfFrames() const noexcept { return m_numberOfFrames; } std::uint16_t AnimationElement::updateInterval() const noexcept { return m_updateInterval; } std::span AnimationElement::buffers() noexcept { return m_buffer; } std::span AnimationElement::buffers() const noexcept { return m_buffer; } std::span AnimationElement::buffer(std::uint16_t frameIndex) noexcept { if (frameIndex >= m_numberOfFrames) { return {}; } std::size_t const imageBufferSize = (m_width * m_height + 8 - 1) / 8; return std::span{m_buffer}.subspan(frameIndex * imageBufferSize, imageBufferSize); } std::span AnimationElement::buffer(std::uint16_t frameIndex) const noexcept { if (frameIndex >= m_numberOfFrames) { return {}; } std::size_t const imageBufferSize = (m_width * m_height + 8 - 1) / 8; return std::span{m_buffer}.subspan(frameIndex * imageBufferSize, imageBufferSize); } MemoryOneBitBuffer AnimationElement::image(std::uint16_t frameIndex) noexcept { return MemoryOneBitBuffer{buffer(frameIndex), m_width, m_height}; } ConstMemoryOneBitBuffer AnimationElement::image(std::uint16_t frameIndex) const noexcept { return ConstMemoryOneBitBuffer{buffer(frameIndex), m_width, m_height}; } AnimationElement::~AnimationElement() { } ElementType AnimationElement::elementType() const { return ElementType::Animation; } std::size_t AnimationElement::serializeTo(std::span target) const { // FIXME: implement this } void AnimationElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) { // FIXME: implement this } std::expected, ParseError> AnimationElement::parse(std::span& buffer) { // FIXME: implement this } } // namespace monoformat