file: brush_oper.c

/* * brush_oper.c - Brush operations * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without fee * is granted provided that the above copyright notice appears in all copies. * It is provided "as is" without express or implied warranty. */ #include "XmdvTool.h" #include <X11/Xaw/SmeBSB.h> #include "brush_oper.h" #include "util.h" #include "color_req.h" extern Widget appShell; extern GC gc; extern int dims; extern int curr_dim; extern double dim_min[MAXDIM], dim_max[MAXDIM]; /* the brushes */ extern Brush brushes[MAXBRUSH]; /* the color cells */ extern unsigned long color_cells[NUM_COLOR_CELLS]; Operation operations[MAXOPER]; /* the operations */ int num_oper; /* number of operations */ int list_edit; /* the list to edit */ char *oper_names[MAXOPER] = {NULL}; /* the operation names */ /* * BrushOperListInitCB() - Initialize the brush operations list * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperListInitCB(Widget w, XtPointer params, XtPointer call_data) { /* initialize one highlight operation for the first brush */ operations[0].order = 1; operations[0].not[0] = 0; operations[0].brush[0] = num_oper; operations[0].oper = OPER_HIGHLIGHT; operations[0].has_color = TRUE; operations[0].menu_item = NULL; if(BrushOperAllocColors(&operations[0])) { fprintf(stderr, "Out of colors, cannot create new operation\n"); XBell(XtDisplay(w), 0); return; } BrushOperInterpolateColors(&operations[0]); num_oper = 1; } /* * BrushOperNewCB() - Callback when the brush operation new button is * clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperNewCB(Widget w, XtPointer params, XtPointer call_data) { /* make list_edit one more than the last operation */ /* if the operation is successfully made, num_oper will be updated */ list_edit = num_oper; ClearOperPopup(); } /* * BrushOperDeleteCB() - Callback when the brush operation delete button is * clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperDeleteCB(Widget w, XtPointer params, XtPointer call_data) { Widget scroll_list_w, list_w; /* list widgets */ XawListReturnStruct *list_ret; /* list return structure */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ int i; /* get the index of the currently selected operation and delete it */ /* find the scrollable list widget */ if(!(scroll_list_w = WcFullNameToWidget(w, "*btb_oper_list"))) { fprintf(stderr, "Error finding *btb_oper_list\n"); return; } /* extract the list widget from the scrollable list widget */ n = 0; XtSetArg(wargs[n], XtNlistWidget, &list_w); n++; XtGetValues(scroll_list_w,wargs,n); if(!list_w) { fprintf(stderr, "Error getting list from scrollable list in "); fprintf(stderr, "BrushOperDeleteCB()\n"); return; } if(!(list_ret = XawListShowCurrent(list_w))) { fprintf(stderr, "Error getting current list selection in BrushOperDeleteCB()\n"); return; } /* if nothing is selected, beep an error and return */ if(list_ret->list_index == XAW_LIST_NONE) { XBell(XtDisplay(w), 0); return; } /* free colors associated with this operation */ if(operations[list_ret->list_index].has_color) { BrushOperFreeColors(&operations[list_ret->list_index]); XtDestroyWidget(operations[list_ret->list_index].menu_item); } /* do the deletion */ for(i=list_ret->list_index+1; i<num_oper; i++) operations[i-1] = operations[i]; num_oper--; /* update the list */ BrushOperUpdateList(); } /* * BrushOperLowCB() - Callback when the brush operation low * priority button is clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperLowCB(Widget w, XtPointer params, XtPointer call_data) { Widget scroll_list_w, list_w; /* list widgets */ XawListReturnStruct *list_ret; /* list return structure */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ int i; Operation temp_oper; /* temporary operation holder */ /* get the index of the currently selected operation and change */ /* it's priority */ /* find the scrollable list widget */ if(!(scroll_list_w = WcFullNameToWidget(w, "*btb_oper_list"))) { fprintf(stderr, "Error finding *btb_oper_list\n"); return; } /* extract the list widget from the scrollable list widget */ n = 0; XtSetArg(wargs[n], XtNlistWidget, &list_w); n++; XtGetValues(scroll_list_w,wargs,n); if(!list_w) { fprintf(stderr, "Error getting list from scrollable list in "); fprintf(stderr, "BrushOperLowCB()\n"); return; } if(!(list_ret = XawListShowCurrent(list_w))) { fprintf(stderr, "Error getting current list selection in BrushOperLowCB()\n"); return; } /* if nothing is selected, beep an error and return */ if(list_ret->list_index == XAW_LIST_NONE) { XBell(XtDisplay(w), 0); return; } /* change the priority */ temp_oper = operations[list_ret->list_index]; for(i=list_ret->list_index+1; i<num_oper; i++) operations[i-1] = operations[i]; operations[num_oper-1] = temp_oper; /* update the list */ BrushOperUpdateList(); } /* * BrushOperHighCB() - Callback when the brush operation high * priority button is clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperHighCB(Widget w, XtPointer params, XtPointer call_data) { Widget scroll_list_w, list_w; /* list widgets */ XawListReturnStruct *list_ret; /* list return structure */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ int i; Operation temp_oper; /* temporary operation holder */ /* get the index of the currently selected operation and change */ /* it's priority */ /* find the scrollable list widget */ if(!(scroll_list_w = WcFullNameToWidget(w, "*btb_oper_list"))) { fprintf(stderr, "Error finding *btb_oper_list\n"); return; } /* extract the list widget from the scrollable list widget */ n = 0; XtSetArg(wargs[n], XtNlistWidget, &list_w); n++; XtGetValues(scroll_list_w,wargs,n); if(!list_w) { fprintf(stderr, "Error getting list from scrollable list in "); fprintf(stderr, "BrushOperHighCB()\n"); return; } if(!(list_ret = XawListShowCurrent(list_w))) { fprintf(stderr, "Error getting current list selection in BrushOperHighCB()\n"); return; } /* if nothing is selected, beep an error and return */ if(list_ret->list_index == XAW_LIST_NONE) { XBell(XtDisplay(w), 0); return; } /* change the priority */ temp_oper = operations[list_ret->list_index]; for(i=list_ret->list_index; i>0; i--) operations[i] = operations[i-1]; operations[0] = temp_oper; /* update the list */ BrushOperUpdateList(); } /* * BrushOperEditCB() - Callback when the brush operation edit button is * clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperEditCB(Widget w, XtPointer params, XtPointer call_data) { Widget scroll_list_w, list_w; /* list widgets */ XawListReturnStruct *list_ret; /* list return structure */ Widget popup_w; /* the popup widget */ int n; Arg wargs[10]; /* for XGetValues() / XSetValues() */ /* get the index of the currently selected operation and */ /* load the operation popup with it */ /* find the scrollable list widget */ if(!(scroll_list_w = WcFullNameToWidget(w, "*btb_oper_list"))) { fprintf(stderr, "Error finding *btb_oper_list\n"); return; } /* extract the list widget from the scrollable list widget */ n = 0; XtSetArg(wargs[n], XtNlistWidget, &list_w); n++; XtGetValues(scroll_list_w,wargs,n); if(!list_w) { fprintf(stderr, "Error getting list from scrollable list in "); fprintf(stderr, "BrushOperEditCB()\n"); return; } if(!(list_ret = XawListShowCurrent(list_w))) { fprintf(stderr, "Error getting current list selection in BrushOperEditCB()\n"); return; } /* if nothing is selected, beep an error and return */ if(list_ret->list_index == XAW_LIST_NONE) { XBell(XtDisplay(w), 0); return; } /* update list_edit to the operation we are editing */ list_edit = list_ret->list_index; /* sanity check */ if(list_edit < 0 || list_edit >= num_oper) { fprintf(stderr, "Invalid operation # returned from XawListShowCurrent()\n"); return; } /* load the operation popup with the correct operation values */ InitOperPopup(&operations[list_edit]); /* popup the brush operation popup */ if(!(popup_w = WcFullNameToWidget(w, "*boper_popup"))) { fprintf(stderr, "Error finding *boper_popup\n"); return; } XtPopup(popup_w, XtGrabNone); } /* * BrushOperOkCB() - Callback when the brush operation ok button is * clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperOkCB(Widget w, XtPointer params, XtPointer call_data) { Operation op; int i; /* get the operation from the popup */ if(OperationFromPopup(&op)) { XBell(XtDisplay(w), 0); return; } /* check if this is a new brush */ if(list_edit >= num_oper) { /* allocate a color if need be */ if(op.has_color) { if(BrushOperAllocColors(&op)) { fprintf(stderr, "Out of colors, cannot create new operation\n"); XBell(XtDisplay(w), 0); return; } BrushOperInterpolateColors(&op); /* initialize the menu item to NULL */ op.menu_item = NULL; } /* update the number of operations */ num_oper = list_edit+1; } else { /* check if we need to free a color */ if(operations[list_edit].has_color && !op.has_color) { BrushOperFreeColors(&operations[list_edit]); /* free the menu item */ if(operations[list_edit].menu_item) XtDestroyWidget(operations[list_edit].menu_item); } /* check if we need to allocate a color */ else if(!operations[list_edit].has_color && op.has_color) { if(BrushOperAllocColors(&op)) { fprintf(stderr, "Out of colors, cannot create new operation\n"); XBell(XtDisplay(w), 0); return; } BrushOperInterpolateColors(&op); /* mark the menu item for allocation */ op.menu_item = NULL; } /* check if we need to copy the color */ else if(op.has_color) { for(i=0; i<NUM_BOUND_COL; i++) { op.cells[i] = operations[list_edit].cells[i]; op.colors[i] = operations[list_edit].colors[i]; } op.menu_item = operations[list_edit].menu_item; } } /* copy the operation into the appropriate place in the */ /* operations array */ operations[list_edit] = op; /* update the operations list */ BrushOperUpdateList(); /* reset list_edit */ list_edit = -1; } /* * BrushOperAllocColors() - Allocate colors for an operation * * PARAMETERS * op Pointer to an operation * * RETURNS * 1 Allocation failed * 0 Allocation successful */ int BrushOperAllocColors(Operation *op) { Colormap cmap; /* the colormap */ int i; /* get the colormap */ cmap = DefaultColormap(XtDisplay(appShell), DefaultScreen(XtDisplay(appShell))); /* printf("allocating %d colors: %p\n", NUM_BOUND_COL, op->cells); */ /* allocate color cells */ if(!XAllocColorCells(XtDisplay(appShell), cmap, True, NULL, 0, op->cells, NUM_BOUND_COL)) return 1; for(i=0; i<NUM_BOUND_COL; i++) { op->colors[i].pixel = op->cells[i]; op->colors[i].flags = DoRed|DoGreen|DoBlue; op->colors[i].red = 62000; op->colors[i].green = 0; op->colors[i].blue = 0; XStoreColor(XtDisplay(appShell), cmap, &op->colors[i]); } return 0; } /* * BrushOperInterpolateColors() - Given an operation, interpolates * the colors from color 0. * * PARAMETERS * op A pointer to the operation that has colors to free * * RETURNS * void */ void BrushOperInterpolateColors(Operation *op) { int i; unsigned short maxcol; /* the max color value */ unsigned short color_dist; /* the distance between the max */ /* color value and MAX_XCOL_VALUE */ Colormap cmap; /* the colormap */ /* get the colormap */ cmap = DefaultColormap(XtDisplay(appShell), DefaultScreen(XtDisplay(appShell))); maxcol = MAX(op->colors[0].red, op->colors[0].green); maxcol = MAX(maxcol, op->colors[0].blue); color_dist = MAX_XCOL_VALUE - maxcol; for(i=1; i<NUM_BOUND_COL; i++) { op->colors[i].red = op->colors[0].red + i / (double)(NUM_BOUND_COL - 1) * color_dist; op->colors[i].green = op->colors[0].green + i / (double)(NUM_BOUND_COL - 1) * color_dist; op->colors[i].blue = op->colors[0].blue + i / (double)(NUM_BOUND_COL - 1) * color_dist; XStoreColor(XtDisplay(appShell), cmap, &op->colors[i]); } /* for(i=0; i<NUM_BOUND_COL; i++) printf("%d %d %d\n", op->colors[i].red, op->colors[i].green, op->colors[i].blue); */ } /* * BrushOperFreeColors() - Free colors allocated with BrushOperAllocColors() * * PARAMETERS * op A pointer to the operation that has colors to free * * RETURNS * void */ void BrushOperFreeColors(Operation *op) { Colormap cmap; /* the colormap */ /* get the colormap */ cmap = DefaultColormap(XtDisplay(appShell), DefaultScreen(XtDisplay(appShell))); /* printf("freeing %d colors: %p\n", NUM_BOUND_COL, op->cells); */ /* free the color cells */ XFreeColors(XtDisplay(appShell), cmap, op->cells, NUM_BOUND_COL, 0); } /* * BrushOperCancelCB() - Callback when the brush operation cancel button is * clicked on. * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperCancelCB(Widget w, XtPointer params, XtPointer call_data) { /* reset list_edit */ list_edit = -1; } /* * NameFromOperation() - Generate an ASCII name for an operation from * an Operation structure. * * PARAMETERS * op The operation number to generate a name for * * RETURNS * An ASCII text name for the operation, or NULL on error. */ char *NameFromOperation(int op) { char buf[256], buf2[256]; /* local name buffers */ int i; Operation *oper; /* the operation */ oper = &operations[op]; /* initialize buffer */ sprintf(buf, "%2d: ", op+1); for(i=0; i<oper->order; i++) { /* add a NOT if necessary */ if(oper->not[i]) strcat(buf, "NOT "); /* add the brush name */ sprintf(buf2, "B%d ", oper->brush[i]+1); strcat(buf, buf2); /* add a conjunction if there are more brushes */ if(i < oper->order-1) switch(oper->conj[i]) { case CONJ_AND: strcat(buf, "AND "); break; case CONJ_OR: strcat(buf, "OR "); break; case CONJ_XOR: strcat(buf, "XOR "); break; default: fprintf(stderr, "Bad conjunction in operation in "); fprintf(stderr, "NameFromOperation()\n"); return(NULL); } } /* now add the operation(s) */ if(oper->oper & OPER_HIGHLIGHT) strcat(buf, "highlight "); if(oper->oper & OPER_MASK) strcat(buf, "mask "); if(oper->oper & OPER_VALUES) strcat(buf, "values "); if(oper->oper & OPER_AVERAGE) strcat(buf, "average "); /* copy the name and return it */ return(str_dup(buf)); } /* * BrushOperResetCB() - Callback when the brush operation reset button is * clicked on. This is just a wrapper for * ClearOperPopup(). * * PARAMETERS * w Selected widget * params User data passed to callback * call_data Data about this callback * * RETURNS * void */ void BrushOperResetCB(Widget w, XtPointer params, XtPointer call_data) { ClearOperPopup(); } /* * ClearOperPopup() - This function clears the brush operation popup. * * PARAMETERS * void * * REUTRNS * void */ void ClearOperPopup(void) { Widget w; Arg wargs[1]; if(!(w = WcFullNameToWidget(appShell,"*boper_highlight"))) { fprintf(stderr, "Error finding *boper_highlight\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_mask"))) { fprintf(stderr, "Error finding *boper_mask\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_values"))) { fprintf(stderr, "Error finding *boper_values\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_average"))) { fprintf(stderr, "Error finding *boper_average\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_1"))) { fprintf(stderr, "Error finding *boper_not_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_2"))) { fprintf(stderr, "Error finding *boper_not_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_3"))) { fprintf(stderr, "Error finding *boper_not_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_4"))) { fprintf(stderr, "Error finding *boper_not_4\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_and_1"))) { fprintf(stderr, "Error finding *boper_and_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_and_2"))) { fprintf(stderr, "Error finding *boper_and_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_and_3"))) { fprintf(stderr, "Error finding *boper_and_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_or_1"))) { fprintf(stderr, "Error finding *boper_or_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_or_2"))) { fprintf(stderr, "Error finding *boper_or_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_or_3"))) { fprintf(stderr, "Error finding *boper_or_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_xor_1"))) { fprintf(stderr, "Error finding *boper_xor_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_xor_2"))) { fprintf(stderr, "Error finding *boper_xor_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_xor_3"))) { fprintf(stderr, "Error finding *boper_xor_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_1"))) { fprintf(stderr, "Error finding *boper_brush_1_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_2"))) { fprintf(stderr, "Error finding *boper_brush_1_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_3"))) { fprintf(stderr, "Error finding *boper_brush_1_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_4"))) { fprintf(stderr, "Error finding *boper_brush_1_4\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_1"))) { fprintf(stderr, "Error finding *boper_brush_2_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_2"))) { fprintf(stderr, "Error finding *boper_brush_2_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_3"))) { fprintf(stderr, "Error finding *boper_brush_2_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_4"))) { fprintf(stderr, "Error finding *boper_brush_2_4\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_1"))) { fprintf(stderr, "Error finding *boper_brush_3_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_2"))) { fprintf(stderr, "Error finding *boper_brush_3_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_3"))) { fprintf(stderr, "Error finding *boper_brush_3_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_4"))) { fprintf(stderr, "Error finding *boper_brush_3_4\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_1"))) { fprintf(stderr, "Error finding *boper_brush_4_1\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_2"))) { fprintf(stderr, "Error finding *boper_brush_4_2\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_3"))) { fprintf(stderr, "Error finding *boper_brush_4_3\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_4"))) { fprintf(stderr, "Error finding *boper_brush_4_4\n"); return; } XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); } /* * InitrOperPopup() - This function initializes the brush operation * popup from a given Operation structure. * * PARAMETERS * oper The Operation to initialize from * * REUTRNS * void */ void InitOperPopup(Operation *oper) { Widget w; Arg wargs[1]; if(!(w = WcFullNameToWidget(appShell,"*boper_highlight"))) { fprintf(stderr, "Error finding *boper_highlight\n"); return; } if(oper->oper & OPER_HIGHLIGHT) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_mask"))) { fprintf(stderr, "Error finding *boper_mask\n"); return; } if(oper->oper & OPER_MASK) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_values"))) { fprintf(stderr, "Error finding *boper_values\n"); return; } if(oper->oper & OPER_VALUES) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_average"))) { fprintf(stderr, "Error finding *boper_average\n"); return; } if(oper->oper & OPER_AVERAGE) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_1"))) { fprintf(stderr, "Error finding *boper_not_1\n"); return; } XtSetArg(wargs[0], XtNstate, oper->not[0]); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_2"))) { fprintf(stderr, "Error finding *boper_not_2\n"); return; } if(oper->order > 1) XtSetArg(wargs[0], XtNstate, oper->not[1]); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_3"))) { fprintf(stderr, "Error finding *boper_not_3\n"); return; } if(oper->order > 2) XtSetArg(wargs[0], XtNstate, oper->not[2]); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_not_4"))) { fprintf(stderr, "Error finding *boper_not_4\n"); return; } if(oper->order > 3) XtSetArg(wargs[0], XtNstate, oper->not[3]); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_and_1"))) { fprintf(stderr, "Error finding *boper_and_1\n"); return; } if(oper->order > 1 && oper->conj[0] == CONJ_AND) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_and_2"))) { fprintf(stderr, "Error finding *boper_and_2\n"); return; } if(oper->order > 2 && oper->conj[1] == CONJ_AND) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_and_3"))) { fprintf(stderr, "Error finding *boper_and_3\n"); return; } if(oper->order > 3 && oper->conj[2] == CONJ_AND) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_or_1"))) { fprintf(stderr, "Error finding *boper_or_1\n"); return; } if(oper->order > 1 && oper->conj[0] == CONJ_OR) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_or_2"))) { fprintf(stderr, "Error finding *boper_or_2\n"); return; } if(oper->order > 2 && oper->conj[1] == CONJ_OR) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_or_3"))) { fprintf(stderr, "Error finding *boper_or_3\n"); return; } if(oper->order > 3 && oper->conj[2] == CONJ_OR) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_xor_1"))) { fprintf(stderr, "Error finding *boper_xor_1\n"); return; } if(oper->order > 1 && oper->conj[0] == CONJ_XOR) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_xor_2"))) { fprintf(stderr, "Error finding *boper_xor_2\n"); return; } if(oper->order > 2 && oper->conj[1] == CONJ_XOR) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_xor_3"))) { fprintf(stderr, "Error finding *boper_xor_3\n"); return; } if(oper->order > 3 && oper->conj[2] == CONJ_XOR) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_1"))) { fprintf(stderr, "Error finding *boper_brush_1_1\n"); return; } if(oper->brush[0] == 0) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_2"))) { fprintf(stderr, "Error finding *boper_brush_1_2\n"); return; } if(oper->brush[0] == 1) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_3"))) { fprintf(stderr, "Error finding *boper_brush_1_3\n"); return; } if(oper->brush[0] == 2) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_4"))) { fprintf(stderr, "Error finding *boper_brush_1_4\n"); return; } if(oper->brush[0] == 3) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_1"))) { fprintf(stderr, "Error finding *boper_brush_2_1\n"); return; } if(oper->order > 1 && oper->brush[1] == 0) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_2"))) { fprintf(stderr, "Error finding *boper_brush_2_2\n"); return; } if(oper->order > 1 && oper->brush[1] == 1) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_3"))) { fprintf(stderr, "Error finding *boper_brush_2_3\n"); return; } if(oper->order > 1 && oper->brush[1] == 2) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_4"))) { fprintf(stderr, "Error finding *boper_brush_2_4\n"); return; } if(oper->order > 1 && oper->brush[1] == 3) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_1"))) { fprintf(stderr, "Error finding *boper_brush_3_1\n"); return; } if(oper->order > 2 && oper->brush[2] == 0) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_2"))) { fprintf(stderr, "Error finding *boper_brush_3_2\n"); return; } if(oper->order > 2 && oper->brush[2] == 1) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_3"))) { fprintf(stderr, "Error finding *boper_brush_3_3\n"); return; } if(oper->order > 2 && oper->brush[2] == 2) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_4"))) { fprintf(stderr, "Error finding *boper_brush_3_4\n"); return; } if(oper->order > 2 && oper->brush[2] == 3) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_1"))) { fprintf(stderr, "Error finding *boper_brush_4_1\n"); return; } if(oper->order > 3 && oper->brush[3] == 0) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_2"))) { fprintf(stderr, "Error finding *boper_brush_4_2\n"); return; } if(oper->order > 3 && oper->brush[3] == 1) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_3"))) { fprintf(stderr, "Error finding *boper_brush_4_3\n"); return; } if(oper->order > 3 && oper->brush[3] == 2) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_4"))) { fprintf(stderr, "Error finding *boper_brush_4_4\n"); return; } if(oper->order > 3 && oper->brush[3] == 3) XtSetArg(wargs[0], XtNstate, True); else XtSetArg(wargs[0], XtNstate, False); XtSetValues(w, wargs, 1); } /* * BrushOperUpdateList() - Regernate the brush operation list from the * operations array. * * PARAMETERS * void * * RETURNS * void */ void BrushOperUpdateList(void) { int i; Widget scroll_w; /* the scrollable list widget */ Widget menu_w; /* the menu */ char menu_name[128]; /* the menu item name */ char cb_name[128]; /* the name to use for the callback */ int n; Arg wargs[10]; /* for XtSetArg() */ for(i=0; i<num_oper; i++) { /* free old name if it exists */ if(oper_names[i]) free(oper_names[i]); oper_names[i] = NameFromOperation(i); /* free menu entry if it exists */ if(operations[i].has_color && operations[i].menu_item) XtDestroyWidget(operations[i].menu_item); } /* add the operations with colors to the color menu */ if(!(menu_w = WcFullNameToWidget(appShell, "*color_req_menu"))) { fprintf(stderr, "Error finding *color_req_menu in BrushOperUpdateList()\n"); return; } for(i=0; i<num_oper; i++) if(operations[i].has_color) { /* set the menu name and the callback name */ sprintf(menu_name, "Operation %s", oper_names[i]); sprintf(cb_name, "Operation %d", i+1); n = 0; XtSetArg(wargs[n], XtNlabel, str_dup(menu_name)); n++; operations[i].menu_item = XtCreateManagedWidget(str_dup(menu_name), smeBSBObjectClass, menu_w, wargs, n); if(!operations[i].menu_item) fprintf(stderr, "Error creating menu item in BrushOperUpdateList()\n"); XtAddCallback(operations[i].menu_item, XtNcallback, ColorReqChooseColorCB, str_dup(cb_name)); XtAddCallback(operations[i].menu_item, XtNcallback, ColorReqRedrawCanvasCB, NULL); } if(!(scroll_w = WcFullNameToWidget(appShell, "*btb_oper_list"))) { fprintf(stderr, "Error finding *btb_oper_list\n"); return; } /* unselect the itmes in the scrollabe list first */ XukcScrListUnselectItems(scroll_w); /* change the list */ if(num_oper == 0) { /* this is a hack to get around the broken Athena list */ /* widget which can't have 0 items in it */ oper_names[0] = str_dup(" "); XukcScrListChange(scroll_w, oper_names, 1); } else XukcScrListChange(scroll_w, oper_names, num_oper); } /* * OperationFromPopup() - Create an operation structure from the * brush operation popup. * * PARAMETERS * oper A pointer to the operation structure to * fill in. * * RETURNS * TRUE Success * FALSE Failure */ int OperationFromPopup(Operation *oper) { Widget w; /* current widget */ Arg wargs[1]; Boolean state; /* toggle state */ int i; /* first initialize all the values */ oper->oper = OPER_NONE; for(i=0; i<MAXBRUSH; i++) { oper->not[i] = 0; oper->brush[i] = BRUSH_NONE; } for(i=0; i<MAXBRUSH-1; i++) oper->conj[i] = CONJ_NONE; if(!(w = WcFullNameToWidget(appShell,"*boper_highlight"))) { fprintf(stderr, "Error finding *boper_highlight\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->oper |= OPER_HIGHLIGHT; if(!(w = WcFullNameToWidget(appShell,"*boper_mask"))) { fprintf(stderr, "Error finding *boper_mask\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->oper |= OPER_MASK; if(!(w = WcFullNameToWidget(appShell,"*boper_values"))) { fprintf(stderr, "Error finding *boper_values\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->oper |= OPER_VALUES; if(!(w = WcFullNameToWidget(appShell,"*boper_average"))) { fprintf(stderr, "Error finding *boper_average\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->oper |= OPER_AVERAGE; if(!(w = WcFullNameToWidget(appShell,"*boper_not_1"))) { fprintf(stderr, "Error finding *boper_not_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->not[0] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_not_2"))) { fprintf(stderr, "Error finding *boper_not_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->not[1] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_not_3"))) { fprintf(stderr, "Error finding *boper_not_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->not[2] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_not_4"))) { fprintf(stderr, "Error finding *boper_not_4\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->not[3] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_and_1"))) { fprintf(stderr, "Error finding *boper_and_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[0] = CONJ_AND; if(!(w = WcFullNameToWidget(appShell,"*boper_and_2"))) { fprintf(stderr, "Error finding *boper_and_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[1] = CONJ_AND; if(!(w = WcFullNameToWidget(appShell,"*boper_and_3"))) { fprintf(stderr, "Error finding *boper_and_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[2] = CONJ_AND; if(!(w = WcFullNameToWidget(appShell,"*boper_or_1"))) { fprintf(stderr, "Error finding *boper_or_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[0] = CONJ_OR; if(!(w = WcFullNameToWidget(appShell,"*boper_or_2"))) { fprintf(stderr, "Error finding *boper_or_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[1] = CONJ_OR; if(!(w = WcFullNameToWidget(appShell,"*boper_or_3"))) { fprintf(stderr, "Error finding *boper_or_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[2] = CONJ_OR; if(!(w = WcFullNameToWidget(appShell,"*boper_xor_1"))) { fprintf(stderr, "Error finding *boper_xor_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[0] = CONJ_XOR; if(!(w = WcFullNameToWidget(appShell,"*boper_xor_2"))) { fprintf(stderr, "Error finding *boper_xor_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[1] = CONJ_XOR; if(!(w = WcFullNameToWidget(appShell,"*boper_xor_3"))) { fprintf(stderr, "Error finding *boper_xor_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->conj[2] = CONJ_XOR; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_1"))) { fprintf(stderr, "Error finding *boper_brush_1_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[0] = 0; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_2"))) { fprintf(stderr, "Error finding *boper_brush_1_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[0] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_3"))) { fprintf(stderr, "Error finding *boper_brush_1_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[0] = 2; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_1_4"))) { fprintf(stderr, "Error finding *boper_brush_1_4\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[0] = 3; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_1"))) { fprintf(stderr, "Error finding *boper_brush_2_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[1] = 0; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_2"))) { fprintf(stderr, "Error finding *boper_brush_2_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[1] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_3"))) { fprintf(stderr, "Error finding *boper_brush_2_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[1] = 2; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_2_4"))) { fprintf(stderr, "Error finding *boper_brush_2_4\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[1] = 3; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_1"))) { fprintf(stderr, "Error finding *boper_brush_3_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[2] = 0; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_2"))) { fprintf(stderr, "Error finding *boper_brush_3_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[2] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_3"))) { fprintf(stderr, "Error finding *boper_brush_3_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[2] = 2; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_3_4"))) { fprintf(stderr, "Error finding *boper_brush_3_4\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[2] = 3; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_1"))) { fprintf(stderr, "Error finding *boper_brush_4_1\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[3] = 0; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_2"))) { fprintf(stderr, "Error finding *boper_brush_4_2\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[3] = 1; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_3"))) { fprintf(stderr, "Error finding *boper_brush_4_3\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[3] = 2; if(!(w = WcFullNameToWidget(appShell,"*boper_brush_4_4"))) { fprintf(stderr, "Error finding *boper_brush_4_4\n"); return(TRUE); } XtSetArg(wargs[0], XtNstate, &state); XtGetValues(w, wargs, 1); if(state) oper->brush[3] = 3; /* determine the order */ for(oper->order = 1; oper->order <= MAXBRUSH-1; oper->order++) if(oper->brush[oper->order] == BRUSH_NONE) break; /* check to make sure all the conjunctions are in there */ for(i=0; i<oper->order-1; i++) if(oper->conj[i] == CONJ_NONE) return(TRUE); /* check that there is an output operation */ if(oper->oper == OPER_NONE) return(TRUE); /* set the has_color flag */ if((oper->oper & OPER_HIGHLIGHT) || (oper->oper & OPER_AVERAGE)) oper->has_color = TRUE; else oper->has_color = FALSE; return(FALSE); } /* * ColorFromOperations() - This function determines the color that * a point should be from the various operations * defined. The lowest numbered operation * has precedence if the point is covered * by multiple operations. * * PARAMETERS * point The point in question * * RETURNS * The color cell to paint the point with. */ unsigned long ColorFromOperations(double *point) { int i; double coverage; /* brush coverage */ int col_index; /* color index */ /* the first operation has highest priority */ for(i=0; i<num_oper; i++) { if(OperationPoint(point, i)) { if(operations[i].oper & OPER_HIGHLIGHT) { /* if(operations[i].bound == BOUND_RAMP) { */ coverage = PercentOperationPoint(point, i); /* fprintf(stderr, "cov: %f\n", coverage); */ col_index = (1.0 - coverage) * NUM_BOUND_COL; col_index = MAX(col_index, 0); col_index = MIN(col_index, NUM_BOUND_COL-1); /* fprintf(stderr, "col index: %d\n", col_index); */ return(operations[i].colors[col_index].pixel); /* } else return(operations[i].colors[0].pixel); */ } else if(operations[i].oper & OPER_MASK) return(COLOR_NONE); } } /* if covered by no operations, just paint in the data color */ return(color_cells[CCELL_DATA]); } /* * OperationPoint() - Compute if a point is covered by the given brush * operation. * * PARAMETERS * point The point in question * op The operation number * * RETURNS * TRUE The point evaluates to TRUE for the given operation * FALSE The point evaluates to FALSE for the given operation */ int OperationPoint(double *point, int op) { int i; Operation *oper; /* the operation */ int result; /* the result of the expression */ int next_br; /* next brush coverage */ oper = &operations[op]; /* check to make sure all brushes are enabled first */ for(i=0; i<oper->order; i++) if(brushes[oper->brush[i]].enable == FALSE) return FALSE; /* set the result to the initial brush coverage */ result = oper->not[0] ? !CheckBrushCoverage(point, oper->brush[0]) : CheckBrushCoverage(point, oper->brush[0]); for(i=1; i<oper->order; i++) { next_br = oper->not[i] ? !CheckBrushCoverage(point, oper->brush[i]) : CheckBrushCoverage(point, oper->brush[i]); switch(oper->conj[i-1]) { case CONJ_AND: result &= next_br; break; case CONJ_OR: result |= next_br; break; case CONJ_XOR: result ^= next_br; break; default: fprintf(stderr, "internal error: bad operation conjunction in"); fprintf(stderr, "OperationPoint()\n"); break; } } return(result); } /* * PercentOperationPoint() - Compute the percent of coverage from * a brush. Only really makes sense for * brushes with non stepped boundaries. * * PARAMETERS * point The point in question * op The operation number * * RETURNS * coverage percent (0..1) */ double PercentOperationPoint(double *point, int op) { int i; Operation *oper; /* the operation */ double coverage=0.0; /* the coverage */ double next_br; /* next brush coverage */ oper = &operations[op]; /* check to make sure all brushes are enabled first */ for(i=0; i<oper->order; i++) if(brushes[oper->brush[i]].enable == FALSE) return(0.0); /* set the result to the initial brush coverage */ coverage = oper->not[0] ? 1.0 - PercentBrushCoverage(point, oper->brush[0]) : PercentBrushCoverage(point, oper->brush[0]); for(i=1; i<oper->order; i++) { next_br = oper->not[i] ? 1.0 - PercentBrushCoverage(point, oper->brush[i]) : PercentBrushCoverage(point, oper->brush[i]); switch(oper->conj[i-1]) { case CONJ_AND: coverage = MIN(coverage, next_br); break; case CONJ_OR: coverage = MAX(coverage, next_br); break; case CONJ_XOR: coverage += next_br; if(coverage > 1.0) coverage = 2.0 - coverage; break; default: fprintf(stderr, "internal error: bad operation conjunction in"); fprintf(stderr, "PercentOperationPoint()\n"); break; } } return(coverage); }


Back to Source File Index


C++ to HTML Conversion by ctoohtml