24 #include "gvplugin_skillgui_papyrus.h" 26 #include <utils/math/angle.h> 27 #include <utils/time/tracker.h> 29 #include <gvplugin_device.h> 30 #include <gvplugin_render.h> 35 #define NOEXPORT __attribute__ ((visibility("hidden"))) 39 NOEXPORT std::valarray<double> __skillgui_render_dashed(6., 1);
40 NOEXPORT std::valarray<double> __skillgui_render_dotted((
double[]){2., 6.}, 2);
42 #ifdef USE_GVPLUGIN_TIMETRACKER 44 NOEXPORT
unsigned int __ttc_page = __tt.add_class(
"Page");
45 NOEXPORT
unsigned int __ttc_beginpage = __tt.add_class(
"Begin Page");
46 NOEXPORT
unsigned int __ttc_ellipse = __tt.add_class(
"Ellipse");
47 NOEXPORT
unsigned int __ttc_bezier = __tt.add_class(
"Bezier");
48 NOEXPORT
unsigned int __ttc_polygon = __tt.add_class(
"Polygon");
49 NOEXPORT
unsigned int __ttc_polyline = __tt.add_class(
"Polyline");
50 NOEXPORT
unsigned int __ttc_text = __tt.add_class(
"Text");
51 NOEXPORT
unsigned int __ttc_text_1 = __tt.add_class(
"Text 1");
52 NOEXPORT
unsigned int __ttc_text_2 = __tt.add_class(
"Text 2");
53 NOEXPORT
unsigned int __ttc_text_3 = __tt.add_class(
"Text 3");
54 NOEXPORT
unsigned int __ttc_text_4 = __tt.add_class(
"Text 4");
55 NOEXPORT
unsigned int __ttc_text_5 = __tt.add_class(
"Text 5");
56 NOEXPORT
unsigned int __tt_count = 0;
57 NOEXPORT
unsigned int __num_ellipse = 0;
58 NOEXPORT
unsigned int __num_bezier = 0;
59 NOEXPORT
unsigned int __num_polygon = 0;
60 NOEXPORT
unsigned int __num_polyline = 0;
61 NOEXPORT
unsigned int __num_text = 0;
65 skillgui_device_init(GVJ_t *firstjob)
67 Glib::RefPtr<const Gdk::Screen> s = __sggvp->get_screen();
68 firstjob->device_dpi.x = s->get_resolution();
69 firstjob->device_dpi.y = s->get_resolution();
70 firstjob->device_sets_dpi =
true;
72 Gtk::Allocation alloc = __sggvp->get_allocation();
73 firstjob->width = alloc.get_width();
74 firstjob->height = alloc.get_height();
76 firstjob->fit_mode = TRUE;
80 skillgui_device_finalize(GVJ_t *firstjob)
84 firstjob->context = (
void *)__sggvp;
85 firstjob->external_context = TRUE;
88 (firstjob->callbacks->refresh)(firstjob);
92 static inline Papyrus::Fill::pointer
93 skillgui_render_solidpattern(gvcolor_t *color)
95 Cairo::RefPtr< Cairo::SolidPattern > pattern;
96 pattern = Cairo::SolidPattern::create_rgba(color->u.RGBA[0],
100 return Papyrus::Fill::create(pattern);
104 static inline Papyrus::Stroke::pointer
105 skillgui_render_stroke(obj_state_t *obj)
107 Papyrus::Stroke::pointer stroke;
109 Cairo::RefPtr< Cairo::SolidPattern > pattern;
110 pattern = Cairo::SolidPattern::create_rgba(obj->pencolor.u.RGBA[0],
111 obj->pencolor.u.RGBA[1],
112 obj->pencolor.u.RGBA[2],
113 obj->pencolor.u.RGBA[3]);
115 stroke = Papyrus::Stroke::create(pattern, obj->penwidth);
117 if (obj->pen == PEN_DASHED) {
118 stroke->set_dash(__skillgui_render_dashed);
119 }
else if (obj->pen == PEN_DOTTED) {
120 stroke->set_dash(__skillgui_render_dotted);
127 skillgui_render_begin_page(GVJ_t *job)
129 #ifdef USE_GVPLUGIN_TIMETRACKER 130 __tt.ping_start(__ttc_page);
131 __tt.ping_start(__ttc_beginpage);
135 Gtk::Allocation alloc = __sggvp->get_allocation();
136 float bbwidth = job->bb.UR.x - job->bb.LL.x;
137 float bbheight = job->bb.UR.y - job->bb.LL.y;
138 float avwidth = alloc.get_width();
139 float avheight = alloc.get_height();
140 float zoom_w = avwidth / bbwidth;
141 float zoom_h = avheight / bbheight;
142 float zoom = std::min(zoom_w, zoom_h);
144 float translate_x = 0;
145 float translate_y = 0;
147 if (bbwidth > avwidth || bbheight > avheight) {
148 float zwidth = bbwidth * zoom;
149 float zheight = bbheight * zoom;
150 translate_x += (avwidth - zwidth ) / 2.;
151 translate_y += (avheight - zheight) / 2.;
154 translate_x += (avwidth - bbwidth) / 2.;
155 translate_y += (avheight - bbheight) / 2.;
158 gvp->
set_bb(bbwidth, bbheight);
159 gvp->
set_pad(job->pad.x, job->pad.y);
164 gvp->
get_affine()->set_translate(translate_x + job->pad.x,
165 translate_y + job->pad.y);
176 #ifdef USE_GVPLUGIN_TIMETRACKER 183 __tt.ping_end(__ttc_beginpage);
188 skillgui_render_end_page(GVJ_t * job)
192 #ifdef USE_GVPLUGIN_TIMETRACKER 193 __tt.ping_end(__ttc_page);
194 if ( ++__tt_count >= 10 ) {
196 __tt.print_to_stdout();
198 printf(
"Num Ellipse: %u\n" 202 "Num Text: %u\n", __num_ellipse, __num_bezier,
203 __num_polygon, __num_polyline, __num_text);
209 skillgui_render_textpara(GVJ_t *job, pointf p, textpara_t *para)
211 #ifdef USE_GVPLUGIN_TIMETRACKER 212 __tt.ping_start(__ttc_text);
216 obj_state_t *obj = job->obj;
218 switch (para->just) {
227 p.x -= para->width / 2.0;
231 p.y += para->height / 2.0 + para->yoffset_centerline;
235 Glib::RefPtr<Pango::Layout> pl = Glib::wrap((PangoLayout *)para->layout,
237 Pango::FontDescription fd = pl->get_font_description();
238 Cairo::FontSlant slant = Cairo::FONT_SLANT_NORMAL;
239 if (fd.get_style() == Pango::STYLE_OBLIQUE ) {
240 slant = Cairo::FONT_SLANT_OBLIQUE;
241 }
else if (fd.get_style() == Pango::STYLE_ITALIC ) {
242 slant = Cairo::FONT_SLANT_ITALIC;
244 Cairo::FontWeight weight = Cairo::FONT_WEIGHT_NORMAL;
245 if ( fd.get_weight() == Pango::WEIGHT_BOLD ) {
246 weight = Cairo::FONT_WEIGHT_BOLD;
249 double offsetx = 0.0;
250 double offsety = 0.0;
253 if ( (obj->type == EDGE_OBJTYPE) && (strcmp(para->str, obj->headlabel) == 0) ) {
254 char *labelrotate = agget(obj->u.e, (
char *)
"labelrotate");
255 if (labelrotate && (strlen(labelrotate) > 0)) {
258 char *labeloffsetx = agget(obj->u.e, (
char *)
"labeloffsetx");
259 if (labeloffsetx && (strlen(labeloffsetx) > 0)) {
260 offsetx = atof(labeloffsetx) * job->scale.x;
262 char *labeloffsety = agget(obj->u.e, (
char *)
"labeloffsety");
263 if (labeloffsety && (strlen(labeloffsety) > 0)) {
264 offsety = atof(labeloffsety) * job->scale.y;
269 Papyrus::Text::pointer t = Papyrus::Text::create(para->str, para->fontsize,
270 fd.get_family(), slant, weight);
274 #ifdef HAVE_TIMS_PAPYRUS_PATCHES 275 t->set_fill(skillgui_render_solidpattern(&(obj->pencolor)),
false);
277 t->set_fill(skillgui_render_solidpattern(&(obj->pencolor)));
281 t->translate(p.x + offsetx, p.y + offsety,
false);
284 if (rotate != 0.0) t->set_rotation(rotate, Papyrus::RADIANS,
false);
290 #ifdef USE_GVPLUGIN_TIMETRACKER 291 __tt.ping_end(__ttc_text);
296 skillgui_render_ellipse(GVJ_t *job, pointf *A,
int filled)
298 #ifdef USE_GVPLUGIN_TIMETRACKER 299 __tt.ping_start(__ttc_ellipse);
304 obj_state_t *obj = job->obj;
306 double rx = fabs(A[1].x - A[0].x);
307 double ry = fabs(A[1].y - A[0].y);
309 Papyrus::Circle::pointer e = Papyrus::Circle::create(rx);
310 e->set_stroke(skillgui_render_stroke(obj));
311 if ( filled ) e->set_fill(skillgui_render_solidpattern(&(obj->fillcolor)));
312 e->translate(A[0].x, A[0].y);
313 e->set_scale_y(ry / rx);
316 #ifdef USE_GVPLUGIN_TIMETRACKER 317 __tt.ping_end(__ttc_ellipse);
322 skillgui_render_polygon(GVJ_t *job, pointf *A,
int n,
int filled)
324 #ifdef USE_GVPLUGIN_TIMETRACKER 325 __tt.ping_start(__ttc_polygon);
330 obj_state_t *obj = job->obj;
333 for (
int i = 0; i < n; ++i) {
334 v.push_back(Papyrus::Vertex(A[i].x, A[i].y));
337 Papyrus::Polygon::pointer p = Papyrus::Polygon::create(v);
338 p->set_stroke(skillgui_render_stroke(obj));
339 if ( filled ) p->set_fill(skillgui_render_solidpattern(&(obj->fillcolor)));
341 #ifdef USE_GVPLUGIN_TIMETRACKER 342 __tt.ping_end(__ttc_polygon);
347 skillgui_render_bezier(GVJ_t * job, pointf * A,
int n,
int arrow_at_start,
348 int arrow_at_end,
int filled)
350 #ifdef USE_GVPLUGIN_TIMETRACKER 351 __tt.ping_start(__ttc_bezier);
356 obj_state_t *obj = job->obj;
358 Papyrus::BezierVertices v;
359 v.push_back(Papyrus::BezierVertex(A[0].x, A[0].y,
362 for (
int i = 1; i < n; i += 3) {
364 v.push_back(Papyrus::BezierVertex(A[i+2].x, A[i+2].y,
366 A[i+3].x, A[i+3].y));
368 v.push_back(Papyrus::BezierVertex(A[i+2].x, A[i+2].y,
370 A[i+2].x, A[i+2].y));
374 Papyrus::Bezierline::pointer p = Papyrus::Bezierline::create(v);
375 p->set_stroke(skillgui_render_stroke(obj));
376 if ( filled ) p->set_fill(skillgui_render_solidpattern(&(obj->fillcolor)));
378 #ifdef USE_GVPLUGIN_TIMETRACKER 379 __tt.ping_end(__ttc_bezier);
384 skillgui_render_polyline(GVJ_t * job, pointf * A,
int n)
386 #ifdef USE_GVPLUGIN_TIMETRACKER 387 __tt.ping_start(__ttc_polyline);
392 obj_state_t *obj = job->obj;
395 for (
int i = 0; i < n; ++i) {
396 v.push_back(Papyrus::Vertex(A[i].x, A[i].y));
399 Papyrus::Polyline::pointer p = Papyrus::Polyline::create(v);
400 p->set_stroke(skillgui_render_stroke(obj));
402 #ifdef USE_GVPLUGIN_TIMETRACKER 403 __tt.ping_end(__ttc_polyline);
408 static gvrender_engine_t skillgui_render_engine = {
415 skillgui_render_begin_page,
416 skillgui_render_end_page,
431 skillgui_render_textpara,
433 skillgui_render_ellipse,
434 skillgui_render_polygon,
435 skillgui_render_bezier,
436 skillgui_render_polyline,
441 static gvdevice_engine_t skillgui_device_engine = {
442 skillgui_device_init,
444 skillgui_device_finalize,
453 static gvrender_features_t skillgui_render_features = {
454 GVRENDER_Y_GOES_DOWN | GVRENDER_DOES_LABELS |
455 GVRENDER_DOES_TRANSFORM,
463 static gvdevice_features_t skillgui_device_features = {
464 GVDEVICE_DOES_TRUECOLOR | GVDEVICE_EVENTS,
470 gvplugin_installed_t gvdevice_types_skillgui[] = {
471 {0, (
char *)
"skillgui:skillgui", 0, &skillgui_device_engine, &skillgui_device_features},
472 {0, NULL, 0, NULL, NULL}
475 gvplugin_installed_t gvrender_types_skillgui[] = {
476 {0, (
char *)
"skillgui", 10, &skillgui_render_engine, &skillgui_render_features},
477 {0, NULL, 0, NULL, NULL}
480 static gvplugin_api_t apis[] = {
481 {API_device, gvdevice_types_skillgui},
482 {API_render, gvrender_types_skillgui},
486 gvplugin_library_t gvplugin_skillgui_LTX_library = { (
char *)
"skillgui", apis };
497 gvAddLibrary(gvc, &gvplugin_skillgui_LTX_library);
void set_pad(double pad_x, double pad_y)
Set padding.
void set_scale(double scale)
Set scale.
bool scale_override()
Check if scale override is enabled.
void add_drawable(Papyrus::Drawable::pointer d)
Add a drawable.
void set_bb(double bbw, double bbh)
Set bounding box.
virtual void clear()
Clear all drawables.
void set_gvjob(GVJ_t *job)
Set current Graphviz job.
Papyrus::AffineController::pointer get_affine()
Get scaler.
void set_translation(double tx, double ty)
Set translation.
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Skill FSM Graph Viewport.