Compare commits

..

13 Commits

Author SHA1 Message Date
Jake Kenneally
2f8a40d09c Merge branch 'master' into feature/add-epub-css-parsing
* master:
  fix: Correct `debugging_monitor.py` script instructions (#676)
  fix: Correct instruction text to match actual button text (#672)
  fix: Increase network SSID display length (#670)
2026-02-03 20:21:04 -05:00
Jake Kenneally
9e1356bb92 perf: skip CSS loading in Sleep and Home activities
Both activities only need book metadata (title, author) and cover image.
Pass skipLoadingCss=true to Epub::load() to avoid unnecessary CSS
parsing and caching operations.
2026-02-03 20:01:04 -05:00
Jake Kenneally
cd61b263e5 feat: integrate CSS rules caching in Epub loader
- Add cssFiles member to Epub class (moved from BookMetadataCache)
- Add getCssRulesCache() and loadCssRulesFromCache() methods
- Update parseCssFiles() to save parsed rules to cache
- Try loading from css_rules.cache before parsing CSS files
- Add skipLoadingCss parameter to Epub::load() for performance
- Remove cssFiles from BookMetadataCache (no longer needed)
- Revert BookMetadataCache version to 5 (pre-CSS-files format)

When loading an EPUB:
1. Try to load cached CSS rules first
2. If cache miss, parse CSS files and save to cache
3. If skipLoadingCss=true, skip CSS entirely (for cover display)
2026-02-03 20:01:04 -05:00
Jake Kenneally
6115bf3cd2 feat: add CSS rules caching to CssParser
Add saveToCache() and loadFromCache() methods to CssParser for persisting
parsed CSS rules to disk. The cache format includes:
- Version byte for cache invalidation
- Rule count
- For each rule: length-prefixed selector string + CssStyle fields

This allows skipping CSS file parsing on subsequent book opens by loading
pre-parsed rules from cache.
2026-02-03 20:01:04 -05:00
Jake Kenneally
a7ffc02c34 refactor: simplify CssParser margin/padding shorthand
Remove intermediary variables (top, right, bottom, left) in margin and
padding shorthand parsing. Directly assign to style fields and reference
previously assigned values for defaulting logic.

No functional change - purely code simplification.
2026-02-03 20:01:04 -05:00
Jake Kenneally
d564173949 refactor: merge TextBlock::Style into BlockStyle; use bitflag underlines
Major consolidation of styling infrastructure:

- Remove TextBlock::Style enum (JUSTIFIED, LEFT_ALIGN, etc.)
  Alignment is now stored in BlockStyle.alignment using CssTextAlign

- Remove wordUnderlines list from TextBlock and ParsedText
  Underline state is now encoded in EpdFontFamily::Style via UNDERLINE bitflag

- Use BlockStyle::fromCssStyle() and getCombinedBlockStyle() in parser
  Removes duplicated createBlockStyleFromCss() and mergeBlockStyles()

- Simplify text block rendering to check style bitflag for underlines

- Revert spurious spaces handling (isAttachingPunctuation logic)
  The actualGapCount approach had issues; using standard word gaps

This reduces code duplication and simplifies the style inheritance model.
2026-02-03 20:01:04 -05:00
Jake Kenneally
f0f6618246 feat: add BlockStyle conversion and combination methods
- Add alignment and textAlignDefined fields to BlockStyle
- Add getCombinedBlockStyle(child) for merging parent/child styles
- Add static fromCssStyle(cssStyle, emSize, paragraphAlignment) factory

These methods centralize the CSS→BlockStyle conversion logic (previously
duplicated in createBlockStyleFromCss) and provide a clean API for
handling nested block element style inheritance.
2026-02-03 20:00:54 -05:00
Jake Kenneally
0fa4bb4100 refactor: rename CssStyle properties to match CSS naming
- TextAlign enum → CssTextAlign (reordered to match settings: Justify=0, Left=1, Center=2, Right=3)
- alignment → textAlign
- indent → textIndent
- decoration → textDecoration
- Update CssPropertyFlags field names to match
- Remove TextAlign::None; default to CssTextAlign::Left

This aligns internal naming with actual CSS property names for clarity.
2026-02-03 20:00:54 -05:00
Jake Kenneally
53931b3693 feat: add UNDERLINE bitflag to EpdFontFamily::Style
Convert Style enum to true bitflags by adding UNDERLINE=4. Update getFont()
to use bitwise operations instead of equality checks, allowing styles like
BOLD|UNDERLINE to work correctly.

This is preparation for encoding underline state directly in the Style
rather than tracking it separately.
2026-02-03 19:39:58 -05:00
Jake Kenneally
9d58952ba7 refactor: rename getIndentWidth to getTextAdvanceX
The function measures the advance width of arbitrary text (specifically
em-space prefix), not just indentation. getTextAdvanceX better reflects
its actual purpose.
2026-02-03 19:39:25 -05:00
Jake Kenneally
78d6e5931c
fix: Correct debugging_monitor.py script instructions (#676)
Some checks are pending
CI / build (push) Waiting to run
## Summary

**What is the goal of this PR?**
- Minor correction to the `debugging_monitor.py` script instructions

**What changes are included?**
- `pyserial` should be installed, NOT `serial`, which is a [different
lib](https://pypi.org/project/serial/)
- Added macOS serial port

## Additional Context

- Just a minor docs update. I can confirm the debugging script is
working great on macOS

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< NO >**_
2026-02-04 00:33:20 +03:00
Luke Stein
dac11c3fdd
fix: Correct instruction text to match actual button text (#672)
## Summary

* Instruction text says "Press OK to scan again" but button label is
actually "Connect" (not OK)
* Corrects instruction text

---

### AI Usage

Did you use AI tools to help write this code? **No**
2026-02-04 00:32:52 +03:00
Aaron Cunliffe
d403044f76
fix: Increase network SSID display length (#670)
Some checks are pending
CI / build (push) Waiting to run
## Rationale 

I have 2 wifi access points with almost identical names, just one has
`_EXT` at the end of it. With the current display limit of 13 characters
before adding ellipsis, I can't tell which is which.

Before device screenshot with masked SSIDs:
<img
src="https://github.com/user-attachments/assets/3c5cbbaa-b2f6-412f-b5a8-6278963bd0f2"
width="300">


## Summary

Adjusted displayed length from 13 characters to 30 in the Wifi selection
screen - I've left some space for potential proportional font changes in
the future

After image with masked SSIDs:
<img
src="https://github.com/user-attachments/assets/c5f0712b-bbd3-4eec-9820-4693fae90c9f"
width="300">

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< NO >**_
2026-02-03 18:24:23 +03:00
2 changed files with 10 additions and 5 deletions

View File

@ -102,13 +102,18 @@ After flashing the new features, its recommended to capture detailed logs fro
First, make sure all required Python packages are installed:
```python
python3 -m pip install serial colorama matplotlib
python3 -m pip install pyserial colorama matplotlib
```
after that run the script:
```sh
# For Linux
# This was tested on Debian and should work on most Linux systems.
python3 scripts/debugging_monitor.py
# For macOS
python3 scripts/debugging_monitor.py /dev/cu.usbmodem2101
```
This was tested on Debian and should work on most Linux systems. Minor adjustments may be required for Windows or macOS.
Minor adjustments may be required for Windows.
## Internals

View File

@ -520,7 +520,7 @@ void WifiSelectionActivity::renderNetworkList() const {
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
const auto top = (pageHeight - height) / 2;
renderer.drawCenteredText(UI_10_FONT_ID, top, "No networks found");
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press OK to scan again");
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press Connect to scan again");
} else {
// Calculate how many networks we can display
constexpr int startY = 60;
@ -546,8 +546,8 @@ void WifiSelectionActivity::renderNetworkList() const {
// Draw network name (truncate if too long)
std::string displayName = network.ssid;
if (displayName.length() > 16) {
displayName.replace(13, displayName.length() - 13, "...");
if (displayName.length() > 33) {
displayName.replace(30, displayName.length() - 30, "...");
}
renderer.drawText(UI_10_FONT_ID, 20, networkY, displayName.c_str());