14 KiB
EPUB Reader Architectural Decisions
Date: 2026-01-23 19:47:23
Status: Active
Based on: EPUB 3.3 Compliance Audit
Purpose
This document captures architectural decisions about which EPUB 3.3 features to implement, intentionally omit, or defer. Each decision includes rationale based on:
- Hardware constraints (ESP32-C3, 800x480 4-level grayscale e-ink)
- Memory limitations (~400KB SRAM, no PSRAM)
- User experience goals
- Implementation complexity
ADR-001: Inline Image Support
Status: RECOMMENDED FOR IMPLEMENTATION
Context
EPUBs frequently contain images for:
- Cover art
- Chapter illustrations
- Diagrams and figures
- Decorative elements
Current implementation displays [Image: alt_text] placeholder.
Decision
Implement inline image rendering using existing infrastructure.
Rationale
-
Infrastructure Exists:
Bitmapclass handles BMP parsing with grayscale conversion and ditheringJpegToBmpConverterconverts JPEG to BMP (most common EPUB image format)GfxRenderer::drawBitmap()already renders bitmaps to e-inkZipFilecan extract files from EPUB archive- Home screen cover rendering demonstrates the pattern works
-
Memory Management Pattern:
- Convert and cache images to SD card (like thumbnail generation)
- Load one image at a time during page render
- Use streaming conversion to minimize RAM usage
-
High User Impact:
- Many EPUBs contain important visual content
- Technical books rely on diagrams
- Children's books heavily use illustrations
Implementation Architecture
┌────────────────────────────────────────────────────────────────┐
│ Image Processing Pipeline │
├────────────────────────────────────────────────────────────────┤
│ │
│ EPUB ZIP ──► Extract Image ──► Convert to BMP ──► Cache to SD │
│ │ │ │
│ │ ├─ JPEG: JpegToBmpConverter│
│ │ └─ BMP: Direct copy │
│ │ │
│ └─► During page render: │
│ Load cached BMP ──► drawBitmap() │
│ │
└────────────────────────────────────────────────────────────────┘
Page Element Structure
// New PageImage element (alongside PageLine)
class PageImage final : public PageElement {
std::string cachedBmpPath; // Path to converted BMP on SD
int16_t width;
int16_t height;
public:
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override;
bool serialize(FsFile& file) override;
static std::unique_ptr<PageImage> deserialize(FsFile& file);
};
Constraints
- No PNG support initially (would require adding
pnglelibrary) - Maximum image size: Scale to viewport width, max 800x480
- Memory budget: ~10KB row buffer during conversion
ADR-002: JavaScript/Scripting Support
Status: INTENTIONALLY OMITTED
Context
EPUB 3.3 allows JavaScript in content documents for interactive features.
Decision
Do not implement JavaScript execution.
Rationale
-
Security Risk:
- Untrusted code execution on embedded device
- No sandboxing infrastructure
- Potential for malicious EPUBs
-
Hardware Limitations:
- E-ink display unsuitable for interactive content
- Limited RAM for JavaScript engine
- No benefit for static reading experience
-
Minimal EPUB Use:
- Most EPUBs don't use JavaScript
- Interactive textbooks target tablets, not e-readers
-
Implementation Complexity:
- Would require embedding V8/Duktape/QuickJS
- DOM manipulation engine
- Event handling system
Alternative
<script> elements are silently ignored. Content remains readable.
ADR-003: Fixed Layout (FXL) Support
Status: INTENTIONALLY OMITTED
Context
EPUB Fixed Layout provides pixel-precise page positioning for:
- Comic books
- Children's picture books
- Magazines
- Technical drawings with precise layout
Decision
Do not implement Fixed Layout support.
Rationale
-
Display Mismatch:
- FXL designed for high-resolution color tablets
- 800x480 grayscale e-ink would require heavy downscaling
- Visual quality would be poor
-
User Experience:
- FXL EPUBs expect pan/zoom interaction
- E-ink refresh rate makes this impractical
- Text would be too small to read without zoom
-
Implementation Complexity:
- Requires full CSS positioning engine
- Viewport meta tag handling
- Coordinate transformation system
Alternative
FXL EPUBs will open but may display incorrectly. Users should use reflowable EPUBs on this device.
ADR-004: Audio/Video and Media Overlays
Status: HARDWARE LIMITED - CANNOT IMPLEMENT
Context
EPUB 3.3 supports:
<audio>and<video>elements- Media Overlays (SMIL synchronization)
- Text-to-speech hints
Decision
Cannot implement due to hardware constraints.
Rationale
-
No Audio Hardware:
- Device has no speaker or audio DAC
- No audio output jack
-
No Video Capability:
- E-ink refresh rate (~1 Hz) incompatible with video
- No video decoding hardware
Alternative
- Audio/video elements are ignored
- Alt text or fallback content displayed if available
- Media Overlays not processed
ADR-005: Color CSS Properties
Status: HARDWARE LIMITED - SIMPLIFIED HANDLING
Context
EPUBs use CSS colors for:
- Text color (
color) - Background color (
background-color) - Border colors
Decision
Ignore color properties; display in grayscale.
Rationale
-
Hardware Constraint:
- Display is 4-level grayscale only
- Cannot render colors
-
Acceptable Degradation:
- Text remains readable in black
- Background remains white
- Colored elements appear as gray variations
Implementation
Color CSS properties are parsed but not applied. Default black text on white background used.
ADR-006: Table Rendering
Status: DEFERRED - OPTIONAL IMPLEMENTATION
Context
Tables appear in:
- Technical documentation
- Reference material
- Data presentations
Current implementation shows [Table omitted] placeholder.
Decision
Implement simple text-based table rendering as an optional enhancement.
Rationale
-
Moderate Impact:
- Some EPUBs use tables, but not majority
- Technical users would benefit most
-
Complexity vs. Benefit:
- Full table layout is complex (colspan, rowspan, sizing)
- Simple tables can be rendered as text columns
Implementation Approach (if implemented)
┌──────────────────────────────────────┐
│ Text-Based Table Rendering │
├──────────────────────────────────────┤
│ │
│ Header1 │ Header2 │ Header3 │
│ ─────────────────────────────────────│
│ Data 1 │ Data 2 │ Data 3 │
│ Data 4 │ Data 5 │ Data 6 │
│ │
└──────────────────────────────────────┘
Constraints
- Equal-width columns (no complex sizing)
- No colspan/rowspan support
- Truncate wide content
- Maximum 4-5 columns before overflow
ADR-007: SVG and MathML
Status: INTENTIONALLY OMITTED
Context
- SVG: Scalable Vector Graphics for illustrations
- MathML: Mathematical notation markup
Decision
Do not implement SVG or MathML rendering.
Rationale
-
Implementation Complexity:
- SVG requires full vector graphics engine
- MathML requires specialized math typesetting
-
Limited Use:
- Most EPUBs use raster images, not SVG
- MathML primarily in academic texts
-
Alternative Exists:
- Many EPUBs include fallback PNG for SVG
- MathML often has image fallback
Alternative
Display alt text or fallback image if available.
ADR-008: CSS Selector Support
Status: CURRENT IMPLEMENTATION SUFFICIENT
Context
CSS selectors enable targeting elements for styling. Current support:
- Element selectors (
p,div) - Class selectors (
.classname) - Element.class selectors (
p.intro)
Decision
Maintain current limited selector support; do not expand.
Rationale
-
Sufficient for Most EPUBs:
- 90%+ of EPUB styling uses simple selectors
- Complex selectors rarely affect core readability
-
Implementation Complexity:
- Descendant selectors require DOM tree
- Pseudo-selectors need state tracking
- Specificity calculation is complex
-
Memory Constraints:
- DOM tree would consume significant RAM
- Current streaming parser is memory-efficient
Not Implemented
- Descendant selectors (
div p) - Child selectors (
ul > li) - Sibling selectors (
h1 + p) - Pseudo-classes (
:first-child,:hover) - Pseudo-elements (
::before,::after) - Attribute selectors (
[type="text"])
ADR-009: Internal Link Navigation
Status: RECOMMENDED FOR IMPLEMENTATION (PHASE 2)
Context
EPUBs use internal links for:
- Footnotes
- Cross-references
- Table of contents
- Index entries
Decision
Implement internal link navigation in Phase 2.
Rationale
-
User Value:
- Footnotes are common in non-fiction
- Reference navigation improves usability
-
Complexity:
- Requires anchor parsing and storage
- Needs selection UI for link activation
- Cross-chapter navigation adds complexity
Implementation Architecture
Link Navigation Flow:
1. Parse <a href="#id"> during HTML parsing
2. Store link targets in PageLine metadata
3. Add link highlighting (underline or marker)
4. User selects link via UI
5. Resolve target: same chapter (anchor) or cross-chapter (spine + anchor)
6. Navigate to target page/position
Deferred
- External links (http://) - no network navigation on e-reader
ADR-010: DRM and Encryption
Status: INTENTIONALLY OMITTED
Context
EPUB supports DRM through:
encryption.xmlin META-INF- Adobe DRM
- Various proprietary schemes
Decision
Do not implement DRM support.
Rationale
-
Licensing Complexity:
- Adobe DRM requires licensing agreements
- Proprietary schemes have legal restrictions
-
User Expectation:
- Open-source e-reader users expect DRM-free content
- DRM conflicts with device modification philosophy
-
Implementation Complexity:
- Each DRM scheme is different
- Secure key storage required
- Regular updates needed for scheme changes
Alternative
Users should remove DRM from purchased content using legal tools before loading to device.
ADR-011: List Rendering Enhancements
Status: RECOMMENDED FOR IMPLEMENTATION (PHASE 1)
Context
Current implementation:
<li>renders bullet character•- No numbered list support
- No nesting indentation
Decision
Enhance list rendering with ordered numbers and nesting.
Rationale
-
Low Complexity:
- Track list type (
<ol>vs<ul>) in parser state - Maintain counter for ordered lists
- Apply indentation based on nesting depth
- Track list type (
-
Clear User Benefit:
- Numbered lists convey sequence
- Indentation shows hierarchy
Implementation
// Parser state additions
int listDepth = 0;
int orderedListCounter = 0;
bool isOrderedList = false;
// On <ol> start
isOrderedList = true;
orderedListCounter = 1;
listDepth++;
// On <li> in ordered list
addWord(std::to_string(orderedListCounter++) + ".", REGULAR);
// Apply indent
textIndent = listDepth * 20; // pixels per level
Summary Table
| Feature | Decision | Rationale |
|---|---|---|
| Inline Images | IMPLEMENT | High impact, infrastructure ready |
| JavaScript | OMIT | Security risk, no benefit for e-ink |
| Fixed Layout | OMIT | Display mismatch, poor UX |
| Audio/Video | CANNOT | No hardware support |
| Color CSS | IGNORE | Grayscale display |
| Tables | DEFER | Moderate impact, high complexity |
| SVG/MathML | OMIT | High complexity, limited use |
| Complex CSS Selectors | OMIT | Memory constraints, limited benefit |
| Internal Links | IMPLEMENT (Phase 2) | User value for references |
| DRM | OMIT | Licensing, philosophy conflict |
| List Enhancements | IMPLEMENT (Phase 1) | Low complexity, clear benefit |
Implementation Priority
Phase 1 (Quick Wins)
- Basic bullet rendering (already implemented)
- Ordered list numbering
- Nested list indentation
- Line-height CSS support
Phase 2 (Image Support)
- Image extraction from EPUB
- JPEG to BMP conversion for inline images
- PageImage element integration
- Image scaling and layout
Phase 3 (Navigation)
- Internal link parsing
- Link selection UI
- Anchor navigation
Deferred/Not Planned
- PNG support (would need library addition)
- Table rendering
- Complex CSS selectors
- JavaScript, FXL, DRM