1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-08 14:18:08 +02:00

Bangle.js - make 'text as bitmaps' have transparent background, and allow font size to be specified - fixes https://github.com/espruino/BangleApps/issues/2057

This commit is contained in:
Gordon Williams 2022-07-25 14:25:49 +01:00
parent 6d92af5794
commit 1e4fb7ee87
6 changed files with 41 additions and 10 deletions

View File

@ -45,6 +45,7 @@ public class DeviceSettingsPreferenceConst {
public static final String PREF_DEVICE_INTENTS = "device_intents";
public static final String PREF_BANGLEJS_TEXT_BITMAP = "banglejs_text_bitmap";
public static final String PREF_BANGLEJS_TEXT_BITMAP_SIZE = "banglejs_txt_bitmap_size";
public static final String PREF_BANGLEJS_WEBVIEW_URL = "banglejs_webview_url";
public static final String PREF_DISCONNECT_NOTIFICATION = "disconnect_notification";

View File

@ -116,6 +116,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALLOW_HIGH_MTU;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BANGLEJS_TEXT_BITMAP_SIZE;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_INTERNET_ACCESS;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_INTENTS;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BANGLEJS_TEXT_BITMAP;
@ -720,7 +721,7 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
for(Emoji emoji : EmojiUtils.getAllEmojis())
if (word.contains(emoji.getEmoji())) hasEmoji = true;
// if we had emoji, ensure we create 3 bit color (not 1 bit B&W)
return "\0"+bitmapToEspruinoString(textToBitmap(word), hasEmoji ? BangleJSBitmapStyle.RGB_3BPP : BangleJSBitmapStyle.MONOCHROME);
return "\0"+bitmapToEspruinoString(textToBitmap(word), hasEmoji ? BangleJSBitmapStyle.RGB_3BPP_TRANSPARENT : BangleJSBitmapStyle.MONOCHROME_TRANSPARENT);
}
public String renderUnicodeAsImage(String txt) {
@ -1097,7 +1098,8 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
public Bitmap textToBitmap(String text) {
Paint paint = new Paint(0); // Paint.ANTI_ALIAS_FLAG not wanted as 1bpp
paint.setTextSize(18);
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()));
paint.setTextSize(devicePrefs.getInt(PREF_BANGLEJS_TEXT_BITMAP_SIZE, 18));
paint.setColor(0xFFFFFFFF);
paint.setTextAlign(Paint.Align.LEFT);
float baseline = -paint.ascent(); // ascent() is negative
@ -1110,8 +1112,10 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
}
public enum BangleJSBitmapStyle {
MONOCHROME,
RGB_3BPP
MONOCHROME, // 1bpp
MONOCHROME_TRANSPARENT, // 1bpp, black = transparent
RGB_3BPP, // 3bpp
RGB_3BPP_TRANSPARENT // 3bpp, least used color as transparent
};
/** Used for writing single bits to an array */
@ -1145,12 +1149,14 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
public static byte[] bitmapToEspruinoArray(Bitmap bitmap, BangleJSBitmapStyle style) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int bpp = (style==BangleJSBitmapStyle.RGB_3BPP) ? 3 : 1;
int bpp = (style==BangleJSBitmapStyle.RGB_3BPP ||
style==BangleJSBitmapStyle.RGB_3BPP_TRANSPARENT) ? 3 : 1;
byte pixels[] = new byte[width * height];
final byte PIXELCOL_TRANSPARENT = -1;
final int ditherMatrix[] = {1*16,5*16,7*16,3*16}; // for bayer dithering
// if doing 3bpp, check image to see if it's transparent
boolean allowTransparency = (style != BangleJSBitmapStyle.MONOCHROME);
// if doing RGB_3BPP_TRANSPARENT, check image to see if it's transparent
// MONOCHROME_TRANSPARENT is handled later on...
boolean allowTransparency = (style == BangleJSBitmapStyle.RGB_3BPP_TRANSPARENT);
boolean isTransparent = false;
byte transparentColorIndex = 0;
/* Work out what colour index each pixel should be and write to pixels.
@ -1175,9 +1181,9 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
g += ditherAmt;
b += ditherAmt;
int col = 0;
if (style == BangleJSBitmapStyle.MONOCHROME)
if (bpp==1)
col = ((r+g+b) >= 768)?1:0;
else if (style == BangleJSBitmapStyle.RGB_3BPP)
else if (bpp==3)
col = ((r>=256)?1:0) | ((g>=256)?2:0) | ((b>=256)?4:0);
if (!pixelTransparent) colUsage[col]++; // if not transparent, record usage
// save colour, mark transparent separately
@ -1199,6 +1205,11 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
if (pixels[n]==PIXELCOL_TRANSPARENT)
pixels[n] = transparentColorIndex;
}
// if we're MONOCHROME_TRANSPARENT, force transparency on bg color
if (style == BangleJSBitmapStyle.MONOCHROME_TRANSPARENT) {
isTransparent = true;
transparentColorIndex = 0;
}
// Write the header
int headerLen = isTransparent ? 4 : 3;
byte bmp[] = new byte[(((height * width * bpp) + 7) >> 3) + headerLen];

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#7E7E7E"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M9,4v3h5v12h3L17,7h5L22,4L9,4zM3,12h3v7h3v-7h3L12,9L3,9v3z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#7E7E7E"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z"/>
</vector>

View File

@ -198,6 +198,8 @@
<string name="pref_summary_transliteration">Enable this if your device has no support for your language\'s font</string>
<string name="pref_title_banglejs_text_bitmap">Text as Bitmaps</string>
<string name="pref_summary_banglejs_text_bitmap">If a word cannot be rendered with the watch\'s font, render it to a bitmap in Gadgetbridge and display the bitmap on the watch</string>
<string name="pref_title_banglejs_txt_bitmap_size">Text Bitmaps Size</string>
<string name="pref_summary_banglejs_txt_bitmap_size">If \'Text as Bitmaps\' enabled, what size should text be rendered?</string>
<string name="pref_title_banglejs_webview_url">App loader URL</string>
<string name="pref_summary_banglejs_webview_url">If you want a custom app loader put your https://…/android.html URL here. Otherwise leave blank for https://banglejs.com/apps</string>
<string name="pref_title_rtl">Right-To-Left</string>

View File

@ -6,9 +6,16 @@
android:key="banglejs_text_bitmap"
android:summary="@string/pref_summary_banglejs_text_bitmap"
android:title="@string/pref_title_banglejs_text_bitmap" />
<EditTextPreference
android:defaultValue="18"
android:inputType="number"
android:icon="@drawable/ic_font_size"
android:key="banglejs_txt_bitmap_size"
android:summary="@string/pref_summary_banglejs_txt_bitmap_size"
android:title="@string/pref_title_banglejs_txt_bitmap_size" />
<EditTextPreference
android:defaultValue=""
android:icon="@drawable/ic_engineering"
android:icon="@drawable/ic_link"
android:key="banglejs_webview_url"
android:summary="@string/pref_summary_banglejs_webview_url"
android:title="@string/pref_title_banglejs_webview_url" />