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 Library 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 * Library 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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 * @short_description: A stroked path entity
25 * The #AdgPath object is probably the simplest entity: it represents a path
26 * (as intended by the #cairo_path_t structure) in model space.
30 #include "adg-path-private.h"
31 #include "adg-line-style.h"
34 #define PARENT_CLASS ((AdgEntityClass *) adg_path_parent_class)
37 static void finalize (GObject
*object
);
38 static void invalidate (AdgEntity
*entity
);
39 static void render (AdgEntity
*entity
,
41 static void clear_path_cache (AdgPath
*path
);
44 G_DEFINE_TYPE(AdgPath
, adg_path
, ADG_TYPE_ENTITY
)
48 adg_path_class_init(AdgPathClass
*klass
)
50 GObjectClass
*gobject_class
;
51 AdgEntityClass
*entity_class
;
53 gobject_class
= (GObjectClass
*) klass
;
54 entity_class
= (AdgEntityClass
*) klass
;
56 g_type_class_add_private(klass
, sizeof(AdgPathPrivate
));
58 gobject_class
->finalize
= finalize
;
60 entity_class
->invalidate
= invalidate
;
61 entity_class
->render
= render
;
65 adg_path_init(AdgPath
*path
)
67 AdgPathPrivate
*priv
= G_TYPE_INSTANCE_GET_PRIVATE(path
, ADG_TYPE_PATH
,
70 priv
->cp
.x
= priv
->cp
.y
= 0.;
71 priv
->cairo_path
= NULL
;
72 priv
->callback
= NULL
;
78 finalize(GObject
*object
)
80 clear_path_cache((AdgPath
*) object
);
82 ((GObjectClass
*) PARENT_CLASS
)->finalize(object
);
87 * @callback: an #AdgCallback callback
88 * @user_data: user provided pointer to pass to the callback
90 * Creates a new path entity. The path must be constructed in the @callback
91 * function: AdgPath will cache and reuse the cairo_copy_path() returned by
92 * the cairo context after the @callback call.
94 * Return value: the new entity
97 adg_path_new(AdgCallback callback
, gpointer user_data
)
101 path
= (AdgPath
*) g_object_new(ADG_TYPE_PATH
, NULL
);
102 path
->priv
->callback
= callback
;
103 path
->priv
->user_data
= user_data
;
105 return (AdgEntity
*) path
;
109 * adg_path_get_cairo_path:
112 * Gets a pointer to the cairo path structure of @path. The return value
113 * is owned by @path and must be considered read-only.
115 * Return value: a pointer to the internal #cairo_path_t structure
118 adg_path_get_cairo_path(AdgPath
*path
)
120 g_return_val_if_fail(ADG_IS_PATH(path
), NULL
);
122 return path
->priv
->cairo_path
;
129 * Dumps the data content of @path to stdout in a human readable format.
132 adg_path_dump(AdgPath
*path
)
136 g_return_if_fail(ADG_IS_PATH(path
));
138 if (!cpml_segment_from_cairo(&segment
, path
->priv
->cairo_path
)) {
139 g_print("Invalid path data to dump!\n");
142 cpml_segment_dump(&segment
);
143 } while (cpml_segment_next(&segment
));
148 invalidate(AdgEntity
*entity
)
150 clear_path_cache((AdgPath
*) entity
);
152 PARENT_CLASS
->invalidate(entity
);
156 render(AdgEntity
*entity
, cairo_t
*cr
)
158 AdgPath
*path
= (AdgPath
*) entity
;
160 if (path
->priv
->cairo_path
) {
161 /* Use cached data */
162 cairo_move_to(cr
, path
->priv
->cp
.x
, path
->priv
->cp
.y
);
163 cairo_append_path(cr
, path
->priv
->cairo_path
);
165 /* Construct and store the cache */
166 cairo_get_current_point(cr
, &path
->priv
->cp
.x
, &path
->priv
->cp
.y
);
168 if (path
->priv
->callback
)
169 path
->priv
->callback(entity
, cr
, path
->priv
->user_data
);
171 path
->priv
->cairo_path
= cairo_copy_path(cr
);
174 adg_entity_apply(entity
, ADG_SLOT_LINE_STYLE
, cr
);
177 PARENT_CLASS
->render(entity
, cr
);
181 clear_path_cache(AdgPath
*path
)
183 AdgPathPrivate
*priv
= path
->priv
;
185 if (priv
->cairo_path
!= NULL
) {
186 cairo_path_destroy(priv
->cairo_path
);
187 priv
->cairo_path
= NULL
;
190 priv
->cp
.x
= priv
->cp
.y
= 0.;