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 description for XYPlot. /// 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\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 ("`øòó".IndexOf(tstr[ptr]) >= 0) // if("`øòó".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 -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); } } }