📄 gcanvas.c
字号:
DeleteDC (gc); return 0;}int GCwritebitmap (Gbitmap_t *bitmap, FILE *fp) { Gwidget_t *widget; HDC gc; COLORREF color; char bufp[2048]; int 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; } gc = CreateCompatibleDC (GC); SelectObject (gc, bitmap->u.bmap.orig); 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++) { color = GetPixel (gc, x, y); bufp[bufi++] = GetRValue (color); bufp[bufi++] = GetGValue (color); bufp[bufi++] = GetBValue (color); if (bufi + 3 >= 2048) { fwrite (bufp, 1, bufi, fp); bufi = 0; } } } if (bufi > 0) fwrite (bufp, 1, bufi, fp); DeleteDC (gc); return 0;}int GCbitblt ( Gwidget_t *widget, Gpoint_t gp, Grect_t gr, Gbitmap_t *bitmap, char *mode, Ggattr_t *ap) { PIXrect_t pr, r; PIXpoint_t pp; PIXsize_t s; Gsize_t scale; Gxy_t p; HBITMAP pix; HDC gc; 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 && scale.y == 1) pix = bitmap->u.bmap.orig; 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); s.x = pr.c.x - pr.o.x + 1, s.y = pr.c.y - pr.o.y + 1; r.o.x = pp.x, r.o.y = pp.y - s.y + 1; r.c.x = r.o.x + s.x - 1, r.c.y = r.o.y + s.y - 1; if (r.o.x < 0) pr.o.x -= r.o.x, r.o.x = 0; if (r.o.y < 0) pr.o.y -= r.o.y, r.o.y = 0; if (r.c.x >= bitmap->size.x * scale.x) { pr.c.x -= (r.c.x + 1 - bitmap->size.x * scale.x); r.c.x = bitmap->size.x * scale.x - 1; } if (r.c.y >= bitmap->size.y * scale.y) { pr.c.y -= (r.c.y + 1 - bitmap->size.y * scale.y); r.c.y = bitmap->size.y * scale.y - 1; } if (pr.o.x < 0) r.o.x -= pr.o.x, pr.o.x = 0; if (pr.o.y < 0) r.o.y -= pr.o.y, pr.o.y = 0; setgattr (widget, ap); gc = CreateCompatibleDC (GC); SelectObject (gc, pix); BitBlt ( GC, pr.o.x, pr.o.y, r.c.x - r.o.x + 1, r.c.y - r.o.y + 1, gc, r.o.x, r.o.y, (WCU->gattr.mode == G_SRC) ? SRCCOPY : SRCINVERT ); DeleteDC (gc); } 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 && scale.y == 1) pix = bitmap->u.bmap.orig; 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); s.x = pr.c.x - pr.o.x + 1, s.y = pr.c.y - pr.o.y + 1; r.o.x = pp.x, r.o.y = pp.y - s.y + 1; r.c.x = r.o.x + s.x - 1, r.c.y = r.o.y + s.y - 1; if (pr.o.x < 0) r.o.x -= pr.o.x, pr.o.x = 0; if (pr.o.y < 0) r.o.y -= pr.o.y, pr.o.y = 0; if (pr.c.x >= bitmap->size.x * scale.x) { r.c.x -= (pr.c.x + 1 - bitmap->size.x * scale.x); pr.c.x = bitmap->size.x * scale.x - 1; } if (pr.c.y >= bitmap->size.y * scale.y) { r.c.y -= (pr.c.y + 1 - bitmap->size.y * scale.y); pr.c.y = bitmap->size.y * scale.y - 1; } if (r.o.x < 0) pr.o.x -= r.o.x, r.o.x = 0; if (r.o.y < 0) pr.o.y -= r.o.y, r.o.y = 0; setgattr (widget, ap); gc = CreateCompatibleDC (GC); SelectObject (gc, pix); BitBlt ( gc, pr.o.x, pr.o.y, r.c.x - r.o.x + 1, r.c.y - r.o.y + 1, GC, r.o.x, r.o.y, (WCU->gattr.mode == G_SRC) ? SRCCOPY : SRCINVERT ); if (pix != bitmap->u.bmap.orig) scalebitmap (widget, bitmap, scale, TRUE, -1); DeleteDC (gc); } return 0;}static int scalebitmap ( Gwidget_t *widget, Gbitmap_t *bitmap, Gsize_t scale, int copybits, int dir) { Gsize_t nsize, o2n; HBITMAP opix, spix; COLORREF color; HDC gc1, gc2; int x, y, x2, y2, xp, yp; double prod, rgb[3], xr2, yr2, xl2, yl2, xf2, yf2, xr, yr, xl, yl; if (!copybits) { if (dir == 1) { nsize.x = (int) (bitmap->size.x * scale.x); nsize.y = (int) (bitmap->size.y * scale.y); if (!(spix = CreateBitmap ( (int) nsize.x, (int) nsize.y, 1, Gdepth, NULL ))) { Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } if (bitmap->u.bmap.scaled) DeleteObject (bitmap->u.bmap.scaled); bitmap->u.bmap.scaled = spix; bitmap->scale = scale; } return 0; } 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 (!(spix = CreateBitmap ( (int) nsize.x, (int) nsize.y, 1, Gdepth, NULL ))) { Gerr (POS, G_ERRCANNOTCREATEBITMAP); return -1; } opix = bitmap->u.bmap.orig; } else { nsize.x = (int) bitmap->size.x; nsize.y = (int) bitmap->size.y; o2n.x = scale.x, o2n.y = scale.y; spix = bitmap->u.bmap.orig; opix = bitmap->u.bmap.scaled; } gc1 = CreateCompatibleDC (GC); SelectObject (gc1, opix); gc2 = CreateCompatibleDC (GC); SelectObject (gc2, spix); prod = o2n.x * o2n.y; y = 0; yr = o2n.y; yl = 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; color = GetPixel (gc1, x2, y2); rgb[0] += (GetRValue (color) * xf2 * yf2 / prod); rgb[1] += (GetGValue (color) * xf2 * yf2 / prod); rgb[2] += (GetBValue (color) * 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; SetPixel (gc2, xp, yp, RGB (rgb[0], rgb[1], rgb[2])); x = x2; xr = xr2; xl = xl2; } y = y2; yr = yr2; yl = yl2; } DeleteDC (gc1); DeleteDC (gc2); if (dir == 1) { if (bitmap->u.bmap.scaled) DeleteObject (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; POINT p; int n1, n2, n3; GetCursorPos (&p); ScreenToClient (widget->w, &p); pp.x = p.x, pp.y = p.y; *gpp = ppixtodraw (widget, pp); n1 = GetAsyncKeyState (VK_LBUTTON); n2 = GetAsyncKeyState (VK_MBUTTON); n3 = GetAsyncKeyState (VK_RBUTTON); *count = (n1 < 0 ? 1 : 0) + (n2 < 0 ? 1 : 0) + (n3 < 0 ? 1 : 0); return 0;}static void setgattr (Gwidget_t *widget, Ggattr_t *ap) { HBRUSH brush, pbrush; HPEN pen, ppen; PALETTEENTRY *colorp; long color, mode, style, width, flag, 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; flag = FALSE; mode = ap->mode; if (mode != WCU->gattr.mode) { WCU->gattr.mode = mode; SetROP2 (GC, (int) mode); } WCU->gattr.fill = ap->fill; color = ap->color; if (color >= G_MAXCOLORS || !(WCU->colors[color].inuse)) color = 1; if (color != WCU->gattr.color) WCU->gattr.color = color, flag = TRUE; width = ap->width; if (width != WCU->gattr.width) WCU->gattr.width = width, flag = TRUE; style = ap->style; if (style != WCU->gattr.style) WCU->gattr.style = style, style = TRUE; if (!flag) return; WCU->gattr.color = color; if (Gdepth == 1) { colorp = &WCU->colors[color].color; intens = ( 0.3 * colorp->peBlue + 0.59 * colorp->peRed + 0.11 * colorp->peGreen ) / 255.0; pati = (intens <= 0.0625) ? 16 : -16.0 * (log (intens) / 2.7725887222); brush = WCU->grays[pati]; } else brush = CreateSolidBrush (PALETTEINDEX (WCU->gattr.color)); pbrush = SelectObject (GC, brush); if (Gdepth != 1) DeleteObject (pbrush); pen = CreatePen ( (int) gstyles[WCU->gattr.style], WCU->gattr.width, PALETTEINDEX (WCU->gattr.color) ); ppen = SelectObject (GC, pen); DeleteObject (ppen); SetTextColor (GC, PALETTEINDEX (WCU->gattr.color));}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;}Gpoint_t ppixtodraw (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 = (int) ((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 = (int) ((bitmap->size.y - 1) * bitmap->scale.y); pp.x = gp.x + 0.5; pp.y = tvy - gp.y + 0.5; return pp;}void Gadjustclip (Gwidget_t *widget) { Gwidget_t *parent; PIXrect_t pr; RECT r1, r2, r3; parent = &Gwidgets[widget->pwi]; GetWindowRect (widget->w, &r1); GetClientRect (parent->w, &r2); GetWindowRect (parent->w, &r3); pr.o.x = max (0, -(r1.left - r3.left)); pr.o.y = max (0, -(r1.top - r3.top)); pr.c.x = min (r1.right - r1.left, pr.o.x + r2.right - r2.left); pr.c.y = min (r1.bottom - r1.top, pr.o.y + r2.bottom - r2.top); 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -