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