[gtk] gsk: Add GskMatrixCategory
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] gsk: Add GskMatrixCategory
- Date: Thu, 21 Feb 2019 18:50:40 +0000 (UTC)
commit 70a1233a282df3b3d89d2b40d7a5c5f101805862
Author: Benjamin Otte <otte redhat com>
Date: Tue Feb 19 06:52:36 2019 +0100
gsk: Add GskMatrixCategory
We'll use that soon.
gsk/gskrendernodeimpl.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
gsk/gskrendernodeprivate.h | 43 +++++++++++++++++++++++++++++++++++++++++++
gtk/inspector/recorder.c | 9 +++++++++
3 files changed, 94 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 8b704aedda..34dd509d1f 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -2387,6 +2387,7 @@ struct _GskTransformNode
GskRenderNode *child;
graphene_matrix_t transform;
+ GskMatrixCategory category;
};
static void
@@ -2422,7 +2423,7 @@ gsk_transform_node_draw (GskRenderNode *node,
}
}
-#define GSK_TRANSFORM_NODE_VARIANT_TYPE "(dddddddddddddddduv)"
+#define GSK_TRANSFORM_NODE_VARIANT_TYPE "(idddddddddddddddduv)"
static GVariant *
gsk_transform_node_serialize (GskRenderNode *node)
@@ -2433,6 +2434,7 @@ gsk_transform_node_serialize (GskRenderNode *node)
graphene_matrix_to_float (&self->transform, mat);
return g_variant_new (GSK_TRANSFORM_NODE_VARIANT_TYPE,
+ self->category,
(double) mat[0], (double) mat[1], (double) mat[2], (double) mat[3],
(double) mat[4], (double) mat[5], (double) mat[6], (double) mat[7],
(double) mat[8], (double) mat[9], (double) mat[10], (double) mat[11],
@@ -2448,6 +2450,7 @@ gsk_transform_node_deserialize (GVariant *variant,
graphene_matrix_t transform;
double mat[16];
guint32 child_type;
+ gint32 category;
GVariant *child_variant;
GskRenderNode *result, *child;
@@ -2455,6 +2458,7 @@ gsk_transform_node_deserialize (GVariant *variant,
return NULL;
g_variant_get (variant, GSK_TRANSFORM_NODE_VARIANT_TYPE,
+ &category,
&mat[0], &mat[1], &mat[2], &mat[3],
&mat[4], &mat[5], &mat[6], &mat[7],
&mat[8], &mat[9], &mat[10], &mat[11],
@@ -2475,7 +2479,7 @@ gsk_transform_node_deserialize (GVariant *variant,
mat[12], mat[13], mat[14], mat[15]
});
- result = gsk_transform_node_new (child, &transform);
+ result = gsk_transform_node_new_with_category (child, &transform, category);
gsk_render_node_unref (child);
@@ -2508,15 +2512,39 @@ GskRenderNode *
gsk_transform_node_new (GskRenderNode *child,
const graphene_matrix_t *transform)
{
- GskTransformNode *self;
-
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
g_return_val_if_fail (transform != NULL, NULL);
+ return gsk_transform_node_new_with_category (child, transform, GSK_MATRIX_CATEGORY_UNKNOWN);
+}
+
+/*<private>
+ * gsk_transform_node_new_with_category:
+ * @child: The node to transform
+ * @transform: The transform to apply
+ * @category: The category @transform belongs to
+ *
+ * Creates a #GskRenderNode that will transform the given @child
+ * with the given @transform.
+ *
+ * The given @category will be used by renderers for optimizations and must
+ * be correct. If you do not know the category of @transform, use
+ * %GSK_MATRIX_CATEGORY_UNKNOWN.
+ *
+ * Returns: A new #GskRenderNode
+ **/
+GskRenderNode *
+gsk_transform_node_new_with_category (GskRenderNode *child,
+ const graphene_matrix_t *transform,
+ GskMatrixCategory category)
+{
+ GskTransformNode *self;
+
self = (GskTransformNode *) gsk_render_node_new (&GSK_TRANSFORM_NODE_CLASS, 0);
self->child = gsk_render_node_ref (child);
graphene_matrix_init_from_matrix (&self->transform, transform);
+ self->category = category;
graphene_matrix_transform_bounds (&self->transform,
&child->bounds,
@@ -2552,6 +2580,16 @@ gsk_transform_node_peek_transform (GskRenderNode *node)
return &self->transform;
}
+GskMatrixCategory
+gsk_transform_node_get_category (GskRenderNode *node)
+{
+ GskTransformNode *self = (GskTransformNode *) node;
+
+ g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_TRANSFORM_NODE), GSK_MATRIX_CATEGORY_UNKNOWN);
+
+ return self->category;
+}
+
/*** GSK_OFFSET_NODE ***/
typedef struct _GskOffsetNode GskOffsetNode;
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 145fec0955..1f0565cfab 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -6,6 +6,44 @@
G_BEGIN_DECLS
+/*<private>
+ * GskMatrixCategory:
+ * @GSK_MATRIX_CATEGORY_UNKNOWN: The category of the matrix has not been
+ * determined.
+ * @GSK_MATRIX_CATEGORY_ANY: Analyzing the matrix concluded that it does
+ * not fit in any other category.
+ * @GSK_MATRIX_CATEGORY_INVERTIBLE: The matrix is linear independant and
+ * should therefor be invertible. Note that this is not guaranteed
+ * to actually be true due to rounding errors when inverting.
+ * @GSK_MATRIX_CATEGORY_2D: The matrix is a 2D matrix. This is equivalent
+ * to graphene_matrix_is_2d() returning %TRUE. In particular, this
+ * means that Cairo can deal with the matrix.
+ * @GSK_MATRIX_CATEGORY_2D_AFFINE: The matrix is a combination of 2D scale
+ * and 2D translation operations. In particular, this means that any
+ * rectangle can be transformed exactly using this matrix.
+ * @GSK_MATRIX_CATEGORY_2D_TRANSLATE: The matrix is a 2D translation.
+ * @GSK_MATRIX_CATEGORY_IDENTITY: The matrix is the identity matrix.
+ *
+ * The categories of matrices relevant for GSK and GTK. Note that any
+ * category includes matrices of all later categories. So if you want
+ * to for example check if a matrix is a 2D matrix,
+ * `category >= GSK_MATRIX_CATEGORY_2D` is the way to do this.
+ *
+ * Also keep in mind that rounding errors may cause matrices to not
+ * conform to their categories. Otherwise, matrix operations done via
+ * mutliplication will not worsen categories. So for the matrix
+ * multiplication `C = A * B`, `category(C) = MIN (category(A), category(B))`.
+ */
+typedef enum
+{
+ GSK_MATRIX_CATEGORY_UNKNOWN,
+ GSK_MATRIX_CATEGORY_ANY,
+ GSK_MATRIX_CATEGORY_INVERTIBLE,
+ GSK_MATRIX_CATEGORY_2D_AFFINE,
+ GSK_MATRIX_CATEGORY_2D_TRANSLATE,
+ GSK_MATRIX_CATEGORY_IDENTITY
+} GskMatrixCategory;
+
typedef struct _GskRenderNodeClass GskRenderNodeClass;
#define GSK_IS_RENDER_NODE_TYPE(node,type) (GSK_IS_RENDER_NODE (node) && (node)->node_class->node_type ==
(type))
@@ -58,6 +96,11 @@ GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType typ
GskRenderNode * gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds,
cairo_surface_t *surface);
+GskRenderNode * gsk_transform_node_new_with_category (GskRenderNode *child,
+ const graphene_matrix_t *transform,
+ GskMatrixCategory category);
+GskMatrixCategory gsk_transform_node_get_category (GskRenderNode *node);
+
GskRenderNode * gsk_text_node_new_with_bounds (PangoFont *font,
PangoGlyphString *glyphs,
const GdkRGBA *color,
diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c
index 26ae9cbdd2..0a56aefb8a 100644
--- a/gtk/inspector/recorder.c
+++ b/gtk/inspector/recorder.c
@@ -901,6 +901,14 @@ populate_render_node_properties (GtkListStore *store,
case GSK_TRANSFORM_NODE:
{
+ static const char * category_names[] = {
+ [GSK_MATRIX_CATEGORY_UNKNOWN] = "unknown",
+ [GSK_MATRIX_CATEGORY_ANY] = "any",
+ [GSK_MATRIX_CATEGORY_INVERTIBLE] = "invertible",
+ [GSK_MATRIX_CATEGORY_2D_AFFINE] = "2D affine",
+ [GSK_MATRIX_CATEGORY_2D_TRANSLATE] = "2D transform",
+ [GSK_MATRIX_CATEGORY_IDENTITY] = "identity"
+ };
float f[16];
guint i;
@@ -913,6 +921,7 @@ populate_render_node_properties (GtkListStore *store,
add_text_row (store, i == 0 ? "Matrix" : "", row_string);
g_free (row_string);
}
+ add_text_row (store, "Category", category_names[gsk_transform_node_get_category (node)]);
}
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]