You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/11/11 19:04:45 UTC

[2/3] guacamole-server git commit: GUACAMOLE-630: Separate setting of font family/size from terminal display initialization.

GUACAMOLE-630: Separate setting of font family/size from terminal display initialization.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/9e28de70
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/9e28de70
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/9e28de70

Branch: refs/heads/master
Commit: 9e28de70ec43e6a260177242fa5de9347cfbd66b
Parents: 0cf2421
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Oct 7 23:38:03 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Sat Nov 10 14:22:23 2018 -0800

----------------------------------------------------------------------
 src/terminal/display.c           | 127 ++++++++++++++++++++++++----------
 src/terminal/terminal.c          |  32 +++++++++
 src/terminal/terminal/display.h  |  30 ++++++++
 src/terminal/terminal/terminal.h |  38 ++++++++++
 4 files changed, 190 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/display.c
----------------------------------------------------------------------
diff --git a/src/terminal/display.c b/src/terminal/display.c
index 1c803b4..d148b41 100644
--- a/src/terminal/display.c
+++ b/src/terminal/display.c
@@ -206,15 +206,15 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
         guac_terminal_color* foreground, guac_terminal_color* background,
         guac_terminal_color (*palette)[256]) {
 
-    PangoFontMap* font_map;
-    PangoFont* font;
-    PangoFontMetrics* metrics;
-    PangoContext* context;
-
     /* Allocate display */
     guac_terminal_display* display = malloc(sizeof(guac_terminal_display));
     display->client = client;
 
+    /* Initially no font loaded */
+    display->font_desc = NULL;
+    display->char_width = 0;
+    display->char_height = 0;
+
     /* Create default surface */
     display->display_layer = guac_client_alloc_layer(client);
     display->select_layer = guac_client_alloc_layer(client);
@@ -225,42 +225,10 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
     guac_protocol_send_move(client->socket, display->select_layer,
             display->display_layer, 0, 0, 0);
 
-    /* Get font */
-    display->font_desc = pango_font_description_new();
-    pango_font_description_set_family(display->font_desc, font_name);
-    pango_font_description_set_weight(display->font_desc, PANGO_WEIGHT_NORMAL);
-    pango_font_description_set_size(display->font_desc,
-            font_size * PANGO_SCALE * dpi / 96);
-
-    font_map = pango_cairo_font_map_get_default();
-    context = pango_font_map_create_context(font_map);
-
-    font = pango_font_map_load_font(font_map, context, display->font_desc);
-    if (font == NULL) {
-        guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to get font \"%s\"", font_name);
-        free(display);
-        return NULL;
-    }
-
-    metrics = pango_font_get_metrics(font, NULL);
-    if (metrics == NULL) {
-        guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
-                "Unable to get font metrics for font \"%s\"", font_name);
-        free(display);
-        return NULL;
-    }
-
     display->default_foreground = display->glyph_foreground = *foreground;
     display->default_background = display->glyph_background = *background;
     display->default_palette = palette;
 
-    /* Calculate character dimensions */
-    display->char_width =
-        pango_font_metrics_get_approximate_digit_width(metrics) / PANGO_SCALE;
-    display->char_height =
-        (pango_font_metrics_get_descent(metrics)
-            + pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE;
-
     /* Initially empty */
     display->width = 0;
     display->height = 0;
@@ -269,12 +237,23 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client,
     /* Initially nothing selected */
     display->text_selected = false;
 
+    /* Attempt to load font */
+    if (guac_terminal_display_set_font(display, font_name, font_size, dpi)) {
+        guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+                "Unable to set initial font \"%s\"", font_name);
+        free(display);
+        return NULL;
+    }
+
     return display;
 
 }
 
 void guac_terminal_display_free(guac_terminal_display* display) {
 
+    /* Free font description */
+    pango_font_description_free(display->font_desc);
+
     /* Free default palette. */
     free(display->default_palette);
 
@@ -966,4 +945,78 @@ void guac_terminal_display_clear_select(guac_terminal_display* display) {
 
 }
 
+int guac_terminal_display_set_font(guac_terminal_display* display,
+        const char* font_name, int font_size, int dpi) {
+
+    PangoFontDescription* font_desc;
+
+    /* Build off existing font description if possible */
+    if (display->font_desc != NULL)
+        font_desc = pango_font_description_copy(display->font_desc);
+
+    /* Create new font description if there is nothing to copy */
+    else {
+        font_desc = pango_font_description_new();
+        pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL);
+    }
+
+    /* Optionally update font name */
+    if (font_name != NULL)
+        pango_font_description_set_family(font_desc, font_name);
+
+    /* Optionally update size */
+    if (font_size != -1) {
+        pango_font_description_set_size(font_desc,
+                font_size * PANGO_SCALE * dpi / 96);
+    }
+
+    PangoFontMap* font_map = pango_cairo_font_map_get_default();
+    PangoContext* context = pango_font_map_create_context(font_map);
+
+    /* Load font from font map */
+    PangoFont* font = pango_font_map_load_font(font_map, context, font_desc);
+    if (font == NULL) {
+        guac_client_log(display->client, GUAC_LOG_INFO, "Unable to load "
+                "font \"%s\"", pango_font_description_get_family(font_desc));
+        pango_font_description_free(font_desc);
+        return 1;
+    }
+
+    /* Get metrics from loaded font */
+    PangoFontMetrics* metrics = pango_font_get_metrics(font, NULL);
+    if (metrics == NULL) {
+        guac_client_log(display->client, GUAC_LOG_INFO, "Unable to get font "
+                "metrics for font \"%s\"",
+                pango_font_description_get_family(font_desc));
+        pango_font_description_free(font_desc);
+        return 1;
+    }
+
+    /* Save effective size of current display */
+    int pixel_width = display->width * display->char_width;
+    int pixel_height = display->height * display->char_height;
+
+    /* Calculate character dimensions using metrics */
+    display->char_width =
+        pango_font_metrics_get_approximate_digit_width(metrics) / PANGO_SCALE;
+    display->char_height =
+        (pango_font_metrics_get_descent(metrics)
+            + pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE;
+
+    /* Atomically replace old font description */
+    PangoFontDescription* old_font_desc = display->font_desc;
+    display->font_desc = font_desc;
+    pango_font_description_free(old_font_desc);
+
+    /* Recalculate dimensions which will fit within current surface */
+    int new_width = pixel_width / display->char_width;
+    int new_height = pixel_height / display->char_height;
+
+    /* Resize display if dimensions have changed */
+    if (new_width != display->width || new_height != display->height)
+        guac_terminal_display_resize(display, new_width, new_height);
+
+    return 0;
+
+}
 

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/terminal.c
----------------------------------------------------------------------
diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c
index 1984185..cf70f92 100644
--- a/src/terminal/terminal.c
+++ b/src/terminal/terminal.c
@@ -360,6 +360,10 @@ guac_terminal* guac_terminal_create(guac_client* client,
     term->upload_path_handler = NULL;
     term->file_download_handler = NULL;
 
+    /* Set size of available screen area */
+    term->outer_width = width;
+    term->outer_height = height;
+
     /* Init modified flag and conditional */
     term->modified = 0;
     pthread_cond_init(&(term->modified_cond), NULL);
@@ -1338,6 +1342,10 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) {
     /* Acquire exclusive access to terminal */
     guac_terminal_lock(terminal);
 
+    /* Set size of available screen area */
+    terminal->outer_width = width;
+    terminal->outer_height = height;
+
     /* Calculate available display area */
     int available_width = width - GUAC_TERMINAL_SCROLLBAR_WIDTH;
     if (available_width < 0)
@@ -1968,3 +1976,27 @@ void guac_terminal_apply_color_scheme(guac_terminal* terminal,
 
 }
 
+void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
+        int font_size, int dpi) {
+
+    guac_client* client = terminal->client;
+    guac_terminal_display* display = terminal->display;
+
+    if (guac_terminal_display_set_font(display, font_name, font_size, dpi))
+        return;
+
+    /* Resize terminal to fit available region, now that font metrics may be
+     * different */
+    guac_terminal_resize(terminal, terminal->outer_width,
+            terminal->outer_height);
+
+    /* Redraw terminal text and background */
+    guac_terminal_repaint_default_layer(terminal, client->socket);
+    __guac_terminal_redraw_rect(terminal, 0, 0,
+            terminal->term_height - 1,
+            terminal->term_width - 1);
+
+    guac_terminal_notify(terminal);
+
+}
+

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/terminal/display.h
----------------------------------------------------------------------
diff --git a/src/terminal/terminal/display.h b/src/terminal/terminal/display.h
index b127423..5377cb1 100644
--- a/src/terminal/terminal/display.h
+++ b/src/terminal/terminal/display.h
@@ -334,5 +334,35 @@ void guac_terminal_display_select(guac_terminal_display* display,
  */
 void guac_terminal_display_clear_select(guac_terminal_display* display);
 
+/**
+ * Alters the font of the terminal display. The available display area and the
+ * regular grid of character cells will be resized as necessary to compensate
+ * for any changes in font metrics.
+ *
+ * If successful, the terminal itself MUST be manually resized to take into
+ * account the new character dimensions, and MUST be manually redrawn. Failing
+ * to do so will result in graphical artifacts.
+ *
+ * @param display
+ *     The display whose font family and/or size are being changed.
+ *
+ * @param font_name
+ *     The name of the new font family, or NULL if the font family should
+ *     remain unchanged.
+ *
+ * @param font_size
+ *     The new font size, in points, or -1 if the font size should remain
+ *     unchanged.
+ *
+ * @param dpi
+ *     The resolution of the display in DPI. If the font size will not be
+ *     changed (the font size given is -1), this value is ignored.
+ *
+ * @return
+ *     Zero if the font was successfully changed, non-zero otherwise.
+ */
+int guac_terminal_display_set_font(guac_terminal_display* display,
+        const char* font_name, int font_size, int dpi);
+
 #endif
 

http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/9e28de70/src/terminal/terminal/terminal.h
----------------------------------------------------------------------
diff --git a/src/terminal/terminal/terminal.h b/src/terminal/terminal/terminal.h
index 28085f6..ac1217e 100644
--- a/src/terminal/terminal/terminal.h
+++ b/src/terminal/terminal/terminal.h
@@ -278,6 +278,20 @@ struct guac_terminal {
     int requested_scrollback;
 
     /**
+     * The width of the space available to all components of the terminal, in
+     * pixels. This may include space which will not actually be used for
+     * character rendering.
+     */
+    int outer_width;
+
+    /**
+     * The height of the space available to all components of the terminal, in
+     * pixels. This may include space which will not actually be used for
+     * character rendering.
+     */
+    int outer_height;
+
+    /**
      * The width of the terminal, in pixels.
      */
     int width;
@@ -1086,5 +1100,29 @@ int guac_terminal_available_scroll(guac_terminal* term);
 void guac_terminal_apply_color_scheme(guac_terminal* terminal,
         const char* color_scheme);
 
+/**
+ * Alters the font of the terminal. The terminal will automatically be redrawn
+ * and resized as necessary. If the terminal size changes, the remote side of
+ * the terminal session must be manually informed of that change or graphical
+ * artifacts may result.
+ *
+ * @param terminal
+ *     The terminal whose font family and/or size are being changed.
+ *
+ * @param font_name
+ *     The name of the new font family, or NULL if the font family should
+ *     remain unchanged.
+ *
+ * @param font_size
+ *     The new font size, in points, or -1 if the font size should remain
+ *     unchanged.
+ *
+ * @param dpi
+ *     The resolution of the display in DPI. If the font size will not be
+ *     changed (the font size given is -1), this value is ignored.
+ */
+void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
+        int font_size, int dpi);
+
 #endif