📄 gcanvas.c
字号:
Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } if ((simg->data = malloc (simg->bytes_per_line * simg->height)) == NULL) { XFreePixmap (Gdisplay, spix); XDestroyImage (oimg); XDestroyImage (simg); Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } y = 0; yr = o2n.y; yl = 0; y2 = yr2 = yl2 = 0; for (yp = 0; yp < nsize.y; yp++) { x = 0; xr = o2n.x; xl = 0; for (xp = 0; xp < nsize.x; xp++) { y2 = y; yr2 = yr; yl2 = yl; rgb[0] = rgb[1] = rgb[2] = 0; do { x2 = x; xr2 = xr; xl2 = xl; yf2 = (yl2 + yr2 > 1) ? 1 - yl2 : yr2, yr2 -= yf2; do { xf2 = (xl2 + xr2 > 1) ? 1 - xl2 : xr2, xr2 -= xf2; pixel = XGetPixel (oimg, x2, y2); for (colori = 0; colori < colorn; colori++) if (colors[colori].pixel == pixel) break; if (colori == colorn) { colors[colori].pixel = pixel; XQueryColor (Gdisplay, WCU->cmap, &colors[colori]); } rgb[0] += (colors[colori].red * xf2 * yf2 / prod); rgb[1] += (colors[colori].green * xf2 * yf2 / prod); rgb[2] += (colors[colori].blue * xf2 * yf2 / prod); xl2 += xf2; if (xl2 >= 1) x2++, xl2 -= 1; } while (xr2 > 0); xr2 = o2n.x; yl2 += yf2; if (yl2 >= 1) y2++, yl2 -= 1; } while (yr2 > 0); yr2 = o2n.y; cmaxdiff = CMINMAXDIFF;l4: 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 l4; } XPutPixel (simg, xp, yp, colors[colori].pixel); x = x2; xr = xr2; xl = xl2; } y = y2; yr = yr2; yl = yl2; } XPutImage ( Gdisplay, spix, widget->u.c->gc, simg, 0, 0, 0, 0, (int) nsize.x, (int) nsize.y ); XDestroyImage (simg); XDestroyImage (oimg); if (dir == 1) { if (bitmap->u.bmap.scaled) XFreePixmap (Gdisplay, bitmap->u.bmap.scaled); bitmap->u.bmap.scaled = spix; bitmap->scale = scale; } return 0;}int GCgetmousecoords (Gwidget_t *widget, Gpoint_t *gpp, int *count) { PIXpoint_t pp; Window rwin, cwin; int rx, ry, x, y; unsigned int mask; XQueryPointer (Gdisplay, WINDOW, &rwin, &cwin, &rx, &ry, &x, &y, &mask); pp.x = x, pp.y = y; *gpp = Gppixtodraw (widget, pp); *count = ( ((mask & Button1Mask) ? 1 : 0) + ((mask & Button2Mask) ? 1 : 0) + ((mask & Button3Mask) ? 1 : 0) ); return 0;}void Gcwbutaction (Widget w, XEvent *evp, char **app, unsigned int *anp) { Gwidget_t *widget; Gevent_t gev; PIXpoint_t pp; int wi, xtype, bn; widget = findwidget ((unsigned long) w, G_CANVASWIDGET); switch ((xtype = evp->type)) { case ButtonPress: case ButtonRelease: gev.type = G_MOUSE; gev.code = (xtype == ButtonPress) ? G_DOWN : G_UP; gev.data = evp->xbutton.button - Button1; if (gev.data > 4) return; pp.x = evp->xbutton.x, pp.y = evp->xbutton.y; gev.p = Gppixtodraw (widget, pp); bn = WCU->bstate[gev.data]; WCU->bstate[gev.data] = (xtype == ButtonPress) ? 1 : 0; bn = WCU->bstate[gev.data] - bn; WCU->buttonsdown += bn; Gbuttonsdown += bn; break; default: return; } wi = gev.wi = widget - &Gwidgets[0]; Gpopdownflag = FALSE; if (WCU->func) (*WCU->func) (&gev); if (Gpopdownflag) { Gpopdownflag = FALSE; if (gev.code == G_DOWN) { gev.code = G_UP; widget = &Gwidgets[wi]; WCU->bstate[gev.data] = 0; WCU->buttonsdown--; Gbuttonsdown--; if (widget->inuse && WCU->func) (*WCU->func) (&gev); } }}void Gcwkeyaction (Widget w, XEvent *evp, char **app, unsigned int *anp) { Gwidget_t *widget; Gevent_t gev; PIXpoint_t pp; Window rwin, cwin; int xtype, rx, ry, x, y; unsigned int mask; char c; widget = findwidget ((unsigned long) w, G_CANVASWIDGET); switch ((xtype = evp->type)) { case KeyPress: case KeyRelease: if (!XLookupString ((XKeyEvent *) evp, &c, 1, NULL, NULL)) return; XQueryPointer ( Gdisplay, WCU->window, &rwin, &cwin, &rx, &ry, &x, &y, &mask ); gev.type = G_KEYBD; gev.code = (xtype == KeyPress) ? G_DOWN : G_UP; gev.data = c; pp.x = x, pp.y = y; gev.p = Gppixtodraw (widget, pp); break; default: return; } gev.wi = widget - &Gwidgets[0]; Gpopdownflag = FALSE; if (WCU->func) (*WCU->func) (&gev); if (Gpopdownflag) Gpopdownflag = FALSE;}static void setgattr (Gwidget_t *widget, Ggattr_t *ap) { XGCValues gcv; XColor *cp; int color, width, mode, style, pati; double intens; if (!(ap->flags & G_GATTRCOLOR)) ap->color = WCU->defgattr.color; if (!(ap->flags & G_GATTRWIDTH)) ap->width = WCU->defgattr.width; if (!(ap->flags & G_GATTRMODE)) ap->mode = WCU->defgattr.mode; if (!(ap->flags & G_GATTRFILL)) ap->fill = WCU->defgattr.fill; if (!(ap->flags & G_GATTRSTYLE)) ap->style = WCU->defgattr.style; color = ap->color; if (color >= G_MAXCOLORS || !(WCU->colors[color].inuse)) color = 1; if (color != WCU->gattr.color) { WCU->gattr.color = color; if (ap->mode == G_XOR) XSetForeground ( Gdisplay, GC, WCU->colors[WCU->gattr.color].color.pixel ^ WCU->colors[0].color.pixel ); else XSetForeground ( Gdisplay, GC, WCU->colors[WCU->gattr.color].color.pixel ); if (Gdepth == 1) { cp = &WCU->colors[color].color; intens = ( 0.3 * cp->blue + 0.59 * cp->red + 0.11 * cp->green ) / 65535.0; pati = ( intens <= 0.0625 ) ? 16 : -16.0 * (log (intens) / 2.7725887222); XSetTile (Gdisplay, GC, WCU->grays[pati]); } } mode = ap->mode; if (mode != WCU->gattr.mode) { WCU->gattr.mode = mode; XSetFunction (Gdisplay, GC, WCU->gattr.mode); if (mode == G_XOR) XSetForeground ( Gdisplay, GC, WCU->colors[WCU->gattr.color].color.pixel ^ WCU->colors[0].color.pixel ); else XSetForeground ( Gdisplay, GC, WCU->colors[WCU->gattr.color].color.pixel ); } width = ap->width; if (width != WCU->gattr.width) { gcv.line_width = WCU->gattr.width = width; XChangeGC (Gdisplay, GC, GCLineWidth, &gcv); } WCU->gattr.fill = ap->fill; style = ap->style; if (style != WCU->gattr.style) { WCU->gattr.style = style; if (style == G_SOLID) { gcv.line_style = LineSolid; XChangeGC (Gdisplay, GC, GCLineStyle, &gcv); } else { XSetDashes (Gdisplay, GC, 0, gstyles[style], 2); gcv.line_style = LineOnOffDash; XChangeGC (Gdisplay, GC, GCLineStyle, &gcv); } }}static PIXrect_t rdrawtopix (Gwidget_t *widget, Grect_t gr) { PIXrect_t pr; double tvx, tvy, twx, twy; tvx = WCU->vsize.x - 1, tvy = WCU->vsize.y - 1; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; pr.o.x = tvx * (gr.o.x - WCU->wrect.o.x) / twx + 0.5; pr.o.y = tvy * (1.0 - (gr.c.y - WCU->wrect.o.y) / twy) + 0.5; pr.c.x = tvx * (gr.c.x - WCU->wrect.o.x) / twx + 0.5; pr.c.y = tvy * (1.0 - (gr.o.y - WCU->wrect.o.y) / twy) + 0.5; return pr;}static PIXpoint_t pdrawtopix (Gwidget_t *widget, Gpoint_t gp) { PIXpoint_t pp; double tvx, tvy, twx, twy; tvx = WCU->vsize.x - 1, tvy = WCU->vsize.y - 1; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; pp.x = tvx * (gp.x - WCU->wrect.o.x) / twx + 0.5; pp.y = tvy * (1.0 - (gp.y - WCU->wrect.o.y) / twy) + 0.5; return pp;}static PIXsize_t sdrawtopix (Gwidget_t *widget, Gsize_t gs) { PIXsize_t ps; double tvx, tvy, twx, twy; tvx = WCU->vsize.x - 1, tvy = WCU->vsize.y - 1; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; ps.x = tvx * (gs.x - 1) / twx + 1.5; ps.y = tvy * (gs.y - 1) / twy + 1.5; return ps;}static Gpoint_t Gppixtodraw (Gwidget_t *widget, PIXpoint_t pp) { Gpoint_t gp; double tvx, tvy, twx, twy; tvx = WCU->vsize.x - 1, tvy = WCU->vsize.y - 1; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; gp.x = (pp.x / tvx) * twx + WCU->wrect.o.x; gp.y = (1.0 - pp.y / tvy) * twy + WCU->wrect.o.y; return gp;}static Gsize_t spixtodraw (Gwidget_t *widget, PIXsize_t ps) { Gsize_t gs; double tvx, tvy, twx, twy; tvx = WCU->vsize.x - 1, tvy = WCU->vsize.y - 1; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; gs.x = ((ps.x - 1) / tvx) * twx + 1; gs.y = ((ps.y - 1) / tvy) * twy + 1; return gs;}static Grect_t rpixtodraw (Gwidget_t *widget, PIXrect_t pr) { Grect_t gr; double tvx, tvy, twx, twy, n; tvx = WCU->vsize.x - 1, tvy = WCU->vsize.y - 1; twx = WCU->wrect.c.x - WCU->wrect.o.x; twy = WCU->wrect.c.y - WCU->wrect.o.y; gr.o.x = (pr.o.x / tvx) * twx + WCU->wrect.o.x; gr.o.y = (1.0 - pr.c.y / tvy) * twy + WCU->wrect.o.y; gr.c.x = (pr.c.x / tvx) * twx + WCU->wrect.o.x; gr.c.y = (1.0 - pr.o.y / tvy) * twy + WCU->wrect.o.y; if (gr.o.x > gr.c.x) n = gr.o.x, gr.o.x = gr.c.x, gr.c.x = n; if (gr.o.y > gr.c.y) n = gr.o.y, gr.o.y = gr.c.y, gr.c.y = n; return gr;}static PIXrect_t rdrawtobpix (Gbitmap_t *bitmap, Grect_t gr) { PIXrect_t pr; double tvy; tvy = (bitmap->size.y - 1) * bitmap->scale.y; pr.o.x = gr.o.x + 0.5; pr.o.y = tvy - gr.c.y + 0.5; pr.c.x = gr.c.x + 0.5; pr.c.y = tvy - gr.o.y + 0.5; return pr;}static PIXpoint_t pdrawtobpix (Gbitmap_t *bitmap, Gpoint_t gp) { PIXpoint_t pp; double tvy; tvy = (bitmap->size.y - 1) * bitmap->scale.y; pp.x = gp.x + 0.5; pp.y = tvy - gp.y + 0.5; return pp;}static void adjustclip (Gwidget_t *widget) { Gwidget_t *parent; Dimension width, height, pwidth, pheight; Position x, y; PIXrect_t pr; parent = &Gwidgets[widget->pwi]; RESETARGS; ADD2ARGS (XtNx, &x); ADD2ARGS (XtNy, &y); ADD2ARGS (XtNwidth, &width); ADD2ARGS (XtNheight, &height); XtGetValues (widget->w, argp, argn); RESETARGS; ADD2ARGS (XtNwidth, &pwidth); ADD2ARGS (XtNheight, &pheight); XtGetValues (parent->w, argp, argn); pr.o.x = max (0, -x); pr.o.y = max (0, -y); pr.c.x = min (width, pr.o.x + pwidth); pr.c.y = min (height, pr.o.y + pheight); pr.c.x = max (pr.o.x, pr.c.x); pr.c.y = max (pr.o.y, pr.c.y); WCU->clip = rpixtodraw (widget, pr);#ifdef FEATURE_GMAP if (WCU->gmapmode) { GMAPwinsetsize (XtWindow (widget->w), width, height); GMAPchansetaspect (XtWindow (widget->w), width, height); }#endif}static Bool cwepredicate (Display *display, XEvent *evp, XPointer data) { if (evp->type == Expose && ((XAnyEvent *) evp)->window == (Window) data) return True; return False;}static void cweventhandler ( Widget w, XtPointer data, XEvent *evp, Boolean *cont) { Gwidget_t *widget; widget = findwidget ((unsigned long) w, G_CANVASWIDGET); Gneedredraw = WCU->needredraw = TRUE; adjustclip (widget);#ifdef FEATURE_GMAP if (WCU->gmapmode) GMAPneedupdate = TRUE;#endif}static Bool cwvpredicate (Display *display, XEvent *evp, XPointer data) { if ( evp->type == VisibilityNotify && ((XAnyEvent *) evp)->window == (Window) data ) return True; return False;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -