1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
23 * @short_description: The base class for renderable objects
25 * This abstract class provides a base interface for all renderable objects
26 * (all the objects that can be printed or viewed).
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
37 #include "adg-entity.h"
38 #include "adg-entity-private.h"
39 #include "adg-canvas.h"
40 #include "adg-context.h"
63 static void get_property (GObject
*object
,
67 static void set_property (GObject
*object
,
71 static void dispose (GObject
*object
);
72 static AdgContainer
* get_parent (AdgEntity
*entity
);
73 static void set_parent (AdgEntity
*entity
,
74 AdgContainer
*parent
);
75 static void parent_set (AdgEntity
*entity
,
76 AdgContainer
*old_parent
);
77 static AdgContext
* get_context (AdgEntity
*entity
);
78 static void set_context (AdgEntity
*entity
,
80 static void set_global_map (AdgEntity
*entity
,
81 const AdgMatrix
*map
);
82 static void set_local_map (AdgEntity
*entity
,
83 const AdgMatrix
*map
);
84 static void model_matrix_changed (AdgEntity
*entity
,
85 AdgMatrix
*parent_matrix
);
86 static void paper_matrix_changed (AdgEntity
*entity
,
87 AdgMatrix
*parent_matrix
);
88 static void render (AdgEntity
*entity
,
90 static const AdgMatrix
*get_model_matrix (AdgEntity
*entity
);
91 static const AdgMatrix
*get_paper_matrix (AdgEntity
*entity
);
93 static guint signals
[LAST_SIGNAL
] = { 0 };
96 G_DEFINE_ABSTRACT_TYPE(AdgEntity
, adg_entity
, G_TYPE_INITIALLY_UNOWNED
);
100 adg_entity_class_init(AdgEntityClass
*klass
)
102 GObjectClass
*gobject_class
;
105 gobject_class
= (GObjectClass
*) klass
;
107 g_type_class_add_private(klass
, sizeof(AdgEntityPrivate
));
109 gobject_class
->get_property
= get_property
;
110 gobject_class
->set_property
= set_property
;
111 gobject_class
->dispose
= dispose
;
113 klass
->get_parent
= get_parent
;
114 klass
->set_parent
= set_parent
;
115 klass
->parent_set
= parent_set
;
116 klass
->get_context
= get_context
;
117 klass
->model_matrix_changed
= model_matrix_changed
;
118 klass
->paper_matrix_changed
= paper_matrix_changed
;
119 klass
->invalidate
= NULL
;
120 klass
->render
= render
;
121 klass
->get_model_matrix
= get_model_matrix
;
122 klass
->get_paper_matrix
= get_paper_matrix
;
124 param
= g_param_spec_object("parent",
125 P_("Parent Container"),
126 P_("The parent AdgContainer of this entity or NULL if this is a top-level entity"),
127 ADG_TYPE_CONTAINER
, G_PARAM_READWRITE
);
128 g_object_class_install_property(gobject_class
, PROP_PARENT
, param
);
130 param
= g_param_spec_object("context",
132 P_("The context associated to this entity or NULL to inherit the parent context"),
133 ADG_TYPE_CONTEXT
, G_PARAM_READWRITE
);
134 g_object_class_install_property(gobject_class
, PROP_CONTEXT
, param
);
136 param
= g_param_spec_boxed("global-map",
138 P_("The transformation to be combined with the parent ones to get the global matrix"),
139 ADG_TYPE_MATRIX
, G_PARAM_READWRITE
);
140 g_object_class_install_property(gobject_class
, PROP_GLOBAL_MAP
, param
);
142 param
= g_param_spec_boxed("local-map",
144 P_("The transformation to be combined with the parent ones to get the local matrix"),
145 ADG_TYPE_MATRIX
, G_PARAM_READWRITE
);
146 g_object_class_install_property(gobject_class
, PROP_LOCAL_MAP
, param
);
149 * AdgEntity::parent-set:
150 * @entity: an #AdgEntity
151 * @parent: the #AdgContainer parent of @entity
153 * Emitted after the parent container has changed.
155 signals
[PARENT_SET
] =
156 g_signal_new("parent-set",
157 G_OBJECT_CLASS_TYPE(gobject_class
),
159 G_STRUCT_OFFSET(AdgEntityClass
, parent_set
),
161 g_cclosure_marshal_VOID__OBJECT
,
162 G_TYPE_NONE
, 1, ADG_TYPE_CONTAINER
);
165 * AdgEntity::model-matrix-changed:
166 * @entity: an #AdgEntity
167 * @parent_matrix: the parent model matrix
169 * Emitted after the current model matrix has changed.
171 signals
[MODEL_MATRIX_CHANGED
] =
172 g_signal_new("model-matrix-changed",
173 G_OBJECT_CLASS_TYPE(gobject_class
),
175 G_STRUCT_OFFSET(AdgEntityClass
, model_matrix_changed
),
177 g_cclosure_marshal_VOID__BOXED
,
179 ADG_TYPE_MATRIX
| G_SIGNAL_TYPE_STATIC_SCOPE
);
182 * AdgEntity::paper-matrix-changed:
183 * @entity: an #AdgEntity
184 * @parent_matrix: the parent paper matrix
186 * Emitted after the current paper matrix has changed.
188 signals
[PAPER_MATRIX_CHANGED
] =
189 g_signal_new("paper-matrix-changed",
190 G_OBJECT_CLASS_TYPE(gobject_class
),
192 G_STRUCT_OFFSET(AdgEntityClass
, paper_matrix_changed
),
194 g_cclosure_marshal_VOID__BOXED
,
196 ADG_TYPE_MATRIX
| G_SIGNAL_TYPE_STATIC_SCOPE
);
199 * AdgEntity::invalidate:
200 * @entity: an #AdgEntity
202 * Clears the cached data of @entity.
204 signals
[INVALIDATE
] =
205 g_signal_new("invalidate",
206 G_OBJECT_CLASS_TYPE(gobject_class
),
208 G_STRUCT_OFFSET(AdgEntityClass
, invalidate
),
210 g_cclosure_marshal_VOID__BOOLEAN
,
215 * @entity: an #AdgEntity
216 * @cr: a #cairo_t drawing context
218 * Causes the rendering of @entity on @cr.
221 g_signal_new("render",
222 G_OBJECT_CLASS_TYPE(gobject_class
),
224 G_STRUCT_OFFSET(AdgEntityClass
, render
),
226 g_cclosure_marshal_VOID__POINTER
,
227 G_TYPE_NONE
, 1, G_TYPE_POINTER
);
231 adg_entity_init(AdgEntity
*entity
)
233 AdgEntityPrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(entity
,
238 data
->context
= NULL
;
239 cairo_matrix_init_identity(&data
->local_map
);
240 cairo_matrix_init_identity(&data
->global_map
);
246 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
249 AdgEntityPrivate
*data
;
251 entity
= (AdgEntity
*) object
;
256 g_value_set_object(value
, get_parent(entity
));
259 g_value_set_object(value
, get_context(entity
));
261 case PROP_GLOBAL_MAP
:
262 g_value_set_boxed(value
, &data
->global_map
);
265 g_value_set_boxed(value
, &data
->local_map
);
268 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
274 set_property(GObject
*object
,
275 guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
277 AdgEntity
*entity
= (AdgEntity
*) object
;
281 set_parent(entity
, g_value_get_object(value
));
284 set_context(entity
, g_value_get_object(value
));
286 case PROP_GLOBAL_MAP
:
287 set_global_map(entity
, g_value_get_boxed(value
));
290 set_local_map(entity
, g_value_get_boxed(value
));
293 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
299 dispose(GObject
*object
)
302 AdgEntityPrivate
*data
;
303 GObjectClass
*object_class
;
305 entity
= (AdgEntity
*) object
;
307 object_class
= (GObjectClass
*) adg_entity_parent_class
;
310 adg_container_remove(data
->parent
, entity
);
312 if (object_class
->dispose
!= NULL
)
313 object_class
->dispose(object
);
318 * adg_entity_get_parent:
319 * @entity: an #AdgEntity
321 * Gets the container parent of @entity.
323 * This function is only useful in entity implementations.
325 * Return value: the container object or %NULL if @entity is not contained
328 adg_entity_get_parent(AdgEntity
*entity
)
330 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
332 return ADG_ENTITY_GET_CLASS(entity
)->get_parent(entity
);
336 * adg_entity_set_parent:
337 * @entity: an #AdgEntity
338 * @parent: an #AdgContainer
340 * Sets a new container of @entity.
342 * This function is only useful in entity implementations.
345 adg_entity_set_parent(AdgEntity
*entity
, AdgContainer
*parent
)
347 g_return_if_fail(ADG_IS_ENTITY(entity
));
349 ADG_ENTITY_GET_CLASS(entity
)->set_parent(entity
, parent
);
350 g_object_notify((GObject
*) entity
, "parent");
354 * adg_entity_unparent:
355 * @entity: an #AdgEntity
357 * Removes the current parent of @entity, properly handling
358 * the references between them.
360 * If @entity has no parent, this function simply returns.
363 adg_entity_unparent(AdgEntity
*entity
)
365 AdgContainer
*old_parent
;
367 g_return_if_fail(ADG_IS_ENTITY(entity
));
369 old_parent
= ADG_ENTITY_GET_CLASS(entity
)->get_parent(entity
);
371 if (old_parent
== NULL
)
374 ADG_ENTITY_GET_CLASS(entity
)->set_parent(entity
, NULL
);
375 g_signal_emit(entity
, signals
[PARENT_SET
], 0, old_parent
);
377 g_object_unref(entity
);
381 * adg_entity_reparent:
382 * @entity: an #AdgEntity
383 * @parent: the new container
385 * Moves @entity from the old parent to @parent, handling reference
386 * count issues to avoid destroying the object.
389 adg_entity_reparent(AdgEntity
*entity
, AdgContainer
*parent
)
391 AdgContainer
*old_parent
;
393 g_return_if_fail(ADG_IS_CONTAINER(parent
));
395 old_parent
= adg_entity_get_parent(entity
);
397 /* Reparenting on the same container: do nothing */
398 if (old_parent
== parent
)
401 g_return_if_fail(ADG_IS_CONTAINER(old_parent
));
403 g_object_ref(entity
);
404 adg_container_remove(old_parent
, entity
);
405 adg_container_add(parent
, entity
);
406 g_object_unref(entity
);
410 * adg_entity_get_context:
411 * @entity: an #AdgEntity instance
413 * Gets the context associated to @entity.
414 * If no context was explicitely set, get the parent context.
416 * Return value: the requested context or %NULL on errors
419 adg_entity_get_context(AdgEntity
*entity
)
421 AdgEntityPrivate
*data
;
423 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
428 return data
->context
;
431 return adg_entity_get_context((AdgEntity
*) data
->parent
);
437 * adg_entity_set_context:
438 * @entity: an #AdgEntity instance
439 * @context: the new context
441 * Sets a new context. The old context (if any) will be unreferenced
442 * while a new reference will be added to @context.
445 adg_entity_set_context(AdgEntity
*entity
, AdgContext
*context
)
447 g_return_if_fail(ADG_IS_ENTITY(entity
));
448 g_return_if_fail(ADG_IS_CONTEXT(context
));
450 set_context(entity
, context
);
451 g_object_notify((GObject
*) entity
, "context");
455 * adg_entity_get_canvas:
456 * @entity: an #AdgEntity
458 * Walks on the @entity hierarchy and gets the first parent of @entity that is
459 * of #AdgCanvas derived type.
461 * Return value: the requested object or %NULL if there is no #AdgCanvas in
462 * the parent hierarchy.
465 adg_entity_get_canvas(AdgEntity
*entity
)
467 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
470 if (ADG_IS_CANVAS(entity
))
471 return (AdgCanvas
*) entity
;
473 entity
= (AdgEntity
*) adg_entity_get_parent(entity
);
480 * adg_entity_get_global_map:
481 * @entity: an #AdgEntity object
482 * @map: where to store the global map
484 * Gets the transformation to be used to compute the global matrix
485 * of @entity and store it in @map.
488 adg_entity_get_global_map(AdgEntity
*entity
, AdgMatrix
*map
)
490 AdgEntityPrivate
*data
;
492 g_return_if_fail(ADG_IS_ENTITY(entity
));
493 g_return_if_fail(map
!= NULL
);
496 adg_matrix_copy(map
, &data
->global_map
);
500 * adg_entity_set_global_map:
501 * @entity: an #AdgEntity object
504 * Sets the new global transformation of @entity to @map:
505 * the old map is discarded. If @map is %NULL an identity
509 adg_entity_set_global_map(AdgEntity
*entity
, const AdgMatrix
*map
)
511 g_return_if_fail(ADG_IS_ENTITY(entity
));
513 set_global_map(entity
, map
);
514 g_object_notify((GObject
*) entity
, "global-map");
518 * adg_entity_get_local_map:
519 * @entity: an #AdgEntity object
520 * @map: where to store the local map
522 * Gets the transformation to be used to compute the local matrix
523 * of @entity and store it in @map.
526 adg_entity_get_local_map(AdgEntity
*entity
, AdgMatrix
*map
)
528 AdgEntityPrivate
*data
;
530 g_return_if_fail(ADG_IS_ENTITY(entity
));
531 g_return_if_fail(map
!= NULL
);
534 adg_matrix_copy(map
, &data
->local_map
);
538 * adg_entity_set_local_map:
539 * @entity: an #AdgEntity object
542 * Sets the new global transformation of @entity to @map:
543 * the old map is discarded. If @map is %NULL an identity
547 adg_entity_set_local_map(AdgEntity
*entity
, const AdgMatrix
*map
)
549 g_return_if_fail(ADG_IS_ENTITY(entity
));
551 set_local_map(entity
, map
);
552 g_object_notify((GObject
*) entity
, "local-map");
556 * adg_entity_get_global_matrix:
557 * @entity: an #AdgEntity object
558 * @matrix: where to store the global matrix
560 * Computes the global matrix by combining all the global maps of the
561 * @entity hierarchy and stores the result in @matrix.
564 adg_entity_get_global_matrix(AdgEntity
*entity
, AdgMatrix
*matrix
)
566 AdgEntityPrivate
*data
;
568 g_return_if_fail(ADG_IS_ENTITY(entity
));
569 g_return_if_fail(matrix
!= NULL
);
573 if (data
->parent
== NULL
) {
574 adg_matrix_copy(matrix
, &data
->global_map
);
576 adg_entity_get_global_matrix((AdgEntity
*) data
->parent
, matrix
);
577 cairo_matrix_multiply(matrix
, &data
->global_map
, matrix
);
582 * adg_entity_get_local_matrix:
583 * @entity: an #AdgEntity object
584 * @matrix: where to store the local matrix
586 * Computes the local matrix by combining all the local maps of the
587 * @entity hierarchy and stores the result in @matrix.
590 adg_entity_get_local_matrix(AdgEntity
*entity
, AdgMatrix
*matrix
)
592 AdgEntityPrivate
*data
;
594 g_return_if_fail(ADG_IS_ENTITY(entity
));
595 g_return_if_fail(matrix
!= NULL
);
599 if (data
->parent
== NULL
) {
600 adg_matrix_copy(matrix
, &data
->local_map
);
602 adg_entity_get_local_matrix((AdgEntity
*) data
->parent
, matrix
);
603 cairo_matrix_multiply(matrix
, &data
->local_map
, matrix
);
608 * adg_entity_get_model_matrix:
609 * @entity: an #AdgEntity object
611 * Gets the model matrix to be used in rendering this @entity.
613 * Return value: the requested matrix
616 adg_entity_get_model_matrix(AdgEntity
*entity
)
618 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
619 return ADG_ENTITY_GET_CLASS(entity
)->get_model_matrix(entity
);
623 * adg_entity_get_paper_matrix:
624 * @entity: an #AdgEntity object
626 * Gets the paper matrix to be used in rendering this @entity.
628 * Return value: the requested matrix
631 adg_entity_get_paper_matrix(AdgEntity
*entity
)
633 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
634 return ADG_ENTITY_GET_CLASS(entity
)->get_paper_matrix(entity
);
638 * adg_entity_build_paper2model:
639 * @entity: an #AdgEntity
640 * @matrix: the destination matrix
642 * Builds a matrix to translate from paper to model space and
643 * put the result in @matrix.
645 * Return value: %TRUE on success, %FALSE on errors
648 adg_entity_build_paper2model(AdgEntity
*entity
, AdgMatrix
*matrix
)
650 cairo_status_t status
;
652 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
653 g_return_val_if_fail(matrix
!= NULL
, FALSE
);
655 adg_matrix_copy(matrix
, adg_entity_get_model_matrix(entity
));
656 status
= cairo_matrix_invert(matrix
);
657 if (status
!= CAIRO_STATUS_SUCCESS
) {
658 g_error("Unable to invert model matrix (cairo message: %s)",
659 cairo_status_to_string(status
));
663 cairo_matrix_multiply(matrix
, matrix
, adg_entity_get_paper_matrix(entity
));
668 * adg_entity_build_model2paper:
669 * @entity: an #AdgEntity
670 * @matrix: the destination matrix
672 * Builds a matrix to translate from model to paper space and
673 * put the result in @matrix.
675 * Return value: %TRUE on success, %FALSE on errors
678 adg_entity_build_model2paper(AdgEntity
*entity
, AdgMatrix
*matrix
)
680 cairo_status_t status
;
682 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
683 g_return_val_if_fail(matrix
!= NULL
, FALSE
);
685 adg_matrix_copy(matrix
, adg_entity_get_paper_matrix(entity
));
686 status
= cairo_matrix_invert(matrix
);
687 if (status
!= CAIRO_STATUS_SUCCESS
) {
688 g_error("Unable to invert paper matrix (cairo message: %s)",
689 cairo_status_to_string(status
));
693 cairo_matrix_multiply(matrix
, matrix
, adg_entity_get_model_matrix(entity
));
698 * adg_entity_model_matrix_changed:
699 * @entity: an #AdgEntity
700 * @parent_matrix: the parent #AdgMatrix
702 * Emits the "model-matrix-changed" signal on @entity.
704 * This function is only useful in entity implementations.
707 adg_entity_model_matrix_changed(AdgEntity
*entity
,
708 const AdgMatrix
*parent_matrix
)
710 g_return_if_fail(ADG_IS_ENTITY(entity
));
712 g_signal_emit(entity
, signals
[MODEL_MATRIX_CHANGED
], 0, parent_matrix
);
716 * adg_entity_paper_matrix_changed:
717 * @entity: an #AdgEntity
718 * @parent_matrix: the parent #AdgMatrix
720 * Emits the "paper-matrix-changed" signal on @entity.
722 * This function is only useful in entity implementations.
725 adg_entity_paper_matrix_changed(AdgEntity
*entity
,
726 const AdgMatrix
*parent_matrix
)
728 g_return_if_fail(ADG_IS_ENTITY(entity
));
730 g_signal_emit(entity
, signals
[PAPER_MATRIX_CHANGED
], 0, parent_matrix
);
734 * adg_entity_get_style:
735 * @entity: an #AdgEntity
736 * @style_slot: the slot of the style to get
738 * Gets a style from this entity. If the entity has no context associated
739 * or the style in undefined within this context, gets the style from its
742 * Return value: the requested style or %NULL on errors
745 adg_entity_get_style(AdgEntity
*entity
, AdgStyleSlot style_slot
)
747 AdgEntityPrivate
*data
;
749 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
754 AdgStyle
*style
= adg_context_get_style(data
->context
, style_slot
);
760 return adg_entity_get_style((AdgEntity
*) data
->parent
, style_slot
);
767 * @entity: an #AdgEntity
768 * @style_slot: the slot of the style to apply
769 * @cr: a #cairo_t drawing context
771 * Applies the specified style to the @cr cairo context.
774 adg_entity_apply(AdgEntity
*entity
, AdgStyleSlot style_slot
, cairo_t
*cr
)
776 AdgStyle
*style
= adg_entity_get_style(entity
, style_slot
);
779 adg_style_apply(style
, cr
);
783 * adg_entity_model_matrix_applied:
784 * @entity: an #AdgEntity
786 * Return value: %TRUE if the model matrix didn't change from the last render
789 adg_entity_model_matrix_applied(AdgEntity
*entity
)
791 AdgEntityPrivate
*data
;
793 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
797 return ADG_ISSET(data
->flags
, MODEL_MATRIX_APPLIED
);
801 * adg_entity_paper_matrix_applied:
802 * @entity: an #AdgEntity
804 * Return value: %TRUE if the paper matrix didn't change from the last render
807 adg_entity_paper_matrix_applied(AdgEntity
*entity
)
809 AdgEntityPrivate
*data
;
811 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
815 return ADG_ISSET(data
->flags
, PAPER_MATRIX_APPLIED
);
819 * adg_entity_model_applied:
820 * @entity: an #AdgEntity
822 * Return value: %TRUE if the model didn't change from the last render
825 adg_entity_model_applied(AdgEntity
*entity
)
827 AdgEntityPrivate
*data
;
829 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
833 return ADG_ISSET(data
->flags
, MODEL_APPLIED
);
837 * adg_entity_invalidate:
838 * @entity: an #AdgEntity
840 * Emits the "invalidate" signal on @entity and all its children, if any,
841 * so subsequent rendering will need a global recomputation.
844 adg_entity_invalidate(AdgEntity
*entity
)
846 g_return_if_fail(ADG_IS_ENTITY(entity
));
848 g_signal_emit(entity
, signals
[INVALIDATE
], 0, NULL
);
853 * @entity: an #AdgEntity
854 * @cr: a #cairo_t drawing context
856 * Emits the "render" signal on @entity and all its children, if any,
857 * causing the rendering operation the @cr cairo context.
860 adg_entity_render(AdgEntity
*entity
, cairo_t
*cr
)
862 g_return_if_fail(ADG_IS_ENTITY(entity
));
864 g_signal_emit(entity
, signals
[RENDER
], 0, cr
);
868 static AdgContainer
*
869 get_parent(AdgEntity
*entity
)
871 AdgEntityPrivate
*data
= entity
->data
;
877 set_parent(AdgEntity
*entity
, AdgContainer
*parent
)
879 AdgEntityPrivate
*data
= entity
->data
;
881 data
->parent
= parent
;
885 parent_set(AdgEntity
*entity
, AdgContainer
*old_parent
)
887 if (ADG_IS_CONTAINER(old_parent
)) {
888 const AdgMatrix
*old_model
;
889 const AdgMatrix
*old_paper
;
891 old_model
= adg_entity_get_model_matrix((AdgEntity
*) old_parent
);
892 old_paper
= adg_entity_get_paper_matrix((AdgEntity
*) old_parent
);
894 adg_entity_model_matrix_changed(entity
, old_model
);
895 adg_entity_paper_matrix_changed(entity
, old_paper
);
900 get_context(AdgEntity
*entity
)
902 AdgEntityPrivate
*data
= entity
->data
;
906 return data
->context
;
908 parent
= (AdgEntity
*) data
->parent
;
910 return parent
? ADG_ENTITY_GET_CLASS(parent
)->get_context(parent
) : NULL
;
914 set_context(AdgEntity
*entity
, AdgContext
*context
)
916 AdgEntityPrivate
*data
= entity
->data
;
919 g_object_unref((GObject
*) data
->context
);
921 g_object_ref((GObject
*) context
);
922 data
->context
= context
;
926 set_global_map(AdgEntity
*entity
, const AdgMatrix
*map
)
928 AdgEntityPrivate
*data
= entity
->data
;
931 cairo_matrix_init_identity(&data
->global_map
);
933 adg_matrix_copy(&data
->global_map
, map
);
937 set_local_map(AdgEntity
*entity
, const AdgMatrix
*map
)
939 AdgEntityPrivate
*data
= entity
->data
;
942 cairo_matrix_init_identity(&data
->local_map
);
944 adg_matrix_copy(&data
->local_map
, map
);
948 model_matrix_changed(AdgEntity
*entity
, AdgMatrix
*parent_matrix
)
950 AdgEntityPrivate
*data
= entity
->data
;
952 ADG_UNSET(data
->flags
, MODEL_MATRIX_APPLIED
);
956 paper_matrix_changed(AdgEntity
*entity
, AdgMatrix
*parent_matrix
)
958 AdgEntityPrivate
*data
= entity
->data
;
960 ADG_UNSET(data
->flags
, PAPER_MATRIX_APPLIED
);
964 render(AdgEntity
*entity
, cairo_t
*cr
)
966 AdgEntityPrivate
*data
= entity
->data
;
969 MODEL_MATRIX_APPLIED
| PAPER_MATRIX_APPLIED
| MODEL_APPLIED
);
972 static const AdgMatrix
*
973 get_model_matrix(AdgEntity
*entity
)
975 AdgEntityPrivate
*data
= entity
->data
;
977 return adg_entity_get_model_matrix((AdgEntity
*) data
->parent
);
980 static const AdgMatrix
*
981 get_paper_matrix(AdgEntity
*entity
)
983 AdgEntityPrivate
*data
= entity
->data
;
985 return adg_entity_get_paper_matrix((AdgEntity
*) data
->parent
);