separate out
This commit is contained in:
parent
9361131304
commit
324891a557
37 changed files with 7447 additions and 0 deletions
204
src/libmemdraw/alloc.c
Normal file
204
src/libmemdraw/alloc.c
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
#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(cc))-1;
|
||||||
|
i->nbits[t] = NBITS(cc);
|
||||||
|
if(NBITS(cc) != 8)
|
||||||
|
bytes = 0;
|
||||||
|
}
|
||||||
|
i->nchan = k;
|
||||||
|
if(bytes)
|
||||||
|
i->flags |= Fbytes;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
116
src/libmemdraw/arc.c
Normal file
116
src/libmemdraw/arc.c
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
61
src/libmemdraw/arctest.c
Normal file
61
src/libmemdraw/arctest.c
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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<n; i++)
|
||||||
|
memarc(x, c, a, b, thick, memblack, sp, alpha, phi, SoverD);
|
||||||
|
t1 = nsec();
|
||||||
|
print("%lld %lld\n", t1-t0-del, del);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawdebug = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
68
src/libmemdraw/cload.c
Normal file
68
src/libmemdraw/cload.c
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
320
src/libmemdraw/cmap.c
Normal file
320
src/libmemdraw/cmap.c
Normal file
|
|
@ -0,0 +1,320 @@
|
||||||
|
/*
|
||||||
|
* generated by mkcmap.c
|
||||||
|
*/
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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){}
|
||||||
96
src/libmemdraw/cread.c
Normal file
96
src/libmemdraw/cread.c
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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<maxy){
|
||||||
|
werrstr("readimage: bad maxy %d", maxy);
|
||||||
|
goto Errout;
|
||||||
|
}
|
||||||
|
if(nb<=0 || ncblock<nb){
|
||||||
|
werrstr("readimage: bad count %d", nb);
|
||||||
|
goto Errout;
|
||||||
|
}
|
||||||
|
if(readn(fd, buf, nb)!=nb)
|
||||||
|
goto Shortread;
|
||||||
|
if(!new) /* old image: flip the data bits */
|
||||||
|
_twiddlecompressed(buf, nb);
|
||||||
|
cloadmemimage(i, Rect(r.min.x, miny, r.max.x, maxy), buf, nb);
|
||||||
|
miny = maxy;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
68
src/libmemdraw/defont.c
Normal file
68
src/libmemdraw/defont.c
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
2489
src/libmemdraw/draw.c
Normal file
2489
src/libmemdraw/draw.c
Normal file
File diff suppressed because it is too large
Load diff
1004
src/libmemdraw/drawtest.c
Normal file
1004
src/libmemdraw/drawtest.c
Normal file
File diff suppressed because it is too large
Load diff
247
src/libmemdraw/ellipse.c
Normal file
247
src/libmemdraw/ellipse.c
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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<a: t/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(b<a && u>b*b || a<b && -u>a*a) {
|
||||||
|
/* if(b<a&&(t<<1)>b*b/a || a<b&&(t<<1)>a*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);
|
||||||
|
}
|
||||||
524
src/libmemdraw/fillpoly.c
Normal file
524
src/libmemdraw/fillpoly.c
Normal file
|
|
@ -0,0 +1,524 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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; i<nseg; i++, s++) {
|
||||||
|
*p = s;
|
||||||
|
if(s->p0.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(y<maxy) {
|
||||||
|
for(q = p = seg; p < ep; p++) {
|
||||||
|
s = *p;
|
||||||
|
if(s->p1.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<<fixshift);
|
||||||
|
iy++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
yscan(Memimage *dst, Seg **seg, Seg *segtab, int nseg, int wind, Memimage *src, Point sp, int fixshift, int op)
|
||||||
|
{
|
||||||
|
long x, maxx, y, y2, yerr, yden, onehalf;
|
||||||
|
Seg **ep, **next, **p, **q, *s;
|
||||||
|
int n, i, ix, cnt, iy, iy2, miny, maxy;
|
||||||
|
Point pt;
|
||||||
|
|
||||||
|
for(i=0, s=segtab, p=seg; i<nseg; i++, s++) {
|
||||||
|
*p = s;
|
||||||
|
if(s->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(x<maxx) {
|
||||||
|
for(q = p = seg; p < ep; p++) {
|
||||||
|
s = *p;
|
||||||
|
if(s->p1.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<<fixshift);
|
||||||
|
ix++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zsort(Seg **seg, Seg **ep)
|
||||||
|
{
|
||||||
|
int done;
|
||||||
|
Seg **q, **p, *s;
|
||||||
|
|
||||||
|
if(ep-seg < 20) {
|
||||||
|
/* bubble sort by z - they should be almost sorted already */
|
||||||
|
q = ep;
|
||||||
|
do {
|
||||||
|
done = 1;
|
||||||
|
q--;
|
||||||
|
for(p = seg; p < q; p++) {
|
||||||
|
if(p[0]->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;
|
||||||
|
}
|
||||||
12
src/libmemdraw/hwdraw.c
Normal file
12
src/libmemdraw/hwdraw.c
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
hwdraw(Memdrawparam *p)
|
||||||
|
{
|
||||||
|
USED(p);
|
||||||
|
return 0; /* could not satisfy request */
|
||||||
|
}
|
||||||
|
|
||||||
12
src/libmemdraw/iprint.c
Normal file
12
src/libmemdraw/iprint.c
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
iprint(char *fmt,...)
|
||||||
|
{
|
||||||
|
USED(fmt);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
486
src/libmemdraw/line.c
Normal file
486
src/libmemdraw/line.c
Normal file
|
|
@ -0,0 +1,486 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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<clipr.max.y))
|
||||||
|
*d ^= (*d^srcval) & m;
|
||||||
|
if(e > 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<clipr.max.x))
|
||||||
|
*d ^= (*d^srcval) & m;
|
||||||
|
if(e > 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 && y<clipr.max.y){
|
||||||
|
d = byteaddr(dst, Pt(x, y));
|
||||||
|
sy = drawreplxy(src->r.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<clipr.max.x){
|
||||||
|
m = m0 >> (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<clipr.max.y){
|
||||||
|
d = byteaddr(dst, Pt(x, y));
|
||||||
|
s = byteaddr(src, addpt(dsrc, Pt(x, y)));
|
||||||
|
*d ^= (*d^*s) & m;
|
||||||
|
}
|
||||||
|
m >>= 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<clipr.max.x){
|
||||||
|
m = m0 >> (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;
|
||||||
|
}
|
||||||
72
src/libmemdraw/load.c
Normal file
72
src/libmemdraw/load.c
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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; y<r.max.y; y++){
|
||||||
|
*q ^= (*data^*q) & m;
|
||||||
|
q += i->width*sizeof(u32int);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
return ndata;
|
||||||
|
}
|
||||||
|
if(lpart==0 && rpart==0){ /* easy case */
|
||||||
|
for(y=r.min.y; y<r.max.y; y++){
|
||||||
|
memmove(q, data, l);
|
||||||
|
q += i->width*sizeof(u32int);
|
||||||
|
data += l;
|
||||||
|
}
|
||||||
|
return ndata;
|
||||||
|
}
|
||||||
|
mr = 0xFF ^ (0xFF >> rpart);
|
||||||
|
if(lpart!=0 && rpart==0){
|
||||||
|
for(y=r.min.y; y<r.max.y; y++){
|
||||||
|
*q ^= (*data^*q) & m;
|
||||||
|
if(l > 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<r.max.y; y++){
|
||||||
|
if(l > 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<r.max.y; y++){
|
||||||
|
*q ^= (*data^*q) & m;
|
||||||
|
if(l > 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;
|
||||||
|
}
|
||||||
79
src/libmemdraw/mkcmap.c
Normal file
79
src/libmemdraw/mkcmap.c
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 <u.h>\n#include <libc.h>\n");
|
||||||
|
else
|
||||||
|
print("#include \"lib9.h\"\n");
|
||||||
|
print("#include <draw.h>\n");
|
||||||
|
print("#include <memdraw.h>\n\n");
|
||||||
|
print("static Memcmap def = {\n");
|
||||||
|
print("/* cmap2rgb */ {\n");
|
||||||
|
for(i=0; i<sizeof(c->cmap2rgb); ){
|
||||||
|
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; i<sizeof(c->rgb2cmap);){
|
||||||
|
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);
|
||||||
|
}
|
||||||
32
src/libmemdraw/mkfile
Normal file
32
src/libmemdraw/mkfile
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
|
LIB=libmemdraw.a
|
||||||
|
|
||||||
|
OFILES=\
|
||||||
|
alloc.$O\
|
||||||
|
arc.$O\
|
||||||
|
cload.$O\
|
||||||
|
cmap.$O\
|
||||||
|
cread.$O\
|
||||||
|
defont.$O\
|
||||||
|
draw.$O\
|
||||||
|
ellipse.$O\
|
||||||
|
fillpoly.$O\
|
||||||
|
hwdraw.$O\
|
||||||
|
iprint.$O\
|
||||||
|
line.$O\
|
||||||
|
load.$O\
|
||||||
|
openmemsubfont.$O\
|
||||||
|
poly.$O\
|
||||||
|
read.$O\
|
||||||
|
string.$O\
|
||||||
|
subfont.$O\
|
||||||
|
unload.$O\
|
||||||
|
write.$O\
|
||||||
|
|
||||||
|
HFILES=\
|
||||||
|
$PLAN9/include/draw.h\
|
||||||
|
$PLAN9/include/memdraw.h\
|
||||||
|
|
||||||
|
<$PLAN9/src/mksyslib
|
||||||
|
|
||||||
53
src/libmemdraw/openmemsubfont.c
Normal file
53
src/libmemdraw/openmemsubfont.c
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
23
src/libmemdraw/poly.c
Normal file
23
src/libmemdraw/poly.c
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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<nvert; i++){
|
||||||
|
e0 = e1 = Enddisc;
|
||||||
|
if(i == 1)
|
||||||
|
e0 = end0;
|
||||||
|
if(i == nvert-1)
|
||||||
|
e1 = end1;
|
||||||
|
memline(dst, vert[i-1], vert[i], e0, e1, radius, src, addpt(d, vert[i-1]), op);
|
||||||
|
}
|
||||||
|
}
|
||||||
111
src/libmemdraw/read.c
Normal file
111
src/libmemdraw/read.c
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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<chunk; j++)
|
||||||
|
tmp[j] ^= 0xFF;
|
||||||
|
|
||||||
|
if(loadmemimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
|
||||||
|
goto Err;
|
||||||
|
miny += dy;
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
66
src/libmemdraw/string.c
Normal file
66
src/libmemdraw/string.c
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
34
src/libmemdraw/subfont.c
Normal file
34
src/libmemdraw/subfont.c
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
25
src/libmemdraw/unload.c
Normal file
25
src/libmemdraw/unload.c
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
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; y<r.max.y; y++){
|
||||||
|
memmove(data, q, l);
|
||||||
|
q += i->width*sizeof(u32int);
|
||||||
|
data += l;
|
||||||
|
}
|
||||||
|
return ndata;
|
||||||
|
}
|
||||||
183
src/libmemdraw/write.c
Normal file
183
src/libmemdraw/write.c
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
|
||||||
|
#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)<<HSHIFT)^(c))&HMASK)
|
||||||
|
typedef struct Hlist Hlist;
|
||||||
|
struct Hlist{
|
||||||
|
uchar *s;
|
||||||
|
Hlist *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
writememimage(int fd, Memimage *i)
|
||||||
|
{
|
||||||
|
uchar *outbuf, *outp, *eout; /* encoded data, pointer, end */
|
||||||
|
uchar *loutp; /* start of encoded line */
|
||||||
|
Hlist *hash; /* heads of hash chains of past strings */
|
||||||
|
Hlist *chain, *hp; /* hash chain members, pointer */
|
||||||
|
Hlist *cp; /* next Hlist to fall out of window */
|
||||||
|
int h; /* hash value */
|
||||||
|
uchar *line, *eline; /* input line, end pointer */
|
||||||
|
uchar *data, *edata; /* input buffer, end pointer */
|
||||||
|
u32int n; /* length of input buffer */
|
||||||
|
u32int nb; /* # of bytes returned by unloadimage */
|
||||||
|
int bpl; /* input line length */
|
||||||
|
int offs, runlen; /* offset, length of consumed data */
|
||||||
|
uchar dumpbuf[NDUMP]; /* dump accumulator */
|
||||||
|
int ndump; /* length of dump accumulator */
|
||||||
|
int miny, dy; /* y values while unloading input */
|
||||||
|
int ncblock; /* size of compressed blocks */
|
||||||
|
Rectangle r;
|
||||||
|
uchar *p, *q, *s, *es, *t;
|
||||||
|
char hdr[11+5*12+1];
|
||||||
|
char cbuf[20];
|
||||||
|
|
||||||
|
r = i->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;
|
||||||
|
}
|
||||||
192
src/libmemlayer/draw.c
Normal file
192
src/libmemlayer/draw.c
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
79
src/libmemlayer/lalloc.c
Normal file
79
src/libmemlayer/lalloc.c
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
112
src/libmemlayer/layerop.c
Normal file
112
src/libmemlayer/layerop.c
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/libmemlayer/ldelete.c
Normal file
67
src/libmemlayer/ldelete.c
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/libmemlayer/lhide.c
Normal file
67
src/libmemlayer/lhide.c
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
122
src/libmemlayer/line.c
Normal file
122
src/libmemlayer/line.c
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
55
src/libmemlayer/load.c
Normal file
55
src/libmemlayer/load.c
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
107
src/libmemlayer/lorigin.c
Normal file
107
src/libmemlayer/lorigin.c
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
35
src/libmemlayer/lsetrefresh.c
Normal file
35
src/libmemlayer/lsetrefresh.c
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
80
src/libmemlayer/ltofront.c
Normal file
80
src/libmemlayer/ltofront.c
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
69
src/libmemlayer/ltorear.c
Normal file
69
src/libmemlayer/ltorear.c
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
25
src/libmemlayer/mkfile
Normal file
25
src/libmemlayer/mkfile
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
|
LIB=libmemlayer.a
|
||||||
|
|
||||||
|
OFILES=\
|
||||||
|
draw.$O\
|
||||||
|
lalloc.$O\
|
||||||
|
layerop.$O\
|
||||||
|
ldelete.$O\
|
||||||
|
lhide.$O\
|
||||||
|
line.$O\
|
||||||
|
load.$O\
|
||||||
|
lorigin.$O\
|
||||||
|
lsetrefresh.$O\
|
||||||
|
ltofront.$O\
|
||||||
|
ltorear.$O\
|
||||||
|
unload.$O\
|
||||||
|
|
||||||
|
HFILES=\
|
||||||
|
$PLAN9/include/draw.h\
|
||||||
|
$PLAN9/include/memdraw.h\
|
||||||
|
$PLAN9/include/memlayer.h\
|
||||||
|
|
||||||
|
<$PLAN9/src/mksyslib
|
||||||
|
|
||||||
52
src/libmemlayer/unload.c
Normal file
52
src/libmemlayer/unload.c
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue