DReader Application
Project Status
| Badge | Description |
|---|---|
| Test Coverage - Percentage of code covered by unit tests | |
| Documentation Coverage - Percentage of code with docstrings | |
| License - Project licensing information |
Description
DReader Application is a complete, production-ready ebook reader built on pyWebLayout. It demonstrates how to build a full-featured ebook reader with library browsing, text highlighting, bookmarks, gesture support, overlays, and position persistence.
This project serves as both a reference implementation and a ready-to-use ereader library for building desktop, web-based, or embedded reading applications.
Key Features
Core Reading Features
- 📖 EPUB Support - Load and render EPUB files with full text extraction
- 📚 Library Management - Browse and select books from your collection
- 📄 Page Rendering - Render pages as PIL Images optimized for any display
- ⬅️➡️ Navigation - Smooth forward and backward page navigation
- 🔖 Bookmarks - Save and restore reading positions with persistence
- 📑 Chapter Navigation - Jump to chapters by title or index via TOC
- 📋 Unified Overlays - Navigation (TOC + Bookmarks) and Settings overlays
- 📊 Progress Tracking - Real-time reading progress percentage
Text Interaction
- 🎨 Text Highlighting - Highlight words and text selections with custom colors
- 💡 Highlight Notes - Attach notes and annotations to highlights
- 🔍 Text Selection - Select words or ranges via pixel coordinates
- 👆 Gesture Support - Handle tap, swipe, pinch, long-press events
- 🎯 Pixel Queries - Query text content at any screen position
Customization & Display
- 🔤 Font Control - Dynamically adjust font size with live preview
- 📏 Spacing Control - Customize line and paragraph spacing
- 💾 Position Persistence - Stable positions across style changes
- ⚡ Smart Reflow - Automatic text reflow on font/spacing changes
- 🎨 Custom Styling - Full control over colors, fonts, and layout
- 💾 Settings Persistence - Save and restore preferences across sessions
Installation
# Clone the repository
git clone https://gitea.tourolle.paris/dtourolle/dreader-application.git
cd dreader-application
# Install in development mode
pip install -e .
# Or install with dev dependencies
pip install -e ".[dev]"
The pyWebLayout dependency will be automatically installed from the git repository.
DReader in Action
Here are animated demonstrations of the key features:
Quick Start
from dreader.application import EbookReader
# Create an ebook reader
with EbookReader(page_size=(800, 1000)) as reader:
# Load an EPUB file
reader.load_epub("mybook.epub")
# Get current page as PIL Image
page = reader.get_current_page()
page.save("page_001.png")
# Navigate through pages
reader.next_page()
reader.previous_page()
# Save reading position
reader.save_position("chapter_3")
# Jump to a chapter
reader.jump_to_chapter("Chapter 5")
# Adjust font size
reader.increase_font_size()
# Highlight text at coordinates
highlight_id = reader.highlight_word(x=200, y=300, note="Important!")
# Get progress
progress = reader.get_reading_progress()
print(f"Progress: {progress*100:.1f}%")
API Overview
Loading Content
reader.load_epub("book.epub")
reader.is_loaded() # Check if book loaded
reader.get_book_info() # Get metadata (title, author, etc.)
Navigation
reader.next_page()
reader.previous_page()
reader.jump_to_chapter("Chapter 1") # By title
reader.jump_to_chapter(0) # By index
reader.get_chapters() # List all chapters
reader.get_current_chapter_info()
reader.get_reading_progress() # Returns 0.0 to 1.0
# Navigation Overlay (unified TOC + Bookmarks)
overlay_image = reader.open_navigation_overlay() # Opens with tabs
reader.close_overlay()
reader.is_overlay_open()
Styling & Display
reader.increase_font_size()
reader.decrease_font_size()
reader.set_font_size(1.5) # 150% scale
reader.get_font_size()
reader.set_line_spacing(8)
reader.set_inter_block_spacing(20)
Bookmarks & Position Management
reader.save_position("my_bookmark")
reader.load_position("my_bookmark")
reader.list_saved_positions()
reader.delete_position("my_bookmark")
Text Highlighting
from pyWebLayout.core.highlight import HighlightColor
# Highlight a word at pixel coordinates
highlight_id = reader.highlight_word(
x=100,
y=200,
color=HighlightColor.YELLOW,
note="Important concept!"
)
# Highlight a text selection
highlight_id = reader.highlight_selection(
start=(100, 200),
end=(300, 250),
color=(255, 255, 0, 128) # RGBA
)
# Query word at position
result = reader.query_pixel(x=200, y=300)
if result:
print(f"Word: {result.word.text}")
# Manage highlights
highlights = reader.list_highlights()
reader.remove_highlight(highlight_id)
reader.clear_highlights()
reader.get_highlights_for_current_page()
Gesture Handling
from dreader.gesture import TouchEvent, GestureType, ActionType
# Handle touch input
event = TouchEvent(GestureType.TAP, x=400, y=300)
response = reader.handle_touch(event)
# Response contains action type and data
if response.action == ActionType.PAGE_TURN:
print(f"Page turned: {response.data['direction']}")
elif response.action == ActionType.WORD_SELECTED:
print(f"Word selected: {response.data['word']}")
elif response.action == ActionType.CHAPTER_SELECTED:
print(f"Chapter selected: {response.data['chapter_title']}")
# Supported gestures:
# - TAP: Select words, activate links, navigate TOC
# - LONG_PRESS: Show definitions or context menu
# - SWIPE_LEFT/RIGHT: Page navigation
# - SWIPE_UP: Open navigation overlay (from bottom 20% of screen)
# - SWIPE_DOWN: Close overlay or open settings (from top 20%)
# - PINCH_IN/OUT: Font size adjustment
# - DRAG: Text selection
Settings Persistence
from dreader.state import StateManager
from pathlib import Path
# Initialize state manager
state_file = Path.home() / ".config" / "dreader" / "state.json"
state_manager = StateManager(state_file=state_file)
# Load saved state
state = state_manager.load_state()
# Create reader and apply saved settings
reader = EbookReader(page_size=(800, 1000))
reader.load_epub("mybook.epub")
reader.apply_settings(state.settings.to_dict())
# Settings are automatically saved
reader.increase_font_size()
state_manager.update_settings(reader.get_current_settings())
state_manager.save_state()
Library Management
from dreader.library import LibraryManager
# Initialize library
library = LibraryManager(
library_path="/path/to/books",
page_size=(800, 1200)
)
# Scan for EPUB files
library.scan_library()
# Render library view
library_image = library.render_library()
# Handle book selection
book_path = library.handle_library_tap(x=400, y=300)
if book_path:
reader.load_epub(book_path)
Examples
Check out the examples/ directory for complete working examples:
Basic Examples
- simple_ereader_example.py - Basic ereader usage with EPUB loading and navigation
- ereader_demo.py - Comprehensive demo showcasing all features
- simple_word_highlight.py - Minimal highlighting example
Text Highlighting
- word_selection_highlighting.py - Text selection and highlighting
Overlays
- demo_toc_overlay.py - Interactive table of contents overlay
- navigation_overlay_example.py - Unified navigation overlay (TOC + Bookmarks)
- demo_settings_overlay.py - Settings panel with font/spacing controls
Library & State
- library_reading_integration.py - Complete library → reading → resume workflow
- persistent_settings_example.py - Save/restore settings across sessions
Advanced
- demo_pagination.py - Pagination system demonstration
- generate_ereader_gifs.py - Generate animated GIF demonstrations
- generate_library_demo_gif.py - Generate library demo animations
Architecture
DReader Application is a high-level application layer that combines pyWebLayout's low-level components:
dreader.application.EbookReader (High-Level API)
↓
├── pyWebLayout.layout.EreaderLayoutManager # Layout engine & pagination
├── pyWebLayout.layout.EreaderLayout # Bidirectional layout
├── pyWebLayout.core.HighlightManager # Highlighting system
├── pyWebLayout.io.gesture # Touch/gesture handling
└── pyWebLayout.io.readers.epub_reader # EPUB parsing
Component Structure
dreader/
├── application.py # Main EbookReader class (coordinator)
├── managers/ # Specialized management modules
│ ├── document.py # Document loading (EPUB/HTML)
│ ├── settings.py # Font and spacing controls
│ └── highlight_coordinator.py # Text highlighting
├── handlers/
│ └── gestures.py # Touch event routing
├── overlays/ # UI overlay system
│ ├── base.py # Base overlay functionality
│ ├── navigation.py # TOC and bookmarks overlay
│ └── settings.py # Settings overlay
├── library.py # Library browsing and book selection
├── state.py # Application state persistence
├── html_generator.py # HTML generation for overlays
└── gesture.py # Gesture definitions and responses
Relationship to pyWebLayout
pyWebLayout is a layout engine library providing low-level primitives:
- Text rendering and layout algorithms
- Document structure and pagination
- Query systems for interactive content
- Core rendering infrastructure
DReader Application is an application framework that:
- Combines pyWebLayout components into a complete reader
- Provides user-friendly APIs for common ereader tasks
- Manages application state (bookmarks, highlights, positions)
- Handles business logic for gestures and interactions
Think of it like this:
- pyWebLayout = React (library)
- DReader Application = Next.js (framework)
State Management
File Structure
~/.config/dreader/
├── state.json # Application state
├── covers/ # Cached book covers
├── bookmarks/ # Per-book bookmarks
├── highlights/ # Per-book highlights
└── xray/ # X-Ray data (future)
State Persistence
- Auto-save: Every 60 seconds
- Immediate save: On mode change, settings change, shutdown
- Boot behavior: Resume last book at last position or show library
- Error handling: Fall back to library if book missing or state corrupt
Position Stability
- Positions stored by abstract document structure (chapter/block/word indices)
- Stable across font size changes, spacing changes, page size changes
- Per-book storage using document IDs
- Special
__auto_resume__bookmark for last reading position
Use Cases
- 📱 Desktop Ereader Applications - Build native ereader apps with Python
- 🌐 Web-based Readers - Serve rendered pages via Flask/FastAPI
- 📟 E-ink Device Firmware - Optimized rendering for e-ink displays
- 📊 Reading Analytics - Track reading patterns, highlights, and engagement
- 🎓 Educational Tools - Create annotated reading experiences with highlights and notes
- 🔬 Research Applications - Build specialized reading tools for academic work
Development
# Install in development mode with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=dreader --cov-report=html
# Format code
black dreader/ tests/
# Type checking
mypy dreader/
# Linting
flake8 dreader/ tests/
Running Examples
# Ensure you have an EPUB file for testing
cd examples
# Run simple example
python simple_ereader_example.py /path/to/book.epub
# Run comprehensive demo
python ereader_demo.py /path/to/book.epub
# Run library integration demo
python library_reading_integration.py /path/to/library/
# Generate animated GIFs
python generate_ereader_gifs.py /path/to/book.epub
Testing
The project includes comprehensive tests covering:
- Application API - All EbookReader methods and workflows
- System Integration - Layout manager, bookmarks, and state management
- Highlighting - Word and selection highlighting with persistence
- Overlays - Navigation and settings overlay interactions
- Gestures - Touch event handling and routing
- Boot Recovery - State persistence and position restoration
- Library - Book scanning, selection, and metadata
- Edge Cases - Error handling, boundary conditions, and recovery
# Run all tests
pytest
# Run specific test file
pytest tests/test_ereader_application.py
# Run with verbose output
pytest -v
# Run with coverage report
pytest --cov=dreader --cov-report=term-missing
Hardware Integration
DReader includes complete hardware support for e-ink displays via the dreader-hal library.
Supported Hardware
- Display: IT8951 e-ink controller (1872×1404)
- Touch: FT5316 capacitive touch panel
- Buttons: GPIO buttons (configurable)
- Sensors: BMA400 accelerometer, PCF8523 RTC, INA219 power monitor
Quick Setup on Raspberry Pi
# 1. Clone and install
git clone https://gitea.tourolle.paris/dtourolle/dreader-application.git
cd dreader-application
python3 -m venv venv
source venv/bin/activate
pip install -e .
./install_hardware_drivers.sh
# 2. Interactive hardware setup
sudo python3 setup_rpi.py
# 3. Run on hardware
python examples/run_on_hardware_config.py
Hardware Configuration
The repository includes a pre-configured hardware_config.json for the reference hardware:
- Buttons: GPIO 22 (prev), GPIO 27 (next), GPIO 21 (power)
- Display: 1872×1404 IT8951 e-ink
- I2C Bus: GPIO 2/3 (touch, sensors, RTC, power)
See HARDWARE_SETUP.md for complete wiring diagrams and setup instructions.
HAL Architecture
from dreader.hal_hardware import HardwareDisplayHAL
from dreader.main import DReaderApplication, AppConfig
# Hardware HAL with GPIO buttons
hal = HardwareDisplayHAL(width=1872, height=1404, vcom=-2.0)
config = AppConfig(display_hal=hal, library_path="~/Books")
app = DReaderApplication(config)
Available HAL Implementations:
- HardwareDisplayHAL - Real e-ink hardware (IT8951 + dreader-hal)
- PygameDisplayHAL - Desktop testing with pygame window
See HARDWARE_PINOUT.md for pin assignments and GPIO_BUTTONS.md for button configuration.
Documentation
- README.md - This file, main project documentation
- REQUIREMENTS.md - Application requirements specification
- ARCHITECTURE.md - System architecture and design details
- HAL_IMPLEMENTATION_SPEC.md - Hardware integration guide
Performance
- Boot Time: ~2-3 seconds to resume reading
- Page Turn: ~50-100ms (depends on page complexity)
- Overlay Open: ~200-250ms (includes HTML generation and rendering)
- Memory Usage: ~20-30MB base + 10-50MB per book
- Cache: Automatic cover image and metadata caching for fast library loading
Contributing
Contributions welcome! This project demonstrates what's possible with pyWebLayout. If you build something cool or find ways to improve the reader, please share!
How to Contribute
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Run tests and ensure coverage stays high
- Format code with black
- Submit a pull request
License
MIT License - see LICENSE file for details
Author
Duncan Tourolle - duncan@tourolle.paris
Related Projects
- pyWebLayout - The underlying layout engine library
Acknowledgments
Built with pyWebLayout - A powerful Python library for HTML-like layout and rendering.





