summaryrefslogtreecommitdiff
path: root/src/debug/HyprNotificationOverlay.cpp
diff options
context:
space:
mode:
authorgiskard <rtgiskard@gmail.com>2024-05-22 16:09:36 +0800
committerGitHub <noreply@github.com>2024-05-22 10:09:36 +0200
commit93fea890433ec11d7a915f5e0466b2e8b513e895 (patch)
treecee3c8acde01dd29c45d4184917f3596622edeac /src/debug/HyprNotificationOverlay.cpp
parente419ef1873de01b0762f7f1a411994170a4d8cab (diff)
renderer: render fonts with pango, add global `font_family` config option (#6138)
Diffstat (limited to 'src/debug/HyprNotificationOverlay.cpp')
-rw-r--r--src/debug/HyprNotificationOverlay.cpp109
1 files changed, 52 insertions, 57 deletions
diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp
index 80c80601..e1fc810b 100644
--- a/src/debug/HyprNotificationOverlay.cpp
+++ b/src/debug/HyprNotificationOverlay.cpp
@@ -1,6 +1,20 @@
+#include <numeric>
+#include <pango/pangocairo.h>
#include "HyprNotificationOverlay.hpp"
#include "../Compositor.hpp"
-#include <pango/pangocairo.h>
+#include "../config/ConfigValue.hpp"
+
+inline auto iconBackendFromLayout(PangoLayout* layout) {
+ // preference: Nerd > FontAwesome > text
+ auto eIconBackendChecks = std::array<eIconBackend, 2>{ICONS_BACKEND_NF, ICONS_BACKEND_FA};
+ for (auto iconID : eIconBackendChecks) {
+ auto iconsText = std::accumulate(ICONS_ARRAY[iconID].begin(), ICONS_ARRAY[iconID].end(), std::string());
+ pango_layout_set_text(layout, iconsText.c_str(), -1);
+ if (pango_layout_get_unknown_glyphs_count(layout) == 0)
+ return iconID;
+ }
+ return ICONS_BACKEND_NONE;
+}
CHyprNotificationOverlay::CHyprNotificationOverlay() {
static auto P = g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) {
@@ -9,31 +23,6 @@ CHyprNotificationOverlay::CHyprNotificationOverlay() {
g_pHyprRenderer->damageBox(&m_bLastDamage);
});
-
- // check for the icon backend
- std::string fonts = execAndGet("fc-list");
- std::string fontsLower = fonts;
- std::transform(fontsLower.begin(), fontsLower.end(), fontsLower.begin(), [&](char& i) { return std::tolower(i); });
-
- size_t index = 0;
-
- if (index = fontsLower.find("nerd"); index != std::string::npos) {
- m_eIconBackend = ICONS_BACKEND_NF;
- } else if (index = fontsLower.find("font awesome"); index != std::string::npos) {
- m_eIconBackend = ICONS_BACKEND_FA;
- } else if (index = fontsLower.find("fontawesome"); index != std::string::npos) {
- m_eIconBackend = ICONS_BACKEND_FA;
- } else {
- return;
- }
-
- const auto LASTNEWLINE = fonts.find_last_of('\n', index);
- const auto COLON = fonts.find(':', LASTNEWLINE);
- const auto COMMA = fonts.find(',', COLON);
- const auto NEWLINE = fonts.find('\n', COLON);
- const auto LASTCHAR = COMMA < NEWLINE ? COMMA : NEWLINE;
-
- m_szIconFontName = fonts.substr(COLON + 2, LASTCHAR - (COLON + 2));
}
CHyprNotificationOverlay::~CHyprNotificationOverlay() {
@@ -81,25 +70,24 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
float offsetY = 10;
float maxWidth = 0;
- const auto SCALE = pMonitor->scale;
-
+ const auto SCALE = pMonitor->scale;
const auto MONSIZE = pMonitor->vecTransformedSize;
- cairo_text_extents_t cairoExtents;
- int iconW = 0, iconH = 0;
+ static auto fontFamily = CConfigValue<std::string>("misc:font_family");
- cairo_select_font_face(m_pCairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ PangoLayout* layout = pango_cairo_create_layout(m_pCairo);
+ PangoFontDescription* pangoFD = pango_font_description_new();
- const auto PBEZIER = g_pAnimationManager->getBezier("default");
+ pango_font_description_set_family(pangoFD, (*fontFamily).c_str());
+ pango_font_description_set_style(pangoFD, PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight(pangoFD, PANGO_WEIGHT_NORMAL);
- for (auto& notif : m_dNotifications) {
- const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
- const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
+ const auto iconBackendID = iconBackendFromLayout(layout);
+ const auto PBEZIER = g_pAnimationManager->getBezier("default");
- PangoLayout* pangoLayout = pango_cairo_create_layout(m_pCairo);
- PangoFontDescription* pangoFD = pango_font_description_from_string(("Sans " + std::to_string(FONTSIZE * ICON_SCALE)).c_str());
- pango_layout_set_font_description(pangoLayout, pangoFD);
- cairo_set_font_size(m_pCairo, FONTSIZE);
+ for (auto& notif : m_dNotifications) {
+ const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
+ const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
// first rect (bg, col)
const float FIRSTRECTANIMP =
@@ -122,31 +110,37 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
const float THIRDRECTPERC = notif->started.getMillis() / notif->timeMs;
// get text size
- cairo_text_extents(m_pCairo, notif->text.c_str(), &cairoExtents);
- const auto ICON = ICONS_ARRAY[m_eIconBackend][notif->icon];
+ const auto ICON = ICONS_ARRAY[iconBackendID][notif->icon];
const auto ICONCOLOR = ICONS_COLORS[notif->icon];
- pango_layout_set_text(pangoLayout, ICON.c_str(), -1);
- pango_layout_set_font_description(pangoLayout, pangoFD);
- pango_cairo_update_layout(m_pCairo, pangoLayout);
- pango_layout_get_size(pangoLayout, &iconW, &iconH);
+
+ int iconW = 0, iconH = 0;
+ pango_font_description_set_absolute_size(pangoFD, PANGO_SCALE * FONTSIZE * ICON_SCALE);
+ pango_layout_set_font_description(layout, pangoFD);
+ pango_layout_set_text(layout, ICON.c_str(), -1);
+ pango_layout_get_size(layout, &iconW, &iconH);
iconW /= PANGO_SCALE;
iconH /= PANGO_SCALE;
- cairo_set_source_rgba(m_pCairo, notif->color.r, notif->color.g, notif->color.b, notif->color.a);
+ int textW = 0, textH = 0;
+ pango_font_description_set_absolute_size(pangoFD, PANGO_SCALE * FONTSIZE);
+ pango_layout_set_font_description(layout, pangoFD);
+ pango_layout_set_text(layout, notif->text.c_str(), -1);
+ pango_layout_get_size(layout, &textW, &textH);
+ textW /= PANGO_SCALE;
+ textH /= PANGO_SCALE;
- const auto NOTIFSIZE = Vector2D{cairoExtents.width + 20 + iconW + 2 * ICONPADFORNOTIF, cairoExtents.height + 10};
+ const auto NOTIFSIZE = Vector2D{textW + 20 + iconW + 2 * ICONPADFORNOTIF, textH + 10};
// draw rects
+ cairo_set_source_rgba(m_pCairo, notif->color.r, notif->color.g, notif->color.b, notif->color.a);
cairo_rectangle(m_pCairo, MONSIZE.x - (NOTIFSIZE.x + NOTIF_LEFTBAR_SIZE) * FIRSTRECTPERC, offsetY, (NOTIFSIZE.x + NOTIF_LEFTBAR_SIZE) * FIRSTRECTPERC, NOTIFSIZE.y);
cairo_fill(m_pCairo);
cairo_set_source_rgb(m_pCairo, 0.f, 0.f, 0.f);
-
cairo_rectangle(m_pCairo, MONSIZE.x - NOTIFSIZE.x * SECONDRECTPERC, offsetY, NOTIFSIZE.x * SECONDRECTPERC, NOTIFSIZE.y);
cairo_fill(m_pCairo);
cairo_set_source_rgba(m_pCairo, notif->color.r, notif->color.g, notif->color.b, notif->color.a);
-
cairo_rectangle(m_pCairo, MONSIZE.x - NOTIFSIZE.x * SECONDRECTPERC + 3, offsetY + NOTIFSIZE.y - 4, THIRDRECTPERC * (NOTIFSIZE.x - 6), 2);
cairo_fill(m_pCairo);
@@ -164,26 +158,27 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
// draw icon
cairo_set_source_rgb(m_pCairo, 1.f, 1.f, 1.f);
- cairo_move_to(m_pCairo, MONSIZE.x - NOTIFSIZE.x * SECONDRECTPERC + NOTIF_LEFTBAR_SIZE + ICONPADFORNOTIF - 1, offsetY + std::round((NOTIFSIZE.y - iconH - 4) / 2.0));
- pango_cairo_show_layout(m_pCairo, pangoLayout);
+ cairo_move_to(m_pCairo, MONSIZE.x - NOTIFSIZE.x * SECONDRECTPERC + NOTIF_LEFTBAR_SIZE + ICONPADFORNOTIF - 1, offsetY - 2 + std::round((NOTIFSIZE.y - iconH) / 2.0));
+ pango_layout_set_text(layout, ICON.c_str(), -1);
+ pango_cairo_show_layout(m_pCairo, layout);
}
// draw text
- cairo_set_font_size(m_pCairo, FONTSIZE);
cairo_set_source_rgb(m_pCairo, 1.f, 1.f, 1.f);
- cairo_move_to(m_pCairo, MONSIZE.x - NOTIFSIZE.x * SECONDRECTPERC + NOTIF_LEFTBAR_SIZE + iconW + 2 * ICONPADFORNOTIF, offsetY + FONTSIZE + (FONTSIZE / 10.0));
- cairo_show_text(m_pCairo, notif->text.c_str());
+ cairo_move_to(m_pCairo, MONSIZE.x - NOTIFSIZE.x * SECONDRECTPERC + NOTIF_LEFTBAR_SIZE + iconW + 2 * ICONPADFORNOTIF, offsetY - 2 + std::round((NOTIFSIZE.y - textH) / 2.0));
+ pango_layout_set_text(layout, notif->text.c_str(), -1);
+ pango_cairo_show_layout(m_pCairo, layout);
// adjust offset and move on
offsetY += NOTIFSIZE.y + 10;
if (maxWidth < NOTIFSIZE.x)
maxWidth = NOTIFSIZE.x;
-
- pango_font_description_free(pangoFD);
- g_object_unref(pangoLayout);
}
+ pango_font_description_free(pangoFD);
+ g_object_unref(layout);
+
// cleanup notifs
std::erase_if(m_dNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; });