Skip to content

Commit 5e5e9f7

Browse files
committedApr 2, 2024·
Graphics: Fix wrapString when attempting to wrap text containing an image that's too large for the wrappable area (fix #2481)
1 parent bbd32bc commit 5e5e9f7

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed
 

‎ChangeLog

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
Bangle.js: 6x15 font tweaks for ISO8859-1
2121
Bangle.js2: Fix 'UNFINISHED STRING' error if non-UTF8 char within UTF8 start char range is at end of string
2222
Bangle.js2: Add Bangle.setOptions({lcdDoubleRefresh:true}) to pulse EXTCOMIN for LCD twice, avoiding contrast 'toggle' effect when viewing LCD off axis
23+
Graphics: Fix wrapString when attempting to wrap text containing an image that's too large for the wrappable area (fix #2481)
2324

2425
2v21 : nRF52: free up 800b more flash by removing vector table padding
2526
Throw Exception when a Promise tries to resolve with another Promise (#2450)

‎libs/graphics/jswrap_graphics.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ JsVar *jswrap_graphics_wrapString(JsVar *parent, JsVar *str, int maxWidth) {
24002400
This is all a bit of a mess but it appears to work as intended now. */
24012401
JsvStringIterator it;
24022402
jsvStringIteratorNewUTF8(&it, str, 0);
2403-
while (jsvStringIteratorHasChar(&it) || endOfText) {
2403+
while ((jsvStringIteratorHasChar(&it) || endOfText) && !jspIsInterrupted()) {
24042404
int ch = jsvStringIteratorGetUTF8CharAndNext(&it);
24052405
bool canBreakOnCh = endOfText || ch=='\n' || ch==' ';
24062406
if (canBreakOnCh || canSplitAfter) { // is breakable - newline,space,dash, image before
@@ -2429,6 +2429,15 @@ JsVar *jswrap_graphics_wrapString(JsVar *parent, JsVar *str, int maxWidth) {
24292429
jsvStringIteratorNew(&wordIt, str, wordStartIdx); // not UTF8 as wordStartIdx isn't UTF8 indexed
24302430
while (jsvStringIteratorGetIndex(&wordIt) < currentPos) {
24312431
int wordCh = jsvStringIteratorGetUTF8CharAndNext(&wordIt);
2432+
#ifndef SAVE_ON_FLASH
2433+
if (wordCh==0) { // it's an image, can't split it
2434+
jsvAppendStringVar(currentLine, str, (size_t)wordStartIdx, (size_t)(currentPos-(wordStartIdx+1)));
2435+
lineWidth += wordWidth;
2436+
wordWidth = 0;
2437+
wordStartIdx = currentPos-1;
2438+
break;
2439+
}
2440+
#endif
24322441
int w = _jswrap_graphics_getCharWidth(&info, wordCh);
24332442
if (width+w < maxWidth || !width) { // add while it fits OR it's the first character
24342443
// !width stops us locking up if char width>split width
@@ -2469,7 +2478,7 @@ JsVar *jswrap_graphics_wrapString(JsVar *parent, JsVar *str, int maxWidth) {
24692478
wordWidth = 0;
24702479
wordStartIdx = currentPos;
24712480
wasNewLine = ch=='\n';
2472-
canSplitAfter = false;
2481+
canSplitAfter = ch==0; // can split after if there is an image next
24732482
if (endOfText) break;
24742483
if (ch!=0) continue; // allow us to handle images next
24752484
}
@@ -2500,7 +2509,7 @@ JsVar *jswrap_graphics_wrapString(JsVar *parent, JsVar *str, int maxWidth) {
25002509
jsvArrayPush(lines, currentLine);
25012510
}
25022511
jsvUnLock2(str,currentLine);
2503-
_jswrap_graphics_freeFontInfo(&info);
2512+
_jswrap_graphics_freeFontInfo(&info);
25042513
return lines;
25052514
}
25062515

‎tests/test_graphics_wrapString.js

+9
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ g.clear().setFont("4x6");
107107
lines = g.wrapString("\0\x08\x08\1\1\2\3\4\5\6\7\8\0\x08\x08\1\1\2\3\4\5\6\7\8\0\x08\x08\1\1\2\3\4\5\6\7\8\0\x08\x08\1\1\2\3\4\5\6\7\8",12)
108108
SHOULD_BE(lines, ["\0\x08\x08\1\1\2\3\4\5\6\7\8","\0\x08\x08\1\1\2\3\4\5\6\7\8","\0\x08\x08\1\1\2\3\4\5\6\7\8","\0\x08\x08\1\1\2\3\4\5\6\7\8"]);
109109

110+
// 16*16px but wrapped to something smaller than the image width https://github.com/espruino/Espruino/issues/2481
111+
g.clear().setFont("4x6");
112+
let image = atob("ABAQAX/+gAGf+a/1t+273b29vn2+fb29u9237a/1n/mAAX/+");
113+
lines = g.wrapString(image+"ABC",8);
114+
SHOULD_BE(lines, ["\0\x10\x10\1\x7F\xFE\x80\1\x9F\xF9\xAF\xF5\xB7\xED\xBB\xDD\xBD\xBD\xBE}\xBE}\xBD\xBD\xBB\xDD\xB7\xED\xAF\xF5\x9F\xF9\x80\1\x7F\xFE","ABC"]);
115+
lines = g.wrapString("Test"+image,30);
116+
// This one is not ideal - we should really have wrapped Test+image after 'test' but we treat it as one word at the moment
117+
SHOULD_BE(lines, ["Test\0\x10\x10\1\x7F\xFE\x80\1\x9F\xF9\xAF\xF5\xB7\xED\xBB\xDD\xBD\xBD\xBE}\xBE}\xBD\xBD\xBB\xDD\xB7\xED\xAF\xF5\x9F\xF9\x80\1\x7F\xFE"]);
118+
110119
// UTF8 chars - no wrapping expected
111120
g.clear().setFont("4x6");
112121
lines = g.wrapString("F\u00F6n K\u00FCr B\u00E4r", 200);

0 commit comments

Comments
 (0)
Please sign in to comment.