parent
c67c467486
commit
c5071bf1ca
@ -0,0 +1,449 @@ |
|||||||
|
// =============================================================================
|
||||||
|
// Mono Display File Format - type definitions
|
||||||
|
// Spec: Mono Display File Format Specification
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Enums
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export enum FileVersion { |
||||||
|
/** Illegal - must not appear in a valid file */ |
||||||
|
Illegal = 0, |
||||||
|
/** Current specification version */ |
||||||
|
V1 = 1, |
||||||
|
} |
||||||
|
|
||||||
|
export enum SectionType { |
||||||
|
/** List of drawn elements - always shown */ |
||||||
|
ElementsAlways = 1, |
||||||
|
/** List of drawn elements - shown only within a POSIX timestamp window */ |
||||||
|
ElementsTimespan = 2, |
||||||
|
/** U8G2-format custom font used by draw elements in this file */ |
||||||
|
CustomFont = 32, |
||||||
|
} |
||||||
|
|
||||||
|
export enum ElementType { |
||||||
|
Image2D = 1, |
||||||
|
Animation = 2, |
||||||
|
HorizontalScroll = 3, |
||||||
|
VerticalScroll = 4, |
||||||
|
Line = 5, |
||||||
|
ClippedText = 16, |
||||||
|
HScrollText = 17, |
||||||
|
/** |
||||||
|
* Current time display. |
||||||
|
* NOTE: the spec diagram labels this element "Type: 16", which collides with |
||||||
|
* ClippedText. This is assumed to be a spec typo; 18 is used here as the |
||||||
|
* probable intended value until the spec is corrected. |
||||||
|
*/ |
||||||
|
CurrentTime = 18, |
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Section flags (section types 1 and 2)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Bit-field flags for ElementsAlways / ElementsTimespan sections. */ |
||||||
|
export interface SectionFlags { |
||||||
|
/** Bit 0 - render elements onto the front-side buffer. */ |
||||||
|
drawFront?: boolean; |
||||||
|
/** Bit 1 - render elements onto the back-side buffer. */ |
||||||
|
drawBack?: boolean; |
||||||
|
/** Bit 2 - clear targeted buffer(s) before drawing this section's elements. */ |
||||||
|
clearBuffer?: boolean; |
||||||
|
// Bits 3-15: reserved; writers MUST write 0.
|
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Scroll element flags (HorizontalScroll / VerticalScroll / HScrollText)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface ScrollElementFlags { |
||||||
|
/** Bit 0 - wrap content endlessly. */ |
||||||
|
endless?: boolean; |
||||||
|
/** Bit 1 - reverse scroll direction. */ |
||||||
|
invertDirection?: boolean; |
||||||
|
/** Bit 2 - pad at start edge (left for H-scroll, top for V-scroll). */ |
||||||
|
padStart?: boolean; |
||||||
|
/** Bit 3 - pad at end edge (right for H-scroll, bottom for V-scroll). */ |
||||||
|
padEnd?: boolean; |
||||||
|
// Bits 4-7: reserved.
|
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// CurrentTime element flags
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface CurrentTimeFlags { |
||||||
|
/** Bit 0 - use 12-hour clock (default 24-hour). */ |
||||||
|
clock12h?: boolean; |
||||||
|
/** Bit 1 - show hours. */ |
||||||
|
showHours?: boolean; |
||||||
|
/** Bit 2 - show minutes. */ |
||||||
|
showMinutes?: boolean; |
||||||
|
/** Bit 3 - show seconds. */ |
||||||
|
showSeconds?: boolean; |
||||||
|
// Bits 4-15: reserved.
|
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Line element flags
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface LineFlags { |
||||||
|
/** Bit 0 - invert pixel values along the line. */ |
||||||
|
invertPixels?: boolean; |
||||||
|
// Bits 1-7: reserved.
|
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Font index helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** |
||||||
|
* Font index encoding: |
||||||
|
* 0 .. 0x7FFF built-in font (device-specific; may not exist) |
||||||
|
* 0x8000+ custom font embedded in this file |
||||||
|
* 0x8000 = first CustomFont section |
||||||
|
* 0x8001 = second, etc. |
||||||
|
*/ |
||||||
|
export type FontIndex = number; |
||||||
|
|
||||||
|
export const CUSTOM_FONT_BASE = 0x8000; |
||||||
|
|
||||||
|
/** Return true when fontIndex refers to a custom (in-file) font. */ |
||||||
|
export function isCustomFont(fontIndex: FontIndex): boolean { |
||||||
|
return fontIndex >= CUSTOM_FONT_BASE; |
||||||
|
} |
||||||
|
|
||||||
|
/** Extract zero-based position of a custom font within the file. */ |
||||||
|
export function customFontOrdinal(fontIndex: FontIndex): number { |
||||||
|
return fontIndex - CUSTOM_FONT_BASE; |
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// User-facing element descriptors (MonoDisplayFile / builder input)
|
||||||
|
// Pixels are 1 byte/pixel (0 = off, 1 = on) in the API; packed to 1bpp on
|
||||||
|
// serialisation.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface Image2DElement { |
||||||
|
type: ElementType.Image2D; |
||||||
|
/** Row-major, 1 byte/pixel (0 = off, 1 = on). Packed to 1bpp on write. */ |
||||||
|
pixels: Uint8Array; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
xOffset?: number; // default 0
|
||||||
|
yOffset?: number; // default 0
|
||||||
|
} |
||||||
|
|
||||||
|
export interface AnimationFrameDescriptor { |
||||||
|
/** 1 byte/pixel, same dimensions as the parent AnimationElement. */ |
||||||
|
pixels: Uint8Array; |
||||||
|
} |
||||||
|
|
||||||
|
export interface AnimationElement { |
||||||
|
type: ElementType.Animation; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
frames: AnimationFrameDescriptor[]; |
||||||
|
/** |
||||||
|
* Advance frame every (updateInterval + 1) ticks. |
||||||
|
* 0 = every tick, 1 = every 2nd tick, ..., 65535 = every 65536th tick. |
||||||
|
* Default 0. |
||||||
|
*/ |
||||||
|
updateInterval?: number; |
||||||
|
xOffset?: number; |
||||||
|
yOffset?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface HScrollElement { |
||||||
|
type: ElementType.HorizontalScroll; |
||||||
|
/** Viewport width in pixels. */ |
||||||
|
width: number; |
||||||
|
/** Viewport height in pixels. */ |
||||||
|
height: number; |
||||||
|
/** Scrolling content pixels (contentWidth × height), 1 byte/pixel. */ |
||||||
|
pixels: Uint8Array; |
||||||
|
contentWidth: number; |
||||||
|
/** |
||||||
|
* Scroll speed byte SS; moves (SS + 1) / 16 pixels per tick. |
||||||
|
* Range 0-255. Default 0 (= 1/16 px/tick). |
||||||
|
*/ |
||||||
|
scrollSpeed?: number; |
||||||
|
flags?: ScrollElementFlags; |
||||||
|
xOffset?: number; |
||||||
|
yOffset?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface VScrollElement { |
||||||
|
type: ElementType.VerticalScroll; |
||||||
|
/** Viewport width in pixels. */ |
||||||
|
width: number; |
||||||
|
/** Viewport height in pixels. */ |
||||||
|
height: number; |
||||||
|
/** Scrolling content pixels (width × contentHeight), 1 byte/pixel. */ |
||||||
|
pixels: Uint8Array; |
||||||
|
contentHeight: number; |
||||||
|
/** Scroll speed byte SS; moves (SS + 1) / 16 pixels per tick. Default 0. */ |
||||||
|
scrollSpeed?: number; |
||||||
|
flags?: ScrollElementFlags; |
||||||
|
xOffset?: number; |
||||||
|
yOffset?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface LineElement { |
||||||
|
type: ElementType.Line; |
||||||
|
xOrigin: number; |
||||||
|
yOrigin: number; |
||||||
|
xTarget: number; |
||||||
|
yTarget: number; |
||||||
|
/** Reserved by spec; writers MUST write 0. */ |
||||||
|
lineStyle?: number; |
||||||
|
invertPixels?: boolean; // flags bit 0
|
||||||
|
} |
||||||
|
|
||||||
|
export interface ClippedTextElement { |
||||||
|
type: ElementType.ClippedText; |
||||||
|
text: string; // UTF-8
|
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
/** 0-32767 = built-in font; 0x8000+ = custom font in file. Default 0. */ |
||||||
|
fontIndex?: FontIndex; |
||||||
|
xOffset?: number; |
||||||
|
yOffset?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface HScrollTextElement { |
||||||
|
type: ElementType.HScrollText; |
||||||
|
text: string; // UTF-8
|
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
scrollSpeed?: number; // SS byte, default 0
|
||||||
|
fontIndex?: FontIndex; |
||||||
|
flags?: ScrollElementFlags; |
||||||
|
xOffset?: number; |
||||||
|
yOffset?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface CurrentTimeElement { |
||||||
|
type: ElementType.CurrentTime; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
/** 0-32767 = built-in font; 0x8000+ = custom font in file. Default 0. */ |
||||||
|
fontIndex?: FontIndex; |
||||||
|
/** |
||||||
|
* UTC offset in whole minutes (signed 16-bit integer). |
||||||
|
* e.g. UTC+5:30 → 330, UTC-8 → -480. |
||||||
|
*/ |
||||||
|
utcOffsetMinutes?: number; |
||||||
|
flags?: CurrentTimeFlags; |
||||||
|
xOffset?: number; |
||||||
|
yOffset?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export type DrawElement = |
||||||
|
| Image2DElement |
||||||
|
| AnimationElement |
||||||
|
| HScrollElement |
||||||
|
| VScrollElement |
||||||
|
| LineElement |
||||||
|
| ClippedTextElement |
||||||
|
| HScrollTextElement |
||||||
|
| CurrentTimeElement; |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Section descriptors (MonoDisplayFile / builder input)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface ElementsAlwaysDescriptor { |
||||||
|
flags?: SectionFlags; |
||||||
|
elements: DrawElement[]; |
||||||
|
} |
||||||
|
|
||||||
|
export interface ElementsTimespanDescriptor { |
||||||
|
flags?: SectionFlags; |
||||||
|
elements: DrawElement[]; |
||||||
|
/** POSIX timestamp (seconds) - section visible when now >= startTimestamp. */ |
||||||
|
startTimestamp: bigint; |
||||||
|
/** POSIX timestamp (seconds) - section visible when now < endTimestamp. */ |
||||||
|
endTimestamp: bigint; |
||||||
|
} |
||||||
|
|
||||||
|
export interface CustomFontDescriptor { |
||||||
|
/** Raw U8G2 font data. */ |
||||||
|
fontData: Uint8Array; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Top-level descriptor passed to MonoDisplayFile. |
||||||
|
* |
||||||
|
* Sections are written in the order they appear here. |
||||||
|
* Custom fonts MUST appear before any element that references them. |
||||||
|
*/ |
||||||
|
export interface MonoDisplayFileDescriptor { |
||||||
|
/** Section type 1 - drawn every render tick. */ |
||||||
|
elements_always?: DrawElement[] | ElementsAlwaysDescriptor; |
||||||
|
/** Section type 2 - drawn only within the given timestamp window. */ |
||||||
|
elements_timespan?: ElementsTimespanDescriptor[]; |
||||||
|
/** Section type 32 - embedded U8G2 custom fonts. */ |
||||||
|
custom_fonts?: CustomFontDescriptor[]; |
||||||
|
} |
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// MonoFormat types (MonoDisplayParser output → renderer input)
|
||||||
|
// Pixels are always unpacked (1 byte/pixel) after parsing.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface MonoFormatPixelImage { |
||||||
|
/** Unpacked: 1 byte per pixel, 0 = off, 1 = on, row-major. */ |
||||||
|
pixels: Uint8Array; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatImage2D { |
||||||
|
type: ElementType.Image2D; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
image: MonoFormatPixelImage; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatAnimation { |
||||||
|
type: ElementType.Animation; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
updateInterval: number; |
||||||
|
frames: MonoFormatPixelImage[]; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatScrollFlags { |
||||||
|
endless: boolean; |
||||||
|
invertDirection: boolean; |
||||||
|
padStart: boolean; |
||||||
|
padEnd: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatHScroll { |
||||||
|
type: ElementType.HorizontalScroll; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
contentWidth: number; |
||||||
|
scrollSpeed: number; |
||||||
|
flags: MonoFormatScrollFlags; |
||||||
|
content: MonoFormatPixelImage; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatVScroll { |
||||||
|
type: ElementType.VerticalScroll; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
contentHeight: number; |
||||||
|
scrollSpeed: number; |
||||||
|
flags: MonoFormatScrollFlags; |
||||||
|
content: MonoFormatPixelImage; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatLine { |
||||||
|
type: ElementType.Line; |
||||||
|
xOrigin: number; |
||||||
|
yOrigin: number; |
||||||
|
xTarget: number; |
||||||
|
yTarget: number; |
||||||
|
lineStyle: number; |
||||||
|
invertPixels: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatClippedText { |
||||||
|
type: ElementType.ClippedText; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
fontIndex: FontIndex; |
||||||
|
text: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatHScrollText { |
||||||
|
type: ElementType.HScrollText; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
scrollSpeed: number; |
||||||
|
fontIndex: FontIndex; |
||||||
|
flags: MonoFormatScrollFlags; |
||||||
|
text: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatCurrentTimeFlags { |
||||||
|
clock12h: boolean; |
||||||
|
showHours: boolean; |
||||||
|
showMinutes: boolean; |
||||||
|
showSeconds: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatCurrentTime { |
||||||
|
type: ElementType.CurrentTime; |
||||||
|
xOffset: number; |
||||||
|
yOffset: number; |
||||||
|
width: number; |
||||||
|
height: number; |
||||||
|
fontIndex: FontIndex; |
||||||
|
/** UTC offset in minutes (signed). */ |
||||||
|
utcOffsetMinutes: number; |
||||||
|
flags: MonoFormatCurrentTimeFlags; |
||||||
|
} |
||||||
|
|
||||||
|
export type MonoFormatElement = |
||||||
|
| MonoFormatImage2D |
||||||
|
| MonoFormatAnimation |
||||||
|
| MonoFormatHScroll |
||||||
|
| MonoFormatVScroll |
||||||
|
| MonoFormatLine |
||||||
|
| MonoFormatClippedText |
||||||
|
| MonoFormatHScrollText |
||||||
|
| MonoFormatCurrentTime; |
||||||
|
|
||||||
|
export interface MonoFormatSectionFlags { |
||||||
|
drawFront: boolean; |
||||||
|
drawBack: boolean; |
||||||
|
clearBuffer: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatElementsAlways { |
||||||
|
sectionType: SectionType.ElementsAlways; |
||||||
|
flags: MonoFormatSectionFlags; |
||||||
|
elements: MonoFormatElement[]; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatElementsTimespan { |
||||||
|
sectionType: SectionType.ElementsTimespan; |
||||||
|
flags: MonoFormatSectionFlags; |
||||||
|
startTimestamp: bigint; // POSIX seconds
|
||||||
|
endTimestamp: bigint; |
||||||
|
elements: MonoFormatElement[]; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MonoFormatCustomFont { |
||||||
|
sectionType: SectionType.CustomFont; |
||||||
|
/** Raw U8G2 font data (actual bytes, not padded). */ |
||||||
|
fontData: Uint8Array; |
||||||
|
} |
||||||
|
|
||||||
|
export type MonoFormatSection = |
||||||
|
| MonoFormatElementsAlways |
||||||
|
| MonoFormatElementsTimespan |
||||||
|
| MonoFormatCustomFont; |
||||||
|
|
||||||
|
/** Top-level MonoDisplayParser output. */ |
||||||
|
export interface MonoFormatFile { |
||||||
|
sections: MonoFormatSection[]; |
||||||
|
} |
||||||
Loading…
Reference in new issue