/* Create a one dimensional box */ Datum cube_f8_f8(PG_FUNCTION_ARGS) { double x0 = PG_GETARG_FLOAT8(0); double x1 = PG_GETARG_FLOAT8(1); NDBOX *result; int size; if (x0 == x1) { size = POINT_SIZE(1); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, 1); SET_POINT_BIT(result); result->x[0] = x0; } else { size = CUBE_SIZE(1); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, 1); result->x[0] = x0; result->x[1] = x1; } PG_RETURN_NDBOX(result); }
Datum cube_subset(PG_FUNCTION_ARGS) { NDBOX *c = PG_GETARG_NDBOX(0); ArrayType *idx = PG_GETARG_ARRAYTYPE_P(1); NDBOX *result; int size, dim, i; int *dx; if (array_contains_nulls(idx)) ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("cannot work with arrays containing NULLs"))); dx = (int32 *) ARR_DATA_PTR(idx); dim = ARRNELEMS(idx); if (dim > CUBE_MAX_DIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("array is too long"), errdetail("A cube cannot have more than %d dimensions.", CUBE_MAX_DIM))); size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, dim); if (IS_POINT(c)) SET_POINT_BIT(result); for (i = 0; i < dim; i++) { if ((dx[i] <= 0) || (dx[i] > DIM(c))) { pfree(result); ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("Index out of bounds"))); } result->x[i] = c->x[dx[i] - 1]; if (!IS_POINT(c)) result->x[i + dim] = c->x[dx[i] + DIM(c) - 1]; } PG_FREE_IF_COPY(c, 0); PG_RETURN_NDBOX(result); }
/* Create a one dimensional box with identical upper and lower coordinates */ Datum cube_f8(PG_FUNCTION_ARGS) { double x = PG_GETARG_FLOAT8(0); NDBOX *result; int size; size = POINT_SIZE(1); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, 1); SET_POINT_BIT(result); result->x[0] = x; PG_RETURN_NDBOX(result); }
/* Add a dimension to an existing cube */ Datum cube_c_f8_f8(PG_FUNCTION_ARGS) { NDBOX *cube = PG_GETARG_NDBOX(0); double x1 = PG_GETARG_FLOAT8(1); double x2 = PG_GETARG_FLOAT8(2); NDBOX *result; int size; int i; if (DIM(cube) + 1 > CUBE_MAX_DIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("can't extend cube"), errdetail("A cube cannot have more than %d dimensions.", CUBE_MAX_DIM))); if (IS_POINT(cube) && (x1 == x2)) { size = POINT_SIZE((DIM(cube) + 1)); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, DIM(cube) + 1); SET_POINT_BIT(result); for (i = 0; i < DIM(cube); i++) result->x[i] = cube->x[i]; result->x[DIM(result) - 1] = x1; } else { size = CUBE_SIZE((DIM(cube) + 1)); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, DIM(cube) + 1); for (i = 0; i < DIM(cube); i++) { result->x[i] = LL_COORD(cube, i); result->x[DIM(result) + i] = UR_COORD(cube, i); } result->x[DIM(result) - 1] = x1; result->x[2 * DIM(result) - 1] = x2; } PG_FREE_IF_COPY(cube, 0); PG_RETURN_NDBOX(result); }
/* Assign_Slit() *========================================================================== * Assigns the 6 slits visible an FNODE, where possible. * IN: FNODE *ptr: Start assigning with this node * FNODE *array[]: A 5 slit pointer array. */ void Assign_Slit( FON_PTR ptr, FON_PTR array[] ) { int i; FON_PTR curptr; curptr = ptr; for( i = 0; i < MAX_SLITS; i++ ) { array[ i ] = NULL; Deselect( First_Obj + i ); #if 0 if( First_Obj == LINE0 ) #endif TedText( First_Obj + i ) = fblank; #if 0 if( First_Obj == OPLINE0 ) TedText( First_Obj + i ) = fblank2; #endif #if 0 if( ( ( IsActiveTree( Maintree ) ) && curptr ) || ( ( IsActiveTree( Oxsizes ) ) && curptr && ( POINT_SIZE( curptr) != 0L ) ) ) #endif if( curptr ) { if( curptr ) { array[i] = curptr; TedText( First_Obj + i ) = FNAME( curptr ); if( AFLAG( curptr ) ) Select( First_Obj + i ); curptr = FNEXT( curptr ); } } } }
/* ** Allows the construction of a zero-volume cube from a float[] */ Datum cube_a_f8(PG_FUNCTION_ARGS) { ArrayType *ur = PG_GETARG_ARRAYTYPE_P(0); NDBOX *result; int i; int dim; int size; double *dur; if (array_contains_nulls(ur)) ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("cannot work with arrays containing NULLs"))); dim = ARRNELEMS(ur); if (dim > CUBE_MAX_DIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("array is too long"), errdetail("A cube cannot have more than %d dimensions.", CUBE_MAX_DIM))); dur = ARRPTR(ur); size = POINT_SIZE(dim); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, dim); SET_POINT_BIT(result); for (i = 0; i < dim; i++) result->x[i] = dur[i]; PG_RETURN_NDBOX(result); }
void lmt_compute_y(WYSIWYG *wn, int i) { int32 v, dr; v = lmt_off_to_abs(wn, Y_REF, Y_OFFSET(i)); /* vertical offset */ dr = lmt_rel_to_abs(wn, 6, 6, &FRAME_DATA(i) rel_data); /* i6 depth relationship */ switch(LOCKPOINT(i)) /* the lock point */ { case TL: /* 'y' = top */ case TR: case TC: v += lmt_rel_to_abs(wn, 0, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ v += lmt_lock_lead(wn, i, v); ELE_DATA(i) rot_rect_top = v; /* top */ if (dr) /* bottom */ ELE_DATA(i) rot_rect_bottom = dr + LAYOUT(wn) dpo; else ELE_DATA(i) rot_rect_bottom = v + LAYOUT(wn) dpo; ELE_DATA(i) rot_rect_y_center = /* y-center */ (ELE_DATA(i) rot_rect_bottom + ELE_DATA(i) rot_rect_top) / 2 ; break; case HL: /* 'y' = Height */ case HR: case HC: v += lmt_rel_to_abs(wn, 0, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ if (TYPE_OF_FRAME(i) == PL_TEXT || TYPE_OF_FRAME(i) == PL_MISC || TYPE_OF_FRAME(i) == PL_FLOW) v -= (int32)(((float)lmt_off_to_abs(wn, Y_REF, LEADING(i)) / (float)wn -> ldb - (float)CAP_HT(i) * (float)lmt_off_to_abs(wn, X_REF, POINT_SIZE(i)) / (float)(wn -> msb * 100L)) * (float)wn -> ldb); v += lmt_lock_lead(wn, i, v); ELE_DATA(i) rot_rect_top = v; /* top */ if (dr) /* bottom */ ELE_DATA(i) rot_rect_bottom = dr + LAYOUT(wn) dpo; else ELE_DATA(i) rot_rect_bottom = ELE_DATA(i) rot_rect_top + LAYOUT(wn) dpo; ELE_DATA(i) rot_rect_y_center = /* y-center */ (ELE_DATA(i) rot_rect_bottom + ELE_DATA(i) rot_rect_top) / 2 ; break; case BL: /* 'y' = bottom */ case BR: case BC: v += lmt_rel_to_abs(wn, 1, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ ELE_DATA(i) rot_rect_bottom = v; /* bottom */ if (dr) /* top */ ELE_DATA(i) rot_rect_top = dr + LAYOUT(wn) dpo + lmt_lock_lead(wn, i, dr + LAYOUT(wn) dpo); else { v += lmt_lock_lead(wn, i, v - LAYOUT(wn) dpo); ELE_DATA(i) rot_rect_top = v - LAYOUT(wn) dpo; ELE_DATA(i) rot_rect_bottom = v; /* bottom */ } ELE_DATA(i) rot_rect_y_center = /* y-center */ (v + ELE_DATA(i) rot_rect_top) / 2 ; break; case CL: /* 'y' = center */ case CR: case CC: { int32 a; v += lmt_rel_to_abs(wn, 2, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ ELE_DATA(i) rot_rect_y_center = v; /* y-center */ if (dr) { LAYOUT(wn) dpo += dr; LAYOUT(wn) dpo -= v; (LAYOUT(wn) dpo < 0) ? (LAYOUT(wn) dpo *= -2) : (LAYOUT(wn) dpo *= 2); } a = lmt_lock_lead(wn, i, v - (LAYOUT(wn) dpo / 2)); v += a; ELE_DATA(i) rot_rect_top = (v - (LAYOUT(wn) dpo / 2)); /* top */ if (dr) v -= a; ELE_DATA(i) rot_rect_bottom = (v + (LAYOUT(wn) dpo / 2)); /* bot */ } break; } }
void lmt_compute_param_y(WYSIWYG *wn, int i, int32 *anchor_y, int32 *depth) { int32 v, dr, top = 0, bottom = 0, y_center; LAYOUT(wn) dpo = lmt_off_to_abs(wn, Y_REF, DEPTH_OFFSET(i)); /* dep offst*/ v = lmt_off_to_abs(wn, Y_REF, Y_OFFSET(i)); /* vertical offset */ dr = lmt_rel_to_abs(wn, 6, 6, &FRAME_DATA(i) rel_data); /* i6 depth relationship */ switch(LOCKPOINT(i)) /* the lock point */ { case TL: /* 'y' = top */ case TR: case TC: v += lmt_rel_to_abs(wn, 0, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ v += lmt_lock_lead(wn, i, v); top = v; /* top */ if (dr) /* bottom */ bottom = dr + LAYOUT(wn) dpo; else bottom = v + LAYOUT(wn) dpo; *anchor_y = top; break; case HL: /* 'y' = Height */ case HR: case HC: v += lmt_rel_to_abs(wn, 0, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ if (TYPE_OF_FRAME(i) == PL_TEXT || TYPE_OF_FRAME(i) == PL_MISC || TYPE_OF_FRAME(i) == PL_FLOW) v -= (int32)(((float)lmt_off_to_abs(wn, Y_REF, LEADING(i)) / (float)wn -> ldb - (float)CAP_HT(i) * (float)lmt_off_to_abs(wn, X_REF, POINT_SIZE(i)) / (float)(wn -> msb * 100L)) * (float)wn -> ldb); v += lmt_lock_lead(wn, i, v); top = v; /* top */ if (dr) bottom = dr + LAYOUT(wn) dpo; else bottom = top + LAYOUT(wn) dpo; *anchor_y = top; break; case BL: /* 'y' = bottom */ case BR: case BC: v += lmt_rel_to_abs(wn, 1, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ bottom = v; if (dr) top = dr + LAYOUT(wn) dpo + lmt_lock_lead(wn,i,dr+ LAYOUT(wn) dpo); else { v += lmt_lock_lead(wn, i, v - LAYOUT(wn) dpo); top = v - LAYOUT(wn) dpo; bottom = v; } *anchor_y = bottom; break; case CL: /* 'y' = center */ case CR: case CC: { int32 a; v += lmt_rel_to_abs(wn, 2, 2, &FRAME_DATA(i) rel_data); /* offset + relationship */ y_center = v; /* y-center */ if (dr) { LAYOUT(wn) dpo += dr; LAYOUT(wn) dpo -= v; (LAYOUT(wn) dpo < 0) ? (LAYOUT(wn) dpo *= -2) : (LAYOUT(wn) dpo *= 2); } a = lmt_lock_lead(wn, i, v - (LAYOUT(wn) dpo / 2)); v += a; top = (v - (LAYOUT(wn) dpo / 2)); /* top */ if (dr) v -= a; bottom = (v + (LAYOUT(wn) dpo / 2)); /* bottom */ *anchor_y = y_center; } break; } *depth = bottom - top; }
/* cube_inter */ Datum cube_inter(PG_FUNCTION_ARGS) { NDBOX *a = PG_GETARG_NDBOX(0); NDBOX *b = PG_GETARG_NDBOX(1); NDBOX *result; bool swapped = false; int i; int dim; int size; /* swap the arguments if needed, so that 'a' is always larger than 'b' */ if (DIM(a) < DIM(b)) { NDBOX *tmp = b; b = a; a = tmp; swapped = true; } dim = DIM(a); size = CUBE_SIZE(dim); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, dim); /* First compute intersection of the dimensions present in both args */ for (i = 0; i < DIM(b); i++) { result->x[i] = Max( Min(LL_COORD(a, i), UR_COORD(a, i)), Min(LL_COORD(b, i), UR_COORD(b, i)) ); result->x[i + DIM(a)] = Min( Max(LL_COORD(a, i), UR_COORD(a, i)), Max(LL_COORD(b, i), UR_COORD(b, i)) ); } /* continue on the higher dimensions only present in 'a' */ for (; i < DIM(a); i++) { result->x[i] = Max(0, Min(LL_COORD(a, i), UR_COORD(a, i)) ); result->x[i + DIM(a)] = Min(0, Max(LL_COORD(a, i), UR_COORD(a, i)) ); } /* * Check if the result was in fact a point, and set the flag in the datum * accordingly. (we don't bother to repalloc it smaller) */ if (cube_is_point_internal(result)) { size = POINT_SIZE(dim); result = repalloc(result, size); SET_VARSIZE(result, size); SET_POINT_BIT(result); } if (swapped) { PG_FREE_IF_COPY(b, 0); PG_FREE_IF_COPY(a, 1); } else { PG_FREE_IF_COPY(a, 0); PG_FREE_IF_COPY(b, 1); } /* * Is it OK to return a non-null intersection for non-overlapping boxes? */ PG_RETURN_NDBOX(result); }
/* cube_union_v0 */ NDBOX * cube_union_v0(NDBOX *a, NDBOX *b) { int i; NDBOX *result; int dim; int size; /* trivial case */ if (a == b) return a; /* swap the arguments if needed, so that 'a' is always larger than 'b' */ if (DIM(a) < DIM(b)) { NDBOX *tmp = b; b = a; a = tmp; } dim = DIM(a); size = CUBE_SIZE(dim); result = palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, dim); /* First compute the union of the dimensions present in both args */ for (i = 0; i < DIM(b); i++) { result->x[i] = Min( Min(LL_COORD(a, i), UR_COORD(a, i)), Min(LL_COORD(b, i), UR_COORD(b, i)) ); result->x[i + DIM(a)] = Max( Max(LL_COORD(a, i), UR_COORD(a, i)), Max(LL_COORD(b, i), UR_COORD(b, i)) ); } /* continue on the higher dimensions only present in 'a' */ for (; i < DIM(a); i++) { result->x[i] = Min(0, Min(LL_COORD(a, i), UR_COORD(a, i)) ); result->x[i + dim] = Max(0, Max(LL_COORD(a, i), UR_COORD(a, i)) ); } /* * Check if the result was in fact a point, and set the flag in the datum * accordingly. (we don't bother to repalloc it smaller) */ if (cube_is_point_internal(result)) { size = POINT_SIZE(dim); SET_VARSIZE(result, size); SET_POINT_BIT(result); } return (result); }
/* Increase or decrease box size by a radius in at least n dimensions. */ Datum cube_enlarge(PG_FUNCTION_ARGS) { NDBOX *a = PG_GETARG_NDBOX(0); double r = PG_GETARG_FLOAT8(1); int32 n = PG_GETARG_INT32(2); NDBOX *result; int dim = 0; int size; int i, j; if (n > CUBE_MAX_DIM) n = CUBE_MAX_DIM; if (r > 0 && n > 0) dim = n; if (DIM(a) > dim) dim = DIM(a); size = CUBE_SIZE(dim); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, dim); for (i = 0, j = dim; i < DIM(a); i++, j++) { if (LL_COORD(a, i) >= UR_COORD(a, i)) { result->x[i] = UR_COORD(a, i) - r; result->x[j] = LL_COORD(a, i) + r; } else { result->x[i] = LL_COORD(a, i) - r; result->x[j] = UR_COORD(a, i) + r; } if (result->x[i] > result->x[j]) { result->x[i] = (result->x[i] + result->x[j]) / 2; result->x[j] = result->x[i]; } } /* dim > a->dim only if r > 0 */ for (; i < dim; i++, j++) { result->x[i] = -r; result->x[j] = r; } /* * Check if the result was in fact a point, and set the flag in the datum * accordingly. (we don't bother to repalloc it smaller) */ if (cube_is_point_internal(result)) { size = POINT_SIZE(dim); SET_VARSIZE(result, size); SET_POINT_BIT(result); } PG_FREE_IF_COPY(a, 0); PG_RETURN_NDBOX(result); }
/* ** Allows the construction of a cube from 2 float[]'s */ Datum cube_a_f8_f8(PG_FUNCTION_ARGS) { ArrayType *ur = PG_GETARG_ARRAYTYPE_P(0); ArrayType *ll = PG_GETARG_ARRAYTYPE_P(1); NDBOX *result; int i; int dim; int size; bool point; double *dur, *dll; if (array_contains_nulls(ur) || array_contains_nulls(ll)) ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("cannot work with arrays containing NULLs"))); dim = ARRNELEMS(ur); if (dim > CUBE_MAX_DIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("can't extend cube"), errdetail("A cube cannot have more than %d dimensions.", CUBE_MAX_DIM))); if (ARRNELEMS(ll) != dim) ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("UR and LL arrays must be of same length"))); dur = ARRPTR(ur); dll = ARRPTR(ll); /* Check if it's a point */ point = true; for (i = 0; i < dim; i++) { if (dur[i] != dll[i]) { point = false; break; } } size = point ? POINT_SIZE(dim) : CUBE_SIZE(dim); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, dim); for (i = 0; i < dim; i++) result->x[i] = dur[i]; if (!point) { for (i = 0; i < dim; i++) result->x[i + dim] = dll[i]; } else SET_POINT_BIT(result); PG_RETURN_NDBOX(result); }