This is ImportXDPS.c in view mode; [Download] [Up]
/*
* $RCSfile: ImportXDPS.c,v $
*
* Copyright (C) 1992 by Adobe Systems Incorporated.
* All rights reserved.
*
* 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 notices appear in all copies and that
* both those copyright notices and this permission notice appear in
* supporting documentation and that the name of Adobe Systems
* Incorporated not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. If any portion of this software is changed, it cannot be
* marketed under Adobe's trademarks and/or copyrights unless Adobe, in
* its sole discretion, approves by a prior writing the quality of the
* resulting implementation.
*
* ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
* ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
* ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
* TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
* PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
*
* PostScript, Display PostScript, and Adobe are trademarks of Adobe Systems
* Incorporated registered in the U.S.A. and other countries.
*
* Author: Adobe Systems Incorporated
*/
/***************************************************************
**
** INCLUDES
**
***************************************************************/
#include "Import.h"
/***************************************************************
**
** DATA DECLARATIONS
**
***************************************************************/
static char FontName[] = "ControlPointsFont";
static char ControlString[] = "aaaaaaaa";
static float CtlPtSize = 4.0; /* size of the control points */
/***************************************************************
**
** FUNCTION: drawSelf
**
** DESCRIPTION: Draws the picture by copying elements to the original
** pixmap. If start is non-NULL, it means that everything
** below start is ok and doesn't need to be copied
**
** PARAMETERS: start Everything below this element is already ok
**
** RETURN: None
**
***************************************************************/
void drawSelf(start)
Element *start;
{
Element *e;
Display *dpy = XtDisplay(AppData.drawingArea);
int x, y;
/*
** Set rendering to original pixmap for drawing background (and
** possibly boxes
*/
XDPSSetContextGState(AppData.dpsCtxt, AppData.origGState);
if (start == NULL) PSWDesktop(0.0, 0.0, PAGE_WIDTH, PAGE_HEIGHT);
DPSWaitContext(AppData.dpsCtxt);
for (e = AppData.lastElement; e != NULL; e = e->prev) {
/*
** See if we're before the start element
*/
if (e == start) start = NULL;
if (start != NULL) continue;
/*
** The moveElement is the element being moved; it should
** temporarily not be in the picture
*/
if (e == AppData.moveElement) continue;
/*
** If we're using boxes, or if there is no image for this
** element, draw a box. Wait after drawing if we're not using
** boxes so that later elements appear correctly stacked
*/
if (AppData.useBoxes || e->image == None) {
PSWDrawBox(e->origBBox.ll.x, e->origBBox.ll.y,
e->origBBox.ur.x, e->origBBox.ur.y,
e->tx, e->ty, e->sx, e->sy, e->rotation);
if (!AppData.useBoxes) DPSWaitContext(AppData.dpsCtxt);
/*
** If not using boxes, copy image through a mask
*/
} else {
x = e->xBBox.x + AppData.originX;
y = e->xBBox.y - AppData.scaledHeight + AppData.originY;
XSetClipOrigin(dpy, AppData.gc, x, y);
XSetClipMask(dpy, AppData.gc, e->mask);
XCopyArea(dpy, e->image, AppData.original, AppData.gc,
0, 0, e->xBBox.width, e->xBBox.height, x, y);
}
if (AppData.useBoxes) DPSWaitContext(AppData.dpsCtxt);
/*
** If showing buffers, refresh original buffer window
*/
if (AppData.showBuffer) {
XSetClipMask(dpy, AppData.gc, None);
XCopyArea(XtDisplay(AppData.drawingArea), AppData.original,
XtWindow(AppData.bufOrig), AppData.gc,
0, 0, AppData.drawingWidth,
AppData.drawingHeight, 0, 0);
}
}
/*
** Reset clip mask
*/
XSetClipMask(dpy, AppData.gc, None);
} /* end drawSelf() */
/***************************************************************
**
** FUNCTION: drawSelfAndUpdate
**
** DESCRIPTION: Draw the picture, then copy the original pixmap into
** the drawing area window
**
** PARAMETERS: start Everything below this element is already ok
**
** RETURN: None
**
***************************************************************/
void drawSelfAndUpdate(start)
Element *start;
{
drawSelf(start);
XCopyArea(XtDisplay(AppData.drawingArea), AppData.original,
XtWindow(AppData.drawingArea), AppData.gc,
0, 0, AppData.drawingWidth, AppData.drawingHeight, 0, 0);
if (AppData.selected) drawSelectionMarks();
} /* end drawSelfAndUpdate() */
/*************************************************************
**
** FUNCTION: convertPoint
**
** DESCRIPTION: Convert an X point into user space, possibly relative
** to previous point
**
** PARAMETERS: x, y Point in X coordinates
** pfx Where to store user space coordinates
** relative If true, make relative to previous point
**
** RETURN: None
**
*************************************************************/
static void convertPoint(x, y, pfx, relative)
int x, y;
float *pfx;
Boolean relative;
{
XPoint xpt;
Point pt;
static Point lastPt;
/*
** Convert to user space and store
*/
xpt.x = x + AppData.originX;
xpt.y = y - AppData.scaledHeight + AppData.originY;
convertToDPS(&xpt, &pt);
*pfx = pt.x;
*(pfx+1) = pt.y;
/*
** If relative, adjust by previous point
*/
if (relative) {
*pfx -= lastPt.x;
*(pfx+1) -= lastPt.y;
}
lastPt = pt;
} /* end convertPoint() */
/*************************************************************
**
** FUNCTION: drawSelectionMarks
**
** DESCRIPTION: Draw marks around the selected object
**
** PARAMETERS: None
**
** RETURN: None
**
*************************************************************/
void drawSelectionMarks()
{
float pts[18];
Element *e = AppData.selected;
XPoint xpt;
Point pt;
XRect *r = &e->sizeBox;
if (e == NULL) return;
/*
** Set gstate for drawing into the window
*/
XDPSSetContextGState(AppData.dpsCtxt, AppData.winGState);
PSgsave();
/*
** Easiest way to do this is to rotate the coordinate system so that
** we don't need to rotate the points. First translate to the origin
** of the picture (== the origin of the sizeBox)
*/
xpt.x = r->x + AppData.originX;
xpt.y = r->y - AppData.scaledHeight + AppData.originY;
convertToDPS(&xpt, &pt);
PStranslate(pt.x, pt.y);
if (e->rotation != 0.0) PSrotate(e->rotation);
/*
** Convert X points to user space coordinates. Subtract the translation
** from the initial point since we've already translated there, and make
** the other points relative
*/
convertPoint(r->x, r->y, &pts[0], False);
pts[0] -= pt.x;
pts[1] -= pt.y;
convertPoint(r->x, r->y + r->height/2, &pts[2], True);
convertPoint(r->x, r->y + r->height, &pts[4], True);
convertPoint(r->x + r->width/2, r->y + r->height, &pts[6], True);
convertPoint(r->x + r->width, r->y + r->height, &pts[8], True);
convertPoint(r->x + r->width, r->y + r->height/2, &pts[10], True);
convertPoint(r->x + r->width, r->y, &pts[12], True);
convertPoint(r->x + r->width/2, r->y, &pts[14], True);
pts[16] = pts[17] = 0;
/*
** Draw the points
*/
PSWDrawControlPoints(pts[0], pts[1], &pts[2], 16,
ControlString, 8);
PSgrestore();
} /* end drawSelectionMarks() */
/*************************************************************
**
** FUNCTION: computeRotatePoint
**
** DESCRIPTION: Rotate an X coordinate
**
** PARAMETERS: x, y Point to rotate
** ox, oy Center of rotation
** rot Rotation (in radians)
** pt Returns rotated point
**
** RETURN: None
**
*************************************************************/
static void computeRotatePoint(x, ox, y, oy, rot, pt)
int x, y, ox, oy;
float rot;
XPoint *pt;
{
float r, theta;
float dx, dy;
/*
** Compute offsets from center of rotation
*/
dx = x - ox;
dy = y - oy;
/*
** Rotate point by angle
*/
if (dx == 0 && dy == 0) {
pt->x = 0;
pt->y = 0;
} else {
r = sqrt(dx * dx + dy * dy);
theta = atan2(dy, dx) + rot;
pt->x = r * cos(theta) + 0.5;
pt->y = r * sin(theta) + 0.5;
}
/*
** Add center of rotation back to get point
*/
pt->x += ox;
pt->y += oy;
} /* end computeRotatePoint() */
/*************************************************************
**
** FUNCTION: drawRotatedRectangle
**
** DESCRIPTION: Draw a rotated rectangle using X functions
**
** PARAMETERS: rect Rectangle to draw
** rotation Amount to rotate (in degrees)
** ox, oy Center of rotation
**
** RETURN: None
**
*************************************************************/
static void drawRotatedRectangle(rect, rotation, ox, oy)
XRect *rect;
float rotation;
int ox, oy;
{
XPoint xpt[5];
float r = -DTOR(rotation);
/*
** Compute the four rotated points and draw lines
*/
computeRotatePoint(rect->x, ox, rect->y, oy, r, xpt);
computeRotatePoint(rect->x + rect->width, ox, rect->y, oy, r, xpt + 1);
computeRotatePoint(rect->x + rect->width, ox, rect->y + rect->height, oy,
r, xpt + 2);
computeRotatePoint(rect->x, ox, rect->y + rect->height, oy, r, xpt + 3);
xpt[4] = xpt[0];
XDrawLines(XtDisplay(AppData.drawingArea), AppData.composite,
AppData.blackgc, xpt, 5, CoordModeOrigin);
} /* end drawRotatedRectangle() */
/*************************************************************
**
** FUNCTION: computeRotatedBounds
**
** DESCRIPTION: Compute the bounding box of a rotated rectangle
**
** PARAMETERS: rect Rectangle to rotate
** rotation Amount to rotate (in degrees)
** ox, oy Center of rotation
**
** RETURN: bounds Returns bounding box
**
*************************************************************/
static void computeRotatedBounds(rect, rotation, ox, oy, bounds)
XRect *rect;
float rotation;
int ox, oy;
XRect *bounds;
{
XPoint xpt[4];
float r = -DTOR(rotation);
int minx, miny, maxx, maxy;
int i;
/*
** Compute the four rotated points
*/
computeRotatePoint(rect->x, ox, rect->y, oy, r, xpt);
computeRotatePoint(rect->x + rect->width, ox, rect->y, oy, r, xpt + 1);
computeRotatePoint(rect->x + rect->width, ox, rect->y + rect->height, oy,
r, xpt + 2);
computeRotatePoint(rect->x, ox, rect->y + rect->height, oy, r, xpt + 3);
/*
** Find the minimum and maximum points
*/
minx = maxx = xpt[0].x;
miny = maxy = xpt[0].y;
for (i = 1; i < 4; i++) {
if (xpt[i].x < minx) minx = xpt[i].x;
else if (xpt[i].x > maxx) maxx = xpt[i].x;
if (xpt[i].y < miny) miny = xpt[i].y;
else if (xpt[i].y > maxy) maxy = xpt[i].y;
}
bounds->x = minx;
bounds->y = miny;
bounds->width = maxx - minx + 1;
bounds->height = maxy - miny + 1;
} /* end computeRotatedBounds() */
/***************************************************************
**
** FUNCTION: copyOrigToComposite
**
** DESCRIPTION: Copies the original buffer to the composite one
** and updates the buffer window
**
** PARAMETERS: None
**
** RETURN: None
**
***************************************************************/
static void copyOrigToComposite()
{
Display *dpy = XtDisplay(AppData.drawingArea);
XCopyArea(dpy, AppData.original, AppData.composite, AppData.gc,
0, 0, AppData.drawingWidth, AppData.drawingHeight,
0, 0);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, 0, 0, AppData.drawingWidth,
AppData.drawingHeight, 0, 0);
}
} /* end copyOrigToComposite() */
/***************************************************************
**
** FUNCTION: checkScrolling
**
** DESCRIPTION: Checks if the point is outside the window, and scrolls
** if so.
**
** PARAMETERS: x Mouse x coordinate
** y Mouse y coordinate
** initPt Initial point
**
** RETURN: whether scrolling occured
**
***************************************************************/
static Boolean checkScrolling(x, y, initPt)
int x, y;
XPoint *initPt;
{
int deltaX = 0, deltaY = 0;
/*
** If inside the window, no scrolling needed
*/
if (x >= 0 && y >= 0 &&
x <= AppData.drawingWidth && y <= AppData.drawingHeight) return False;
/*
** If x is outside to left, scroll to left...but not beyond left edge
*/
if (x < 0) {
deltaX = x;
if (deltaX < -AppData.scrollX) deltaX = -AppData.scrollX;
} else if (x > AppData.drawingWidth) {
/*
** Ditto for outside to right
*/
if (AppData.scaledWidth > AppData.drawingWidth) {
if (AppData.scrollX + x > AppData.scaledWidth) {
deltaX = AppData.scaledWidth -
(AppData.scrollX + AppData.drawingWidth);
} else deltaX = x - AppData.drawingWidth;
}
}
/*
** Now do the same thing for y
*/
if (y < 0) {
deltaY = y;
if (deltaY < -AppData.scrollY) deltaY = -AppData.scrollY;
} else if (y > AppData.drawingHeight) {
if (AppData.scaledHeight > AppData.drawingHeight) {
if (AppData.scrollY + y > AppData.scaledHeight) {
deltaY = AppData.scaledHeight -
(AppData.scrollY + AppData.drawingHeight);
} else deltaY = y - AppData.drawingHeight;
}
}
/*
** We may have hit an edge and not need to scroll after all
*/
if (deltaX == 0 && deltaY == 0) return False;
/*
** Do the scroll
*/
doScroll(deltaX, deltaY);
/*
** Reflect new scrolled values in scrollbars
*/
XtVaSetValues(AppData.hScroll, XmNvalue, AppData.scrollX, NULL);
XtVaSetValues(AppData.vScroll, XmNvalue, AppData.scrollY, NULL);
initPt->x -= deltaX;
initPt->y -= deltaY;
return True;
} /* end checkScrolling() */
/***************************************************************
**
** FUNCTION: getNextMouseEvent
**
** DESCRIPTION: Returns the next button release or motion event
**
** PARAMETERS: dpy Display
** win Window
**
** RETURN: event Event
**
***************************************************************/
static void getNextMouseEvent(dpy, win, event)
Display *dpy;
Window win;
XEvent *event;
{
XWindowEvent(dpy, win, ButtonMotionMask | ButtonReleaseMask, event);
/*
** Do motion compression by skipping over more motion events
*/
while (event->type != ButtonRelease) {
if (!XCheckWindowEvent(dpy, win,
ButtonMotionMask | ButtonReleaseMask,
event)) break;
}
} /* end getNextMouseEvent() */
/***************************************************************
**
** FUNCTION: mergeXRects
**
** DESCRIPTION: Adds the second X rectangle to the first
**
** PARAMETERS: orig Original rectangle
** add Rect being added
**
** RETURN: None
**
***************************************************************/
static void mergeXRects(orig, add)
XRect *orig, *add;
{
if (add->x < orig->x) {
orig->width += orig->x - add->x;
orig->x = add->x;
}
if (add->y < orig->y) {
orig->height += orig->y - add->y;
orig->y = add->y;
}
if (add->x + add->width > orig->x + orig->width) {
orig->width = add->x + add->width - orig->x;
}
if (add->y + add->height > orig->y + orig->height) {
orig->height = add->y + add->height - orig->y;
}
} /* end mergeXRects() */
/***************************************************************
**
** FUNCTION: computeMergeBBox
**
** DESCRIPTION: Compute bounding box that must be updated
**
** PARAMETERS: rect Pointer to rectangle
** oldBBox Previous curve bounding box (updated)
**
** RETURN: copy Rectangle to copy
**
***************************************************************/
static void computeMergeBBox(rect, oldBBox, copy)
XRect *rect;
XRect *oldBBox, *copy;
{
XRect currentBBox;
currentBBox = *rect;
currentBBox.width++;
currentBBox.height++;
mergeXRects(oldBBox, ¤tBBox);
*copy = *oldBBox;
*oldBBox = currentBBox;
} /* end computeMergeBBox() */
/***************************************************************
**
** FUNCTION: doSweep
**
** DESCRIPTION: Handle a mouse movement during rectangle sweep
**
** PARAMETERS: initPt Where the mouse started
** curPt Where the mouse currently is
** first Whether this is the first time
** scrolled Whether we scrolled this time through
** ratio width/height ratio of rectangle
** b bounding box of rectangle
**
** RETURN: rect Rectangle swept out
**
***************************************************************/
static void doSweep(initPt, curPt, first, scrolled, ratio, b, rect)
XPoint *initPt, *curPt;
Boolean *first, scrolled;
float ratio;
BBox *b;
XRect *rect;
{
static XRect oldBBox;
XRect copy;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
float newratio;
/*
** Construct a rectangle from initial point to current point
*/
rect->x = initPt->x;
rect->y = initPt->y;
rect->width = curPt->x - initPt->x;
rect->height = curPt->y - initPt->y;
/*
** If the first time through, set up the bounding box for the initial
** drawing (normal size)
*/
if (*first) {
oldBBox.width = (b->ur.x - b->ll.x) * AppData.scaledWidth / PAGE_WIDTH;
oldBBox.height = (b->ur.y - b->ll.y) * AppData.scaledHeight /
PAGE_HEIGHT;
oldBBox.x = initPt->x;
oldBBox.y = initPt->y - oldBBox.height;
*first = False;
}
/*
** If swept area is 0 width or height, use normal size
*/
if (rect->width == 0 || rect->height == 0) {
rect->width = (b->ur.x - b->ll.x) * AppData.scaledWidth / PAGE_WIDTH;
rect->height = (b->ur.y - b->ll.y) * AppData.scaledHeight /
PAGE_HEIGHT;
rect->y -= rect->height;
} else {
/*
** Adjust box to make it match the ratio of the picture
*/
newratio = ABS((float) rect->width) / ABS((float) rect->height);
if (newratio > ratio) {
/*
** Too wide, make narrower
*/
rect->width = (int) (ratio * (float) ABS(rect->height) + 0.5) *
SIGN(rect->width);
} else if (newratio < ratio) {
/*
** Too tall, make shorter
*/
rect->height = (int) ((float) ABS(rect->width) / ratio + 0.5) *
SIGN(rect->height);
}
}
/*
** Make into a proper X rectangle
*/
if (rect->width < 0) {
rect->x += rect->width;
rect->width = -rect->width;
}
if (rect->height < 0) {
rect->y += rect->height;
rect->height = -rect->height;
}
/*
** Compute area that must be updated. If we scrolled, make it
** everything, but we still have to compute the bbox so we have
** an oldBBox for next time around
*/
computeMergeBBox(rect, &oldBBox, ©);
if (scrolled) {
copy.x = copy.y = 0;
copy.width = AppData.drawingWidth;
copy.height = AppData.drawingHeight;
}
/*
** Copy original into composite
*/
XCopyArea(dpy, AppData.original, AppData.composite, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
/*
** Draw the rectangle to the composite pixmap and copy to window
*/
XDrawRectangle(XtDisplay(AppData.drawingArea), AppData.composite,
AppData.blackgc, rect->x, rect->y,
rect->width, rect->height);
XCopyArea(dpy, AppData.composite, win, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, copy.x, copy.y, copy.width, copy.height,
copy.x, copy.y);
}
} /* end doSweep() */
/***************************************************************
**
** FUNCTION: doSweepLoop
**
** DESCRIPTION: Event handling loop for sweeping a rectangle
**
** PARAMETERS: initPt Initial mouse down point
** ratio width/height ration of rectangle
** b bounding box
**
** RETURN: rect Rectangle swept out
**
***************************************************************/
static void doSweepLoop(initPt, ratio, b, rect)
XPoint *initPt;
float ratio;
BBox *b;
XRect *rect;
{
XEvent event;
XPoint xpoint, lastPt;
Boolean first = True;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
Boolean scrolled;
lastPt = *initPt;
do {
/*
** Wait for a motion or button release event
*/
getNextMouseEvent(dpy, win, &event);
/*
** See if user moved outside of window, and scroll drawing if so
*/
scrolled = checkScrolling(event.xbutton.x, event.xbutton.y, initPt);
/*
** Store new coordinates in xpoint
*/
xpoint.x = event.xbutton.x;
xpoint.y = event.xbutton.y;
/*
** If the mouse moved, update
*/
if (xpoint.x - lastPt.x || xpoint.y - lastPt.y) {
doSweep(initPt, &xpoint, &first, scrolled, ratio, b, rect);
}
lastPt = xpoint;
} while (event.type != ButtonRelease);
} /* end doSweepLoop() */
/***************************************************************
**
** FUNCTION: sweepRectangle
**
** DESCRIPTION: Sweep out a rectangle with the mouse
**
** PARAMETERS: pt X coordinates of button press
** b bounding box of rectangle, for ratio
**
** RETURN: rect returned X rectangle
**
***************************************************************/
void sweepRectangle(pt, b, rect)
XPoint *pt;
BBox *b;
XRect *rect;
{
float ratio;
/*
** Copy the original to the composite pixmap
*/
copyOrigToComposite();
/*
** Compute the initial ratio and the starting rectangle
*/
ratio = (b->ur.x - b->ll.x) / (b->ur.y - b->ll.y);
rect->width = (b->ur.x - b->ll.x) * AppData.scaledWidth / PAGE_WIDTH;
rect->height = (b->ur.y - b->ll.y) * AppData.scaledHeight / PAGE_HEIGHT;
rect->x = pt->x;
rect->y = pt->y - rect->height;;
/*
** Draw the starting rectangle to the composite pixmap and copy to window
*/
XDrawRectangle(XtDisplay(AppData.drawingArea), AppData.composite,
AppData.blackgc, rect->x, rect->y,
rect->width, rect->height);
XCopyArea(XtDisplay(AppData.drawingArea), AppData.composite,
XtWindow(AppData.drawingArea), AppData.gc,
rect->x, rect->y, rect->width+1, rect->height+1,
rect->x, rect->y);
/*
** Call sweep event dispatching loop
*/
doSweepLoop(pt, ratio, b, rect);
/*
** Copy original into window
*/
XCopyArea(XtDisplay(AppData.drawingArea), AppData.original,
XtWindow(AppData.drawingArea), AppData.gc,
rect->x, rect->y, rect->width+1, rect->height+1,
rect->x, rect->y);
} /* end sweepRectangle() */
/*************************************************************
**
** FUNCTION: computeMoveBBox
**
** DESCRIPTION: Compute the bounding box that must be updated
**
** PARAMETERS: rect Pointer to rectangle
** oldBBox Previous curve bounding box (updated)
**
** RETURN: copy Rectangle to copy
**
*************************************************************/
static void computeMoveBBox(rect, oldBBox, copy)
XRect *rect;
XRect *oldBBox, *copy;
{
XRect currentBBox;
currentBBox = *rect;
currentBBox.x += AppData.originX;
currentBBox.y -= AppData.scaledHeight - AppData.originY;
mergeXRects(oldBBox, ¤tBBox);
*copy = *oldBBox;
copy->x -= 2;
copy->y -= 2;
copy->width += 4;
copy->height += 4;
*oldBBox = currentBBox;
} /* end computeMoveBBox() */
/*************************************************************
**
** FUNCTION: doMove
**
** DESCRIPTION: Handle a mouse movement during move
**
** PARAMETERS: initPt Where the mouse started
** curPt Where the mouse currently is
** first Whether this is the first time
** scrolled Whether we scrolled this time through
** e Element being moved
**
** RETURN: None
**
*************************************************************/
static void doMove(initPt, curPt, first, scrolled, e)
XPoint *initPt, *curPt;
Boolean *first, scrolled;
Element *e;
{
static XRect oldBBox;
XRect copy, rect;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
int x, y;
XPoint xpt;
Point pt;
/*
** If first time, compute old bounding box.
*/
if (*first) {
oldBBox = e->xBBox;
oldBBox.x += AppData.originX;
oldBBox.y -= AppData.scaledHeight - AppData.originY;
*first = False;
}
/*
** Find area that will be
*/
rect.x = e->xBBox.x + curPt->x - initPt->x;
rect.y = e->xBBox.y + curPt->y - initPt->y;
rect.width = e->xBBox.width;
rect.height = e->xBBox.height;
/*
** Compute area that must be updated. If we scrolled, make it
** everything, but we still have to compute the bbox so we have
** an oldBBox for next time around
*/
computeMoveBBox(&rect, &oldBBox, ©);
if (scrolled) {
copy.x = copy.y = 0;
copy.width = AppData.drawingWidth;
copy.height = AppData.drawingHeight;
}
/*
** Copy original into composite
*/
XCopyArea(dpy, AppData.original, AppData.composite, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
/*
** Copy picture to the composite pixmap
*/
if (!AppData.useBoxes && e->image != None) {
x = rect.x + AppData.originX;
y = rect.y - AppData.scaledHeight + AppData.originY;
XSetClipOrigin(dpy, AppData.gc, x, y);
XSetClipMask(dpy, AppData.gc, e->mask);
XCopyArea(dpy, e->image, AppData.composite, AppData.gc,
0, 0, e->xBBox.width, e->xBBox.height, x, y);
XSetClipMask(dpy, AppData.gc, None);
/*
** If drawing a box, translate to new locale
*/
} else {
xpt.x = e->sizeBox.x + AppData.originX + curPt->x - initPt->x;
xpt.y = e->sizeBox.y - AppData.scaledHeight + AppData.originY +
curPt->y - initPt->y;
convertToDPS(&xpt, &pt);
PSWDrawBox(e->origBBox.ll.x, e->origBBox.ll.y,
e->origBBox.ur.x, e->origBBox.ur.y,
pt.x, pt.y, e->sx, e->sy, e->rotation);
DPSWaitContext(AppData.dpsCtxt);
}
/*
** Copy to the window
*/
XCopyArea(dpy, AppData.composite, win, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, copy.x, copy.y, copy.width, copy.height,
copy.x, copy.y);
}
} /* end doMove() */
/*************************************************************
**
** FUNCTION: doMoveLoop
**
** DESCRIPTION: Event handling loop for moving an element
**
** PARAMETERS: initPt Initial mouse down point
** e Element being moved
**
** RETURN: None
**
*************************************************************/
static void doMoveLoop(initPt, e)
XPoint *initPt;
Element *e;
{
XEvent event;
XPoint xpoint, lastPt;
Boolean first = True;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
Boolean scrolled;
lastPt = *initPt;
do {
/*
** Wait for a motion or button release event
*/
getNextMouseEvent(dpy, win, &event);
/*
** See if user moved outside of window, and scroll drawing if so
*/
scrolled = checkScrolling(event.xbutton.x, event.xbutton.y, initPt);
/*
** Store new coordinates in xpoint
*/
xpoint.x = event.xbutton.x;
xpoint.y = event.xbutton.y;
/*
** If the mouse moved, update
*/
if (xpoint.x - lastPt.x || xpoint.y - lastPt.y) {
doMove(initPt, &xpoint, &first, scrolled, e);
}
lastPt = xpoint;
} while (event.type != ButtonRelease);
/*
** Update bounding boxes to reflect new location
*/
e->xBBox.x += xpoint.x - initPt->x;
e->xBBox.y += xpoint.y - initPt->y;
e->sizeBox.x += xpoint.x - initPt->x;
e->sizeBox.y += xpoint.y - initPt->y;
} /* end doMoveLoop() */
/*************************************************************
**
** FUNCTION: moveElement
**
** DESCRIPTION: Move an element in the picture
**
** PARAMETERS: xpt Initial mouse down point
** e Element being moved
**
** RETURN: None
**
*************************************************************/
void moveElement(xpt, e)
XPoint *xpt;
Element *e;
{
int x, y;
Display *dpy = XtDisplay(AppData.drawingArea);
Point pt;
/*
** Redraw original, without the moving element
*/
AppData.moveElement = e;
drawSelf(NULL);
/*
** Copy the original to the composite pixmap
*/
copyOrigToComposite();
/*
** Draw the moving object or box to the composite pixmap
*/
x = e->xBBox.x + AppData.originX;
y = e->xBBox.y - AppData.scaledHeight + AppData.originY;
if (!AppData.useBoxes && e->image != None) {
XSetClipOrigin(dpy, AppData.gc, x, y);
XSetClipMask(dpy, AppData.gc, e->mask);
XCopyArea(dpy, e->image, AppData.composite, AppData.gc,
0, 0, e->xBBox.width, e->xBBox.height, x, y);
XSetClipMask(dpy, AppData.gc, None);
} else {
XDPSSetContextGState(AppData.dpsCtxt, AppData.compGState);
PSWDrawBox(e->origBBox.ll.x, e->origBBox.ll.y,
e->origBBox.ur.x, e->origBBox.ur.y,
e->tx, e->ty, e->sx, e->sy, e->rotation);
DPSWaitContext(AppData.dpsCtxt);
}
/*
** Copy pixmap to window
*/
XCopyArea(dpy, AppData.composite,
XtWindow(AppData.drawingArea), AppData.gc,
x, y, e->xBBox.width, e->xBBox.height, x, y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, 0, 0, AppData.drawingWidth,
AppData.drawingHeight, 0, 0);
}
/*
** Handle mouse events during move
*/
doMoveLoop(xpt, e);
/*
** Compute new translation and redraw picture
*/
xpt->x = e->sizeBox.x + AppData.originX;
xpt->y = e->sizeBox.y - AppData.scaledHeight + AppData.originY;
convertToDPS(xpt, &pt);
e->tx = pt.x;
e->ty = pt.y;
AppData.moveElement = NULL;
drawSelfAndUpdate(e);
} /* end moveElement() */
/***************************************************************
**
** FUNCTION: doScale
**
** DESCRIPTION: Handle a mouse movement during rectangle scale
**
** PARAMETERS: initPt Where the mouse started
** curPt Where the mouse currently is
** first Whether this is the first time
** scrolled Whether we scrolled this time through
** e Element being scaled
**
** RETURN: rect Current scale rectangle
**
***************************************************************/
static void doScale(initPt, curPt, first, scrolled, rect, e)
XPoint *initPt, *curPt;
Boolean *first, scrolled;
XRect *rect;
Element *e;
{
static XRect oldBBox;
XRect copy, bounds;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
int origX, origY, height, width;
float r, theta;
/*
** Compute origin of scale
*/
origX = e->sizeBox.x + AppData.originX;
origY = e->sizeBox.y - AppData.scaledHeight + AppData.originY;
if (*first) {
oldBBox = e->xBBox;
initPt->x -= origX;
initPt->y -= origY;
/*
** Rotate the initial point by the element rotation to obtain
** the offsets perpendicular to the element axes
*/
if (e->rotation != 0.0) {
r = sqrt((float) (initPt->x * initPt->x + initPt->y * initPt->y));
if (initPt->x == 0 && initPt->y == 0) theta = DTOR(e->rotation);
else theta = atan2((float) initPt->y, (float) initPt->x) +
DTOR(e->rotation);
initPt->x = r * cos(theta);
initPt->y = r * sin(theta);
}
*first = False;
}
curPt->x -= origX;
curPt->y -= origY;
/*
** Rotate current point by the element rotation to obtain
** the offsets perpendicular to the element axes
*/
if (e->rotation != 0.0) {
r = sqrt((float) (curPt->x * curPt->x + curPt->y * curPt->y));
if (curPt->x == 0 && curPt->y == 0) theta = DTOR(e->rotation);
else theta = atan2((float) curPt->y, (float) curPt->x) +
DTOR(e->rotation);
curPt->x = r * cos(theta);
curPt->y = r * sin(theta);
}
/*
** Scale width and height. Make sure they're not 0
*/
if (initPt->x != 0) {
width = e->sizeBox.width * (float) curPt->x / (float) initPt->x;
} else width = e->sizeBox.width;
if (width == 0) width = 1;
if (initPt->y != 0) {
height = e->sizeBox.height * (float) curPt->y / (float) initPt->y;
} else height = e->sizeBox.height;
if (height == 0) height = -1;
/*
** Define rectangle for new size and find its bounds
*/
rect->x = origX;
rect->y = origY;
rect->width = width;
rect->height = height;
computeRotatedBounds(rect, e->rotation, rect->x, rect->y, &bounds);
/*
** Compute area that must be updated. If we scrolled, make it
** everything, but we still have to compute the bbox so we have
** an oldBBox for next time around
*/
computeMergeBBox(&bounds, &oldBBox, ©);
if (scrolled) {
copy.x = copy.y = 0;
copy.width = AppData.drawingWidth;
copy.height = AppData.drawingHeight;
}
/*
** Copy original into composite
*/
XCopyArea(dpy, AppData.original, AppData.composite, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
/*
** Draw the rotated box to the composite pixmap and copy to window
*/
drawRotatedRectangle(rect, e->rotation, rect->x, rect->y);
XCopyArea(dpy, AppData.composite, win, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, copy.x, copy.y, copy.width, copy.height,
copy.x, copy.y);
}
} /* end doScale() */
/***************************************************************
**
** FUNCTION: doScaleLoop
**
** DESCRIPTION: Event handling loop for scaling a rectangle
**
** PARAMETERS: initPt Initial mouse down point
** rect Current scale rectangle
** e Element being scaled
**
** RETURN: None
**
***************************************************************/
static void doScaleLoop(initPt, rect, e)
XPoint *initPt;
XRect *rect;
Element *e;
{
XEvent event;
XPoint xpoint, lastPt;
Boolean first = True;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
Boolean scrolled;
lastPt = *initPt;
do {
/*
** Wait for a motion or button release event
*/
getNextMouseEvent(dpy, win, &event);
/*
** See if user moved outside of window, and scroll drawing if so
*/
scrolled = checkScrolling(event.xbutton.x, event.xbutton.y, initPt);
/*
** Store new coordinates in xpoint
*/
xpoint.x = event.xbutton.x;
xpoint.y = event.xbutton.y;
/*
** If the mouse moved, update
*/
if (xpoint.x - lastPt.x || xpoint.y - lastPt.y) {
doScale(initPt, &xpoint, &first, scrolled, rect, e);
}
lastPt = xpoint;
} while (event.type != ButtonRelease);
} /* end doScaleLoop() */
/*************************************************************
**
** FUNCTION: scaleElement
**
** DESCRIPTION: Scale an element in the picture
**
** PARAMETERS: xpt Initial mouse down point
** e Element being moved
**
** RETURN: None
**
*************************************************************/
void scaleElement(xpt, e)
XPoint *xpt;
Element *e;
{
Display *dpy = XtDisplay(AppData.drawingArea);
XRect rect, copy;
/*
** Copy the original to the composite pixmap
*/
copyOrigToComposite();
/*
** Compute the original rectangle and bounding box
*/
rect = e->sizeBox;
rect.x += AppData.originX;
rect.y -= AppData.scaledHeight - AppData.originY;
copy = e->xBBox;
copy.x += AppData.originX;
copy.y -= AppData.scaledHeight - AppData.originY;
/*
** Draw the bounding box to the composite pixmap and copy to window
*/
drawRotatedRectangle(&rect, e->rotation, rect.x, rect.y);
XCopyArea(dpy, AppData.composite,
XtWindow(AppData.drawingArea), AppData.gc,
copy.x, copy.y, copy.width+1, copy.height+1,
copy.x, copy.y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, 0, 0, AppData.drawingWidth,
AppData.drawingHeight, 0, 0);
}
/*
** Handle mouse events during scale
*/
doScaleLoop(xpt, &rect, e);
/*
** Update scale factors and redraw the picture
*/
e->sx *= ((float) rect.width / (float) e->sizeBox.width);
e->sy *= ((float) rect.height / (float) e->sizeBox.height);
updateElement(e);
drawSelfAndUpdate(NULL);
XDefineCursor(XtDisplay(AppData.drawingArea),
XtWindow(AppData.drawingArea), None);
} /* end scaleElement() */
/***************************************************************
**
** FUNCTION: doRotate
**
** DESCRIPTION: Handle a mouse movement during rectangle rotate
**
** PARAMETERS: initPt Where the mouse started
** curPt Where the mouse currently is
** first Whether this is the first time
** scrolled Whether we scrolled this time through
** e Element being scaled
**
** RETURN: rot Rotation
**
***************************************************************/
static void doRotate(initPt, curPt, first, scrolled, rot, e)
XPoint *initPt, *curPt;
Boolean *first, scrolled;
float *rot;
Element *e;
{
static XRect oldBBox;
XRect copy;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
static float theta1;
float theta2;
XRect rect, bounds;
/*
** Define the rectangle we'll be rotating
*/
rect = e->sizeBox;
rect.x += AppData.originX;
rect.y -= AppData.scaledHeight - AppData.originY;
/*
** If first time, compute original bounding box and find rotation
** of original point from the horizontal
*/
if (*first) {
oldBBox = e->xBBox;
oldBBox.x += AppData.originX;
oldBBox.y -= AppData.scaledHeight - AppData.originY;
if (initPt->x == rect.x && initPt->y == rect.y) initPt->x++;
theta1 = atan2((float) (initPt->y - rect.y),
(float) (initPt->x - rect.x));
*first = False;
}
/*
** Compute the rotation of the current point from the horizontal and
** subtract the initial point rotation to find the real rotation
*/
if (curPt->x == rect.x && curPt->y == rect.y) {
*rot = 0;
} else {
theta2 = atan2((float) (curPt->y - rect.y),
(float) curPt->x - rect.x);
*rot = RTOD(theta1 - theta2);
}
computeRotatedBounds(&rect, e->rotation + *rot, rect.x, rect.y, &bounds);
/*
** Compute area that must be updated. If we scrolled, make it
** everything, but we still have to compute the bbox so we have
** an oldBBox for next time around
*/
computeMergeBBox(&bounds, &oldBBox, ©);
if (scrolled) {
copy.x = copy.y = 0;
copy.width = AppData.drawingWidth;
copy.height = AppData.drawingHeight;
}
/*
** Copy original into composite
*/
XCopyArea(dpy, AppData.original, AppData.composite, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
/*
** Draw the new box to the composite pixmap and copy to window
*/
drawRotatedRectangle(&rect, e->rotation + *rot, rect.x, rect.y);
XCopyArea(dpy, AppData.composite, win, AppData.gc,
copy.x, copy.y, copy.width, copy.height, copy.x, copy.y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, copy.x, copy.y, copy.width, copy.height,
copy.x, copy.y);
}
} /* end doRotate() */
/***************************************************************
**
** FUNCTION: doRotateLoop
**
** DESCRIPTION: Event handling loop for rotating a rectangle
**
** PARAMETERS: initPt Initial mouse down point
** e Element being scaled
**
** RETURN: rot Rotation
**
***************************************************************/
static void doRotateLoop(initPt, rot, e)
XPoint *initPt;
float *rot;
Element *e;
{
XEvent event;
XPoint xpoint, lastPt;
Boolean first = True;
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
Boolean scrolled;
lastPt = *initPt;
do {
/*
** Wait for a motion or button release event
*/
getNextMouseEvent(dpy, win, &event);
/*
** See if user moved outside of window, and scroll drawing if so
*/
scrolled = checkScrolling(event.xbutton.x, event.xbutton.y, initPt);
/*
** Store new coordinates in xpoint
*/
xpoint.x = event.xbutton.x;
xpoint.y = event.xbutton.y;
/*
** If the mouse moved, update
*/
if (xpoint.x - lastPt.x || xpoint.y - lastPt.y) {
doRotate(initPt, &xpoint, &first, scrolled, rot, e);
}
lastPt = xpoint;
} while (event.type != ButtonRelease);
} /* end doRotateLoop() */
/*************************************************************
**
** FUNCTION: rotateElement
**
** DESCRIPTION: Rotate an element in the picture
**
** PARAMETERS: xpt Initial mouse down point
** e Element being moved
**
** RETURN: None
**
*************************************************************/
void rotateElement(xpt, e)
XPoint *xpt;
Element *e;
{
Display *dpy = XtDisplay(AppData.drawingArea);
float rot;
XRect rect, copy;
/*
** Copy the original to the composite pixmap
*/
copyOrigToComposite();
/*
** Compute original rectangle and bounding box
*/
rect = e->sizeBox;
rect.x += AppData.originX;
rect.y -= AppData.scaledHeight - AppData.originY;
copy = e->xBBox;
copy.x += AppData.originX;
copy.y -= AppData.scaledHeight - AppData.originY;
/*
** Draw the bounding box to the composite pixmap and copy to window
*/
drawRotatedRectangle(&rect, e->rotation, rect.x, rect.y);
XCopyArea(dpy, AppData.composite,
XtWindow(AppData.drawingArea), AppData.gc,
copy.x, copy.y, copy.width+1, copy.height+1,
copy.x, copy.y);
if (AppData.showBuffer) {
XCopyArea(dpy, AppData.composite, XtWindow(AppData.bufComp),
AppData.gc, 0, 0, AppData.drawingWidth,
AppData.drawingHeight, 0, 0);
}
/*
** Handle mouse events during rotate
*/
doRotateLoop(xpt, &rot, e);
/*
** Update rotation and redraw the picture
*/
e->rotation += rot;
updateElement(e);
drawSelfAndUpdate(NULL);
XDefineCursor(XtDisplay(AppData.drawingArea),
XtWindow(AppData.drawingArea), None);
} /* end rotateElement() */
/***************************************************************
**
** FUNCTION: initBuffers
**
** DESCRIPTION: Creates the buffers and the gstates that refer to them
**
** PARAMETERS: None
**
** RETURN: None
**
***************************************************************/
static void initBuffers()
{
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
int depth;
XtVaGetValues(AppData.drawingArea, XtNdepth, &depth, NULL);
/*
** Create pixmap buffers
*/
AppData.original = XCreatePixmap(dpy, win,
AppData.drawingWidth, AppData.drawingHeight, depth);
AppData.composite = XCreatePixmap(dpy, win,
AppData.drawingWidth, AppData.drawingHeight, depth);
/*
** Clear pixmaps
*/
XFillRectangle(dpy, AppData.original, AppData.gc, 0, 0,
AppData.drawingWidth, AppData.drawingHeight);
XFillRectangle(dpy, AppData.composite, AppData.gc, 0, 0,
AppData.drawingWidth, AppData.drawingHeight);
/*
** Create gstates
*/
(void) XDPSSetContextDrawable(AppData.dpsCtxt,
AppData.original, AppData.drawingHeight);
(void) XDPSCaptureContextGState(AppData.dpsCtxt, &AppData.origGState);
(void) XDPSSetContextDrawable(AppData.dpsCtxt,
AppData.composite, AppData.drawingHeight);
(void) XDPSCaptureContextGState(AppData.dpsCtxt, &AppData.compGState);
} /* end initBuffers() */
/***************************************************************
**
** FUNCTION: initDPSContext
**
** DESCRIPTION: Handle post-Realize initialization:
**
** PARAMETERS: None
**
** RETURN: None
**
***************************************************************/
void initDPSContext()
{
Display *dpy = XtDisplay(AppData.drawingArea);
XPoint xpt1, xpt2;
Point pt;
int i;
/*
** Get height and width of drawing window
*/
XtVaGetValues(AppData.drawingArea, XtNheight, &AppData.drawingHeight,
XtNwidth, &AppData.drawingWidth, NULL);
/*
** Create the DPSContext in which rendering will occur
*/
AppData.dpsCtxt = XDPSGetSharedContext(dpy);
(void) XDPSSetEventDelivery(dpy, dps_event_pass_through);
if (AppData.dpsCtxt == NULL) {
printf("Couldn't create a Display PostScript context.\n");
exit(1);
}
if (XDPSSetContextDrawable(AppData.dpsCtxt, XtWindow(AppData.drawingArea),
AppData.drawingHeight) != dps_status_success) {
printf ("Couldn't set Display PostScript context drawable.\n");
exit (1);
}
XDPSChainTextContext (AppData.dpsCtxt, AppData.trace);
/*
** Set the default DPSContext
*/
DPSSetContext(AppData.dpsCtxt);
/*
** Create context for EPS imaging
*/
AppData.imageCtxt =
XDPSCreateSimpleContext(XtDisplay(AppData.drawingArea),
None, None, 0, 0, DPSDefaultTextBackstop,
DPSDefaultErrorProc, NULL);
if (AppData.imageCtxt == NULL) {
printf("Couldn't create Display PostScript imaging context.\n");
exit(1);
}
XDPSRegisterContext(AppData.imageCtxt, False);
XDPSChainTextContext (AppData.imageCtxt, AppData.trace);
PSWDefineExecFunction(AppData.imageCtxt);
/*
** Create the control point font
*/
PSWDefineFont(FontName);
PSselectfont(FontName, CtlPtSize);
(void) XDPSCaptureContextGState(AppData.dpsCtxt, &AppData.winGState);
/*
** Initialize the buffers -- must be last initialization;
** leaves the right gstate
*/
initBuffers();
/*
** Get the transformation matrices
*/
PSWGetTransform(AppData.ctm, AppData.invctm,
&AppData.xOffset, &AppData.yOffset);
for (i = 0; i < 6; i++) AppData.origInvctm[i] = AppData.invctm[i];
/*
** Compute how large a page would be needed to draw the whole thing
*/
pt.x = 0;
pt.y = 0;
convertToX(&xpt1, &pt);
pt.x = PAGE_WIDTH;
pt.y = PAGE_HEIGHT;
convertToX(&xpt2, &pt);
AppData.scaledWidth = xpt2.x - xpt1.x;
AppData.scaledHeight = xpt1.y - xpt2.y;
/*
** Position the drawing area so the center is in the center of the window
*/
positionDrawingArea(PAGE_WIDTH / 2, PAGE_HEIGHT / 2,
AppData.drawingWidth / 2, AppData.drawingHeight / 2);
} /* end initDPSContext() */
/***************************************************************
**
** FUNCTION: convertToX
**
** DESCRIPTION: Convert user space to X coordinates.
**
** PARAMETERS: pXPt points to the target XPoint struct;
** pUPt points to the target Point struct;
**
** RETURN: None
**
***************************************************************/
void convertToX (pXPt, pUPt)
XPoint *pXPt;
Point *pUPt;
{
pXPt->x = AppData.ctm[A_COEFF] * pUPt->x + AppData.ctm[C_COEFF] * pUPt->y +
AppData.ctm[TX_CONS] + AppData.xOffset;
pXPt->y = AppData.ctm[B_COEFF] * pUPt->x + AppData.ctm[D_COEFF] * pUPt->y +
AppData.ctm[TY_CONS] + AppData.yOffset;
} /* end convertToX() */
/***************************************************************
**
** FUNCTION: convertToDPS
**
** DESCRIPTION: Convert X coordinates to user space
**
** PARAMETERS: pXPt points to the target XPoint struct;
** pUPt points to the target Point struct;
**
** RETURN: None
**
***************************************************************/
void convertToDPS(pXPt, pUPt)
XPoint *pXPt;
Point *pUPt;
{
int ix, iy;
ix = pXPt->x - AppData.xOffset;
iy = pXPt->y - AppData.yOffset;
pUPt->x = AppData.invctm[A_COEFF] * ix + AppData.invctm[C_COEFF] * iy +
AppData.invctm[TX_CONS];
pUPt->y = AppData.invctm[B_COEFF] * ix + AppData.invctm[D_COEFF] * iy +
AppData.invctm[TY_CONS];
} /* end convertToDPS() */
/***************************************************************
**
** FUNCTION: convertToOrigDPS
**
** DESCRIPTION: Convert X coordinates to user space using the original
** transformation matrix
**
** PARAMETERS: pXPt points to the target XPoint struct;
** pUPt points to the target Point struct;
**
** RETURN: None
**
***************************************************************/
void convertToOrigDPS(pXPt, pUPt)
XPoint *pXPt;
Point *pUPt;
{
int ix, iy;
ix = pXPt->x - AppData.xOffset;
iy = pXPt->y - AppData.yOffset;
pUPt->x = AppData.origInvctm[A_COEFF] * ix +
AppData.origInvctm[C_COEFF] * iy + AppData.origInvctm[TX_CONS];
pUPt->y = AppData.origInvctm[B_COEFF] * ix +
AppData.origInvctm[D_COEFF] * iy + AppData.origInvctm[TY_CONS];
} /* end convertToOrigDPS() */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.