diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 6c369e1e..26996e89 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -121,6 +121,7 @@ set(SOURCES src/egl_dynprocs.c src/eglutil.c src/overlay_utils.c + src/overlay_utils.cpp src/overlay/fps.c src/overlay/graphs.c diff --git a/client/include/overlay_utils.h b/client/include/overlay_utils.h index 1906f5fe..4ef7994e 100644 --- a/client/include/overlay_utils.h +++ b/client/include/overlay_utils.h @@ -23,6 +23,15 @@ #include "common/types.h" +#ifdef __cplusplus +extern "C" { +#endif + void overlayGetImGuiRect(struct Rect * rect); +void imGuiResetStyle(void); + +#ifdef __cplusplus +} +#endif #endif diff --git a/client/include/util.h b/client/include/util.h index f1124a54..8936ee85 100644 --- a/client/include/util.h +++ b/client/include/util.h @@ -46,4 +46,7 @@ static inline double util_clamp(double x, double min, double max) return x; } +#define DEFAULT_FONT_NAME "DejaVu Sans Mono" +char * util_getUIFont(const char * fontName); + #endif diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index fffbae36..3591f6b0 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -504,6 +504,10 @@ void egl_on_resize(void * opaque, const int width, const int height, const doubl damage->count = 0; free(atomic_exchange(&this->desktopDamage, damage)); + // this is needed to refresh the font atlas texture + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplOpenGL3_NewFrame(); + egl_damage_resize(this->damage, this->translateX, this->translateY, this->scaleX, this->scaleY); } diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 11e74539..60299b92 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -354,6 +354,10 @@ void opengl_on_resize(void * opaque, const int width, const int height, const do 1.0f ); } + + // this is needed to refresh the font atlas texture + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplOpenGL2_NewFrame(); } bool opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, diff --git a/client/src/app.c b/client/src/app.c index d94933b1..8c793b8e 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -677,14 +677,6 @@ int app_renderOverlay(struct Rect * rects, int maxRects) const int written = overlay->ops->render(overlay->udata, false, buffer, MAX_OVERLAY_RECTS); - for (int i = 0; i < written; ++i) - { - buffer[i].x *= g_state.windowScale; - buffer[i].y *= g_state.windowScale; - buffer[i].w *= g_state.windowScale; - buffer[i].h *= g_state.windowScale; - } - // It is an error to run out of rectangles, because we will not be able to // correctly calculate the damage of the next frame. assert(written >= 0); diff --git a/client/src/main.c b/client/src/main.c index f8d63fa6..e67dfadc 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -56,6 +56,8 @@ #include "ll.h" #include "egl_dynprocs.h" #include "overlays.h" +#include "overlay_utils.h" +#include "util.h" // forwards static int cursorThread(void * unused); @@ -180,14 +182,18 @@ static int renderThread(void * unused) if (resize) { g_state.io->DisplaySize = (ImVec2) { - .x = g_state.windowW, - .y = g_state.windowH - }; - g_state.io->DisplayFramebufferScale = (ImVec2) { - .x = g_state.windowScale, - .y = g_state.windowScale, + .x = g_state.windowW * g_state.windowScale, + .y = g_state.windowH * g_state.windowScale }; + imGuiResetStyle(); + ImGuiStyle_ScaleAllSizes(g_state.style, g_state.windowScale); + + ImFontAtlas_Clear(g_state.io->Fonts); + ImFontAtlas_AddFontFromFileTTF(g_state.io->Fonts, g_state.fontName, + 14 * g_state.windowScale, NULL, NULL); + ImFontAtlas_Build(g_state.io->Fonts); + if (g_state.lgr) g_state.lgr->on_resize(g_state.lgrData, g_state.windowW, g_state.windowH, g_state.windowScale, g_state.dstRect, g_params.winRotate); @@ -755,12 +761,18 @@ static int lg_run(void) /* setup imgui */ igCreateContext(NULL); - g_state.io = igGetIO(); + g_state.io = igGetIO(); + g_state.style = igGetStyle(); + unsigned char *text_pixels = NULL; int text_w, text_h; ImFontAtlas_GetTexDataAsRGBA32(g_state.io->Fonts, &text_pixels, &text_w, &text_h, NULL); + g_state.windowScale = 1.0; + g_state.fontName = util_getUIFont(DEFAULT_FONT_NAME); + DEBUG_INFO("Using font: %s", g_state.fontName); + g_state.overlays = ll_new(); app_registerOverlay(&LGOverlayFPS , NULL); app_registerOverlay(&LGOverlayGraphs, NULL); @@ -1149,6 +1161,7 @@ static void lg_shutdown(void) ringbuffer_free(&g_state.renderTimings); ringbuffer_free(&g_state.frameTimings ); + free(g_state.fontName); igDestroyContext(NULL); } diff --git a/client/src/main.h b/client/src/main.h index 61443169..34994671 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -47,8 +47,10 @@ struct AppState { enum RunState state; - ImGuiIO * io; - struct ll * overlays; + ImGuiIO * io; + ImGuiStyle * style; + struct ll * overlays; + char * fontName; struct LG_DisplayServerOps * ds; bool dsInitialized; diff --git a/client/src/overlay/graphs.c b/client/src/overlay/graphs.c index 21cee688..a82f2435 100644 --- a/client/src/overlay/graphs.c +++ b/client/src/overlay/graphs.c @@ -93,6 +93,8 @@ static int graphs_render(void * udata, bool interactive, if (!g_state.showTiming) return 0; + float fontSize = igGetFontSize(); + ImVec2 pos = {0.0f, 0.0f}; igSetNextWindowBgAlpha(0.4f); igSetNextWindowPos(pos, 0, pos); @@ -121,7 +123,7 @@ static int graphs_render(void * udata, bool interactive, } char title[64]; - const ImVec2 size = {400.0f, 100.0f}; + const ImVec2 size = {28.0f * fontSize, 7.0f * fontSize}; snprintf(title, sizeof(title), "%s: min:%4.2f max:%4.2f avg:%4.2f/%4.2fHz", diff --git a/client/src/overlay_utils.cpp b/client/src/overlay_utils.cpp new file mode 100644 index 00000000..75bbe4f3 --- /dev/null +++ b/client/src/overlay_utils.cpp @@ -0,0 +1,28 @@ +/** + * Looking Glass + * Copyright (C) 2017-2021 The Looking Glass Authors + * https://looking-glass.io + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "overlay_utils.h" + +#include "imgui.h" + +void imGuiResetStyle(void) +{ + ImGui::GetStyle() = ImGuiStyle(); +} diff --git a/client/src/util.c b/client/src/util.c index b6293ea1..d4493054 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -29,6 +29,7 @@ #include #include #include +#include bool util_fileGetContents(const char * filename, char ** buffer, size_t * length) { @@ -258,3 +259,48 @@ int util_mergeOverlappingRects(FrameDamageRect * out, const FrameDamageRect * re out[o++] = out[i]; return o; } + +char * util_getUIFont(const char * fontName) +{ + static FcConfig * fc = NULL; + char * ttf = NULL; + + if (!fc) + fc = FcInitLoadConfigAndFonts(); + + if (!fc) + { + DEBUG_ERROR("FcInitLoadConfigAndFonts Failed"); + return NULL; + } + + FcPattern * pat = FcNameParse((const FcChar8*) fontName); + if (!pat) + { + DEBUG_ERROR("FCNameParse failed"); + return NULL; + } + + FcConfigSubstitute(fc, pat, FcMatchPattern); + FcDefaultSubstitute(pat); + FcResult result; + FcChar8 * file = NULL; + FcPattern * match = FcFontMatch(fc, pat, &result); + + if (!match) + { + DEBUG_ERROR("FcFontMatch Failed"); + goto fail_parse; + } + + if (FcPatternGetString(match, FC_FILE, 0, &file) == FcResultMatch) + ttf = strdup((char *) file); + else + DEBUG_ERROR("Failed to locate the requested font: %s", fontName); + + FcPatternDestroy(match); + +fail_parse: + FcPatternDestroy(pat); + return ttf; +}