diff --git a/font.go b/fonts/cache.go similarity index 55% rename from font.go rename to fonts/cache.go index 8d31304..88cba84 100644 --- a/font.go +++ b/fonts/cache.go @@ -1,4 +1,4 @@ -package main +package fonts import ( "fmt" @@ -6,13 +6,13 @@ import ( "github.com/llgcode/draw2d" ) -type MyFontCache map[string]*truetype.Font +type Cache map[string]*truetype.Font -func (fc MyFontCache) Store(fd draw2d.FontData, font *truetype.Font) { +func (fc Cache) Store(fd draw2d.FontData, font *truetype.Font) { fc[fd.Name] = font } -func (fc MyFontCache) Load(fd draw2d.FontData) (*truetype.Font, error) { +func (fc Cache) Load(fd draw2d.FontData) (*truetype.Font, error) { font, stored := fc[fd.Name] if !stored { return nil, fmt.Errorf("font %s is not stored in font cache", fd.Name) diff --git a/fonts/fonts.go b/fonts/fonts.go index eae68cc..526bdbc 100644 --- a/fonts/fonts.go +++ b/fonts/fonts.go @@ -1,20 +1,71 @@ package fonts -import _ "embed" - -//go:embed ttf/OpenSans-Bold.ttf -var Bold []byte +import ( + _ "embed" + "fmt" + "github.com/golang/freetype/truetype" + "github.com/llgcode/draw2d" +) //go:embed ttf/OpenSans-Regular.ttf -var Regular []byte +var RegularTTF []byte + +//go:embed ttf/OpenSans-SemiBold.ttf +var SemiBoldTTF []byte + +//go:embed ttf/OpenSans-Bold.ttf +var BoldTTF []byte //go:embed ttf/OpenSans-Italic.ttf -var Italic []byte +var ItalicTTF []byte //go:embed ttf/Phosphor.ttf -var Icons []byte +var IconsTTF []byte const ( IconXOffset = 38 IconYOffset = 2 ) + +const ( + Regular = "regular" + SemiBold = "semibold" + Bold = "bold" + Italic = "italic" + Icons = "icons" +) + +func NewCache() (Cache, error) { + cache := Cache{} + + fonts := []struct { + ttf []byte + name string + }{ + {RegularTTF, Regular}, + {SemiBoldTTF, SemiBold}, + {BoldTTF, Bold}, + {ItalicTTF, Italic}, + {IconsTTF, Icons}, + } + + for _, font := range fonts { + err := loadFont(cache, font.ttf, font.name) + if err != nil { + return cache, fmt.Errorf("loading font %q: %w", font.name, err) + } + } + + return cache, nil +} + +func loadFont(fontCache Cache, ttf []byte, name string) error { + font, err := truetype.Parse(ttf) + if err != nil { + return fmt.Errorf("parsing font %v: %w", name, err) + } + + fontCache.Store(draw2d.FontData{Name: name}, font) + + return nil +} diff --git a/fonts/ttf/OpenSans-SemiBold.ttf b/fonts/ttf/OpenSans-SemiBold.ttf new file mode 100644 index 0000000..e5ab464 Binary files /dev/null and b/fonts/ttf/OpenSans-SemiBold.ttf differ diff --git a/img.go b/img.go index 8696690..327d1a3 100644 --- a/img.go +++ b/img.go @@ -149,8 +149,7 @@ func getImg(ctx context.Context, nowFunc func() time.Time, transportsClient *tra } func drawMsg(gc *draw2dimg.GraphicContext, quote string) { - text(gc, quote, 15, leftX, 450, fontItalic) - + text(gc, quote, 15, leftX, 450, fonts.Italic) } func drawWeather(ctx context.Context, gc *draw2dimg.GraphicContext, wthr *weather.Prevision) { @@ -172,15 +171,15 @@ func drawWeather(ctx context.Context, gc *draw2dimg.GraphicContext, wthr *weathe slog.ErrorContext(ctx, "Failed to draw weather icon", "err", err) } - text(gc, formatTemp(wthr.Current.Temp), 23, leftX, 125, fontRegular) + text(gc, formatTemp(wthr.Current.Temp), 23, leftX, 125, fonts.Regular) const xAlign = 120 const fontSize = 18 - text(gc, "journée", fontSize, xAlign, 35, fontBold) - text(gc, "max "+formatTemp(daily.Temp.Max), fontSize, xAlign, 65, fontRegular) - text(gc, fmt.Sprintf("pluie %v%%", int(math.Round(daily.Pop*100))), fontSize, xAlign, 95, fontRegular) - text(gc, dailyWeather.Description, fontSize, xAlign, 125, fontRegular) + text(gc, "journée", fontSize, xAlign, 35, fonts.Bold) + text(gc, "max "+formatTemp(daily.Temp.Max), fontSize, xAlign, 65, fonts.Regular) + text(gc, fmt.Sprintf("pluie %v%%", int(math.Round(daily.Pop*100))), fontSize, xAlign, 95, fonts.Regular) + text(gc, dailyWeather.Description, fontSize, xAlign, 125, fonts.Regular) } func drawWeatherIcon(gc *draw2dimg.GraphicContext, dailyWeather weather.Weather) error { @@ -209,21 +208,21 @@ func drawVelov(gc *draw2dimg.GraphicContext, station *transports.Station, yOffse return } - text(gc, station.Name, 23, rightX, yOffset, fontBold) + text(gc, station.Name, 23, rightX, yOffset, fonts.Bold) yOffset += 30 - text(gc, "\uE0D6", 22, rightX, yOffset+fonts.IconYOffset, fontIcons) // bike icon - text(gc, strconv.Itoa(station.BikesAvailable), 22, rightX+fonts.IconXOffset, yOffset, fontRegular) + text(gc, "\uE0D6", 22, rightX, yOffset+fonts.IconYOffset, fonts.Icons) // bike icon + text(gc, strconv.Itoa(station.BikesAvailable), 22, rightX+fonts.IconXOffset, yOffset, fonts.Regular) nextCol := rightX + 100.0 - text(gc, "\uEC08", 22, nextCol, yOffset+fonts.IconYOffset, fontIcons) // parking icon - text(gc, strconv.Itoa(station.DocksAvailable), 22, nextCol+fonts.IconXOffset, yOffset, fontRegular) + text(gc, "\uEC08", 22, nextCol, yOffset+fonts.IconYOffset, fonts.Icons) // parking icon + text(gc, strconv.Itoa(station.DocksAvailable), 22, nextCol+fonts.IconXOffset, yOffset, fonts.Regular) } func drawDate(gc *draw2dimg.GraphicContext, now time.Time) { - text(gc, now.Format("15:04"), 110, leftX, 300, fontBold) - text(gc, getDate(now), 30, leftX, 345, fontRegular) + text(gc, now.Format("15:04"), 110, leftX, 300, fonts.Bold) + text(gc, getDate(now), 30, leftX, 345, fonts.Regular) } func drawFete(gc *draw2dimg.GraphicContext, fetes *fete.Fete) { @@ -231,7 +230,7 @@ func drawFete(gc *draw2dimg.GraphicContext, fetes *fete.Fete) { return } - text(gc, fmt.Sprintf("On fête les %s", fetes.Name), 18, leftX, 380, fontRegular) + text(gc, fmt.Sprintf("On fête les %s", fetes.Name), 18, leftX, 380, fonts.Regular) } func drawTCL(gc *draw2dimg.GraphicContext, passages *transports.Passages, yoffset float64) { @@ -241,11 +240,11 @@ func drawTCL(gc *draw2dimg.GraphicContext, passages *transports.Passages, yoffse for i, passage := range passages.Passages { x := float64(rightX + i*120) - text(gc, "\uE106", 23, x, yoffset+fonts.IconYOffset, fontIcons) - text(gc, passage.Ligne, 23, x+fonts.IconXOffset, yoffset, fontBold) + text(gc, "\uE106", 23, x, yoffset+fonts.IconYOffset, fonts.Icons) + text(gc, passage.Ligne, 23, x+fonts.IconXOffset, yoffset, fonts.Bold) for j, delay := range passage.Delays { y := yoffset + float64(j+1)*35 - text(gc, delay, 22, x, y, fontRegular) + text(gc, delay, 22, x, y, fonts.Regular) if j >= 2 { // limit number of delays displayed break } diff --git a/main.go b/main.go index 84c17df..f34f36f 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,6 @@ import ( "github.com/Crocmagnon/display-epaper/home_assistant" "github.com/Crocmagnon/display-epaper/transports" "github.com/Crocmagnon/display-epaper/weather" - "github.com/golang/freetype/truetype" "github.com/llgcode/draw2d" _ "golang.org/x/image/bmp" "log/slog" @@ -15,23 +14,16 @@ import ( "time" ) -const ( - fontRegular = "regular" - fontBold = "bold" - fontItalic = "italic" - fontIcons = "icons" -) - func main() { ctx := context.Background() slog.InfoContext(ctx, "starting...") - fontCache := MyFontCache{} - loadFont(ctx, fontCache, fonts.Regular, fontRegular) - loadFont(ctx, fontCache, fonts.Bold, fontBold) - loadFont(ctx, fontCache, fonts.Italic, fontItalic) - loadFont(ctx, fontCache, fonts.Icons, fontIcons) + fontCache, err := fonts.NewCache() + if err != nil { + slog.ErrorContext(ctx, "could not create font cache", "error", err.Error()) + os.Exit(1) + } draw2d.SetFontCache(fontCache) @@ -85,12 +77,3 @@ func main() { slog.InfoContext(ctx, "done") } - -func loadFont(ctx context.Context, fontCache MyFontCache, ttf []byte, name string) { - font, err := truetype.Parse(ttf) - if err != nil { - slog.ErrorContext(ctx, "error loading font", "err", err) - os.Exit(1) - } - fontCache.Store(draw2d.FontData{Name: name}, font) -}