Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
366
cde/programs/dticon/graphics.c
Normal file
366
cde/programs/dticon/graphics.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/* $XConsortium: graphics.c /main/4 1995/11/02 14:05:07 rswiston $ */
|
||||
/*********************************************************************
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
|
||||
* Novell, Inc.
|
||||
**********************************************************************/
|
||||
/******************************************************************************
|
||||
** Program: dticon
|
||||
**
|
||||
** Description: X11-based multi-color icon editor
|
||||
**
|
||||
** File: graphics.c, which contains the following subroutines or
|
||||
** functions:
|
||||
** Flicker_Arc()
|
||||
** Circle_Box()
|
||||
** Set_HotBox_Coords()
|
||||
** Start_HotBox()
|
||||
** Do_HotBox()
|
||||
** Stop_HotBox()
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
|
||||
** All rights are reserved. Copying or reproduction of this program,
|
||||
** except for archival purposes, is prohibited without prior written
|
||||
** consent of Hewlett-Packard Company.
|
||||
**
|
||||
** Hewlett-Packard makes no representations about the suitibility of this
|
||||
** software for any purpose. It is provided "as is" without express or
|
||||
** implied warranty.
|
||||
**
|
||||
******************************************************************************/
|
||||
#include <Xm/Xm.h>
|
||||
#include <math.h>
|
||||
#include "externals.h"
|
||||
|
||||
extern GC scratch_gc;
|
||||
|
||||
Widget editMenu_cut_pb;
|
||||
Widget editMenu_copy_pb;
|
||||
Widget editMenu_rotate_pb;
|
||||
Widget editMenu_flip_pb;
|
||||
Widget editMenu_scale_pb;
|
||||
|
||||
extern void Stop_HotBox(void);
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Routine: Flicker_Arc *
|
||||
* *
|
||||
* Purpose: Given 2 points (top-left and bottom-right), draw an *
|
||||
* invertable ellipse around the box they form. *
|
||||
* *
|
||||
*X11***********************************************************************/
|
||||
|
||||
void
|
||||
Flicker_Arc(
|
||||
Window win,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2 )
|
||||
{
|
||||
int x, y, width, height;
|
||||
|
||||
x = min(x1, x2);
|
||||
y = min(y1, y2);
|
||||
width = abs(x1 - x2);
|
||||
height = abs(y1 - y2);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Doing Flicker_Arc: x=%d, y=%d, width=%d, height=%d\n",
|
||||
x, y, width, height);
|
||||
#endif
|
||||
|
||||
if ((width > 0) && (height > 0))
|
||||
XDrawArc(dpy, win, Flicker_gc, x, y, width, height, 0, 360*64);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Routine: Circle_Box *
|
||||
* *
|
||||
* Purpose: Given 2 points (the center and radius of a circle) *
|
||||
* generate a box which would exactly enclose this circle, *
|
||||
* and then draw a flickering circle that matches the box. *
|
||||
* WARNING: [x1,y1] are always assumed to be the centerpoint *
|
||||
* and this routine will generate bogus results if this is *
|
||||
* not TRUE. *
|
||||
* *
|
||||
*X11***********************************************************************/
|
||||
|
||||
void
|
||||
Circle_Box(
|
||||
Window win,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
XRectangle *box )
|
||||
{
|
||||
int radius, top_x, top_y, bottom_x, bottom_y, width, height;
|
||||
double size;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Entering Circle_Box\n");
|
||||
#endif
|
||||
|
||||
width = mag(x1, x2);
|
||||
height = mag(y1, y2);
|
||||
size = (double) ((width * width) + (height * height));
|
||||
radius = (int) sqrt(size);
|
||||
|
||||
top_x = x1 - radius;
|
||||
top_y = y1 - radius;
|
||||
bottom_x = x1 + radius;
|
||||
bottom_y = y1 + radius;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out(" Circle_Box values: tx=%d, ty=%d, bx=%d, by=%d\n",
|
||||
top_x, top_y, bottom_x, bottom_x);
|
||||
#endif
|
||||
|
||||
Flicker_Arc(win, top_x, top_y, bottom_x, bottom_y);
|
||||
|
||||
box->x = top_x;
|
||||
box->y = top_y;
|
||||
box->width = bottom_x - top_x + 1;
|
||||
box->height = bottom_y - top_y + 1;
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Leaving Circle_Box\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Routine: Set_HotBox_Coords *
|
||||
* *
|
||||
* Purpose: A SELECT operation has just occurred. Initiate a timer *
|
||||
* calculate the area to enclose. *
|
||||
* not TRUE. *
|
||||
* *
|
||||
*X11***********************************************************************/
|
||||
|
||||
#define FLASH_INTERVAL 300
|
||||
static Boolean FlashState=False;
|
||||
static int flash_x, flash_y, flash_width, flash_height;
|
||||
static int box_x1, box_y1, box_x2, box_y2;
|
||||
static XtIntervalId selectTimerID;
|
||||
static void Do_HotBox();
|
||||
|
||||
void
|
||||
Set_HotBox_Coords( void )
|
||||
{
|
||||
int min_x, min_y, max_x, max_y, tmp_x, tmp_y;
|
||||
|
||||
min_x = min(ix, last_ix);
|
||||
min_y = min(iy, last_iy);
|
||||
max_x = max(ix, last_ix);
|
||||
max_y = max(iy, last_iy);
|
||||
|
||||
/*** make sure all four points are on the tablet ***/
|
||||
|
||||
if (min_x < 0)
|
||||
min_x = 0;
|
||||
if (min_y < 0)
|
||||
min_y = 0;
|
||||
if ((max_x) >= icon_width)
|
||||
max_x = icon_width-1;
|
||||
if ((max_y) >= icon_height)
|
||||
max_y = icon_height-1;
|
||||
|
||||
select_box.x = min_x;
|
||||
select_box.y = min_y;
|
||||
select_box.width = max_x - min_x + 1;
|
||||
select_box.height = max_y - min_y + 1;
|
||||
|
||||
box_x1 = min_x;
|
||||
box_y1 = min_y;
|
||||
box_x2 = max_x+1;
|
||||
box_y2 = max_y+1;
|
||||
|
||||
Tablet_Coords(min_x, min_y, &flash_x, &flash_y);
|
||||
Tablet_Coords(max_x+1, max_y+1, &tmp_x, &tmp_y);
|
||||
flash_width = tmp_x - flash_x;
|
||||
flash_height = tmp_y - flash_y;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug) {
|
||||
stat_out(" select_box: x=%d, y=%d, width=%d, height=%d\n",
|
||||
select_box.x, select_box.y,
|
||||
select_box.width, select_box.height);
|
||||
stat_out(" flash box: x=%d, y=%d, width=%d, height=%d\n",
|
||||
flash_x, flash_y, flash_width, flash_height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Routine: Start_HotBox *
|
||||
* *
|
||||
* Purpose: A SELECT operation has just occurred. Initiate a timer *
|
||||
* which flashes a 1-pixel wide box around the perimeter of *
|
||||
* the selected rectangle every FLASH_INTERVAL milliseconds. *
|
||||
* Use the global variables ix, iy, last_ix, last_iy to *
|
||||
* calculate the area to enclose. *
|
||||
* *
|
||||
*X11***********************************************************************/
|
||||
|
||||
void
|
||||
Start_HotBox(
|
||||
int flag )
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Entering Start_HotBox\n");
|
||||
#endif
|
||||
|
||||
Selected = True;
|
||||
/* turn on stuff that uses the selected area */
|
||||
XtSetSensitive( editMenu_cut_pb, True);
|
||||
XtSetSensitive( editMenu_copy_pb, True);
|
||||
XtSetSensitive(editMenu_rotate_pb, True);
|
||||
XtSetSensitive(editMenu_flip_pb, True);
|
||||
XtSetSensitive(editMenu_scale_pb, True);
|
||||
XSync(dpy, 0);
|
||||
if (flag == INITIAL)
|
||||
Set_HotBox_Coords();
|
||||
|
||||
selectTimerID = XtAppAddTimeOut(AppContext,
|
||||
FLASH_INTERVAL,
|
||||
(XtTimerCallbackProc) Do_HotBox,
|
||||
NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Leaving Start_HotBox - TimerID=%d\n", selectTimerID);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Routine: Do_HotBox *
|
||||
* *
|
||||
* Purpose: Flash one alternating pulse around the selected area, and *
|
||||
* then re-set itself to activate again in FLASH_INTERVAL *
|
||||
* milliseconds. *
|
||||
* *
|
||||
* note: Check selectTimerID so that timeouts added for previous selects *
|
||||
* are ignored. ex: if new select is started before previous select *
|
||||
* timeout is serviced, "Selected" will already be set to true again *
|
||||
* (for new select) when timeout from old selection is called... so *
|
||||
* now Stop_HotBox is called immediately (before HotBox Coords are *
|
||||
* set for new select), and last timeout is ignored. *
|
||||
* *
|
||||
*X11***********************************************************************/
|
||||
|
||||
static void
|
||||
Do_HotBox(
|
||||
XtPointer *client_data,
|
||||
XtIntervalId *local_id )
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out(". ");
|
||||
#endif
|
||||
|
||||
if (GraphicsOp != SELECT)
|
||||
Selected = False;
|
||||
if (*local_id == selectTimerID)
|
||||
{
|
||||
if (Selected)
|
||||
{
|
||||
if (FlashState) {
|
||||
FlashState = False;
|
||||
XSetForeground(dpy, scratch_gc, black_pixel);
|
||||
}
|
||||
else
|
||||
{
|
||||
FlashState = True;
|
||||
XSetForeground(dpy, scratch_gc, white_pixel);
|
||||
}
|
||||
XSetLineAttributes(dpy, scratch_gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
XDrawRectangle(dpy, tablet_win, scratch_gc,
|
||||
flash_x, flash_y, flash_width, flash_height);
|
||||
selectTimerID=XtAppAddTimeOut(AppContext,
|
||||
FLASH_INTERVAL,
|
||||
(XtTimerCallbackProc) Do_HotBox,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
Stop_HotBox();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Routine: Stop_HotBox *
|
||||
* *
|
||||
* Purpose: Undo the last Selected border operation. *
|
||||
* *
|
||||
*X11***********************************************************************/
|
||||
|
||||
void
|
||||
Stop_HotBox( void )
|
||||
{
|
||||
int min_x, min_y, max_x, max_y, tmp_x, tmp_y;
|
||||
static int tmp_ix, tmp_iy;
|
||||
static Boolean Rotate_Move=False;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Entering Stop_HotBox\n");
|
||||
#endif
|
||||
|
||||
if (GridEnabled) {
|
||||
XDrawLine(dpy, tablet_win, Grid_gc,
|
||||
flash_x, flash_y, (flash_x+flash_width), flash_y);
|
||||
XDrawLine(dpy, tablet_win, Grid_gc,
|
||||
flash_x, (flash_y+flash_height), (flash_x+flash_width),
|
||||
(flash_y+flash_height));
|
||||
XDrawLine(dpy, tablet_win, Grid_gc,
|
||||
flash_x, flash_y, flash_x, (flash_y+flash_height));
|
||||
XDrawLine(dpy, tablet_win, Grid_gc,
|
||||
(flash_x+flash_width), flash_y, (flash_x+flash_width),
|
||||
(flash_y+flash_height));
|
||||
}
|
||||
else {
|
||||
/* since Rotate left and right moves ix and iy revert to tmp_ix, tmp_iy */
|
||||
if (Rotate_Move) { Rotate_Move = False;
|
||||
ix = tmp_ix;
|
||||
iy = tmp_iy; }
|
||||
min_x = min(ix, last_ix);
|
||||
min_y = min(iy, last_iy);
|
||||
max_x = max(ix, last_ix);
|
||||
max_y = max(iy, last_iy);
|
||||
if (++max_x >= icon_width) max_x--;
|
||||
if (++max_y >= icon_height) max_y--;
|
||||
Transfer_Back_Image(min_x, min_y, max_x, max_y, HOLLOW);
|
||||
/* if it is a Rotate Op. then keep ix, iy */
|
||||
if(GraphicsOp == S_ROTATE) { Rotate_Move = True;
|
||||
tmp_ix = ix;
|
||||
tmp_iy = iy; }
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug)
|
||||
stat_out("Leaving Stop_HotBox\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user