2227 lines
56 KiB
C#
2227 lines
56 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.IO;
|
||
using System.Windows.Forms;
|
||
using System.Text;
|
||
using System.Drawing;
|
||
using VG;
|
||
using C1.C1Pdf;
|
||
|
||
namespace XYPlots
|
||
{
|
||
/// <summary>
|
||
/// Summary description for XYPlot.
|
||
/// </summary>
|
||
public class XYPlot
|
||
{
|
||
// private int ConvertToTwips = 1440;
|
||
private double ConvertToTwips = 4.8;
|
||
|
||
static long HP3_HPGL_COMPENSATEX = 1016L; /* OK, so you don't believe it */
|
||
static long HP3_HPGL_COMPENSATEY = 1016L;/* OK, so you don't believe it */
|
||
static long PRINTAPLOT_COMPENSATE = 1020L;/* but these resolve differently*/
|
||
static int MAX_XY_STACK = 8; /* this is max of CIE cursor/font stack */
|
||
|
||
static int DPI = 1440; //300;
|
||
static int CWIDEDOTS = 120; //25;
|
||
static int CHIGHDOTS = 240; //50;
|
||
|
||
static int STRAIGHT = 0;
|
||
static int CURVE = 1;
|
||
static int DASH = 2;
|
||
|
||
static int X = 0;
|
||
static int Y = 1;
|
||
static int Dimensions = 2;
|
||
static int USER = 0;
|
||
static int PLOT = 1;
|
||
|
||
static double PI=3.141592653;
|
||
static double Zero=0.0;
|
||
static double ANGLELIMIT=1.0;
|
||
|
||
// !!!! NEED REAL SUPERSCRIPT ON/OFF TOKENS
|
||
static string []SuperScript = {"##","##"};
|
||
static string []SubScript = {"~~","~~"};
|
||
|
||
FileStream XYPlotFile;
|
||
|
||
int []SavedX;
|
||
int []SavedY;
|
||
int stack;
|
||
int HPGLMode;
|
||
long HP_FudgeX = HP3_HPGL_COMPENSATEX;
|
||
long HP_FudgeY = HP3_HPGL_COMPENSATEY;
|
||
|
||
string GoodOldStringX;
|
||
string GoodOldStringY;
|
||
|
||
|
||
public int LinesUsed;
|
||
string valuestring;
|
||
string powerstring;
|
||
int GridOnFlag,Visible,ShadowFlag;
|
||
char[] type = new char[Dimensions];
|
||
double FontPitch = 10.0;
|
||
double[] minimum = new double[Dimensions];
|
||
double[] maximum = new double[Dimensions];
|
||
double[] userunits = new double[Dimensions];
|
||
int[] printerunits = new int[Dimensions];
|
||
int[] Position = new int[Dimensions];
|
||
double[,] Scale = new double[2,Dimensions];
|
||
double[,] Offset = new double[2,Dimensions];
|
||
double[] delta = new double[Dimensions];
|
||
int[] cycles = new int[Dimensions];
|
||
int[] onecycle = new int[Dimensions];
|
||
int[] minor = new int[Dimensions];
|
||
int[] spcminor = new int[Dimensions];
|
||
string[] AxisTitles = new string[Dimensions];
|
||
int[] AxisLabel = new int[Dimensions];// = {1,1}; /* 1 for YES(default), 0 for NO*/
|
||
string LineBuff;
|
||
int CurPenWidth, DrawDirection, LineFlag, LineDiv;
|
||
int EndFlag = 0;
|
||
public string Buff; //[4096],*BuffPtr;
|
||
int BuffPtr = 0;
|
||
|
||
//double (*f[2][2])(double);
|
||
|
||
bool [,]doLOG10 = {{false,false},{false,false}};
|
||
|
||
struct point
|
||
{
|
||
public int[] xyValue; //new int[Dimensions];
|
||
}
|
||
|
||
struct BoxList
|
||
{
|
||
public int Shadow;
|
||
public string BoxText;
|
||
public point BoxMinimum;
|
||
public point BoxMaximum;
|
||
//BoxList *NextBox;
|
||
};
|
||
ArrayList AllBoxes = new ArrayList();
|
||
|
||
struct ActiveBoxList
|
||
{
|
||
public ArrayList BoxPtr;
|
||
//ActiveBoxList *NextActiveBox;
|
||
};
|
||
ArrayList AllActiveBoxes = new ArrayList();
|
||
|
||
class PointList
|
||
{
|
||
private point m_APoint;
|
||
private double m_slope; /* slope of tangent to circle at this point */
|
||
public point APoint
|
||
{
|
||
get{return m_APoint;}
|
||
set{m_APoint=value;}
|
||
}
|
||
public double slope
|
||
{
|
||
get{return m_slope;}
|
||
set{m_slope=value;}
|
||
}
|
||
//PointList *NextPoint;
|
||
};
|
||
// public ArrayList PointListArray = new ArrayList();
|
||
|
||
struct LineList
|
||
{
|
||
public int PlotType;
|
||
public int PlotDivisions;
|
||
// public PointList PlotPoint;
|
||
public ArrayList PlotPointsList;
|
||
// public LineList NextPlot;
|
||
};
|
||
ArrayList AllPlots = new ArrayList();
|
||
|
||
int YLandScape=0; /* y axis title is horizontal */
|
||
point YTitleOrigin; /* y axis title origin if vertical */
|
||
|
||
double FixAngle(double a1)
|
||
{
|
||
double retval;
|
||
int sign;
|
||
if(a1 < 0)
|
||
{
|
||
a1=-a1;
|
||
sign=-1;
|
||
}
|
||
else
|
||
sign=1;
|
||
retval=sign*Math.Floor(0.5+a1);
|
||
return(retval);
|
||
}
|
||
|
||
double dsquare(int val)
|
||
{
|
||
double result;
|
||
result = (double)(val*val);
|
||
return( result );
|
||
}
|
||
|
||
double FMin(double f1,double f2)
|
||
{
|
||
return((f1>=f2)?f2:f1);
|
||
}
|
||
|
||
double FMax(double f1,double f2)
|
||
{
|
||
return((f1>=f2)?f1:f2);
|
||
}
|
||
|
||
double atan_deg(double x)
|
||
{
|
||
return( Math.Atan(x) * 180.0/PI );
|
||
}
|
||
|
||
double cos_deg(double x)
|
||
{
|
||
return( Math.Cos(x*PI/180.0) );
|
||
}
|
||
|
||
double tan_deg(double x)
|
||
{
|
||
return( Math.Tan(x*PI/180.0) );
|
||
}
|
||
|
||
double sin_deg(double x)
|
||
{
|
||
return( Math.Sin(x*PI/180.0) );
|
||
}
|
||
|
||
/*
|
||
** the following function is pointed to by a function pointer
|
||
** and is provided for compatibility with log10() function usage
|
||
*/
|
||
double linear(double x)
|
||
{
|
||
return(x);
|
||
}
|
||
|
||
bool isWhiteSpace(char cptr)
|
||
{
|
||
bool rtnval = false;
|
||
if (!cptr.Equals(null))
|
||
{
|
||
int idx = "\t\n\r\f ".IndexOf(cptr);
|
||
rtnval = (idx > -1);
|
||
}
|
||
return rtnval;
|
||
// return((c) ? strchr("\t\n\r\f ",c):NULL);
|
||
}
|
||
|
||
// int NextPiece()
|
||
string NextPiece()
|
||
{
|
||
string rtnval;
|
||
// char *ptr;
|
||
int ptr;
|
||
// int buflen = Buff.Length;
|
||
while(BuffPtr >= 0 && Buff[BuffPtr] != 0 && isWhiteSpace(Buff[BuffPtr]))BuffPtr++;
|
||
// while(BuffPtr < buflen && Buff[BuffPtr] != 0 && isWhiteSpace(Buff[BuffPtr]))BuffPtr++;
|
||
ptr=BuffPtr;
|
||
while(BuffPtr >= 0 && Buff[BuffPtr] != 0 && !isWhiteSpace(Buff[BuffPtr]))BuffPtr++;
|
||
// while(BuffPtr < buflen && Buff[BuffPtr] != 0 && !isWhiteSpace(Buff[BuffPtr]))BuffPtr++;
|
||
if ( EndOfCommand() ) EndFlag=1;
|
||
|
||
rtnval = Buff.Substring(ptr,BuffPtr-ptr);
|
||
BuffPtr++;
|
||
return rtnval;
|
||
}
|
||
|
||
bool EndOfCommand()
|
||
{
|
||
int tmpPtr = BuffPtr;
|
||
// if (BuffPtr >= Buff.Length)
|
||
// return true;
|
||
while (!Buff[tmpPtr].Equals('\0') && Buff[tmpPtr].Equals(' ')) tmpPtr++;
|
||
if (!Buff[tmpPtr].Equals('\0') && !isWhiteSpace(Buff[tmpPtr]))
|
||
return false;
|
||
else if (Buff[tmpPtr] == '\r' || Buff[tmpPtr] == '\n' || Buff[tmpPtr] == '\0')
|
||
return true;
|
||
else
|
||
return false;
|
||
}
|
||
|
||
bool LoadBuff(string FileName)
|
||
{
|
||
if (!File.Exists(FileName))
|
||
{
|
||
// File does not exist, show error message
|
||
MessageBox.Show(String.Format("X/Y Plot File {0} Does Not Exist",FileName),"Error Opening X/Y Plot File");
|
||
return false;
|
||
}
|
||
|
||
// Open the X/Y Plot file
|
||
try
|
||
{
|
||
XYPlotFile = File.OpenRead(FileName);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
// cannot open the x/y plot file
|
||
MessageBox.Show(e.Message,String.Format("Error Opening {0} for Reading",FileName));
|
||
return false;
|
||
}
|
||
|
||
int blen = (int)XYPlotFile.Length;
|
||
int bread = 0;
|
||
|
||
// initialize a byte array to read into
|
||
byte []bbuf = new byte[blen+1];
|
||
for (int i=0; i<blen; i++) bbuf[i]=0;
|
||
|
||
// Read the contents of the x/y plot file into the byte array
|
||
try
|
||
{
|
||
bread = XYPlotFile.Read(bbuf,0,blen);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
MessageBox.Show(e.Message,String.Format("Error Reading {0}",FileName));
|
||
return false;
|
||
}
|
||
|
||
try
|
||
{
|
||
XYPlotFile.Close();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
MessageBox.Show(e.Message,String.Format("Error Closing {0}",FileName));
|
||
return false;
|
||
}
|
||
|
||
// save the byte array to the Buff string type
|
||
// Buff = bbuf.ToString();
|
||
StringBuilder sb = new StringBuilder();
|
||
for (int i=0;i<bbuf.Length;i++)
|
||
{
|
||
if (bbuf[i] =='\r' && bbuf[i-1] == ' ')
|
||
sb.Remove(i-1,1);
|
||
// if (bbuf[i] != '\0')
|
||
sb.Append(Convert.ToChar(bbuf[i]));
|
||
}
|
||
Buff = sb.ToString();
|
||
BuffPtr = 0;
|
||
return true;
|
||
}
|
||
|
||
int getint()
|
||
{
|
||
int retval;
|
||
retval = Convert.ToInt32(NextPiece(),10);
|
||
return retval;
|
||
}
|
||
|
||
double getdouble()
|
||
{
|
||
double retval;
|
||
retval = Convert.ToDouble(NextPiece());
|
||
return retval;
|
||
}
|
||
|
||
char NextChar()
|
||
{
|
||
return Buff[BuffPtr++];
|
||
}
|
||
|
||
char getchr()
|
||
{
|
||
string nxtstring = NextPiece();
|
||
if (nxtstring.Equals(""))
|
||
return '\0';
|
||
else
|
||
return nxtstring[0];
|
||
// return NextPiece()[0];
|
||
}
|
||
|
||
point GetPair(int flag)
|
||
{
|
||
point retval = new point();
|
||
retval.xyValue = new int[Dimensions];
|
||
double x,y;
|
||
char []sepchar = {','};
|
||
string []xystr = NextPiece().Split(sepchar);
|
||
x = double.Parse(xystr[0]);
|
||
y = double.Parse(xystr[1]);
|
||
|
||
if (doLOG10[flag,X])
|
||
retval.xyValue[X] = (int)(Offset[flag,X] + Scale[flag,X] * Math.Log10(x) + .5);
|
||
else
|
||
retval.xyValue[X] = (int)(Offset[flag,X] + Scale[flag,X] * x + .5);
|
||
if (doLOG10[flag,Y])
|
||
retval.xyValue[Y] = (int)(printerunits[Y] - (Offset[flag,Y] + Scale[flag,Y] * Math.Log10(y) + .5));
|
||
else
|
||
retval.xyValue[Y] = (int)(printerunits[Y] - (Offset[flag,Y] + Scale[flag,Y] * y + .5));
|
||
|
||
return(retval);
|
||
}
|
||
|
||
string GetString()
|
||
{
|
||
char retval;
|
||
// int ptr = 0;
|
||
StringBuilder Lbuff = new StringBuilder();
|
||
retval = NextChar();
|
||
if (retval != '"')
|
||
MessageBox.Show("Double Quote not found","String value syntax problem");
|
||
retval = NextChar();
|
||
while (retval != 0 && retval != '\n')
|
||
{
|
||
switch (retval)
|
||
{
|
||
case '"':
|
||
retval=NextChar();
|
||
if(retval==' ')
|
||
{
|
||
Lbuff.Append('\n');
|
||
retval=NextChar();
|
||
retval=NextChar();
|
||
}
|
||
break;
|
||
case '\r':
|
||
retval=NextChar();
|
||
break;
|
||
case '\\':
|
||
retval=NextChar(); /*always take next*/
|
||
Lbuff.Append(retval);
|
||
retval=NextChar();
|
||
break;
|
||
default:
|
||
Lbuff.Append(retval);
|
||
retval=NextChar();
|
||
break;
|
||
}
|
||
}
|
||
return Lbuff.ToString();
|
||
|
||
}
|
||
|
||
void FixBuffIfNeeded()
|
||
{
|
||
int ptr=0;
|
||
if (Buff.StartsWith("<<G "))
|
||
{
|
||
Buff = Buff.Substring(4);
|
||
}
|
||
|
||
while ((ptr = Buff.IndexOf(">\r\n<",ptr)) > 0)
|
||
{
|
||
// blank out ">"
|
||
Buff = Buff.Remove(ptr,1);
|
||
Buff = Buff.Insert(ptr," ");
|
||
// remove "<"
|
||
Buff = Buff.Remove(ptr+3,1);
|
||
// if command on next line is blank,
|
||
// combine with the previous line
|
||
if (Buff[ptr+3] == ' ')
|
||
Buff = Buff.Remove(ptr,3);
|
||
}
|
||
ptr = Buff.Length-5;
|
||
// if (Buff.EndsWith(">>\r\n"))
|
||
if (Buff.IndexOf(">>\r\n",ptr) > 0)
|
||
{
|
||
Buff = Buff.Remove(ptr,2);
|
||
Buff = Buff.Insert(ptr," ");
|
||
// Buff[ptr] = ' ';
|
||
// Buff[ptr+1] = ' ';
|
||
}
|
||
}
|
||
|
||
void CloseGraph()
|
||
{
|
||
/* Send back number of lines used assuming 6 lines per inch */
|
||
if( LinesUsed==0 )
|
||
LinesUsed=(int)(1.5 * CHIGHDOTS); /* adjust for x axis tics */
|
||
LinesUsed += printerunits[Y];
|
||
LinesUsed = LinesUsed/CHIGHDOTS;
|
||
}
|
||
|
||
void GetScaleInfo()
|
||
{
|
||
GridOnFlag=getint();
|
||
userunits[X]=getdouble();
|
||
userunits[Y]=getdouble();
|
||
// f[USER][X]=linear; /* f is a function pointer */
|
||
// f[USER][Y]=linear; /* linear is a function */
|
||
printerunits[X]=(int)(DPI*userunits[X]);
|
||
printerunits[Y]=(int)(DPI*userunits[Y]);
|
||
minimum[X]=getdouble();
|
||
maximum[X]=getdouble();
|
||
minimum[Y]=getdouble();
|
||
maximum[Y]=getdouble();
|
||
type[X]=getchr();
|
||
type[Y]=getchr();
|
||
if(EndFlag == 0) delta[X]=getdouble();
|
||
if(EndFlag == 0) delta[Y]=getdouble();
|
||
if(EndFlag == 0) spcminor[X]=getint();
|
||
if(EndFlag == 0) spcminor[Y]=getint();
|
||
Offset[USER,X]=0;
|
||
Offset[USER,Y]=0;
|
||
Scale[USER,X]=DPI;
|
||
Scale[USER,Y]=DPI;
|
||
|
||
/*
|
||
in the following if blocks, the array variable f is a function
|
||
pointer which is set to either the function linear or log10.
|
||
*/
|
||
/* X-axis function generation and scaling */
|
||
if(type[X] != 'L')
|
||
{
|
||
// Linear
|
||
doLOG10[PLOT,X]=false;
|
||
LinearScale(X);
|
||
Scale[PLOT,X] = printerunits[X] / (maximum[X]- minimum[X]);
|
||
Offset[PLOT,X] =- Scale[PLOT,X] * minimum[X];
|
||
}
|
||
else
|
||
{
|
||
// Log10
|
||
doLOG10[PLOT,X]=true;
|
||
LogScale(X);
|
||
Scale[PLOT,X] = printerunits[X] /
|
||
(Math.Log10(maximum[X])- Math.Log10(minimum[X]));
|
||
Offset[PLOT,X] =- Scale[PLOT,X] * Math.Log10(minimum[X]);
|
||
}
|
||
|
||
/* Y-axis function generation and scaling */
|
||
if(type[Y] != 'L')
|
||
{
|
||
// Linear
|
||
doLOG10[PLOT,Y]=false;
|
||
LinearScale(Y);
|
||
Scale[PLOT,Y]=printerunits[Y]/ (maximum[Y] - minimum[Y]);
|
||
Offset[PLOT,Y] =- Scale[PLOT,Y] * minimum[Y];
|
||
}
|
||
else
|
||
{
|
||
// Log10
|
||
doLOG10[PLOT,Y]=true;
|
||
LogScale(Y);
|
||
Scale[PLOT,Y]=printerunits[Y]/
|
||
(Math.Log10(maximum[Y]) - Math.Log10(minimum[Y]));
|
||
Offset[PLOT,Y] =- Scale[PLOT,Y] * Math.Log10(minimum[Y]);
|
||
}
|
||
}
|
||
|
||
|
||
void GetAxisTitle(int flag)
|
||
{
|
||
AxisTitles[flag]=GetString();
|
||
}
|
||
|
||
string stripSuperSub(string instr)
|
||
{
|
||
StringBuilder sb = new StringBuilder(instr);
|
||
sb.Replace(SuperScript[0],"");
|
||
sb.Replace(SuperScript[1],"");
|
||
sb.Replace(SubScript[0],"");
|
||
sb.Replace(SubScript[1],"");
|
||
return sb.ToString();
|
||
}
|
||
|
||
point DetermineBoxMax(BoxList boxptr)
|
||
{
|
||
|
||
point newval = new point();
|
||
newval.xyValue = new int[Dimensions];
|
||
string tmp;
|
||
int pos = 0, prevPos = 0;
|
||
int nl = 0, xmax = 0, ilen = 0;
|
||
tmp = stripSuperSub(boxptr.BoxText);
|
||
while ((pos = tmp.IndexOf('\n',pos)) > -1)
|
||
{
|
||
ilen = pos - prevPos; // -1; this will fix an arythmatic bug
|
||
xmax = Math.Max(xmax,ilen);
|
||
prevPos = pos;
|
||
pos++;
|
||
nl++;
|
||
}
|
||
ilen = tmp.Substring(prevPos+1).Length;
|
||
xmax = Math.Max(xmax,ilen) + 2;
|
||
// nl += 2;
|
||
newval.xyValue[X] = boxptr.BoxMinimum.xyValue[X]+(xmax*CWIDEDOTS);
|
||
newval.xyValue[Y] = boxptr.BoxMinimum.xyValue[Y]-(nl*CHIGHDOTS)-(int)(30 * ConvertToTwips);
|
||
// newval.xyValue[Y] = boxptr.BoxMinimum.xyValue[Y]+(nl*CHIGHDOTS)-(int)(30 * ConvertToTwips);
|
||
// boxptr.BoxMaximum = newval;
|
||
return newval;
|
||
}
|
||
|
||
|
||
void GetBoxParameters()
|
||
{
|
||
BoxList NewBox = new BoxList();
|
||
// point Origin = new point();
|
||
// Origin.xyValue = new int[Dimensions];
|
||
point Origin;
|
||
Origin = GetPair(USER);
|
||
string str = GetString();
|
||
NewBox.BoxText = str;
|
||
NewBox.BoxMinimum = Origin;
|
||
NewBox.Shadow = ShadowFlag;
|
||
ShadowFlag = 0;
|
||
NewBox.BoxMaximum = DetermineBoxMax(NewBox);
|
||
// jsj
|
||
point minPoint = new point();
|
||
minPoint.xyValue = new int[Dimensions];
|
||
point maxPoint = new point();
|
||
maxPoint.xyValue = new int[Dimensions];
|
||
minPoint.xyValue[X] = Origin.xyValue[X];
|
||
minPoint.xyValue[Y] = NewBox.BoxMaximum.xyValue[Y];
|
||
maxPoint.xyValue[X] = NewBox.BoxMaximum.xyValue[X];
|
||
maxPoint.xyValue[Y] = Origin.xyValue[Y];
|
||
|
||
NewBox.BoxMinimum = minPoint;
|
||
NewBox.BoxMaximum = maxPoint;
|
||
//jsj
|
||
AllBoxes.Add(NewBox);
|
||
}
|
||
|
||
void GetLineParameters()
|
||
{
|
||
// PointList NewPlotData;
|
||
// int curptr, prevptr;
|
||
ArrayList PointListArray = new ArrayList();
|
||
int pointcount;
|
||
pointcount = EndFlag = 0;
|
||
while (EndFlag == 0)
|
||
{
|
||
PointList pl = new PointList();
|
||
pl.APoint = new point();
|
||
//pl.APoint.xyValue = new int[Dimensions];
|
||
pl.APoint = GetPair(PLOT);
|
||
pointcount++;
|
||
PointListArray.Add(pl);
|
||
}
|
||
if (LineFlag == CURVE && pointcount > 2)
|
||
CalculateSlopes(PointListArray);
|
||
else
|
||
LineFlag = STRAIGHT;
|
||
#if DEBUG
|
||
ShowPoints(PointListArray);
|
||
#endif
|
||
AddAPlot(PointListArray);
|
||
}
|
||
#if DEBUG
|
||
void ShowPoints(ArrayList al)
|
||
{
|
||
foreach(PointList pl in al)
|
||
{
|
||
Console.WriteLine("x={0},y={1},slope={2}",pl.APoint.xyValue[0],pl.APoint.xyValue[1], pl.slope);
|
||
}
|
||
}
|
||
#endif
|
||
double FindSlope(point first, point last)
|
||
{
|
||
double dx, dy, result;
|
||
dx = last.xyValue[X] - first.xyValue[X];
|
||
dy = (last.xyValue[Y] - first.xyValue[Y]);
|
||
// dy = first.xyValue[Y] - last.xyValue[Y];
|
||
if (dx == 0.0)
|
||
{
|
||
if (dy > 0)
|
||
result = Convert.ToDouble("1.E99");
|
||
else
|
||
result = Convert.ToDouble("-1.E99");
|
||
}
|
||
else
|
||
result = dy/dx;
|
||
return result;
|
||
}
|
||
|
||
double FindEndSlope(point first, point last,double s1)
|
||
{
|
||
double result;
|
||
result = 2.0 * FindSlope (first,last) - s1;
|
||
if (result * s1 < 0.0)
|
||
result = 0.0;
|
||
return result;
|
||
}
|
||
|
||
void CalculateSlopes(ArrayList PlAry)
|
||
{
|
||
PointList thispt, prevpt, firstpt;
|
||
long yval, y1, y3;
|
||
int PlAryIdx = 0;
|
||
int PlAryNumItems = PlAry.Count;
|
||
prevpt = (PointList) PlAry[PlAryIdx];
|
||
PlAryIdx++;
|
||
thispt = (PointList) PlAry[PlAryIdx];
|
||
while (PlAryIdx + 1 < PlAry.Count)
|
||
{
|
||
thispt.slope = Zero;
|
||
yval = thispt.APoint.xyValue[Y];
|
||
y1 = prevpt.APoint.xyValue[Y];
|
||
y3 = ((PointList)PlAry[PlAryIdx +1]).APoint.xyValue[Y];
|
||
if ((yval-y1)*(y3-yval) > 0)
|
||
// if ((yval-y1)*(y3-yval) < 0) // jsj
|
||
thispt.slope = FindSlope(prevpt.APoint,((PointList)PlAry[PlAryIdx +1]).APoint);
|
||
prevpt = thispt;
|
||
PlAryIdx++;
|
||
thispt = (PointList)PlAry[PlAryIdx];
|
||
}
|
||
firstpt = (PointList)PlAry[0];
|
||
firstpt.slope = FindEndSlope(firstpt.APoint,((PointList)PlAry[1]).APoint,((PointList)PlAry[1]).slope);
|
||
|
||
thispt.slope = FindEndSlope(thispt.APoint,prevpt.APoint,prevpt.slope);
|
||
}
|
||
|
||
void AddAPlot(ArrayList ptr)
|
||
{
|
||
LineList NewLine = new LineList();
|
||
NewLine.PlotType = LineFlag;
|
||
NewLine.PlotDivisions = LineDiv;
|
||
NewLine.PlotPointsList = ptr;
|
||
AllPlots.Insert(0,NewLine);
|
||
}
|
||
|
||
void GenerateGrid(VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
AllActiveBoxes.Clear();
|
||
SetPenDiameter(5);
|
||
Position[X]= 0;
|
||
Position[Y]= 0; // printerunits[Y];
|
||
SavePosition();
|
||
BoxRelative(printerunits[X],printerunits[Y],CurPenWidth,pg,pdf);
|
||
if(GridOnFlag == 0) Visible=0;
|
||
DrawDirection=Y;
|
||
DoGrid(X,pg,pdf);
|
||
DrawDirection=X;
|
||
DoGrid(Y,pg,pdf);
|
||
Visible=1;
|
||
RecallPosition();
|
||
}
|
||
|
||
void DoGrid(int flag,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
if( type[flag] != 'L' )
|
||
DoLinearGrid(flag,pg,pdf);
|
||
else
|
||
DoLogGrid(flag,pg,pdf);
|
||
}
|
||
|
||
void DoLinearGrid(int flag,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int i,n,ns,subminor;
|
||
// int i,n,ns,x1,x2,y1,y2,subminor;
|
||
int ptval;
|
||
n = (int)(0.5 + (maximum[flag] - minimum[flag]) / delta[flag]);
|
||
ns = n * minor[flag];
|
||
if ((minor[flag] % 2) != 0)
|
||
subminor = minor[flag];
|
||
else
|
||
subminor = minor[flag] / 2;
|
||
for(i=0; i <= ns; i++)
|
||
{
|
||
SetPenDiameter((((i % minor[flag])!=0) ? (((i % subminor)!=0) ? 1 : 2) : 3));
|
||
ptval = ((int)printerunits[flag]) * i / ns;
|
||
if (flag ==Y)
|
||
ptval = printerunits[Y] - ptval;
|
||
MoveAbsolute(((flag == X)? ptval : 0),((flag == Y)? ptval : 0));
|
||
// MoveAbsolute(((flag == X)? ptval : 0),((flag == Y)? ptval : printerunits[Y]));
|
||
if(i % minor[flag] == 0)
|
||
WriteValue(flag,minimum[flag] + i * delta[flag] / minor[flag],false,pg,pdf);
|
||
// DrawGridLine(!flag,ptval);
|
||
DrawGridLine((flag==0)?1:0,ptval,pg,pdf);
|
||
}
|
||
}
|
||
|
||
void DoLogGrid(int flag,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
double showval;
|
||
int gs,ge,gd;
|
||
int i,ptval;
|
||
// int i,x1,x2,y1,y2,ptval;
|
||
showval =minimum[flag];
|
||
for (i=0; i < cycles[flag]; i++)
|
||
{
|
||
gs = gd = 100;
|
||
ge = 1000;
|
||
ptval=((int)printerunits[flag]) * i / cycles[flag];
|
||
if (flag ==Y)
|
||
ptval = printerunits[Y] - ptval; //jj
|
||
MoveAbsolute(((flag == X)? ptval : 0),((flag == Y)? ptval : 0));
|
||
SetPenDiameter(3);
|
||
WriteValue(flag,showval,false,pg,pdf);
|
||
GenGrid(flag,gs,ge,gd,onecycle[flag],2,i * onecycle[flag],pg,pdf);
|
||
showval *= 10.0;
|
||
}
|
||
ptval=((int)printerunits[flag]) * i / cycles[flag];
|
||
if (flag ==Y)
|
||
ptval = printerunits[Y] - ptval; //jj
|
||
MoveAbsolute(((flag == X)? ptval : 0),((flag == Y)? ptval : 0));
|
||
SetPenDiameter(3);
|
||
WriteValue(flag,showval,false,pg,pdf);
|
||
}
|
||
|
||
void WriteValue(int flag, double val, bool SubLogValue, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int size;
|
||
size=GenNumberString(val);
|
||
SavePosition();
|
||
if (flag == X)
|
||
{
|
||
MoveRelative(0,-printerunits[Y]);
|
||
// DrawGridRelative(0,30,pg,pdf);
|
||
// DrawGridRelative(0,(int)(-30 * ConvertToTwips) - printerunits[Y],pg,pdf);
|
||
if (!SubLogValue)
|
||
DrawGridRelative(0,(int)(-30 * ConvertToTwips),pg,pdf);
|
||
// MoveRelative((int)((-150 * size / (int)FontPitch) * ConvertToTwips), (int)(60 * ConvertToTwips));
|
||
MoveRelative((int)((-130 * size / (int)FontPitch) * ConvertToTwips), (int)(-60 * ConvertToTwips));
|
||
if ((AxisLabel[0])!=0)
|
||
{
|
||
if (SubLogValue)
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
sb.Append(SuperScript[0]);
|
||
sb.Append(valuestring);
|
||
sb.Append(SuperScript[1]);
|
||
valuestring = sb.ToString();
|
||
MoveRelative(30,30);
|
||
}
|
||
GraphText(valuestring,pg,pdf);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// DrawGridRelative(-30,0,pg,pdf);
|
||
if (!SubLogValue)
|
||
DrawGridRelative((int)(-30 * ConvertToTwips),0,pg,pdf);
|
||
// MoveRelative((int)(-(15 + 300 * size / (int)FontPitch) * ConvertToTwips), (int) (15 * ConvertToTwips));
|
||
MoveRelative((int)(-(15 + 300 * size / (int)FontPitch) * ConvertToTwips), (int) (-15 * ConvertToTwips));
|
||
if((AxisLabel[1])!=0)
|
||
{
|
||
if (SubLogValue)
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
sb.Append(SuperScript[0]);
|
||
sb.Append(valuestring);
|
||
sb.Append(SuperScript[1]);
|
||
valuestring = sb.ToString();
|
||
MoveRelative(90,-90); //jj
|
||
}
|
||
GraphText(valuestring,pg,pdf);
|
||
}
|
||
}
|
||
RecallPosition();
|
||
}
|
||
|
||
int GenNumberString(double x)
|
||
{
|
||
int power,size,sign;
|
||
double mantissa;
|
||
if(x==0.0) return(savenumber(x));
|
||
if(x<0.0)
|
||
{
|
||
x=-x;
|
||
sign=1;
|
||
}
|
||
else
|
||
sign=0;
|
||
mantissa=Math.Log10(x);
|
||
power=0;
|
||
while(mantissa < 0.999)
|
||
{
|
||
power--;
|
||
mantissa++;
|
||
}
|
||
while(mantissa >= 0.999)
|
||
{
|
||
power++;
|
||
mantissa--;
|
||
}
|
||
if(mantissa < 0)
|
||
mantissa=0;
|
||
if(power > -5 && power < 5)
|
||
size=savenumber(x);
|
||
else
|
||
{
|
||
size = savenumber(Math.Pow(10.0,mantissa));
|
||
size += addpower(power);
|
||
if (valuestring.StartsWith("1x"))
|
||
{
|
||
size -= 2;
|
||
valuestring = valuestring.Remove(0,2);
|
||
}
|
||
}
|
||
if(sign != 0)
|
||
{
|
||
valuestring = "-" + valuestring;
|
||
size++;
|
||
}
|
||
return(size);
|
||
}
|
||
|
||
int savenumber(double x)
|
||
{
|
||
// valuestring = x.ToString("F");
|
||
valuestring = x.ToString("G");
|
||
return valuestring.Length;
|
||
}
|
||
|
||
int addpower(int i)
|
||
{
|
||
int tlen;
|
||
powerstring = string.Format("x10{0}{1}{2}",SuperScript[1],i.ToString(),SuperScript[2]);
|
||
valuestring = valuestring + powerstring;
|
||
tlen=SuperScript[0].Length + SuperScript[1].Length;
|
||
return(powerstring.Length - tlen);
|
||
}
|
||
|
||
void DoAxisTitles(VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int len,frommargin;
|
||
// int axismax,axismin;
|
||
string str;
|
||
// string []newstr = {"",""};
|
||
|
||
SavePosition();
|
||
if((AxisTitles[X] != null) && (len=AxisTitles[X].Length) > 0 )
|
||
{
|
||
frommargin=(int)((0.5 * (printerunits[X])) - (0.5 * (len * CWIDEDOTS)));
|
||
// MoveAbsolute(frommargin, -3 * CHIGHDOTS);
|
||
MoveAbsolute(frommargin, (3 * CHIGHDOTS) + printerunits[Y]);
|
||
PrintText(AxisTitles[X],pg,pdf);
|
||
LinesUsed += (3 * CHIGHDOTS);
|
||
// Zfree(&AxisTitles[X]);
|
||
AxisTitles[X] = null;
|
||
}
|
||
if((AxisTitles[Y] != null) && (len=AxisTitles[Y].Length) > 0)
|
||
{
|
||
if(YLandScape > 0)
|
||
{
|
||
int strIdx = 0;
|
||
// newstr[1] = null;
|
||
MoveTo(YTitleOrigin);
|
||
str = AxisTitles[Y];
|
||
while(strIdx < str.Length)
|
||
{
|
||
// newstr[0] = *str;
|
||
// PrintText( newstr );
|
||
PrintText (str[strIdx].ToString(),pg,pdf);
|
||
MoveRelative(0,-CHIGHDOTS);
|
||
strIdx ++;
|
||
// str++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// MoveAbsolute(-3 * CWIDEDOTS, printerunits[Y] + CHIGHDOTS);
|
||
MoveAbsolute(-3 * CWIDEDOTS, - CHIGHDOTS);
|
||
PrintText(AxisTitles[Y],pg,pdf);
|
||
}
|
||
// Zfree(&AxisTitles[Y]);
|
||
AxisTitles[Y] = null;
|
||
}
|
||
RecallPosition();
|
||
}
|
||
|
||
void DoBoxes(VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int dx,dy;
|
||
BoxList current;
|
||
string str;
|
||
//string nextstr;
|
||
SavePosition();
|
||
int BoxIdx = 0;
|
||
SetPenDiameter(5);
|
||
while(BoxIdx < AllBoxes.Count)
|
||
{
|
||
current=(BoxList)AllBoxes[BoxIdx];
|
||
MoveTo(current.BoxMinimum);
|
||
dx=current.BoxMaximum.xyValue[X] - current.BoxMinimum.xyValue[X];
|
||
// dy=current.BoxMinimum.xyValue[Y] - current.BoxMaximum.xyValue[Y];
|
||
dy=current.BoxMaximum.xyValue[Y] - current.BoxMinimum.xyValue[Y];
|
||
if( current.Shadow != 2 ) BoxRelative(dx,dy,CurPenWidth,pg,pdf);
|
||
if( current.Shadow == 1 )
|
||
{
|
||
int savePenWidth = CurPenWidth;
|
||
SavePosition();
|
||
SetPenDiameter(10);
|
||
MoveRelative((int)(10 * ConvertToTwips),-(dy+(int)(5*ConvertToTwips)));
|
||
DrawRelative(dx,0,pg,pdf);
|
||
// BlockRelative(dx,(int)(10 * ConvertToTwips),pg,pdf);
|
||
MoveRelative(-(int)(3 * ConvertToTwips),-(int)(5*ConvertToTwips));
|
||
// BlockRelative((int)(10 * ConvertToTwips),dy,pg,pdf);
|
||
DrawRelative(0,dy,pg,pdf);
|
||
CurPenWidth = savePenWidth;
|
||
// MoveRelative(dx + (int)(10 * ConvertToTwips),0);
|
||
// BlockRelative(-dx,(int)(10 * ConvertToTwips),pg,pdf);
|
||
// BlockRelative((int)(-10 * ConvertToTwips),dy + (int)(10 * ConvertToTwips),pg,pdf);
|
||
RecallPosition();
|
||
}
|
||
//jj MoveRelative((CWIDEDOTS * (3/2)),dy + (CHIGHDOTS * (5/4)));
|
||
MoveRelative((CWIDEDOTS * (3/2)),-(CHIGHDOTS * (5/4)));
|
||
str=current.BoxText;
|
||
int stridx = 0;
|
||
while(stridx < str.Length)
|
||
{
|
||
string tstr = str;
|
||
int idx;
|
||
if ((idx = str.IndexOf("\n",stridx)) >= 0)
|
||
{
|
||
tstr = str.Substring(stridx,idx-stridx);
|
||
stridx = idx + 1;
|
||
}
|
||
// if( (nextstr=strchr(str,'\n')) != NULL ) *nextstr++=0;
|
||
PrintText(tstr,pg,pdf);
|
||
MoveRelative(0,-CHIGHDOTS);
|
||
// str=nextstr;
|
||
}
|
||
// current=current->NextBox;
|
||
BoxIdx++;
|
||
}
|
||
RecallPosition();
|
||
}
|
||
|
||
void DrawLines(VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int PlotsIdx = 0;
|
||
PointList curpoint;
|
||
LineList current;
|
||
|
||
SavePosition();
|
||
// if( HPGL_Command[0] ) {
|
||
// if( UsePP ) { /* PRINTAPLOT third party software */
|
||
// if( (PRT=fopen("HPGL.tmp","wb")) == NULL )
|
||
// {fprintf(stderr,"Could not open HPGL.tmp");PRT=stdprn;return;}
|
||
// HP_FudgeX=PRINTAPLOT_COMPENSATE;
|
||
// HP_FudgeY=PRINTAPLOT_COMPENSATE;
|
||
//
|
||
// } else { /* standard HPGL */
|
||
// PRT=stdprn;
|
||
// HP_FudgeX=HP3_HPGL_COMPENSATEX;
|
||
// HP_FudgeY=HP3_HPGL_COMPENSATEY;
|
||
// }
|
||
// HPGLMode=1;
|
||
// ANGLELIMIT=2.0;
|
||
// fprintf(PRT,HPGL_Command[0]); /* Initialization */
|
||
//
|
||
// } else { /* All other printers */
|
||
//PRT=stdprn;
|
||
//HPGLMode=0;
|
||
SetPenDiameter(8);
|
||
// }
|
||
|
||
/* begin plotting the graph lines, which may be straight or curved */
|
||
while(PlotsIdx < AllPlots.Count)
|
||
{
|
||
current=(LineList)AllPlots[PlotsIdx];
|
||
int pntListIdx = 0;
|
||
LineDiv=current.PlotDivisions;
|
||
if( current.PlotType == STRAIGHT )
|
||
{ /* straight plot */
|
||
curpoint=(PointList)current.PlotPointsList[pntListIdx];
|
||
MoveTo(curpoint.APoint);
|
||
// while( (curpoint=curpoint->NextPoint) != 0 )
|
||
while( ++pntListIdx < current.PlotPointsList.Count )
|
||
{
|
||
curpoint = (PointList)current.PlotPointsList[pntListIdx];
|
||
DrawLineTo(curpoint.APoint,pg,pdf);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
DrawCurve(current,pg,pdf); /* curved plot */
|
||
}
|
||
|
||
/* HP printers seem to have a bug (or this code does) which */
|
||
/* requires that each plot or curve be redrawn relative to the */
|
||
/* origin, or plot offsetting occurs. */
|
||
// if(HPGLMode && !UsePP) {
|
||
// Graphics(0);
|
||
// RecallPosition();
|
||
// SavePosition();
|
||
// Graphics(1);
|
||
// fprintf(PRT,HPGL_Command[0]); /* Initialization */
|
||
// }
|
||
|
||
// current=current.NextPlot; /* point to next curve */
|
||
PlotsIdx++;
|
||
// if (PlotsIdx < AllPlots.Count)
|
||
// current=(LineList)AllPlots[PlotsIdx];
|
||
} /* repeat for each plot (while) */
|
||
|
||
// if(HPGLMode) {
|
||
// fprintf(PRT,HPGL_Command[1]); /* Cleanup */
|
||
// if( UsePP ) { fclose(PRT); PRT=stdprn; }
|
||
// }
|
||
RecallPosition();
|
||
}
|
||
|
||
point FindCenterOfArc( point StartPoint, double Slope1, point EndPoint, double Slope2)
|
||
{
|
||
point center = new point();
|
||
double s1,s2;
|
||
int x1,y1,x2,y2;
|
||
|
||
center.xyValue = new int[Dimensions];
|
||
s1 = tan_deg(FixAngle(atan_deg(Slope1)));
|
||
s2=tan_deg(FixAngle(atan_deg(Slope2)));
|
||
x1=StartPoint.xyValue[X];
|
||
y1=StartPoint.xyValue[Y];
|
||
x2=EndPoint.xyValue[X];
|
||
y2=EndPoint.xyValue[Y];
|
||
center.xyValue[X]=(int)(((s2*s1)*(y2-y1)+(s1*x2)-(s2*x1))/(s1-s2));
|
||
if(s1==0.0)
|
||
center.xyValue[Y] = (int)(y2-((center.xyValue[X]-x2)/s2));
|
||
else
|
||
center.xyValue[Y] = (int)(y1-((center.xyValue[X]-x1)/s1));
|
||
return(center);
|
||
}
|
||
|
||
point FindModifiedCenter(double rprime,point PtOnArc, double ang)
|
||
{
|
||
point newcenter = new point();
|
||
newcenter.xyValue = new int[Dimensions];
|
||
newcenter.xyValue[X] = (int)(PtOnArc.xyValue[X] - rprime * cos_deg(ang));
|
||
newcenter.xyValue[Y] = (int)(PtOnArc.xyValue[Y] - rprime * sin_deg(ang));
|
||
return(newcenter);
|
||
}
|
||
|
||
int AddMidPoint(ArrayList ptLstAry, int pt1Idx,int pt2Idx)
|
||
{
|
||
PointList midpt;
|
||
PointList pt1, pt2;
|
||
point pt;
|
||
double so;
|
||
int x1,y1,x2,y2;
|
||
pt1 = (PointList)ptLstAry[pt1Idx];
|
||
pt2 = (PointList)ptLstAry[pt2Idx];
|
||
x1=pt1.APoint.xyValue[X];
|
||
y1=pt1.APoint.xyValue[Y];
|
||
x2=pt2.APoint.xyValue[X];
|
||
y2=pt2.APoint.xyValue[Y];
|
||
midpt = new PointList();
|
||
pt=new point();
|
||
pt.xyValue = new int[Dimensions];
|
||
so=FindSlope(pt1.APoint,pt2.APoint);
|
||
midpt.slope = (4.0 * so - pt1.slope - pt2.slope)/2.0;
|
||
pt.xyValue[X]=x1+(x2-x1)/2;
|
||
pt.xyValue[Y]=y1+(y2-y1)/2;
|
||
midpt.APoint=pt;
|
||
ptLstAry.Insert(pt1Idx+1,midpt);
|
||
//midpt->NextPoint=pt2;
|
||
return(pt1Idx+1);
|
||
}
|
||
|
||
double FindTheta(point Endpoint, point Centerpoint)
|
||
{
|
||
double dy,dx,result;
|
||
dx = Endpoint.xyValue[X] - Centerpoint.xyValue[X];
|
||
dy = Endpoint.xyValue[Y] - Centerpoint.xyValue[Y];
|
||
result=90.0 - atan_deg((dy/dx));
|
||
if( dx<0 ) result+=180.0;
|
||
return(result);
|
||
}
|
||
|
||
double FindRadius(point Endpoint, point Centerpoint)
|
||
{
|
||
double dy,dx,r;
|
||
// double dy,dx,ddx,ddy,r;
|
||
dx = Centerpoint.xyValue[X] - Endpoint.xyValue[X];
|
||
dy = Centerpoint.xyValue[Y] - Endpoint.xyValue[Y];
|
||
r = Math.Sqrt(((dx*dx)+(dy*dy)));
|
||
return(r);
|
||
}
|
||
|
||
|
||
void DrawCurve(LineList linestart, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
//PointList curpoint,pt2;
|
||
int pltptListIdx = -1;
|
||
// int debug = 1; //jj
|
||
//curpoint=(PointList)linestart.PlotPointsList[pltptListIdx];
|
||
while( ++pltptListIdx < linestart.PlotPointsList.Count -1 )
|
||
{
|
||
DoSubArcs(linestart.PlotPointsList,pltptListIdx,pg,pdf);
|
||
// pltptListIdx = linestart.PlotPointsList.Count * debug; // jj
|
||
// debug++; //jj
|
||
//DoSubArcs(curpoint);
|
||
//curpoint=(PointList)linestart.PlotPointsList[pltptListIdx];
|
||
}
|
||
}
|
||
|
||
double GetAngle(double s1)
|
||
{
|
||
double t1;
|
||
t1=atan_deg(s1);
|
||
return(t1);
|
||
}
|
||
|
||
double GetAngleBetweenPoints(point pt1, point pt2)
|
||
{
|
||
double retval;
|
||
retval=GetAngle(FindSlope(pt1,pt2));
|
||
if(pt2.xyValue[X] < pt1.xyValue[X])
|
||
{
|
||
if(retval<0)
|
||
retval+=180;
|
||
else
|
||
retval-=180;
|
||
}
|
||
return(retval);
|
||
}
|
||
|
||
double SpecialGetAngleBetweenPoints(point pt1,point pt2, double s1)
|
||
{
|
||
double retval;
|
||
if(s1==0.0)
|
||
{
|
||
if(pt1.xyValue[Y] < pt2.xyValue[Y])
|
||
s1=Convert.ToDouble("1.E99");
|
||
else
|
||
s1=Convert.ToDouble("-1.E99");
|
||
}
|
||
else
|
||
s1 = -1/s1;
|
||
retval=GetAngle(s1);
|
||
if(pt2.xyValue[X] < pt1.xyValue[X])
|
||
{
|
||
if(retval<0)
|
||
retval+=180;
|
||
else
|
||
retval-=180;
|
||
}
|
||
return(retval);
|
||
}
|
||
|
||
double GetArcAngle(double s1, double s2)
|
||
{
|
||
double result,t1,t2;
|
||
t1=GetAngle(s1);
|
||
t2=GetAngle(s2);
|
||
result=t1-t2;
|
||
return(result);
|
||
}
|
||
|
||
void DoSubArcs(ArrayList ptListAry,int aryIdx, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
bool debug = false; //jsj
|
||
int x,y,x1,x2,y1,y2;
|
||
PointList pt1 = (PointList)ptListAry[aryIdx];
|
||
PointList pt2 = (PointList)ptListAry[aryIdx+1];
|
||
#if DEBUG
|
||
Console.WriteLine("pt1={0},{1},{2}",pt1.APoint.xyValue[0],pt1.APoint.xyValue[1],pt1.slope);
|
||
Console.WriteLine("pt2={0},{1},{2}",pt2.APoint.xyValue[0],pt2.APoint.xyValue[1],pt2.slope);
|
||
#endif
|
||
double theta,delta1,delta2,r1,r2,t1,t2,theta1,theta2,thetaa,t3,t4;
|
||
double c1,c2,s1,s2;
|
||
// point cp,cp1,cp2;
|
||
point cp1,cp2;
|
||
t3=FixAngle(GetAngle(pt1.slope));
|
||
t4=FixAngle(GetAngle(pt2.slope));
|
||
thetaa=GetAngleBetweenPoints(pt1.APoint,pt2.APoint);
|
||
if((t3-thetaa)*(t4-thetaa) >= 0.0)
|
||
{
|
||
double tprime;
|
||
tprime=FixAngle(thetaa);
|
||
if (Math.Abs(tprime-t3) < ANGLELIMIT )
|
||
{
|
||
MoveTo(pt1.APoint);
|
||
DrawTo(pt2.APoint,pg,pdf);
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
pt2=(PointList)ptListAry[AddMidPoint(ptListAry,aryIdx,aryIdx+1)];
|
||
t4=FixAngle(GetAngle(pt2.slope));
|
||
thetaa=GetAngleBetweenPoints(pt1.APoint,pt2.APoint);
|
||
}
|
||
}
|
||
// if (debug) //jsj
|
||
// return;
|
||
|
||
if(thetaa < t3)
|
||
t1=t3+90;
|
||
else
|
||
t1=t3-90;
|
||
if(thetaa > t4)
|
||
t2=t4+90;
|
||
else
|
||
t2=t4-90;
|
||
theta=t2-t1;
|
||
theta1=FixAngle(thetaa-t3);
|
||
theta2=theta-theta1;
|
||
if(Math.Abs(theta1) < Math.Abs(theta2))
|
||
{
|
||
if(Math.Abs(theta1) < ANGLELIMIT )
|
||
{
|
||
theta1=0;
|
||
theta2=theta;
|
||
}
|
||
}
|
||
else if(Math.Abs(theta2) < Math.Abs(theta1))
|
||
{
|
||
if(Math.Abs(theta2) < ANGLELIMIT )
|
||
{
|
||
theta2=0;
|
||
theta1=theta;
|
||
}
|
||
}
|
||
x1=pt1.APoint.xyValue[X];
|
||
y1=pt1.APoint.xyValue[Y];
|
||
x2=pt2.APoint.xyValue[X];
|
||
y2=pt2.APoint.xyValue[Y];
|
||
s1=sin_deg(t1+180);
|
||
s2=sin_deg(t2+180);
|
||
c1=cos_deg(t1+180);
|
||
c2=cos_deg(t2+180);
|
||
if(s1 == 0.0)
|
||
{
|
||
r2=(x1-x2)/s2;
|
||
r1=(y2+r2*c2-y1)/c1;
|
||
}
|
||
else if(s2 == 0.0)
|
||
{
|
||
r1=(x2-x1)/s1;
|
||
r2=(y1+r1*c1-y2)/c2;
|
||
}
|
||
else if(c1 == 0.0)
|
||
{
|
||
r2=(y1-y2)/c2;
|
||
r1=(x2+r2*s2-x1)/s1;
|
||
}
|
||
else if(c2 == 0.0)
|
||
{
|
||
r1=(y2-y1)/c1;
|
||
r2=(x1+r1*s1-x2)/s2;
|
||
}
|
||
else
|
||
{
|
||
r2=(((x2-x1)/c1) - ((y2-y1)/s1)) / (s2/s1 - c2/c1);
|
||
r1=(y2-y1+r2*s2)/s1;
|
||
}
|
||
MoveTo(pt1.APoint);
|
||
if (debug) //jsj
|
||
{
|
||
DrawTo(pt2.APoint,pg,pdf);
|
||
return;
|
||
}
|
||
if(Math.Abs(theta1)>ANGLELIMIT && Math.Abs(theta2)>ANGLELIMIT)
|
||
{
|
||
delta1=(r2-r1)/(
|
||
(1.0-cos_deg(theta1)) +
|
||
(1.0-cos_deg(theta2))*sin_deg(theta1)/sin_deg(theta2));
|
||
r1=Math.Floor(0.5+r1+delta1);
|
||
cp1=FindModifiedCenter(r1,pt1.APoint,t1);
|
||
// cp1 = FindCenterOfArc(pt1.APoint,pt1.slope,pt2.APoint,pt2.slope); // jj
|
||
x=(int)(cp1.xyValue[X]+r1*cos_deg(t1+theta1));
|
||
y=(int)(cp1.xyValue[Y]+r1*sin_deg(t1+theta1));
|
||
delta2=delta1*sin_deg(theta1)/sin_deg(theta2);
|
||
// x = pt2.APoint.xyValue[X]; //jj
|
||
// y = pt2.APoint.xyValue[Y]; //jj
|
||
r2=Math.Floor(0.5+r2-delta2);
|
||
cp2=FindModifiedCenter(r2,pt2.APoint,t2);
|
||
#if DEBUG
|
||
Console.WriteLine("DrawArc1");
|
||
#endif
|
||
DrawArc(r1,t1,t1+theta1,cp1,x,y,pg,pdf);
|
||
MoveTo(pt2.APoint);
|
||
if(r2 > 15000)
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawAbs1 {0},{1}",x,y);
|
||
#endif
|
||
DrawAbsolute(x,y,pg,pdf);
|
||
}
|
||
else
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawArc2");
|
||
#endif
|
||
DrawArc(r2,t2,t2-theta2,cp2,x,y,pg,pdf);
|
||
}
|
||
// // Zfree(&cp1);
|
||
// // Zfree(&cp2);
|
||
}
|
||
else if(Math.Abs(theta1)>ANGLELIMIT)
|
||
{
|
||
delta1=(r2-r1)/(1.0-cos_deg(theta1));
|
||
r1=Math.Floor(0.5+r1+delta1);
|
||
cp1=FindModifiedCenter(r1,pt1.APoint,t1);
|
||
// cp1=FindCenterOfArc(pt1.APoint,pt1.slope,pt2.APoint,pt2.slope); //jj
|
||
x=(int)(cp1.xyValue[X]+r1*cos_deg(t1+theta1));
|
||
y=(int)(cp1.xyValue[Y]+r1*sin_deg(t1+theta1));
|
||
if(r1 > 15000)
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawAbs2");
|
||
#endif
|
||
DrawAbsolute(x,y,pg,pdf);
|
||
}
|
||
else
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawArc3");
|
||
#endif
|
||
DrawArc(r1,t1,t1+theta1,cp1,x,y,pg,pdf);
|
||
}
|
||
MoveAbsolute(x,y);
|
||
#if DEBUG
|
||
Console.WriteLine("DrawTo1");
|
||
#endif
|
||
DrawTo(pt2.APoint,pg,pdf);
|
||
// x = pt2.APoint.xyValue[X]; //jj
|
||
// y = pt2.APoint.xyValue[Y]; //jj
|
||
#if DEBUG
|
||
Console.WriteLine("DrawArc4");
|
||
#endif
|
||
DrawArc(r1,t1,t1+theta1,cp1,x,y,pg,pdf);
|
||
// Zfree(&cp1);
|
||
|
||
}
|
||
else if(Math.Abs(theta2)>ANGLELIMIT)
|
||
{
|
||
delta2=(r2-r1)/(1.0-cos_deg(theta2));
|
||
r2=Math.Floor(0.5+r2-delta2);
|
||
cp2=FindModifiedCenter(r2,pt2.APoint,t2);
|
||
// cp2=FindCenterOfArc(pt1.APoint,pt1.slope,pt2.APoint,pt2.slope); //jj
|
||
x=(int)(cp2.xyValue[X]+r2*cos_deg(t2-theta2));
|
||
y=(int)(cp2.xyValue[Y]+r2*sin_deg(t2-theta2));
|
||
#if DEBUG
|
||
Console.WriteLine("DrawAbs3");
|
||
#endif
|
||
DrawAbsolute(x,y,pg,pdf);
|
||
MoveTo(pt2.APoint);
|
||
if(r2 > 15000)
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawAbs4");
|
||
#endif
|
||
DrawAbsolute(x,y,pg,pdf);
|
||
}
|
||
else
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawArc5");
|
||
#endif
|
||
DrawArc(r2,t2,t2-theta2,cp2,x,y,pg,pdf);
|
||
}
|
||
// x = pt2.APoint.xyValue[X]; //jj
|
||
// y = pt2.APoint.xyValue[Y]; //jj
|
||
#if DEBUG
|
||
Console.WriteLine("DrawArc6");
|
||
#endif
|
||
DrawArc(r2,t2,t2-theta2,cp2,x,y,pg,pdf);
|
||
// Zfree(&cp2);
|
||
|
||
}
|
||
else
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("DrawTo2");
|
||
#endif
|
||
DrawTo(pt2.APoint,pg,pdf);
|
||
pt2.slope=FindSlope(pt1.APoint,pt2.APoint);
|
||
}
|
||
return;
|
||
}
|
||
|
||
void Graphics(int flag)
|
||
{
|
||
// if(graph_GraphicsStr[flag])
|
||
// fprintf(stdprn,"%s",graph_GraphicsStr[flag]);
|
||
}
|
||
|
||
void SetPenDiameter(int pd)
|
||
{
|
||
if ((pd * ConvertToTwips) != CurPenWidth)
|
||
{
|
||
CurPenWidth= (int)(pd * ConvertToTwips);
|
||
}
|
||
}
|
||
|
||
void PrintStackError(string relation, int limit)
|
||
{
|
||
MessageBox.Show(String.Format("Position Stack Pointer {0} {1}",relation,limit.ToString()),"Print Stack Error");
|
||
// printf("Position Stack Pointer %s %d",relation,limit);
|
||
// spc_exit(3);
|
||
}
|
||
|
||
void SavePosition()
|
||
{
|
||
if(stack >= MAX_XY_STACK) PrintStackError(">=",MAX_XY_STACK);
|
||
SavedX[stack]=Position[X];
|
||
SavedY[stack++]=Position[Y];
|
||
}
|
||
|
||
void RecallPosition()
|
||
{
|
||
if(stack <= 0) PrintStackError(" <",0);
|
||
Position[X]=SavedX[--stack];
|
||
Position[Y]=SavedY[stack];
|
||
}
|
||
|
||
void MoveTo(point pnt)
|
||
{
|
||
MoveAbsolute(pnt.xyValue[X],pnt.xyValue[Y]);
|
||
}
|
||
|
||
void DrawTo(point pnt, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
DrawAbsolute(pnt.xyValue[X],pnt.xyValue[Y],pg,pdf);
|
||
}
|
||
|
||
void MoveAbsolute(int ptx, int pty)
|
||
{
|
||
int x,y;
|
||
x=ptx-Position[X];
|
||
y=Position[Y]-pty;
|
||
MoveRelative(x,y);
|
||
}
|
||
|
||
void DrawAbsolute(int ptx,int pty, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int x,y;
|
||
x=ptx-Position[X];
|
||
y=Position[Y]-pty;
|
||
DrawRelative(x,y,pg,pdf);
|
||
}
|
||
|
||
void DrawGridAbsolute(int ptx,int pty,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int x,y;
|
||
x=ptx-Position[X];
|
||
y=Position[Y]-pty;
|
||
DrawGridRelative(x,y,pg,pdf);
|
||
}
|
||
|
||
void relval(string ptr,int i)
|
||
{
|
||
ptr = string.Format("+{0}",i.ToString());
|
||
}
|
||
|
||
long DotsToPlotterUnitsX(int x)
|
||
{
|
||
long retval;
|
||
retval = (long)((1.0*x*HP_FudgeX) / 300.0 + .5);
|
||
return( retval );
|
||
}
|
||
|
||
long DotsToPlotterUnitsY(int y)
|
||
{
|
||
long retval;
|
||
retval = (long)((1.0*y*HP_FudgeY) / 300.0 + .5);
|
||
return( retval );
|
||
}
|
||
|
||
void MoveRelative(int x,int y)
|
||
{
|
||
long xl,yl;
|
||
Position[X]+=x;
|
||
Position[Y]-=y;
|
||
}
|
||
|
||
void DrawRelative(int x,int y,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
// long xl,yl;
|
||
if(Visible == 0)
|
||
MoveRelative(x,y);
|
||
else
|
||
{
|
||
int toX, toY;
|
||
toX = Position[X]+x;
|
||
toY = Position[Y]-y;
|
||
// toY = Position[Y]+y;
|
||
VG_Line RelLine = new VG_Line(Position[X],Position[Y],toX,toY,CurPenWidth,pg);
|
||
// VG_Line RelLine = new VG_Line(Position[X],Position[Y],x,-y,CurPenWidth,pg);
|
||
Position[X]+=x;
|
||
Position[Y]-=y;
|
||
// Position[Y]+=y;
|
||
RelLine.ToPdf(pdf);
|
||
// if(HPGLMode != 0)
|
||
// {
|
||
// xl=DotsToPlotterUnitsX(x);
|
||
// yl=DotsToPlotterUnitsY(y);
|
||
// // !!! OUTPUT DRAW RELATIVE COMMAND
|
||
// MessageBox.Show("!!! OUTPUT DRAW RELATIVE COMMAND 1","DrawRelative()");
|
||
// // fprintf(PRT,HPGL_Command[3],-xl,yl); /* */
|
||
// }
|
||
// else
|
||
// MessageBox.Show("!!! OUTPUT DRAW RELATIVE COMMAND 2","DrawRelative()");
|
||
// // !!! OUTPUT DRAW RELATIVE COMMAND
|
||
// // fprintf(PRT,graph_DrawRelative,x,y);
|
||
}
|
||
}
|
||
|
||
void DrawGridRelative(int x, int y,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
if(Visible == 0)
|
||
MoveRelative(x,y);
|
||
else
|
||
{
|
||
/***
|
||
if(StupidHP == 2)
|
||
{ //StupidHP==5 is RTF driver
|
||
if(x==0) BlockRelative(PrevPen,y);
|
||
else if(y==0) BlockRelative(x,PrevPen);
|
||
MoveRelative(x,y);
|
||
|
||
}
|
||
else
|
||
***/
|
||
DrawRelative(x,y,pg,pdf);
|
||
}
|
||
}
|
||
|
||
void MoveForArc(point pnt)
|
||
{
|
||
Position[X]+=pnt.xyValue[X];
|
||
Position[Y]-=pnt.xyValue[Y];
|
||
}
|
||
|
||
void DrawArc(double radius,double Sangle,double Eangle,point cp,int x, int y, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
#if DEBUG
|
||
Console.WriteLine("r={0} sAngle={1} eAngle={2} cp={3},{4} x={5} y={6}",radius,Sangle,Eangle,cp.xyValue[0],cp.xyValue[1],x,y);
|
||
#endif
|
||
// double inc=2000.,r1;
|
||
int dx,dy;
|
||
long radchk;
|
||
radchk=(long)radius;
|
||
// if(radchk > 15000L)
|
||
if(radchk > 72000L)
|
||
{
|
||
DrawAbsolute(x,y,pg,pdf);
|
||
return;
|
||
}
|
||
dx = x - cp.xyValue[X]; //jj
|
||
// dx=cp.xyValue[X]-Position[X];
|
||
// dy=cp.xyValue[Y]-Position[Y];
|
||
dy=Math.Abs(cp.xyValue[Y]-Position[Y]); //jj
|
||
//r1=radius;
|
||
/*
|
||
** for the HP series of printers we recalculate the the x and y positions
|
||
** because of a rounding error that will propagate every time
|
||
** an arc segment is drawn. This has the nasty effect of incorrectly
|
||
** drawing curves.
|
||
*/
|
||
// if( HPGLMode != 0 )
|
||
// {
|
||
// Position[X] += (int)((radius*cos_deg(Eangle) - radius*cos_deg(Sangle)));
|
||
// Position[Y] -= (int)((radius*sin_deg(Sangle) - radius*sin_deg(Eangle)));
|
||
// }
|
||
// Sangle=90-Sangle;
|
||
// Eangle=90-Eangle;
|
||
// Sangle=180-Sangle; //jj
|
||
// Eangle=180-Eangle; //jj
|
||
|
||
// if(HPGLMode != 0)
|
||
// {
|
||
// long xl,yl;
|
||
// xl=DotsToPlotterUnitsX(dx);
|
||
// yl=DotsToPlotterUnitsY(dy);
|
||
// fprintf(PRT,HPGL_Command[4],-xl,-yl,(int)(Sangle-Eangle));
|
||
// VG_Arc arc = new VG_Arc(cp.xyValue[X]-dx,cp.xyValue[Y]+dy,dx*2,dy*2,(float)Sangle,(float)(Sangle - Eangle),5,pg);
|
||
// VG_Arc arc = new VG_Arc(cp.xyValue[X]-dx,cp.xyValue[Y]-dy,dx*2,dy*2,(float)Sangle,(float)(Sangle - Eangle),CurPenWidth,pg);
|
||
radius=radius;
|
||
float x1=cp.xyValue[X]-(float)radius;
|
||
float y1=cp.xyValue[Y]-(float)radius;
|
||
float w1=(float) radius * 2;
|
||
VG_Arc arc = new VG_Arc(x1,y1,w1,w1,(float)Sangle,(float)(Eangle - Sangle),CurPenWidth,pg);
|
||
//VG_Arc arc = new VG_Arc(0,0,5000,5000,(float)Sangle,(float)(Eangle - Sangle),CurPenWidth,pg);
|
||
#if DEBUG
|
||
Console.WriteLine("arc {0},{1},{2},{3},{4},{5}",x1,y1,w1,w1,(float)Sangle,(float)(Eangle - Sangle));
|
||
#endif
|
||
arc.ToPdf(pdf);
|
||
// MessageBox.Show("!!! HPGL_COMMAND[4]","DrawArc()");
|
||
// }
|
||
// else
|
||
// {
|
||
// SavePosition();
|
||
// if(dx>0)
|
||
// MessageBox.Show("!!! graph_MoveRelativeXPos","DrawArc()");
|
||
// // fprintf(PRT,graph_MoveRelativeXPos,dx);
|
||
// else
|
||
// MessageBox.Show("!!! graph_MoveRelativeXNeg","DrawArc()");
|
||
// // fprintf(PRT,graph_MoveRelativeXNeg,-dx);
|
||
// if(dy>0)
|
||
// MessageBox.Show("!!! graph_MoveRelativeYPos","DrawArc()");
|
||
// // fprintf(PRT,graph_MoveRelativeYPos,dy);
|
||
// else
|
||
// MessageBox.Show("!!! graph_MoveRelativeYNeg","DrawArc()");
|
||
// // fprintf(PRT,graph_MoveRelativeYNeg,-dy);
|
||
// MessageBox.Show("!!! graph_ArcFunction1","DrawArc()");
|
||
// // fprintf(PRT,graph_ArcFunction1,
|
||
// // radius-4,(radius+4),FMin(Sangle,Eangle),FMax(Sangle,Eangle));
|
||
// RecallPosition();
|
||
// }
|
||
}
|
||
|
||
void DrawGridLine(int flag,int val,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
ActiveBoxList curbox;
|
||
int v1,v2;
|
||
int BoxesIdx = 0;
|
||
int BoxPtrIdx = 0;
|
||
// FindBoxesinArea(val, !flag);
|
||
FindBoxesinArea(val,(flag==0)?1:0);
|
||
v1=Position[flag];
|
||
if (AllActiveBoxes.Count > 0)
|
||
{
|
||
curbox=(ActiveBoxList)AllActiveBoxes[BoxesIdx];
|
||
while(BoxesIdx < AllActiveBoxes.Count)
|
||
{
|
||
int my_x, my_y;
|
||
v2=((BoxList)curbox.BoxPtr[BoxPtrIdx]).BoxMinimum.xyValue[flag];
|
||
my_x = (flag==X)? ( (v2 < printerunits[flag])? v2 : printerunits[flag] )
|
||
: val;
|
||
my_y = (flag==Y) ?
|
||
( (v2 < printerunits[flag]) ? v2 : printerunits[flag] )
|
||
: val;
|
||
DrawGridAbsolute(my_x,my_y,pg,pdf);
|
||
v1=((BoxList)curbox.BoxPtr[BoxPtrIdx]).BoxMaximum.xyValue[flag];
|
||
while((BoxesIdx < AllActiveBoxes.Count) && (((BoxList)curbox.BoxPtr[BoxPtrIdx]).BoxMinimum.xyValue[flag] < v1))
|
||
{
|
||
v1=(((BoxList)curbox.BoxPtr[BoxPtrIdx]).BoxMaximum.xyValue[flag]);
|
||
BoxesIdx++;
|
||
if (BoxesIdx < AllActiveBoxes.Count)
|
||
curbox=(ActiveBoxList)AllActiveBoxes[BoxesIdx];
|
||
}
|
||
MoveAbsolute((flag==X?v1:val),(flag==Y?v1:val));
|
||
}
|
||
}
|
||
v2=printerunits[flag];
|
||
if (v1 < v2) DrawGridAbsolute((flag==X?v2:val),(flag==Y?v2:val),pg,pdf);
|
||
FreeActiveBoxes();
|
||
}
|
||
|
||
void LogScale(int flag)
|
||
{
|
||
double newminimum, newmaximum, maxlimit=maximum[flag]*.9;
|
||
// int i;
|
||
newminimum=1.0;
|
||
while(newminimum < minimum[flag])newminimum *= 10.0;
|
||
while(newminimum > minimum[flag])newminimum /= 10.0;
|
||
newmaximum=10.0 * newminimum;
|
||
cycles[flag]=1;
|
||
while( newmaximum < maxlimit )
|
||
{
|
||
newmaximum *= 10.0;
|
||
cycles[flag]++;
|
||
}
|
||
onecycle[flag]=printerunits[flag]/cycles[flag];
|
||
minimum[flag]=newminimum;
|
||
maximum[flag]=newmaximum;
|
||
}
|
||
|
||
void LinearScale(int flag)
|
||
{
|
||
double mantissa,nx;
|
||
double newminimum, newmaximum;
|
||
int power=0;
|
||
if( spcminor[flag] == 0 )
|
||
minor[flag]=10;
|
||
else
|
||
minor[flag]=spcminor[flag];
|
||
if( delta[flag] == 0 )
|
||
{
|
||
delta[flag]=maximum[flag]-minimum[flag];
|
||
mantissa=Math.Log10(delta[flag]);
|
||
while(mantissa < 1.2)
|
||
{
|
||
mantissa++;
|
||
power--;
|
||
}
|
||
while(mantissa > 1.2)
|
||
{
|
||
mantissa--;
|
||
power++;
|
||
}
|
||
if(mantissa < 0)mantissa=0;
|
||
nx=Math.Pow(10.0,mantissa);
|
||
if(nx > 5.0)
|
||
{
|
||
delta[flag]=1.0;
|
||
}
|
||
else if(nx > 3.001)
|
||
{ // allow for roundoff
|
||
delta[flag]=0.5;
|
||
}
|
||
else if(nx > 2.001)
|
||
{ // allow for roundoff
|
||
delta[flag]=0.25;
|
||
}
|
||
else
|
||
{
|
||
delta[flag]=0.2;
|
||
if(spcminor[flag] == 0) minor[flag]=8;
|
||
}
|
||
while(power>0)
|
||
{
|
||
power--;
|
||
delta[flag] *= 10.0;
|
||
}
|
||
while(power<0)
|
||
{
|
||
power++;
|
||
delta[flag] /= 10.0;
|
||
}
|
||
}
|
||
if(GridOnFlag==0 || GridOnFlag==1)
|
||
minor[flag]=1;
|
||
else if(GridOnFlag==2)
|
||
minor[flag] /= 2;
|
||
newminimum=((int)(0.01+minimum[flag]/delta[flag])) * delta[flag];
|
||
if(newminimum > minimum[flag]+(delta[flag] * 0.001))
|
||
newminimum-=delta[flag];
|
||
newmaximum=((int)(maximum[flag]/delta[flag])) * delta[flag];
|
||
if(newmaximum < maximum[flag]-(delta[flag] * 0.001))
|
||
newmaximum+=delta[flag];
|
||
minimum[flag]=newminimum;
|
||
maximum[flag]=newmaximum;
|
||
}
|
||
|
||
void err_exit(string msg,string msg2)
|
||
{
|
||
MessageBox.Show(msg + "\n" + msg2 + "\n\n This p=Process Will Terminate","\n## ERROR ## - ");
|
||
Environment.Exit(255);
|
||
}
|
||
|
||
void FindBoxesinArea(int ptval,int flag)
|
||
{
|
||
BoxList cptr;
|
||
int BoxesIdx =0;
|
||
while (BoxesIdx < AllBoxes.Count)
|
||
{
|
||
cptr= (BoxList)AllBoxes[BoxesIdx];
|
||
if ( cptr.BoxMinimum.xyValue[flag] <= ptval &&
|
||
cptr.BoxMaximum.xyValue[flag] >= ptval )
|
||
AddBoxToActiveList(cptr);
|
||
BoxesIdx++;
|
||
}
|
||
}
|
||
|
||
void AddBoxToActiveList(BoxList bptr)
|
||
{
|
||
ActiveBoxList NewActiveBox = new ActiveBoxList();
|
||
int prevboxIdx = -1;
|
||
ActiveBoxList cbox;
|
||
|
||
NewActiveBox.BoxPtr = new ArrayList();
|
||
NewActiveBox.BoxPtr.Add(bptr);
|
||
int AllActBoxIdx = 0;
|
||
if( AllActiveBoxes.Count > 0 )
|
||
{
|
||
cbox = (ActiveBoxList)AllActiveBoxes[AllActBoxIdx];
|
||
prevboxIdx = 0;
|
||
while ( AllActBoxIdx < AllActiveBoxes.Count &&
|
||
(cbox.BoxPtr.Count > 0 && (bptr.BoxMinimum.xyValue[DrawDirection] >
|
||
((BoxList)cbox.BoxPtr[AllActBoxIdx]).BoxMinimum.xyValue[DrawDirection])) )
|
||
{
|
||
prevboxIdx=AllActBoxIdx;
|
||
AllActBoxIdx++;
|
||
if (AllActBoxIdx < AllActiveBoxes.Count)
|
||
cbox=(ActiveBoxList)AllActiveBoxes[AllActBoxIdx];
|
||
else
|
||
prevboxIdx = -1; // will append to end of list
|
||
}
|
||
if (AllActBoxIdx < AllActiveBoxes.Count)
|
||
AllActiveBoxes.Insert(AllActBoxIdx,NewActiveBox);
|
||
}
|
||
if(prevboxIdx == -1)
|
||
AllActiveBoxes.Add(NewActiveBox);
|
||
|
||
}
|
||
|
||
void FreeActiveBoxes()
|
||
{
|
||
AllActiveBoxes.Clear();
|
||
}
|
||
|
||
void GenGrid(int flag,int ss,int ee,int dd,int w,int lw,int goffset,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int val,wn,valn;
|
||
double p2;
|
||
// double p2,size;
|
||
int n,dn,MinorGrid=0;
|
||
if((GridOnFlag * lw)<=1)return;
|
||
if (ee/ss == 10) MinorGrid=2;
|
||
n=ss;
|
||
p2=n;
|
||
// w = (int)(Math.Log10(ee/p2) / w); //jj
|
||
w = (int)(w / Math.Log10(ee/p2)); //jj
|
||
// w /= (int)Math.Log10(ee/p2);
|
||
val=(int)(Math.Log10(p2/ss)*w + goffset);
|
||
MoveAbsolute((flag==X?val:0),(flag==Y?val:0));
|
||
DrawGridLine((flag==0)?1:0,val,pg,pdf);
|
||
if((GridOnFlag * lw) == 2)return;
|
||
SetPenDiameter(lw);
|
||
while(n < ee)
|
||
{
|
||
n+=dd;
|
||
p2=n;
|
||
valn=(int)(Math.Log10(p2/ss)*w + goffset);
|
||
wn=valn-val;
|
||
if(wn > DPI/20 && lw > 1)
|
||
{
|
||
if(wn > DPI*2/5)dn=dd/10;
|
||
else if(wn > DPI/5) dn=dd/5;
|
||
else dn=dd/2;
|
||
GenGrid(flag,n-dd,n,dn,wn,lw-1,val,pg,pdf);
|
||
wn=0;
|
||
}
|
||
val=valn;
|
||
if (flag ==Y)
|
||
val = printerunits[Y] - val; //jj
|
||
MoveAbsolute((flag==X?val:0),(flag==Y?val:0));
|
||
if((MinorGrid != 0) && (MinorGrid < 10))
|
||
{
|
||
// SavePosition();
|
||
// double SaveFontPitch = FontPitch; //jj
|
||
// fprintf(PRT,graph_MinorMark[flag],MinorGrid++);
|
||
// if (flag == 0)
|
||
// MoveRelative((int)(15 * ConvertToTwips),(int)(60 * ConvertToTwips)); // these numbers are in dots
|
||
// else
|
||
// MoveRelative((int)(-30 * ConvertToTwips),(int)(9 * ConvertToTwips));
|
||
// FontPitch = 5.0; //jj
|
||
// if (flag == 0)
|
||
// MoveRelative(0,160); // these numbers are in dots
|
||
//// MoveRelative(0,40); // these numbers are in dots
|
||
// else
|
||
// MoveRelative(-30,0);
|
||
// SavePosition();
|
||
// if (flag == 0)
|
||
// MoveRelative(30,0); // these numbers are in dots
|
||
// else
|
||
// MoveRelative(0,0);
|
||
WriteValue(flag,MinorGrid++,true,pg,pdf); //these numbers are in dots
|
||
// FontPitch = SaveFontPitch; //jj
|
||
// RecallPosition();
|
||
}
|
||
DrawGridLine((flag==0)?1:0,val,pg,pdf);
|
||
}
|
||
}
|
||
|
||
void PrintText(string txt,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
StringBuilder tstr = new StringBuilder(txt);
|
||
// int ptr,sptr;
|
||
int ptr;
|
||
SavePosition(); /* 'cause TEXT...,E screws up position! */
|
||
ptr=0;
|
||
// sptr=0;
|
||
while (ptr < tstr.Length)
|
||
// while(ptr < txt.Length)
|
||
{
|
||
if ("`<60><><EFBFBD>".IndexOf(tstr[ptr]) >= 0)
|
||
// if("`<60><><EFBFBD>".IndexOf(txt[ptr]) >= 0 )
|
||
{
|
||
string SpecialChar="";
|
||
// int len = 0;
|
||
switch ( (byte)tstr[ptr])
|
||
// switch ( (byte)txt[ptr] )
|
||
{
|
||
case 0x60 : /* backquote */
|
||
case 0xF8 : SpecialChar = "\u00B0"; /* degree symbol */
|
||
break;
|
||
case 0xF2 : SpecialChar= "\u2265"; /* greaterthanequal */
|
||
break;
|
||
case 0xF3 : SpecialChar= "\u2264"; /* lessthanequal */
|
||
break;
|
||
}
|
||
tstr.Remove(ptr,1);
|
||
tstr.Insert(ptr,SpecialChar);
|
||
ptr++;
|
||
// len = txt.Substring(sptr,ptr-sptr).Length;
|
||
// GraphText( txt.Substring(sptr,ptr-sptr),pg,pdf);
|
||
// MoveRelative(len * CWIDEDOTS,0);
|
||
// sptr = ++ptr;
|
||
// GraphText(SpecialChar,pg,pdf);
|
||
// MoveRelative(CWIDEDOTS,0);
|
||
|
||
// //!!! ADD CALLS TO OUTPUT THESE STRINGS
|
||
// MessageBox.Show("ADD CALLS TO OUTPUT SPECIAL CHARS","PrintText()");
|
||
// // fprintf(PRT,graph_PrntStr[2]);
|
||
// // fprintf(PRT,"%c",GraphicChar&0x7F);
|
||
// // fprintf(PRT,graph_PrntStr[3]);
|
||
}
|
||
else
|
||
{
|
||
ptr++;
|
||
}
|
||
}
|
||
GraphText(tstr.ToString(),pg,pdf);
|
||
// if( ptr > sptr ) GraphText( txt.Substring(sptr,ptr-sptr),pg,pdf);
|
||
RecallPosition();
|
||
}
|
||
|
||
void FreeBoxList()
|
||
{
|
||
AllBoxes.Clear();
|
||
}
|
||
|
||
void FreeLineList()
|
||
{
|
||
AllPlots.Clear();
|
||
}
|
||
|
||
// void FreePointList(PointList ptr)
|
||
// {
|
||
// PointListArray.Clear();
|
||
// // struct PointList *bptr,*nptr;
|
||
// // bptr=ptr;
|
||
// // while(bptr)
|
||
// // {
|
||
// // nptr=bptr->NextPoint;
|
||
// // Zfree(&bptr->APoint);
|
||
// // Zfree(&bptr);
|
||
// // bptr=nptr;
|
||
// // }
|
||
// }
|
||
|
||
void Init_Graphic_Vars()
|
||
{
|
||
int i;
|
||
SavedX = new int[MAX_XY_STACK];
|
||
SavedY = new int[MAX_XY_STACK];
|
||
LinesUsed=0; /* Number lines used by graph, in dots */
|
||
Visible=1;
|
||
ShadowFlag = 0;
|
||
// _setmem(valuestring,100,'\0');
|
||
// _setmem(powerstring,100,'\0');
|
||
CurPenWidth = 0;
|
||
DrawDirection = -1;
|
||
AxisTitles[X] = null;
|
||
AxisTitles[Y] = null;
|
||
AxisLabel[0] = 1;
|
||
AxisLabel[1] = 1;
|
||
EndFlag=0;
|
||
for (i=0;i<Dimensions;i++)
|
||
{
|
||
Scale[0,i] = 0;
|
||
Scale[1,i] =0;
|
||
Offset[0,i] = 0;
|
||
Offset[1,i] =0;
|
||
delta[i]=0;
|
||
cycles[i]=0;
|
||
onecycle[i]=0;
|
||
minor[i]=0;
|
||
}
|
||
}
|
||
|
||
void DrawLineTo(point pnt, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
int x1,y1,x2,y2;
|
||
int nd,x,y,i;
|
||
long ddx,ddy,dx,dy;
|
||
x1=Position[X];
|
||
y1=Position[Y];
|
||
x2=pnt.xyValue[X];
|
||
y2=pnt.xyValue[Y];
|
||
if(LineDiv != 0)
|
||
{
|
||
nd=LineDiv*4;
|
||
dx=x2-x1;
|
||
dy=y2-y1;
|
||
for(i=1;i<=nd;i++)
|
||
{
|
||
ddx=dx*i;
|
||
ddy=dy*i;
|
||
x=(int)(x1+ddx/nd);
|
||
y=(int) (y1+ddy/nd);
|
||
if((i&2)!= 0)
|
||
MoveAbsolute(x,y);
|
||
else
|
||
DrawAbsolute(x,y,pg,pdf);
|
||
}
|
||
}
|
||
else
|
||
DrawTo(pnt,pg,pdf);
|
||
}
|
||
|
||
void BlockRelative(int dx,int dy,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
pdf.FillRectangle(Brushes.Black,Position[X],Position[Y],dx,dy);
|
||
}
|
||
|
||
void BoxRelative(int dx, int dy, int LineWidth, VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
VG_Rect vgrec = new VG_Rect(Position[X],Position[Y],dx,dy,LineWidth,pg);
|
||
vgrec.ToPdf(pdf);
|
||
}
|
||
|
||
void GraphText(string txt,VG.Page pg, C1.C1Pdf.C1PdfDocument pdf)
|
||
{
|
||
// Look for a Superscript or Subsript.
|
||
// - break up the string (if needed) and change the font pitch
|
||
// for the text that is to be super/subscripted
|
||
VG_Text drawText;
|
||
string tstr = "";
|
||
int Xpos, Ypos;
|
||
int sidx = 0; // beginning of string
|
||
int idx =0; // current position in string
|
||
Xpos = Position[X];
|
||
Ypos = Position[Y];
|
||
while (idx < txt.Length)
|
||
{
|
||
int tidx;
|
||
if ((tidx = txt.IndexOf(SuperScript[0],idx)) > -1)
|
||
{
|
||
// print text up to the superscript
|
||
tstr = txt.Substring(sidx,tidx-sidx);
|
||
drawText = new VG_Text(Xpos,Ypos,(int)FontPitch,tstr,"Letter Gothic","","","",pg);
|
||
drawText.ToPdf(pdf);
|
||
Xpos+= (CWIDEDOTS * tstr.Length);
|
||
tidx+= SuperScript[0].Length;
|
||
idx = tidx;
|
||
sidx = idx;
|
||
tidx = txt.IndexOf(SuperScript[1],idx);
|
||
if (tidx > 0)
|
||
{
|
||
// switch font pitch, move up some, and print the superscript text
|
||
tstr = txt.Substring(sidx,tidx - sidx);
|
||
// Xpos+= (CWIDEDOTS * tstr.Length);
|
||
Ypos -= (CHIGHDOTS / 2); // move up half a char heigth
|
||
drawText = new VG_Text(Xpos,Ypos,(int)(FontPitch/2),tstr,"Letter Gothic","","","",pg);
|
||
drawText.ToPdf(pdf);
|
||
Ypos += (CHIGHDOTS / 2); // move back down
|
||
Xpos += ((CWIDEDOTS/2) * tstr.Length); // positon half the width of the string
|
||
tidx += SuperScript[1].Length;
|
||
idx = tidx;
|
||
sidx = idx;
|
||
continue; // go back to beginning of while loop
|
||
}
|
||
}
|
||
else if ((tidx = txt.IndexOf(SubScript[0],idx)) > -1)
|
||
{
|
||
// print text up to the superscript
|
||
tstr = txt.Substring(sidx,tidx-sidx);
|
||
drawText = new VG_Text(Xpos,Ypos,(int)FontPitch,tstr,"Letter Gothic","","","",pg);
|
||
drawText.ToPdf(pdf);
|
||
Xpos+= (CWIDEDOTS * tstr.Length);
|
||
tidx+= SubScript[0].Length;
|
||
idx=tidx;
|
||
sidx = idx;
|
||
tidx = txt.IndexOf(SubScript[1],idx);
|
||
if (tidx > 0)
|
||
{
|
||
// switch font pitch, move up some, and print the superscript text
|
||
tstr = txt.Substring(sidx,tidx - sidx);
|
||
// Xpos+= (CWIDEDOTS * tstr.Length);
|
||
// Ypos += (CHIGHDOTS / 2); // move down half a char heigth
|
||
drawText = new VG_Text(Xpos,Ypos,(int)(FontPitch/2),tstr,"Letter Gothic","","","",pg);
|
||
drawText.ToPdf(pdf);
|
||
// Ypos -= (CHIGHDOTS / 2); // move back up
|
||
Xpos += ((CWIDEDOTS/2) * tstr.Length); // positon half the width of the string
|
||
tidx += SubScript[1].Length;
|
||
idx = tidx;
|
||
sidx = idx;
|
||
continue; // go back to beginning of while loop
|
||
}
|
||
}
|
||
else
|
||
{
|
||
idx++;
|
||
}
|
||
} // end while
|
||
|
||
if (sidx < txt.Length)
|
||
{
|
||
tstr = txt.Substring(sidx);
|
||
drawText = new VG_Text(Xpos,Ypos,(int)FontPitch,tstr,"Letter Gothic","","","",pg);
|
||
drawText.ToPdf(pdf);
|
||
}
|
||
}
|
||
|
||
|
||
// public XYPlot()
|
||
// {
|
||
// //
|
||
// // TODO: Add constructor logic here
|
||
// //
|
||
// AxisLabel[0] = 1;
|
||
// AxisLabel[1] = 1;
|
||
// }
|
||
|
||
public XYPlot(string fname, string PdfFileName)
|
||
{
|
||
char Command, PrevCommand = ' ';
|
||
Init_Graphic_Vars();
|
||
LoadBuff(fname);
|
||
FixBuffIfNeeded();
|
||
GetScaleInfo();
|
||
|
||
C1.C1Pdf.C1PdfDocument c1pdf = new C1.C1Pdf.C1PdfDocument();
|
||
c1pdf.FontType = C1.C1Pdf.FontTypeEnum.Embedded; // embed fonts
|
||
|
||
VG.Page pg = new Page(true,(float)(1440),(float)(1440));
|
||
|
||
while ((Command = char.ToUpper(getchr())) != '\0')
|
||
{
|
||
LineDiv = 0;
|
||
LineFlag = CURVE;
|
||
ShadowFlag = 0;
|
||
switch (Command)
|
||
{
|
||
case 'T':
|
||
ShadowFlag+=2; // 2 for no box
|
||
GetBoxParameters();
|
||
break;
|
||
case 'W':
|
||
ShadowFlag++; // 1 for shadow box
|
||
GetBoxParameters();
|
||
break;
|
||
case 'B':
|
||
GetBoxParameters(); // 0 for box
|
||
break;
|
||
case 'D':
|
||
LineDiv = getint();
|
||
LineFlag = STRAIGHT;
|
||
GetLineParameters();
|
||
break;
|
||
case 'L':
|
||
LineFlag = STRAIGHT;
|
||
GetLineParameters();
|
||
break;
|
||
case 'C':
|
||
GetLineParameters();
|
||
break;
|
||
case 'X':
|
||
GetAxisTitle(X);
|
||
break;
|
||
case 'Y':
|
||
GetAxisTitle(Y);
|
||
break;
|
||
case 'Z':
|
||
YLandScape = 1;
|
||
YTitleOrigin = GetPair(USER);
|
||
GetAxisTitle(Y);
|
||
break;
|
||
case 'A':
|
||
AxisLabel[0] = getint();
|
||
AxisLabel[1] = getint();
|
||
break;
|
||
default:
|
||
if (PrevCommand.Equals(null))
|
||
MessageBox.Show("Check the first line of the X/Y Plot definition.","Unrecognized Graph Command");
|
||
else
|
||
MessageBox.Show(string.Format("Problem with the X/Y Plot Command after {0}",PrevCommand.ToString()),"Unrecognized Graph Command");
|
||
// sprintf(LineBuff,"Unrecognized Graph Command: '%c'",command);
|
||
// err_exit(LineBuff,0);
|
||
break;
|
||
}
|
||
PrevCommand = Command;
|
||
}
|
||
Graphics(1);
|
||
GenerateGrid(pg,c1pdf);
|
||
DoAxisTitles(pg,c1pdf);
|
||
DoBoxes(pg,c1pdf);
|
||
DrawLines(pg,c1pdf);
|
||
Graphics(0);
|
||
c1pdf.Save(PdfFileName);
|
||
FreeBoxList();
|
||
FreeLineList();
|
||
|
||
CloseGraph();
|
||
// return(LinesUsed);
|
||
}
|
||
}
|
||
|
||
}
|