diff --git a/apps.json b/apps.json index f7bec7695..d16213364 100644 --- a/apps.json +++ b/apps.json @@ -4,7 +4,7 @@ "tags": "tool,system,b2", "type":"bootloader", "icon": "bootloader.png", - "version":"0.30", + "version":"0.31", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "storage": [ {"name":".boot0","url":"boot0.js"}, diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 7f2220572..6cdf1b0e5 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -30,3 +30,4 @@ 0.29: Update boot0 to avoid code block (faster execution) Fix issues where 'Uncaught Error: Function not found' could happen with multiple .boot.js 0.30: Remove 'Get GPS time' at boot. Latest firmwares keep time through reboots, so this is not needed now +0.31: Add polyfills for g.wrapString, g.imageMetrics, g.stringMetrics diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index 199bff6e3..7210ae731 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -131,6 +131,41 @@ else if (mode=="updown") { throw new Error("Unknown UI mode"); };\n`; } +if (!g.imageMetrics) { // added in 2v11 - this is a limited functionality polyfill + boot += `Graphics.prototype.imageMetrics=function(src) { + if (src[0]) return {width:src[0],height:src[1]}; + else if ('object'==typeof src) return { + width:("width" in src) ? src.width : src.getWidth(), + height:("height" in src) ? src.height : src.getHeight()}; + var im = E.toString(src); + return {width:im.charCodeAt(0), height:im.charCodeAt(1)}; +};\n`; +} +if (!g.stringMetrics) { // added in 2v11 - this is a limited functionality polyfill + boot += `Graphics.prototype.stringMetrics=function(txt) { + return {width:this.stringWidth(txt), height:this.getFontHeight()}; +};\n`; +} +if (!g.wrapString) { // added in 2v11 - this is a limited functionality polyfill + boot += `Graphics.prototype.wrapString=function(str, maxWidth) { + var lines = []; + for (var unwrappedLine of str.split("\n")) { + var words = unwrappedLine.split(" "); + var line = words.shift(); + for (var word of words) { + if (g.stringWidth(line + " " + word) > maxWidth) { + lines.push(line); + line = word; + } else { + line += " " + word; + } + } + lines.push(line); + } + return lines; +};\n`; +} + // Append *.boot.js files require('Storage').list(/\.boot\.js/).forEach(bootFile=>{ // we add a semicolon so if the file is wrapped in (function(){ ... }() diff --git a/modules/Layout.js b/modules/Layout.js index 94abd42fd..99ce9b042 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -190,24 +190,6 @@ Layout.prototype.remove = function (l) { } }; -function wrappedLines(str, maxWidth) { - var lines = []; - for (var unwrappedLine of str.split("\n")) { - var words = unwrappedLine.split(" "); - var line = words.shift(); - for (var word of words) { - if (g.stringWidth(line + " " + word) > maxWidth) { - lines.push(line); - line = word; - } else { - line += " " + word; - } - } - lines.push(line); - } - return lines; -} - function prepareLazyRender(l, rectsToClear, drawList, rects, parentBg) { var bgCol = l.bgCol == null ? parentBg : g.toColor(l.bgCol); if (bgCol != parentBg || l.type == "txt" || l.type == "btn" || l.type == "img" || l.type == "custom") { @@ -246,8 +228,9 @@ Layout.prototype.render = function (l) { "txt":function(l){ if (l.wrap) { g.setFont(l.font,l.fsz).setFontAlign(0,-1); - var lines = wrappedLines(l.label, l.w); + var lines = g.wrapString(l.label, l.w); var y = l.y+((l.h-g.getFontHeight()*lines.length)>>1); + // TODO: on 2v11 we can just render in a single drawString call lines.forEach((line, i) => g.drawString(line, l.x+(l.w>>1), y+g.getFontHeight()*i)); } else { g.setFont(l.font,l.fsz).setFontAlign(0,0,l.r).drawString(l.label, l.x+(l.w>>1), l.y+(l.h>>1)); @@ -377,26 +360,16 @@ Layout.prototype.update = function() { if (l.wrap) { l._h = l._w = 0; } else { - g.setFont(l.font,l.fsz); - l._h = g.getFontHeight(); - l._w = g.stringWidth(l.label); + var m = g.setFont(l.font,l.fsz).stringMetrics(l.label); + l._w = m.width; l._h = m.height; } }, "btn": function(l) { l._h = 32; l._w = 20 + l.label.length*12; }, "img": function(l) { - var src = l.src(); // get width and height out of image - if (src[0]) { - l._w = src[0]; - l._h = src[1]; - } else if ('object'==typeof src) { - l._w = ("width" in src) ? src.width : src.getWidth(); - l._h = ("height" in src) ? src.height : src.getHeight(); - } else { - var im = E.toString(src); - l._w = im.charCodeAt(0); - l._h = im.charCodeAt(1); - } + var m = g.imageMetrics(l.src()); // get width and height out of image + l._w = m.width; + l._h = m.height; }, "": function(l) { // size should already be set up in width/height l._w = 0; diff --git a/tests/Layout/bin/espruino b/tests/Layout/bin/espruino index 3a423c185..8f9c1d878 100755 Binary files a/tests/Layout/bin/espruino and b/tests/Layout/bin/espruino differ