void Mark_XMC(XtermWidget xw, int param) { static IChar *glitch; TScreen *screen = TScreenOf(xw); Bool found = False; unsigned my_attrs = CharOf(screen->xmc_attributes & XMC_FLAGS); unsigned whichone = 0; if (glitch == 0) { unsigned len = screen->xmc_glitch; glitch = TypeMallocN(IChar, len); while (len--) glitch[len] = XMC_GLITCH; } switch (param) { case -1: /* DEFAULT */ case 0: /* FALLTHRU */ found = MARK_OFF((xw->flags & XMC_FLAGS)); break; case 1: found = MARK_ON(BOLD); break; case 4: found = MARK_ON(UNDERLINE); break; case 5: found = MARK_ON(BLINK); break; case 7: found = MARK_ON(INVERSE); break; case 22: found = MARK_OFF(BOLD); break; case 24: found = MARK_OFF(UNDERLINE); break; case 25: found = MARK_OFF(BLINK); break; case 27: found = MARK_OFF(INVERSE); break; } /* * Write a glitch with the attributes temporarily set to the new(er) * ones. */ if (found) { unsigned save = xw->flags; xw->flags ^= whichone; TRACE(("XMC Writing glitch (%d/%d) after SGR %d\n", my_attrs, whichone, param)); dotext(xw, '?', glitch, screen->xmc_glitch); xw->flags = save; } }
int draw_mag(void) { char buf[10]; sprintf(buf, "%d", mag); dotext(buf, value.top, value.bottom, value.left, value.right, WHITE); return 0; }
main() { char buf[80]; while( fgets( buf, 79, stdin ) != NULL ) { if( buf[0] == 'q' ) break; dotext( buf ); } }
void Mark_XMC(register TScreen *screen, int param) { static IChar *glitch; Boolean found = FALSE; Char my_attrs = (screen->xmc_attributes & XMC_FLAGS); Char whichone = 0; if (glitch == 0) { unsigned len = screen->xmc_glitch; glitch = (IChar *)malloc(len * sizeof(IChar)); while (len--) glitch[len] = XMC_GLITCH; } switch (param) { case -1:/* DEFAULT */ case 0: /* FALLTHRU */ found = MARK_OFF((term->flags & XMC_FLAGS)); break; case 1: found = MARK_ON(BOLD); break; case 4: found = MARK_ON(UNDERLINE); break; case 7: found = MARK_ON(INVERSE); break; case 22: found = MARK_OFF(BOLD); break; case 24: found = MARK_OFF(UNDERLINE); break; case 27: found = MARK_OFF(INVERSE); break; } /* * Write a glitch with the attributes temporarily set to the new(er) * ones. */ if (found) { unsigned save = term->flags; term->flags ^= whichone; TRACE(("XMC Writing glitch (%d/%d) after SGR %d\n", my_attrs, whichone, param)); dotext(screen, '?', glitch, screen->xmc_glitch); term->flags = save; } }
static void objtext(double x, double y, obj *p) { double *bnd; int i, nt2 = (unsigned int) p->o_nt2, t; t = text[p->o_nt1].t_type; for (i = p->o_nt1; i < nt2; i++) if (text[i].t_type != t) break; if (i == nt2 && p->o_type != TEXT) { /* all strings same type */ bnd = text_bounds(p); if (t & RJUST) x += (bnd[2] - bnd[0]) / 2; if (t & LJUST) x -= (bnd[2] - bnd[0]) / 2; } dotext(x, y, p); }
static int dobox(struct box *box, char *text, int color, int top, int left, int right, int centered) { int bottom; bottom = top + height; /* fill inside of box with color */ R_standard_color(color); R_box_abs(left + 1, top + 1, right - 1, bottom - 1); /* draw box outline and text in black */ R_standard_color(BLACK); Outline_box(top, bottom, left, right); dotext(text, top, bottom, left, right, centered); R_flush(); box->top = top; box->bottom = bottom; box->left = left; box->right = right; return 0; }
int ask_magnification(int *magnification) { static int use = 1; int x, y; int height; int stat; int width; int top, bottom, left, right; static Objects objects[] = { OTHER(incr, &use), {0} }; Menu_msg(""); mag = *magnification; if (mag < 1) mag = 1; height = VIEW_MENU->nrows; R_text_size(height - 4, height - 4); Get_mouse_xy(&x, &y); top = y - height / 2; if (top < SCREEN_TOP) top = SCREEN_TOP; bottom = top + 4 * height; if (bottom >= VIEW_MENU->top) { top -= bottom - (VIEW_MENU->top - 1); bottom = VIEW_MENU->top - 1; } width = Text_width("MAGNIFICATION") + 4; left = x - width / 2; if (left < SCREEN_LEFT) left = SCREEN_LEFT; right = left + width; if (right > SCREEN_RIGHT) { left -= right - SCREEN_RIGHT; right = SCREEN_RIGHT; } R_panel_save(tempfile1, top, bottom, left, right); R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_standard_color(BLACK); Outline_box(top, bottom, left, right); plus.top = top + height; plus.bottom = plus.top + height; plus.left = left; plus.right = plus.left + Text_width("++") + 4; Outline_box(plus.top, plus.bottom, plus.left, plus.right); minus.top = top + height; minus.bottom = minus.top + height; minus.right = right; minus.left = minus.right - Text_width("--") - 4; Outline_box(minus.top, minus.bottom, minus.left, minus.right); value.top = top + height; value.bottom = value.top + height; value.left = plus.right; value.right = minus.left; Outline_box(value.top, value.bottom, value.left, value.right); accept.top = value.bottom; accept.bottom = accept.top + height; accept.left = left; accept.right = right; Outline_box(accept.top, accept.bottom, accept.left, accept.right); cancel.top = accept.bottom; cancel.bottom = cancel.top + height; cancel.left = left; cancel.right = right; Outline_box(cancel.top, cancel.bottom, cancel.left, cancel.right); dotext("MAGNIFICATION", top, top + height, left, right, WHITE); dotext("+", plus.top, plus.bottom, plus.left, plus.right, GREY); dotext("-", minus.top, minus.bottom, minus.left, minus.right, GREY); dotext("ACCEPT", accept.top, accept.bottom, accept.left, accept.right, GREY); dotext("CANCEL", cancel.top, cancel.bottom, cancel.left, cancel.right, GREY); draw_mag(); stat = Input_pointer(objects); /* to respond to user */ R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_flush(); R_panel_restore(tempfile1); R_panel_delete(tempfile1); *magnification = mag; return stat > 0; }
int ask_line_color(char *colors, int len1, char *xname, int position) { static int use = 1; int pick(); static Objects objects[] = { OTHER(pick, &use), {0} }; char msg[100]; int width; int len2 = 0, len; long offset; long *page_offset; int col, nlist; int line; int stat; char buf[100]; int top, bottom, left, right, center; int topx, bottomx, leftx, rightx, widthx; char name[100], mapset[100], cur_mapset[100]; int new_mapset; Menu_msg(""); sprintf(msg, "Double click on color to assign to vector layer"); /* * build a popup window at center of the screen. * 35% the height and wide enough to hold 2 columms of file names * * the window is for choosing file names and will be laid out in 2 columns * * ------------------------------------------ * | CANCEL | (MORE) | (LESS) | * ------------------------------------------ * | mapset | * ------------------------------------------ * | name1 | name2 | * ------------------------------------------ * | name3 | name4 | * ------------------------------------------ * | name5 | name6 | * | . | * | . | * | . | * ------------------------------------------ */ /* height of 1 line, based on NLINES taking up 35% vertical space */ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP)) / NLINES + 1; /* size of text, 80% of line height */ text_size = .8 * height; size = text_size - 1; /* fudge for computing pixels width of text */ /* indent for the text */ edge = .1 * height + 1; /* this is a fudge to determine the length of the largest text */ len1 = 2 * len1; /* name in 2 columns */ len2 += strlen("mapset "); len = (len1 > len2 ? len1 : len2); /* width is for max chars plus sidecar for more/less */ width = len * size + height; widthx = strlen(msg) * size; if (widthx < width) widthx = width; /* define the window */ top = (SCREEN_TOP + SCREEN_BOTTOM - height * NLINES) / 2; bottom = top + height * NLINES; center = (SCREEN_LEFT + SCREEN_RIGHT) / 2; if (position > 0) { right = (center + SCREEN_RIGHT + width) / 2; if (right >= SCREEN_RIGHT) right = SCREEN_RIGHT - 1; left = right - width; } else if (position < 0) { left = (center + SCREEN_LEFT - width) / 2; if (left <= SCREEN_LEFT) left = SCREEN_LEFT + 1; right = left + width; } else { left = center + width / 2; right = left + width; } topx = top - 3 * height; bottomx = topx + 2 * height; leftx = (left + right - widthx) / 2; if (leftx < SCREEN_LEFT) leftx = SCREEN_LEFT; rightx = leftx + widthx; /* save what is under these areas, so they can be restored */ R_panel_save(tempfile1, top, bottom, left, right); R_panel_save(tempfile2, topx, bottomx, leftx, rightx); /* fill it top with GREY, pick area with white */ R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_standard_color(GREY); R_box_abs(leftx, topx, rightx, bottomx); R_standard_color(BLACK); Outline_box(top, bottom, left, right); right -= height; /* reduce it to exclude sidecar */ Outline_box(top, bottom, left, right); /* print messages above the files */ dotext(msg, topx, topx + height, leftx, rightx, 1); dotext("Double click here to cancel", topx + height, bottomx, leftx, rightx, 1); cancel.top = topx; cancel.bottom = bottomx; cancel.left = leftx; cancel.right = rightx; /* start the mouse in the cancel box */ Set_mouse_xy((leftx + rightx) / 2, (topx + bottomx) / 2); dobox(&less, "", WHITE, top, right, right + height, 0); dobox(&more, "", WHITE, bottom - height, right, right + height, 0); /* as we read the file of names, keep track of pages so we can * page backward */ page = 0; page_offset = (long *)G_calloc(npages = 1, sizeof(long)); *page_offset = ftell(fd); nlist = sizeof(list) / sizeof(list[0]); for (stat = -1; stat < 0;) { line = 0; count = 0; *cur_mapset = 0; col = 0; while (1) { /* offset = ftell (fd); if (fgets (buf, sizeof buf, fd) == NULL || sscanf (buf, "%s %s", name, mapset) != 2) break; if(new_mapset = (strcmp (cur_mapset,mapset) != 0)) { if(line) line++; if (col) line++; col = 0; } if (count >= nlist || line+new_mapset >= NLINES) { if (page+1 == npages) { npages++; page_offset = (long *) G_realloc (page_offset, npages * sizeof (long)); page_offset[npages-1] = offset; } break; } if (new_mapset) { struct box dummy; char label[100]; strcpy (cur_mapset, mapset); sprintf (label, "Mapset %s", mapset); dobox (&dummy, label, WHITE, top+line*height, left, right, 0); line++; } if (col) { dobox (&list[count].box, name, GREY, top+line*height, left+width/2, right, 0); line++; col = 0; } else { dobox (&list[count].box, name, GREY, top+line*height, left, left+width/2, 0); col = 1; } strcpy (list[count].name, name); strcpy (list[count].mapset, mapset); count++; } downarrow (&more, page+1 < npages ? BLACK : WHITE); uparrow (&less, page > 0 ? BLACK : WHITE); which = -1; switch(Input_pointer(objects)) { case -1: /* more or less */ break; case -2: /* cancel */ stat = 0; continue; default: /* file picked */ strcpy(xname, list[which].name); stat = 1; continue; } fseek(fd, page_offset[page], 0); R_standard_color(WHITE); R_box_abs(left + 1, top + 1, right - 1, bottom - 1); } /* all done. restore what was under the window */ right += height; /* move it back over the sidecar */ R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_panel_restore(tempfile1); R_panel_restore(tempfile2); R_panel_delete(tempfile1); R_panel_delete(tempfile2); R_flush(); G_free(page_offset); return stat; }
int analyze(void) { static int use = 1; static Objects objects[] = { MENU("DONE", done, &use), MENU("PRINT", to_printer, &use), MENU("FILE", to_file, &use), MENU("OVERLAY", do_warp, &use), MENU(delete_msg, delete_mark, &use), INFO("Transform->", &use), MENU(order_msg, get_order, &use), INFO(pick_msg, &use), OTHER(pick, &use), {0} }; int color; int tsize; int cury; int len; int line; int top, bottom, left, right, width, middle, nums; /* to give user a response of some sort */ Menu_msg("Preparing analysis ..."); /* * build a popup window at center of the screen. * 35% the height and wide enough to hold the report * */ /* height of 1 line, based on NLINES taking up 35% vertical space */ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP)) / NLINES + 1; /* size of text, 80% of line height */ tsize = .8 * height; size = tsize - 2; /* fudge for computing pixels width of text */ /* indent for the text */ edge = .1 * height + 1; /* determine the length, in chars, of printed line */ FMT0(buf, 0); nums = strlen(buf) * size; FMT1(buf, 0.0, 0.0, 0.0); len = strlen(buf); middle = len * size; FMT2(buf, 0.0, 0.0, 0.0, 0.0); len += strlen(buf); /* width is for max chars plus sidecar for more/less */ width = len * size + nums + 2 * height; if ((SCREEN_RIGHT - SCREEN_LEFT) < width) width = SCREEN_RIGHT - SCREEN_LEFT; /* define the window */ bottom = VIEW_MENU->top - 1; top = bottom - height * NLINES; left = SCREEN_LEFT; right = left + width; middle += left + nums; nums += left; /* save what is under this area, so it can be restored */ R_panel_save(tempfile1, top, bottom + 1, left, right + 1); /* fill it with white */ R_standard_color(BACKGROUND); R_box_abs(left, top, right, bottom); right -= 2 * height; /* reduce it to exclude sidecar */ /* print messages in message area */ R_text_size(tsize, tsize); /* setup the more/less boxes in the sidecar */ R_standard_color(BLACK); less.top = top; less.bottom = top + 2 * height; less.left = right; less.right = right + 2 * height; Outline_box(less.top, less.bottom, less.left, less.right); more.top = bottom - 2 * height; more.bottom = bottom; more.left = right; more.right = right + 2 * height; Outline_box(more.top, more.bottom, more.left, more.right); /* * top two lines are for column labels * last two line is for overall rms error. */ nlines = NLINES - 3; first_point = 0; /* allocate predicted values */ xres = (double *)G_calloc(group.points.count, sizeof(double)); yres = (double *)G_calloc(group.points.count, sizeof(double)); gnd = (double *)G_calloc(group.points.count, sizeof(double)); /* compute transformation for the first time */ compute_transformation(); /* put head on the report */ cury = top; dotext(LHEAD1, cury, cury + height, left, middle, 0, BLACK); dotext(RHEAD1, cury, cury + height, middle, right - 1, 0, BLACK); cury += height; dotext(LHEAD2, cury, cury + height, left, middle, 0, BLACK); dotext(RHEAD2, cury, cury + height, middle, right - 1, 0, BLACK); cury += height; R_move_abs(left, cury - 1); R_cont_abs(right, cury - 1); /* isolate the sidecar */ R_move_abs(right, top); R_cont_abs(right, bottom); /* define report box */ report.top = cury; report.left = left; report.right = right; /* lets do it */ pager = 1; while (1) { R_text_size(tsize, tsize); line = 0; curp = first_point; cury = top + 2 * height; while (1) { if (line >= nlines || curp >= group.points.count) break; line++; if (!delete_mode) color = BLACK; else color = BLUE; if (group.equation_stat > 0 && group.points.status[curp] > 0) { /* color = BLACK; */ FMT1(buf, xres[curp], yres[curp], gnd[curp]); if (curp == xmax || curp == ymax || curp == gmax) color = RED; dotext(buf, cury, cury + height, nums, middle, 0, color); } else if (group.points.status[curp] > 0) dotext("?", cury, cury + height, nums, middle, 1, color); else dotext("not used", cury, cury + height, nums, middle, 1, color); if (pager) { FMT0(buf, curp + 1); dotext(buf, cury, cury + height, left, nums, 0, color); FMT2(buf, group.points.e1[curp], group.points.n1[curp], group.points.e2[curp], group.points.n2[curp]); dotext(buf, cury, cury + height, middle, right - 1, 0, color); } cury += height; curp++; } report.bottom = cury; downarrow(&more, curp < group.points.count ? color : BACKGROUND); uparrow(&less, first_point > 0 ? color : BACKGROUND); R_standard_color(BACKGROUND); R_box_abs(left, cury, right - 1, bottom); if (group.equation_stat < 0) { if (group.equation_stat == -1) { color = RED; strcpy(buf, "Poorly placed control points"); } else { if (group.equation_stat == -2) G_fatal_error("NOT ENOUGH MEMORY"); else G_fatal_error("PARAMETER ERROR"); } } else if (group.equation_stat == 0) { color = RED; strcpy(buf, "No active control points"); } else { color = BLACK; sprintf(buf, "Overall rms error: %.2f", rms); } dotext(buf, bottom - height, bottom, left, right - 1, 0, color); R_standard_color(BLACK); R_move_abs(left, bottom - height); R_cont_abs(right - 1, bottom - height); pager = 0; which = -1; if (Input_pointer(objects) < 0) break; display_points(1); } /* all done. restore what was under the window */ right += 2 * height; /* move it back over the sidecar */ R_standard_color(BACKGROUND); R_box_abs(left, top, right, bottom); R_panel_restore(tempfile1); R_panel_delete(tempfile1); R_flush(); G_free(xres); G_free(yres); G_free(gnd); I_put_control_points(group.name, &group.points); display_points(1); return 0; /* return but don't QUIT */ }
static obj * print_xform(int layer, obj *p) { double r, ox, oy, dx, dy, x0, y0, x1, y1, M[4]; double b, tx0, ty0, tx1, ty1; valtype *X; obj *op, *q; int n; op = p; if (p->o_layer != layer && p->o_type != BLOCK) return p; #if 0 if (p->o_type == TEXT) { ox = Xformx(p->o_parent, 1, p->o_x, p->o_y); oy = Xformy(p->o_parent, 0, p->o_x, p->o_y); } else { #endif ox = Xformx(p, 1, p->o_x, p->o_y); oy = Xformy(p, 0, p->o_x, p->o_y); #if 0 } #endif X = (valtype *)0; if (p->o_type < TEXT && (p->o_attr & (FILLED | EDGED))) chk_attrs (p); switch (p->o_type) { case TROFF: n = p->o_nt1; if (text[n].t_type & EQNTXT) puteqn(ox, oy, text[n].t_type, atoi(text[n].t_val)); else troff(text[n].t_val); return p; case BLOCK: for (q = p->o_next; q != p->o_val[N_VAL].o; q = q->o_next) if (q->o_type <= TEXT || q->o_nt2 > q->o_nt1) q = print_xform(layer,q); p = q; break; case PSFILE: puteps(p); /* CAREFUL!! THIS FLOWS THROUGH INTO BOX!! */ case BOX: if (p->o_attr & (FILLED|EDGED)) { if ((X = (valtype *)malloc(10*sizeof(valtype))) == NULL) yyerror("out of room in print_xform"); r = p->o_val[N_VAL].f; X[6].f = X[0].f = -(X[2].f = X[4].f = p->o_wid/2); X[1].f = X[3].f = -(X[5].f = X[7].f = p->o_ht/2); for (n = 0; n < 8; n += 2) { x1 = ox + Linx(p, 0, X[n].f, X[n+1].f); X[n+1].f = oy + Liny(p, 0, X[n].f, X[n+1].f); X[n].f = x1; } X[n] = X[0]; X[++n] = X[1]; x1 = Linx(p, 0, r, 0.); r = Liny(p, 0, r, 0.); r = sqrt(x1 * x1 + r * r); pline(4, 1, X, r); } break; case CIRCLE: case ELLIPSE: if (p->o_attr & (FILLED|EDGED)) { get_matrix(&x0, &y0, &x1, &y1); x0 *= p->o_wid/2; y0 *= p->o_wid/2; x1 *= p->o_ht/2; y1 *= p->o_ht/2; ellipse(ox, oy, x0, y0, x1, y1, 0., 2*M_PI, 0); } break; case SECTOR: case ARC: if (p->o_attr & (FILLED|EDGED)) { register double ang1, ang2; r = p->o_val[N_VAL+0].f; x0 = p->o_val[N_VAL+2].f; /* starting point */ y0 = p->o_val[N_VAL+3].f; x1 = p->o_val[N_VAL+4].f; /* ending point */ y1 = p->o_val[N_VAL+5].f; ang1 = atan2(y0 - p->o_y, x0 - p->o_x); ang2 = atan2(y1 - p->o_y, x1 - p->o_x); /* * If there are arrowheads and non-zero line thickness, we * adjust the end points so the thick lines do not go all the * way to the end of the arrows, obliterating the points. */ if (p->o_attr & HEAD12) { dx = p->o_val[N_VAL+8].f; dy = p->o_val[N_VAL+9].f; if (p->o_weight > 0.) { b = p->o_weight / 2 / dx; b *= sqrt(dx*dx + 4*dy*dy); b = 2. * atan2(b, r); if (p->o_attr & HEAD1) ang1 += b; if (p->o_attr & HEAD2) ang2 -= b; } } tmp_xform(p); line_weight = p->o_weight; /* use REAL weight here */ ellipse(p->o_x, p->o_y, r, 0., 0., r, ang1, ang2, (int)p->o_type); undo_tmpx(); /* This is a kludge. Because tmp_xform and undo_tmpx put the * ellipse stuff (including a new_weight()) inside a gs/gr pair, * the postscript line-weight is unchanged, but new_weight thinks * it is set to line_weight. To get around this, we call a sub- * that just resets the last_weight variable in plps.c. */ reset_line_weight(); if (p->o_attr & (HEAD1 | HEAD2)) arc_arrow(p); } break; case LINE: case ARROW: case SPLINE: if (p->o_attr & (FILLED|EDGED)) { int c, i, nxy; r = p->o_val[N_VAL+0].f; x1 = Linx(p, 0, r, 0.); r = Liny(p, 0, r, 0.); r = sqrt(x1 * x1 + r * r); nxy = p->o_val[N_VAL+3].f; /* segment count */ X = (valtype *)malloc((2*nxy+2)*sizeof(valtype)); if (X == NULL) yyerror("out of room in print_xform"); for (i = 0, n = N_VAL+4; i <= 2 * nxy; ) { register double xx = p->o_val[n++].f, yy = p->o_val[n++].f; X[i++].f = Xformx(p, 0, xx, yy); X[i++].f = Xformy(p, 0, xx, yy); } x0 = X[0].f; y0 = X[1].f; x1 = X[i-2].f; y1 = X[i-1].f; tx0 = ty0 = tx1 = ty1 = 0.; n = 2 * nxy - 2; if (p->o_attr & HEAD12) { get_matrix(M, M+1, M+2, M+3); /* DBK: I added the fabs to eliminate sqrt errors * and make it same as xprint.c. 9/20/90 */ dy = dx = sqrt(fabs(M[0]*M[3] - M[1]*M[2])); dx *= p->o_val[N_VAL+1].f; dy *= p->o_val[N_VAL+2].f; if (p->o_weight > 0.) { double linex, liney, a; b = p->o_weight / 2 / p->o_val[N_VAL+1].f; b *= sqrt(dx*dx + 4*dy*dy); if (p->o_attr & HEAD2) { linex = x1 - X[n].f; liney = y1 - X[n+1].f; a = b / sqrt(linex*linex + liney*liney); tx1 = -a * linex; ty1 = -a * liney; x1 = X[n+2].f += tx1; y1 = X[n+3].f += ty1; } if (p->o_attr & HEAD1) { linex = x0 - X[2].f; liney = y0 - X[3].f; a = b / sqrt(linex*linex + liney*liney); tx0 = -a * linex; ty0 = -a * liney; x0 = X[0].f += tx0; y0 = X[1].f += ty0; } } } /* The first two args are just to give a direction to * the second two. To make sure that the direction * isn't reversed, adjust the first two by the same * amount as we adjusted x1 and y1 above. */ c = (x0 == x1 && y0 == y1); /* flags closure */ if (nxy == 1) line(X[0].f, X[1].f, X[2].f, X[3].f); else if (p->o_type == SPLINE) spline(nxy, c, X); else pline (nxy, c, X, r); if (p->o_attr & HEAD2) { tx1 += X[n].f; ty1 += X[n+1].f; arrow(tx1, ty1, x1, y1, dx, dy, 0.0, p->o_attr); } if (p->o_attr & HEAD1) { tx0 += X[2].f; ty0 += X[3].f; arrow(tx0, ty0, x0, y0, dx, dy, 0.0, p->o_attr); } } break; case TEXT: tmp_xform(p); #if 0 dotext(ox, oy, p); #else dotext(p->o_x, p->o_y, p); #endif undo_tmpx(); return p; } if (X) free(X); if (op->o_nt1 < op->o_nt2) objtext(ox, oy, op); return p; }
print() { obj *p; int i, j, k, m; float x0, y0, x1, y1, ox, oy, dx, dy, ndx, ndy; for (i = 0; i < nobj; i++) { p = objlist[i]; ox = p->o_x; oy = p->o_y; if (p->o_count >= 1) x1 = p->o_val[0]; if (p->o_count >= 2) y1 = p->o_val[1]; m = p->o_mode; switch (p->o_type) { case TROFF: troff(text[p->o_nt1].t_val); break; case BOX: case BLOCK: move(ox, oy); dotext(p); /* if there are any text strings */ x0 = ox - x1 / 2; y0 = oy - y1 / 2; x1 = ox + x1 / 2; y1 = oy + y1 / 2; if (p->o_attr & INVIS || p->o_type == BLOCK) ; /* nothing at all */ else if (p->o_attr & (DOTBIT|DASHBIT)) dotbox(x0, y0, x1, y1, p->o_attr, p->o_ddval); else box(x0, y0, x1, y1); if (ishor(m)) move(isright(m) ? x1 : x0, oy); /* right side */ else move(ox, isdown(m) ? y0 : y1); /* bottom */ break; case BLOCKEND: break; case CIRCLE: move(ox, oy); dotext(p); if ((p->o_attr & INVIS) == 0) circle(ox, oy, x1); if (ishor(m)) move(ox + isright(m) ? x1 : -x1, oy); else move(ox, oy + isup(m) ? x1 : -x1); break; case ELLIPSE: move(ox, oy); dotext(p); if ((p->o_attr & INVIS) == 0) ellipse(ox, oy, x1, y1); if (ishor(m)) move(ox + isright(m) ? x1 : -x1, oy); else move(ox, oy - isdown(m) ? y1 : -y1); break; case ARC: move(ox, oy); dotext(p); if (p->o_attr & HEAD1) arrow(x1 - (y1 - oy), y1 + (x1 - ox), x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead); if (p->o_attr & INVIS) /* probably wrong when it's cw */ move(x1, y1); else arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]); if (p->o_attr & HEAD2) arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox), p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5], -p->o_val[5]/p->o_val[6]/2, p->o_nhead); if (p->o_attr & CW_ARC) move(x1, y1); /* because drawn backwards */ break; case LINE: case ARROW: case SPLINE: move((ox + x1)/2, (oy + y1)/2); /* center */ dotext(p); if (p->o_attr & HEAD1) arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); if (p->o_attr & INVIS) move(x1, y1); else if (p->o_type == SPLINE) spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr & (DOTBIT|DASHBIT), p->o_ddval); else { dx = ox; dy = oy; for (k=0, j=5; k < p->o_val[4]; k++, j += 2) { ndx = dx + p->o_val[j]; ndy = dy + p->o_val[j+1]; if (p->o_attr & (DOTBIT|DASHBIT)) dotline(dx, dy, ndx, ndy, p->o_attr, p->o_ddval); else line(dx, dy, ndx, ndy); dx = ndx; dy = ndy; } } if (p->o_attr & HEAD2) { dx = ox; dy = oy; for (k = 0, j = 5; k < p->o_val[4] - 1; k++, j += 2) { dx += p->o_val[j]; dy += p->o_val[j+1]; } arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); } break; case MOVE: case TEXT: move(ox, oy); dotext(p); break; } } }