/******************************************************************** This file is part of the abs 0.907 distribution. abs is a spreadsheet with graphical user interface. Copyright (C) 1998-2001 André Bertin (Andre.Bertin@ping.be) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version if in the same spirit as version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Concact: abs@pi.be http://home.pi.be/bertin/abs.shtml *********************************************************************/ #include "sheetdrawer.h" #include "gr_interf.h" #include "application.h" #include "mainwin.h" #include "finite_state.h" #include "param.h" #include "callback.h" extern int is_selecting (); #define AW ActiveWorksheet #define CW worksheet_getcolw #define LH worksheet_getrowh #define SW worksheet_setcolw #define SH worksheet_setrowh #define Letext ActiveMainwin->commandline_obj->text #define Drawarea ActiveMainwin->draw #define linindex ActiveMainwin->linindex #define colindex ActiveMainwin->colindex #define corner ActiveMainwin->corner #define toplevel ActiveMainwin->toplevel #define Infoarea ActiveMainwin->info #define DrawAreaPixmap ActiveMainwin->DrawAreaPixmap #define linpixmap ActiveMainwin->LinPixmap #define colpixmap ActiveMainwin->ColPixmap #define cornerpixmap ActiveMainwin->CornerPixmap #define dpy ActiveMainwin->dpy #define screen ActiveMainwin->screen #define AMwin ActiveMainwin->draw_window #define Height ActiveMainwin->height #define Width ActiveMainwin->width int create_active_mainwin_pixmaps (int width, int height) { Height = height; Width = width; DrawAreaPixmap = createpixmap (Drawarea, width, height); setbackpix (Drawarea, DrawAreaPixmap); linpixmap = createpixmap (linindex, 40, height); colpixmap = createpixmap (colindex, width, 20); cornerpixmap = createpixmap (corner, 40, 20); setbackpix (linindex, linpixmap); setbackpix (colindex, colpixmap); setbackpix (corner, cornerpixmap); setbackpix (Drawarea, DrawAreaPixmap); return 0; } int cb_resize (int width, int height) { freepixmap (Drawarea, DrawAreaPixmap); freepixmap (linindex, linpixmap); freepixmap (colindex, colpixmap); Height = height - 20; Width = width - 40; DrawAreaPixmap = createpixmap (Drawarea, width - 40, height - 20); setbackpix (Drawarea, DrawAreaPixmap); linpixmap = createpixmap (linindex, 40, height - 20); colpixmap = createpixmap (colindex, width - 40, 20); setbackpix (linindex, linpixmap); setbackpix (colindex, colpixmap); xrepaint ("cb_resize"); return 0; } int xfit (int ii, int jj) { int ret = 0; ret = xfitcolumn (ii, jj); if (!ret) ret = xfitline (ii, jj); return ret; } int xfitcolumn (int ii, int jj) { int cwidth; int font, fontw, fonts; char *name; Cell *cell; if (AW == NULL) return -1; if (ii < 0 || ii > AW->nblin || jj < 0 || jj > AW->nbcol) return -1; cell = (Cell *) applicationcell (ii, jj, -1); if (cell == NULL) return -1; name = cell_gettext (cell); if (name == NULL) return 0; if (strlen (name) < 1) return 0; font = cell_getfont (cell); fontw = cell_getfontw (cell); fonts = cell_getfonts (cell); cwidth = gettextw (name, strlen (name), font, fontw, fonts) + 2; if (CW (AW, jj + 1) - CW (AW, jj) < cwidth) { SW (AW, jj, cwidth); } return 0; } int xfitline (int ii, int jj) { int cheight; int font, fontw, fonts; char *name; Cell *cell; if (AW == NULL) return -1; if (ii < 0 || ii > AW->nblin || jj < 0 || jj > AW->nbcol) return -1; cell = (Cell *) applicationcell (ii, jj, -1); if (cell == NULL) return -1; name = cell_gettext (cell); if (name == NULL) return 0; if (strlen (name) < 1) return 0; font = cell_getfont (cell); fontw = cell_getfontw (cell); fonts = cell_getfonts (cell); cheight = gettexth (name, strlen (name), font, fontw, fonts) + 2; if (LH (AW, ii + 1) - LH (AW, ii) < cheight) { SW (AW, ii, cheight); } return 0; } static int numover = 0; int checkwidth (char *name, int width, Cell * cell, int r, int c, int type) { int cwidth; int nchar; int i, j; int color, just, font, fontw, fonts; int delta; char *formula = NULL; Cell *cl; if (name == NULL) return width; nchar = strlen (name); if (nchar < 1) return width; color = cell_getfg (cell); just = cell_getjust (cell); font = cell_getfont (cell); fontw = cell_getfontw (cell); fonts = cell_getfonts (cell); cwidth = gettextw (name, nchar, font, fontw, fonts); if (type == 2 || type == 3) delta = CW (AW, c + 1 + numover) - CW (AW, c + 1); else delta = 0; if (cwidth > width - 2 + delta && (type != 2 && type != 3)) { i = r; j = c; cl = (Cell *) applicationcell (i, j + 1, -1); if (cl != NULL) formula = cell_getformula (cl); else formula = NULL; while (((cwidth > width - 2 + delta && formula == NULL) || (cwidth > width - 2 + delta && (type == 2 || type == 3)) ) && (width < 1000) ) { j++; if (type == 2 || type == 3) numover++; delta = CW (AW, j + 1) - CW (AW, c + 1); cl = (Cell *) applicationcell (i, j + 1, -1); if (cl != NULL) formula = cell_getformula (cl); else formula = NULL; } } return width + delta; } int xdrawstring (char *name, int x, int y, int width, int widthmax, int height, int type, Cell * cell) { int textx, texty; int cheight, cwidth; int nchar; int color, just, font, fontw, fonts; if (FS->l1 == StBatch || BatchMode) return 0; if (name == NULL) return 0; nchar = strlen (name); if (nchar < 1) return 0; font = cell_getfont (cell); fontw = cell_getfontw (cell); fonts = cell_getfonts (cell); cheight = gettexth (name, nchar, font, fontw, fonts); cwidth = gettextw (name, nchar, font, fontw, fonts); if (height < (cheight + 2)) return width; while (cwidth > widthmax - 2 && nchar > 0) { nchar--; cwidth = gettextw (name, nchar, font, fontw, fonts); } if (nchar < 1) return 0; color = cell_getfg (cell); just = cell_getjust (cell); if (type == 3) just = 0; textx = x + 1; if (just == 1) textx = x + width / 2 - cwidth / 2; if (just == 2) textx = x + width - cwidth; if (textx < x + 1) textx = x + 1; texty = y + height / 2 + cheight / 2 + 1; setfont2 (color, font, fontw, fonts); drawstring (XtDisplay (Drawarea), DrawAreaPixmap, color, textx, texty, name, nchar, CW (AW, AW->cc), LH (AW, AW->ll)); return 0; } int xdrawrrect (int x, int y, int width, int height, int type, Cell * cell) { int bg = cell_getbg (cell); int fg = cell_getfg (cell); if (FS->l1 == StBatch || BatchMode) return 0; if (bg < 0) bg = 0; if (fg < 0) fg = 5; switch (type) { case 0: { fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 0); break; } case 4: { fillrectangle (dpy, DrawAreaPixmap, 2, x, y, width, height, CW (AW, AW->cc), LH (AW, AW->ll), 0); fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 1); break; } case 7: { fillrectangle (dpy, DrawAreaPixmap, 2, x, y, width, height, 0, 0, 0); fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 0); break; } case 5: { if (bg != 0 && bg != 45) fillrectangle (dpy, DrawAreaPixmap, bg, x + 1, y + 1, width - 1, height - 1, CW (AW, AW->cc), LH (AW, AW->ll), 5); break; } case 2: { fillrectangle (dpy, DrawAreaPixmap, bg, x + 2, y + 2, width - 3, height - 3, CW (AW, AW->cc), LH (AW, AW->ll), 0); break; } case 3: { fillrectangle (dpy, DrawAreaPixmap, bg, x + 2, y + 2, width - 3, height - 3, CW (AW, AW->cc), LH (AW, AW->ll), 0); break; } case 6: { fillrectangle (dpy, DrawAreaPixmap, bg, x + 2, y + 2, width - 3, height - 3, CW (AW, AW->cc), LH (AW, AW->ll), 0); break; } } if (cell_gettop (cell)) { drawline (dpy, DrawAreaPixmap, fg, x, y, x + width, y, CW (AW, AW->cc), LH (AW, AW->ll)); } if (cell_getbot (cell)) { drawline (dpy, DrawAreaPixmap, fg, x + width, y + height, x, y + height, CW (AW, AW->cc), LH (AW, AW->ll)); } if (cell_getrig (cell)) { drawline (dpy, DrawAreaPixmap, fg, x + width, y, x + width, y + height, CW (AW, AW->cc), LH (AW, AW->ll)); } if (cell_getlef (cell)) { drawline (dpy, DrawAreaPixmap, fg, x, y, x, y + height, CW (AW, AW->cc), LH (AW, AW->ll)); } return 0; } int xdrawcursor (int pop, int selmove) { int x1, x2, y1, y2; int i, j; int d = 4; if (ActiveWorksheet == NULL) return 0; if (ActiveCell == NULL) return 0; if (FS->l1 == StBatch || FS->l1 == 0 || BatchMode) return 0; i = ActiveWorksheet->cur_r; j = ActiveWorksheet->cur_c; x1 = CW (AW, j) - CW (AW, AW->cc); y1 = LH (AW, i) - LH (AW, AW->ll); x2 = CW (AW, j + 1) - CW (AW, AW->cc); y2 = LH (AW, i + 1) - LH (AW, AW->ll); if (is_selecting ()) d = 0; setlineattributes (dpy, 1, 2, LineSolid, CapProjecting, JoinBevel); drawline (dpy, AMwin, 5, x1, y1, x2, y1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, AMwin, 5, x2 + 1, y1, x2 + 1, y2 - d, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, AMwin, 5, x2 - d, y2 + 1, x1, y2 + 1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, AMwin, 5, x1, y2 + 1, x1, y1, CW (AW, AW->cc), LH (AW, AW->ll)); { if (!is_selecting ()) { drawline (dpy, AMwin, 1, x2 - 1, y2 + 2, x2 + 2, y2 + 2, 0, 0); drawline (dpy, AMwin, 1, x2 + 2, y2 - 1, x2 + 2, y2 + 1, 0, 0); } } setlineattributes (dpy, 1, 1, LineSolid, CapButt, JoinBevel); return 0; } int xdrawlincell (int i, int j, int color) { char label[8]; int height; int top; int act = 0; int zoom = AW->zoom; if (FS->l1 == StBatch || BatchMode) return 0; if (i <= 0) return -1; if (i > ActiveWorksheet->nblin) return -1; height = (LH (AW, i + 1) - LH (AW, i)) * zoom / 100 - 1; top = (LH (AW, i) - LH (AW, AW->ll)) * zoom / 100 + 1; sprintf (label, "%d", i); desactivate_zoom (); /*haut */ drawline (XtDisplay (linindex), linpixmap, 0, 2, top, 38, top, 0, 0); if (AW != NULL) if (AW->cur_r == i) act = 1; fillrectangle (XtDisplay (linindex), linpixmap, 2, 2, top + 1, 37, height - 1, 0, 0, 0); if (act) { drawline (XtDisplay (linindex), linpixmap, 1, 2, (top + height), 38, (top + height), 0, 0); /*bas-in */ drawline (XtDisplay (linindex), linpixmap, 3, 3, (top + height) - 1, 37, (top + height) - 1, 0, 0); /*gauch */ drawline (XtDisplay (linindex), linpixmap, 0, 2, 1 + top, 2, (top + height) - 1, 0, 0); /*droi */ drawline (XtDisplay (linindex), linpixmap, 1, 39, top, 39, (top + height), 0, 0); /*droi-in */ drawline (XtDisplay (linindex), linpixmap, 3, 38, top + 1, 38, (top + height) - 1, 0, 0); /*droi-in-top */ drawline (XtDisplay (linindex), linpixmap, 2, 38, top, 38, top, 0, 0); } else { drawline (XtDisplay (linindex), linpixmap, 3, 2, (top + height), 38, (top + height), 0, 0); /*gauch */ drawline (XtDisplay (linindex), linpixmap, 2, 2, top + 1, 2, (top + height) - 1, 0, 0); /*droi */ drawline (XtDisplay (linindex), linpixmap, 3, 39, top, 39, (top + height), 0, 0); } reactivate_zoom (); setfont2 (0, 1, 0, 3); drawstring (XtDisplay (linindex), linpixmap, 1, 1 + 3 * 100 / zoom, (top + height - 4) * 100 / zoom, label, strlen (label), 0, 0); return 0; } int xdrawcolcell (int i, int j, int color) { char label[4]; int width; int left; int act = 0; int zoom = AW->zoom; if (FS->l1 == StBatch || BatchMode) return 0; if (j <= 0) return -1; if (j > ActiveWorksheet->nbcol) return -1; width = CW (AW, j + 1) - CW (AW, j); left = CW (AW, j) - CW (AW, AW->cc); if (j <= 26) { label[0] = 'A' + j - 1; label[1] = '\0'; } else { label[0] = 'A' + (j - 1) / 26 - 1; label[1] = 'A' + j - 26 * ((j - 1) / 26) - 1; label[2] = '\0'; } if (AW != NULL) if (AW->cur_c == j) act = 1; desactivate_zoom (); fillrectangle (XtDisplay (colindex), colpixmap, 2, left * zoom / 100 + 1, 2, width * zoom / 100 - 1, 17, 0, 0, 0); if (act) { drawline (XtDisplay (colindex), colpixmap, 0, left * zoom / 100 + 1, 2, left * zoom / 100 + 1, 19, 0, 0); drawline (XtDisplay (colindex), colpixmap, 1, (left + width) * zoom / 100, 2, (left + width) * zoom / 100, 19, 0, 0); drawline (XtDisplay (colindex), colpixmap, 1, left * zoom / 100 + 1, 19, (left + width) * zoom / 100 - 1, 19, 0, 0); drawline (XtDisplay (colindex), colpixmap, 0, left * zoom / 100 + 1, 2, (left + width) * zoom / 100 - 1, 2, 0, 0); drawline (XtDisplay (colindex), colpixmap, 3, left * zoom / 100 + 1, 18, (left + width) * zoom / 100 - 1, 18, 0, 0); drawline (XtDisplay (colindex), colpixmap, 2, left * zoom / 100 + 1, 18, left * zoom / 100 + 1, 18, 0, 0); drawline (XtDisplay (colindex), colpixmap, 3, (left + width) * zoom / 100 - 1, 3, (left + width) * zoom / 100 - 1, 18, 0, 0); } else { drawline (XtDisplay (colindex), colpixmap, 0, left * zoom / 100 + 1, 2, left * zoom / 100 + 1, 19, 0, 0); drawline (XtDisplay (colindex), colpixmap, 3, (left + width) * zoom / 100, 2, (left + width) * zoom / 100, 19, 0, 0); drawline (XtDisplay (colindex), colpixmap, 3, left * zoom / 100 + 1, 19, (left + width) * zoom / 100 - 1, 19, 0, 0); drawline (XtDisplay (colindex), colpixmap, 2, left * zoom / 100 + 2, 2, (left + width) * zoom / 100 - 1, 2, 0, 0); } reactivate_zoom (); setfont2 (0, 1, 0, 3); drawstring (XtDisplay (colindex), colpixmap, 1, left + width / 2 - 5, 15 * 100 / zoom, label, strlen (label), 0, 0); return 0; } int xdrawcell (int i, int j, int type, int noclear) { Cell *cell = (Cell *) applicationcell (i, j, -1); return xdrawcell2 (cell, type, noclear); } int xdrawcell2 (Cell * cell, int type, int noclear) { int left, top, width, widthmax, height; char *buf = NULL; int i, j; if (FS->l1 == StBatch || FS->l1 == 0) return 0; if (cell == NULL) return -1; i = cell->r; j = cell->c; if (type == 2) numover = 0; if (cell == NULL && (type == 4 || type == 5)) return 0; if (type == DRAW_FORCED) numover = 0; width = CW (AW, j + 1) - CW (AW, j); left = CW (AW, j) - CW (AW, AW->cc); height = LH (AW, i + 1) - LH (AW, i); top = LH (AW, i) - LH (AW, AW->ll); if (cell != NULL) buf = (char *) cell_gettext (cell); if (type == 2 && cell != NULL) buf = (char *) cell_getformula (cell); if (type == 3) { buf = (char *) GetEntryString (Letext); } widthmax = width; if (buf != NULL) { if (type == 3 || type == 2 || (cell_getrig (cell) == 0)) widthmax = checkwidth (buf, width, cell, i, j, type); if (type == 2) { left += 2; top += 2; width -= 4; height -= 4; } } xdrawrrect (left, top, widthmax, height, type, cell); if (buf != NULL) xdrawstring (buf, left, top, width, widthmax, height, type, cell); if (!noclear) cleararea (dpy, AMwin, left, top, widthmax + 1, height + 1, False); return 0; } static int i0; static int j0; static int li; static int lj; int initselectbox (int _i0, int _j0) { i0 = _i0; j0 = _j0; drawselectbox (i0, j0, i0, j0); li = i0; lj = j0; return 0; } int extendselectbox (int i, int j) { int di = i - li; int dj = j - lj; if (!(di) && !(dj)) return -1; set_visible (i, j); copypix ("extendselectbox"); drawselectbox (i0, j0, i, j); return 0; } int drawselectbox (int i1, int j1, int i2, int j2) { int x1, y1, x2, y2; double fact = 100.0 / AW->zoom; if (i2 >= i1 && j2 >= j1) { i2++; j2++; } if (i2 < i1 && j2 >= j1) { j2++; i1++; } if (i2 >= i1 && j2 < j1) { i2++; j1++; } if (i2 < i1 && j2 < j1) { i1++; j1++; } ijtoxy (i1, j1, &x1, &y1); ijtoxy (i2, j2, &x2, &y2); if (x1 < 0) x1 = 0; if (x2 < 0) x2 = 0; if (y1 < 0) y1 = 0; if (y2 < 0) y2 = 0; if (x1 > Width * fact) x1 = Width * fact; if (x2 > Width * fact) x2 = Width * fact; if (y1 > Height * fact) y1 = Height * fact; if (y2 > Height * fact) y2 = Height * fact; setlineattributes (dpy, 1, 3, LineDoubleDash, CapButt, JoinBevel); drawline (dpy, AMwin, 1, x1, y1, x2, y1, 0, 0); drawline (dpy, AMwin, 1, x2, y1, x2, y2 - 4, 0, 0); drawline (dpy, AMwin, 1, x2 - 4, y2, x1, y2, 0, 0); drawline (dpy, AMwin, 1, x1, y2, x1, y1, 0, 0); setlineattributes (dpy, 1, 3, LineSolid, CapButt, JoinBevel); drawline (dpy, AMwin, 1, x2 - 2, y2 + 2, x2 + 2, y2 + 2, 0, 0); drawline (dpy, AMwin, 1, x2 + 2, y2 - 2, x2 + 2, y2 + 4, 0, 0); setlineattributes (dpy, 1, 1, LineSolid, CapButt, JoinBevel); return 0; } int xytoij (int x, int y, int *i, int *j) { int jj = 0; int x1, x2, y1, y2; x += CW (AW, AW->cc); y += LH (AW, AW->ll); get_visible (&x1, &x2, &y1, &y2); while (x > CW (AW, jj)) { jj++; } *j = jj - 1; jj = 0; while (y > LH (AW, jj)) { jj++; } *i = jj - 1; if (*i < 1) *i = 1; if (*j < 1) *j = 1; if (*i > AW->nblin - 1) *i = AW->nblin - 1; if (*j > AW->nbcol - 1) *j = AW->nbcol - 1; if (x < x1 + CW (AW, 1)) *j = 1; if (y < y1 + LH (AW, 1)) *i = 1; return 1; } int ijtoxy (int i, int j, int *x, int *y) { if (AW == NULL) return -1; *x = CW (AW, j); *y = LH (AW, i); *x -= CW (AW, AW->cc); *y -= LH (AW, AW->ll); return 1; } int absijtoxy (int i, int j, int *x, int *y) { if (AW == NULL) return -1; *x = CW (AW, j); *y = LH (AW, i); return 1; } int xytoclotherij (int x, int y, int *i, int *j) { int jj = 0; x += CW (AW, AW->cc); y += LH (AW, AW->ll); while (x > CW (AW, jj)) { jj++; } *j = jj - 1; if (CW (AW, jj) - x < x - CW (AW, jj - 1)) *j = jj; jj = 0; while (y > LH (AW, jj)) { jj++; } *i = jj - 1; if (LH (AW, jj) - y < y - LH (AW, jj - 1)) *i = jj; if (*i < 1) *i = 1; if (*j < 1) *j = 1; if (*i > AW->nblin - 1) *i = AW->nblin - 1; if (*j > AW->nbcol - 1) *j = AW->nbcol - 1; return 1; } int get_visible (int *x1, int *x2, int *y1, int *y2) { *x1 = CW (AW, AW->cc); *y1 = LH (AW, AW->ll); *x2 = *x1 + Width * 100 / AW->zoom; *y2 = *y1 + Height * 100 / AW->zoom; return 0; } int get_visible_cells (int *i1, int *j1, int *i2, int *j2) { *i1 = AW->ll; *j1 = AW->cc; *i2 = *i1; *j2 = *j1; while (LH (AW, *i2) < LH (AW, AW->ll) + Height * 100 / AW->zoom && *i2 < AW->nblin) { (*i2)++; } while (CW (AW, *j2) < CW (AW, AW->cc) + Width * 100 / AW->zoom && *j2 < AW->nbcol) { (*j2)++; } return 0; } int resizegra () { Graph *gr; gr = (Graph *) getlastgra (); freepixmap (Drawarea, gr->pixmap); gr->pixmap = createpixmap (Drawarea, gr->w * gr->zoom / 100, gr->h * gr->zoom / 100); fillrectangle (dpy, gr->pixmap, 0, 0, 0, gr->w, gr->h, 0, 0, 0); return 0; } int redrawbt (Button * btn) { int x1, x2, y1, y2; x1 = btn->x1 - CW (AW, AW->cc); y1 = btn->y1 - LH (AW, AW->ll); x2 = btn->x2 - CW (AW, AW->cc); y2 = btn->y2 - LH (AW, AW->ll); drawbuttonup (dpy, DrawAreaPixmap, x1, y1, x2, y2, button_getlabel (btn), CW (AW, AW->cc), LH (AW, AW->ll)); return 0; } int redrawbtdown (Button * btn) { int x1, x2, y1, y2; char *label; x1 = btn->x1 - CW (AW, AW->cc); y1 = btn->y1 - LH (AW, AW->ll); x2 = btn->x2 - CW (AW, AW->cc); y2 = btn->y2 - LH (AW, AW->ll); drawline (dpy, DrawAreaPixmap, 2, x1, y1, x2 - 1, y1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 2, x1, y1, x1, y2, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x1 + 1, y1 + 1, x2 - 1, y1 + 1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x1 + 1, y1 + 2, x1 + 1, y2 - 1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x2, y1, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x1, y2, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 0, x2 - 1, y1, x2 - 1, y2 - 1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 0, x1 + 1, y2 - 1, x2 - 1, y2 - 1, CW (AW, AW->cc), LH (AW, AW->ll)); fillrectangle (dpy, DrawAreaPixmap, 2, x1 + 2, y1 + 2, x2 - x1 - 3, y2 - y1 - 3, CW (AW, AW->cc), LH (AW, AW->ll), 1); label = button_getlabel (btn); drawstring (dpy, DrawAreaPixmap, 1, x1 + 10, (y1 + y2) / 2, label, strlen (label), CW (AW, AW->cc), LH (AW, AW->ll)); return 0; } int redrawdr (Drawing * dr) { int centerx, centery, width, height, a1 = 0, a2 = 0; int pi = 90 * 64; int x1, x2, y1, y2; x1 = dr->x1 - CW (AW, AW->cc); y1 = dr->y1 - LH (AW, AW->ll); x2 = dr->x2 - CW (AW, AW->cc); y2 = dr->y2 - LH (AW, AW->ll); switch (dr->type) { case LINE: { drawline (dpy, DrawAreaPixmap, 1, x1, y1, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll)); break; } case RECT: { drawline (dpy, DrawAreaPixmap, 1, x1, y1, x2, y1, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x2, y1, x2, y2, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x2, y2, x1, y2, CW (AW, AW->cc), LH (AW, AW->ll)); drawline (dpy, DrawAreaPixmap, 1, x1, y2, x1, y1, CW (AW, AW->cc), LH (AW, AW->ll)); break; } case ARC: { centerx = x1; centery = y1; width = 2 * abs (x1 - x2); height = 2 * abs (y1 - y2); if (x1 <= x2 && y1 <= y2) { a1 = 0; a2 = pi; centery += height / 2; } if (x1 >= x2 && y1 <= y2) { a1 = -pi; a2 = pi; centerx -= width / 2; } if (x1 >= x2 && y1 >= y2) { a1 = 2 * pi; a2 = pi; centery -= height / 2; } if (x1 <= x2 && y1 >= y2) { a1 = pi; a2 = pi; centerx += width / 2; } drawarc (dpy, DrawAreaPixmap, 1, centerx - width / 2, centery - height / 2, width, height, a1, a2, CW (AW, AW->cc), LH (AW, AW->ll)); break; } case CIRCLE: { centerx = (x1 + x2) / 2; centery = (y1 + y2) / 2; width = abs (x1 - x2); height = abs (y1 - y2); drawarc (dpy, DrawAreaPixmap, 1, centerx - width / 2, centery - height / 2, width, height, 0, 360 * 64, CW (AW, AW->cc), LH (AW, AW->ll)); break; } } return 0; } Pixmap createpixmapforgraph (Graph * gr) { gr->pixmap = createpixmap (Drawarea, gr->w, gr->h); fillrectangle (dpy, gr->pixmap, 0, 0, 0, gr->w, gr->h, 0, 0, 0); return gr->pixmap; } Pixmap getpixmap (Graph * gr, int *x, int *y, int *w, int *h) { *x = gr->x; *y = gr->y; *w = gr->w; *h = gr->h; return gr->pixmap; }