This is ControlXDPS.c in view mode; [Download] [Up]
/* * $RCSfile: ControlXDPS.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 */ /*************************************************************** ** ** INCLUDE FILES ** ***************************************************************/ #include "Control.h" #include "ControlWraps.h" /*************************************************************** ** ** DATA DECLARATIONS ** ***************************************************************/ /* ** Font name for drawing with show and xyshow operators */ static char fontname[] = "ControlPointsFont"; /* ** The first entry in each of these arrays is the size */ /* ** Points and operators for drawing filled rectangles ** using large user paths and cached user paths */ static float ptsRectFill[] = {8, -2, -2, 0, 4, 4, 0, 0, -4}; static DPSUserPathOp opsRectFill[] = {5, dps_rmoveto, dps_rlineto, dps_rlineto, dps_rlineto, dps_closepath}; /* ** Points and operators for drawing open rectangles ** using large user paths and cached user paths */ static float ptsRectOpen[] = {8, -2, -2, 0, 4, 4, 0, 0, -4}; static DPSUserPathOp opsRectOpen[] = {5, dps_rmoveto, dps_rlineto, dps_rlineto, dps_rlineto, dps_closepath}; /* ** Points and operators for drawing X's ** using large user paths and cached user paths */ static float ptsX[] = {8, -2, -2, 4, 4, 0, -4, -4, 4}; static DPSUserPathOp opsX[] = {4, dps_rmoveto, dps_rlineto, dps_rmoveto, dps_rlineto}; /* ** Points and operators for drawing crosses ** using large user paths and cached user paths */ static float ptsCross[] = {8, 0, 2, 0, -4, -2, 2, 4, 0}; static DPSUserPathOp opsCross[] = {4, dps_rmoveto, dps_rlineto, dps_rmoveto, dps_rlineto}; /* ** Array of XY coordinate points at which all control points ** are drawn */ static float XYPoints [MAX_ARRAY]; /* ** Arrays to store points and operators for drawing ** using large user paths, cached user paths, and XYSHOW */ static DPSUserPathOp OpsBuffer [MAX_UPATHOPS]; static char ShowBuffer [MAX_UPATHOPS]; static float XYBuffer [MAX_UPATHPTS]; static float BBox [4]; /* ** The size we will use; */ static float figureSize = FIGURESIZE; /* ** Variables for transformation between DPS/X and ** X Window System coordinates */ static float Ctm[6], Invctm[6]; /* transformation matrices */ static int XOffset, YOffset; /* coordinate system offsets */ /*************************************************************** ** ** FUNCTION: erasePage ** ** DESCRIPTION: Erase the current DPS drawing page. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void erasePage () { /* ** Erase the DPS context page */ PSerasepage (); } /* end erasePage () */ /*************************************************************** ** ** FUNCTION: initArray ** ** DESCRIPTION: Builds the arrays of points to be drawn. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void initArray() { int i; /* ** initialize the random number generator */ srandom (time((long )NULL)); /* ** Fill the array of XY coordinate points with random values ** adjusted to fit within the window boundaries */ for (i = 0; i < 2 * MAX_POINTS; i += 2) { XYPoints[i] = (float) ((long) random() % (((long) (AppData.width - figureSize)) * 100) + figureSize / 2 * 100) * 0.01; XYPoints[i + 1] = (float) ((long) random() % (((long) (AppData.height - figureSize)) * 100) + figureSize / 2 * 100) * 0.01; } /* ** Initialize one extra XY coordinate for the relative ** computations done in cached user paths */ XYPoints[i] = 0; XYPoints[i+1] = 0; /* ** Initialize index and number of points */ AppData.index = 0; AppData.numPoints = 5; setRectFill(); } /* end initArray () */ /*************************************************************** ** ** FUNCTION: setRectFill ** ** DESCRIPTION: Set the control parameters for a filled rectangle. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void setRectFill () { AppData.fontchar = 'a'; AppData.basicProc = "BRF"; AppData.userPtsArray = ptsRectFill; AppData.userOpsArray = opsRectFill; AppData.userOp = dps_ufill; AppData.rectOp = "rectfill"; } /* end setRectFill () */ /*************************************************************** ** ** FUNCTION: setRectOpen ** ** DESCRIPTION: Set the control parameters for an open rectangle. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void setRectOpen () { AppData.fontchar = 'b'; AppData.basicProc = "BRS"; AppData.userPtsArray = ptsRectOpen; AppData.userOpsArray = opsRectOpen; AppData.userOp = dps_ustroke; AppData.rectOp = "rectstroke"; } /* end setRectOpen () */ /*************************************************************** ** ** FUNCTION: setX ** ** DESCRIPTION: Set the control parameters for an 'X'. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void setX () { AppData.fontchar = 'c'; AppData.basicProc = "BX"; AppData.userPtsArray = ptsX; AppData.userOpsArray = opsX; AppData.userOp = dps_ustroke; AppData.rectOp = "pop"; } /* end setX () */ /*************************************************************** ** ** FUNCTION: setCross ** ** DESCRIPTION: Set the control parameters for a cross ('+'). ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void setCross () { AppData.fontchar = 'd'; AppData.basicProc = "BC"; AppData.userPtsArray = ptsCross; AppData.userOpsArray = opsCross; AppData.userOp = dps_ustroke; AppData.rectOp = "pop"; } /* end setCross () */ /*************************************************************** ** ** FUNCTION: adjust ** ** DESCRIPTION: Adjusts X and Y to be in the center of a pixel in ** device space ** ** PARAMETERS: X pointer to x value ** Y pointer to y value ** ** RETURN: None. ** ***************************************************************/ static void adjust(X, Y) register float *X, *Y; { float x, y; /* Convert to device space */ x = floor(Ctm[A_COEFF] * *X + Ctm[C_COEFF] * *Y + Ctm[TX_CONS]); y = floor(Ctm[B_COEFF] * *X + Ctm[D_COEFF] * *Y + Ctm[TY_CONS]); /* Stroke adjust */ x += 0.5; y += 0.5; /* Convert back */ *X = Invctm[A_COEFF] * x + Invctm[C_COEFF] * y + Invctm[TX_CONS]; *Y = Invctm[B_COEFF] * x + Invctm[D_COEFF] * y +Invctm[TY_CONS]; } /* end adjust () */ /*************************************************************** ** ** FUNCTION: adjustFigureSize ** ** DESCRIPTION: Adjusts figure size so that points do not fall ** directly on pixel boundaries. This avoids round-off ** error ** ** PARAMETERS: None ** ** RETURN: None. ** ***************************************************************/ static void adjustFigureSize() { int intX, intY; double floatX, floatY; float x, y; /* ** Convert (0.5, 0.5) into user space */ x = Invctm[A_COEFF] * .5 + Invctm[C_COEFF] * .5 + Invctm[TX_CONS]; y = Invctm[B_COEFF] * .5 + Invctm[D_COEFF] * .5 + Invctm[TY_CONS]; /* ** Move to a corner */ x -= figureSize/2; y -= figureSize/2; /* ** Convert to device space */ floatX = Ctm[A_COEFF] * x + Ctm[C_COEFF] * y + Ctm[TX_CONS]; floatY = Ctm[B_COEFF] * x + Ctm[D_COEFF] * y + Ctm[TY_CONS]; /* ** Round to nearest integer */ intX = floor(floatX + 0.5); intY = floor(floatY + 0.5); /* ** If we are too close to a pixel boundary, make figure larger and ** adjust coordinates in user path descriptions. */ if (ABS(floatX - (double) intX) < 0.0005 || ABS(floatY - (double) intY) < 0.0005) { figureSize += 0.001; ptsRectFill[4] = ptsRectFill[5] = figureSize; ptsRectFill[8] = -figureSize; ptsRectFill[1] = ptsRectFill[2] = -figureSize/2; ptsRectOpen[4] = ptsRectOpen[5] = figureSize; ptsRectOpen[8] = -figureSize; ptsRectOpen[1] = ptsRectOpen[2] = -figureSize/2; ptsX[3] = ptsX[4] = ptsX[8] = figureSize; ptsX[6] = ptsX[7] = -figureSize; ptsX[1] = ptsX[2] = -figureSize/2; ptsCross[7] = figureSize; ptsCross[4] = -figureSize; ptsCross[2] = ptsCross[6] = figureSize/2; ptsCross[5] = -figureSize/2; } } /*************************************************************** ** ** FUNCTION: drawBasic ** ** DESCRIPTION: Draw the control points using basic drawing. ** Each point is rendered with a separate wrap call. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawBasic () { int i; float x, y; for (i = AppData.index; i < AppData.index + (AppData.numPoints * 2); i += 2) { /* ** Render the control point using basic drawing */ x = XYPoints[i]; y = XYPoints[i + 1]; if (AppData.devIndependent) adjust(&x, &y); PSWBasic(x, y, AppData.basicProc); } } /* end drawBasic () */ /*************************************************************** ** ** FUNCTION: drawUserCache ** ** DESCRIPTION: Draw the control points using cached user paths. ** The user path for the control point is cached. ** Each point is rendered with a separate wrap call. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawUserCache () { int i, i_op = 0, i_pt; /* ** Set the initial operator to cache the user path */ OpsBuffer[i_op++] = dps_ucache; /* ** Set up the bounding box points */ BBox[0] = -figureSize/2; BBox[1] = -figureSize/2; BBox[2] = figureSize/2; BBox[3] = figureSize/2; /* ** Start the user path out at the origin */ XYBuffer[0] = 0; XYBuffer[1] = 0; OpsBuffer[i_op++] = dps_moveto; if (AppData.devIndependent) adjust(XYBuffer, XYBuffer+1); /* ** Copy the user path points for rendering the control point ** into the XY coordinate point array */ i_pt = 2; for (i = 1; i <= AppData.userPtsArray[0]; i++) XYBuffer[i_pt++] = AppData.userPtsArray[i]; /* ** Copy the operators for rendering the control point into ** the operator array */ for (i = 1; i <= AppData.userOpsArray[0]; i++) OpsBuffer[i_op++] = AppData.userOpsArray[i]; /* ** Save the graphics state for the translations that follow */ PSgsave(); /* ** Translate the user space to the first point ** (relative to the origin) */ PStranslate(XYPoints[AppData.index], XYPoints[AppData.index + 1]); for (i = AppData.index; i < AppData.index + (AppData.numPoints * 2); i += 2) { /* ** Render the control point using the cached user path */ PSDoUserPath((DPSPointer) XYBuffer, i_pt, dps_float, OpsBuffer, i_op, (DPSPointer) BBox, AppData.userOp); /* ** Translate the user space to the next point ** (relative to the previous point) */ PStranslate(XYPoints[i + 2] - XYPoints[i], XYPoints[i + 3] - XYPoints[i + 1]); } /* ** Restore the graphics state */ PSgrestore(); } /* end drawUserCache () */ /*************************************************************** ** ** FUNCTION: drawUserPath ** ** DESCRIPTION: Draw the control points using large user paths. ** Each point, DPS operator, and user path is added ** to an XY coordinate array and an operator array. ** The points are rendered in groups based on the ** array limits. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawUserPath () { int i, i_op, i_pt, j; /* ** Set up the bounding box points */ BBox[0] = 0; BBox[1] = 0; BBox[2] = AppData.width; BBox[3] = AppData.height; i = 0; i_pt = 0; i_op = 0; while (i < AppData.numPoints * 2) { /* ** Send the array to the server if the array limit has ** been reached */ if ((i_pt + AppData.userPtsArray[0] > MAX_UPATHPTS) || (i_op + (int) AppData.userOpsArray[0] > MAX_UPATHOPS)) { /* ** Render the control points using the large user path */ PSDoUserPath((DPSPointer) XYBuffer, i_pt, dps_float, OpsBuffer, i_op, (DPSPointer) BBox, AppData.userOp); i_pt = 0; i_op = 0; } /* ** Set the next XY coordinate point and operator */ XYBuffer[i_pt++] = XYPoints[AppData.index + i++]; XYBuffer[i_pt++] = XYPoints[AppData.index + i++]; if (AppData.devIndependent) adjust (XYBuffer+i_pt-2, XYBuffer+i_pt-1); OpsBuffer[i_op++] = dps_moveto; /* ** Copy the user path points for rendering the control point ** into the XY coordinate point array */ for ( j = 1; j <= AppData.userPtsArray[0]; j++, i_pt++) XYBuffer[i_pt] = AppData.userPtsArray[j]; /* ** Copy the operators for rendering the control point into ** the operator array */ for ( j = 1; j <= (int) AppData.userOpsArray[0]; j++, i_op++) OpsBuffer[i_op] = AppData.userOpsArray[j]; } /* ** Render the last control point using the large user path */ PSDoUserPath((DPSPointer) XYBuffer, i_pt, dps_float, OpsBuffer, i_op, (DPSPointer) BBox, AppData.userOp); } /* end drawUserPath () */ /*************************************************************** ** ** FUNCTION: drawRectOp ** ** DESCRIPTION: Draw the control points using rect operators. ** Each point is added to an array of rectangular ** parameters. The points are rendered in groups ** based on the array limit. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawRectOp () { int i, j; for (i = AppData.index, j = 0; i < AppData.index + (AppData.numPoints * 2); i += 2, j += 4) { /* ** Draw the rectangles if the array limit has been reached */ if (j + 3 > MAX_RECTPTS) { /* ** Render the control points using the rect operators */ PSWRectDraw(XYBuffer, j, AppData.rectOp); j = 0; } /* ** Set up XY coordinate points and size of the next ** rectangle to be drawn */ XYBuffer[j] = XYPoints[i]; XYBuffer[j + 1] = XYPoints[i + 1]; if (AppData.devIndependent) adjust (XYBuffer+j, XYBuffer+j+1); XYBuffer[j] -= figureSize/2; XYBuffer[j + 1] -= figureSize/2; XYBuffer[j + 2] = figureSize; XYBuffer[j + 3] = figureSize; } /* ** Render the last control points using the rect operators */ PSWRectDraw(XYBuffer, j, AppData.rectOp); } /* end drawRectOp () */ /*************************************************************** ** ** FUNCTION: drawImage ** ** DESCRIPTION: Draw the control points for the composite ** drawing approach. The control point is rendered ** once to a bit-clearing pixmap and a second time to a ** bit-setting pixmap. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawImage () { float x, y, x1, y1; int status; Display *dpy = XtDisplay(AppData.drawingArea); DPSPointer pushCookie; XFillRectangle(dpy, AppData.bitClearPixmap, AppData.bitClearGC, 0, 0, AppData.pixmapWidth, AppData.pixmapHeight); XFillRectangle(dpy, AppData.bitSetPixmap, AppData.bitSetGC, 0, 0, AppData.pixmapWidth, AppData.pixmapHeight); /* Convert the center of the pixmap into a coordinate */ x1 = ((float) AppData.pixmapWidth) / 2; y1 = -((float) AppData.pixmapHeight) / 2; x = Invctm[A_COEFF] * x1 + Invctm[C_COEFF] * y1 + Invctm[TX_CONS]; y = Invctm[B_COEFF] * x1 + Invctm[D_COEFF] * y1 + Invctm[TY_CONS]; if (AppData.devIndependent) adjust(&x, &y); status = XDPSPushContextGState(AppData.dpsCtxt, AppData.bitSetGState, &pushCookie); PSWBasic(x, y, AppData.basicProc); status = XDPSSetContextGState(AppData.dpsCtxt, AppData.bitClearGState); PSWBasic(x, y, AppData.basicProc); XDPSPopContextGState(pushCookie); } /* end drawImage () */ /*************************************************************** ** ** FUNCTION: drawPixmaps ** ** DESCRIPTION: Draw the control points using the composite ** drawing approach. The control point is rendered ** once to a bit-clearing pixmap and a second time to a ** bit-setting pixmap. The clearing pixmap is ** logically ANDed and the setting pixmap ** is logically ORed to the display window. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawPixmaps () { float ux, uy; int x, y; int i; Display *dpy = XtDisplay(AppData.drawingArea); /* ** Render the control point to the bit-clearing and -setting pixmaps. */ drawImage(); /* ** Wait to make sure the DPS image rendering has completed ** before any Xlib calls using the images */ DPSWaitContext(AppData.dpsCtxt); for (i = AppData.index; i < AppData.index + (AppData.numPoints * 2); i += 2) { /* ** Convert the DPS user space XY coordinates to X Window ** System XY coordinates */ ux = XYPoints [i]; uy = XYPoints [i + 1]; x = Ctm[A_COEFF] * ux + Ctm[C_COEFF] * uy + Ctm[TX_CONS] + XOffset - AppData.pixmapWidth/2; y = Ctm[B_COEFF] * ux + Ctm[D_COEFF] * uy + Ctm[TY_CONS] + YOffset - AppData.pixmapHeight/2; /* ** AND the bit-clearing pixmap into the display window */ XCopyArea (dpy, AppData.bitClearPixmap, XtWindow (AppData.drawingArea), AppData.andGC, (int) 0, (int) 0, AppData.pixmapWidth, AppData.pixmapHeight, x, y); /* ** OR the bit-setting pixmap into the display window */ XCopyArea (dpy, AppData.bitSetPixmap, XtWindow (AppData.drawingArea), AppData.orGC, (int) 0, (int) 0, AppData.pixmapWidth, AppData.pixmapHeight, x, y); } } /* end drawPixmaps () */ /*************************************************************** ** ** FUNCTION: drawShow ** ** DESCRIPTION: Draw the control points using the show operator. ** Each point is rendered with a separate wrap call. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawShow () { char fontchar[2]; int i; /* ** Set up the control point as a single character string */ fontchar[0] = AppData.fontchar; fontchar[1] = 0; /* ** Select and scale the font */ PSselectfont(fontname, figureSize); for (i = AppData.index; i < AppData.index + (AppData.numPoints * 2); i += 2) { /* ** Render the control point using the show operator */ PSWShow(XYPoints[i], XYPoints[i+1], fontchar); } } /* end drawShow () */ /*************************************************************** ** ** FUNCTION: drawXYShow ** ** DESCRIPTION: Draw the control points using the xyshow operator. ** Each point is added to an array of XY coordinate ** points. The points are all rendered with one wrap ** call. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void drawXYShow () { int i, j; /* ** Set up the control points as a repeated character string */ for (i = 0; i < AppData.numPoints; i++) ShowBuffer[i] = AppData.fontchar; ShowBuffer[i] = 0; /* ** Select and scale the font */ PSselectfont(fontname, figureSize); for (i = AppData.index + 2, j = 0; i < AppData.index + (AppData.numPoints * 2); i++, j++) { /* ** Calculate the points as delta values from the ** previous point */ XYBuffer[j] = XYPoints[i] - XYPoints[i - 2]; } XYBuffer[j++] = 0; XYBuffer[j++] = 0; /* ** Render the control points using the xyshow operator */ PSWXYShow(XYPoints[AppData.index], XYPoints[AppData.index + 1], ShowBuffer, XYBuffer, j); } /* end drawXYShow () */ /*************************************************************** ** ** FUNCTION: initPixmaps ** ** DESCRIPTION: Create bit-clearing and -setting pixmaps and GCs for the ** control point. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ void initPixmaps() { XGCValues xgc; float ux, uy; int status; int depth; Display *dpy = XtDisplay(AppData.drawingArea); /* ** Compute width and height for the composite control points ** (in pixels). Add one for the line width. */ ux = figureSize+1; uy = AppData.height - figureSize - 1; AppData.pixmapWidth = ceil(Ctm[A_COEFF] * ux + Ctm[C_COEFF] * uy + Ctm[TX_CONS] + XOffset) + 1; AppData.pixmapHeight = ceil(Ctm[B_COEFF] * ux + Ctm[D_COEFF] * uy + Ctm[TY_CONS] + YOffset) + 1; XtVaGetValues(AppData.drawingArea, XtNdepth, &depth, NULL); /* ** Create two pixmaps into which the composite control point ** will be drawn. The first is for bit-clearing; the second is ** for bit-setting */ AppData.bitClearPixmap = XCreatePixmap (dpy, XtWindow (AppData.drawingArea), AppData.pixmapWidth, AppData.pixmapHeight, depth); AppData.bitSetPixmap = XCreatePixmap (dpy, XtWindow (AppData.drawingArea), AppData.pixmapWidth, AppData.pixmapHeight, depth); /* ** Create the GC for the bit-clearing pixmap with the foreground and ** background pixel values defined to be all bits on */ xgc.foreground = ~0; xgc.background = ~0; AppData.bitClearGC = XCreateGC (dpy, AppData.bitClearPixmap, GCForeground | GCBackground, &xgc); /* ** Create the GC for the bit-setting pixmap with the ** foreground and background pixel values defined to be all ** bits off */ xgc.foreground = 0; xgc.background = 0; AppData.bitSetGC = XCreateGC (dpy, AppData.bitSetPixmap, GCForeground | GCBackground, &xgc); /* ** Create the ANDing and ORing GCs */ xgc.function = GXand; AppData.andGC = XCreateGC (dpy, AppData.bitClearPixmap, GCFunction, &xgc); xgc.function = GXor; AppData.orGC = XCreateGC (dpy, AppData.bitSetPixmap, GCFunction, &xgc); /* ** Set the DPS context window to the bit-clearing pixmap */ PSgsave(); status = XDPSSetContextDrawable(AppData.dpsCtxt, AppData.bitClearPixmap, AppData.pixmapHeight); status = XDPSCaptureContextGState(AppData.dpsCtxt, &AppData.bitSetGState); /* ** Set the DPS context window to the bit-setting pixmap */ status = XDPSSetContextDrawable(AppData.dpsCtxt, AppData.bitSetPixmap, AppData.pixmapHeight); status = XDPSCaptureContextGState(AppData.dpsCtxt, &AppData.bitClearGState); /* ** Reset the DPS context window to the display window */ PSgrestore(); } /* end initPixmaps () */ /*************************************************************** ** ** FUNCTION: initDPSContext ** ** DESCRIPTION: Post-Realization initialization of DPSContext and such. ** ** PARAMETERS: shell Application shell for program ** ** RETURN: None. ** ***************************************************************/ void initDPSContext (shell) Widget shell; { Display *dpy = XtDisplay(shell); Dimension height; Dimension width; int x, y; /* ** Get height and width of drawing window */ XtVaGetValues(AppData.drawingArea, XtNheight, &height, XtNwidth, &width, 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), height) != 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); /* ** Compute the DPS user space height and width of the window */ PSWGetTransform(Ctm, Invctm, &XOffset, &YOffset); x = (int) width; y = 0; x -= XOffset; y -= YOffset; AppData.width = Invctm[A_COEFF] * x + Invctm[C_COEFF] * y + Invctm[TX_CONS]; AppData.height= Invctm[B_COEFF] * x + Invctm[D_COEFF] * y + Invctm[TY_CONS]; /* ** Adjust figure size to avoid having points fall into "pixel cracks" */ adjustFigureSize(); /* ** Set up PSW definitions */ PSWDefineControlPoints (figureSize); PSWDefineFont (fontname); initArray (); /* ** Create bit-clearing and -setting pixmaps */ initPixmaps (); } /* end initDPSContext () */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.