diff --git a/Specification.rst b/Specification.rst index 1cf4c21..1541275 100644 --- a/Specification.rst +++ b/Specification.rst @@ -43,7 +43,8 @@ All sections and elements are aligned to 32 bits. In doubt padding bytes with va Fonts ----- -? +All fonts must be in the U8G2 font format that can be parsed by the u8g2-fonts Rust crate, see + for details. File Header =========== @@ -194,7 +195,14 @@ Custom Font This section defines a custom font that is to be used within this file. Any custom font used by draw elements MUST occur in the file before the font is used. -font support t.b.d. +The section consists of the following type-specific header: + + 0 1 2 3 + +------------------------+------------------------+------------------------+------------------------+ + 0 | Actual Size of Font (octets) | Reserved | + +------------------------+------------------------+------------------------+------------------------+ + +This is followed by the font data itself in the format. The actual size indicates how long the font actually is in octets, which may be smaller than the padded length of the section indicates. Elements ======== @@ -371,11 +379,7 @@ Horizontally Scrolling Text +------------------------+------------------------+------------------------+------------------------+ 8 | Height | Flags | Scroll Speed | +------------------------+------------------------+------------------------+------------------------+ - 12 | Font Name Size | Text Length | - +------------------------+------------------------+------------------------+------------------------+ - 16 | Font Name ... | - +------------------------+------------------------+------------------------+------------------------+ - ... | ... Font Name | Text ... | + 12 | Font Index | Text ... | +------------------------+------------------------+------------------------+------------------------+ ... | ... Text | Padding (if required) | +------------------------+------------------------+------------------------+------------------------+ diff --git a/cpp/src/monoformat_structured.cpp b/cpp/src/monoformat_structured.cpp index d9ee8cf..99bd689 100644 --- a/cpp/src/monoformat_structured.cpp +++ b/cpp/src/monoformat_structured.cpp @@ -125,7 +125,7 @@ std::size_t ImageElement::serializeTo(std::span target) const { // FIXME: serialize } -void ImageElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) { +void ImageElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) { // FIXME: draw } @@ -133,7 +133,7 @@ std::expected, ParseError> ImageElement::parse(std // 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::uint8_t updateInterval) +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} @@ -165,7 +165,7 @@ std::uint16_t AnimationElement::numberOfFrames() const noexcept { return m_numberOfFrames; } -std::uint8_t AnimationElement::updateInterval() const noexcept { +std::uint16_t AnimationElement::updateInterval() const noexcept { return m_updateInterval; } @@ -212,7 +212,7 @@ std::size_t AnimationElement::serializeTo(std::span target) const { // FIXME: implement this } -void AnimationElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) { +void AnimationElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) { // FIXME: implement this } diff --git a/cpp/src/monoformat_structured.hpp b/cpp/src/monoformat_structured.hpp index 6a50e09..400ea43 100644 --- a/cpp/src/monoformat_structured.hpp +++ b/cpp/src/monoformat_structured.hpp @@ -50,7 +50,7 @@ struct Element { virtual ~Element() = default; virtual ElementType elementType() const = 0; virtual std::size_t serializeTo(std::span target) const = 0; - virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) = 0; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) = 0; protected: Element() = default; @@ -93,7 +93,7 @@ struct ImageElement : public Element { virtual ~ImageElement() override; virtual ElementType elementType() const override; virtual std::size_t serializeTo(std::span target) const override; - virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; static std::expected, ParseError> parse(std::span& buffer); @@ -106,14 +106,14 @@ private: }; struct AnimationElement : public Element { - AnimationElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t numberOfFrames, std::uint8_t updateInterval); + 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); std::uint16_t x() const noexcept; std::uint16_t y() const noexcept; std::uint16_t width() const noexcept; std::uint16_t height() const noexcept; std::uint16_t numberOfFrames() const noexcept; - std::uint8_t updateInterval() const noexcept; + std::uint16_t updateInterval() const noexcept; std::span buffers() noexcept; std::span buffers() const noexcept; std::span buffer(std::uint16_t frameIndex) noexcept; @@ -124,7 +124,7 @@ struct AnimationElement : public Element { virtual ~AnimationElement() override; virtual ElementType elementType() const override; virtual std::size_t serializeTo(std::span target) const override; - virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; static std::expected, ParseError> parse(std::span& buffer); @@ -134,7 +134,7 @@ private: std::uint16_t m_width{}; std::uint16_t m_height{}; std::uint16_t m_numberOfFrames{}; - std::uint8_t m_updateInterval{}; + std::uint16_t m_updateInterval{}; std::vector m_buffer; }; @@ -156,7 +156,7 @@ struct HScrollImageElement : public Element { virtual ~HScrollImageElement() override; virtual ElementType elementType() const override; virtual std::size_t serializeTo(std::span target) const override; - virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; static std::expected, ParseError> parse(std::span& buffer); @@ -189,7 +189,7 @@ struct VScrollImageElement : public Element { virtual ~VScrollImageElement() override; virtual ElementType elementType() const override; virtual std::size_t serializeTo(std::span target) const override; - virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; static std::expected, ParseError> parse(std::span& buffer); @@ -221,7 +221,7 @@ struct LineElement : public Element { virtual ~LineElement() override; virtual ElementType elementType() const override; virtual std::size_t serializeTo(std::span target) const override; - virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick) override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; static std::expected, ParseError> parse(std::span& buffer); @@ -234,7 +234,89 @@ private: std::uint8_t m_flags{}; }; -// FIXME: text elements +struct ClippedTextElement : public Element { + ClippedTextElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t fontIndex, std::string text); + + std::uint16_t x() const noexcept; + std::uint16_t y() const noexcept; + std::uint16_t width() const noexcept; + std::uint16_t height() const noexcept; + std::uint16_t fontIndex() const noexcept; + std::string text() const; + + virtual ~ClippedTextElement() override; + virtual ElementType elementType() const override; + virtual std::size_t serializeTo(std::span target) const override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; + + static std::expected, ParseError> parse(std::span& buffer); + +private: + std::uint16_t m_x{}; + std::uint16_t m_y{}; + std::uint16_t m_width{}; + std::uint16_t m_height{}; + std::uint16_t m_fontIndex{}; + std::string m_text; +}; + +struct HScrollTextElement : public Element { + HScrollTextElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint8_t flags, std::uint8_t scrollSpeed, std::uint16_t fontIndex, std::string text); + + std::uint16_t x() const noexcept; + std::uint16_t y() const noexcept; + std::uint16_t width() const noexcept; + std::uint16_t height() const noexcept; + std::uint8_t flags() const noexcept; + std::uint8_t scrollSpeed() const noexcept; + std::uint16_t fontIndex() const noexcept; + std::string text() const; + + virtual ~HScrollTextElement() override; + virtual ElementType elementType() const override; + virtual std::size_t serializeTo(std::span target) const override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; + + static std::expected, ParseError> parse(std::span& buffer); + +private: + std::uint16_t m_x{}; + std::uint16_t m_y{}; + std::uint16_t m_width{}; + std::uint16_t m_height{}; + std::uint8_t m_flags{}; + std::uint8_t m_scrollSpeed{}; + std::uint16_t m_fontIndex{}; + std::string m_text; +}; + +struct CurrentTimeElement : public Element { + CurrentTimeElement(std::uint16_t x, std::uint16_t y, std::uint16_t width, std::uint16_t height, std::uint16_t fontIndex, std::uint16_t utcOffset, std::uint16_t flags); + + std::uint16_t x() const noexcept; + std::uint16_t y() const noexcept; + std::uint16_t width() const noexcept; + std::uint16_t height() const noexcept; + std::uint16_t fontIndex() const noexcept; + std::uint16_t utcOffset() const noexcept; + std::uint16_t flags() const noexcept; + + virtual ~CurrentTimeElement() override; + virtual ElementType elementType() const override; + virtual std::size_t serializeTo(std::span target) const override; + virtual void drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) override; + + static std::expected, ParseError> parse(std::span& buffer); + +private: + std::uint16_t m_x{}; + std::uint16_t m_y{}; + std::uint16_t m_width{}; + std::uint16_t m_height{}; + std::uint16_t m_fontIndex{}; + std::uint16_t m_utcOffset{}; + std::uint16_t m_flags{}; +}; struct AlwaysDrawnSection : public Section { AlwaysDrawnSection() = default; @@ -259,6 +341,8 @@ struct AlwaysDrawnSection : public Section { virtual SectionType sectionType() const override; virtual std::size_t serializeTo(std::span target) const override; + static std::expected, ParseError> parse(std::span& buffer); + private: std::vector> m_elements; bool m_drawOnFront{true}; @@ -294,6 +378,8 @@ struct TimeBasedDrawnSection : public Section { virtual SectionType sectionType() const override; virtual std::size_t serializeTo(std::span target) const override; + static std::expected, ParseError> parse(std::span& buffer); + private: std::vector> m_elements; std::uint64_t m_startTimestamp{}; @@ -303,7 +389,18 @@ private: bool m_clearBeforeDrawing{true}; }; -// FIXME: custom font sections +struct CustomFontSection : public Section { + CustomFontSection() = default; + virtual ~CustomFontSection() override; + + virtual SectionType sectionType() const override; + virtual std::size_t serializeTo(std::span target) const override; + + static std::expected, ParseError> parse(std::span& buffer); + +private: + std::vector m_fontData; +}; struct File { std::vector> sections;