📄 gcanvas.c
字号:
XTextExtents16 ( font, (XChar2b *) tlp[i].p, tlp[i].n / 2, &dir, &asc, &des, &txtinfo ); ps.x = max (ps.x, txtinfo.width), ps.y += asc + des; } *gsp = spixtodraw (widget, ps); return 0;}static XFontStruct *findfont (char *name, int size) { XFontStruct *font; int fi, n, i; if (name[0] == '\000') return Gfontp[0].font; sprintf (&Gbufp[0], name, size); for (fi = 0; fi < Gfontn; fi++) if (strcmp (&Gbufp[0], Gfontp[fi].name) == 0) return Gfontp[fi].font; if (!(font = XLoadQueryFont (Gdisplay, &Gbufp[0]))) { n = strlen (&Gbufp[0]) + 1; for (i = 1; i < size; i++) { sprintf (&Gbufp[n], name, size - i); if ((font = XLoadQueryFont (Gdisplay, &Gbufp[n]))) break; sprintf (&Gbufp[n], name, size + i); if ((font = XLoadQueryFont (Gdisplay, &Gbufp[n]))) break; } } if (!font) font = Gfontp[0].font; Gfontp = Marraygrow (Gfontp, (long) (Gfontn + 1) * FONTSIZE); Gfontp[Gfontn].name = strdup (&Gbufp[0]); Gfontp[Gfontn].font = font; Gfontn++; return font;}int GCcreatebitmap (Gwidget_t *widget, Gbitmap_t *bitmap, Gsize_t s) { if (!widget) { Gerr (POS, G_ERRNOPARENTWIDGET); return -1; } if (!bitmap) { Gerr (POS, G_ERRNOBITMAP); return -1; } if (!(bitmap->u.bmap.orig = XCreatePixmap ( Gdisplay, XtWindow (widget->w), (int) s.x, (int) s.y, Gdepth)) ) { Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } bitmap->u.bmap.scaled = 0; bitmap->scale.x = bitmap->scale.y = 1; bitmap->ctype = widget->type; bitmap->canvas = widget - &Gwidgets[0]; bitmap->size = s; return 0;}int GCdestroybitmap (Gbitmap_t *bitmap) { if (!bitmap) { Gerr (POS, G_ERRNOBITMAP); return -1; } XFreePixmap (Gdisplay, bitmap->u.bmap.orig); if (bitmap->u.bmap.scaled) XFreePixmap (Gdisplay, bitmap->u.bmap.scaled); return 0;}#define COMPDIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a))#define CDIFF(a, b) ( \ COMPDIFF (a.red, b[0]) + COMPDIFF (a.green, b[1]) + \ COMPDIFF (a.blue, b[2]) \)#define CMINMAXDIFF 20000int GCreadbitmap (Gwidget_t *widget, Gbitmap_t *bitmap, FILE *fp) { Gsize_t s; XImage *img; XColor colors[G_MAXCOLORS]; char bufp[2048]; int rgb[3]; char *s1, *s2; char c; int cmaxdiff, colori, colorn, bufn, bufi, step, x, y, k; s.x = s.y = 0; if (!widget) { Gerr (POS, G_ERRNOPARENTWIDGET); return -1; } if (!bitmap) { Gerr (POS, G_ERRNOBITMAP); return -1; } step = 0; while (step < 3) {l1: if (!fgets (bufp, 2048, fp)) { Gerr (POS, G_ERRCANNOTREADBITMAP); return -1; } s1 = &bufp[0];l2: for (; *s1 && isspace (*s1); s1++) ; if (!*s1 || *s1 == '#') goto l1; switch (step) { case 0: if (strncmp (s1, "P6", 2) != 0) { Gerr (POS, G_ERRCANNOTREADBITMAP); return -1; } step++, s1 += 2; goto l2; case 1: for (s2 = s1; *s2 && *s2 >= '0' && *s2 <= '9'; s2++) ; c = *s2, *s2 = 0; if (s2 == s1 || (s.x = atoi (s1)) <= 0) { *s2 = c, Gerr (POS, G_ERRCANNOTREADBITMAP); return -1; } *s2 = c, step++, s1 = s2; goto l2; case 2: for (s2 = s1; *s2 && *s2 >= '0' && *s2 <= '9'; s2++) ; c = *s2, *s2 = 0; if (s2 == s1 || (s.y = atoi (s1)) <= 0) { *s2 = c, Gerr (POS, G_ERRCANNOTREADBITMAP); return -1; } *s2 = c, step++, s1 = s2; goto l2; } } if (!(bitmap->u.bmap.orig = XCreatePixmap ( Gdisplay, XtWindow (widget->w), (int) s.x, (int) s.y, Gdepth ))) { Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } bitmap->u.bmap.scaled = 0; bitmap->scale.x = bitmap->scale.y = 1; bitmap->ctype = widget->type; bitmap->canvas = widget - &Gwidgets[0]; bitmap->size = s; if ((img = XCreateImage ( Gdisplay, DefaultVisual (Gdisplay, Gscreenn), Gdepth, ZPixmap, 0, NULL, (int) s.x, (int) s.y, 32, 0 )) == NULL) { XFreePixmap (Gdisplay, bitmap->u.bmap.orig); Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } if ((img->data = malloc (img->bytes_per_line * img->height)) == NULL) { XFreePixmap (Gdisplay, bitmap->u.bmap.orig); XDestroyImage (img); Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } colorn = 0; for (colori = 0; colori < G_MAXCOLORS; colori++) { if (widget->u.c->colors[colori].inuse) { colors[colorn] = widget->u.c->colors[colori].color; colorn++; } } bufi = bufn = 0; bufp[bufi] = 0; for (y = 0; y < s.y; y++) { for (x = 0; x < s.x; x++) { for (k = 0; k < 3; k++) { if (bufi == bufn) { if ((bufn = fread (bufp, 1, 2047, fp)) == 0) { XFreePixmap (Gdisplay, bitmap->u.bmap.orig); XDestroyImage (img); Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } bufi = 0; } rgb[k] = 257 * (unsigned char) bufp[bufi++]; } cmaxdiff = CMINMAXDIFF;l3: for (colori = 0; colori < colorn; colori++) if (CDIFF (colors[colori], rgb) < cmaxdiff) break; if ( colori == colorn && colorn < G_MAXCOLORS && cmaxdiff == CMINMAXDIFF ) { colors[colorn].red = rgb[0]; colors[colorn].green = rgb[1]; colors[colorn].blue = rgb[2]; if (XAllocColor (Gdisplay, widget->u.c->cmap, &colors[colorn])) colorn++; } if (colori == colorn) { cmaxdiff *= 10; goto l3; } XPutPixel (img, x, y, colors[colori].pixel); } } for (colori = 0; colori < G_MAXCOLORS && colori < colorn; colori++) { if (!widget->u.c->colors[colori].inuse) { widget->u.c->colors[colori].color = colors[colori]; widget->u.c->colors[colori].inuse = TRUE; } } XPutImage ( Gdisplay, bitmap->u.bmap.orig, widget->u.c->gc, img, 0, 0, 0, 0, (int) s.x, (int) s.y ); XDestroyImage (img); return 0;}int GCwritebitmap (Gbitmap_t *bitmap, FILE *fp) { Gwidget_t *widget; XImage *img; XColor colors[G_MAXCOLORS]; char bufp[2048]; int colori, colorn, bufi, x, y, w, h; if (!bitmap) { Gerr (POS, G_ERRNOBITMAP); return -1; } if ( bitmap->canvas < 0 || bitmap->canvas >= Gwidgetn || !Gwidgets[bitmap->canvas].inuse ) { Gerr (POS, G_ERRBADWIDGETID, bitmap->canvas); return -1; } widget = &Gwidgets[bitmap->canvas]; if (widget->type != G_CANVASWIDGET && widget->type != G_PCANVASWIDGET) { Gerr (POS, G_ERRNOTACANVAS, bitmap->canvas); return -1; } for (colori = 0, colorn = 0; colori < G_MAXCOLORS; colori++) if (widget->u.c->colors[colori].inuse) { colors[colori].pixel = widget->u.c->colors[colori].color.pixel; colorn++; } XQueryColors (Gdisplay, widget->u.c->cmap, &colors[0], colorn); if (!(img = XGetImage ( Gdisplay, bitmap->u.bmap.orig, 0, 0, bitmap->size.x, bitmap->size.y, AllPlanes, ZPixmap ))) { Gerr (POS, G_ERRNOBITMAP); return -1; } fprintf (fp, "P6\n%d %d 255\n", (int) bitmap->size.x, (int) bitmap->size.y); bufi = 0; w = bitmap->size.x; h = bitmap->size.y; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { colori = XGetPixel (img, x, y); bufp[bufi++] = colors[colori].red / 257; bufp[bufi++] = colors[colori].green / 257; bufp[bufi++] = colors[colori].blue / 257; if (bufi + 3 >= 2048) { fwrite (bufp, 1, bufi, fp); bufi = 0; } } } if (bufi > 0) fwrite (bufp, 1, bufi, fp); XDestroyImage (img); return 0;}int GCbitblt ( Gwidget_t *widget, Gpoint_t gp, Grect_t gr, Gbitmap_t *bitmap, char *mode, Ggattr_t *ap) { PIXrect_t pr; PIXpoint_t pp; Gsize_t scale; Gxy_t p; Pixmap pix; double tvx, tvy, twx, twy; if (gr.o.x > gr.c.x) p.x = gr.o.x, gr.o.x = gr.c.x, gr.c.x = p.x; if (gr.o.y > gr.c.y) p.y = gr.o.y, gr.o.y = gr.c.y, gr.c.y = p.y; if (strcmp (mode, "b2c") == 0) { if (!ISVISIBLE (gr)) return 1; tvx = WCU->vsize.x, tvy = WCU->vsize.y; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; scale.x = tvx / twx, scale.y = tvy / twy; if ( scale.x >= 1.0 - 1E-4 && scale.x <= 1.0 + 1E-4 && scale.y >= 1.0 - 1E-4 && scale.y <= 1.0 + 1E-4 ) { pix = bitmap->u.bmap.orig; bitmap->scale = scale; } else { if (scale.x != bitmap->scale.x || scale.y != bitmap->scale.y) scalebitmap (widget, bitmap, scale, TRUE, 1); pix = bitmap->u.bmap.scaled; } pr = rdrawtopix (widget, gr); pp = pdrawtobpix (bitmap, gp); setgattr (widget, ap); XCopyArea ( Gdisplay, pix, WINDOW, GC, pp.x, pp.y - pr.c.y + pr.o.y, pr.c.x - pr.o.x + 1, pr.c.y - pr.o.y + 1, pr.o.x, pr.o.y ); } else if (strcmp (mode, "c2b") == 0) { tvx = WCU->vsize.x, tvy = WCU->vsize.y; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; scale.x = tvx / twx, scale.y = tvy / twy; if ( scale.x >= 1.0 - 1E-4 && scale.x <= 1.0 + 1E-4 && scale.y >= 1.0 - 1E-4 && scale.y <= 1.0 + 1E-4 ) { pix = bitmap->u.bmap.orig; bitmap->scale = scale; } else { if (scale.x != bitmap->scale.x || scale.y != bitmap->scale.y) scalebitmap (widget, bitmap, scale, FALSE, 1); pix = bitmap->u.bmap.scaled; } pr = rdrawtobpix (bitmap, gr); pp = pdrawtopix (widget, gp); setgattr (widget, ap); XCopyArea ( Gdisplay, WINDOW, pix, GC, pp.x, pp.y - pr.c.y + pr.o.y, pr.c.x - pr.o.x + 1, pr.c.y - pr.o.y + 1, pr.o.x, pr.o.y ); if (pix != bitmap->u.bmap.orig) scalebitmap (widget, bitmap, scale, TRUE, -1); } return 0;}static int scalebitmap ( Gwidget_t *widget, Gbitmap_t *bitmap, Gsize_t scale, int copybits, int dir) { Gsize_t nsize, o2n; Pixmap spix; XImage *oimg, *simg; XColor colors[G_MAXCOLORS + 1]; int cmaxdiff, colorn, colori, x, y, x2, y2, xp, yp; double prod, rgb[3], xr2, yr2, xl2, yl2, xf2, yf2, xr, yr, xl, yl; unsigned long pixel; if (!copybits) { if (dir == 1) { nsize.x = (int) (bitmap->size.x * scale.x); nsize.y = (int) (bitmap->size.y * scale.y); if (!(spix = XCreatePixmap ( Gdisplay, XtWindow (widget->w), (int) nsize.x, (int) nsize.y, Gdepth ))) { Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } if (bitmap->u.bmap.scaled) XFreePixmap (Gdisplay, bitmap->u.bmap.scaled); bitmap->u.bmap.scaled = spix; bitmap->scale = scale; } return 0; } for (colori = 0, colorn = 0; colori < G_MAXCOLORS; colori++) if (widget->u.c->colors[colori].inuse) { colors[colori].pixel = widget->u.c->colors[colori].color.pixel; colorn++; } XQueryColors (Gdisplay, widget->u.c->cmap, &colors[0], colorn); if (dir == 1) { nsize.x = (int) (bitmap->size.x * scale.x); nsize.y = (int) (bitmap->size.y * scale.y); o2n.x = 1 / scale.x, o2n.y = 1 / scale.y; if (!(oimg = XGetImage ( Gdisplay, bitmap->u.bmap.orig, 0, 0, (int) bitmap->size.x, (int) bitmap->size.y, AllPlanes, ZPixmap ))) { Gerr (POS, G_ERRNOBITMAP); return -1; } if (!(spix = XCreatePixmap ( Gdisplay, XtWindow (widget->w), (int) nsize.x, (int) nsize.y, Gdepth ))) { XDestroyImage (oimg); Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } } else { nsize.x = (int) bitmap->size.x; nsize.y = (int) bitmap->size.y; o2n.x = scale.x, o2n.y = scale.y; if (!(oimg = XGetImage ( Gdisplay, bitmap->u.bmap.scaled, 0, 0, (int) (bitmap->size.x * scale.x), (int) (bitmap->size.y * scale.y), AllPlanes, ZPixmap ))) { Gerr (POS, G_ERRNOBITMAP); return -1; } spix = bitmap->u.bmap.orig; } prod = o2n.x * o2n.y; if (!(simg = XCreateImage ( Gdisplay, DefaultVisual (Gdisplay, Gscreenn), Gdepth, ZPixmap, 0, NULL, (int) nsize.x, (int) nsize.y, 32, 0 ))) { XFreePixmap (Gdisplay, spix); XDestroyImage (oimg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -