allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (01/22/89)
Posting-number: Volume 6, Issue 8 Submitted-by: federico@actisb.UUCP (Federico Heinz) Archive-name: yahp2ps/part06 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 6)." # Contents: mchinery.c # Wrapped by federico@actisb on Wed Jan 4 13:34:50 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'mchinery.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mchinery.c'\" else echo shar: Extracting \"'mchinery.c'\" \(13950 characters\) sed "s/^X//" >'mchinery.c' <<'END_OF_FILE' X/* X HPGL to PostScript converter X Copyright (C) 1988 (and following) Federico Heinz X Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY XWARRANTY. No author or distributor accepts responsibility to anyone Xfor the consequences of using it or for whether it serves any Xparticular purpose or works at all, unless he says so in writing. XRefer to the Free Software Foundation's General Public License for full details. X XEveryone is granted permission to copy, modify and redistribute yahp2ps, Xbut only under the conditions described in the GNU General Public XLicense. A copy of this license is supposed to have been given to you Xalong with yahp2ps so you can know your rights and responsibilities. It Xshould be in a file named COPYING. Among other things, the copyright Xnotice and this notice must be preserved on all copies. X XIn other words, go ahead and share yahp2ps, but don't try to stop Xanyone else from sharing it farther. Help stamp out software hoarding! X Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation, Xit is only released under the same conditions. X X For bug reports, wishes, etc. send e-mail to X X ...!mcvax!unido!tub!actisb!federico (from Europe) X ...!uunet!pyramid!actisb!federico (from anywhere else) X X For Physical mail: X X Federico Heinz X Beusselstr. 21 X 1000 Berlin 21 X X Tel. (+49 30) 396 77 92 X X*/ X/*************************************************************************** X Mapping of plotter primitives onto PostScript. All coordinates are X considered to be in plotter space. X X***************************************************************************/ X X#include <stdio.h> X#include "defs.h" X#include "penctrl.h" X#include "io.h" X#include "mchinery.h" X#include "circle.h" X#include "shade.h" X X Xstatic Number PenWidth; /* Current pen's width in plotter units */ Xstatic Number PenColor; /* Current Pen's color */ Xstatic Boolean StrokePending; /* Should a stroke be done on penUp? */ X Xstatic Boolean PenWidthChange; /* Pen width changed (for delayed change) */ Xstatic Boolean PatternChange; /* Pattern changed (for delayed change) */ Xstatic Boolean ColorChange; /* Color changed (for delayed change) */ X X X/************************************************************************ X X Different line patterns. X X***********************************************************************/ X X X Xstatic void pattern1(length) X XNumber length; X X{ if (length <= PenWidth) return; X writeNumber(Zero); X writeNumber(length); X} X X X Xstatic void pattern2(length) X XNumber length; X X{ Number halfLength; X X halfLength = length/2; X if (halfLength <= PenWidth) return; X writeNumber(halfLength); X writeNumber(halfLength); X} X X X Xstatic void pattern3(length) X XNumber length; X X{ Number threeQuarterLength; X X if (length/4 <= PenWidth) return; X threeQuarterLength = (3 * length) / 4; X writeNumber(threeQuarterLength); X writeNumber(length - threeQuarterLength); X} X X X Xstatic void pattern4(length) X XNumber length; X X{ Number fourFifthLength, whiteSpace; X X fourFifthLength = (4 * length) / 5; X whiteSpace = (length - fourFifthLength - PenWidth) / 2; X if (whiteSpace <= PenWidth) return; X writeNumber(fourFifthLength); X writeNumber(whiteSpace); X writeNumber(Zero); X writeNumber(length - (fourFifthLength + whiteSpace)); X} X X X Xstatic void pattern5(length) X XNumber length; X X{ Number threeQuarterLength, dashLength; X X threeQuarterLength = (3 * length) / 4; X dashLength = (length - threeQuarterLength) / 3; X if (dashLength <= PenWidth) return; X writeNumber(threeQuarterLength); X writeNumber(dashLength); X writeNumber(dashLength); X writeNumber(length - (threeQuarterLength + 2 * dashLength)); X} X X X Xstatic void pattern6(length) X XNumber length; X X{ Number halfLength, dashLength; X X halfLength = length/2; X dashLength = halfLength/5; X if (dashLength <= PenWidth) return; X writeNumber(halfLength); X writeNumber(dashLength); X writeNumber(dashLength); X writeNumber(dashLength); X writeNumber(dashLength); X writeNumber(length - (halfLength + 4 * dashLength)); X} X X X Xtypedef void (*DashFnct)(); X Xstatic DashFnct DashPattern[] = X { pattern1, pattern2, pattern3, X pattern4, pattern5, pattern6 }; X X Xstatic DashFnct NewDashFnct; /* Pointer to function to change pattern */ Xstatic Number PatternLength; /* Total length of a cicle */ X X X/* X X Change the line pattern. X X*/ X Xvoid setPattern(pattern, patternLength) X XNumber pattern, patternLength; X X{ if ((pattern > Zero) && (pattern != FullLine)) X NewDashFnct = DashPattern[(pattern/One)-1]; X else X NewDashFnct = NULL; X PatternLength = patternLength; X PatternChange = True; X} X X X X/*************************************************************************** X X PostScript pen control. X X***************************************************************************/ X X X X/* X X Draw a line for internal purposes. Call only after doing a stroke()! X X*/ X Xstatic void invisibleLine(toX, toY) X X{ writeNumber(toX); X writeNumber(toY); X writeString("L\n"); X} X X X X/* X X Do the real ink-dropping if needed. X X*/ X Xvoid stroke() X X{ if (StrokePending) X { if (PenWidthChange) X { writeNumber(PenWidth); X writeString("W\n"); X PenWidthChange = False; X } X if (ColorChange) X { writeNumber(PenColor); X writeString("G\n"); X ColorChange = False; X } X if (PatternChange) X { writeString("["); X if (NewDashFnct != NULL) X (*NewDashFnct)(PatternLength); X writeString("] D\n"); X PatternChange = False; X } X writeString("S\n"); X StrokePending = False; X } X} X X X X/* X X Draw a line from the current pen position to the target. X X*/ X Xvoid drawLine(targetX, targetY) X XNumber targetX, targetY; X X{ writeNumber(targetX); X writeNumber(targetY); X writeString("L\n"); X StrokePending = True; X} X X X/* X X Draw a dot at current pen position. X X*/ X Xvoid drawDot() X{ writeString("CD\n"); X} X X X/* X X Move the PostScript pen to the specified coordinates. X X*/ X Xvoid setCurrentPoint(targetX, targetY) X XNumber targetX, targetY; X X{ writeNumber(targetX); X writeNumber(targetY); X writeString("M\n"); X} X X X/************************************************************************** X X Rotate/unrotate coordinate System X X**************************************************************************/ X X/* X X Rotate the coordinate system. X X*/ X Xvoid doRotation() X X{ writeString("POR\n"); } X X X X/* X X Undo the rotation. X X*/ X Xvoid undoRotation() X X{ writeString("LND\n"); } X X X X/************************************************************************** X X Set/reset clipping path. X X**************************************************************************/ X Xstatic CoordinatePair ClipCorner1, ClipCorner2; X X X/* X X Set the clipping window to the given rectangle. X X*/ X Xvoid setClip(corner1, corner2) X XCoordinatePair corner1, corner2; X X{ Boolean penWasDown; X X if (penWasDown = !PenIsUp) X liftPen(); X writeString("RC\n"); X setCurrentPoint(corner1[X], corner1[Y]); X invisibleLine(corner1[X], corner2[Y]); X invisibleLine(corner2[X], corner2[Y]); X invisibleLine(corner2[X], corner1[Y]); X invisibleLine(corner1[X], corner1[Y]); X writeString("SC\n"); X ClipCorner1[X] = corner1[X]; X ClipCorner1[Y] = corner1[Y]; X ClipCorner2[X] = corner2[X]; X ClipCorner2[Y] = corner2[Y]; X if (penWasDown) X lowerPen(); X} X X X X/* X X Make sure the clipping path is the one that was last set. X X*/ X Xvoid correctClip() X X{ setClip(ClipCorner1, ClipCorner2); X} X X X/************************************************************************** X X Initialize/shut down the machinery X X***************************************************************************/ X Xchar *PreludeFile = DEFAULT_PRELUDE; X X Xvoid initializeMachinery() X X{ FILE *fp; X char c; X X if (PreludeFile == NULL) return; X if ((fp = fopen(PreludeFile, "r")) == NULL) X error("Cannot open prelude file."); X while ((c = getc(fp)) != EOF) X putChar(c); X fclose(fp); X} X X X Xvoid shutdownMachinery() X X{ stroke(); X writeString("showpage\n"); X} X X X X/************************************************************************** X X Change the parameters of the pen we're plotting with. X X**************************************************************************/ X X X/* X X From now on, the pen will be 'width' mm thick. X X*/ X Xvoid setPenWidth(width) X XNumber width; X X{ PenWidth = width * PlotterUnitsFactor; X PenWidthChange = True; X} X X X X/* X X From now on, the pen has the given color. X X*/ X Xvoid setPenColor(color) X XNumber color; X X{ PenColor = color; X ColorChange = True; X} X X X X/************************************************************************** X X Filling squares & wedges X X**************************************************************************/ X X X Xstatic void fillPath(fillType, spacing, angle) X XNumber fillType, spacing, angle; X X{ writeString("C "); X if (fillType < ParallelLines) X writeString("fill\n"); X else X { writeString("gsave clip\n"); X if (angle) X { writeNumber(angle); X writeString("R\n"); X } X writeString("T "); X writeNumber(spacing); X if (fillType == ParallelLines) X writeString("false "); X else X writeString("true "); X writeString("H\n"); X } X} X X X X/* X X Shade a rectangle with one corner at current position and the opposite X at the specified absolute (but maybe User) CoordinatePair. X X*/ X X Xvoid doShadeRectangle(oppositeCorner, fillType, spacing, angle) X XCoordinatePair oppositeCorner; XNumber fillType, spacing, angle; X X{ CoordinatePair thisCorner; X Boolean penWasDown; X X if (penWasDown = !PenIsUp) X liftPen(); X setCurrentPoint(PenPosition[X], PenPosition[Y]); X thisCorner[X] = PenPosition[X]; thisCorner[Y] = PenPosition[Y]; X invisibleLine(plotterXCoord(thisCorner[X]), X plotterYCoord(oppositeCorner[Y])); X invisibleLine(plotterXCoord(oppositeCorner[X]), X plotterYCoord(oppositeCorner[Y])); X invisibleLine(plotterXCoord(oppositeCorner[X]), X plotterYCoord(thisCorner[Y])); X invisibleLine(plotterXCoord(thisCorner[X]), X plotterYCoord(thisCorner[Y])); X fillPath(fillType, spacing, angle); X if (penWasDown) lowerPen(); X} X X X/* X X Shade a circle wedge. X The chordAngle should divide the sweepAngle and (of course) X be != 0. If it does not divide the sweepAngle, then the last chord X will be shorter. X X*/ X Xvoid doShadeWedge(center, radius, startAngle, sweepAngle, chordAngle, X fillType, spacing, angle) X XCoordinatePair center; XNumber radius, startAngle, sweepAngle, chordAngle; X X{ Number currentAngle, endAngle; X CoordinatePair thisPoint; X Boolean penWasDown; X int times; X X if (penWasDown = !PenIsUp) X liftPen(); X else X setCurrentPoint(plotterXCoord(PenPosition[X]), X plotterYCoord(PenPosition[Y])); X polarToCartesian(thisPoint, center, radius, startAngle); X invisibleLine(plotterXCoord(thisPoint[X]), X plotterYCoord(thisPoint[Y])); X times = sweepAngle / chordAngle; X if (times < 0) X { chordAngle = -chordAngle; X times = -times; X } X currentAngle = startAngle; X while (times--) X { currentAngle = currentAngle + chordAngle; X polarToCartesian(thisPoint, center, radius, currentAngle); X invisibleLine(plotterXCoord(thisPoint[X]), X plotterYCoord(thisPoint[Y])); X } X if (sweepAngle % chordAngle) X { polarToCartesian(thisPoint, center, radius, startAngle + sweepAngle); X invisibleLine(thisPoint[X], thisPoint[Y]); X } X invisibleLine(plotterXCoord(center[X]), X plotterYCoord(center[Y])); X fillPath(fillType, spacing, angle); X if (penWasDown) lowerPen(); X} X X X X/***************************************************************************** X X Maximum resolution arc stuff X X*****************************************************************************/ X X X X/* X X Distort plotter space so as to reflex the user coordinate system. This is X intended as a means for doing arcs at maximum resolution in user space. X IT IS NOT ALLOWED TO DO TWO distortSpace CALLS IN A ROW. The only way is X distort, undistort, and distort again. X X*/ X Xstatic void distortSpace() X X{ writeNumber(XScaleFactor); X writeNumber(YScaleFactor); X writeNumber(XOrigin); X writeNumber(YOrigin); X writeString("TS\n"); X} X X X X/* X X Undo the distortion caused by the last call to distortSpace. X X*/ X Xstatic void undistortSpace() X X{ writeString("SSM\n"); X} X X X X/* X X Do an arc at maximum resolution. Center and radius are in user units. X X*/ X Xvoid doHRArc(center, radius, startAngle, sweepAngle) X X{ if (UserMode) X distortSpace(); X writeCoordinatePair(center); X writeNumber(radius); X writeNumber(startAngle); X writeNumber(startAngle + sweepAngle); X writeString("A\n"); X StrokePending = True; X if (UserMode) X undistortSpace(); X} X X X X/**************************************************************************** X X Tick drawing. At list one of the legths must be != Zero. X X****************************************************************************/ X X X X/* X X Draw a tick. X X*/ X Xstatic void drawTick(fromX, fromY, toX, toY) X XNumber fromX, fromY, toX, toY; X X{ writeString("TB "); X writeNumber(fromX); X writeNumber(fromY); X writeString("M "); X writeNumber(toX); X writeNumber(toY); X writeString("TE\n"); X} X X X X/* X X Do a horizontal tick. X X*/ X Xvoid doYTick(positiveLength, negativeLength) X XNumber positiveLength, negativeLength; X X{ Number plotterXPenPosition, plotterYPenPosition; X X plotterXPenPosition = plotterXCoord(PenPosition[X]); X plotterYPenPosition = plotterYCoord(PenPosition[Y]); X drawTick(plotterXPenPosition - negativeLength, plotterYPenPosition, X plotterXPenPosition + positiveLength, plotterYPenPosition); X} X X X X/* X X Do a vertical tick. X X*/ X Xvoid doXTick(positiveLength, negativeLength) X XNumber positiveLength, negativeLength; X X{ Number plotterXPenPosition, plotterYPenPosition; X X plotterXPenPosition = plotterXCoord(PenPosition[X]); X plotterYPenPosition = plotterYCoord(PenPosition[Y]); X drawTick(plotterXPenPosition, plotterYPenPosition - negativeLength, X plotterXPenPosition, plotterYPenPosition + positiveLength); X} X END_OF_FILE if test 13950 -ne `wc -c <'mchinery.c'`; then echo shar: \"'mchinery.c'\" unpacked with wrong size! fi # end of 'mchinery.c' fi echo shar: End of archive 6 \(of 6\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0