Merge branch 'simplify-rendering' into 'master'

Simplify layout and rendering

See merge request Librem5/squeekboard!102
This commit is contained in:
Dorota Czaplejewicz
2019-07-31 09:10:57 +00:00
5 changed files with 54 additions and 152 deletions

View File

@ -57,9 +57,6 @@ typedef struct _EekGtkKeyboardPrivate
EekKeyboard *keyboard; EekKeyboard *keyboard;
EekTheme *theme; EekTheme *theme;
int origin_x;
int origin_y;
GdkEventSequence *sequence; // unowned reference GdkEventSequence *sequence; // unowned reference
} EekGtkKeyboardPrivate; } EekGtkKeyboardPrivate;
@ -111,9 +108,6 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
gtk_widget_get_allocation (self, &allocation); gtk_widget_get_allocation (self, &allocation);
cairo_save (cr);
cairo_translate (cr, priv->origin_x, priv->origin_y);
if (!priv->renderer) { if (!priv->renderer) {
PangoContext *pcontext; PangoContext *pcontext;
@ -131,8 +125,6 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
eek_renderer_render_keyboard (priv->renderer, cr); eek_renderer_render_keyboard (priv->renderer, cr);
cairo_restore (cr);
/* redraw pressed key */ /* redraw pressed key */
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (priv->keyboard);
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
@ -157,9 +149,6 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
EekGtkKeyboardPrivate *priv = EekGtkKeyboardPrivate *priv =
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self)); eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
priv->origin_x = (allocation->width - 360) / 2;
priv->origin_y = 0;
if (priv->renderer) if (priv->renderer)
eek_renderer_set_allocation_size (priv->renderer, eek_renderer_set_allocation_size (priv->renderer,
allocation->width, allocation->width,
@ -172,8 +161,7 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
static void depress(EekGtkKeyboard *self, static void depress(EekGtkKeyboard *self,
gdouble x, gdouble y, guint32 time) { gdouble x, gdouble y, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
x - priv->origin_x, y - priv->origin_y);
if (key) { if (key) {
eek_keyboard_press_key(priv->keyboard, key, time); eek_keyboard_press_key(priv->keyboard, key, time);
@ -184,8 +172,7 @@ static void depress(EekGtkKeyboard *self,
static void drag(EekGtkKeyboard *self, static void drag(EekGtkKeyboard *self,
gdouble x, gdouble y, guint32 time) { gdouble x, gdouble y, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
x - priv->origin_x, y - priv->origin_y);
if (key) { if (key) {
GList *list, *head; GList *list, *head;
@ -501,13 +488,13 @@ render_pressed_key (GtkWidget *widget,
cairo_region_t *region = gdk_window_get_clip_region (window); cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context); cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
gdouble scale = eek_renderer_get_scale (priv->renderer);
cairo_translate (cr, priv->origin_x, priv->origin_y);
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
magnify_bounds (widget, &bounds, &large_bounds, 1.5); magnify_bounds (widget, &bounds, &large_bounds, 1.5);
cairo_save (cr); cairo_save (cr);
cairo_scale (cr, scale, scale);
cairo_translate (cr, bounds.x, bounds.y); cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE); eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
cairo_restore (cr); cairo_restore (cr);
@ -534,13 +521,15 @@ render_locked_key (GtkWidget *widget,
cairo_region_t *region = gdk_window_get_clip_region (window); cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context); cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
gdouble scale = eek_renderer_get_scale (priv->renderer);
cairo_translate (cr, priv->origin_x, priv->origin_y);
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE); eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
cairo_save (cr);
cairo_scale (cr, scale, scale);
cairo_translate (cr, bounds.x, bounds.y); cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE); eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
cairo_restore (cr);
gdk_window_end_draw_frame (window, context); gdk_window_end_draw_frame (window, context);
@ -560,11 +549,6 @@ render_released_key (GtkWidget *widget,
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context); cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
cairo_translate (cr, priv->origin_x, priv->origin_y);
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
eek_renderer_render_keyboard (priv->renderer, cr); eek_renderer_render_keyboard (priv->renderer, cr);
gdk_window_end_draw_frame (window, context); gdk_window_end_draw_frame (window, context);

View File

@ -129,60 +129,8 @@ eek_layout_place_sections(EekKeyboard *keyboard)
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds); eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
} }
static void scale_bounds_callback (EekElement *element,
gpointer user_data);
static void
scale_bounds (EekElement *element,
gdouble scale)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.x *= scale;
bounds.y *= scale;
bounds.width *= scale;
bounds.height *= scale;
eek_element_set_bounds (element, &bounds);
if (EEK_IS_CONTAINER(element))
eek_container_foreach_child (EEK_CONTAINER(element),
scale_bounds_callback,
&scale);
}
static void
scale_bounds_callback (EekElement *element,
gpointer user_data)
{
scale_bounds (element, *(gdouble *)user_data);
}
void
eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale)
{
gsize n_outlines;
scale_bounds (EEK_ELEMENT(keyboard), scale);
n_outlines = eek_keyboard_get_n_outlines (keyboard);
for (guint i = 0; i < n_outlines; i++) {
EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
gint j;
for (j = 0; j < outline->num_points; j++) {
outline->points[j].x *= scale;
outline->points[j].y *= scale;
}
}
keyboard->scale = scale;
}
void void
eek_layout_update_layout(EekKeyboard *keyboard) eek_layout_update_layout(EekKeyboard *keyboard)
{ {
eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
eek_layout_place_sections(keyboard); eek_layout_place_sections(keyboard);
eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
} }

View File

@ -57,8 +57,6 @@ GType eek_layout_get_type (void) G_GNUC_CONST;
void eek_layout_place_sections(EekKeyboard *keyboard); void eek_layout_place_sections(EekKeyboard *keyboard);
void eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale);
void eek_layout_update_layout(EekKeyboard *keyboard); void eek_layout_update_layout(EekKeyboard *keyboard);
G_END_DECLS G_END_DECLS

View File

@ -49,6 +49,8 @@ typedef struct _EekRendererPrivate
gdouble allocation_height; gdouble allocation_height;
gdouble scale; gdouble scale;
gint scale_factor; /* the outputs scale factor */ gint scale_factor; /* the outputs scale factor */
gint origin_x;
gint origin_y;
PangoFontDescription *ascii_font; PangoFontDescription *ascii_font;
PangoFontDescription *font; PangoFontDescription *font;
@ -111,12 +113,12 @@ create_keyboard_surface_key_callback (EekElement *element,
cairo_save (data->cr); cairo_save (data->cr);
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
cairo_translate (data->cr, bounds.x * priv->scale, bounds.y * priv->scale); cairo_translate (data->cr, bounds.x, bounds.y);
cairo_rectangle (data->cr, cairo_rectangle (data->cr,
0.0, 0.0,
0.0, 0.0,
bounds.width * priv->scale + 100, bounds.width + 100,
bounds.height * priv->scale + 100); bounds.height + 100);
cairo_clip (data->cr); cairo_clip (data->cr);
render_key (data->renderer, data->cr, EEK_KEY(element), FALSE); render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
@ -135,7 +137,7 @@ create_keyboard_surface_section_callback (EekElement *element,
cairo_save (data->cr); cairo_save (data->cr);
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
cairo_translate (data->cr, bounds.x * priv->scale, bounds.y * priv->scale); cairo_translate (data->cr, bounds.x, bounds.y);
angle = eek_section_get_angle (EEK_SECTION(element)); angle = eek_section_get_angle (EEK_SECTION(element));
cairo_rotate (data->cr, angle * G_PI / 180); cairo_rotate (data->cr, angle * G_PI / 180);
@ -167,7 +169,9 @@ render_keyboard_surface (EekRenderer *renderer)
data.cr = cairo_create (priv->keyboard_surface); data.cr = cairo_create (priv->keyboard_surface);
data.renderer = renderer; data.renderer = renderer;
cairo_translate (data.cr, bounds.x * priv->scale, bounds.y * priv->scale); cairo_save (data.cr);
cairo_scale (data.cr, priv->scale, priv->scale);
cairo_translate (data.cr, bounds.x, bounds.y);
/* blank background */ /* blank background */
cairo_set_source_rgba (data.cr, cairo_set_source_rgba (data.cr,
@ -187,6 +191,8 @@ render_keyboard_surface (EekRenderer *renderer)
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard), eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
create_keyboard_surface_section_callback, create_keyboard_surface_section_callback,
&data); &data);
cairo_restore (data.cr);
cairo_destroy (data.cr); cairo_destroy (data.cr);
} }
@ -243,14 +249,7 @@ render_key_outline (EekRenderer *renderer,
eek_element_get_bounds(EEK_ELEMENT(key), &bounds); eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
outline = eek_outline_copy (outline); outline = eek_outline_copy (outline);
for (guint i = 0; i < outline->num_points; i++) { cairo_translate (cr, border_width, border_width);
outline->points[i].x *= priv->scale;
outline->points[i].y *= priv->scale;
}
cairo_translate (cr,
border_width * priv->scale,
border_width * priv->scale);
if (gradient_type != EEK_GRADIENT_NONE) { if (gradient_type != EEK_GRADIENT_NONE) {
cairo_pattern_t *pat; cairo_pattern_t *pat;
@ -261,17 +260,17 @@ render_key_outline (EekRenderer *renderer,
pat = cairo_pattern_create_linear (0.0, pat = cairo_pattern_create_linear (0.0,
0.0, 0.0,
0.0, 0.0,
bounds.height * priv->scale); bounds.height);
break; break;
case EEK_GRADIENT_HORIZONTAL: case EEK_GRADIENT_HORIZONTAL:
pat = cairo_pattern_create_linear (0.0, pat = cairo_pattern_create_linear (0.0,
0.0, 0.0,
bounds.width * priv->scale, bounds.width,
0.0); 0.0);
break; break;
case EEK_GRADIENT_RADIAL: case EEK_GRADIENT_RADIAL:
cx = bounds.width / 2 * priv->scale; cx = bounds.width / 2;
cy = bounds.height / 2 * priv->scale; cy = bounds.height / 2;
pat = cairo_pattern_create_radial (cx, pat = cairo_pattern_create_radial (cx,
cy, cy,
0, 0,
@ -328,9 +327,7 @@ render_key_outline (EekRenderer *renderer,
outline->num_points); outline->num_points);
cairo_stroke (cr); cairo_stroke (cr);
cairo_translate (cr, cairo_translate (cr, -border_width, -border_width);
-border_width * priv->scale,
-border_width * priv->scale);
eek_outline_free (outline); eek_outline_free (outline);
} }
@ -447,8 +444,6 @@ render_key (EekRenderer *self,
/* render outline */ /* render outline */
eek_element_get_bounds (EEK_ELEMENT(key), &bounds); eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
bounds.width *= priv->scale;
bounds.height *= priv->scale;
if (active) if (active)
outline_surface_cache = priv->active_outline_surface_cache; outline_surface_cache = priv->active_outline_surface_cache;
@ -644,7 +639,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
priv->font); priv->font);
pango_font_description_set_size (font, pango_font_description_set_size (font,
pango_font_description_get_size (font) * pango_font_description_get_size (font) *
prop->scale * priv->scale * scale); prop->scale * scale);
pango_layout_set_font_description (layout, font); pango_layout_set_font_description (layout, font);
pango_font_description_free (font); pango_font_description_free (font);
@ -653,7 +648,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
if (line->resolved_dir == PANGO_DIRECTION_RTL) if (line->resolved_dir == PANGO_DIRECTION_RTL)
pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
pango_layout_set_width (layout, pango_layout_set_width (layout,
PANGO_SCALE * bounds.width * priv->scale * scale); PANGO_SCALE * bounds.width * scale);
if (prop->ellipses) if (prop->ellipses)
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
} }
@ -678,7 +673,10 @@ eek_renderer_real_render_key (EekRenderer *self,
gdouble scale, gdouble scale,
gboolean rotate) gboolean rotate)
{ {
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
cairo_save (cr); cairo_save (cr);
cairo_translate (cr, priv->origin_x, priv->origin_y);
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate); eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key)); render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
cairo_restore (cr); cairo_restore (cr);
@ -695,6 +693,10 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
g_return_if_fail (priv->allocation_width > 0.0); g_return_if_fail (priv->allocation_width > 0.0);
g_return_if_fail (priv->allocation_height > 0.0); g_return_if_fail (priv->allocation_height > 0.0);
cairo_save (cr);
cairo_translate (cr, priv->origin_x, priv->origin_y);
if (priv->keyboard_surface) if (priv->keyboard_surface)
cairo_surface_destroy (priv->keyboard_surface); cairo_surface_destroy (priv->keyboard_surface);
@ -708,6 +710,8 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
source = cairo_get_source (cr); source = cairo_get_source (cr);
cairo_pattern_set_extend (source, CAIRO_EXTEND_PAD); cairo_pattern_set_extend (source, CAIRO_EXTEND_PAD);
cairo_paint (cr); cairo_paint (cr);
cairo_restore (cr);
} }
static void static void
@ -923,21 +927,19 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
priv->allocation_width = width; priv->allocation_width = width;
priv->allocation_height = height; priv->allocation_height = height;
/* Calculate a scale factor to use when rendering the keyboard into the
available space. */
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
if (bounds.height * width / bounds.width <= height) gdouble w = (bounds.x * 2) + bounds.width;
scale = width / bounds.width; gdouble h = (bounds.y * 2) + bounds.height;
else if (bounds.width * height / bounds.height <= width)
scale = height / bounds.height; scale = MIN(width / w, height / h);
else {
if (bounds.width * height < bounds.height * width)
scale = bounds.width / width;
else
scale = bounds.height / height;
}
if (scale != priv->scale) { if (scale != priv->scale) {
priv->scale = scale; priv->scale = scale;
priv->origin_x = 0;
priv->origin_y = 0;
invalidate (renderer); invalidate (renderer);
} }
} }
@ -955,9 +957,9 @@ eek_renderer_get_size (EekRenderer *renderer,
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
if (width) if (width)
*width = bounds.width * priv->scale; *width = bounds.width;
if (height) if (height)
*height = bounds.height * priv->scale; *height = bounds.height;
} }
void void
@ -988,10 +990,6 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
if (!rotate) { if (!rotate) {
bounds->x += keyboard_bounds.x + section_bounds.x; bounds->x += keyboard_bounds.x + section_bounds.x;
bounds->y += keyboard_bounds.y + section_bounds.y; bounds->y += keyboard_bounds.y + section_bounds.y;
bounds->x *= priv->scale;
bounds->y *= priv->scale;
bounds->width *= priv->scale;
bounds->height *= priv->scale;
return; return;
} }
points[0].x = bounds->x; points[0].x = bounds->x;
@ -1023,10 +1021,6 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
bounds->y = keyboard_bounds.y + section_bounds.y + min.y; bounds->y = keyboard_bounds.y + section_bounds.y + min.y;
bounds->width = (max.x - min.x); bounds->width = (max.x - min.x);
bounds->height = (max.y - min.y); bounds->height = (max.y - min.y);
bounds->x *= priv->scale;
bounds->y *= priv->scale;
bounds->width *= priv->scale;
bounds->height *= priv->scale;
} }
gdouble gdouble
@ -1274,8 +1268,6 @@ find_key_by_position_key_callback (EekElement *element,
eek_point_rotate (&points[i], data->angle); eek_point_rotate (&points[i], data->angle);
points[i].x += data->origin.x; points[i].x += data->origin.x;
points[i].y += data->origin.y; points[i].y += data->origin.y;
points[i].x *= priv->scale;
points[i].y *= priv->scale;
} }
b1 = sign (&data->point, &points[0], &points[1]) < 0.0; b1 = sign (&data->point, &points[0], &points[1]) < 0.0;
@ -1331,13 +1323,17 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL); g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
x /= priv->scale;
y /= priv->scale;
x -= priv->origin_x;
y -= priv->origin_y;
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
if (x < bounds.x * priv->scale || if (x < bounds.x ||
y < bounds.y * priv->scale || y < bounds.y ||
x > bounds.width * priv->scale || x > bounds.width ||
y > bounds.height * priv->scale) y > bounds.height)
return NULL; return NULL;
data.point.x = x; data.point.x = x;

View File

@ -79,10 +79,6 @@ static gboolean parse_symbols (const gchar *path,
EekKeyboard *keyboard, EekKeyboard *keyboard,
GError **error); GError **error);
static void scale_keyboard (EekKeyboard *keyboard,
gdouble width,
gdouble height);
static gboolean validate (const gchar **valid_path_list, static gboolean validate (const gchar **valid_path_list,
gsize valid_path_list_len, gsize valid_path_list_len,
const gchar *element_name, const gchar *element_name,
@ -946,9 +942,6 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
eek_layout_place_sections(keyboard); eek_layout_place_sections(keyboard);
/* Fit keyboard in the given width and height. */
scale_keyboard (keyboard, initial_width, initial_height);
/* Use pre-defined modifier mask here. */ /* Use pre-defined modifier mask here. */
eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK); eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK); eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
@ -1358,23 +1351,6 @@ parse_keyboards (const gchar *path, GError **error)
return keyboards; return keyboards;
} }
static void scale_keyboard (EekKeyboard *keyboard,
gdouble width,
gdouble height)
{
gdouble scale;
EekBounds bounds;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
if (width * bounds.height < height * bounds.width)
scale = width / bounds.width;
else
scale = height / bounds.height;
eek_layout_scale_keyboard(keyboard, scale);
}
static gboolean static gboolean
validate (const gchar **valid_path_list, validate (const gchar **valid_path_list,
gsize valid_path_list_len, gsize valid_path_list_len,