Pull in enough structs and defines from XKBstr.h to only need XKB.h
[platform/upstream/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 "X11/extensions/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 Bool
80 XkbcComputeShapeTop(struct xkb_shape * shape, struct xkb_bounds * bounds)
81 {
82     int p;
83     struct xkb_outline * outline;
84     struct xkb_point * pt;
85
86     if ((!shape) || (shape->num_outlines < 1))
87         return False;
88
89     if (shape->approx)
90         outline = shape->approx;
91     else
92         outline = &shape->outlines[shape->num_outlines - 1];
93
94     if (outline->num_points < 2) {
95          bounds->x1 = bounds->y1 = 0;
96          bounds->x2 = bounds->y2 = 0;
97     }
98     else {
99         bounds->x1 = bounds->y1 = MAXSHORT;
100         bounds->x2 = bounds->y2 = MINSHORT;
101     }
102
103     for (pt = outline->points, p = 0; p < outline->num_points; p++, pt++)
104         _XkbCheckBounds(bounds, pt->x, pt->y);
105
106     return True;
107 }
108
109 Bool
110 XkbcComputeRowBounds(struct xkb_geometry * geom, struct xkb_section * section, struct xkb_row * row)
111 {
112     int k, pos;
113     struct xkb_key * key;
114     struct xkb_bounds *bounds, *sbounds;
115
116     if (!geom || !section || !row)
117         return False;
118
119     pos = 0;
120     bounds = &row->bounds;
121     bzero(bounds, sizeof(struct xkb_bounds));
122
123     for (key = row->keys, pos = k = 0; k < row->num_keys; k++, key++) {
124         sbounds = &XkbKeyShape(geom, key)->bounds;
125         _XkbCheckBounds(bounds, pos, 0);
126
127         if (!row->vertical) {
128             if (key->gap != 0) {
129                 pos += key->gap;
130                 _XkbCheckBounds(bounds, pos, 0);
131             }
132             _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1);
133             _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2);
134             pos += sbounds->x2;
135         }
136         else {
137             if (key->gap != 0) {
138                 pos += key->gap;
139                 _XkbCheckBounds(bounds, 0, pos);
140             }
141             _XkbCheckBounds(bounds,pos + sbounds->x1, sbounds->y1);
142             _XkbCheckBounds(bounds,pos + sbounds->x2, sbounds->y2);
143             pos += sbounds->y2;
144         }
145     }
146
147     return True;
148 }
149
150 Bool
151 XkbcComputeSectionBounds(struct xkb_geometry * geom, struct xkb_section * section)
152 {
153     int i;
154     struct xkb_shape * shape;
155     struct xkb_row * row;
156     union xkb_doodad * doodad;
157     struct xkb_bounds * bounds, *rbounds = NULL;
158
159     if (!geom || !section)
160         return False;
161
162     bounds = &section->bounds;
163     bzero(bounds, sizeof(struct xkb_bounds));
164
165     for (i = 0, row = section->rows; i < section->num_rows; i++, row++) {
166         if (!XkbcComputeRowBounds(geom, section, row))
167             return False;
168         rbounds = &row->bounds;
169         _XkbCheckBounds(bounds, row->left + rbounds->x1,
170                         row->top + rbounds->y1);
171         _XkbCheckBounds(bounds, row->left + rbounds->x2,
172                         row->top + rbounds->y2);
173     }
174
175     for (i = 0, doodad = section->doodads; i < section->num_doodads;
176          i++, doodad++)
177     {
178         static struct xkb_bounds tbounds;
179
180         switch (doodad->any.type) {
181         case XkbOutlineDoodad:
182         case XkbSolidDoodad:
183             shape = XkbShapeDoodadShape(geom, &doodad->shape);
184             rbounds = &shape->bounds;
185             break;
186         case XkbTextDoodad:
187             tbounds.x1 = doodad->text.left;
188             tbounds.y1 = doodad->text.top;
189             tbounds.x2 = tbounds.x1 + doodad->text.width;
190             tbounds.y2 = tbounds.y1 + doodad->text.height;
191             rbounds = &tbounds;
192             break;
193         case XkbIndicatorDoodad:
194             shape = XkbIndicatorDoodadShape(geom, &doodad->indicator);
195             rbounds = &shape->bounds;
196             break;
197         case XkbLogoDoodad:
198             shape = XkbLogoDoodadShape(geom, &doodad->logo);
199             rbounds = &shape->bounds;
200             break;
201         default:
202             tbounds.x1 = tbounds.x2 = doodad->any.left;
203             tbounds.y1 = tbounds.y2 = doodad->any.top;
204             break;
205         }
206
207         _XkbCheckBounds(bounds, rbounds->x1, rbounds->y1);
208         _XkbCheckBounds(bounds, rbounds->x2, rbounds->y2);
209     }
210
211     return True;
212 }