filled circles, factor out physical size calculations, slightly adjust bottom text

This commit is contained in:
Caleb Connolly 2023-02-19 16:32:31 +00:00
parent 22f07eb624
commit d7e9eca325
No known key found for this signature in database
GPG key ID: 0583312B195F64B6
2 changed files with 108 additions and 70 deletions

View file

@ -21,7 +21,7 @@ void circles_wave(int frame, int w, int y_off, long dpi)
int dist = rad * 3; int dist = rad * 3;
int amplitude = rad * 1; int amplitude = rad * 1;
int left = (w / 2) - (dist * (n_circles - 1) / 2.0); int left = ((float)w / 2) - (dist * (n_circles - 1) / 2.0);
for (unsigned int i = 0; i < n_circles; i++) { for (unsigned int i = 0; i < n_circles; i++) {
int x = left + (i * dist); int x = left + (i * dist);
double offset = sin(f / 60.0 * PI + i); double offset = sin(f / 60.0 * PI + i);
@ -29,9 +29,10 @@ void circles_wave(int frame, int w, int y_off, long dpi)
tfb_fill_rect(x - rad - 3, y_off - amplitude - rad - 3, tfb_fill_rect(x - rad - 3, y_off - amplitude - rad - 3,
rad * 2 + 6, amplitude * 2 + rad * 2 + 6, rad * 2 + 6, amplitude * 2 + rad * 2 + 6,
tfb_black); tfb_black);
tfb_draw_circle(x, y, rad, t_col); tfb_fill_circle(x, y, rad, t_col);
tfb_draw_circle(x, y, rad+1, t_col); // tfb_draw_circle(x, y, rad, t_col);
tfb_draw_circle(x, y, rad+2, t_col); // tfb_draw_circle(x, y, rad+1, t_col);
// tfb_draw_circle(x, y, rad+2, t_col);
} }
} }

View file

@ -23,7 +23,7 @@
#define DEFAULT_FONT_PATH "/usr/share/pbsplash/OpenSans-Regular.svg" #define DEFAULT_FONT_PATH "/usr/share/pbsplash/OpenSans-Regular.svg"
#define LOGO_SIZE_MAX_MM 40 #define LOGO_SIZE_MAX_MM 40
#define FONT_SIZE_PT 9 #define FONT_SIZE_PT 9
#define FONT_SIZE_B_PT 5 #define FONT_SIZE_B_PT 6
#define PT_TO_MM 0.38f #define PT_TO_MM 0.38f
#define TTY_PATH_LEN 11 #define TTY_PATH_LEN 11
@ -159,7 +159,7 @@ static void draw_text(NSVGimage *font, char *text, int x, int y, int width,
* Get the dimensions of a string in pixels. * Get the dimensions of a string in pixels.
* based on the font size and the font SVG file. * based on the font size and the font SVG file.
*/ */
static char* getTextDimensions(NSVGimage *font, char *text, float scale, static char *getTextDimensions(NSVGimage *font, char *text, float scale,
int *width, int *height) int *width, int *height)
{ {
int i; int i;
@ -205,6 +205,66 @@ static char* getTextDimensions(NSVGimage *font, char *text, float scale,
return out_text; return out_text;
} }
struct dpi_info {
long dpi;
int pixels_per_milli;
float logo_size_px;
int logo_size_max_mm;
};
static void calculate_dpi_info(struct dpi_info *info)
{
int w_mm = tfb_screen_width_mm();
int h_mm = tfb_screen_height_mm();
if ((w_mm < 1 || h_mm < 1) && !info->dpi) {
FILE *fp = fopen("/dev/kmsg", "w");
if (fp != NULL) {
fprintf(fp, "PBSPLASH: Invalid screen size: %dx%d\n",
w_mm, h_mm);
fclose(fp);
}
fprintf(stderr, "Invalid screen size: %dx%d\n", w_mm, h_mm);
// Assume a dpi of 300
// This should be readable everywhere
// Except ridiculous HiDPI displays
// which honestly should expose their physical
// dimensions....
info->dpi = 300;
}
// If DPI is specified on cmdline then calculate display size from it
// otherwise calculate the dpi based on the display size.
if (info->dpi > 0) {
w_mm = screenWidth / (float)info->dpi * 25.4;
h_mm = screenHeight / (float)info->dpi * 25.4;
} else {
info->dpi = (float)screenWidth / (float)w_mm * 25.4;
}
info->pixels_per_milli = (float)screenWidth / (float)w_mm;
if (info->logo_size_max_mm * info->pixels_per_milli > screenWidth)
info->logo_size_max_mm = (screenWidth * 0.75f) / info->pixels_per_milli;
info->logo_size_px =
(float)(screenWidth < screenHeight ? screenWidth :
screenHeight) *
0.75f;
if (w_mm > 0 && h_mm > 0) {
if (w_mm < h_mm) {
if (w_mm > info->logo_size_max_mm * 1.2f)
info->logo_size_px = info->logo_size_max_mm * info->pixels_per_milli;
} else {
if (h_mm > info->logo_size_max_mm * 1.2f)
info->logo_size_px = info->logo_size_max_mm * info->pixels_per_milli;
}
}
LOG("%dx%d @ %dx%dmm, dpi=%ld, logo_size_px=%f\n", screenWidth,
screenHeight, w_mm, h_mm, info->dpi, info->logo_size_px);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int rc = 0; int rc = 0;
@ -218,9 +278,13 @@ int main(int argc, char **argv)
struct sigaction action; struct sigaction action;
float font_size = FONT_SIZE_PT; float font_size = FONT_SIZE_PT;
float font_size_b = FONT_SIZE_B_PT; float font_size_b = FONT_SIZE_B_PT;
float logo_size_max = LOGO_SIZE_MAX_MM; struct dpi_info dpi_info = {
.dpi = 0,
.pixels_per_milli = 0,
.logo_size_px = 0,
.logo_size_max_mm = LOGO_SIZE_MAX_MM
};
int optflag; int optflag;
long dpi = 0;
bool animation = true; bool animation = true;
memset(active_tty, '\0', TTY_PATH_LEN); memset(active_tty, '\0', TTY_PATH_LEN);
@ -268,7 +332,7 @@ int main(int argc, char **argv)
} }
break; break;
case 'q': case 'q':
logo_size_max = strtof(optarg, &end); dpi_info.logo_size_max_mm = strtof(optarg, &end);
if (end == optarg) { if (end == optarg) {
fprintf(stderr, "Invalid max logo size: %s\n", fprintf(stderr, "Invalid max logo size: %s\n",
optarg); optarg);
@ -276,10 +340,9 @@ int main(int argc, char **argv)
} }
break; break;
case 'd': case 'd':
dpi = strtol(optarg, &end, 10); dpi_info.dpi = strtol(optarg, &end, 10);
if (end == optarg) { if (end == optarg) {
fprintf(stderr, "Invalid dpi: %s\n", fprintf(stderr, "Invalid dpi: %s\n", optarg);
optarg);
return usage(); return usage();
} }
break; break;
@ -304,7 +367,7 @@ int main(int argc, char **argv)
LOG("active tty: '%s'\n", active_tty); LOG("active tty: '%s'\n", active_tty);
if ((rc = tfb_acquire_fb(/*TFB_FL_NO_TTY_KD_GRAPHICS */0, "/dev/fb0", if ((rc = tfb_acquire_fb(/*TFB_FL_NO_TTY_KD_GRAPHICS */ 0, "/dev/fb0",
active_tty)) != TFB_SUCCESS) { active_tty)) != TFB_SUCCESS) {
fprintf(stderr, "tfb_acquire_fb() failed with error code: %d\n", fprintf(stderr, "tfb_acquire_fb() failed with error code: %d\n",
rc); rc);
@ -315,38 +378,9 @@ int main(int argc, char **argv)
screenWidth = (int)tfb_screen_width(); screenWidth = (int)tfb_screen_width();
screenHeight = (int)tfb_screen_height(); screenHeight = (int)tfb_screen_height();
int w_mm = tfb_screen_width_mm(); calculate_dpi_info(&dpi_info);
int h_mm = tfb_screen_height_mm();
// If DPI is specified on cmdline then calculate display size from it
// otherwise calculate the dpi based on the display size.
if (dpi > 0) {
w_mm = screenWidth / (float)dpi * 25.4;
h_mm = screenHeight / (float)dpi * 25.4;
} else {
dpi = (float)screenWidth / (float)w_mm * 25.4;
}
int pixels_per_milli = (float)screenWidth / (float)w_mm;
if (logo_size_max * pixels_per_milli > screenWidth) image = nsvgParseFromFile(splash_image, "", dpi_info.logo_size_px);
logo_size_max = (screenWidth * 0.75f) / pixels_per_milli;
float logo_size_px = (float)(screenWidth < screenHeight ? screenWidth : screenHeight) * 0.75f;
if (w_mm > 0 && h_mm > 0) {
if (w_mm < h_mm) {
if (w_mm > logo_size_max * 1.2f)
logo_size_px = logo_size_max *
pixels_per_milli;
} else {
if (h_mm > logo_size_max * 1.2f)
logo_size_px = logo_size_max *
pixels_per_milli;
}
}
LOG("%dx%d @ %dx%dmm, dpi=%ld, logo_size_px=%f\n", screenWidth, screenHeight, w_mm, h_mm,
dpi, logo_size_px);
image = nsvgParseFromFile(splash_image, "", logo_size_px);
if (!image) { if (!image) {
fprintf(stderr, "failed to load SVG image\n"); fprintf(stderr, "failed to load SVG image\n");
rc = 1; rc = 1;
@ -354,17 +388,18 @@ int main(int argc, char **argv)
} }
if (image->width < image->height * 1.5) if (image->width < image->height * 1.5)
logo_size_px = MM_TO_PX(dpi, 25); dpi_info.logo_size_px = MM_TO_PX(dpi_info.dpi, 25);
float sz = float sz =
(float)logo_size_px / (float)dpi_info.logo_size_px /
(image->width > image->height ? image->height : image->width); (image->width > image->height ? image->height : image->width);
float image_w = image->width * sz + 0.5; float image_w = image->width * sz + 0.5;
float image_h = image->height * sz + 0.5; float image_h = image->height * sz + 0.5;
if (image_w > (logo_size_max * pixels_per_milli)) { if (image_w > (dpi_info.logo_size_max_mm * dpi_info.pixels_per_milli)) {
float scalefactor = ((float)(logo_size_max * pixels_per_milli)/ image_w); float scalefactor =
((float)(dpi_info.logo_size_max_mm * dpi_info.pixels_per_milli) / image_w);
printf("Got scale factor: %f\n", scalefactor); printf("Got scale factor: %f\n", scalefactor);
image_w = logo_size_max * pixels_per_milli; image_w = dpi_info.logo_size_max_mm * dpi_info.pixels_per_milli;
image_h *= scalefactor; image_h *= scalefactor;
} }
float x = (float)screenWidth / 2; float x = (float)screenWidth / 2;
@ -372,7 +407,7 @@ int main(int argc, char **argv)
// Center the image // Center the image
x -= image_w * 0.5f; x -= image_w * 0.5f;
y -= image_h * 0.5f; y -= image_h * 0.5f;
float animation_y = y + image_h + MM_TO_PX(dpi, 5); float animation_y = y + image_h + MM_TO_PX(dpi_info.dpi, 5);
tfb_clear_screen(tfb_make_color(background_color.r, background_color.g, tfb_clear_screen(tfb_make_color(background_color.r, background_color.g,
background_color.b)); background_color.b));
@ -380,7 +415,8 @@ int main(int argc, char **argv)
draw_svg(image, x, y, image_w, image_h); draw_svg(image, x, y, image_w, image_h);
if (message || message_bottom) { if (message || message_bottom) {
int textWidth, textHeight, bottomTextHeight = MM_TO_PX(dpi, 5); int textWidth, textHeight, bottomTextHeight = MM_TO_PX(dpi_info.dpi, 6);
int bottomTextOffset = MM_TO_PX(dpi_info.dpi, 3);
float fontsz; float fontsz;
int tx, ty; int tx, ty;
@ -394,32 +430,33 @@ int main(int argc, char **argv)
if (message_bottom) { if (message_bottom) {
fontsz = ((float)font_size_b * PT_TO_MM) / fontsz = ((float)font_size_b * PT_TO_MM) /
(font->fontAscent - font->fontDescent) * (font->fontAscent - font->fontDescent) *
pixels_per_milli; dpi_info.pixels_per_milli;
message_bottom = getTextDimensions(font, message_bottom, fontsz, message_bottom = getTextDimensions(font, message_bottom,
&textWidth, &bottomTextHeight); fontsz, &textWidth,
&bottomTextHeight);
tx = screenWidth / 2.f - textWidth / 2.f; tx = screenWidth / 2.f - textWidth / 2.f;
ty = screenHeight - bottomTextHeight - MM_TO_PX(dpi, 2); ty = screenHeight - bottomTextHeight - bottomTextOffset;
draw_text(font, message_bottom, tx, ty, screenWidth, draw_text(font, message_bottom, tx, ty, textWidth,
bottomTextHeight, fontsz, tfb_gray); bottomTextHeight, fontsz, tfb_gray);
} }
if (message) { if (message) {
fontsz = ((float)font_size * PT_TO_MM) / fontsz = ((float)font_size * PT_TO_MM) /
(font->fontAscent - font->fontDescent) * (font->fontAscent - font->fontDescent) *
pixels_per_milli; dpi_info.pixels_per_milli;
LOG("Fontsz: %f\n", fontsz); LOG("Fontsz: %f\n", fontsz);
message = getTextDimensions(font, message, fontsz, &textWidth, message = getTextDimensions(font, message, fontsz,
&textHeight); &textWidth, &textHeight);
tx = screenWidth / 2.f - textWidth / 2.f; tx = screenWidth / 2.f - textWidth / 2.f;
ty = screenHeight - bottomTextHeight - MM_TO_PX(dpi, font_size_b * PT_TO_MM * 2) - textHeight; ty = (screenHeight - bottomTextHeight - bottomTextOffset) -
MM_TO_PX(dpi_info.dpi, font_size_b * PT_TO_MM) -
textHeight;
draw_text(font, message, tx, ty, textWidth, textHeight, fontsz, draw_text(font, message, tx, ty, textWidth, textHeight,
tfb_gray); fontsz, tfb_gray);
} }
} }
tfb_flush_window(); tfb_flush_window();
@ -436,7 +473,7 @@ int main(int argc, char **argv)
sleep(1); sleep(1);
continue; continue;
} }
animate_frame(frame++, screenWidth, animation_y, dpi); animate_frame(frame++, screenWidth, animation_y, dpi_info.dpi);
tfb_flush_fb(); tfb_flush_fb();
} }