From 170b2ecec060631062cca67fcb192f1966972f92 Mon Sep 17 00:00:00 2001 From: Philoul Date: Sun, 3 Sep 2023 17:38:08 +0200 Subject: [PATCH] Wear CWF Allow custom fonts (up to 4) within zip file --- .../rx/weardata/CustomWatchfaceFormat.kt | 42 +++++++++++++++++-- .../androidaps/watchfaces/CustomWatchface.kt | 40 ++++++++++++------ 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/app-wear-shared/shared/src/main/java/info/nightscout/rx/weardata/CustomWatchfaceFormat.kt b/app-wear-shared/shared/src/main/java/info/nightscout/rx/weardata/CustomWatchfaceFormat.kt index 989b458635..a6151eb964 100644 --- a/app-wear-shared/shared/src/main/java/info/nightscout/rx/weardata/CustomWatchfaceFormat.kt +++ b/app-wear-shared/shared/src/main/java/info/nightscout/rx/weardata/CustomWatchfaceFormat.kt @@ -2,6 +2,7 @@ package info.nightscout.rx.weardata import android.content.res.Resources import android.graphics.BitmapFactory +import android.graphics.Typeface import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.PictureDrawable @@ -49,7 +50,11 @@ enum class ResFileMap(val fileName: String) { ARROW_FLAT("ArrowFlat"), ARROW_FORTY_FIVE_DOWN("Arrow45Down"), ARROW_SINGLE_DOWN("ArrowSingleDown"), - ARROW_DOUBLE_DOWN("ArrowDoubleDown"); + ARROW_DOUBLE_DOWN("ArrowDoubleDown"), + FONT1("Font1"), + FONT2("Font2"), + FONT3("Font3"), + FONT4("Font4"); companion object { @@ -61,7 +66,8 @@ enum class ResFormat(val extension: String) { UNKNOWN(""), SVG("svg"), JPG("jpg"), - PNG("png"); + PNG("png"), + TTF("ttf"); companion object { @@ -90,7 +96,32 @@ data class ResData(val value: ByteArray, val format: ResFormat) { } } - else -> null + else -> null + } + } catch (e: Exception) { + return null + } + } + + fun toTypeface(): Typeface? { + try { + return when (format) { + ResFormat.TTF -> { + // Workaround with temporary File, Typeface.createFromFileDescriptor(null, value, 0, value.size) more simple not available + val tempFile = File.createTempFile("temp", ".ttf") + val fileOutputStream = FileOutputStream(tempFile) + fileOutputStream.write(value) + fileOutputStream.close() + + val typeface = Typeface.createFromFile(tempFile) + tempFile.delete() // delete tempfile after usage + typeface + } + + else -> { + null + + } } } catch (e: Exception) { return null @@ -224,7 +255,10 @@ enum class JsonKeyValues(val key: String, val jsonKey: JsonKeys) { BOLD_ITALIC("bold_italic", JsonKeys.FONTSTYLE), ITALIC("italic", JsonKeys.FONTSTYLE), BGCOLOR("bgColor", JsonKeys.COLOR), - BGCOLOR1("bgColor", JsonKeys.FONTCOLOR) + FONT1("font1", JsonKeys.FONTCOLOR), + FONT2("font2", JsonKeys.FONTCOLOR), + FONT3("font3", JsonKeys.FONTCOLOR), + FONT4("font4", JsonKeys.FONTCOLOR) } enum class ViewType(@StringRes val comment: Int?) { diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/CustomWatchface.kt b/wear/src/main/java/info/nightscout/androidaps/watchfaces/CustomWatchface.kt index 778d06869b..c56e71f01b 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/CustomWatchface.kt +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/CustomWatchface.kt @@ -67,7 +67,7 @@ class CustomWatchface : BaseWatchFace() { override fun onCreate() { super.onCreate() - FontMap.init(context) + FontMap.init(context, resDataMap) } @Suppress("DEPRECATION") @@ -149,6 +149,7 @@ class CustomWatchface : BaseWatchFace() { try { val json = JSONObject(it.customWatchfaceData.json) resDataMap = it.customWatchfaceData.resDatas + FontMap.init(context, resDataMap) enableSecond = json.optBoolean(ENABLESECOND.key) && sp.getBoolean(R.string.key_show_seconds, true) highColor = getColor(json.optString(HIGHCOLOR.key), ContextCompat.getColor(this, R.color.dark_highColor)) midColor = getColor(json.optString(MIDCOLOR.key), ContextCompat.getColor(this, R.color.inrange)) @@ -529,20 +530,35 @@ private enum class GravityMap(val key: String, val gravity: Int) { } } -private enum class FontMap(val key: String, var font: Typeface, @FontRes val fontRessources: Int?) { - SANS_SERIF(JsonKeyValues.SANS_SERIF.key, Typeface.SANS_SERIF, null), - DEFAULT(JsonKeyValues.DEFAULT.key, Typeface.DEFAULT, null), - DEFAULT_BOLD(JsonKeyValues.DEFAULT_BOLD.key, Typeface.DEFAULT_BOLD, null), - MONOSPACE(JsonKeyValues.MONOSPACE.key, Typeface.MONOSPACE, null), - SERIF(JsonKeyValues.SERIF.key, Typeface.SERIF, null), - ROBOTO_CONDENSED_BOLD(JsonKeyValues.ROBOTO_CONDENSED_BOLD.key, Typeface.DEFAULT, R.font.roboto_condensed_bold), - ROBOTO_CONDENSED_LIGHT(JsonKeyValues.ROBOTO_CONDENSED_LIGHT.key, Typeface.DEFAULT, R.font.roboto_condensed_light), - ROBOTO_CONDENSED_REGULAR(JsonKeyValues.ROBOTO_CONDENSED_REGULAR.key, Typeface.DEFAULT, R.font.roboto_condensed_regular), - ROBOTO_SLAB_LIGHT(JsonKeyValues.ROBOTO_SLAB_LIGHT.key, Typeface.DEFAULT, R.font.roboto_slab_light); +private enum class FontMap(val key: String, var font: Typeface, @FontRes val fontRessources: Int?, val customFont: ResFileMap?) { + SANS_SERIF(JsonKeyValues.SANS_SERIF.key, Typeface.SANS_SERIF, null, null), + DEFAULT(JsonKeyValues.DEFAULT.key, Typeface.DEFAULT, null, null), + DEFAULT_BOLD(JsonKeyValues.DEFAULT_BOLD.key, Typeface.DEFAULT_BOLD, null, null), + MONOSPACE(JsonKeyValues.MONOSPACE.key, Typeface.MONOSPACE, null, null), + SERIF(JsonKeyValues.SERIF.key, Typeface.SERIF, null, null), + ROBOTO_CONDENSED_BOLD(JsonKeyValues.ROBOTO_CONDENSED_BOLD.key, Typeface.DEFAULT, R.font.roboto_condensed_bold, null), + ROBOTO_CONDENSED_LIGHT(JsonKeyValues.ROBOTO_CONDENSED_LIGHT.key, Typeface.DEFAULT, R.font.roboto_condensed_light, null), + ROBOTO_CONDENSED_REGULAR(JsonKeyValues.ROBOTO_CONDENSED_REGULAR.key, Typeface.DEFAULT, R.font.roboto_condensed_regular, null), + ROBOTO_SLAB_LIGHT(JsonKeyValues.ROBOTO_SLAB_LIGHT.key, Typeface.DEFAULT, R.font.roboto_slab_light, null), + FONT1(JsonKeyValues.FONT1.key, Typeface.DEFAULT, null, ResFileMap.FONT1), + FONT2(JsonKeyValues.FONT2.key, Typeface.DEFAULT, null, ResFileMap.FONT2), + FONT3(JsonKeyValues.FONT3.key, Typeface.DEFAULT, null, ResFileMap.FONT3), + FONT4(JsonKeyValues.FONT4.key, Typeface.DEFAULT, null, ResFileMap.FONT4); companion object { - fun init(context: Context) = values().forEach { it.font = it.fontRessources?.let { font -> ResourcesCompat.getFont(context, font) } ?: it.font } + fun init(context: Context, resDataMap: CwfResDataMap) = values().forEach { fontMap -> + fontMap.customFont?.let { customFont -> + fontMap.font = Typeface.DEFAULT + resDataMap[customFont]?.toTypeface()?.let { resData -> + fontMap.font = resData + } + } ?: run { + fontMap.font = fontMap.fontRessources?.let { fontResource -> + ResourcesCompat.getFont(context, fontResource) + } ?: fontMap.font + } + } fun font(key: String) = values().firstOrNull { it.key == key }?.font ?: DEFAULT.font fun key() = DEFAULT.key }