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.
24 * @short_description: The base class for renderable objects
26 * This abstract class provides a base interface for all renderable objects
27 * (all the objects that can be printed or viewed).
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
38 #include "adg-entity.h"
39 #include "adg-entity-private.h"
40 #include "adg-canvas.h"
41 #include "adg-context.h"
64 static void get_property (GObject
*object
,
68 static void set_property (GObject
*object
,
72 static void dispose (GObject
*object
);
73 static AdgContainer
* get_parent (AdgEntity
*entity
);
74 static void set_parent (AdgEntity
*entity
,
75 AdgContainer
*parent
);
76 static void parent_set (AdgEntity
*entity
,
77 AdgContainer
*old_parent
);
78 static AdgContext
* get_context (AdgEntity
*entity
);
79 static void set_context (AdgEntity
*entity
,
81 static void set_global_map (AdgEntity
*entity
,
82 const AdgMatrix
*map
);
83 static void set_local_map (AdgEntity
*entity
,
84 const AdgMatrix
*map
);
85 static void model_matrix_changed (AdgEntity
*entity
,
86 AdgMatrix
*parent_matrix
);
87 static void paper_matrix_changed (AdgEntity
*entity
,
88 AdgMatrix
*parent_matrix
);
89 static void render (AdgEntity
*entity
,
91 static const AdgMatrix
*get_model_matrix (AdgEntity
*entity
);
92 static const AdgMatrix
*get_paper_matrix (AdgEntity
*entity
);
94 static guint signals
[LAST_SIGNAL
] = { 0 };
97 G_DEFINE_ABSTRACT_TYPE(AdgEntity
, adg_entity
, G_TYPE_INITIALLY_UNOWNED
);
101 adg_entity_class_init(AdgEntityClass
*klass
)
103 GObjectClass
*gobject_class
;
106 gobject_class
= (GObjectClass
*) klass
;
108 g_type_class_add_private(klass
, sizeof(AdgEntityPrivate
));
110 gobject_class
->get_property
= get_property
;
111 gobject_class
->set_property
= set_property
;
112 gobject_class
->dispose
= dispose
;
114 klass
->get_parent
= get_parent
;
115 klass
->set_parent
= set_parent
;
116 klass
->parent_set
= parent_set
;
117 klass
->get_context
= get_context
;
118 klass
->model_matrix_changed
= model_matrix_changed
;
119 klass
->paper_matrix_changed
= paper_matrix_changed
;
120 klass
->invalidate
= NULL
;
121 klass
->render
= render
;
122 klass
->get_model_matrix
= get_model_matrix
;
123 klass
->get_paper_matrix
= get_paper_matrix
;
125 param
= g_param_spec_object("parent",
126 P_("Parent Container"),
127 P_("The parent AdgContainer of this entity or NULL if this is a top-level entity"),
128 ADG_TYPE_CONTAINER
, G_PARAM_READWRITE
);
129 g_object_class_install_property(gobject_class
, PROP_PARENT
, param
);
131 param
= g_param_spec_object("context",
133 P_("The context associated to this entity or NULL to inherit the parent context"),
134 ADG_TYPE_CONTEXT
, G_PARAM_READWRITE
);
135 g_object_class_install_property(gobject_class
, PROP_CONTEXT
, param
);
137 param
= g_param_spec_boxed("global-map",
139 P_("The transformation to be combined with the parent ones to get the global matrix"),
140 ADG_TYPE_MATRIX
, G_PARAM_READWRITE
);
141 g_object_class_install_property(gobject_class
, PROP_GLOBAL_MAP
, param
);
143 param
= g_param_spec_boxed("local-map",
145 P_("The transformation to be combined with the parent ones to get the local matrix"),
146 ADG_TYPE_MATRIX
, G_PARAM_READWRITE
);
147 g_object_class_install_property(gobject_class
, PROP_LOCAL_MAP
, param
);
150 * AdgEntity::parent-set:
151 * @entity: an #AdgEntity
152 * @parent: the #AdgContainer parent of @entity
154 * Emitted after the parent container has changed.
156 signals
[PARENT_SET
] =
157 g_signal_new("parent-set",
158 G_OBJECT_CLASS_TYPE(gobject_class
),
160 G_STRUCT_OFFSET(AdgEntityClass
, parent_set
),
162 g_cclosure_marshal_VOID__OBJECT
,
163 G_TYPE_NONE
, 1, ADG_TYPE_CONTAINER
);
166 * AdgEntity::model-matrix-changed:
167 * @entity: an #AdgEntity
168 * @parent_matrix: the parent model matrix
170 * Emitted after the current model matrix has changed.
172 signals
[MODEL_MATRIX_CHANGED
] =
173 g_signal_new("model-matrix-changed",
174 G_OBJECT_CLASS_TYPE(gobject_class
),
176 G_STRUCT_OFFSET(AdgEntityClass
, model_matrix_changed
),
178 g_cclosure_marshal_VOID__BOXED
,
180 ADG_TYPE_MATRIX
| G_SIGNAL_TYPE_STATIC_SCOPE
);
183 * AdgEntity::paper-matrix-changed:
184 * @entity: an #AdgEntity
185 * @parent_matrix: the parent paper matrix
187 * Emitted after the current paper matrix has changed.
189 signals
[PAPER_MATRIX_CHANGED
] =
190 g_signal_new("paper-matrix-changed",
191 G_OBJECT_CLASS_TYPE(gobject_class
),
193 G_STRUCT_OFFSET(AdgEntityClass
, paper_matrix_changed
),
195 g_cclosure_marshal_VOID__BOXED
,
197 ADG_TYPE_MATRIX
| G_SIGNAL_TYPE_STATIC_SCOPE
);
200 * AdgEntity::invalidate:
201 * @entity: an #AdgEntity
203 * Clears the cached data of @entity.
205 signals
[INVALIDATE
] =
206 g_signal_new("invalidate",
207 G_OBJECT_CLASS_TYPE(gobject_class
),
209 G_STRUCT_OFFSET(AdgEntityClass
, invalidate
),
211 g_cclosure_marshal_VOID__BOOLEAN
,
216 * @entity: an #AdgEntity
217 * @cr: a #cairo_t drawing context
219 * Causes the rendering of @entity on @cr.
222 g_signal_new("render",
223 G_OBJECT_CLASS_TYPE(gobject_class
),
225 G_STRUCT_OFFSET(AdgEntityClass
, render
),
227 g_cclosure_marshal_VOID__POINTER
,
228 G_TYPE_NONE
, 1, G_TYPE_POINTER
);
232 adg_entity_init(AdgEntity
*entity
)
234 AdgEntityPrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(entity
,
239 data
->context
= NULL
;
240 cairo_matrix_init_identity(&data
->local_map
);
241 cairo_matrix_init_identity(&data
->global_map
);
247 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
250 AdgEntityPrivate
*data
;
252 entity
= (AdgEntity
*) object
;
257 g_value_set_object(value
, get_parent(entity
));
260 g_value_set_object(value
, get_context(entity
));
262 case PROP_GLOBAL_MAP
:
263 g_value_set_boxed(value
, &data
->global_map
);
266 g_value_set_boxed(value
, &data
->local_map
);
269 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
275 set_property(GObject
*object
,
276 guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
278 AdgEntity
*entity
= (AdgEntity
*) object
;
282 set_parent(entity
, g_value_get_object(value
));
285 set_context(entity
, g_value_get_object(value
));
287 case PROP_GLOBAL_MAP
:
288 set_global_map(entity
, g_value_get_boxed(value
));
291 set_local_map(entity
, g_value_get_boxed(value
));
294 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
300 dispose(GObject
*object
)
303 AdgEntityPrivate
*data
;
304 GObjectClass
*object_class
;
306 entity
= (AdgEntity
*) object
;
308 object_class
= (GObjectClass
*) adg_entity_parent_class
;
311 adg_container_remove(data
->parent
, entity
);
313 if (object_class
->dispose
!= NULL
)
314 object_class
->dispose(object
);
319 * adg_entity_get_parent:
320 * @entity: an #AdgEntity
322 * Gets the container parent of @entity.
324 * This function is only useful in entity implementations.
326 * Return value: the container object or %NULL if @entity is not contained
329 adg_entity_get_parent(AdgEntity
*entity
)
331 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
333 return ADG_ENTITY_GET_CLASS(entity
)->get_parent(entity
);
337 * adg_entity_set_parent:
338 * @entity: an #AdgEntity
339 * @parent: an #AdgContainer
341 * Sets a new container of @entity.
343 * This function is only useful in entity implementations.
346 adg_entity_set_parent(AdgEntity
*entity
, AdgContainer
*parent
)
348 g_return_if_fail(ADG_IS_ENTITY(entity
));
350 ADG_ENTITY_GET_CLASS(entity
)->set_parent(entity
, parent
);
351 g_object_notify((GObject
*) entity
, "parent");
355 * adg_entity_unparent:
356 * @entity: an #AdgEntity
358 * Removes the current parent of @entity, properly handling
359 * the references between them.
361 * If @entity has no parent, this function simply returns.
364 adg_entity_unparent(AdgEntity
*entity
)
366 AdgContainer
*old_parent
;
368 g_return_if_fail(ADG_IS_ENTITY(entity
));
370 old_parent
= ADG_ENTITY_GET_CLASS(entity
)->get_parent(entity
);
372 if (old_parent
== NULL
)
375 ADG_ENTITY_GET_CLASS(entity
)->set_parent(entity
, NULL
);
376 g_signal_emit(entity
, signals
[PARENT_SET
], 0, old_parent
);
378 g_object_unref(entity
);
382 * adg_entity_reparent:
383 * @entity: an #AdgEntity
384 * @parent: the new container
386 * Moves @entity from the old parent to @parent, handling reference
387 * count issues to avoid destroying the object.
390 adg_entity_reparent(AdgEntity
*entity
, AdgContainer
*parent
)
392 AdgContainer
*old_parent
;
394 g_return_if_fail(ADG_IS_CONTAINER(parent
));
396 old_parent
= adg_entity_get_parent(entity
);
398 /* Reparenting on the same container: do nothing */
399 if (old_parent
== parent
)
402 g_return_if_fail(ADG_IS_CONTAINER(old_parent
));
404 g_object_ref(entity
);
405 adg_container_remove(old_parent
, entity
);
406 adg_container_add(parent
, entity
);
407 g_object_unref(entity
);
411 * adg_entity_get_context:
412 * @entity: an #AdgEntity instance
414 * Gets the context associated to @entity.
415 * If no context was explicitely set, get the parent context.
417 * Return value: the requested context or %NULL on errors
420 adg_entity_get_context(AdgEntity
*entity
)
422 AdgEntityPrivate
*data
;
424 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
429 return data
->context
;
432 return adg_entity_get_context((AdgEntity
*) data
->parent
);
438 * adg_entity_set_context:
439 * @entity: an #AdgEntity instance
440 * @context: the new context
442 * Sets a new context. The old context (if any) will be unreferenced
443 * while a new reference will be added to @context.
446 adg_entity_set_context(AdgEntity
*entity
, AdgContext
*context
)
448 g_return_if_fail(ADG_IS_ENTITY(entity
));
449 g_return_if_fail(ADG_IS_CONTEXT(context
));
451 set_context(entity
, context
);
452 g_object_notify((GObject
*) entity
, "context");
456 * adg_entity_get_canvas:
457 * @entity: an #AdgEntity
459 * Walks on the @entity hierarchy and gets the first parent of @entity that is
460 * of #AdgCanvas derived type.
462 * Return value: the requested object or %NULL if there is no #AdgCanvas in
463 * the parent hierarchy.
466 adg_entity_get_canvas(AdgEntity
*entity
)
468 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
471 if (ADG_IS_CANVAS(entity
))
472 return (AdgCanvas
*) entity
;
474 entity
= (AdgEntity
*) adg_entity_get_parent(entity
);
481 * adg_entity_get_global_map:
482 * @entity: an #AdgEntity object
483 * @map: where to store the global map
485 * Gets the transformation to be used to compute the global matrix
486 * of @entity and store it in @map.
489 adg_entity_get_global_map(AdgEntity
*entity
, AdgMatrix
*map
)
491 AdgEntityPrivate
*data
;
493 g_return_if_fail(ADG_IS_ENTITY(entity
));
494 g_return_if_fail(map
!= NULL
);
497 adg_matrix_copy(map
, &data
->global_map
);
501 * adg_entity_set_global_map:
502 * @entity: an #AdgEntity object
505 * Sets the new global transformation of @entity to @map:
506 * the old map is discarded. If @map is %NULL an identity
510 adg_entity_set_global_map(AdgEntity
*entity
, const AdgMatrix
*map
)
512 g_return_if_fail(ADG_IS_ENTITY(entity
));
514 set_global_map(entity
, map
);
515 g_object_notify((GObject
*) entity
, "global-map");
519 * adg_entity_get_local_map:
520 * @entity: an #AdgEntity object
521 * @map: where to store the local map
523 * Gets the transformation to be used to compute the local matrix
524 * of @entity and store it in @map.
527 adg_entity_get_local_map(AdgEntity
*entity
, AdgMatrix
*map
)
529 AdgEntityPrivate
*data
;
531 g_return_if_fail(ADG_IS_ENTITY(entity
));
532 g_return_if_fail(map
!= NULL
);
535 adg_matrix_copy(map
, &data
->local_map
);
539 * adg_entity_set_local_map:
540 * @entity: an #AdgEntity object
543 * Sets the new global transformation of @entity to @map:
544 * the old map is discarded. If @map is %NULL an identity
548 adg_entity_set_local_map(AdgEntity
*entity
, const AdgMatrix
*map
)
550 g_return_if_fail(ADG_IS_ENTITY(entity
));
552 set_local_map(entity
, map
);
553 g_object_notify((GObject
*) entity
, "local-map");
557 * adg_entity_get_global_matrix:
558 * @entity: an #AdgEntity object
559 * @matrix: where to store the global matrix
561 * Computes the global matrix by combining all the global maps of the
562 * @entity hierarchy and stores the result in @matrix.
565 adg_entity_get_global_matrix(AdgEntity
*entity
, AdgMatrix
*matrix
)
567 AdgEntityPrivate
*data
;
569 g_return_if_fail(ADG_IS_ENTITY(entity
));
570 g_return_if_fail(matrix
!= NULL
);
574 if (data
->parent
== NULL
) {
575 adg_matrix_copy(matrix
, &data
->global_map
);
577 adg_entity_get_global_matrix((AdgEntity
*) data
->parent
, matrix
);
578 cairo_matrix_multiply(matrix
, &data
->global_map
, matrix
);
583 * adg_entity_get_local_matrix:
584 * @entity: an #AdgEntity object
585 * @matrix: where to store the local matrix
587 * Computes the local matrix by combining all the local maps of the
588 * @entity hierarchy and stores the result in @matrix.
591 adg_entity_get_local_matrix(AdgEntity
*entity
, AdgMatrix
*matrix
)
593 AdgEntityPrivate
*data
;
595 g_return_if_fail(ADG_IS_ENTITY(entity
));
596 g_return_if_fail(matrix
!= NULL
);
600 if (data
->parent
== NULL
) {
601 adg_matrix_copy(matrix
, &data
->local_map
);
603 adg_entity_get_local_matrix((AdgEntity
*) data
->parent
, matrix
);
604 cairo_matrix_multiply(matrix
, &data
->local_map
, matrix
);
609 * adg_entity_get_model_matrix:
610 * @entity: an #AdgEntity object
612 * Gets the model matrix to be used in rendering this @entity.
614 * Return value: the requested matrix
617 adg_entity_get_model_matrix(AdgEntity
*entity
)
619 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
620 return ADG_ENTITY_GET_CLASS(entity
)->get_model_matrix(entity
);
624 * adg_entity_get_paper_matrix:
625 * @entity: an #AdgEntity object
627 * Gets the paper matrix to be used in rendering this @entity.
629 * Return value: the requested matrix
632 adg_entity_get_paper_matrix(AdgEntity
*entity
)
634 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
635 return ADG_ENTITY_GET_CLASS(entity
)->get_paper_matrix(entity
);
639 * adg_entity_build_paper2model:
640 * @entity: an #AdgEntity
641 * @matrix: the destination matrix
643 * Builds a matrix to translate from paper to model space and
644 * put the result in @matrix.
646 * Return value: %TRUE on success, %FALSE on errors
649 adg_entity_build_paper2model(AdgEntity
*entity
, AdgMatrix
*matrix
)
651 cairo_status_t status
;
653 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
654 g_return_val_if_fail(matrix
!= NULL
, FALSE
);
656 adg_matrix_copy(matrix
, adg_entity_get_model_matrix(entity
));
657 status
= cairo_matrix_invert(matrix
);
658 if (status
!= CAIRO_STATUS_SUCCESS
) {
659 g_error("Unable to invert model matrix (cairo message: %s)",
660 cairo_status_to_string(status
));
664 cairo_matrix_multiply(matrix
, matrix
, adg_entity_get_paper_matrix(entity
));
669 * adg_entity_build_model2paper:
670 * @entity: an #AdgEntity
671 * @matrix: the destination matrix
673 * Builds a matrix to translate from model to paper space and
674 * put the result in @matrix.
676 * Return value: %TRUE on success, %FALSE on errors
679 adg_entity_build_model2paper(AdgEntity
*entity
, AdgMatrix
*matrix
)
681 cairo_status_t status
;
683 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
684 g_return_val_if_fail(matrix
!= NULL
, FALSE
);
686 adg_matrix_copy(matrix
, adg_entity_get_paper_matrix(entity
));
687 status
= cairo_matrix_invert(matrix
);
688 if (status
!= CAIRO_STATUS_SUCCESS
) {
689 g_error("Unable to invert paper matrix (cairo message: %s)",
690 cairo_status_to_string(status
));
694 cairo_matrix_multiply(matrix
, matrix
, adg_entity_get_model_matrix(entity
));
699 * adg_entity_model_matrix_changed:
700 * @entity: an #AdgEntity
701 * @parent_matrix: the parent #AdgMatrix
703 * Emits the "model-matrix-changed" signal on @entity.
705 * This function is only useful in entity implementations.
708 adg_entity_model_matrix_changed(AdgEntity
*entity
,
709 const AdgMatrix
*parent_matrix
)
711 g_return_if_fail(ADG_IS_ENTITY(entity
));
713 g_signal_emit(entity
, signals
[MODEL_MATRIX_CHANGED
], 0, parent_matrix
);
717 * adg_entity_paper_matrix_changed:
718 * @entity: an #AdgEntity
719 * @parent_matrix: the parent #AdgMatrix
721 * Emits the "paper-matrix-changed" signal on @entity.
723 * This function is only useful in entity implementations.
726 adg_entity_paper_matrix_changed(AdgEntity
*entity
,
727 const AdgMatrix
*parent_matrix
)
729 g_return_if_fail(ADG_IS_ENTITY(entity
));
731 g_signal_emit(entity
, signals
[PAPER_MATRIX_CHANGED
], 0, parent_matrix
);
735 * adg_entity_get_style:
736 * @entity: an #AdgEntity
737 * @style_slot: the slot of the style to get
739 * Gets a style from this entity. If the entity has no context associated
740 * or the style in undefined within this context, gets the style from its
743 * Return value: the requested style or %NULL on errors
746 adg_entity_get_style(AdgEntity
*entity
, AdgStyleSlot style_slot
)
748 AdgEntityPrivate
*data
;
750 g_return_val_if_fail(ADG_IS_ENTITY(entity
), NULL
);
755 AdgStyle
*style
= adg_context_get_style(data
->context
, style_slot
);
761 return adg_entity_get_style((AdgEntity
*) data
->parent
, style_slot
);
768 * @entity: an #AdgEntity
769 * @style_slot: the slot of the style to apply
770 * @cr: a #cairo_t drawing context
772 * Applies the specified style to the @cr cairo context.
775 adg_entity_apply(AdgEntity
*entity
, AdgStyleSlot style_slot
, cairo_t
*cr
)
777 AdgStyle
*style
= adg_entity_get_style(entity
, style_slot
);
780 adg_style_apply(style
, cr
);
784 * adg_entity_model_matrix_applied:
785 * @entity: an #AdgEntity
787 * Return value: %TRUE if the model matrix didn't change from the last render
790 adg_entity_model_matrix_applied(AdgEntity
*entity
)
792 AdgEntityPrivate
*data
;
794 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
798 return ADG_ISSET(data
->flags
, MODEL_MATRIX_APPLIED
);
802 * adg_entity_paper_matrix_applied:
803 * @entity: an #AdgEntity
805 * Return value: %TRUE if the paper matrix didn't change from the last render
808 adg_entity_paper_matrix_applied(AdgEntity
*entity
)
810 AdgEntityPrivate
*data
;
812 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
816 return ADG_ISSET(data
->flags
, PAPER_MATRIX_APPLIED
);
820 * adg_entity_model_applied:
821 * @entity: an #AdgEntity
823 * Return value: %TRUE if the model didn't change from the last render
826 adg_entity_model_applied(AdgEntity
*entity
)
828 AdgEntityPrivate
*data
;
830 g_return_val_if_fail(ADG_IS_ENTITY(entity
), FALSE
);
834 return ADG_ISSET(data
->flags
, MODEL_APPLIED
);
838 * adg_entity_invalidate:
839 * @entity: an #AdgEntity
841 * Emits the "invalidate" signal on @entity and all its children, if any,
842 * so subsequent rendering will need a global recomputation.
845 adg_entity_invalidate(AdgEntity
*entity
)
847 g_return_if_fail(ADG_IS_ENTITY(entity
));
849 g_signal_emit(entity
, signals
[INVALIDATE
], 0, NULL
);
854 * @entity: an #AdgEntity
855 * @cr: a #cairo_t drawing context
857 * Emits the "render" signal on @entity and all its children, if any,
858 * causing the rendering operation the @cr cairo context.
861 adg_entity_render(AdgEntity
*entity
, cairo_t
*cr
)
863 g_return_if_fail(ADG_IS_ENTITY(entity
));
865 g_signal_emit(entity
, signals
[RENDER
], 0, cr
);
869 static AdgContainer
*
870 get_parent(AdgEntity
*entity
)
872 AdgEntityPrivate
*data
= entity
->data
;
878 set_parent(AdgEntity
*entity
, AdgContainer
*parent
)
880 AdgEntityPrivate
*data
= entity
->data
;
882 data
->parent
= parent
;
886 parent_set(AdgEntity
*entity
, AdgContainer
*old_parent
)
888 if (ADG_IS_CONTAINER(old_parent
)) {
889 const AdgMatrix
*old_model
;
890 const AdgMatrix
*old_paper
;
892 old_model
= adg_entity_get_model_matrix((AdgEntity
*) old_parent
);
893 old_paper
= adg_entity_get_paper_matrix((AdgEntity
*) old_parent
);
895 adg_entity_model_matrix_changed(entity
, old_model
);
896 adg_entity_paper_matrix_changed(entity
, old_paper
);
901 get_context(AdgEntity
*entity
)
903 AdgEntityPrivate
*data
= entity
->data
;
907 return data
->context
;
909 parent
= (AdgEntity
*) data
->parent
;
911 return parent
? ADG_ENTITY_GET_CLASS(parent
)->get_context(parent
) : NULL
;
915 set_context(AdgEntity
*entity
, AdgContext
*context
)
917 AdgEntityPrivate
*data
= entity
->data
;
920 g_object_unref((GObject
*) data
->context
);
922 g_object_ref((GObject
*) context
);
923 data
->context
= context
;
927 set_global_map(AdgEntity
*entity
, const AdgMatrix
*map
)
929 AdgEntityPrivate
*data
= entity
->data
;
932 cairo_matrix_init_identity(&data
->global_map
);
934 adg_matrix_copy(&data
->global_map
, map
);
938 set_local_map(AdgEntity
*entity
, const AdgMatrix
*map
)
940 AdgEntityPrivate
*data
= entity
->data
;
943 cairo_matrix_init_identity(&data
->local_map
);
945 adg_matrix_copy(&data
->local_map
, map
);
949 model_matrix_changed(AdgEntity
*entity
, AdgMatrix
*parent_matrix
)
951 AdgEntityPrivate
*data
= entity
->data
;
953 ADG_UNSET(data
->flags
, MODEL_MATRIX_APPLIED
);
957 paper_matrix_changed(AdgEntity
*entity
, AdgMatrix
*parent_matrix
)
959 AdgEntityPrivate
*data
= entity
->data
;
961 ADG_UNSET(data
->flags
, PAPER_MATRIX_APPLIED
);
965 render(AdgEntity
*entity
, cairo_t
*cr
)
967 AdgEntityPrivate
*data
= entity
->data
;
970 MODEL_MATRIX_APPLIED
| PAPER_MATRIX_APPLIED
| MODEL_APPLIED
);
973 static const AdgMatrix
*
974 get_model_matrix(AdgEntity
*entity
)
976 AdgEntityPrivate
*data
= entity
->data
;
978 return adg_entity_get_model_matrix((AdgEntity
*) data
->parent
);
981 static const AdgMatrix
*
982 get_paper_matrix(AdgEntity
*entity
)
984 AdgEntityPrivate
*data
= entity
->data
;
986 return adg_entity_get_paper_matrix((AdgEntity
*) data
->parent
);