# DReader Application ## Project Status | Badge | Description | |-------|-------------| | ![Test Coverage](https://gitea.tourolle.paris/dtourolle/dreader-application/raw/branch/badges/cov_info/coverage.svg) | **Test Coverage** - Percentage of code covered by unit tests | | ![Documentation Coverage](https://gitea.tourolle.paris/dtourolle/dreader-application/raw/branch/badges/cov_info/coverage-docs.svg) | **Documentation Coverage** - Percentage of code with docstrings | | ![License](https://img.shields.io/badge/license-MIT-blue.svg) | **License** - Project licensing information | ## Description DReader Application is a complete, production-ready ebook reader built on [pyWebLayout](https://gitea.tourolle.paris/dtourolle/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 ```bash # 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:
Page Navigation
Page Navigation
Forward and backward navigation through pages
Font Size Adjustment
Font Size
Dynamic font size scaling with position preservation
Chapter Navigation
Chapter Navigation
Jump directly to chapters by title or index
Bookmarks & Positions
Bookmarks
Save and restore reading positions anywhere in the book
Text Highlighting
Highlighting
Highlight words and selections with custom colors and notes
TOC Overlay
TOC Overlay
Interactive table of contents with gesture-based navigation
## Quick Start ```python 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 ```python reader.load_epub("book.epub") reader.is_loaded() # Check if book loaded reader.get_book_info() # Get metadata (title, author, etc.) ``` ### Navigation ```python 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 ```python 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 ```python reader.save_position("my_bookmark") reader.load_position("my_bookmark") reader.list_saved_positions() reader.delete_position("my_bookmark") ``` ### Text Highlighting ```python 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 ```python 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 ```python 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 ```python 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/](examples/) directory for complete working examples: ### Basic Examples - **[simple_ereader_example.py](examples/simple_ereader_example.py)** - Basic ereader usage with EPUB loading and navigation - **[ereader_demo.py](examples/ereader_demo.py)** - Comprehensive demo showcasing all features - **[simple_word_highlight.py](examples/simple_word_highlight.py)** - Minimal highlighting example ### Text Highlighting - **[word_selection_highlighting.py](examples/word_selection_highlighting.py)** - Text selection and highlighting ### Overlays - **[demo_toc_overlay.py](examples/demo_toc_overlay.py)** - Interactive table of contents overlay - **[navigation_overlay_example.py](examples/navigation_overlay_example.py)** - Unified navigation overlay (TOC + Bookmarks) - **[demo_settings_overlay.py](examples/demo_settings_overlay.py)** - Settings panel with font/spacing controls ### Library & State - **[library_reading_integration.py](examples/library_reading_integration.py)** - Complete library → reading → resume workflow - **[persistent_settings_example.py](examples/persistent_settings_example.py)** - Save/restore settings across sessions ### Advanced - **[demo_pagination.py](examples/demo_pagination.py)** - Pagination system demonstration - **[generate_ereader_gifs.py](examples/generate_ereader_gifs.py)** - Generate animated GIF demonstrations - **[generate_library_demo_gif.py](examples/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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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](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](HARDWARE_SETUP.md) for complete wiring diagrams and setup instructions. ### HAL Architecture ```python 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](HARDWARE_PINOUT.md) for pin assignments and [GPIO_BUTTONS.md](GPIO_BUTTONS.md) for button configuration. ## Documentation - [README.md](README.md) - This file, main project documentation - [REQUIREMENTS.md](REQUIREMENTS.md) - Application requirements specification - [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture and design details - [HAL_IMPLEMENTATION_SPEC.md](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 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Make your changes with tests 4. Run tests and ensure coverage stays high 5. Format code with black 6. Submit a pull request ## License MIT License - see [LICENSE](LICENSE) file for details ## Author Duncan Tourolle - duncan@tourolle.paris ## Related Projects - [pyWebLayout](https://gitea.tourolle.paris/dtourolle/pyWebLayout) - The underlying layout engine library ## Acknowledgments Built with [pyWebLayout](https://gitea.tourolle.paris/dtourolle/pyWebLayout) - A powerful Python library for HTML-like layout and rendering.