1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 #include <dxconfig.h>
9 
10 #include <dx/dx.h>
11 #include <stdlib.h>
12 
13 #if defined(HAVE_STRING_H)
14 #include <string.h>
15 #endif
16 
17 #include "plot.h"
18 #include "color.h"
19 #include "autoaxes.h"
20 
21 #define MINTICPIX 5
22 
23 typedef struct
24 {
25   float x;
26   float y;
27 } Point2D;
28 
29 
30 static Error TransposeColors(Array);
31 static Error SimpleBar(Array *, Array *, RGBColor *);
32 
33 static RGBColor DEFAULTTICCOLOR = {0.3, 0.3, 0.3};
34 static RGBColor DEFAULTLABELCOLOR = {1.0, 1.0, 1.0};
35 
36 Error
m_ColorBar(Object * in,Object * out)37 m_ColorBar(Object *in, Object *out)
38 {
39   Pointer axeshandle=NULL;
40   Object outo, outscreen, o, oo, ooo;
41   Object newo, ob;
42   Array a_positions, a_newpositions=NULL;
43   Array a_newcolors=NULL, a_colors, a_newconnections=NULL;
44   Array corners;
45   char *nullstring="", *fontname, extralabel[80];
46   int numpos, numcolors, i, flag, horizontal, intzero = 0, frame;
47   int tics, usedobject, adjust, curcount, lastin;
48   int colorcount, lastok;
49   float *pos_ptr, frac, minticsize, *actualcorners = NULL;
50   int numarrayitems;
51   float minvalue, maxvalue;
52   Point min, max;
53   float *col_ptr_f=NULL;
54   int *col_ptr_i=NULL;
55   Point box[8], translation, corner1, corner2, point;
56   float length, scalewidth, scaleheight, captionsize, labelscale=1.0;
57   RGBColor color, *color_ptr, ticcolor, labelcolor;
58   RGBColor framecolor;
59   Class class;
60   Type type, colortype;
61   int rank, shapearray[32], axeslines=1;
62   Category category;
63   char *att, *label;
64   Field colormap;
65   int doaxes = 1;
66   Array ticklocations=NULL;
67   float *list_ptr;
68   int numlist;
69   int dofixedfontsize=0;
70   float fixedfontsize=0;
71   int fixedfontsizepixels=10;
72 
73 
74 
75   typedef struct {
76     float height, width, thickness;
77   }  Shape;
78   Shape shape;
79 
80   strcpy(extralabel,nullstring);
81   adjust = 0;
82   captionsize = 15.0;
83   outo = NULL;
84   corners = NULL;
85   o = NULL;
86   oo = NULL;
87 
88 
89   if (!in[0])
90     DXErrorGoto(ERROR_BAD_PARAMETER, "missing colormap");
91 
92 
93 
94   class = DXGetObjectClass(in[0]);
95   if ((class != CLASS_FIELD)&&(class != CLASS_ARRAY)&&(class != CLASS_GROUP)) {
96     DXSetError(ERROR_BAD_PARAMETER, "#10111","colormap");
97     goto error;
98   }
99 
100   if (class == CLASS_ARRAY) {
101     if (!DXGetArrayInfo((Array)in[0], &numarrayitems, &type, &category,
102 			&rank, shapearray)){
103       goto error;
104     }
105     if (numarrayitems != 1) {
106       DXSetError(ERROR_BAD_PARAMETER,"#10111","colormap");
107       goto error;
108     }
109     if ((type!=TYPE_FLOAT)||(category!=CATEGORY_REAL)||(rank!=1)||
110         (shapearray[0]!=3)) {
111       DXSetError(ERROR_BAD_PARAMETER,"#10111","colormap");
112       goto error;
113     }
114     DXWarning("colormap is a single color--no axes information available");
115     colormap=(Field)in[0];
116   }
117   else {
118     if (class==CLASS_FIELD && DXEmptyField((Field)in[0])) {
119       return OK;
120     }
121     /* see if it's an imported colormap */
122     if (!_dxfIsImportedColorMap(in[0], NULL, (Object *)&colormap, NULL)) {
123       if (!(_dxfIsColorMap(in[0]))) {
124         goto error;
125       }
126       colormap=(Field)in[0];
127     }
128   }
129 
130   if (!in[3]) {
131     horizontal = 0;
132   }
133   else {
134     if (!(DXExtractInteger(in[3], &horizontal))) {
135       DXSetError(ERROR_BAD_PARAMETER,"#10070","horizontal");
136       goto error;
137     }
138     if ((horizontal != 0)&&(horizontal != 1)) {
139       DXSetError(ERROR_BAD_PARAMETER,"#10070","horizontal");
140       goto error;
141     }
142   }
143 
144   if (!in[1]) {
145     if (horizontal==0) {
146       translation.x = 0.95;
147       translation.y = 0.95;
148       translation.z = 0.0;
149     }
150     else {
151       translation.x = 0.5;
152       translation.y = 0.95;
153       translation.z = 0.0;
154     }
155   }
156   else {
157     if (!DXExtractParameter(in[1], TYPE_FLOAT, 3, 1, (Pointer)&translation)) {
158       if (!DXExtractParameter(in[1], TYPE_FLOAT, 2, 1,
159 			      (Pointer)&translation)) {
160 	DXSetError(ERROR_BAD_PARAMETER,"#10231","position", 2, 3);
161 	goto error;
162       }
163     }
164     translation.z = 0.0;
165   }
166 
167   if ((translation.x < 0)||(translation.x > 1)||(translation.y<0.0)||
168       (translation.y>1.0)) {
169     DXSetError(ERROR_BAD_PARAMETER, "#10110", "position", 0, 1);
170     goto error;
171   }
172 
173   if (!in[2]) {
174     shape.height = 300.0;
175     shape.width = 25.0;
176     shape.thickness = 1.0;
177   }
178   else {
179     if (!DXExtractParameter(in[2], TYPE_FLOAT, 3, 1, (Pointer)&shape)) {
180       if (!DXExtractParameter(in[2], TYPE_FLOAT, 2, 1, (Pointer)&shape)) {
181         DXSetError(ERROR_BAD_PARAMETER,"#10231","shape", 2, 3);
182         goto error;
183       }
184       shape.thickness = 1;
185     }
186 
187     if (shape.height <= 0.0) {
188       DXSetError(ERROR_BAD_PARAMETER,"#10531","shape");
189       goto error;
190     }
191     if (shape.width <= 0.0) {
192       DXSetError(ERROR_BAD_PARAMETER,"#10531","shape");
193       goto error;
194     }
195   }
196 
197 
198   if (!in[4]) {
199     /* magic formula to figure out how many ticks */
200     tics = shape.height/(captionsize*2.0);
201   }
202   else {
203     if (!DXExtractInteger(in[4],&tics)) {
204       DXSetError(ERROR_BAD_PARAMETER, "#10030","ticks");
205       goto error;
206     }
207   }
208 
209   if (!_dxfGetColorBarAnnotationColors(in[8], in[9], DEFAULTTICCOLOR,
210                           DEFAULTLABELCOLOR, &ticcolor, &labelcolor,
211                           &framecolor, &frame))
212      goto error;
213 
214   if (frame==1) axeslines=1;
215   else axeslines=0;
216 
217   if (in[10]) {
218      if (!DXExtractFloat(in[10],&labelscale)) {
219         DXSetError(ERROR_BAD_PARAMETER,"#10090","labelscale");
220         goto error;
221      }
222      if (labelscale < 0) {
223         DXSetError(ERROR_BAD_PARAMETER,"#10090","labelscale");
224         goto error;
225      }
226   }
227 
228   if (in[11]) {
229      if (!DXExtractString(in[11],&fontname)) {
230         DXSetError(ERROR_BAD_PARAMETER,"#10200","font");
231         goto error;
232      }
233    }
234    else {
235      fontname = "standard";
236    }
237 
238 
239   if (class == CLASS_ARRAY) {
240     /* make a simple, simple, bar, all one color */
241     color_ptr = (RGBColor *)DXGetArrayData((Array)colormap);
242     if (!SimpleBar(&a_newpositions, &a_newcolors, color_ptr))
243        goto error;
244     curcount = 4;
245     minvalue = 0;
246     maxvalue = 1;
247     att = "positions";
248     doaxes = 0;
249   }
250   /* a "normal" field color map */
251   else {
252     if (class == CLASS_GROUP) {
253        DXSetError(ERROR_DATA_INVALID,
254                   "colormap must be a single field; not a group");
255        goto error;
256     }
257     else if (class != CLASS_FIELD) {
258        DXSetError(ERROR_DATA_INVALID,
259                   "colormap must be a single field");
260        goto error;
261     }
262     usedobject = 0;
263     if (in[5]) {
264       if (!DXExtractFloat(in[5], &minvalue)) {
265 	if (!DXStatistics(in[5],"data",&minvalue, &maxvalue, NULL, NULL)) {
266           DXSetError(ERROR_BAD_PARAMETER,
267 		     "min must be a field with data or scalar");
268           goto error;
269 	}
270 	usedobject = 1;
271       }
272     }
273     else {
274       if (!DXStatistics((Object)colormap, "positions",&minvalue, NULL, NULL, NULL)) {
275 	DXAddMessage("invalid colormap");
276 	goto error;
277       }
278     }
279 
280 
281     if (in[6]) {
282       if (!DXExtractFloat(in[6], &maxvalue)) {
283 	if (!DXStatistics(in[6],"data",NULL, &maxvalue, NULL, NULL)) {
284           DXSetError(ERROR_BAD_PARAMETER,
285 		     "max must be a field with data or scalar");
286           goto error;
287 	}
288       }
289     }
290     else {
291       if (!usedobject) {
292 	if (!DXStatistics((Object)colormap, "positions",NULL, &maxvalue, NULL, NULL)) {
293 	  DXAddMessage("invalid colormap");
294 	  goto error;
295 	}
296       }
297     }
298 
299     if (minvalue == maxvalue) {
300       color_ptr =
301           (RGBColor *)DXGetArrayData((Array)DXGetComponentValue(colormap,
302                                                                  "data"));
303       if (!SimpleBar(&a_newpositions, &a_newcolors, color_ptr))
304          goto error;
305       att = "positions";
306       curcount = 4;
307       sprintf(extralabel,"%f",minvalue);
308       minvalue = 0;
309       maxvalue = 1;
310       doaxes = 1;
311       tics = 0;
312       goto drawbar;
313     }
314 
315 
316     if (minvalue > maxvalue) {
317       DXSetError(ERROR_BAD_PARAMETER,"#11220","min","max");
318       goto error;
319     }
320 
321     if (!(a_positions = (Array)DXGetComponentValue((Field)colormap,
322 						   "positions"))) {
323       DXSetError(ERROR_BAD_PARAMETER,"colormap has no positions");
324       goto error;
325     }
326     if (!(a_colors = (Array)DXGetComponentValue((Field)colormap,"data"))) {
327       DXSetError(ERROR_BAD_PARAMETER,"colormap has no data");
328       goto error;
329     }
330 
331     if (!DXGetArrayInfo(a_positions,&numpos, NULL, NULL, NULL, NULL)) {
332       goto error;
333     }
334     if (!DXGetArrayInfo(a_colors,&numcolors, &colortype, NULL, NULL, NULL)) {
335       goto error;
336     }
337     switch (colortype) {
338       case (TYPE_FLOAT):
339         if (!(col_ptr_f = (float *)DXGetArrayData(a_colors)))
340            goto error;
341         break;
342       case (TYPE_INT):
343         if (!(col_ptr_i = (int *)DXGetArrayData(a_colors)))
344            goto error;
345         break;
346       default:
347         DXSetError(ERROR_DATA_INVALID,
348                    "colormap colors must be integer or float");
349         goto error;
350     }
351     if (numcolors == 0) {
352       DXSetError(ERROR_DATA_INVALID,"colormap has no colors (data component)");
353       goto error;
354     }
355 
356     if (!(pos_ptr = (float *)DXGetArrayData(a_positions))) {
357       goto error;
358     }
359 
360     if (!(a_newpositions = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 2))) {
361       goto error;
362     }
363 
364     if (! DXSetStringAttribute((Object)a_newpositions, "dep", "positions"))
365       goto error;
366 
367     if (!(a_newcolors = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3))) {
368       goto error;
369     }
370 
371     if (horizontal == 0) {
372       corner1 = DXPt(0.0, minvalue, 0.0);
373       corner2 = DXPt(1.0, maxvalue, 0.0);
374     }
375     else {
376       corner1 = DXPt(minvalue, 0.0, 0.0);
377       corner2 = DXPt(maxvalue, 1.0, 0.0);
378     }
379     if (in[5]||in[6]) {
380       corners = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,3);
381       if (!(DXAddArrayData(corners, 0, 1, (Pointer)&corner1)))
382 	goto error;
383       if (!(DXAddArrayData(corners, 1, 1, (Pointer)&corner2)))
384 	goto error;
385     }
386     if (!(att = DXGetString((String)DXGetComponentAttribute((Field)colormap,
387 							    "data","dep")))) {
388       DXSetError(ERROR_DATA_INVALID,"missing data dependency attribute");
389       goto error;
390     }
391     if (strcmp(att,"positions") && strcmp(att,"connections")) {
392       DXSetError(ERROR_DATA_INVALID,"unknown data dependent attribute %s",
393 		 att);
394       goto error;
395     }
396 
397 
398     curcount = 0;
399     colorcount = 0;
400     lastok = 0;
401     if (!strcmp(att,"positions")) {
402       if (corners) {
403         lastin = 0;
404 	if (horizontal == 0) {
405 	  for (i=0; i<numpos; i++) {
406 	    if ((pos_ptr[i]>=corner1.y) &&  (pos_ptr[i]<=corner2.y)) {
407               if ((i > 0) && (lastin == 0)) {
408 		point = DXPt(0.0, corner1.y, 0.0);
409 		if (!(DXAddArrayData(a_newpositions, curcount, 1,
410 				     (Pointer)&point))) {
411 		  goto error;
412 		}
413 		curcount++;
414 		point = DXPt(1.0, corner1.y, 0.0);
415 		if (!(DXAddArrayData(a_newpositions, curcount, 1,
416 				     (Pointer)&point))) {
417 		  goto error;
418 		}
419 		curcount++;
420 		frac =
421 		  (corner1.y - pos_ptr[i-1])/(pos_ptr[i]-pos_ptr[i-1]);
422                 switch (colortype) {
423                 case (TYPE_FLOAT):
424 		color = DXRGB(frac*(col_ptr_f[3*i]-col_ptr_f[3*(i-1)])
425 			      + col_ptr_f[3*(i-1)],
426 			      frac*(col_ptr_f[3*i+1]-col_ptr_f[3*(i-1)+1])
427 			      + col_ptr_f[3*(i-1)+1],
428 			      frac*(col_ptr_f[3*i+2]-col_ptr_f[3*(i-1)+2])
429 			      + col_ptr_f[3*(i-1)+2]);
430                 break;
431                 case (TYPE_INT):
432 		color = DXRGB(frac*(col_ptr_i[3*i]-col_ptr_i[3*(i-1)])
433 			      + col_ptr_i[3*(i-1)],
434 			      frac*(col_ptr_i[3*i+1]-col_ptr_i[3*(i-1)+1])
435 			      + col_ptr_i[3*(i-1)+1],
436 			      frac*(col_ptr_i[3*i+2]-col_ptr_i[3*(i-1)+2])
437 			      + col_ptr_i[3*(i-1)+2]);
438                 break;
439 		default:
440 		  break;
441                 }
442 		if (!(DXAddArrayData(a_newcolors, colorcount,
443 		 		     1, (Pointer)&color))) {
444 		  goto error;
445 		}
446 		colorcount++;
447 		if (!(DXAddArrayData(a_newcolors, colorcount,
448 		 		     1, (Pointer)&color))) {
449 		  goto error;
450 		}
451 		colorcount++;
452               }
453 	      point = DXPt(0.0, pos_ptr[i],0.0);
454 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
455 				   (Pointer)&point))) {
456 		goto error;
457 	      }
458 	      curcount++;
459               switch (colortype) {
460               case (TYPE_FLOAT):
461 	      color = DXRGB(col_ptr_f[3*i],
462 			    col_ptr_f[3*i+1],
463 			    col_ptr_f[3*i+2]);
464               break;
465               case (TYPE_INT):
466 	      color = DXRGB(col_ptr_i[3*i],
467 			    col_ptr_i[3*i+1],
468 			    col_ptr_i[3*i+2]);
469               break;
470 	      default:
471 	        break;
472               }
473 
474 	      if (!(DXAddArrayData(a_newcolors, colorcount,
475 				   1, (Pointer)&color))) {
476 		goto error;
477 	      }
478 	      colorcount++;
479 	      point = DXPt(1.0, pos_ptr[i],0.0);
480 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
481 				   (Pointer)&point))) {
482 		goto error;
483 	      }
484 	      curcount++;
485 	      if (!(DXAddArrayData(a_newcolors, colorcount,
486 				   1, (Pointer)&color))) {
487 		goto error;
488 	      }
489 	      colorcount++;
490               lastin=1;
491 	    }
492 	    else {
493               if (lastin == 1) {
494 		point = DXPt(0.0, corner2.y, 0.0);
495 		if (!(DXAddArrayData(a_newpositions, curcount, 1,
496 				     (Pointer)&point))) {
497 		  goto error;
498 		}
499 		curcount++;
500 		point = DXPt(1.0, corner2.y, 0.0);
501 		if (!(DXAddArrayData(a_newpositions, curcount, 1,
502 				     (Pointer)&point))) {
503 		  goto error;
504 		}
505 		curcount++;
506 		frac =
507 		  (corner2.y - pos_ptr[i-1])/(pos_ptr[i]-pos_ptr[i-1]);
508                 switch (colortype) {
509                 case (TYPE_FLOAT):
510 		color = DXRGB(frac*(col_ptr_f[3*i]-col_ptr_f[3*(i-1)])
511 			      + col_ptr_f[3*(i-1)],
512 			      frac*(col_ptr_f[3*i+1]-col_ptr_f[3*(i-1)+1])
513 			      + col_ptr_f[3*(i-1)+1],
514 			      frac*(col_ptr_f[3*i+2]-col_ptr_f[3*(i-1)+2])
515 			      + col_ptr_f[3*(i-1)+2]);
516                 break;
517                 case (TYPE_INT):
518 		color = DXRGB(frac*(col_ptr_i[3*i]-col_ptr_i[3*(i-1)])
519 			      + col_ptr_i[3*(i-1)],
520 			      frac*(col_ptr_i[3*i+1]-col_ptr_i[3*(i-1)+1])
521 			      + col_ptr_i[3*(i-1)+1],
522 			      frac*(col_ptr_i[3*i+2]-col_ptr_i[3*(i-1)+2])
523 			      + col_ptr_i[3*(i-1)+2]);
524                 break;
525 		default:
526 		  break;
527                 }
528 		if (!(DXAddArrayData(a_newcolors, colorcount,
529 				     1, (Pointer)&color))) {
530 		  goto error;
531 		}
532 		colorcount++;
533 		if (!(DXAddArrayData(a_newcolors, colorcount,
534 				     1, (Pointer)&color))) {
535 		  goto error;
536 		}
537 		colorcount++;
538               }
539 	      lastin = 0;
540 	    }
541 	  }
542 	}
543 	else {
544 	  for (i=0; i<numpos; i++) {
545 	    if ((pos_ptr[i]>=corner1.x) &&  (pos_ptr[i]<=corner2.x)) {
546               if ((i > 0) && (lastin == 0)) {
547 		point = DXPt(corner1.x, 0.0, 0.0);
548 		if (!(DXAddArrayData(a_newpositions, curcount, 1,
549 				     (Pointer)&point))) {
550 		  goto error;
551 		}
552 		curcount++;
553 		point = DXPt(corner1.x, 1.0, 0.0);
554 		if (!(DXAddArrayData(a_newpositions, curcount, 1,
555 				     (Pointer)&point))) {
556 		  goto error;
557 		}
558 		curcount++;
559 		frac =
560 		  (corner1.x - pos_ptr[i-1])/(pos_ptr[i]-pos_ptr[i-1]);
561                 switch (colortype) {
562                 case (TYPE_FLOAT):
563 		color = DXRGB(frac*(col_ptr_f[3*i]-col_ptr_f[3*(i-1)])
564 			      + col_ptr_f[3*(i-1)],
565 			      frac*(col_ptr_f[3*i+1]-col_ptr_f[3*(i-1)+1])
566 			      + col_ptr_f[3*(i-1)+1],
567 			      frac*(col_ptr_f[3*i+2]-col_ptr_f[3*(i-1)+2])
568 			      + col_ptr_f[3*(i-1)+2]);
569                 break;
570                 case (TYPE_INT):
571 		color = DXRGB(frac*(col_ptr_i[3*i]-col_ptr_i[3*(i-1)])
572 			      + col_ptr_i[3*(i-1)],
573 			      frac*(col_ptr_i[3*i+1]-col_ptr_i[3*(i-1)+1])
574 			      + col_ptr_i[3*(i-1)+1],
575 			      frac*(col_ptr_i[3*i+2]-col_ptr_i[3*(i-1)+2])
576 			      + col_ptr_i[3*(i-1)+2]);
577                 break;
578 		default:
579 		  break;
580                 }
581 		if (!(DXAddArrayData(a_newcolors, colorcount,
582 				     1, (Pointer)&color))) {
583 		  goto error;
584 		}
585 		colorcount++;
586 		if (!(DXAddArrayData(a_newcolors, colorcount,
587 				     1, (Pointer)&color))) {
588 		  goto error;
589 		}
590 		colorcount++;
591               }
592 	      point = DXPt(0.0, pos_ptr[i],0.0);
593 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
594 				   (Pointer)&point))) {
595 		goto error;
596 	      }
597 	      point = DXPt(pos_ptr[i],0.0,0.0);
598 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
599 				   (Pointer)&point))) {
600 		goto error;
601 	      }
602 	      curcount++;
603               switch (colortype) {
604               case (TYPE_FLOAT):
605 	      color = DXRGB(col_ptr_f[3*i], col_ptr_f[3*i+1], col_ptr_f[3*i+2]);
606               break;
607               case (TYPE_INT):
608 	      color = DXRGB(col_ptr_i[3*i], col_ptr_i[3*i+1], col_ptr_i[3*i+2]);
609               break;
610 	      default:
611 	        break;
612               }
613 	      if (!(DXAddArrayData(a_newcolors, colorcount,
614 				   1, (Pointer)&color))) {
615 		goto error;
616 	      }
617 	      colorcount++;
618 	      point = DXPt(pos_ptr[i],1.0,0.0);
619 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
620 				   (Pointer)&point))) {
621 		goto error;
622 	      }
623 	      curcount++;
624 	      if (!(DXAddArrayData(a_newcolors, colorcount,
625 				   1, (Pointer)&color))) {
626 		goto error;
627 	      }
628 	      colorcount++;
629               lastin=1;
630 	    }
631             else {
632               if (lastin == 1) {
633                 point = DXPt(corner2.x, 0.0, 0.0);
634                 if (!(DXAddArrayData(a_newpositions, curcount, 1,
635 				     (Pointer)&point))) {
636                   goto error;
637                 }
638                 curcount++;
639                 point = DXPt(corner2.x, 1.0, 0.0);
640                 if (!(DXAddArrayData(a_newpositions, curcount, 1,
641 				     (Pointer)&point))) {
642                   goto error;
643                 }
644                 curcount++;
645                 frac =
646                   (corner2.x - pos_ptr[i-1])/(pos_ptr[i]-pos_ptr[i-1]);
647                 switch (colortype) {
648                 case (TYPE_FLOAT):
649                 color = DXRGB(frac*(col_ptr_f[3*i]-col_ptr_f[3*(i-1)])
650 			      + col_ptr_f[3*(i-1)],
651 			      frac*(col_ptr_f[3*i+1]-col_ptr_f[3*(i-1)+1])
652 			      + col_ptr_f[3*(i-1)+1],
653 			      frac*(col_ptr_f[3*i+2]-col_ptr_f[3*(i-1)+2])
654 			      + col_ptr_f[3*(i-1)+2]);
655                 break;
656                 case (TYPE_INT):
657                 color = DXRGB(frac*(col_ptr_i[3*i]-col_ptr_i[3*(i-1)])
658 			      + col_ptr_i[3*(i-1)],
659 			      frac*(col_ptr_i[3*i+1]-col_ptr_i[3*(i-1)+1])
660 			      + col_ptr_i[3*(i-1)+1],
661 			      frac*(col_ptr_i[3*i+2]-col_ptr_i[3*(i-1)+2])
662 			      + col_ptr_i[3*(i-1)+2]);
663                   break;
664 		default:
665 		  break;
666                 }
667                 if (!(DXAddArrayData(a_newcolors, colorcount,
668 				     1, (Pointer)&color))) {
669                   goto error;
670                 }
671                 colorcount++;
672                 if (!(DXAddArrayData(a_newcolors, colorcount,
673 				     1, (Pointer)&color))) {
674                   goto error;
675                 }
676                 colorcount++;
677               }
678               lastin = 0;
679             }
680 	  }
681 	}
682       }
683       else {
684 	if (horizontal == 0) {
685 	  for (i=0; i<numpos; i++) {
686 	    point = DXPt(0.0, pos_ptr[i],0.0);
687 	    if (!(DXAddArrayData(a_newpositions, curcount,
688 				 1, (Pointer)&point))) {
689 	      goto error;
690 	    }
691 	    curcount++;
692             switch (colortype) {
693             case (TYPE_FLOAT):
694 	      color = DXRGB(col_ptr_f[3*i], col_ptr_f[3*i+1], col_ptr_f[3*i+2]);
695               break;
696             case (TYPE_INT):
697 	      color = DXRGB(col_ptr_i[3*i], col_ptr_i[3*i+1], col_ptr_i[3*i+2]);
698               break;
699 	    default:
700 	      break;
701             }
702 	    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
703 				 (Pointer)&color))) {
704 	      goto error;
705 	    }
706 	    colorcount++;
707 	    point = DXPt(1.0, pos_ptr[i],0.0);
708 	    if (!(DXAddArrayData(a_newpositions, curcount,
709 				 1, (Pointer)&point))) {
710 	      goto error;
711 	    }
712 	    curcount++;
713 	    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
714 				 (Pointer)&color))) {
715 	      goto error;
716 	    }
717 	    colorcount++;
718 	  }
719 	}
720 	else {
721 	  for (i=0; i<numpos; i++) {
722 	    point = DXPt(pos_ptr[i],0.0,0.0);
723 	    if (!(DXAddArrayData(a_newpositions, curcount,
724 				 1, (Pointer)&point))) {
725 	      goto error;
726 	    }
727 	    curcount++;
728             switch (colortype) {
729             case (TYPE_FLOAT):
730 	      color = DXRGB(col_ptr_f[3*i], col_ptr_f[3*i+1], col_ptr_f[3*i+2]);
731               break;
732             case (TYPE_INT):
733 	      color = DXRGB(col_ptr_i[3*i], col_ptr_i[3*i+1], col_ptr_i[3*i+2]);
734               break;
735 	    default:
736 	      break;
737             }
738 	    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
739 				 (Pointer)&color))) {
740 	      goto error;
741 	    }
742 	    colorcount++;
743 	    point = DXPt(pos_ptr[i],1.0,0.0);
744 	    if (!(DXAddArrayData(a_newpositions, curcount,
745 				 1, (Pointer)&point))) {
746 	      goto error;
747 	    }
748 	    curcount++;
749 	    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
750 				 (Pointer)&color))) {
751 	      goto error;
752 	    }
753 	    colorcount++;
754 	  }
755 	}
756       }
757     }
758     /* else dep on connections */
759     else {
760       if (corners) {
761         lastin=0;
762 	if (horizontal == 0) {
763 
764           /* add the minimum if given */
765           point = DXPt(0.0, corner1.y,0.0);
766           if (!(DXAddArrayData(a_newpositions, curcount, 1,
767 			       (Pointer)&point)))
768 	    goto error;
769           curcount++;
770 	  point = DXPt(1.0, corner1.y,0.0);
771 	  if (!(DXAddArrayData(a_newpositions, curcount, 1,
772 			       (Pointer)&point)))
773             goto error;
774           curcount++;
775 
776 
777 	  for (i=0; i<numpos; i++) {
778 	    if ((pos_ptr[i]>=corner1.y) &&  (pos_ptr[i]<=corner2.y)) {
779 	      point = DXPt(0.0, pos_ptr[i],0.0);
780 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
781 				   (Pointer)&point))) {
782 		goto error;
783 	      }
784 	      curcount++;
785               if ((!lastok)&&(i <= numcolors)) { /* deal with the first bin */
786                 if (i==0) /* make first bin black */
787 		  {
788 		    color = DXRGB(0.0, 0.0, 0.0);
789 		    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
790 					 (Pointer)&color)))
791 		      goto error;
792 		    colorcount++;
793 		  }
794                 else
795 		  {
796 		    switch (colortype) {
797 		    case (TYPE_FLOAT):
798 		      color = DXRGB(col_ptr_f[3*(i-1)],
799 			            col_ptr_f[3*(i-1)+1],
800 			            col_ptr_f[3*(i-1)+2]);
801 		      break;
802 		    case (TYPE_INT):
803 		      color = DXRGB(col_ptr_i[3*(i-1)],
804 		            	    col_ptr_i[3*(i-1)+1],
805 			            col_ptr_i[3*(i-1)+2]);
806 		      break;
807 		    default:
808 		      break;
809 		    }
810 		    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
811 					 (Pointer)&color)))
812 		      goto error;
813 		    colorcount++;
814 		  }
815               }
816 	      if (lastok && (i <= numcolors)) {
817                 switch (colortype) {
818                 case (TYPE_FLOAT):
819 		  color = DXRGB(col_ptr_f[3*(i-1)],
820 				col_ptr_f[3*(i-1)+1],
821 				col_ptr_f[3*(i-1)+2]);
822 		  break;
823                 case (TYPE_INT):
824 		  color = DXRGB(col_ptr_i[3*(i-1)],
825 				col_ptr_i[3*(i-1)+1],
826 				col_ptr_i[3*(i-1)+2]);
827 		  break;
828 		default:
829 		  break;
830                 }
831 		if (!(DXAddArrayData(a_newcolors, colorcount, 1,
832 				     (Pointer)&color))) {
833 		  goto error;
834 		}
835 		colorcount++;
836 	      }
837 	      point = DXPt(1.0, pos_ptr[i],0.0);
838 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
839 				   (Pointer)&point))) {
840 		goto error;
841 	      }
842 	      curcount++;
843 	      lastok=1;
844 	    }
845 	    if (pos_ptr[i]>corner2.y)
846                break;
847 	  }
848           /* add the maximum if given */
849           point = DXPt(0.0, corner2.y,0.0);
850           if (!(DXAddArrayData(a_newpositions, curcount, 1,
851 			       (Pointer)&point)))
852 	    goto error;
853           curcount++;
854 	  point = DXPt(1.0, corner2.y,0.0);
855 	  if (!(DXAddArrayData(a_newpositions, curcount, 1,
856 			       (Pointer)&point)))
857             goto error;
858           curcount++;
859           if (i>numcolors) /* make last bin black */
860 	    {
861 	      color = DXRGB(0.0, 0.0, 0.0);
862 	      if (!(DXAddArrayData(a_newcolors, colorcount, 1,
863 				   (Pointer)&color)))
864 	        goto error;
865 	      colorcount++;
866 	    }
867           else
868 	    {
869 	      switch (colortype) {
870               case (TYPE_FLOAT):
871 		color = DXRGB(col_ptr_f[3*(i-1)],
872 			      col_ptr_f[3*(i-1)+1],
873 			      col_ptr_f[3*(i-1)+2]);
874                 break;
875               case (TYPE_INT):
876 		color = DXRGB(col_ptr_i[3*(i-1)],
877 			      col_ptr_i[3*(i-1)+1],
878 			      col_ptr_i[3*(i-1)+2]);
879 		break;
880 	      default:
881 	        break;
882 	      }
883 	      if (!(DXAddArrayData(a_newcolors, colorcount, 1,
884 				   (Pointer)&color)))
885 		goto error;
886 	      colorcount++;
887 	    }
888 	}
889 	/* else horizontal = 1 */
890 	else {
891           /* add the minimum if given */
892           point = DXPt(corner1.x,0.0, 0.0);
893           if (!(DXAddArrayData(a_newpositions, curcount, 1,
894 			       (Pointer)&point)))
895 	    goto error;
896           curcount++;
897 	  point = DXPt(corner1.x,1.0, 0.0);
898 	  if (!(DXAddArrayData(a_newpositions, curcount, 1,
899 			       (Pointer)&point)))
900 	    goto error;
901           curcount++;
902 	  for (i=0; i<numpos; i++) {
903 	    if ((pos_ptr[i]>=corner1.x) &&  (pos_ptr[i]<=corner2.x)) {
904 	      point = DXPt(pos_ptr[i],0.0,0.0);
905 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
906 				   (Pointer)&point))) {
907 		goto error;
908 	      }
909 	      curcount++;
910               if ((!lastok)&&(i <= numcolors)) { /* deal with the first bin */
911                 if (i==0) /* make first bin black */
912 		  {
913 		    color = DXRGB(0.0, 0.0, 0.0);
914 		    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
915 					 (Pointer)&color)))
916 		      goto error;
917 		    colorcount++;
918 		  }
919                 else
920 		  {
921 		    switch (colortype) {
922 		    case (TYPE_FLOAT):
923 		      color = DXRGB(col_ptr_f[3*(i-1)],
924 			            col_ptr_f[3*(i-1)+1],
925 			            col_ptr_f[3*(i-1)+2]);
926 		      break;
927 		    case (TYPE_INT):
928 		      color = DXRGB(col_ptr_i[3*(i-1)],
929 		            	    col_ptr_i[3*(i-1)+1],
930 			            col_ptr_i[3*(i-1)+2]);
931 		      break;
932 		    default:
933 		      break;
934 		    }
935 		    if (!(DXAddArrayData(a_newcolors, colorcount, 1,
936 					 (Pointer)&color)))
937 		      goto error;
938 		    colorcount++;
939 		  }
940               }
941 	      if (lastok&&(i<=numcolors)) {
942                 switch (colortype) {
943                 case (TYPE_FLOAT):
944 		  color = DXRGB(col_ptr_f[3*(i-1)],
945 				col_ptr_f[3*(i-1)+1],
946 				col_ptr_f[3*(i-1)+2]);
947 		  break;
948                 case (TYPE_INT):
949 		  color = DXRGB(col_ptr_i[3*(i-1)],
950 				col_ptr_i[3*(i-1)+1],
951 				col_ptr_i[3*(i-1)+2]);
952 		  break;
953 		default:
954 		  break;
955                 }
956 		if (!(DXAddArrayData(a_newcolors, colorcount, 1,
957 				     (Pointer)&color))) {
958 		  goto error;
959 		}
960 		colorcount++;
961 	      }
962 	      point = DXPt(pos_ptr[i],1.0,0.0);
963 	      if (!(DXAddArrayData(a_newpositions, curcount, 1,
964 				   (Pointer)&point))) {
965 		goto error;
966 	      }
967 	      curcount++;
968 	      lastok=1;
969 	    }
970 	    if (pos_ptr[i]>corner2.x)
971                break;
972 	  }
973           /* add the maximum if given */
974           point = DXPt(corner2.x,0.0, 0.0);
975           if (!(DXAddArrayData(a_newpositions, curcount, 1,
976 			       (Pointer)&point)))
977 	    goto error;
978           curcount++;
979 	  point = DXPt(corner2.x, 1.0, 0.0);
980 	  if (!(DXAddArrayData(a_newpositions, curcount, 1,
981 			       (Pointer)&point)))
982             goto error;
983           curcount++;
984           if (i>numcolors) /* make last bin black */
985 	    {
986 	      color = DXRGB(0.0, 0.0, 0.0);
987 	      if (!(DXAddArrayData(a_newcolors, colorcount, 1,
988 				   (Pointer)&color)))
989 	        goto error;
990 	      colorcount++;
991 	    }
992           else
993 	    {
994 	      switch (colortype) {
995               case (TYPE_FLOAT):
996 		color = DXRGB(col_ptr_f[3*(i-1)],
997 			      col_ptr_f[3*(i-1)+1],
998 			      col_ptr_f[3*(i-1)+2]);
999                 break;
1000               case (TYPE_INT):
1001 		color = DXRGB(col_ptr_i[3*(i-1)],
1002 			      col_ptr_i[3*(i-1)+1],
1003 			      col_ptr_i[3*(i-1)+2]);
1004 		break;
1005 	      default:
1006 	        break;
1007 	      }
1008 	      if (!(DXAddArrayData(a_newcolors, colorcount, 1,
1009 				   (Pointer)&color)))
1010 		goto error;
1011 	      colorcount++;
1012 	    }
1013 	}
1014       }
1015       /* else no corners */
1016       else {
1017 	if (horizontal == 0) {
1018 	  for (i=0; i<numpos; i++) {
1019 	    point = DXPt(0.0, pos_ptr[i],0.0);
1020 	    if (!(DXAddArrayData(a_newpositions, curcount,
1021 				 1, (Pointer)&point))) {
1022 	      goto error;
1023 	    }
1024 	    curcount++;
1025 	    if (lastok&&(i<=numcolors)) {
1026               switch (colortype) {
1027               case (TYPE_FLOAT):
1028 	      color = DXRGB(col_ptr_f[3*(i-1)],
1029 			    col_ptr_f[3*(i-1)+1],
1030 			    col_ptr_f[3*(i-1)+2]);
1031               break;
1032               case (TYPE_INT):
1033 	      color = DXRGB(col_ptr_i[3*(i-1)],
1034 			    col_ptr_i[3*(i-1)+1],
1035 			    col_ptr_i[3*(i-1)+2]);
1036               break;
1037 	      default:
1038 	      break;
1039               }
1040 	      if (!(DXAddArrayData(a_newcolors, colorcount,
1041 				   1, (Pointer)&color))) {
1042 		goto error;
1043 	      }
1044 	      colorcount++;
1045 	    }
1046 	    point = DXPt(1.0, pos_ptr[i],0.0);
1047 	    if (!(DXAddArrayData(a_newpositions, curcount,
1048 				 1, (Pointer)&point))) {
1049 	      goto error;
1050 	    }
1051 	    curcount++;
1052 	    lastok=1;
1053 	  }
1054 	}
1055 	else {
1056 	  for (i=0; i<numpos; i++) {
1057 	    point = DXPt(pos_ptr[i],0.0,0.0);
1058 	    if (!(DXAddArrayData(a_newpositions, curcount,
1059 				 1, (Pointer)&point))) {
1060 	      goto error;
1061 	    }
1062 	    curcount++;
1063 	    if (lastok&&(i<=numcolors)) {
1064               switch (colortype) {
1065               case (TYPE_FLOAT):
1066 	      color = DXRGB(col_ptr_f[3*(i-1)],
1067 			    col_ptr_f[3*(i-1)+1],
1068 			    col_ptr_f[3*(i-1)+2]);
1069               break;
1070               case (TYPE_INT):
1071 	      color = DXRGB(col_ptr_i[3*(i-1)],
1072 			    col_ptr_i[3*(i-1)+1],
1073 			    col_ptr_i[3*(i-1)+2]);
1074               break;
1075 	      default:
1076 	        break;
1077               }
1078 	      if (!(DXAddArrayData(a_newcolors, colorcount,
1079 				   1, (Pointer)&color))) {
1080 		goto error;
1081 	      }
1082 	      colorcount++;
1083 	    }
1084 	    point = DXPt(pos_ptr[i],1.0,0.0);
1085 	    if (!(DXAddArrayData(a_newpositions, curcount,
1086 				 1, (Pointer)&point))) {
1087 	      goto error;
1088 	    }
1089 	    curcount++;
1090 	    lastok=1;
1091 	  }
1092 	}
1093       }
1094     }
1095     }
1096 
1097 drawbar:
1098     /* now, if it's vertical, need to reorder positions so that the quads
1099        face the right way */
1100     if (!horizontal) {
1101        if (!DXGetArrayInfo(a_newpositions, &numpos, NULL,NULL,NULL,NULL))
1102          goto error;
1103        if (!strcmp(att,"positions")) {
1104          if (!_dxfTransposePositions(a_newpositions))
1105             goto error;
1106          if (!TransposeColors(a_newcolors))
1107             goto error;
1108        }
1109        else {
1110          if (!_dxfTransposePositions(a_newpositions))
1111             goto error;
1112        }
1113   }
1114   outo = (Object)DXNewField();
1115 
1116   if (!(DXSetComponentValue((Field)outo,"positions",
1117 			    (Object)a_newpositions))) {
1118     goto error;
1119   }
1120   a_newpositions=NULL;
1121   if (!(DXSetComponentValue((Field)outo,"colors", (Object)a_newcolors))) {
1122     goto error;
1123   }
1124   a_newcolors=NULL;
1125   if (!(DXSetComponentAttribute((Field)outo,"colors","dep",
1126 				(Object)DXNewString(att)))) {
1127     goto error;
1128   }
1129 
1130   if (curcount == 0) {
1131     DXSetError(ERROR_BAD_PARAMETER,"#11824");
1132     goto error;
1133   }
1134 
1135   if (horizontal) {
1136     if (!(a_newconnections = DXMakeGridConnections(2, curcount/2, 2))) {
1137       goto error;
1138     }
1139   }
1140   else {
1141     if (!(a_newconnections = DXMakeGridConnections(2, 2, curcount/2))) {
1142       goto error;
1143     }
1144   }
1145   if (!(DXSetComponentValue((Field)outo,"connections",
1146 			    (Object)a_newconnections))) {
1147     goto error;
1148   }
1149   a_newconnections=NULL;
1150   if (!(DXSetComponentAttribute((Field)outo, "connections", "ref",
1151 				(Object)DXNewString("positions")))) {
1152     goto error;
1153   }
1154   if (!(DXSetComponentAttribute((Field)outo, "connections", "element type",
1155 				(Object)DXNewString("quads")))) {
1156     goto error;
1157   }
1158 
1159   /* first get the map to start at 0.0 */
1160 
1161 
1162   /* now I know that the color map is monotonic */
1163   length = maxvalue-minvalue;
1164 
1165   scaleheight = shape.height/length;
1166   scalewidth = shape.width;
1167   /* figure out the minimum tic size */
1168   minticsize = MINTICPIX;
1169 
1170 
1171 
1172   /* check the label param */
1173   if (!in[7]) {
1174      label = nullstring;
1175   }
1176   else {
1177      if (!DXExtractString(in[7], &label)) {
1178         DXSetError(ERROR_DATA_INVALID,"#10200", "label");
1179         goto error;
1180      }
1181   }
1182 
1183   /* now do user-given tick locations and labels */
1184   if (in[12]) {
1185      if (!(DXGetObjectClass(in[12])==CLASS_ARRAY)) {
1186          DXSetError(ERROR_BAD_PARAMETER,"ticklocations must be a scalar list");
1187          return ERROR;
1188      }
1189      ticklocations = (Array)in[12];
1190    }
1191    if (in[13]) {
1192      if (!(DXGetObjectClass(in[13])==CLASS_ARRAY)) {
1193          DXSetError(ERROR_BAD_PARAMETER,"ticklabels must be a string list");
1194          return ERROR;
1195      }
1196      if (!DXGetArrayInfo((Array)in[13], &numlist, NULL,NULL,NULL,NULL))
1197         goto error;
1198      if (!in[12]) {
1199          /* need to make an array to use. It will go from 0 to n-1 */
1200          ticklocations = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0);
1201          if (!ticklocations) goto error;
1202          list_ptr = DXAllocate(numlist*sizeof(float));
1203          if (!list_ptr) goto error;
1204          for (i=0; i<numlist; i++)
1205              list_ptr[i] = (float)i;
1206          if (!DXAddArrayData(ticklocations, 0, numlist, list_ptr))
1207              goto error;
1208          DXFree((Pointer)list_ptr);
1209       }
1210    }
1211 
1212    /* determine if the user has set a fixed label size */
1213    if (in[14]) {
1214      if (!DXExtractInteger(in[14], &dofixedfontsize)) {
1215         DXSetError(ERROR_DATA_INVALID,"usefixedfontsize must be 0 or 1");
1216         goto error;
1217      }
1218      if ((dofixedfontsize != 0)&&(dofixedfontsize != 1)) {
1219         DXSetError(ERROR_DATA_INVALID,"usefixedfontsize must be 0 or 1");
1220         goto error;
1221      }
1222   }
1223   if (dofixedfontsize) {
1224      if (in[15]) {
1225         if (!DXExtractInteger(in[15], &fixedfontsizepixels)) {
1226            DXSetError(ERROR_DATA_INVALID,"fixedfontsize must be a positive integer");
1227            goto error;
1228         }
1229         if (fixedfontsize < 0) {
1230            DXSetError(ERROR_DATA_INVALID,"fixedfontsize must be a positive integer");
1231            goto error;
1232         }
1233      }
1234      if (horizontal) fixedfontsize = fixedfontsizepixels/shape.height;
1235      else fixedfontsize = fixedfontsizepixels/shape.width;
1236 
1237   }
1238 
1239   /* get the thing into pixel units now */
1240   if (doaxes) {
1241     if (horizontal == 0) {
1242       axeshandle = _dxfNew2DAxesObject();
1243       if (!axeshandle)
1244 	goto error;
1245       ob = (Object)DXNewXform((Object)outo,
1246 			      DXScale(scalewidth, scaleheight, 1.0));
1247 
1248       /* put a little negative fuzz on the color bar object */
1249       DXSetFloatAttribute((Object)ob, "fuzz", -2.0);
1250       _dxfSet2DAxesCharacteristic(axeshandle, "OBJECT", (Pointer)&ob);
1251       _dxfSet2DAxesCharacteristic(axeshandle, "XLABEL", (Pointer)extralabel);
1252       _dxfSet2DAxesCharacteristic(axeshandle, "YLABEL",(Pointer)label);
1253       _dxfSet2DAxesCharacteristic(axeshandle, "FONT",(Pointer)fontname);
1254       _dxfSet2DAxesCharacteristic(axeshandle, "LABELSCALE",
1255                                   (Pointer)&labelscale);
1256       _dxfSet2DAxesCharacteristic(axeshandle,"TICKS", (Pointer)&intzero);
1257       _dxfSet2DAxesCharacteristic(axeshandle,"TICKSX", (Pointer)&intzero);
1258       _dxfSet2DAxesCharacteristic(axeshandle,"TICKSY", (Pointer)&tics);
1259       if (corners)
1260       _dxfSet2DAxesCharacteristic(axeshandle, "CORNERS", (Pointer)&corners);
1261       _dxfSet2DAxesCharacteristic(axeshandle,"FRAME", (Pointer)&frame);
1262       _dxfSet2DAxesCharacteristic(axeshandle,"ADJUST", (Pointer)&adjust);
1263       _dxfSet2DAxesCharacteristic(axeshandle,"GRID", (Pointer)&intzero);
1264       _dxfSet2DAxesCharacteristic(axeshandle,"ISLOGX", (Pointer)&intzero);
1265       _dxfSet2DAxesCharacteristic(axeshandle,"ISLOGY", (Pointer)&intzero);
1266       _dxfSet2DAxesCharacteristic(axeshandle,"MINTICKSIZE",
1267 				  (Pointer)&minticsize);
1268       _dxfSet2DAxesCharacteristic(axeshandle,"AXESLINES",(Pointer)&axeslines);
1269       _dxfSet2DAxesCharacteristic(axeshandle,"JUSTRIGHT",(Pointer)&intzero);
1270       _dxfSet2DAxesCharacteristic(axeshandle,"RETURNCORNERS",
1271 				  (Pointer)actualcorners);
1272       _dxfSet2DAxesCharacteristic(axeshandle,"LABELCOLOR",
1273 				  (Pointer)&labelcolor);
1274       _dxfSet2DAxesCharacteristic(axeshandle,"TICKCOLOR", (Pointer)&ticcolor);
1275       _dxfSet2DAxesCharacteristic(axeshandle,"AXESCOLOR", (Pointer)&framecolor);
1276       _dxfSet2DAxesCharacteristic(axeshandle,"XLOCS", (Pointer)NULL);
1277       _dxfSet2DAxesCharacteristic(axeshandle,"YLOCS", (Pointer)ticklocations);
1278       _dxfSet2DAxesCharacteristic(axeshandle,"XLABELS", (Pointer)NULL);
1279       _dxfSet2DAxesCharacteristic(axeshandle,"YLABELS", (Pointer)in[13]);
1280       _dxfSet2DAxesCharacteristic(axeshandle,"DOFIXEDFONTSIZE", (Pointer)&dofixedfontsize);
1281       _dxfSet2DAxesCharacteristic(axeshandle,"FIXEDFONTSIZE", (Pointer)&fixedfontsize);
1282 
1283       if (DXGetError() != ERROR_NONE) goto error;
1284 
1285       o = (Object)_dxfAxes2D(axeshandle);
1286       if (!o) goto error;
1287       /* get the new bounding box */
1288       if (!DXBoundingBox(o,box)) goto error;
1289       min=box[0];
1290       max=box[0];
1291       for (i=0; i<7; i++) {
1292         min = DXMin(min,box[i]);
1293       }
1294       for (i=0; i<7; i++) {
1295         max = DXMax(max,box[i]);
1296       }
1297       shape.width = max.x - min.x;
1298       shape.height = max.y - min.y;
1299       newo = (Object)DXNewXform(o, DXTranslate(
1300 			   DXPt(shape.width*(-translation.x
1301 					     +
1302 					     (min.x/(min.x-max.x))),
1303 				shape.height*(-translation.y +
1304 					      (min.y/(min.y-max.y))),
1305 				0.0)));
1306       if (!newo) goto error;
1307     }
1308     /* else horizontal */
1309     else {
1310       axeshandle = _dxfNew2DAxesObject();
1311       if (!axeshandle)
1312 	goto error;
1313       ob = (Object)DXNewXform((Object)outo,
1314 			      DXScale(scaleheight, scalewidth, 1.0));
1315       /* put a little negative fuzz on the color bar object */
1316       DXSetFloatAttribute((Object)ob, "fuzz", -2);
1317       _dxfSet2DAxesCharacteristic(axeshandle, "OBJECT", (Pointer)&ob);
1318       _dxfSet2DAxesCharacteristic(axeshandle, "XLABEL",(Pointer)label);
1319       _dxfSet2DAxesCharacteristic(axeshandle, "YLABEL", (Pointer)extralabel);
1320       _dxfSet2DAxesCharacteristic(axeshandle, "FONT",(Pointer)fontname);
1321       _dxfSet2DAxesCharacteristic(axeshandle, "LABELSCALE",
1322                                  (Pointer)&labelscale);
1323       _dxfSet2DAxesCharacteristic(axeshandle,"TICKS", (Pointer)&intzero);
1324       _dxfSet2DAxesCharacteristic(axeshandle,"TICKSX", (Pointer)&tics);
1325       _dxfSet2DAxesCharacteristic(axeshandle,"TICKSY", (Pointer)&intzero);
1326       if (corners)
1327       _dxfSet2DAxesCharacteristic(axeshandle, "CORNERS", (Pointer)&corners);
1328       _dxfSet2DAxesCharacteristic(axeshandle,"FRAME", (Pointer)&frame);
1329       _dxfSet2DAxesCharacteristic(axeshandle,"ADJUST", (Pointer)&adjust);
1330       _dxfSet2DAxesCharacteristic(axeshandle,"GRID", (Pointer)&intzero);
1331       _dxfSet2DAxesCharacteristic(axeshandle,"ISLOGX", (Pointer)&intzero);
1332       _dxfSet2DAxesCharacteristic(axeshandle,"ISLOGY", (Pointer)&intzero);
1333       _dxfSet2DAxesCharacteristic(axeshandle,"MINTICKSIZE",
1334 				  (Pointer)&minticsize);
1335       _dxfSet2DAxesCharacteristic(axeshandle,"AXESLINES",(Pointer)&axeslines);
1336       _dxfSet2DAxesCharacteristic(axeshandle,"JUSTRIGHT",(Pointer)&intzero);
1337       _dxfSet2DAxesCharacteristic(axeshandle,"RETURNCORNERS",
1338 				  (Pointer)actualcorners);
1339       _dxfSet2DAxesCharacteristic(axeshandle,"LABELCOLOR",
1340 				  (Pointer)&labelcolor);
1341       _dxfSet2DAxesCharacteristic(axeshandle,"TICKCOLOR", (Pointer)&ticcolor);
1342       _dxfSet2DAxesCharacteristic(axeshandle,"AXESCOLOR", (Pointer)&framecolor);
1343       _dxfSet2DAxesCharacteristic(axeshandle,"XLOCS", (Pointer)ticklocations);
1344       _dxfSet2DAxesCharacteristic(axeshandle,"YLOCS", (Pointer)NULL);
1345       _dxfSet2DAxesCharacteristic(axeshandle,"XLABELS", (Pointer)in[13]);
1346       _dxfSet2DAxesCharacteristic(axeshandle,"YLABELS", (Pointer)NULL);
1347       _dxfSet2DAxesCharacteristic(axeshandle,"DOFIXEDFONTSIZE", (Pointer)&dofixedfontsize);
1348       _dxfSet2DAxesCharacteristic(axeshandle,"FIXEDFONTSIZE", (Pointer)&fixedfontsize);
1349 
1350       /* &&& there are prob. corners issues here too */
1351       if (DXGetError() != ERROR_NONE) goto error;
1352 
1353       /* get the new bounding box */
1354       o = (Object)_dxfAxes2D(axeshandle);
1355       if (!o) goto error;
1356       if (!DXBoundingBox(o,box)) goto error;
1357       min=box[0];
1358       max=box[0];
1359       for (i=0; i<7; i++) {
1360         min = DXMin(min,box[i]);
1361       }
1362       for (i=0; i<7; i++) {
1363         max = DXMax(max,box[i]);
1364       }
1365       shape.width = max.y - min.y;
1366       shape.height = max.x - min.x;
1367       newo = (Object)DXNewXform(o,
1368 				DXTranslate(DXPt(shape.height*(-translation.x +
1369                                       (min.x/(min.x-max.x))),
1370 				       shape.width*(-translation.y +
1371 						    (min.y/(min.y-max.y))),
1372 						 0.0)));
1373       if (!newo) goto error;
1374     }
1375   }
1376   /* for non-field color maps, don't call autoaxes */
1377   else {
1378     if (horizontal == 0) {
1379       /* DXTranslate(_dxfAutoAxes(Scaled to pixel object)) */
1380       newo = (Object)DXNewXform(
1381 				(Object)DXNewXform((Object)outo,
1382 						   DXScale(scalewidth,
1383 							   scaleheight, 1.0)),
1384 				DXTranslate(DXPt(shape.width*(-translation.x),
1385                                    shape.height*(-translation.y +
1386 					      (minvalue/(minvalue-maxvalue))),
1387 						 0.0)));
1388       if (!newo) goto error;
1389     }
1390     /* else horizontal */
1391     else {
1392       /* DXTranslate(_dxfAutoAxes(Scaled to pixel object)) */
1393       newo = (Object)DXNewXform(
1394 				(Object)DXNewXform((Object)outo,
1395 						   DXScale(scaleheight,
1396 							   scalewidth,  1.0)),
1397 				DXTranslate(DXPt(shape.height*(-translation.x +
1398 				      (minvalue/(minvalue-maxvalue))),
1399 						 -translation.y*shape.width,
1400 						 0.0)));
1401       if (!newo) goto error;
1402     }
1403   }
1404 
1405   flag = SCREEN_VIEWPORT;
1406   if (!(outscreen =(Object)DXNewScreen((Object)newo, flag, 1))) {
1407     goto error;
1408   }
1409 
1410   oo = (Object)DXNewXform((Object)outscreen, DXTranslate(translation));
1411   if (!oo) goto error;
1412 
1413   /* make it immovable */
1414   ooo = (Object)DXNewScreen(oo, SCREEN_STATIONARY, 0);
1415   if (!ooo) goto error;
1416 
1417 
1418 
1419   out[0]=ooo;
1420   DXDelete((Object)corners);
1421   DXDelete((Object)a_newpositions);
1422   DXDelete((Object)a_newconnections);
1423   DXDelete((Object)a_newcolors);
1424   _dxfFreeAxesHandle((Pointer)axeshandle);
1425   if (!in[12]) DXDelete((Object)ticklocations);
1426   return OK;
1427 
1428  error:
1429   if (!in[12]) DXDelete((Object)ticklocations);
1430   DXDelete((Object)oo);
1431   DXDelete((Object)corners);
1432   DXDelete((Object)a_newpositions);
1433   DXDelete((Object)a_newconnections);
1434   DXDelete((Object)a_newcolors);
1435   if (axeshandle)
1436     _dxfFreeAxesHandle((Pointer)axeshandle);
1437   return ERROR;
1438 }
1439 
1440 
1441 
1442 
_dxfGetColorBarAnnotationColors(Object colors,Object which,RGBColor defaultticcolor,RGBColor defaultlabelcolor,RGBColor * ticcolor,RGBColor * labelcolor,RGBColor * framecolor,int * frame)1443 Error _dxfGetColorBarAnnotationColors(Object colors, Object which,
1444                                      RGBColor defaultticcolor,
1445                                      RGBColor defaultlabelcolor,
1446                                      RGBColor *ticcolor, RGBColor *labelcolor,
1447                                      RGBColor *framecolor, int *frame)
1448 {
1449   RGBColor *colorlist =NULL;
1450   int i, numcolors, numcolorobjects;
1451   char *colorstring, *newcolorstring;
1452 
1453   *frame = 0;
1454 
1455 
1456   /* in[9] is the colors list */
1457   /* first set up the default colors */
1458   *ticcolor = defaultticcolor;
1459   *labelcolor = defaultlabelcolor;
1460   if (colors) {
1461     if (DXExtractNthString(colors,0,&colorstring)) {
1462       /* it's a list of strings */
1463       /* first figure out how many there are */
1464       if (!_dxfHowManyStrings(colors, &numcolors))
1465 	goto error;
1466       /* allocate space for the 3-vectors */
1467       colorlist = DXAllocateLocal(numcolors*sizeof(RGBColor));
1468       if (!colorlist) goto error;
1469       for (i=0; i<numcolors;i++) {
1470         DXExtractNthString(colors,i,&colorstring);
1471         if (!strcmp(colorstring,"clear")) {
1472           colorlist[i]=DXRGB(-1.0, -1.0, -1.0);
1473         }
1474         else {
1475           if (!DXColorNameToRGB(colorstring, &colorlist[i]))
1476             goto error;
1477         }
1478       }
1479     }
1480     else {
1481       if (!DXQueryParameter(colors, TYPE_FLOAT, 3, &numcolors)) {
1482 	DXSetError(ERROR_BAD_PARAMETER,
1483 		   "colors must be a list of strings or a list of 3-vectors");
1484 	goto error;
1485       }
1486       /* it's a list of 3-vectors */
1487       colorlist = DXAllocateLocal(numcolors*sizeof(RGBColor));
1488       if (!colorlist) goto error;
1489       if (!DXExtractParameter(colors, TYPE_FLOAT, 3, numcolors,
1490 			      (Pointer)colorlist)) {
1491         DXSetError(ERROR_DATA_INVALID,"bad color list");
1492 	goto error;
1493       }
1494     }
1495   }
1496   if (!which) {
1497     if (colors) {
1498       /* all objects get whatever color was there */
1499       if (numcolors != 1) {
1500 	DXSetError(ERROR_BAD_PARAMETER,
1501 		   "more than one color specified for colors parameter; this requires a list of objects to color");
1502 	goto error;
1503       }
1504       *ticcolor = colorlist[0];
1505       *labelcolor = colorlist[0];
1506     }
1507   }
1508   else {
1509     /* a list of strings was specified */
1510     /* figure out how many */
1511     if (!_dxfHowManyStrings(which, &numcolorobjects)) {
1512       DXSetError(ERROR_BAD_PARAMETER,"annotation must be a string list");
1513       goto error;
1514     }
1515     if (numcolors==1) {
1516       for (i=0; i< numcolorobjects; i++) {
1517 	DXExtractNthString(which, i, &colorstring);
1518 	_dxfLowerCase(colorstring, &newcolorstring);
1519 	/* XXX lower case */
1520 	if (!strcmp(newcolorstring, "ticks"))
1521 	  *ticcolor = colorlist[0];
1522 	else if (!strcmp(newcolorstring, "labels"))
1523 	  *labelcolor = colorlist[0];
1524 	else if (!strcmp(newcolorstring, "frame")) {
1525           if ((colorlist[0].r==-1)&&
1526               (colorlist[0].g==-1)&&
1527               (colorlist[0].b==-1)) {
1528               *frame=0;
1529           }
1530           else {
1531               *frame=1;
1532               *framecolor=colorlist[0];
1533           }
1534         }
1535 	else if (!strcmp(newcolorstring,"all")) {
1536 	  *ticcolor = colorlist[0];
1537 	  *labelcolor = colorlist[0];
1538 	}
1539 	else {
1540 	  DXSetError(ERROR_BAD_PARAMETER,
1541 		     "annotation objects must be one of \"ticks\", \"labels\", or \"frame\" ");
1542 	  goto error;
1543 	}
1544 	DXFree((Pointer)newcolorstring);
1545       }
1546     }
1547     else {
1548       if (numcolors != numcolorobjects) {
1549         DXSetError(ERROR_BAD_PARAMETER,"number of colors must match number of annotation objects if number of colors is greater than 1");
1550         goto error;
1551       }
1552       for (i=0; i< numcolorobjects; i++) {
1553 	DXExtractNthString(which, i, &colorstring);
1554 	_dxfLowerCase(colorstring, &newcolorstring);
1555 	/* XXX lower case */
1556 	if (!strcmp(newcolorstring, "ticks"))
1557 	  *ticcolor = colorlist[i];
1558 	else if (!strcmp(newcolorstring, "labels"))
1559 	  *labelcolor = colorlist[i];
1560 	else if (!strcmp(newcolorstring, "frame")) {
1561 	  if ((colorlist[i].r==-1)&&
1562 	      (colorlist[i].g==-1)&&
1563 	      (colorlist[i].b==-1)) {
1564 	    *frame = 0;
1565 	  }
1566 	  else {
1567 	    *frame = 1;
1568 	    *framecolor = colorlist[i];
1569 	  }
1570 	}
1571 	else {
1572 	  DXSetError(ERROR_BAD_PARAMETER,
1573 		     "annotation objects must be one of \"ticks\", \"labels\", or \"frame\" ");
1574 	  goto error;
1575 	}
1576 	DXFree((Pointer)newcolorstring);
1577       }
1578     }
1579   }
1580   DXFree((Pointer)colorlist);
1581   return OK;
1582  error:
1583   DXFree((Pointer)colorlist);
1584   return ERROR;
1585 }
1586 
_dxfTransposePositions(Array array)1587 Error _dxfTransposePositions(Array array)
1588 {
1589 
1590   int i, num;
1591   Point2D *scratch=NULL, *oldarrayptr;
1592 
1593 
1594   if (!DXGetArrayInfo(array, &num, NULL, NULL, NULL, NULL))
1595      goto error;
1596   oldarrayptr = (Point2D *)DXGetArrayData(array);
1597   scratch = (Point2D *)DXAllocate(num*sizeof(Point2D));
1598   if (!scratch) goto error;
1599   for (i=0; i<num; i+=2) {
1600      scratch[i/2]=oldarrayptr[i];
1601      scratch[num/2 + i/2 ]= oldarrayptr[i+1];
1602   }
1603   if (!DXAddArrayData(array, 0, num, scratch))
1604      goto error;
1605 
1606   DXFree(scratch);
1607   return OK;
1608 
1609 
1610 error:
1611   DXFree(scratch);
1612   return ERROR;
1613 
1614 }
1615 
1616 
TransposeColors(Array array)1617 static Error TransposeColors(Array array)
1618 {
1619 
1620   int i, num;
1621   Point *scratch=NULL, *oldarrayptr;
1622 
1623 
1624   if (!DXGetArrayInfo(array, &num, NULL, NULL, NULL, NULL))
1625      goto error;
1626   oldarrayptr = (Point *)DXGetArrayData(array);
1627   scratch = (Point *)DXAllocate(num*sizeof(Point));
1628   if (!scratch) goto error;
1629   for (i=0; i<num; i+=2) {
1630      scratch[i/2]=oldarrayptr[i];
1631      scratch[num/2 + i/2 ]= oldarrayptr[i+1];
1632   }
1633   if (!DXAddArrayData(array, 0, num, scratch))
1634      goto error;
1635 
1636   DXFree(scratch);
1637   return OK;
1638 
1639 
1640 error:
1641   DXFree(scratch);
1642   return ERROR;
1643 
1644 }
1645 
1646 
1647 
SimpleBar(Array * pos,Array * col,RGBColor * color)1648 static Error SimpleBar(Array *pos, Array *col, RGBColor *color)
1649 {
1650     Array a_newpositions, a_newcolors;
1651     float *pos_ptr;
1652     int i;
1653 
1654     if (!(a_newpositions = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,2))) {
1655       goto error;
1656     }
1657     if (!(a_newcolors = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,3))) {
1658       goto error;
1659     }
1660     if (!(DXAddArrayData(a_newpositions,0,4,NULL))) {
1661       goto error;
1662     }
1663     for (i=0; i<4; i++) {
1664       if (!(DXAddArrayData(a_newcolors,i,1,(Pointer)color))) {
1665         goto error;
1666       }
1667     }
1668     pos_ptr = (float *)DXGetArrayData(a_newpositions);
1669     /* bottom left */
1670     pos_ptr[0] = pos_ptr[1] = 0.0;
1671     /* bottom right */
1672     pos_ptr[2] = 1.0;
1673     pos_ptr[3] = 0.0;
1674     /* top left */
1675     pos_ptr[4] = 0.0;
1676     pos_ptr[5] = 1.0;
1677     /* top right */
1678     pos_ptr[6] = 1.0;
1679     pos_ptr[7] = 1.0;
1680 
1681     *pos = a_newpositions;
1682     *col = a_newcolors;
1683     return OK;
1684 error:
1685     return ERROR;
1686 }
1687