Skip to content

Commit d7bfb01

Browse files
committed
Smart pointer fonts
1 parent 25d854b commit d7bfb01

7 files changed

Lines changed: 51 additions & 68 deletions

File tree

doc/ExternalResources.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,12 @@ Load a font from the external resources.
5757

5858
You don't need to check if it exists in the constructor as LVGL can handle the font not existing gracefully (nothing will render).
5959
However, do check that it exists in the `IsAvailable()` method so users can see when resources are missing (the watchface will not be selectable in the list if `IsAvailable()` returns `false`).
60-
Remember to free any loaded fonts (with `free()`) in the screen destructor.
60+
The fonts will free themselves when the owning object is destructed.
6161

6262
```
63-
lv_font_t* font_teko = nullptr;
64-
font_teko = Pinetime::Components::FastFont::LoadFont(filesystem, "/fastfonts/teko.bin");
63+
Components::FastFont::Font fontTeko = Components::FastFont::LoadFont(filesystem, "/fastfonts/teko.bin");
6564
66-
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko);
65+
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, fontTeko.get());
6766
6867
```
6968

src/displayapp/fonts/FastFont.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "components/fs/FS.h"
44

5+
#include <cstdint>
6+
#include <memory>
57
#include <type_traits>
68

79
using namespace Pinetime::Components;
@@ -19,7 +21,7 @@ namespace {
1921
}
2022
}
2123

22-
lv_font_t* FastFont::LoadFont(Pinetime::Controllers::FS& filesystem, const char* fontPath) {
24+
FastFont::Font FastFont::LoadFont(Pinetime::Controllers::FS& filesystem, const char* fontPath) {
2325
int ret;
2426
lfs_file_t file;
2527
ret = filesystem.FileOpen(&file, fontPath, LFS_O_RDONLY);
@@ -28,19 +30,18 @@ lv_font_t* FastFont::LoadFont(Pinetime::Controllers::FS& filesystem, const char*
2830
}
2931
// Can use stat to get the size, but since the file is open we can grab it from there
3032
lfs_size_t size = file.ctz.size;
31-
void* fontData = malloc(size);
32-
if (fontData == nullptr) {
33+
auto fontData = std::make_unique_for_overwrite<uint8_t[]>(size);
34+
if (fontData.get() == nullptr) {
3335
filesystem.FileClose(&file);
3436
return nullptr;
3537
}
36-
ret = filesystem.FileRead(&file, static_cast<uint8_t*>(fontData), size);
38+
ret = filesystem.FileRead(&file, fontData.get(), size);
3739
filesystem.FileClose(&file);
3840
if (ret != static_cast<int>(size)) {
39-
free(fontData);
4041
return nullptr;
4142
}
42-
auto* font = static_cast<lv_font_t*>(fontData);
43-
auto base = reinterpret_cast<uintptr_t>(fontData);
43+
auto* font = reinterpret_cast<lv_font_t*>(fontData.get());
44+
auto base = reinterpret_cast<uintptr_t>(fontData.get());
4445

4546
// Fix LVGL fetch pointers
4647
font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt;
@@ -75,5 +76,5 @@ lv_font_t* FastFont::LoadFont(Pinetime::Controllers::FS& filesystem, const char*
7576
}
7677
}
7778

78-
return font;
79+
return FastFont::Font(reinterpret_cast<lv_font_t*>(fontData.release()));
7980
}

src/displayapp/fonts/FastFont.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1+
#pragma once
2+
13
#include "displayapp/LittleVgl.h"
4+
#include <memory>
25

36
namespace Pinetime {
47
namespace Components {
58
namespace FastFont {
6-
lv_font_t* LoadFont(Pinetime::Controllers::FS& filesystem, const char* fontPath);
9+
// Since the font pointer is actually a u8 array containing all loaded font data
10+
// we need to use the deleter for the true datatype rather than the single struct
11+
struct CastingDeleter {
12+
void operator()(lv_font_t* fontData) const {
13+
auto* fontDataReal = reinterpret_cast<uint8_t*>(fontData);
14+
std::default_delete<uint8_t[]> {}(fontDataReal);
15+
}
16+
};
17+
18+
using Font = std::unique_ptr<lv_font_t, CastingDeleter>;
19+
Font LoadFont(Pinetime::Controllers::FS& filesystem, const char* fontPath);
720
}
821
}
922
}

src/displayapp/screens/WatchFaceCasioStyleG7710.cpp

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "components/heartrate/HeartRateController.h"
1313
#include "components/motion/MotionController.h"
1414
#include "components/settings/Settings.h"
15-
#include "displayapp/fonts/FastFont.h"
1615
using namespace Pinetime::Applications::Screens;
1716

1817
WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTimeController,
@@ -64,19 +63,19 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi
6463
label_day_of_week = lv_label_create(lv_scr_act(), nullptr);
6564
lv_obj_align(label_day_of_week, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 10, 64);
6665
lv_obj_set_style_local_text_color(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
67-
lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40);
66+
lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40.get());
6867
lv_label_set_text_static(label_day_of_week, "SUN");
6968

7069
label_week_number = lv_label_create(lv_scr_act(), nullptr);
7170
lv_obj_align(label_week_number, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 22);
7271
lv_obj_set_style_local_text_color(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
73-
lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40);
72+
lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40.get());
7473
lv_label_set_text_static(label_week_number, "WK26");
7574

7675
label_day_of_year = lv_label_create(lv_scr_act(), nullptr);
7776
lv_obj_align(label_day_of_year, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 30);
7877
lv_obj_set_style_local_text_color(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
79-
lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40);
78+
lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40.get());
8079
lv_label_set_text_static(label_day_of_year, "181-184");
8180

8281
lv_style_init(&style_line);
@@ -107,7 +106,7 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi
107106
label_date = lv_label_create(lv_scr_act(), nullptr);
108107
lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 70);
109108
lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
110-
lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40);
109+
lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40.get());
111110
lv_label_set_text_static(label_date, "6-30");
112111

113112
line_date = lv_line_create(lv_scr_act(), nullptr);
@@ -117,7 +116,7 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi
117116

118117
label_time = lv_label_create(lv_scr_act(), nullptr);
119118
lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
120-
lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment115);
119+
lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment115.get());
121120
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 40);
122121

123122
line_time = lv_line_create(lv_scr_act(), nullptr);
@@ -167,18 +166,6 @@ WatchFaceCasioStyleG7710::~WatchFaceCasioStyleG7710() {
167166
lv_style_reset(&style_line);
168167
lv_style_reset(&style_border);
169168

170-
if (font_dot40 != nullptr) {
171-
free(font_dot40);
172-
}
173-
174-
if (font_segment40 != nullptr) {
175-
free(font_segment40);
176-
}
177-
178-
if (font_segment115 != nullptr) {
179-
free(font_segment115);
180-
}
181-
182169
lv_obj_clean(lv_scr_act());
183170
}
184171

@@ -302,22 +289,17 @@ void WatchFaceCasioStyleG7710::Refresh() {
302289
}
303290

304291
bool WatchFaceCasioStyleG7710::IsAvailable(Pinetime::Controllers::FS& filesystem) {
305-
lfs_file file = {};
292+
lfs_info stat {};
306293

307-
if (filesystem.FileOpen(&file, "/fastfonts/lv_font_dots_40.bin", LFS_O_RDONLY) < 0) {
294+
if (filesystem.Stat("/fastfonts/lv_font_dots_40.bin", &stat) != LFS_ERR_OK) {
308295
return false;
309296
}
310-
311-
filesystem.FileClose(&file);
312-
if (filesystem.FileOpen(&file, "/fastfonts/seven_segments_40.bin", LFS_O_RDONLY) < 0) {
297+
if (filesystem.Stat("/fastfonts/seven_segments_40.bin", &stat) != LFS_ERR_OK) {
313298
return false;
314299
}
315-
316-
filesystem.FileClose(&file);
317-
if (filesystem.FileOpen(&file, "/fastfonts/seven_segments_115.bin", LFS_O_RDONLY) < 0) {
300+
if (filesystem.Stat("/fastfonts/seven_segments_115.bin", &stat) != LFS_ERR_OK) {
318301
return false;
319302
}
320303

321-
filesystem.FileClose(&file);
322304
return true;
323305
}

src/displayapp/screens/WatchFaceCasioStyleG7710.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "components/ble/BleController.h"
1212
#include "utility/DirtyValue.h"
1313
#include "displayapp/apps/Apps.h"
14+
#include "displayapp/fonts/FastFont.h"
1415

1516
namespace Pinetime {
1617
namespace Controllers {
@@ -96,9 +97,9 @@ namespace Pinetime {
9697
Controllers::MotionController& motionController;
9798

9899
lv_task_t* taskRefresh;
99-
lv_font_t* font_dot40 = nullptr;
100-
lv_font_t* font_segment40 = nullptr;
101-
lv_font_t* font_segment115 = nullptr;
100+
Components::FastFont::Font font_dot40;
101+
Components::FastFont::Font font_segment40;
102+
Components::FastFont::Font font_segment115;
102103
};
103104
}
104105

src/displayapp/screens/WatchFaceInfineat.cpp

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "components/ble/BleController.h"
1010
#include "components/ble/NotificationManager.h"
1111
#include "components/motion/MotionController.h"
12-
#include "displayapp/fonts/FastFont.h"
1312

1413
using namespace Pinetime::Applications::Screens;
1514

@@ -192,16 +191,16 @@ WatchFaceInfineat::WatchFaceInfineat(Controllers::DateTime& dateTimeController,
192191

193192
labelHour = lv_label_create(lv_scr_act(), nullptr);
194193
lv_label_set_text_static(labelHour, "01");
195-
lv_obj_set_style_local_text_font(labelHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas);
194+
lv_obj_set_style_local_text_font(labelHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas.get());
196195
lv_obj_align(labelHour, timeContainer, LV_ALIGN_IN_TOP_MID, 0, 0);
197196

198197
labelMinutes = lv_label_create(lv_scr_act(), nullptr);
199-
lv_obj_set_style_local_text_font(labelMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas);
198+
lv_obj_set_style_local_text_font(labelMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas.get());
200199
lv_label_set_text_static(labelMinutes, "00");
201200
lv_obj_align(labelMinutes, timeContainer, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
202201

203202
labelTimeAmPm = lv_label_create(lv_scr_act(), nullptr);
204-
lv_obj_set_style_local_text_font(labelTimeAmPm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko);
203+
lv_obj_set_style_local_text_font(labelTimeAmPm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko.get());
205204

206205
lv_label_set_text_static(labelTimeAmPm, "");
207206
lv_obj_align(labelTimeAmPm, timeContainer, LV_ALIGN_OUT_RIGHT_TOP, 0, 15);
@@ -214,7 +213,7 @@ WatchFaceInfineat::WatchFaceInfineat(Controllers::DateTime& dateTimeController,
214213
static constexpr lv_color_t grayColor = LV_COLOR_MAKE(0x99, 0x99, 0x99);
215214
labelDate = lv_label_create(lv_scr_act(), nullptr);
216215
lv_obj_set_style_local_text_color(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, grayColor);
217-
lv_obj_set_style_local_text_font(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko);
216+
lv_obj_set_style_local_text_font(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko.get());
218217
lv_obj_align(labelDate, dateContainer, LV_ALIGN_IN_TOP_MID, 0, 0);
219218
lv_label_set_text_static(labelDate, "Mon 01");
220219

@@ -225,7 +224,7 @@ WatchFaceInfineat::WatchFaceInfineat(Controllers::DateTime& dateTimeController,
225224

226225
stepValue = lv_label_create(lv_scr_act(), nullptr);
227226
lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, grayColor);
228-
lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko);
227+
lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko.get());
229228
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 10, 0);
230229
lv_label_set_text_static(stepValue, "0");
231230

@@ -296,13 +295,6 @@ WatchFaceInfineat::WatchFaceInfineat(Controllers::DateTime& dateTimeController,
296295
WatchFaceInfineat::~WatchFaceInfineat() {
297296
lv_task_del(taskRefresh);
298297

299-
if (font_bebas != nullptr) {
300-
free(font_bebas);
301-
}
302-
if (font_teko != nullptr) {
303-
free(font_teko);
304-
}
305-
306298
lv_obj_clean(lv_scr_act());
307299
}
308300

@@ -484,22 +476,17 @@ void WatchFaceInfineat::ToggleBatteryIndicatorColor(bool showSideCover) {
484476
}
485477

486478
bool WatchFaceInfineat::IsAvailable(Pinetime::Controllers::FS& filesystem) {
487-
lfs_file file = {};
479+
lfs_info stat {};
488480

489-
if (filesystem.FileOpen(&file, "/fastfonts/teko.bin", LFS_O_RDONLY) < 0) {
481+
if (filesystem.Stat("/fastfonts/teko.bin", &stat) != LFS_ERR_OK) {
490482
return false;
491483
}
492-
493-
filesystem.FileClose(&file);
494-
if (filesystem.FileOpen(&file, "/fastfonts/bebas.bin", LFS_O_RDONLY) < 0) {
484+
if (filesystem.Stat("/fastfonts/bebas.bin", &stat) != LFS_ERR_OK) {
495485
return false;
496486
}
497-
498-
filesystem.FileClose(&file);
499-
if (filesystem.FileOpen(&file, "/images/pine_small.bin", LFS_O_RDONLY) < 0) {
487+
if (filesystem.Stat("/images/pine_small.bin", &stat) != LFS_ERR_OK) {
500488
return false;
501489
}
502490

503-
filesystem.FileClose(&file);
504491
return true;
505492
}

src/displayapp/screens/WatchFaceInfineat.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
#include <lvgl/lvgl.h>
44
#include <chrono>
55
#include <cstdint>
6-
#include <memory>
76
#include <displayapp/Controllers.h>
87
#include "displayapp/screens/Screen.h"
98
#include "components/datetime/DateTimeController.h"
109
#include "utility/DirtyValue.h"
1110
#include "displayapp/apps/Apps.h"
11+
#include "displayapp/fonts/FastFont.h"
1212

1313
namespace Pinetime {
1414
namespace Controllers {
@@ -96,8 +96,8 @@ namespace Pinetime {
9696
void ToggleBatteryIndicatorColor(bool showSideCover);
9797

9898
lv_task_t* taskRefresh;
99-
lv_font_t* font_teko = nullptr;
100-
lv_font_t* font_bebas = nullptr;
99+
Components::FastFont::Font font_teko;
100+
Components::FastFont::Font font_bebas;
101101
};
102102
}
103103

0 commit comments

Comments
 (0)