1 /* -*- Mode: C; c-basic-offset: 4 -*- */
2 /* Dia -- a diagram creation/manipulation program
3 * Copyright (C) 1998 Alexander Larsson
4 *
5 * vdx-export.c: Visio XML export filter for dia
6 * Copyright (C) 2006-2007 Ian Redfern
7 * based on the xfig filter code
8 * Copyright (C) 2001 Lars Clausen
9 * based on the dxf filter code
10 * Copyright (C) 2000 James Henstridge, Steffen Macke
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdio.h>
32
33 #include <string.h>
34 #include <math.h>
35 #include <glib.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <locale.h>
39 #include <glib/gstdio.h>
40
41 #include "intl.h"
42 #include "message.h"
43 #include "geometry.h"
44 #include "diarenderer.h"
45 #include "filter.h"
46 #include "object.h"
47 #include "properties.h"
48 #include "dia_image.h"
49 #include "group.h"
50
51 #include "vdx.h"
52 #include "visio-types.h"
53
54 /* Following code taken from xfig-export.c */
55
56 #define VDX_TYPE_RENDERER (vdx_renderer_get_type ())
57 #define VDX_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VDX_TYPE_RENDERER, VDXRenderer))
58 #define VDX_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VDX_TYPE_RENDERER, VDXRendererClass))
59 #define VDX_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VDX_TYPE_RENDERER))
60 #define VDX_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VDX_TYPE_RENDERER, VDXRendererClass))
61
62 GType vdx_renderer_get_type (void) G_GNUC_CONST;
63
64 typedef struct _VDXRenderer VDXRenderer;
65 typedef struct _VDXRendererClass VDXRendererClass;
66
67 struct _VDXRendererClass
68 {
69 DiaRendererClass parent_class;
70 };
71
72 struct _VDXRenderer
73 {
74 DiaRenderer parent_instance;
75
76 FILE *file;
77
78 int depth;
79
80 real linewidth;
81 LineCaps capsmode;
82 LineJoin joinmode;
83 LineStyle stylemode;
84 real dashlength;
85 FillStyle fillmode;
86 DiaFont *font;
87 real fontheight;
88
89 /* Additions for VDX */
90
91 gboolean first_pass; /* When we make table of colours and fonts */
92 GArray *Colors; /* Table of colours */
93 GArray *Fonts; /* Table of fonts */
94 unsigned int shapeid; /* Shape counter */
95 unsigned int version; /* Visio version */
96 unsigned int xml_depth; /* Pretty-printer */
97 };
98
99
100 static void begin_render(DiaRenderer *self);
101 static void end_render(DiaRenderer *renderer);
102 static void set_linewidth(DiaRenderer *self, real linewidth);
103 static void set_linecaps(DiaRenderer *self, LineCaps mode);
104 static void set_linejoin(DiaRenderer *self, LineJoin mode);
105 static void set_linestyle(DiaRenderer *self, LineStyle mode);
106 static void set_dashlength(DiaRenderer *self, real length);
107 static void set_fillstyle(DiaRenderer *self, FillStyle mode);
108 static void set_font(DiaRenderer *self, DiaFont *font, real height);
109 static void draw_line(DiaRenderer *self,
110 Point *start, Point *end,
111 Color *color);
112 static void draw_polyline(DiaRenderer *self,
113 Point *points, int num_points,
114 Color *color);
115 static void draw_polygon(DiaRenderer *self,
116 Point *points, int num_points,
117 Color *color);
118 static void fill_polygon(DiaRenderer *self,
119 Point *points, int num_points,
120 Color *color);
121 static void draw_rect(DiaRenderer *self,
122 Point *ul_corner, Point *lr_corner,
123 Color *color);
124 static void fill_rect(DiaRenderer *self,
125 Point *ul_corner, Point *lr_corner,
126 Color *color);
127 static void draw_arc(DiaRenderer *self,
128 Point *center,
129 real width, real height,
130 real angle1, real angle2,
131 Color *color);
132 static void fill_arc(DiaRenderer *self,
133 Point *center,
134 real width, real height,
135 real angle1, real angle2,
136 Color *color);
137 static void draw_ellipse(DiaRenderer *self,
138 Point *center,
139 real width, real height,
140 Color *color);
141 static void fill_ellipse(DiaRenderer *self,
142 Point *center,
143 real width, real height,
144 Color *color);
145 static void draw_string(DiaRenderer *self,
146 const char *text,
147 Point *pos, Alignment alignment,
148 Color *color);
149 static void draw_image(DiaRenderer *self,
150 Point *point,
151 real width, real height,
152 DiaImage *image);
153
154 static void vdx_renderer_class_init (VDXRendererClass *klass);
155
156 static void
157 export_vdx(DiagramData *data, const gchar *filename,
158 const gchar *diafilename, void* user_data);
159
160 static int
161 vdxCheckColor(VDXRenderer *renderer, Color *color);
162
163 static gpointer parent_class = NULL;
164
165
166 /** Renderer type handler
167 * @returns renderer type
168 */
169
170 GType
vdx_renderer_get_type(void)171 vdx_renderer_get_type (void)
172 {
173 static GType object_type = 0;
174
175 if (!object_type)
176 {
177 static const GTypeInfo object_info =
178 {
179 sizeof (VDXRendererClass),
180 (GBaseInitFunc) NULL,
181 (GBaseFinalizeFunc) NULL,
182 (GClassInitFunc) vdx_renderer_class_init,
183 NULL, /* class_finalize */
184 NULL, /* class_data */
185 sizeof (VDXRenderer),
186 0, /* n_preallocs */
187 NULL /* init */
188 };
189
190 object_type = g_type_register_static (DIA_TYPE_RENDERER,
191 "VDXRenderer",
192 &object_info, 0);
193 }
194
195 return object_type;
196 }
197
198 /** Finalise a renderer
199 * @param object a renderer
200 */
201
202 static void
vdx_renderer_finalize(GObject * object)203 vdx_renderer_finalize (GObject *object)
204 {
205 G_OBJECT_CLASS (parent_class)->finalize (object);
206 }
207
208 /** Class constructor for renderer
209 * @param klass a renderer
210 */
211
212 static void
vdx_renderer_class_init(VDXRendererClass * klass)213 vdx_renderer_class_init (VDXRendererClass *klass)
214 {
215 GObjectClass *object_class = G_OBJECT_CLASS (klass);
216 DiaRendererClass *renderer_class = DIA_RENDERER_CLASS (klass);
217
218 parent_class = g_type_class_peek_parent (klass);
219
220 object_class->finalize = vdx_renderer_finalize;
221
222 renderer_class->begin_render = begin_render;
223 renderer_class->end_render = end_render;
224
225 renderer_class->set_linewidth = set_linewidth;
226 renderer_class->set_linecaps = set_linecaps;
227 renderer_class->set_linejoin = set_linejoin;
228 renderer_class->set_linestyle = set_linestyle;
229 renderer_class->set_dashlength = set_dashlength;
230 renderer_class->set_fillstyle = set_fillstyle;
231 renderer_class->set_font = set_font;
232
233 renderer_class->draw_line = draw_line;
234 renderer_class->draw_polyline = draw_polyline;
235
236 renderer_class->draw_polygon = draw_polygon;
237 renderer_class->fill_polygon = fill_polygon;
238
239 renderer_class->draw_rect = draw_rect;
240 renderer_class->fill_rect = fill_rect;
241
242 renderer_class->draw_arc = draw_arc;
243 renderer_class->fill_arc = fill_arc;
244
245 renderer_class->draw_ellipse = draw_ellipse;
246 renderer_class->fill_ellipse = fill_ellipse;
247
248 /* Until we have NURBS, let Dia use lines */
249 /* renderer_class->draw_bezier = draw_bezier; */
250 /* renderer_class->fill_bezier = fill_bezier; */
251 /* renderer_class->draw_bezier_with_arrows = draw_bezier_with_arrows; */
252
253 renderer_class->draw_string = draw_string;
254
255 renderer_class->draw_image = draw_image;
256
257 /* Believe these are never used or are unnecessary */
258 /* renderer_class->draw_line_with_arrows = draw_line_with_arrows; */
259 /* renderer_class->draw_polyline_with_arrows = draw_polyline_with_arrows; */
260 /* renderer_class->draw_arc_with_arrows = draw_arc_with_arrows; */
261 /* renderer_class->draw_object = draw_object; */
262
263 }
264
265 /** Initialises VDXrenderer
266 * @param self a renderer
267 */
268
269 static void
begin_render(DiaRenderer * self)270 begin_render(DiaRenderer *self)
271 {
272 VDXRenderer *renderer = VDX_RENDERER(self);
273 Color c;
274
275 renderer->depth = 0;
276
277 renderer->linewidth = 0;
278 renderer->capsmode = 0;
279 renderer->joinmode = 0;
280 renderer->stylemode = 0;
281 renderer->dashlength = 0;
282 renderer->fillmode = 0;
283 renderer->font = NULL;
284 renderer->fontheight = 1;
285
286 /* Specific to VDX */
287
288 renderer->Colors = g_array_new(FALSE, TRUE, sizeof (Color));
289 renderer->Fonts = g_array_new(FALSE, TRUE, sizeof (char *));
290 renderer->shapeid = 0;
291 /* renderer->version = 0; */
292
293 /* Black and white are 0 and 1 respectively */
294 c.red = 0.0; c.green = 0.0; c.blue = 0.0;
295 vdxCheckColor(renderer, &c);
296 c.red = 1.0; c.green = 1.0; c.blue = 1.0;
297 vdxCheckColor(renderer, &c);
298 }
299
300 /** Destructor for renderer
301 * @param self a renderer
302 */
303
304 static void
end_render(DiaRenderer * self)305 end_render(DiaRenderer *self)
306 {
307 VDXRenderer *renderer = VDX_RENDERER(self);
308
309 /* Specific to VDX */
310 g_array_free(renderer->Colors, TRUE);
311 g_array_free(renderer->Fonts, TRUE);
312 }
313
314 /** Convert a Dia point to a Visio one
315 * @param p a Dia-space point
316 * @returns a Visio-space point
317 */
318
319 static Point
visio_point(Point p)320 visio_point(Point p)
321 {
322 Point q;
323 q.x = p.x/vdx_Point_Scale;
324 q.y = (p.y - vdx_Y_Offset)/vdx_Y_Flip/vdx_Point_Scale;
325 return q;
326 }
327
328 /** Convert a Dia absolute length to a Visio one
329 * @param length a length
330 * @returns length in Visio space
331 */
332
333 static double
visio_length(double length)334 visio_length(double length)
335 {
336 return length/vdx_Point_Scale;
337 }
338
339 /** Set line width
340 * @param self a renderer
341 * @param linewidth new line width
342 */
343
344 static void
set_linewidth(DiaRenderer * self,real linewidth)345 set_linewidth(DiaRenderer *self, real linewidth)
346 {
347 VDXRenderer *renderer = VDX_RENDERER(self);
348
349 renderer->linewidth = linewidth;
350 }
351
352 /** Set line caps
353 * @param self a renderer
354 * @param mode new line caps
355 */
356
357 static void
set_linecaps(DiaRenderer * self,LineCaps mode)358 set_linecaps(DiaRenderer *self, LineCaps mode)
359 {
360 VDXRenderer *renderer = VDX_RENDERER(self);
361
362 renderer->capsmode = mode;
363 }
364
365 /** Set line join
366 * @param self a renderer
367 * @param mode new line join
368 */
369
370 static void
set_linejoin(DiaRenderer * self,LineJoin mode)371 set_linejoin(DiaRenderer *self, LineJoin mode)
372 {
373 VDXRenderer *renderer = VDX_RENDERER(self);
374
375 renderer->joinmode = mode;
376 }
377
378 /** Set line style
379 * @param self a renderer
380 * @param mode new line style
381 */
382
383 static void
set_linestyle(DiaRenderer * self,LineStyle mode)384 set_linestyle(DiaRenderer *self, LineStyle mode)
385 {
386 VDXRenderer *renderer = VDX_RENDERER(self);
387
388 renderer->stylemode = mode;
389 }
390
391 /** Set dash length
392 * @param self a renderer
393 * @param mode new dash length
394 */
395
396 static void
set_dashlength(DiaRenderer * self,real length)397 set_dashlength(DiaRenderer *self, real length)
398 {
399 VDXRenderer *renderer = VDX_RENDERER(self);
400
401 renderer->dashlength = length;
402 }
403
404 /** Set fill style
405 * @param self a renderer
406 * @param mode new file style
407 */
408
409 static void
set_fillstyle(DiaRenderer * self,FillStyle mode)410 set_fillstyle(DiaRenderer *self, FillStyle mode)
411 {
412 VDXRenderer *renderer = VDX_RENDERER(self);
413
414 renderer->fillmode = mode;
415 }
416
417 /** Set font
418 * @param self a renderer
419 * @param font new font
420 * @param height new font height
421 */
422
423 static void
set_font(DiaRenderer * self,DiaFont * font,real height)424 set_font(DiaRenderer *self, DiaFont *font, real height)
425 {
426 VDXRenderer *renderer = VDX_RENDERER(self);
427
428 renderer->font = font;
429 renderer->fontheight = height;
430 }
431
432 /** Get colour number from colour table
433 * @param renderer a renderer
434 * @param color the colour
435 * @returns a colour index (black=0)
436 */
437
438 static int
vdxCheckColor(VDXRenderer * renderer,Color * color)439 vdxCheckColor(VDXRenderer *renderer, Color *color)
440 {
441 int i;
442
443 Color cmp_color;
444 for (i = 0; i < renderer->Colors->len; i++)
445 {
446 cmp_color = g_array_index(renderer->Colors, Color, i);
447 if (color_equals(color, &cmp_color)) return i;
448 }
449 /* Grow table */
450 g_array_append_val(renderer->Colors, *color);
451 return renderer->Colors->len;
452 }
453
454 /** Get font number from font table
455 * @param renderer a renderer
456 * @returns a font index (from 0)
457 */
458
459 static int
vdxCheckFont(VDXRenderer * renderer)460 vdxCheckFont(VDXRenderer *renderer)
461 {
462 int i;
463
464 const char *cmp_font;
465 const char *font = dia_font_get_legacy_name(renderer->font);
466 for (i = 0; i < renderer->Fonts->len; i++)
467 {
468 cmp_font = g_array_index(renderer->Fonts, char *, i);
469 if (!strcmp(cmp_font, font)) return i;
470 }
471 /* Grow table */
472 g_array_append_val(renderer->Fonts, font);
473 return renderer->Fonts->len;
474 }
475
476 /** Create a Visio line style object
477 * @param self a VDXRenderer
478 * @param color a colour
479 * @param Line a Line object
480 * @param start_arrow optional start arrow
481 * @param end_arrow optional end arrow
482 * @todo join, caps, dashlength
483 */
484
485 static void
create_Line(VDXRenderer * renderer,Color * color,struct vdx_Line * Line,Arrow * start_arrow,Arrow * end_arrow)486 create_Line(VDXRenderer *renderer, Color *color, struct vdx_Line *Line,
487 Arrow *start_arrow, Arrow *end_arrow)
488 {
489 /* A Line (colour etc) */
490 memset(Line, 0, sizeof(*Line));
491 Line->type = vdx_types_Line;
492 switch (renderer->stylemode)
493 {
494 case LINESTYLE_DASHED:
495 Line->LinePattern = 2;
496 break;
497 case LINESTYLE_DOTTED:
498 Line->LinePattern = 3;
499 break;
500 case LINESTYLE_DASH_DOT:
501 Line->LinePattern = 4;
502 break;
503 case LINESTYLE_DASH_DOT_DOT:
504 Line->LinePattern = 5;
505 break;
506 default:
507 case LINESTYLE_SOLID:
508 Line->LinePattern = 1;
509 break;
510 }
511 Line->LineColor = *color;
512 Line->LineWeight = renderer->linewidth / vdx_Line_Scale;
513 if (start_arrow || end_arrow)
514 {
515 g_debug("create_Line (ARROWS)");
516 }
517 }
518
519
520 /** Create a Visio fill style object
521 * @param self a VDXRenderer
522 * @param color a colour
523 * @todo fillstyle
524 */
525
526 static void
create_Fill(VDXRenderer * renderer,Color * color,struct vdx_Fill * Fill)527 create_Fill(VDXRenderer *renderer, Color *color, struct vdx_Fill *Fill)
528 {
529 /* A Fill (colour etc) */
530 memset(Fill, 0, sizeof(*Fill));
531 Fill->type = vdx_types_Fill;
532 Fill->FillForegnd = *color;
533 Fill->FillPattern = 1; /* Solid fill */
534 }
535
536
537 /** Render a Dia line
538 * @param self a renderer
539 * @param start start of line
540 * @param end end of line
541 * @param color line colour
542 */
543
544 static void
draw_line(DiaRenderer * self,Point * start,Point * end,Color * color)545 draw_line(DiaRenderer *self, Point *start, Point *end, Color *color)
546 {
547 VDXRenderer *renderer = VDX_RENDERER(self);
548 Point a, b;
549 struct vdx_Shape Shape;
550 struct vdx_XForm XForm;
551 struct vdx_XForm1D XForm1D;
552 struct vdx_Geom Geom;
553 struct vdx_MoveTo MoveTo;
554 struct vdx_LineTo LineTo;
555 struct vdx_Line Line;
556 char NameU[VDX_NAMEU_LEN];
557
558 /* First time through, just construct the colour table */
559 if (renderer->first_pass)
560 {
561 vdxCheckColor(renderer, color);
562 return;
563 }
564
565 g_debug("draw_line((%f,%f), (%f,%f))", start->x, start->y, end->x, end->y);
566
567 /* Setup the standard shape object */
568 memset(&Shape, 0, sizeof(Shape));
569 Shape.type = vdx_types_Shape;
570 Shape.ID = renderer->shapeid++;
571 Shape.Type = "Shape";
572 sprintf(NameU, "Line.%d", Shape.ID);
573 Shape.NameU = NameU;
574 Shape.LineStyle_exists = 1;
575 Shape.FillStyle_exists = 1;
576 Shape.TextStyle_exists = 1;
577
578 /* An XForm */
579 memset(&XForm, 0, sizeof(XForm));
580 XForm.type = vdx_types_XForm;
581 a = visio_point(*start);
582 b = visio_point(*end);
583 XForm.PinX = a.x; /* Start */
584 XForm.PinY = a.y;
585 XForm.Width = fabs(b.x - a.x); /* Must be non-negative */
586 XForm.Height = fabs(b.y - a.y); /* Must be non-negative */
587 XForm.LocPinX = 0.0;
588 XForm.LocPinY = 0.0;
589 XForm.Angle = 0.0;
590
591 /* Lines must have an XForm1D as well */
592 memset(&XForm1D, 0, sizeof(XForm1D));
593 XForm1D.type = vdx_types_XForm1D;
594 XForm1D.BeginX = a.x;
595 XForm1D.BeginY = a.y;
596 XForm1D.EndX = b.x;
597 XForm1D.EndY = b.y;
598
599 /* Standard Geom object */
600 memset(&Geom, 0, sizeof(Geom));
601 Geom.NoFill = 1;
602 Geom.type = vdx_types_Geom;
603
604 /* Two children - MoveTo(start) and LineTo(end) */
605 memset(&MoveTo, 0, sizeof(MoveTo));
606 MoveTo.type = vdx_types_MoveTo;
607 MoveTo.IX = 1;
608 MoveTo.X = 0;
609 MoveTo.Y = 0;
610
611 memset(&LineTo, 0, sizeof(LineTo));
612 LineTo.type = vdx_types_LineTo;
613 LineTo.IX = 2;
614 LineTo.X = b.x-a.x;
615 LineTo.Y = b.y-a.y;
616
617 /* A Line (colour etc) */
618 create_Line(renderer, color, &Line, 0, 0);
619
620 /* Setup children */
621 Geom.children = g_slist_append(Geom.children, &MoveTo);
622 Geom.children = g_slist_append(Geom.children, &LineTo);
623
624 Shape.children = g_slist_append(Shape.children, &XForm);
625 Shape.children = g_slist_append(Shape.children, &XForm1D);
626 Shape.children = g_slist_append(Shape.children, &Line);
627 Shape.children = g_slist_append(Shape.children, &Geom);
628
629 /* Write out XML */
630 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
631
632 /* Free up list entries */
633 g_slist_free(Geom.children);
634 g_slist_free(Shape.children);
635 }
636
637
638 /** Render a Dia polyline
639 * @param self a renderer
640 * @param points the points
641 * @param num_points how many points
642 * @param color line colour
643 */
644
draw_polyline(DiaRenderer * self,Point * points,int num_points,Color * color)645 static void draw_polyline(DiaRenderer *self, Point *points, int num_points,
646 Color *color)
647 {
648 VDXRenderer *renderer = VDX_RENDERER(self);
649 Point a, b;
650 struct vdx_Shape Shape;
651 struct vdx_XForm XForm;
652 struct vdx_Geom Geom;
653 struct vdx_MoveTo MoveTo;
654 struct vdx_LineTo* LineTo;
655 struct vdx_Line Line;
656 char NameU[VDX_NAMEU_LEN];
657 unsigned int i;
658 double minX, minY, maxX, maxY;
659
660 /* First time through, just construct the colour table */
661 if (renderer->first_pass)
662 {
663 vdxCheckColor(renderer, color);
664 return;
665 }
666
667 g_debug("draw_polyline(%d)", num_points);
668
669 /* Setup the standard shape object */
670 memset(&Shape, 0, sizeof(Shape));
671 Shape.type = vdx_types_Shape;
672 Shape.ID = renderer->shapeid++;
673 Shape.Type = "Shape";
674 sprintf(NameU, "PolyLine.%d", Shape.ID);
675 Shape.NameU = NameU;
676 Shape.LineStyle_exists = 1;
677 Shape.FillStyle_exists = 1;
678 Shape.TextStyle_exists = 1;
679
680 /* An XForm */
681 memset(&XForm, 0, sizeof(XForm));
682 XForm.type = vdx_types_XForm;
683 a = visio_point(points[0]);
684
685 /* Find width and height */
686 minX = points[0].x; minY = points[0].y;
687 maxX = points[0].x; maxY = points[0].y;
688 for (i=1; i<num_points; i++)
689 {
690 if (points[i].x < minX) minX = points[i].x;
691 if (points[i].x > maxX) maxX = points[i].x;
692 if (points[i].y < minY) minY = points[i].y;
693 if (points[i].y > maxY) maxY = points[i].y;
694 }
695 XForm.Width = visio_length(maxX - minX);
696 XForm.Height = visio_length(maxY - minY);
697
698 XForm.PinX = a.x; /* Start */
699 XForm.PinY = a.y;
700 XForm.LocPinX = 0.0;
701 XForm.LocPinY = 0.0;
702 XForm.Angle = 0.0;
703
704 /* Standard Geom object */
705 memset(&Geom, 0, sizeof(Geom));
706 Geom.NoFill = 1;
707 Geom.type = vdx_types_Geom;
708
709 /* Multiple children - MoveTo(start) and LineTo(others) */
710 memset(&MoveTo, 0, sizeof(MoveTo));
711 MoveTo.type = vdx_types_MoveTo;
712 MoveTo.IX = 1;
713 MoveTo.X = 0;
714 MoveTo.Y = 0;
715
716 LineTo = g_new0(struct vdx_LineTo, num_points-1);
717 for (i=0; i<num_points-1; i++)
718 {
719 LineTo[i].type = vdx_types_LineTo;
720 LineTo[i].IX = i+2;
721 b = visio_point(points[i+1]);
722 LineTo[i].X = b.x-a.x;
723 LineTo[i].Y = b.y-a.y;
724 }
725
726 /* A Line (colour etc) */
727 create_Line(renderer, color, &Line, 0, 0);
728
729 /* Setup children */
730 Geom.children = g_slist_append(Geom.children, &MoveTo);
731 for (i=0; i<num_points-1; i++)
732 {
733 Geom.children = g_slist_append(Geom.children, &LineTo[i]);
734 }
735
736 Shape.children = g_slist_append(Shape.children, &XForm);
737 Shape.children = g_slist_append(Shape.children, &Line);
738 Shape.children = g_slist_append(Shape.children, &Geom);
739
740 /* Write out XML */
741 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
742
743 /* Free up list entries */
744 g_slist_free(Geom.children);
745 g_slist_free(Shape.children);
746 g_free(LineTo);
747 }
748
749 /** Render a Dia polygon
750 * @param self a renderer
751 * @param points corners of polygon
752 * @param num_points number of points
753 * @param color line colour
754 */
755
draw_polygon(DiaRenderer * self,Point * points,int num_points,Color * color)756 static void draw_polygon(DiaRenderer *self,
757 Point *points, int num_points,
758 Color *color)
759 {
760 Point *more_points = g_new0(Point, num_points+1);
761 memcpy(more_points, points, num_points*sizeof(Point));
762 more_points[num_points] = more_points[0];
763 g_debug("draw_polygon -> draw_polyline");
764 draw_polyline(self, more_points, num_points+1, color);
765 g_free(more_points);
766 }
767
768 /** Render a Dia filled polygon
769 * @param self a renderer
770 * @param points corners of polygon
771 * @param num_points number of points
772 * @param color line colour
773 */
774
fill_polygon(DiaRenderer * self,Point * points,int num_points,Color * color)775 static void fill_polygon(DiaRenderer *self,
776 Point *points, int num_points,
777 Color *color)
778 {
779 VDXRenderer *renderer = VDX_RENDERER(self);
780 Point a, b;
781 struct vdx_Shape Shape;
782 struct vdx_XForm XForm;
783 struct vdx_Geom Geom;
784 struct vdx_MoveTo MoveTo;
785 struct vdx_LineTo* LineTo;
786 struct vdx_Fill Fill;
787 char NameU[VDX_NAMEU_LEN];
788 unsigned int i;
789 double minX, minY, maxX, maxY;
790
791 /* First time through, just construct the colour table */
792 if (renderer->first_pass)
793 {
794 vdxCheckColor(renderer, color);
795 return;
796 }
797
798 g_debug("fill_polygon(%d)", num_points);
799
800 /* Setup the standard shape object */
801 memset(&Shape, 0, sizeof(Shape));
802 Shape.type = vdx_types_Shape;
803 Shape.ID = renderer->shapeid++;
804 Shape.Type = "Shape";
805 sprintf(NameU, "FillPolygon.%d", Shape.ID);
806 Shape.NameU = NameU;
807 Shape.LineStyle_exists = 1;
808 Shape.FillStyle_exists = 1;
809 Shape.TextStyle_exists = 1;
810
811 /* An XForm */
812 memset(&XForm, 0, sizeof(XForm));
813 XForm.type = vdx_types_XForm;
814 a = visio_point(points[0]);
815
816 /* Find width and height */
817 minX = points[0].x; minY = points[0].y;
818 maxX = points[0].x; maxY = points[0].y;
819 for (i=1; i<num_points; i++)
820 {
821 if (points[i].x < minX) minX = points[i].x;
822 if (points[i].x > maxX) maxX = points[i].x;
823 if (points[i].y < minY) minY = points[i].y;
824 if (points[i].y > maxY) maxY = points[i].y;
825 }
826 XForm.Width = visio_length(maxX - minX);
827 XForm.Height = visio_length(maxY - minY);
828
829 XForm.PinX = a.x; /* Start */
830 XForm.PinY = a.y;
831 XForm.LocPinX = 0.0;
832 XForm.LocPinY = 0.0;
833 XForm.Angle = 0.0;
834
835 /* Standard Geom object */
836 memset(&Geom, 0, sizeof(Geom));
837 Geom.type = vdx_types_Geom;
838
839 /* Multiple children - MoveTo(start) and LineTo(others) */
840 memset(&MoveTo, 0, sizeof(MoveTo));
841 MoveTo.type = vdx_types_MoveTo;
842 MoveTo.IX = 1;
843 MoveTo.X = 0;
844 MoveTo.Y = 0;
845
846 LineTo = g_new0(struct vdx_LineTo, num_points);
847 for (i=0; i<num_points; i++)
848 {
849 LineTo[i].type = vdx_types_LineTo;
850 LineTo[i].IX = i+2;
851 /* Last point = first */
852 if (i == num_points-1) b = a;
853 else b = visio_point(points[i+1]);
854 LineTo[i].X = b.x-a.x;
855 LineTo[i].Y = b.y-a.y;
856 }
857
858 /* A Line (colour etc) */
859 create_Fill(renderer, color, &Fill);
860
861 /* Setup children */
862 Geom.children = g_slist_append(Geom.children, &MoveTo);
863 for (i=0; i<num_points; i++)
864 {
865 Geom.children = g_slist_append(Geom.children, &LineTo[i]);
866 }
867
868 Shape.children = g_slist_append(Shape.children, &XForm);
869 Shape.children = g_slist_append(Shape.children, &Fill);
870 Shape.children = g_slist_append(Shape.children, &Geom);
871
872 /* Write out XML */
873 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
874
875 /* Free up list entries */
876 g_slist_free(Geom.children);
877 g_slist_free(Shape.children);
878 g_free(LineTo);
879 }
880
881 /** Render a Dia rectangle
882 * @param self a renderer
883 * @param ul_corner Upper-left corner
884 * @param lr_corner Loower-right corner
885 * @param color line colour
886 */
887
draw_rect(DiaRenderer * self,Point * ul_corner,Point * lr_corner,Color * color)888 static void draw_rect(DiaRenderer *self,
889 Point *ul_corner, Point *lr_corner,
890 Color *color)
891 {
892 Point points[5]; /* 5 so we close path */
893
894 g_debug("draw_rect((%f,%f), (%f,%f)) -> draw_polyline",
895 ul_corner->x, ul_corner->y, lr_corner->x, lr_corner->y);
896 points[0].x = ul_corner->x; points[0].y = lr_corner->y;
897 points[1] = *lr_corner;
898 points[2].x = lr_corner->x; points[2].y = ul_corner->y;
899 points[3] = *ul_corner;
900 points[4] = points[0];
901
902 draw_polygon(self, points, 5, color);
903 }
904
905 /** Render a Dia filled rectangle
906 * @param self a renderer
907 * @param ul_corner Upper-left corner
908 * @param lr_corner Lower-right corner
909 * @param color line colour
910 */
911
fill_rect(DiaRenderer * self,Point * ul_corner,Point * lr_corner,Color * color)912 static void fill_rect(DiaRenderer *self,
913 Point *ul_corner, Point *lr_corner,
914 Color *color)
915 {
916 Point points[5]; /* 5 so we close path */
917
918 g_debug("fill_rect -> fill_polygon");
919 points[0].x = ul_corner->x; points[0].y = lr_corner->y;
920 points[1] = *lr_corner;
921 points[2].x = lr_corner->x; points[2].y = ul_corner->y;
922 points[3] = *ul_corner;
923 points[4] = points[0];
924
925 fill_polygon(self, points, 5, color);
926 }
927
928 /** Render a Dia arc
929 * @param self a renderer
930 * @param center centre of arc
931 * @param width width of ellipse
932 * @param height height of ellipse (= width for Dia circular arcs)
933 * @param angle1 start angle to x axis in degrees
934 * @param angle2 end angle to x axis in degrees
935 * @param color line colour
936 * @todo Not done yet
937 */
938
draw_arc(DiaRenderer * self,Point * center,real width,real height,real angle1,real angle2,Color * color)939 static void draw_arc(DiaRenderer *self,
940 Point *center,
941 real width, real height,
942 real angle1, real angle2,
943 Color *color)
944 {
945 VDXRenderer *renderer = VDX_RENDERER(self);
946 Point a;
947 struct vdx_Shape Shape;
948 struct vdx_XForm XForm;
949 struct vdx_Geom Geom;
950 struct vdx_EllipticalArcTo EllipticalArcTo;
951 struct vdx_MoveTo MoveTo;
952 struct vdx_Line Line;
953 char NameU[VDX_NAMEU_LEN];
954 Point start, control, end;
955 float control_angle;
956
957 /* First time through, just construct the colour table */
958 if (renderer->first_pass)
959 {
960 vdxCheckColor(renderer, color);
961 return;
962 }
963
964 g_debug("draw_arc((%f,%f),%f,%f;%f,%f)", center->x, center->y,
965 width, height, angle1, angle2);
966
967 /* Setup the standard shape object */
968 memset(&Shape, 0, sizeof(Shape));
969 Shape.type = vdx_types_Shape;
970 Shape.ID = renderer->shapeid++;
971 Shape.Type = "Shape";
972 sprintf(NameU, "Arc.%d", Shape.ID);
973 Shape.NameU = NameU;
974 Shape.LineStyle_exists = 1;
975 Shape.FillStyle_exists = 1;
976 Shape.TextStyle_exists = 1;
977
978 /* An XForm */
979 memset(&XForm, 0, sizeof(XForm));
980 XForm.type = vdx_types_XForm;
981
982 /* Find the start of the arc */
983 start = *center;
984 start.x += (width/2.0)*cos(angle1*DEG_TO_RAD);
985 start.y -= (height/2.0)*sin(angle1*DEG_TO_RAD);
986 g_debug("start(%f,%f)", start.x, start.y);
987 start = visio_point(start);
988
989 /* Find a control point at the midpoint of the arc */
990 control = *center;
991 control_angle = (angle1 + angle2)/2.0;
992 if (angle1 > angle2)
993 {
994 /* Arc goes antclockwise - allow for this */
995 control_angle -= 180;
996 }
997 control.x += (width/2.0)*cos(control_angle*DEG_TO_RAD);
998 control.y -= (height/2.0)*sin(control_angle*DEG_TO_RAD);
999 g_debug("control(%f,%f @ %f)", control.x, control.y, control_angle);
1000 control = visio_point(control);
1001
1002 /* And the endpoint */
1003 end = *center;
1004 end.x += (width/2.0)*cos(angle2*DEG_TO_RAD);
1005 end.y -= (height/2.0)*sin(angle2*DEG_TO_RAD);
1006 g_debug("end(%f,%f)", end.x, end.y);
1007 end = visio_point(end);
1008
1009 a = start;
1010 XForm.PinX = a.x; /* Start */
1011 XForm.PinY = a.y;
1012 XForm.Width = visio_length(width);
1013 XForm.Height = visio_length(height);
1014 XForm.LocPinX = 0;
1015 XForm.LocPinY = 0;
1016 XForm.Angle = 0.0;
1017
1018 /* Standard Geom object */
1019 memset(&Geom, 0, sizeof(Geom));
1020 Geom.NoFill = 1;
1021 Geom.type = vdx_types_Geom;
1022
1023 memset(&MoveTo, 0, sizeof(MoveTo));
1024 MoveTo.type = vdx_types_MoveTo;
1025 MoveTo.IX = 1;
1026 MoveTo.X = 0;
1027 MoveTo.Y = 0;
1028
1029 /* Second child - EllipticalArcTo */
1030 memset(&EllipticalArcTo, 0, sizeof(EllipticalArcTo));
1031 EllipticalArcTo.type = vdx_types_EllipticalArcTo;
1032 EllipticalArcTo.IX = 2;
1033
1034 /* X and Y are the end point
1035 A and B are a control point on the arc
1036 C is the angle of the major axis
1037 D is the ratio of the major to minor axes */
1038
1039 /* Need to fix these */
1040 EllipticalArcTo.X = end.x - a.x;
1041 EllipticalArcTo.Y = end.y - a.y;
1042 EllipticalArcTo.A = control.x - a.x;
1043 EllipticalArcTo.B = control.y - a.y;
1044 EllipticalArcTo.C = 0.0; /* Dia major axis always x axis */
1045 if (fabs(height) > EPSILON)
1046 EllipticalArcTo.D = width/height; /* Always 1 for Dia */
1047 else
1048 EllipticalArcTo.D = 1/EPSILON;
1049
1050 /* A Line (colour etc) */
1051 create_Line(renderer, color, &Line, 0, 0);
1052
1053 /* Setup children */
1054 Geom.children = g_slist_append(Geom.children, &MoveTo);
1055 Geom.children = g_slist_append(Geom.children, &EllipticalArcTo);
1056
1057 Shape.children = g_slist_append(Shape.children, &XForm);
1058 Shape.children = g_slist_append(Shape.children, &Line);
1059 Shape.children = g_slist_append(Shape.children, &Geom);
1060
1061 /* Write out XML */
1062 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
1063
1064 /* Free up list entries */
1065 g_slist_free(Geom.children);
1066 g_slist_free(Shape.children);
1067 }
1068
1069 /** Render a Dia filled arc
1070 * @param self a renderer
1071 * @param center centre of arc
1072 * @param width width of bounding box
1073 * @param height height of bounding box
1074 * @param angle1 start angle
1075 * @param angle2 end angle
1076 * @param color line colour
1077 * @todo Not done yet - believe unused
1078 */
1079
fill_arc(DiaRenderer * self,Point * center,real width,real height,real angle1,real angle2,Color * color)1080 static void fill_arc(DiaRenderer *self,
1081 Point *center,
1082 real width, real height,
1083 real angle1, real angle2,
1084 Color *color)
1085 {
1086 VDXRenderer *renderer = VDX_RENDERER(self);
1087
1088 if (renderer->first_pass)
1089 {
1090 vdxCheckColor(renderer, color);
1091 return;
1092 }
1093 g_debug("fill_arc (TODO)");
1094 }
1095
1096 /** Render a Dia ellipse (parallel to axes)
1097 * @param self a renderer
1098 * @param center centre of ellipse
1099 * @param width width of bounding box
1100 * @param height height of bounding box
1101 * @param color line colour
1102 */
1103
draw_ellipse(DiaRenderer * self,Point * center,real width,real height,Color * color)1104 static void draw_ellipse(DiaRenderer *self,
1105 Point *center,
1106 real width, real height,
1107 Color *color)
1108 {
1109 VDXRenderer *renderer = VDX_RENDERER(self);
1110 Point a;
1111 struct vdx_Shape Shape;
1112 struct vdx_XForm XForm;
1113 struct vdx_Geom Geom;
1114 struct vdx_Ellipse Ellipse;
1115 struct vdx_Line Line;
1116 char NameU[VDX_NAMEU_LEN];
1117
1118 /* First time through, just construct the colour table */
1119 if (renderer->first_pass)
1120 {
1121 vdxCheckColor(renderer, color);
1122 return;
1123 }
1124
1125 g_debug("draw_ellipse");
1126
1127 /* Setup the standard shape object */
1128 memset(&Shape, 0, sizeof(Shape));
1129 Shape.type = vdx_types_Shape;
1130 Shape.ID = renderer->shapeid++;
1131 Shape.Type = "Shape";
1132 sprintf(NameU, "Ellipse.%d", Shape.ID);
1133 Shape.NameU = NameU;
1134 Shape.LineStyle_exists = 1;
1135 Shape.FillStyle_exists = 1;
1136 Shape.TextStyle_exists = 1;
1137
1138 /* An XForm */
1139 memset(&XForm, 0, sizeof(XForm));
1140 XForm.type = vdx_types_XForm;
1141 a = visio_point(*center);
1142 XForm.PinX = a.x; /* Start */
1143 XForm.PinY = a.y;
1144 XForm.Width = visio_length(width);
1145 XForm.Height = visio_length(height);
1146 XForm.LocPinX = XForm.Width/2.0;
1147 XForm.LocPinY = XForm.Height/2.0;
1148 XForm.Angle = 0.0;
1149
1150 /* Standard Geom object */
1151 memset(&Geom, 0, sizeof(Geom));
1152 Geom.NoFill = 1;
1153 Geom.type = vdx_types_Geom;
1154
1155 /* One child - Ellipse */
1156 memset(&Ellipse, 0, sizeof(Ellipse));
1157 Ellipse.type = vdx_types_Ellipse;
1158 Ellipse.IX = 1;
1159 Ellipse.X = XForm.Width/2.0;
1160 Ellipse.Y = XForm.Height/2.0;
1161 Ellipse.A = XForm.Width;
1162 Ellipse.B = XForm.Height/2.0;
1163 Ellipse.C = XForm.Width/2.0;
1164 Ellipse.D = XForm.Height;
1165
1166 /* A Line (colour etc) */
1167 create_Line(renderer, color, &Line, 0, 0);
1168
1169 /* Setup children */
1170 Geom.children = g_slist_append(Geom.children, &Ellipse);
1171
1172 Shape.children = g_slist_append(Shape.children, &XForm);
1173 Shape.children = g_slist_append(Shape.children, &Line);
1174 Shape.children = g_slist_append(Shape.children, &Geom);
1175
1176 /* Write out XML */
1177 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
1178
1179 /* Free up list entries */
1180 g_slist_free(Geom.children);
1181 g_slist_free(Shape.children);
1182 }
1183
1184 /** Render a Dia filled ellipse (parallel to axes)
1185 * @param self a renderer
1186 * @param center centre of ellipse
1187 * @param width width of bounding box
1188 * @param height height of bounding box
1189 * @param color line colour
1190 */
1191
fill_ellipse(DiaRenderer * self,Point * center,real width,real height,Color * color)1192 static void fill_ellipse(DiaRenderer *self,
1193 Point *center,
1194 real width, real height,
1195 Color *color)
1196 {
1197 VDXRenderer *renderer = VDX_RENDERER(self);
1198 Point a;
1199 struct vdx_Shape Shape;
1200 struct vdx_XForm XForm;
1201 struct vdx_Geom Geom;
1202 struct vdx_Ellipse Ellipse;
1203 struct vdx_Fill Fill;
1204 char NameU[VDX_NAMEU_LEN];
1205
1206 /* First time through, just construct the colour table */
1207 if (renderer->first_pass)
1208 {
1209 vdxCheckColor(renderer, color);
1210 return;
1211 }
1212
1213 g_debug("fill_ellipse");
1214
1215 /* Setup the standard shape object */
1216 memset(&Shape, 0, sizeof(Shape));
1217 Shape.type = vdx_types_Shape;
1218 Shape.ID = renderer->shapeid++;
1219 Shape.Type = "Shape";
1220 sprintf(NameU, "FillEllipse.%d", Shape.ID);
1221 Shape.NameU = NameU;
1222 Shape.LineStyle_exists = 1;
1223 Shape.FillStyle_exists = 1;
1224 Shape.TextStyle_exists = 1;
1225
1226 /* An XForm */
1227 memset(&XForm, 0, sizeof(XForm));
1228 XForm.type = vdx_types_XForm;
1229 a = visio_point(*center);
1230 XForm.PinX = a.x; /* Start */
1231 XForm.PinY = a.y;
1232 XForm.Width = visio_length(width);
1233 XForm.Height = visio_length(height);
1234 XForm.LocPinX = XForm.Width/2.0;
1235 XForm.LocPinY = XForm.Height/2.0;
1236 XForm.Angle = 0.0;
1237
1238 /* Standard Geom object */
1239 memset(&Geom, 0, sizeof(Geom));
1240 Geom.type = vdx_types_Geom;
1241
1242 /* One child - Ellipse */
1243 memset(&Ellipse, 0, sizeof(Ellipse));
1244 Ellipse.type = vdx_types_Ellipse;
1245 Ellipse.IX = 1;
1246 Ellipse.X = XForm.Width/2.0;
1247 Ellipse.Y = XForm.Height/2.0;
1248 Ellipse.A = XForm.Width;
1249 Ellipse.B = XForm.Height/2.0;
1250 Ellipse.C = XForm.Width/2.0;
1251 Ellipse.D = XForm.Height;
1252
1253 /* A Fill (colour etc) */
1254 create_Fill(renderer, color, &Fill);
1255
1256 /* Setup children */
1257 Geom.children = g_slist_append(Geom.children, &Ellipse);
1258
1259 Shape.children = g_slist_append(Shape.children, &XForm);
1260 Shape.children = g_slist_append(Shape.children, &Fill);
1261 Shape.children = g_slist_append(Shape.children, &Geom);
1262
1263 /* Write out XML */
1264 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
1265
1266 /* Free up list entries */
1267 g_slist_free(Geom.children);
1268 g_slist_free(Shape.children);
1269 }
1270
1271 /** Render a Dia string
1272 * @param self a renderer
1273 * @param text the string
1274 * @param pos start (or centre etc.)
1275 * @param alignment alignment
1276 * @param color line colour
1277 * @todo Alignment, colour
1278 * @bug Bounding box incorrect
1279 */
1280
draw_string(DiaRenderer * self,const char * text,Point * pos,Alignment alignment,Color * color)1281 static void draw_string(DiaRenderer *self,
1282 const char *text,
1283 Point *pos, Alignment alignment,
1284 Color *color)
1285 {
1286 VDXRenderer *renderer = VDX_RENDERER(self);
1287 Point a;
1288 struct vdx_Shape Shape;
1289 struct vdx_XForm XForm;
1290 struct vdx_Char Char;
1291 struct vdx_Text Text;
1292 struct vdx_text my_text;
1293 char NameU[VDX_NAMEU_LEN];
1294
1295 if (renderer->first_pass)
1296 {
1297 /* Add to colour and font tables */
1298 vdxCheckColor(renderer, color);
1299 vdxCheckFont(renderer);
1300 return;
1301 }
1302
1303 g_debug("draw_string");
1304 /* Standard shape */
1305 memset(&Shape, 0, sizeof(Shape));
1306 Shape.type = vdx_types_Shape;
1307 Shape.ID = renderer->shapeid++;
1308 Shape.Type = "Shape";
1309 sprintf(NameU, "Text.%d", Shape.ID);
1310 Shape.NameU = NameU;
1311 Shape.LineStyle_exists = 1;
1312 Shape.FillStyle_exists = 1;
1313 Shape.TextStyle_exists = 1;
1314
1315 /* XForm describes bounding box */
1316 memset(&XForm, 0, sizeof(XForm));
1317 XForm.type = vdx_types_XForm;
1318 a = visio_point(*pos);
1319 XForm.PinX = a.x;
1320 XForm.PinY = a.y;
1321 XForm.Angle = 0;
1322 /* Hack to give it an approximate bounding box */
1323 XForm.Height = renderer->fontheight/vdx_Font_Size_Conversion;
1324 XForm.Width = strlen(text)*renderer->fontheight/vdx_Font_Size_Conversion;
1325
1326 /* Character properties */
1327 memset(&Char, 0, sizeof(Char));
1328 Char.type = vdx_types_Char;
1329 Char.Font = vdxCheckFont(renderer);
1330 Char.Color = *color;
1331 Char.FontScale = 1;
1332 Char.Size = renderer->fontheight/vdx_Font_Size_Conversion;
1333
1334 /* Text object - no attributes */
1335 memset(&Text, 0, sizeof(Text));
1336 Text.type = vdx_types_Text;
1337
1338 /* text object (XML pseudo-tag) - no attributes */
1339 memset(&my_text, 0, sizeof(my_text));
1340 my_text.type = vdx_types_text;
1341 my_text.text = (char *)text;
1342
1343 /* Construct the children */
1344 Text.children = g_slist_append(Text.children, &my_text);
1345
1346 Shape.children = g_slist_append(Shape.children, &XForm);
1347 Shape.children = g_slist_append(Shape.children, &Char);
1348 Shape.children = g_slist_append(Shape.children, &Text);
1349
1350 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
1351
1352 g_slist_free(Text.children);
1353 g_slist_free(Shape.children);
1354 }
1355
1356 /** Reads binary file and converts to Base64 data
1357 * @param filename file to read
1358 * @returns Base64 encoded data (or NULL if problem)
1359 * @note glibc 2.12 offers g_base64_encode()
1360 */
1361
1362 static char *
read_base64_file(const char * filename)1363 read_base64_file(const char *filename)
1364 {
1365 FILE *f;
1366 char *b64 = 0;
1367 char *s = 0;
1368 int c = 0;
1369 char map[64];
1370 unsigned int buf_len = 0;
1371 unsigned char buf[3];
1372 struct stat stat_buf;
1373
1374 if (g_stat(filename, &stat_buf))
1375 {
1376 message_error(_("Couldn't read file %s"), filename);
1377 return 0;
1378 }
1379 b64 = g_new0(char, stat_buf.st_size*4/3+5);
1380 s = b64;
1381
1382 f = g_fopen(filename, "r+b");
1383 if (!f)
1384 {
1385 message_error(_("Couldn't read file %s"), filename);
1386 return 0;
1387 }
1388
1389 /* Construct Base64 mapping table */
1390 for(c=0; c<26; c++) map[c] = 'A' + c;
1391 for(c=0; c<26; c++) map[c+26] = 'a' + c;
1392 for(c=0; c<10; c++) map[c+52] = '0' + c;
1393 map[62] = '+';
1394 map[63] = '/';
1395
1396 while((c = fgetc(f)) != EOF)
1397 {
1398 buf[buf_len++] = (unsigned char)c;
1399 if (buf_len == 3)
1400 {
1401 *s++ = map[buf[0] >> 2];
1402 *s++ = map[((buf[0] & 3) << 4) + (buf[1] >> 4)];
1403 *s++ = map[((buf[1] & 15) << 2) + (buf[2] >> 6)];
1404 *s++ = map[buf[2] & 63];
1405 buf_len = 0;
1406 }
1407 }
1408
1409 if (buf_len == 1)
1410 {
1411 *s++ = map[buf[0] >> 2];
1412 *s++ = map[((buf[0] & 3) << 4)];
1413 *s++ = '=';
1414 *s++ = '=';
1415 }
1416 if (buf_len == 2)
1417 {
1418 *s++ = map[buf[0] >> 2];
1419 *s++ = map[((buf[0] & 3) << 4) + (buf[1] >> 4)];
1420 *s++ = map[((buf[1] & 15) << 2)];
1421 *s++ = '=';
1422 }
1423
1424 fclose(f);
1425 *s = 0;
1426 return b64;
1427
1428 /* Deal with any chunks left over */
1429 if (buf_len)
1430 {
1431 fputc(buf[0] << 2 | buf[1] >> 4, f);
1432 if (buf_len > 1)
1433 {
1434 fputc(buf[1] << 4 | buf[2] >> 2, f);
1435 if (buf_len > 2)
1436 {
1437 /* This one can't happen */
1438 fputc(buf[2] << 6 | buf[3], f);
1439 }
1440 }
1441 }
1442
1443 fclose(f);
1444 }
1445
1446 /** Render a Dia bitmap
1447 * @param self a renderer
1448 * @param point top left
1449 * @param width width
1450 * @param height height
1451 */
1452
draw_image(DiaRenderer * self,Point * point,real width,real height,DiaImage * image)1453 static void draw_image(DiaRenderer *self,
1454 Point *point,
1455 real width, real height,
1456 DiaImage *image)
1457 {
1458 VDXRenderer *renderer = VDX_RENDERER(self);
1459 Point a, bottom_left;
1460 struct vdx_Shape Shape;
1461 struct vdx_XForm XForm;
1462 struct vdx_Geom Geom;
1463 struct vdx_Foreign Foreign;
1464 struct vdx_ForeignData ForeignData;
1465 struct vdx_text text;
1466 char NameU[VDX_NAMEU_LEN];
1467 const char *filename = NULL;
1468 const char *suffix = NULL;
1469
1470 if (renderer->first_pass)
1471 {
1472 return;
1473 }
1474
1475 g_debug("draw_image((%f,%f), %f, %f, %s", point->x, point->y,
1476 width, height, dia_image_filename(image));
1477 /* Setup the standard shape object */
1478 memset(&Shape, 0, sizeof(Shape));
1479 Shape.type = vdx_types_Shape;
1480 Shape.ID = renderer->shapeid++;
1481 Shape.Type = "Foreign";
1482 sprintf(NameU, "Foreign.%d", Shape.ID);
1483 Shape.NameU = NameU;
1484 Shape.LineStyle_exists = 1;
1485 Shape.FillStyle_exists = 1;
1486 Shape.TextStyle_exists = 1;
1487
1488 /* An XForm */
1489 memset(&XForm, 0, sizeof(XForm));
1490 XForm.type = vdx_types_XForm;
1491 bottom_left.x = point->x;
1492 bottom_left.y = point->y + height;
1493 a = visio_point(bottom_left);
1494 XForm.PinX = a.x; /* Start */
1495 XForm.PinY = a.y;
1496 XForm.Width = visio_length(width);
1497 XForm.Height = visio_length(height);
1498 XForm.LocPinX = 0;
1499 XForm.LocPinY = 0;
1500 XForm.Angle = 0.0;
1501
1502 /* Standard Geom object */
1503 memset(&Geom, 0, sizeof(Geom));
1504 Geom.type = vdx_types_Geom;
1505 /* We don't use it, but our decoder needs it */
1506
1507 /* And a Foreign */
1508 memset(&Foreign, 0, sizeof(Foreign));
1509 Foreign.type = vdx_types_Foreign;
1510 Foreign.ImgOffsetX = 0;
1511 Foreign.ImgOffsetY = 0;
1512 Foreign.ImgHeight = visio_length(height);
1513 Foreign.ImgWidth = visio_length(width);
1514
1515 /* And a ForeignData */
1516 memset(&ForeignData, 0, sizeof(ForeignData));
1517 ForeignData.type = vdx_types_ForeignData;
1518 ForeignData.ForeignType = "Bitmap";
1519 ForeignData.CompressionType = "JPEG";
1520 ForeignData.CompressionLevel = 1.0;
1521 ForeignData.ObjectHeight = visio_length(height);
1522 ForeignData.ObjectWidth = visio_length(width);
1523
1524 filename = dia_image_filename(image);
1525 if ((suffix = strrchr(filename, '.')))
1526 {
1527 suffix++;
1528 if (!g_ascii_strncasecmp(suffix, "png", 3)) { ForeignData.CompressionType = "PNG"; }
1529 if (!g_ascii_strncasecmp(suffix, "gif", 3)) { ForeignData.CompressionType = "GIF"; }
1530 if (!g_ascii_strncasecmp(suffix, "jpg", 3) || !g_ascii_strncasecmp(suffix, "jpeg", 4))
1531 { ForeignData.CompressionType = "JPEG"; }
1532 if (!g_ascii_strncasecmp(suffix, "tif", 3) || !g_ascii_strncasecmp(suffix, "tiff", 4))
1533 { ForeignData.CompressionType = "TIFF"; }
1534 }
1535
1536 /* And the data itself */
1537 memset(&text, 0, sizeof(text));
1538 text.type = vdx_types_text;
1539 text.text = read_base64_file(filename);
1540 if (!text.text) return; /* Problem reading file */
1541
1542 /* Setup children */
1543 Shape.children = g_slist_append(Shape.children, &XForm);
1544 Shape.children = g_slist_append(Shape.children, &Geom);
1545 Shape.children = g_slist_append(Shape.children, &Foreign);
1546 Shape.children = g_slist_append(Shape.children, &ForeignData);
1547 ForeignData.children = g_slist_append(ForeignData.children, &text);
1548
1549 /* Write out XML */
1550 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
1551
1552 /* Free up list entries */
1553 g_slist_free(ForeignData.children);
1554 g_slist_free(Shape.children);
1555
1556 /* And the Base64 data */
1557 g_free(text.text);
1558 }
1559
1560 /** Convert Dia colour to hex string
1561 * @param c a colour
1562 * @returns string in form #000000
1563 * @note static buffer overwritten with next call; not thread-safe
1564 */
1565
1566 const char *
vdx_string_color(Color c)1567 vdx_string_color(Color c)
1568 {
1569 static char buf[8];
1570 sprintf(buf, "#%.2X%.2X%.2X",
1571 (int)(c.red*255), (int)(c.green*255), (int)(c.blue*255));
1572 return buf;
1573 }
1574
1575 /** Return string XML-encoded
1576 * @param s a string
1577 * @returns encoded string
1578 * @note uses static buffer so can be used as inline filter in printf
1579 */
1580
1581 const char *
vdx_convert_xml_string(const char * s)1582 vdx_convert_xml_string(const char *s)
1583 {
1584 static char *out = 0;
1585 char *c;
1586
1587 /* If (as almost always) no change required, return intact */
1588 if (strcspn(s, "&<>\"'") == strlen(s)) return s;
1589
1590 /* Ensure we have enough space, even if all the string is quotes */
1591 out = realloc(out, 6*strlen(s)+1);
1592 c = out;
1593
1594 while(*s)
1595 {
1596 switch(*s)
1597 {
1598 case '&':
1599 strcpy(c, "&"); c += 5;
1600 break;
1601 case '<':
1602 strcpy(c, "<"); c += 4;
1603 break;
1604 case '>':
1605 strcpy(c, ">"); c += 4;
1606 break;
1607 case '\"':
1608 case '\'':
1609 strcpy(c, """); c += 6;
1610 break;
1611 default:
1612 *c++ = *s;
1613 }
1614 s++;
1615 }
1616 *c = 0;
1617 return out;
1618 }
1619
1620 /** Write VDX file header
1621 * @param data diagram data
1622 * @param renderer a renderer
1623 * @note Must know if 2002 or 2003 before start
1624 * @todo paper size, orientation, metadata, 2003 font attributes
1625 */
1626
1627 static void
write_header(DiagramData * data,VDXRenderer * renderer)1628 write_header(DiagramData *data, VDXRenderer *renderer)
1629 {
1630 FILE *file = renderer->file;
1631 Color c;
1632 const char *f;
1633 unsigned int i;
1634 struct vdx_StyleSheet StyleSheet;
1635 struct vdx_StyleProp StyleProp;
1636 struct vdx_Line Line;
1637 struct vdx_Fill Fill;
1638 struct vdx_TextBlock TextBlock;
1639 struct vdx_Char Char;
1640 struct vdx_Para Para;
1641 struct vdx_Tabs Tabs;
1642 static Color color_black = {0,0,0};
1643
1644 g_debug("write_header");
1645
1646 /* Basic XML identifying info */
1647
1648 fprintf(file, "<?xml version='1.0' encoding='utf-8'?>\n");
1649 fprintf(file, "<!-- Created by Dia -->\n");
1650 if (renderer->version == 2002)
1651 {
1652 fprintf(file,
1653 "<VisioDocument "
1654 "xmlns='urn:schemas-microsoft-com:office:visio'>\n");
1655 }
1656 if (renderer->version == 2003)
1657 {
1658 fprintf(file, "<VisioDocument "
1659 "xmlns='http://schemas.microsoft.com/visio/2003/core' "
1660 "start='190' metric='0' "
1661 "DocLangID='1033' version='11.0' xml:space='preserve'>\n");
1662 }
1663
1664 /* Skipping DocumentProperties, DocumentSettings - observed unnecessary */
1665
1666 /* Other fields that may be useful:
1667 fprintf(file, (data->paper.is_portrait?"Portrait\n":"Landscape\n"));
1668 fprintf(file, "%s\n", data->paper.name);
1669 fprintf(file, "%f\n", data->paper.scaling*100.0);
1670 */
1671
1672 /* Colour table */
1673
1674 fprintf(file, " <Colors>\n");
1675 for (i = 0; i < renderer->Colors->len; i++)
1676 {
1677 c = g_array_index(renderer->Colors, Color, i);
1678 fprintf(file, " <ColorEntry IX='%d' RGB='%s'/>\n",
1679 i, vdx_string_color(c));
1680 }
1681 fprintf(file, " </Colors>\n");
1682
1683 /* Font table - different between the two versions (alas) */
1684
1685 if (renderer->version == 2002)
1686 {
1687 fprintf(file, " <Fonts>\n");
1688 for (i = 0; i < renderer->Fonts->len; i++)
1689 {
1690 struct vdx_FontEntry Font;
1691 memset(&Font, 0, sizeof(Font));
1692 Font.type = vdx_types_FontEntry;
1693 f = g_array_index(renderer->Fonts, char *, i);
1694
1695 /* Assume want stndard fonts names converted */
1696 if (!strcmp(f, "Helvetica")) f = "Arial";
1697 if (!strcmp(f, "Times")) f = "Times New Roman";
1698
1699 Font.Name = (char *)f;
1700 /* Sensible defaults */
1701 Font.CharSet = 0;
1702 Font.CharSet_exists = 1;
1703 Font.PitchAndFamily = 18;
1704 Font.PitchAndFamily_exists = 1;
1705 Font.Attributes = 23040;
1706 Font.Attributes_exists = 1;
1707 Font.Weight = 0;
1708 Font.Unicode = 0;
1709
1710 /* Some observed values */
1711 if (!strcmp(f, "Arial")) Font.PitchAndFamily = 32;
1712 if (!strcmp(f, "Wingdings") || !strcmp(f, "Monotype Sorts") ||
1713 !strcmp(f, "Symbol")) Font.CharSet = 2;
1714 if (!strcmp(f, "Monotype Sorts")) Font.Attributes = 4096;
1715 if (!strcmp(f, "Wingdings") || !strcmp(f, "Monotype Sorts"))
1716 Font.PitchAndFamily = 2;
1717 vdx_write_object(renderer->file, 2, &Font);
1718 }
1719 fprintf(file, " </Fonts>\n");
1720 }
1721 if (renderer->version == 2003)
1722 {
1723 fprintf(file, " <FaceNames>\n");
1724 for (i = 0; i < renderer->Fonts->len; i++)
1725 {
1726 f = g_array_index(renderer->Fonts, char *, i);
1727
1728 /* Assume want stndard fonts names converted */
1729 if (!strcmp(f, "Helvetica")) f = "Arial";
1730 if (!strcmp(f, "Times")) f = "Times New Roman";
1731
1732 /* Missing attrs UnicodeRanges="31367 -2147483648 8 0"
1733 CharSets="1073742335 -65536"
1734 Panos="2 11 6 4 2 2 2 2 2 4" Flags="325" */
1735 fprintf(file, " <FaceName ID='%d' Name='%s'/>\n",
1736 i, f);
1737 }
1738 fprintf(file, " </FaceNames>\n");
1739 }
1740
1741 /* An initial stylesheet (mandatory) */
1742 memset(&StyleSheet, 0, sizeof(StyleSheet));
1743 StyleSheet.type = vdx_types_StyleSheet;
1744 StyleSheet.NameU = "No Style";
1745
1746 /* All these values observed */
1747 memset(&StyleProp, 0, sizeof(StyleProp));
1748 StyleProp.type = vdx_types_StyleProp;
1749 StyleProp.EnableLineProps = 1;
1750 StyleProp.EnableFillProps = 1;
1751 StyleProp.EnableTextProps = 1;
1752
1753 memset(&Line, 0, sizeof(Line));
1754 Line.type = vdx_types_Line;
1755 Line.LineWeight = 0.01;
1756 Line.LinePattern = 1;
1757
1758 memset(&Fill, 0, sizeof(Fill));
1759 Fill.type = vdx_types_Fill;
1760 Fill.FillForegnd = color_black;
1761 Fill.FillPattern = 1;
1762
1763 memset(&TextBlock, 0, sizeof(TextBlock));
1764 TextBlock.type = vdx_types_TextBlock;
1765 TextBlock.VerticalAlign = 1;
1766 TextBlock.DefaultTabStop = 0.59055118110236;
1767
1768 memset(&Char, 0, sizeof(Char));
1769 Char.type = vdx_types_Char;
1770 Char.FontScale = 1;
1771 Char.Size = 0.16666666666667;
1772
1773 memset(&Para, 0, sizeof(Para));
1774 Para.type = vdx_types_Para;
1775 Para.SpLine = -1.2;
1776 Para.HorzAlign = 1;
1777 Para.BulletStr = "";
1778 Para.BulletFontSize = "-1";
1779
1780 memset(&Tabs, 0, sizeof(Tabs));
1781 Tabs.type = vdx_types_Tabs;
1782
1783 /* Setup children */
1784 StyleSheet.children = g_slist_append(StyleSheet.children, &StyleProp);
1785 StyleSheet.children = g_slist_append(StyleSheet.children, &Line);
1786 StyleSheet.children = g_slist_append(StyleSheet.children, &Fill);
1787 StyleSheet.children = g_slist_append(StyleSheet.children, &TextBlock);
1788 StyleSheet.children = g_slist_append(StyleSheet.children, &Char);
1789 StyleSheet.children = g_slist_append(StyleSheet.children, &Para);
1790 StyleSheet.children = g_slist_append(StyleSheet.children, &Tabs);
1791
1792 fprintf(file, " <StyleSheets>\n");
1793 vdx_write_object(renderer->file, 2, &StyleSheet);
1794 fprintf(file, " </StyleSheets>\n");
1795
1796 g_slist_free(StyleSheet.children);
1797
1798 /* Following attributes observed */
1799 fprintf(file, " <Pages>\n");
1800 fprintf(file, " <Page ID='0' NameU='Page-1' ViewScale='-1' "
1801 "ViewCenterX='5.8425196850394' ViewCenterY='3.7244094488189'>\n");
1802 fprintf(file, " <Shapes>\n");
1803 renderer->xml_depth = 4;
1804 renderer->shapeid = 1;
1805
1806 /* Exit nested <VisioDocument><Pages><Page><Shapes> */
1807 }
1808
1809 /** Write VDX file trailer
1810 * @param data diagram data
1811 * @param renderer a renderer
1812 */
1813
1814 static void
write_trailer(DiagramData * data,VDXRenderer * renderer)1815 write_trailer(DiagramData *data, VDXRenderer *renderer)
1816 {
1817 FILE *file = renderer->file;
1818
1819 g_debug("write_trailer");
1820
1821 /* Enter nested <VisioDocument><Pages><Page><Shapes> */
1822
1823 fprintf(file, " </Shapes>\n");
1824 fprintf(file, " </Page>\n");
1825 fprintf(file, " </Pages>\n");
1826 fprintf(file, "</VisioDocument>\n");
1827 }
1828
1829 /** Write VDX file
1830 * @param data diagram data
1831 * @param filename output file (should check suffix)
1832 * @param diafilename input filename (unused)
1833 * @param user_data user data (unused)
1834 * @note Must know if 2002 or 2003 before start
1835 */
1836
1837 static void
export_vdx(DiagramData * data,const gchar * filename,const gchar * diafilename,void * user_data)1838 export_vdx(DiagramData *data, const gchar *filename,
1839 const gchar *diafilename, void* user_data)
1840 {
1841 FILE *file;
1842 VDXRenderer *renderer;
1843 int i;
1844 Layer *layer;
1845 char* old_locale;
1846
1847 file = g_fopen(filename, "w");
1848
1849 if (file == NULL) {
1850 message_error(_("Can't open output file %s: %s\n"),
1851 dia_message_filename(filename), strerror(errno));
1852 return;
1853 }
1854
1855 /* ugly, but still better than creatin corrupt files */
1856 old_locale = setlocale(LC_NUMERIC, "C");
1857
1858 /* Create and initialise our renderer */
1859 renderer = g_object_new(VDX_TYPE_RENDERER, NULL);
1860
1861 renderer->file = file;
1862
1863 renderer->first_pass = TRUE;
1864
1865 renderer->version = 2002; /* For now */
1866
1867 DIA_RENDERER_GET_CLASS(renderer)->begin_render(DIA_RENDERER(renderer));
1868
1869 /* First run through without drawing to setup tables */
1870 for (i=0; i<data->layers->len; i++)
1871 {
1872 layer = (Layer *) g_ptr_array_index(data->layers, i);
1873 layer_render(layer, DIA_RENDERER(renderer), NULL, NULL, data, 0);
1874 renderer->depth++;
1875 }
1876
1877 write_header(data, renderer);
1878
1879 DIA_RENDERER_GET_CLASS(renderer)->end_render(DIA_RENDERER(renderer));
1880
1881 renderer->first_pass = FALSE;
1882
1883 DIA_RENDERER_GET_CLASS(renderer)->begin_render(DIA_RENDERER(renderer));
1884
1885 /* Now render */
1886
1887 for (i=0; i<data->layers->len; i++)
1888 {
1889 layer = (Layer *) g_ptr_array_index(data->layers, i);
1890 layer_render(layer, DIA_RENDERER(renderer), NULL, NULL, data, 0);
1891 renderer->depth++;
1892 }
1893
1894 DIA_RENDERER_GET_CLASS(renderer)->end_render(DIA_RENDERER(renderer));
1895
1896 /* Done */
1897
1898 write_trailer(data, renderer);
1899
1900 g_object_unref(renderer);
1901
1902 /* dont screw Dia's global state */
1903 setlocale(LC_NUMERIC, old_locale);
1904
1905 fclose(file);
1906 }
1907
1908 /* interface from filter.h */
1909
1910 static const gchar *extensions[] = { "vdx", NULL };
1911 DiaExportFilter vdx_export_filter = {
1912 N_("Visio XML format"),
1913 extensions,
1914 export_vdx
1915 };
1916
1917 #if 0
1918
1919 /* The following are not provided by vdx-export.c so we use the defaults.
1920 If they become necessary after testing, we can reinstate them */
1921
1922 /** Render a Dia line with arrows
1923 * @param self a renderer
1924 * @param start start of line
1925 * @param end end of line
1926 * @param line_width width of line
1927 * @param color line colour
1928 * @param start_arrow start arrow
1929 * @param end_arrow end arrow
1930 */
1931
1932 static void draw_line_with_arrows(DiaRenderer *self,
1933 Point *start, Point *end,
1934 real line_width,
1935 Color *color,
1936 Arrow *start_arrow,
1937 Arrow *end_arrow)
1938 {
1939 VDXRenderer *renderer = VDX_RENDERER(self);
1940 Point a, b;
1941 struct vdx_Shape Shape;
1942 struct vdx_XForm XForm;
1943 struct vdx_XForm1D XForm1D;
1944 struct vdx_Geom Geom;
1945 struct vdx_MoveTo MoveTo;
1946 struct vdx_LineTo LineTo;
1947 struct vdx_Line Line;
1948 char NameU[VDX_NAMEU_LEN];
1949
1950 /* Exactly as draw_line for now */
1951
1952 if (renderer->first_pass)
1953 {
1954 vdxCheckColor(renderer, color);
1955 return;
1956 }
1957
1958 g_debug("draw_line_with_arrows");
1959 memset(&Shape, 0, sizeof(Shape));
1960 Shape.type = vdx_types_Shape;
1961 Shape.ID = renderer->shapeid++;
1962 Shape.Type = "Shape";
1963 sprintf(NameU, "ArrowLine.%d", Shape.ID);
1964 Shape.NameU = NameU;
1965 Shape.LineStyle_exists = 1;
1966 Shape.FillStyle_exists = 1;
1967 Shape.TextStyle_exists = 1;
1968
1969 memset(&XForm, 0, sizeof(XForm));
1970 XForm.type = vdx_types_XForm;
1971 a = visio_point(*start);
1972 b = visio_point(*end);
1973 XForm.PinX = a.x;
1974 XForm.PinY = a.y;
1975 XForm.Width = fabs(b.x - a.x);
1976 XForm.Height = fabs(b.y - a.y);
1977 XForm.LocPinX = 0.0;
1978 XForm.LocPinY = 0.0;
1979 XForm.Angle = 0.0;
1980
1981 memset(&XForm1D, 0, sizeof(XForm1D));
1982 XForm1D.type = vdx_types_XForm1D;
1983 XForm1D.BeginX = a.x;
1984 XForm1D.BeginY = a.y;
1985 XForm1D.EndX = b.x;
1986 XForm1D.EndY = b.y;
1987
1988 memset(&Geom, 0, sizeof(Geom));
1989 Geom.NoFill = 1;
1990 Geom.type = vdx_types_Geom;
1991
1992 memset(&MoveTo, 0, sizeof(MoveTo));
1993 MoveTo.type = vdx_types_MoveTo;
1994 MoveTo.IX = 1;
1995 MoveTo.X = 0;
1996 MoveTo.Y = 0;
1997
1998 memset(&LineTo, 0, sizeof(LineTo));
1999 LineTo.type = vdx_types_LineTo;
2000 LineTo.IX = 2;
2001 LineTo.X = b.x-a.x;
2002 LineTo.Y = b.y-a.y;
2003
2004 create_Line(renderer, color, &Line, start_arrow, end_arrow);
2005
2006 Geom.children = g_slist_append(Geom.children, &MoveTo);
2007 Geom.children = g_slist_append(Geom.children, &LineTo);
2008
2009 Shape.children = g_slist_append(Shape.children, &XForm);
2010 Shape.children = g_slist_append(Shape.children, &XForm1D);
2011 Shape.children = g_slist_append(Shape.children, &Line);
2012 Shape.children = g_slist_append(Shape.children, &Geom);
2013
2014 vdx_write_object(renderer->file, renderer->xml_depth, &Shape);
2015
2016 g_slist_free(Geom.children);
2017 g_slist_free(Shape.children);
2018 }
2019
2020 /** Render a Dia polyline with arrows
2021 * @param self a renderer
2022 * @param points points on line
2023 * @param num_points number of points
2024 * @param line_width width of line
2025 * @param color line colour
2026 * @param start_arrow start arrow
2027 * @param end_arrow end arrow
2028 * @todo Not done yet
2029 */
2030
2031 static void draw_polyline_with_arrows(DiaRenderer *self,
2032 Point *points, int num_points,
2033 real line_width,
2034 Color *color,
2035 Arrow *start_arrow,
2036 Arrow *end_arrow)
2037 {
2038 VDXRenderer *renderer = VDX_RENDERER(self);
2039
2040 if (renderer->first_pass)
2041 {
2042 vdxCheckColor(renderer, color);
2043 return;
2044 }
2045 g_debug("draw_polyline_with_arrows (UNUSED)");
2046 }
2047
2048 /** Render a Dia arc with arrows
2049 * @param self a renderer
2050 * @param startpoint start of arc
2051 * @param endpoint end of arc
2052 * @param midpoint middle of arc
2053 * @param line_width line width
2054 * @param color line colour
2055 * @param start_arrow start arrow
2056 * @param end_arrow end arrow
2057 * @todo Not done yet - believe unused
2058 */
2059
2060 static void draw_arc_with_arrows(DiaRenderer *self,
2061 Point *startpoint,
2062 Point *endpoint,
2063 Point *midpoint,
2064 real line_width,
2065 Color *color,
2066 Arrow *start_arrow,
2067 Arrow *end_arrow)
2068 {
2069 VDXRenderer *renderer = VDX_RENDERER(self);
2070
2071 if (renderer->first_pass)
2072 {
2073 vdxCheckColor(renderer, color);
2074 return;
2075 }
2076 g_debug("draw_arc_with_arrows (TODO)");
2077 }
2078
2079 /** Render a Dia Bezier
2080 * @param self a renderer
2081 * @param points list of Bezier points
2082 * @param numpoints number of points
2083 * @param color line colour
2084 * @todo Not done yet - either convert to arcs or NURBS (Visio 2003)
2085 */
2086
2087 static void draw_bezier(DiaRenderer *self,
2088 BezPoint *points,
2089 int numpoints,
2090 Color *color)
2091 {
2092 VDXRenderer *renderer = VDX_RENDERER(self);
2093
2094 if (renderer->first_pass)
2095 {
2096 vdxCheckColor(renderer, color);
2097 return;
2098 }
2099 g_debug("draw_bezier (TODO)");
2100 }
2101
2102 /** Render a Dia Bezier with arrows
2103 * @param self a renderer
2104 * @param points list of Bezier points
2105 * @param numpoints number of points
2106 * @param line_width line width
2107 * @param color line colour
2108 * @param start_arrow start arrow
2109 * @param end_arrow end arrow
2110 * @todo Not done yet - either convert to arcs or NURBS (Visio 2003)
2111 */
2112
2113 static void draw_bezier_with_arrows(DiaRenderer *self,
2114 BezPoint *points,
2115 int numpoints,
2116 real line_width,
2117 Color *color,
2118 Arrow *start_arrow,
2119 Arrow *end_arrow)
2120 {
2121 VDXRenderer *renderer = VDX_RENDERER(self);
2122
2123 if (renderer->first_pass)
2124 {
2125 vdxCheckColor(renderer, color);
2126 return;
2127 }
2128 g_debug("draw_bezier_with_arrows (TODO)");
2129 }
2130
2131 /** Render a Dia filled Bezier
2132 * @param self a renderer
2133 * @param points list of Bezier points (last = first)
2134 * @param numpoints number of points
2135 * @param color line colour
2136 * @todo Not done yet - either convert to arcs or NURBS (Visio 2003)
2137 */
2138
2139 static void fill_bezier(DiaRenderer *self,
2140 BezPoint *points,
2141 int numpoints,
2142 Color *color)
2143 {
2144 VDXRenderer *renderer = VDX_RENDERER(self);
2145
2146 if (renderer->first_pass)
2147 {
2148 vdxCheckColor(renderer, color);
2149 return;
2150 }
2151
2152 g_debug("fill_bezier (TODO)");
2153 }
2154
2155 /** Render a Dia object
2156 * @param self a renderer
2157 * @param object an object
2158 * @note No work done here - perhaps should push/pop renderer state
2159 */
2160
2161 static void draw_object(DiaRenderer *self,
2162 DiaObject *object)
2163 {
2164 VDXRenderer *renderer = VDX_RENDERER(self);
2165
2166 g_debug("draw_object -> renderer");
2167 /* Get the object to draw itself */
2168 object->ops->draw(object, DIA_RENDERER(renderer));
2169 }
2170
2171
2172 #endif
2173