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

📄 gcanvas.c

📁 Graphviz - Graph Drawing Programs from AT&T Research and Lucent Bell Labs See doc/build.html for
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Id: gcanvas.c,v 1.4 2005/11/08 17:21:46 ellson Exp $ $Revision: 1.4 $ */ /* vim:set shiftwidth=4 ts=8: *//***********************************************************      This software is part of the graphviz package      **                http://www.graphviz.org/                 **                                                         **            Copyright (c) 1994-2004 AT&T Corp.           **                and is licensed under the                **            Common Public License, Version 1.0           **                      by AT&T Corp.                      **                                                         **        Information and Software Systems Research        **              AT&T Research, Florham Park NJ             ***********************************************************//* Lefteris Koutsofios - AT&T Labs Research */#include "common.h"#include "g.h"#include "gcommon.h"#include "mem.h"#ifdef FEATURE_GMAP#include <gmap.h>#endif#define WCU widget->u.c#define WINDOW widget->u.c->window#define GC widget->u.c->gc#define ISVISIBLE(r) ( \    (r.o.x <= WCU->clip.c.x) && (r.c.x >= WCU->clip.o.x) && \    (r.o.y <= WCU->clip.c.y) && (r.c.y >= WCU->clip.o.y) \)#define IS8BIT(font) ((font)->min_byte1 == 0 && (font)->max_byte1 == 0)static struct cursormap_t {    Cursor id;    char name[40];} cursormap[XC_num_glyphs];static int curcursori = -1;#define max(a, b) (((a) >= (b)) ? (a) : (b))#define min(a, b) (((a) <= (b)) ? (a) : (b))static char gstyles[][2] = {    /* G_SOLID */       { 16,  0, },    /* G_DASHED */      {  4,  4, },    /* G_DOTTED */      {  2,  2, },    /* G_LONGDASHED */  {  4, 12, },    /* G_SHORTDASHED */ { 12,  4, },};static char grays[][4] = {    { 0x00,0x00,0x00,0x00, },    { 0x08,0x00,0x00,0x00, },    { 0x08,0x00,0x02,0x00, },    { 0x0A,0x00,0x02,0x00, },    { 0x0A,0x00,0x0A,0x00, },    { 0x0A,0x04,0x0A,0x00, },    { 0x0A,0x04,0x0A,0x01, },    { 0x0A,0x05,0x0A,0x01, },    { 0x0A,0x05,0x0A,0x05, },    { 0x0E,0x05,0x0A,0x05, },    { 0x0E,0x05,0x0B,0x05, },    { 0x0F,0x05,0x0B,0x05, },    { 0x0F,0x05,0x0F,0x05, },    { 0x0F,0x0D,0x0F,0x05, },    { 0x0F,0x0D,0x0F,0x07, },    { 0x0F,0x0F,0x0F,0x07, },    { 0x0F,0x0F,0x0F,0x0F, },};static void bezier (PIXpoint_t, PIXpoint_t, PIXpoint_t, PIXpoint_t);static XFontStruct *findfont (char *, int);static int scalebitmap (Gwidget_t *, Gbitmap_t *, Gsize_t, int, int);static void setgattr (Gwidget_t *, Ggattr_t *);static PIXrect_t  rdrawtopix (Gwidget_t *, Grect_t);static PIXpoint_t pdrawtopix (Gwidget_t *, Gpoint_t);static PIXsize_t  sdrawtopix (Gwidget_t *, Gsize_t);static Gpoint_t   Gppixtodraw (Gwidget_t *, PIXpoint_t);static Gsize_t    spixtodraw (Gwidget_t *, PIXsize_t);static Grect_t    rpixtodraw (Gwidget_t *, PIXrect_t);static PIXrect_t  rdrawtobpix (Gbitmap_t *, Grect_t);static PIXpoint_t pdrawtobpix (Gbitmap_t *, Gpoint_t);static void       adjustclip (Gwidget_t *);static Bool cwvpredicate (Display *, XEvent *, XPointer);static void cweventhandler (Widget, XtPointer, XEvent *, Boolean *);static Bool cwepredicate (Display *, XEvent *, XPointer);int GCcreatewidget (    Gwidget_t *parent, Gwidget_t *widget, int attrn, Gwattr_t *attrp) {    PIXsize_t ps;    Dimension width, height;#ifdef FEATURE_BACKINGSTORE    XSetWindowAttributes xswa;#endif    XEvent ev;    XColor *cp;    XGCValues gcv;    int curi, color, ai, r, g, b, i;#ifdef FEATURE_GMAP    XVisualInfo *vip;    int gmapmode = FALSE;#endif    if (!parent) {        Gerr (POS, G_ERRNOPARENTWIDGET);        return -1;    }    WCU->func = NULL;    WCU->needredraw = FALSE;    WCU->buttonsdown = 0;    WCU->bstate[0] = WCU->bstate[1] = WCU->bstate[2] = 0;    WCU->bstate[3] = WCU->bstate[4] = 0;    ps.x = ps.y = MINCWSIZE;    RESETARGS;    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRSIZE:            GETSIZE (attrp[ai].u.s, ps, MINCWSIZE);            break;        case G_ATTRBORDERWIDTH:            ADD2ARGS (XtNborderWidth, attrp[ai].u.i);            break;#ifdef FEATURE_GMAP        case G_ATTRMODE:            if (strcmp ("gmap", attrp[ai].u.t) == 0) {                gmapmode = TRUE;            } else {                Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);                return -1;            }            break;#endif        case G_ATTRCURSOR:            /* will do it after the widget is created */            break;        case G_ATTRCOLOR:            /* will do it after the widget is created */            break;        case G_ATTRVIEWPORT:            /* will do it after the widget is created */            break;        case G_ATTRWINDOW:            /* will do it after the widget is created */            break;        case G_ATTRWINDOWID:            Gerr (POS, G_ERRCANNOTSETATTR1, "windowid");            return -1;        case G_ATTREVENTCB:            WCU->func = (Gcanvascb) attrp[ai].u.func;            break;        case G_ATTRUSERDATA:            widget->udata = attrp[ai].u.u;            break;        default:            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);            return -1;        }    }    ADD2ARGS (XtNwidth, ps.x);    ADD2ARGS (XtNheight, ps.y);#ifdef FEATURE_GMAP    if (gmapmode) {        vip = pfChooseFBConfig (Gdisplay, -1, NULL);        ADD2ARGS (GLwNvisualInfo, vip);        if (!(widget->w = XtCreateWidget (            "graphics", glwDrawingAreaWidgetClass, parent->w, argp, argn        ))) {            Gerr (POS, G_ERRCANNOTCREATEWIDGET);            return -1;        }    } else {        if (!(widget->w = XtCreateWidget (            "graphics", coreWidgetClass, parent->w, argp, argn        ))) {            Gerr (POS, G_ERRCANNOTCREATEWIDGET);            return -1;        }    }    WCU->gmapmode = gmapmode;#else    if (!(widget->w = XtCreateWidget (        "graphics", coreWidgetClass, parent->w, argp, argn    ))) {        Gerr (POS, G_ERRCANNOTCREATEWIDGET);        return -1;    }#endif    XtOverrideTranslations (widget->w, Gcwanytable);    XtAddEventHandler (        widget->w, VisibilityChangeMask | ExposureMask,        FALSE, cweventhandler, NULL    );    Glazymanage (widget->w);    Gflushlazyq ();#ifdef FEATURE_BACKINGSTORE    xswa.backing_store = WhenMapped;    XChangeWindowAttributes (        Gdisplay, XtWindow (widget->w), CWBackingStore, &xswa    );#endif    /* wait for window to become visible */    XPeekIfEvent (Gdisplay, &ev, cwvpredicate, (XPointer) XtWindow (widget->w));    RESETARGS;    ADD2ARGS (XtNwidth, &width);    ADD2ARGS (XtNheight, &height);    XtGetValues (widget->w, argp, argn);    ps.x = width, ps.y = height;    WCU->window = XtWindow (widget->w);    WCU->cmap = DefaultColormap (Gdisplay, Gscreenn);    WCU->gc = XCreateGC (Gdisplay, WCU->window, 0, NULL);    RESETARGS;    WCU->colors[0].color.pixel = WCU->colors[1].color.pixel = 1000000;    ADD2ARGS (XtNbackground, &WCU->colors[0].color.pixel);    ADD2ARGS (XtNforeground, &WCU->colors[1].color.pixel);    XtGetValues (widget->w, argp, argn);    if (WCU->colors[0].color.pixel == 1000000) {        if (XGetGCValues (Gdisplay, GC, GCBackground, &gcv) != 0)            WCU->colors[0].color.pixel = gcv.background;        else            WCU->colors[0].color.pixel = WhitePixel (Gdisplay, Gscreenn);    }    if (WCU->colors[1].color.pixel == 1000000) {        if (XGetGCValues (Gdisplay, GC, GCForeground, &gcv) != 0)            WCU->colors[1].color.pixel = gcv.foreground;        else            WCU->colors[1].color.pixel = BlackPixel (Gdisplay, Gscreenn);    }    XQueryColor (Gdisplay, WCU->cmap, &WCU->colors[0].color);    WCU->colors[0].inuse = TRUE;    XQueryColor (Gdisplay, WCU->cmap, &WCU->colors[1].color);    WCU->colors[1].inuse = TRUE;    WCU->allocedcolor[0] = WCU->allocedcolor[1] = FALSE;    for (i = 2; i < G_MAXCOLORS; i++)        WCU->colors[i].inuse = FALSE;    WCU->gattr.color = 1;    XSetBackground (Gdisplay, GC, WCU->colors[0].color.pixel);    XSetForeground (Gdisplay, GC, WCU->colors[1].color.pixel);    WCU->gattr.width = 0;    WCU->gattr.mode = G_SRC;    WCU->gattr.fill = 0;    WCU->gattr.style = 0;    WCU->defgattr = WCU->gattr;    WCU->font = NULL;    WCU->wrect.o.x = 0.0, WCU->wrect.o.y = 0.0;    WCU->wrect.c.x = 1.0, WCU->wrect.c.y = 1.0;    WCU->vsize.x = ps.x, WCU->vsize.y = ps.y;    if (Gdepth == 1) {        XSetFillStyle (Gdisplay, GC, FillTiled);        for (i = 0; i < 17; i++)            WCU->grays[i] = XCreatePixmapFromBitmapData (                Gdisplay, WCU->window, &grays[i][0], 4, 4,                BlackPixel (Gdisplay, Gscreenn),                WhitePixel (Gdisplay, Gscreenn), 1            );    }    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRCURSOR:            if ((curi = XmuCursorNameToIndex (attrp[ai].u.t)) == -1) {                if (strcmp (attrp[ai].u.t, "default") == 0) {                    XUndefineCursor (Gdisplay, XtWindow (widget->w));                    curcursori = -1;                } else {                    Gerr (POS, G_ERRNOSUCHCURSOR, attrp[ai].u.t);                    return -1;                }            } else {                if (!cursormap[curi].id) {                    cursormap[curi].id = XCreateFontCursor (Gdisplay, curi);                    strcpy (cursormap[curi].name, attrp[ai].u.t);                }                XDefineCursor (                    Gdisplay, XtWindow (widget->w), cursormap[curi].id                );                curcursori = curi;            }            break;        case G_ATTRCOLOR:            color = attrp[ai].u.c.index;            if (color < 0 || color > G_MAXCOLORS) {                Gerr (POS, G_ERRBADCOLORINDEX, color);                return -1;            }            r = attrp[ai].u.c.r * 257;            g = attrp[ai].u.c.g * 257;            b = attrp[ai].u.c.b * 257;            cp = &WCU->colors[color].color;            if (WCU->colors[color].inuse)                if (cp->red != r || cp->green != g || cp->blue != b)                    if (color > 1 || WCU->allocedcolor[color])                        XFreeColors (Gdisplay, WCU->cmap, &cp->pixel, 1, 0);            cp->red = r, cp->green = g, cp->blue = b;            if (XAllocColor (Gdisplay, WCU->cmap, cp)) {                WCU->colors[color].inuse = TRUE;                if (color <= 1)                    WCU->allocedcolor[color] = TRUE;            }            /* XAllocColor may change the rgb values */            cp->red = r, cp->green = g, cp->blue = b;            if (color == WCU->gattr.color)                WCU->gattr.color = -1;            if (color == 0 || color == 1) {                RESETARGS;                if (color == 0)                    ADD2ARGS (XtNbackground, cp->pixel);                else                    ADD2ARGS (XtNforeground, cp->pixel);                XtSetValues (widget->w, argp, argn);            }            break;        case G_ATTRVIEWPORT:            WCU->vsize.x = (int) (attrp[ai].u.s.x + 0.5);            WCU->vsize.y = (int) (attrp[ai].u.s.y + 0.5);            if (WCU->vsize.x > 32767)                WCU->vsize.x = 32767;            if (WCU->vsize.y > 32767)                WCU->vsize.y = 32767;            RESETARGS;            ADD2ARGS (XtNwidth, WCU->vsize.x);            ADD2ARGS (XtNheight, WCU->vsize.y);            XtSetValues (widget->w, argp, argn);            break;        case G_ATTRWINDOW:            WCU->wrect = attrp[ai].u.r;            break;        }    }    adjustclip (widget);    return 0;}int GCsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {    PIXsize_t ps;    XColor *cp;    int curi, color, ai, r, g, b;    RESETARGS;    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRSIZE:            GETSIZE (attrp[ai].u.s, ps, MINCWSIZE);            ADD2ARGS (XtNwidth, ps.x);            ADD2ARGS (XtNheight, ps.y);            break;        case G_ATTRBORDERWIDTH:            ADD2ARGS (XtNborderWidth, attrp[ai].u.i);            break;        case G_ATTRCURSOR:            if ((curi = XmuCursorNameToIndex (attrp[ai].u.t)) == -1) {                if (strcmp (attrp[ai].u.t, "default") == 0) {                    XUndefineCursor (Gdisplay, XtWindow (widget->w));                    curcursori = -1;                } else {                    Gerr (POS, G_ERRNOSUCHCURSOR, attrp[ai].u.t);                    return -1;                }            } else {                if (!cursormap[curi].id) {                    cursormap[curi].id = XCreateFontCursor (Gdisplay, curi);                    strcpy (cursormap[curi].name, attrp[ai].u.t);                }                XDefineCursor (                    Gdisplay, XtWindow (widget->w), cursormap[curi].id                );                curcursori = curi;            }            Gsync ();            break;        case G_ATTRCOLOR:            color = attrp[ai].u.c.index;            if (color < 0 || color > G_MAXCOLORS) {                Gerr (POS, G_ERRBADCOLORINDEX, color);                return -1;            }            r = attrp[ai].u.c.r * 257;            g = attrp[ai].u.c.g * 257;            b = attrp[ai].u.c.b * 257;            cp = &WCU->colors[color].color;            if (WCU->colors[color].inuse)                if (cp->red != r || cp->green != g || cp->blue != b)                    if (color > 1 || WCU->allocedcolor[color])                        XFreeColors (Gdisplay, WCU->cmap, &cp->pixel, 1, 0);            cp->red = r, cp->green = g, cp->blue = b;            if (XAllocColor (Gdisplay, WCU->cmap, cp)) {                WCU->colors[color].inuse = TRUE;                if (color <= 1)                    WCU->allocedcolor[color] = TRUE;            }            /* XAllocColor may change the rgb values */            cp->red = r, cp->green = g, cp->blue = b;            if (color == 0) {                XSetBackground (Gdisplay, GC, WCU->colors[0].color.pixel);                ADD2ARGS (XtNbackground, WCU->colors[0].color.pixel);            } else if (color == 1) {                XSetForeground (Gdisplay, GC, WCU->colors[1].color.pixel);                ADD2ARGS (XtNforeground, WCU->colors[1].color.pixel);            }            XtSetValues (widget->w, argp, argn);            RESETARGS;            if (color == WCU->gattr.color)                WCU->gattr.color = -1;            break;        case G_ATTRVIEWPORT:            WCU->vsize.x = (int) (attrp[ai].u.s.x + 0.5);            WCU->vsize.y = (int) (attrp[ai].u.s.y + 0.5);            if (WCU->vsize.x > 32767)                WCU->vsize.x = 32767;            if (WCU->vsize.y > 32767)                WCU->vsize.y = 32767;            ADD2ARGS (XtNwidth, WCU->vsize.x);            ADD2ARGS (XtNheight, WCU->vsize.y);            XtSetValues (widget->w, argp, argn);            adjustclip (widget);            RESETARGS;            break;        case G_ATTRWINDOW:            WCU->wrect = attrp[ai].u.r;            XtSetValues (widget->w, argp, argn);            adjustclip (widget);            RESETARGS;            break;        case G_ATTRWINDOWID:            Gerr (POS, G_ERRCANNOTSETATTR2, "windowid");            return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -