Updated Esperanto translation
[gtkhtml.git] / gtkhtml / htmlshape.c
blob02ef740496e1c1eaa179b517e09eef549dbaefb9
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* This file is part of the GtkHTML library.
4 * Copyright (C) 2001, Ximian, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include <glib.h>
23 #include <string.h>
24 #include <math.h>
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include "htmlstyle.h"
28 #include "htmlshape.h"
30 struct _HTMLShape {
31 HTMLShapeType type;
32 gchar *url;
33 gchar *target;
34 GPtrArray *coords;
37 static HTMLLength *
38 parse_length (const gchar **str)
40 const gchar *cur = *str;
41 HTMLLength *len = g_new0 (HTMLLength, 1);
43 /* g_warning ("begin \"%s\"", *str); */
45 while (isspace (*cur)) cur++;
47 len->val = atoi (cur);
48 len->type = HTML_LENGTH_TYPE_PIXELS;
50 while (isdigit (*cur) || *cur == '-') cur++;
52 switch (*cur) {
53 case '*':
54 if (len->val == 0)
55 len->val = 1;
56 len->type = HTML_LENGTH_TYPE_FRACTION;
57 cur++;
58 break;
59 case '%':
60 len->type = HTML_LENGTH_TYPE_PERCENT;
61 cur++;
62 break;
65 if (cur <= *str) {
66 g_free (len);
67 return NULL;
70 /* g_warning ("length len->val=%d, len->type=%d", len->val, len->type); */
71 *str = cur;
72 cur = strstr (cur, ",");
73 if (cur) {
74 cur++;
75 *str = cur;
78 return len;
81 void
82 html_length_array_parse (GPtrArray *array,
83 const gchar *str)
85 HTMLLength *length;
87 if (str == NULL)
88 return;
90 while ((length = parse_length (&str)))
91 g_ptr_array_add (array, length);
94 void
95 html_length_array_destroy (GPtrArray *array)
97 gint i;
99 for (i = 0; i < array->len; i++)
100 g_free (g_ptr_array_index (array, i));
103 #define HTML_DIST(x,y) (gint)sqrt((x)*(x) + (y)*(y))
105 gboolean
106 html_shape_point (HTMLShape *shape,
107 gint x,
108 gint y)
110 gint i;
111 gint j = 0;
112 gint odd = 0;
114 HTMLLength **poly = (HTMLLength **) shape->coords->pdata;
117 * TODO: Add support for percentage lengths, The information is stored
118 * so it is simply a matter of modifying the point routine to know the
119 * the overall size, then scaling the values.
122 switch (shape->type) {
123 case HTML_SHAPE_RECT:
124 if ((x >= poly[0]->val)
125 && (x <= poly[2]->val)
126 && (y >= poly[1]->val)
127 && (y <= poly[3]->val))
128 return TRUE;
129 break;
130 case HTML_SHAPE_CIRCLE:
131 if (HTML_DIST (x - poly[0]->val, y - poly[1]->val) <= poly[2]->val)
132 return TRUE;
134 break;
135 case HTML_SHAPE_POLY:
136 for (i = 0; i < shape->coords->len; i+=2) {
137 j+=2;
138 if (j == shape->coords->len)
139 j = 0;
141 if ((poly[i + 1]->val < y && poly[j + 1]->val >= y)
142 || (poly[j + 1]->val < y && poly[i + 1]->val >= y)) {
144 if (poly[i]->val + (y - poly[i + 1]->val)
145 / (poly[j + 1]->val - poly[i + 1]->val)
146 * (poly[j]->val - poly[i]->val) < x) {
147 odd = !odd;
151 return odd;
152 break;
153 case HTML_SHAPE_DEFAULT:
154 return TRUE;
155 break;
157 return FALSE;
160 static HTMLShapeType
161 parse_shape_type (gchar *token)
163 HTMLShapeType type = HTML_SHAPE_RECT;
165 if (!token || g_ascii_strncasecmp (token, "rect", 4) == 0)
166 type = HTML_SHAPE_RECT;
167 else if (g_ascii_strncasecmp (token, "poly", 4) == 0)
168 type = HTML_SHAPE_POLY;
169 else if (g_ascii_strncasecmp (token, "circle", 6) == 0)
170 type = HTML_SHAPE_CIRCLE;
171 else if (g_ascii_strncasecmp (token, "default", 7) == 0)
172 type = HTML_SHAPE_DEFAULT;
174 return type;
177 gchar *
178 html_shape_get_url (HTMLShape *shape)
180 return shape->url;
183 HTMLShape *
184 html_shape_new (gchar *type_str,
185 gchar *coords,
186 gchar *url,
187 gchar *target)
189 HTMLShape *shape;
190 HTMLShapeType type = parse_shape_type (type_str);
192 if (coords == NULL && type != HTML_SHAPE_DEFAULT)
193 return NULL;
195 shape = g_new (HTMLShape, 1);
197 shape->type = type;
198 shape->url = g_strdup (url);
199 shape->target = g_strdup (target);
200 shape->coords = g_ptr_array_new ();
202 html_length_array_parse (shape->coords, coords);
204 switch (shape->type) {
205 case HTML_SHAPE_RECT:
206 while (shape->coords->len < 4)
207 g_ptr_array_add (shape->coords,
208 g_new0 (HTMLLength, 1));
209 case HTML_SHAPE_CIRCLE:
210 while (shape->coords->len < 3)
211 g_ptr_array_add (shape->coords,
212 g_new0 (HTMLLength, 1));
213 case HTML_SHAPE_POLY:
214 if (shape->coords->len % 2)
215 g_ptr_array_add (shape->coords,
216 g_new0 (HTMLLength, 1));
218 break;
219 default:
220 break;
222 return shape;
225 void
226 html_shape_destroy (HTMLShape *shape)
228 g_free (shape->url);
229 g_free (shape->target);
230 html_length_array_destroy (shape->coords);
232 g_free (shape);