]> www.fi.muni.cz Git - evince.git/blob - backend/impress/r_geometry.c
6662de6815e45327b9bf500631b779e04c7ba5f3
[evince.git] / backend / impress / r_geometry.c
1 /* imposter (OO.org Impress viewer)
2 ** Copyright (C) 2003-2005 Gurer Ozen
3 ** This code is free software; you can redistribute it and/or
4 ** modify it under the terms of GNU General Public License.
5 */
6
7 #include "common.h"
8 #include "internal.h"
9 #include <math.h>
10
11 void
12 r_parse_color(const char *color, ImpColor *ic)
13 {
14         unsigned int cval;
15
16         if (1 != sscanf(color, "#%X", &cval)) return;
17
18         ic->red = (cval & 0xFF0000) >> 8;
19         ic->green = cval & 0x00FF00;
20         ic->blue = (cval & 0xFF) << 8;
21 }
22
23 int
24 r_get_color(ImpRenderCtx *ctx, iks *node, char *name, ImpColor *ic)
25 {
26         char *color;
27
28         color = r_get_style(ctx, node, name);
29         if (!color) return 0;
30         r_parse_color(color, ic);
31
32         return 1;
33 }
34
35 static void
36 fg_color(ImpRenderCtx *ctx, void *drw_data, iks *node, char *name)
37 {
38         ImpColor ic;
39
40         if (r_get_color(ctx, node, name, &ic)) {
41                 ctx->drw->set_fg_color(drw_data, &ic);
42         }
43 }
44
45 int
46 r_get_x (ImpRenderCtx *ctx, iks *node, char *name)
47 {
48         char *val;
49
50         val = iks_find_attrib (node, name);
51         if (!val) return 0;
52         return atof (val) * ctx->fact_x;
53 }
54
55 int
56 r_get_y (ImpRenderCtx *ctx, iks *node, char *name)
57 {
58         char *val;
59
60         val = iks_find_attrib (node, name);
61         if (!val) return 0;
62         return atof (val) * ctx->fact_y;
63 }
64
65 int
66 r_get_angle (iks *node, char *name, int def)
67 {
68         char *tmp;
69
70         tmp = iks_find_attrib (node, name);
71         if (!tmp) return def;
72         return atof (tmp);
73 }
74
75 static int x, y, w, h;
76 static int px, py, pw, ph;
77
78 static void
79 r_get_viewbox (iks *node)
80 {
81         char *tmp;
82
83         tmp = iks_find_attrib (node, "svg:viewBox");
84         if (!tmp) return;
85         sscanf (tmp, "%d %d %d %d", &px, &py, &pw, &ph);
86 }
87
88 void
89 r_polygon(ImpRenderCtx *ctx, void *drw_data, iks *node)
90 {
91         char *data;
92         ImpPoint *points;
93         int i, cnt, j;
94         int num;
95         int fill = 1;
96
97         data = r_get_style (ctx, node, "draw:fill");
98         if (!data || strcmp (data, "solid") != 0) fill = 0;
99
100         x = r_get_x (ctx, node, "svg:x");
101         y = r_get_y (ctx, node, "svg:y");
102         w = r_get_x (ctx, node, "svg:width");
103         h = r_get_y (ctx, node, "svg:height");
104         r_get_viewbox (node);
105
106         data = iks_find_attrib (node, "draw:points");
107         points = malloc (sizeof (ImpPoint) * strlen (data) / 4);
108
109         cnt = 0;
110         j = 0;
111         num = -1;
112         for (i = 0; data[i]; i++) {
113                 if (data[i] >= '0' && data[i] <= '9') {
114                         if (num == -1) num = i;
115                 } else {
116                         if (num != -1) {
117                                 if (j == 0) {
118                                         points[cnt].x = atoi (data + num);
119                                         j = 1;
120                                 } else {
121                                         points[cnt++].y = atoi (data + num);
122                                         j = 0;
123                                 }
124                                 num = -1;
125                         }
126                 }
127         }
128         if (num != -1) {
129                 if (j == 0) {
130                         points[cnt].x = atoi (data + num);
131                 } else {
132                         points[cnt++].y = atoi (data + num);
133                 }
134         }
135         for (i = 0; i < cnt; i++) {
136                 points[i].x = x + points[i].x * w / pw;
137                 points[i].y = y + points[i].y * h / ph;
138         }
139
140         if (fill) {
141                 fg_color(ctx, drw_data, node, "draw:fill-color");
142                 ctx->drw->draw_polygon(drw_data, 1, points, cnt);
143         }
144         fg_color(ctx, drw_data, node, "svg:stroke-color");
145         ctx->drw->draw_polygon(drw_data, 0, points, cnt);
146
147         free (points);
148 }
149
150 void
151 r_polyline(ImpRenderCtx *ctx, void *drw_data, iks *node)
152 {
153         char *data;
154         ImpPoint *points;
155         int i, cnt, j;
156         int num;
157         int pen_x, pen_y;
158
159         x = r_get_x (ctx, node, "svg:x");
160         y = r_get_y (ctx, node, "svg:y");
161         w = r_get_x (ctx, node, "svg:width");
162         h = r_get_y (ctx, node, "svg:height");
163         r_get_viewbox (node);
164
165         data = iks_find_attrib (node, "draw:points");
166         points = malloc (sizeof (ImpPoint) * strlen (data) / 4);
167
168         cnt = 0;
169         j = 0;
170         num = -1;
171         for (i = 0; data[i]; i++) {
172                 if (data[i] >= '0' && data[i] <= '9') {
173                         if (num == -1) num = i;
174                 } else {
175                         if (num != -1) {
176                                 if (j == 0) {
177                                         points[cnt].x = atoi (data + num);
178                                         j = 1;
179                                 } else {
180                                         points[cnt++].y = atoi (data + num);
181                                         j = 0;
182                                 }
183                                 num = -1;
184                         }
185                 }
186         }
187         if (num != -1) {
188                 if (j == 0) {
189                         points[cnt].x = atoi (data + num);
190                 } else {
191                         points[cnt++].y = atoi (data + num);
192                 }
193         }
194
195         pen_x = x + points[0].x * w /pw;
196         pen_y = y + points[0].y * h / ph;
197         fg_color(ctx, drw_data, node, "svg:stroke-color");
198         for (i = 1; i < cnt; i++) {
199                 int tx, ty;
200                 tx = x + points[i].x * w / pw;
201                 ty = y + points[i].y * h / ph;
202                 ctx->drw->draw_line(drw_data, pen_x, pen_y, tx, ty);
203                 pen_x = tx;
204                 pen_y = ty;
205         }
206         free (points);
207 }