📄 graphic.c
字号:
int i, d1, d2, d3; /* dummies */ XCharStruct size; static char *sample = "The Quick Brown Fox Jumped Over The Lazy Dog 0123456789";#else UINT algn;#endif if (cmd->type == cTEXT3) arg2 = pop (stSTRING)->pointer; if (cmd->type == cTEXT2 || cmd->type == cTEXT3) arg1 = pop (stSTRING)->pointer; if (arg1) { if (check_alignment (arg1)) { align = arg1; } else { fontname = arg1; } } if (arg2) { if (check_alignment (arg2)) { if (align) { sprintf (string, "Found two possible alignments: '%s' and '%s'", arg1, arg2); error (ERROR, string); } align = arg2; } else { fontname = arg2; } } if (arg2 && check_alignment (arg2)) { align = arg2; if (arg1) fontname = arg1; } if (arg1 && arg2 && !align) { error (ERROR, "There should be a specification for a text alignment (e.g. 'ct')"); error (ERROR, "among the last two arguments"); return; } if (!align) align = text_align; if (fontname && !change_font (fontname)) return; text = pop (stSTRING)->pointer; y = pop (stNUMBER)->value; x = pop (stNUMBER)->value; transform (&x, &y); if (!winopened) { error (ERROR, "Got no window to draw"); return; } len = strlen (text);#ifdef UNIX XTextExtents (myfont, text, len, &d1, &d2, &d3, &size); if (align[0] == 'l') xoff = 0; else if (align[0] == 'r') xoff = -size.width; else xoff = -size.width / 2; if (align[1] == 't') yoff = fontheight; else if (align[1] == 'b') yoff = 0; else yoff = fontheight / 2; XDrawString (display, window, gc, x + xoff, y + yoff, text, len); XDrawString (display, backbit, gc, x + xoff, y + yoff, text, len); XFlush (display); if (printerfile) { for (i = 0; i < INBUFFLEN; i++) { if (*text == '(' || *text == ')') { string[i] = '\\'; i++; } string[i] = *text; if (!*text) break; text++; } if (firsttext) { firsttext = FALSE; XTextExtents (myfont, sample, strlen (sample), &d1, &d2, &d3, &size); fprintf (printerfile, "/Helvetica findfont setfont newpath 0 0 moveto\n"); fprintf (printerfile, "(%s) false charpath flattenpath pathbbox\n", sample); fprintf (printerfile, "3 -1 roll pop pop sub abs %g exch div\n", (double) psscale * size.width * 1.095 /* mysterious scaling factor ! */ ); fprintf (printerfile, "/Helvetica findfont exch scalefont setfont\n"); } fprintf (printerfile, "%g %g (%c) (%s) AT\n", x * psscale, (winheight - y - yoff) * psscale, align[0], string); }#else /* WINDOWS */ startdraw (FALSE); SelectObject (devcon, myfont); SetBkMode (devcon, TRANSPARENT); SelectObject (bitcon, myfont); SetBkMode (bitcon, TRANSPARENT); algn = 0; xoff = yoff = 0; if (align[0] == 'l') algn |= TA_LEFT; else if (align[0] == 'r') algn |= TA_RIGHT; else algn |= TA_CENTER; if (align[1] == 't') algn |= TA_TOP; else if (align[1] == 'b') algn |= TA_BOTTOM; else { algn |= TA_BOTTOM; yoff = fontheight / 2; } SetTextAlign (devcon, algn); TextOut (devcon, (int) (x + xoff), (int) (y + yoff), text, len); SetTextAlign (bitcon, algn); TextOut (bitcon, (int) (x + xoff), (int) (y + yoff), text, len); enddraw (); if (printer) { SetBkMode (printer, TRANSPARENT); SetTextAlign (printer, algn); TextOut (printer, (int) ((x + xoff) * prnscale + prnoffx), (int) ((y + yoff) * prnscale + prnoffy), text, strlen (text)); }#endif}intcheck_alignment (char *al){ /* checks, if text-alignement is valid */ if (!al[0] || !al[1]) return FALSE; al[0] = tolower ((int) al[0]); al[1] = tolower ((int) al[1]); if (!strchr ("clr", al[0]) || !strchr ("ctb", al[1])) return FALSE; else return TRUE;}voidclosewin (){ /* close the window */#ifdef UNIX int status;#endif if (!winopened) { error (WARNING, "Got no window to close"); return; } winopened = FALSE;#ifdef UNIX if (backpid > 0) { kill (backpid, SIGTERM); waitpid (backpid, &status, 0); backpid = -1; } XFreePixmap (display, backbit); XDestroyWindow (display, window); XFlush (display); if (printerfile) closeprinter ();#else /* WINDOWS */ PostThreadMessage (wtid, WM_QUIT, 0, 0);#endif}voidclearwin (){ /* clear the window */#ifdef WINDOWS RECT interior;#endif if (!winopened) { error (WARNING, "Got no window to clear"); return; }#ifdef UNIX XFillRectangle (display, window, rgc, 0, 0, winwidth, winheight); XFillRectangle (display, backbit, rgc, 0, 0, winwidth, winheight); XFlush (display); if (printerfile) { fprintf (printerfile, "showpage\n"); fflush (printerfile); }#else /* WINDOWS */ startdraw (FALSE); GetClientRect (window, &interior); FillRect (devcon, &interior, backbrush); FillRect (bitcon, &interior, backbrush); if (printer) { EndPage (printer); StartPage (printer); } enddraw ();#endif}voidmoveorigin (char *or){ /* move origin of window */ if (or == NULL) or = pop (stSTRING)->pointer; or[0] = tolower ((int) or[0]); or[1] = tolower ((int) or[1]); if (or[2] != '\0' || !strchr ("lcr", or[0]) || !strchr ("tbc", or[1])) { error (ERROR, "invalid window origin"); return; } strcpy (winorigin, or); return;}static voiditransform (int *ix, int *iy){ /* integer variant of transform() */ double dx, dy; dx = *ix; dy = *iy; transform (&dx, &dy); *ix = (int) dx; *iy = (int) dy;}static voidtransform (double *x, double *y){ /* do coordinate transformation */ double xz, yz, xd, yd; double xalt, yalt; if (infolevel >= DEBUG) { xalt = *x; yalt = *y; } switch (winorigin[0]) { case 'l': xz = 0; xd = 1.0; break; case 'c': xz = winwidth / 2; xd = 1.0; break; case 'r': xz = winwidth; xd = -1.0; break; } switch (winorigin[1]) { case 't': yz = 0; yd = 1.0; break; case 'c': yz = winheight / 2; yd = 1.0; break; case 'b': yz = winheight; yd = -1.0; break; } if (infolevel >= DEBUG) { sprintf (string, "transforming (%g,%g) into (%g,%g)", xalt, yalt, *x, *y); error (DEBUG, string); } *x = xz + (*x) * xd; *y = yz + (*y) * yd;}voidrect (struct command *cmd){ /* draw a (filled) rect */#ifdef WINDOWS RECT box, prbox;#endif int fill, clear; double x1, y1, x2, y2, s; if (!winopened) { error (ERROR, "Got no window to draw"); return; } fill = cmd->tag & dmFILL; clear = cmd->tag & dmCLEAR; y2 = pop (stNUMBER)->value; x2 = pop (stNUMBER)->value; y1 = pop (stNUMBER)->value; x1 = pop (stNUMBER)->value; transform (&x1, &y1); transform (&x2, &y2); if (x1 > x2) { s = x2; x2 = x1; x1 = s; } if (y1 > y2) { s = y2; y2 = y1; y1 = s; }#ifdef UNIX if (clear) { if (fill) { XFillRectangle (display, window, rgc, x1, y1, x2 - x1 + 1, y2 - y1 + 1); XFillRectangle (display, backbit, rgc, x1, y1, x2 - x1 + 1, y2 - y1 + 1); } else { XDrawRectangle (display, window, rgc, x1, y1, x2 - x1, y2 - y1); XDrawRectangle (display, backbit, rgc, x1, y1, x2 - x1, y2 - y1); } } else { if (fill) { XFillRectangle (display, window, gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1); XFillRectangle (display, backbit, gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1); } else { XDrawRectangle (display, window, gc, x1, y1, x2 - x1, y2 - y1); XDrawRectangle (display, backbit, gc, x1, y1, x2 - x1, y2 - y1); } } XFlush (display); if (printerfile) { fprintf (printerfile, "%g %g %g %g (%c) (%c) RE\n", x1 * psscale, (winheight - y1) * psscale, x2 * psscale, (winheight - y2) * psscale, clear ? 'y' : 'n', fill ? 'y' : 'n'); fflush (printerfile); }#else startdraw (clear); box.left = (long) x1; box.right = (long) x2 + 1; box.top = (long) y1; box.bottom = (long) y2 + 1; prbox.left = (long) (x1 * prnscale + prnoffx); prbox.right = (long) (x2 * prnscale + prnoffx); prbox.top = (long) (y1 * prnscale + prnoffy); prbox.bottom = (long) (y2 * prnscale + prnoffy); if (fill) { if (clear) FillRect (devcon, &box, backbrush); else FillRect (devcon, &box, forebrush); if (clear) FillRect (bitcon, &box, backbrush); else FillRect (bitcon, &box, forebrush); if (printer) { FillRect (printer, &prbox, GetStockObject (clear ? WHITE_BRUSH : BLACK_BRUSH)); } } else { if (clear) FrameRect (devcon, &box, backbrush); else FrameRect (devcon, &box, forebrush); if (clear) FrameRect (bitcon, &box, backbrush); else FrameRect (bitcon, &box, forebrush); if (printer) { MoveToEx (printer, prbox.left, prbox.top, NULL); LineTo (printer, prbox.left, prbox.bottom); LineTo (printer, prbox.right, prbox.bottom); LineTo (printer, prbox.right, prbox.top); LineTo (printer, prbox.left, prbox.top); } } enddraw ();#endif}voidputbit (void){ /* put rect into win */ char *mode, *pm, *bitstring, *pb; char m; int xe, ye, we, he; int x, y, xdest, ydest, w, h, n, badimage; unsigned short red, green, blue;#ifdef UNIX int should_pixel; XImage *bits = NULL; XGCValues vals;#else /* */ static COLORREF should_pixel;#endif /* */ mode = pop (stSTRING)->pointer; if (print_to_file) { error (ERROR, "Cannot bitblit to printer"); return; } if (!winopened) { error (ERROR, "Got no window to draw"); return; } for (pm = mode; *pm; pm++) *pm = tolower (*pm); if (strlen (mode) && !strncmp (mode, "solid", strlen (mode))) m = 's'; else if (strlen (mode) && !strncmp (mode, "transparent", strlen (mode))) m = 't'; else { sprintf (string, "Invalid mode for bitblit: '%s', only 'solid' and 'transparent' are allowed", mode); error (ERROR, string); } ydest = (int) pop (stNUMBER)->value; xdest = (int) pop (stNUMBER)->value; itransform (&xdest, &ydest); bitstring = pop (stSTRING)->pointer; badimage = FALSE; if (sscanf (bitstring, "rgb %d,%d:%n", &w, &h, &n) != 2) badimage = TRUE; for (pb = bitstring + n; *pb; pb++) { *pb = tolower (*pb); if (!strchr ("0123456789abcdef", *pb)) { badimage = TRUE; break; } } if (badimage || w < 0 || h < 0) { error (ERROR, "Invalid bitmap (must start with 'rgb X,Y:', where X and Y are >0)"); return; } if (xdest >= winwidth || ydest >= winheight || xdest + w < 0 || ydest + h < 0) return; xe = xdest; ye = ydest; we = w; he = h; if (xe < 0) { we += xe; xe = 0; } if (ye < 0) { he += ye; ye = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -