/******************************************************************** 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 #include #include #include #include #include "memory.h" #include "gr_interf.h" #include "scale.h" #include "fig.h" #include "gr_interf_decl.h" extern int BatchMode; #define SCREEN 0 #define PRINTER 1 #define FIG 2 static int output = 0; static int px0, py0; static int pxscale, pyscale; static Pixmap Pixmaps[50]; static int nPixmap = 0; static int nfreepix = 0; static int freepix[50]; static Display *Dpy; static Window Win; static int screen; static Visual *Vis; static int D; static GC TheGc; GC getTheGc () { return TheGc; }; typedef struct { Pixel foreground; Pixel background; XFontStruct *font; int ncol; Boolean showsize; } res_data, *res_data_ptr; static res_data res; static XtResource application_resources[] = { {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), XtOffset (res_data_ptr, foreground), XtRString, "Black"}, {XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel), XtOffset (res_data_ptr, background), XtRString, "#C000C000C000"}, {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *), XtOffset (res_data_ptr, font), XtRString, "Fixed"}, }; int setzoom (z) int z; { grz = z; return 0; } int getzoom () { return grz; } static int grzbak; int desactivate_zoom () { grzbak = grz; grz = 100; return 0; } int reactivate_zoom () { grz = grzbak; return 0; } int setXparam (dpy, win, toplevel) Display *dpy; Window win; Widget toplevel; { XGCValues gcv; XGCValues gcvr; int i, j, k; if (BatchMode) return 0; Dpy = dpy; Win = win; screen = DefaultScreen (Dpy); Vis = DefaultVisual (Dpy, screen); D = DefaultDepth (Dpy, screen); parse_color (win); XtGetApplicationResources (toplevel, &res, application_resources, XtNumber (application_resources), NULL, 0); gcv.foreground = res.foreground; gcv.background = res.background; gcv.font = res.font->fid; gcvr.foreground = res.background; gcvr.background = res.foreground; gcvr.font = res.font->fid; TheGc = XCreateGC (Dpy, Win, (GCFont | GCForeground | GCBackground), &gcv); for (i = 0; i < 5; i++) for (j = 0; j < 4; j++) for (k = 0; k < 7; k++) allfont[i][j][k] = 0; return 0; } char * parse_GetR (db, resource) XrmDatabase db; char *resource; { char name[16], class[128], *rc; strcpy (name, Name); strcat (name, resource); strcpy (class, Class); strcat (class, resource); rc = XrmGetResource (db, name, class, type, &value) ? (char *) value.addr : (char *) 0; return (rc); } int parse_color (Window win) { unsigned long black = BlackPixel (Dpy, screen) /* , white = WhitePixel(Dpy, screen) */ ; char color[128], *v; XColor xcolor; Colormap cmap; int depth; double intensity = -1; int i, n; XColor *cols = NULL; unsigned int ncols = 0; depth = DefaultDepth (Dpy, screen); cmap = DefaultColormap (Dpy, screen); ncols = Vis->map_entries; cols = (XColor *) absmalloc (ncols * sizeof (XColor), "cols"); for (i = 0; i < ncols; ++i) cols[i].pixel = i; XQueryColors (Dpy, cmap, cols, ncols); for (n = 0; n < Ncolors; n++) { v = color_values[n]; if (sscanf (v, "%30[^,],%lf", color, &intensity) == 2) { if (intensity < 0 || intensity > 1) { fprintf (stderr, "\ninvalid color intensity in '%s'\n", color); intensity = 1; } } else { strcpy (color, v); intensity = 1; } if (!XParseColor (Dpy, cmap, color, &xcolor)) { fprintf (stderr, "\nunable to parse '%s'. using black.\n", color); colors[n] = black; } else { xcolor.red *= intensity; xcolor.green *= intensity; xcolor.blue *= intensity; if (XAllocColor (Dpy, cmap, &xcolor)) { colors[n] = xcolor.pixel; } else { #define COLOR_FACTOR 3 #define BRIGHTNESS_FACTOR 1 int closeness = 1e9; int alternative = 0; int c; for (i = 0; i < ncols; i++) { c = COLOR_FACTOR * (abs ((long) xcolor.red - (long) cols[i].red) + abs ((long) xcolor.green - (long) cols[i].green) + abs ((long) xcolor.blue - (long) cols[i].blue)) + BRIGHTNESS_FACTOR * abs (((long) xcolor.red + (long) xcolor.green + (long) xcolor.blue) - ((long) cols[i].red + (long) cols[i].green + (long) cols[i].blue)); if (c < closeness) { closeness = c; alternative = i; } } colors[n] = cols[alternative].pixel; } } } absfree (cols, "cols"); return 0; } Pixmap createpixmap (w, width, height) Widget w; int width, height; { int locpix; if (nfreepix) { nfreepix--; locpix = freepix[nfreepix]; } else { locpix = nPixmap; nPixmap++; } if (locpix == 49) { fprintf (stderr, "create pix: no more pixmaps"); return Pixmaps[49]; } if (width <= 0 || width > 10000) width = 1; if (height <= 0 || height > 10000) height = 1; Pixmaps[locpix] = XCreatePixmap (XtDisplay (w), XtWindow (w), width, height, D); return Pixmaps[locpix]; } int freepixmap (w, pixmap) Widget w; Pixmap pixmap; { int i = 0; while (i < 50 && pixmap != Pixmaps[i]) i++; if (i > 49) return -1; freepix[nfreepix] = i; nfreepix++; XFreePixmap (XtDisplay (w), pixmap); return 0; } int createpixgc (w, pixmap) Widget w; Pixmap pixmap; { return 0; } int setbackpix (w, pixmap) Widget w; Pixmap pixmap; { XSetWindowBackgroundPixmap (XtDisplay (w), XtWindow (w), pixmap); return 0; } int copyarea (pix1, pix2, ngc, x1, y1, w, h, x2, y2) Pixmap pix1, pix2; int ngc, x1, y1, w, h, x2, y2; { if (BatchMode) return 0; XCopyArea (Dpy, pix1, pix2, TheGc, x1, y1, w, h, x2, y2); return 0; } int clearnflush () { if (BatchMode) return 0; XClearWindow (Dpy, Win); XFlush (Dpy); return 0; } int clearwin (w) Widget w; { if (BatchMode) return 0; XClearWindow (XtDisplay (w), XtWindow (w)); return 0; } static Pixel fgpix, bgpix; Pixel getcolor (int col) { return colors[col]; } int setforeground (ngc, ncol) int ngc; int ncol; { if (!BatchMode) XSetForeground (Dpy, TheGc, colors[ncol]); fgpix = colors[ncol]; if (output) { FIG_setcol (ncol); } return 0; } int setbackground (ngc, ncol) int ngc; int ncol; { if (!BatchMode) XSetBackground (Dpy, TheGc, colors[ncol]); bgpix = colors[ncol]; return 0; } Pixel getforeground () { return fgpix; } Pixel getbackground () { return bgpix; } int setfont (ngc, fontname) int ngc; String fontname; { int num_fonts; char **buf; if (BatchMode) return 0; buf = XListFonts (Dpy, fontname, 1000, &num_fonts); if (num_fonts) XSetFont (Dpy, TheGc, XLoadFont (Dpy, buf[0])); return 0; } int parse_font (i, j, k) int i, j, k; { char **buf; char fontname[128]; int num_fonts; char italic[2]; if (BatchMode) return 0; switch (i) { case 0: { sprintf (fontname, "-*-fixed-"); strcpy (italic, "i"); break; }; case 1: { sprintf (fontname, "-*-courier-"); strcpy (italic, "o"); break; }; case 2: { sprintf (fontname, "-*-helv*-"); strcpy (italic, "o"); break; }; case 3: { sprintf (fontname, "-*-times-"); strcpy (italic, "i"); break; }; case 4: { sprintf (fontname, "-*-symb*-"); strcpy (italic, "i"); break; }; } switch (j) { case 0: { sprintf (fontname, "%smedium-r-*-*-*-", fontname); break; }; case 1: { sprintf (fontname, "%sbold-r-*-*-*-", fontname); break; }; case 2: { sprintf (fontname, "%smedium-%1s-*-*-*-", fontname, italic); break; }; case 3: { sprintf (fontname, "%sbold-%1s-*-*-*-", fontname, italic); break; }; } switch (k) { case 0: { sprintf (fontname, "%s60-*", fontname); break; }; case 1: { sprintf (fontname, "%s80-*", fontname); break; }; case 2: { sprintf (fontname, "%s100-*", fontname); break; }; case 3: { sprintf (fontname, "%s120-*", fontname); break; }; case 4: { sprintf (fontname, "%s140-*", fontname); break; }; case 5: { sprintf (fontname, "%s180-*", fontname); break; }; case 6: { sprintf (fontname, "%s240-*", fontname); break; }; } buf = XListFonts (Dpy, fontname, 1, &num_fonts); if (num_fonts < 1) printf ("Warning! nomatch for fontname:%s \n", fontname); if (num_fonts >= 1) allfont[i][j][k] = XLoadFont (Dpy, buf[0]); else { allfont[i][j][k] = res.font->fid; if (j == 1 || j == 2) allfont[i][j][k] = allfont[i][0][k]; if (j == 3 && allfont[i][1][k] != res.font->fid) allfont[i][j][k] = allfont[i][1][k]; if (j == 3 && allfont[i][2][k] != res.font->fid) allfont[i][j][k] = allfont[i][2][k]; } allfontstr[i][j][k] = XQueryFont (Dpy, allfont[i][j][k]); XFreeFontNames (buf); return 0; } static int activefont = 2; static int activefontw = 0; static int activefonts = 3; int setfont2 (ngc, font, fontw, fonts) int ngc; int font, fontw, fonts; { if (font < 0 || fontw < 0 || fonts < 0 || font > 4 || fontw > 3 || fonts > 6) return -1; if (activefont == font && activefontw == fontw && activefonts == fonts) return 0; activefont = font; activefontw = fontw; activefonts = fonts; if (allfont[font][fontw][fonts] == 0) parse_font (font, fontw, fonts); if (!BatchMode && allfont[font][fontw][fonts] != 0) XSetFont (Dpy, TheGc, allfont[font][fontw][fonts]); if (output) { FIG_setfont (font, fontw, fonts); } return 0; } XFontStruct * font2fontstr (int font, int fontw, int fonts) { setfont2 (1, font, fontw, fonts); return allfontstr[activefont][activefontw][activefonts]; } int setdashes (dpy, ngc, DashOffset, DashList, Number) Display *dpy; int ngc; int DashOffset; char DashList[]; int Number; { if (BatchMode) return 0; XSetDashes (dpy, TheGc, DashOffset, DashList, Number); return 0; } int setlineattributes (dpy, ngc, LineWidth, LineStyle, CapStyle, JoinStyle) Display *dpy; int ngc; unsigned int LineWidth; int LineStyle; int CapStyle; int JoinStyle; { if (BatchMode) return 0; XSetLineAttributes (dpy, TheGc, LineWidth, LineStyle, CapStyle, JoinStyle); return 0; } int setfillstyle (dpy, ngc, FillStyle) Display *dpy; int ngc; int FillStyle; { if (BatchMode) return 0; XSetFillStyle (dpy, TheGc, FillStyle); return 0; } int setstipple (dpy, ngc, Stipple) Display *dpy; int ngc; Pixmap Stipple; { if (BatchMode) return 0; XSetStipple (dpy, TheGc, Stipple); return 0; } int gettexth (name, nchar, font, fontw, fonts) char *name; int nchar, font, fontw, fonts; { XCharStruct overall; int ascent, descent, direction; if (BatchMode) return 0; if (allfont[font][fontw][fonts] == 0) parse_font (font, fontw, fonts); if (allfont[font][fontw][fonts] == 0) return 10; XTextExtents (allfontstr[font][fontw][fonts], name, nchar, &direction, &ascent, &descent, &overall); return overall.ascent + overall.descent; } int gettextw (name, nchar, font, fontw, fonts) char *name; int nchar, font, fontw, fonts; { XCharStruct overall; int ascent, descent, direction; if (BatchMode) return 0; if (allfont[font][fontw][fonts] == 0) parse_font (font, fontw, fonts); if (allfont[font][fontw][fonts] == 0) { fprintf (stderr, "gettextw: problem with font allocation..."); return 10; } overall.width = 0; XTextExtents (allfontstr[font][fontw][fonts], name, nchar, &direction, &ascent, &descent, &overall); return overall.width; } int setout (ppstate, ppxscale, ppyscale, ppx0, ppy0) int ppstate, ppxscale, ppyscale, ppx0, ppy0; { pxscale = ppxscale; pyscale = ppyscale; px0 = ppx0; py0 = ppy0; output = ppstate; return 0; } int drawline (dpy, pixmap, ngc, x1, y1, x2, y2, x0, y0) Display *dpy; Pixmap pixmap; int ngc; int x1, y1, x2, y2, x0, y0; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; x2 = (x2 + x0 - px0) * pxscale; y2 = (y2 + y0 - py0) * pyscale; if (output == 1) { } else { FIG_setcol (ngc); FIG_line (x1, y1, x2, y2); } } else { if (BatchMode) return 0; if (grz != 100) { x1 = x1 * grz / 100; y1 = y1 * grz / 100; x2 = x2 * grz / 100; y2 = y2 * grz / 100; } return XDrawLine (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, x2, y2); } return 0; } int drawlines (dpy, pixmap, ngc, points, nb, mode, x0, y0) Display *dpy; Pixmap pixmap; int ngc; XPoint *points; int nb, mode; int x0, y0; { int x1, y1, x2, y2, i; if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output && nb > 0) { FIG_setcol (ngc); x1 = (points[0].x + x0 - px0) * pxscale; y1 = (points[0].y + y0 - py0) * pyscale; for (i = 1; i < nb; i++) { x2 = x1 + (points[i].x) * pxscale; y2 = y1 + (points[i].y) * pyscale; FIG_line (x1, y1, x2, y2); x1 = x2; y1 = y2; } } else { if (BatchMode) return 0; if (grz != 100) { for (i = 0; i < nb; i++) { points[i].x = points[i].x * grz / 100; points[i].y = points[i].y * grz / 100; } } return XDrawLines (dpy, pixmap, TheGc /*[ngc] */ , points, nb, mode); } return 0; } int drawimagestring (dpy, pixmap, ngc, x1, y1, name, nchar, x0, y0) Display *dpy; Pixmap pixmap; int ngc; int x1, y1; char *name; int nchar; int x0, y0; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; if (output == 1) { } else { FIG_setcol (ngc); FIG_put_text (x1, y1, name); } } else { if (BatchMode) return 0; if (grz != 100) { double scale = grz; x1 = x1 * grz / 100; y1 = y1 * grz / 100; i18n_draw_string (dpy, pixmap, TheGc, x1, y1, name, nchar, 1, 1, scale); return 0; } return XDrawImageString (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, name, nchar); } return 0; } int drawstring (dpy, pixmap, ngc, x1, y1, name, nchar, x0, y0) Display *dpy; Pixmap pixmap; int ngc; char *name; int nchar; int x1, y1, x0, y0; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; if (output == 1) { } else { FIG_setcol (ngc); FIG_put_text (x1, y1, name); } } else { if (BatchMode) return 0; if (grz != 100) { double scale = grz; x1 = x1 * grz / 100; y1 = y1 * grz / 100; i18n_draw_string (dpy, pixmap, TheGc, x1, y1, name, nchar, 1, 1, scale); return 0; } return XDrawString (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, name, nchar); } return 0; } int drawrectangle (dpy, pixmap, ngc, x1, y1, w, h, x0, y0) Display *dpy; Pixmap pixmap; int ngc; int x1, y1, w, h, x0, y0; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; w = w * pxscale; h = h * pyscale; if (output == 1) { } else { FIG_setcol (ngc); FIG_rectangle (x1, y1, w, h); } } else { if (BatchMode) return 0; if (grz != 100) { x1 = x1 * grz / 100; y1 = y1 * grz / 100; w = w * grz / 100; h = h * grz / 100; } return XDrawRectangle (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h); } return 0; } int drawarc (dpy, pixmap, ngc, x1, y1, w, h, a1, a2, x0, y0) Display *dpy; Pixmap pixmap; int ngc; int x1, y1, w, h, x0, y0; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; w = w * pxscale; h = h * pyscale; FIG_setcol (ngc); FIG_arc (x1, y1, w, h, a1, a2); } else { if (BatchMode) return 0; if (grz != 100) { x1 = x1 * grz / 100; y1 = y1 * grz / 100; w = w * grz / 100; h = h * grz / 100; } return XDrawArc (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h, a1, a2); } return 0; } int fillarc (dpy, pixmap, ngc, x1, y1, w, h, a1, a2, x0, y0) Display *dpy; Pixmap pixmap; int ngc; int x1, y1, w, h, x0, y0; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; w = w * pxscale; h = h * pyscale; FIG_setcol (ngc); FIG_fillarc (x1, y1, w, h, a1, a2); } else { if (BatchMode) return 0; if (grz != 100) { x1 = x1 * grz / 100; y1 = y1 * grz / 100; w = w * grz / 100; h = h * grz / 100; } return XFillArc (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h, a1, a2); } return 0; } int fillrectangle (dpy, pixmap, ngc, x1, y1, w, h, x0, y0, doprint) Display *dpy; Pixmap pixmap; int ngc; int x1, y1, w, h, x0, y0; int doprint; { if (ngc < 0 || ngc > 45) ngc = 1; setforeground (0, ngc); if (output && doprint) { if (doprint > 0) { x1 = (x1 + x0 - px0) * pxscale; y1 = (y1 + y0 - py0) * pyscale; w = w * pxscale; h = h * pyscale; FIG_setcol (ngc); FIG_fillrectangle (x1, y1, w, h, doprint); } } else { if (BatchMode) return 0; if (grz != 100) { x1 = x1 * grz / 100; y1 = y1 * grz / 100; w = w * grz / 100; h = h * grz / 100; } return XFillRectangle (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h); } return 0; } int cleararea (Display * dpy, Pixmap pixmap, int x, int y, int w, int h, Boolean yes) { if (BatchMode) return 0; if (grz != 100) { x = x * grz / 100; y = y * grz / 100; w = w * grz / 100; h = h * grz / 100; } XClearArea (dpy, pixmap, x, y, w, h, yes); return 0; } int drawbuttonup (Display * dpy, Pixmap pixmap, int x1, int y1, int x2, int y2, char *label, int X0, int Y0) { drawline (dpy, pixmap, 2, x1, y1, x2 - 1, y1, X0, Y0); drawline (dpy, pixmap, 2, x1, y1, x1, y2, X0, Y0); drawline (dpy, pixmap, 0, x1 + 1, y1 + 1, x2 - 1, y1 + 1, X0, Y0); drawline (dpy, pixmap, 0, x1 + 1, y1 + 2, x1 + 1, y2 - 1, X0, Y0); drawline (dpy, pixmap, 1, x2, y1, x2, y2, X0, Y0); drawline (dpy, pixmap, 1, x1, y2, x2, y2, X0, Y0); drawline (dpy, pixmap, 3, x2 - 1, y1, x2 - 1, y2 - 1, X0, Y0); drawline (dpy, pixmap, 3, x1 + 1, y2 - 1, x2 - 1, y2 - 1, X0, Y0); fillrectangle (dpy, pixmap, 2, x1 + 2, y1 + 2, x2 - x1 - 3, y2 - y1 - 3, X0, Y0, 1); if (label != NULL) if (strlen (label) > 0) drawstring (dpy, pixmap, 1, x1 + 10, (y1 + y2) / 2, label, strlen (label), X0, Y0); return 0; }