1 /* output-svg.h - output in SVG format
2 
3    Copyright (C) 1999, 2000, 2001 Bernhard Herzog
4 
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public License
7    as published by the Free Software Foundation; either version 2.1 of
8    the License, or (at your option) any later version.
9 
10    This library is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18    USA. */
19 
20 #include "spline.h"
21 #include "output-svg.h"
22 
23 
24 
25 static void
outSplineList(FILE * const fileP,spline_list_type const splineList,unsigned int const height)26 outSplineList(FILE *           const fileP,
27               spline_list_type const splineList,
28               unsigned int     const height) {
29 
30     unsigned splineSeq;
31 
32     for (splineSeq = 0;
33          splineSeq < SPLINE_LIST_LENGTH(splineList);
34          ++splineSeq) {
35 
36         spline_type const spline = SPLINE_LIST_ELT(splineList, splineSeq);
37 
38         if (SPLINE_DEGREE(spline) == LINEARTYPE) {
39             fprintf(fileP, "L%g %g",
40                     END_POINT(spline).x, height - END_POINT(spline).y);
41         } else
42             fprintf(fileP, "C%g %g %g %g %g %g",
43                     CONTROL1(spline).x, height  - CONTROL1(spline).y,
44                     CONTROL2(spline).x, height  - CONTROL2(spline).y,
45                     END_POINT(spline).x, height - END_POINT(spline).y);
46     }
47 }
48 
49 
50 
51 static void
out_splines(FILE * const fileP,spline_list_array_type const shape,unsigned int const height)52 out_splines(FILE *                 const fileP,
53             spline_list_array_type const shape,
54             unsigned int           const height) {
55 
56     unsigned listSeq;
57     pixel lastColor;
58 
59     PPM_ASSIGN(lastColor, 0, 0, 0);
60 
61     for (listSeq = 0;
62          listSeq < SPLINE_LIST_ARRAY_LENGTH(shape);
63          ++listSeq) {
64 
65         spline_list_type const splineList =
66             SPLINE_LIST_ARRAY_ELT(shape, listSeq);
67         spline_type const first = SPLINE_LIST_ELT(splineList, 0);
68 
69         if (listSeq == 0 || !PPM_EQUAL(splineList.color, lastColor)) {
70             if (listSeq > 0) {
71                 /* Close previous <path> element */
72                 if (!(shape.centerline || splineList.open))
73                     fputs("z", fileP);
74                 fputs("\"/>\n", fileP);
75             }
76             /* Open new <path> element */
77             fprintf(fileP, "<path style=\"%s:#%02x%02x%02x; %s:none;\" d=\"",
78                     (shape.centerline || splineList.open) ? "stroke" : "fill",
79                     PPM_GETR(splineList.color),
80                     PPM_GETG(splineList.color),
81                     PPM_GETB(splineList.color),
82                     (shape.centerline || splineList.open) ? "fill" : "stroke");
83         }
84         fprintf(fileP, "M%g %g",
85                 START_POINT(first).x, height - START_POINT(first).y);
86 
87         outSplineList(fileP, splineList, height);
88 
89         lastColor = splineList.color;
90     }
91 
92     if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) {
93         spline_list_type const lastSplineList =
94             SPLINE_LIST_ARRAY_ELT(shape, SPLINE_LIST_ARRAY_LENGTH(shape)-1);
95 
96         if (!(shape.centerline || lastSplineList.open))
97             fputs("z", fileP);
98 
99         /* Close last <path> element */
100         fputs("\"/>\n", fileP);
101     }
102 }
103 
104 
105 
106 int
output_svg_writer(FILE * const fileP,const char * const name,int const llx,int const lly,int const urx,int const ury,at_output_opts_type * const opts,at_spline_list_array_type const shape,at_msg_func msg_func,void * const msg_data)107 output_svg_writer(FILE *                    const fileP,
108                   const char *              const name,
109                   int                       const llx,
110                   int                       const lly,
111                   int                       const urx,
112                   int                       const ury,
113                   at_output_opts_type *     const opts,
114                   at_spline_list_array_type const shape,
115                   at_msg_func                     msg_func,
116                   void *                    const msg_data) {
117 
118     int const width  = urx - llx;
119     int const height = ury - lly;
120 
121     fputs("<?xml version=\"1.0\" standalone=\"yes\"?>\n", fileP);
122 
123     fprintf(fileP, "<svg width=\"%d\" height=\"%d\">\n", width, height);
124 
125     out_splines(fileP, shape, height);
126 
127     fputs("</svg>\n", fileP);
128 
129     return 0;
130 }
131