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

📄 gcanvas.c

📁 Graphviz - Graph Drawing Programs from AT&T Research and Lucent Bell Labs See doc/build.html for
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: gcanvas.c,v 1.2 2005/04/08 20:45:34 erg Exp $ $Revision: 1.2 $ *//* 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"#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 max(a, b) (((a) >= (b)) ? (a) : (b))#define min(a, b) (((a) <= (b)) ? (a) : (b))static long gstyles[5] = {    /* G_SOLID */       PS_SOLID,    /* G_DASHED */      PS_DASH,    /* G_DOTTED */      PS_DOT,    /* G_LONGDASHED */  PS_DASH,    /* G_SHORTDASHED */ PS_DASH,};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 int curcursori = -1;static void bezier (PIXpoint_t, PIXpoint_t, PIXpoint_t, PIXpoint_t);static HFONT 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 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);int GCcreatewidget (    Gwidget_t *parent, Gwidget_t *widget, int attrn, Gwattr_t *attrp) {    PIXsize_t ps;    /* the 2 here is to provide enough space for palPalEntry[0] and [1] */    LOGPALETTE pal[2];    HBRUSH brush;    HPEN pen;    HBITMAP bmap;    HCURSOR cursor;    DWORD wflags;    int color, ai, i;    if (!parent) {        Gerr (POS, G_ERRNOPARENTWIDGET);        return -1;    }    wflags = WS_CHILDWINDOW;    WCU->func = NULL;    WCU->needredraw = FALSE;    WCU->buttonsdown = 0;    WCU->bstate[0] = WCU->bstate[1] = WCU->bstate[2] = 0;    ps.x = ps.y = MINCWSIZE;    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRSIZE:            GETSIZE (attrp[ai].u.s, ps, MINCWSIZE);            break;        case G_ATTRBORDERWIDTH:            wflags |= WS_BORDER;            break;        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 = 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;        }    }    Gadjustwrect (parent, &ps);    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 (!(widget->w = CreateWindow (        "CanvasClass", "canvas", wflags, 0, 0,        ps.x, ps.y, parent->w, (HMENU) (widget - &Gwidgets[0]),        hinstance, NULL    ))) {        Gerr (POS, G_ERRCANNOTCREATEWIDGET);        return -1;    }    ShowWindow (widget->w, SW_SHOW);    UpdateWindow (widget->w);    SetCursor (LoadCursor ((HINSTANCE) NULL, IDC_ARROW));    GC = GetDC (widget->w);    WCU->ncolor = 2;    pal[0].palVersion = 0x300; /* HA HA HA */    pal[0].palNumEntries = 2;    pal[0].palPalEntry[0].peRed = 255;    pal[0].palPalEntry[0].peGreen = 255;    pal[0].palPalEntry[0].peBlue = 255;    pal[0].palPalEntry[0].peFlags = 0;    pal[0].palPalEntry[1].peRed = 0;    pal[0].palPalEntry[1].peGreen = 0;    pal[0].palPalEntry[1].peBlue = 0;    pal[0].palPalEntry[1].peFlags = 0;    WCU->cmap = CreatePalette (&pal[0]);    WCU->colors[0].color = pal[0].palPalEntry[0];    for (i = 1; i < G_MAXCOLORS; i++)        WCU->colors[i].color = pal[0].palPalEntry[1];    SelectPalette (GC, WCU->cmap, FALSE);    RealizePalette (GC);    WCU->colors[0].inuse = TRUE;    WCU->colors[1].inuse = TRUE;    for (i = 2; i < G_MAXCOLORS; i++)        WCU->colors[i].inuse = FALSE;    WCU->gattr.color = 1;    brush = CreateSolidBrush (PALETTEINDEX (1));    SelectObject (GC, brush);    pen = CreatePen (PS_SOLID, 1, PALETTEINDEX (1));    SelectObject (GC, pen);    SetTextColor (GC, PALETTEINDEX (1));    SetBkMode (GC, TRANSPARENT);    WCU->gattr.width = 0;    WCU->gattr.mode = G_SRC;    WCU->gattr.fill = 0;    WCU->gattr.style = 0;    WCU->defgattr = WCU->gattr;    WCU->font = NULL;    if (Gdepth == 1) {        for (i = 0; i < 17; i++) {            if (!(bmap = CreateBitmap (4, 4, 1, 1, &grays[i][0])))                continue;            WCU->grays[i] = CreatePatternBrush (bmap);        }    }    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRCURSOR:            if (strcmp (attrp[ai].u.t, "watch") == 0) {                curcursori = 1;                cursor = LoadCursor ((HINSTANCE) NULL, IDC_WAIT);            } else if (strcmp (attrp[ai].u.t, "default") == 0) {                curcursori = -1;                cursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);            } else {                Gerr (POS, G_ERRNOSUCHCURSOR, attrp[ai].u.t);                return -1;            }            SetCursor (cursor);            break;        case G_ATTRCOLOR:            color = attrp[ai].u.c.index;            if (color < 0 || color > G_MAXCOLORS) {                Gerr (POS, G_ERRBADCOLORINDEX, color);                return -1;            }            WCU->colors[color].color.peRed = attrp[ai].u.c.r;            WCU->colors[color].color.peGreen = attrp[ai].u.c.g;            WCU->colors[color].color.peBlue = attrp[ai].u.c.b;            WCU->colors[color].color.peFlags = 0;            if (color >= WCU->ncolor)                ResizePalette (WCU->cmap, color + 1), WCU->ncolor = color + 1;            SetPaletteEntries (                WCU->cmap, (int) color, 1, &WCU->colors[color].color);            RealizePalette (GC);            WCU->colors[color].inuse = TRUE;            if (color == WCU->gattr.color)                WCU->gattr.color = -1;            break;        case G_ATTRVIEWPORT:            if (attrp[ai].u.s.x == 0)                attrp[ai].u.s.x = 1;            if (attrp[ai].u.s.y == 0)                attrp[ai].u.s.y = 1;            WCU->vsize.x = (int) (attrp[ai].u.s.x + 0.5);            WCU->vsize.y = (int) (attrp[ai].u.s.y + 0.5);            SetWindowPos (                widget->w, (HWND) NULL, 0, 0, WCU->vsize.x,                WCU->vsize.y, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE            );            break;        case G_ATTRWINDOW:            if (attrp[ai].u.r.o.x == attrp[ai].u.r.c.x)                attrp[ai].u.r.c.x = attrp[ai].u.r.o.x + 1;            if (attrp[ai].u.r.o.y == attrp[ai].u.r.c.y)                attrp[ai].u.r.c.y = attrp[ai].u.r.o.y + 1;            WCU->wrect = attrp[ai].u.r;            break;        }    }    if (parent && parent->type == G_ARRAYWIDGET)        Gawinsertchild (parent, widget);    Gadjustclip (widget);    return 0;}int GCsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {    HCURSOR cursor;    Gwidget_t *parent;    PIXsize_t ps;    DWORD wflags1;    int ai, color;    parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi];    wflags1 = SWP_NOMOVE | SWP_NOZORDER;    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRSIZE:            GETSIZE (attrp[ai].u.s, ps, MINCWSIZE);            Gadjustwrect (parent, &ps);            SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps.x, ps.y, wflags1);            break;        case G_ATTRBORDERWIDTH:            Gerr (POS, G_ERRCANNOTSETATTR2, "borderwidth");            return -1;        case G_ATTRCURSOR:            if (strcmp (attrp[ai].u.t, "watch") == 0) {                curcursori = 1;                cursor = LoadCursor ((HINSTANCE) NULL, IDC_WAIT);            } else if (strcmp (attrp[ai].u.t, "default") == 0) {                curcursori = -1;                cursor = LoadCursor ((HINSTANCE) NULL, IDC_ARROW);            } else {                Gerr (POS, G_ERRNOSUCHCURSOR, attrp[ai].u.t);                return -1;            }            SetCursor (cursor);            break;        case G_ATTRCOLOR:            color = attrp[ai].u.c.index;            if (color < 0 || color > G_MAXCOLORS) {                Gerr (POS, G_ERRBADCOLORINDEX, color);                return -1;            }            WCU->colors[color].color.peRed = attrp[ai].u.c.r;            WCU->colors[color].color.peGreen = attrp[ai].u.c.g;            WCU->colors[color].color.peBlue = attrp[ai].u.c.b;            WCU->colors[color].color.peFlags = 0;            if (color >= WCU->ncolor)                ResizePalette (WCU->cmap, color + 1), WCU->ncolor = color + 1;            SetPaletteEntries (                WCU->cmap, (int) color, 1, &WCU->colors[color].color            );            RealizePalette (GC);            WCU->colors[color].inuse = TRUE;            if (color == WCU->gattr.color)                WCU->gattr.color = -1;            break;        case G_ATTRVIEWPORT:            if (attrp[ai].u.s.x == 0)                attrp[ai].u.s.x = 1;            if (attrp[ai].u.s.y == 0)                attrp[ai].u.s.y = 1;            WCU->vsize.x = (int) (attrp[ai].u.s.x + 0.5);            WCU->vsize.y = (int) (attrp[ai].u.s.y + 0.5);            ps.x = WCU->vsize.x, ps.y = WCU->vsize.y;            Gadjustwrect (&Gwidgets[widget->pwi], &ps);            SetWindowPos (                widget->w, (HWND) NULL, 0, 0, ps.x,                ps.y, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE            );            Gadjustclip (widget);            break;        case G_ATTRWINDOW:            if (attrp[ai].u.r.o.x == attrp[ai].u.r.c.x)                attrp[ai].u.r.c.x = attrp[ai].u.r.o.x + 1;            if (attrp[ai].u.r.o.y == attrp[ai].u.r.c.y)                attrp[ai].u.r.c.y = attrp[ai].u.r.o.y + 1;            WCU->wrect = attrp[ai].u.r;            Gadjustclip (widget);            break;        case G_ATTRWINDOWID:            Gerr (POS, G_ERRCANNOTSETATTR2, "windowid");            return -1;        case G_ATTREVENTCB:            WCU->func = 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;        }    }    return 0;}int GCgetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {    PALETTEENTRY *cp;    RECT r;    int color, ai;    for (ai = 0; ai < attrn; ai++) {        switch (attrp[ai].id) {        case G_ATTRSIZE:            GetWindowRect (widget->w, &r);            attrp[ai].u.s.x = r.right - r.left;            attrp[ai].u.s.y = r.bottom - r.top;            break;        case G_ATTRBORDERWIDTH:            Gerr (POS, G_ERRCANNOTGETATTR, "borderwidth");            return -1;        case G_ATTRCURSOR:            attrp[ai].u.t = (curcursori == -1) ? "default" : "watch";            break;        case G_ATTRCOLOR:            color = attrp[ai].u.c.index;            if (color < 0 || color > G_MAXCOLORS) {                Gerr (POS, G_ERRBADCOLORINDEX, color);                return -1;            }            if (WCU->colors[color].inuse) {                cp = &WCU->colors[color].color;                attrp[ai].u.c.r = cp->peRed;                attrp[ai].u.c.g = cp->peGreen;                attrp[ai].u.c.b = cp->peBlue;            } else {                attrp[ai].u.c.r = -1;                attrp[ai].u.c.g = -1;                attrp[ai].u.c.b = -1;            }            break;        case G_ATTRVIEWPORT:            attrp[ai].u.s = WCU->vsize;            break;        case G_ATTRWINDOW:            attrp[ai].u.r = WCU->wrect;            break;        case G_ATTRWINDOWID:            sprintf (&Gbufp[0], "0x%lx", widget->w);            attrp[ai].u.t = &Gbufp[0];            break;        case G_ATTREVENTCB:            attrp[ai].u.func = WCU->func;            break;        case G_ATTRUSERDATA:            attrp[ai].u.u = widget->udata;            break;        default:            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);            return -1;        }    }    return 0;}int GCdestroywidget (Gwidget_t *widget) {    Gwidget_t *parent;    parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi];    if (parent && parent->type == G_ARRAYWIDGET)        Gawdeletechild (parent, widget);    DestroyWindow (widget->w);    return 0;}int GCcanvasclear (Gwidget_t *widget) {    Ggattr_t attr;    RECT r;    HBRUSH brush, pbrush;    attr.flags = 0;    setgattr (widget, &attr);    brush = CreateSolidBrush (PALETTEINDEX (0));    pbrush = SelectObject (GC, brush);    GetClientRect (widget->w, &r);    Rectangle (GC, r.left, r.top, r.right, r.bottom);    SelectObject (GC, pbrush);    DeleteObject (brush);    WCU->needredraw = FALSE;    return 0;}int GCsetgfxattr (Gwidget_t *widget, Ggattr_t *ap) {    setgattr (widget, ap);    WCU->defgattr = WCU->gattr;    return 0;}int GCgetgfxattr (Gwidget_t *widget, Ggattr_t *ap) {    if ((ap->flags & G_GATTRCOLOR))        ap->color = WCU->gattr.color;    if ((ap->flags & G_GATTRWIDTH))        ap->width = WCU->gattr.width;    if ((ap->flags & G_GATTRMODE))        ap->mode = WCU->gattr.mode;    if ((ap->flags & G_GATTRFILL))        ap->fill = WCU->gattr.fill;    if ((ap->flags & G_GATTRSTYLE))        ap->style = WCU->gattr.style;    return 0;}int GCarrow (Gwidget_t *widget, Gpoint_t gp1, Gpoint_t gp2, Ggattr_t *ap) {    PIXpoint_t pp1, pp2, pa, pb, pd;    Grect_t gr;    double tangent, l;    if (gp1.x < gp2.x)        gr.o.x = gp1.x, gr.c.x = gp2.x;    else

⌨️ 快捷键说明

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