aboutsummaryrefslogtreecommitdiff
path: root/internal/render/icons.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/render/icons.go')
-rw-r--r--internal/render/icons.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/internal/render/icons.go b/internal/render/icons.go
new file mode 100644
index 0000000..59ae3d3
--- /dev/null
+++ b/internal/render/icons.go
@@ -0,0 +1,84 @@
+package render
+
+// Weather glyphs per icon set, keyed by WMO code group.
+//
+// The "nerd" codepoints are from the Nerd Fonts Weather range (U+E300-U+E3E3),
+// which JetBrains Mono Nerd Font and MesloLGS NF both carry. They are single
+// cell and monochrome, so they take the terminal's foreground colour and do not
+// break a remapped palette.
+//
+// The "emoji" set is colour and comes from a fallback font. Its glyphs are not
+// all one cell wide -- see width.go -- which is why every pad goes through
+// DisplayWidth.
+var iconSets = map[string]map[string]string{
+ "nerd": {
+ "clear": "",
+ "partly": "",
+ "cloudy": "",
+ "fog": "",
+ "drizzle": "",
+ "rain": "",
+ "snow": "",
+ "storm": "",
+ },
+ "emoji": {
+ "clear": "☀",
+ "partly": "⛅",
+ "cloudy": "☁",
+ "fog": "\U0001F32B",
+ "drizzle": "\U0001F326",
+ "rain": "\U0001F327",
+ "snow": "\U0001F328",
+ "storm": "⛈",
+ },
+}
+
+// iconGroup maps a WMO weather code onto a glyph group.
+func iconGroup(code int) string {
+ switch {
+ case code == 0 || code == 1:
+ return "clear"
+ case code == 2:
+ return "partly"
+ case code == 3:
+ return "cloudy"
+ case code == 45 || code == 48:
+ return "fog"
+ case code >= 51 && code <= 57:
+ return "drizzle"
+ case code >= 61 && code <= 67, code >= 80 && code <= 82:
+ return "rain"
+ case code >= 71 && code <= 77, code == 85 || code == 86:
+ return "snow"
+ case code >= 95:
+ return "storm"
+ }
+ return "cloudy"
+}
+
+// Icon returns the glyph for a weather code in the named set. An unknown set,
+// or "none", yields an empty string so the column simply renders blank.
+func Icon(set string, code int) string {
+ glyphs, ok := iconSets[set]
+ if !ok {
+ return ""
+ }
+ return glyphs[iconGroup(code)]
+}
+
+// IconWidth is the display width the icon column should reserve for a set.
+// The emoji set contains wide glyphs, so its column is two cells even for the
+// entries that happen to be one.
+func IconWidth(set string) int {
+ glyphs, ok := iconSets[set]
+ if !ok {
+ return 0
+ }
+ w := 1
+ for _, g := range glyphs {
+ if gw := DisplayWidth(g); gw > w {
+ w = gw
+ }
+ }
+ return w
+}