in src/terminal/display.c [106:204]
int __guac_terminal_set(guac_terminal_display* display, int row, int col, int codepoint) {
int width;
int bytes;
char utf8[4];
/* Use foreground color */
const guac_terminal_color* color = &display->glyph_foreground;
/* Use background color */
const guac_terminal_color* background = &display->glyph_background;
cairo_surface_t* surface;
cairo_t* cairo;
int surface_width, surface_height;
PangoLayout* layout;
int layout_width, layout_height;
int ideal_layout_width, ideal_layout_height;
/* Calculate width in columns */
width = wcwidth(codepoint);
if (width < 0)
width = 1;
/* Do nothing if glyph is empty */
if (width == 0)
return 0;
/* Convert to UTF-8 */
bytes = guac_terminal_encode_utf8(codepoint, utf8);
surface_width = width * display->char_width;
surface_height = display->char_height;
ideal_layout_width = surface_width * PANGO_SCALE;
ideal_layout_height = surface_height * PANGO_SCALE;
/* Prepare surface */
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
surface_width, surface_height);
cairo = cairo_create(surface);
/* Fill background */
cairo_set_source_rgb(cairo,
background->red / 255.0,
background->green / 255.0,
background->blue / 255.0);
cairo_rectangle(cairo, 0, 0, surface_width, surface_height);
cairo_fill(cairo);
/* Get layout */
layout = pango_cairo_create_layout(cairo);
pango_layout_set_font_description(layout, display->font_desc);
pango_layout_set_text(layout, utf8, bytes);
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
pango_layout_get_size(layout, &layout_width, &layout_height);
/* If layout bigger than available space, scale it back */
if (layout_width > ideal_layout_width || layout_height > ideal_layout_height) {
double scale = fmin(ideal_layout_width / (double) layout_width,
ideal_layout_height / (double) layout_height);
cairo_scale(cairo, scale, scale);
/* Update layout to reflect scaled surface */
pango_layout_set_width(layout, ideal_layout_width / scale);
pango_layout_set_height(layout, ideal_layout_height / scale);
pango_cairo_update_layout(cairo, layout);
}
/* Draw */
cairo_set_source_rgb(cairo,
color->red / 255.0,
color->green / 255.0,
color->blue / 255.0);
cairo_move_to(cairo, 0.0, 0.0);
pango_cairo_show_layout(cairo, layout);
/* Draw */
guac_common_surface_draw(display->display_surface,
display->char_width * col,
display->char_height * row,
surface);
/* Free all */
g_object_unref(layout);
cairo_destroy(cairo);
cairo_surface_destroy(surface);
return 0;
}