-
Notifications
You must be signed in to change notification settings - Fork 0
Garmin Font Analyzer
If you install @markw65/monkeyc-optimizer, you can use it to analyze Garmin's .cft files.
If you don't already have it, you will first need to install nodejs/npm. Once that's done, you can install @markw65/monkeyc-optimizer.
Local installation (ie per project) is usually the best way to work with npm packages. To do so, switch to the root of your project directory, and execute the following command:
npm install --save-dev @markw65/monkeyc-optimizer
If you prefer a global installation, you can instead run
npm install -g @markw65/monkeyc-optimizer
You can now run the font file analyzer via npx cft-font-info
if you installed locally, or just cft-font-info
if you installed globally. The rest of the instructions will assume you installed locally.
-
--chars=<characters>
- The characters to return information about. If omitted, all characters defined by the font are listed. -
--char-info-as-array
- Changes the format of thecharInfo
array from an array of objects, to an array of arrays (and adds acharInfoNames
field describing the elements of each sub-array.
Each remaining argument is treated as a glob pattern. If the pattern ends in .cft (case insensitive) it will match font files in your ConnectIQ/Fonts
directory, otherwise it will match devices in the ConnectIQ/Devices
directory. For each device listed, all the fonts used by that device will be added to the list of fonts to analyze.
The output is a JSON object (jq can be very useful for filtering the bits you need).
The top level entries are fonts
and devices
.
-
fonts
is an object whose keys are font names, and whose values are objects with keys:-
height
integer height of font -
ascent
integer ascent of font -
internalLeading
space reserved above the font for diacriticals -
charInfo
an array of character descriptors, each in the format-
code
integer value of the unicode character -
char
the character value as a unicode string -
width
integer width of the character -
glyphAscent
integer ascent for this character -
glyphDescent
integer descent for this character
-
-
-
devices
is an object whose keys are device names, and whose values are objects with keys:-
langMap
an object whose keys are language abbreviations, and whose values arefontSet
names -
fontSets
an object whose keys arefontSet
names, and whose values are objects mappingGraphics.FONT_*
names to font names
-
For example, npx cft-font-info fr235 --chars="01"
would produce the following (formatted via jq)
{
"FNT_BEBAS_NEUE_20B": {
"height": 29,
"ascent": 25,
"internalLeading": 5,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 11,
"glyphAscent": 20,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 11,
"glyphAscent": 20,
"glyphDescent": 0
}
]
},
"FNT_BEBAS_NEUE_32B": {
"height": 47,
"ascent": 40,
"internalLeading": 8,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 18,
"glyphAscent": 32,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 18,
"glyphAscent": 32,
"glyphDescent": 0
}
]
},
"FNT_BEBAS_NEUE_40B": {
"height": 59,
"ascent": 51,
"internalLeading": 11,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 23,
"glyphAscent": 40,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 23,
"glyphAscent": 40,
"glyphDescent": 0
}
]
},
"FNT_BEBAS_NEUE_72B": {
"height": 104,
"ascent": 89,
"internalLeading": 17,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 40,
"glyphAscent": 71,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 40,
"glyphAscent": 70,
"glyphDescent": 0
}
]
},
"FNT_NOTO_SANS_CJK_KR_MEDIUM_18": {
"height": 18,
"ascent": 14,
"internalLeading": 4,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 7,
"glyphAscent": 9,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 7,
"glyphAscent": 9,
"glyphDescent": 0
}
]
},
"FNT_NOTO_SANS_CJK_KR_MEDIUM_21": {
"height": 21,
"ascent": 16,
"internalLeading": 4,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 8,
"glyphAscent": 11,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 8,
"glyphAscent": 11,
"glyphDescent": 0
}
]
},
"FNT_NOTO_SANS_CJK_KR_REGULAR_26": {
"height": 26,
"ascent": 20,
"internalLeading": 5,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 10,
"glyphAscent": 14,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 10,
"glyphAscent": 14,
"glyphDescent": 0
}
]
},
"FNT_ROBOTO_12B": {
"height": 19,
"ascent": 15,
"internalLeading": 3,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 8,
"glyphAscent": 11,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 8,
"glyphAscent": 11,
"glyphDescent": 0
}
]
},
"FNT_ROBOTO_15": {
"height": 24,
"ascent": 19,
"internalLeading": 4,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 9,
"glyphAscent": 14,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 9,
"glyphAscent": 14,
"glyphDescent": 0
}
]
},
"FNT_ROBOTO_20B": {
"height": 32,
"ascent": 25,
"internalLeading": 5,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 13,
"glyphAscent": 19,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 13,
"glyphAscent": 19,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_CN_BOLD_15": {
"height": 14,
"ascent": 11,
"internalLeading": 3,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 6,
"glyphAscent": 8,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 6,
"glyphAscent": 8,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_CN_BOLD_21": {
"height": 22,
"ascent": 17,
"internalLeading": 6,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 9,
"glyphAscent": 11,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 9,
"glyphAscent": 11,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_CN_BOLD_26": {
"height": 26,
"ascent": 20,
"internalLeading": 6,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 11,
"glyphAscent": 14,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 11,
"glyphAscent": 14,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_JP_BOLD_15": {
"height": 14,
"ascent": 11,
"internalLeading": 3,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 6,
"glyphAscent": 8,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 6,
"glyphAscent": 8,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_JP_BOLD_21": {
"height": 22,
"ascent": 17,
"internalLeading": 6,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 9,
"glyphAscent": 11,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 9,
"glyphAscent": 11,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_JP_BOLD_26": {
"height": 26,
"ascent": 20,
"internalLeading": 6,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 11,
"glyphAscent": 14,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 11,
"glyphAscent": 14,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_TWHK_BOLD_15": {
"height": 14,
"ascent": 11,
"internalLeading": 3,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 6,
"glyphAscent": 8,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 6,
"glyphAscent": 8,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_TWHK_BOLD_21": {
"height": 22,
"ascent": 17,
"internalLeading": 6,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 9,
"glyphAscent": 11,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 9,
"glyphAscent": 11,
"glyphDescent": 0
}
]
},
"FNT_SOURCE_HAN_SANS_TWHK_BOLD_26": {
"height": 26,
"ascent": 20,
"internalLeading": 6,
"charInfo": [
{
"code": 48,
"char": "0",
"width": 11,
"glyphAscent": 14,
"glyphDescent": 0
},
{
"code": 49,
"char": "1",
"width": 11,
"glyphAscent": 14,
"glyphDescent": 0
}
]
},
"devices": {
"fr235": {
"fontSets": {
"ww": {
"FONT_XTINY": "FNT_ROBOTO_12B",
"FONT_TINY": "FNT_ROBOTO_12B",
"FONT_SMALL": "FNT_ROBOTO_12B",
"FONT_MEDIUM": "FNT_ROBOTO_15",
"FONT_LARGE": "FNT_ROBOTO_20B",
"FONT_NUMBER_MILD": "FNT_BEBAS_NEUE_20B",
"FONT_NUMBER_MEDIUM": "FNT_BEBAS_NEUE_32B",
"FONT_NUMBER_HOT": "FNT_BEBAS_NEUE_40B",
"FONT_NUMBER_THAI_HOT": "FNT_BEBAS_NEUE_72B"
},
"apac_chn": {
"FONT_XTINY": "FNT_SOURCE_HAN_SANS_CN_BOLD_15",
"FONT_TINY": "FNT_SOURCE_HAN_SANS_CN_BOLD_15",
"FONT_SMALL": "FNT_SOURCE_HAN_SANS_CN_BOLD_15",
"FONT_MEDIUM": "FNT_SOURCE_HAN_SANS_CN_BOLD_21",
"FONT_LARGE": "FNT_SOURCE_HAN_SANS_CN_BOLD_26",
"FONT_NUMBER_MILD": "FNT_BEBAS_NEUE_20B",
"FONT_NUMBER_MEDIUM": "FNT_BEBAS_NEUE_32B",
"FONT_NUMBER_HOT": "FNT_BEBAS_NEUE_40B",
"FONT_NUMBER_THAI_HOT": "FNT_BEBAS_NEUE_72B"
},
"apac_twn": {
"FONT_XTINY": "FNT_SOURCE_HAN_SANS_TWHK_BOLD_15",
"FONT_TINY": "FNT_SOURCE_HAN_SANS_TWHK_BOLD_15",
"FONT_SMALL": "FNT_SOURCE_HAN_SANS_TWHK_BOLD_15",
"FONT_MEDIUM": "FNT_SOURCE_HAN_SANS_TWHK_BOLD_21",
"FONT_LARGE": "FNT_SOURCE_HAN_SANS_TWHK_BOLD_26",
"FONT_NUMBER_MILD": "FNT_BEBAS_NEUE_20B",
"FONT_NUMBER_MEDIUM": "FNT_BEBAS_NEUE_32B",
"FONT_NUMBER_HOT": "FNT_BEBAS_NEUE_40B",
"FONT_NUMBER_THAI_HOT": "FNT_BEBAS_NEUE_72B"
},
"apac_jpn": {
"FONT_XTINY": "FNT_SOURCE_HAN_SANS_JP_BOLD_15",
"FONT_TINY": "FNT_SOURCE_HAN_SANS_JP_BOLD_15",
"FONT_SMALL": "FNT_SOURCE_HAN_SANS_JP_BOLD_15",
"FONT_MEDIUM": "FNT_SOURCE_HAN_SANS_JP_BOLD_21",
"FONT_LARGE": "FNT_SOURCE_HAN_SANS_JP_BOLD_26",
"FONT_NUMBER_MILD": "FNT_BEBAS_NEUE_20B",
"FONT_NUMBER_MEDIUM": "FNT_BEBAS_NEUE_32B",
"FONT_NUMBER_HOT": "FNT_BEBAS_NEUE_40B",
"FONT_NUMBER_THAI_HOT": "FNT_BEBAS_NEUE_72B"
},
"apac_tha": {
"FONT_XTINY": "bitstreamVeraSans 16",
"FONT_TINY": "bitstreamVeraSans 16",
"FONT_SMALL": "bitstreamVeraSans 16",
"FONT_MEDIUM": "bitstreamVeraSans 21",
"FONT_LARGE": "bitstreamVeraSans 27",
"FONT_NUMBER_MILD": "FNT_BEBAS_NEUE_20B",
"FONT_NUMBER_MEDIUM": "FNT_BEBAS_NEUE_32B",
"FONT_NUMBER_HOT": "FNT_BEBAS_NEUE_40B",
"FONT_NUMBER_THAI_HOT": "FNT_BEBAS_NEUE_72B"
},
"apac_kor": {
"FONT_XTINY": "FNT_NOTO_SANS_CJK_KR_MEDIUM_18",
"FONT_TINY": "FNT_NOTO_SANS_CJK_KR_MEDIUM_18",
"FONT_SMALL": "FNT_NOTO_SANS_CJK_KR_MEDIUM_18",
"FONT_MEDIUM": "FNT_NOTO_SANS_CJK_KR_MEDIUM_21",
"FONT_LARGE": "FNT_NOTO_SANS_CJK_KR_REGULAR_26",
"FONT_NUMBER_MILD": "FNT_BEBAS_NEUE_20B",
"FONT_NUMBER_MEDIUM": "FNT_BEBAS_NEUE_32B",
"FONT_NUMBER_HOT": "FNT_BEBAS_NEUE_40B",
"FONT_NUMBER_THAI_HOT": "FNT_BEBAS_NEUE_72B"
}
},
"langMap": {
"hrv": "ww",
"ces": "ww",
"dan": "ww",
"dut": "ww",
"eng": "ww",
"fin": "ww",
"fre": "ww",
"deu": "ww",
"gre": "ww",
"hun": "ww",
"ita": "ww",
"nob": "ww",
"pol": "ww",
"por": "ww",
"rus": "ww",
"slo": "ww",
"slv": "ww",
"spa": "ww",
"swe": "ww",
"ind": "ww",
"zhs": "apac_chn",
"zht": "apac_twn",
"kor": "apac_kor",
"tha": "apac_tha",
"jpn": "apac_jpn"
}
}
}
}