commit 74dc60da74c62e07f0d63179da9724d705794a6d from: rsc date: Sun Jun 25 18:59:29 2006 UTC bye commit - 324891a5579d6f504201a6107369c64dab245a98 commit + 74dc60da74c62e07f0d63179da9724d705794a6d blob - 7ab9be19afcc6df0e7f807ba2dca598ffc9c2bc8 blob + 0d15c12d8d3152d9b1745bcb342fdf659b24715c --- src/libdraw/alloc.c +++ src/libdraw/alloc.c @@ -132,7 +132,7 @@ namedimage(Display *d, char *name) a[6+n] = 'I'; if(flushimage(d, 0) < 0) goto Error; - if(_drawmsgread(d, buf, sizeof buf) < 12*12) + if(_displayrddraw(d, buf, sizeof buf) < 12*12) goto Error; buf[12*12] = '\0'; blob - 2f67cde88a92b539fdbf7c79bb578ead82af8653 blob + 6e4d7f5c3e5424fe8371deb521129783e2b63f19 --- src/libdraw/event.c +++ src/libdraw/event.c @@ -1,28 +1,12 @@ #include +#include #include #include #include #include -typedef struct Slave Slave; -typedef struct Ebuf Ebuf; - -struct Slave -{ - int pid; - Ebuf *head; /* ueue of messages for this descriptor */ - Ebuf *tail; - int (*fn)(int, Event*, uchar*, int); -}; -struct Ebuf -{ - Ebuf *next; - int n; /* number of bytes in buf */ - uchar buf[EMAXMSG]; -}; -static Slave eslave[MAXSLAVE]; static int Skeyboard = -1; static int Smouse = -1; static int Stimer = -1; blob - 0f8cc76625af91be62d4b0a864f20ecba755d561 blob + bbce668b684ca0c7ad1db3dda92896cbdd09e9fd --- src/libdraw/init.c +++ src/libdraw/init.c @@ -11,6 +11,7 @@ static char deffontname[] = "*default*"; Screen *_screen; int debuglockdisplay = 1; +char *winsize; /* static void @@ -27,19 +28,17 @@ drawshutdown(void) */ int -initdraw(void (*error)(Display*, char*), char *fontname, char *label) +geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *label, char *windir, int ref) { Subfont *df; char buf[128]; - rfork(RFNOTEG); /* x11-event.c will postnote hangup */ - display = _initdisplay(error, label); /* sets screen too */ + if(label == nil) + label = argv0; + display = _initdisplay(error, label); if(display == nil) return -1; - lockdisplay(display); - display->screenimage = display->image; - /* * Set up default font */ @@ -53,7 +52,7 @@ initdraw(void (*error)(Display*, char*), char *fontnam return -1; } if(fontname == nil) - fontname = getenv("font"); /* leak */ + fontname = getenv("font"); /* * Build fonts with caches==depth of screen, for speed. @@ -62,32 +61,28 @@ initdraw(void (*error)(Display*, char*), char *fontnam if(fontname == nil){ snprint(buf, sizeof buf, "%d %d\n0 %d\t%s\n", df->height, df->ascent, df->n-1, deffontname); -/*BUG: Need something better for this installsubfont("*default*", df); */ +//BUG: Need something better for this installsubfont("*default*", df); font = buildfont(display, buf, deffontname); if(font == nil){ - fprint(2, "initdraw: can't open default font: %r\n"); + fprint(2, "imageinit: can't open default font: %r\n"); goto Error; } }else{ font = openfont(display, fontname); /* BUG: grey fonts */ if(font == nil){ - fprint(2, "initdraw: can't open font %s: %r\n", fontname); + fprint(2, "imageinit: can't open font %s: %r\n", fontname); goto Error; } } display->defaultfont = font; - display->white = allocimage(display, Rect(0,0,1,1), GREY1, 1, DWhite); - display->black = allocimage(display, Rect(0,0,1,1), GREY1, 1, DBlack); - if(display->white == nil || display->black == nil){ - fprint(2, "initdraw: can't allocate white and black"); - goto Error; - } - display->opaque = display->white; - display->transparent = display->black; - _screen = allocscreen(display->image, display->white, 0); + display->screenimage = display->image; /* _allocwindow wants screenimage->chan */ screen = _allocwindow(nil, _screen, display->image->r, Refnone, DWhite); + if(screen == nil){ + fprint(2, "_allocwindow: %r\n"); + goto Error; + } display->screenimage = screen; draw(screen, screen->r, display->white, nil, ZP); flushimage(display, 1); @@ -100,8 +95,167 @@ initdraw(void (*error)(Display*, char*), char *fontnam * atexit(drawshutdown); */ return 1; +} + +int +initdraw(void (*error)(Display*, char*), char *fontname, char *label) +{ + return geninitdraw("/dev", error, fontname, label, "/dev", Refnone); +} + +extern int _freeimage1(Image*); + +static Image* +getimage0(Display *d, Image *image) +{ + char info[12*12+1]; + uchar *a; + int n; + + /* + * If there's an old screen, it has id 0. The 'J' request below + * will try to install the new screen as id 0, so the old one + * must be freed first. + */ + if(image){ + _freeimage1(image); + memset(image, 0, sizeof(Image)); + } + + a = bufimage(d, 2); + a[0] = 'J'; + a[1] = 'I'; + if(flushimage(d, 0) < 0){ + fprint(2, "cannot read screen info: %r\n"); + return nil; + } + + n = _displayrddraw(d, info, sizeof info); + if(n != 12*12){ + fprint(2, "short screen info\n"); + return nil; + } + + if(image == nil){ + image = mallocz(sizeof(Image), 1); + if(image == nil){ + fprint(2, "cannot allocate image: %r\n"); + return nil; + } + } + + image->display = d; + image->id = 0; + image->chan = strtochan(info+2*12); + image->depth = chantodepth(image->chan); + image->repl = atoi(info+3*12); + image->r.min.x = atoi(info+4*12); + image->r.min.y = atoi(info+5*12); + image->r.max.x = atoi(info+6*12); + image->r.max.y = atoi(info+7*12); + image->clipr.min.x = atoi(info+8*12); + image->clipr.min.y = atoi(info+9*12); + image->clipr.max.x = atoi(info+10*12); + image->clipr.max.y = atoi(info+11*12); + return image; +} + +/* + * Attach, or possibly reattach, to window. + * If reattaching, maintain value of screen pointer. + */ +int +getwindow(Display *d, int ref) +{ + Image *i, *oi; + + /* XXX check for destroyed? */ + + /* + * Libdraw promises not to change the value of "screen", + * so we have to reuse the image structure + * memory we already have. + */ + oi = d->image; + i = getimage0(d, oi); + if(i == nil) + sysfatal("getwindow failed"); + d->image = i; + /* fprint(2, "getwindow %p -> %p\n", oi, i); */ + + freescreen(_screen); + _screen = allocscreen(i, d->white, 0); + _freeimage1(screen); + screen = _allocwindow(screen, _screen, i->r, ref, DWhite); + d->screenimage = screen; + return 0; } +Display* +_initdisplay(void (*error)(Display*, char*), char *label) +{ + Display *disp; + Image *image; + + fmtinstall('P', Pfmt); + fmtinstall('R', Rfmt); + + disp = mallocz(sizeof(Display), 1); + if(disp == nil){ + Error1: + return nil; + } + disp->srvfd = -1; + image = nil; + if(0){ + Error2: + free(image); + free(disp); + goto Error1; + } + disp->bufsize = 65500; + disp->buf = malloc(disp->bufsize+5); /* +5 for flush message */ + disp->bufp = disp->buf; + disp->error = error; + qlock(&disp->qlock); + + if(disp->buf == nil) + goto Error2; + if(0){ + Error3: + free(disp->buf); + goto Error2; + } + + if(_displaymux(disp) < 0 + || _displayconnect(disp) < 0 + || _displayinit(disp, label, winsize) < 0) + goto Error3; + if(0){ + Error4: + close(disp->srvfd); + goto Error3; + } + + image = getimage0(disp, nil); + if(image == nil) + goto Error4; + + disp->image = image; + disp->white = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DWhite); + disp->black = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DBlack); + if(disp->white == nil || disp->black == nil){ + free(disp->white); + free(disp->black); + goto Error4; + } + + disp->opaque = disp->white; + disp->transparent = disp->black; + + return disp; +} + /* * Call with d unlocked. * Note that disp->defaultfont and defaultsubfont are not freed here. @@ -131,6 +285,8 @@ closedisplay(Display *disp) freeimage(disp->white); if(disp->black) freeimage(disp->black); + if(disp->srvfd >= 0) + close(disp->srvfd); free(disp); } @@ -177,7 +333,7 @@ doflush(Display *d) if(n <= 0) return 1; - if(_drawmsgwrite(d, d->buf, n) != n){ + if(_displaywrdraw(d, d->buf, n) != n){ if(_drawdebug) fprint(2, "flushimage fail: d=%p: %r\n", d); /**/ d->bufp = d->buf; /* might as well; chance of continuing */ blob - 0a8ec010eac632e383c93e8fd20ed0b99681a5ab blob + 755ffbd327361a61847c9dbeb9f40b5c856af88b --- src/libdraw/keyboard.c +++ src/libdraw/keyboard.c @@ -4,25 +4,18 @@ #include #include - void closekeyboard(Keyboardctl *kc) { + Rune r; + if(kc == nil) return; - postnote(PNPROC, kc->pid, "kill"); +/* postnote(PNPROC, kc->pid, "kill"); */ -#ifdef BUG - /* Drain the channel */ - while(?kc->c) - <-kc->c; -#endif - - close(kc->ctlfd); - close(kc->consfd); - free(kc->file); - free(kc->c); + do; while(nbrecv(kc->c, &r) > 0); + chanfree(kc->c); free(kc); } @@ -30,29 +23,15 @@ static void _ioproc(void *arg) { - int m, n; - char buf[20]; Rune r; Keyboardctl *kc; - + kc = arg; threadsetname("kbdproc"); - kc->pid = getpid(); - n = 0; for(;;){ - while(n>0 && fullrune(buf, n)){ - m = chartorune(&r, buf); - n -= m; - memmove(buf, buf+m, n); - send(kc->c, &r); - } - m = read(kc->consfd, buf+n, sizeof buf-n); - if(m <= 0){ - yield(); /* if error is due to exiting, we'll exit here */ - fprint(2, "keyboard read error: %r\n"); - threadexits("error"); - } - n += m; + if(_displayrdkbd(display, &r) < 0) + threadexits("read error"); + send(kc->c, &r); } } @@ -60,44 +39,14 @@ Keyboardctl* initkeyboard(char *file) { Keyboardctl *kc; - char *t; kc = mallocz(sizeof(Keyboardctl), 1); if(kc == nil) return nil; - if(file == nil) - file = "/dev/cons"; - kc->file = strdup(file); - kc->consfd = open(file, ORDWR|OCEXEC); - t = malloc(strlen(file)+16); - if(kc->consfd<0 || t==nil){ -Error1: - free(kc); - return nil; - } - sprint(t, "%sctl", file); - kc->ctlfd = open(t, OWRITE|OCEXEC); - if(kc->ctlfd < 0){ - fprint(2, "initkeyboard: can't open %s: %r\n", t); -Error2: - close(kc->consfd); - free(t); - goto Error1; - } - if(ctlkeyboard(kc, "rawon") < 0){ - fprint(2, "initkeyboard: can't turn on raw mode on %s: %r\n", t); - close(kc->ctlfd); - goto Error2; - } - free(t); + USED(file); kc->c = chancreate(sizeof(Rune), 20); chansetname(kc->c, "kbdc"); - proccreate(_ioproc, kc, 4096); + proccreate(_ioproc, kc, 32*1024); return kc; } -int -ctlkeyboard(Keyboardctl *kc, char *m) -{ - return write(kc->ctlfd, m, strlen(m)); -} blob - b6ad61a73511c09d9c969629c292374b752e28bf (mode 644) blob + /dev/null --- src/libdraw/md-alloc.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include - -#define poolalloc(a, b) malloc(b) -#define poolfree(a, b) free(b) - -void -memimagemove(void *from, void *to) -{ - Memdata *md; - - md = *(Memdata**)to; - if(md->base != from){ - print("compacted data not right: #%p\n", md->base); - abort(); - } - md->base = to; - - /* if allocmemimage changes this must change too */ - md->bdata = (uchar*)md->base+sizeof(Memdata*)+sizeof(ulong); -} - -Memimage* -allocmemimaged(Rectangle r, u32int chan, Memdata *md, void *X) -{ - int d; - u32int l; - Memimage *i; - - if(Dx(r) <= 0 || Dy(r) <= 0){ - werrstr("bad rectangle %R", r); - return nil; - } - if((d = chantodepth(chan)) == 0) { - werrstr("bad channel descriptor %.8lux", chan); - return nil; - } - - l = wordsperline(r, d); - - i = mallocz(sizeof(Memimage), 1); - if(i == nil) - return nil; - - i->X = X; - i->data = md; - i->zero = sizeof(u32int)*l*r.min.y; - - if(r.min.x >= 0) - i->zero += (r.min.x*d)/8; - else - i->zero -= (-r.min.x*d+7)/8; - i->zero = -i->zero; - i->width = l; - i->r = r; - i->clipr = r; - i->flags = 0; - i->layer = nil; - i->cmap = memdefcmap; - if(memsetchan(i, chan) < 0){ - free(i); - return nil; - } - return i; -} - -Memimage* -_allocmemimage(Rectangle r, u32int chan) -{ - int d; - u32int l, nw; - uchar *p; - Memdata *md; - Memimage *i; - - if((d = chantodepth(chan)) == 0) { - werrstr("bad channel descriptor %.8lux", chan); - return nil; - } - - l = wordsperline(r, d); - nw = l*Dy(r); - md = malloc(sizeof(Memdata)); - if(md == nil) - return nil; - - md->ref = 1; - md->base = poolalloc(imagmem, sizeof(Memdata*)+(1+nw)*sizeof(ulong)); - if(md->base == nil){ - free(md); - return nil; - } - - p = (uchar*)md->base; - *(Memdata**)p = md; - p += sizeof(Memdata*); - - *(ulong*)p = getcallerpc(&r); - p += sizeof(ulong); - - /* if this changes, memimagemove must change too */ - md->bdata = p; - md->allocd = 1; - - i = allocmemimaged(r, chan, md, nil); - if(i == nil){ - poolfree(imagmem, md->base); - free(md); - return nil; - } - md->imref = i; - return i; -} - -void -_freememimage(Memimage *i) -{ - if(i == nil) - return; - if(i->data->ref-- == 1 && i->data->allocd){ - if(i->data->base) - poolfree(imagmem, i->data->base); - free(i->data); - } - free(i); -} - -/* - * Wordaddr is deprecated. - */ -u32int* -wordaddr(Memimage *i, Point p) -{ - return (u32int*) ((ulong)byteaddr(i, p) & ~(sizeof(u32int)-1)); -} - -uchar* -byteaddr(Memimage *i, Point p) -{ - uchar *a; - - a = i->data->bdata+i->zero+sizeof(u32int)*p.y*i->width; - - if(i->depth < 8){ - /* - * We need to always round down, - * but C rounds toward zero. - */ - int np; - np = 8/i->depth; - if(p.x < 0) - return a+(p.x-np+1)/np; - else - return a+p.x/np; - } - else - return a+p.x*(i->depth/8); -} - -int -memsetchan(Memimage *i, u32int chan) -{ - int d; - int t, j, k; - u32int cc; - int bytes; - - if((d = chantodepth(chan)) == 0) { - werrstr("bad channel descriptor"); - return -1; - } - - i->depth = d; - i->chan = chan; - i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes); - bytes = 1; - for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){ - t=TYPE(cc); - if(t < 0 || t >= NChan){ - werrstr("bad channel string"); - return -1; - } - if(t == CGrey) - i->flags |= Fgrey; - if(t == CAlpha) - i->flags |= Falpha; - if(t == CMap && i->cmap == nil){ - i->cmap = memdefcmap; - i->flags |= Fcmap; - } - - i->shift[t] = j; - i->mask[t] = (1<nbits[t] = NBITS(cc); - if(NBITS(cc) != 8) - bytes = 0; - } - i->nchan = k; - if(bytes) - i->flags |= Fbytes; - return 0; -} blob - df836a00e324c99a4c8f7dee7db0a0af37e81123 (mode 644) blob + /dev/null --- src/libdraw/md-arc.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include - -/* - * elarc(dst,c,a,b,t,src,sp,alpha,phi) - * draws the part of an ellipse between rays at angles alpha and alpha+phi - * measured counterclockwise from the positive x axis. other - * arguments are as for ellipse(dst,c,a,b,t,src,sp) - */ - -enum -{ - R, T, L, B /* right, top, left, bottom */ -}; - -static -Point corners[] = { - {1,1}, - {-1,1}, - {-1,-1}, - {1,-1} -}; - -static -Point p00; - -/* - * 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); -} blob - b3a8c21119b67ad4a227fbe2caa4e497b1ed1350 (mode 644) blob + /dev/null --- src/libdraw/md-arctest.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include - -extern int drawdebug; -void -main(int argc, char **argv) -{ - char cc; - 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; - - 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 -#include -#include -#include - -int -_cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - int y, bpl, c, cnt, offs; - uchar mem[NMEM], *memp, *omemp, *emem, *linep, *elinep, *u, *eu; - - if(!rectinrect(r, i->r)) - return -1; - bpl = bytesperline(r, i->depth); - u = data; - eu = data+ndata; - memp = mem; - emem = mem+NMEM; - y = r.min.y; - linep = byteaddr(i, Pt(r.min.x, y)); - elinep = linep+bpl; - for(;;){ - if(linep == elinep){ - if(++y == r.max.y) - break; - linep = byteaddr(i, Pt(r.min.x, y)); - elinep = linep+bpl; - } - if(u == eu){ /* buffer too small */ - return -1; - } - c = *u++; - if(c >= 128){ - for(cnt=c-128+1; cnt!=0 ;--cnt){ - if(u == eu){ /* buffer too small */ - return -1; - } - if(linep == elinep){ /* phase error */ - return -1; - } - *linep++ = *u; - *memp++ = *u++; - if(memp == emem) - memp = mem; - } - } - else{ - if(u == eu) /* short buffer */ - return -1; - offs = *u++ + ((c&3)<<8)+1; - if(memp-mem < offs) - omemp = memp+(NMEM-offs); - else - omemp = memp-offs; - for(cnt=(c>>2)+NMATCH; cnt!=0; --cnt){ - if(linep == elinep) /* phase error */ - return -1; - *linep++ = *omemp; - *memp++ = *omemp++; - if(omemp == emem) - omemp = mem; - if(memp == emem) - memp = mem; - } - } - } - return u-data; -} blob - 2561c3f1cd2e9309849728ab0f16e3c0fc00c504 (mode 644) blob + /dev/null --- src/libdraw/md-cmap.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * generated by mkcmap.c - */ -#include -#include -#include -#include - -static Memcmap def = { -/* cmap2rgb */ { - 0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x88,0x00,0x00,0xcc,0x00,0x44,0x00,0x00, - 0x44,0x44,0x00,0x44,0x88,0x00,0x44,0xcc,0x00,0x88,0x00,0x00,0x88,0x44,0x00,0x88, - 0x88,0x00,0x88,0xcc,0x00,0xcc,0x00,0x00,0xcc,0x44,0x00,0xcc,0x88,0x00,0xcc,0xcc, - 0x00,0xdd,0xdd,0x11,0x11,0x11,0x00,0x00,0x55,0x00,0x00,0x99,0x00,0x00,0xdd,0x00, - 0x55,0x00,0x00,0x55,0x55,0x00,0x4c,0x99,0x00,0x49,0xdd,0x00,0x99,0x00,0x00,0x99, - 0x4c,0x00,0x99,0x99,0x00,0x93,0xdd,0x00,0xdd,0x00,0x00,0xdd,0x49,0x00,0xdd,0x93, - 0x00,0xee,0x9e,0x00,0xee,0xee,0x22,0x22,0x22,0x00,0x00,0x66,0x00,0x00,0xaa,0x00, - 0x00,0xee,0x00,0x66,0x00,0x00,0x66,0x66,0x00,0x55,0xaa,0x00,0x4f,0xee,0x00,0xaa, - 0x00,0x00,0xaa,0x55,0x00,0xaa,0xaa,0x00,0x9e,0xee,0x00,0xee,0x00,0x00,0xee,0x4f, - 0x00,0xff,0x55,0x00,0xff,0xaa,0x00,0xff,0xff,0x33,0x33,0x33,0x00,0x00,0x77,0x00, - 0x00,0xbb,0x00,0x00,0xff,0x00,0x77,0x00,0x00,0x77,0x77,0x00,0x5d,0xbb,0x00,0x55, - 0xff,0x00,0xbb,0x00,0x00,0xbb,0x5d,0x00,0xbb,0xbb,0x00,0xaa,0xff,0x00,0xff,0x00, - 0x44,0x00,0x44,0x44,0x00,0x88,0x44,0x00,0xcc,0x44,0x44,0x00,0x44,0x44,0x44,0x44, - 0x44,0x88,0x44,0x44,0xcc,0x44,0x88,0x00,0x44,0x88,0x44,0x44,0x88,0x88,0x44,0x88, - 0xcc,0x44,0xcc,0x00,0x44,0xcc,0x44,0x44,0xcc,0x88,0x44,0xcc,0xcc,0x44,0x00,0x00, - 0x55,0x00,0x00,0x55,0x00,0x55,0x4c,0x00,0x99,0x49,0x00,0xdd,0x55,0x55,0x00,0x55, - 0x55,0x55,0x4c,0x4c,0x99,0x49,0x49,0xdd,0x4c,0x99,0x00,0x4c,0x99,0x4c,0x4c,0x99, - 0x99,0x49,0x93,0xdd,0x49,0xdd,0x00,0x49,0xdd,0x49,0x49,0xdd,0x93,0x49,0xdd,0xdd, - 0x4f,0xee,0xee,0x66,0x00,0x00,0x66,0x00,0x66,0x55,0x00,0xaa,0x4f,0x00,0xee,0x66, - 0x66,0x00,0x66,0x66,0x66,0x55,0x55,0xaa,0x4f,0x4f,0xee,0x55,0xaa,0x00,0x55,0xaa, - 0x55,0x55,0xaa,0xaa,0x4f,0x9e,0xee,0x4f,0xee,0x00,0x4f,0xee,0x4f,0x4f,0xee,0x9e, - 0x55,0xff,0xaa,0x55,0xff,0xff,0x77,0x00,0x00,0x77,0x00,0x77,0x5d,0x00,0xbb,0x55, - 0x00,0xff,0x77,0x77,0x00,0x77,0x77,0x77,0x5d,0x5d,0xbb,0x55,0x55,0xff,0x5d,0xbb, - 0x00,0x5d,0xbb,0x5d,0x5d,0xbb,0xbb,0x55,0xaa,0xff,0x55,0xff,0x00,0x55,0xff,0x55, - 0x88,0x00,0x88,0x88,0x00,0xcc,0x88,0x44,0x00,0x88,0x44,0x44,0x88,0x44,0x88,0x88, - 0x44,0xcc,0x88,0x88,0x00,0x88,0x88,0x44,0x88,0x88,0x88,0x88,0x88,0xcc,0x88,0xcc, - 0x00,0x88,0xcc,0x44,0x88,0xcc,0x88,0x88,0xcc,0xcc,0x88,0x00,0x00,0x88,0x00,0x44, - 0x99,0x00,0x4c,0x99,0x00,0x99,0x93,0x00,0xdd,0x99,0x4c,0x00,0x99,0x4c,0x4c,0x99, - 0x4c,0x99,0x93,0x49,0xdd,0x99,0x99,0x00,0x99,0x99,0x4c,0x99,0x99,0x99,0x93,0x93, - 0xdd,0x93,0xdd,0x00,0x93,0xdd,0x49,0x93,0xdd,0x93,0x93,0xdd,0xdd,0x99,0x00,0x00, - 0xaa,0x00,0x00,0xaa,0x00,0x55,0xaa,0x00,0xaa,0x9e,0x00,0xee,0xaa,0x55,0x00,0xaa, - 0x55,0x55,0xaa,0x55,0xaa,0x9e,0x4f,0xee,0xaa,0xaa,0x00,0xaa,0xaa,0x55,0xaa,0xaa, - 0xaa,0x9e,0x9e,0xee,0x9e,0xee,0x00,0x9e,0xee,0x4f,0x9e,0xee,0x9e,0x9e,0xee,0xee, - 0xaa,0xff,0xff,0xbb,0x00,0x00,0xbb,0x00,0x5d,0xbb,0x00,0xbb,0xaa,0x00,0xff,0xbb, - 0x5d,0x00,0xbb,0x5d,0x5d,0xbb,0x5d,0xbb,0xaa,0x55,0xff,0xbb,0xbb,0x00,0xbb,0xbb, - 0x5d,0xbb,0xbb,0xbb,0xaa,0xaa,0xff,0xaa,0xff,0x00,0xaa,0xff,0x55,0xaa,0xff,0xaa, - 0xcc,0x00,0xcc,0xcc,0x44,0x00,0xcc,0x44,0x44,0xcc,0x44,0x88,0xcc,0x44,0xcc,0xcc, - 0x88,0x00,0xcc,0x88,0x44,0xcc,0x88,0x88,0xcc,0x88,0xcc,0xcc,0xcc,0x00,0xcc,0xcc, - 0x44,0xcc,0xcc,0x88,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0xcc,0x00,0x44,0xcc,0x00,0x88, - 0xdd,0x00,0x93,0xdd,0x00,0xdd,0xdd,0x49,0x00,0xdd,0x49,0x49,0xdd,0x49,0x93,0xdd, - 0x49,0xdd,0xdd,0x93,0x00,0xdd,0x93,0x49,0xdd,0x93,0x93,0xdd,0x93,0xdd,0xdd,0xdd, - 0x00,0xdd,0xdd,0x49,0xdd,0xdd,0x93,0xdd,0xdd,0xdd,0xdd,0x00,0x00,0xdd,0x00,0x49, - 0xee,0x00,0x4f,0xee,0x00,0x9e,0xee,0x00,0xee,0xee,0x4f,0x00,0xee,0x4f,0x4f,0xee, - 0x4f,0x9e,0xee,0x4f,0xee,0xee,0x9e,0x00,0xee,0x9e,0x4f,0xee,0x9e,0x9e,0xee,0x9e, - 0xee,0xee,0xee,0x00,0xee,0xee,0x4f,0xee,0xee,0x9e,0xee,0xee,0xee,0xee,0x00,0x00, - 0xff,0x00,0x00,0xff,0x00,0x55,0xff,0x00,0xaa,0xff,0x00,0xff,0xff,0x55,0x00,0xff, - 0x55,0x55,0xff,0x55,0xaa,0xff,0x55,0xff,0xff,0xaa,0x00,0xff,0xaa,0x55,0xff,0xaa, - 0xaa,0xff,0xaa,0xff,0xff,0xff,0x00,0xff,0xff,0x55,0xff,0xff,0xaa,0xff,0xff,0xff, -}, -/* rgb2cmap */ { - 0x00,0x00,0x11,0x01,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x00,0x11,0x11,0x01,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x11,0x11,0x11,0x01,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x17,0x07,0x07,0x18,0x18,0x29, - 0x04,0x04,0x04,0x05,0x05,0x05,0x16,0x06,0x06,0x17,0x28,0x07,0x07,0x18,0x29,0x3a, - 0x15,0x15,0x15,0x05,0x05,0x16,0x16,0x06,0x06,0x17,0x28,0x39,0x07,0x18,0x29,0x3a, - 0x26,0x26,0x26,0x05,0x16,0x16,0x27,0x27,0x38,0x28,0x28,0x39,0x39,0x29,0x29,0x3a, - 0x37,0x37,0x37,0x09,0x09,0x09,0x27,0x38,0x0a,0x0a,0x39,0x0b,0x0b,0x0b,0x1c,0x3a, - 0x08,0x08,0x08,0x09,0x09,0x09,0x38,0x0a,0x0a,0x0a,0x1b,0x0b,0x0b,0x1c,0x1c,0x2d, - 0x19,0x19,0x19,0x09,0x1a,0x1a,0x2b,0x0a,0x0a,0x1b,0x1b,0x0b,0x0b,0x1c,0x2d,0x3e, - 0x2a,0x2a,0x2a,0x1a,0x2b,0x2b,0x2b,0x3c,0x1b,0x1b,0x2c,0x2c,0x3d,0x2d,0x2d,0x3e, - 0x3b,0x3b,0x3b,0x0d,0x0d,0x3c,0x3c,0x0e,0x0e,0x0e,0x2c,0x3d,0x0f,0x0f,0x3e,0x3e, - 0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x3c,0x0e,0x0e,0x0e,0x3d,0x0f,0x0f,0x0f,0x10,0x3e, - 0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x2f,0x0e,0x1f,0x1f,0x20,0x0f,0x0f,0x10,0x10,0x21, - 0x2e,0x2e,0x2e,0x1e,0x2f,0x2f,0x2f,0x1f,0x1f,0x20,0x20,0x31,0x10,0x10,0x21,0x21, - 0x3f,0x3f,0x3f,0x2f,0x30,0x30,0x30,0x30,0x20,0x31,0x31,0x31,0x31,0x21,0x21,0x32, - 0x00,0x11,0x11,0x01,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x11,0x11,0x11,0x01,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x11,0x11,0x22,0x22,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x04,0x04,0x22,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x17,0x07,0x07,0x18,0x18,0x29, - 0x04,0x04,0x04,0x05,0x05,0x05,0x16,0x06,0x06,0x17,0x28,0x07,0x07,0x18,0x29,0x3a, - 0x15,0x15,0x15,0x05,0x05,0x16,0x16,0x06,0x06,0x17,0x28,0x39,0x07,0x18,0x29,0x3a, - 0x26,0x26,0x26,0x05,0x16,0x16,0x27,0x27,0x38,0x28,0x28,0x39,0x39,0x29,0x29,0x3a, - 0x37,0x37,0x37,0x09,0x09,0x09,0x27,0x38,0x0a,0x0a,0x39,0x0b,0x0b,0x0b,0x1c,0x3a, - 0x08,0x08,0x08,0x09,0x09,0x09,0x38,0x0a,0x0a,0x0a,0x1b,0x0b,0x0b,0x1c,0x1c,0x2d, - 0x19,0x19,0x19,0x09,0x1a,0x1a,0x2b,0x0a,0x0a,0x1b,0x1b,0x0b,0x0b,0x1c,0x2d,0x3e, - 0x2a,0x2a,0x2a,0x1a,0x2b,0x2b,0x2b,0x3c,0x1b,0x1b,0x2c,0x2c,0x3d,0x2d,0x2d,0x3e, - 0x3b,0x3b,0x3b,0x0d,0x0d,0x3c,0x3c,0x0e,0x0e,0x0e,0x2c,0x3d,0x0f,0x0f,0x3e,0x3e, - 0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x3c,0x0e,0x0e,0x0e,0x3d,0x0f,0x0f,0x0f,0x10,0x3e, - 0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x2f,0x0e,0x1f,0x1f,0x20,0x0f,0x0f,0x10,0x10,0x21, - 0x2e,0x2e,0x2e,0x1e,0x2f,0x2f,0x2f,0x1f,0x1f,0x20,0x20,0x31,0x10,0x10,0x21,0x21, - 0x3f,0x3f,0x3f,0x2f,0x30,0x30,0x30,0x30,0x20,0x31,0x31,0x31,0x31,0x21,0x21,0x32, - 0x11,0x11,0x11,0x01,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x11,0x11,0x22,0x22,0x01,0x12,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x11,0x22,0x22,0x22,0x33,0x33,0x23,0x34,0x02,0x13,0x24,0x35,0x03,0x14,0x25,0x36, - 0x04,0x22,0x22,0x33,0x33,0x33,0x05,0x06,0x06,0x06,0x17,0x07,0x07,0x18,0x18,0x29, - 0x04,0x04,0x33,0x33,0x33,0x05,0x16,0x06,0x06,0x17,0x28,0x07,0x07,0x18,0x29,0x3a, - 0x15,0x15,0x33,0x33,0x05,0x16,0x16,0x06,0x06,0x17,0x28,0x39,0x07,0x18,0x29,0x3a, - 0x26,0x26,0x26,0x05,0x16,0x16,0x27,0x27,0x38,0x28,0x28,0x39,0x39,0x29,0x29,0x3a, - 0x37,0x37,0x37,0x09,0x09,0x09,0x27,0x38,0x0a,0x0a,0x39,0x0b,0x0b,0x0b,0x1c,0x3a, - 0x08,0x08,0x08,0x09,0x09,0x09,0x38,0x0a,0x0a,0x0a,0x1b,0x0b,0x0b,0x1c,0x1c,0x2d, - 0x19,0x19,0x19,0x09,0x1a,0x1a,0x2b,0x0a,0x0a,0x1b,0x1b,0x0b,0x0b,0x1c,0x2d,0x3e, - 0x2a,0x2a,0x2a,0x1a,0x2b,0x2b,0x2b,0x3c,0x1b,0x1b,0x2c,0x2c,0x3d,0x2d,0x2d,0x3e, - 0x3b,0x3b,0x3b,0x0d,0x0d,0x3c,0x3c,0x0e,0x0e,0x0e,0x2c,0x3d,0x0f,0x0f,0x3e,0x3e, - 0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x3c,0x0e,0x0e,0x0e,0x3d,0x0f,0x0f,0x0f,0x10,0x3e, - 0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x2f,0x0e,0x1f,0x1f,0x20,0x0f,0x0f,0x10,0x10,0x21, - 0x2e,0x2e,0x2e,0x1e,0x2f,0x2f,0x2f,0x1f,0x1f,0x20,0x20,0x31,0x10,0x10,0x21,0x21, - 0x3f,0x3f,0x3f,0x2f,0x30,0x30,0x30,0x30,0x20,0x31,0x31,0x31,0x31,0x21,0x21,0x32, - 0x4f,0x4f,0x22,0x40,0x40,0x40,0x40,0x41,0x41,0x41,0x52,0x42,0x42,0x53,0x53,0x64, - 0x4f,0x22,0x22,0x22,0x40,0x40,0x40,0x41,0x41,0x41,0x52,0x42,0x42,0x53,0x53,0x64, - 0x22,0x22,0x22,0x33,0x33,0x33,0x40,0x41,0x41,0x41,0x52,0x42,0x42,0x53,0x53,0x64, - 0x43,0x22,0x33,0x33,0x33,0x44,0x44,0x45,0x45,0x45,0x56,0x46,0x46,0x46,0x57,0x68, - 0x43,0x43,0x33,0x33,0x44,0x44,0x44,0x45,0x45,0x45,0x56,0x46,0x46,0x57,0x57,0x68, - 0x43,0x43,0x33,0x44,0x44,0x44,0x55,0x45,0x45,0x56,0x56,0x46,0x46,0x57,0x68,0x68, - 0x43,0x43,0x43,0x44,0x44,0x55,0x55,0x45,0x45,0x56,0x67,0x46,0x46,0x57,0x68,0x79, - 0x47,0x47,0x47,0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x4a,0x4a,0x4a,0x5b,0x79, - 0x47,0x47,0x47,0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x5a,0x4a,0x4a,0x4a,0x5b,0x6c, - 0x47,0x47,0x47,0x48,0x48,0x59,0x59,0x49,0x49,0x5a,0x5a,0x4a,0x4a,0x5b,0x5b,0x6c, - 0x58,0x58,0x58,0x59,0x59,0x59,0x6a,0x49,0x5a,0x5a,0x6b,0x6b,0x5b,0x5b,0x6c,0x7d, - 0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x6b,0x4e,0x4e,0x4e,0x6c,0x7d, - 0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x5e,0x4e,0x4e,0x4e,0x5f,0x5f, - 0x5c,0x5c,0x5c,0x4c,0x5d,0x5d,0x5d,0x4d,0x4d,0x5e,0x5e,0x4e,0x4e,0x5f,0x5f,0x60, - 0x5c,0x5c,0x5c,0x5d,0x5d,0x6e,0x6e,0x5e,0x5e,0x5e,0x6f,0x6f,0x5f,0x5f,0x60,0x60, - 0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x7f,0x7f,0x6f,0x6f,0x70,0x70,0x5f,0x60,0x60,0x71, - 0x4f,0x4f,0x40,0x40,0x40,0x40,0x51,0x41,0x41,0x52,0x63,0x42,0x42,0x53,0x64,0x75, - 0x4f,0x4f,0x22,0x40,0x40,0x40,0x51,0x41,0x41,0x52,0x63,0x42,0x42,0x53,0x64,0x75, - 0x43,0x22,0x33,0x33,0x33,0x40,0x51,0x41,0x41,0x52,0x63,0x42,0x42,0x53,0x64,0x75, - 0x43,0x43,0x33,0x33,0x44,0x44,0x44,0x45,0x45,0x45,0x56,0x46,0x46,0x57,0x57,0x68, - 0x43,0x43,0x33,0x44,0x44,0x44,0x55,0x45,0x45,0x56,0x56,0x46,0x46,0x57,0x68,0x68, - 0x43,0x43,0x43,0x44,0x44,0x55,0x55,0x45,0x45,0x56,0x67,0x46,0x46,0x57,0x68,0x79, - 0x54,0x54,0x54,0x44,0x55,0x55,0x55,0x45,0x56,0x56,0x67,0x78,0x78,0x57,0x68,0x79, - 0x47,0x47,0x47,0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x4a,0x4a,0x4a,0x5b,0x79, - 0x47,0x47,0x47,0x48,0x48,0x48,0x59,0x49,0x49,0x49,0x5a,0x4a,0x4a,0x5b,0x5b,0x6c, - 0x58,0x58,0x58,0x48,0x59,0x59,0x59,0x49,0x49,0x5a,0x5a,0x4a,0x4a,0x5b,0x6c,0x6c, - 0x69,0x69,0x69,0x59,0x59,0x6a,0x6a,0x49,0x5a,0x5a,0x6b,0x6b,0x5b,0x5b,0x6c,0x7d, - 0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x7b,0x4d,0x4d,0x4d,0x6b,0x4e,0x4e,0x4e,0x7d,0x7d, - 0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x7b,0x4d,0x4d,0x4d,0x5e,0x4e,0x4e,0x4e,0x5f,0x7d, - 0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5d,0x4d,0x5e,0x5e,0x5e,0x4e,0x4e,0x5f,0x5f,0x60, - 0x6d,0x6d,0x6d,0x5d,0x6e,0x6e,0x6e,0x5e,0x5e,0x6f,0x6f,0x70,0x5f,0x5f,0x60,0x60, - 0x7e,0x7e,0x7e,0x6e,0x6e,0x7f,0x7f,0x7f,0x6f,0x6f,0x70,0x70,0x70,0x60,0x60,0x71, - 0x50,0x50,0x50,0x40,0x40,0x51,0x51,0x41,0x41,0x52,0x63,0x74,0x42,0x53,0x64,0x75, - 0x50,0x50,0x50,0x40,0x40,0x51,0x51,0x41,0x41,0x52,0x63,0x74,0x42,0x53,0x64,0x75, - 0x50,0x50,0x33,0x33,0x40,0x51,0x51,0x41,0x41,0x52,0x63,0x74,0x42,0x53,0x64,0x75, - 0x43,0x43,0x33,0x44,0x44,0x44,0x55,0x45,0x45,0x56,0x56,0x46,0x46,0x57,0x68,0x68, - 0x43,0x43,0x43,0x44,0x44,0x55,0x55,0x45,0x45,0x56,0x67,0x46,0x46,0x57,0x68,0x79, - 0x54,0x54,0x54,0x44,0x55,0x55,0x55,0x45,0x56,0x56,0x67,0x78,0x78,0x57,0x68,0x79, - 0x54,0x54,0x54,0x55,0x55,0x55,0x66,0x66,0x56,0x67,0x67,0x78,0x78,0x68,0x68,0x79, - 0x47,0x47,0x47,0x48,0x48,0x48,0x66,0x49,0x49,0x49,0x78,0x78,0x4a,0x4a,0x5b,0x79, - 0x47,0x47,0x47,0x48,0x48,0x59,0x59,0x49,0x49,0x5a,0x5a,0x4a,0x4a,0x5b,0x6c,0x6c, - 0x58,0x58,0x58,0x59,0x59,0x59,0x6a,0x49,0x5a,0x5a,0x6b,0x6b,0x5b,0x5b,0x6c,0x7d, - 0x69,0x69,0x69,0x59,0x6a,0x6a,0x6a,0x7b,0x5a,0x6b,0x6b,0x6b,0x7c,0x6c,0x6c,0x7d, - 0x7a,0x7a,0x7a,0x4c,0x4c,0x7b,0x7b,0x7b,0x4d,0x6b,0x6b,0x7c,0x7c,0x4e,0x7d,0x7d, - 0x4b,0x4b,0x4b,0x4c,0x4c,0x7b,0x7b,0x4d,0x4d,0x5e,0x7c,0x7c,0x4e,0x5f,0x5f,0x7d, - 0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x6e,0x4d,0x5e,0x5e,0x6f,0x4e,0x5f,0x5f,0x60,0x60, - 0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6e,0x5e,0x6f,0x6f,0x6f,0x70,0x5f,0x60,0x60,0x71, - 0x7e,0x7e,0x7e,0x6e,0x7f,0x7f,0x7f,0x7f,0x6f,0x70,0x70,0x70,0x70,0x60,0x71,0x71, - 0x61,0x61,0x61,0x40,0x51,0x51,0x62,0x62,0x73,0x63,0x63,0x74,0x74,0x64,0x64,0x75, - 0x61,0x61,0x61,0x40,0x51,0x51,0x62,0x62,0x73,0x63,0x63,0x74,0x74,0x64,0x64,0x75, - 0x61,0x61,0x61,0x40,0x51,0x51,0x62,0x62,0x73,0x63,0x63,0x74,0x74,0x64,0x64,0x75, - 0x43,0x43,0x43,0x44,0x44,0x55,0x55,0x45,0x45,0x56,0x67,0x46,0x46,0x57,0x68,0x79, - 0x54,0x54,0x54,0x44,0x55,0x55,0x55,0x45,0x56,0x56,0x67,0x78,0x78,0x57,0x68,0x79, - 0x54,0x54,0x54,0x55,0x55,0x55,0x66,0x66,0x56,0x67,0x67,0x78,0x78,0x68,0x68,0x79, - 0x65,0x65,0x65,0x55,0x55,0x66,0x66,0x66,0x77,0x67,0x78,0x78,0x78,0x78,0x79,0x79, - 0x65,0x65,0x65,0x48,0x48,0x66,0x66,0x77,0x77,0x77,0x78,0x78,0x78,0x5b,0x79,0x79, - 0x76,0x76,0x76,0x48,0x59,0x59,0x77,0x77,0x77,0x5a,0x5a,0x4a,0x4a,0x5b,0x6c,0x6c, - 0x69,0x69,0x69,0x59,0x59,0x6a,0x6a,0x77,0x5a,0x5a,0x6b,0x6b,0x5b,0x6c,0x6c,0x7d, - 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x7b,0x7b,0x5a,0x6b,0x6b,0x7c,0x7c,0x6c,0x7d,0x7d, - 0x7a,0x7a,0x7a,0x4c,0x7b,0x7b,0x7b,0x7b,0x4d,0x6b,0x7c,0x7c,0x7c,0x7c,0x7d,0x7d, - 0x7a,0x7a,0x7a,0x4c,0x7b,0x7b,0x7b,0x7b,0x4d,0x5e,0x7c,0x7c,0x7c,0x5f,0x5f,0x7d, - 0x6d,0x6d,0x6d,0x5d,0x5d,0x6e,0x7b,0x5e,0x5e,0x6f,0x6f,0x7c,0x5f,0x5f,0x60,0x60, - 0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x7f,0x7f,0x6f,0x6f,0x70,0x70,0x5f,0x60,0x60,0x71, - 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x6f,0x70,0x70,0x70,0x70,0x60,0x71,0x71, - 0x72,0x72,0x72,0x8f,0x8f,0x62,0x62,0x73,0x73,0x80,0x74,0x81,0x81,0x81,0x92,0x75, - 0x72,0x72,0x72,0x8f,0x8f,0x62,0x62,0x73,0x73,0x80,0x74,0x81,0x81,0x81,0x92,0x75, - 0x72,0x72,0x72,0x83,0x83,0x62,0x62,0x73,0x73,0x80,0x74,0x81,0x81,0x81,0x92,0x75, - 0x82,0x82,0x82,0x83,0x83,0x83,0x83,0x84,0x84,0x84,0x84,0x85,0x85,0x85,0x96,0x79, - 0x82,0x82,0x82,0x83,0x83,0x83,0x66,0x84,0x84,0x84,0x67,0x85,0x85,0x85,0x96,0x79, - 0x65,0x65,0x65,0x83,0x83,0x66,0x66,0x66,0x84,0x84,0x78,0x78,0x85,0x85,0x96,0x79, - 0x65,0x65,0x65,0x83,0x66,0x66,0x66,0x77,0x77,0x77,0x78,0x78,0x78,0x96,0x79,0x79, - 0x76,0x76,0x76,0x87,0x87,0x66,0x77,0x77,0x77,0x88,0x78,0x89,0x89,0x89,0x89,0x79, - 0x76,0x76,0x76,0x87,0x87,0x87,0x77,0x77,0x88,0x88,0x88,0x89,0x89,0x89,0x9a,0x9a, - 0x86,0x86,0x86,0x87,0x87,0x87,0x77,0x88,0x88,0x88,0x6b,0x89,0x89,0x9a,0x9a,0x7d, - 0x7a,0x7a,0x7a,0x87,0x6a,0x7b,0x7b,0x7b,0x88,0x6b,0x6b,0x7c,0x7c,0x9a,0x7d,0x7d, - 0x8a,0x8a,0x8a,0x8b,0x8b,0x7b,0x7b,0x8c,0x8c,0x8c,0x7c,0x7c,0x8d,0x8d,0x7d,0x7d, - 0x8a,0x8a,0x8a,0x8b,0x8b,0x8b,0x7b,0x8c,0x8c,0x8c,0x7c,0x8d,0x8d,0x8d,0x9e,0x9e, - 0x8a,0x8a,0x8a,0x8b,0x8b,0x8b,0x9c,0x8c,0x8c,0x9d,0x9d,0x8d,0x8d,0x9e,0x9e,0x9e, - 0x9b,0x9b,0x9b,0x9c,0x9c,0x9c,0x7f,0x8c,0x9d,0x9d,0x70,0x70,0x9e,0x9e,0x9e,0x71, - 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x9d,0x70,0x70,0x70,0x9e,0x9e,0x71,0x71, - 0x8e,0x8e,0x8e,0x8f,0x8f,0x8f,0x73,0x73,0x80,0x80,0x91,0x81,0x81,0x92,0x92,0xa3, - 0x8e,0x8e,0x8e,0x8f,0x8f,0x8f,0x73,0x73,0x80,0x80,0x91,0x81,0x81,0x92,0x92,0xa3, - 0x82,0x82,0x82,0x83,0x83,0x83,0x73,0x73,0x80,0x80,0x91,0x81,0x81,0x92,0x92,0xa3, - 0x82,0x82,0x82,0x83,0x83,0x83,0x83,0x84,0x84,0x84,0x95,0x85,0x85,0x85,0x96,0xa7, - 0x82,0x82,0x82,0x83,0x83,0x83,0x94,0x84,0x84,0x84,0x95,0x85,0x85,0x96,0x96,0xa7, - 0x82,0x82,0x82,0x83,0x83,0x94,0x94,0x84,0x84,0x95,0x95,0x85,0x85,0x96,0xa7,0xa7, - 0x76,0x76,0x76,0x83,0x94,0x94,0x77,0x77,0x77,0x95,0x95,0x85,0x85,0x96,0xa7,0xa7, - 0x76,0x76,0x76,0x87,0x87,0x87,0x77,0x77,0x88,0x88,0x88,0x89,0x89,0x89,0x9a,0x9a, - 0x86,0x86,0x86,0x87,0x87,0x87,0x77,0x88,0x88,0x88,0x99,0x89,0x89,0x9a,0x9a,0xab, - 0x86,0x86,0x86,0x87,0x87,0x98,0x98,0x88,0x88,0x99,0x99,0x89,0x89,0x9a,0x9a,0xab, - 0x97,0x97,0x97,0x98,0x98,0x98,0x98,0x88,0x99,0x99,0x99,0x89,0x9a,0x9a,0xab,0xab, - 0x8a,0x8a,0x8a,0x8b,0x8b,0x8b,0x8b,0x8c,0x8c,0x8c,0x8c,0x8d,0x8d,0x8d,0xab,0xbc, - 0x8a,0x8a,0x8a,0x8b,0x8b,0x8b,0x8b,0x8c,0x8c,0x8c,0x9d,0x8d,0x8d,0x8d,0x9e,0x9e, - 0x9b,0x9b,0x9b,0x8b,0x9c,0x9c,0x9c,0x8c,0x9d,0x9d,0x9d,0x8d,0x8d,0x9e,0x9e,0xaf, - 0x9b,0x9b,0x9b,0x9c,0x9c,0xad,0xad,0x9d,0x9d,0x9d,0xae,0xae,0x9e,0x9e,0xaf,0xaf, - 0xac,0xac,0xac,0xad,0xad,0xad,0xad,0x9d,0xae,0xae,0xae,0xbf,0x9e,0xaf,0xaf,0xaf, - 0x9f,0x9f,0x9f,0x8f,0x90,0x90,0xa1,0x80,0x80,0x91,0x91,0x81,0x81,0x92,0xa3,0xb4, - 0x9f,0x9f,0x9f,0x8f,0x90,0x90,0xa1,0x80,0x80,0x91,0x91,0x81,0x81,0x92,0xa3,0xb4, - 0x9f,0x9f,0x9f,0x83,0x90,0x90,0xa1,0x80,0x80,0x91,0x91,0x81,0x81,0x92,0xa3,0xb4, - 0x82,0x82,0x82,0x83,0x83,0x94,0x94,0x84,0x84,0x95,0x95,0x85,0x85,0x96,0x96,0xa7, - 0x93,0x93,0x93,0x83,0x94,0x94,0x94,0x84,0x84,0x95,0x95,0x85,0x85,0x96,0xa7,0xa7, - 0x93,0x93,0x93,0x94,0x94,0x94,0xa5,0x84,0x95,0x95,0xa6,0xa6,0x96,0x96,0xa7,0xb8, - 0xa4,0xa4,0xa4,0x94,0x94,0xa5,0xa5,0x77,0x95,0x95,0xa6,0xa6,0x96,0xa7,0xa7,0xb8, - 0x86,0x86,0x86,0x87,0x87,0x87,0x77,0x88,0x88,0x88,0x99,0x89,0x89,0x9a,0x9a,0xb8, - 0x86,0x86,0x86,0x87,0x87,0x98,0x98,0x88,0x88,0x99,0x99,0x89,0x89,0x9a,0x9a,0xab, - 0x97,0x97,0x97,0x98,0x98,0x98,0x98,0x88,0x99,0x99,0x99,0x89,0x9a,0x9a,0xab,0xab, - 0x97,0x97,0x97,0x98,0x98,0xa9,0xa9,0x99,0x99,0x99,0xaa,0xaa,0x9a,0xab,0xab,0xbc, - 0x8a,0x8a,0x8a,0x8b,0x8b,0xa9,0xa9,0x8c,0x8c,0x8c,0xaa,0x8d,0x8d,0x8d,0xab,0xbc, - 0x8a,0x8a,0x8a,0x8b,0x8b,0x9c,0x9c,0x8c,0x8c,0x9d,0x9d,0x8d,0x8d,0x9e,0x9e,0xbc, - 0x9b,0x9b,0x9b,0x9c,0x9c,0x9c,0xad,0x9d,0x9d,0x9d,0xae,0x8d,0x9e,0x9e,0xaf,0xaf, - 0xac,0xac,0xac,0x9c,0xad,0xad,0xad,0x9d,0x9d,0xae,0xae,0xae,0x9e,0xaf,0xaf,0xaf, - 0xbd,0xbd,0xbd,0xad,0xad,0xbe,0xbe,0xbe,0xae,0xae,0xbf,0xbf,0xbf,0xaf,0xaf,0xb0, - 0xa0,0xa0,0xa0,0x90,0xa1,0xa1,0xa1,0xb2,0x91,0x91,0xa2,0xa2,0xb3,0xa3,0xa3,0xb4, - 0xa0,0xa0,0xa0,0x90,0xa1,0xa1,0xa1,0xb2,0x91,0x91,0xa2,0xa2,0xb3,0xa3,0xa3,0xb4, - 0xa0,0xa0,0xa0,0x90,0xa1,0xa1,0xa1,0xb2,0x91,0x91,0xa2,0xa2,0xb3,0xa3,0xa3,0xb4, - 0x93,0x93,0x93,0x94,0x94,0x94,0xa5,0x84,0x95,0x95,0xa6,0xa6,0x96,0x96,0xa7,0xb8, - 0xa4,0xa4,0xa4,0x94,0x94,0xa5,0xa5,0x84,0x95,0x95,0xa6,0xa6,0x96,0x96,0xa7,0xb8, - 0xa4,0xa4,0xa4,0x94,0xa5,0xa5,0xa5,0xb6,0x95,0xa6,0xa6,0xa6,0xb7,0xa7,0xa7,0xb8, - 0xa4,0xa4,0xa4,0xa5,0xa5,0xa5,0xb6,0xb6,0x95,0xa6,0xa6,0xb7,0xb7,0xa7,0xb8,0xb8, - 0xb5,0xb5,0xb5,0x87,0x87,0xb6,0xb6,0xb6,0x88,0x99,0xa6,0xb7,0xb7,0x9a,0xb8,0xb8, - 0x97,0x97,0x97,0x98,0x98,0x98,0x98,0x88,0x99,0x99,0x99,0x89,0x9a,0x9a,0xab,0xab, - 0x97,0x97,0x97,0x98,0x98,0xa9,0xa9,0x99,0x99,0x99,0xaa,0xaa,0x9a,0xab,0xab,0xbc, - 0xa8,0xa8,0xa8,0xa9,0xa9,0xa9,0xa9,0xa9,0x99,0xaa,0xaa,0xaa,0xbb,0xab,0xab,0xbc, - 0xa8,0xa8,0xa8,0xa9,0xa9,0xa9,0xba,0xba,0x8c,0xaa,0xaa,0xbb,0xbb,0xab,0xbc,0xbc, - 0xb9,0xb9,0xb9,0x9c,0x9c,0xba,0xba,0xba,0x9d,0x9d,0xbb,0xbb,0xbb,0x9e,0x9e,0xbc, - 0xac,0xac,0xac,0x9c,0x9c,0xad,0xad,0x9d,0x9d,0xae,0xae,0xae,0x9e,0x9e,0xaf,0xaf, - 0xac,0xac,0xac,0xad,0xad,0xad,0xbe,0xbe,0xae,0xae,0xae,0xbf,0x9e,0xaf,0xaf,0xb0, - 0xbd,0xbd,0xbd,0xbe,0xbe,0xbe,0xbe,0xbe,0xae,0xbf,0xbf,0xbf,0xbf,0xaf,0xb0,0xb0, - 0xb1,0xb1,0xb1,0xce,0xce,0xb2,0xb2,0xcf,0xcf,0xa2,0xa2,0xb3,0xb3,0xc0,0xb4,0xb4, - 0xb1,0xb1,0xb1,0xce,0xce,0xb2,0xb2,0xcf,0xcf,0xa2,0xa2,0xb3,0xb3,0xc0,0xb4,0xb4, - 0xb1,0xb1,0xb1,0xc2,0xc2,0xb2,0xb2,0xc3,0xc3,0xa2,0xa2,0xb3,0xb3,0xc0,0xb4,0xb4, - 0xc1,0xc1,0xc1,0xc2,0xc2,0xc2,0xa5,0xc3,0xc3,0xc3,0xa6,0xc4,0xc4,0xc4,0xa7,0xb8, - 0xc1,0xc1,0xc1,0xc2,0xc2,0xa5,0xb6,0xc3,0xc3,0xc3,0xa6,0xc4,0xc4,0xc4,0xb8,0xb8, - 0xb5,0xb5,0xb5,0xc2,0xa5,0xb6,0xb6,0xb6,0xc3,0xa6,0xa6,0xb7,0xb7,0xc4,0xb8,0xb8, - 0xb5,0xb5,0xb5,0xa5,0xb6,0xb6,0xb6,0xb6,0xc3,0xa6,0xb7,0xb7,0xb7,0xb7,0xb8,0xb8, - 0xc5,0xc5,0xc5,0xc6,0xc6,0xb6,0xb6,0xc7,0xc7,0xc7,0xb7,0xb7,0xc8,0xc8,0xb8,0xb8, - 0xc5,0xc5,0xc5,0xc6,0xc6,0xc6,0xc6,0xc7,0xc7,0xc7,0xaa,0xc8,0xc8,0xc8,0xab,0xbc, - 0xa8,0xa8,0xa8,0xc6,0xc6,0xa9,0xa9,0xc7,0xc7,0xaa,0xaa,0xaa,0xc8,0xc8,0xab,0xbc, - 0xa8,0xa8,0xa8,0xa9,0xa9,0xa9,0xba,0xba,0xaa,0xaa,0xaa,0xbb,0xbb,0xab,0xbc,0xbc, - 0xb9,0xb9,0xb9,0xca,0xca,0xba,0xba,0xba,0xcb,0xaa,0xbb,0xbb,0xbb,0xcc,0xbc,0xbc, - 0xb9,0xb9,0xb9,0xca,0xca,0xba,0xba,0xcb,0xcb,0xcb,0xbb,0xbb,0xcc,0xcc,0xcc,0xbc, - 0xc9,0xc9,0xc9,0xca,0xca,0xca,0xba,0xcb,0xcb,0xcb,0xae,0xcc,0xcc,0xcc,0xaf,0xaf, - 0xbd,0xbd,0xbd,0xad,0xbe,0xbe,0xbe,0xbe,0xae,0xae,0xbf,0xbf,0xcc,0xaf,0xaf,0xb0, - 0xbd,0xbd,0xbd,0xbe,0xbe,0xbe,0xbe,0xbe,0xbf,0xbf,0xbf,0xbf,0xbf,0xaf,0xb0,0xb0, - 0xcd,0xcd,0xcd,0xce,0xce,0xce,0xb2,0xcf,0xcf,0xcf,0xb3,0xb3,0xc0,0xc0,0xd1,0xb4, - 0xcd,0xcd,0xcd,0xce,0xce,0xce,0xb2,0xcf,0xcf,0xcf,0xb3,0xb3,0xc0,0xc0,0xd1,0xb4, - 0xc1,0xc1,0xc1,0xc2,0xc2,0xc2,0xb2,0xc3,0xc3,0xc3,0xb3,0xb3,0xc0,0xc0,0xd1,0xb4, - 0xc1,0xc1,0xc1,0xc2,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3,0xd4,0xc4,0xc4,0xc4,0xd5,0xd5, - 0xc1,0xc1,0xc1,0xc2,0xc2,0xc2,0xb6,0xc3,0xc3,0xc3,0xd4,0xc4,0xc4,0xc4,0xd5,0xb8, - 0xc1,0xc1,0xc1,0xc2,0xc2,0xb6,0xb6,0xc3,0xc3,0xd4,0xb7,0xb7,0xc4,0xd5,0xd5,0xb8, - 0xb5,0xb5,0xb5,0xc2,0xb6,0xb6,0xb6,0xb6,0xc3,0xd4,0xb7,0xb7,0xb7,0xd5,0xd5,0xb8, - 0xc5,0xc5,0xc5,0xc6,0xc6,0xc6,0xb6,0xc7,0xc7,0xc7,0xb7,0xc8,0xc8,0xc8,0xd9,0xd9, - 0xc5,0xc5,0xc5,0xc6,0xc6,0xc6,0xc6,0xc7,0xc7,0xc7,0xd8,0xc8,0xc8,0xc8,0xd9,0xd9, - 0xc5,0xc5,0xc5,0xc6,0xc6,0xd7,0xd7,0xc7,0xc7,0xd8,0xd8,0xc8,0xc8,0xd9,0xd9,0xbc, - 0xb9,0xb9,0xb9,0xd7,0xd7,0xba,0xba,0xba,0xd8,0xd8,0xbb,0xbb,0xbb,0xd9,0xd9,0xbc, - 0xb9,0xb9,0xb9,0xca,0xca,0xba,0xba,0xcb,0xcb,0xcb,0xbb,0xbb,0xcc,0xcc,0xcc,0xbc, - 0xc9,0xc9,0xc9,0xca,0xca,0xca,0xba,0xcb,0xcb,0xcb,0xbb,0xcc,0xcc,0xcc,0xdd,0xdd, - 0xc9,0xc9,0xc9,0xca,0xca,0xdb,0xdb,0xcb,0xcb,0xdc,0xdc,0xcc,0xcc,0xdd,0xdd,0xdd, - 0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdb,0xdc,0xdc,0xdc,0xdc,0xcc,0xdd,0xdd,0xdd,0xb0, - 0xbd,0xbd,0xbd,0xdb,0xbe,0xbe,0xbe,0xdc,0xdc,0xbf,0xbf,0xbf,0xdd,0xdd,0xb0,0xb0, - 0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xcf,0xd0,0xd0,0xe1,0xc0,0xc0,0xd1,0xd1,0xe2, - 0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xcf,0xd0,0xd0,0xe1,0xc0,0xc0,0xd1,0xd1,0xe2, - 0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xc3,0xd0,0xd0,0xe1,0xc0,0xc0,0xd1,0xd1,0xe2, - 0xd2,0xd2,0xd2,0xc2,0xd3,0xd3,0xd3,0xc3,0xc3,0xd4,0xd4,0xc4,0xc4,0xd5,0xd5,0xe6, - 0xd2,0xd2,0xd2,0xd3,0xd3,0xd3,0xd3,0xc3,0xd4,0xd4,0xd4,0xc4,0xc4,0xd5,0xd5,0xe6, - 0xd2,0xd2,0xd2,0xd3,0xd3,0xd3,0xe4,0xc3,0xd4,0xd4,0xe5,0xc4,0xd5,0xd5,0xe6,0xe6, - 0xe3,0xe3,0xe3,0xd3,0xd3,0xe4,0xb6,0xd4,0xd4,0xe5,0xe5,0xb7,0xd5,0xd5,0xe6,0xe6, - 0xc5,0xc5,0xc5,0xc6,0xc6,0xc6,0xd7,0xc7,0xc7,0xd8,0xd8,0xc8,0xc8,0xd9,0xd9,0xd9, - 0xd6,0xd6,0xd6,0xc6,0xd7,0xd7,0xd7,0xc7,0xd8,0xd8,0xd8,0xc8,0xc8,0xd9,0xd9,0xea, - 0xd6,0xd6,0xd6,0xd7,0xd7,0xd7,0xe8,0xd8,0xd8,0xd8,0xe9,0xc8,0xd9,0xd9,0xea,0xea, - 0xe7,0xe7,0xe7,0xd7,0xd7,0xe8,0xe8,0xd8,0xd8,0xe9,0xe9,0xe9,0xd9,0xd9,0xea,0xea, - 0xc9,0xc9,0xc9,0xca,0xca,0xca,0xba,0xcb,0xcb,0xcb,0xe9,0xcc,0xcc,0xcc,0xea,0xea, - 0xc9,0xc9,0xc9,0xca,0xca,0xdb,0xdb,0xcb,0xcb,0xdc,0xdc,0xcc,0xcc,0xdd,0xdd,0xdd, - 0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdb,0xdc,0xdc,0xdc,0xdc,0xcc,0xdd,0xdd,0xdd,0xee, - 0xda,0xda,0xda,0xdb,0xdb,0xec,0xec,0xdc,0xdc,0xed,0xed,0xed,0xdd,0xdd,0xee,0xee, - 0xeb,0xeb,0xeb,0xec,0xec,0xec,0xec,0xdc,0xed,0xed,0xed,0xed,0xdd,0xee,0xee,0xee, - 0xef,0xef,0xef,0xdf,0xe0,0xe0,0xe0,0xd0,0xd0,0xe1,0xe1,0xf2,0xd1,0xd1,0xe2,0xe2, - 0xef,0xef,0xef,0xdf,0xe0,0xe0,0xe0,0xd0,0xd0,0xe1,0xe1,0xf2,0xd1,0xd1,0xe2,0xe2, - 0xef,0xef,0xef,0xdf,0xe0,0xe0,0xe0,0xd0,0xd0,0xe1,0xe1,0xf2,0xd1,0xd1,0xe2,0xe2, - 0xd2,0xd2,0xd2,0xd3,0xd3,0xe4,0xe4,0xd4,0xd4,0xd4,0xe5,0xe5,0xd5,0xd5,0xe6,0xe6, - 0xe3,0xe3,0xe3,0xd3,0xe4,0xe4,0xe4,0xd4,0xd4,0xe5,0xe5,0xf6,0xd5,0xd5,0xe6,0xe6, - 0xe3,0xe3,0xe3,0xe4,0xe4,0xe4,0xe4,0xd4,0xe5,0xe5,0xe5,0xf6,0xd5,0xe6,0xe6,0xf7, - 0xe3,0xe3,0xe3,0xe4,0xe4,0xe4,0xf5,0xf5,0xe5,0xe5,0xf6,0xf6,0xd5,0xe6,0xe6,0xf7, - 0xd6,0xd6,0xd6,0xd7,0xd7,0xd7,0xf5,0xc7,0xd8,0xd8,0xf6,0xc8,0xd9,0xd9,0xd9,0xf7, - 0xd6,0xd6,0xd6,0xd7,0xd7,0xe8,0xe8,0xd8,0xd8,0xd8,0xe9,0xe9,0xd9,0xd9,0xea,0xea, - 0xe7,0xe7,0xe7,0xd7,0xe8,0xe8,0xe8,0xd8,0xd8,0xe9,0xe9,0xe9,0xd9,0xea,0xea,0xea, - 0xe7,0xe7,0xe7,0xe8,0xe8,0xe8,0xf9,0xf9,0xe9,0xe9,0xe9,0xfa,0xd9,0xea,0xea,0xfb, - 0xf8,0xf8,0xf8,0xe8,0xf9,0xf9,0xf9,0xcb,0xe9,0xe9,0xfa,0xfa,0xcc,0xea,0xea,0xfb, - 0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdb,0xdc,0xdc,0xdc,0xdc,0xcc,0xdd,0xdd,0xdd,0xee, - 0xda,0xda,0xda,0xdb,0xdb,0xec,0xec,0xdc,0xdc,0xed,0xed,0xed,0xdd,0xdd,0xee,0xee, - 0xeb,0xeb,0xeb,0xec,0xec,0xec,0xec,0xdc,0xed,0xed,0xed,0xed,0xdd,0xee,0xee,0xee, - 0xeb,0xeb,0xeb,0xec,0xec,0xfd,0xfd,0xfd,0xed,0xed,0xfe,0xfe,0xee,0xee,0xee,0xff, - 0xf0,0xf0,0xf0,0xe0,0xf1,0xf1,0xf1,0xf1,0xe1,0xf2,0xf2,0xf2,0xf2,0xe2,0xe2,0xf3, - 0xf0,0xf0,0xf0,0xe0,0xf1,0xf1,0xf1,0xf1,0xe1,0xf2,0xf2,0xf2,0xf2,0xe2,0xe2,0xf3, - 0xf0,0xf0,0xf0,0xe0,0xf1,0xf1,0xf1,0xf1,0xe1,0xf2,0xf2,0xf2,0xf2,0xe2,0xe2,0xf3, - 0xe3,0xe3,0xe3,0xe4,0xe4,0xe4,0xf5,0xf5,0xe5,0xe5,0xf6,0xf6,0xd5,0xe6,0xe6,0xf7, - 0xf4,0xf4,0xf4,0xe4,0xe4,0xf5,0xf5,0xf5,0xe5,0xe5,0xf6,0xf6,0xf6,0xe6,0xe6,0xf7, - 0xf4,0xf4,0xf4,0xe4,0xf5,0xf5,0xf5,0xf5,0xe5,0xf6,0xf6,0xf6,0xf6,0xe6,0xf7,0xf7, - 0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5,0xe5,0xf6,0xf6,0xf6,0xf6,0xe6,0xf7,0xf7, - 0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5,0xd8,0xf6,0xf6,0xf6,0xd9,0xd9,0xf7,0xf7, - 0xe7,0xe7,0xe7,0xe8,0xe8,0xe8,0xe8,0xd8,0xe9,0xe9,0xe9,0xfa,0xd9,0xea,0xea,0xea, - 0xf8,0xf8,0xf8,0xe8,0xe8,0xf9,0xf9,0xf9,0xe9,0xe9,0xfa,0xfa,0xfa,0xea,0xea,0xfb, - 0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xe9,0xfa,0xfa,0xfa,0xfa,0xea,0xfb,0xfb, - 0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfa,0xea,0xfb,0xfb, - 0xf8,0xf8,0xf8,0xdb,0xf9,0xf9,0xf9,0xdc,0xdc,0xfa,0xfa,0xfa,0xdd,0xdd,0xee,0xfb, - 0xeb,0xeb,0xeb,0xec,0xec,0xec,0xec,0xdc,0xed,0xed,0xed,0xed,0xdd,0xee,0xee,0xee, - 0xeb,0xeb,0xeb,0xec,0xec,0xfd,0xfd,0xfd,0xed,0xed,0xfe,0xfe,0xee,0xee,0xee,0xff, - 0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xed,0xfe,0xfe,0xfe,0xfe,0xee,0xff,0xff, -} -}; -Memcmap *memdefcmap = &def; -void _memmkcmap(void){} blob - 4fa5942a4bb9b578fd213cc7debafbc2230ba35b (mode 644) blob + /dev/null --- src/libdraw/md-cread.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#include - -Memimage* -creadmemimage(int fd) -{ - char hdr[5*12+1]; - Rectangle r; - int m, nb, miny, maxy, new, ldepth, ncblock; - uchar *buf; - Memimage *i; - u32int chan; - - if(readn(fd, hdr, 5*12) != 5*12){ - werrstr("readmemimage: short header (2)"); - return nil; - } - - /* - * distinguish new channel descriptor from old ldepth. - * channel descriptors have letters as well as numbers, - * while ldepths are a single digit formatted as %-11d. - */ - new = 0; - for(m=0; m<10; m++){ - if(hdr[m] != ' '){ - new = 1; - break; - } - } - if(hdr[11] != ' '){ - werrstr("creadimage: bad format"); - return nil; - } - if(new){ - hdr[11] = '\0'; - if((chan = strtochan(hdr)) == 0){ - werrstr("creadimage: bad channel string %s", hdr); - return nil; - } - }else{ - ldepth = ((int)hdr[10])-'0'; - if(ldepth<0 || ldepth>3){ - werrstr("creadimage: bad ldepth %d", ldepth); - return nil; - } - chan = drawld2chan[ldepth]; - } - r.min.x=atoi(hdr+1*12); - r.min.y=atoi(hdr+2*12); - r.max.x=atoi(hdr+3*12); - r.max.y=atoi(hdr+4*12); - if(r.min.x>r.max.x || r.min.y>r.max.y){ - werrstr("creadimage: bad rectangle"); - return nil; - } - - i = allocmemimage(r, chan); - if(i == nil) - return nil; - ncblock = _compblocksize(r, i->depth); - buf = malloc(ncblock); - if(buf == nil) - goto Errout; - miny = r.min.y; - while(miny != r.max.y){ - if(readn(fd, hdr, 2*12) != 2*12){ - Shortread: - werrstr("readmemimage: short read"); - Errout: - freememimage(i); - free(buf); - return nil; - } - maxy = atoi(hdr+0*12); - nb = atoi(hdr+1*12); - if(maxy<=miny || r.max.y -#include -#include -#include - -Memsubfont* -getmemdefont(void) -{ - char *hdr, *p; - int n; - Fontchar *fc; - Memsubfont *f; - int ld; - Rectangle r; - Memdata *md; - Memimage *i; - - /* - * make sure data is word-aligned. this is true with Plan 9 compilers - * but not in general. the byte order is right because the data is - * declared as char*, not u32int*. - */ - p = (char*)defontdata; - n = (uintptr)p & 3; - if(n != 0){ - memmove(p+(4-n), p, sizeofdefont-n); - p += 4-n; - } - ld = atoi(p+0*12); - r.min.x = atoi(p+1*12); - r.min.y = atoi(p+2*12); - r.max.x = atoi(p+3*12); - r.max.y = atoi(p+4*12); - - md = mallocz(sizeof(Memdata), 1); - if(md == nil) - return nil; - - p += 5*12; - - md->base = nil; /* so freememimage doesn't free p */ - md->bdata = (uchar*)p; /* ick */ - md->ref = 1; - md->allocd = 1; /* so freememimage does free md */ - - i = allocmemimaged(r, drawld2chan[ld], md, nil); - if(i == nil){ - free(md); - return nil; - } - - hdr = p+Dy(r)*i->width*sizeof(u32int); - n = atoi(hdr); - p = hdr+3*12; - fc = malloc(sizeof(Fontchar)*(n+1)); - if(fc == 0){ - freememimage(i); - return 0; - } - _unpackinfo(fc, (uchar*)p, n); - f = allocmemsubfont("*default*", n, atoi(hdr+12), atoi(hdr+24), fc, i); - if(f == 0){ - freememimage(i); - free(fc); - return 0; - } - return f; -} blob - 2d8681e5ee156abfa91e72b41a88477921e13fa7 (mode 644) blob + /dev/null --- src/libdraw/md-draw.c +++ /dev/null @@ -1,2489 +0,0 @@ -#include -#include -#include -#include - -int drawdebug; -static int tablesbuilt; - -/* perfect approximation to NTSC = .299r+.587g+.114b when 0 ≤ r,g,b < 256 */ -#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19) - -/* - * for 0 ≤ x ≤ 255*255, (x*0x0101+0x100)>>16 is a perfect approximation. - * for 0 ≤ x < (1<<16), x/255 = ((x+1)*0x0101)>>16 is a perfect approximation. - * the last one is perfect for all up to 1<<16, avoids a multiply, but requires a rathole. - */ -/* #define DIV255(x) (((x)*257+256)>>16) */ -#define DIV255(x) ((((x)+1)*257)>>16) -/* #define DIV255(x) (tmp=(x)+1, (tmp+(tmp>>8))>>8) */ - -#define MUL(x, y, t) (t = (x)*(y)+128, (t+(t>>8))>>8) -#define MASK13 0xFF00FF00 -#define MASK02 0x00FF00FF -#define MUL13(a, x, t) (t = (a)*(((x)&MASK13)>>8)+128, ((t+((t>>8)&MASK02))>>8)&MASK02) -#define MUL02(a, x, t) (t = (a)*(((x)&MASK02)>>0)+128, ((t+((t>>8)&MASK02))>>8)&MASK02) -#define MUL0123(a, x, s, t) ((MUL13(a, x, s)<<8)|MUL02(a, x, t)) - -#define MUL2(u, v, x, y) (t = (u)*(v)+(x)*(y)+256, (t+(t>>8))>>8) - -static void mktables(void); -typedef int Subdraw(Memdrawparam*); -static Subdraw chardraw, alphadraw, memoptdraw; - -static Memimage* memones; -static Memimage* memzeros; -Memimage *memwhite; -Memimage *memblack; -Memimage *memtransparent; -Memimage *memopaque; - -int __ifmt(Fmt*); - -void -memimageinit(void) -{ - static int didinit = 0; - - if(didinit) - return; - - didinit = 1; - - mktables(); - _memmkcmap(); - - fmtinstall('R', Rfmt); - fmtinstall('P', Pfmt); - fmtinstall('b', __ifmt); - - memones = allocmemimage(Rect(0,0,1,1), GREY1); - memones->flags |= Frepl; - memones->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); - *byteaddr(memones, ZP) = ~0; - - memzeros = allocmemimage(Rect(0,0,1,1), GREY1); - memzeros->flags |= Frepl; - memzeros->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); - *byteaddr(memzeros, ZP) = 0; - - if(memones == nil || memzeros == nil) - assert(0 /*cannot initialize memimage library */); /* RSC BUG */ - - memwhite = memones; - memblack = memzeros; - memopaque = memones; - memtransparent = memzeros; -} - -u32int _imgtorgba(Memimage*, u32int); -u32int _rgbatoimg(Memimage*, u32int); -u32int _pixelbits(Memimage*, Point); - -#define DBG if(drawdebug) -static Memdrawparam par; - -Memdrawparam* -_memimagedrawsetup(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op) -{ - if(mask == nil) - mask = memopaque; - -DBG print("memimagedraw %p/%luX %R @ %p %p/%luX %P %p/%luX %P... ", dst, dst->chan, r, dst->data->bdata, src, src->chan, p0, mask, mask->chan, p1); - - if(drawclip(dst, &r, src, &p0, mask, &p1, &par.sr, &par.mr) == 0){ -/* if(drawdebug) */ -/* iprint("empty clipped rectangle\n"); */ - return nil; - } - - if(op < Clear || op > SoverD){ -/* if(drawdebug) */ -/* iprint("op out of range: %d\n", op); */ - return nil; - } - - par.op = op; - par.dst = dst; - par.r = r; - par.src = src; - /* par.sr set by drawclip */ - par.mask = mask; - /* par.mr set by drawclip */ - - par.state = 0; - if(src->flags&Frepl){ - par.state |= Replsrc; - if(Dx(src->r)==1 && Dy(src->r)==1){ - par.sval = pixelbits(src, src->r.min); - par.state |= Simplesrc; - par.srgba = _imgtorgba(src, par.sval); - par.sdval = _rgbatoimg(dst, par.srgba); - if((par.srgba&0xFF) == 0 && (op&DoutS)){ -/* if (drawdebug) iprint("fill with transparent source\n"); */ - return nil; /* no-op successfully handled */ - } - if((par.srgba&0xFF) == 0xFF) - par.state |= Fullsrc; - } - } - - if(mask->flags & Frepl){ - par.state |= Replmask; - if(Dx(mask->r)==1 && Dy(mask->r)==1){ - par.mval = pixelbits(mask, mask->r.min); - if(par.mval == 0 && (op&DoutS)){ -/* if(drawdebug) iprint("fill with zero mask\n"); */ - return nil; /* no-op successfully handled */ - } - par.state |= Simplemask; - if(par.mval == ~0) - par.state |= Fullmask; - par.mrgba = _imgtorgba(mask, par.mval); - } - } - -/* if(drawdebug) */ -/* iprint("dr %R sr %R mr %R...", r, par.sr, par.mr); */ -DBG print("draw dr %R sr %R mr %R %lux\n", r, par.sr, par.mr, par.state); - - return ∥ -} - -void -_memimagedraw(Memdrawparam *par) -{ - /* - * Now that we've clipped the parameters down to be consistent, we - * simply try sub-drawing routines in order until we find one that was able - * to handle us. If the sub-drawing routine returns zero, it means it was - * unable to satisfy the request, so we do not return. - */ - - /* - * Hardware support. Each video driver provides this function, - * which checks to see if there is anything it can help with. - * There could be an if around this checking to see if dst is in video memory. - */ -DBG print("test hwdraw\n"); - if(hwdraw(par)){ -/*if(drawdebug) iprint("hw handled\n"); */ -DBG print("hwdraw handled\n"); - return; - } - /* - * Optimizations using memmove and memset. - */ -DBG print("test memoptdraw\n"); - if(memoptdraw(par)){ -/*if(drawdebug) iprint("memopt handled\n"); */ -DBG print("memopt handled\n"); - return; - } - - /* - * Character drawing. - * Solid source color being painted through a boolean mask onto a high res image. - */ -DBG print("test chardraw\n"); - if(chardraw(par)){ -/*if(drawdebug) iprint("chardraw handled\n"); */ -DBG print("chardraw handled\n"); - return; - } - - /* - * General calculation-laden case that does alpha for each pixel. - */ -DBG print("do alphadraw\n"); - alphadraw(par); -/*if(drawdebug) iprint("alphadraw handled\n"); */ -DBG print("alphadraw handled\n"); -} -#undef DBG - -/* - * Clip the destination rectangle further based on the properties of the - * source and mask rectangles. Once the destination rectangle is properly - * clipped, adjust the source and mask rectangles to be the same size. - * Then if source or mask is replicated, move its clipped rectangle - * so that its minimum point falls within the repl rectangle. - * - * Return zero if the final rectangle is null. - */ -int -drawclip(Memimage *dst, Rectangle *r, Memimage *src, Point *p0, Memimage *mask, Point *p1, Rectangle *sr, Rectangle *mr) -{ - Point rmin, delta; - int splitcoords; - Rectangle omr; - - if(r->min.x>=r->max.x || r->min.y>=r->max.y) - return 0; - splitcoords = (p0->x!=p1->x) || (p0->y!=p1->y); - /* clip to destination */ - rmin = r->min; - if(!rectclip(r, dst->r) || !rectclip(r, dst->clipr)) - return 0; - /* move mask point */ - p1->x += r->min.x-rmin.x; - p1->y += r->min.y-rmin.y; - /* move source point */ - p0->x += r->min.x-rmin.x; - p0->y += r->min.y-rmin.y; - /* map destination rectangle into source */ - sr->min = *p0; - sr->max.x = p0->x+Dx(*r); - sr->max.y = p0->y+Dy(*r); - /* sr is r in source coordinates; clip to source */ - if(!(src->flags&Frepl) && !rectclip(sr, src->r)) - return 0; - if(!rectclip(sr, src->clipr)) - return 0; - /* compute and clip rectangle in mask */ - if(splitcoords){ - /* move mask point with source */ - p1->x += sr->min.x-p0->x; - p1->y += sr->min.y-p0->y; - mr->min = *p1; - mr->max.x = p1->x+Dx(*sr); - mr->max.y = p1->y+Dy(*sr); - omr = *mr; - /* mr is now rectangle in mask; clip it */ - if(!(mask->flags&Frepl) && !rectclip(mr, mask->r)) - return 0; - if(!rectclip(mr, mask->clipr)) - return 0; - /* reflect any clips back to source */ - sr->min.x += mr->min.x-omr.min.x; - sr->min.y += mr->min.y-omr.min.y; - sr->max.x += mr->max.x-omr.max.x; - sr->max.y += mr->max.y-omr.max.y; - *p1 = mr->min; - }else{ - if(!(mask->flags&Frepl) && !rectclip(sr, mask->r)) - return 0; - if(!rectclip(sr, mask->clipr)) - return 0; - *p1 = sr->min; - } - - /* move source clipping back to destination */ - delta.x = r->min.x - p0->x; - delta.y = r->min.y - p0->y; - r->min.x = sr->min.x + delta.x; - r->min.y = sr->min.y + delta.y; - r->max.x = sr->max.x + delta.x; - r->max.y = sr->max.y + delta.y; - - /* move source rectangle so sr->min is in src->r */ - if(src->flags&Frepl) { - delta.x = drawreplxy(src->r.min.x, src->r.max.x, sr->min.x) - sr->min.x; - delta.y = drawreplxy(src->r.min.y, src->r.max.y, sr->min.y) - sr->min.y; - sr->min.x += delta.x; - sr->min.y += delta.y; - sr->max.x += delta.x; - sr->max.y += delta.y; - } - *p0 = sr->min; - - /* move mask point so it is in mask->r */ - *p1 = drawrepl(mask->r, *p1); - mr->min = *p1; - mr->max.x = p1->x+Dx(*sr); - mr->max.y = p1->y+Dy(*sr); - - assert(Dx(*sr) == Dx(*mr) && Dx(*mr) == Dx(*r)); - assert(Dy(*sr) == Dy(*mr) && Dy(*mr) == Dy(*r)); - assert(ptinrect(*p0, src->r)); - assert(ptinrect(*p1, mask->r)); - assert(ptinrect(r->min, dst->r)); - - return 1; -} - -/* - * Conversion tables. - */ -static uchar replbit[1+8][256]; /* replbit[x][y] is the replication of the x-bit quantity y to 8-bit depth */ -static uchar conv18[256][8]; /* conv18[x][y] is the yth pixel in the depth-1 pixel x */ -static uchar conv28[256][4]; /* ... */ -static uchar conv48[256][2]; - -/* - * bitmap of how to replicate n bits to fill 8, for 1 ≤ n ≤ 8. - * the X's are where to put the bottom (ones) bit of the n-bit pattern. - * only the top 8 bits of the result are actually used. - * (the lower 8 bits are needed to get bits in the right place - * when n is not a divisor of 8.) - * - * Should check to see if its easier to just refer to replmul than - * use the precomputed values in replbit. On PCs it may well - * be; on machines with slow multiply instructions it probably isn't. - */ -#define a ((((((((((((((((0 -#define X *2+1) -#define _ *2) -static int replmul[1+8] = { - 0, - a X X X X X X X X X X X X X X X X, - a _ X _ X _ X _ X _ X _ X _ X _ X, - a _ _ X _ _ X _ _ X _ _ X _ _ X _, - a _ _ _ X _ _ _ X _ _ _ X _ _ _ X, - a _ _ _ _ X _ _ _ _ X _ _ _ _ X _, - a _ _ _ _ _ X _ _ _ _ _ X _ _ _ _, - a _ _ _ _ _ _ X _ _ _ _ _ _ X _ _, - a _ _ _ _ _ _ _ X _ _ _ _ _ _ _ X, -}; -#undef a -#undef X -#undef _ - -static void -mktables(void) -{ - int i, j, mask, sh, small; - - if(tablesbuilt) - return; - - fmtinstall('R', Rfmt); - fmtinstall('P', Pfmt); - tablesbuilt = 1; - - /* bit replication up to 8 bits */ - for(i=0; i<256; i++){ - for(j=0; j<=8; j++){ /* j <= 8 [sic] */ - small = i & ((1<>8; - } - } - - /* bit unpacking up to 8 bits, only powers of 2 */ - for(i=0; i<256; i++){ - for(j=0, sh=7, mask=1; j<8; j++, sh--) - conv18[i][j] = replbit[1][(i>>sh)&mask]; - - for(j=0, sh=6, mask=3; j<4; j++, sh-=2) - conv28[i][j] = replbit[2][(i>>sh)&mask]; - - for(j=0, sh=4, mask=15; j<2; j++, sh-=4) - conv48[i][j] = replbit[4][(i>>sh)&mask]; - } -} - -static uchar ones = 0xff; - -/* - * General alpha drawing case. Can handle anything. - */ -typedef struct Buffer Buffer; -struct Buffer { - /* used by most routines */ - uchar *red; - uchar *grn; - uchar *blu; - uchar *alpha; - uchar *grey; - u32int *rgba; - int delta; /* number of bytes to add to pointer to get next pixel to the right */ - - /* used by boolcalc* for mask data */ - uchar *m; /* ptr to mask data r.min byte; like p->bytermin */ - int mskip; /* no. of left bits to skip in *m */ - uchar *bm; /* ptr to mask data img->r.min byte; like p->bytey0s */ - int bmskip; /* no. of left bits to skip in *bm */ - uchar *em; /* ptr to mask data img->r.max.x byte; like p->bytey0e */ - int emskip; /* no. of right bits to skip in *em */ -}; - -typedef struct Param Param; -typedef Buffer Readfn(Param*, uchar*, int); -typedef void Writefn(Param*, uchar*, Buffer); -typedef Buffer Calcfn(Buffer, Buffer, Buffer, int, int, int); - -enum { - MAXBCACHE = 16 -}; - -/* giant rathole to customize functions with */ -struct Param { - Readfn *replcall; - Readfn *greymaskcall; - Readfn *convreadcall; - Writefn *convwritecall; - - Memimage *img; - Rectangle r; - int dx; /* of r */ - int needbuf; - int convgrey; - int alphaonly; - - uchar *bytey0s; /* byteaddr(Pt(img->r.min.x, img->r.min.y)) */ - uchar *bytermin; /* byteaddr(Pt(r.min.x, img->r.min.y)) */ - uchar *bytey0e; /* byteaddr(Pt(img->r.max.x, img->r.min.y)) */ - int bwidth; - - int replcache; /* if set, cache buffers */ - Buffer bcache[MAXBCACHE]; - u32int bfilled; - uchar *bufbase; - int bufoff; - int bufdelta; - - int dir; - - int convbufoff; - uchar *convbuf; - Param *convdpar; - int convdx; -}; - -static uchar *drawbuf; -static int ndrawbuf; -static int mdrawbuf; -static Param spar, mpar, dpar; /* easier on the stacks */ -static Readfn greymaskread, replread, readptr; -static Writefn nullwrite; -static Calcfn alphacalc0, alphacalc14, alphacalc2810, alphacalc3679, alphacalc5, alphacalc11, alphacalcS; -static Calcfn boolcalc14, boolcalc236789, boolcalc1011; - -static Readfn* readfn(Memimage*); -static Readfn* readalphafn(Memimage*); -static Writefn* writefn(Memimage*); - -static Calcfn* boolcopyfn(Memimage*, Memimage*); -static Readfn* convfn(Memimage*, Param*, Memimage*, Param*); - -static Calcfn *alphacalc[Ncomp] = -{ - alphacalc0, /* Clear */ - alphacalc14, /* DoutS */ - alphacalc2810, /* SoutD */ - alphacalc3679, /* DxorS */ - alphacalc14, /* DinS */ - alphacalc5, /* D */ - alphacalc3679, /* DatopS */ - alphacalc3679, /* DoverS */ - alphacalc2810, /* SinD */ - alphacalc3679, /* SatopD */ - alphacalc2810, /* S */ - alphacalc11, /* SoverD */ -}; - -static Calcfn *boolcalc[Ncomp] = -{ - alphacalc0, /* Clear */ - boolcalc14, /* DoutS */ - boolcalc236789, /* SoutD */ - boolcalc236789, /* DxorS */ - boolcalc14, /* DinS */ - alphacalc5, /* D */ - boolcalc236789, /* DatopS */ - boolcalc236789, /* DoverS */ - boolcalc236789, /* SinD */ - boolcalc236789, /* SatopD */ - boolcalc1011, /* S */ - boolcalc1011, /* SoverD */ -}; - -static int -allocdrawbuf(void) -{ - uchar *p; - - if(ndrawbuf > mdrawbuf){ - p = realloc(drawbuf, ndrawbuf); - if(p == nil){ - werrstr("memimagedraw out of memory"); - return -1; - } - drawbuf = p; - mdrawbuf = ndrawbuf; - } - return 0; -} - -static void -getparam(Param *p, Memimage *img, Rectangle r, int convgrey, int needbuf) -{ - int nbuf; - - memset(p, 0, sizeof *p); - - p->img = img; - p->r = r; - p->dx = Dx(r); - p->needbuf = needbuf; - p->convgrey = convgrey; - - assert(img->r.min.x <= r.min.x && r.min.x < img->r.max.x); - - p->bytey0s = byteaddr(img, Pt(img->r.min.x, img->r.min.y)); - p->bytermin = byteaddr(img, Pt(r.min.x, img->r.min.y)); - p->bytey0e = byteaddr(img, Pt(img->r.max.x, img->r.min.y)); - p->bwidth = sizeof(u32int)*img->width; - - assert(p->bytey0s <= p->bytermin && p->bytermin <= p->bytey0e); - - if(p->r.min.x == p->img->r.min.x) - assert(p->bytermin == p->bytey0s); - - nbuf = 1; - if((img->flags&Frepl) && Dy(img->r) <= MAXBCACHE && Dy(img->r) < Dy(r)){ - p->replcache = 1; - nbuf = Dy(img->r); - } - p->bufdelta = 4*p->dx; - p->bufoff = ndrawbuf; - ndrawbuf += p->bufdelta*nbuf; -} - -static void -clipy(Memimage *img, int *y) -{ - int dy; - - dy = Dy(img->r); - if(*y == dy) - *y = 0; - else if(*y == -1) - *y = dy-1; - assert(0 <= *y && *y < dy); -} - -static void -dumpbuf(char *s, Buffer b, int n) -{ - int i; - uchar *p; - - print("%s", s); - for(i=0; ir); - r = par->r; - dx = Dx(r); - dy = Dy(r); - - ndrawbuf = 0; - - src = par->src; - mask = par->mask; - dst = par->dst; - sr = par->sr; - mr = par->mr; - op = par->op; - - isgrey = dst->flags&Fgrey; - - /* - * Buffering when src and dst are the same bitmap is sufficient but not - * necessary. There are stronger conditions we could use. We could - * check to see if the rectangles intersect, and if simply moving in the - * correct y direction can avoid the need to buffer. - */ - needbuf = (src->data == dst->data); - - getparam(&spar, src, sr, isgrey, needbuf); - getparam(&dpar, dst, r, isgrey, needbuf); - getparam(&mpar, mask, mr, 0, needbuf); - - dir = (needbuf && byteaddr(dst, r.min) > byteaddr(src, sr.min)) ? -1 : 1; - spar.dir = mpar.dir = dpar.dir = dir; - - /* - * If the mask is purely boolean, we can convert from src to dst format - * when we read src, and then just copy it to dst where the mask tells us to. - * This requires a boolean (1-bit grey) mask and lack of a source alpha channel. - * - * The computation is accomplished by assigning the function pointers as follows: - * rdsrc - read and convert source into dst format in a buffer - * rdmask - convert mask to bytes, set pointer to it - * rddst - fill with pointer to real dst data, but do no reads - * calc - copy src onto dst when mask says to. - * wrdst - do nothing - * This is slightly sleazy, since things aren't doing exactly what their names say, - * but it avoids a fair amount of code duplication to make this a case here - * rather than have a separate booldraw. - */ -/*if(drawdebug) iprint("flag %lud mchan %lux=?%x dd %d\n", src->flags&Falpha, mask->chan, GREY1, dst->depth); */ - if(!(src->flags&Falpha) && mask->chan == GREY1 && dst->depth >= 8 && op == SoverD){ -/*if(drawdebug) iprint("boolcopy..."); */ - rdsrc = convfn(dst, &dpar, src, &spar); - rddst = readptr; - rdmask = readfn(mask); - calc = boolcopyfn(dst, mask); - wrdst = nullwrite; - }else{ - /* usual alphadraw parameter fetching */ - rdsrc = readfn(src); - rddst = readfn(dst); - wrdst = writefn(dst); - calc = alphacalc[op]; - - /* - * If there is no alpha channel, we'll ask for a grey channel - * and pretend it is the alpha. - */ - if(mask->flags&Falpha){ - rdmask = readalphafn(mask); - mpar.alphaonly = 1; - }else{ - mpar.greymaskcall = readfn(mask); - mpar.convgrey = 1; - rdmask = greymaskread; - - /* - * Should really be above, but then boolcopyfns would have - * to deal with bit alignment, and I haven't written that. - * - * This is a common case for things like ellipse drawing. - * When there's no alpha involved and the mask is boolean, - * we can avoid all the division and multiplication. - */ - if(mask->chan == GREY1 && !(src->flags&Falpha)) - calc = boolcalc[op]; - else if(op == SoverD && !(src->flags&Falpha)) - calc = alphacalcS; - } - } - - /* - * If the image has a small enough repl rectangle, - * we can just read each line once and cache them. - */ - if(spar.replcache){ - spar.replcall = rdsrc; - rdsrc = replread; - } - if(mpar.replcache){ - mpar.replcall = rdmask; - rdmask = replread; - } - - if(allocdrawbuf() < 0) - return 0; - - /* - * Before we were saving only offsets from drawbuf in the parameter - * structures; now that drawbuf has been grown to accomodate us, - * we can fill in the pointers. - */ - spar.bufbase = drawbuf+spar.bufoff; - mpar.bufbase = drawbuf+mpar.bufoff; - dpar.bufbase = drawbuf+dpar.bufoff; - spar.convbuf = drawbuf+spar.convbufoff; - - if(dir == 1){ - starty = 0; - endy = dy; - }else{ - starty = dy-1; - endy = -1; - } - - /* - * srcy, masky, and dsty are offsets from the top of their - * respective Rectangles. they need to be contained within - * the rectangles, so clipy can keep them there without division. - */ - srcy = (starty + sr.min.y - src->r.min.y)%Dy(src->r); - masky = (starty + mr.min.y - mask->r.min.y)%Dy(mask->r); - dsty = starty + r.min.y - dst->r.min.y; - - assert(0 <= srcy && srcy < Dy(src->r)); - assert(0 <= masky && masky < Dy(mask->r)); - assert(0 <= dsty && dsty < Dy(dst->r)); - - if(drawdebug) - print("alphadraw: rdsrc=%p rdmask=%p rddst=%p calc=%p wrdst=%p\n", - rdsrc, rdmask, rddst, calc, wrdst); - for(y=starty; y!=endy; y+=dir, srcy+=dir, masky+=dir, dsty+=dir){ - clipy(src, &srcy); - clipy(dst, &dsty); - clipy(mask, &masky); - - bsrc = rdsrc(&spar, spar.bufbase, srcy); -DBG print("["); - bmask = rdmask(&mpar, mpar.bufbase, masky); -DBG print("]\n"); - bdst = rddst(&dpar, dpar.bufbase, dsty); -DBG dumpbuf("src", bsrc, dx); -DBG dumpbuf("mask", bmask, dx); -DBG dumpbuf("dst", bdst, dx); - bdst = calc(bdst, bsrc, bmask, dx, isgrey, op); -DBG dumpbuf("bdst", bdst, dx); - wrdst(&dpar, dpar.bytermin+dsty*dpar.bwidth, bdst); - } - - return 1; -} -#undef DBG - -static Buffer -alphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op) -{ - USED(grey); - USED(op); - memset(bdst.rgba, 0, dx*bdst.delta); - return bdst; -} - -static Buffer -alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op) -{ - Buffer obdst; - int fd, sadelta; - int i, sa, ma, q; - u32int s, t; - - obdst = bdst; - sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta; - q = bsrc.delta == 4 && bdst.delta == 4; - - for(i=0; ibcache[y]; - if((p->bfilled & (1<bfilled |= 1<replcall(p, p->bufbase+y*p->bufdelta, y); - } - return *b; -} - -/* - * Alpha reading function that simply relabels the grey pointer. - */ -static Buffer -greymaskread(Param *p, uchar *buf, int y) -{ - Buffer b; - - b = p->greymaskcall(p, buf, y); - b.alpha = b.grey; - return b; -} - -#define DBG if(0) -static Buffer -readnbit(Param *p, uchar *buf, int y) -{ - Buffer b; - Memimage *img; - uchar *repl, *r, *w, *ow, bits; - int i, n, sh, depth, x, dx, npack, nbits; - - memset(&b, 0, sizeof b); - b.rgba = (u32int*)buf; - b.grey = w = buf; - b.red = b.blu = b.grn = w; - b.alpha = &ones; - b.delta = 1; - - dx = p->dx; - img = p->img; - depth = img->depth; - repl = &replbit[depth][0]; - npack = 8/depth; - sh = 8-depth; - - /* copy from p->r.min.x until end of repl rectangle */ - x = p->r.min.x; - n = dx; - if(n > p->img->r.max.x - x) - n = p->img->r.max.x - x; - - r = p->bytermin + y*p->bwidth; -DBG print("readnbit dx %d %p=%p+%d*%d, *r=%d fetch %d ", dx, r, p->bytermin, y, p->bwidth, *r, n); - bits = *r++; - nbits = 8; - if(i=x&(npack-1)){ -DBG print("throwaway %d...", i); - bits <<= depth*i; - nbits -= depth*i; - } - for(i=0; i>sh]; -DBG print("bit %x...", repl[bits>>sh]); - bits <<= depth; - nbits -= depth; - } - dx -= n; - if(dx == 0) - return b; - - assert(x+i == p->img->r.max.x); - - /* copy from beginning of repl rectangle until where we were before. */ - x = p->img->r.min.x; - n = dx; - if(n > p->r.min.x - x) - n = p->r.min.x - x; - - r = p->bytey0s + y*p->bwidth; -DBG print("x=%d r=%p...", x, r); - bits = *r++; - nbits = 8; - if(i=x&(npack-1)){ - bits <<= depth*i; - nbits -= depth*i; - } -DBG print("nbits=%d...", nbits); - for(i=0; i>sh]; -DBG print("bit %x...", repl[bits>>sh]); - bits <<= depth; - nbits -= depth; -DBG print("bits %x nbits %d...", bits, nbits); - } - dx -= n; - if(dx == 0) - return b; - - assert(dx > 0); - /* now we have exactly one full scan line: just replicate the buffer itself until we are done */ - ow = buf; - while(dx--) - *w++ = *ow++; - - return b; -} -#undef DBG - -#define DBG if(0) -static void -writenbit(Param *p, uchar *w, Buffer src) -{ - uchar *r; - u32int bits; - int i, sh, depth, npack, nbits, x, ex; - - assert(src.grey != nil && src.delta == 1); - - x = p->r.min.x; - ex = x+p->dx; - depth = p->img->depth; - npack = 8/depth; - - i=x&(npack-1); - bits = i ? (*w >> (8-depth*i)) : 0; - nbits = depth*i; - sh = 8-depth; - r = src.grey; - - for(; x> sh); - nbits += depth; - if(nbits == 8){ - *w++ = bits; - nbits = 0; - } - } - - if(nbits){ - sh = 8-nbits; - bits <<= sh; - bits |= *w & ((1<bytey0s + y*p->bwidth; - r = p->bytermin + y*p->bwidth; - end = p->bytey0e + y*p->bwidth; - cmap = p->img->cmap->cmap2rgb; - convgrey = p->convgrey; - copyalpha = (p->img->flags&Falpha) ? 1 : 0; - - w = buf; - dx = p->dx; - if(copyalpha){ - b.alpha = buf++; - a = p->img->shift[CAlpha]/8; - m = p->img->shift[CMap]/8; - for(i=0; iimg->cmap->rgb2cmap; - - delta = src.delta; - red= src.red; - grn = src.grn; - blu = src.blu; - - dx = p->dx; - for(i=0; i>4)*256+(*grn>>4)*16+(*blu>>4)]; -} - -#define DBG if(drawdebug) -static Buffer -readbyte(Param *p, uchar *buf, int y) -{ - Buffer b; - Memimage *img; - int dx, isgrey, convgrey, alphaonly, copyalpha, i, nb; - uchar *begin, *end, *r, *w, *rrepl, *grepl, *brepl, *arepl, *krepl; - uchar ured, ugrn, ublu; - u32int u; - - img = p->img; - begin = p->bytey0s + y*p->bwidth; - r = p->bytermin + y*p->bwidth; - end = p->bytey0e + y*p->bwidth; - - w = buf; - dx = p->dx; - nb = img->depth/8; - - convgrey = p->convgrey; /* convert rgb to grey */ - isgrey = img->flags&Fgrey; - alphaonly = p->alphaonly; - copyalpha = (img->flags&Falpha) ? 1 : 0; - - /* if we can, avoid processing everything */ - if(!(img->flags&Frepl) && !convgrey && (img->flags&Fbytes)){ - memset(&b, 0, sizeof b); - if(p->needbuf){ - memmove(buf, r, dx*nb); - r = buf; - } - b.rgba = (u32int*)r; - if(copyalpha) - b.alpha = r+img->shift[CAlpha]/8; - else - b.alpha = &ones; - if(isgrey){ - b.grey = r+img->shift[CGrey]/8; - b.red = b.grn = b.blu = b.grey; - }else{ - b.red = r+img->shift[CRed]/8; - b.grn = r+img->shift[CGreen]/8; - b.blu = r+img->shift[CBlue]/8; - } - b.delta = nb; - return b; - } - - rrepl = replbit[img->nbits[CRed]]; - grepl = replbit[img->nbits[CGreen]]; - brepl = replbit[img->nbits[CBlue]]; - arepl = replbit[img->nbits[CAlpha]]; - krepl = replbit[img->nbits[CGrey]]; - - for(i=0; i>img->shift[CAlpha]) & img->mask[CAlpha]]; - - if(isgrey) - *w++ = krepl[(u >> img->shift[CGrey]) & img->mask[CGrey]]; - else if(!alphaonly){ - ured = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]]; - ugrn = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]]; - ublu = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]]; - if(convgrey){ - *w++ = RGB2K(ured, ugrn, ublu); - }else{ - *w++ = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]]; - *w++ = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]]; - *w++ = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]]; - } - } - r += nb; - if(r == end) - r = begin; - } - - b.alpha = copyalpha ? buf : &ones; - b.rgba = (u32int*)buf; - if(alphaonly){ - b.red = b.grn = b.blu = b.grey = nil; - if(!copyalpha) - b.rgba = nil; - b.delta = 1; - }else if(isgrey || convgrey){ - b.grey = buf+copyalpha; - b.red = b.grn = b.blu = buf+copyalpha; - b.delta = copyalpha+1; - }else{ - b.blu = buf+copyalpha; - b.grn = buf+copyalpha+1; - b.grey = nil; - b.red = buf+copyalpha+2; - b.delta = copyalpha+3; - } - return b; -} -#undef DBG - -#define DBG if(drawdebug) -static void -writebyte(Param *p, uchar *w, Buffer src) -{ - Memimage *img; - int i, isalpha, isgrey, nb, delta, dx, adelta; - uchar ff, *red, *grn, *blu, *grey, *alpha; - u32int u, mask; - - img = p->img; - - red = src.red; - grn = src.grn; - blu = src.blu; - alpha = src.alpha; - delta = src.delta; - grey = src.grey; - dx = p->dx; - - nb = img->depth/8; - mask = (nb==4) ? 0 : ~((1<depth)-1); - - isalpha = img->flags&Falpha; - isgrey = img->flags&Fgrey; - adelta = src.delta; - - if(isalpha && (alpha == nil || alpha == &ones)){ - ff = 0xFF; - alpha = &ff; - adelta = 0; - } - - for(i=0; i> (8-img->nbits[CGrey])) & img->mask[CGrey]) << img->shift[CGrey]; -DBG print("|grey %.8lux...", u); - grey += delta; - }else{ - u |= ((*red >> (8-img->nbits[CRed])) & img->mask[CRed]) << img->shift[CRed]; - u |= ((*grn >> (8-img->nbits[CGreen])) & img->mask[CGreen]) << img->shift[CGreen]; - u |= ((*blu >> (8-img->nbits[CBlue])) & img->mask[CBlue]) << img->shift[CBlue]; - red += delta; - grn += delta; - blu += delta; -DBG print("|rgb %.8lux...", u); - } - - if(isalpha){ - u |= ((*alpha >> (8-img->nbits[CAlpha])) & img->mask[CAlpha]) << img->shift[CAlpha]; - alpha += adelta; -DBG print("|alpha %.8lux...", u); - } - - w[0] = u; - w[1] = u>>8; - w[2] = u>>16; - w[3] = u>>24; -DBG print("write back %.8lux...", u); - w += nb; - } -} -#undef DBG - -static Readfn* -readfn(Memimage *img) -{ - if(img->depth < 8) - return readnbit; - if(img->nbits[CMap] == 8) - return readcmap; - return readbyte; -} - -static Readfn* -readalphafn(Memimage *m) -{ - USED(m); - return readbyte; -} - -static Writefn* -writefn(Memimage *img) -{ - if(img->depth < 8) - return writenbit; - if(img->chan == CMAP8) - return writecmap; - return writebyte; -} - -static void -nullwrite(Param *p, uchar *s, Buffer b) -{ - USED(p); - USED(s); -} - -static Buffer -readptr(Param *p, uchar *s, int y) -{ - Buffer b; - uchar *q; - - USED(s); - memset(&b, 0, sizeof b); - q = p->bytermin + y*p->bwidth; - b.red = q; /* ptr to data */ - b.grn = b.blu = b.grey = b.alpha = nil; - b.rgba = (u32int*)q; - b.delta = p->img->depth/8; - return b; -} - -static Buffer -boolmemmove(Buffer bdst, Buffer bsrc, Buffer b1, int dx, int i, int o) -{ - USED(i); - USED(o); - memmove(bdst.red, bsrc.red, dx*bdst.delta); - return bdst; -} - -static Buffer -boolcopy8(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m, *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = bdst.red; - r = bsrc.red; - ew = w+dx; - for(; w < ew; w++,r++) - if(*m++) - *w = *r; - return bdst; /* not used */ -} - -static Buffer -boolcopy16(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m; - ushort *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = (ushort*)bdst.red; - r = (ushort*)bsrc.red; - ew = w+dx; - for(; w < ew; w++,r++) - if(*m++) - *w = *r; - return bdst; /* not used */ -} - -static Buffer -boolcopy24(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m; - uchar *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = bdst.red; - r = bsrc.red; - ew = w+dx*3; - while(w < ew){ - if(*m++){ - *w++ = *r++; - *w++ = *r++; - *w++ = *r++; - }else{ - w += 3; - r += 3; - } - } - return bdst; /* not used */ -} - -static Buffer -boolcopy32(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o) -{ - uchar *m; - u32int *r, *w, *ew; - - USED(i); - USED(o); - m = bmask.grey; - w = (u32int*)bdst.red; - r = (u32int*)bsrc.red; - ew = w+dx; - for(; w < ew; w++,r++) - if(*m++) - *w = *r; - return bdst; /* not used */ -} - -static Buffer -genconv(Param *p, uchar *buf, int y) -{ - Buffer b; - int nb; - uchar *r, *w, *ew; - - /* read from source into RGB format in convbuf */ - b = p->convreadcall(p, p->convbuf, y); - - /* write RGB format into dst format in buf */ - p->convwritecall(p->convdpar, buf, b); - - if(p->convdx){ - nb = p->convdpar->img->depth/8; - r = buf; - w = buf+nb*p->dx; - ew = buf+nb*p->convdx; - while(wchan == src->chan && !(src->flags&Frepl)){ -/*if(drawdebug) iprint("readptr..."); */ - return readptr; - } - - if(dst->chan==CMAP8 && (src->chan==GREY1||src->chan==GREY2||src->chan==GREY4)){ - /* cheat because we know the replicated value is exactly the color map entry. */ -/*if(drawdebug) iprint("Readnbit..."); */ - return readnbit; - } - - spar->convreadcall = readfn(src); - spar->convwritecall = writefn(dst); - spar->convdpar = dpar; - - /* allocate a conversion buffer */ - spar->convbufoff = ndrawbuf; - ndrawbuf += spar->dx*4; - - if(spar->dx > Dx(spar->img->r)){ - spar->convdx = spar->dx; - spar->dx = Dx(spar->img->r); - } - -/*if(drawdebug) iprint("genconv..."); */ - return genconv; -} - -/* - * Do NOT call this directly. pixelbits is a wrapper - * around this that fetches the bits from the X server - * when necessary. - */ -u32int -_pixelbits(Memimage *i, Point pt) -{ - uchar *p; - u32int val; - int off, bpp, npack; - - val = 0; - p = byteaddr(i, pt); - switch(bpp=i->depth){ - case 1: - case 2: - case 4: - npack = 8/bpp; - off = pt.x%npack; - val = p[0] >> bpp*(npack-1-off); - val &= (1<flags&Frepl && Dx(mask->r)==1 && Dy(mask->r)==1 && pixelbits(mask, mask->r.min)==~0) - return boolmemmove; - - switch(img->depth){ - case 8: - return boolcopy8; - case 16: - return boolcopy16; - case 24: - return boolcopy24; - case 32: - return boolcopy32; - default: - assert(0 /* boolcopyfn */); - } - return 0; -} - -/* - * Optimized draw for filling and scrolling; uses memset and memmove. - */ -static void -memsets(void *vp, ushort val, int n) -{ - ushort *p, *ep; - - p = vp; - ep = p+n; - while(p>8; - c = val>>16; - while(pchan; chan; chan>>=8){ - nb = NBITS(chan); - ov = v = val&((1<>= nb; - - while(nb < 8){ - v |= v<>= (nb-8); - - switch(TYPE(chan)){ - case CRed: - r = v; - break; - case CGreen: - g = v; - break; - case CBlue: - b = v; - break; - case CAlpha: - a = v; - break; - case CGrey: - r = g = b = v; - break; - case CMap: - p = img->cmap->cmap2rgb+3*ov; - r = *p++; - g = *p++; - b = *p; - break; - } - } - return (r<<24)|(g<<16)|(b<<8)|a; -} - -u32int -_rgbatoimg(Memimage *img, u32int rgba) -{ - u32int chan; - int d, nb; - u32int v; - uchar *p, r, g, b, a, m; - - v = 0; - r = rgba>>24; - g = rgba>>16; - b = rgba>>8; - a = rgba; - d = 0; - for(chan=img->chan; chan; chan>>=8){ - nb = NBITS(chan); - switch(TYPE(chan)){ - case CRed: - v |= (r>>(8-nb))<>(8-nb))<>(8-nb))<>(8-nb))<cmap->rgb2cmap; - m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; - v |= (m>>(8-nb))<>(8-nb))<r); - dy = Dy(par->r); - src = par->src; - dst = par->dst; - op = par->op; - -DBG print("state %lux mval %lux dd %d\n", par->state, par->mval, dst->depth); - /* - * If we have an opaque mask and source is one opaque pixel we can convert to the - * destination format and just replicate with memset. - */ - m = Simplesrc|Simplemask|Fullmask; - if((par->state&m)==m && (par->srgba&0xFF) == 0xFF && (op ==S || op == SoverD)){ - uchar *dp, p[4]; - int d, dwid, ppb, np, nb; - uchar lm, rm; - -DBG print("memopt, dst %p, dst->data->bdata %p\n", dst, dst->data->bdata); - dwid = dst->width*sizeof(u32int); - dp = byteaddr(dst, par->r.min); - v = par->sdval; -DBG print("sdval %lud, depth %d\n", v, dst->depth); - switch(dst->depth){ - case 1: - case 2: - case 4: - for(d=dst->depth; d<8; d*=2) - v |= (v<depth; /* pixels per byte */ - m = ppb-1; - /* left edge */ - np = par->r.min.x&m; /* no. pixels unused on left side of word */ - dx -= (ppb-np); - nb = 8 - np * dst->depth; /* no. bits used on right side of word */ - lm = (1<r.min.x, nb, lm, ppb, m); - - /* right edge */ - np = par->r.max.x&m; /* no. pixels used on left side of word */ - dx -= np; - nb = 8 - np * dst->depth; /* no. bits unused on right side of word */ - rm = ~((1<r.max.x, nb, rm, ppb, m); - -DBG print("dx %d Dx %d\n", dx, Dx(par->r)); - /* lm, rm are masks that are 1 where we should touch the bits */ - if(dx < 0){ /* just one byte */ - lm &= rm; - for(y=0; y>8; - v = *(ushort*)p; -DBG print("dp=%p; dx=%d; for(y=0; y<%d; y++, dp+=%d)\nmemsets(dp, v, dx);\n", - dp, dx, dy, dwid); - for(y=0; y>8; - p[2] = v>>16; - p[3] = v>>24; - v = *(u32int*)p; - for(y=0; ystate&(m|Replsrc))==m && src->depth >= 8 - && src->chan == dst->chan && !(src->flags&Falpha) && (op == S || op == SoverD)){ - uchar *sp, *dp; - long swid, dwid, nb; - int dir; - - if(src->data == dst->data && byteaddr(dst, par->r.min) > byteaddr(src, par->sr.min)) - dir = -1; - else - dir = 1; - - swid = src->width*sizeof(u32int); - dwid = dst->width*sizeof(u32int); - sp = byteaddr(src, par->sr.min); - dp = byteaddr(dst, par->r.min); - if(dir == -1){ - sp += (dy-1)*swid; - dp += (dy-1)*dwid; - swid = -swid; - dwid = -dwid; - } - nb = (dx*src->depth)/8; - for(y=0; ystate&(Simplemask|Simplesrc|Replmask|Replsrc))==0 - && dst->chan==GREY1 && src->chan==GREY1 && par->mask->chan==GREY1 - && (par->r.min.x&7)==(par->sr.min.x&7) && (par->r.min.x&7)==(par->mr.min.x&7)){ - uchar *sp, *dp, *mp; - uchar lm, rm; - long swid, dwid, mwid; - int i, x, dir; - - sp = byteaddr(src, par->sr.min); - dp = byteaddr(dst, par->r.min); - mp = byteaddr(par->mask, par->mr.min); - swid = src->width*sizeof(u32int); - dwid = dst->width*sizeof(u32int); - mwid = par->mask->width*sizeof(u32int); - - if(src->data == dst->data && byteaddr(dst, par->r.min) > byteaddr(src, par->sr.min)){ - dir = -1; - }else - dir = 1; - - lm = 0xFF>>(par->r.min.x&7); - rm = 0xFF<<(8-(par->r.max.x&7)); - dx -= (8-(par->r.min.x&7)) + (par->r.max.x&7); - - if(dx < 0){ /* one byte wide */ - lm &= rm; - if(dir == -1){ - dp += dwid*(dy-1); - sp += swid*(dy-1); - mp += mwid*(dy-1); - dwid = -dwid; - swid = -swid; - mwid = -mwid; - } - for(y=0; ymask->flags, par->mask->depth, par->src->flags, - Dx(par->src->r), Dy(par->src->r), par->dst->depth, par->dst->data, par->src->data); - - mask = par->mask; - src = par->src; - dst = par->dst; - r = par->r; - mr = par->mr; - op = par->op; - - if((par->state&(Replsrc|Simplesrc|Fullsrc|Replmask)) != (Replsrc|Simplesrc|Fullsrc) - || mask->depth != 1 || dst->depth<8 || dst->data==src->data - || op != SoverD) - return 0; - -/*if(drawdebug) iprint("chardraw..."); */ - - depth = mask->depth; - maskwid = mask->width*sizeof(u32int); - rp = byteaddr(mask, mr.min); - npack = 8/depth; - bsh = (mr.min.x % npack) * depth; - - wp = byteaddr(dst, r.min); - dstwid = dst->width*sizeof(u32int); -DBG print("bsh %d\n", bsh); - dy = Dy(r); - dx = Dx(r); - - ddepth = dst->depth; - - /* - * for loop counts from bsh to bsh+dx - * - * we want the bottom bits to be the amount - * to shift the pixels down, so for n≡0 (mod 8) we want - * bottom bits 7. for n≡1, 6, etc. - * the bits come from -n-1. - */ - - bx = -bsh-1; - ex = -bsh-1-dx; - SET(bits); - v = par->sdval; - - /* make little endian */ - sp[0] = v; - sp[1] = v>>8; - sp[2] = v>>16; - sp[3] = v>>24; - -/*print("sp %x %x %x %x\n", sp[0], sp[1], sp[2], sp[3]); */ - for(y=0; yex; x--, wc++){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG print("bits %lux sh %d...", bits, i); - if((bits>>i)&1) - *wc = v; - } - break; - case 16: - ws = (ushort*)wp; - v = *(ushort*)sp; - for(x=bx; x>ex; x--, ws++){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG print("bits %lux sh %d...", bits, i); - if((bits>>i)&1) - *ws = v; - } - break; - case 24: - wc = wp; - for(x=bx; x>ex; x--, wc+=3){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG print("bits %lux sh %d...", bits, i); - if((bits>>i)&1){ - wc[0] = sp[0]; - wc[1] = sp[1]; - wc[2] = sp[2]; - } - } - break; - case 32: - wl = (u32int*)wp; - v = *(u32int*)sp; - for(x=bx; x>ex; x--, wl++){ - i = x&7; - if(i == 8-1) - bits = *q++; -DBG iprint("bits %lux sh %d...", bits, i); - if((bits>>i)&1) - *wl = v; - } - break; - } - } - -DBG print("\n"); - return 1; -} -#undef DBG - - -/* - * Fill entire byte with replicated (if necessary) copy of source pixel, - * assuming destination ldepth is >= source ldepth. - * - * This code is just plain wrong for >8bpp. - * -u32int -membyteval(Memimage *src) -{ - int i, val, bpp; - uchar uc; - - unloadmemimage(src, src->r, &uc, 1); - bpp = src->depth; - uc <<= (src->r.min.x&(7/src->depth))*src->depth; - uc &= ~(0xFF>>bpp); - * pixel value is now in high part of byte. repeat throughout byte - val = uc; - for(i=bpp; i<8; i<<=1) - val |= val>>i; - return val; -} - * - */ - -void -_memfillcolor(Memimage *i, u32int val) -{ - u32int bits; - int d, y; - uchar p[4]; - - if(val == DNofill) - return; - - bits = _rgbatoimg(i, val); - switch(i->depth){ - case 24: /* 24-bit images suck */ - for(y=i->r.min.y; yr.max.y; y++) - memset24(byteaddr(i, Pt(i->r.min.x, y)), bits, Dx(i->r)); - break; - default: /* 1, 2, 4, 8, 16, 32 */ - for(d=i->depth; d<32; d*=2) - bits = (bits << d) | bits; - p[0] = bits; /* make little endian */ - p[1] = bits>>8; - p[2] = bits>>16; - p[3] = bits>>24; - bits = *(u32int*)p; - memsetl(wordaddr(i, i->r.min), bits, i->width*Dy(i->r)); - break; - } -} - blob - 9d991782589c4659265a782c13fc3bd707e800f4 (mode 644) blob + /dev/null --- src/libdraw/md-drawtest.c +++ /dev/null @@ -1,1004 +0,0 @@ -#include -#include -#include -#include -#include - -#define DBG if(0) -#define RGB2K(r,g,b) ((299*((u32int)(r))+587*((u32int)(g))+114*((u32int)(b)))/1000) - -/* - * This program tests the 'memimagedraw' primitive stochastically. - * It tests the combination aspects of it thoroughly, but since the - * three images it uses are disjoint, it makes no check of the - * correct behavior when images overlap. That is, however, much - * easier to get right and to test. - */ - -void drawonepixel(Memimage*, Point, Memimage*, Point, Memimage*, Point); -void verifyone(void); -void verifyline(void); -void verifyrect(void); -void verifyrectrepl(int, int); -void putpixel(Memimage *img, Point pt, u32int nv); -u32int rgbatopix(uchar, uchar, uchar, uchar); - -char *dchan, *schan, *mchan; -int dbpp, sbpp, mbpp; - -int drawdebug=0; -int seed; -int niters = 100; -int dbpp; /* bits per pixel in destination */ -int sbpp; /* bits per pixel in src */ -int mbpp; /* bits per pixel in mask */ -int dpm; /* pixel mask at high part of byte, in destination */ -int nbytes; /* in destination */ - -int Xrange = 64; -int Yrange = 8; - -Memimage *dst; -Memimage *src; -Memimage *mask; -Memimage *stmp; -Memimage *mtmp; -Memimage *ones; -uchar *dstbits; -uchar *srcbits; -uchar *maskbits; -u32int *savedstbits; - -void -rdb(void) -{ -} - -int -iprint(char *fmt, ...) -{ - int n; - va_list va; - char buf[1024]; - - va_start(va, fmt); - n = doprint(buf, buf+sizeof buf, fmt, va) - buf; - va_end(va); - - write(1,buf,n); - return 1; -} - -void -main(int argc, char *argv[]) -{ - memimageinit(); - seed = time(0); - - ARGBEGIN{ - case 'x': - Xrange = atoi(ARGF()); - break; - case 'y': - Yrange = atoi(ARGF()); - break; - case 'n': - niters = atoi(ARGF()); - break; - case 's': - seed = atoi(ARGF()); - break; - }ARGEND - - dchan = "r8g8b8"; - schan = "r8g8b8"; - mchan = "r8g8b8"; - switch(argc){ - case 3: mchan = argv[2]; - case 2: schan = argv[1]; - case 1: dchan = argv[0]; - case 0: break; - default: goto Usage; - Usage: - fprint(2, "usage: dtest [dchan [schan [mchan]]]\n"); - exits("usage"); - } - - fmtinstall('b', numbconv); /* binary! */ - - fprint(2, "%s -x %d -y %d -s 0x%x %s %s %s\n", argv0, Xrange, Yrange, seed, dchan, schan, mchan); - srand(seed); - - dst = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(dchan)); - src = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(schan)); - mask = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(mchan)); - stmp = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(schan)); - mtmp = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(mchan)); - ones = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(mchan)); -/* print("chan %lux %lux %lux %lux %lux %lux\n", dst->chan, src->chan, mask->chan, stmp->chan, mtmp->chan, ones->chan); */ - if(dst==0 || src==0 || mask==0 || mtmp==0 || ones==0) { - Alloc: - fprint(2, "dtest: allocation failed: %r\n"); - exits("alloc"); - } - nbytes = (4*Xrange+4)*Yrange; - srcbits = malloc(nbytes); - dstbits = malloc(nbytes); - maskbits = malloc(nbytes); - savedstbits = malloc(nbytes); - if(dstbits==0 || srcbits==0 || maskbits==0 || savedstbits==0) - goto Alloc; - dbpp = dst->depth; - sbpp = src->depth; - mbpp = mask->depth; - dpm = 0xFF ^ (0xFF>>dbpp); - memset(ones->data->bdata, 0xFF, ones->width*sizeof(u32int)*Yrange); - - - fprint(2, "dtest: verify single pixel operation\n"); - verifyone(); - - fprint(2, "dtest: verify full line non-replicated\n"); - verifyline(); - - fprint(2, "dtest: verify full rectangle non-replicated\n"); - verifyrect(); - - fprint(2, "dtest: verify full rectangle source replicated\n"); - verifyrectrepl(1, 0); - - fprint(2, "dtest: verify full rectangle mask replicated\n"); - verifyrectrepl(0, 1); - - fprint(2, "dtest: verify full rectangle source and mask replicated\n"); - verifyrectrepl(1, 1); - - exits(0); -} - -/* - * Dump out an ASCII representation of an image. The label specifies - * a list of characters to put at various points in the picture. - */ -static void -Bprintr5g6b5(Biobuf *bio, char*, u32int v) -{ - int r,g,b; - r = (v>>11)&31; - g = (v>>5)&63; - b = v&31; - Bprint(bio, "%.2x%.2x%.2x", r,g,b); -} - -static void -Bprintr5g5b5a1(Biobuf *bio, char*, u32int v) -{ - int r,g,b,a; - r = (v>>11)&31; - g = (v>>6)&31; - b = (v>>1)&31; - a = v&1; - Bprint(bio, "%.2x%.2x%.2x%.2x", r,g,b,a); -} - -void -dumpimage(char *name, Memimage *img, void *vdata, Point labelpt) -{ - Biobuf b; - uchar *data; - uchar *p; - char *arg; - void (*fmt)(Biobuf*, char*, u32int); - int npr, x, y, nb, bpp; - u32int v, mask; - Rectangle r; - - fmt = nil; - arg = nil; - switch(img->depth){ - case 1: - case 2: - case 4: - fmt = (void(*)(Biobuf*,char*,u32int))Bprint; - arg = "%.1ux"; - break; - case 8: - fmt = (void(*)(Biobuf*,char*,u32int))Bprint; - arg = "%.2ux"; - break; - case 16: - arg = nil; - if(img->chan == RGB16) - fmt = Bprintr5g6b5; - else{ - fmt = (void(*)(Biobuf*,char*,u32int))Bprint; - arg = "%.4ux"; - } - break; - case 24: - fmt = (void(*)(Biobuf*,char*,u32int))Bprint; - arg = "%.6lux"; - break; - case 32: - fmt = (void(*)(Biobuf*,char*,u32int))Bprint; - arg = "%.8lux"; - break; - } - if(fmt == nil){ - fprint(2, "bad format\n"); - abort(); - } - - r = img->r; - Binit(&b, 2, OWRITE); - data = vdata; - bpp = img->depth; - Bprint(&b, "%s\t%d\tr %R clipr %R repl %d data %p *%P\n", name, r.min.x, r, img->clipr, (img->flags&Frepl) ? 1 : 0, vdata, labelpt); - mask = (1ULL<data->bdata); - Bprint(&b, "%-4d\t", y); -/* for(x=r.min.x; x>nb)&mask); - } - Bprint(&b, "\n"); - } - Bterm(&b); -} - -/* - * Verify that the destination pixel has the specified value. - * The value is in the high bits of v, suitably masked, but must - * be extracted from the destination Memimage. - */ -void -checkone(Point p, Point sp, Point mp) -{ - int delta; - uchar *dp, *sdp; - - delta = (uchar*)byteaddr(dst, p)-(uchar*)dst->data->bdata; - dp = (uchar*)dst->data->bdata+delta; - sdp = (uchar*)savedstbits+delta; - - if(memcmp(dp, sdp, (dst->depth+7)/8) != 0) { - fprint(2, "dtest: one bad pixel drawing at dst %P from source %P mask %P\n", p, sp, mp); - fprint(2, " %.2ux %.2ux %.2ux %.2ux should be %.2ux %.2ux %.2ux %.2ux\n", - dp[0], dp[1], dp[2], dp[3], sdp[0], sdp[1], sdp[2], sdp[3]); - fprint(2, "addresses dst %p src %p mask %p\n", dp, byteaddr(src, sp), byteaddr(mask, mp)); - dumpimage("src", src, src->data->bdata, sp); - dumpimage("mask", mask, mask->data->bdata, mp); - dumpimage("origdst", dst, dstbits, p); - dumpimage("dst", dst, dst->data->bdata, p); - dumpimage("gooddst", dst, savedstbits, p); - abort(); - } -} - -/* - * Verify that the destination line has the same value as the saved line. - */ -#define RECTPTS(r) (r).min.x, (r).min.y, (r).max.x, (r).max.y -void -checkline(Rectangle r, Point sp, Point mp, int y, Memimage *stmp, Memimage *mtmp) -{ - u32int *dp; - int nb; - u32int *saved; - - dp = wordaddr(dst, Pt(0, y)); - saved = savedstbits + y*dst->width; - if(dst->depth < 8) - nb = Xrange/(8/dst->depth); - else - nb = Xrange*(dst->depth/8); - if(memcmp(dp, saved, nb) != 0){ - fprint(2, "dtest: bad line at y=%d; saved %p dp %p\n", y, saved, dp); - fprint(2, "draw dst %R src %P mask %P\n", r, sp, mp); - dumpimage("src", src, src->data->bdata, sp); - if(stmp) dumpimage("stmp", stmp, stmp->data->bdata, sp); - dumpimage("mask", mask, mask->data->bdata, mp); - if(mtmp) dumpimage("mtmp", mtmp, mtmp->data->bdata, mp); - dumpimage("origdst", dst, dstbits, r.min); - dumpimage("dst", dst, dst->data->bdata, r.min); - dumpimage("gooddst", dst, savedstbits, r.min); - abort(); - } -} - -/* - * Fill the bits of an image with random data. - * The Memimage parameter is used only to make sure - * the data is well formatted: only ucbits is written. - */ -void -fill(Memimage *img, uchar *ucbits) -{ - int i, x, y; - ushort *up; - uchar alpha, r, g, b; - void *data; - - if((img->flags&Falpha) == 0){ - up = (ushort*)ucbits; - for(i=0; i> 7; - if(i+i != nbytes) - *(uchar*)up = lrand() >> 7; - }else{ - data = img->data->bdata; - img->data->bdata = ucbits; - - for(x=img->r.min.x; xr.max.x; x++) - for(y=img->r.min.y; yr.max.y; y++){ - alpha = rand() >> 4; - r = rand()%(alpha+1); - g = rand()%(alpha+1); - b = rand()%(alpha+1); - putpixel(img, Pt(x,y), rgbatopix(r,g,b,alpha)); - } - img->data->bdata = data; - } - -} - -/* - * Mask is preset; do the rest - */ -void -verifyonemask(void) -{ - Point dp, sp, mp; - - fill(dst, dstbits); - fill(src, srcbits); - memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange); - memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange); - - dp.x = nrand(Xrange); - dp.y = nrand(Yrange); - - sp.x = nrand(Xrange); - sp.y = nrand(Yrange); - - mp.x = nrand(Xrange); - mp.y = nrand(Yrange); - - drawonepixel(dst, dp, src, sp, mask, mp); - memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange); - memmove(savedstbits, dst->data->bdata, dst->width*sizeof(u32int)*Yrange); - - memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - memimagedraw(dst, Rect(dp.x, dp.y, dp.x+1, dp.y+1), src, sp, mask, mp, SoverD); - memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange); - - checkone(dp, sp, mp); -} - -void -verifyone(void) -{ - int i; - - /* mask all zeros */ - memset(maskbits, 0, nbytes); - for(i=0; idata->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange); - memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange); - - dr.min.x = nrand(Xrange-1); - dr.min.y = nrand(Yrange-1); - dr.max.x = dr.min.x + 1 + nrand(Xrange-1-dr.min.x); - dr.max.y = dr.min.y + 1; - - sp.x = nrand(Xrange); - sp.y = nrand(Yrange); - - mp.x = nrand(Xrange); - mp.y = nrand(Yrange); - - tp = sp; - up = mp; - for(x=dr.min.x; xdata->bdata, dst->width*sizeof(u32int)*Yrange); - - memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - - memimagedraw(dst, dr, src, sp, mask, mp, SoverD); - checkline(dr, drawrepl(src->r, sp), drawrepl(mask->r, mp), dr.min.y, nil, nil); -} - -void -verifyline(void) -{ - int i; - - /* mask all ones */ - memset(maskbits, 0xFF, nbytes); - for(i=0; idata->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange); - memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange); - - dr.min.x = nrand(Xrange-1); - dr.min.y = nrand(Yrange-1); - dr.max.x = dr.min.x + 1 + nrand(Xrange-1-dr.min.x); - dr.max.y = dr.min.y + 1 + nrand(Yrange-1-dr.min.y); - - sp.x = nrand(Xrange); - sp.y = nrand(Yrange); - - mp.x = nrand(Xrange); - mp.y = nrand(Yrange); - - tp = sp; - up = mp; - for(y=dr.min.y; ydata->bdata, dst->width*sizeof(u32int)*Yrange); - - memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - - memimagedraw(dst, dr, src, sp, mask, mp, SoverD); - for(y=0; yr, sp), drawrepl(mask->r, mp), y, nil, nil); -} - -void -verifyrect(void) -{ - int i; - - /* mask all zeros */ - memset(maskbits, 0, nbytes); - for(i=0; ir) */ - r.min.x = nrand(Xrange-1); - r.min.y = nrand(Yrange-1); - /* make it trivial more often than pure chance allows */ - switch(lrand()&0){ - case 1: - r.max.x = r.min.x + 2; - r.max.y = r.min.y + 2; - if(r.max.x < Xrange && r.max.y < Yrange) - break; - /* fall through */ - case 0: - r.max.x = r.min.x + 1; - r.max.y = r.min.y + 1; - break; - default: - if(r.min.x+3 >= Xrange) - r.max.x = Xrange; - else - r.max.x = r.min.x+3 + nrand(Xrange-(r.min.x+3)); - - if(r.min.y+3 >= Yrange) - r.max.y = Yrange; - else - r.max.y = r.min.y+3 + nrand(Yrange-(r.min.y+3)); - } - assert(r.min.x >= 0); - assert(r.max.x <= Xrange); - assert(r.min.y >= 0); - assert(r.max.y <= Yrange); - /* copy from i to tmp so we have just the replicated bits */ - nb = tmp->width*sizeof(u32int)*Yrange; - memset(tmp->data->bdata, 0, nb); - memimagedraw(tmp, r, i, r.min, ones, r.min, SoverD); - memmove(i->data->bdata, tmp->data->bdata, nb); - /* i is now a non-replicated instance of the replication */ - /* replicate it by hand through tmp */ - memset(tmp->data->bdata, 0, nb); - x = -(tilexy(r.min.x, r.max.x, 0)-r.min.x); - for(; xflags |= Frepl; - i->r = r; - i->clipr = randrect(); -/* fprint(2, "replicate [[%d %d] [%d %d]] [[%d %d][%d %d]]\n", r.min.x, r.min.y, r.max.x, r.max.y, */ -/* i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y); */ - tmp->clipr = i->clipr; -} - -/* - * Mask is preset; do the rest - */ -void -verifyrectmaskrepl(int srcrepl, int maskrepl) -{ - Point sp, mp, tp, up; - Rectangle dr; - int x, y; - Memimage *s, *m; - -/* print("verfrect %d %d\n", srcrepl, maskrepl); */ - src->flags &= ~Frepl; - src->r = Rect(0, 0, Xrange, Yrange); - src->clipr = src->r; - stmp->flags &= ~Frepl; - stmp->r = Rect(0, 0, Xrange, Yrange); - stmp->clipr = src->r; - mask->flags &= ~Frepl; - mask->r = Rect(0, 0, Xrange, Yrange); - mask->clipr = mask->r; - mtmp->flags &= ~Frepl; - mtmp->r = Rect(0, 0, Xrange, Yrange); - mtmp->clipr = mask->r; - - fill(dst, dstbits); - fill(src, srcbits); - - memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange); - memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange); - - if(srcrepl){ - replicate(src, stmp); - s = stmp; - }else - s = src; - if(maskrepl){ - replicate(mask, mtmp); - m = mtmp; - }else - m = mask; - - dr = randrect(); - - sp.x = nrand(Xrange); - sp.y = nrand(Yrange); - - mp.x = nrand(Xrange); - mp.y = nrand(Yrange); - -DBG print("smalldraws\n"); - for(tp.y=sp.y,up.y=mp.y,y=dr.min.y; ydata->bdata, dst->width*sizeof(u32int)*Yrange); - - memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange); - -DBG print("bigdraw\n"); - memimagedraw(dst, dr, src, sp, mask, mp, SoverD); - for(y=0; yr, sp), drawrepl(mask->r, mp), y, srcrepl?stmp:nil, maskrepl?mtmp:nil); -} - -void -verifyrectrepl(int srcrepl, int maskrepl) -{ - int i; - - /* mask all ones */ - memset(maskbits, 0xFF, nbytes); - for(i=0; i>= (nhave-nwant); - return v & ((1<>24; - *r = v>>16; - *g = v>>8; - *b = v; -} - -/* - * Convert uchar channels into u32int pixel. - */ -u32int -rgbatopix(uchar r, uchar g, uchar b, uchar a) -{ - return (a<<24)|(r<<16)|(g<<8)|b; -} - -/* - * Retrieve the pixel value at pt in the image. - */ -u32int -getpixel(Memimage *img, Point pt) -{ - uchar r, g, b, a, *p; - int nbits, npack, bpp; - u32int v, c, rbits, bits; - - r = g = b = 0; - a = ~0; /* default alpha is full */ - - p = byteaddr(img, pt); - v = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24); - bpp = img->depth; - if(bpp<8){ - /* - * Sub-byte greyscale pixels. - * - * We want to throw away the top pt.x%npack pixels and then use the next bpp bits - * in the bottom byte of v. This madness is due to having big endian bits - * but little endian bytes. - */ - npack = 8/bpp; - v >>= 8 - bpp*(pt.x%npack+1); - v &= (1<chan; c; c>>=8){ - nbits = NBITS(c); - bits = v & ((1<>= nbits; - switch(TYPE(c)){ - case CRed: - r = rbits; - break; - case CGreen: - g = rbits; - break; - case CBlue: - b = rbits; - break; - case CGrey: - r = g = b = rbits; - break; - case CAlpha: - a = rbits; - break; - case CMap: - p = img->cmap->cmap2rgb + 3*bits; - r = p[0]; - g = p[1]; - b = p[2]; - break; - case CIgnore: - break; - default: - fprint(2, "unknown channel type %lud\n", TYPE(c)); - abort(); - } - } - } - return rgbatopix(r, g, b, a); -} - -/* - * Return the greyscale equivalent of a pixel. - */ -uchar -getgrey(Memimage *img, Point pt) -{ - uchar r, g, b, a; - pixtorgba(getpixel(img, pt), &r, &g, &b, &a); - return RGB2K(r, g, b); -} - -/* - * Return the value at pt in image, if image is interpreted - * as a mask. This means the alpha channel if present, else - * the greyscale or its computed equivalent. - */ -uchar -getmask(Memimage *img, Point pt) -{ - if(img->flags&Falpha) - return getpixel(img, pt)>>24; - else - return getgrey(img, pt); -} -#undef DBG - -#define DBG if(0) -/* - * Write a pixel to img at point pt. - * - * We do this by reading a 32-bit little endian - * value from p and then writing it back - * after tweaking the appropriate bits. Because - * the data is little endian, we don't have to worry - * about what the actual depth is, as long as it is - * less than 32 bits. - */ -void -putpixel(Memimage *img, Point pt, u32int nv) -{ - uchar r, g, b, a, *p, *q; - u32int c, mask, bits, v; - int bpp, sh, npack, nbits; - - pixtorgba(nv, &r, &g, &b, &a); - - p = byteaddr(img, pt); - v = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24); - bpp = img->depth; -DBG print("v %.8lux...", v); - if(bpp < 8){ - /* - * Sub-byte greyscale pixels. We need to skip the leftmost pt.x%npack pixels, - * which is equivalent to skipping the rightmost npack - pt.x%npack - 1 pixels. - */ - npack = 8/bpp; - sh = bpp*(npack - pt.x%npack - 1); - bits = RGB2K(r,g,b); -DBG print("repl %lux 8 %d = %lux...", bits, bpp, replbits(bits, 8, bpp)); - bits = replbits(bits, 8, bpp); - mask = (1<chan; c; c>>=8){ - nbits = NBITS(c); - switch(TYPE(c)){ - case CRed: - bits = r; - break; - case CGreen: - bits = g; - break; - case CBlue: - bits = b; - break; - case CGrey: - bits = RGB2K(r, g, b); - break; - case CAlpha: - bits = a; - break; - case CIgnore: - bits = 0; - break; - case CMap: - q = img->cmap->rgb2cmap; - bits = q[(r>>4)*16*16+(g>>4)*16+(b>>4)]; - break; - default: - SET(bits); - fprint(2, "unknown channel type %lud\n", TYPE(c)); - abort(); - } - -DBG print("repl %lux 8 %d = %lux...", bits, nbits, replbits(bits, 8, nbits)); - if(TYPE(c) != CMap) - bits = replbits(bits, 8, nbits); - mask = (1<>8; - p[2] = v>>16; - p[3] = v>>24; -} -#undef DBG - -#define DBG if(0) -void -drawonepixel(Memimage *dst, Point dp, Memimage *src, Point sp, Memimage *mask, Point mp) -{ - uchar m, M, sr, sg, sb, sa, sk, dr, dg, db, da, dk; - - pixtorgba(getpixel(dst, dp), &dr, &dg, &db, &da); - pixtorgba(getpixel(src, sp), &sr, &sg, &sb, &sa); - m = getmask(mask, mp); - M = 255-(sa*m)/255; - -DBG print("dst %x %x %x %x src %x %x %x %x m %x = ", dr,dg,db,da, sr,sg,sb,sa, m); - if(dst->flags&Fgrey){ - /* - * We need to do the conversion to grey before the alpha calculation - * because the draw operator does this, and we need to be operating - * at the same precision so we get exactly the same answers. - */ - sk = RGB2K(sr, sg, sb); - dk = RGB2K(dr, dg, db); - dk = (sk*m + dk*M)/255; - dr = dg = db = dk; - da = (sa*m + da*M)/255; - }else{ - /* - * True color alpha calculation treats all channels (including alpha) - * the same. It might have been nice to use an array, but oh well. - */ - dr = (sr*m + dr*M)/255; - dg = (sg*m + dg*M)/255; - db = (sb*m + db*M)/255; - da = (sa*m + da*M)/255; - } - -DBG print("%x %x %x %x\n", dr,dg,db,da); - putpixel(dst, dp, rgbatopix(dr, dg, db, da)); -} blob - 7dc45cd6fee3dab9ea799c8b0dcdb62422018e20 (mode 644) blob + /dev/null --- src/libdraw/md-ellipse.c +++ /dev/null @@ -1,247 +0,0 @@ -#include -#include -#include -#include - -/* - * ellipse(dst, c, a, b, t, src, sp) - * draws an ellipse centered at c with semiaxes a,b>=0 - * and semithickness t>=0, or filled if t<0. point sp - * in src maps to c in dst - * - * very thick skinny ellipses are brushed with circles (slow) - * others are approximated by filling between 2 ellipses - * criterion for very thick when b 0.5*x/(1-x) - * where x = b/a - */ - -typedef struct Param Param; -typedef struct State State; - -static void bellipse(int, State*, Param*); -static void erect(int, int, int, int, Param*); -static void eline(int, int, int, int, Param*); - -struct Param { - Memimage *dst; - Memimage *src; - Point c; - int t; - Point sp; - Memimage *disc; - int op; -}; - -/* - * denote residual error by e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 - * e(x,y) = 0 on ellipse, e(x,y) < 0 inside, e(x,y) > 0 outside - */ - -struct State { - int a; - int x; - vlong a2; /* a^2 */ - vlong b2; /* b^2 */ - vlong b2x; /* b^2 * x */ - vlong a2y; /* a^2 * y */ - vlong c1; - vlong c2; /* test criteria */ - vlong ee; /* ee = e(x+1/2,y-1/2) - (a^2+b^2)/4 */ - vlong dxe; - vlong dye; - vlong d2xe; - vlong d2ye; -}; - -static -State* -newstate(State *s, int a, int b) -{ - s->x = 0; - s->a = a; - s->a2 = (vlong)(a*a); - s->b2 = (vlong)(b*b); - s->b2x = (vlong)0; - s->a2y = s->a2*(vlong)b; - s->c1 = -((s->a2>>2) + (vlong)(a&1) + s->b2); - s->c2 = -((s->b2>>2) + (vlong)(b&1)); - s->ee = -s->a2y; - s->dxe = (vlong)0; - s->dye = s->ee<<1; - s->d2xe = s->b2<<1; - s->d2ye = s->a2<<1; - return s; -} - -/* - * return x coord of rightmost pixel on next scan line - */ -static -int -step(State *s) -{ - while(s->x < s->a) { - if(s->ee+s->b2x <= s->c1 || /* e(x+1,y-1/2) <= 0 */ - s->ee+s->a2y <= s->c2) { /* e(x+1/2,y) <= 0 (rare) */ - s->dxe += s->d2xe; - s->ee += s->dxe; - s->b2x += s->b2; - s->x++; - continue; - } - s->dye += s->d2ye; - s->ee += s->dye; - s->a2y -= s->a2; - if(s->ee-s->a2y <= s->c2) { /* e(x+1/2,y-1) <= 0 */ - s->dxe += s->d2xe; - s->ee += s->dxe; - s->b2x += s->b2; - return s->x++; - } - break; - } - return s->x; -} - -void -memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int op) -{ - State in, out; - int y, inb, inx, outx, u; - Param p; - - if(a < 0) - a = -a; - if(b < 0) - b = -b; - p.dst = dst; - p.src = src; - p.c = c; - p.t = t; - p.sp = subpt(sp, c); - p.disc = nil; - p.op = op; - - u = (t<<1)*(a-b); - if(bb*b || aa*a) { -/* if(bb*b/a || aa*a/b) # very thick */ - bellipse(b, newstate(&in, a, b), &p); - return; - } - - if(t < 0) { - inb = -1; - newstate(&out, a, y = b); - } else { - inb = b - t; - newstate(&out, a+t, y = b+t); - } - if(t > 0) - newstate(&in, a-t, inb); - inx = 0; - for( ; y>=0; y--) { - outx = step(&out); - if(y > inb) { - erect(-outx, y, outx, y, &p); - if(y != 0) - erect(-outx, -y, outx, -y, &p); - continue; - } - if(t > 0) { - inx = step(&in); - if(y == inb) - inx = 0; - } else if(inx > outx) - inx = outx; - erect(inx, y, outx, y, &p); - if(y != 0) - erect(inx, -y, outx, -y, &p); - erect(-outx, y, -inx, y, &p); - if(y != 0) - erect(-outx, -y, -inx, -y, &p); - inx = outx + 1; - } -} - -static Point p00 = {0, 0}; - -/* - * a brushed ellipse - */ -static -void -bellipse(int y, State *s, Param *p) -{ - int t, ox, oy, x, nx; - - t = p->t; - p->disc = allocmemimage(Rect(-t,-t,t+1,t+1), GREY1); - if(p->disc == nil) - return; - memfillcolor(p->disc, DTransparent); - memellipse(p->disc, p00, t, t, -1, memopaque, p00, p->op); - oy = y; - ox = 0; - nx = x = step(s); - do { - while(nx==x && y-->0) - nx = step(s); - y++; - eline(-x,-oy,-ox, -y, p); - eline(ox,-oy, x, -y, p); - eline(-x, y,-ox, oy, p); - eline(ox, y, x, oy, p); - ox = x+1; - x = nx; - y--; - oy = y; - } while(oy > 0); -} - -/* - * a rectangle with closed (not half-open) coordinates expressed - * relative to the center of the ellipse - */ -static -void -erect(int x0, int y0, int x1, int y1, Param *p) -{ - Rectangle r; - -/* print("R %d,%d %d,%d\n", x0, y0, x1, y1); */ - r = Rect(p->c.x+x0, p->c.y+y0, p->c.x+x1+1, p->c.y+y1+1); - memdraw(p->dst, r, p->src, addpt(p->sp, r.min), memopaque, p00, p->op); -} - -/* - * a brushed point similarly specified - */ -static -void -epoint(int x, int y, Param *p) -{ - Point p0; - Rectangle r; - -/* print("P%d %d,%d\n", p->t, x, y); */ - p0 = Pt(p->c.x+x, p->c.y+y); - r = Rpt(addpt(p0, p->disc->r.min), addpt(p0, p->disc->r.max)); - memdraw(p->dst, r, p->src, addpt(p->sp, r.min), p->disc, p->disc->r.min, p->op); -} - -/* - * a brushed horizontal or vertical line similarly specified - */ -static -void -eline(int x0, int y0, int x1, int y1, Param *p) -{ -/* print("L%d %d,%d %d,%d\n", p->t, x0, y0, x1, y1); */ - if(x1 > x0+1) - erect(x0+1, y0-p->t, x1-1, y1+p->t, p); - else if(y1 > y0+1) - erect(x0-p->t, y0+1, x1+p->t, y1-1, p); - epoint(x0, y0, p); - if(x1-x0 || y1-y0) - epoint(x1, y1, p); -} blob - fcacae51afdb6b43a5d33fdc4584964bfec86471 (mode 644) blob + /dev/null --- src/libdraw/md-fillpoly.c +++ /dev/null @@ -1,524 +0,0 @@ -#include -#include -#include -#include - -typedef struct Seg Seg; - -struct Seg -{ - Point p0; - Point p1; - long num; - long den; - long dz; - long dzrem; - long z; - long zerr; - long d; -}; - -static void zsort(Seg **seg, Seg **ep); -static int ycompare(const void*, const void*); -static int xcompare(const void*, const void*); -static int zcompare(const void*, const void*); -static void xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int, int, int); -static void yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int, int); - -#if 0 -static void -fillcolor(Memimage *dst, int left, int right, int y, Memimage *src, Point p) -{ - int srcval; - - USED(src); - srcval = p.x; - p.x = left; - p.y = y; - memset(byteaddr(dst, p), srcval, right-left); -} -#endif - -static void -fillline(Memimage *dst, int left, int right, int y, Memimage *src, Point p, int op) -{ - Rectangle r; - - r.min.x = left; - r.min.y = y; - r.max.x = right; - r.max.y = y+1; - p.x += left; - p.y += y; - memdraw(dst, r, src, p, memopaque, p, op); -} - -static void -fillpoint(Memimage *dst, int x, int y, Memimage *src, Point p, int op) -{ - Rectangle r; - - r.min.x = x; - r.min.y = y; - r.max.x = x+1; - r.max.y = y+1; - p.x += x; - p.y += y; - memdraw(dst, r, src, p, memopaque, p, op); -} - -void -memfillpoly(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int op) -{ - _memfillpolysc(dst, vert, nvert, w, src, sp, 0, 0, 0, op); -} - -void -_memfillpolysc(Memimage *dst, Point *vert, int nvert, int w, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op) -{ - Seg **seg, *segtab; - Point p0; - int i; - - if(nvert == 0) - return; - - seg = malloc((nvert+2)*sizeof(Seg*)); - if(seg == nil) - return; - segtab = malloc((nvert+1)*sizeof(Seg)); - if(segtab == nil) { - free(seg); - return; - } - - sp.x = (sp.x - vert[0].x) >> fixshift; - sp.y = (sp.y - vert[0].y) >> fixshift; - p0 = vert[nvert-1]; - if(!fixshift) { - p0.x <<= 1; - p0.y <<= 1; - } - for(i = 0; i < nvert; i++) { - segtab[i].p0 = p0; - p0 = vert[i]; - if(!fixshift) { - p0.x <<= 1; - p0.y <<= 1; - } - segtab[i].p1 = p0; - segtab[i].d = 1; - } - if(!fixshift) - fixshift = 1; - - xscan(dst, seg, segtab, nvert, w, src, sp, detail, fixshift, clipped, op); - if(detail) - yscan(dst, seg, segtab, nvert, w, src, sp, fixshift, op); - - free(seg); - free(segtab); -} - -static long -mod(long x, long y) -{ - long z; - - z = x%y; - if((long)(((ulong)z)^((ulong)y)) > 0 || z == 0) - return z; - return z + y; -} - -static long -sdiv(long x, long y) -{ - if((long)(((ulong)x)^((ulong)y)) >= 0 || x == 0) - return x/y; - - return (x+((y>>30)|1))/y-1; -} - -static long -smuldivmod(long x, long y, long z, long *mod) -{ - vlong vx; - - if(x == 0 || y == 0){ - *mod = 0; - return 0; - } - vx = x; - vx *= y; - *mod = vx % z; - if(*mod < 0) - *mod += z; /* z is always >0 */ - if((vx < 0) == (z < 0)) - return vx/z; - return -((-vx)/z); -} - -static void -xscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int detail, int fixshift, int clipped, int op) -{ - long y, maxy, x, x2, xerr, xden, onehalf; - Seg **ep, **next, **p, **q, *s; - long n, i, iy, cnt, ix, ix2, minx, maxx; - Point pt; - void (*fill)(Memimage*, int, int, int, Memimage*, Point, int); - - fill = fillline; -/* - * This can only work on 8-bit destinations, since fillcolor is - * just using memset on sp.x. - * - * I'd rather not even enable it then, since then if the general - * code is too slow, someone will come up with a better improvement - * than this sleazy hack. -rsc - * - if(clipped && (src->flags&Frepl) && src->depth==8 && Dx(src->r)==1 && Dy(src->r)==1) { - fill = fillcolor; - sp.x = membyteval(src); - } - * - */ - USED(clipped); - - - for(i=0, s=segtab, p=seg; ip0.y == s->p1.y) - continue; - if(s->p0.y > s->p1.y) { - pt = s->p0; - s->p0 = s->p1; - s->p1 = pt; - s->d = -s->d; - } - s->num = s->p1.x - s->p0.x; - s->den = s->p1.y - s->p0.y; - s->dz = sdiv(s->num, s->den) << fixshift; - s->dzrem = mod(s->num, s->den) << fixshift; - s->dz += sdiv(s->dzrem, s->den); - s->dzrem = mod(s->dzrem, s->den); - p++; - } - n = p-seg; - if(n == 0) - return; - *p = 0; - qsort(seg, p-seg , sizeof(Seg*), ycompare); - - onehalf = 0; - if(fixshift) - onehalf = 1 << (fixshift-1); - - minx = dst->clipr.min.x; - maxx = dst->clipr.max.x; - - y = seg[0]->p0.y; - if(y < (dst->clipr.min.y << fixshift)) - y = dst->clipr.min.y << fixshift; - iy = (y + onehalf) >> fixshift; - y = (iy << fixshift) + onehalf; - maxy = dst->clipr.max.y << fixshift; - - ep = next = seg; - - while(yp1.y < y) - continue; - s->z += s->dz; - s->zerr += s->dzrem; - if(s->zerr >= s->den) { - s->z++; - s->zerr -= s->den; - if(s->zerr < 0 || s->zerr >= s->den) - print("bad ratzerr1: %ld den %ld dzrem %ld\n", s->zerr, s->den, s->dzrem); - } - *q++ = s; - } - - for(p = next; *p; p++) { - s = *p; - if(s->p0.y >= y) - break; - if(s->p1.y < y) - continue; - s->z = s->p0.x; - s->z += smuldivmod(y - s->p0.y, s->num, s->den, &s->zerr); - if(s->zerr < 0 || s->zerr >= s->den) - print("bad ratzerr2: %ld den %ld ratdzrem %ld\n", s->zerr, s->den, s->dzrem); - *q++ = s; - } - ep = q; - next = p; - - if(ep == seg) { - if(*next == 0) - break; - iy = (next[0]->p0.y + onehalf) >> fixshift; - y = (iy << fixshift) + onehalf; - continue; - } - - zsort(seg, ep); - - for(p = seg; p < ep; p++) { - cnt = 0; - x = p[0]->z; - xerr = p[0]->zerr; - xden = p[0]->den; - ix = (x + onehalf) >> fixshift; - if(ix >= maxx) - break; - if(ix < minx) - ix = minx; - cnt += p[0]->d; - p++; - for(;;) { - if(p == ep) { - print("xscan: fill to infinity"); - return; - } - cnt += p[0]->d; - if((cnt&wind) == 0) - break; - p++; - } - x2 = p[0]->z; - ix2 = (x2 + onehalf) >> fixshift; - if(ix2 <= minx) - continue; - if(ix2 > maxx) - ix2 = maxx; - if(ix == ix2 && detail) { - if(xerr*p[0]->den + p[0]->zerr*xden > p[0]->den*xden) - x++; - ix = (x + x2) >> (fixshift+1); - ix2 = ix+1; - } - (*fill)(dst, ix, ix2, iy, src, sp, op); - } - y += (1<p0.x == s->p1.x) - continue; - if(s->p0.x > s->p1.x) { - pt = s->p0; - s->p0 = s->p1; - s->p1 = pt; - s->d = -s->d; - } - s->num = s->p1.y - s->p0.y; - s->den = s->p1.x - s->p0.x; - s->dz = sdiv(s->num, s->den) << fixshift; - s->dzrem = mod(s->num, s->den) << fixshift; - s->dz += sdiv(s->dzrem, s->den); - s->dzrem = mod(s->dzrem, s->den); - p++; - } - n = p-seg; - if(n == 0) - return; - *p = 0; - qsort(seg, n , sizeof(Seg*), xcompare); - - onehalf = 0; - if(fixshift) - onehalf = 1 << (fixshift-1); - - miny = dst->clipr.min.y; - maxy = dst->clipr.max.y; - - x = seg[0]->p0.x; - if(x < (dst->clipr.min.x << fixshift)) - x = dst->clipr.min.x << fixshift; - ix = (x + onehalf) >> fixshift; - x = (ix << fixshift) + onehalf; - maxx = dst->clipr.max.x << fixshift; - - ep = next = seg; - - while(xp1.x < x) - continue; - s->z += s->dz; - s->zerr += s->dzrem; - if(s->zerr >= s->den) { - s->z++; - s->zerr -= s->den; - if(s->zerr < 0 || s->zerr >= s->den) - print("bad ratzerr1: %ld den %ld ratdzrem %ld\n", s->zerr, s->den, s->dzrem); - } - *q++ = s; - } - - for(p = next; *p; p++) { - s = *p; - if(s->p0.x >= x) - break; - if(s->p1.x < x) - continue; - s->z = s->p0.y; - s->z += smuldivmod(x - s->p0.x, s->num, s->den, &s->zerr); - if(s->zerr < 0 || s->zerr >= s->den) - print("bad ratzerr2: %ld den %ld ratdzrem %ld\n", s->zerr, s->den, s->dzrem); - *q++ = s; - } - ep = q; - next = p; - - if(ep == seg) { - if(*next == 0) - break; - ix = (next[0]->p0.x + onehalf) >> fixshift; - x = (ix << fixshift) + onehalf; - continue; - } - - zsort(seg, ep); - - for(p = seg; p < ep; p++) { - cnt = 0; - y = p[0]->z; - yerr = p[0]->zerr; - yden = p[0]->den; - iy = (y + onehalf) >> fixshift; - if(iy >= maxy) - break; - if(iy < miny) - iy = miny; - cnt += p[0]->d; - p++; - for(;;) { - if(p == ep) { - print("yscan: fill to infinity"); - return; - } - cnt += p[0]->d; - if((cnt&wind) == 0) - break; - p++; - } - y2 = p[0]->z; - iy2 = (y2 + onehalf) >> fixshift; - if(iy2 <= miny) - continue; - if(iy2 > maxy) - iy2 = maxy; - if(iy == iy2) { - if(yerr*p[0]->den + p[0]->zerr*yden > p[0]->den*yden) - y++; - iy = (y + y2) >> (fixshift+1); - fillpoint(dst, ix, iy, src, sp, op); - } - } - x += (1<z > p[1]->z) { - s = p[0]; - p[0] = p[1]; - p[1] = s; - done = 0; - } - } - } while(!done); - } else { - q = ep-1; - for(p = seg; p < q; p++) { - if(p[0]->z > p[1]->z) { - qsort(seg, ep-seg, sizeof(Seg*), zcompare); - break; - } - } - } -} - -static int -ycompare(const void *a, const void *b) -{ - Seg **s0, **s1; - long y0, y1; - - s0 = (Seg**)a; - s1 = (Seg**)b; - y0 = (*s0)->p0.y; - y1 = (*s1)->p0.y; - - if(y0 < y1) - return -1; - if(y0 == y1) - return 0; - return 1; -} - -static int -xcompare(const void *a, const void *b) -{ - Seg **s0, **s1; - long x0, x1; - - s0 = (Seg**)a; - s1 = (Seg**)b; - x0 = (*s0)->p0.x; - x1 = (*s1)->p0.x; - - if(x0 < x1) - return -1; - if(x0 == x1) - return 0; - return 1; -} - -static int -zcompare(const void *a, const void *b) -{ - Seg **s0, **s1; - long z0, z1; - - s0 = (Seg**)a; - s1 = (Seg**)b; - z0 = (*s0)->z; - z1 = (*s1)->z; - - if(z0 < z1) - return -1; - if(z0 == z1) - return 0; - return 1; -} blob - 3f36250f22ec43c8bf6cb3d064bc2cc8e01333e5 (mode 644) blob + /dev/null --- src/libdraw/md-hwdraw.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include -#include - -int -hwdraw(Memdrawparam *p) -{ - USED(p); - return 0; /* could not satisfy request */ -} - blob - 923b6b448c8e075b6c258e5777eb21a24de21cdd (mode 644) blob + /dev/null --- src/libdraw/md-iprint.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include -#include - -int -iprint(char *fmt,...) -{ - USED(fmt); - return -1; -} - blob - c7042b9fc4f1ac4f9d1c6ffb105213f4b59a42a3 (mode 644) blob + /dev/null --- src/libdraw/md-line.c +++ /dev/null @@ -1,486 +0,0 @@ -#include -#include -#include -#include - -enum -{ - Arrow1 = 8, - Arrow2 = 10, - Arrow3 = 3 -}; - -/* -static -int -lmin(int a, int b) -{ - if(a < b) - return a; - return b; -} -*/ - -static -int -lmax(int a, int b) -{ - if(a > b) - return a; - return b; -} - -#ifdef NOTUSED -/* - * Rather than line clip, we run the Bresenham loop over the full line, - * and clip on each pixel. This is more expensive but means that - * lines look the same regardless of how the windowing has tiled them. - * For speed, we check for clipping outside the loop and make the - * test easy when possible. - */ - -static -void -horline1(Memimage *dst, Point p0, Point p1, int srcval, Rectangle clipr) -{ - int x, y, dy, deltay, deltax, maxx; - int dd, easy, e, bpp, m, m0; - uchar *d; - - deltax = p1.x - p0.x; - deltay = p1.y - p0.y; - dd = dst->width*sizeof(u32int); - dy = 1; - if(deltay < 0){ - dd = -dd; - deltay = -deltay; - dy = -1; - } - maxx = lmin(p1.x, clipr.max.x-1); - bpp = dst->depth; - m0 = 0xFF^(0xFF>>bpp); - m = m0 >> (p0.x&(7/dst->depth))*bpp; - easy = ptinrect(p0, clipr) && ptinrect(p1, clipr); - e = 2*deltay - deltax; - y = p0.y; - d = byteaddr(dst, p0); - deltay *= 2; - deltax = deltay - 2*deltax; - for(x=p0.x; x<=maxx; x++){ - if(easy || (clipr.min.x<=x && clipr.min.y<=y && y 0){ - y += dy; - d += dd; - e += deltax; - }else - e += deltay; - d++; - m >>= bpp; - if(m == 0) - m = m0; - } -} - -static -void -verline1(Memimage *dst, Point p0, Point p1, int srcval, Rectangle clipr) -{ - int x, y, deltay, deltax, maxy; - int easy, e, bpp, m, m0, dd; - uchar *d; - - deltax = p1.x - p0.x; - deltay = p1.y - p0.y; - dd = 1; - if(deltax < 0){ - dd = -1; - deltax = -deltax; - } - maxy = lmin(p1.y, clipr.max.y-1); - bpp = dst->depth; - m0 = 0xFF^(0xFF>>bpp); - m = m0 >> (p0.x&(7/dst->depth))*bpp; - easy = ptinrect(p0, clipr) && ptinrect(p1, clipr); - e = 2*deltax - deltay; - x = p0.x; - d = byteaddr(dst, p0); - deltax *= 2; - deltay = deltax - 2*deltay; - for(y=p0.y; y<=maxy; y++){ - if(easy || (clipr.min.y<=y && clipr.min.x<=x && x 0){ - x += dd; - d += dd; - e += deltay; - }else - e += deltax; - d += dst->width*sizeof(u32int); - m >>= bpp; - if(m == 0) - m = m0; - } -} - -static -void -horliner(Memimage *dst, Point p0, Point p1, Memimage *src, Point dsrc, Rectangle clipr) -{ - int x, y, sx, sy, deltay, deltax, minx, maxx; - int bpp, m, m0; - uchar *d, *s; - - deltax = p1.x - p0.x; - deltay = p1.y - p0.y; - sx = drawreplxy(src->r.min.x, src->r.max.x, p0.x+dsrc.x); - minx = lmax(p0.x, clipr.min.x); - maxx = lmin(p1.x, clipr.max.x-1); - bpp = dst->depth; - m0 = 0xFF^(0xFF>>bpp); - m = m0 >> (minx&(7/dst->depth))*bpp; - for(x=minx; x<=maxx; x++){ - y = p0.y + (deltay*(x-p0.x)+deltax/2)/deltax; - if(clipr.min.y<=y && yr.min.y, src->r.max.y, y+dsrc.y); - s = byteaddr(src, Pt(sx, sy)); - *d ^= (*d^*s) & m; - } - if(++sx >= src->r.max.x) - sx = src->r.min.x; - m >>= bpp; - if(m == 0) - m = m0; - } -} - -static -void -verliner(Memimage *dst, Point p0, Point p1, Memimage *src, Point dsrc, Rectangle clipr) -{ - int x, y, sx, sy, deltay, deltax, miny, maxy; - int bpp, m, m0; - uchar *d, *s; - - deltax = p1.x - p0.x; - deltay = p1.y - p0.y; - sy = drawreplxy(src->r.min.y, src->r.max.y, p0.y+dsrc.y); - miny = lmax(p0.y, clipr.min.y); - maxy = lmin(p1.y, clipr.max.y-1); - bpp = dst->depth; - m0 = 0xFF^(0xFF>>bpp); - for(y=miny; y<=maxy; y++){ - if(deltay == 0) /* degenerate line */ - x = p0.x; - else - x = p0.x + (deltax*(y-p0.y)+deltay/2)/deltay; - if(clipr.min.x<=x && x> (x&(7/dst->depth))*bpp; - d = byteaddr(dst, Pt(x, y)); - sx = drawreplxy(src->r.min.x, src->r.max.x, x+dsrc.x); - s = byteaddr(src, Pt(sx, sy)); - *d ^= (*d^*s) & m; - } - if(++sy >= src->r.max.y) - sy = src->r.min.y; - } -} - -static -void -horline(Memimage *dst, Point p0, Point p1, Memimage *src, Point dsrc, Rectangle clipr) -{ - int x, y, deltay, deltax, minx, maxx; - int bpp, m, m0; - uchar *d, *s; - - deltax = p1.x - p0.x; - deltay = p1.y - p0.y; - minx = lmax(p0.x, clipr.min.x); - maxx = lmin(p1.x, clipr.max.x-1); - bpp = dst->depth; - m0 = 0xFF^(0xFF>>bpp); - m = m0 >> (minx&(7/dst->depth))*bpp; - for(x=minx; x<=maxx; x++){ - y = p0.y + (deltay*(x-p0.x)+deltay/2)/deltax; - if(clipr.min.y<=y && y>= bpp; - if(m == 0) - m = m0; - } -} - -static -void -verline(Memimage *dst, Point p0, Point p1, Memimage *src, Point dsrc, Rectangle clipr) -{ - int x, y, deltay, deltax, miny, maxy; - int bpp, m, m0; - uchar *d, *s; - - deltax = p1.x - p0.x; - deltay = p1.y - p0.y; - miny = lmax(p0.y, clipr.min.y); - maxy = lmin(p1.y, clipr.max.y-1); - bpp = dst->depth; - m0 = 0xFF^(0xFF>>bpp); - for(y=miny; y<=maxy; y++){ - if(deltay == 0) /* degenerate line */ - x = p0.x; - else - x = p0.x + deltax*(y-p0.y)/deltay; - if(clipr.min.x<=x && x> (x&(7/dst->depth))*bpp; - d = byteaddr(dst, Pt(x, y)); - s = byteaddr(src, addpt(dsrc, Pt(x, y))); - *d ^= (*d^*s) & m; - } - } -} -#endif /* NOTUSED */ - -static Memimage* -membrush(int radius) -{ - static Memimage *brush; - static int brushradius; - - if(brush==nil || brushradius!=radius){ - freememimage(brush); - brush = allocmemimage(Rect(0, 0, 2*radius+1, 2*radius+1), memopaque->chan); - if(brush != nil){ - memfillcolor(brush, DTransparent); /* zeros */ - memellipse(brush, Pt(radius, radius), radius, radius, -1, memopaque, Pt(radius, radius), S); - } - brushradius = radius; - } - return brush; -} - -static -void -discend(Point p, int radius, Memimage *dst, Memimage *src, Point dsrc, int op) -{ - Memimage *disc; - Rectangle r; - - disc = membrush(radius); - if(disc != nil){ - r.min.x = p.x - radius; - r.min.y = p.y - radius; - r.max.x = p.x + radius+1; - r.max.y = p.y + radius+1; - memdraw(dst, r, src, addpt(r.min, dsrc), disc, Pt(0,0), op); - } -} - -static -void -arrowend(Point tip, Point *pp, int end, int sin, int cos, int radius) -{ - int x1, x2, x3; - - /* before rotation */ - if(end == Endarrow){ - x1 = Arrow1; - x2 = Arrow2; - x3 = Arrow3; - }else{ - x1 = (end>>5) & 0x1FF; /* distance along line from end of line to tip */ - x2 = (end>>14) & 0x1FF; /* distance along line from barb to tip */ - x3 = (end>>23) & 0x1FF; /* distance perpendicular from edge of line to barb */ - } - - /* comments follow track of right-facing arrowhead */ - pp->x = tip.x+((2*radius+1)*sin/2-x1*cos); /* upper side of shaft */ - pp->y = tip.y-((2*radius+1)*cos/2+x1*sin); - pp++; - pp->x = tip.x+((2*radius+2*x3+1)*sin/2-x2*cos); /* upper barb */ - pp->y = tip.y-((2*radius+2*x3+1)*cos/2+x2*sin); - pp++; - pp->x = tip.x; - pp->y = tip.y; - pp++; - pp->x = tip.x+(-(2*radius+2*x3+1)*sin/2-x2*cos); /* lower barb */ - pp->y = tip.y-(-(2*radius+2*x3+1)*cos/2+x2*sin); - pp++; - pp->x = tip.x+(-(2*radius+1)*sin/2-x1*cos); /* lower side of shaft */ - pp->y = tip.y+((2*radius+1)*cos/2-x1*sin); -} - -void -_memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op) -{ - /* - * BUG: We should really really pick off purely horizontal and purely - * vertical lines and handle them separately with calls to memimagedraw - * on rectangles. - */ - - int hor; - int sin, cos, dx, dy, t; - Rectangle oclipr, r; - Point q, pts[10], *pp, d; - - if(radius < 0) - return; - if(rectclip(&clipr, dst->r) == 0) - return; - if(rectclip(&clipr, dst->clipr) == 0) - return; - d = subpt(sp, p0); - if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0) - return; - if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0) - return; - /* this means that only verline() handles degenerate lines (p0==p1) */ - hor = (abs(p1.x-p0.x) > abs(p1.y-p0.y)); - /* - * Clipping is a little peculiar. We can't use Sutherland-Cohen - * clipping because lines are wide. But this is probably just fine: - * we do all math with the original p0 and p1, but clip when deciding - * what pixels to draw. This means the layer code can call this routine, - * using clipr to define the region being written, and get the same set - * of pixels regardless of the dicing. - */ - if((hor && p0.x>p1.x) || (!hor && p0.y>p1.y)){ - q = p0; - p0 = p1; - p1 = q; - t = end0; - end0 = end1; - end1 = t; - } - - if((p0.x == p1.x || p0.y == p1.y) && (end0&0x1F) == Endsquare && (end1&0x1F) == Endsquare){ - r.min = p0; - r.max = p1; - if(p0.x == p1.x){ - r.min.x -= radius; - r.max.x += radius+1; - } - else{ - r.min.y -= radius; - r.max.y += radius+1; - } - oclipr = dst->clipr; - dst->clipr = clipr; - memimagedraw(dst, r, src, sp, memopaque, sp, op); - dst->clipr = oclipr; - return; - } - -/* Hard: */ - /* draw thick line using polygon fill */ - icossin2(p1.x-p0.x, p1.y-p0.y, &cos, &sin); - dx = (sin*(2*radius+1))/2; - dy = (cos*(2*radius+1))/2; - pp = pts; - oclipr = dst->clipr; - dst->clipr = clipr; - q.x = ICOSSCALE*p0.x+ICOSSCALE/2-cos/2; - q.y = ICOSSCALE*p0.y+ICOSSCALE/2-sin/2; - switch(end0 & 0x1F){ - case Enddisc: - discend(p0, radius, dst, src, d, op); - /* fall through */ - case Endsquare: - default: - pp->x = q.x-dx; - pp->y = q.y+dy; - pp++; - pp->x = q.x+dx; - pp->y = q.y-dy; - pp++; - break; - case Endarrow: - arrowend(q, pp, end0, -sin, -cos, radius); - _memfillpolysc(dst, pts, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1, op); - pp[1] = pp[4]; - pp += 2; - } - q.x = ICOSSCALE*p1.x+ICOSSCALE/2+cos/2; - q.y = ICOSSCALE*p1.y+ICOSSCALE/2+sin/2; - switch(end1 & 0x1F){ - case Enddisc: - discend(p1, radius, dst, src, d, op); - /* fall through */ - case Endsquare: - default: - pp->x = q.x+dx; - pp->y = q.y-dy; - pp++; - pp->x = q.x-dx; - pp->y = q.y+dy; - pp++; - break; - case Endarrow: - arrowend(q, pp, end1, sin, cos, radius); - _memfillpolysc(dst, pp, 5, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 1, 10, 1, op); - pp[1] = pp[4]; - pp += 2; - } - _memfillpolysc(dst, pts, pp-pts, ~0, src, addpt(pts[0], mulpt(d, ICOSSCALE)), 0, 10, 1, op); - dst->clipr = oclipr; - return; -} - -void -memimageline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op) -{ - _memimageline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op); -} - -/* - * Simple-minded conservative code to compute bounding box of line. - * Result is probably a little larger than it needs to be. - */ -static -void -addbbox(Rectangle *r, Point p) -{ - if(r->min.x > p.x) - r->min.x = p.x; - if(r->min.y > p.y) - r->min.y = p.y; - if(r->max.x < p.x+1) - r->max.x = p.x+1; - if(r->max.y < p.y+1) - r->max.y = p.y+1; -} - -int -memlineendsize(int end) -{ - int x3; - - if((end&0x3F) != Endarrow) - return 0; - if(end == Endarrow) - x3 = Arrow3; - else - x3 = (end>>23) & 0x1FF; - return x3; -} - -Rectangle -memlinebbox(Point p0, Point p1, int end0, int end1, int radius) -{ - Rectangle r, r1; - int extra; - - r.min.x = 10000000; - r.min.y = 10000000; - r.max.x = -10000000; - r.max.y = -10000000; - extra = lmax(memlineendsize(end0), memlineendsize(end1)); - r1 = insetrect(canonrect(Rpt(p0, p1)), -(radius+extra)); - addbbox(&r, r1.min); - addbbox(&r, r1.max); - return r; -} blob - 6788fa90b3a78b55526c106beac8620ff9269e7b (mode 644) blob + /dev/null --- src/libdraw/md-load.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include - -int -_loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - int y, l, lpart, rpart, mx, m, mr; - uchar *q; - - if(!rectinrect(r, i->r)) - return -1; - l = bytesperline(r, i->depth); - if(ndata < l*Dy(r)) - return -1; - ndata = l*Dy(r); - q = byteaddr(i, r.min); - mx = 7/i->depth; - lpart = (r.min.x & mx) * i->depth; - rpart = (r.max.x & mx) * i->depth; - m = 0xFF >> lpart; - /* may need to do bit insertion on edges */ - if(l == 1){ /* all in one byte */ - if(rpart) - m ^= 0xFF >> rpart; - for(y=r.min.y; ywidth*sizeof(u32int); - data++; - } - return ndata; - } - if(lpart==0 && rpart==0){ /* easy case */ - for(y=r.min.y; ywidth*sizeof(u32int); - data += l; - } - return ndata; - } - mr = 0xFF ^ (0xFF >> rpart); - if(lpart!=0 && rpart==0){ - for(y=r.min.y; y 1) - memmove(q+1, data+1, l-1); - q += i->width*sizeof(u32int); - data += l; - } - return ndata; - } - if(lpart==0 && rpart!=0){ - for(y=r.min.y; y 1) - memmove(q, data, l-1); - q[l-1] ^= (data[l-1]^q[l-1]) & mr; - q += i->width*sizeof(u32int); - data += l; - } - return ndata; - } - for(y=r.min.y; y 2) - memmove(q+1, data+1, l-2); - q[l-1] ^= (data[l-1]^q[l-1]) & mr; - q += i->width*sizeof(u32int); - data += l; - } - return ndata; -} blob - e8d5efc394486da4f81a362839441ed54c1f5030 (mode 644) blob + /dev/null --- src/libdraw/md-mkcmap.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include - -/* -struct Memcmap -{ - uchar cmap2rgb[3*256]; - uchar rgb2cmap[16*16*16]; -}; -*/ - -static Memcmap* -mkcmap(void) -{ - static Memcmap def; - - int i, rgb, r, g, b; - - for(i=0; i<256; i++){ - rgb = cmap2rgb(i); - r = (rgb>>16)&0xff; - g = (rgb>>8)&0xff; - b = rgb&0xff; - def.cmap2rgb[3*i] = r; - def.cmap2rgb[3*i+1] = g; - def.cmap2rgb[3*i+2] = b; - } - - for(r=0; r<16; r++) - for(g=0; g<16; g++) - for(b=0; b<16; b++) - def.rgb2cmap[r*16*16+g*16+b] = rgb2cmap(r*0x11, g*0x11, b*0x11); - return &def; -} - -void -main(int argc, char **argv) -{ - Memcmap *c; - int i, j, inferno; - - inferno = 0; - ARGBEGIN{ - case 'i': - inferno = 1; - }ARGEND - - memimageinit(); - c = mkcmap(); - if(!inferno) - print("#include \n#include \n"); - else - print("#include \"lib9.h\"\n"); - print("#include \n"); - print("#include \n\n"); - print("static Memcmap def = {\n"); - print("/* cmap2rgb */ {\n"); - for(i=0; icmap2rgb); ){ - print("\t"); - for(j=0; j<16; j++, i++) - print("0x%2.2ux,", c->cmap2rgb[i]); - print("\n"); - } - print("},\n"); - print("/* rgb2cmap */ {\n"); - for(i=0; irgb2cmap);){ - print("\t"); - for(j=0; j<16; j++, i++) - print("0x%2.2ux,", c->rgb2cmap[i]); - print("\n"); - } - print("}\n"); - print("};\n"); - print("Memcmap *memdefcmap = &def;\n"); - print("void _memmkcmap(void){}\n"); - exits(0); -} blob - c8d926e4a69378605dcfb59f83ebbc8e8c24f700 (mode 644) blob + /dev/null --- src/libdraw/md-openmemsubfont.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include - -Memsubfont* -openmemsubfont(char *name) -{ - Memsubfont *sf; - Memimage *i; - Fontchar *fc; - int fd, n; - char hdr[3*12+4+1]; - uchar *p; - - fd = open(name, OREAD); - if(fd < 0) - return nil; - p = nil; - i = readmemimage(fd); - if(i == nil) - goto Err; - if(read(fd, hdr, 3*12) != 3*12){ - werrstr("openmemsubfont: header read error: %r"); - goto Err; - } - n = atoi(hdr); - p = malloc(6*(n+1)); - if(p == nil) - goto Err; - if(read(fd, p, 6*(n+1)) != 6*(n+1)){ - werrstr("openmemsubfont: fontchar read error: %r"); - goto Err; - } - fc = malloc(sizeof(Fontchar)*(n+1)); - if(fc == nil) - goto Err; - _unpackinfo(fc, p, n); - sf = allocmemsubfont(name, n, atoi(hdr+12), atoi(hdr+24), fc, i); - if(sf == nil){ - free(fc); - goto Err; - } - free(p); - return sf; -Err: - close(fd); - if (i != nil) - freememimage(i); - if (p != nil) - free(p); - return nil; -} blob - d16c0a92a7bb0407aa5be4a7553b84a8a82ae966 (mode 644) blob + /dev/null --- src/libdraw/md-poly.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include - -void -mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, Memimage *src, Point sp, int op) -{ - int i, e0, e1; - Point d; - - if(nvert < 2) - return; - d = subpt(sp, vert[0]); - for(i=1; i -#include -#include -#include - -Memimage* -readmemimage(int fd) -{ - char hdr[5*12+1]; - int dy; - u32int chan; - uint l, n; - int m, j; - int new, miny, maxy; - Rectangle r; - uchar *tmp; - int ldepth, chunk; - Memimage *i; - - if(readn(fd, hdr, 11) != 11){ - werrstr("readimage: short header"); - return nil; - } - if(memcmp(hdr, "compressed\n", 11) == 0) - return creadmemimage(fd); - if(readn(fd, hdr+11, 5*12-11) != 5*12-11){ - werrstr("readimage: short header (2)"); - return nil; - } - - /* - * distinguish new channel descriptor from old ldepth. - * channel descriptors have letters as well as numbers, - * while ldepths are a single digit formatted as %-11d. - */ - new = 0; - for(m=0; m<10; m++){ - if(hdr[m] != ' '){ - new = 1; - break; - } - } - if(hdr[11] != ' '){ - werrstr("readimage: bad format"); - return nil; - } - if(new){ - hdr[11] = '\0'; - if((chan = strtochan(hdr)) == 0){ - werrstr("readimage: bad channel string %s", hdr); - return nil; - } - }else{ - ldepth = ((int)hdr[10])-'0'; - if(ldepth<0 || ldepth>3){ - werrstr("readimage: bad ldepth %d", ldepth); - return nil; - } - chan = drawld2chan[ldepth]; - } - - r.min.x = atoi(hdr+1*12); - r.min.y = atoi(hdr+2*12); - r.max.x = atoi(hdr+3*12); - r.max.y = atoi(hdr+4*12); - if(r.min.x>r.max.x || r.min.y>r.max.y){ - werrstr("readimage: bad rectangle"); - return nil; - } - - miny = r.min.y; - maxy = r.max.y; - - l = bytesperline(r, chantodepth(chan)); - i = allocmemimage(r, chan); - if(i == nil) - return nil; - chunk = 32*1024; - if(chunk < l) - chunk = l; - tmp = malloc(chunk); - if(tmp == nil) - goto Err; - while(maxy > miny){ - dy = maxy - miny; - if(dy*l > chunk) - dy = chunk/l; - if(dy <= 0){ - werrstr("readmemimage: image too wide for buffer"); - goto Err; - } - n = dy*l; - m = readn(fd, tmp, n); - if(m != n){ - werrstr("readmemimage: read count %d not %d: %r", m, n); - Err: - freememimage(i); - free(tmp); - return nil; - } - if(!new) /* an old image: must flip all the bits */ - for(j=0; j -#include -#include -#include - -Point -memimagestring(Memimage *b, Point p, Memimage *color, Point cp, Memsubfont *f, char *cs) -{ - int w, width; - uchar *s; - Rune c; - Fontchar *i; - - s = (uchar*)cs; - for(; c=*s; p.x+=width, cp.x+=width){ - width = 0; - if(c < Runeself) - s++; - else{ - w = chartorune(&c, (char*)s); - if(w == 0){ - s++; - continue; - } - s += w; - } - if(c >= f->n) - continue; - i = f->info+c; - width = i->width; - memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom), - color, cp, f->bits, Pt(i->x, i->top), SoverD); - } - return p; -} - -Point -memsubfontwidth(Memsubfont *f, char *cs) -{ - Rune c; - Point p; - uchar *s; - Fontchar *i; - int w, width; - - p = Pt(0, f->height); - s = (uchar*)cs; - for(; c=*s; p.x+=width){ - width = 0; - if(c < Runeself) - s++; - else{ - w = chartorune(&c, (char*)s); - if(w == 0){ - s++; - continue; - } - s += w; - } - if(c >= f->n) - continue; - i = f->info+c; - width = i->width; - } - return p; -} blob - e2bdee5c02d1af5f0551f015329c5ff6278ee58c (mode 644) blob + /dev/null --- src/libdraw/md-subfont.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include -#include - -Memsubfont* -allocmemsubfont(char *name, int n, int height, int ascent, Fontchar *info, Memimage *i) -{ - Memsubfont *f; - - f = malloc(sizeof(Memsubfont)); - if(f == 0) - return 0; - f->n = n; - f->height = height; - f->ascent = ascent; - f->info = info; - f->bits = i; - if(name) - f->name = strdup(name); - else - f->name = 0; - return f; -} - -void -freememsubfont(Memsubfont *f) -{ - if(f == 0) - return; - free(f->info); /* note: f->info must have been malloc'ed! */ - freememimage(f->bits); - free(f); -} blob - 86835757b3dcf34a83621d1c04b04594c8e397e5 (mode 644) blob + /dev/null --- src/libdraw/md-unload.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include - -int -_unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - int y, l; - uchar *q; - - if(!rectinrect(r, i->r)) - return -1; - l = bytesperline(r, i->depth); - if(ndata < l*Dy(r)) - return -1; - ndata = l*Dy(r); - q = byteaddr(i, r.min); - for(y=r.min.y; ywidth*sizeof(u32int); - data += l; - } - return ndata; -} blob - c03c58e8728711e66d2a458c8341e737df9f3a71 (mode 644) blob + /dev/null --- src/libdraw/md-write.c +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include -#include -#include - -#define CHUNK 8000 - -#define HSHIFT 3 /* HSHIFT==5 runs slightly faster, but hash table is 64x bigger */ -#define NHASH (1<<(HSHIFT*NMATCH)) -#define HMASK (NHASH-1) -#define hupdate(h, c) ((((h)<r; - bpl = bytesperline(r, i->depth); - n = Dy(r)*bpl; - data = malloc(n); - ncblock = _compblocksize(r, i->depth); - outbuf = malloc(ncblock); - hash = malloc(NHASH*sizeof(Hlist)); - chain = malloc(NMEM*sizeof(Hlist)); - if(data == 0 || outbuf == 0 || hash == 0 || chain == 0){ - ErrOut: - free(data); - free(outbuf); - free(hash); - free(chain); - return -1; - } - for(miny = r.min.y; miny != r.max.y; miny += dy){ - dy = r.max.y-miny; - if(dy*bpl > CHUNK) - dy = CHUNK/bpl; - nb = unloadmemimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), - data+(miny-r.min.y)*bpl, dy*bpl); - if(nb != dy*bpl) - goto ErrOut; - } - sprint(hdr, "compressed\n%11s %11d %11d %11d %11d ", - chantostr(cbuf, i->chan), r.min.x, r.min.y, r.max.x, r.max.y); - if(write(fd, hdr, 11+5*12) != 11+5*12) - goto ErrOut; - edata = data+n; - eout = outbuf+ncblock; - line = data; - r.max.y = r.min.y; - while(line != edata){ - memset(hash, 0, NHASH*sizeof(Hlist)); - memset(chain, 0, NMEM*sizeof(Hlist)); - cp = chain; - h = 0; - outp = outbuf; - for(n = 0; n != NMATCH; n++) - h = hupdate(h, line[n]); - loutp = outbuf; - while(line != edata){ - ndump = 0; - eline = line+bpl; - for(p = line; p != eline; ){ - if(eline-p < NRUN) - es = eline; - else - es = p+NRUN; - q = 0; - runlen = 0; - for(hp = hash[h].next; hp; hp = hp->next){ - s = p + runlen; - if(s >= es) - continue; - t = hp->s + runlen; - for(; s >= p; s--) - if(*s != *t--) - goto matchloop; - t += runlen+2; - s += runlen+2; - for(; s < es; s++) - if(*s != *t++) - break; - n = s-p; - if(n > runlen){ - runlen = n; - q = hp->s; - if(n == NRUN) - break; - } - matchloop: ; - } - if(runlen < NMATCH){ - if(ndump == NDUMP){ - if(eout-outp < ndump+1) - goto Bfull; - *outp++ = ndump-1+128; - memmove(outp, dumpbuf, ndump); - outp += ndump; - ndump = 0; - } - dumpbuf[ndump++] = *p; - runlen = 1; - } - else{ - if(ndump != 0){ - if(eout-outp < ndump+1) - goto Bfull; - *outp++ = ndump-1+128; - memmove(outp, dumpbuf, ndump); - outp += ndump; - ndump = 0; - } - offs = p-q-1; - if(eout-outp < 2) - goto Bfull; - *outp++ = ((runlen-NMATCH)<<2) + (offs>>8); - *outp++ = offs&255; - } - for(q = p+runlen; p != q; p++){ - if(cp->prev) - cp->prev->next = 0; - cp->next = hash[h].next; - cp->prev = &hash[h]; - if(cp->next) - cp->next->prev = cp; - cp->prev->next = cp; - cp->s = p; - if(++cp == &chain[NMEM]) - cp = chain; - if(edata-p > NMATCH) - h = hupdate(h, p[NMATCH]); - } - } - if(ndump != 0){ - if(eout-outp < ndump+1) - goto Bfull; - *outp++ = ndump-1+128; - memmove(outp, dumpbuf, ndump); - outp += ndump; - } - line = eline; - loutp = outp; - r.max.y++; - } - Bfull: - if(loutp == outbuf) - goto ErrOut; - n = loutp-outbuf; - sprint(hdr, "%11d %11ld ", r.max.y, n); - write(fd, hdr, 2*12); - write(fd, outbuf, n); - r.min.y = r.max.y; - } - free(data); - free(outbuf); - free(hash); - free(chain); - return 0; -} blob - da115f31a1f1796c3df08277743aaa58afd44882 blob + f1c981dbd0bf4ba060d1f4e4faf334642d308008 --- src/libdraw/mkfile +++ src/libdraw/mkfile @@ -17,6 +17,8 @@ OFILES=\ debug.$O\ defont.$O\ draw.$O\ + drawclient.$O\ + drawfcall.$O\ drawrepl.$O\ egetrect.$O\ ellipse.$O\ @@ -29,11 +31,12 @@ OFILES=\ icossin.$O\ icossin2.$O\ init.$O\ + keyboard.$O\ line.$O\ - latin1.$O\ loadimage.$O\ menuhit.$O\ mkfont.$O\ + mouse.$O\ openfont.$O\ poly.$O\ readimage.$O\ @@ -42,6 +45,7 @@ OFILES=\ replclipr.$O\ rgb.$O\ scroll.$O\ + snarf.$O\ string.$O\ stringbg.$O\ stringsubfont.$O\ @@ -53,79 +57,17 @@ OFILES=\ window.$O\ writeimage.$O\ writesubfont.$O\ - md-alloc.$O\ - md-arc.$O\ - md-cload.$O\ - md-cmap.$O\ - md-cread.$O\ - md-defont.$O\ - md-draw.$O\ - md-ellipse.$O\ - md-fillpoly.$O\ - md-hwdraw.$O\ - md-iprint.$O\ - md-line.$O\ - md-load.$O\ - md-openmemsubfont.$O\ - md-poly.$O\ - md-read.$O\ - md-string.$O\ - md-subfont.$O\ - md-unload.$O\ - md-write.$O\ - ml-draw.$O\ - ml-lalloc.$O\ - ml-layerop.$O\ - ml-ldelete.$O\ - ml-lhide.$O\ - ml-line.$O\ - ml-load.$O\ - ml-lorigin.$O\ - ml-lsetrefresh.$O\ - ml-ltofront.$O\ - ml-ltorear.$O\ - ml-unload.$O\ - devdraw.$O\ + wsys.$O\ unix.$O\ HFILES=\ $PLAN9/include/draw.h\ - $PLAN9/include/memdraw.h\ - $PLAN9/include/memlayer.h\ + $PLAN9/include/drawfcall.h\ + $PLAN9/include/mux.h\ $PLAN9/include/event.h\ $PLAN9/include/cursor.h\ $PLAN9/include/mouse.h\ $PLAN9/include/keyboard.h\ -# some of these should move to wsysofiles - -XHFILES=\ - x11-inc.h\ - x11-memdraw.h\ - -<|sh ./mkwsysrules.sh - -WSYSOFILES=\ - $WSYSTYPE-alloc.$O\ - $WSYSTYPE-cload.$O\ - $WSYSTYPE-draw.$O\ - $WSYSTYPE-event.$O\ - $WSYSTYPE-fill.$O\ - $WSYSTYPE-get.$O\ - $WSYSTYPE-init.$O\ - $WSYSTYPE-itrans.$O\ - $WSYSTYPE-keyboard.$O\ - $WSYSTYPE-keysym2ucs.$O\ - $WSYSTYPE-load.$O\ - $WSYSTYPE-mouse.$O\ - $WSYSTYPE-pixelbits.$O\ - $WSYSTYPE-unload.$O\ - $WSYSTYPE-wsys.$O\ - -OFILES=$OFILES $WSYSOFILES - <$PLAN9/src/mksyslib -test: test.o $PLAN9/lib/$LIB - gcc -o test test.o -L$PLAN9/lib -ldraw -l9 -lfmt -lutf -L$X11/lib -lX11 -lm - blob - c352a0b2c3fbceaab100c4d5af5f7ad829dd0921 (mode 644) blob + /dev/null --- src/libdraw/ml-draw.c +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include -#include -#include -#include - -struct Draw -{ - Point deltas; - Point deltam; - Memlayer *dstlayer; - Memimage *src; - Memimage *mask; - int op; -}; - -static -void -ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave) -{ - struct Draw *d; - Point p0, p1; - Rectangle oclipr, srcr, r, mr; - int ok; - - d = etc; - if(insave && d->dstlayer->save==nil) - return; - - p0 = addpt(screenr.min, d->deltas); - p1 = addpt(screenr.min, d->deltam); - - if(insave){ - r = rectsubpt(screenr, d->dstlayer->delta); - clipr = rectsubpt(clipr, d->dstlayer->delta); - }else - r = screenr; - - /* now in logical coordinates */ - - /* clipr may have narrowed what we should draw on, so clip if necessary */ - if(!rectinrect(r, clipr)){ - oclipr = dst->clipr; - dst->clipr = clipr; - ok = drawclip(dst, &r, d->src, &p0, d->mask, &p1, &srcr, &mr); - dst->clipr = oclipr; - if(!ok) - return; - } - memdraw(dst, r, d->src, p0, d->mask, p1, d->op); -} - -void -memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op) -{ - struct Draw d; - Rectangle srcr, tr, mr; - Memlayer *dl, *sl; - - if(drawdebug) - iprint("memdraw %p %R %p %P %p %P\n", dst, r, src, p0, mask, p1); - - if(mask == nil) - mask = memopaque; - - if(mask->layer){ -if(drawdebug) iprint("mask->layer != nil\n"); - return; /* too hard, at least for now */ - } - - Top: - if(dst->layer==nil && src->layer==nil){ - memimagedraw(dst, r, src, p0, mask, p1, op); - return; - } - - if(drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0){ -if(drawdebug) iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr); - return; - } - - /* - * Convert to screen coordinates. - */ - dl = dst->layer; - if(dl != nil){ - r.min.x += dl->delta.x; - r.min.y += dl->delta.y; - r.max.x += dl->delta.x; - r.max.y += dl->delta.y; - } - Clearlayer: - if(dl!=nil && dl->clear){ - if(src == dst){ - p0.x += dl->delta.x; - p0.y += dl->delta.y; - src = dl->screen->image; - } - dst = dl->screen->image; - goto Top; - } - - sl = src->layer; - if(sl != nil){ - p0.x += sl->delta.x; - p0.y += sl->delta.y; - srcr.min.x += sl->delta.x; - srcr.min.y += sl->delta.y; - srcr.max.x += sl->delta.x; - srcr.max.y += sl->delta.y; - } - - /* - * Now everything is in screen coordinates. - * mask is an image. dst and src are images or obscured layers. - */ - - /* - * if dst and src are the same layer, just draw in save area and expose. - */ - if(dl!=nil && dst==src){ - if(dl->save == nil) - return; /* refresh function makes this case unworkable */ - if(rectXrect(r, srcr)){ - tr = r; - if(srcr.min.x < tr.min.x){ - p1.x += tr.min.x - srcr.min.x; - tr.min.x = srcr.min.x; - } - if(srcr.min.y < tr.min.y){ - p1.y += tr.min.x - srcr.min.x; - tr.min.y = srcr.min.y; - } - if(srcr.max.x > tr.max.x) - tr.max.x = srcr.max.x; - if(srcr.max.y > tr.max.y) - tr.max.y = srcr.max.y; - memlhide(dst, tr); - }else{ - memlhide(dst, r); - memlhide(dst, srcr); - } - memdraw(dl->save, rectsubpt(r, dl->delta), dl->save, - subpt(srcr.min, src->layer->delta), mask, p1, op); - memlexpose(dst, r); - return; - } - - if(sl){ - if(sl->clear){ - src = sl->screen->image; - if(dl != nil){ - r.min.x -= dl->delta.x; - r.min.y -= dl->delta.y; - r.max.x -= dl->delta.x; - r.max.y -= dl->delta.y; - } - goto Top; - } - /* relatively rare case; use save area */ - if(sl->save == nil) - return; /* refresh function makes this case unworkable */ - memlhide(src, srcr); - /* convert back to logical coordinates */ - p0.x -= sl->delta.x; - p0.y -= sl->delta.y; - srcr.min.x -= sl->delta.x; - srcr.min.y -= sl->delta.y; - srcr.max.x -= sl->delta.x; - srcr.max.y -= sl->delta.y; - src = src->layer->save; - } - - /* - * src is now an image. dst may be an image or a clear layer - */ - if(dst->layer==nil) - goto Top; - if(dst->layer->clear) - goto Clearlayer; - - /* - * dst is an obscured layer - */ - d.deltas = subpt(p0, r.min); - d.deltam = subpt(p1, r.min); - d.dstlayer = dl; - d.src = src; - d.op = op; - d.mask = mask; - _memlayerop(ldrawop, dst, r, r, &d); -} blob - 17d934d319271a9fc2e8d1c44faebad413d7339b (mode 644) blob + /dev/null --- src/libdraw/ml-lalloc.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include - -Memimage* -memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, u32int 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, nil); - 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; -} blob - 800ffc859e7ce4be661c1f52bbda287f82cb63fb (mode 644) blob + /dev/null --- src/libdraw/ml-layerop.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include - -#define RECUR(a,b,c,d) _layerop(fn, i, Rect(a.x, b.y, c.x, d.y), clipr, etc, front->layer->rear); - -static void -_layerop( - void (*fn)(Memimage*, Rectangle, Rectangle, void*, int), - Memimage *i, - Rectangle r, - Rectangle clipr, - void *etc, - Memimage *front) -{ - Rectangle fr; - - Top: - if(front == i){ - /* no one is in front of this part of window; use the screen */ - fn(i->layer->screen->image, r, clipr, etc, 0); - return; - } - fr = front->layer->screenr; - if(rectXrect(r, fr) == 0){ - /* r doesn't touch this window; continue on next rearmost */ - /* assert(front && front->layer && front->layer->screen && front->layer->rear); */ - front = front->layer->rear; - goto Top; - } - if(fr.max.y < r.max.y){ - RECUR(r.min, fr.max, r.max, r.max); - r.max.y = fr.max.y; - } - if(r.min.y < fr.min.y){ - RECUR(r.min, r.min, r.max, fr.min); - r.min.y = fr.min.y; - } - if(fr.max.x < r.max.x){ - RECUR(fr.max, r.min, r.max, r.max); - r.max.x = fr.max.x; - } - if(r.min.x < fr.min.x){ - RECUR(r.min, r.min, fr.min, r.max); - r.min.x = fr.min.x; - } - /* r is covered by front, so put in save area */ - (*fn)(i->layer->save, r, clipr, etc, 1); -} - -/* - * Assumes incoming rectangle has already been clipped to i's logical r and clipr - */ -void -_memlayerop( - void (*fn)(Memimage*, Rectangle, Rectangle, void*, int), - Memimage *i, - Rectangle screenr, /* clipped to window boundaries */ - Rectangle clipr, /* clipped also to clipping rectangles of hierarchy */ - void *etc) -{ - Memlayer *l; - Rectangle r, scr; - - l = i->layer; - if(!rectclip(&screenr, l->screenr)) - return; - if(l->clear){ - fn(l->screen->image, screenr, clipr, etc, 0); - return; - } - r = screenr; - scr = l->screen->image->clipr; - - /* - * Do the piece on the screen - */ - if(rectclip(&screenr, scr)) - _layerop(fn, i, screenr, clipr, etc, l->screen->frontmost); - if(rectinrect(r, scr)) - return; - - /* - * Do the piece off the screen - */ - if(!rectXrect(r, scr)){ - /* completely offscreen; easy */ - fn(l->save, r, clipr, etc, 1); - return; - } - if(r.min.y < scr.min.y){ - /* above screen */ - fn(l->save, Rect(r.min.x, r.min.y, r.max.x, scr.min.y), clipr, etc, 1); - r.min.y = scr.min.y; - } - if(r.max.y > scr.max.y){ - /* below screen */ - fn(l->save, Rect(r.min.x, scr.max.y, r.max.x, r.max.y), clipr, etc, 1); - r.max.y = scr.max.y; - } - if(r.min.x < scr.min.x){ - /* left of screen */ - fn(l->save, Rect(r.min.x, r.min.y, scr.min.x, r.max.y), clipr, etc, 1); - r.min.x = scr.min.x; - } - if(r.max.x > scr.max.x){ - /* right of screen */ - fn(l->save, Rect(scr.max.x, r.min.y, r.max.x, r.max.y), clipr, etc, 1); - } -} blob - 34cd6eadbc2a9d1c8ab46f5dd8caa286945d88be (mode 644) blob + /dev/null --- src/libdraw/ml-ldelete.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include -#include - -void -memldelete(Memimage *i) -{ - Memscreen *s; - Memlayer *l; - - l = i->layer; - /* free backing store and disconnect refresh, to make pushback fast */ - freememimage(l->save); - l->save = nil; - l->refreshptr = nil; - memltorear(i); - - /* window is now the rearmost; clean up screen structures and deallocate */ - s = i->layer->screen; - if(s->fill){ - i->clipr = i->r; - memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min, S); - } - if(l->front){ - l->front->layer->rear = nil; - s->rearmost = l->front; - }else{ - s->frontmost = nil; - s->rearmost = nil; - } - free(l); - freememimage(i); -} - -/* - * Just free the data structures, don't do graphics - */ -void -memlfree(Memimage *i) -{ - Memlayer *l; - - l = i->layer; - freememimage(l->save); - free(l); - freememimage(i); -} - -void -_memlsetclear(Memscreen *s) -{ - Memimage *i, *j; - Memlayer *l; - - for(i=s->rearmost; i; i=i->layer->front){ - l = i->layer; - l->clear = rectinrect(l->screenr, l->screen->image->clipr); - if(l->clear) - for(j=l->front; j; j=j->layer->front) - if(rectXrect(l->screenr, j->layer->screenr)){ - l->clear = 0; - break; - } - } -} blob - d6aaa55fe2ce93dc01b060d7b567135f73b43f4e (mode 644) blob + /dev/null --- src/libdraw/ml-lhide.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include -#include - -/* - * Hide puts that portion of screenr now on the screen into the window's save area. - * Expose puts that portion of screenr now in the save area onto the screen. - * - * Hide and Expose both require that the layer structures in the screen - * match the geometry they are being asked to update, that is, they update the - * save area (hide) or screen (expose) based on what those structures tell them. - * This means they must be called at the correct time during window shuffles. - */ - -static -void -lhideop(Memimage *src, Rectangle screenr, Rectangle clipr, void *etc, int insave) -{ - Rectangle r; - Memlayer *l; - - USED(clipr.min.x); - USED(insave); - l = etc; - if(src != l->save){ /* do nothing if src is already in save area */ - r = rectsubpt(screenr, l->delta); - memdraw(l->save, r, src, screenr.min, nil, screenr.min, S); - } -} - -void -memlhide(Memimage *i, Rectangle screenr) -{ - if(i->layer->save == nil) - return; - if(rectclip(&screenr, i->layer->screen->image->r) == 0) - return; - _memlayerop(lhideop, i, screenr, screenr, i->layer); -} - -static -void -lexposeop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave) -{ - Memlayer *l; - Rectangle r; - - USED(clipr.min.x); - if(insave) /* if dst is save area, don't bother */ - return; - l = etc; - r = rectsubpt(screenr, l->delta); - if(l->save) - memdraw(dst, screenr, l->save, r.min, nil, r.min, S); - else - l->refreshfn(dst, r, l->refreshptr); -} - -void -memlexpose(Memimage *i, Rectangle screenr) -{ - if(rectclip(&screenr, i->layer->screen->image->r) == 0) - return; - _memlayerop(lexposeop, i, screenr, screenr, i->layer); -} blob - f74930ef0440253c6e3a26f22dde7a1b46594a38 (mode 644) blob + /dev/null --- src/libdraw/ml-line.c +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include -#include -#include -#include - -struct Lline -{ - Point p0; - Point p1; - Point delta; - int end0; - int end1; - int radius; - Point sp; - Memlayer *dstlayer; - Memimage *src; - int op; -}; - -static void llineop(Memimage*, Rectangle, Rectangle, void*, int); - -static -void -_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op) -{ - Rectangle r; - struct Lline ll; - Point d; - int srcclipped; - Memlayer *dl; - - if(radius < 0) - return; - if(src->layer) /* can't draw line with layered source */ - return; - srcclipped = 0; - - Top: - dl = dst->layer; - if(dl == nil){ - _memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op); - return; - } - if(!srcclipped){ - d = subpt(sp, p0); - if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0) - return; - if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0) - return; - srcclipped = 1; - } - - /* dst is known to be a layer */ - p0.x += dl->delta.x; - p0.y += dl->delta.y; - p1.x += dl->delta.x; - p1.y += dl->delta.y; - clipr.min.x += dl->delta.x; - clipr.min.y += dl->delta.y; - clipr.max.x += dl->delta.x; - clipr.max.y += dl->delta.y; - if(dl->clear){ - dst = dst->layer->screen->image; - goto Top; - } - - /* XXX */ - /* this is not the correct set of tests */ -/* if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3) */ -/* return; */ - - /* can't use sutherland-cohen clipping because lines are wide */ - r = memlinebbox(p0, p1, end0, end1, radius); - /* - * r is now a bounding box for the line; - * use it as a clipping rectangle for subdivision - */ - if(rectclip(&r, clipr) == 0) - return; - ll.p0 = p0; - ll.p1 = p1; - ll.end0 = end0; - ll.end1 = end1; - ll.sp = sp; - ll.dstlayer = dst->layer; - ll.src = src; - ll.radius = radius; - ll.delta = dl->delta; - ll.op = op; - _memlayerop(llineop, dst, r, r, &ll); -} - -static -void -llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave) -{ - struct Lline *ll; - Point p0, p1; - - USED(screenr.min.x); - ll = etc; - if(insave && ll->dstlayer->save==nil) - return; - if(!rectclip(&clipr, screenr)) - return; - if(insave){ - p0 = subpt(ll->p0, ll->delta); - p1 = subpt(ll->p1, ll->delta); - clipr = rectsubpt(clipr, ll->delta); - }else{ - p0 = ll->p0; - p1 = ll->p1; - } - _memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op); -} - -void -memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op) -{ - _memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op); -} blob - d211564be0c81883cfa425d4e8a6f1c14edf8e95 (mode 644) blob + /dev/null --- src/libdraw/ml-load.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include -#include - -int -memload(Memimage *dst, Rectangle r, uchar *data, int n, int iscompressed) -{ - int (*loadfn)(Memimage*, Rectangle, uchar*, int); - Memimage *tmp; - Memlayer *dl; - Rectangle lr; - int dx; - - loadfn = loadmemimage; - if(iscompressed) - loadfn = cloadmemimage; - - Top: - dl = dst->layer; - if(dl == nil) - return loadfn(dst, 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/dst->depth); - if(dl->clear && dx==0){ - dst = dl->screen->image; - goto Top; - } - - /* - * dst is an obscured layer or data is unaligned - */ - if(dl->save && dx==0){ - n = loadfn(dl->save, lr, data, n); - if(n > 0) - memlexpose(dst, r); - return n; - } - tmp = allocmemimage(lr, dst->chan); - if(tmp == nil) - return -1; - n = loadfn(tmp, lr, data, n); - memdraw(dst, lr, tmp, lr.min, nil, lr.min, S); - freememimage(tmp); - return n; -} blob - 0926ee8d216bd66119a4dc3c1a2932e2bb587287 (mode 644) blob + /dev/null --- src/libdraw/ml-lorigin.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include -#include - -/* - * 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 -memlnorefresh(Memimage *l, Rectangle r, void *v) -{ - USED(l); - USED(r.min.x); - USED(v); -} blob - 526bd668a533cedbf0970ef1153c08e4795bc1f1 (mode 644) blob + /dev/null --- src/libdraw/ml-lsetrefresh.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include -#include - -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; -} blob - 447b40bdfdf51ccccab7932bdb72c2df30b26c00 (mode 644) blob + /dev/null --- src/libdraw/ml-ltofront.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include - -/* - * Pull i towards top of screen, just behind front -*/ -static -void -_memltofront(Memimage *i, Memimage *front, int fill) -{ - Memlayer *l; - Memscreen *s; - Memimage *f, *ff, *rr; - Rectangle x; - int overlap; - - l = i->layer; - s = l->screen; - while(l->front != front){ - f = l->front; - x = l->screenr; - overlap = rectclip(&x, f->layer->screenr); - if(overlap){ - memlhide(f, x); - f->layer->clear = 0; - } - /* swap l and f in screen's list */ - ff = f->layer->front; - rr = l->rear; - if(ff == nil) - s->frontmost = i; - else - ff->layer->rear = i; - if(rr == nil) - s->rearmost = f; - else - rr->layer->front = f; - l->front = ff; - l->rear = f; - f->layer->front = i; - f->layer->rear = rr; - if(overlap && fill) - memlexpose(i, x); - } -} - -void -_memltofrontfill(Memimage *i, int fill) -{ - _memltofront(i, nil, fill); - _memlsetclear(i->layer->screen); -} - -void -memltofront(Memimage *i) -{ - _memltofront(i, nil, 1); - _memlsetclear(i->layer->screen); -} - -void -memltofrontn(Memimage **ip, int n) -{ - Memimage *i, *front; - Memscreen *s; - - if(n == 0) - return; - front = nil; - while(--n >= 0){ - i = *ip++; - _memltofront(i, front, 1); - front = i; - } - s = front->layer->screen; - _memlsetclear(s); -} blob - d53e8cc95e3a3c757c886690a9f47b2c007990d7 (mode 644) blob + /dev/null --- src/libdraw/ml-ltorear.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -#include - -void -_memltorear(Memimage *i, Memimage *rear) -{ - Memlayer *l; - Memscreen *s; - Memimage *f, *r, *rr; - Rectangle x; - int overlap; - - l = i->layer; - s = l->screen; - while(l->rear != rear){ - r = l->rear; - x = l->screenr; - overlap = rectclip(&x, r->layer->screenr); - if(overlap){ - memlhide(i, x); - l->clear = 0; - } - /* swap l and r in screen's list */ - rr = r->layer->rear; - f = l->front; - if(rr == nil) - s->rearmost = i; - else - rr->layer->front = i; - if(f == nil) - s->frontmost = r; - else - f->layer->rear = r; - l->rear = rr; - l->front = r; - r->layer->rear = i; - r->layer->front = f; - if(overlap) - memlexpose(r, x); - } -} - -void -memltorear(Memimage *i) -{ - _memltorear(i, nil); - _memlsetclear(i->layer->screen); -} - -void -memltorearn(Memimage **ip, int n) -{ - Memimage *i, *rear; - Memscreen *s; - - if(n == 0) - return; - rear = nil; - while(--n >= 0){ - i = *ip++; - _memltorear(i, rear); - rear = i; - } - s = rear->layer->screen; - _memlsetclear(s); -} blob - b953411771b7a2800631983b5fefa3528a1a865f (mode 644) blob + /dev/null --- src/libdraw/ml-unload.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include - -int -memunload(Memimage *src, Rectangle r, uchar *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 != 0) - 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; -} blob - 3b3cbb6befd9a5f84d935e2f30a6760d709388bc blob + 5c6d0970a3246e82be1d227477e1a505e7ea3059 --- src/libdraw/mouse.c +++ src/libdraw/mouse.c @@ -6,10 +6,10 @@ #include void -moveto(Mousectl *m, Point pt) +moveto(Mousectl *mc, Point pt) { - fprint(m->mfd, "m%d %d", pt.x, pt.y); - m->xy = pt; + _displaymoveto(mc->display, pt); + mc->m.xy = pt; } void @@ -18,24 +18,20 @@ closemouse(Mousectl *mc) if(mc == nil) return; - postnote(PNPROC, mc->pid, "kill"); +/* postnote(PNPROC, mc->pid, "kill"); */ - do; while(nbrecv(mc->c, &mc->Mouse) > 0); - - close(mc->mfd); - close(mc->cfd); - free(mc->file); - free(mc->c); - free(mc->resizec); + do; while(nbrecv(mc->c, &mc->m) > 0); + chanfree(mc->c); + chanfree(mc->resizec); free(mc); } int readmouse(Mousectl *mc) { - if(mc->image) - flushimage(mc->image->display, 1); - if(recv(mc->c, &mc->Mouse) < 0){ + if(mc->display) + flushimage(mc->display, 1); + if(recv(mc->c, &mc->m) < 0){ fprint(2, "readmouse: %r\n"); return -1; } @@ -46,45 +42,27 @@ static void _ioproc(void *arg) { - int n, nerr, one; - char buf[1+5*12]; + int one, resized; Mouse m; Mousectl *mc; mc = arg; threadsetname("mouseproc"); - one = 1; memset(&m, 0, sizeof m); - mc->pid = getpid(); - nerr = 0; + one = 1; + resized = 0; for(;;){ - n = read(mc->mfd, buf, sizeof buf); - if(n != 1+4*12){ - yield(); /* if error is due to exiting, we'll exit here */ - fprint(2, "mouse: bad count %d not 49: %r\n", n); - if(n<0 || ++nerr>10) - threadexits("read error"); - continue; - } - nerr = 0; - switch(buf[0]){ - case 'r': + if(_displayrdmouse(mc->display, &m, &resized) < 0) + threadexits("read error"); + if(resized) send(mc->resizec, &one); - /* fall through */ - case 'm': - m.xy.x = atoi(buf+1+0*12); - m.xy.y = atoi(buf+1+1*12); - m.buttons = atoi(buf+1+2*12); - m.msec = atoi(buf+1+3*12); - send(mc->c, &m); - /* - * mc->Mouse is updated after send so it doesn't have wrong value if we block during send. - * This means that programs should receive into mc->Mouse (see readmouse() above) if - * they want full synchrony. - */ - mc->Mouse = m; - break; - } + send(mc->c, &m); + /* + * mc->m is updated after send so it doesn't have wrong value if we block during send. + * This means that programs should receive into mc->Mouse (see readmouse() above) if + * they want full synchrony. + */ + mc->m = m; } } @@ -92,50 +70,21 @@ Mousectl* initmouse(char *file, Image *i) { Mousectl *mc; - char *t, *sl; mc = mallocz(sizeof(Mousectl), 1); - if(file == nil) - file = "/dev/mouse"; - mc->file = strdup(file); - mc->mfd = open(file, ORDWR|OCEXEC); - if(mc->mfd<0 && strcmp(file, "/dev/mouse")==0){ - bind("#m", "/dev", MAFTER); - mc->mfd = open(file, ORDWR|OCEXEC); - } - if(mc->mfd < 0){ - free(mc); - return nil; - } - t = malloc(strlen(file)+16); - strcpy(t, file); - sl = utfrrune(t, '/'); - if(sl) - strcpy(sl, "/cursor"); - else - strcpy(t, "/dev/cursor"); - mc->cfd = open(t, ORDWR|OCEXEC); - free(t); - mc->image = i; + if(i) + mc->display = i->display; mc->c = chancreate(sizeof(Mouse), 0); chansetname(mc->c, "mousec"); mc->resizec = chancreate(sizeof(int), 2); chansetname(mc->resizec, "resizec"); - proccreate(_ioproc, mc, 4096); + proccreate(_ioproc, mc, 32*1024); return mc; } void setcursor(Mousectl *mc, Cursor *c) { - char curs[2*4+2*2*16]; - - if(c == nil) - write(mc->cfd, curs, 0); - else{ - BPLONG(curs+0*4, c->offset.x); - BPLONG(curs+1*4, c->offset.y); - memmove(curs+2*4, c->clr, 2*2*16); - write(mc->cfd, curs, sizeof curs); - } + _displaycursor(mc->display, c); } + blob - 2c92f6feefdfeccbbb2f0eadba4a8dc3f07e4871 (mode 644) blob + /dev/null --- src/libdraw/nowsys-alloc.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include -#include - -Memimage* -allocmemimage(Rectangle r, u32int chan) -{ - return _allocmemimage(r, chan); -} - -void -freememimage(Memimage *m) -{ - _freememimage(m); -} - blob - 3d5261d12e938d72f580f8e51c5b414a266a8307 (mode 644) blob + /dev/null --- src/libdraw/nowsys-cload.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#include - -int -cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - return _cloadmemimage(i, r, data, ndata); -} - blob - 5eac24f0d43a27315dfc8351012a8f13f553c97e (mode 644) blob + /dev/null --- src/libdraw/nowsys-draw.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include -#include - -void -memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp, - Memimage *mask, Point mp, int op) -{ - Memdrawparam *par; - - if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil) - return; - _memimagedraw(par); -} blob - 0f168e0f5eb5e958f0079acff2a275ceaec6ce4a (mode 644) blob + /dev/null --- src/libdraw/nowsys-event.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include -#include - -static int -bad(void) -{ - sysfatal("compiled with no window system support"); - return 0; -} - -ulong -event(Event *e) -{ - USED(e); - return bad(); -} - -ulong -eread(ulong keys, Event *e) -{ - USED(keys); - USED(e); - return bad(); -} - -void -einit(ulong keys) -{ - USED(keys); - bad(); -} - -int -ekbd(void) -{ - return bad(); -} - -Mouse -emouse(void) -{ - Mouse m; - - bad(); - return m; -} - -int -ecanread(ulong keys) -{ - USED(keys); - return bad(); -} - -int -ecanmouse(void) -{ - return bad(); -} - -int -ecankbd(void) -{ - return bad(); -} - -void -emoveto(Point p) -{ -/* USED(p); */ - bad(); -} - -void -esetcursor(Cursor *c) -{ - USED(c); - bad(); -} - blob - d75459f1780b5ed24f9e690dea080479877b60b7 (mode 644) blob + /dev/null --- src/libdraw/nowsys-fill.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#include - -void -memfillcolor(Memimage *m, u32int val) -{ - _memfillcolor(m, val); -} - blob - 2481df1823e074de1ba2acd5944f6069517d7793 (mode 644) blob + /dev/null --- src/libdraw/nowsys-get.c +++ /dev/null @@ -1,3 +0,0 @@ -/* so that there's *something* in this file */ -int __nowsys__get(void) {return 0;} - blob - 763be54019b21d7a14b85ad7996690d5e97785aa (mode 644) blob + /dev/null --- src/libdraw/nowsys-init.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include -#include -#include - -char *winsize; - -static int -bad(void) -{ - sysfatal("compiled with no window system support"); - return 0; -} - -Display* -_initdisplay(void (*error)(Display*, char*), char *label) -{ - USED(error); - USED(label); - - bad(); - return nil; -} - -int -getwindow(Display *d, int ref) -{ - USED(d); - USED(ref); - return bad(); -} - -int -drawsetlabel(char *label) -{ - USED(label); - return bad(); -} - -void -_flushmemscreen(Rectangle r) -{ - bad(); -} - blob - 8c60c6bf2c597b0326a020822b824151e763ca42 (mode 644) blob + /dev/null --- src/libdraw/nowsys-itrans.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - -static int -bad(void) -{ - sysfatal("compiled with no window system support"); - return 0; -} - -void -putsnarf(char *data) -{ - USED(data); - bad(); -} - -char* -getsnarf(void) -{ - bad(); - return nil; -} blob - 3b78b5bcc164d095cf9538fa75d991e1607a23d6 (mode 644) blob + /dev/null --- src/libdraw/nowsys-keyboard.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static int -bad(void) -{ - sysfatal("compiled with no window system support"); - return 0; -} - -void -closekeyboard(Keyboardctl *mc) -{ - USED(mc); - bad(); -} - -Keyboardctl* -initkeyboard(char *file) -{ - USED(file); - bad(); - return nil; -} blob - fa8ac518ee992e4b9efa340828d474a5c8636ef0 (mode 644) blob + /dev/null --- src/libdraw/nowsys-keysym2ucs.c +++ /dev/null @@ -1,2 +0,0 @@ -/* so that there's *something* in this file */ -int __nowsys__itrans(void) {return 0;} blob - b0d5fcee18d715c9b7f1327dcf6b113bc45328e1 (mode 644) blob + /dev/null --- src/libdraw/nowsys-load.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#include - -int -loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - return _loadmemimage(i, r, data, ndata); -} - blob - af1bf990e7977f7fa4b7c945a650d269c9fcda13 (mode 644) blob + /dev/null --- src/libdraw/nowsys-mouse.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int _wantfocuschanges; -static int -bad(void) -{ - sysfatal("compiled with no window system support"); - return 0; -} - -void -moveto(Mousectl *m, Point pt) -{ - USED(m); -/* USED(pt); */ - bad(); -} - -void -closemouse(Mousectl *mc) -{ - USED(mc); - bad(); -} - -int -readmouse(Mousectl *mc) -{ - USED(mc); - return bad(); -} - -Mousectl* -initmouse(char *file, Image *i) -{ - USED(file); - USED(i); - bad(); - return nil; -} - -void -setcursor(Mousectl *mc, Cursor *c) -{ - USED(mc); - USED(c); - bad(); -} - -void -bouncemouse(Mouse *m) -{ - USED(m); - bad(); -} - blob - de744b969e175db57481c82750ffaf1b0717f17d (mode 644) blob + /dev/null --- src/libdraw/nowsys-pixelbits.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include -#include - -u32int -pixelbits(Memimage *m, Point p) -{ - return _pixelbits(m, p); -} - - blob - 3859321379e5384073273728aa498d1209fdb41d (mode 644) blob + /dev/null --- src/libdraw/nowsys-unload.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#include - -int -unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - return _unloadmemimage(i, r, data, ndata); -} - blob - c5b50ad7775203743dcda7f6c84fc17e80f79520 (mode 644) blob + /dev/null --- src/libdraw/nowsys-wsys.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -static int -bad(void) -{ - sysfatal("compiled with no window system support"); - return 0; -} - -void -drawtopwindow(void) -{ - bad(); -} - -void -drawresizewindow(Rectangle r) -{ - bad(); -} blob - c203b9c293823ae9257313b9126eeee86ea85aa9 blob + 2a688b58cebfb4a646118c423cf4fbf6bf93292e --- src/libdraw/unloadimage.c +++ src/libdraw/unloadimage.c @@ -43,7 +43,7 @@ unloadimage(Image *i, Rectangle r, uchar *data, int nd BPLONG(a+17, r.min.y+dy); if(flushimage(d, 0) < 0) return -1; - n = _drawmsgread(d, data+ntot, ndata-ntot); + n = _displayrddraw(d, data+ntot, ndata-ntot); if(n < 0) return n; ntot += n; blob - 5792864ffd5abc741208cfcbe361b0f17e18df3a (mode 644) blob + /dev/null --- src/libdraw/x11-alloc.c +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -/* - * Allocate a Memimage with an optional pixmap backing on the X server. - */ -Memimage* -_xallocmemimage(Rectangle r, u32int chan, int pixmap) -{ - int d, offset; - Memimage *m; - Xmem *xm; - XImage *xi; - - m = _allocmemimage(r, chan); - if(chan != GREY1 && chan != _x.chan) - return m; - if(_x.display == 0) - return m; - - /* - * For bootstrapping, don't bother storing 1x1 images - * on the X server. Memimageinit needs to allocate these - * and we memimageinit before we do the rest of the X stuff. - * Of course, 1x1 images on the server are useless anyway. - */ - if(Dx(r)==1 && Dy(r)==1) - return m; - - xm = mallocz(sizeof(Xmem), 1); - if(xm == nil){ - freememimage(m); - return nil; - } - - /* - * Allocate backing store. - */ - if(chan == GREY1) - d = 1; - else - d = _x.depth; - if(pixmap != PMundef) - xm->pixmap = pixmap; - else - xm->pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), d); - - /* - * We want to align pixels on word boundaries. - */ - if(m->depth == 24) - offset = r.min.x&3; - else - offset = r.min.x&(31/m->depth); - r.min.x -= offset; - assert(wordsperline(r, m->depth) <= m->width); - - /* - * Wrap our data in an XImage structure. - */ - xi = XCreateImage(_x.display, _x.vis, d, - ZPixmap, 0, (char*)m->data->bdata, Dx(r), Dy(r), - 32, m->width*sizeof(u32int)); - if(xi == nil){ - freememimage(m); - if(xm->pixmap != pixmap) - XFreePixmap(_x.display, xm->pixmap); - return nil; - } - - xm->xi = xi; - xm->r = r; - - /* - * Set the XImage parameters so that it looks exactly like - * a Memimage -- we're using the same data. - */ - if(m->depth < 8 || m->depth == 24) - xi->bitmap_unit = 8; - else - xi->bitmap_unit = m->depth; - xi->byte_order = LSBFirst; - xi->bitmap_bit_order = MSBFirst; - xi->bitmap_pad = 32; - XInitImage(xi); - XFlush(_x.display); - - m->X = xm; - return m; -} - -Memimage* -allocmemimage(Rectangle r, u32int chan) -{ - return _xallocmemimage(r, chan, PMundef); -} - -void -freememimage(Memimage *m) -{ - Xmem *xm; - - if(m == nil) - return; - - xm = m->X; - if(xm && m->data->ref == 1){ - if(xm->xi){ - xm->xi->data = nil; - XFree(xm->xi); - } - XFreePixmap(_x.display, xm->pixmap); - free(xm); - m->X = nil; - } - _freememimage(m); -} - blob - 33e3170a52527aa897bf1460928201a8ca5eeb98 (mode 644) blob + /dev/null --- src/libdraw/x11-cload.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -int -cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - int n; - - n = _cloadmemimage(i, r, data, ndata); - if(n > 0 && i->X) - _xputxdata(i, r); - return n; -} - blob - 6c41daffd1cf889f03ce7842461391e1ba9b4ea5 (mode 644) blob + /dev/null --- src/libdraw/x11-draw.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -static int xdraw(Memdrawparam*); - -/* - * The X acceleration doesn't fit into the standard hwaccel - * model because we have the extra steps of pulling the image - * data off the server and putting it back when we're done. - */ -void -memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp, - Memimage *mask, Point mp, int op) -{ - Memdrawparam *par; - - if((par = _memimagedrawsetup(dst, r, src, sp, mask, mp, op)) == nil) - return; - - /* only fetch dst data if we need it */ - if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask)) - _xgetxdata(par->dst, par->r); - - /* always fetch source and mask */ - _xgetxdata(par->src, par->sr); - _xgetxdata(par->mask, par->mr); - - /* now can run memimagedraw on the in-memory bits */ - _memimagedraw(par); - - if(xdraw(par)) - return; - - /* put bits back on x server */ - _xputxdata(par->dst, par->r); -} - -static int -xdraw(Memdrawparam *par) -{ - u32int sdval; - uint m, state; - Memimage *src, *dst, *mask; - Point dp, mp, sp; - Rectangle r; - Xmem *xdst, *xmask, *xsrc; - XGC gc; - - if(par->dst->X == nil) - return 0; - - dst = par->dst; - mask = par->mask; - r = par->r; - src = par->src; - state = par->state; - - /* - * If we have an opaque mask and source is one opaque pixel, - * we can convert to the destination format and just XFillRectangle. - */ - m = Simplesrc|Fullsrc|Simplemask|Fullmask; - if((state&m) == m){ - _xfillcolor(dst, r, par->sdval); - /* xdirtyxdata(dst, r); */ - return 1; - } - - /* - * If no source alpha and an opaque mask, we can just copy - * the source onto the destination. If the channels are the - * same and the source is not replicated, XCopyArea works. - */ - m = Simplemask|Fullmask; - if((state&(m|Replsrc))==m && src->chan==dst->chan && src->X){ - xdst = dst->X; - xsrc = src->X; - dp = subpt(r.min, dst->r.min); - sp = subpt(par->sr.min, src->r.min); - gc = dst->chan==GREY1 ? _x.gccopy0 : _x.gccopy; - - XCopyArea(_x.display, xsrc->pixmap, xdst->pixmap, gc, - sp.x, sp.y, Dx(r), Dy(r), dp.x, dp.y); - /* xdirtyxdata(dst, r); */ - return 1; - } - - /* - * If no source alpha, a 1-bit mask, and a simple source, - * we can copy through the mask onto the destination. - */ - if(dst->X && mask->X && !(mask->flags&Frepl) - && mask->chan==GREY1 && (state&Simplesrc)){ - xdst = dst->X; - xmask = mask->X; - sdval = par->sdval; - - dp = subpt(r.min, dst->r.min); - mp = subpt(r.min, subpt(par->mr.min, mask->r.min)); - - if(dst->chan == GREY1){ - gc = _x.gcsimplesrc0; - if(_x.gcsimplesrc0color != sdval){ - XSetForeground(_x.display, gc, sdval); - _x.gcsimplesrc0color = sdval; - } - if(_x.gcsimplesrc0pixmap != xmask->pixmap){ - XSetStipple(_x.display, gc, xmask->pixmap); - _x.gcsimplesrc0pixmap = xmask->pixmap; - } - }else{ - /* this doesn't work on rob's mac? */ - return 0; - /* gc = _x.gcsimplesrc; - if(dst->chan == CMAP8 && _x.usetable) - sdval = _x.tox11[sdval]; - - if(_x.gcsimplesrccolor != sdval){ - XSetForeground(_x.display, gc, sdval); - _x.gcsimplesrccolor = sdval; - } - if(_x.gcsimplesrcpixmap != xmask->pixmap){ - XSetStipple(_x.display, gc, xmask->pixmap); - _x.gcsimplesrcpixmap = xmask->pixmap; - } - */ - } - XSetTSOrigin(_x.display, gc, mp.x, mp.y); - XFillRectangle(_x.display, xdst->pixmap, gc, dp.x, dp.y, - Dx(r), Dy(r)); - /* xdirtyxdata(dst, r); */ - return 1; - } - - /* - * Can't accelerate. - */ - return 0; -} - blob - 2d8e9ea4ffd380e135b6e2b34d95f8a3507ad435 (mode 644) blob + /dev/null --- src/libdraw/x11-event.c +++ /dev/null @@ -1,187 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include -#include -#include "x11-memdraw.h" - -/* - * Should change this to support etimer and estartfn again. - * The main eread() would prepare a select mask from the keys - * and then call select() to wait for input. Then it would read an - * event from the readied fd and return it. Use XCheckWindowEvent - * to poll the X connection. - */ - -ulong -event(Event *e) -{ - return eread(~0UL, e); -} - -static void -eflush(void) -{ - /* avoid generating a message if there's nothing to show. */ - /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */ - /* also: make sure we don't interfere if we're multiprocessing the display */ - if(display->locking){ - /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */ - if(canqlock(&display->qlock)){ - if(display->bufp > display->buf) - flushimage(display, 1); - unlockdisplay(display); - } - }else - if(display->bufp > display->buf) - flushimage(display, 1); -} - -ulong -eread(ulong keys, Event *e) -{ - int r; - ulong xmask; - XEvent xevent; - - xmask = ExposureMask; - - eflush(); - - if(keys&Emouse) - xmask |= MouseMask|StructureNotifyMask; - if(keys&Ekeyboard){ - xmask |= KeyPressMask; - if((r = _xtoplan9kbd(nil)) >= 0){ - e->kbdc = r; - return Ekeyboard; - } - } - - xmask |= EnterWindowMask|LeaveWindowMask; - - XSelectInput(_x.display, _x.drawable, xmask); -again: - XWindowEvent(_x.display, _x.drawable, xmask, &xevent); - - switch(xevent.type){ - case Expose: - _xexpose(&xevent, _x.display); - goto again; - case DestroyNotify: - if(_xdestroy(&xevent, _x.display)) - postnote(PNGROUP, getpgrp(), "hangup"); - goto again; - case ConfigureNotify: - if(_xconfigure(&xevent, _x.display)) - eresized(1); - goto again; - case ButtonPress: - case ButtonRelease: - case MotionNotify: - if(_xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0) - goto again; - return Emouse; - case KeyPress: - e->kbdc = _xtoplan9kbd(&xevent); - if(e->kbdc == -1) - goto again; - return Ekeyboard; - default: - goto again; - } -} - -void -einit(ulong keys) -{ - keys &= ~(Emouse|Ekeyboard); - if(keys){ - fprint(2, "unknown keys in einit\n"); - abort(); - } -} - -int -ekbd(void) -{ - Event e; - - eread(Ekeyboard, &e); - return e.kbdc; -} - -Mouse -emouse(void) -{ - Event e; - - eread(Emouse, &e); - return e.mouse; -} - -int -ecanread(ulong keys) -{ - int can; - - can = 0; - if(keys&Emouse) - can |= ecanmouse(); - if(keys&Ekeyboard) - can |= ecankbd(); - return can; -} - -int -ecanmouse(void) -{ - XEvent xe; - Mouse m; - - eflush(); -again: - if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){ - if(_xtoplan9mouse(_x.display, &xe, &m) < 0) - goto again; - XPutBackEvent(_x.display, &xe); - return 1; - } - return 0; -} - -int -ecankbd(void) -{ - XEvent xe; - int r; - - eflush(); - if((r = _xtoplan9kbd(nil)) >= 0){ - _xtoplan9kbd((XEvent*)-1); - return 1; - } -again: - if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){ - if(_xtoplan9kbd(&xe) == -1) - goto again; - XPutBackEvent(_x.display, &xe); - return 1; - } - return 0; -} - -void -emoveto(Point p) -{ - _xmoveto(p); -} - -void -esetcursor(Cursor *c) -{ - _xsetcursor(c); -} - blob - fc43a684f7c42dcfb4a19643c00377221f5bd5b2 (mode 644) blob + /dev/null --- src/libdraw/x11-fill.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -void -memfillcolor(Memimage *m, u32int val) -{ - _memfillcolor(m, val); - if(m->X == nil) - return; - if((val & 0xFF) == 0xFF) /* full alpha */ - _xfillcolor(m, m->r, _rgbatoimg(m, val)); - else - _xputxdata(m, m->r); -} - -void -_xfillcolor(Memimage *m, Rectangle r, u32int v) -{ - Point p; - Xmem *xm; - XGC gc; - - xm = m->X; - assert(xm != nil); - - /* - * Set up fill context appropriately. - */ - if(m->chan == GREY1){ - gc = _x.gcfill0; - if(_x.gcfill0color != v){ - XSetForeground(_x.display, gc, v); - _x.gcfill0color = v; - } - }else{ - if(m->chan == CMAP8 && _x.usetable) - v = _x.tox11[v]; - gc = _x.gcfill; - if(_x.gcfillcolor != v){ - XSetForeground(_x.display, gc, v); - _x.gcfillcolor = v; - } - } - - /* - * XFillRectangle takes coordinates relative to image rectangle. - */ - p = subpt(r.min, m->r.min); - XFillRectangle(_x.display, xm->pixmap, gc, p.x, p.y, Dx(r), Dy(r)); -} - - blob - 395f45559c7c5461e0c2fe47c3e2202f50d106d1 (mode 644) blob + /dev/null --- src/libdraw/x11-get.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -static void -addrect(Rectangle *rp, Rectangle r) -{ - if(rp->min.x >= rp->max.x) - *rp = r; - else - combinerect(rp, r); -} - -XImage* -_xgetxdata(Memimage *m, Rectangle r) -{ - int x, y; - uchar *p; - Point tp, xdelta, delta; - Xmem *xm; - - xm = m->X; - if(xm == nil) - return nil; - - if(xm->dirty == 0) - return xm->xi; - - abort(); /* should never call this now */ - - r = xm->dirtyr; - if(Dx(r)==0 || Dy(r)==0) - return xm->xi; - - delta = subpt(r.min, m->r.min); - - tp = xm->r.min; /* need temp for Digital UNIX */ - xdelta = subpt(r.min, tp); - - XGetSubImage(_x.display, xm->pixmap, delta.x, delta.y, Dx(r), Dy(r), - AllPlanes, ZPixmap, xm->xi, xdelta.x, delta.y); - - if(_x.usetable && m->chan==CMAP8){ - for(y=r.min.y; ydirty = 0; - xm->dirtyr = Rect(0,0,0,0); - return xm->xi; -} - -void -_xputxdata(Memimage *m, Rectangle r) -{ - int offset, x, y; - uchar *p; - Point tp, xdelta, delta; - Xmem *xm; - XGC gc; - XImage *xi; - - xm = m->X; - if(xm == nil) - return; - - xi = xm->xi; - gc = m->chan==GREY1 ? _x.gccopy0 : _x.gccopy; - if(m->depth == 24) - offset = r.min.x & 3; - else - offset = r.min.x & (31/m->depth); - - delta = subpt(r.min, m->r.min); - - tp = xm->r.min; /* need temporary on Digital UNIX */ - xdelta = subpt(r.min, tp); - - if(_x.usetable && m->chan==CMAP8){ - for(y=r.min.y; ypixmap, gc, xi, xdelta.x, xdelta.y, delta.x, delta.y, - Dx(r), Dy(r)); - - if(_x.usetable && m->chan==CMAP8){ - for(y=r.min.y; yX; - if(xm == nil) - return; - - xm->dirty = 1; - addrect(&xm->dirtyr, r); -} - - - blob - 4baf4b1afca1b06cee1cbe12d5a32c2b33449bc5 (mode 644) blob + /dev/null --- src/libdraw/x11-inc.h +++ /dev/null @@ -1,31 +0,0 @@ -#define Colormap XColormap -#define Cursor XCursor -#define Display XDisplay -#define Drawable XDrawable -#define Font XFont -#define GC XGC -#define Point XPoint -#define Rectangle XRectangle -#define Screen XScreen -#define Visual XVisual -#define Window XWindow - -#include -#include -#include -#include -#include -#include - -#undef Colormap -#undef Cursor -#undef Display -#undef Drawable -#undef Font -#undef GC -#undef Point -#undef Rectangle -#undef Screen -#undef Visual -#undef Window - blob - b824441b49efb6233da511e9c4be98175204b8ba (mode 644) blob + /dev/null --- src/libdraw/x11-init.c +++ /dev/null @@ -1,940 +0,0 @@ -/* - * Some of the stuff in this file is not X-dependent and should be elsewhere. - */ -#include -#include "x11-inc.h" -#include -#include -#include -#include -#include -#include -#include "x11-memdraw.h" - -char *winsize; -static int parsewinsize(char*, Rectangle*, int*); - -static Memimage *xattach(char*); -static void plan9cmap(void); -static int setupcmap(XWindow); -static int xreplacescreenimage(void); -static XGC xgc(XDrawable, int, int); -static Image *getimage0(Display*, Image*); - -Xprivate _x; - -Display* -_initdisplay(void (*error)(Display*, char*), char *label) -{ - Display *d; - Memimage *m; - - /* - * This rfork(RFNOTEG) isn't exactly right, - * but we need some way to signal window - * closes. Right now we post a hangup - * note to the note group, which kills a whole - * lot more than just the current program - * if we don't do this. - */ - /* - * Actually, I don't know what I changed but - * this appears not to be necessary anymore. - * I'll regret this probably. - rfork(RFNOTEG); - */ - memimageinit(); - - d = mallocz(sizeof(Display), 1); - if(d == nil) - return nil; - - d->buf = malloc(16000+5); - d->obuf = malloc(16000); - if(d->buf == nil || d->obuf == nil){ - free(d->buf); - free(d->obuf); - free(d); - return nil; - } - d->bufsize = 16000; - d->obufsize = 16000; - d->bufp = d->buf; - d->obufp = d->obuf; - - m = xattach(label); - if(m == nil){ - free(d); - return nil; - } - - d->error = error; - _initdisplaymemimage(d, m); - d->image = getimage0(d, 0); - - return d; -} - -static Image* -getimage0(Display *d, Image *image) -{ - char info[12*12+1]; - uchar *a; - int n; - extern int _freeimage1(Image*); - - /* - * If there's an old screen, it has id 0. The 'J' request below - * will try to install the new screen as id 0, so the old one - * must be freed first. - */ - if(image){ - _freeimage1(image); - memset(image, 0, sizeof(Image)); - } - - a = bufimage(d, 2); - a[0] = 'J'; - a[1] = 'I'; - if(flushimage(d, 0) < 0){ - fprint(2, "cannot read screen info: %r\n"); - abort(); - } - - n = _drawmsgread(d, info, sizeof info); - if(n != 12*12){ - fprint(2, "short screen info\n"); - abort(); - } - - if(image == nil){ - image = mallocz(sizeof(Image), 1); - if(image == nil){ - fprint(2, "cannot allocate image: %r\n"); - abort(); - } - } - - image->display = d; - image->id = 0; - image->chan = strtochan(info+2*12); - image->depth = chantodepth(image->chan); - image->repl = atoi(info+3*12); - image->r.min.x = atoi(info+4*12); - image->r.min.y = atoi(info+5*12); - image->r.max.x = atoi(info+6*12); - image->r.max.y = atoi(info+7*12); - image->clipr.min.x = atoi(info+8*12); - image->clipr.min.y = atoi(info+9*12); - image->clipr.max.x = atoi(info+10*12); - image->clipr.max.y = atoi(info+11*12); - return image; -} - -int -getwindow(Display *d, int ref) -{ - Image *i; - Image *oi; - - if(_x.destroyed){ - postnote(PNGROUP, getpgrp(), "hangup"); - return -1; - } - if(xreplacescreenimage() == 0) - return 0; - - /* - * Libdraw promises not to change the value of "screen", - * so we have to reuse the image structure - * memory we already have. - */ - oi = d->image; - i = getimage0(d, oi); - d->image = i; - /* fprint(2, "getwindow %p -> %p\n", oi, i); */ - - freescreen(_screen); - _screen = allocscreen(i, d->white, 0); - _freeimage1(screen); - screen = _allocwindow(screen, _screen, i->r, ref, DWhite); - d->screenimage = screen; - return 0; -} - -static int -xerror(XDisplay *d, XErrorEvent *e) -{ - char buf[200]; - - if(e->request_code == 42) /* XSetInputFocus */ - return 0; - if(e->request_code == 18) /* XChangeProperty */ - return 0; - - print("X error: error_code=%d, request_code=%d, minor=%d disp=%p\n", - e->error_code, e->request_code, e->minor_code, d); - XGetErrorText(d, e->error_code, buf, sizeof buf); - print("%s\n", buf); - return 0; -} - -static int -xioerror(XDisplay *d) -{ - /*print("X I/O error\n"); */ - sysfatal("X I/O error\n"); - abort(); - return -1; -} - - -static Memimage* -xattach(char *label) -{ - char *argv[2], *disp; - int i, havemin, height, mask, n, width, x, xrootid, y; - Rectangle r; - XClassHint classhint; - XDrawable pmid; - XPixmapFormatValues *pfmt; - XScreen *xscreen; - XSetWindowAttributes attr; - XSizeHints normalhint; - XTextProperty name; - XVisualInfo xvi; - XWindow xrootwin; - XWindowAttributes wattr; - XWMHints hint; - Atom atoms[2]; - - /* - if(XInitThreads() == 0){ - fprint(2, "XInitThreads failed\n"); - abort(); - } - */ - - /* - * Connect to X server. - */ - _x.display = XOpenDisplay(NULL); - if(_x.display == nil){ - disp = getenv("DISPLAY"); - werrstr("XOpenDisplay %s: %r", disp ? disp : ":0"); - free(disp); - return nil; - } - XSetErrorHandler(xerror); - XSetIOErrorHandler(xioerror); - xrootid = DefaultScreen(_x.display); - xrootwin = DefaultRootWindow(_x.display); - - /* - * Figure out underlying screen format. - */ - if(XMatchVisualInfo(_x.display, xrootid, 16, TrueColor, &xvi) - || XMatchVisualInfo(_x.display, xrootid, 16, DirectColor, &xvi)){ - _x.vis = xvi.visual; - _x.depth = 16; - } - else - if(XMatchVisualInfo(_x.display, xrootid, 15, TrueColor, &xvi) - || XMatchVisualInfo(_x.display, xrootid, 15, DirectColor, &xvi)){ - _x.vis = xvi.visual; - _x.depth = 15; - } - else - if(XMatchVisualInfo(_x.display, xrootid, 24, TrueColor, &xvi) - || XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){ - _x.vis = xvi.visual; - _x.depth = 24; - } - else - if(XMatchVisualInfo(_x.display, xrootid, 8, PseudoColor, &xvi) - || XMatchVisualInfo(_x.display, xrootid, 8, StaticColor, &xvi)){ - if(_x.depth > 8){ - werrstr("can't deal with colormapped depth %d screens", - _x.depth); - goto err0; - } - _x.vis = xvi.visual; - _x.depth = 8; - } - else{ - _x.depth = DefaultDepth(_x.display, xrootid); - if(_x.depth != 8){ - werrstr("can't understand depth %d screen", _x.depth); - goto err0; - } - _x.vis = DefaultVisual(_x.display, xrootid); - } - - if(DefaultDepth(_x.display, xrootid) == _x.depth) - _x.usetable = 1; - - /* - * _x.depth is only the number of significant pixel bits, - * not the total number of pixel bits. We need to walk the - * display list to find how many actual bits are used - * per pixel. - */ - _x.chan = 0; - pfmt = XListPixmapFormats(_x.display, &n); - for(i=0; iclass != StaticColor){ - plan9cmap(); - setupcmap(xrootwin); - } - - /* - * We get to choose the initial rectangle size. - * This is arbitrary. In theory we should read the - * command line and allow the traditional X options. - */ - mask = 0; - x = 0; - y = 0; - if(winsize){ - if(parsewinsize(winsize, &r, &havemin) < 0) - sysfatal("%r"); - }else{ - /* - * Parse the various X resources. Thanks to Peter Canning. - */ - char *screen_resources, *display_resources, *geom, - *geomrestype, *home, *file; - XrmDatabase database; - XrmValue geomres; - - database = XrmGetDatabase(_x.display); - screen_resources = XScreenResourceString(xscreen); - if(screen_resources != nil){ - XrmCombineDatabase(XrmGetStringDatabase(screen_resources), &database, False); - XFree(screen_resources); - } - - display_resources = XResourceManagerString(_x.display); - if(display_resources == nil){ - home = getenv("HOME"); - if(home!=nil && (file=smprint("%s/.Xdefaults", home)) != nil){ - XrmCombineFileDatabase(file, &database, False); - free(file); - } - free(home); - }else - XrmCombineDatabase(XrmGetStringDatabase(display_resources), &database, False); - - geom = smprint("%s.geometry", label); - if(geom && XrmGetResource(database, geom, nil, &geomrestype, &geomres)) - mask = XParseGeometry(geomres.addr, &x, &y, (uint*)&width, (uint*)&height); - free(geom); - - if((mask & WidthValue) && (mask & HeightValue)){ - r = Rect(0, 0, width, height); - }else{ - r = Rect(0, 0, WidthOfScreen(xscreen)*3/4, - HeightOfScreen(xscreen)*3/4); - if(Dx(r) > Dy(r)*3/2) - r.max.x = r.min.x + Dy(r)*3/2; - if(Dy(r) > Dx(r)*3/2) - r.max.y = r.min.y + Dx(r)*3/2; - } - if(mask & XNegative){ - x += WidthOfScreen(xscreen); - } - if(mask & YNegative){ - y += HeightOfScreen(xscreen); - } - havemin = 0; - } - - memset(&attr, 0, sizeof attr); - attr.colormap = _x.cmap; - attr.background_pixel = ~0; - attr.border_pixel = 0; - _x.drawable = XCreateWindow( - _x.display, /* display */ - xrootwin, /* parent */ - x, /* x */ - y, /* y */ - Dx(r), /* width */ - Dy(r), /* height */ - 0, /* border width */ - _x.depth, /* depth */ - InputOutput, /* class */ - _x.vis, /* visual */ - /* valuemask */ - CWBackPixel|CWBorderPixel|CWColormap, - &attr /* attributes (the above aren't?!) */ - ); - - /* - * Label and other properties required by ICCCCM. - */ - memset(&name, 0, sizeof name); - if(label == nil) - label = "pjw-face-here"; - name.value = (uchar*)label; - name.encoding = XA_STRING; - name.format = 8; - name.nitems = strlen((char*)name.value); - - memset(&normalhint, 0, sizeof normalhint); - normalhint.flags = PSize|PMaxSize; - if(winsize){ - normalhint.flags &= ~PSize; - normalhint.flags |= USSize; - normalhint.width = Dx(r); - normalhint.height = Dy(r); - }else{ - if((mask & WidthValue) && (mask & HeightValue)){ - normalhint.flags &= ~PSize; - normalhint.flags |= USSize; - normalhint.width = width; - normalhint.height = height; - } - if((mask & WidthValue) && (mask & HeightValue)){ - normalhint.flags |= USPosition; - normalhint.x = x; - normalhint.y = y; - } - } - - normalhint.max_width = WidthOfScreen(xscreen); - normalhint.max_height = HeightOfScreen(xscreen); - - memset(&hint, 0, sizeof hint); - hint.flags = InputHint|StateHint; - hint.input = 1; - hint.initial_state = NormalState; - - memset(&classhint, 0, sizeof classhint); - classhint.res_name = label; - classhint.res_class = label; - - argv[0] = label; - argv[1] = nil; - - XSetWMProperties( - _x.display, /* display */ - _x.drawable, /* window */ - &name, /* XA_WM_NAME property */ - &name, /* XA_WM_ICON_NAME property */ - argv, /* XA_WM_COMMAND */ - 1, /* argc */ - &normalhint, /* XA_WM_NORMAL_HINTS */ - &hint, /* XA_WM_HINTS */ - &classhint /* XA_WM_CLASSHINTS */ - ); - XFlush(_x.display); - - if(havemin){ - XWindowChanges ch; - - memset(&ch, 0, sizeof ch); - ch.x = r.min.x; - ch.y = r.min.y; - XConfigureWindow(_x.display, _x.drawable, CWX|CWY, &ch); - /* - * Must pretend origin is 0,0 for X. - */ - r = Rect(0,0,Dx(r),Dy(r)); - } - /* - * Look up clipboard atom. - */ - _x.clipboard = XInternAtom(_x.display, "CLIPBOARD", False); - _x.utf8string = XInternAtom(_x.display, "UTF8_STRING", False); - _x.targets = XInternAtom(_x.display, "TARGETS", False); - _x.text = XInternAtom(_x.display, "TEXT", False); - _x.compoundtext = XInternAtom(_x.display, "COMPOUND_TEXT", False); - _x.takefocus = XInternAtom(_x.display, "WM_TAKE_FOCUS", False); - _x.losefocus = XInternAtom(_x.display, "_9WM_LOSE_FOCUS", False); - _x.wmprotos = XInternAtom(_x.display, "WM_PROTOCOLS", False); - - atoms[0] = _x.takefocus; - atoms[1] = _x.losefocus; - XChangeProperty(_x.display, _x.drawable, _x.wmprotos, XA_ATOM, 32, - PropModeReplace, (uchar*)atoms, 2); - - /* - * Put the window on the screen, check to see what size we actually got. - */ - XMapWindow(_x.display, _x.drawable); - XSync(_x.display, False); - - if(!XGetWindowAttributes(_x.display, _x.drawable, &wattr)) - fprint(2, "XGetWindowAttributes failed\n"); - else if(wattr.width && wattr.height){ - if(wattr.width != Dx(r) || wattr.height != Dy(r)){ - r.max.x = wattr.width; - r.max.y = wattr.height; - } - }else - fprint(2, "XGetWindowAttributes: bad attrs\n"); - - /* - * Allocate our local backing store. - */ - _x.screenr = r; - _x.screenpm = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth); - _x.nextscreenpm = _x.screenpm; - _x.screenimage = _xallocmemimage(r, _x.chan, _x.screenpm); - - /* - * Allocate some useful graphics contexts for the future. - */ - _x.gcfill = xgc(_x.screenpm, FillSolid, -1); - _x.gccopy = xgc(_x.screenpm, -1, -1); - _x.gcsimplesrc = xgc(_x.screenpm, FillStippled, -1); - _x.gczero = xgc(_x.screenpm, -1, -1); - _x.gcreplsrc = xgc(_x.screenpm, FillTiled, -1); - - pmid = XCreatePixmap(_x.display, _x.drawable, 1, 1, 1); - _x.gcfill0 = xgc(pmid, FillSolid, 0); - _x.gccopy0 = xgc(pmid, -1, -1); - _x.gcsimplesrc0 = xgc(pmid, FillStippled, -1); - _x.gczero0 = xgc(pmid, -1, -1); - _x.gcreplsrc0 = xgc(pmid, FillTiled, -1); - XFreePixmap(_x.display, pmid); - - /* - * Lots of display connections for various procs. - */ - _x.kbdcon = XOpenDisplay(NULL); - _x.mousecon = XOpenDisplay(NULL); - _x.snarfcon = XOpenDisplay(NULL); - - if(0) fprint(2, "x: display=%p kbd=%p mouse=%p snarf=%p\n", - _x.display, _x.kbdcon, _x.mousecon, _x.snarfcon); - - return _x.screenimage; - -err0: - /* - * Should do a better job of cleaning up here. - */ - XCloseDisplay(_x.display); - return nil; -} - -int -drawsetlabel(char *label) -{ - XTextProperty name; - - /* - * Label and other properties required by ICCCCM. - */ - memset(&name, 0, sizeof name); - if(label == nil) - label = "pjw-face-here"; - name.value = (uchar*)label; - name.encoding = XA_STRING; - name.format = 8; - name.nitems = strlen((char*)name.value); - - XSetWMProperties( - _x.display, /* display */ - _x.drawable, /* window */ - &name, /* XA_WM_NAME property */ - &name, /* XA_WM_ICON_NAME property */ - nil, /* XA_WM_COMMAND */ - 0, /* argc */ - nil, /* XA_WM_NORMAL_HINTS */ - nil, /* XA_WM_HINTS */ - nil /* XA_WM_CLASSHINTS */ - ); - XFlush(_x.display); - return 0; -} - -/* - * Create a GC with a particular fill style and XXX. - * Disable generation of GraphicsExpose/NoExpose events in the GC. - */ -static XGC -xgc(XDrawable d, int fillstyle, int foreground) -{ - XGC gc; - XGCValues v; - - memset(&v, 0, sizeof v); - v.function = GXcopy; - v.graphics_exposures = False; - gc = XCreateGC(_x.display, d, GCFunction|GCGraphicsExposures, &v); - if(fillstyle != -1) - XSetFillStyle(_x.display, gc, fillstyle); - if(foreground != -1) - XSetForeground(_x.display, gc, 0); - return gc; -} - - -/* - * Initialize map with the Plan 9 rgbv color map. - */ -static void -plan9cmap(void) -{ - int r, g, b, cr, cg, cb, v, num, den, idx, v7, idx7; - static int once; - - if(once) - return; - once = 1; - - for(r=0; r!=4; r++) - for(g = 0; g != 4; g++) - for(b = 0; b!=4; b++) - for(v = 0; v!=4; v++){ - den=r; - if(g > den) - den=g; - if(b > den) - den=b; - /* divide check -- pick grey shades */ - if(den==0) - cr=cg=cb=v*17; - else { - num=17*(4*den+v); - cr=r*num/den; - cg=g*num/den; - cb=b*num/den; - } - idx = r*64 + v*16 + ((g*4 + b + v - r) & 15); - _x.map[idx].red = cr*0x0101; - _x.map[idx].green = cg*0x0101; - _x.map[idx].blue = cb*0x0101; - _x.map[idx].pixel = idx; - _x.map[idx].flags = DoRed|DoGreen|DoBlue; - - v7 = v >> 1; - idx7 = r*32 + v7*16 + g*4 + b; - if((v & 1) == v7){ - _x.map7to8[idx7][0] = idx; - if(den == 0) { /* divide check -- pick grey shades */ - cr = ((255.0/7.0)*v7)+0.5; - cg = cr; - cb = cr; - } - else { - num=17*15*(4*den+v7*2)/14; - cr=r*num/den; - cg=g*num/den; - cb=b*num/den; - } - _x.map7[idx7].red = cr*0x0101; - _x.map7[idx7].green = cg*0x0101; - _x.map7[idx7].blue = cb*0x0101; - _x.map7[idx7].pixel = idx7; - _x.map7[idx7].flags = DoRed|DoGreen|DoBlue; - } - else - _x.map7to8[idx7][1] = idx; - } -} - -/* - * Initialize and install the rgbv color map as a private color map - * for this application. It gets the best colors when it has the - * cursor focus. - * - * We always choose the best depth possible, but that might not - * be the default depth. On such "suboptimal" systems, we have to allocate an - * empty color map anyway, according to Axel Belinfante. - */ -static int -setupcmap(XWindow w) -{ - char buf[30]; - int i; - u32int p, pp; - XColor c; - - if(_x.depth <= 1) - return 0; - - if(_x.depth >= 24) { - if(_x.usetable == 0) - _x.cmap = XCreateColormap(_x.display, w, _x.vis, AllocNone); - - /* - * The pixel value returned from XGetPixel needs to - * be converted to RGB so we can call rgb2cmap() - * to translate between 24 bit X and our color. Unfortunately, - * the return value appears to be display server endian - * dependant. Therefore, we run some heuristics to later - * determine how to mask the int value correctly. - * Yeah, I know we can look at _x.vis->byte_order but - * some displays say MSB even though they run on LSB. - * Besides, this is more anal. - */ - c = _x.map[19]; /* known to have different R, G, B values */ - if(!XAllocColor(_x.display, _x.cmap, &c)){ - werrstr("XAllocColor: %r"); - return -1; - } - p = c.pixel; - pp = rgb2cmap((p>>16)&0xff,(p>>8)&0xff,p&0xff); - if(pp != _x.map[19].pixel) { - /* check if endian is other way */ - pp = rgb2cmap(p&0xff,(p>>8)&0xff,(p>>16)&0xff); - if(pp != _x.map[19].pixel){ - werrstr("cannot detect X server byte order"); - return -1; - } - - switch(_x.chan){ - case RGB24: - _x.chan = BGR24; - break; - case XRGB32: - _x.chan = XBGR32; - break; - default: - werrstr("cannot byteswap channel %s", - chantostr(buf, _x.chan)); - break; - } - } - }else if(_x.vis->class == TrueColor || _x.vis->class == DirectColor){ - /* - * Do nothing. We have no way to express a - * mixed-endian 16-bit screen, so pretend they don't exist. - */ - if(_x.usetable == 0) - _x.cmap = XCreateColormap(_x.display, w, _x.vis, AllocNone); - }else if(_x.vis->class == PseudoColor){ - if(_x.usetable == 0){ - _x.cmap = XCreateColormap(_x.display, w, _x.vis, AllocAll); - XStoreColors(_x.display, _x.cmap, _x.map, 256); - for(i = 0; i < 256; i++){ - _x.tox11[i] = i; - _x.toplan9[i] = i; - } - }else{ - for(i = 0; i < 128; i++){ - c = _x.map7[i]; - if(!XAllocColor(_x.display, _x.cmap, &c)){ - werrstr("can't allocate colors in 7-bit map"); - return -1; - } - _x.tox11[_x.map7to8[i][0]] = c.pixel; - _x.tox11[_x.map7to8[i][1]] = c.pixel; - _x.toplan9[c.pixel] = _x.map7to8[i][0]; - } - } - }else{ - werrstr("unsupported visual class %d", _x.vis->class); - return -1; - } - return 0; -} - -void -_flushmemscreen(Rectangle r) -{ - if(_x.nextscreenpm != _x.screenpm){ - qlock(&_x.screenlock); - XSync(_x.display, False); - XFreePixmap(_x.display, _x.screenpm); - _x.screenpm = _x.nextscreenpm; - qunlock(&_x.screenlock); - } - - if(r.min.x >= r.max.x || r.min.y >= r.max.y) - return; - XCopyArea(_x.display, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y, - Dx(r), Dy(r), r.min.x, r.min.y); - XFlush(_x.display); -} - -void -_xexpose(XEvent *e, XDisplay *xd) -{ - XExposeEvent *xe; - Rectangle r; - - qlock(&_x.screenlock); - if(_x.screenpm != _x.nextscreenpm){ - qunlock(&_x.screenlock); - return; - } - xe = (XExposeEvent*)e; - r.min.x = xe->x; - r.min.y = xe->y; - r.max.x = xe->x+xe->width; - r.max.y = xe->y+xe->height; - XCopyArea(xd, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y, - Dx(r), Dy(r), r.min.x, r.min.y); - XSync(xd, False); - qunlock(&_x.screenlock); -} - -int -_xdestroy(XEvent *e, XDisplay *xd) -{ - XDestroyWindowEvent *xe; - - xe = (XDestroyWindowEvent*)e; - if(xe->window == _x.drawable){ - _x.destroyed = 1; - return 1; - } - return 0; -} - -int -_xconfigure(XEvent *e, XDisplay *xd) -{ - Rectangle r; - XConfigureEvent *xe = (XConfigureEvent*)e; - - if(xe->width == Dx(_x.screenr) && xe->height == Dy(_x.screenr)) - return 0; - if(xe->width==0 || xe->height==0) - fprint(2, "ignoring resize to %dx%d\n", xe->width, xe->height); - r = Rect(0, 0, xe->width, xe->height); - qlock(&_x.screenlock); - if(_x.screenpm != _x.nextscreenpm){ - XCopyArea(xd, _x.screenpm, _x.drawable, _x.gccopy, r.min.x, r.min.y, - Dx(r), Dy(r), r.min.x, r.min.y); - XSync(xd, False); - } - qunlock(&_x.screenlock); - _x.newscreenr = r; - return 1; -} - -static int -xreplacescreenimage(void) -{ - Memimage *m; - XDrawable pixmap; - Rectangle r; - - r = _x.newscreenr; - if(eqrect(_x.screenr, r)) - return 0; - - pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth); - m = _xallocmemimage(r, _x.chan, pixmap); - if(_x.nextscreenpm != _x.screenpm) - XFreePixmap(_x.display, _x.nextscreenpm); - _x.nextscreenpm = pixmap; - _x.screenr = r; - _drawreplacescreenimage(m); - return 1; -} - -static int -parsewinsize(char *s, Rectangle *r, int *havemin) -{ - char c, *os; - int i, j, k, l; - - os = s; - *havemin = 0; - *r = Rect(0,0,0,0); - if(!isdigit((uchar)*s)) - goto oops; - i = strtol(s, &s, 0); - if(*s == 'x'){ - s++; - if(!isdigit((uchar)*s)) - goto oops; - j = strtol(s, &s, 0); - r->max.x = i; - r->max.y = j; - if(*s == 0) - return 0; - if(*s != '@') - goto oops; - - s++; - if(!isdigit((uchar)*s)) - goto oops; - i = strtol(s, &s, 0); - if(*s != ',' && *s != ' ') - goto oops; - s++; - if(!isdigit((uchar)*s)) - goto oops; - j = strtol(s, &s, 0); - if(*s != 0) - goto oops; - *r = rectaddpt(*r, Pt(i,j)); - *havemin = 1; - return 0; - } - - c = *s; - if(c != ' ' && c != ',') - goto oops; - s++; - if(!isdigit((uchar)*s)) - goto oops; - j = strtol(s, &s, 0); - if(*s != c) - goto oops; - s++; - if(!isdigit((uchar)*s)) - goto oops; - k = strtol(s, &s, 0); - if(*s != c) - goto oops; - s++; - if(!isdigit((uchar)*s)) - goto oops; - l = strtol(s, &s, 0); - if(*s != 0) - goto oops; - *r = Rect(i,j,k,l); - *havemin = 1; - return 0; - -oops: - werrstr("bad syntax in window size '%s'", os); - return -1; -} blob - d8c1ff6bc4ff01dcea4a1942ebde76bc9300455b (mode 644) blob + /dev/null --- src/libdraw/x11-itrans.c +++ /dev/null @@ -1,675 +0,0 @@ -/* input event and data structure translation */ - -#include -#include "x11-inc.h" -#ifdef __APPLE__ -#define APPLESNARF -#define Boolean AppleBoolean -#define Rect AppleRect -#define EventMask AppleEventMask -#define Point ApplePoint -#define Cursor AppleCursor -#include -AUTOFRAMEWORK(Carbon) -#undef Boolean -#undef Rect -#undef EventMask -#undef Point -#undef Cursor -#endif -#include -#include -#include -#include -#include -#include -#include "x11-memdraw.h" -#include "x11-keysym2ucs.h" -#undef time - -static KeySym -__xtoplan9kbd(XEvent *e) -{ - KeySym k; - - if(e->xany.type != KeyPress) - return -1; - needstack(64*1024); /* X has some *huge* buffers in openobject */ - /* and they're even bigger on SuSE */ - XLookupString((XKeyEvent*)e,NULL,0,&k,NULL); - if(k == XK_Multi_key || k == NoSymbol) - return -1; - - if(k&0xFF00){ - switch(k){ - case XK_BackSpace: - case XK_Tab: - case XK_Escape: - case XK_Delete: - case XK_KP_0: - case XK_KP_1: - case XK_KP_2: - case XK_KP_3: - case XK_KP_4: - case XK_KP_5: - case XK_KP_6: - case XK_KP_7: - case XK_KP_8: - case XK_KP_9: - case XK_KP_Divide: - case XK_KP_Multiply: - case XK_KP_Subtract: - case XK_KP_Add: - case XK_KP_Decimal: - k &= 0x7F; - break; - case XK_Linefeed: - k = '\r'; - break; - case XK_KP_Space: - k = ' '; - break; - case XK_Home: - case XK_KP_Home: - k = Khome; - break; - case XK_Left: - case XK_KP_Left: - k = Kleft; - break; - case XK_Up: - case XK_KP_Up: - k = Kup; - break; - case XK_Down: - case XK_KP_Down: - k = Kdown; - break; - case XK_Right: - case XK_KP_Right: - k = Kright; - break; - case XK_Page_Down: - case XK_KP_Page_Down: - k = Kpgdown; - break; - case XK_End: - case XK_KP_End: - k = Kend; - break; - case XK_Page_Up: - case XK_KP_Page_Up: - k = Kpgup; - break; - case XK_Insert: - case XK_KP_Insert: - k = Kins; - break; - case XK_KP_Enter: - case XK_Return: - k = '\n'; - break; - case XK_Alt_L: - case XK_Meta_L: /* Shift Alt on PCs */ - case XK_Alt_R: - case XK_Meta_R: /* Shift Alt on PCs */ - k = Kalt; - break; - default: /* not ISO-1 or tty control */ - if(k>0xff) { - k = _p9keysym2ucs(k); - if(k==-1) return -1; - } - } - } - - /* Compensate for servers that call a minus a hyphen */ - if(k == XK_hyphen) - k = XK_minus; - /* Do control mapping ourselves if translator doesn't */ - if(e->xkey.state&ControlMask) - k &= 0x9f; - if(k == NoSymbol) { - return -1; - } - - return k+0; -} - -static Rune* -xtoplan9latin1(XEvent *e) -{ - static Rune k[10]; - static int alting, nk; - int n; - int r; - - r = __xtoplan9kbd(e); - if(r < 0) - return nil; - if(alting){ - /* - * Kludge for Mac's X11 3-button emulation. - * It treats Command+Button as button 3, but also - * ends up sending XK_Meta_L twice. - */ - if(r == Kalt){ - alting = 0; - return nil; - } - k[nk++] = r; - n = _latin1(k, nk); - if(n > 0){ - alting = 0; - k[0] = n; - k[1] = 0; - return k; - } - if(n == -1){ - alting = 0; - k[nk] = 0; - return k; - } - /* n < -1, need more input */ - return nil; - }else if(r == Kalt){ - alting = 1; - nk = 0; - return nil; - }else{ - k[0] = r; - k[1] = 0; - return k; - } -} - -int -_xtoplan9kbd(XEvent *e) -{ - static Rune *r; - - if(e == (XEvent*)-1){ - assert(r); - r--; - return 0; - } - if(e) - r = xtoplan9latin1(e); - if(r && *r) - return *r++; - return -1; -} - -int -_xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m) -{ - int s; - XButtonEvent *be; - XMotionEvent *me; - - if(_x.putsnarf != _x.assertsnarf){ - _x.assertsnarf = _x.putsnarf; - XSetSelectionOwner(_x.mousecon, XA_PRIMARY, _x.drawable, CurrentTime); - if(_x.clipboard != None) - XSetSelectionOwner(_x.mousecon, _x.clipboard, _x.drawable, CurrentTime); - XFlush(xd); - } - - switch(e->type){ - case ButtonPress: - be = (XButtonEvent*)e; - /* - * Fake message, just sent to make us announce snarf. - * Apparently state and button are 16 and 8 bits on - * the wire, since they are truncated by the time they - * get to us. - */ - if(be->send_event - && (~be->state&0xFFFF)==0 - && (~be->button&0xFF)==0) - return -1; - /* BUG? on mac need to inherit these from elsewhere? */ - m->xy.x = be->x; - m->xy.y = be->y; - s = be->state; - m->msec = be->time; - switch(be->button){ - case 1: - s |= Button1Mask; - break; - case 2: - s |= Button2Mask; - break; - case 3: - s |= Button3Mask; - break; - case 4: - s |= Button4Mask; - break; - case 5: - s |= Button5Mask; - break; - } - break; - case ButtonRelease: - be = (XButtonEvent*)e; - m->xy.x = be->x; - m->xy.y = be->y; - s = be->state; - m->msec = be->time; - switch(be->button){ - case 1: - s &= ~Button1Mask; - break; - case 2: - s &= ~Button2Mask; - break; - case 3: - s &= ~Button3Mask; - break; - case 4: - s &= ~Button4Mask; - break; - case 5: - s &= ~Button5Mask; - break; - } - break; - - case MotionNotify: - me = (XMotionEvent*)e; - s = me->state; - m->xy.x = me->x; - m->xy.y = me->y; - m->msec = me->time; - break; - - default: - return -1; - } - - m->buttons = 0; - if(s & Button1Mask) - m->buttons |= 1; - if(s & Button2Mask) - m->buttons |= 2; - if(s & Button3Mask) - m->buttons |= 4; - if(s & Button4Mask) - m->buttons |= 8; - if(s & Button5Mask) - m->buttons |= 16; - return 0; -} - -void -_xmoveto(Point p) -{ - XWarpPointer(_x.display, None, _x.drawable, 0, 0, 0, 0, p.x, p.y); - XFlush(_x.display); -} - -static int -revbyte(int b) -{ - int r; - - r = 0; - r |= (b&0x01) << 7; - r |= (b&0x02) << 5; - r |= (b&0x04) << 3; - r |= (b&0x08) << 1; - r |= (b&0x10) >> 1; - r |= (b&0x20) >> 3; - r |= (b&0x40) >> 5; - r |= (b&0x80) >> 7; - return r; -} - -static void -xcursorarrow(void) -{ - if(_x.cursor != 0){ - XFreeCursor(_x.display, _x.cursor); - _x.cursor = 0; - } - XUndefineCursor(_x.display, _x.drawable); - XFlush(_x.display); -} - - -void -_xsetcursor(Cursor *c) -{ - XColor fg, bg; - XCursor xc; - Pixmap xsrc, xmask; - int i; - uchar src[2*16], mask[2*16]; - - if(c == nil){ - xcursorarrow(); - return; - } - for(i=0; i<2*16; i++){ - src[i] = revbyte(c->set[i]); - mask[i] = revbyte(c->set[i] | c->clr[i]); - } - - fg = _x.map[0]; - bg = _x.map[255]; - xsrc = XCreateBitmapFromData(_x.display, _x.drawable, (char*)src, 16, 16); - xmask = XCreateBitmapFromData(_x.display, _x.drawable, (char*)mask, 16, 16); - xc = XCreatePixmapCursor(_x.display, xsrc, xmask, &fg, &bg, -c->offset.x, -c->offset.y); - if(xc != 0) { - XDefineCursor(_x.display, _x.drawable, xc); - if(_x.cursor != 0) - XFreeCursor(_x.display, _x.cursor); - _x.cursor = xc; - } - XFreePixmap(_x.display, xsrc); - XFreePixmap(_x.display, xmask); - XFlush(_x.display); -} - -struct { - QLock lk; - char buf[SnarfSize]; -#ifdef APPLESNARF - Rune rbuf[SnarfSize]; - PasteboardRef apple; -#endif -} clip; - -char* -_xgetsnarf(XDisplay *xd) -{ - uchar *data, *xdata; - Atom clipboard, type, prop; - ulong len, lastlen, dummy; - int fmt, i; - XWindow w; - - qlock(&clip.lk); - /* - * Have we snarfed recently and the X server hasn't caught up? - */ - if(_x.putsnarf != _x.assertsnarf) - goto mine; - - /* - * Is there a primary selection (highlighted text in an xterm)? - */ - clipboard = XA_PRIMARY; - w = XGetSelectionOwner(xd, XA_PRIMARY); - if(w == _x.drawable){ - mine: - data = (uchar*)strdup(clip.buf); - goto out; - } - - /* - * If not, is there a clipboard selection? - */ - if(w == None && _x.clipboard != None){ - clipboard = _x.clipboard; - w = XGetSelectionOwner(xd, _x.clipboard); - if(w == _x.drawable) - goto mine; - } - - /* - * If not, give up. - */ - if(w == None){ - data = nil; - goto out; - } - - /* - * We should be waiting for SelectionNotify here, but it might never - * come, and we have no way to time out. Instead, we will clear - * local property #1, request our buddy to fill it in for us, and poll - * until he's done or we get tired of waiting. - * - * We should try to go for _x.utf8string instead of XA_STRING, - * but that would add to the polling. - */ - prop = 1; - XChangeProperty(xd, _x.drawable, prop, XA_STRING, 8, PropModeReplace, (uchar*)"", 0); - XConvertSelection(xd, clipboard, XA_STRING, prop, _x.drawable, CurrentTime); - XFlush(xd); - lastlen = 0; - for(i=0; i<10 || (lastlen!=0 && i<30); i++){ - usleep(100*1000); - XGetWindowProperty(xd, _x.drawable, prop, 0, 0, 0, AnyPropertyType, - &type, &fmt, &dummy, &len, &data); - if(lastlen == len && len > 0) - break; - lastlen = len; - } - if(i == 10){ - data = nil; - goto out; - } - /* get the property */ - data = nil; - XGetWindowProperty(xd, _x.drawable, prop, 0, SnarfSize/sizeof(ulong), 0, - AnyPropertyType, &type, &fmt, &len, &dummy, &xdata); - if((type != XA_STRING && type != _x.utf8string) || len == 0){ - if(xdata) - XFree(xdata); - data = nil; - }else{ - if(xdata){ - data = (uchar*)strdup((char*)xdata); - XFree(xdata); - }else - data = nil; - } -out: - qunlock(&clip.lk); - return (char*)data; -} - -void -_xputsnarf(XDisplay *xd, char *data) -{ - XButtonEvent e; - - if(strlen(data) >= SnarfSize) - return; - qlock(&clip.lk); - strcpy(clip.buf, data); - /* leave note for mouse proc to assert selection ownership */ - _x.putsnarf++; - - /* send mouse a fake event so snarf is announced */ - memset(&e, 0, sizeof e); - e.type = ButtonPress; - e.window = _x.drawable; - e.state = ~0; - e.button = ~0; - XSendEvent(xd, _x.drawable, True, ButtonPressMask, (XEvent*)&e); - XFlush(xd); - qunlock(&clip.lk); -} - -int -_xselect(XEvent *e, XDisplay *xd) -{ - char *name; - XEvent r; - XSelectionRequestEvent *xe; - Atom a[4]; - - memset(&r, 0, sizeof r); - xe = (XSelectionRequestEvent*)e; -if(0) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d\n", - xe->target, xe->requestor, xe->property, xe->selection); - r.xselection.property = xe->property; - if(xe->target == _x.targets){ - a[0] = XA_STRING; - a[1] = _x.utf8string; - a[2] = _x.text; - a[3] = _x.compoundtext; - - XChangeProperty(xd, xe->requestor, xe->property, xe->target, - 8, PropModeReplace, (uchar*)a, sizeof a); - }else if(xe->target == XA_STRING - || xe->target == _x.utf8string - || xe->target == _x.text - || xe->target == _x.compoundtext - || ((name = XGetAtomName(xd, xe->target)) && strcmp(name, "text/plain;charset=UTF-8") == 0)){ - /* text/plain;charset=UTF-8 seems nonstandard but is used by Synergy */ - /* if the target is STRING we're supposed to reply with Latin1 XXX */ - qlock(&clip.lk); - XChangeProperty(xd, xe->requestor, xe->property, xe->target, - 8, PropModeReplace, (uchar*)clip.buf, strlen(clip.buf)); - qunlock(&clip.lk); - }else{ - if(strcmp(name, "TIMESTAMP") != 0) - fprint(2, "%s: cannot handle selection request for '%s' (%d)\n", argv0, name, (int)xe->target); - r.xselection.property = None; - } - - r.xselection.display = xe->display; - /* r.xselection.property filled above */ - r.xselection.target = xe->target; - r.xselection.type = SelectionNotify; - r.xselection.requestor = xe->requestor; - r.xselection.time = xe->time; - r.xselection.send_event = True; - r.xselection.selection = xe->selection; - XSendEvent(xd, xe->requestor, False, 0, &r); - XFlush(xd); - return 0; -} - -#ifdef APPLESNARF -char* -applegetsnarf(void) -{ - char *s, *t; - CFArrayRef flavors; - CFDataRef data; - CFIndex nflavor, ndata, j; - CFStringRef type; - ItemCount nitem; - PasteboardItemID id; - PasteboardSyncFlags flags; - UInt32 i; - -/* fprint(2, "applegetsnarf\n"); */ - qlock(&clip.lk); - if(clip.apple == nil){ - if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){ - fprint(2, "apple pasteboard create failed\n"); - qunlock(&clip.lk); - return nil; - } - } - flags = PasteboardSynchronize(clip.apple); - if(flags&kPasteboardClientIsOwner){ - s = strdup(clip.buf); - qunlock(&clip.lk); - return s; - } - if(PasteboardGetItemCount(clip.apple, &nitem) != noErr){ - fprint(2, "apple pasteboard get item count failed\n"); - qunlock(&clip.lk); - return nil; - } - for(i=1; i<=nitem; i++){ - if(PasteboardGetItemIdentifier(clip.apple, i, &id) != noErr) - continue; - if(PasteboardCopyItemFlavors(clip.apple, id, &flavors) != noErr) - continue; - nflavor = CFArrayGetCount(flavors); - for(j=0; j= SnarfSize) - return; - qlock(&clip.lk); - strcpy(clip.buf, s); - runesnprint(clip.rbuf, nelem(clip.rbuf), "%s", s); - if(clip.apple == nil){ - if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){ - fprint(2, "apple pasteboard create failed\n"); - qunlock(&clip.lk); - return; - } - } - if(PasteboardClear(clip.apple) != noErr){ - fprint(2, "apple pasteboard clear failed\n"); - qunlock(&clip.lk); - return; - } - flags = PasteboardSynchronize(clip.apple); - if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){ - fprint(2, "apple pasteboard cannot assert ownership\n"); - qunlock(&clip.lk); - return; - } - cfdata = CFDataCreate(kCFAllocatorDefault, - (uchar*)clip.rbuf, runestrlen(clip.rbuf)*2); - if(cfdata == nil){ - fprint(2, "apple pasteboard cfdatacreate failed\n"); - qunlock(&clip.lk); - return; - } - if(PasteboardPutItemFlavor(clip.apple, (PasteboardItemID)1, - CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){ - fprint(2, "apple pasteboard putitem failed\n"); - CFRelease(cfdata); - qunlock(&clip.lk); - return; - } - /* CFRelease(cfdata); ??? */ - qunlock(&clip.lk); -} -#endif /* APPLESNARF */ - -void -putsnarf(char *data) -{ -#ifdef APPLESNARF - appleputsnarf(data); -#endif - _xputsnarf(_x.snarfcon, data); -} - -char* -getsnarf(void) -{ - return _xgetsnarf(_x.snarfcon); -} - blob - 77fa78ba106ca1d40345ce482d81302d5813d662 (mode 644) blob + /dev/null --- src/libdraw/x11-keyboard.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include -#include -#include "x11-memdraw.h" - -void -closekeyboard(Keyboardctl *kc) -{ - if(kc == nil) - return; - -/* postnote(PNPROC, kc->pid, "kill"); -*/ - -#ifdef BUG - /* Drain the channel */ - while(?kc->c) - <-kc->c; -#endif - - close(kc->ctlfd); - close(kc->consfd); - free(kc->file); - free(kc->c); - free(kc); -} - -static -void -_ioproc(void *arg) -{ - int i; - int fd; - Keyboardctl *kc; - Rune r; - XEvent xevent; - - kc = arg; - threadsetname("kbdproc"); - kc->pid = getpid(); - fd = XConnectionNumber(_x.kbdcon); - XSelectInput(_x.kbdcon, _x.drawable, KeyPressMask); - for(;;){ - XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent); - switch(xevent.type){ - case KeyPress: - i = _xtoplan9kbd(&xevent); - if(i == -1) - continue; - r = i; - send(kc->c, &r); - while((i=_xtoplan9kbd(nil)) >= 0){ - r = i; - send(kc->c, &r); - } - break; - } - } -} - -Keyboardctl* -initkeyboard(char *file) -{ - Keyboardctl *kc; - - kc = mallocz(sizeof(Keyboardctl), 1); - if(kc == nil) - return nil; - kc->c = chancreate(sizeof(Rune), 20); - chansetname(kc->c, "kbdc"); - proccreate(_ioproc, kc, 256*1024); - return kc; -} - blob - 572f01d393ebdeeafa5584f2f191d0ee6f00d9ff (mode 644) blob + /dev/null --- src/libdraw/x11-keysym2ucs.c +++ /dev/null @@ -1,857 +0,0 @@ -/* $XFree86: xc/programs/xterm/keysym2ucs.c,v 1.5 2001/06/18 19:09:26 dickey Exp $ - * This module converts keysym values into the corresponding ISO 10646 - * (UCS, Unicode) values. - * - * The array keysymtab[] contains pairs of X11 keysym values for graphical - * characters and the corresponding Unicode value. The function - * keysym2ucs() maps a keysym onto a Unicode value using a binary search, - * therefore keysymtab[] must remain SORTED by keysym value. - * - * The keysym -> UTF-8 conversion will hopefully one day be provided - * by Xlib via XmbLookupString() and should ideally not have to be - * done in X applications. But we are not there yet. - * - * We allow to represent any UCS character in the range U-00000000 to - * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. - * This admittedly does not cover the entire 31-bit space of UCS, but - * it does cover all of the characters up to U-10FFFF, which can be - * represented by UTF-16, and more, and it is very unlikely that higher - * UCS codes will ever be assigned by ISO. So to get Unicode character - * U+ABCD you can directly use keysym 0x0100abcd. - * - * NOTE: The comments in the table below contain the actual character - * encoded in UTF-8, so for viewing and editing best use an editor in - * UTF-8 mode. - * - * Author: Markus G. Kuhn , University of Cambridge, April 2001 - * - * Special thanks to Richard Verhoeven for preparing - * an initial draft of the mapping table. - * - * This software is in the public domain. Share and enjoy! - * - * AUTOMATICALLY GENERATED FILE, DO NOT EDIT !!! (unicode/convmap.pl) - */ - -#ifndef KEYSYM2UCS_INCLUDED - -#include "x11-keysym2ucs.h" -#define VISIBLE /* */ - -#else - -#define VISIBLE static - -#endif - -static struct codepair { - unsigned short keysym; - unsigned short ucs; -} keysymtab[] = { - { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ - { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ - { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ - { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ - { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ - { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ - { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ - { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ - { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ - { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ - { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ - { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ - { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ - { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ - { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ - { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ - { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ - { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ - { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ - { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ - { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ - { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ - { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ - { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ - { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ - { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ - { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ - { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ - { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ - { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ - { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ - { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ - { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ - { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ - { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ - { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ - { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ - { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ - { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ - { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ - { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ - { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ - { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ - { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ - { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ - { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ - { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ - { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ - { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ - { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ - { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ - { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ - { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ - { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ - { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ - { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ - { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ - { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ - { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ - { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ - { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ - { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ - { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ - { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ - { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ - { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ - { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ - { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ - { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ - { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ - { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ - { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ - { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ - { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ - { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ - { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ - { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ - { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ - { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ - { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ - { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ - { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ - { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ - { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ - { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ - { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ - { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ - { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ - { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ - { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ - { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ - { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ - { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ - { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ - { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ - { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ - { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ - { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ - { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ - { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ - { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ - { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ - { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ - { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ - { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ - { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ - { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ - { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ - { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ - { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ - { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ - { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ - { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ - { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ - { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ - { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ - { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ - { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ - { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ - { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ - { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ - { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ - { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ - { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ - { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ - { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ - { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ - { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ - { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ - { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ - { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ - { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ - { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ - { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ - { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ - { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ - { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ - { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ - { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ - { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ - { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ - { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ - { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ - { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ - { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ - { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ - { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ - { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ - { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ - { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ - { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ - { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ - { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ - { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ - { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ - { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ - { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ - { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ - { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ - { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ - { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ - { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ - { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ - { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ - { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ - { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ - { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ - { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ - { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ - { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ - { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ - { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ - { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ - { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ - { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ - { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ - { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ - { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ - { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ - { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ - { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ - { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ - { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ - { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ - { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ - { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ - { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ - { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ - { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ - { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ - { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ - { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ - { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ - { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ - { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ - { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ - { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ - { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ - { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ - { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ - { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ - { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ - { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ - { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ - { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ - { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ - { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ - { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ - { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ - { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ - { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ - { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ - { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ - { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ - { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ - { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ - { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ - { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ - { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ - { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ - { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ - { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ - { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ - { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ - { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ - { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ - { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ - { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ - { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ - { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ - { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ - { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ - { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ - { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ - { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ - { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ - { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ - { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ - { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ - { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ - { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ - { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ - { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ - { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ - { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ - { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ - { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ - { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ - { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ - { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ - { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ - { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ - { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ - { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ - { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ - { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ - { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ - { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ - { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ - { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ - { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ - { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ - { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ - { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ - { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ - { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ - { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ - { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ - { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ - { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ - { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ - { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ - { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ - { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ - { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ - { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ - { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ - { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ - { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ - { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ - { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ - { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ - { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ - { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ - { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ - { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ - { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ - { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ - { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ - { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ - { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ - { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ - { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ - { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ - { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ - { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ - { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ - { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ - { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ - { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ - { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ - { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ - { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ - { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ - { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ - { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ - { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ - { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ - { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ - { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ - { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ - { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ - { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ - { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ - { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ - { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ - { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ - { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ - { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ - { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ - { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ - { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ - { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ - { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ - { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ - { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ - { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ - { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ - { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ - { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ - { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ - { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ - { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ - { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ - { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ - { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ - { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ - { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ - { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ - { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ - { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ - { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ - { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ - { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ - { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ - { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ - { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ - { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ - { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ - { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ - { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ - { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ - { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ - { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ - { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ - { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ - { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ - { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ - { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ - { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ - { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ - { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ - { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ - { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ - { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ - { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ - { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ - { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ - { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ - { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ - { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ - { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ - { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ - { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ - { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ - { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ - { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ - { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ - { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ - { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ - { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ - { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ - { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ - { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ - { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ - { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ - { 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */ - { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ - { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ - { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ - { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */ - { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */ - { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */ - { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */ - { 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */ - { 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */ - { 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */ - { 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */ - { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */ - { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */ -/* 0x08b1 topleftsummation ? ??? */ -/* 0x08b2 botleftsummation ? ??? */ -/* 0x08b3 topvertsummationconnector ? ??? */ -/* 0x08b4 botvertsummationconnector ? ??? */ -/* 0x08b5 toprightsummation ? ??? */ -/* 0x08b6 botrightsummation ? ??? */ -/* 0x08b7 rightmiddlesummation ? ??? */ - { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ - { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ - { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ - { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ - { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ - { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ - { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ - { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ - { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */ - { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ - { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ - { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ - { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ - { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ - { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ - { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ - { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ - { 0x08dd, 0x222a }, /* union ∪ UNION */ - { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ - { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ - { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ - { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ - { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ - { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ - { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ - { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ -/* 0x09df blank ? ??? */ - { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ - { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ - { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ - { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ - { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ - { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ - { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ - { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ - { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ - { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ - { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ - { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ - { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */ - { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */ - { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ - { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */ - { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */ - { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ - { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ - { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ - { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ - { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ - { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ - { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ - { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ - { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ - { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ - { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ - { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ - { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ - { 0x0aaa, 0x2013 }, /* endash – EN DASH */ -/* 0x0aac signifblank ? ??? */ - { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ - { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ - { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ - { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ - { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ - { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ - { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ - { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ - { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ - { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ - { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ - { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ - { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ -/* 0x0abd decimalpoint ? ??? */ - { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ -/* 0x0abf marker ? ??? */ - { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ - { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ - { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ - { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ - { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ - { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ -/* 0x0acb trademarkincircle ? ??? */ - { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ - { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ - { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ - { 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */ - { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ - { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ - { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ - { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ - { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ - { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ - { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ - { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ -/* 0x0ada hexagram ? ??? */ - { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ - { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ - { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ - { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ - { 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */ - { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ - { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ - { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ - { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ - { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ - { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ - { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ - { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ - { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ - { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ - { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ - { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ - { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ - { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ - { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ - { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ - { 0x0af1, 0x2020 }, /* dagger † DAGGER */ - { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ - { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ - { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ - { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ - { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ - { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ - { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ - { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ - { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ - { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ - { 0x0afc, 0x2038 }, /* caret ‸ CARET */ - { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ - { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ -/* 0x0aff cursor ? ??? */ - { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ - { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ - { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ - { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ - { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ - { 0x0bc2, 0x22a5 }, /* downtack ⊥ UP TACK */ - { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ - { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ - { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ - { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ - { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ - { 0x0bce, 0x22a4 }, /* uptack ⊤ DOWN TACK */ - { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ - { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ - { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ - { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ - { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ - { 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */ - { 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */ - { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ - { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ - { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ - { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ - { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ - { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ - { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ - { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ - { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ - { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ - { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ - { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ - { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ - { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ - { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ - { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ - { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ - { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ - { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ - { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ - { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ - { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ - { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ - { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ - { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ - { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ - { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ - { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ - { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ - { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ - { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ - { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ - { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ - { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ - { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ - { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ - { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ - { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ - { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ - { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ - { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ - { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ - { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ - { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ - { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ - { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ - { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ - { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ - { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ - { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ - { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ - { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ - { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ - { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ - { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ - { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ - { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ - { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ - { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ - { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ - { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ - { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ - { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ - { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ - { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ - { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ - { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ - { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ - { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ - { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ - { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ - { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ - { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ - { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ - { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ - { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ - { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ - { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ - { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ - { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ - { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ - { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ - { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ - { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ - { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ - { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ -/* 0x0dde Thai_maihanakat_maitho ? ??? */ - { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ - { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ - { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ - { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ - { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ - { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ - { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ - { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ - { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ - { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ - { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ - { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ - { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ - { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ - { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ - { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ - { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ - { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ - { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ - { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ - { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ - { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ - { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ - { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ - { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ - { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ - { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ - { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ - { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ - { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ - { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ - { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ - { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ - { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ - { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ - { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ - { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ - { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ - { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ - { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ - { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ - { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ - { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ - { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ - { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ - { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ - { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ - { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ - { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ - { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ - { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ - { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ - { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ - { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ - { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ - { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ - { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ - { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ - { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ - { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ - { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ - { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ - { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ - { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ - { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ - { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ - { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ - { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ - { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ - { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ - { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ - { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ - { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ - { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ - { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ - { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ - { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ - { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ - { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ - { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ - { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ - { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ - { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ - { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ - { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ - { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ - { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ - { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ - { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ - { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ - { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ - { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ - { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ - { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ - { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ - { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ - { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ - { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ - { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ - { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ - { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ - { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ - { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ - { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ - { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ - { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ - { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ - { 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */ - { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ - { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ - { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ - { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ - { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ - { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ - { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ - { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ - { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */ - { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ - { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ - { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ - { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ -}; - -VISIBLE -long _p9keysym2ucs(KeySym keysym) -{ - int min = 0; - int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; - int mid; - - /* first check for Latin-1 characters (1:1 mapping) */ - if ((keysym >= 0x0020 && keysym <= 0x007e) || - (keysym >= 0x00a0 && keysym <= 0x00ff)) - return keysym; - - /* also check for directly encoded 24-bit UCS characters */ - if ((keysym & 0xff000000) == 0x01000000) - return keysym & 0x00ffffff; - - /* binary search in table */ - while (max >= min) { - mid = (min + max) / 2; - if (keysymtab[mid].keysym < keysym) - min = mid + 1; - else if (keysymtab[mid].keysym > keysym) - max = mid - 1; - else { - /* found it */ - return keysymtab[mid].ucs; - } - } - - /* no matching Unicode value found */ - return -1; -} blob - 77050e1b74c4008782d2e2642f8d9f7b8ba049af (mode 644) blob + /dev/null --- src/libdraw/x11-keysym2ucs.h +++ /dev/null @@ -1,9 +0,0 @@ -/* $XFree86: xc/programs/xterm/keysym2ucs.h,v 1.1 1999/06/12 15:37:18 dawes Exp $ */ -/* - * This module converts keysym values into the corresponding ISO 10646-1 - * (UCS, Unicode) values. - */ - -#include - -long _p9keysym2ucs(KeySym keysym); blob - a7446f37dda49dee73b4b595e685401fd333f08a (mode 644) blob + /dev/null --- src/libdraw/x11-load.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -int -loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - int n; - - n = _loadmemimage(i, r, data, ndata); - if(n > 0 && i->X) - _xputxdata(i, r); - return n; -} - blob - c8d5e661b746cb4bfdd099972f0a446861d1ba87 (mode 644) blob + /dev/null --- src/libdraw/x11-memdraw.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Structure pointed to by X field of Memimage - */ - -typedef struct Xmem Xmem; -typedef struct Xprivate Xprivate; - -enum -{ - PMundef = ~0 -}; - -struct Xmem -{ - int pixmap; /* pixmap id */ - XImage *xi; /* local image */ - int dirty; /* is the X server ahead of us? */ - Rectangle dirtyr; /* which pixels? */ - Rectangle r; /* size of image */ -}; - -struct Xprivate { - u32int chan; - XColormap cmap; - XCursor cursor; - XDisplay *display; - int depth; /* of screen */ - XDrawable drawable; - XColor map[256]; - XColor map7[128]; - uchar map7to8[128][2]; - XGC gccopy; - XGC gccopy0; - XGC gcfill; - u32int gcfillcolor; - XGC gcfill0; - u32int gcfill0color; - XGC gcreplsrc; - u32int gcreplsrctile; - XGC gcreplsrc0; - u32int gcreplsrc0tile; - XGC gcsimplesrc; - u32int gcsimplesrccolor; - u32int gcsimplesrcpixmap; - XGC gcsimplesrc0; - u32int gcsimplesrc0color; - u32int gcsimplesrc0pixmap; - XGC gczero; - u32int gczeropixmap; - XGC gczero0; - u32int gczero0pixmap; - XDisplay *kbdcon; - XDisplay *mousecon; - Rectangle newscreenr; - Memimage* screenimage; - QLock screenlock; - XDrawable screenpm; - XDrawable nextscreenpm; - Rectangle screenr; - XDisplay *snarfcon; - int toplan9[256]; - int tox11[256]; - int usetable; - XVisual *vis; - Atom clipboard; - Atom utf8string; - Atom targets; - Atom text; - Atom compoundtext; - Atom takefocus; - Atom losefocus; - Atom wmprotos; - uint putsnarf; - uint assertsnarf; - int destroyed; -}; - -extern Xprivate _x; - -extern Memimage *_xallocmemimage(Rectangle, u32int, int); -extern XImage *_xallocxdata(Memimage*, Rectangle); -extern void _xdirtyxdata(Memimage*, Rectangle); -extern void _xfillcolor(Memimage*, Rectangle, u32int); -extern void _xfreexdata(Memimage*); -extern XImage *_xgetxdata(Memimage*, Rectangle); -extern void _xputxdata(Memimage*, Rectangle); -extern void _initdisplaymemimage(Display*, Memimage*); - -struct Mouse; -extern int _xtoplan9mouse(XDisplay*, XEvent*, struct Mouse*); -extern int _xtoplan9kbd(XEvent*); -extern void _xexpose(XEvent*, XDisplay*); -extern int _xselect(XEvent*, XDisplay*); -extern int _xconfigure(XEvent*, XDisplay*); -extern int _xdestroy(XEvent*, XDisplay*); -extern void _flushmemscreen(Rectangle); -extern void _xmoveto(Point); -struct Cursor; -extern void _xsetcursor(struct Cursor*); - -#define MouseMask (\ - ButtonPressMask|\ - ButtonReleaseMask|\ - PointerMotionMask|\ - Button1MotionMask|\ - Button2MotionMask|\ - Button3MotionMask) - blob - 4440639549f0028761116d3ef55e33722195a50f (mode 644) blob + /dev/null --- src/libdraw/x11-mouse.c +++ /dev/null @@ -1,221 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include -#include -#include -#include "x11-memdraw.h" - -int _windowhasfocus = 1; -int _wantfocuschanges; - -void -moveto(Mousectl *m, Point pt) -{ - _xmoveto(pt); -} - -void -closemouse(Mousectl *mc) -{ - if(mc == nil) - return; - -/* postnote(PNPROC, mc->pid, "kill"); -*/ - do; while(nbrecv(mc->c, &mc->m) > 0); - close(mc->mfd); - close(mc->cfd); - free(mc->file); - chanfree(mc->c); - chanfree(mc->resizec); - free(mc); -} - -int -readmouse(Mousectl *mc) -{ - if(mc->display) - flushimage(mc->display, 1); - if(recv(mc->c, &mc->m) < 0){ - fprint(2, "readmouse: %r\n"); - return -1; - } - return 0; -} - -/* - * This is necessary because some X libraries (e.g., on FC3) - * use an inordinate amount of stack space to do _xsetcursor. - * Perhaps instead there should be a generic "run this X routine" - * stack that you send a function and argument to. - */ -static -void -_cursorproc(void *arg) -{ - Mousectl *mc; - Cursor *c; - - mc = arg; - threadsetname("cursorproc (sigh)"); - for(;;){ - c = recvp(mc->ccursor); - _xsetcursor(c); - sendp(mc->ccursorwait, nil); - } -} - -static -void -_ioproc(void *arg) -{ - int fd, one, buttons; - Atom a; - ulong mask; - Mouse m; - Mousectl *mc; - XEvent xevent; - - one = 1; - mc = arg; - threadsetname("mouseproc"); - memset(&m, 0, sizeof m); - mc->pid = getpid(); - mask = MouseMask|ExposureMask|StructureNotifyMask; - XSelectInput(_x.mousecon, _x.drawable, mask); - fd = XConnectionNumber(_x.mousecon); - buttons = 0; - for(;;){ - XNextEvent(_x.mousecon, &xevent); - switch(xevent.type){ - case Expose: - _xexpose(&xevent, _x.mousecon); - continue; - case DestroyNotify: - if(_xdestroy(&xevent, _x.mousecon)){ - /* drain it before sending */ - /* apps that care can notice we sent a 0 */ - /* otherwise we'll have getwindow send SIGHUP */ - nbrecv(mc->resizec, 0); - nbrecv(mc->resizec, 0); - send(mc->resizec, 0); - } - continue; - case ConfigureNotify: - if(_xconfigure(&xevent, _x.mousecon)) - nbsend(mc->resizec, &one); - continue; - case SelectionRequest: - _xselect(&xevent, _x.mousecon); - continue; - case ButtonPress: - case ButtonRelease: - case MotionNotify: - /* If the motion notifications are backing up, skip over some. */ - if(0 && xevent.type == MotionNotify){ - while(XCheckWindowEvent(_x.mousecon, _x.drawable, MouseMask, &xevent)){ - if(xevent.type != MotionNotify) - break; - } - } - m.buttons = buttons; - if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0) - continue; - buttons = m.buttons; - send(mc->c, &m); - /* - * mc->Mouse is updated after send so it doesn't have wrong value if we block during send. - * This means that programs should receive into mc->Mouse (see readmouse() above) if - * they want full synchrony. - */ - mc->m = m; - break; - case ClientMessage: - if(xevent.xclient.message_type == _x.wmprotos){ - a = xevent.xclient.data.l[0]; - if(_wantfocuschanges && a == _x.takefocus){ - _windowhasfocus = 1; - _x.newscreenr = _x.screenr; - nbsend(mc->resizec, &one); - }else if(_wantfocuschanges && a == _x.losefocus){ - _windowhasfocus = 0; - _x.newscreenr = _x.screenr; - nbsend(mc->resizec, &one); - } - } - break; - } - } -} - -Mousectl* -initmouse(char *file, Image *i) -{ - Mousectl *mc; - - mc = mallocz(sizeof(Mousectl), 1); - if(i) - mc->display = i->display; - mc->c = chancreate(sizeof(Mouse), 0); - chansetname(mc->c, "mousec"); - mc->resizec = chancreate(sizeof(int), 2); - chansetname(mc->resizec, "resizec"); - mc->ccursor = chancreate(sizeof(void*), 0); - chansetname(mc->ccursor, "ccursor"); - mc->ccursorwait = chancreate(sizeof(void*), 0); - chansetname(mc->ccursor, "ccursorwait"); - proccreate(_ioproc, mc, 256*1024); - proccreate(_cursorproc, mc, 256*1024); /* sigh */ - return mc; -} - -void -setcursor(Mousectl *mc, Cursor *c) -{ - qlock(&mc->cursorlock); - sendp(mc->ccursor, c); - recvp(mc->ccursorwait); - qunlock(&mc->cursorlock); -} - -/* - * Send the mouse event back to the window manager. - * So that 9term can tell rio to pop up its button3 menu. - * Note that we're using _x.mousecon in a few places, - * so we have to be sure that the mouse proc isn't using it - * when we call! This is all a bit wonky and should be - * avoided unless you know what you're doing. - */ -void -bouncemouse(Mouse *m) -{ - XButtonEvent e; - XWindow dw; - - e.type = ButtonPress; - e.state = 0; - e.button = 0; - if(m->buttons&1) - e.button = 1; - else if(m->buttons&2) - e.button = 2; - else if(m->buttons&4) - e.button = 3; - e.same_screen = 1; - XTranslateCoordinates(_x.display, _x.drawable, - DefaultRootWindow(_x.display), - m->xy.x, m->xy.y, &e.x_root, &e.y_root, &dw); - e.root = DefaultRootWindow(_x.mousecon); - e.window = e.root; - e.subwindow = None; - e.x = e.x_root; - e.y = e.y_root; -#undef time - e.time = CurrentTime; - XUngrabPointer(_x.mousecon, m->msec); - XSendEvent(_x.mousecon, e.root, True, ButtonPressMask, (XEvent*)&e); - XFlush(_x.mousecon); -} blob - 5cbdded84267122b86eac07b0ff296456c1691c1 (mode 644) blob + /dev/null --- src/libdraw/x11-pixelbits.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -u32int -pixelbits(Memimage *m, Point p) -{ - if(m->X) - _xgetxdata(m, Rect(p.x, p.y, p.x+1, p.y+1)); - return _pixelbits(m, p); -} - - blob - d01a232ff99e9d228100ff1724e918f3c2a7f52f (mode 644) blob + /dev/null --- src/libdraw/x11-unload.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -int -unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) -{ - if(i->X) - _xgetxdata(i, r); - return _unloadmemimage(i, r, data, ndata); -} - blob - 582b68e1d86fe10ef54bc1b4b199afe0012843cd (mode 644) blob + /dev/null --- src/libdraw/x11-wsys.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include "x11-inc.h" -#include -#include -#include -#include "x11-memdraw.h" - -void -drawtopwindow(void) -{ - XMapRaised(_x.display, _x.drawable); - XFlush(_x.display); - /* - * Should not be using kbdcon since we're not running - * in the kbdproc, but this is necessary to make the keyboard - * take focus if the window is hidden when drawtopwindow - * is called. Let's hope that XSetInputFocus is only a write - * on the fd, and so it's okay to do even though the kbdproc - * is reading at the same time. - */ - XSetInputFocus(_x.kbdcon, _x.drawable, RevertToPointerRoot, - CurrentTime); - XFlush(_x.kbdcon); -} - -void -drawresizewindow(Rectangle r) -{ -/* XConfigureRequestEvent e; */ - XWindowChanges e; - int value_mask; - - memset(&e, 0, sizeof e); - value_mask = CWWidth|CWHeight; -/* e.x = r.min.x; */ -/* e.y = r.min.y; */ - e.width = Dx(r); - e.height = Dy(r); - XConfigureWindow(_x.display, _x.drawable, value_mask, &e); - XFlush(_x.display); -}