Move include path from X11/extensions/ to xkbcommon/
[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 "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     pos = 0;
90     bounds = &row->bounds;
91     bzero(bounds, sizeof(struct xkb_bounds));
92
93     for (key = row->keys, pos = k = 0; k < row->num_keys; k++, key++) {
94         sbounds = &XkbKeyShape(geom, key)->bounds;
95         _XkbCheckBounds(bounds, pos, 0);
96
97         if (!row->vertical) {
98             if (key->gap != 0) {
99                 pos += key->gap;
100                 _XkbCheckBounds(bounds, pos, 0);
101             }
102             _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1);
103             _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2);
104             pos += sbounds->x2;
105         }
106         else {
107             if (key->gap != 0) {
108                 pos += key->gap;
109                 _XkbCheckBounds(bounds, 0, pos);
110             }
111             _XkbCheckBounds(bounds,pos + sbounds->x1, sbounds->y1);
112             _XkbCheckBounds(bounds,pos + sbounds->x2, sbounds->y2);
113             pos += sbounds->y2;
114         }
115     }
116
117     return True;
118 }
119
120 Bool
121 XkbcComputeSectionBounds(struct xkb_geometry * geom, struct xkb_section * section)
122 {
123     int i;
124     struct xkb_shape * shape;
125     struct xkb_row * row;
126     union xkb_doodad * doodad;
127     struct xkb_bounds * bounds, *rbounds = NULL;
128
129     if (!geom || !section)
130         return False;
131
132     bounds = &section->bounds;
133     bzero(bounds, sizeof(struct xkb_bounds));
134
135     for (i = 0, row = section->rows; i < section->num_rows; i++, row++) {
136         if (!XkbcComputeRowBounds(geom, section, row))
137             return False;
138         rbounds = &row->bounds;
139         _XkbCheckBounds(bounds, row->left + rbounds->x1,
140                         row->top + rbounds->y1);
141         _XkbCheckBounds(bounds, row->left + rbounds->x2,
142                         row->top + rbounds->y2);
143     }
144
145     for (i = 0, doodad = section->doodads; i < section->num_doodads;
146          i++, doodad++)
147     {
148         static struct xkb_bounds tbounds;
149
150         switch (doodad->any.type) {
151         case XkbOutlineDoodad:
152         case XkbSolidDoodad:
153             shape = XkbShapeDoodadShape(geom, &doodad->shape);
154             rbounds = &shape->bounds;
155             break;
156         case XkbTextDoodad:
157             tbounds.x1 = doodad->text.left;
158             tbounds.y1 = doodad->text.top;
159             tbounds.x2 = tbounds.x1 + doodad->text.width;
160             tbounds.y2 = tbounds.y1 + doodad->text.height;
161             rbounds = &tbounds;
162             break;
163         case XkbIndicatorDoodad:
164             shape = XkbIndicatorDoodadShape(geom, &doodad->indicator);
165             rbounds = &shape->bounds;
166             break;
167         case XkbLogoDoodad:
168             shape = XkbLogoDoodadShape(geom, &doodad->logo);
169             rbounds = &shape->bounds;
170             break;
171         default:
172             tbounds.x1 = tbounds.x2 = doodad->any.left;
173             tbounds.y1 = tbounds.y2 = doodad->any.top;
174             break;
175         }
176
177         _XkbCheckBounds(bounds, rbounds->x1, rbounds->y1);
178         _XkbCheckBounds(bounds, rbounds->x2, rbounds->y2);
179     }
180
181     return True;
182 }