a
This commit is contained in:
33
libmemdraw/Makefile
Normal file
33
libmemdraw/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
LIB=libmemdraw.a
|
||||
CC=gcc
|
||||
CFLAGS=-I../include -I. -c -ggdb -D_THREAD_SAFE -pthread
|
||||
O=o
|
||||
|
||||
OFILES=\
|
||||
alloc.$O\
|
||||
arc.$O\
|
||||
cload.$O\
|
||||
cmap.$O\
|
||||
cread.$O\
|
||||
defont.$O\
|
||||
draw.$O\
|
||||
ellipse.$O\
|
||||
fillpoly.$O\
|
||||
hwdraw.$O\
|
||||
line.$O\
|
||||
load.$O\
|
||||
openmemsubfont.$O\
|
||||
poly.$O\
|
||||
read.$O\
|
||||
string.$O\
|
||||
subfont.$O\
|
||||
unload.$O\
|
||||
write.$O
|
||||
|
||||
$(LIB): $(OFILES)
|
||||
ar r $(LIB) $(OFILES)
|
||||
ranlib $(LIB)
|
||||
|
||||
%.$O: %.c
|
||||
$(CC) $(CFLAGS) $*.c
|
||||
|
200
libmemdraw/alloc.c
Normal file
200
libmemdraw/alloc.c
Normal file
@@ -0,0 +1,200 @@
|
||||
#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[2];
|
||||
}
|
||||
|
||||
Memimage*
|
||||
allocmemimaged(Rectangle r, ulong chan, Memdata *md, void *X)
|
||||
{
|
||||
int d;
|
||||
ulong 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(ulong)*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, ulong chan)
|
||||
{
|
||||
int d;
|
||||
ulong l, nw;
|
||||
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, (2+nw)*sizeof(ulong));
|
||||
if(md->base == nil){
|
||||
free(md);
|
||||
return nil;
|
||||
}
|
||||
|
||||
md->base[0] = (ulong)md;
|
||||
md->base[1] = getcallerpc(&r);
|
||||
|
||||
/* if this changes, memimagemove must change too */
|
||||
md->bdata = (uchar*)&md->base[2];
|
||||
|
||||
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.
|
||||
*/
|
||||
ulong*
|
||||
wordaddr(Memimage *i, Point p)
|
||||
{
|
||||
return (ulong*) ((ulong)byteaddr(i, p) & ~(sizeof(ulong)-1));
|
||||
}
|
||||
|
||||
uchar*
|
||||
byteaddr(Memimage *i, Point p)
|
||||
{
|
||||
uchar *a;
|
||||
|
||||
a = i->data->bdata+i->zero+sizeof(ulong)*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, ulong chan)
|
||||
{
|
||||
int d;
|
||||
int t, j, k;
|
||||
ulong 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;
|
||||
}
|
9
libmemdraw/alpha.hoc
Normal file
9
libmemdraw/alpha.hoc
Normal file
@@ -0,0 +1,9 @@
|
||||
func f(x) {
|
||||
return x-x%1
|
||||
}
|
||||
|
||||
func pixel(dr, dg, db, da, sr, sg, sb, sa, m) {
|
||||
M = 255-f((sa*m)/255)
|
||||
print f((sr*m+dr*M)/255), " ", f((sg*m+dg*M)/255), " ", f((sb*m+db*M)/255), " ", f((sa*m+da*M)/255), "\n"
|
||||
return 0
|
||||
}
|
117
libmemdraw/arc.c
Normal file
117
libmemdraw/arc.c
Normal file
@@ -0,0 +1,117 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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);
|
||||
}
|
62
libmemdraw/arctest.c
Normal file
62
libmemdraw/arctest.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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
libmemdraw/cload.c
Normal file
68
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
libmemdraw/cmap.c
Normal file
320
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
libmemdraw/cread.c
Normal file
96
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;
|
||||
ulong 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
libmemdraw/defont.c
Normal file
68
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 ulong*.
|
||||
*/
|
||||
p = (char*)defontdata;
|
||||
n = (ulong)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(ulong);
|
||||
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;
|
||||
}
|
2499
libmemdraw/draw.c
Normal file
2499
libmemdraw/draw.c
Normal file
File diff suppressed because it is too large
Load Diff
1004
libmemdraw/drawtest.c
Normal file
1004
libmemdraw/drawtest.c
Normal file
File diff suppressed because it is too large
Load Diff
248
libmemdraw/ellipse.c
Normal file
248
libmemdraw/ellipse.c
Normal file
@@ -0,0 +1,248 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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);
|
||||
}
|
523
libmemdraw/fillpoly.c
Normal file
523
libmemdraw/fillpoly.c
Normal file
@@ -0,0 +1,523 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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(void*, void*);
|
||||
static int xcompare(void*, void*);
|
||||
static int zcompare(void*, 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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(void *a, void *b)
|
||||
{
|
||||
Seg **s0, **s1;
|
||||
long y0, y1;
|
||||
|
||||
s0 = a;
|
||||
s1 = b;
|
||||
y0 = (*s0)->p0.y;
|
||||
y1 = (*s1)->p0.y;
|
||||
|
||||
if(y0 < y1)
|
||||
return -1;
|
||||
if(y0 == y1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
xcompare(void *a, void *b)
|
||||
{
|
||||
Seg **s0, **s1;
|
||||
long x0, x1;
|
||||
|
||||
s0 = a;
|
||||
s1 = b;
|
||||
x0 = (*s0)->p0.x;
|
||||
x1 = (*s1)->p0.x;
|
||||
|
||||
if(x0 < x1)
|
||||
return -1;
|
||||
if(x0 == x1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zcompare(void *a, void *b)
|
||||
{
|
||||
Seg **s0, **s1;
|
||||
long z0, z1;
|
||||
|
||||
s0 = a;
|
||||
s1 = b;
|
||||
z0 = (*s0)->z;
|
||||
z1 = (*s1)->z;
|
||||
|
||||
if(z0 < z1)
|
||||
return -1;
|
||||
if(z0 == z1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
12
libmemdraw/hwdraw.c
Normal file
12
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
libmemdraw/iprint.c
Normal file
12
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;
|
||||
}
|
||||
|
485
libmemdraw/line.c
Normal file
485
libmemdraw/line.c
Normal file
@@ -0,0 +1,485 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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(ulong);
|
||||
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(ulong);
|
||||
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
libmemdraw/load.c
Normal file
72
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(ulong);
|
||||
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(ulong);
|
||||
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(ulong);
|
||||
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(ulong);
|
||||
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(ulong);
|
||||
data += l;
|
||||
}
|
||||
return ndata;
|
||||
}
|
79
libmemdraw/mkcmap.c
Normal file
79
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);
|
||||
}
|
27
libmemdraw/mkfile
Normal file
27
libmemdraw/mkfile
Normal file
@@ -0,0 +1,27 @@
|
||||
<$DSRC/mkfile-$CONF
|
||||
TARG=libmemdraw.$L
|
||||
|
||||
OFILES=\
|
||||
alloc.$O\
|
||||
arc.$O\
|
||||
cload.$O\
|
||||
cmap.$O\
|
||||
cread.$O\
|
||||
defont.$O\
|
||||
draw.$O\
|
||||
ellipse.$O\
|
||||
fillpoly.$O\
|
||||
hwdraw.$O\
|
||||
line.$O\
|
||||
load.$O\
|
||||
openmemsubfont.$O\
|
||||
poly.$O\
|
||||
read.$O\
|
||||
string.$O\
|
||||
subfont.$O\
|
||||
unload.$O\
|
||||
write.$O
|
||||
|
||||
HFILE=\
|
||||
|
||||
<$DSRC/mklib-$CONF
|
53
libmemdraw/openmemsubfont.c
Normal file
53
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;
|
||||
}
|
24
libmemdraw/poly.c
Normal file
24
libmemdraw/poly.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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
libmemdraw/read.c
Normal file
111
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;
|
||||
ulong 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;
|
||||
}
|
68
libmemdraw/string.c
Normal file
68
libmemdraw/string.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
#include <memlayer.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;
|
||||
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
libmemdraw/subfont.c
Normal file
34
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);
|
||||
}
|
19
libmemdraw/times
Normal file
19
libmemdraw/times
Normal file
@@ -0,0 +1,19 @@
|
||||
draw1: 6M for draw 0,0,100,100 no repl
|
||||
draw3: 4M for draw 0,0,100,100 no repl
|
||||
just read src, dst - 250k
|
||||
mask reading - 650k
|
||||
write dst - 100k
|
||||
alpha calculation - 3000k
|
||||
|
||||
olddraw: 10M for draw 0, 0, 1000, 1000 no repl all ldepth 3
|
||||
44M for draw 0, 0, 1000, 1000 src, mask ldepth 2 dst ldepth 3
|
||||
draw4: 160M for draw 0, 0, 1000, 1000 no repl all r8g8b8
|
||||
null loop: 10k
|
||||
src, dst reading: 13-15M each
|
||||
mask reading: 30M
|
||||
alpha calculation loop: 90M
|
||||
null alpha loop: 2M
|
||||
minimal loop control +20M
|
||||
alpha calculation with divides +190M
|
||||
alpha calculation wtih shifts +70M
|
||||
writeback: 11M
|
25
libmemdraw/unload.c
Normal file
25
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(ulong);
|
||||
data += l;
|
||||
}
|
||||
return ndata;
|
||||
}
|
183
libmemdraw/write.c
Normal file
183
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 */
|
||||
ulong n; /* length of input buffer */
|
||||
ulong 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;
|
||||
}
|
Reference in New Issue
Block a user