summaryrefslogtreecommitdiffstats
path: root/src/gui.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/gui.cpp106
1 files changed, 82 insertions, 24 deletions
diff --git a/src/gui.cpp b/src/gui.cpp
index b512ef3..417860f 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -39,6 +39,8 @@ static unsigned long g_font_title = 0;
39static int g_body_h = 15; 39static int g_body_h = 15;
40static int g_title_h = 20; 40static int g_title_h = 20;
41static float g_font_scale = 0.0f; 41static float g_font_scale = 0.0f;
42static void *g_font_local = (void *)-1;
43static bool g_font_fail_logged = false;
42static int g_scr_w = 0, g_scr_h = 0; 44static int g_scr_w = 0, g_scr_h = 0;
43 45
44static void s_color(int r, int g, int b, int a) { 46static void s_color(int r, int g, int b, int a) {
@@ -485,41 +487,97 @@ bool gui_toasts_active() {
485 return active; 487 return active;
486} 488}
487 489
488static void ensure_fonts() { 490static bool font_valid(unsigned long f) {
489 if (g_font_body && fabsf(g_font_scale - g_scale) < 0.001f) 491 if (!f || !g_surface)
490 return; 492 return false;
491 g_font_scale = g_scale; 493 int w = 0, h = 0;
492 g_body_h = (int)(15.0f * g_scale + 0.5f); 494 s_text_size(f, L"M", w, h);
493 g_title_h = (int)(20.0f * g_scale + 0.5f); 495 return w > 0 && h > 0;
494 if (g_body_h < 11) g_body_h = 11; 496}
495 if (g_title_h < 15) g_title_h = 15; 497
498static void gui_reset_fonts() {
499 g_font_body = 0;
500 g_font_title = 0;
501 g_font_scale = 0.0f;
502}
503
504static unsigned long create_gui_font(int tall) {
496 static const char *families[] = {"Liberation Sans", "DejaVu Sans", 505 static const char *families[] = {"Liberation Sans", "DejaVu Sans",
497 "Noto Sans", "Tahoma", "Verdana", "Arial", 506 "Noto Sans", "Tahoma", "Verdana", "Arial",
498 nullptr}; 507 nullptr};
508 for (int i = 0; families[i]; i++) {
509 unsigned long f = s_create_font();
510 if (!f)
511 break;
512 if (s_set_font(f, families[i], tall, 400, 0x400, 0x20, 0xFF) &&
513 font_valid(f))
514 return f;
515 }
516 return 0;
517}
518
519static void ensure_fonts() {
520 void *le = nullptr;
521 if (g_iface.engine && g_iface.entitylist) {
522 int local = engine_get_local_player();
523 if (local > 0)
524 le = entitylist_get(local);
525 }
526 if (le != g_font_local) {
527 g_font_local = le;
528 gui_reset_fonts();
529 }
530
531 bool scale_changed = fabsf(g_font_scale - g_scale) >= 0.001f;
532 if (g_font_body && g_font_title && !scale_changed &&
533 font_valid(g_font_body) && font_valid(g_font_title))
534 return;
535 // Level transitions can silently invalidate VGUI font handles. Recreate
536 // them instead of drawing invisible text.
537 if ((g_font_body && !font_valid(g_font_body)) ||
538 (g_font_title && !font_valid(g_font_title)))
539 gui_reset_fonts();
540 if (scale_changed)
541 gui_reset_fonts();
542
543 g_font_scale = g_scale;
544 int req_body = (int)(15.0f * g_scale + 0.5f);
545 int req_title = (int)(20.0f * g_scale + 0.5f);
546 if (req_body < 11) req_body = 11;
547 if (req_title < 15) req_title = 15;
548 g_body_h = req_body;
549 g_title_h = req_title;
550
551 if (!g_font_body)
552 g_font_body = create_gui_font(g_body_h);
553 if (!g_font_title)
554 g_font_title = create_gui_font(g_title_h);
555
556 // Small scaled sizes can fail in the font manager; 16 px is the proven ESP
557 // size, so use it as a readable fallback.
499 if (!g_font_body) { 558 if (!g_font_body) {
500 for (int i = 0; families[i] && !g_font_body; i++) { 559 g_body_h = 16;
501 unsigned long f = s_create_font(); 560 g_font_body = create_gui_font(g_body_h);
502 if (!f)
503 break;
504 if (s_set_font(f, families[i], g_body_h, 400, 0x400, 0x20, 0xFF))
505 g_font_body = f;
506 }
507 } 561 }
508 if (!g_font_title) { 562 if (!g_font_title) {
509 for (int i = 0; families[i] && !g_font_title; i++) { 563 g_title_h = 16;
510 unsigned long f = s_create_font(); 564 g_font_title = create_gui_font(g_title_h);
511 if (!f)
512 break;
513 if (s_set_font(f, families[i], g_title_h, 400, 0x400, 0x20, 0xFF))
514 g_font_title = f;
515 }
516 } 565 }
517 if (!g_font_title) 566 if (!g_font_title)
518 g_font_title = g_font_body; 567 g_font_title = g_font_body;
568
519 if (!g_font_body) { 569 if (!g_font_body) {
520 logf("gui: no usable body font"); 570 if (!g_font_fail_logged) {
521 toastf(TOAST_ERROR, "No usable GUI font"); 571 g_font_fail_logged = true;
572 logf("gui: no usable body font");
573 toastf(TOAST_ERROR, "No usable GUI font");
574 }
575 return;
522 } 576 }
577 g_font_fail_logged = false;
578 if (g_body_h != req_body || g_title_h != req_title)
579 logd("gui: font fallback body=%d title=%d (requested %d/%d)", g_body_h,
580 g_title_h, req_body, req_title);
523} 581}
524 582
525static int text_w(const char *s, int tall) { 583static int text_w(const char *s, int tall) {