|
Packit |
b099d7 |
/* $XConsortium: DrArrow.c /main/6 1995/10/25 19:59:56 cde-sun $ */
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* HISTORY
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include "XmI.h"
|
|
Packit |
b099d7 |
#include <Xm/DrawP.h>
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/****************************XmeDrawArrow**********************************/
|
|
Packit |
b099d7 |
void XmeDrawArrow(Display *display, Drawable d,
|
|
Packit |
b099d7 |
GC top_gc, GC bot_gc, GC cent_gc,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int x, int y,
|
|
Packit |
b099d7 |
int width, int height, int shadow_thick,
|
|
Packit |
b099d7 |
unsigned int direction)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Position x, Position y,
|
|
Packit |
b099d7 |
Dimension width, Dimension height, Dimension shadow_thick,
|
|
Packit |
b099d7 |
unsigned char direction)
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* cent_gc might be NULL, which means don't draw anything on the center,
|
|
Packit |
b099d7 |
but if shadow_thick is 1, then center is not NULL, see in ArrowB */
|
|
Packit |
b099d7 |
/* in the current implementation, on shadow_thick = 2, 1 or 0 supported */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static unsigned int allocated = 0;
|
|
Packit |
b099d7 |
static XRectangle * top = NULL;
|
|
Packit |
b099d7 |
static XRectangle * cent = NULL;
|
|
Packit |
b099d7 |
static XRectangle * bot = NULL;
|
|
Packit |
b099d7 |
XRectangle * rect_tmp;
|
|
Packit |
b099d7 |
int size, xOffset = 0, yOffset = 0, wwidth, start;
|
|
Packit |
b099d7 |
register int temp, yy, i, h, w;
|
|
Packit |
b099d7 |
short t = 0 , b = 0 , c = 0 ;
|
|
Packit |
b099d7 |
XtAppContext app;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!d) return ;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
app = XtDisplayToApplicationContext(display);
|
|
Packit |
b099d7 |
_XmAppLock(app);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Get the size and the position and allocate the rectangle lists */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (width > height) {
|
|
Packit |
b099d7 |
size = height - 2;
|
|
Packit |
b099d7 |
xOffset = (width - height) / 2;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
size = width - 2 ;
|
|
Packit |
b099d7 |
yOffset = (height - width) / 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (size < 1) { _XmAppUnlock(app); return; }
|
|
Packit |
b099d7 |
if (allocated < size) {
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
top = (XRectangle *) XtRealloc ((char*)top,
|
|
Packit |
b099d7 |
sizeof (XRectangle) * (size/2+6));
|
|
Packit |
b099d7 |
cent = (XRectangle *) XtRealloc ((char*)cent,
|
|
Packit |
b099d7 |
sizeof (XRectangle) * (size/2+6));
|
|
Packit |
b099d7 |
bot = (XRectangle *) XtRealloc ((char*)bot,
|
|
Packit |
b099d7 |
sizeof (XRectangle) * (size/2+6));
|
|
Packit |
b099d7 |
allocated = size;
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define SWAP(x,y) temp = x ; x = y; y = temp
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (direction == XmARROW_RIGHT || direction == XmARROW_LEFT) {
|
|
Packit |
b099d7 |
SWAP(xOffset,yOffset) ;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Set up a loop to generate the segments. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wwidth = size;
|
|
Packit |
b099d7 |
yy = size - 1 + yOffset;
|
|
Packit |
b099d7 |
start = 1 + xOffset;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmProcessLock();
|
|
Packit |
b099d7 |
while (wwidth > 0) {
|
|
Packit |
b099d7 |
if (wwidth == 1) {
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy + 1;
|
|
Packit |
b099d7 |
top[t].width = 1; top[t].height = 1;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else if (wwidth == 2) {
|
|
Packit |
b099d7 |
if (size == 2 || (direction == XmARROW_UP ||
|
|
Packit |
b099d7 |
direction == XmARROW_LEFT)) {
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy;
|
|
Packit |
b099d7 |
top[t].width = 2; top[t].height = 1;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy + 1;
|
|
Packit |
b099d7 |
top[t].width = 1; top[t].height = 1;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
bot[b].x = start + 1; bot[b].y = yy + 1;
|
|
Packit |
b099d7 |
bot[b].width = 1; bot[b].height = 1;
|
|
Packit |
b099d7 |
b++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
if (start == 1 + xOffset)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
if (direction == XmARROW_UP || direction == XmARROW_LEFT) {
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy;
|
|
Packit |
b099d7 |
top[t].width = 2; top[t].height = 1;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy + 1;
|
|
Packit |
b099d7 |
top[t].width = 1; top[t].height = 1;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
bot[b].x = start + 1; bot[b].y = yy + 1;
|
|
Packit |
b099d7 |
bot[b].width = 1; bot[b].height = 1;
|
|
Packit |
b099d7 |
b++;
|
|
Packit |
b099d7 |
bot[b].x = start + 2; bot[b].y = yy;
|
|
Packit |
b099d7 |
bot[b].width = wwidth - 2; bot[b].height = 2;
|
|
Packit |
b099d7 |
b++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy;
|
|
Packit |
b099d7 |
top[t].width = 2; top[t].height = 1;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
bot[b].x = start; bot[b].y = yy + 1;
|
|
Packit |
b099d7 |
bot[b].width = 2; bot[b].height = 1;
|
|
Packit |
b099d7 |
b++;
|
|
Packit |
b099d7 |
bot[b].x = start + 2; bot[b].y = yy;
|
|
Packit |
b099d7 |
bot[b].width = wwidth - 2; bot[b].height = 2;
|
|
Packit |
b099d7 |
b++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
top[t].x = start; top[t].y = yy;
|
|
Packit |
b099d7 |
top[t].width = 2; top[t].height = 2;
|
|
Packit |
b099d7 |
t++;
|
|
Packit |
b099d7 |
bot[b].x = start + wwidth - 2; bot[b].y = yy;
|
|
Packit |
b099d7 |
bot[b].width = 2; bot[b].height = 2;
|
|
Packit |
b099d7 |
if (wwidth == 3) {
|
|
Packit |
b099d7 |
bot[b].width = 1;
|
|
Packit |
b099d7 |
bot[b].x += 1;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
b++;
|
|
Packit |
b099d7 |
if (wwidth > 4) {
|
|
Packit |
b099d7 |
cent[c].x = start + 2; cent[c].y = yy;
|
|
Packit |
b099d7 |
cent[c].width = wwidth - 4; cent[c].height = 2;
|
|
Packit |
b099d7 |
c++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
start++;
|
|
Packit |
b099d7 |
wwidth -= 2;
|
|
Packit |
b099d7 |
yy -= 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (direction == XmARROW_DOWN || direction == XmARROW_RIGHT) {
|
|
Packit |
b099d7 |
rect_tmp = top; top = bot; bot = rect_tmp;
|
|
Packit |
b099d7 |
SWAP(t, b);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Transform the "up" pointing arrow to the correct direction */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch (direction) {
|
|
Packit |
b099d7 |
case XmARROW_LEFT:
|
|
Packit |
b099d7 |
i = -1;
|
|
Packit |
b099d7 |
do {
|
|
Packit |
b099d7 |
i++;
|
|
Packit |
b099d7 |
if (i < t) {
|
|
Packit |
b099d7 |
SWAP(top[i].y, top[i].x);
|
|
Packit |
b099d7 |
SWAP(top[i].width, top[i].height);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i < b) {
|
|
Packit |
b099d7 |
SWAP(bot[i].y, bot[i].x);
|
|
Packit |
b099d7 |
SWAP(bot[i].width, bot[i].height);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i < c) {
|
|
Packit |
b099d7 |
SWAP(cent[i].y, cent[i].x);
|
|
Packit |
b099d7 |
SWAP(cent[i].width, cent[i].height);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} while (i < t || i < b || i < c);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
case XmARROW_RIGHT:
|
|
Packit |
b099d7 |
h = height - 2;
|
|
Packit |
b099d7 |
w = width - 2;
|
|
Packit |
b099d7 |
i = -1;
|
|
Packit |
b099d7 |
do {
|
|
Packit |
b099d7 |
i++;
|
|
Packit |
b099d7 |
if (i < t) {
|
|
Packit |
b099d7 |
SWAP(top[i].y, top[i].x);
|
|
Packit |
b099d7 |
SWAP(top[i].width, top[i].height);
|
|
Packit |
b099d7 |
top[i].x = w - top[i].x - top[i].width + 2;
|
|
Packit |
b099d7 |
top[i].y = h - top[i].y - top[i].height + 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i < b) {
|
|
Packit |
b099d7 |
SWAP(bot[i].y, bot[i].x);
|
|
Packit |
b099d7 |
SWAP(bot[i].width, bot[i].height);
|
|
Packit |
b099d7 |
bot[i].x = w - bot[i].x - bot[i].width + 2;
|
|
Packit |
b099d7 |
bot[i].y = h - bot[i].y - bot[i].height + 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i < c) {
|
|
Packit |
b099d7 |
SWAP(cent[i].y, cent[i].x);
|
|
Packit |
b099d7 |
SWAP(cent[i].width, cent[i].height);
|
|
Packit |
b099d7 |
cent[i].x = w - cent[i].x - cent[i].width + 2;
|
|
Packit |
b099d7 |
cent[i].y = h - cent[i].y - cent[i].height + 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} while (i < t || i < b || i < c);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
case XmARROW_DOWN:
|
|
Packit |
b099d7 |
w = width - 2;
|
|
Packit |
b099d7 |
h = height - 2;
|
|
Packit |
b099d7 |
i = -1;
|
|
Packit |
b099d7 |
do {
|
|
Packit |
b099d7 |
i++;
|
|
Packit |
b099d7 |
if (i < t) {
|
|
Packit |
b099d7 |
top[i].x = w - top[i].x - top[i].width + 2;
|
|
Packit |
b099d7 |
top[i].y = h - top[i].y - top[i].height + 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i < b) {
|
|
Packit |
b099d7 |
bot[i].x = w - bot[i].x - bot[i].width + 2;
|
|
Packit |
b099d7 |
bot[i].y = h - bot[i].y - bot[i].height + 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i < c) {
|
|
Packit |
b099d7 |
cent[i].x = w - cent[i].x - cent[i].width + 2;
|
|
Packit |
b099d7 |
cent[i].y = h - cent[i].y - cent[i].height + 2;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} while (i < t || i < b || i < c);
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (x != 0 || y != 0) {
|
|
Packit |
b099d7 |
for (i = 0; i < t; i++) {
|
|
Packit |
b099d7 |
top[i].x += x;
|
|
Packit |
b099d7 |
top[i].y += y;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
for (i = 0; i < c; i++) {
|
|
Packit |
b099d7 |
cent[i].x += x;
|
|
Packit |
b099d7 |
cent[i].y += y;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
for (i = 0; i < b; i++) {
|
|
Packit |
b099d7 |
bot[i].x += x;
|
|
Packit |
b099d7 |
bot[i].y += y;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (shadow_thick) { /* 1 or 2 shadow thickness: always draw
|
|
Packit |
b099d7 |
2 thickness at that point, we'll correct it
|
|
Packit |
b099d7 |
later */
|
|
Packit |
b099d7 |
XFillRectangles (display, d, top_gc, top, t);
|
|
Packit |
b099d7 |
XFillRectangles (display, d, bot_gc, bot, b);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* handle the case where arrow shadow_thickness = 0, which give
|
|
Packit |
b099d7 |
a flat arrow: draw the shadow area with the center color */
|
|
Packit |
b099d7 |
if (cent_gc) {
|
|
Packit |
b099d7 |
XFillRectangles (display, d, cent_gc, top, t);
|
|
Packit |
b099d7 |
XFillRectangles (display, d, cent_gc, bot, b);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (shadow_thick == 1) {
|
|
Packit |
b099d7 |
/* we already drawn the shadow of 2, now let's draw a
|
|
Packit |
b099d7 |
bigger center area: ask for a smaller arrow with
|
|
Packit |
b099d7 |
flat look */
|
|
Packit |
b099d7 |
XmeDrawArrow(display, d, top_gc, bot_gc, cent_gc,
|
|
Packit |
b099d7 |
x+1, y+1, width-2, height-2, 0, direction) ;
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
if (cent_gc) XFillRectangles (display, d, cent_gc, cent, c);
|
|
Packit |
b099d7 |
_XmProcessUnlock();
|
|
Packit |
b099d7 |
_XmAppUnlock(app);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|