/***********************************************************************/ /* 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 /* * $Header: /home/gda/dxcvs/dx/src/exec/dxmods/text.c,v 1.3 1999/05/10 15:45:32 gda Exp $ */ #include /* XXX (and is char* ok in arg block) */ extern Array _dxfPostArray(Field, char *, char *); typedef struct textarg { Field fieldin; Group groupout; float height; char *font; Vector direction; Vector up; int direction_defaulted; int up_defaulted; } Textarg; static Error TextField(Pointer p) { Textarg *textarg = (Textarg *)p; Field fieldin; Group groupout; Object font=NULL, o, t; float height; char *f, *attr, *attr1, *string; Vector direction, up, z; float dotprod; Matrix m; Point position; int i, j=0, numitems, rank, shape[8], posdim, datadim, regcolors, posted; int trank, tshape[8]; int brank, bshape[8]; int nrank, nshape[8]; int direction_defaulted, up_defaulted, delayed; int numtextpos, n, counts[8], groupcount=0; float posorigin[30], posdeltas[30]; Type type, ttype, btype, ntype; Category category; float *pos_ptr=NULL; RGBColor *colors_ptr; RGBColor color; Array positions=NULL, data, invalid, colors, textcolors=NULL, textpositions; Array tangents=NULL, binormals=NULL, normals=NULL, colormap=NULL; InvalidComponentHandle invalidhandle=NULL; float *tangents_ptr, *binormals_ptr, *normals_ptr; ubyte *delayedcolors_ptr, delayedcolor; Point current_tangent, current_binormal, current_normal; RGBColor *colormap_ptr; fieldin = textarg->fieldin; groupout = textarg->groupout; height = textarg->height; f = textarg->font; direction = textarg->direction; up = textarg->up; direction_defaulted = textarg->direction_defaulted; up_defaulted = textarg->up_defaulted; /* uses cache */ if (!f) f = "variable"; font = DXGetFont(f, NULL, NULL); if (!font) goto error; data = (Array)DXGetComponentValue(fieldin,"data"); if (!data) { DXSetError(ERROR_INVALID_DATA,"#10250", "field","data"); goto error; } DXGetArrayInfo(data, &numitems, &type, &category, &rank, shape); if (type != TYPE_STRING) { DXSetError(ERROR_INVALID_DATA,"#10370", "data component", "type string"); goto error; } if (category != CATEGORY_REAL) { DXSetError(ERROR_INVALID_DATA,"data component must be category real"); goto error; } if (rank != 1) { DXSetError(ERROR_INVALID_DATA,"rank of data component must equal 1"); goto error; } datadim = shape[0]; attr = DXGetString((String)DXGetComponentAttribute((Field)fieldin, "data", "dep")); if (!attr) { DXSetError(ERROR_MISSING_DATA,"#10241", "data"); goto error; } if (strcmp(attr,"positions")&&(strcmp(attr,"connections"))) { DXSetError(ERROR_INVALID_DATA, "data component must be dep positions or dep connections"); goto error; } /* see if there's an invalid positions array */ if (!strcmp(attr,"positions")) { invalid = (Array)DXGetComponentValue(fieldin,"invalid positions"); if (invalid) { invalidhandle = DXCreateInvalidComponentHandle((Object)fieldin, NULL, "positions"); if (!invalidhandle) goto error; } } else { invalid = (Array)DXGetComponentValue(fieldin,"invalid connections"); if (invalid) { invalidhandle = DXCreateInvalidComponentHandle((Object)fieldin, NULL,"connections"); if (!invalidhandle) goto error; } } /* see if there's a colors component */ colors = (Array)DXGetComponentValue(fieldin,"colors"); /* check for delayed */ if (colors) { DXGetArrayInfo(colors, NULL, &type, NULL, &rank, shape); if ((type==TYPE_FLOAT)&&(rank==1)&&(shape[0]==3)) { delayed = 0; } else { if (rank==0) { rank=1; shape[0]=1; } /* better be delayed */ if ((type != TYPE_UBYTE)||(rank != 1) || (shape[0] != 1)) { DXSetError(ERROR_INVALID_DATA,"#11363", "byte colors", 1); goto error; } if (!(colormap = (Array)DXGetComponentValue(fieldin,"color map"))) { DXSetError(ERROR_MISSING_DATA,"#13050"); goto error; } colormap_ptr = (RGBColor *)DXGetArrayData(colormap); delayed = 1; } } regcolors = 1; if (colors) { if (!delayed) { if (!(DXQueryConstantArray(colors, NULL, (Pointer)&color))) regcolors = 0; colors_ptr = (RGBColor *)DXGetArrayData(colors); } else if (!(DXQueryConstantArray(colors, NULL, (Pointer)&delayedcolor))) regcolors = 0; delayedcolors_ptr = (ubyte *)DXGetArrayData(colors); } posted = 0; if (!strcmp(attr,"connections")) { /* I need to check whether the positions are regular. If they * are, a simple grid shift is in order. Otherwise, use PostArray * to shift them */ Array pos, con; pos = (Array)DXGetComponentValue((Field)fieldin,"positions"); con = (Array)DXGetComponentValue((Field)fieldin,"connections"); if ((DXQueryGridPositions(pos, &n, counts, posorigin, posdeltas)) && DXQueryGridConnections(con, NULL, NULL)) { for (i=0; i 1) { posorigin[i]+=0.5*posdeltas[i + j*n]; } } } for (i=0; i1) counts[i] = counts[i]-1; } positions = DXMakeGridPositionsV(n, counts, posorigin, posdeltas); } /* else the positions are irregular */ else { positions = _dxfPostArray((Field)fieldin, "positions","connections"); } if (!positions) { DXSetError(ERROR_BAD_PARAMETER, "could not compute text positions for cell-centered data"); goto error; } posted = 1; } else { /* get positions component */ positions = (Array)DXGetComponentValue(fieldin,"positions"); if (!positions) { DXSetError(ERROR_INVALID_DATA,"#10250", "field", "positions"); goto error; } } DXGetArrayInfo(positions, &numitems, &type, &category, &rank, shape); if ((type != TYPE_FLOAT)||(category != CATEGORY_REAL)) { DXSetError(ERROR_INVALID_DATA, "positions must be type float, category real"); goto error; } if (rank != 1) { DXSetError(ERROR_INVALID_DATA, "positions must be rank 1"); goto error; } if ((shape[0]<1) || (shape[0] > 3)) { DXSetError(ERROR_INVALID_DATA, "#10370", "positions", "1, 2, or 3-dimensional"); goto error; } posdim= shape[0]; /* see if there's a tangent component (correponds to direction) */ /* if the user specified direction in the config dialog box, we don't really care if there's a tangents component */ tangents = (Array)DXGetComponentValue(fieldin,"tangents"); if (tangents) { if (direction_defaulted) { tangents_ptr = (float *)DXGetArrayData(tangents); DXGetArrayInfo(tangents, &numitems, &ttype, NULL, &trank, tshape); if (ttype != TYPE_FLOAT) { DXSetError(ERROR_INVALID_DATA,"tangents component must be type float"); goto error; } if (trank != 1) { DXSetError(ERROR_INVALID_DATA,"tangents component must be rank 1"); goto error; } if (tshape[0] != 2 && tshape[0] != 3) { DXSetError(ERROR_INVALID_DATA,"tangents component must be 2D or 3D"); goto error; } attr1 = DXGetString((String)DXGetComponentAttribute((Field)fieldin, "tangents", "dep")); if (!attr1) { DXSetError(ERROR_MISSING_DATA, "#10242", "tangents"); goto error; } if (strcmp(attr,attr1)) { DXSetError(ERROR_INVALID_DATA, "#10360", "tangents", "data"); goto error; } } else { DXWarning("tangents component is ignored because direction is set in the configuration dialog box"); tangents=NULL; } } binormals = (Array)DXGetComponentValue(fieldin,"binormals"); if (binormals) { if (up_defaulted) { binormals_ptr = (float *)DXGetArrayData(binormals); DXGetArrayInfo(binormals, &numitems, &btype, NULL, &brank, bshape); if (btype != TYPE_FLOAT) { DXSetError(ERROR_INVALID_DATA, "binormals component must be type float"); goto error; } if (brank != 1) { DXSetError(ERROR_INVALID_DATA,"binormals component must be rank 1"); goto error; } if (bshape[0] != 2 && bshape[0] != 3) { DXSetError(ERROR_INVALID_DATA,"binormals component must be 2D or 3D"); goto error; } attr1 = DXGetString((String)DXGetComponentAttribute((Field)fieldin, "binormals", "dep")); if (!attr1) { DXSetError(ERROR_MISSING_DATA, "#10241", "binormals"); goto error; } if (strcmp(attr,attr1)) { DXSetError(ERROR_INVALID_DATA, "#10360", "binormals", "data"); goto error; } } else { DXWarning("binormals component ignored because up is set in configuration dialog box"); binormals=NULL; } } /* we only care about normals if tangents and binormals aren't both already specified */ normals = (Array)DXGetComponentValue(fieldin,"normals"); if (normals) { if ( (!binormals || up_defaulted ) || (!tangents || direction_defaulted)) { normals_ptr = (float *)DXGetArrayData(normals); DXGetArrayInfo(normals, &numitems, &ntype, NULL, &nrank, nshape); if (ntype != TYPE_FLOAT) { DXSetError(ERROR_INVALID_DATA, "normals component must be type float"); goto error; } if (nrank != 1) { DXSetError(ERROR_INVALID_DATA,"normals component must be rank 1"); goto error; } if (nshape[0] != 2 && nshape[0] != 3) { DXSetError(ERROR_INVALID_DATA,"normals component must be 2D or 3D"); goto error; } attr1 = DXGetString((String)DXGetComponentAttribute((Field)fieldin, "normals", "dep")); if (!attr1) { DXSetError(ERROR_MISSING_DATA, "#10241", "normals"); goto error; } if (strcmp(attr,attr1)) { DXSetError(ERROR_INVALID_DATA, "#10360", "normals", "data"); goto error; } } else { DXWarning("normals component is ignored because text direction is already sufficiently specified through direction (or tangents) and up (or binormals)"); normals=NULL; } } pos_ptr = (float *)DXGetArrayData(positions); /* the ones coming in from above */ /* these should not be colinear, so I don't need to worry here */ direction = DXNormalize(direction); up = DXNormalize(up); z = DXNormalize(DXCross(direction, up)); for (i=0; i