Skip to content

Commit

Permalink
Support for international fonts, and rendering UTF8 characters that c…
Browse files Browse the repository at this point in the history
…ome from iOS direct in the messages app
  • Loading branch information
gfwilliams committed Mar 15, 2024
1 parent ee0b0f2 commit 591c1f8
Show file tree
Hide file tree
Showing 28 changed files with 264 additions and 74 deletions.
40 changes: 32 additions & 8 deletions README.md
Expand Up @@ -251,7 +251,7 @@ and which gives information about the app for the Launcher.
"description": "...", // long description (can contain markdown)
"icon": "icon.png", // icon in apps/
"screenshots" : [ { "url":"screenshot.png" } ], // optional screenshot for app
"type":"...", // optional(if app) -
"type":"...", // optional(if app) -
// 'app' - an application
// 'clock' - a clock - required for clocks to automatically start
// 'widget' - a widget
Expand Down Expand Up @@ -300,7 +300,7 @@ and which gives information about the app for the Launcher.
"customConnect": true, // if supplied, ensure we are connected to a device
// before the "custom.html" iframe is loaded. An
// onInit function in "custom.html" is then called
// with info on the currently connected device.
// with info on the currently connected device.
"interface": "interface.html", // if supplied, apps/interface.html is loaded in an
// iframe, and it may interact with the connected Bangle
Expand Down Expand Up @@ -328,9 +328,9 @@ and which gives information about the app for the Launcher.
{"name":"appid.data.json", // filename used in storage
"storageFile":true // if supplied, file is treated as storageFile
"url":"", // if supplied URL of file to load (currently relative to apps/)
"content":"...", // if supplied, this content is loaded directly
"content":"...", // if supplied, this content is loaded directly
"evaluate":true, // if supplied, data isn't quoted into a String before upload
// (eg it's evaluated as JS)
// (eg it's evaluated as JS)
},
{"wildcard":"appid.data.*" // wildcard of filenames used in storage
}, // this is mutually exclusive with using "name"
Expand Down Expand Up @@ -424,9 +424,9 @@ See [apps/gpsrec/interface.html](the GPS Recorder) for a full example.

### Adding configuration to the "Settings" menu

Apps (or widgets) can add their own settings to the "Settings" menu under "App/widget settings".
Apps (or widgets) can add their own settings to the "Settings" menu under "App/widget settings".
To do so, the app needs to include a `settings.js` file, containing a single function
that handles configuring the app.
that handles configuring the app.
When the app settings are opened, this function is called with one
argument, `back`: a callback to return to the settings menu.

Expand All @@ -449,12 +449,12 @@ Example `settings.js`
'Monkeys': {
value: settings.monkeys,
onchange: (m) => {save('monkeys', m)}
}
}
};
E.showMenu(appMenu)
})
```
In this example the app needs to add `myappid.settings.js` to `storage` in `metadata.json`.
In this example the app needs to add `myappid.settings.js` to `storage` in `metadata.json`.
It should also add `myappid.json` to `data`, to make sure it is cleaned up when the app is uninstalled.
```json
{ "id": "myappid",
Expand Down Expand Up @@ -554,6 +554,30 @@ You can use `g.setColor(r,g,b)` OR `g.setColor(16bitnumber)` - some common 16 bi
| GreenYellow | 0xAFE5 |
| Pink | 0xF81F |

## Fonts

A recent addition to Bangle.js is the ability to use extra fonts with support for more characters.
For example [all regions](https://banglejs.com/apps/?id=fontall) or [extended](https://banglejs.com/apps/?id=fontext) fonts.

Once installed, these apps cause a new font, `Intl` to be added to `Graphics`, which can be used with just `g.setFont("Intl")`.

There is also a `font` library - this is not implemented yet, but more information about the planned implementation
is available at https://github.com/espruino/BangleApps/issues/3109

For now, to make your app work with the international font, you can check if `Graphics.prototype.setFontIntl` exists,
and if so you can change the font you plan on using:

```JS
myFont = "6x8:2";
if (Graphics.prototype.setFontIntl)
myFont = "Intl";
```

Any new Font library must contain the metadata `"icon": "app.png", "tags": "font", "type": "module", "provides_modules" : ["fonts"],`
and should provide a `font` library, as well as a `boot.js` that adds `Graphics.prototype.setFontIntl`. If you plan on
making a new library it's best to just copy one of the existing ones for now.


## API Reference

[Reference](http://www.espruino.com/Reference#software)
Expand Down
4 changes: 3 additions & 1 deletion apps/.eslintrc.js
Expand Up @@ -164,7 +164,9 @@ module.exports = {
"D28": "readonly",
"D29": "readonly",
"D30": "readonly",
"D31": "readonly"
"D31": "readonly",

"bleServiceOptions": "writable", // available in boot.js code that's called ad part of bootupdate
},
"parserOptions": {
"ecmaVersion": 11
Expand Down
1 change: 1 addition & 0 deletions apps/fontall/ChangeLog
@@ -0,0 +1 @@
0.01: New App!
22 changes: 22 additions & 0 deletions apps/fontall/README.md
@@ -0,0 +1,22 @@
# Fonts (all languages)

This library provides an international font that can be used to display messages.

The font is the 16px high [GNU Unifont](https://unifoundry.com/unifont/index.html).
All characters from Unicode codepoint 32 up until codepoint 65535 (U+FFFF) are included here,
which should be enough for most languages.

**The font is 2MB and takes a while to upload** - if you don't require all the languages
it provides, consider installing another Font library like [extended fonts](https://banglejs.com/apps/?id=fontsext)
that contains just the characters you need instead.

## Usage

See [the BangleApps README file](https://github.com/espruino/BangleApps/blob/master/README.md#api-reference)
for more information on fonts.


## Recreating font.pbf

* Go to `bin` directory
* Run `./font_creator.js "All" ../apps/fontall/font.pbf`
Binary file added apps/fontall/app.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/fontall/boot.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added apps/fontall/font.pbf
Binary file not shown.
3 changes: 3 additions & 0 deletions apps/fontall/lib.js
@@ -0,0 +1,3 @@
exports.getFont = (options) => {
return "Intl"; // placeholder for now - see https://github.com/espruino/BangleApps/issues/3109
};
16 changes: 16 additions & 0 deletions apps/fontall/metadata.json
@@ -0,0 +1,16 @@
{ "id": "fontall",
"name": "Fonts (all languages)",
"version":"0.01",
"description": "Installs a font containing over 50,000 Unifont characters for Chinese, Japanese, Korean, Russian, and more. **Requires 2MB storage**",
"icon": "app.png",
"tags": "font",
"type": "module",
"provides_modules" : ["font"],
"supports" : ["BANGLEJS2"],
"readme": "README.md",
"storage": [
{"name":"font","url":"lib.js"},
{"name":"fontall.boot.js","url":"boot.js"},
{"name":"fontall.pbf","url":"font.pbf"}
]
}
1 change: 1 addition & 0 deletions apps/fontext/ChangeLog
@@ -0,0 +1 @@
0.01: New App!
25 changes: 25 additions & 0 deletions apps/fontext/README.md
@@ -0,0 +1,25 @@
# Fonts (extended)

This library provides an international font that can be used to display messages.

The font is the 16px high [GNU Unifont](https://unifoundry.com/unifont/index.html).
All characters from Unicode codepoint 32 up until codepoint 1103 (U+044F) are included here,
which should be enough for [around 90% of languages](https://arxiv.org/pdf/1801.07779.pdf#page=5)
but **not** Chinese/Japanese/Korean.

The font is 20kb so is far more sensible than the [2MB all regions](https://banglejs.com/apps/?id=fontsall) font
if you don't require non-latin languages.


https://arxiv.org/pdf/1801.07779.pdf#page=5

## Usage

See [the BangleApps README file](https://github.com/espruino/BangleApps/blob/master/README.md#api-reference)
for more information on fonts.


## Recreating font.pbf

* Go to `bin` directory
* Run `./font_creator.js "Extended" ../apps/fontext/font.pbf`
Binary file added apps/fontext/app.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/fontext/boot.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added apps/fontext/font.pbf
Binary file not shown.
3 changes: 3 additions & 0 deletions apps/fontext/lib.js
@@ -0,0 +1,3 @@
exports.getFont = (options) => {
return "Intl"; // placeholder for now - see https://github.com/espruino/BangleApps/issues/3109
};
16 changes: 16 additions & 0 deletions apps/fontext/metadata.json
@@ -0,0 +1,16 @@
{ "id": "fontext",
"name": "Fonts (150+ languages)",
"version":"0.01",
"description": "Installs a font containing 1000 Unifont characters, which should handle the majority of non-Chinese/Japanese/Korean languages (only 20kb)",
"icon": "app.png",
"tags": "font",
"type": "module",
"provides_modules" : ["font"],
"supports" : ["BANGLEJS2"],
"readme": "README.md",
"storage": [
{"name":"font","url":"lib.js"},
{"name":"fontext.boot.js","url":"boot.js"},
{"name":"fontext.pbf","url":"font.pbf"}
]
}
3 changes: 2 additions & 1 deletion apps/ios/ChangeLog
Expand Up @@ -14,4 +14,5 @@
0.14: Add settings page, allow time sync
Allow negative/positive actions to pass through to message GUI
0.15: Enable calendar and weather updates via custom notifications (via shortcuts app)
0.16: Always request Current Time service from iOS
0.16: Always request Current Time service from iOS
0.17: Default to passing full UTF8 strings into messages app (which can now process them with an international font)
12 changes: 9 additions & 3 deletions apps/ios/README.md
Expand Up @@ -9,9 +9,15 @@ prompted for immediatly after you connect the Bangle to the iPhone.

### Setting

Under `Settings -> Apps -> iOS Integration` there is
a `Time Sync` setting. This will enable syncing between the
watch and iOS.
Under `Settings -> Apps -> iOS Integration` there are some settings:

* `Time Sync` - This will enable syncing between the watch and iOS.
* `Disable UTF8` - As of version 0.17 of this app, text strings from iOS
are treated as UTF8. If you install a font library like https://banglejs.com/apps/?id=fontsall
then the messages app will be able to use that to render characters from iOS. Without fonts
installed, non-european (ISO8859-1) characters won't be displayed. If `Disable UTF8`
is true *or no fonts library is installed*, text from iOS is converted to ISO8859-1, and known characters with equivalents
within that range are converted (so text will display without a font library).

### Connecting your Bangle.js to your iPhone

Expand Down
93 changes: 50 additions & 43 deletions apps/ios/boot.js
Expand Up @@ -124,44 +124,9 @@ E.on('notify',msg=>{
"tv.twitch": "Twitch",
// could also use NRF.ancsGetAppInfo(msg.appId) here
};
var unicodeRemap = {
'2019':"'",
'260':"A",
'261':"a",
'262':"C",
'263':"c",
'268':"C",
'269':"c",
'270':"D",
'271':"d",
'280':"E",
'281':"e",
'282':"E",
'283':"e",
'321':"L",
'322':"l",
'323':"N",
'324':"n",
'327':"N",
'328':"n",
'344':"R",
'345':"r",
'346':"S",
'347':"s",
'352':"S",
'353':"s",
'356':"T",
'357':"t",
'377':"Z",
'378':"z",
'379':"Z",
'380':"z",
'381':"Z",
'382':"z",
};
var replacer = ""; //(n)=>print('Unknown unicode '+n.toString(16));

//if (appNames[msg.appId]) msg.a
if (msg.title&&E.decodeUTF8(msg.title, unicodeRemap, replacer) === "BangleDumpCalendar") {
if (msg.title === "BangleDumpCalendar") {
// parse the message body into json:
const d = JSON.parse(msg.message);
/* Example:
Expand All @@ -178,7 +143,7 @@ E.on('notify',msg=>{
{t:"calendar", id:int, type:int, timestamp:seconds, durationInSeconds, title:string, description:string,location:string,calName:string.color:int,allDay:bool
for gadgetbridge
*/
calEvent = {
let calEvent = {
t: "calendar",
id: parseInt(d.id),
type: 0,
Expand All @@ -205,14 +170,14 @@ E.on('notify',msg=>{
NRF.ancsAction(msg.uid, false);
return;
}
if (msg.title&&E.decodeUTF8(msg.title, unicodeRemap, replacer) === "BangleDumpWeather") {
if (msg.title === "BangleDumpWeather") {
const d = JSON.parse(msg.message);
/* Example:
{"temp":"291.07","hi":"293.02","lo":"288.18","hum":"49","rain":"0","uv":"0","wind":"1.54","code":"01d","txt":"Mostly Sunny","wdir":"303","loc":"Berlin"}
what we want:
t:"weather", temp,hi,lo,hum,rain,uv,code,txt,wind,wdir,loc
*/
weatherEvent = {
let weatherEvent = {
t: "weather",
temp: d.temp,
hi: d.hi,
Expand All @@ -236,9 +201,9 @@ E.on('notify',msg=>{
id : msg.uid,
src : appNames[msg.appId] || msg.appId,
new : msg.new,
title : msg.title&&E.decodeUTF8(msg.title, unicodeRemap, replacer),
subject : msg.subtitle&&E.decodeUTF8(msg.subtitle, unicodeRemap, replacer),
body : msg.message&&E.decodeUTF8(msg.message, unicodeRemap, replacer) || "Cannot display",
title : msg.title&&Bangle.ancsConvertUTF8(msg.title),
subject : msg.subtitle&&Bangle.ancsConvertUTF8(msg.subtitle),
body : msg.message&&Bangle.ancsConvertUTF8(msg.message) || "Cannot display",
positive : msg.positive,
negative : msg.negative
});
Expand Down Expand Up @@ -333,4 +298,46 @@ E.emit("ANCS", {
NRF.ctsGetTime().then(ctsUpdate, function(){ /* */ })
E.on('CTS',ctsUpdate);
}
if (settings.no_utf8 || !require("Storage").read("fonts")) {
// if UTF8 disabled or there is no fonts lib, convert UTF8 to ISO8859-1
let unicodeRemap = {
'2019':"'",
'260':"A",
'261':"a",
'262':"C",
'263':"c",
'268':"C",
'269':"c",
'270':"D",
'271':"d",
'280':"E",
'281':"e",
'282':"E",
'283':"e",
'321':"L",
'322':"l",
'323':"N",
'324':"n",
'327':"N",
'328':"n",
'344':"R",
'345':"r",
'346':"S",
'347':"s",
'352':"S",
'353':"s",
'356':"T",
'357':"t",
'377':"Z",
'378':"z",
'379':"Z",
'380':"z",
'381':"Z",
'382':"z",
};
let replacer = ""; //(n)=>print('Unknown unicode '+n.toString(16));
Bangle.ancsConvertUTF8 = text => E.decodeUTF8(text, unicodeRemap, replacer);
} else {
Bangle.ancsConvertUTF8 = E.asUTF8;
}
}
2 changes: 1 addition & 1 deletion apps/ios/metadata.json
@@ -1,7 +1,7 @@
{
"id": "ios",
"name": "iOS Integration",
"version": "0.16",
"version": "0.17",
"description": "Display notifications/music/etc from iOS devices",
"icon": "app.png",
"tags": "tool,system,ios,apple,messages,notifications",
Expand Down
7 changes: 7 additions & 0 deletions apps/ios/settings.js
Expand Up @@ -12,6 +12,13 @@
settings.timeSync = v;
updateSettings();
}
},
/*LANG*/"Disable UTF8" : {
value : !!settings.no_utf8,
onchange: v => {
settings.no_utf8 = v;
updateSettings();
}
}
};
E.showMenu(mainmenu);
Expand Down

0 comments on commit 591c1f8

Please sign in to comment.