Use memset instead of bzero
[profile/ivi/libxkbcommon.git] / src / geom.c
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include "xkbgeom.h"
32 #include "xkbcommon/xkbcommon.h"
33 #include "XKBcommonint.h"
34
35 #ifndef MINSHORT
36 #define MINSHORT -32768
37 #endif
38 #ifndef MAXSHORT
39 #define MAXSHORT 32767
40 #endif
41
42 static void
43 _XkbCheckBounds(struct xkb_bounds * bounds, int x, int y)
44 {
45     if (x < bounds->x1)
46         bounds->x1 = x;
47     if (x > bounds->x2)
48         bounds->x2 = x;
49     if (y < bounds->y1)
50         bounds->y1 = y;
51     if (y > bounds->y2)
52         bounds->y2 = y;
53 }
54
55 Bool
56 XkbcComputeShapeBounds(struct xkb_shape * shape)
57 {
58     int o, p;
59     struct xkb_outline * outline;
60     struct xkb_point * pt;
61
62     if ((!shape) || (shape->num_outlines < 1))
63         return False;
64
65     shape->bounds.x1 = shape->bounds.y1 = MAXSHORT;
66     shape->bounds.x2 = shape->bounds.y2 = MINSHORT;
67
68     for (outline = shape->outlines, o = 0; o < shape->num_outlines;
69          o++, outline++)
70     {
71         for (pt = outline->points, p = 0; p < outline->num_points; p++, pt++)
72             _XkbCheckBounds(&shape->bounds, pt->x, pt->y);
73         if (outline->num_points < 2)
74             _XkbCheckBounds(&shape->bounds, 0, 0);
75     }
76     return True;
77 }
78
79 static Bool
80 XkbcComputeRowBounds(struct xkb_geometry * geom, struct xkb_section * section, struct xkb_row * row)
81 {
82     int k, pos;
83     struct xkb_key * key;
84     struct xkb_bounds *bounds, *sbounds;
85
86     if (!geom || !section || !row)
87         return False;
88
89     bounds = &row->bounds;
90     memset(bounds, 0, sizeof(struct xkb_bounds));
91
92     for (key = row->keys, pos = k = 0; k < row->num_keys; k++, key++) {
93         sbounds = &XkbKeyShape(geom, key)->bounds;
94         _XkbCheckBounds(bounds, pos, 0);
95
96         if (!row->vertical) {
97             if (key->gap != 0) {
98                 pos += key->gap;
99                 _XkbCheckBounds(bounds, pos, 0);
100             }
101             _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1);
102             _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2);
103             pos += sbounds->x2;
104         }
105         else {
106             if (key->gap != 0) {
107                 pos += key->gap;
108                 _XkbCheckBounds(bounds, 0, pos);
109             }
110             _XkbCheckBounds(bounds,pos + sbounds->x1, sbounds->y1);
111             _XkbCheckBounds(bounds,pos + sbounds->x2, sbounds->y2);
112             pos += sbounds->y2;
113         }
114     }
115
116     return True;
117 }
118
119 Bool
120 XkbcComputeSectionBounds(struct xkb_geometry * geom, struct xkb_section * section)
121 {
122     int i;
123     struct xkb_shape * shape;
124     struct xkb_row * row;
125     union xkb_doodad * doodad;
126     struct xkb_bounds * bounds, *rbounds = NULL;
127
128     if (!geom || !section)
129         return False;
130
131     bounds = &section->bounds;
132     memset(bounds, 0, sizeof(struct xkb_bounds));
133
134     for (i = 0, row = section->rows; i < section->num_rows; i++, row++) {
135         if (!XkbcComputeRowBounds(geom, section, row))
136             return False;
137         rbounds = &row->bounds;
138         _XkbCheckBounds(bounds, row->left + rbounds->x1,
139                         row->top + rbounds->y1);
140         _XkbCheckBounds(bounds, row->left + rbounds->x2,
141                         row->top + rbounds->y2);
142     }
143
144     for (i = 0, doodad = section->doodads; i < section->num_doodads;
145          i++, doodad++)
146     {
147         static struct xkb_bounds tbounds;
148
149         switch (doodad->any.type) {
150         case XkbOutlineDoodad:
151         case XkbSolidDoodad:
152             shape = XkbShapeDoodadShape(geom, &doodad->shape);
153             rbounds = &shape->bounds;
154             break;
155         case XkbTextDoodad:
156             tbounds.x1 = doodad->text.left;
157             tbounds.y1 = doodad->text.top;
158             tbounds.x2 = tbounds.x1 + doodad->text.width;
159             tbounds.y2 = tbounds.y1 + doodad->text.height;
160             rbounds = &tbounds;
161             break;
162         case XkbIndicatorDoodad:
163             shape = XkbIndicatorDoodadShape(geom, &doodad->indicator);
164             rbounds = &shape->bounds;
165             break;
166         case XkbLogoDoodad:
167             shape = XkbLogoDoodadShape(geom, &doodad->logo);
168             rbounds = &shape->bounds;
169             break;
170         default:
171             tbounds.x1 = tbounds.x2 = doodad->any.left;
172             tbounds.y1 = tbounds.y2 = doodad->any.top;
173             rbounds = &tbounds;
174             break;
175         }
176
177         _XkbCheckBounds(bounds, rbounds->x1, rbounds->y1);
178         _XkbCheckBounds(bounds, rbounds->x2, rbounds->y2);
179     }
180
181     return True;
182 }