/***********************************************************************/ /* 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" */ /***********************************************************************/ /* * $Header: /home/gda/dxcvs/dx/src/exec/dxmods/arrange.c,v 1.3 1999/05/10 15:45:22 gda Exp $ */ #include /* The positioning Algorithm has been enhanced. * * The arrangement can be compact or not in either x or y. * If compact.x != 0 then the width of each column of images will be * equal to the maximum width of all images IN THAT COLUMN. Similarly * for compact.y != 0. If compact.x = 0, the width in each column will * be the maximum width of all images. * * Position specifies the location of the center of each image in its new * frame. Thus [0.5 0.5] will center each, and [0 0] will put them in * the lower left. The new location is adjusted toward the center if * there is any overhang in each frame. * * Size overrides the arrangement specification and forces the width * or height (if either x or y is !0) to be that specified. * * If the array of images does not span to the edge of the frame, * and either size is not zero or comact is zero, dummy 1 pixel corner * images will be added to provide the effect of padding around * the edge of the image array. * * Handling of Composite Fields adds a certain amount of complexity: * Essentially, a new position is given to Fields and Composite Fields * only. Members of a composite field all have their origins adjusted * with respect to the sum of all members of that and are not made to * be rearranged amongst themselves. */ #include #include #include <_helper_jea.h> #define ARRANGE_INF 2147483647 static Object _arrange ( CompositeField parent, Object inp, int nrows, int ncols, int *count, int *binx, int *biny, Vector c, Vector p, Vector s, int transposed ); static Error _get_bins(Object I_group, int num_images, int nrows, int ncols, Vector c, Vector p, Vector s, int *binx, int *biny); static Error _get_all_image_bounds(Object o, int n, int *count, int ncols, int *binx, int *biny); static Error _get_new_origin(Object inp, int *origin, int count, int ncols, int *binx, int *biny, Vector p); static Error getvec(Object o, Vector *v) { int rc = DXExtractParameter(o, TYPE_FLOAT, 3, 1, (Pointer)v) || DXExtractParameter(o, TYPE_FLOAT, 2, 1, (Pointer)v); v->z = 0; return rc; } m_Arrange ( Object *in, Object *out ) { #define I_group in[0] #define I_horizontal in[1] #define I_compact in[2] #define I_position in[3] #define I_size in[4] #define O_image out[0] int limit; int count; int offset; int min_x; int min_y; int max_x; int max_y; int num_images; int transposed; Vector p,c,s; int nrows,ncols; int *binx, *biny; O_image = NULL; binx = NULL; biny = NULL; if ( !I_group ) DXErrorGoto2 ( ERROR_MISSING_DATA, "#10000", "'group' parameter" ) else if ( ( DXGetObjectClass ( I_group ) != CLASS_FIELD ) && ( DXGetObjectClass ( I_group ) != CLASS_GROUP ) ) DXErrorGoto2 ( ERROR_BAD_PARAMETER, "#10190", /* %s must be a field or a group */ "\'group\' parameter" ) if ( I_horizontal ) { if ( !DXExtractInteger ( I_horizontal, &limit ) || ( limit < 1 ) || ( limit > ARRANGE_INF ) ) DXErrorGoto2 ( ERROR_BAD_PARAMETER, "#10020", "'horizontal'" ); } else limit = ARRANGE_INF; num_images = 0; if ( !_dxf_CountImages ( I_group, &num_images ) ) goto error; if ( num_images == 0 ) { if ( ERROR == ( O_image = (Object)DXNewCompositeField() ) ) goto error; return OK; } #if 0 else if ( ( num_images == 1 ) && ( ( DXGetObjectClass ( I_group ) == CLASS_FIELD ) || ( ( DXGetObjectClass ( I_group ) == CLASS_GROUP ) && ( DXGetGroupClass ( (Group)I_group ) == CLASS_COMPOSITEFIELD ) ) ) ) { O_image = I_group; return OK; } #endif if (limit>num_images) limit = ARRANGE_INF; c = DXPt(0,0,0); if (I_compact && !getvec(I_compact,&c)) { DXSetError(ERROR_BAD_PARAMETER, "10221"); return ERROR; } p = DXPt(0.5,0.5,0); if (I_position && !getvec(I_position,&p)) { DXSetError(ERROR_BAD_PARAMETER, "10221"); return ERROR; } s = DXPt(0,0,0); if (I_size && !getvec(I_size,&s)) { DXSetError(ERROR_BAD_PARAMETER, "10221"); return ERROR; } if ( !DXGetImageBounds ( I_group, &min_x, &min_y, &max_x, &max_y ) || !_dxf_CheckImageDeltas ( I_group, &transposed ) ) goto error; DXDebug ( "A", "Arrange FYI: Image In =([%d,%d], w,h=[%d,%d]), count (%d)", min_x, min_y, max_x, max_y, num_images ); if ( transposed == 1 ) DXErrorGoto ( ERROR_NOT_IMPLEMENTED, "#11712" ) /* transposed images not supported,... deltas are {[0,1],[1,0]} */ offset = ( (unsigned int) num_images + (unsigned int)(limit-1) ) / (unsigned int)limit; nrows = offset; ncols = limit; if (ncols>num_images) ncols=num_images; if (s.x && s.x < max_x) { s.x = max_x; DXWarning("#11713", "x", max_x); } if (s.y && s.y < max_y) { s.y = max_y; DXWarning("#11713", "y", max_y); } binx = DXAllocateLocalZero((ncols+1)*sizeof(int)); biny = DXAllocateLocalZero((nrows+1)*sizeof(int)); if (ERROR == _get_bins(I_group, num_images, nrows, ncols, c, p, s, binx, biny)) { DXSetError(ERROR_NO_MEMORY, "8360"); return ERROR; } count = 0; num_images = 0; if ( ( ERROR == ( O_image = _arrange ( NULL, I_group, nrows, ncols, &count, binx, biny, c, p, s, transposed ) ) ) || ( ERROR == ( O_image = _dxf_FlattenHierarchy ( O_image ) ) ) || !DXGetImageBounds ( O_image, &min_x, &min_y, &max_x, &max_y ) || !_dxf_CountImages ( O_image, &num_images ) ) goto error; /* Now we add dummy corner images to force padding around the border, */ /* if the images don't span the region and they're not to be compact. */ if ((!c.x || !c.y || s.x || s.y) && (min_x || min_y)) { Field LL = DXMakeImage(1,1); if (!LL) goto error; if ( !_dxf_SetImageOrigin((Field)LL, 0, 0) || !DXSetMember((Group)O_image, NULL, (Object)LL) ) goto error; } if ((!c.x || !c.y || s.x || s.y) && ((max_y != biny[0]) || (max_x != binx[ncols]))) { Field UR = DXMakeImage(1,1); if (!UR) goto error; if ( !_dxf_SetImageOrigin((Field)UR, binx[ncols], biny[0]) || !DXSetMember((Group)O_image, NULL, (Object)UR) ) goto error; } DXDebug ( "A", "Arrange FYI: Image Out =([%d,%d], w,h=[%d,%d]), count (%d)", min_x, min_y, max_x, max_y, count ); DXFree(binx); DXFree(biny); return OK; error: DXDelete ( O_image ); O_image = NULL; DXFree(binx); DXFree(biny); DXASSERT ( DXGetError() != ERROR_NONE ); return ERROR; } static Object _arrange ( CompositeField parent, Object inp, int nrows, int ncols, int *count, int *binx, int *biny, Vector c, Vector p, Vector s, int transposed ) { CompositeField new_parent = NULL; Class class; Object out = NULL; Object inp_member; int origin[2]; int isizex, isizey, bsizex, bsizey; int xoffset, yoffset; int min_x, min_y; int row, col; int i; DXASSERTGOTO ( inp != ERROR ); switch ( class = DXGetObjectClass ( inp ) ) { case CLASS_GROUP: switch ( class = DXGetGroupClass ( (Group)inp ) ) { case CLASS_GROUP: case CLASS_SERIES: if ( !parent ) if ( ERROR == ( new_parent = DXNewCompositeField() ) ) goto error; else parent = new_parent; out = (Object)parent; for ( i=0; inp_member = DXGetEnumeratedMember ( (Group)inp, i, NULL ); i++ ) if ( !_arrange ( parent, inp_member, nrows, ncols, count, binx, biny, c, p, s, transposed ) ) goto error; break; case CLASS_COMPOSITEFIELD: _get_new_origin(inp, origin, *count, ncols, binx, biny, p); (*count)++; if ( ( ERROR == ( out = DXCopy ( inp, COPY_STRUCTURE ) ) ) || !_dxf_SetCompositeImageOrigin ( (CompositeField)out, origin[0], origin[1] ) ) goto error; if ( NULL != DXExists((Field)out, "data")) if (!DXRemove((Field)out, "data")) goto error; if ( !DXUnsetGroupType((Group)out)) goto error; if ( parent ) if ( !DXSetMember ( (Group)parent, NULL, out ) ) goto error; break; default: DXErrorGoto2 ( ERROR_BAD_CLASS, "#10190", "'image(s)'" ); } break; case CLASS_FIELD: if ( ERROR == ( out = DXCopy ( inp, COPY_STRUCTURE ) ) ) goto error; _get_new_origin(inp, origin, *count, ncols, binx, biny, p); (*count)++; /* * This test and set is to prevent CompositeField group complaints * to the tune of: * "Bad parameter: Group member has bad type" * from DXSetMember within CLASS_COMPOSITEFIELDs * when the data types do not match between images. */ if ( NULL != DXGetComponentValue ( (Field)out, "data" ) ) if ( !DXSetComponentValue ( (Field)out, "data", NULL ) ) goto error; if ( !_dxf_SetImageOrigin ( (Field)out, origin[0], origin[1] ) ) goto error; if ( parent ) if ( !DXSetMember ( (Group)parent, NULL, out ) ) goto error; break; default: DXErrorGoto2 ( ERROR_BAD_CLASS, "#10190", "'image(s)'" ); } return out; error: if ( out != (Object) parent ) DXDelete ( out ); DXDelete ( (Object) new_parent ); new_parent = NULL; out = NULL; DXASSERT ( DXGetError() != ERROR_NONE ); return ERROR; } static Error _get_bins(Object o, int num_images, int nrows, int ncols, Vector c, Vector p, Vector s, int *binx, int *biny) { int n,i,j; int count; int max_w, max_h; int new_w, new_h; count = 0; _get_all_image_bounds(o, num_images, &count, ncols, binx, biny); max_w = 0; max_h = 0; for (i=0;i0) new_w = s.x; if (s.y>0) new_h = s.y; binx[0]=0; for (i=0;ibsizex) xoffset=bsizex-isizex; yoffset = bsizey*p.y-(isizey/2); if (yoffset<0) yoffset=0; if (yoffset+isizey>bsizey) yoffset=bsizey-isizey; origin[0] = binx[col]+xoffset; origin[1] = biny[row]+yoffset; return OK; }