home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume6
/
yahp2ps
/
part05
/
penctrl.c
< prev
Wrap
C/C++ Source or Header
|
1989-02-03
|
12KB
|
568 lines
/*
HPGL to PostScript converter
Copyright (C) 1988 (and following) Federico Heinz
yahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the Free Software Foundation's General Public License for full details.
Everyone is granted permission to copy, modify and redistribute yahp2ps,
but only under the conditions described in the GNU General Public
License. A copy of this license is supposed to have been given to you
along with yahp2ps so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share yahp2ps, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
yahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
it is only released under the same conditions.
For bug reports, wishes, etc. send e-mail to
...!mcvax!unido!tub!actisb!federico (from Europe)
...!uunet!pyramid!actisb!federico (from anywhere else)
For Physical mail:
Federico Heinz
Beusselstr. 21
1000 Berlin 21
Tel. (+49 30) 396 77 92
*/
/***************************************************************************
Primitive pen control routines. Provides the interface between the
ideal plotter and the machinery.
****************************************************************************/
#include "defs.h"
#include "mchinery.h"
#include "penctrl.h"
#include "circle.h"
#include "tick.h"
#include "io.h"
/***************************************************************************
Data defining the plotter's status.
***************************************************************************/
/* Current plotting pen's coordinates */
CoordinatePair PenPosition = { Zero, Zero };
/* Pn's position in User Space */
static CoordinatePair UserP1, UserP2;
/* Pn's coords in Plotter Space */
CoordinatePair PlotterP1, PlotterP2;
/* P1-P2 distance */
Number P1P2Diagonal;
/* Size of paper in use */
static int PaperSize = A4;
static Number LineType; /* Line type used for stroking */
static Number LinePatternLength; /* Length of a pattern cicle */
static Number PenHeld = Zero; /* Pen we're holding */
Boolean UserMode = False; /* Plotting in User Space? */
static Boolean Rotated = False; /* Is the plot rotated 90 degrees? */
Boolean PenIsUp = True; /* Is the plotting pen up? */
static Boolean LineDrawn = False; /* Have we drawn a line? */
CoordinatePair FurthestPoint[] = { { MaxXA, MaxYA },
{ MaxXA4, MaxYA4 },
{ MaxXB, MaxYB },
{ MaxXA3, MaxXA3 } };
CoordinatePair FurthestPointRotated[] =
{ { MaxYA, MaxXA },
{ MaxYA4, MaxXA4 },
{ MaxYB, MaxXB },
{ MaxXA3, MaxXA3 } };
CoordinatePair DefaultP1[] = { {InitialP1XA, InitialP1YA},
{InitialP1XA4, InitialP1YA4},
{InitialP1XB, InitialP1YB},
{InitialP1XA3, InitialP1YA3} };
CoordinatePair DefaultP2[] = { {InitialP2XA, InitialP2YA},
{InitialP2XA4, InitialP2YA4},
{InitialP2XB, InitialP2YB},
{InitialP2XA3, InitialP2YA3} };
CoordinatePair DefaultP1Rotated[] =
{ {InitialP1XAR, InitialP1YAR},
{InitialP1XA4R, InitialP1YA4R},
{InitialP1XBR, InitialP1YBR},
{InitialP1XA3R, InitialP1YA3R} };
CoordinatePair DefaultP2Rotated[] =
{ {InitialP2XAR, InitialP2YAR},
{InitialP2XA4R, InitialP2YA4R},
{InitialP2XBR, InitialP2YBR},
{InitialP2XA3R, InitialP2YA3R} };
/**************************************************************************
Paper size.
/*************************************************************************/
void changePaperSize(newPaperSize)
int newPaperSize;
{ PaperSize = newPaperSize; }
/***************************************************************************
Pen changing.
***************************************************************************/
/*
Each pen's width and color.
*/
static Number PenWidth[MaxPen/One] = { 2500, 3500, 5000,
7500, 10000, 20000 };
static Number PenColor[MaxPen/One] = { Zero, Zero, Zero, Zero, Zero, Zero };
/*
Change the pen sizes.
*/
void getPenSizes(string)
char *string;
{ int i;
i = 0;
while (*string && (i < (MaxPen/One)))
if (!ASCIIToNumber(&PenWidth[i++], &string))
error("Illegal pen width.");
}
/*
Get a new pen
*/
void changePen(pen)
Number pen;
{ Boolean penWasDown;
int oldPen;
if (pen == PenHeld)
return;
if ((penWasDown = !PenIsUp)) liftPen();
if ((pen > Zero) && (pen <= MaxPen))
{ oldPen = (PenHeld/One) - 1;
PenHeld = pen;
pen = (pen / One ) - 1;
if (PenWidth[pen] != PenWidth[oldPen])
setPenWidth(PenWidth[pen]);
if (PenColor[pen] != PenColor[oldPen])
setPenColor(PenColor[pen]);
}
else if (!pen)
PenHeld = Zero;
else
warning("Pen number out of range.");
if (penWasDown) lowerPen();
}
/*
Update the pattern to new parameters.
*/
static void updateLinePattern()
{ Boolean penWasDown;
if ((penWasDown = !PenIsUp)) liftPen();
setPattern(LineType, mulNum(LinePatternLength, P1P2Diagonal)/100);
if (penWasDown) lowerPen();
}
/*
Change the line pattern
*/
void setDash(pattern, patternLength)
Number pattern, patternLength;
{ Boolean penWasDown;
if ((LineType == pattern) &&
((patternLength <= 0) ||
(patternLength >= (128*One)) ||
(patternLength == LinePatternLength)))
return;
if ((patternLength > 0) && (patternLength < (128*One)))
LinePatternLength = patternLength;
LineType = pattern;
updateLinePattern();
}
/**************************************************************************
Clipping rectangle.
**************************************************************************/
static CoordinatePair Origin = { Zero, Zero };
/*
Set a new clipping rectangle.
*/
void setWindow(corner1, corner2)
CoordinatePair corner1, corner2;
{ setClip(corner1, corner2); }
/*
Set the clipping rectangle to the whole plotting area.
*/
void resetWindow()
{
if (Rotated)
setWindow(Origin, FurthestPointRotated[PaperSize]);
else
setWindow(Origin, FurthestPoint[PaperSize]);
}
/**************************************************************************
Scaling of User Space.
**************************************************************************/
/* Parameters for scaling */
Number XScaleFactor = One, YScaleFactor = One;
Number XOrigin = Zero, YOrigin = Zero;
/*
Convert from plotter coordinates to user coordinates.
*/
static void plotterToUser(target, plotterPoint)
CoordinatePair target, plotterPoint;
{
target[X] = divNum(plotterPoint[X] - XOrigin, XScaleFactor);
target[Y] = divNum(plotterPoint[Y] - YOrigin, YScaleFactor);
}
/*
Set the scaling parameters to the appropriate values.
*/
void updateScaling()
{ CoordinatePair plotterPenPosition;
if (UserMode)
{ plotterPenPosition[X] = plotterXCoord(PenPosition[X]);
plotterPenPosition[Y] = plotterYCoord(PenPosition[Y]);
XScaleFactor = divNum((PlotterP2[X] - PlotterP1[X]),
(UserP2[X] - UserP1[X]));
XOrigin = PlotterP1[X] - mulNum(XScaleFactor, UserP1[X]);
YScaleFactor = divNum((PlotterP2[Y] - PlotterP1[Y]),
(UserP2[Y] - UserP1[Y]));
YOrigin = PlotterP1[Y] - mulNum(YScaleFactor, UserP1[Y]);
plotterToUser(PenPosition, plotterPenPosition);
}
}
/*
From now on, coordinates won't be scaled any more.
*/
void turnScalingOff()
{ PenPosition[X] = plotterXCoord(PenPosition[X]);
PenPosition[Y] = plotterYCoord(PenPosition[Y]);
UserMode = False;
}
/*
From now on, coordinates will be scaled according to the user's taste.
*/
void turnScalingOn(newUserP1, newUserP2)
CoordinatePair newUserP1, newUserP2;
{ if ((newUserP1[X] == newUserP2[X]) || (newUserP1[Y] == newUserP2[Y]))
warning("Invalid scale parameters.");
else
{ UserMode = True;
UserP1[X] = newUserP1[X];
UserP1[Y] = newUserP1[Y];
UserP2[X] = newUserP2[X];
UserP2[Y] = newUserP2[Y];
updateScaling();
}
}
/*
Change the scaling points and update everything needed.
*/
void changeP1P2(newP1, newP2)
CoordinatePair newP1, newP2;
{ Number dummy;
CoordinatePair delta;
PlotterP1[X] = newP1[X];
PlotterP1[Y] = newP1[Y];
PlotterP2[X] = newP2[X];
PlotterP2[Y] = newP2[Y];
delta[X] = PlotterP2[X] - PlotterP1[X];
delta[Y] = PlotterP2[Y] - PlotterP1[Y];
cartesianToPolar(&P1P2Diagonal, &dummy, delta);
updateScaling();
updateTicks();
updateLinePattern();
}
/*
Rotate the coordinate system.
*/
void rotate()
{ CoordinatePair plotterPenPosition;
if (!Rotated)
{ plotterPenPosition[Y] = plotterXCoord(PenPosition[X]);
plotterPenPosition[X] = FurthestPoint[PaperSize][Y] -
plotterYCoord(PenPosition[Y]);
plotterToUser(PenPosition, plotterPenPosition);
doRotation();
correctClip();
Rotated = True;
}
}
/*
Return paper to default orientation.
*/
void unRotate()
{ CoordinatePair plotterPenPosition;
if (Rotated)
{ plotterPenPosition[X] = plotterYCoord(PenPosition[Y]);
plotterPenPosition[Y] = FurthestPoint[PaperSize][Y] -
plotterXCoord(PenPosition[X]);
plotterToUser(PenPosition, plotterPenPosition);
undoRotation();
correctClip();
Rotated = False;
}
}
/**************************************************************************
Plotter status initialization.
**************************************************************************/
/*
Set the scaling points to the default values.
*/
void resetP1P2()
{ if (Rotated)
changeP1P2(DefaultP1Rotated[PaperSize], DefaultP2Rotated[PaperSize]);
else
changeP1P2(DefaultP1[PaperSize], DefaultP2[PaperSize]);
}
/*
Set default parameters of this module's stuff.
*/
void penctrlInit()
{ liftPen();
resetP1P2();
unRotate();
}
/**************************************************************************
Moving the pen around.
**************************************************************************/
/*
Move the logical pen in it's current state to some place in User Space.
*/
void doLine(targetX, targetY)
Number targetX, targetY;
{ Number absoluteTargetX, absoluteTargetY;
if (!PenIsUp && PenHeld)
{ LineDrawn = True;
if (LineType)
drawLine(plotterXCoord(targetX),
plotterYCoord(targetY));
else /* Linetype 0: just dots at coords */
{ liftPen();
PenPosition[X] = targetX;
PenPosition[Y] = targetY;
lowerPen();
return;
}
}
PenPosition[X] = targetX;
PenPosition[Y] = targetY;
}
/*
Lift the plotting pen.
*/
void liftPen()
{ if (!PenIsUp)
{ if (LineDrawn)
LineDrawn = False;
else
if (PenHeld)
drawDot();
stroke();
PenIsUp = True;
}
}
/*
Lower the plotting pen. At least a dot is plotted.
*/
void lowerPen()
{ if (PenIsUp)
{ setCurrentPoint(plotterXCoord(PenPosition[X]),
plotterYCoord(PenPosition[Y]));
PenIsUp = False;
}
}