clutter/canvas: Implement clutter_canvas_{get,set}_scale_factor

https://bugzilla.gnome.org/show_bug.cgi?id=765011
https://gitlab.gnome.org/GNOME/mutter/merge_requests/3
This commit is contained in:
Marco Trevisan (Treviño) 2017-07-31 14:21:05 +02:00 committed by Marco Trevisan
parent d3beb3ddb7
commit 02813d74e1
2 changed files with 89 additions and 6 deletions

View File

@ -44,6 +44,7 @@
#include "clutter-build-config.h" #include "clutter-build-config.h"
#include <math.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <cairo-gobject.h> #include <cairo-gobject.h>
@ -69,6 +70,7 @@ struct _ClutterCanvasPrivate
int width; int width;
int height; int height;
float scale_factor;
CoglTexture *texture; CoglTexture *texture;
gboolean dirty; gboolean dirty;
@ -82,6 +84,7 @@ enum
PROP_WIDTH, PROP_WIDTH,
PROP_HEIGHT, PROP_HEIGHT,
PROP_SCALE_FACTOR,
LAST_PROP LAST_PROP
}; };
@ -178,6 +181,19 @@ clutter_canvas_set_property (GObject *gobject,
} }
break; break;
case PROP_SCALE_FACTOR:
{
gfloat new_scale_factor = g_value_get_float (value);
if (priv->scale_factor != new_scale_factor)
{
priv->scale_factor = new_scale_factor;
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
}
}
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break; break;
@ -202,6 +218,10 @@ clutter_canvas_get_property (GObject *gobject,
g_value_set_int (value, priv->height); g_value_set_int (value, priv->height);
break; break;
case PROP_SCALE_FACTOR:
g_value_set_float (value, priv->scale_factor);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break; break;
@ -245,6 +265,19 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS); G_PARAM_STATIC_STRINGS);
/**
* ClutterCanvas:scale-factor:
*
* The height of the canvas.
*/
obj_props[PROP_SCALE_FACTOR] =
g_param_spec_float ("scale-factor",
P_("Scale Factor"),
P_("The Scale factor of the canvas"),
0.01f, G_MAXFLOAT,
1.0f,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/** /**
* ClutterCanvas::draw: * ClutterCanvas::draw:
@ -291,6 +324,7 @@ clutter_canvas_init (ClutterCanvas *self)
self->priv->width = -1; self->priv->width = -1;
self->priv->height = -1; self->priv->height = -1;
self->priv->scale_factor = 1.0f;
} }
static void static void
@ -340,8 +374,8 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
priv->dirty = TRUE; priv->dirty = TRUE;
real_width = priv->width; real_width = ceilf (priv->width * priv->scale_factor);
real_height = priv->height; real_height = ceilf (priv->height * priv->scale_factor);
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d", CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d",
priv->width, priv->height); priv->width, priv->height);
@ -387,6 +421,10 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
mapped_buffer = FALSE; mapped_buffer = FALSE;
} }
cairo_surface_set_device_scale (surface,
priv->scale_factor,
priv->scale_factor);
self->priv->cr = cr = cairo_create (surface); self->priv->cr = cr = cairo_create (surface);
g_signal_emit (self, canvas_signals[DRAW], 0, g_signal_emit (self, canvas_signals[DRAW], 0,
@ -448,10 +486,10 @@ clutter_canvas_get_preferred_size (ClutterContent *content,
return FALSE; return FALSE;
if (width != NULL) if (width != NULL)
*width = priv->width; *width = ceilf (priv->width * priv->scale_factor);
if (height != NULL) if (height != NULL)
*height = priv->height; *height = ceilf (priv->height * priv->scale_factor);
return TRUE; return TRUE;
} }
@ -560,3 +598,48 @@ clutter_canvas_set_size (ClutterCanvas *canvas,
return clutter_canvas_invalidate_internal (canvas, width, height); return clutter_canvas_invalidate_internal (canvas, width, height);
} }
/**
* clutter_canvas_set_scale_factor:
* @canvas: a #ClutterCanvas
* @scale: the integer scaling factor of the canvas
*
* Sets the scaling factor of the @canvas, and invalidates the content.
*
* This function will cause the @canvas to be invalidated only
* if the scale factor of the canvas surface has changed.
*/
void
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
float scale)
{
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (scale >= 1.0f);
if (canvas->priv->scale_factor != scale)
{
canvas->priv->scale_factor = scale;
g_object_freeze_notify (G_OBJECT (canvas));
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
g_object_thaw_notify (G_OBJECT (canvas));
g_object_notify_by_pspec (G_OBJECT (canvas), obj_props[PROP_SCALE_FACTOR]);
}
}
/**
* clutter_canvas_get_scale_factor:
* @canvas: a #ClutterCanvas
*
* Gets the scale factor of the @canvas.
*
* Return value: the current @canvas scale factor or -1 if invalid
*/
float
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
{
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1.0f);
return canvas->priv->scale_factor;
}

View File

@ -97,9 +97,9 @@ gboolean clutter_canvas_set_size (ClutterCanvas *
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_canvas_set_scale_factor (ClutterCanvas *canvas, void clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
int scale); float scale);
CLUTTER_EXPORT CLUTTER_EXPORT
int clutter_canvas_get_scale_factor (ClutterCanvas *canvas); float clutter_canvas_get_scale_factor (ClutterCanvas *canvas);
G_END_DECLS G_END_DECLS