/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ /*********************************************************************/ #include #include #include #include #include #include #include "plot.h" struct legendargstruct { int islabel ; char *label; int ismark ; int scatter ; char *mark; }; struct plotargstruct { int ismark; char *mark; int markevery; float markscale; int scatter; }; struct arg { Object ino; int needtoclip; Point clippoint1; Point clippoint2; float epsilonx; float epsilony; float xlog; float ylog; int mark; char *marker; int markevery; float markscale; int scatter; }; static RGBColor DEFAULTTICCOLOR = {1.0, 1.0, 0.0}; static RGBColor DEFAULTLABELCOLOR = {1.0, 1.0, 1.0}; static RGBColor DEFAULTAXESCOLOR = {1.0, 1.0, 0.0}; static RGBColor DEFAULTGRIDCOLOR = {0.3, 0.3, 0.3}; static RGBColor DEFAULTBACKGROUNDCOLOR = {0.05, 0.05, 0.05}; static Error GetPlotHeight(Object, int, float *, float *, float *); extern Object _dxfFieldWithInformation(Object); extern Error _dxfFreeAxesHandle(Pointer); extern Pointer _dxfNew2DAxesObject(void); extern Error _dxfLowerCase(char *, char **); extern Error _dxfSet2DAxesCharacteristic(Pointer, char *, Pointer); extern Error _dxfGetAnnotationColors(Object, Object, RGBColor, RGBColor, RGBColor, RGBColor, RGBColor, RGBColor *, RGBColor *, RGBColor *, RGBColor *, RGBColor *, int *); extern int _dxfHowManyTics(int, int, float, float, float, float, int, int *, int *); extern Object _dxfAxes2D(Pointer); extern Error _dxfHowManyStrings(Object, int *); static Error plottask(Pointer); static Error DoPlot(Object,int,Point,Point,float,float, int, int, struct plotargstruct *); static Error DrawLine(Array, Array, int *, int *, int, float, float, int, RGBColor, Array); static Error DrawDashed(Array, Array, int *, int *, int, float, float, float, float, float, float, float, float *, int *); static Error PlotDepPositions(struct arg *); static Error PlotDepConnections(struct arg *); static Object MakeLabel(char *, RGBColor, int, float *, float, Object, int, int, char *, RGBColor); static Error MakeLegend(Object, Object, int *, float *, float, Object, struct legendargstruct *, RGBColor); static Error DoPlotField(Object,int,Point,Point,float, float, int, int, struct plotargstruct *); static Error GetLineColor(Object, RGBColor *); static Error AddX(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddStar(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddTri(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddSquare(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddCircle(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddDiamond(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddDot(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); static Error AddPoint(Array, int *, Array, int *, float, float, float, float, int, RGBColor, Array); #define E .0001 /* fuzz */ #define EPS_SCALE 80 /* reduction for markers*/ #define FFLOOR(x) ((x)+E>0? (int)((x)+E) : (int)((x)+E)-1) /* fuzzy floor */ #define FCEIL(x) ((x)-E>0? (int)((x)-E)+1 : (int)((x)-E)) /* fuzzy ceiling */ #define FLOOR(x) (x)>0? (int)(x) : (int)((x)-1) /* floor */ #define CEIL(x) (x)>0? (int)((x)+1) : (int)(x) /* ceiling */ #define MIN(a,b) (a>b ? b : a) #define ABS(x) (((x) < 0.0) ? (- (x)) : (x)) static RGBColor DEFAULTCOLOR = {1.0, 1.0, 1.0}; static char nullstring[11] = "NULLSTRING"; /* this is a circle */ Point pointsarray[]={ 1.00, 0.00, 0.00, 0.81, 0.59, 0.00, 0.31, 0.95, 0.00, -0.31, 0.95, 0.00, -0.81, 0.59, 0.00, -1.00, 0.00, 0.00, -0.81, -0.59, 0.00, -0.31, -0.95, 0.00, 0.31, -0.95, 0.00, 0.81, -0.59, 0.00 }; m_Plot(Object *in, Object *out) { Pointer *axeshandle=NULL; int i, adjust, resolution, ticks, ticks2, tx, ty, tz, num, background; int needtoclip=0, frame; float floatzero=0.0, floatone=1.0, labelscale=1.0; int xlog, ylog, ylog2, secondplot, intzero=0, intone=1; int numtickitems, rank, shape[32], *ticks_ptr, *ticks2_ptr, autoadjust; float aspect, ascent, descent, maxstring, cp[4], cp2[2], *actualcorners=NULL; float linepositionx, linepositiony, linelength, *ptr; float mindata, maxdata, minpos, maxpos; float minplotdata, maxplotdata, minplotpos, maxplotpos; float minplotdata2, maxplotdata2; float scalingx, scalingy; Object legendscreen=NULL, subin, scaled=NULL; Object ino=NULL, ino2=NULL, font=NULL, legend=NULL; Object olegend=NULL, outlegend=NULL, legendo=NULL; Object newcorners=NULL, newcorners2=NULL; int givencorners, givencorners2; Object tmpino=NULL, tmpino2=NULL; Group group=NULL; Field emptyfield=NULL; Matrix matrix, translation1, translation2, xform, scaling, transformation; Point up, box[8], min, max, min2, max2, clippoint1, clippoint2; Object outgroup=NULL, outlabels; float xwidth, ywidth, ywidth2, camwidth; char window[8], *labelx, *labely, *labely2, *labelz, fmt[30], *fontname; char *aspectstring; Class class; float buffer[4]; int bufferint[3], grid, mark, markevery; Object withaxes=NULL, withaxes2=NULL; Type type; char *plottypex, *plottypey, *plottypey2; char ptypex[30], ptypey[30], ptypey2[30]; char marker[30], plotlabel[60]; float markscale; Category category; float xscaling, yscaling, yscaling2, epsilon, epsilonx, epsilony; RGBColor ticcolor, labelcolor, axescolor, gridcolor, backgroundcolor; float *xptr=NULL, *list_ptr; Array xticklocations=NULL, yticklocations=NULL, y1ticklocations=NULL; int numlist, dofixedfontsize=0; float fixedfontsize=0.1; struct legendargstruct legendarg; struct plotargstruct plotarg; strcpy(marker, ""); strcpy(plotlabel,""); legendarg.islabel=0; legendarg.label=plotlabel; legendarg.ismark=0; legendarg.mark=marker; legendarg.scatter=0; plotarg.ismark = 0; plotarg.mark = marker; plotarg.markevery = 1; plotarg.markscale = 1; plotarg.scatter = 0; /* note: attributes (such as markers) might be set at the composite * field level. Therefore attributes should be checked for at each * level of recursion, and if found, passed down */ outlabels=NULL; if (!in[0]) { DXSetError(ERROR_BAD_PARAMETER, "#10000","input"); goto error; } if (!_dxfFieldWithInformation(in[0])) { out[0] = in[0]; return OK; } if (!(class=DXGetObjectClass(in[0]))) return ERROR; if ((class != CLASS_GROUP)&& (class != CLASS_FIELD)&&(class != CLASS_XFORM)) { DXSetError(ERROR_BAD_PARAMETER,"#10190","input"); return ERROR; } if (!in[1]) { labelx = "x"; labely = "y"; } else { if (!DXExtractNthString(in[1], 0, &labelx)) { DXSetError(ERROR_BAD_PARAMETER, "#10204", "labels", 2); goto error; } if (!DXExtractNthString(in[1], 1, &labely)) { DXSetError(ERROR_BAD_PARAMETER, "#10204", "labels", 2); goto error; } if (DXExtractNthString(in[1], 2, &labelz)) { DXSetError(ERROR_BAD_PARAMETER, "#10204", "labels", 2); goto error; } } ticks = tx = ty = tz = 0; if (!in[2]) { ticks = 10; } else { if (!(DXGetObjectClass(in[2])==CLASS_ARRAY)) { DXSetError(ERROR_BAD_PARAMETER, "#10012", "ticks", 2); goto error; } if (!DXGetArrayInfo((Array)in[2], &numtickitems, &type, &category, &rank, shape)) { goto error; } if ((type!=TYPE_INT) || (category !=CATEGORY_REAL)) { DXSetError(ERROR_BAD_PARAMETER,"#10012","ticks", 2); goto error; } if (! ((rank == 0) || ((rank == 1)&&(shape[0]=1)))) { DXSetError(ERROR_BAD_PARAMETER,"#10012","ticks", 2); goto error; } if (numtickitems == 1) { if (!DXExtractInteger(in[2], &ticks)) { DXSetError(ERROR_BAD_PARAMETER,"#10012","ticks", 2); goto error; } } else if (numtickitems == 2) { ticks_ptr = (int *)DXGetArrayData((Array)in[2]); tx = ticks_ptr[0]; ty = ticks_ptr[1]; tz = 0.0; } else { DXSetError(ERROR_BAD_PARAMETER,"#10012", "ticks", 2); goto error; } } givencorners = 0; if (in[3]) { givencorners = 1; if (!DXExtractParameter(in[3], TYPE_FLOAT, 2, 2, (Pointer)cp)) { class = DXGetObjectClass(in[3]); if ((class != CLASS_FIELD)&& (class != CLASS_GROUP)) { DXSetError(ERROR_BAD_PARAMETER,"#10013", "corners", 2, 2); goto error; } else { if (!(DXStatistics(in[3], "positions", &minpos, &maxpos, NULL, NULL))){ DXAddMessage("invalid corners object"); goto error; } if (!(DXStatistics(in[3], "data", &mindata, &maxdata, NULL, NULL))){ DXAddMessage("invalid corners object"); goto error; } cp[0] = minpos; cp[1] = mindata; cp[2] = maxpos; cp[3] = maxdata; minplotpos = cp[0]; maxplotpos = cp[2]; minplotdata = cp[1]; maxplotdata = cp[3]; } } } /* good idea to check now if there's another plot */ secondplot = 0; if (in[13]) { /* we have a second plot to put in the first one */ secondplot = 1; class = DXGetObjectClass(in[13]); if ((class != CLASS_GROUP)&& (class != CLASS_FIELD)&&(class != CLASS_XFORM)) { DXSetError(ERROR_BAD_PARAMETER,"#10190", "input2"); return ERROR; } /* assume that the limits will be different */ needtoclip=1; /* make a group to hold both sets of lines, to get all the labels */ group = DXNewGroup(); if (!group) goto error; /* DXReference(in[0]); */ if (!DXSetMember(group,NULL,in[0])) goto error; emptyfield = DXNewField(); DXSetAttribute((Object)emptyfield,"label",(Object)DXNewString(nullstring)); if (!DXSetMember(group,NULL,(Object)emptyfield)) goto error; emptyfield = NULL; if (!DXSetMember(group,NULL,in[13])) goto error; /* get the x positions from the union of the two sets of lines */ if (!(DXStatistics((Object)group,"positions", &minplotpos, &maxplotpos, NULL, NULL))) { goto error; } /* get the y's from only this set */ if (!(DXStatistics(in[0],"data", &minplotdata, &maxplotdata, NULL, NULL))) goto error; if (!givencorners) { cp[0] = minplotpos; cp[1] = minplotdata; cp[2] = maxplotpos; cp[3] = maxplotdata; } givencorners = 1; } else { if (!givencorners) { if (!(DXStatistics(in[0],"positions", &minplotpos, &maxplotpos, NULL, NULL))) goto error; if (!(DXStatistics(in[0],"data", &minplotdata, &maxplotdata, NULL, NULL))) goto error; cp[0] = minplotpos; cp[1] = minplotdata; cp[2] = maxplotpos; cp[3] = maxplotdata; } } adjust =0; if (in[4]) { if (!DXExtractInteger(in[4], &adjust)) { DXSetError(ERROR_BAD_PARAMETER,"#10070", "adjust"); goto error; } if ((adjust != 0)&&(adjust != 1)) { DXSetError(ERROR_BAD_PARAMETER,"#10070", "adjust"); goto error; } } frame = 0; if (in[5]) { if (!DXExtractInteger(in[5], &frame)) { DXSetError(ERROR_BAD_PARAMETER, "#10040", "frame", 0, 2); goto error; } if ((frame < 0) || (frame > 2)) { DXSetError(ERROR_BAD_PARAMETER,"#10040", "frame", 0, 2); goto error; } } if (in[6]) { if (!DXExtractNthString(in[6], 0, &plottypex)) { DXSetError(ERROR_BAD_PARAMETER,"#10205", "type"); goto error; } if (!DXExtractNthString(in[6], 1, &plottypey)) { plottypey = plottypex; } } else { plottypex="lin"; plottypey="lin"; } i= 0; while (i <= 29 && plottypex[i] != '\0') { ptypex[i]= tolower(plottypex[i]); i++; } ptypex[i] = '\0'; i= 0; while (i <= 29 && plottypey[i] != '\0') { ptypey[i]= tolower(plottypey[i]); i++; } ptypey[i] = '\0'; if (!strcmp(ptypex,"log10")) strcpy(ptypex, "log"); if (!strcmp(ptypex,"linear")) strcpy(ptypex, "lin"); if (!strcmp(ptypey,"log10")) strcpy(ptypey, "log"); if (!strcmp(ptypey,"linear")) strcpy(ptypey, "lin"); if (strcmp(ptypex,"lin")&&(strcmp(ptypex,"log"))) { DXSetError(ERROR_BAD_PARAMETER,"#10211", "type", "log, lin"); goto error; } if (strcmp(ptypey,"lin")&&(strcmp(ptypey,"log"))) { DXSetError(ERROR_BAD_PARAMETER,"#10211", "type", "log, lin"); goto error; } if (!strcmp(ptypex,"lin")) xlog = 0; else xlog = 1; if (!strcmp(ptypey,"lin")) ylog = 0; else ylog = 1; if (in[7]) { if (!DXExtractInteger(in[7], &grid)) { DXSetError(ERROR_BAD_PARAMETER,"#10040", "grid", 0, 3); goto error; } if ((grid < 0) || (grid > 3)) { DXSetError(ERROR_BAD_PARAMETER,"#10040", "grid", 0, 3); goto error; } /* if grid is set, adjust should be 1 */ if ((adjust == 0)&&(grid>0)) DXWarning("setting grid sets adjust parameter to be 1"); adjust = 1; } else { grid = 0; } if (in[8]) { if (DXExtractString(in[8], &aspectstring)) { if (strcmp(aspectstring,"inherent")) { DXSetError(ERROR_BAD_PARAMETER, "aspect must be a positive number or the string \'inherent\'"); return ERROR; } /* if there's a second plot, then "inherent" doesn't make sense */ if (!in[13]) autoadjust = 0; else { DXWarning("Because a second plot is specified, inherent is overruled"); autoadjust = 1; aspect = 1.0; } } else { if (!DXExtractFloat(in[8], &aspect)) { DXSetError(ERROR_BAD_PARAMETER, "aspect must be a positive number or the string \'inherent\'"); return ERROR; } if (aspect <= 0.0) { DXSetError(ERROR_BAD_PARAMETER,"#10090", "aspect"); return ERROR; } autoadjust = 1; } } else { aspect = 1.0; autoadjust = 1; } /* in[9] is the colors list */ /* in[10] is the color objects list */ if (!_dxfGetAnnotationColors(in[9], in[10], DEFAULTTICCOLOR, DEFAULTLABELCOLOR, DEFAULTAXESCOLOR, DEFAULTGRIDCOLOR, DEFAULTBACKGROUNDCOLOR, &ticcolor, &labelcolor, &axescolor, &gridcolor, &backgroundcolor, &background)) goto error; /* label scale */ if (in[11]) { if (!DXExtractFloat(in[11], &labelscale)) { DXSetError(ERROR_BAD_PARAMETER,"#10090", "labelscale"); goto error; } if (labelscale < 0) { DXSetError(ERROR_BAD_PARAMETER,"#10090", "labelscale"); goto error; } } if (in[12]) { if (!DXExtractString(in[12], &fontname)) { DXSetError(ERROR_BAD_PARAMETER,"#10200","font"); goto error; } } else { fontname = "standard"; } if (in[14]) { /* label */ if (!secondplot) { DXWarning("label2 specified without input2"); } if (!DXExtractString(in[14], &labely2)) { DXSetError(ERROR_BAD_PARAMETER,"#10200", "label2"); goto error; } } else { labely2 = "y2"; } if (in[15]) { /*ticks*/ if (!secondplot) { DXWarning("ticks2 specified without input2"); } if (!DXExtractInteger(in[15], &ticks2)) { DXSetError(ERROR_BAD_PARAMETER,"#10030", "ticks2"); goto error; } } else { ticks2 = 5; } givencorners2 = 0; if (in[16]) { if (!secondplot) { DXWarning("corners2 specified without input2"); } givencorners2 = 1; if (!DXExtractParameter(in[16], TYPE_FLOAT, 2, 1, (Pointer)cp2)) { class = DXGetObjectClass(in[16]); if ((class != CLASS_FIELD)&& (class != CLASS_GROUP)) { DXSetError(ERROR_BAD_PARAMETER,"#10014", "corners2", 2); goto error; } else { if (!(DXStatistics(in[16], "data", &mindata, &maxdata, NULL, NULL))){ DXAddMessage("invalid corners2 object"); goto error; } cp2[0] = mindata; cp2[1] = maxdata; minplotdata2 = mindata; maxplotdata2 = maxdata; } } } else { if (secondplot) { if (!(DXStatistics(in[13], "data", &minplotdata2, &maxplotdata2,NULL, NULL))){ goto error; } } } if (in[17]) { if (!secondplot) { DXWarning("type2 specified without input2"); } if (!DXExtractNthString(in[17], 0, &plottypey2)) { DXSetError(ERROR_BAD_PARAMETER,"#10200", "type2"); goto error; } } else { plottypey2="lin"; } if (secondplot) { i= 0; while (i <= 29 && plottypey2[i] != '\0') { ptypey2[i]= tolower(plottypey2[i]); i++; } ptypey2[i] = '\0'; if (!strcmp(ptypey2,"log10")) strcpy(ptypey2, "log"); if (!strcmp(ptypey,"linear")) strcpy(ptypey2, "lin"); if (strcmp(ptypey2,"lin")&&(strcmp(ptypey2,"log"))) { DXSetError(ERROR_BAD_PARAMETER,"#10203", "type2", "log, lin"); goto error; } if (!strcmp(ptypey2,"lin")) ylog2 = 0; else ylog2 = 1; } /* If specified, these should override the corners and the tics params */ /* user-forced xtic locations */ if (in[18]) { if (!(DXGetObjectClass(in[18])==CLASS_ARRAY)) { DXSetError(ERROR_BAD_PARAMETER,"xlocations must be a scalar list"); return ERROR; } if (!_dxfCheckLocationsArray(in[18], &num, &xptr)) goto error; /* cp[0]=xptr[0]; cp[2]=xptr[num-1]; XXX */ DXFree((Pointer)xptr); xptr = NULL; xticklocations = (Array)in[18]; } if (in[19]) { if (!(DXGetObjectClass(in[19])==CLASS_ARRAY)) { DXSetError(ERROR_BAD_PARAMETER,"y1locations must be a scalar list"); return ERROR; } if (!_dxfCheckLocationsArray(in[19], &num, &xptr)) goto error; /* cp[1]=xptr[0]; cp[3]=xptr[num-1]; */ DXFree((Pointer)xptr); xptr = NULL; yticklocations = (Array)in[19]; } if (in[20]) { if (!(DXGetObjectClass(in[20])==CLASS_ARRAY)) { DXSetError(ERROR_BAD_PARAMETER,"y2locations must be a scalar list"); return ERROR; } if (!_dxfCheckLocationsArray(in[20], &num, &xptr)) goto error; /* cp2[0]=xptr[0]; cp2[1]=xptr[num-1]; */ DXFree((Pointer)xptr); xptr = NULL; y1ticklocations = (Array)in[20]; } if (in[21]) { if (!(DXGetObjectClass(in[21])==CLASS_ARRAY)) { DXSetError(ERROR_BAD_PARAMETER,"xlabels must be a string list"); return ERROR; } if (!DXGetArrayInfo((Array)in[21], &numlist, NULL, NULL, NULL, NULL)) goto error; if (!in[18]) { /* need to make an array to use. It will go from 0 to n-1 */ xticklocations = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 0); if (!xticklocations) goto error; list_ptr = DXAllocate(numlist*sizeof(float)); if (!list_ptr) goto error; for (i=0; iino; xlog = arg->xlog; ylog = arg->ylog; clippoint1 = arg->clippoint1; clippoint2 = arg->clippoint2; if (!(adata = (Array)DXGetComponentValue((Field)ino, "data"))) { DXSetError(ERROR_BAD_PARAMETER,"#10240", "input","data"); goto error; } if (DXGetComponentAttribute((Field)ino, "data", "dep")) strcpy(depatt,DXGetString((String)DXGetComponentAttribute((Field)ino, "data","dep"))); else { DXSetError(ERROR_INVALID_DATA,"data component is missing dep attribute"); goto error; } handle = DXCreateInvalidComponentHandle(ino,NULL,depatt); if (!handle) goto error; if (ylog) { /* change the clippoint */ if ((clippoint1.y > 0.0)&&(clippoint2.y > 0.0)) { clippoint1.y = log10(clippoint1.y); clippoint2.y = log10(clippoint2.y); } else { DXSetError(ERROR_INVALID_DATA,"#10531", "for log plot, corners"); goto error; } arg->clippoint1 = clippoint1; arg->clippoint2 = clippoint2; /* make a new data array */ DXGetArrayInfo(adata,&numitems, &type, &category, &rank, shape); if (!((rank==0)||((rank==1)&&(shape[0]=1)))) { DXSetError(ERROR_INVALID_DATA,"#10081", "data component"); goto error; } if (category != CATEGORY_REAL) { DXSetError(ERROR_INVALID_DATA, "data component must be category real"); goto error; } /* if it's log, the data component has got to end up as float */ if (ylog) adatanew = DXNewArrayV(TYPE_FLOAT,category,rank,shape); else adatanew = DXNewArrayV(type,category,rank,shape); if (!DXAddArrayData(adatanew,0,numitems,NULL)) goto error; new_ptr = (float *)DXGetArrayData(adatanew); switch (type) { case (TYPE_UBYTE): old_ubyte_ptr = (unsigned char *)DXGetArrayData(adata); break; case (TYPE_SHORT): old_short_ptr = (short *)DXGetArrayData(adata); break; case (TYPE_INT): old_int_ptr = (int *)DXGetArrayData(adata); break; case (TYPE_FLOAT): old_ptr = (float *)DXGetArrayData(adata); break; case (TYPE_DOUBLE): old_double_ptr = (double *)DXGetArrayData(adata); break; case (TYPE_BYTE): old_byte_ptr = (byte *)DXGetArrayData(adata); break; case (TYPE_USHORT): old_ushort_ptr = (ushort *)DXGetArrayData(adata); break; case (TYPE_UINT): old_uint_ptr = (uint *)DXGetArrayData(adata); break; default: DXSetError(ERROR_INVALID_DATA,"#11829", "data"); goto error; } for (i=0; i0.0) new_ptr[i] = log10((float)old_short_ptr[i]); else { DXSetError(ERROR_INVALID_DATA, "#11860", "data"); goto error; } break; case (TYPE_INT): if (old_int_ptr[i]>0.0) new_ptr[i] = log10((float)old_int_ptr[i]); else { DXSetError(ERROR_INVALID_DATA, "#11860", "data"); goto error; } break; case (TYPE_FLOAT): if (old_ptr[i] > 0.0) new_ptr[i] = log10(old_ptr[i]); else { DXSetError(ERROR_INVALID_DATA, "#11860", "data"); goto error; } break; case (TYPE_DOUBLE): if (old_double_ptr[i]>0.0) new_ptr[i] = log10((float)old_double_ptr[i]); else { DXSetError(ERROR_INVALID_DATA, "#11860", "data"); goto error; } break; case (TYPE_BYTE): if (old_byte_ptr[i]>0.0) new_ptr[i] = log10((float)old_byte_ptr[i]); else { DXSetError(ERROR_INVALID_DATA, "#11860", "data"); goto error; } break; case (TYPE_USHORT): new_ptr[i] = log10((float)old_ushort_ptr[i]); break; case (TYPE_UINT): new_ptr[i] = log10((float)old_uint_ptr[i]); break; default: DXSetError(ERROR_INVALID_DATA,"#11829", "data"); goto error; } } else { new_ptr[i] = 0.0; } } DXSetComponentValue((Field)ino,"data",(Object)adatanew); arg->ino = ino; adatanew=NULL; } if (xlog) { /* change the clippoint */ if ((clippoint1.x > 0.0)&&(clippoint2.x > 0.0)) { clippoint1.x = log10(clippoint1.x); clippoint2.x = log10(clippoint2.x); } else { DXSetError(ERROR_INVALID_DATA,"#10531", "for log plot, corners"); goto error; } arg->clippoint1 = clippoint1; arg->clippoint2 = clippoint2; /* make a new positions array */ apos = (Array)DXGetComponentValue((Field)ino,"positions"); if (!apos) { DXSetError(ERROR_MISSING_DATA,"#10250", "input","positions"); goto error; } DXGetArrayInfo(apos,&numitems, &type, &category, &rank, shape); if (!((rank==0)||((rank==1)&&(shape[0]=1)))) { DXSetError(ERROR_INVALID_DATA, "#11363", "positions component", 1); goto error; } if ((type != TYPE_FLOAT)||(category != CATEGORY_REAL)) { DXSetError(ERROR_INVALID_DATA, "positions component must be type float category real"); goto error; } aposnew = DXNewArrayV(type,category,rank,shape); if (!DXAddArrayData(aposnew,0,numitems,NULL)) goto error; new_ptr = (float *)DXGetArrayData(aposnew); old_ptr = (float *)DXGetArrayData(apos); for (i=0; i0.0) new_ptr[i] = log10(old_ptr[i]); else { DXSetError(ERROR_INVALID_DATA, "#10531", "for log plot, positions"); goto error; } } else { new_ptr[i]=0.0; } } DXSetComponentValue((Field)ino,"positions",(Object)aposnew); arg->ino = ino; aposnew=NULL; } if (!(DXGetString((String)DXGetComponentAttribute((Field)ino, "data","dep")))){ DXSetError (ERROR_INVALID_DATA, "#10241", "data"); goto error; } strcpy(depatt,DXGetString((String)DXGetComponentAttribute((Field)ino, "data","dep"))); if (!strcmp(depatt,"connections")) { if (!PlotDepConnections(arg)) goto error; } else if (!strcmp(depatt,"positions")) { if (!PlotDepPositions(arg)) goto error; } else { DXSetError(ERROR_INVALID_DATA,"#11250", "data"); goto error; } DXDelete((Object)adatanew); DXDelete((Object)aposnew); DXFreeInvalidComponentHandle(handle); return OK; error: DXDelete((Object)adatanew); DXDelete((Object)aposnew); DXFreeInvalidComponentHandle(handle); return ERROR; } static Error PlotDepConnections(struct arg *arg) { Array apos, acolors, aposnew, aconnew, acolorsnew, adata; Array acon, colormap; Array invalid; InvalidComponentHandle invalidhandle=NULL; Type colorstype; Category category; int splat = 0, mark = 0, markevery = 1, markcount = 0, rank, shape[32]; char lineatt[30], *marker, coldepatt[30]; float *p_pos, *p_posnew; float *p_data_f; int *p_data_i; uint *p_data_ui; short *p_data_s; ushort *p_data_us; ubyte *p_data_ub; byte *p_data_b; double *p_data_d; Type type; float dataval; int *dp_conn, numitems; int poscount, datacount, conncount, i, needtoclip, count_p, count_c; int thisok, thisquadok,lastok, clipregcolors; int nooutput=0; RGBColor defaultcolor, *color_ptr, color, origin; Point clippoint1, clippoint2, newpoint; Line newcon; Quadrilateral newconquad; Object ino; float epsilonx, epsilony; char *color_ubyte_ptr; defaultcolor = DEFAULTCOLOR; aposnew=NULL; aconnew=NULL; acolorsnew=NULL; clipregcolors=0; ino = arg->ino; needtoclip = arg->needtoclip; clippoint1 = arg->clippoint1; clippoint2 = arg->clippoint2; epsilonx = arg->epsilonx; epsilony = arg->epsilony; /* check for invalid component */ invalid = (Array)DXGetComponentValue((Field)ino,"invalid connections"); if (invalid) { invalidhandle = DXCreateInvalidComponentHandle((Object)ino,NULL, "connections"); if (!invalidhandle) goto error; } /* extract, typecheck, and get the data from the ``positions'' component */ apos = (Array) DXGetComponentValue((Field)ino, "positions"); if (!apos) { DXSetError(ERROR_MISSING_DATA, "#10250", "input" ,"positions"); return ERROR; } if ((!DXTypeCheck(apos, TYPE_FLOAT, CATEGORY_REAL, 1, 1))&& (!DXTypeCheck(apos, TYPE_FLOAT, CATEGORY_REAL, 0, NULL))) { DXSetError(ERROR_BAD_TYPE, "#11364", "positions", 1); return ERROR; } p_pos = (float *) DXGetArrayData(apos); /* find out how many positions there are */ if (!(DXGetArrayInfo(apos, &poscount, NULL, NULL, NULL, NULL))) { return ERROR; } /* check the colors component, if present */ if (DXGetComponentValue((Field)ino,"colors")) { if (!(DXGetString((String)DXGetComponentAttribute((Field)ino, "colors","dep")))){ DXSetError (ERROR_INVALID_DATA, "#10241", "colors"); goto error; } strcpy(coldepatt,DXGetString((String)DXGetComponentAttribute((Field)ino, "colors","dep"))); if (strcmp(coldepatt,"connections")) { DXSetError(ERROR_INVALID_DATA, "#10360", "data", "colors"); goto error; } } /* Now make a brand-new positions array. It will be two dimensional */ if (!(aposnew = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 2))) { return ERROR; } /* Now get a pointer to the data component of the input object */ if (!(adata = (Array)DXGetComponentValue((Field)ino, "data"))) { DXSetError(ERROR_BAD_PARAMETER,"#10250", "input", "data"); goto error; } if (!DXGetArrayInfo(adata,NULL, &type,&category,&rank,shape)) goto error; if (!((rank==0) ||((rank==1)&&(shape[0]=1)))) { DXSetError(ERROR_INVALID_DATA,"#11363", "data", 1); goto error; } switch (type) { case (TYPE_UBYTE): if (!(p_data_ub = (ubyte *)DXGetArrayData(adata))) goto error; break; case (TYPE_SHORT): if (!(p_data_s = (short *)DXGetArrayData(adata))) goto error; break; case (TYPE_INT): if (!(p_data_i = (signed int *)DXGetArrayData(adata))) goto error; break; case (TYPE_FLOAT): if (!(p_data_f = (float *)DXGetArrayData(adata))) goto error; break; case (TYPE_DOUBLE): if (!(p_data_d = (double *)DXGetArrayData(adata))) goto error; break; case (TYPE_BYTE): if (!(p_data_b = (byte *)DXGetArrayData(adata))) goto error; break; case (TYPE_USHORT): if (!(p_data_us = (ushort *)DXGetArrayData(adata))) goto error; break; case (TYPE_UINT): if (!(p_data_ui = (uint *)DXGetArrayData(adata))) goto error; break; default: DXSetError(ERROR_INVALID_DATA,"#11829", "data"); goto error; } if (!DXGetArrayInfo(adata, &datacount, NULL, NULL, NULL, NULL)) goto error; if (datacount != (poscount-1)) { DXSetError(ERROR_BAD_PARAMETER, "#11161", "connection-dependent data items", datacount, "(#positions-1)", poscount-1); goto error; } /* if there's an invalid component, we need to check every point */ if (invalid) needtoclip = 1; if (!needtoclip) { if (!(acon = (Array)DXGetComponentValue((Field)ino,"connections"))) { DXSetError(ERROR_INVALID_DATA, "#10251", "data", "connections"); goto error; } if (!(DXGetArrayInfo(acon, &conncount, NULL, NULL, NULL, NULL))) { return ERROR; } /* make quads */ aconnew = (Array)DXNewArray(TYPE_INT,CATEGORY_REAL,1,4); aconnew = DXAddArrayData(aconnew,0,conncount,NULL); if (!acon) return ERROR; dp_conn = (int *)DXGetArrayData(aconnew); for (i=0; i=clippoint1.x && p_pos[i]<=clippoint2.x && p_pos[i+1]>=clippoint1.x && p_pos[i+1]<=clippoint2.x )) { if (acolors && !clipregcolors) { switch (colorstype) { case (TYPE_FLOAT): color = color_ptr[i]; break; case (TYPE_UBYTE): color = color_ptr[(int)color_ubyte_ptr[i]]; break; } if (!DXAddColor((Field)ino, count_c, color)) goto error; } /* now add the current points */ /* XXX mindata? */ newpoint = DXPt(p_pos[i], clippoint1.y, 0.0); if (!DXAddArrayData(aposnew, count_p, 1, (Pointer)&newpoint)) goto error; count_p ++; switch (type) { case (TYPE_UBYTE): dataval = (float)p_data_ub[i]; break; case (TYPE_SHORT): dataval = (float)p_data_s[i]; break; case (TYPE_INT): dataval = (float)p_data_i[i]; break; case (TYPE_FLOAT): dataval = (float)p_data_f[i]; break; case (TYPE_DOUBLE): dataval = (float)p_data_d[i]; break; case (TYPE_BYTE): dataval = (float)p_data_b[i]; break; case (TYPE_USHORT): dataval = (float)p_data_us[i]; break; case (TYPE_UINT): dataval = (float)p_data_ui[i]; break; default: DXSetError(ERROR_INVALID_DATA,"#11829", "data"); goto error; } if (dataval < clippoint1.y) newpoint = DXPt(p_pos[i], clippoint1.y, 0.0); else if (dataval > clippoint2.y) newpoint = DXPt(p_pos[i], clippoint2.y, 0.0); else newpoint = DXPt(p_pos[i], dataval, 0.0); if (!DXAddArrayData(aposnew, count_p, 1, (Pointer)&newpoint)) goto error; count_p ++; newpoint = DXPt(p_pos[i+1], clippoint1.y, 0.0); if (!DXAddArrayData(aposnew, count_p, 1, (Pointer)&newpoint)) goto error; count_p ++; if (dataval < clippoint1.y) newpoint = DXPt(p_pos[i+1], clippoint1.y, 0.0); else if (dataval > clippoint2.y) newpoint = DXPt(p_pos[i+1], clippoint2.y, 0.0); else newpoint = DXPt(p_pos[i+1], dataval, 0.0); if (!DXAddArrayData(aposnew, count_p, 1, (Pointer)&newpoint)) goto error; count_p ++; newconquad = DXQuad(count_p-4, count_p-3, count_p-2, count_p-1); if (!(DXAddArrayData(aconnew, count_c, 1, (Pointer)&newconquad))) goto error; count_c++; } } DXSetComponentValue((Field)ino,"positions",(Object)aposnew); aposnew = NULL; DXSetComponentValue((Field)ino,"connections",(Object)aconnew); aconnew = NULL; DXSetComponentAttribute((Field)ino,"connections","ref", (Object)DXNewString("positions")); DXSetComponentAttribute((Field)ino,"connections","element type", (Object)DXNewString("quads")); if (!clipregcolors) DXSetComponentAttribute((Field)ino,"colors","dep", (Object)DXNewString("connections")); conncount = count_c; if (conncount == 0) nooutput=1; else nooutput =0; } if (nooutput) DXWarning("Plot: corners exclude entire line"); /* check if there's a colors component already */ if ((!(DXGetComponentValue((Field)ino, "colors")))&&(!clipregcolors)) { /* if it doesn't give it one */ acolorsnew = (Array)DXNewConstantArray(conncount, (Pointer)&defaultcolor, TYPE_FLOAT, CATEGORY_REAL, 1, 3); if (!(DXSetComponentValue((Field)ino,"colors",(Object)acolorsnew))) { goto error; } acolorsnew = NULL; if (!(DXSetComponentAttribute((Field)ino,"colors", "dep", (Object)DXNewString("connections")))) { goto error; } } else { if (clipregcolors) { acolorsnew = (Array)DXNewConstantArray(conncount, (Pointer)&origin, TYPE_FLOAT, CATEGORY_REAL, 1, 3); if (!(DXSetComponentValue((Field)ino,"colors",(Object)acolorsnew))) { goto error; } acolorsnew = NULL; if (!(DXSetComponentAttribute((Field)ino,"colors", "dep", (Object)DXNewString("connections")))) { goto error; } } } if (!DXChangedComponentValues((Field)ino,"positions")) goto error; if (!DXChangedComponentValues((Field)ino,"colors")) goto error; if (!DXChangedComponentValues((Field)ino,"connections")) goto error; /* delete the data component because #positions may be different */ DXDeleteComponent((Field)ino,"data"); if (!(DXEndField((Field)ino))) goto error; if (!DXFreeInvalidComponentHandle(invalidhandle)) goto error; return OK; error: DXDelete((Object)aposnew); DXFreeInvalidComponentHandle(invalidhandle); DXDelete((Object)aconnew); DXDelete((Object)acolorsnew); return ERROR; } static Error PlotDepPositions(struct arg *arg) { Object markobject=NULL, linetypeobject=NULL, scatterobject=NULL; Array apos, acolors, aposnew, aconnew, acolorsnew, adata; Array acon; Array colormap; Array invalid; InvalidComponentHandle invalidhandle=NULL; Type type, colorstype, datatype; Category category, datacat; float stepon, stepoff, used=0.0, factor, dataval; int splat = 0, markcount = 0, isline = 1, rank, shape[32],numitems; int datarank, datashape[8]; int lastorigindex=0, lastnewindex=0; char lineatt[30], *linetype="solid", coldepatt[30]; short *p_data_s; ushort *p_data_us; double *p_data_d; byte *p_data_b; ubyte *p_data_ub; float *p_data_f; int *p_data_i; uint *p_data_ui; float *p_pos, *p_posnew, status=0.0, *p_data_old, *p_pos_old; int *dp_conn; int poscount, datacount, conncount, i, needtoclip, count_p, count_c; int thisok, thisquadok,lastok, regcolors; int nooutput=0; RGBColor *color_ptr, color, origin, defaultcolor, *p_colors; char *p_ubyte_colors; Point clippoint1, clippoint2, newpoint; Line newcon; Quadrilateral newconquad; Object ino; float epsilonx, epsilony; int mark, markevery, scatterflag=0; float markscale; char *marker, *label; defaultcolor = DEFAULTCOLOR; aposnew=NULL; aconnew=NULL; acolorsnew=NULL; regcolors=0; ino = arg->ino; needtoclip = arg->needtoclip; clippoint1 = arg->clippoint1; clippoint2 = arg->clippoint2; epsilonx = arg->epsilonx; epsilony = arg->epsilony; mark = arg->mark; markevery = arg->markevery; marker = arg->marker; markscale = arg->markscale; scatterflag = arg->scatter; /* check for an invalid component */ invalid = (Array)DXGetComponentValue((Field)ino, "invalid positions"); if (invalid) { invalidhandle = DXCreateInvalidComponentHandle((Object)ino,NULL, "positions"); if (!invalidhandle) goto error; } stepon = 4*epsilonx; stepoff = stepon/2.0; factor = epsilony/epsilonx; /* extract, typecheck, and get the data from the ``positions'' component */ apos = (Array) DXGetComponentValue((Field)ino, "positions"); if (!apos) { DXSetError(ERROR_MISSING_DATA, "#10250", "input", "positions"); return ERROR; } if ((!DXTypeCheck(apos, TYPE_FLOAT, CATEGORY_REAL, 1, 1))&& (!DXTypeCheck(apos, TYPE_FLOAT, CATEGORY_REAL, 0, NULL))) { DXSetError(ERROR_BAD_TYPE, "#11364", "positions", 1); return ERROR; } /* find out how many positions there are */ if (!(DXGetArrayInfo(apos, &poscount, NULL, NULL, NULL, NULL))) { return ERROR; } p_pos = (float *) DXGetArrayData(apos); /* check the colors component, if present */ if (DXGetComponentValue((Field)ino,"colors")) { if (!(DXGetString((String)DXGetComponentAttribute((Field)ino, "colors","dep")))){ DXSetError (ERROR_INVALID_DATA, "#10241", "colors"); goto error; } strcpy(coldepatt,DXGetString((String)DXGetComponentAttribute((Field)ino, "colors","dep"))); if (strcmp(coldepatt,"positions")) { DXSetError(ERROR_INVALID_DATA, "#10360", "data", "colors"); goto error; } } /* Now make a brand-new positions array. It will be two dimensional */ if (!(aposnew = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 2))) { return ERROR; } /* Now get a pointer to the data component of the input object */ if (!(adata = (Array)DXGetComponentValue((Field)ino, "data"))) { DXSetError(ERROR_BAD_PARAMETER,"#10250", "input","data"); goto error; } if (!DXGetArrayInfo(adata, &datacount, &datatype, &datacat, &datarank, datashape)) goto error; if (datacat != CATEGORY_REAL) { DXSetError(ERROR_INVALID_DATA,"data are not category real"); goto error; } if (!((datarank==0)||((datarank==1)&&(datashape[0]==1)))) { DXSetError(ERROR_INVALID_DATA,"#11363", "data",1); goto error; } switch (datatype) { case (TYPE_UBYTE): if (!(p_data_ub = (ubyte *)DXGetArrayData(adata))) goto error; break; case (TYPE_SHORT): if (!(p_data_s = (short *)DXGetArrayData(adata))) goto error; break; case (TYPE_INT): if (!(p_data_i = (signed int *)DXGetArrayData(adata))) goto error; break; case (TYPE_FLOAT): if (!(p_data_f = (float *)DXGetArrayData(adata))) goto error; break; case (TYPE_DOUBLE): if (!(p_data_d = (double *)DXGetArrayData(adata))) goto error; break; case (TYPE_BYTE): if (!(p_data_b= (byte *)DXGetArrayData(adata))) goto error; break; case (TYPE_USHORT): if (!(p_data_us= (ushort *)DXGetArrayData(adata))) goto error; break; case (TYPE_UINT): if (!(p_data_ui= (uint *)DXGetArrayData(adata))) goto error; break; default: DXSetError(ERROR_INVALID_DATA,"#11829", "data"); goto error; } /* first set things up using the marks coming in from above */ if (mark) splat = 1; /* override if things are set at the field level */ markobject = DXGetAttribute((Object)ino, "mark"); scatterobject = DXGetAttribute((Object)ino,"scatter"); if (scatterobject) { if (!DXExtractInteger(scatterobject, &scatterflag)) { DXSetError(ERROR_INVALID_DATA, "scatter attribute must be 0 or 1"); goto error; } if ((scatterflag!=0)&&(scatterflag!=1)) { DXSetError(ERROR_INVALID_DATA, "scatter attribute must be 0 or 1"); goto error; } } if ((scatterflag == 1)&&(!markobject)) { marker = "x"; splat = 1; } if (markobject) { splat = 1; if (!DXExtractNthString(markobject, 0, &marker)) { DXSetError(ERROR_INVALID_DATA,"#10200", "mark"); goto error; } } if (DXGetAttribute((Object)ino,"mark every")) { if (!DXExtractInteger(DXGetAttribute((Object)ino, "mark every"), &markevery)) { DXSetError(ERROR_INVALID_DATA, "#10020", "mark every attribute"); goto error; } if (markevery < 0) { DXSetError(ERROR_INVALID_DATA, "mark every attribute must non-negative"); goto error; } } if (DXGetAttribute((Object)ino,"mark scale")) { if (!DXExtractFloat(DXGetAttribute((Object)ino, "mark scale"), &markscale)) { DXSetError(ERROR_INVALID_DATA,"#10090", "mark scale attribute"); goto error; } if (markscale <= 0) { DXSetError(ERROR_INVALID_DATA,"#10090", "mark scale attribute"); goto error; } } epsilonx = epsilonx*markscale; epsilony = epsilony*markscale; linetypeobject = DXGetAttribute((Object)ino, "linetype"); if (linetypeobject) { if (!DXExtractNthString(linetypeobject, 0, &linetype)) { DXSetError(ERROR_INVALID_DATA,"#10200", "linetype"); goto error; } } if (strcmp(linetype,"solid")) { DXWarning("Plot: only solid lines supported"); linetype = "solid"; } needtoclip = 1; if (datacount != poscount) { DXSetError(ERROR_BAD_PARAMETER, "#11161", "position-dependent data items", datacount, "number of positions", poscount); goto error; } if (acolors = (Array)DXGetComponentValue((Field)ino, "colors")) { DXGetArrayInfo(acolors, &numitems, &colorstype, &category, &rank, shape); if (!DXQueryConstantArray(acolors,NULL,NULL)) { regcolors = 0; switch (colorstype) { case (TYPE_FLOAT): if ((rank!=1)||(shape[0]!=3)) { DXSetError(ERROR_INVALID_DATA,"#11363", "colors", 3); goto error; } p_colors = (RGBColor *)DXGetArrayData(acolors); break; case (TYPE_UBYTE): if (!((rank==0)||((rank==1)&&(shape[0]==1)))) { DXSetError(ERROR_INVALID_DATA,"#11363", "byte colors", 1); goto error; } p_ubyte_colors = (char *)DXGetArrayData(acolors); colormap = (Array)DXGetComponentValue((Field)ino,"color map"); if (!colormap) { DXSetError(ERROR_MISSING_DATA, "#13050"); goto error; } p_colors = (RGBColor *)DXGetArrayData(colormap); break; default: DXSetError(ERROR_INVALID_DATA,"#11838", "colors component"); goto error; } acolorsnew = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,3); } else { regcolors = 1; DXQueryConstantArray((Array)acolors, NULL, (Pointer)&origin); } } else { /* we'll add the default color */ regcolors = 1; origin = DEFAULTCOLOR; } aconnew = DXNewArray(TYPE_INT,CATEGORY_REAL, 1, 2); count_p = 0; count_c = 0; lastok = 0; thisok = 0; color = DXRGB(0.0, 0.0, 0.0); for (i=0; i=clippoint1.x && p_pos[i]<=clippoint2.x && dataval>=clippoint1.y && dataval<=clippoint2.y) { thisok = 1; if (!regcolors) switch (colorstype) { case (TYPE_FLOAT): color = p_colors[i]; break; case (TYPE_UBYTE): color = p_colors[(int)p_ubyte_colors[i]]; break; } /* now add the current point */ if ((thisok)&&(lastok)) { /* first draw the line from old point to where I am now */ /* only if scatter != 1 */ if (scatterflag != 1) { if (!DrawLine(aconnew, aposnew, &count_c, &count_p, lastnewindex, p_pos[i], dataval, regcolors, color, acolorsnew)) goto error; } } /* else don't draw the line, just the point */ else { newpoint = DXPt(p_pos[i], dataval, 0.0); if (!DXAddArrayData(aposnew, count_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) { if (!DXAddArrayData(acolorsnew, count_p, 1, (Pointer)&color)) goto error; } count_p++; } lastorigindex = i; lastnewindex = count_p-1; if (splat) { if ((markcount % markevery )==0) { if (!strcmp(marker,"x")) { if (!AddX(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony,regcolors,color, acolorsnew )) goto error; } else if (!strcmp(marker,"triangle")) { if (!AddTri(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony,regcolors,color, acolorsnew)) goto error; } else if (!strcmp(marker,"square")) { if (!AddSquare(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony, regcolors, color, acolorsnew)) goto error; } else if (!strcmp(marker,"circle")) { if (!AddCircle(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony, regcolors, color, acolorsnew)) goto error; } else if (!strcmp(marker,"star")) { if (!AddStar(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony, regcolors, color, acolorsnew)) goto error; } else if (!strcmp(marker,"diamond")) { if (!AddDiamond(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony, regcolors, color, acolorsnew)) goto error; } else if (!strcmp(marker,"dot")) { if (!AddDot(aposnew, &count_p, aconnew, &count_c, p_pos[i], dataval, epsilonx, epsilony, regcolors, color, acolorsnew)) goto error; } else if (!strcmp(marker,"")) { } else { DXSetError(ERROR_BAD_PARAMETER,"#10203", "mark", "x, triangle, square, circle, star, dots, diamond"); goto error; } } markcount++; } lastok=1; } else { lastok = 0; } } DXSetComponentValue((Field)ino,"positions",(Object)aposnew); aposnew = NULL; DXSetComponentValue((Field)ino,"connections",(Object)aconnew); aconnew = NULL; DXSetComponentAttribute((Field)ino,"connections","ref", (Object)DXNewString("positions")); DXSetComponentAttribute((Field)ino,"connections","element type", (Object)DXNewString("lines")); poscount = count_p; if (poscount == 0) nooutput=1; else nooutput =0; if (nooutput) { DXWarning("Plot: corners exclude entire line"); DXDelete((Object)ino); ino = (Object)DXNewField(); } /* delete the invalid positions and invalid connections */ DXDeleteComponent((Field)ino,"invalid positions"); DXDeleteComponent((Field)ino,"invalid connections"); /* check if there's a colors component already */ if (regcolors) { acolorsnew = (Array)DXNewConstantArray(poscount, (Pointer)&origin, TYPE_FLOAT, CATEGORY_REAL, 1, 3); if (!(DXSetComponentValue((Field)ino,"colors",(Object)acolorsnew))) { goto error; } acolorsnew = NULL; if (!(DXSetComponentAttribute((Field)ino,"colors", "dep", (Object)DXNewString("positions")))) { goto error; } } else { DXSetComponentValue((Field)ino,"colors", (Object)acolorsnew); acolorsnew = NULL; DXSetComponentAttribute((Field)ino,"colors","dep", (Object)DXNewString("positions")); } if (!DXChangedComponentValues((Field)ino,"positions")) goto error; if (!DXChangedComponentValues((Field)ino,"colors")) goto error; if (!DXChangedComponentValues((Field)ino,"connections")) goto error; if (!DXChangedComponentValues((Field)ino,"invalid connections")) goto error; if (!DXChangedComponentValues((Field)ino,"invalid positions")) goto error; /* delete the data component because #positions may be different */ DXDeleteComponent((Field)ino,"data"); if (!(DXEndField((Field)ino))) goto error; if (!DXFreeInvalidComponentHandle(invalidhandle)) goto error; return OK; error: DXFreeInvalidComponentHandle(invalidhandle); DXDelete((Object)aposnew); DXDelete((Object)aconnew); DXDelete((Object)acolorsnew); return ERROR; } static Error DrawLine(Array aconnew, Array aposnew, int *count_c, int *count_p, int lastindex, float x, float y, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_c; newpoint = DXPt(x, y,0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; if (tmp_p > 0) newcon = DXLn(lastindex, tmp_p); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; tmp_p++; *count_p = tmp_p; *count_c = tmp_c; return OK; error: return ERROR; } static Error DrawDashed(Array aconnew, Array aposnew, int *count_c, int *count_p, int lastindex, float x, float y, float lastx, float lasty, float stepon, float stepoff, float factor, float *used, int *isline) { Point newpoint, direction, lastpoint, endpoint; float tmp_stepon, tmp_stepoff, angle, tmp_used; Line line; int tmp_p, tmp_c, num, i, first = 1; double dist, nextlen, nextdist, fraction; float scalefactor; tmp_p = *count_p; tmp_c = *count_c; lastpoint = DXPt(lastx, lasty, 0.0); endpoint = DXPt(x,y,0.0); dist = sqrt((x-lastx)*(x-lastx) + (y-lasty)*(y-lasty)); if (dist > 0.0) { direction = DXMul(DXPt(x-lastx, y-lasty,0.0), 1.0/dist); angle = atan2(direction.y, direction.x); /* if this thing is going to be scaled, I need to worry about the line lengths; ie. the angle at which they run. Since the scaling will affect the length of the dashes */ scalefactor = ABS(cos(angle)) + factor*(ABS(sin(angle))); tmp_stepon = stepon*scalefactor; tmp_stepoff = stepoff*scalefactor; tmp_used = *used*scalefactor; while (1) { nextdist = DXLength(DXSub(lastpoint, endpoint)); direction = DXMul(DXSub(endpoint,lastpoint), 1.0/nextdist); nextlen = *isline?(tmp_stepon-tmp_used):(tmp_stepoff-tmp_used); *used = 0.0; tmp_used = 0.0; if (nextlen < nextdist) { newpoint = DXAdd(lastpoint, DXMul(direction, nextlen)); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; tmp_p++; lastpoint = newpoint; if (*isline) { line = DXLn(lastindex, tmp_p-1); if (!DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&line)) goto error; tmp_c++; } lastindex = tmp_p-1; *isline = !(*isline); } else { newpoint = endpoint; lastpoint = newpoint; if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; tmp_p++; if (*isline) { line = DXLn(lastindex, tmp_p-1); if (!DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&line)) goto error; tmp_c++; } lastindex = tmp_p-1; goto done; } } } done: *used = nextdist; *count_p = tmp_p; *count_c = tmp_c; return OK; error: return ERROR; } static Error AddDiamond(Array aposnew, int *count_p, Array aconnew, int *count_c, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_c; newpoint = DXPt(x, y-1.2*epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x-1.2*epsilonx, y, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x, y+1.2*epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+1.2*epsilonx, y, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newcon = DXLn(tmp_p-4, tmp_p-3); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-3, tmp_p-2); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-2, tmp_p-1); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-1, tmp_p-4); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_c = tmp_c; return OK; error: return ERROR; } static Error AddSquare(Array aposnew, int *count_p, Array aconnew, int *count_c, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_c; newpoint = DXPt(x-epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x-epsilonx, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newcon = DXLn(tmp_p-4, tmp_p-3); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-3, tmp_p-2); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-2, tmp_p-1); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-1, tmp_p-4); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_c = tmp_c; return OK; error: return ERROR; } static Error AddCircle(Array aposnew, int *count_p, Array aconnew, int *count_c, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c, i; tmp_p = *count_p; tmp_c = *count_c; for (i=0; i< 10; i++) { newpoint = DXPt(x+pointsarray[i].x*epsilonx, y+pointsarray[i].y*epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; } for (i=0; i<9; i++) { newcon = DXLn(tmp_p-10+i, tmp_p-9+i); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; } newcon = DXLn(tmp_p-1, tmp_p-10); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_c = tmp_c; return OK; error: return ERROR; } static Error AddTri(Array aposnew, int *count_p, Array aconnew, int *count_c, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_c; newpoint = DXPt(x, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x-epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newcon = DXLn(tmp_p-3, tmp_p-2); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-2, tmp_p-1); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-1, tmp_p-3); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_c = tmp_c; return OK; error: return ERROR; } static Error AddDot(Array aposnew, int *count_p, Array aconnew, int *count_conn, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_conn; newpoint = DXPt(x, y, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x, y, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newcon = DXLn(tmp_p-2, tmp_p-1); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_conn = tmp_c; return OK; error: return ERROR; } static Error AddStar(Array aposnew, int *count_p, Array aconnew, int *count_conn, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_conn; newpoint = DXPt(x-epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x-epsilonx, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x-epsilonx, y, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newcon = DXLn(tmp_p-8, tmp_p-7); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-6, tmp_p-5); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-4, tmp_p-3); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-2, tmp_p-1); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_conn = tmp_c; return OK; error: return ERROR; } static Error AddX(Array aposnew, int *count_p, Array aconnew, int *count_conn, float x, float y, float epsilonx, float epsilony, int regcolors, RGBColor color, Array acolorsnew) { Point newpoint; Line newcon; int tmp_p, tmp_c; tmp_p = *count_p; tmp_c = *count_conn; newpoint = DXPt(x-epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x+epsilonx, y-epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newpoint = DXPt(x-epsilonx, y+epsilony, 0.0); if (!DXAddArrayData(aposnew, tmp_p, 1, (Pointer)&newpoint)) goto error; if (!regcolors) if (!DXAddArrayData(acolorsnew, tmp_p, 1, (Pointer)&color)) goto error; tmp_p++; newcon = DXLn(tmp_p-4, tmp_p-3); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; newcon = DXLn(tmp_p-2, tmp_p-1); if (!(DXAddArrayData(aconnew, tmp_c, 1, (Pointer)&newcon))) goto error; tmp_c++; *count_p = tmp_p; *count_conn = tmp_c; return OK; error: return ERROR; } static Error DoPlotField(Object ino, int needtoclip, Point clippoint1, Point clippoint2, float epsilonx, float epsilony, int xlog, int ylog, struct plotargstruct *plotarg) { struct arg arg; int i; Object oo; switch (DXGetObjectClass(ino)) { case CLASS_FIELD: /* set up the argument block */ arg.ino = (Object)ino; arg.needtoclip = needtoclip; arg.clippoint1 = clippoint1; arg.clippoint2 = clippoint2; arg.epsilonx = epsilonx; arg.epsilony = epsilony; arg.xlog = xlog; arg.ylog = ylog; arg.mark = plotarg->ismark; arg.markevery = plotarg->markevery; arg.marker = plotarg->mark; arg.markscale = plotarg->markscale; arg.scatter = plotarg->scatter; if (!(DXAddTask(plottask,(Pointer)&arg,sizeof(arg),0.0))) { return ERROR; } break; case CLASS_GROUP: /* recursively traverse groups */ for (i=0; oo=DXGetEnumeratedMember((Group)ino, i, NULL); i++) { if (!DoPlotField((Object)oo, needtoclip, clippoint1, clippoint2, epsilonx, epsilony, xlog, ylog, plotarg)) return ERROR; } break; } return OK; } static Error _dxfSetTextColor(Field f, RGBColor color) { Array pos, col; int numpos; pos = (Array)DXGetComponentValue(f,"positions"); DXGetArrayInfo(pos,&numpos,NULL,NULL,NULL,NULL); col = (Array)DXNewConstantArray(numpos, (Pointer)&color, TYPE_FLOAT, CATEGORY_REAL, 1, 3); DXSetComponentValue(f,"colors",(Object)col); return OK; } static Object MakeLabel(char *label, RGBColor color, int num, float *maxstring, float linelength, Object font, int mark, int scatter, char *marker, RGBColor labelcolor) { Object labeltext, outo=NULL, outgroup, outline, geotext; Array linepositions=NULL, lineconnections=NULL, linecolors=NULL; float width, xpos, ypos; Point *dp; float epsilon; int *dc, numpoints, numconn, num_mark_pos, num_mark_con, count_pos; int linepoints, lineconns; int count_con, regcolors, scatterflag =0; RGBColor dummy; Array acolors=NULL; dummy = DXRGB(0.0, 0.0, 0.0); if (mark) { if (!strcmp(marker,"x")) { num_mark_pos = 4; num_mark_con = 2; } else if (!strcmp(marker,"triangle")) { num_mark_pos = 3; num_mark_con = 3; } else if (!strcmp(marker,"square")) { num_mark_pos = 4; num_mark_con = 4; } else if (!strcmp(marker,"circle")) { num_mark_pos = 10; num_mark_con = 10; } else if (!strcmp(marker,"dot")) { num_mark_pos = 2; num_mark_con = 1; } else if (!strcmp(marker,"star")) { num_mark_pos = 8; num_mark_con = 4; } else if (!strcmp(marker,"diamond")) { num_mark_pos = 4; num_mark_con = 4; } else if (!strcmp(marker,"")) { } else { DXSetError(ERROR_INVALID_DATA,"#10203", "mark", "x, triangle, square, circle, star, diamond"); goto error; } } /* here we need to put the legend in */ /* it will be in pixel units, and will become a screen object at the */ /* top level */ geotext = DXGeometricText(label, font, &width); _dxfSetTextColor((Field)geotext,labelcolor); if (!(labeltext = (Object)DXNewXform(geotext, DXScale(15, 15, 1)))) { return NULL; } if (width*15 > *maxstring) *maxstring=width*15; xpos = linelength; epsilon = linelength/8; ypos = -(num-1)*20; outo = (Object)DXNewXform((Object)labeltext, DXTranslate(DXPt(xpos,ypos-3,0))); if (scatter) { linepoints = 0; lineconns = 0; } else { linepoints = 2; lineconns = 1; } if (mark) { numpoints = linepoints + num_mark_pos; numconn = lineconns + num_mark_con; } else { numpoints = linepoints; numconn = lineconns; } /* XXX check out legends for data dep connections */ /* always reg colors for the legend */ regcolors = 1; linepositions = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3); if (!DXAddArrayData(linepositions,0,numpoints,NULL)) goto error; if (!(dp = (Point *)DXGetArrayData(linepositions))) goto error; /* draw the line */ if (!scatter) { dp[0] = DXPt(0, ypos, 0.0); dp[1] = DXPt(linelength*0.9,ypos,0.0); } lineconnections = DXNewArray(TYPE_INT,CATEGORY_REAL, 1, 2); if (!DXAddArrayData(lineconnections,0,numconn,NULL)) goto error; dc = (int *)DXGetArrayData(lineconnections); if (!scatter) { dc[0]=0; dc[1]=1; } if (mark) { count_pos=linepoints; count_con=lineconns; if (!strcmp(marker,"x")) { AddX(linepositions, &count_pos, lineconnections, &count_con, linelength*.45, ypos, epsilon, epsilon, regcolors, dummy, acolors); } else if (!strcmp(marker,"triangle")) { AddTri(linepositions, &count_pos, lineconnections, &count_con, linelength*.45, ypos, epsilon, epsilon, regcolors, dummy, acolors); } else if (!strcmp(marker,"square")) { AddSquare(linepositions, &count_pos, lineconnections, &count_con, linelength*.45, ypos, epsilon, epsilon,regcolors, dummy, acolors); } else if (!strcmp(marker,"circle")) { AddCircle(linepositions, &count_pos, lineconnections, &count_con, linelength*.45, ypos, epsilon, epsilon,regcolors, dummy, acolors); } else if (!strcmp(marker,"star")) { AddStar(linepositions, &count_pos, lineconnections, &count_con, linelength*.45, ypos, epsilon, epsilon,regcolors, dummy, acolors); } else if (!strcmp(marker,"diamond")) { AddDiamond(linepositions, &count_pos, lineconnections, &count_con, linelength*.45, ypos, epsilon, epsilon,regcolors, dummy, acolors); } } linecolors = (Array)DXNewConstantArray(numpoints, (Pointer)&color, TYPE_FLOAT, CATEGORY_REAL, 1, 3); outline = (Object)DXNewField(); DXSetComponentValue((Field)outline,"positions",(Object)linepositions); linepositions = NULL; DXSetComponentValue((Field)outline,"connections",(Object)lineconnections); lineconnections = NULL; DXSetComponentValue((Field)outline,"colors",(Object)linecolors); linecolors = NULL; DXSetComponentAttribute((Field)outline,"connections","element type", (Object)DXNewString("lines")); DXSetComponentAttribute((Field)outline,"connections","ref", (Object)DXNewString("positions")); DXEndField((Field)outline); outgroup = (Object)DXNewGroup(); DXSetMember((Group)outgroup,NULL,outline); outline = NULL; DXSetMember((Group)outgroup,NULL,outo); outo = NULL; return outgroup; error: DXDelete((Object)linepositions); DXDelete((Object)lineconnections); DXDelete((Object)linecolors); return NULL; } /* static Error GetIntersection(Point clippoint1, Point clippoint2, float thispos, float thisdata, float lastpos, float lastdata) { Point p1, p2, p3, p4; if (thispos[i]>=clippoint1.x && thispos[i]<=clippoint2.x && thisdata[i]>=clippoint1.y && thisdata[i]<=clippoint2.y) { if } else { } */ static Error GetLineColor(Object ino, RGBColor *color) { Array colorcomp; Class class; Field oo; RGBColor *p_color; switch (DXGetObjectClass(ino)) { case CLASS_FIELD: colorcomp = (Array)DXGetComponentValue((Field)ino,"colors"); if (!colorcomp) *color = DXRGB(1.0, 1.0, 1.0); else { if (!DXQueryConstantArray(colorcomp,NULL,NULL)) { /* let's use the first color in the array */ p_color = (RGBColor *)DXGetArrayData(colorcomp); *color = p_color[0]; } else { DXQueryConstantArray((Array)colorcomp, NULL, (Pointer)color); } } break; case CLASS_GROUP: /* XXX what's going on here? */ /* get the first color */ oo = DXGetPart(ino, 0); colorcomp = (Array)DXGetComponentValue((Field)oo,"colors"); if (!colorcomp) *color = DXRGB(1.0, 1.0, 1.0); else { if (!DXQueryConstantArray(colorcomp, NULL,NULL)) { /* let's use the first color in the array */ p_color = (RGBColor *)DXGetArrayData(colorcomp); *color = p_color[0]; } else { DXQueryConstantArray((Array)colorcomp, NULL, (Pointer)color); } } break; case CLASS_XFORM: /* get the first color */ oo = DXGetPart(ino, 0); colorcomp = (Array)DXGetComponentValue((Field)oo,"colors"); if (!colorcomp) *color = DXRGB(1.0, 1.0, 1.0); else { if (!DXQueryConstantArray(colorcomp,NULL,NULL)) { /* let's use the first color in the array */ p_color = (RGBColor *)DXGetArrayData(colorcomp); *color = p_color[0]; } else { DXQueryConstantArray((Array)colorcomp, NULL, (Pointer)color); } } break; } return OK; } extern Error _dxfGetAnnotationColors(Object colors, Object which, RGBColor defaultticcolor, RGBColor defaultlabelcolor, RGBColor defaultaxescolor, RGBColor defaultgridcolor, RGBColor defaultbackgroundcolor, RGBColor *ticcolor, RGBColor *labelcolor, RGBColor *axescolor, RGBColor *gridcolor, RGBColor *backgroundcolor, int *background) { RGBColor *colorlist =NULL; int i, numcolors, numcolorobjects; char *colorstring, *newcolorstring; /* in[9] is the colors list */ /* first set up the default colors */ *ticcolor = defaultticcolor; *labelcolor = defaultlabelcolor; *axescolor = defaultaxescolor; *gridcolor = defaultgridcolor; /* by default, we don't make a background */ *background = 0; *backgroundcolor = defaultbackgroundcolor; if (colors) { if (DXExtractNthString(colors,0,&colorstring)) { /* it's a list of strings */ /* first figure out how many there are */ if (!_dxfHowManyStrings(colors, &numcolors)) goto error; /* allocate space for the 3-vectors */ colorlist = DXAllocateLocal(numcolors*sizeof(RGBColor)); if (!colorlist) goto error; for (i=0; i