diff --git a/lib/Epub/Epub/hyphenation/Hyphenator.cpp b/lib/Epub/Epub/hyphenation/Hyphenator.cpp index 9d3d12d2..4ae5307e 100644 --- a/lib/Epub/Epub/hyphenation/Hyphenator.cpp +++ b/lib/Epub/Epub/hyphenation/Hyphenator.cpp @@ -123,7 +123,7 @@ void appendApostropheContractionBreaks(const std::vector& cps, } } - // Avoid stranding short clitics like "l'"/"d'" or tiny suffixes like "'t"/"'re"/"'ve"/"'ll". + // Avoid stranding short clitics like "l'"/"d'" or contraction tails like "'ve"/"'re"/"'ll". if (leftPrefixLen >= kMinLeftSegmentLen && rightSuffixLen >= kMinRightSegmentLen) { outBreaks.push_back({cps[i + 1].byteOffset, false}); } diff --git a/lib/Epub/Epub/hyphenation/Hyphenator.h b/lib/Epub/Epub/hyphenation/Hyphenator.h index 74886ba6..931695f9 100644 --- a/lib/Epub/Epub/hyphenation/Hyphenator.h +++ b/lib/Epub/Epub/hyphenation/Hyphenator.h @@ -26,8 +26,8 @@ class Hyphenator { // 2. Apostrophe contractions between letters (e.g. all'improvviso). // Liang patterns are run per alphabetic segment around apostrophes. // A direct break at the apostrophe boundary is allowed only when the left - // segment has at least 3 letters and the right segment has at least 2 letters, - // avoiding short clitics (e.g. l', d') and short contraction tails (e.g. can't). + // segment has at least 3 letters and the right segment has at least 3 letters, + // avoiding short clitics (e.g. l', d') and contraction tails (e.g. 've, 're, 'll). // 3. Language-specific Liang patterns (e.g. German de_patterns). // Example: "Quadratkilometer" -> Qua|drat|ki|lo|me|ter. // 4. Fallback every-N-chars splitting (only when includeFallback is true AND no diff --git a/lib/hal/HalGPIO.h b/lib/hal/HalGPIO.h index 45ca50a5..09e1fa52 100644 --- a/lib/hal/HalGPIO.h +++ b/lib/hal/HalGPIO.h @@ -54,3 +54,5 @@ class HalGPIO { static constexpr uint8_t BTN_DOWN = 5; static constexpr uint8_t BTN_POWER = 6; }; + +extern HalGPIO gpio; // Singleton diff --git a/src/components/themes/BaseTheme.cpp b/src/components/themes/BaseTheme.cpp index f94cba1f..fc0a0156 100644 --- a/src/components/themes/BaseTheme.cpp +++ b/src/components/themes/BaseTheme.cpp @@ -34,13 +34,36 @@ void drawBatteryIcon(const GfxRenderer& renderer, int x, int y, int battWidth, i renderer.drawPixel(x + battWidth - 1, y + rectHeight - 4); renderer.drawLine(x + battWidth - 0, y + 4, x + battWidth - 0, y + rectHeight - 5); + const bool charging = gpio.isUsbConnected(); + // The +1 is to round up, so that we always fill at least one pixel - int filledWidth = percentage * (battWidth - 5) / 100 + 1; - if (filledWidth > battWidth - 5) { - filledWidth = battWidth - 5; // Ensure we don't overflow + constexpr int maxFillWidth = battWidth - 5; + int filledWidth = percentage * maxFillWidth / 100 + 1; + if (filledWidth > maxFillWidth) { + filledWidth = maxFillWidth; + } + + // When charging, ensure minimum fill so lightning bolt is fully visible + constexpr int minFillForBolt = 8; + if (charging && filledWidth < minFillForBolt) { + filledWidth = minFillForBolt; } renderer.fillRect(x + 2, y + 2, filledWidth, rectHeight - 4); + + // Draw lightning bolt when charging (white/inverted on black fill for visibility) + if (charging) { + const int boltX = x + 4; + const int boltY = y + 2; + renderer.drawLine(boltX + 4, boltY + 0, boltX + 5, boltY + 0, false); + renderer.drawLine(boltX + 3, boltY + 1, boltX + 4, boltY + 1, false); + renderer.drawLine(boltX + 2, boltY + 2, boltX + 5, boltY + 2, false); + renderer.drawLine(boltX + 3, boltY + 3, boltX + 4, boltY + 3, false); + renderer.drawLine(boltX + 2, boltY + 4, boltX + 3, boltY + 4, false); + renderer.drawLine(boltX + 1, boltY + 5, boltX + 4, boltY + 5, false); + renderer.drawLine(boltX + 2, boltY + 6, boltX + 3, boltY + 6, false); + renderer.drawLine(boltX + 1, boltY + 7, boltX + 2, boltY + 7, false); + } } } // namespace