void swcursorinit(void) { static int init; if(!init){ init = 1; addclock0link(swcursorclock, 10); swenabled = 1; } if(swback){ freememimage(swback); freememimage(swmask); freememimage(swmask1); freememimage(swimg); freememimage(swimg1); } swback = allocmemimage(Rect(0,0,32,32), gscreen->chan); swmask = allocmemimage(Rect(0,0,16,16), GREY8); swmask1 = allocmemimage(Rect(0,0,16,16), GREY1); swimg = allocmemimage(Rect(0,0,16,16), GREY8); swimg1 = allocmemimage(Rect(0,0,16,16), GREY1); if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){ print("software cursor: allocmemimage fails\n"); return; } memfillcolor(swmask, DOpaque); memfillcolor(swmask1, DOpaque); memfillcolor(swimg, DBlack); memfillcolor(swimg1, DBlack); }
Memimage* rot90(Memimage *m) { int line, bpp, x, y, dx, dy; ulong chan; uchar *s, *d; Memimage *w; bpp = (m->depth+7)/8; chan = m->chan; switch(chan){ case GREY1: case GREY2: case GREY4: if((w = allocmemimage(m->r, GREY8)) == nil) sysfatal("allocmemimage: %r"); memimagedraw(w, w->r, m, m->r.min, nil, ZP, S); freememimage(m); m = w; break; } dx = Dx(m->r); dy = Dy(m->r); if((w = allocmemimage(Rect(m->r.min.x, m->r.min.y, m->r.min.x+dy, m->r.min.y+dx), m->chan)) == nil) sysfatal("allocmemimage: %r"); line = w->width*sizeof(ulong); for(y=0; y<dy; y++){ s = byteaddr(m, addpt(m->r.min, Pt(0, y))); d = byteaddr(w, addpt(w->r.min, Pt(dy-y-1, 0))); for(x=0; x<dx; x++){ switch(bpp){ case 4: d[3] = s[3]; case 3: d[2] = s[2]; case 2: d[1] = s[1]; case 1: d[0] = s[0]; } s += bpp; d += line; } } freememimage(m); if(w->chan != chan){ if((m = allocmemimage(w->r, chan)) == nil) sysfatal("allocmemimage: %r"); memimagedraw(m, m->r, w, w->r.min, nil, ZP, S); freememimage(w); w = m; } return w; }
int memlsetrefresh(Memimage *i, Refreshfn fn, void *ptr) { Memlayer *l; l = i->layer; if(l->refreshfn!=0 && fn!=0) { /* just change functions */ l->refreshfn = fn; l->refreshptr = ptr; return 1; } if(l->refreshfn == 0) { /* is using backup image; just free it */ freememimage(l->save); l->save = nil; l->refreshfn = fn; l->refreshptr = ptr; return 1; } l->save = allocmemimage(i->r, i->chan); if(l->save == nil) return 0; /* easiest way is just to update the entire save area */ l->refreshfn(i, i->r, l->refreshptr); l->refreshfn = 0; l->refreshptr = nil; return 1; }
void main(int argc, char **argv) { Memimage *x; Point c = {208,871}; int a = 441; int b = 441; int thick = 0; Point sp = {0,0}; int alpha = 51; int phi = 3; vlong t0, t1; int i, n; vlong del; if (argc != 2) { fprint(2, "usage: arctest number\n"); exits("usage"); } memimageinit(); x = allocmemimage(Rect(0,0,1000,1000), CMAP8); n = atoi(argv[1]); t0 = nsec(); t0 = nsec(); t0 = nsec(); t1 = nsec(); del = t1-t0; t0 = nsec(); for(i=0; i<n; i++) memarc(x, c, a, b, thick, memblack, sp, alpha, phi, SoverD); t1 = nsec(); print("%lld %lld\n", t1-t0-del, del); }
void screeninit(void) { int fmt; int dx, dy; ProcessSerialNumber psn = { 0, kCurrentProcess }; TransformProcessType(&psn, kProcessTransformToForegroundApplication); SetFrontProcess(&psn); fmt = XBGR32; //XRGB32; devRect = max_bounds(); dx = devRect.size.width; dy = devRect.size.height; gscreen = allocmemimage(Rect(0,0,dx,dy), fmt); dataProviderRef = CGDataProviderCreateWithData(0, gscreen->data->bdata, dx * dy * 4, 0); fullScreenImage = CGImageCreate(dx, dy, 8, 32, dx * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipLast, dataProviderRef, 0, 0, kCGRenderingIntentDefault); devRect = CGDisplayBounds(CGMainDisplayID()); kproc("osxscreen", winproc, nil, 0); kproc("osxflush", flushproc, nil, 0); Sleep(&rend, isready, nil); }
void swcursorinit(void) { static int init, warned; VGAscr *scr; didswcursorinit = 1; if(!init){ init = 1; addclock0link(swcursorclock, 10); } scr = &vgascreen[0]; if(scr==nil || scr->gscreen==nil) return; if(scr->dev == nil || scr->dev->linear == nil){ if(!warned){ print("cannot use software cursor on non-linear vga screen\n"); warned = 1; } return; } if(swback){ freememimage(swback); freememimage(swmask); freememimage(swmask1); freememimage(swimg); freememimage(swimg1); } swback = allocmemimage(Rect(0,0,32,32), gscreen->chan); swmask = allocmemimage(Rect(0,0,16,16), GREY8); swmask1 = allocmemimage(Rect(0,0,16,16), GREY1); swimg = allocmemimage(Rect(0,0,16,16), GREY8); swimg1 = allocmemimage(Rect(0,0,16,16), GREY1); if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){ print("software cursor: allocmemimage fails"); return; } memfillcolor(swmask, DOpaque); memfillcolor(swmask1, DOpaque); memfillcolor(swimg, DBlack); memfillcolor(swimg1, DBlack); }
Memimage* allocrepl(ulong color) { Memimage *m; m = allocmemimage(Rect(0,0,1,1), RGB24); memfillcolor(m, color); m->flags |= Frepl; m->clipr = Rect(-1000000, -1000000, 1000000, 1000000); return m; }
void vgaimageinit(ulong chan) { if(back == nil){ back = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */ if(back == nil) panic("back alloc"); /* RSC BUG */ back->flags |= Frepl; back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); memfillcolor(back, DBlack); } if(conscol == nil){ conscol = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */ if(conscol == nil) panic("conscol alloc"); /* RSC BUG */ conscol->flags |= Frepl; conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); memfillcolor(conscol, DWhite); } }
Memimage* memmultichan(Memimage *i) { Memimage *ni; if(notrans(i->chan)) return i; ni = allocmemimage(i->r, RGB24); if(ni == nil) return ni; memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S); return ni; }
int memunload(Memimage *src, Rectangle r, uint8_t *data, int n) { Memimage *tmp; Memlayer *dl; Rectangle lr; int dx; Top: dl = src->layer; if(dl == nil) return unloadmemimage(src, r, data, n); /* * Convert to screen coordinates. */ lr = r; r.min.x += dl->delta.x; r.min.y += dl->delta.y; r.max.x += dl->delta.x; r.max.y += dl->delta.y; dx = dl->delta.x&(7/src->depth); if(dl->clear && dx==0){ src = dl->screen->image; goto Top; } /* * src is an obscured layer or data is unaligned */ if(dl->save && dx==0){ if(dl->refreshfn != nil) return -1; /* can't unload window if it's not Refbackup */ if(n > 0) memlhide(src, r); n = unloadmemimage(dl->save, lr, data, n); return n; } tmp = allocmemimage(lr, src->chan); if(tmp == nil) return -1; memdraw(tmp, lr, src, lr.min, nil, lr.min, S); n = unloadmemimage(tmp, lr, data, n); freememimage(tmp); return n; }
static void screenwin(void) { Point p, q; char *greet; Memimage *orange; Rectangle r; memsetchan(gscreen, RGB16); back = memwhite; conscol = memblack; orange = allocmemimage(Rect(0,0,1,1), RGB16); orange->flags |= Frepl; orange->clipr = gscreen->r; orange->data->bdata[0] = 0x40; orange->data->bdata[1] = 0xfd; w = memdefont->info[' '].width; h = memdefont->height; r = insetrect(gscreen->r, 4); memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S); window = insetrect(r, 4); memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S); memimagedraw(gscreen, Rect(window.min.x, window.min.y, window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP, S); freememimage(orange); window = insetrect(window, 5); greet = " Plan 9 Console "; p = addpt(window.min, Pt(10, 0)); q = memsubfontwidth(memdefont, greet); memimagestring(gscreen, p, conscol, ZP, memdefont, greet); flushmemscreen(r); window.min.y += h+6; curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; }
static void screenwin(void) { Point p; char *greet; Memimage *grey; drawqlock(); back = memwhite; conscol = memblack; memfillcolor(gscreen, 0x444488FF); h = memdefont->height; window.min = addpt(gscreen->r.min, Pt(20,20)); window.max.x = window.min.x + Dx(gscreen->r)*3/4-40; window.max.y = window.min.y + Dy(gscreen->r)*3/4-100; memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S); window = insetrect(window, 4); memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S); /* a lot of work to get a grey color */ grey = allocmemimage(Rect(0,0,1,1), CMAP8); grey->flags |= Frepl; grey->clipr = gscreen->r; memfillcolor(grey, 0xAAAAAAFF); memimagedraw(gscreen, Rect(window.min.x, window.min.y, window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S); freememimage(grey); window = insetrect(window, 5); greet = " Plan 9 Console "; p = addpt(window.min, Pt(10, 0)); memimagestring(gscreen, p, conscol, ZP, memdefont, greet); window.min.y += h+6; curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; flushmemscreen(gscreen->r); drawqunlock(); }
void screeninit(void) { int fmt; int dx, dy; memimageinit(); if(depth == 0) depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL); switch(depth){ case 32: screen.dibtype = DIB_RGB_COLORS; screen.depth = 32; fmt = XRGB32; break; case 24: screen.dibtype = DIB_RGB_COLORS; screen.depth = 24; fmt = RGB24; break; case 16: screen.dibtype = DIB_RGB_COLORS; screen.depth = 16; fmt = RGB15; /* [sic] */ break; case 8: default: screen.dibtype = DIB_PAL_COLORS; screen.depth = 8; depth = 8; fmt = CMAP8; break; } dx = GetDeviceCaps(GetDC(NULL), HORZRES); dy = GetDeviceCaps(GetDC(NULL), VERTRES); gscreen = allocmemimage(Rect(0,0,dx,dy), fmt); kproc("winscreen", winproc, 0); ksleep(&rend, isready, 0); }
void screeninit(int x, int y, char *chanstr) { Point p, q; char *greet; char buf[128]; Memimage *grey; Rectangle r; int chan; cursorver = 0; memimageinit(); chan = strtochan(chanstr); if(chan == 0) error("bad screen channel string"); r = Rect(0, 0, x, y); gscreen = allocmemimage(r, chan); if(gscreen == nil){ snprint(buf, sizeof buf, "can't allocate screen image: %r"); error(buf); } offscreen = Pt(x + 100, y + 100); cursorr = Rect(0, 0, CURSORDIM, CURSORDIM); cursorset = allocmemimage(cursorr, GREY8); cursorclear = allocmemimage(cursorr, GREY1); if(cursorset == nil || cursorclear == nil){ freememimage(gscreen); freememimage(cursorset); freememimage(cursorclear); gscreen = nil; cursorset = nil; cursorclear = nil; snprint(buf, sizeof buf, "can't allocate cursor images: %r"); error(buf); } drawlock(); /* * set up goo for screenputs */ memdefont = getmemdefont(); back = memwhite; conscol = memblack; /* a lot of work to get a grey color */ curscol = allocmemimage(Rect(0,0,1,1), RGBA32); curscol->flags |= Frepl; curscol->clipr = gscreen->r; memfillcolor(curscol, 0xff0000ff); memfillcolor(gscreen, 0x444488FF); w = memdefont->info[' '].width; h = memdefont->height; window.min = addpt(gscreen->r.min, Pt(20,20)); window.max.x = window.min.x + Dx(gscreen->r)*3/4-40; window.max.y = window.min.y + Dy(gscreen->r)*3/4-100; memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S); window = insetrect(window, 4); memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S); /* a lot of work to get a grey color */ grey = allocmemimage(Rect(0,0,1,1), CMAP8); grey->flags |= Frepl; grey->clipr = gscreen->r; memfillcolor(grey, 0xAAAAAAFF); memimagedraw(gscreen, Rect(window.min.x, window.min.y, window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S); freememimage(grey); window = insetrect(window, 5); greet = " Plan 9 Console "; p = addpt(window.min, Pt(10, 0)); q = memsubfontwidth(memdefont, greet); memimagestring(gscreen, p, conscol, ZP, memdefont, greet); window.min.y += h+6; curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; flushmemscreen(gscreen->r); drawunlock(); setcursor(&arrow); }
/* * Place i so i->r.min = log, i->layer->screenr.min == scr. */ int memlorigin(Memimage *i, Point log, Point scr) { Memlayer *l; Memscreen *s; Memimage *t, *shad, *nsave; Rectangle x, newr, oldr; Point delta; int overlap, eqlog, eqscr, wasclear; l = i->layer; s = l->screen; oldr = l->screenr; newr = Rect(scr.x, scr.y, scr.x+Dx(oldr), scr.y+Dy(oldr)); eqscr = eqpt(scr, oldr.min); eqlog = eqpt(log, i->r.min); if(eqscr && eqlog) return 0; nsave = nil; if(eqlog==0 && l->save!=nil){ nsave = allocmemimage(Rect(log.x, log.y, log.x+Dx(oldr), log.y+Dy(oldr)), i->chan); if(nsave == nil) return -1; } /* * Bring it to front and move logical coordinate system. */ memltofront(i); wasclear = l->clear; if(nsave){ if(!wasclear) memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0), S); freememimage(l->save); l->save = nsave; } delta = subpt(log, i->r.min); i->r = rectaddpt(i->r, delta); i->clipr = rectaddpt(i->clipr, delta); l->delta = subpt(l->screenr.min, i->r.min); if(eqscr) return 0; /* * To clean up old position, make a shadow window there, don't paint it, * push it behind this one, and (later) delete it. Because the refresh function * for this fake window is a no-op, this will cause no graphics action except * to restore the background and expose the windows previously hidden. */ shad = memlalloc(s, oldr, memlnorefresh, nil, DNofill); if(shad == nil) return -1; s->frontmost = i; if(s->rearmost == i) s->rearmost = shad; else l->rear->layer->front = shad; shad->layer->front = i; shad->layer->rear = l->rear; l->rear = shad; l->front = nil; shad->layer->clear = 0; /* * Shadow is now holding down the fort at the old position. * Move the window and hide things obscured by new position. */ for(t=l->rear->layer->rear; t!=nil; t=t->layer->rear){ x = newr; overlap = rectclip(&x, t->layer->screenr); if(overlap){ memlhide(t, x); t->layer->clear = 0; } } l->screenr = newr; l->delta = subpt(scr, i->r.min); l->clear = rectinrect(newr, l->screen->image->clipr); /* * Everything's covered. Copy to new position and delete shadow window. */ if(wasclear) memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0), S); else memlexpose(i, newr); memldelete(shad); return 1; }
void main(int argc, char *argv[]) { char *tostr, *file; int fd, uncompressed; ulong tochan; Memimage *m, *n; tostr = nil; uncompressed = 0; ARGBEGIN{ case 'c': tostr = EARGF(usage()); break; case 'u': uncompressed = 1; break; default: usage(); }ARGEND memimageinit(); file = "<stdin>"; m = nil; switch(argc){ case 0: m = readmemimage(0); break; case 1: file = argv[0]; fd = open(file, OREAD); if(fd < 0) sysfatal("can't open %s: %r", file); m = readmemimage(fd); close(fd); break; default: usage(); } if(m == nil) sysfatal("can't read %s: %r", file); if(tostr == nil) tochan = m->chan; else{ tochan = strtochan(tostr); if(tochan == 0) sysfatal("bad channel descriptor '%s'", tostr); } n = allocmemimage(m->r, tochan); if(n == nil) sysfatal("can't allocate new image: %r"); memimagedraw(n, n->r, m, m->r.min, nil, ZP, S); if(uncompressed) writeuncompressed(1, n); else writememimage(1, n); exits(nil); }
int image2psfile(int fd, Memimage *im, int dpi) { Rectangle r; Rectangle bbox; int e; int xmargin = 36; int ymargin = 36; double paperaspectratio; double imageaspectratio; Biobuf ioutb; Memimage *tmp; if(im->depth >= 8 && im->chan != CMAP8 && im->chan != GREY8){ /* * the postscript libraries can only handle [1248]-bit grey, 8-bit cmap, * and 24-bit color, so convert. */ tmp = allocmemimage(im->r, strtochan("b8g8r8")); if(tmp == nil) return 1; memimagedraw(tmp, tmp->r, im, im->r.min, nil, ZP, S); freememimage(im); im = tmp; } Binit(&ioutb, fd, OWRITE); r = im->r; width = Dx(r); height = Dy(r); imageaspectratio = (double) width / (double) height; if (landscape) { paperaspectratio = ((double)paperlength - (ymargin * 2)) / ((double)paperwidth - (xmargin * 2)); if (dpi > 0) { iwidth = width * 72 / dpi; iheight = height * 72 / dpi; } else if (imageaspectratio > paperaspectratio) { iwidth = paperlength - (ymargin * 2); iheight = iwidth / imageaspectratio; } else { iheight = paperwidth - (xmargin * 2); iwidth = iheight * imageaspectratio; } xstart = paperwidth - xmargin - (iheight * ymagnification); ystart = paperlength - ymargin; rotation = -90; } else { paperaspectratio = ((double)paperwidth - (xmargin * 2)) / ((double)paperlength - (ymargin * 2)); if (dpi > 0) { iwidth = width * 72 / dpi; iheight = height * 72 / dpi; } else if (imageaspectratio > paperaspectratio) { iwidth = paperwidth - (xmargin * 2); iheight = iwidth / imageaspectratio; } else { iheight = paperlength - (ymargin * 2); iwidth = iheight * imageaspectratio; } xstart = xmargin; ystart = paperlength - ymargin - (iheight * ymagnification); rotation = 0; } bbox = Rect(xstart,ystart,xstart+iwidth,ystart+iheight); e = preamble(&ioutb, bbox); if(e != 0) return e; Bprint(&ioutb, "%%%%Page: 1\n%%%%BeginPageSetup\n"); Bprint(&ioutb, "/pgsave save def\n"); Bprint(&ioutb, "%%%%EndPageSetup\n"); bps = im->depth; Bprint(&ioutb, "%d 0 %d %d %d %d %d %d %s doimage\n", iheight, iwidth, ystart, xstart, height, width, bps, im->flags&Fgrey ? "true" : "false"); imagebits(&ioutb, im); Bprint(&ioutb, "pgsave restore\nshowpage\n"); e = trailer(&ioutb, 1); if(e != 0) return e; Bterm(&ioutb); return 0; }
void imagebits(Biobuf *ioutb, Memimage *im) { int spb; int bitoff; int j, n, n4, i, bpl, nrest; int lsf; uchar c85[6], *data, *src, *dst; Memimage *tmp; Rectangle r; tmp = nil; if (debug) fprint(2, "imagebits, r=%d %d %d %d, depth=%d\n", im->r.min.x, im->r.min.y, im->r.max.x, im->r.max.y, im->depth); width = Dx(im->r); height = Dy(im->r); bps = im->depth; /* # bits per sample */ bitoff = 0; /* # bit offset of beginning sample within first byte */ if (bps < 8) { spb = 8 / bps; bitoff = (im->r.min.x % spb) * bps; } if (bitoff != 0) { /* # Postscript image wants beginning of line at beginning of byte */ r = im->r; r.min.x -= bitoff/im->depth; r.max.x -= bitoff/im->depth; tmp = allocmemimage(r, im->chan); if(tmp == nil){ fprint(2, "p9bitpost: allocmemimage failed: %r\n"); exits("alloc"); } memimagedraw(tmp, r, im, im->r.min, nil, ZP, S); im = tmp; } lsf = 0; /* compact data to remove word-boundary padding */ bpl = bytesperline(im->r, im->depth); n = bpl*Dy(im->r); data = malloc(n); if(data == nil){ fprint(2, "p9bitpost: malloc failed: %r\n"); exits("malloc"); } for(i=0; i<Dy(im->r); i++){ /* memmove(data+bpl*i, byteaddr(im, Pt(im->r.min.x, im->r.min.y+i)), bpl); with inversion */ dst = data+bpl*i; src = byteaddr(im, Pt(im->r.min.x, im->r.min.y+i)); for(j=0; j<bpl; j++) *dst++ = 255 - *src++; } n4 = (n / 4) * 4; for (i = 0; i < n4; i += 4){ cmap2ascii85(data+i, c85); lsf += strlen((char *)c85); Bprint(ioutb, "%s", (char *)c85); if (lsf > 74) { Bprint(ioutb, "\n"); lsf = 0; } } nrest = n - n4; if (nrest != 0) { uchar foo[4]; for (i=0; i<nrest; i++) foo[i] = data[n4+i]; for (i=nrest; i<4; i++) foo[i] = '\0'; cmap2ascii85(foo, c85); if (strcmp((char *)c85, "z") == 0 ) strcpy((char *)c85, "!!!!!"); Bprint(ioutb, "%.*s", nrest+1, (char *)c85); } Bprint(ioutb, "\n~>"); Bprint(ioutb, "\n"); freememimage(tmp); }
/* * make a "wedge" mask covering the desired angle and contained in * a surrounding square; draw a full ellipse; intersect that with the * wedge to make a mask through which to copy src to dst. */ void memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op) { int i, w, beta, tmp, c1, c2, m, m1; Rectangle rect; Point p, bnd[8]; Memimage *wedge, *figure, *mask; if(a < 0) a = -a; if(b < 0) b = -b; w = t; if(w < 0) w = 0; alpha = -alpha; /* compensate for upside-down coords */ phi = -phi; beta = alpha + phi; if(phi < 0){ tmp = alpha; alpha = beta; beta = tmp; phi = -phi; } if(phi >= 360){ memellipse(dst, c, a, b, t, src, sp, op); return; } while(alpha < 0) alpha += 360; while(beta < 0) beta += 360; c1 = alpha/90 & 3; /* number of nearest corner */ c2 = beta/90 & 3; /* * icossin returns point at radius ICOSSCALE. * multiplying by m1 moves it outside the ellipse */ rect = Rect(-a-w, -b-w, a+w+1, b+w+1); m = rect.max.x; /* inradius of bounding square */ if(m < rect.max.y) m = rect.max.y; m1 = (m+ICOSSCALE-1) >> 10; m = m1 << 10; /* assure m1*cossin is inside */ i = 0; bnd[i++] = Pt(0,0); icossin(alpha, &p.x, &p.y); bnd[i++] = mulpt(p, m1); for(;;) { bnd[i++] = mulpt(corners[c1], m); if(c1==c2 && phi<180) break; c1 = (c1+1) & 3; phi -= 90; } icossin(beta, &p.x, &p.y); bnd[i++] = mulpt(p, m1); figure = nil; mask = nil; wedge = allocmemimage(rect, GREY1); if(wedge == nil) goto Return; memfillcolor(wedge, DTransparent); memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S); figure = allocmemimage(rect, GREY1); if(figure == nil) goto Return; memfillcolor(figure, DTransparent); memellipse(figure, p00, a, b, t, memopaque, p00, S); mask = allocmemimage(rect, GREY1); if(mask == nil) goto Return; memfillcolor(mask, DTransparent); memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S); c = subpt(c, dst->r.min); memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op); Return: freememimage(wedge); freememimage(figure); freememimage(mask); }
Memimage* statgraph(Graph *g) { int i, nbin, x, lo, hi, min, max, first; Memimage *m; Rectangle r; Statbin *b, bin[2000]; /* 32 kB, but whack is worse */ needstack(8192); /* double check that bin didn't kill us */ if(g->wid <= MinWidth) g->wid = DefaultWidth; if(g->ht <= MinHeight) g->ht = DefaultHeight; if(g->wid > nelem(bin)) g->wid = nelem(bin); if(g->fill < 0) g->fill = ((uint)(uintptr)g->arg>>8)%nelem(lofill); if(g->fill > nelem(lofill)) g->fill %= nelem(lofill); nbin = g->wid - (Left+Right); binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin); /* * compute bounds */ min = g->min; max = g->max; if(min < 0 || max <= min){ min = max = 0; first = 1; for(i=0; i<nbin; i++){ b = &bin[i]; if(b->nsamp == 0) continue; if(first || b->min < min) min = b->min; if(first || b->max > max) max = b->max; first = 0; } } qlock(&memdrawlock); ginit(); if(smallfont==nil || black==nil || blue==nil || red==nil || hifill[0]==nil || lofill[0]==nil){ werrstr("graphics initialization failed: %r"); qunlock(&memdrawlock); return nil; } /* fresh image */ m = allocmemimage(Rect(0,0,g->wid,g->ht), ABGR32); if(m == nil){ qunlock(&memdrawlock); return nil; } r = Rect(Left, Top, g->wid-Right, g->ht-Bottom); memfillcolor(m, DTransparent); /* x axis */ memimagedraw(m, Rect(r.min.x, r.max.y, r.max.x, r.max.y+1), black, ZP, memopaque, ZP, S); /* y labels */ drawlabel(m, r.min, max); if(min != 0) drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min); /* actual data */ for(i=0; i<nbin; i++){ b = &bin[i]; if(b->nsamp == 0) continue; lo = scalept(b->min, min, max, r.max.y, r.min.y); hi = scalept(b->max, min, max, r.max.y, r.min.y); x = r.min.x+i; hi-=2; memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S); memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill%nelem(lofill)], ZP, memopaque, ZP, S); } if(bin[nbin-1].nsamp) drawlabel(m, Pt(r.max.x, r.min.y+(Dy(r)-smallfont->height)/2), bin[nbin-1].avg); qunlock(&memdrawlock); return m; }
Memimage* memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, ulong val) { Memlayer *l; Memimage *n; static Memimage *paint; if(paint == nil){ paint = allocmemimage(Rect(0,0,1,1), RGBA32); if(paint == nil) return nil; paint->flags |= Frepl; paint->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); } n = allocmemimaged(screenr, s->image->chan, s->image->data); if(n == nil) return nil; l = malloc(sizeof(Memlayer)); if(l == nil){ free(n); return nil; } l->screen = s; if(refreshfn) l->save = nil; else{ l->save = allocmemimage(screenr, s->image->chan); if(l->save == nil){ free(l); free(n); return nil; } /* allocmemimage doesn't initialize memory; this paints save area */ if(val != DNofill) memfillcolor(l->save, val); } l->refreshfn = refreshfn; l->refreshptr = nil; /* don't set it until we're done */ l->screenr = screenr; l->delta = Pt(0,0); n->data->ref++; n->zero = s->image->zero; n->width = s->image->width; n->layer = l; /* start with new window behind all existing ones */ l->front = s->rearmost; l->rear = nil; if(s->rearmost) s->rearmost->layer->rear = n; s->rearmost = n; if(s->frontmost == nil) s->frontmost = n; l->clear = 0; /* now pull new window to front */ _memltofrontfill(n, val != DNofill); l->refreshptr = refreshptr; /* * paint with requested color; previously exposed areas are already right * if this window has backing store, but just painting the whole thing is simplest. */ if(val != DNofill){ memsetchan(paint, n->chan); memfillcolor(paint, val); memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S); } return n; }
void main(int argc, char **argv) { int fd, xsize, ysize; Memimage *im, *nim; ulong ochan, tchan; xsize = ysize = 0; ARGBEGIN{ case 'a': xsize = ysize = getsize(EARGF(usage())); break; case 'x': xsize = getsize(EARGF(usage())); break; case 'y': ysize = getsize(EARGF(usage())); break; default: usage(); }ARGEND fd = 0; if(*argv){ fd = open(*argv, OREAD); if(fd < 0) sysfatal("open: %r"); } memimageinit(); if((im = readmemimage(fd)) == nil) sysfatal("readmemimage: %r"); if(xsize & PERCENT) xsize = ((xsize & ~PERCENT) * Dx(im->r)) / 100; if(ysize & PERCENT) ysize = ((ysize & ~PERCENT) * Dy(im->r)) / 100; if(xsize || ysize){ if(ysize == 0) ysize = (xsize * Dy(im->r)) / Dx(im->r); if(xsize == 0) xsize = (ysize * Dx(im->r)) / Dy(im->r); ochan = im->chan; switch(ochan){ default: for(tchan = ochan; tchan; tchan >>= 8) if(TYPE(tchan) == CAlpha){ tchan = RGBA32; break; } if(tchan == 0) tchan = RGB24; break; case GREY8: case RGB24: case RGBA32: case ARGB32: case XRGB32: tchan = ochan; break; case GREY1: case GREY2: case GREY4: tchan = GREY8; break; } if(tchan != ochan){ if((nim = allocmemimage(im->r, tchan)) == nil) sysfatal("allocimage: %r"); memimagedraw(nim, nim->r, im, im->r.min, nil, ZP, S); freememimage(im); im = nim; } if((nim = allocmemimage( Rect(im->r.min.x, im->r.min.y, im->r.min.x+xsize, im->r.min.y+ysize), tchan)) == nil) sysfatal("allocmemimage: %r"); resample(nim, nim->r, im, im->r); freememimage(im); im = nim; if(tchan != ochan){ if((im = allocmemimage(nim->r, ochan)) == nil) sysfatal("allocimage: %r"); memimagedraw(im, im->r, nim, nim->r.min, nil, ZP, S); freememimage(nim); } } if(writememimage(1, im) < 0) sysfatal("writememimage: %r"); exits(0); }
Memsubfont* mksubfont(XFont *f, char *name, int lo, int hi, int size, int antialias) { CFStringRef s; CGColorSpaceRef color; CGContextRef ctxt; CTFontRef font; CTFontDescriptorRef desc; CGRect bbox; Memimage *m, *mc, *m1; int x, y, y0; int i, height, ascent; Fontchar *fc, *fc0; Memsubfont *sf; CGFloat whitef[] = { 1.0, 1.0 }; CGColorRef white; s = c2mac(name); desc = CTFontDescriptorCreateWithNameAndSize(s, size); CFRelease(s); if(desc == nil) return nil; font = CTFontCreateWithFontDescriptor(desc, 0, nil); CFRelease(desc); if(font == nil) return nil; bbox = CTFontGetBoundingBox(font); x = (int)(bbox.size.width*2 + 0.99999999); fontheight(f, size, &height, &ascent); y = height; y0 = height - ascent; m = allocmemimage(Rect(0, 0, x*(hi+1-lo)+1, y+1), GREY8); if(m == nil) return nil; mc = allocmemimage(Rect(0, 0, x+1, y+1), GREY8); if(mc == nil){ freememimage(m); return nil; } memfillcolor(m, DBlack); memfillcolor(mc, DBlack); fc = malloc((hi+2 - lo) * sizeof fc[0]); sf = malloc(sizeof *sf); if(fc == nil || sf == nil) { freememimage(m); freememimage(mc); free(fc); free(sf); return nil; } fc0 = fc; color = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); ctxt = CGBitmapContextCreate(byteaddr(mc, mc->r.min), Dx(mc->r), Dy(mc->r), 8, mc->width*sizeof(u32int), color, kCGImageAlphaNone); white = CGColorCreate(color, whitef); CGColorSpaceRelease(color); if(ctxt == nil) { freememimage(m); freememimage(mc); free(fc); free(sf); return nil; } CGContextSetAllowsAntialiasing(ctxt, antialias); CGContextSetTextPosition(ctxt, 0, 0); // XXX #if OSX_VERSION >= 101400 CGContextSetAllowsFontSmoothing(ctxt, false); #endif x = 0; for(i=lo; i<=hi; i++, fc++) { char buf[20]; CFStringRef str; CFDictionaryRef attrs; CFAttributedStringRef attrString; CTLineRef line; CGRect r; CGPoint p1; CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; CFTypeRef values[] = { font, white }; sprint(buf, "%C", (Rune)mapUnicode(name, i)); str = c2mac(buf); // See https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/CoreText_Programming/LayoutOperations/LayoutOperations.html#//apple_ref/doc/uid/TP40005533-CH12-SW2 attrs = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); attrString = CFAttributedStringCreate(kCFAllocatorDefault, str, attrs); CFRelease(str); CFRelease(attrs); line = CTLineCreateWithAttributedString(attrString); CGContextSetTextPosition(ctxt, 0, y0); r = CTLineGetImageBounds(line, ctxt); memfillcolor(mc, DBlack); CTLineDraw(line, ctxt); CFRelease(line); fc->x = x; fc->top = 0; fc->bottom = Dy(m->r); // fprint(2, "printed %#x: %g %g\n", mapUnicode(i), p1.x, p1.y); p1 = CGContextGetTextPosition(ctxt); if(p1.x <= 0 || mapUnicode(name, i) == 0xfffd) { fc->width = 0; fc->left = 0; if(i == 0) { drawpjw(m, fc, x, (int)(bbox.size.width + 0.99999999), y, y - y0); x += fc->width; } continue; } memimagedraw(m, Rect(x, 0, x + p1.x, y), mc, ZP, memopaque, ZP, S); fc->width = p1.x; fc->left = 0; x += p1.x; } fc->x = x; // round up to 32-bit boundary // so that in-memory data is same // layout as in-file data. if(x == 0) x = 1; if(y == 0) y = 1; if(antialias) x += -x & 3; else x += -x & 31; m1 = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1); memimagedraw(m1, m1->r, m, m->r.min, memopaque, ZP, S); freememimage(m); freememimage(mc); sf->name = nil; sf->n = hi+1 - lo; sf->height = Dy(m1->r); sf->ascent = Dy(m1->r) - y0; sf->info = fc0; sf->bits = m1; return sf; }