about summary refs log tree commit diff
path: root/converter/other/pamtosvg/output-svg.c
blob: 53a8d4fdee639a92c7db07775928a1be0fa31dfa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* output-svg.h - output in SVG format

   Copyright (C) 1999, 2000, 2001 Bernhard Herzog

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation; either version 2.1 of
   the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA. */

#include "spline.h"
#include "output-svg.h"



static void
outSplineList(FILE *           const fileP,
              spline_list_type const splineList,
              unsigned int     const height) {
              
    unsigned splineSeq;
        
    for (splineSeq = 0;
         splineSeq < SPLINE_LIST_LENGTH(splineList);
         ++splineSeq) {
        
        spline_type const spline = SPLINE_LIST_ELT(splineList, splineSeq);
        
        if (SPLINE_DEGREE(spline) == LINEARTYPE) {
            fprintf(fileP, "L%g %g",
                    END_POINT(spline).x, height - END_POINT(spline).y);
        } else
            fprintf(fileP, "C%g %g %g %g %g %g",
                    CONTROL1(spline).x, height  - CONTROL1(spline).y,
                    CONTROL2(spline).x, height  - CONTROL2(spline).y,
                    END_POINT(spline).x, height - END_POINT(spline).y);
    }
}



static void
out_splines(FILE *                 const fileP,
            spline_list_array_type const shape,
            unsigned int           const height) {

    unsigned listSeq;
    pixel lastColor;
    
    PPM_ASSIGN(lastColor, 0, 0, 0);
    
    for (listSeq = 0;
         listSeq < SPLINE_LIST_ARRAY_LENGTH(shape);
         ++listSeq) {
        
        spline_list_type const splineList =
            SPLINE_LIST_ARRAY_ELT(shape, listSeq);
        spline_type const first = SPLINE_LIST_ELT(splineList, 0);

        if (listSeq == 0 || !PPM_EQUAL(splineList.color, lastColor)) {
            if (listSeq > 0) {
                /* Close previous <path> element */
                if (!(shape.centerline || splineList.open))
                    fputs("z", fileP);
                fputs("\"/>\n", fileP);
            }
            /* Open new <path> element */
            fprintf(fileP, "<path style=\"%s:#%02x%02x%02x; %s:none;\" d=\"",
                    (shape.centerline || splineList.open) ? "stroke" : "fill",
                    PPM_GETR(splineList.color),
                    PPM_GETG(splineList.color),
                    PPM_GETB(splineList.color),
                    (shape.centerline || splineList.open) ? "fill" : "stroke");
        }
        fprintf(fileP, "M%g %g",
                START_POINT(first).x, height - START_POINT(first).y);

        outSplineList(fileP, splineList, height);

        lastColor = splineList.color;
    }

    if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) {
        spline_list_type const lastSplineList =
            SPLINE_LIST_ARRAY_ELT(shape, SPLINE_LIST_ARRAY_LENGTH(shape)-1);

        if (!(shape.centerline || lastSplineList.open))
            fputs("z", fileP);

        /* Close last <path> element */
        fputs("\"/>\n", fileP);
    }
}



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) {

    int const width  = urx - llx;
    int const height = ury - lly;

    fputs("<?xml version=\"1.0\" standalone=\"yes\"?>\n", fileP);

    fprintf(fileP, "<svg width=\"%d\" height=\"%d\">\n", width, height);

    out_splines(fileP, shape, height);

    fputs("</svg>\n", fileP);
    
    return 0;
}