/***********************************************************************/ /* 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 static Object ScreenObject(Object, Vector, Vector, int, int, int); m_Screen(Object *in, Object *out) { Point translation, size, box[8], min, max; Object o=NULL, oo=NULL, outscreen=NULL, ino; Object oscreen=NULL, ooscreen=NULL, oooscreen=NULL; int depthflag, units, how, i; float width, height, scalewidth, scaleheight, scalarsize; /* in[0] is the object to be turned into a screen object */ if (!in[0]) { DXSetError(ERROR_BAD_PARAMETER, "#10000", "object"); return ERROR; } ino = in[0]; /* in[1] is the position */ if (in[1]) { if (!DXExtractParameter(in[1], TYPE_FLOAT, 3, 1, (Pointer)&translation)) { if (!DXExtractParameter(in[1], TYPE_FLOAT, 2, 1, (Pointer)&translation)) { DXSetError(ERROR_BAD_PARAMETER,"#10231", "position", 2, 3); goto error; } } translation.z = 0.0; } /* in[2] is units of screen object location */ if (in[2]) { if (!DXExtractInteger(in[2], &how)) { DXSetError(ERROR_BAD_PARAMETER, "#10040", "how", 0, 2); goto error; } if ((how < 0)||(how > 2)) { DXSetError(ERROR_BAD_PARAMETER, "#10040", "how", 0, 2); goto error; } if (how == 0) how = SCREEN_VIEWPORT; else if (how == 1) how = SCREEN_PIXEL; else how = SCREEN_WORLD; } else { how = SCREEN_VIEWPORT; } if (!in[1]) { if (how == SCREEN_VIEWPORT) { translation.x = 0.5; translation.y = 0.5; translation.z = 0.0; } else { translation.x = 0.0; translation.y = 0.0; translation.z = 0.0; } } /* now check the translation */ if (how==SCREEN_VIEWPORT) { if ((translation.x < 0)||(translation.y < 0)|| (translation.x > 1)||(translation.y > 1)) { DXSetError(ERROR_BAD_PARAMETER, "#10110", "for how = viewport, position", 0, 1); goto error; } } else if (how==SCREEN_PIXEL) { if ((translation.x < 0)||(translation.y < 0)) { DXSetError(ERROR_BAD_PARAMETER, "#10532", "for how = pixel, position"); goto error; } } /* in[3] is the size */ if (in[3]) { /* here's where you want to handle a single number also */ if (DXExtractFloat(in[3], &scalarsize)) { size.x = scalarsize; /* if the user specifies only an x size, then the aspect ratio * of the object is preserved. size.y = -1 is a flag that this * is what's going on */ size.y = -1; if (size.x < 0) { DXSetError(ERROR_BAD_PARAMETER,"#10531", "size"); goto error; } } else { if (!DXExtractParameter(in[3], TYPE_FLOAT, 3, 1, (Pointer)&size)) { if (!DXExtractParameter(in[3], TYPE_FLOAT, 2, 1, (Pointer)&size)) { DXSetError(ERROR_BAD_PARAMETER,"#10231", "size", 2, 3); goto error; } } if ((size.x < 0)||(size.y<0.0)) { DXSetError(ERROR_BAD_PARAMETER,"#10531", "size"); goto error; } } size.z = 0.0; } else { /* default */ size.x = 100; size.y = -1; size.z = 1; } /* now check the translation */ if (how == SCREEN_VIEWPORT) { if ((translation.x < 0)||(translation.x > 1)||(translation.y<0.0)|| (translation.y>1.0)) { DXSetError(ERROR_BAD_PARAMETER, "#10110", "for viewport relative, each position element", 0, 1); goto error; } } /* now the coordinates of the size parameter */ if (in[4]) { if (!DXExtractInteger(in[4], &units)) { DXSetError(ERROR_NOT_IMPLEMENTED,"#10370","units", "1"); goto error; } if (units != 1) { DXSetError(ERROR_NOT_IMPLEMENTED,"#10370","units", "1"); goto error; } } else { units = 1; } /* in[5] is within, infrontof, behind */ if (in[5]) { if (!DXExtractInteger(in[5], &depthflag)) { DXSetError(ERROR_BAD_PARAMETER, "#10040", "depth", -1, 1); goto error; } if ((depthflag != -1)&&(depthflag != 0)&&(depthflag != 1)) { DXSetError(ERROR_BAD_PARAMETER, "#10040", "depth", -1, 1); goto error; } } else { depthflag = 1; } if (!(out[0] = ScreenObject(ino, translation, size, how, units, depthflag))) goto error; return OK; error: return ERROR; } static Object ScreenObject(Object ino, Vector translation, Vector size, int how, int units, int depthflag) { Point box[8], min, max; Object o=NULL, oo=NULL, outscreen=NULL; Object oscreen=NULL, ooscreen=NULL, oooscreen=NULL; int i; float width, height, scalewidth, scaleheight, xtranslation, ytranslation; /* need the bounding box of the input object */ if (!DXBoundingBox(ino,box)) { DXSetError(ERROR_INVALID_DATA,"#11020", "object"); goto error; } min=box[0]; max=box[0]; for (i=0; i<7; i++) { min = DXMin(min,box[i]); } for (i=0; i<7; i++) { max = DXMax(max,box[i]); } width = max.x - min.x; height = max.y - min.y; /* get the thing into pixel units now */ /* now nudge it a bit so that the reference point is at "position" relative to the object (just like caption, colorbar, etc) */ if (how != SCREEN_VIEWPORT) o = (Object)DXNewXform(ino, DXTranslate(DXPt(-min.x, -min.y, 0.0))); else { if (width != 0) xtranslation = width*(-translation.x - min.x/width); else xtranslation = 0.0; if (height != 0) ytranslation = height*(-translation.y - min.y/height); else ytranslation = 0.0; o = (Object)DXNewXform(ino, DXTranslate(DXPt(xtranslation, ytranslation, 0.0))); } if (!o) goto error; /* scale the object to be unit size; therefore need to use the width and height. Different behavior if the user specified only an x size. */ if (size.y >= 0) { if (width > 0) scalewidth = size.x/width; else scalewidth = size.x; if (height > 0) scaleheight = size.y/height; else scaleheight = size.y; oo = (Object)DXNewXform((Object)o, DXScale(scalewidth, scaleheight, 1.0)); } else { if (width > 0) scalewidth = size.x/width; else scalewidth = size.x; oo = (Object)DXNewXform((Object)o, DXScale(scalewidth, scalewidth, 1.0)); } if (!o) goto error; /* now make it a screen object */ if (!(outscreen =(Object)DXNewScreen((Object)oo, how, depthflag))) { goto error; } /* now we're ready to really translate it where it's supposed to go */ ooscreen = (Object)DXNewXform((Object)outscreen, DXTranslate(translation)); if (!ooscreen) goto error; /* make it immovable (only if not in world coordinates) */ if (how != SCREEN_WORLD) { oooscreen = (Object)DXNewScreen(ooscreen, SCREEN_STATIONARY, 0); if (!oooscreen) goto error; return oooscreen; } else { return ooscreen; } error: DXDelete((Object)o); DXDelete((Object)oo); DXDelete((Object)oscreen); DXDelete((Object)ooscreen); DXDelete((Object)oooscreen); return NULL; }