⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gcanvas.c

📁 Graphviz - Graph Drawing Programs from AT&T Research and Lucent Bell Labs See doc/build.html for
💻 C
📖 第 1 页 / 共 4 页
字号:
            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 + -