From 62482b9614112e1477264dc1d209ff3fb7ddd3fc Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Sat, 28 Mar 2009 16:08:46 -0700 Subject: [PATCH] Add geometry Compute API from XKBlib A small needed subset from libX11/src/xkb/XKBGeom.c. --- include/X11/extensions/XKBcommon.h | 12 ++ src/Makefile.am | 3 +- src/geom.c | 187 +++++++++++++++++++++++++++++ src/xkbcomp/geometry.c | 4 +- 4 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 src/geom.c diff --git a/include/X11/extensions/XKBcommon.h b/include/X11/extensions/XKBcommon.h index 3e6852a..ee35e1c 100644 --- a/include/X11/extensions/XKBcommon.h +++ b/include/X11/extensions/XKBcommon.h @@ -276,6 +276,18 @@ XkbcKeyNameText(char *name); extern char * XkbcSIMatchText(unsigned type); +extern Bool +XkbcComputeShapeBounds(XkbShapePtr shape); + +extern Bool +XkbcComputeShapeTop(XkbShapePtr shape, XkbBoundsPtr bounds); + +extern Bool +XkbcComputeRowBounds(XkbGeometryPtr geom, XkbSectionPtr section, XkbRowPtr row); + +extern Bool +XkbcComputeSectionBounds(XkbGeometryPtr geom, XkbSectionPtr section); + _XFUNCPROTOEND #endif /* _XKBCOMMON_H_ */ diff --git a/src/Makefile.am b/src/Makefile.am index 3fcf6bb..b495a53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,8 @@ libxkbcommon_la_LIBADD = xkbcomp/libxkbcomp.la libxkbcommon_la_SOURCES = \ XKBcommonint.h \ alloc.c \ - galloc.c \ atom.c \ + galloc.c \ + geom.c \ keysym.c \ text.c diff --git a/src/geom.c b/src/geom.c new file mode 100644 index 0000000..9a40c14 --- /dev/null +++ b/src/geom.c @@ -0,0 +1,187 @@ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "X11/extensions/XKBcommon.h" +#include "XKBcommonint.h" + +#ifndef MINSHORT +#define MINSHORT -32768 +#endif +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif + +static void +_XkbCheckBounds(XkbBoundsPtr bounds,int x,int y) +{ + if (xx1) bounds->x1= x; + if (x>bounds->x2) bounds->x2= x; + if (yy1) bounds->y1= y; + if (y>bounds->y2) bounds->y2= y; + return; +} + +Bool +XkbcComputeShapeBounds(XkbShapePtr shape) +{ +register int o,p; +XkbOutlinePtr outline; +XkbPointPtr pt; + + if ((!shape)||(shape->num_outlines<1)) + return False; + shape->bounds.x1= shape->bounds.y1= MAXSHORT; + shape->bounds.x2= shape->bounds.y2= MINSHORT; + for (outline=shape->outlines,o=0;onum_outlines;o++,outline++) { + for (pt=outline->points,p=0;pnum_points;p++,pt++) { + _XkbCheckBounds(&shape->bounds,pt->x,pt->y); + } + if (outline->num_points<2) { + _XkbCheckBounds(&shape->bounds,0,0); + } + } + return True; +} + +Bool +XkbcComputeShapeTop(XkbShapePtr shape,XkbBoundsPtr bounds) +{ +register int p; +XkbOutlinePtr outline; +XkbPointPtr pt; + + if ((!shape)||(shape->num_outlines<1)) + return False; + if (shape->approx) outline= shape->approx; + else outline= &shape->outlines[shape->num_outlines-1]; + if (outline->num_points<2) { + bounds->x1= bounds->y1= 0; + bounds->x2= bounds->y2= 0; + } + else { + bounds->x1= bounds->y1= MAXSHORT; + bounds->x2= bounds->y2= MINSHORT; + } + for (pt=outline->points,p=0;pnum_points;p++,pt++) { + _XkbCheckBounds(bounds,pt->x,pt->y); + } + return True; +} + +Bool +XkbcComputeRowBounds(XkbGeometryPtr geom,XkbSectionPtr section,XkbRowPtr row) +{ +register int k,pos; +XkbKeyPtr key; +XkbBoundsPtr bounds,sbounds; + + if ((!geom)||(!section)||(!row)) + return False; + pos= 0; + bounds= &row->bounds; + bzero(bounds,sizeof(XkbBoundsRec)); + for (key=row->keys,pos=k=0;knum_keys;k++,key++) { + sbounds= &XkbKeyShape(geom,key)->bounds; + _XkbCheckBounds(bounds,pos,0); + if (!row->vertical) { + if (key->gap!=0) { + pos+= key->gap; + _XkbCheckBounds(bounds,pos,0); + } + _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1); + _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2); + pos+= sbounds->x2; + } + else { + if (key->gap!=0) { + pos+= key->gap; + _XkbCheckBounds(bounds,0,pos); + } + _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1); + _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2); + pos+= sbounds->y2; + } + } + return True; +} + +Bool +XkbcComputeSectionBounds(XkbGeometryPtr geom,XkbSectionPtr section) +{ +register int i; +XkbShapePtr shape; +XkbRowPtr row; +XkbDoodadPtr doodad; +XkbBoundsPtr bounds,rbounds=NULL; + + if ((!geom)||(!section)) + return False; + bounds= §ion->bounds; + bzero(bounds,sizeof(XkbBoundsRec)); + for (i=0,row=section->rows;inum_rows;i++,row++) { + if (!XkbcComputeRowBounds(geom,section,row)) + return False; + rbounds= &row->bounds; + _XkbCheckBounds(bounds,row->left+rbounds->x1,row->top+rbounds->y1); + _XkbCheckBounds(bounds,row->left+rbounds->x2,row->top+rbounds->y2); + } + for (i=0,doodad=section->doodads;inum_doodads;i++,doodad++) { + static XkbBoundsRec tbounds; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + shape= XkbShapeDoodadShape(geom,&doodad->shape); + rbounds= &shape->bounds; + break; + case XkbTextDoodad: + tbounds.x1= doodad->text.left; + tbounds.y1= doodad->text.top; + tbounds.x2= tbounds.x1+doodad->text.width; + tbounds.y2= tbounds.y1+doodad->text.height; + rbounds= &tbounds; + break; + case XkbIndicatorDoodad: + shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); + rbounds= &shape->bounds; + break; + case XkbLogoDoodad: + shape= XkbLogoDoodadShape(geom,&doodad->logo); + rbounds= &shape->bounds; + break; + default: + tbounds.x1= tbounds.x2= doodad->any.left; + tbounds.y1= tbounds.y2= doodad->any.top; + break; + } + _XkbCheckBounds(bounds,rbounds->x1,rbounds->y1); + _XkbCheckBounds(bounds,rbounds->x2,rbounds->y2); + } + return True; +} diff --git a/src/xkbcomp/geometry.c b/src/xkbcomp/geometry.c index c73e580..0b66173 100644 --- a/src/xkbcomp/geometry.c +++ b/src/xkbcomp/geometry.c @@ -2919,7 +2919,7 @@ CopyShapeDef(XkbGeometryPtr geom, ShapeInfo * si) n = (si->primary - si->outlines); shape->primary = &shape->outlines[n]; } - XkbComputeShapeBounds(shape); + XkbcComputeShapeBounds(shape); return True; } @@ -3582,7 +3582,7 @@ CopySectionDef(XkbGeometryPtr geom, SectionInfo * si, GeometryInfo * info) CopyOverlayDef(geom, section, oi, info); } } - if (XkbComputeSectionBounds(geom, section)) + if (XkbcComputeSectionBounds(geom, section)) { /* 7/6/94 (ef) -- check for negative origin and translate */ if ((si->defs.defined & _GS_Width) == 0)