source: trunk/third/gtkhtml3/src/htmlshape.c @ 21116

Revision 21116, 4.9 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21115, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/* This file is part of the GtkHTML library.
3   
4   Copyright (C) 2001, Ximian, Inc.
5
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.
10
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.
15
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., 59 Temple Place - Suite 330,
19   Boston, MA 02111-1307, USA.
20*/
21
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"
29
30struct _HTMLShape {
31        HTMLShapeType type;
32        gchar *url;
33        gchar *target;
34        GPtrArray *coords;
35};
36
37static HTMLLength *
38parse_length (char **str) {
39        char *cur = *str;
40        HTMLLength *len = g_new0 (HTMLLength, 1);
41       
42        /* g_warning ("begin \"%s\"", *str); */
43
44        while (isspace (*cur)) cur++;
45
46        len->val = atoi (cur);
47        len->type = HTML_LENGTH_TYPE_PIXELS;
48
49        while (isdigit (*cur) || *cur == '-') cur++;
50
51        switch (*cur) {
52        case '*':
53                if (len->val == 0)
54                        len->val = 1;
55                len->type = HTML_LENGTH_TYPE_FRACTION;
56                cur++;
57                break;
58        case '%':
59                len->type = HTML_LENGTH_TYPE_PERCENT;
60                cur++;
61                break;
62        }
63       
64        if (cur <= *str) {
65                g_free (len);
66                return NULL;
67        }
68
69        /* g_warning ("length len->val=%d, len->type=%d", len->val, len->type); */
70        *str = cur;
71        cur = strstr (cur, ",");       
72        if (cur) {
73                cur++;
74                *str = cur;
75        }
76
77        return len;
78}
79
80void
81html_length_array_parse (GPtrArray *array, char *str)
82{
83        HTMLLength *length;
84
85        if (str == NULL)
86                return;
87
88        while ((length = parse_length (&str)))
89               g_ptr_array_add (array, length);
90
91}
92
93void
94html_length_array_destroy (GPtrArray *array)
95{
96        int i;
97       
98        for (i = 0; i < array->len; i++)
99                g_free (g_ptr_array_index (array, i));
100}
101
102#define HTML_DIST(x,y) (gint)sqrt((x)*(x) + (y)*(y))
103
104gboolean
105html_shape_point (HTMLShape *shape, gint x, gint y)
106{
107        int i;
108        int j = 0;
109        int odd = 0;
110
111        HTMLLength **poly = (HTMLLength **)shape->coords->pdata;
112
113        /*
114         * TODO: Add support for percentage lengths, The information is stored
115         * so it is simply a matter of modifying the point routine to know the
116         * the overall size, then scaling the values.
117         */
118
119        switch (shape->type) {
120        case HTML_SHAPE_RECT:
121                if ((x >= poly[0]->val)
122                    && (x <= poly[2]->val)
123                    && (y >= poly[1]->val)
124                    && (y <= poly[3]->val))
125                        return TRUE;
126                break;
127        case HTML_SHAPE_CIRCLE:
128                if (HTML_DIST (x - poly[0]->val, y - poly[1]->val) <= poly[2]->val)
129                        return TRUE;
130               
131                break;
132        case HTML_SHAPE_POLY:
133                for (i=0; i < shape->coords->len; i+=2) {
134                        j+=2;
135                        if (j == shape->coords->len)
136                                j=0;
137                       
138                        if ((poly[i+1]->val < y && poly[j+1]->val >= y)
139                            || (poly[j+1]->val < y && poly[i+1]->val >= y)) {
140                               
141                                if (poly[i]->val + (y - poly[i+1]->val)
142                                    / (poly[j+1]->val - poly[i+1]->val)
143                                    * (poly[j]->val - poly[i]->val) < x) {
144                                        odd = !odd;
145                                }
146                        }
147                }
148                return odd;
149                break;
150        case HTML_SHAPE_DEFAULT:
151                return TRUE;
152                break;
153        }
154        return FALSE;
155}
156
157static HTMLShapeType
158parse_shape_type (char *token) {
159        HTMLShapeType type = HTML_SHAPE_RECT;
160
161        if (!token || strncasecmp (token, "rect", 4) == 0)
162                type = HTML_SHAPE_RECT;
163        else if (strncasecmp (token, "poly", 4) == 0)
164                type = HTML_SHAPE_POLY;
165        else if (strncasecmp (token, "circle", 6) == 0)
166                type = HTML_SHAPE_CIRCLE;
167        else if (strncasecmp (token, "default", 7) == 0)
168                type = HTML_SHAPE_DEFAULT;
169
170        return type;
171}
172
173char *
174html_shape_get_url (HTMLShape *shape)
175{
176        return shape->url;
177}
178
179HTMLShape *
180html_shape_new (char *type_str, char *coords, char *url, char *target)
181{
182        HTMLShape *shape;
183        HTMLShapeType type = parse_shape_type (type_str);
184
185        if (coords == NULL && type != HTML_SHAPE_DEFAULT)
186                return NULL;
187
188        shape = g_new (HTMLShape, 1);
189
190        shape->type = type;
191        shape->url = g_strdup (url);
192        shape->target = g_strdup (target);
193        shape->coords = g_ptr_array_new ();
194
195        html_length_array_parse (shape->coords, coords);
196       
197        switch (shape->type) {
198        case HTML_SHAPE_RECT:
199                while (shape->coords->len < 4)
200                        g_ptr_array_add (shape->coords,
201                                         g_new0 (HTMLLength, 1));
202        case HTML_SHAPE_CIRCLE:
203                while (shape->coords->len < 3)
204                        g_ptr_array_add (shape->coords,
205                                         g_new0 (HTMLLength, 1));
206        case HTML_SHAPE_POLY:
207                if (shape->coords->len % 2)
208                        g_ptr_array_add (shape->coords,
209                                         g_new0 (HTMLLength, 1));
210
211                break;
212        default:
213                break;
214        }
215        return shape;
216}
217
218void
219html_shape_destroy (HTMLShape *shape)
220{
221        g_free (shape->url);
222        g_free (shape->target);
223        html_length_array_destroy (shape->coords);
224       
225        g_free (shape);
226}
227               
228
229
Note: See TracBrowser for help on using the repository browser.