Introduce fermi-ware code

Adding fermi-ware code.

refs #1
This commit is contained in:
Alex Lin 2016-06-08 13:01:29 -05:00
parent 0f7a396db1
commit 577c0bbf0e
13 changed files with 7813 additions and 1 deletions

View File

@ -1 +0,0 @@
fermi-ware

View File

@ -0,0 +1,2 @@
object_*

View File

@ -0,0 +1,4 @@
# fermi-ware
Fermi-ware plot widgets for use with Trick
Trick is on GitHub: https://github.com/nasa/trick

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
/*******************************************************************************
* *
* XY.h - General Purpose Plot Widget, Public Header File *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* May 28, 1992 *
* *
* Written by Mark Edel *
* *
*******************************************************************************/
#ifndef XY_H
#define XY_H
enum XYRescaleModes {XY_NO_RESCALE, XY_RESCALE, XY_RESCALE_AT_MAX};
enum XYStringAlignments {XY_LEFT, XY_CENTER, XY_RIGHT};
#define XY_N_MARK_STYLES 10
#define XY_N_MARK_SIZES 4
#define XY_N_LINE_STYLES 13
/* JBF added if _CURVE_INFO_ define stuff to match old versions and
* to be compatible w/Data Products
*/
#ifndef _CURVE_INFO_
#define _CURVE_INFO_
enum XYMarkStyles {XY_NO_MARK, XY_SQUARE_MARK, XY_CIRCLE_MARK, XY_STAR_MARK,
XY_X_MARK, XY_TRIANGLE_MARK, XY_SOLID_SQUARE_MARK, XY_SOLID_CIRCLE_MARK,
XY_THICK_SQUARE_MARK, XY_THICK_CIRCLE_MARK};
enum XYMarkSizes {XY_TINY, XY_SMALL, XY_MEDIUM, XY_LARGE};
enum XYLineStyles {XY_NO_LINE, XY_PLAIN_LINE, XY_FINE_DASH, XY_MED_FINE_DASH,
XY_DASH, XY_LONG_DASH, XY_X_LONG_DASH, XY_1_DOT_DASH, XY_2_DOT_DASH,
XY_3_DOT_DASH, XY_4_DOT_DASH, XY_THICK_LINE, XY_X_THICK_LINE};
#endif /* _CURVE_INFO_ */
/* Resource strings */
#define XmNdoubleBuffer "doubleBuffer"
#define XmCDoubleBuffer "DoubleBuffer"
#define XmNshowLegend "showLegend"
#define XmCShowLegend "ShowLegend"
#define XmNshowGrid "showGrid"
#define XmCShowGrid "ShowGrid"
#define XmNgridColor "gridColor"
#define XmCGridColor "gridColor"
#define XmNprintGridColor "printGridColor"
#define XmCPrintGridColor "printGridColor"
#define XmNxLogScaling "xLogScaling"
#define XmCXLogScaling "XLogScaling"
#define XmNyLogScaling "yLogScaling"
#define XmCYLogScaling "YLogScaling"
#define XmNmarginPercent "marginPercent"
#define XmCMarginPercent "MarginPercent"
#define XmNbtn2Callback "btn2Callback"
#define XmCBtn2Callback "Btn2Callback"
#define XmNbtn3Callback "btn3Callback"
#define XmCBtn3Callback "Btn3Callback"
/* JBF - added plotTitle from old version */
#define XmNplotTitle "plotTitle"
#define XmCPlotTitle "PlotTitle"
#define XmNxAxisLabel "xAxisLabel"
#define XmCXAxisLabel "XAxisLabel"
#define XmNyAxisLabel "yAxisLabel"
#define XmCYAxisLabel "YAxisLabel"
#define XmNredisplayCallback "redisplayCallback"
#define XmCRedisplayCallback "RedisplayCallback"
/* Keith added the crosshairs */
#define XmNenableCrosshairs "enableCrosshairs"
#define XmCEnableCrosshairs "EnableCrosshairs"
#define XmNValueDisplay "valueDisplay"
#define XmCValueDisplay "ValueDisplay"
#define XmNyAxisFormat "yAxisFormat"
#define XmCYAxisFormat "YAxisFormat"
extern WidgetClass xyWidgetClass;
typedef struct _XYClassRec *XYWidgetClass;
typedef struct _XYRec *XYWidget;
/*
* It is possible that XYPoint will be defined in AppUtil.hh or somewhere else
* This is my work around... :-(
*/
#ifndef _XYPOINT_
#define _XYPOINT_
typedef struct _XYPoint {
double x, y;
} XYPoint;
#endif
typedef struct _XYErrorBar {
float min, max;
} XYErrorBar;
typedef struct _XYString {
float x, y;
#if XmVERSION < 2
XmFontList render_font;
#else
XmRenderTable render_font;
#endif
Pixel color;
int alignment;
XmString string;
} XYString;
typedef struct {
int reason;
XEvent *event;
} XYCallbackStruct;
typedef struct _XYCurve {
XmString curve_id ;
XmString name;
char markerStyle;
char markerSize;
char lineStyle;
Pixel markerPixel;
Pixel linePixel;
int nPoints;
XYPoint *points;
XYErrorBar *horizBars;
XYErrorBar *vertBars;
int flatline ;
double flatlineValue ;
} XYCurve;
typedef struct {
Widget x_formula ;
Widget y_formula ;
XYWidget w ;
} XYManipulateCurveCBData ;
typedef struct {
Widget curves_formula ;
XYWidget w ;
} XYCombineCurvesCBData ;
void XYSetContents(Widget w, XYCurve *curves, int nCurves, int rescaleMode);
void XYUpdateStyles(Widget w, XYCurve *curves);
void XYUpdateData(Widget w, XYCurve *curves, int rescaleMode);
void XYSetStrings(Widget w, XYString *strings, int nStrings);
void XYSetVisibleRange(Widget w, double minXLim, double minYLim,
double maxXLim, double maxYLim);
void XYGetVisibleRange(Widget w, double *minXLim, double *minYLim,
double *maxXLim, double *maxYLim);
void XYZoomOut(Widget w);
void XYZoomIn(Widget w);
void XYResetZoom(Widget w);
void XYPrintContents(Widget w, char *psFileName);
/* JBF */
void XYPrintMultiple(Widget w[],
int landscape,
int num_plots,
int num_rows,
int num_columns,
char *page_title,
char *page_sub_title,
Boolean DestroyOldFile,
char *psFileName);
int getXYCurves(Widget w, XYCurve **curve) ;
int addXYPoints(Widget w, int curve_num, XYPoint *data, int num_points) ;
/* end JBF */
void XYDrawMarker(Display *display, Drawable drawBuf, GC gc, int size,
int style, Pixel color, int x, int y);
void XYDrawLine(Display *display, Drawable drawBuf, GC gc, int style,
Pixel color, int x1, int y1, int x2, int y2);
#endif

View File

@ -0,0 +1,125 @@
/*******************************************************************************
* *
* XYP.h - General Purpose Plot Widget, Private Header File *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* May 28, 1992 *
* *
* Written by Mark Edel *
* *
*******************************************************************************/
#ifndef XYP_H
#define XYP_H
#include "XY.h"
#include <Xm/XmP.h>
#if XmVERSION >= 2
#include <Xm/PrimitiveP.h>
#endif
typedef struct _XYClassPart{
int ignore;
} XYClassPart;
typedef struct _XYClassRec{
CoreClassPart core_class;
XmPrimitiveClassPart primitive_class;
XYClassPart xy_class;
} XYClassRec;
extern XYClassRec xyClassRec;
typedef struct _XYPart {
/* JBF - added zoomGC from old version */
GC zoomGC; /* Graphics context for zoom box */
GC gc; /* Graphics context for axes & labels */
GC contentsGC; /* Graphics context for plot contents */
Pixmap drawBuffer; /* Double buffering for non-flashing draws */
Pixmap valueBuffer; /* Double buffering for value mark */
int valueX ; /* coordinates of mark */
int valueY ; /* coordinates of mark */
int xMin, yMin, xMax, yMax; /* Boundaries of the drawable area of widget */
#if XmVERSION < 2
XmFontList render_font; /* Motif font list associated with widget */
#else
XmRenderTable render_font; /* Motif Render Table associated with widget */
#endif
XtCallbackList resize; /* Callbacks */
XtCallbackList btn2;
XtCallbackList btn3;
XtCallbackList redisplay;
Boolean doubleBuffer; /* When set, draw first to offscreen pixmap */
Boolean xLogScaling; /* When set, plot X axis as log of X */
Boolean yLogScaling; /* When set, plot Y axis as log of Y */
Boolean showLegend; /* When set, show the plot legend */
Boolean showGrid; /* When set, draw the grid lines */
Pixel gridColor; /* color for grid lines */
Pixel printGridColor; /* color for grid lines */
/* JBF - added plotTitle from old version */
XmString plotTitle; /* Compound string for plot title */
XmString xAxisLabel; /* Compound string labels for axes */
XmString yAxisLabel;
XmString yAxisFormat; /* printf format to show on Y axis */
int marginPercent; /* Size of plot border in % of data range */
int xOrigin, yOrigin; /* The point where the axis lines meet */
int xEnd, yEnd; /* The ends of the x and y axis lines */
int legendTop; /* Y coord. of the top of the plot legend */
int legendLeftMargin; /* left edge of legend */
int axisLeft, axisTop; /* Along with xOrigin and yOrigin, define */
int axisBottom, axisRight; /* the boundaries of the axis areas */
int legendRows; /* Number of rows in the plot legend */
int legendColumnSpacing; /* How far apart to space legend columns */
int dragState; /* Is the user currently dragging the mouse? */
double xDragStart; /* X (data coord) position of start of drag */
double yDragStart; /* Y (data coord) position of start of drag */
double minXData, maxXData; /* Minimum and maximum x data values */
double minYData, maxYData; /* Minimum and maximum y data values */
double minXLim, maxXLim; /* Min and max x data actually displayed */
double minYLim, maxYLim; /* Min and max y data actually displayed */
XYCurve *curves; /* Data to be displayed on the plot */
int nCurves; /* Number of curves in curves above */
XYString *strings; /* Text strings to be displayed on the plot */
int nStrings; /* Number of text strings in strings above */
int selectedCurve ; /* Index of curve selected by user */
Boolean enableCrosshairs ; /* User preference */
int crosshairFirst ; /* First time to display crosshair */
int lastCrosshairX ; /* Save X-Y pixel location of crosshair */
int lastCrosshairY ;
int crosshairHoriXTextCoord ; /* X-Y pix location of value on horizontal */
int crosshairHoriYTextCoord ; /* line in cross hair */
int crosshairVertXTextCoord ; /* X-Y pix location of value on vertical */
int crosshairVertYTextCoord ; /* line in cross hair */
char crosshairHoriText[16] ; /* Numbers displayed for crosshair */
char crosshairVertText[16] ;
Boolean valueDisplay ; /* User preference */
} XYPart;
typedef struct _XYRec {
CorePart core;
XmPrimitivePart primitive;
XYPart xy;
} XYRec;
#endif

View File

@ -0,0 +1,221 @@
/*******************************************************************************
* *
* dragAxes.c - Handle axis dragging for 2D plotting widgets *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* May 28, 1992 *
* *
* Written by Mark Edel *
* *
*******************************************************************************/
#include <math.h>
#include <X11/Xlib.h>
#include "dragAxes.h"
enum dragStates {NOT_DRAGGING, DRAGGING_NOTHING, DRAGGING_TOP, DRAGGING_BOTTOM,
DRAGGING_BOTTOM_AND_LEFT, DRAGGING_LEFT, DRAGGING_RIGHT, DRAGGING_DATA};
/*
** ResetAxisDragging
**
** Call this before calling DragAxes to initialize the drag state. Can also
** be called to stop any axis dragging currently in progress.
*/
void ResetAxisDragging(int *dragState)
{
*dragState = NOT_DRAGGING;
}
/*
** DragAxes
**
** process a button motion (mouse drag) event to 1) check if it is within
** the boundaries of the axis dragging areas and 2) if so process the
** drag event to adjust the plotting limits. Requires the caller to
** maintain the dragState, xDragStart, and yDragStart variables between
** calls. Call ResetAxisDragging to initialize dragState before calling
** this routine.
*/
int DragAxes(XEvent *event, int xOrigin, int xEnd, int yOrigin,
int yEnd, int axisLeft, int axisTop, int axisBottom, int axisRight,
double minXData, double maxXData, double minYData, double maxYData,
int xLogScaling, int yLogScaling, double *minXLimit, double *maxXLimit,
double *minYLimit, double *maxYLimit, int *dragState,
double *xDragStart, double *yDragStart)
{
double minXLim, minYLim, maxXLim, maxYLim;
double minXDat, minYDat, maxXDat, maxYDat;
double xScale, yScale, xOffset, yOffset, newLim;
int x, y;
int redrawArea = DA_REDRAW_NONE;
/* use log coordinates (which are linear) for log scaling on either axis */
if (xLogScaling) {
minXLim = log10(*minXLimit); maxXLim = log10(*maxXLimit);
minXDat = log10(minXData); maxXDat = log10(maxXData);
} else {
minXLim = *minXLimit; maxXLim = *maxXLimit;
minXDat = minXData; maxXDat = maxXData;
}
if (yLogScaling) {
minYLim = log10(*minYLimit); maxYLim = log10(*maxYLimit);
minYDat = log10(minYData); maxYDat = log10(maxYData);
} else {
minYLim = *minYLimit; maxYLim = *maxYLimit;
minYDat = minYData; maxYDat = maxYData;
}
/* calculate scale factors for translating data coords to pixel coords */
xScale = (maxXLim - minXLim)/(xEnd - xOrigin);
yScale = (maxYLim - minYLim)/(yOrigin - yEnd);
if (event->type == ButtonPress || event->type == MotionNotify) {
x = event->xbutton.x;
y = event->xbutton.y;
switch (*dragState) {
case NOT_DRAGGING:
if (x >= xOrigin && x <= xEnd && y <= yOrigin && y >= yEnd)
*dragState = DRAGGING_DATA;
else if (x >= axisLeft && x <= xOrigin &&
y >= yOrigin && y <= axisBottom)
*dragState = DRAGGING_BOTTOM_AND_LEFT;
else if (x >= axisLeft && x <= xOrigin &&
y >= axisTop && y <= axisBottom)
if (y < yEnd + (yOrigin - yEnd)/2)
*dragState = DRAGGING_TOP;
else
*dragState = DRAGGING_BOTTOM;
else if (x >= axisLeft && x <= axisRight &&
y <= axisBottom && y >= yOrigin )
if (x < xOrigin + (xEnd - xOrigin)/2)
*dragState = DRAGGING_LEFT;
else
*dragState = DRAGGING_RIGHT;
else
*dragState = DRAGGING_NOTHING;
*xDragStart = minXLim + (double)(x - xOrigin) * xScale;
*yDragStart = minYLim + (double)(yOrigin - y) * yScale;
break;
case DRAGGING_NOTHING:
break;
case DRAGGING_DATA:
xOffset = minXLim - (*xDragStart - (x - xOrigin) * xScale);
yOffset = minYLim - (*yDragStart - (yOrigin - y) * yScale);
if (maxXLim - xOffset > maxXDat)
xOffset = maxXLim - maxXDat;
else if (minXLim - xOffset < minXDat)
xOffset = minXLim - minXDat;
if (xOffset != 0.) {
*maxXLimit = xLogScaling ? pow(10., maxXLim-xOffset) :
maxXLim-xOffset;
*minXLimit = xLogScaling ? pow(10., minXLim-xOffset) :
minXLim-xOffset;
redrawArea |= DA_REDRAW_H_AXIS | DA_REDRAW_CONTENTS;
}
if (maxYLim - yOffset > maxYDat)
yOffset = maxYLim - maxYDat;
else if (minYLim - yOffset < minYDat)
yOffset = minYLim - minYDat;
if (yOffset != 0.) {
*maxYLimit = yLogScaling ? pow(10., maxYLim-yOffset) :
maxYLim-yOffset;
*minYLimit = yLogScaling ? pow(10., minYLim-yOffset) :
minYLim-yOffset;
redrawArea |= DA_REDRAW_V_AXIS | DA_REDRAW_CONTENTS;
}
break;
case DRAGGING_TOP:
if (y < yOrigin)
newLim = minYLim + (*yDragStart - minYLim) *
(double)(yOrigin-yEnd)/(double)(yOrigin-y);
if (y >= yOrigin || newLim > maxYDat)
newLim = maxYDat;
if (newLim != maxYLim)
redrawArea |= DA_REDRAW_V_AXIS | DA_REDRAW_CONTENTS;
*maxYLimit = yLogScaling ? pow(10., newLim) : newLim;
break;
case DRAGGING_BOTTOM:
if (y > yEnd)
newLim = maxYLim - (maxYLim - *yDragStart) *
(double)(yOrigin - yEnd)/(double)(y - yEnd);
if (y <= yEnd || newLim < minYDat)
newLim = minYDat;
if (newLim != minYLim)
redrawArea |= DA_REDRAW_V_AXIS | DA_REDRAW_CONTENTS;
*minYLimit = yLogScaling ? pow(10., newLim) : newLim;
break;
case DRAGGING_BOTTOM_AND_LEFT:
if (y > yEnd)
newLim = maxYLim - (maxYLim - *yDragStart) *
(double)(yOrigin - yEnd)/(double)(y - yEnd);
if (y <= yEnd || newLim < minYDat)
newLim = minYDat;
if (newLim != minYLim)
redrawArea |= DA_REDRAW_V_AXIS | DA_REDRAW_CONTENTS;
*minYLimit = yLogScaling ? pow(10., newLim) : newLim;
if (x < xEnd)
newLim = maxXLim - (maxXLim - *xDragStart) *
(double)(xEnd - xOrigin)/(double)(xEnd - x);
if (x >= xEnd || newLim < minXDat)
newLim = minXDat;
if (newLim != minXLim)
redrawArea |= DA_REDRAW_H_AXIS | DA_REDRAW_CONTENTS;
*minXLimit = xLogScaling ? pow(10., newLim) : newLim;
break;
case DRAGGING_RIGHT:
if (x > xOrigin)
newLim = minXLim + (*xDragStart - minXLim) *
(double)(xEnd - xOrigin)/(double)(x - xOrigin);
if (x <= xOrigin || newLim > maxXDat)
newLim = maxXDat;
if (newLim != maxXLim)
redrawArea |= DA_REDRAW_H_AXIS | DA_REDRAW_CONTENTS;
*maxXLimit = xLogScaling ? pow(10., newLim) : newLim;
break;
case DRAGGING_LEFT:
if (x < xEnd)
newLim = maxXLim - (maxXLim - *xDragStart) *
(double)(xEnd - xOrigin)/(double)(xEnd - x);
if (x >= xEnd || newLim < minXDat)
newLim = minXDat;
if (newLim != minXLim)
redrawArea |= DA_REDRAW_H_AXIS | DA_REDRAW_CONTENTS;
*minXLimit = xLogScaling ? pow(10., newLim) : newLim;
break;
}
}
/* conversion back and forth to log coordinates can introduce error which
will make the plot limits not match the data limits when the user has
dragged the scale all the way back in. This code restores them */
if (xLogScaling) {
minXLim = log10(*minXLimit); maxXLim = log10(*maxXLimit);
if (fabs(minXLim - minXDat) < (maxXLim - minXLim) / 1000.)
*minXLimit = minXData;
if (fabs(maxXLim - maxXDat) < (maxXLim - minXLim) / 1000.)
*maxXLimit = maxXData;
}
if (yLogScaling) {
minYLim = log10(*minYLimit); maxYLim = log10(*maxYLimit);
if (fabs(minYLim - minYDat) < (maxYLim - minYLim) / 1000.)
*minYLimit = minYData;
if (fabs(maxYLim - maxYDat) < (maxYLim - minYLim) / 1000.)
*maxYLimit = maxYData;
}
return redrawArea;
}

View File

@ -0,0 +1,36 @@
/*******************************************************************************
* *
* dragAxes.h - Handle axis dragging for 2D plotting widgets *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* May 28, 1992 *
* *
* Written by Mark Edel *
* *
*******************************************************************************/
#define DA_REDRAW_NONE 0
#define DA_REDRAW_H_AXIS 1
#define DA_REDRAW_V_AXIS 2
#define DA_REDRAW_CONTENTS 4
void ResetAxisDragging(int *dragState);
int DragAxes(XEvent *event, int xOrigin, int xEnd, int yOrigin,
int yEnd, int axisLeft, int axisTop, int axisBottom, int axisRight,
double minXData, double maxXData, double minYData, double maxYData,
int xLogScaling, int yLogScaling, double *minXLimit, double *maxXLimit,
double *minYLimit, double *maxYLimit, int *dragState,
double *xDragStart, double *yDragStart);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
/*******************************************************************************
* *
* drawAxes.h -- Generic axis drawing routines for 2D graphs & plots *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* May 28, 1992 *
* *
* Written by Mark Edel *
* *
*******************************************************************************/
int HAxisHeight(XFontStruct *fs);
int HAxisEndClearance(XFontStruct *fs);
int VAxisWidth(XFontStruct *fs, XmString format);
int VAxisEndClearance(XFontStruct *fs);
void DrawHorizontalAxis(Display *display, Drawable window, GC gc,
XFontStruct *fs, int outDevice, int y, int y2, int x1, int x2,
double minData, double maxData, double minLimit, double maxLimit,
int logScaling, int nBins,
int showGrid, Pixel gridColor, Pixel printGridColor );
void DrawVerticalAxis(Display *display, Drawable window, GC gc, XFontStruct *fs,
int outDevice, int x, int x2, int y1, int y2, double minData, double maxData,
double minLimit, double maxLimit, int logScaling, XmString yAxisFormat ,
int showGrid, Pixel gridColor, Pixel printGridColor );
void RedrawHAxisArrows(Display *display, Drawable window, GC gc,
int y, int x1, int x2, double minData, double maxData,
double minLimit, double maxLimit);
void RedrawVAxisArrows(Display *display, Drawable window, GC gc,
int x, int y1, int y2, double minData, double maxData,
double minLimit, double maxLimit);

View File

@ -0,0 +1,62 @@
include ${TRICK_HOME}/share/trick/makefiles/Makefile.common
CC = cc
OBJ_DIR = object_${TRICK_HOST_CPU}
DP_CFLAGS = -g -Wall -I/usr/X11R6/include -I/usr/X11/include -I${TRICK_HOME}/trick_source
ifeq ($(TRICK_HOST_TYPE), Darwin)
DP_CFLAGS += -I/sw/include
endif
ifeq ($(TRICK_DP_FORCE_32BIT), 1)
DP_CFLAGS += -m32
endif
OBJECTS= \
${OBJ_DIR}/XY.o \
${OBJ_DIR}/drawAxes.o \
${OBJ_DIR}/dragAxes.o \
${OBJ_DIR}/psUtils.o
LIBDIR = object_${TRICK_HOST_CPU}
LIBNAME = libfermi.a
all: $(LIBDIR)/$(LIBNAME)
@ echo "Library up to date"
$(OBJ_DIR):
@ mkdir -p $(OBJ_DIR)
@ echo "Created $(OBJ_DIR)"
$(LIBDIR):
- mkdir -p $(LIBDIR)
$(LIBDIR)/$(LIBNAME): $(OBJECTS) | $(LIBDIR)
ar cr $(LIBDIR)/$(LIBNAME) $?
# For XY.c, disable "implicit declaration of function" warnings
# generated due to it's use of obsolete Motif functions that have no
# prototypes in Motif 2.x packages. Yes, this is a naughty thing to
# do.
${OBJ_DIR}/XY.o : XY.c | $(OBJ_DIR)
$(CC) $(DP_CFLAGS) -c ${@F:.o=.c} -o $@
${OBJ_DIR}/drawAxes.o : drawAxes.c | $(OBJ_DIR)
$(CC) $(DP_CFLAGS) -c ${@F:.o=.c} -o $@
${OBJ_DIR}/dragAxes.o : dragAxes.c | $(OBJ_DIR)
$(CC) $(DP_CFLAGS) -c ${@F:.o=.c} -o $@
${OBJ_DIR}/psUtils.o : psUtils.c | $(OBJ_DIR)
$(CC) $(DP_CFLAGS) -c ${@F:.o=.c} -o $@
clean:
rm -rf $(LIB) $(OBJ_DIR)
@ echo "Object files successfully removed"
real_clean: clean
$(MODEL_BIN_DIR)/XY.o: psUtils.h drawAxes.h dragAxes.h XYP.h XY.h
$(MODEL_BIN_DIR)/dragAxes.o: dragAxes.h
$(MODEL_BIN_DIR)/drawAxes.o: psUtils.h drawAxes.h

View File

@ -0,0 +1,864 @@
/*******************************************************************************
* *
* psUtils.c -- PostScript file output routines *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* April 16, 1992 *
* *
* Written by Arnulfo Zepeda-Navratil *
* Centro de Investigacion y Estudio Avanzados ( CINVESTAV ) *
* Mexico *
* *
* With some portions from psFiles.c by Sanza T. Kazadi, Fermilab *
* *
* June 1994 : Upgrade to Encapsulated Postscript, by P. Lebrun *
* Include also a routine to draw rectangles *
* *
*******************************************************************************/
#include <stdio.h>
#include <unistd.h> /* access */
#include <time.h>
#include <X11/Xlib.h>
#include <Xm/Xm.h>
#include "psUtils.h"
static void echPS(char *str, int siz, int posx, int posy, int anchor,
char *fontname, double red, double green, double blue);
static void setXGCLineParams(Display *display, GC gc);
static void getXParms(Display *display, GC gc,
unsigned short *red_ptr, unsigned short *green_ptr,
unsigned short *blue_ptr, double *lineWidth);
static XFontStruct *getFontStruct(XmFontList font);
/* Parameters of the current open file */
static int PSWidth = 0;
static int PSHeight = 0;
static FILE *PSFile;
/* Maximum color component value in X Windows */
#define COLOR_FACTOR 65535.0
/* Amount of space to leave on the edge of the printer page in 72nds of an
inch. If this is too big, part of the page will be wasted, too small,
and some (espescially color) printers will clip off part of the plot */
#define PAGE_MARGIN 18
/* Coordinate conversion if necessary is done here */
#define x_X2PS(x) (x)
#define y_X2PS(y) (PSHeight?PSHeight-y:(y))
/*
** Open a text file for one page of PostScript output, append text if
** already created. On error, return a NULL pointer. This routine
** also sets up the coordinate system and clipping for later output routines
*/
FILE *OpenPS(char fname[], int width, int height)
{
time_t tt;
PSFile = fopen(fname,"w");
if (PSFile == NULL)
return NULL;
fprintf(PSFile, "%%!PS-Adobe-3.0\n");
fprintf(PSFile, "%%%%BoundingBox: %d %d %d %d \n", PAGE_MARGIN,
PAGE_MARGIN, width*72/75 + PAGE_MARGIN, height*72/75 + PAGE_MARGIN);
fprintf(PSFile, "%%%%Title: %s \n", fname);
time(&tt);
fprintf(PSFile, "%%%%CreationDate: %s \n", ctime(&tt));
/* Set up the page margin. This is essential since most PostScript
printers can't print all of the way to the edge of the page. For
encapsulated PostScript, we aren't allowed to use initclip to find
out the real boundaries of the page, so this guess must suffice */
fprintf(PSFile, "%d %d translate\n", PAGE_MARGIN, PAGE_MARGIN);
/* Scale coordinates to 75 dpi rather than 72 because most X screens
are closer to 75, and because being an even multiple of 300, simple
line thicknesses like 1.0 and .5 will be more uniform */
fprintf(PSFile, "72 75 div dup scale\n");
/* Define PostScript procedures for drawing dots and line segments:
d draws a dot using x and y coordinates from the stack, l draws
a line between arguments x1 y1 x2 y2 from the stack, rect draws
a rectangle, fillrect fills a rectangle */
fprintf(PSFile, "%% Draw a dot. Args are x, y\n\
/d {\n\
currentlinewidth 2 div sub moveto\n\
0 currentlinewidth rlineto stroke\n\
} def\n\
%% Draw a line. Args are x1, y1, x2, y2\n\
/l {\n\
moveto lineto stroke\n\
} def\n\
%% Draw a rectangle. Args are width, height, bottom, left\n\
/rect {\n\
gsave\n\
translate\n\
matrix currentmatrix\n\
3 1 roll\n\
scale\n\
newpath\n\
0 0 moveto\n\
0 1 lineto\n\
1 1 lineto\n\
1 0 lineto\n\
closepath\n\
setmatrix\n\
stroke\n\
grestore\n\
} def\n\
%% Draw a filled rectangle. Args are width, height, bottom, left\n\
/fillrect {\n\
gsave\n\
translate\n\
scale\n\
newpath\n\
0 0 moveto\n\
0 1 lineto\n\
1 1 lineto\n\
1 0 lineto\n\
closepath\n\
fill\n\
grestore\n\
} def\n\
%% Draw an arc. Args are: x, y, radius, angle1, angle2\n\
/xarc {\n\
newpath\n\
arc\n\
stroke\n\
} def\n\
%% Draw a filled arc. Args are: x, y, radius, angle1, angle2\n\
/fillarc {\n\
newpath\n\
arc\n\
fill\n\
} def\n");
/* Clip to the width and height of the window on the screen */
fprintf(PSFile, "0 0 moveto\n");
fprintf(PSFile, "%d 0 lineto\n", width);
fprintf(PSFile, "%d %d lineto\n", width, height);
fprintf(PSFile, "0 %d lineto\n", height);
fprintf(PSFile, "closepath clip\n");
fprintf(PSFile, "newpath\n");
/* save the width and height */
PSWidth = width;
PSHeight = height;
return(PSFile);
}
/*
* JBF - This routine copied from OpenPS and modified.
*
** Open a text file for one page of PostScript output, append text if
** already created and if desired. On error, return a NULL pointer.
** This routine also sets up the coordinate system for later output routines.
*/
FILE *OpenPSNoClip(int landscape , char fname[], Boolean DestroyOldFile, int width, int height)
{
time_t tt;
Boolean write_header_flag;
/*
* Does the user wish to append to a file, if it already exists ?
* Does the file already exist ?
*/
if ((DestroyOldFile == False) && (access(fname,F_OK) == 0))
{
/*
* Append to an existing file.
*/
PSFile = fopen(fname,"a");
if (PSFile == NULL)
return NULL;
fseek (PSFile, 0L, SEEK_END);
if (ftell(PSFile) == 0l)
write_header_flag = True;
else
write_header_flag = False;
}
else
{
/*
* Create a new file.
*/
PSFile = fopen(fname,"w");
if (PSFile == NULL)
return NULL;
write_header_flag = True;
}
if (write_header_flag == True)
{
fprintf(PSFile, "%%!PS-Adobe-3.0\n");
/*
fprintf(PSFile, "%%%%BoundingBox: %d %d %d %d \n", PAGE_MARGIN,
PAGE_MARGIN, width*72/75 + PAGE_MARGIN, height*72/75 + PAGE_MARGIN);
*/
fprintf(PSFile, "%%%%Title: %s \n", fname);
time(&tt);
fprintf(PSFile, "%%%%CreationDate: %s \n", ctime(&tt));
/* Set up the page margin. This is essential since most PostScript
printers can't print all of the way to the edge of the page. For
encapsulated PostScript, we aren't allowed to use initclip to find
out the real boundaries of the page, so this guess must suffice */
if ( landscape ) {
fprintf(PSFile, "90 rotate 0 -612 translate\n");
}
fprintf(PSFile, "%d %d translate\n", PAGE_MARGIN, PAGE_MARGIN);
/* Scale coordinates to 75 dpi rather than 72 because most X screens
are closer to 75, and because being an even multiple of 300, simple
line thicknesses like 1.0 and .5 will be more uniform */
fprintf(PSFile, "72 75 div dup scale\n");
/* Define PostScript procedures for drawing dots and line segments:
d draws a dot using x and y coordinates from the stack, l draws
a line between arguments x1 y1 x2 y2 from the stack, rect draws
a rectangle, fillrect fills a rectangle */
fprintf(PSFile, "%% Draw a dot. Args are x, y\n\
/d {\n\
currentlinewidth 2 div sub moveto\n\
0 currentlinewidth rlineto stroke\n\
} def\n\
%% Draw a line. Args are x1, y1, x2, y2\n\
/l {\n\
moveto lineto stroke\n\
} def\n\
%% Draw a rectangle. Args are width, height, bottom, left\n\
/rect {\n\
gsave\n\
translate\n\
matrix currentmatrix\n\
3 1 roll\n\
scale\n\
newpath\n\
0 0 moveto\n\
0 1 lineto\n\
1 1 lineto\n\
1 0 lineto\n\
closepath\n\
setmatrix\n\
stroke\n\
grestore\n\
} def\n\
%% Draw a filled rectangle. Args are width, height, bottom, left\n\
/fillrect {\n\
gsave\n\
translate\n\
scale\n\
newpath\n\
0 0 moveto\n\
0 1 lineto\n\
1 1 lineto\n\
1 0 lineto\n\
closepath\n\
fill\n\
grestore\n\
} def\n\
%% Draw an arc. Args are: x, y, radius, angle1, angle2\n\
/xarc {\n\
newpath\n\
arc\n\
stroke\n\
} def\n\
%% Draw a filled arc. Args are: x, y, radius, angle1, angle2\n\
/fillarc {\n\
newpath\n\
arc\n\
fill\n\
} def\n");
}
/* save the width and height */
PSWidth = width;
PSHeight = height;
return(PSFile);
}
/*
** End writing to a PostScript file
*/
void EndPS(void)
{
fprintf(PSFile, "showpage grestore\n");
fclose(PSFile);
}
/*
** Draw a continuous connected line from an array of X XPoint structures
** to the PostScript file
*/
void PSDrawLines(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XPoint *points, int nPoints, int mode)
{
int i;
XPoint *point;
if (mode != CoordModeOrigin) {
fprintf(stderr, "PSDrawLines only does CoordModeOrigin (so far)\n");
return;
}
/* set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
/* generate PostScript calls to the line drawing procedure l defined
in OpenPS above to draw each of the segments in the array */
fprintf(PSFile, "%d %d moveto\n", x_X2PS(points->x), y_X2PS(points->y));
for(i=1, point= &points[1]; i<nPoints; i++, point++)
fprintf(PSFile, "%d %d lineto\n", x_X2PS(point->x), y_X2PS(point->y));
fprintf(PSFile, "stroke\n");
}
/*
** Draw colored line segments from an array of X XSegment structures
** to the PostScript file
*/
void PSDrawSegments(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XSegment *segment, int nSegments)
{
int j;
/* set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
/* generate PostScript calls to the line drawing procedure l defined
in OpenPS above to draw each of the segments in the array */
for(j=0; j<nSegments; j++,segment++)
fprintf(PSFile, "%d %d %d %d l\n",
x_X2PS(segment->x1), y_X2PS(segment->y1),
x_X2PS(segment->x2), y_X2PS(segment->y2));
}
void PSDrawLine(Display *display, Drawable w, GC gc, int x1, int y1,
int x2, int y2)
{
XSegment seg;
seg.x1 = x1; seg.x2 = x2; seg.y1 = y1; seg.y2 = y2;
PSDrawSegments(display, w, gc, &seg, 1);
}
/*
** Draw colored line segments from a floating point equivalent of the
** XSegment data structure to the PostScript File. The coordinate system
** is still assumed to be set up to be equivalent to X coordinate system,
** the floating point values just allow lines to be positioned at a greater
** precision within the 72 dpi grid of the screen coordinate system.
*/
void PSFloatDrawSegments(Display *display, Drawable w __attribute__ ((unused)), GC gc,
FloatSegment *segment, int nSegments)
{
int j;
/* set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
/* generate PostScript calls to the line drawing procedure l defined
in OpenPS above to draw each of the segments in the array */
for(j=0; j<nSegments; j++,segment++)
fprintf(PSFile, "%g %g %g %g l\n",
x_X2PS(segment->x1), y_X2PS(segment->y1),
x_X2PS(segment->x2), y_X2PS(segment->y2));
}
/*
** Draw a continuous connected line from a floating point equivalent of the
** XPoint data structure to the PostScript File. The coordinate system
** is still assumed to be set up to be equivalent to X coordinate system,
** the floating point values just allow lines to be positioned at a greater
** precision within the 72 dpi grid of the screen coordinate system.
*/
void PSFloatDrawLines(Display *display, Drawable w __attribute__ ((unused)), GC gc,
FloatPoint *points, int nPoints)
{
int i;
FloatPoint *point;
/* set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
/* generate PostScript calls to the line drawing procedure l defined
in OpenPS above to draw each of the segments in the array */
fprintf(PSFile, "%g %g moveto\n", x_X2PS(points->x), y_X2PS(points->y));
for(i=1, point= &points[1]; i<nPoints; i++, point++)
fprintf(PSFile, "%g %g lineto\n", x_X2PS(point->x), y_X2PS(point->y));
fprintf(PSFile, "stroke\n");
}
/*
** Draw colored points from an X XPoint structure to the PostScript file
*/
void PSDrawPoints(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XPoint *point, int npoints, int mode __attribute__ ((unused)))
{
int j;
/* Set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
/* generate PostScript calls to the line drawing procedure l defined
in OpenPS above to draw each of the segments in the array */
for(j=0; j<npoints; j++,point++)
fprintf(PSFile, "%d %d d\n", x_X2PS(point->x), y_X2PS(point->y));
}
/*
** Display a colored Motif compound string in Times Roman at a point size
** one point smaller than the default font of the fontlist specified.
** Parameters are the same as XmStringDraw, except minus layout direction
** and clipping. The routine can't yet handle multiline strings,
** clipping, or right-to-left character sets.
*/
void PSDrawXmString(Display *display, Drawable w, XmFontList font, XmString msg,
GC gc, int x, int y, int width, int alignment)
{
char *ansiMsg;
XFontStruct *fs = getFontStruct(font);
int adjX, adjY, anchor;
/* Calculate revised coordinates and anchor mode for drawing the string,
using the parameters in the form required by XmStringDraw */
adjY = y + fs->ascent; /* change y to top left corner of string */
if (alignment == XmALIGNMENT_BEGINNING) {
adjX = x;
anchor = PS_LEFT;
} else if (alignment == XmALIGNMENT_CENTER) {
adjX = x + width/2;
anchor = PS_CENTER;
} else /* XmALIGNMENT_END */ {
adjX = x + width;
anchor = PS_RIGHT;
}
/* Convert the string to a C style stle string and call PSDrawString */
XmStringGetLtoR(msg, XmSTRING_DEFAULT_CHARSET, &ansiMsg);
PSDrawString(display, w, gc, fs, adjX, adjY, anchor, ansiMsg);
XtFree(ansiMsg);
}
/*
** Display a colored string in Times Roman at a point size
** one point smaller than the default font specified in fs
*/
void PSDrawString(Display *display, Drawable w __attribute__ ((unused)), GC gc, XFontStruct *fs,
int x, int y, int anchor, char *msg)
{
double lw;
unsigned short red, green, blue;
getXParms(display, gc, &red, &green, &blue, &lw);
echPS(msg, fs->ascent + fs->descent - 2, x_X2PS(x), y_X2PS(y),
anchor, "Times-Roman",
(float)red / COLOR_FACTOR,
(float)green / COLOR_FACTOR,
(float)blue / COLOR_FACTOR);
}
#ifdef notdef /* paul's original */
/*
** Draw colored rectangles from an X XRectangle structure
** to the PostScript file
*/
void PSDrawRectangles(Display *display, Drawable w, GC gc,
XRectangle *rect, int nrects, int mode)
{
int j;
/* Set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
/* generate PostScript calls to the box drawing procedure defined
here.
Note : we rely here on a non-rescaling version of X2PS */
fprintf(PSFile,"/box{newpath \n");
fprintf(PSFile,"0 0 moveto \n");
fprintf(PSFile,"0 1 lineto \n");
fprintf(PSFile,"1 1 lineto \n");
fprintf(PSFile,"1 0 lineto \n");
fprintf(PSFile,"closepath \n");
fprintf(PSFile,"}def \n");
for(j=0; j<nrects; j++, rect++) {
fprintf(PSFile,"gsave \n");
fprintf(PSFile,"%d %d translate\n",x_X2PS(rect->x),
(y_X2PS(rect->y) - rect->height));
fprintf(PSFile,"%d %d scale\n",rect->width, rect->height);
if (mode ==0)
fprintf(PSFile,"box \n");
else
fprintf(PSFile,"box fill \n");
fprintf(PSFile,"grestore \n");
/* Code for Postscript Level 2
if (mode == 0)
fprintf(PSFile, "%d %d %d %d rectstroke\n",
x_X2PS(rect->x), y_X2PS(rect->y), rect->width, rect->height);
else
fprintf(PSFile, "%d %d %d %d rectfill\n",
x_X2PS(rect->x), y_X2PS(rect->y), rect->width, rect->height);
*/
}
}
#endif
/*
** Draw rectangles from an array of X XRectangle structures
*/
void PSDrawRectangles(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XRectangle *rects, int nRects)
{
int j;
XRectangle *rect;
/* Set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
for(j=0, rect=rects; j<nRects; j++, rect++)
fprintf(PSFile,"%d %d %d %d rect\n", rect->width, rect->height,
x_X2PS(rect->x), y_X2PS(rect->y) - rect->height);
}
/*
** Draw filled rectangles from an array of X XRectangle structures
*/
void PSFillRectangles(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XRectangle *rects, int nRects)
{
int j;
XRectangle *rect;
/* Set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
for(j=0, rect=rects; j<nRects; j++, rect++)
fprintf(PSFile,"%d %d %d %d fillrect\n", rect->width, rect->height,
x_X2PS(rect->x), y_X2PS(rect->y) - rect->height);
}
/*
** Draw arcs from an array of X XArc structures
*/
void PSDrawArcs(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XArc *arcs, int nArcs)
{
int j;
XArc *arc;
/* Set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
for(j=0, arc=arcs; j<nArcs; j++, arc++) {
if (arc->width != arc->height) {
fprintf(stderr, "PSDrawArcs doesn't yet support eliptical arcs\n");
return;
}
fprintf(PSFile,"%d %d %d %d %d xarc\n", x_X2PS(arc->x + arc->width/2),
y_X2PS(arc->y - arc->height/2), arc->width/2, arc->angle1/64,
arc->angle2/64);
}
}
/*
** Draw filled arcs from an array of X XArc structures
*/
void PSFillArcs(Display *display, Drawable w __attribute__ ((unused)), GC gc,
XArc *arcs, int nArcs)
{
int j;
XArc *arc;
/* Set line drawing parameters from contents of X graphics context */
setXGCLineParams(display, gc);
for(j=0, arc=arcs; j<nArcs; j++, arc++) {
if (arc->width != arc->height) {
fprintf(stderr, "PSDrawArcs doesn't yet support eliptical arcs\n");
return;
}
fprintf(PSFile,"%d %d %d %d %d fillarc\n",
x_X2PS(arc->x + arc->width/2), y_X2PS(arc->y - arc->height/2),
arc->width/2, arc->angle1/64, arc->angle2/64);
}
}
/*
** draw an image
*/
void PSDrawImage(
Display *display,
Drawable w __attribute__ ((unused)),
GC gc,
int scanLength, int scanLines, int bitsPerSample, int x, int y,
unsigned char *bitmap )
{
int i, disp_x, disp_y ;
/* set image drawing parameters from the contents of X graphics context */
setXGCLineParams(display, gc);
/* translate the origin to drawing position */
disp_x = x;
disp_y = y ;
/* draw image */
fprintf(PSFile, "%d %d translate\n", x_X2PS(disp_x), y_X2PS(disp_y));
fprintf(PSFile, "%d %d %d [%d 0 0 %d 0 0] {<", scanLength,
scanLines, bitsPerSample, scanLength, scanLines);
for (i = 0; i < scanLength; i++) {
fprintf(PSFile, "%02x", bitmap[i]);
}
fprintf(PSFile, ">} image\n");
/* restore origin */
fprintf(PSFile, "%d %d translate\n", -x_X2PS(disp_x), -y_X2PS(disp_y));
}
/*
** Draw dashed (or solid) line segments (dashed lines can't be drawn by
** PSDrawSegments because X does not provide access to the complete dash
** information in the gc
*/
void PSDrawDashedSegments(Display *display, Drawable w, GC gc,
XSegment *segments, int nSegments, char *dashList, int dashOffset)
{
int i, len;
XGCValues valuesRet;
/* if dashed lines are turned off in the GC, draw solid */
XGetGCValues(display, gc, GCLineStyle, &valuesRet);
if (valuesRet.line_style == LineSolid) {
PSDrawSegments(display, w, gc, segments, nSegments);
return;
}
/* transform and set dash list */
len = strlen(dashList);
if (len != 0) {
fprintf(PSFile, "[");
for (i = 0; i < len - 1; i++)
fprintf(PSFile, "%3d ", (int)dashList[i]);
fprintf(PSFile, "%3d] %d setdash\n", (int)(dashList[len-1]),
dashOffset);
}
/* draw the segments */
PSDrawSegments(display, w, gc, segments, nSegments);
/* set the line style back to solid line */
fprintf(PSFile, "[] 0 setdash\n");
}
/*
** Draw continuous dashed lines from the floating point equivalent of the
** XPoint data structure
*/
void PSFloatDrawDashedLines(Display *display, Drawable w, GC gc,
FloatPoint *points, int nPoints, char *dashList, int dashOffset)
{
int i, len;
XGCValues valuesRet;
/* if dashed lines are turned off in the GC, draw solid */
XGetGCValues(display, gc, GCLineStyle, &valuesRet);
if (valuesRet.line_style == LineSolid) {
PSFloatDrawLines(display, w, gc, points, nPoints);
return;
}
/* transform and set dash list */
len = strlen(dashList);
if (len != 0) {
fprintf(PSFile, "[");
for (i = 0; i < len - 1; i++)
fprintf(PSFile, "%3d ", (int)dashList[i]);
fprintf(PSFile, "%3d] %d setdash\n", (int)(dashList[len-1]),
dashOffset);
}
/* draw the lines */
PSFloatDrawLines(display, w, gc, points, nPoints);
/* set the line style back to solid line */
fprintf(PSFile, "[] 0 setdash\n");
}
/*
** Draw a dashed line (dashed lines can't be drawn by PSDrawLine because
** X does not give access to the complete dash information in the gc
*/
void PSDrawDashedLine(Display *display, Drawable w, GC gc, int x1, int y1,
int x2, int y2, char *dashList, int dashOffset)
{
XSegment seg;
seg.x1 = x1; seg.x2 = x2; seg.y1 = y1; seg.y2 = y2;
PSDrawDashedSegments(display, w, gc, &seg, 1, dashList, dashOffset);
}
/*
** Change the current clip rectangle
*/
void PSSetClipRectangle(int x1, int y1, int x2, int y2)
{
fprintf(PSFile, "newpath\n");
fprintf(PSFile, "%d %d moveto\n", x_X2PS(x1), y_X2PS(y1));
fprintf(PSFile, "%d %d lineto\n", x_X2PS(x2), y_X2PS(y1));
fprintf(PSFile, "%d %d lineto\n", x_X2PS(x2), y_X2PS(y2));
fprintf(PSFile, "%d %d lineto\n", x_X2PS(x1), y_X2PS(y2));
fprintf(PSFile, " %d %d lineto\n", x_X2PS(x1), y_X2PS(y1));
fprintf(PSFile, "closepath clip newpath\n");
}
/*
** Output colored text
*/
static void echPS(char *str, int siz, int posx, int posy, int anchor,
char *fontname, double red, double green, double blue)
{
fprintf(PSFile, "%.2f %.2f %.2f setrgbcolor ", red, green, blue);
fprintf(PSFile, "/%s findfont %04d scalefont setfont\n", fontname, siz);
if (anchor == PS_LEFT)
fprintf(PSFile, "%d %d moveto\n", posx, posy);
else if (anchor == PS_CENTER)
fprintf(PSFile, "(%s) stringwidth pop 2 div neg %d add %d moveto\n",
str, posx, posy);
else if (anchor == PS_RIGHT)
fprintf(PSFile, "(%s) stringwidth pop neg %d add %d moveto\n",
str, posx, posy);
else {
fprintf(stderr, "Internal error: bad anchor value in echPS\n");
return;
}
fprintf(PSFile, "(%s) show\n", str);
}
/*
** Set a subset of GC parameters relating to line appearance for subsequent
** drawing operations
*/
static void setXGCLineParams(Display *display, GC gc)
{
double lineWidth;
unsigned short red, green, blue;
/* Set line drawing parameters from contents of X graphics context */
getXParms(display, gc, &red, &green, &blue, &lineWidth);
fprintf(PSFile, "%.2f %.2f %.2f setrgbcolor ", (float)red/COLOR_FACTOR,
(float)green/COLOR_FACTOR, (float)blue/COLOR_FACTOR);
fprintf(PSFile, "%.2f setlinewidth\n", lineWidth);
}
/*
** Obtain X Window related drawing parameters
** and massage them for PostScript printers
*/
static void getXParms(Display *display, GC gc, unsigned short *red_ptr,
unsigned short *green_ptr, unsigned short *blue_ptr, double *lineWidth)
{
XGCValues valuesRet;
XColor ret_color;
XGetGCValues(display, gc, GCForeground | GCLineWidth, &valuesRet);
/*XGetWindowAttributes(display, w, window_attributes);*/
ret_color.pixel = valuesRet.foreground;
ret_color.flags = DoRed | DoGreen | DoBlue ;
XQueryColor(display, /*window_attributes.colormap*/ /* Get color rgb */
DefaultColormap(display,0), &ret_color);
*red_ptr = ret_color.red;
*green_ptr = ret_color.green;
*blue_ptr = ret_color.blue;
*lineWidth = valuesRet.line_width == 0 ? 0.5 : valuesRet.line_width;
}
/*
** Get the XFontStruct that corresponds to the default (first) font in
** a Motif font list. Since Motif stores this, it saves us from storing
** it or querying it from the X server.
*/
#if ((XmVERSION >= 1) && (XmREVISION >= 2))
/*
* JBF - updated for motif 1.2
* XmFontListGetNextFont is obsolete in Motif 1.2
*/
/* Motif 1.2 or newer */
static XFontStruct *getFontStruct(XmFontList font)
{
XFontStruct *fs;
XmFontContext context;
XmFontListEntry entry;
XmFontType type_return;
XtPointer font_info;
int num_fs;
XFontStruct **font_struct_list_return;
char **font_name_list_return;
XmFontListInitFontContext(&context, font);
entry = XmFontListNextEntry(context);
if (entry != (XmFontListEntry) NULL)
{
font_info = XmFontListEntryGetFont(entry,&type_return);
if (type_return == XmFONT_IS_FONT)
fs = (XFontStruct *)font_info;
else /* type_return == XmFONT_IS_FONTSET */
{
num_fs = XFontsOfFontSet((XFontSet)font_info,
&font_struct_list_return,
&font_name_list_return);
if (num_fs > 0)
fs = font_struct_list_return[0];
else
fs = (XFontStruct *)NULL;
}
}
else
fs = (XFontStruct *)NULL;
XmFontListFreeFontContext(context);
return fs;
}
#else
/* Motif 1.1 */
static XFontStruct *getFontStruct(XmFontList font)
{
XFontStruct *fs;
XmFontContext context;
XmStringCharSet charset;
XmFontListInitFontContext(&context, font);
XmFontListGetNextFont(context, &charset, &fs);
XmFontListFreeFontContext(context);
XtFree(charset);
return fs;
}
#endif

View File

@ -0,0 +1,78 @@
/*******************************************************************************
* *
* psUtils.h -- PostScript file output routines Public Header File *
* *
* Copyright (c) 1991 Universities Research Association, Inc. *
* All rights reserved. *
* *
* This material resulted from work developed under a Government Contract and *
* is subject to the following license: The Government retains a paid-up, *
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
* works, perform publicly and display publicly by or for the Government, *
* including the right to distribute to other Government contractors. Neither *
* the United States nor the United States Department of Energy, nor any of *
* their employees, makes any warrenty, express or implied, or assumes any *
* legal liability or responsibility for the accuracy, completeness, or *
* usefulness of any information, apparatus, product, or process disclosed, or *
* represents that its use would not infringe privately owned rights. *
* *
* Fermilab Nirvana GUI Library *
* April 16, 1992 *
* *
* Written by Arnulfo Zepeda-Navratil *
* Centro de Investigacion y Estudio Avanzados ( CINVESTAV ) *
* Mexico *
* *
* With some portions from psFiles.c by Sanza T. Kazadi, Fermilab *
* *
*******************************************************************************/
/* SCCS ID: psUtils.h 1.7 2/1/95 */
enum outdevice {X_SCREEN, PS_PRINTER};
enum anchorModes {PS_LEFT, PS_CENTER, PS_RIGHT};
typedef struct {
float x1, y1, x2, y2;
} FloatSegment;
typedef struct {
float x, y;
} FloatPoint;
FILE *OpenPS_v2(char fname[], int width, int height);
FILE *OpenPS(char fname[], int width, int height);
FILE *OpenPSNoClip(int landscape , char fname[], Boolean DestroyOldFile, int width, int height);
void EndPS(void);
void PSDrawSegments(Display *display, Drawable w, GC gc,
XSegment *segment, int nsegments);
void PSDrawLine(Display *display, Drawable w, GC gc, int x1, int y1,
int x2, int y2);
void PSDrawLines(Display *display, Drawable w, GC gc,
XPoint *points, int nPoints, int mode);
void PSFloatDrawSegments(Display *display, Drawable w, GC gc,
FloatSegment *segment, int nSegments);
void PSFloatDrawLines(Display *display, Drawable w, GC gc,
FloatPoint *points, int nPoints);
void PSDrawPoints(Display *display, Drawable w, GC gc,
XPoint *point, int npoints, int mode);
void PSDrawRectangles(Display *display, Drawable w, GC gc,
XRectangle *rects, int nRects);
void PSFillRectangles(Display *display, Drawable w, GC gc,
XRectangle *rects, int nRects);
void PSDrawArcs(Display *display, Drawable w, GC gc,
XArc *arcs, int nArcs);
void PSFillArcs(Display *display, Drawable w, GC gc,
XArc *arcs, int nArcs);
void PSDrawString(Display *display, Drawable w, GC gc, XFontStruct *fs,
int x, int y, int anchor, char *msg);
void PSDrawXmString(Display *display, Drawable w, XmFontList font, XmString msg,
GC gc, int x, int y, int width, int alignment);
void PSDrawImage(Display *display, Drawable w, GC gc, int scanLength,
int scanLines, int bitsPerSample, int x, int y, unsigned char *bitmap);
void PSDrawDashedSegments(Display *display, Drawable w, GC gc,
XSegment *segments, int nSegments, char *dashList, int dashOffset);
void PSDrawDashedLine(Display *display, Drawable w, GC gc, int x1, int y1,
int x2, int y2, char *dashList, int dashOffset);
void PSFloatDrawDashedLines(Display *display, Drawable w, GC gc,
FloatPoint *points, int nPoints, char *dashList, int dashOffset);
void PSSetClipRectangle(int x1, int y1, int x2, int y2);