Initial import.

This commit is contained in:
rsc 2003-09-30 17:47:42 +00:00
parent b2cfc4e2e7
commit ed7c8e8d02
41 changed files with 3226 additions and 0 deletions

View file

@ -0,0 +1,43 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
Image*
allocimagemix(Display *d, u32int color1, u32int color3)
{
Image *t, *b;
static Image *qmask;
if(qmask == nil)
qmask = allocimage(d, Rect(0,0,1,1), GREY8, 1, 0x3F3F3FFF);
if(d->screenimage->depth <= 8){ /* create a 2×2 texture */
t = allocimage(d, Rect(0,0,1,1), d->screenimage->chan, 0, color1);
if(t == nil)
return nil;
b = allocimage(d, Rect(0,0,2,2), d->screenimage->chan, 1, color3);
if(b == nil){
freeimage(t);
return nil;
}
draw(b, Rect(0,0,1,1), t, nil, ZP);
freeimage(t);
return b;
}else{ /* use a solid color, blended using alpha */
t = allocimage(d, Rect(0,0,1,1), d->screenimage->chan, 1, color1);
if(t == nil)
return nil;
b = allocimage(d, Rect(0,0,1,1), d->screenimage->chan, 1, color3);
if(b == nil){
freeimage(t);
return nil;
}
draw(b, b->r, t, qmask, ZP);
freeimage(t);
return b;
}
}

244
src/libdraw/bezier.c Normal file
View file

@ -0,0 +1,244 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#define PINC 32 /* realloc granularity */
typedef struct Plist Plist;
struct Plist
{
Point *p;
int np; /* -1 if malloc/realloc failed */
};
static void
appendpt(Plist *l, Point p)
{
if(l->np == -1)
return;
if(l->np == 0)
l->p = malloc(PINC*sizeof(Point));
else if(l->np%PINC == 0)
l->p = realloc(l->p, (l->np+PINC)*sizeof(Point));
if(l->p == 0){
l->np = -1;
return;
}
l->p[l->np++] = p;
}
static int
normsq(Point p)
{
return p.x*p.x+p.y*p.y;
}
static int
psdist(Point p, Point a, Point b)
{
int num, den;
p = subpt(p, a);
b = subpt(b, a);
num = p.x*b.x + p.y*b.y;
if(num <= 0)
return normsq(p);
den = normsq(b);
if(num >= den)
return normsq(subpt(b, p));
return normsq(subpt(divpt(mulpt(b, num), den), p));
}
/*
* Convert cubic Bezier curve control points to polyline
* vertices. Leaves the last vertex off, so you can continue
* with another curve.
*/
static void
bpts1(Plist *l, Point p0, Point p1, Point p2, Point p3, int scale)
{
Point p01, p12, p23, p012, p123, p0123;
Point tp0, tp1, tp2, tp3;
tp0=divpt(p0, scale);
tp1=divpt(p1, scale);
tp2=divpt(p2, scale);
tp3=divpt(p3, scale);
if(psdist(tp1, tp0, tp3)<=1 && psdist(tp2, tp0, tp3)<=1){
appendpt(l, tp0);
appendpt(l, tp1);
appendpt(l, tp2);
}
else{
/*
* if scale factor is getting too big for comfort,
* rescale now & concede the rounding error
*/
if(scale>(1<<12)){
p0=tp0;
p1=tp1;
p2=tp2;
p3=tp3;
scale=1;
}
p01=addpt(p0, p1);
p12=addpt(p1, p2);
p23=addpt(p2, p3);
p012=addpt(p01, p12);
p123=addpt(p12, p23);
p0123=addpt(p012, p123);
bpts1(l, mulpt(p0, 8), mulpt(p01, 4), mulpt(p012, 2), p0123, scale*8);
bpts1(l, p0123, mulpt(p123, 2), mulpt(p23, 4), mulpt(p3, 8), scale*8);
}
}
static void
bpts(Plist *l, Point p0, Point p1, Point p2, Point p3)
{
bpts1(l, p0, p1, p2, p3, 1);
}
static void
bezierpts(Plist *l, Point p0, Point p1, Point p2, Point p3)
{
bpts(l, p0, p1, p2, p3);
appendpt(l, p3);
}
static void
_bezsplinepts(Plist *l, Point *pt, int npt)
{
Point *p, *ep;
Point a, b, c, d;
int periodic;
if(npt<3)
return;
ep = &pt[npt-3];
periodic = eqpt(pt[0], ep[2]);
if(periodic){
a = divpt(addpt(ep[1], pt[0]), 2);
b = divpt(addpt(ep[1], mulpt(pt[0], 5)), 6);
c = divpt(addpt(mulpt(pt[0], 5), pt[1]), 6);
d = divpt(addpt(pt[0], pt[1]), 2);
bpts(l, a, b, c, d);
}
for(p=pt; p<=ep; p++){
if(p==pt && !periodic){
a = p[0];
b = divpt(addpt(p[0], mulpt(p[1], 2)), 3);
}
else{
a = divpt(addpt(p[0], p[1]), 2);
b = divpt(addpt(p[0], mulpt(p[1], 5)), 6);
}
if(p==ep && !periodic){
c = divpt(addpt(mulpt(p[1], 2), p[2]), 3);
d = p[2];
}
else{
c = divpt(addpt(mulpt(p[1], 5), p[2]), 6);
d = divpt(addpt(p[1], p[2]), 2);
}
bpts(l, a, b, c, d);
}
appendpt(l, d);
}
int
bezsplinepts(Point *pt, int npt, Point **pp)
{
Plist l;
l.np = 0;
l.p = nil;
_bezsplinepts(&l, pt, npt);
*pp = l.p;
return l.np;
}
int
bezier(Image *dst, Point p0, Point p1, Point p2, Point p3, int end0, int end1, int radius, Image *src, Point sp)
{
return bezierop(dst, p0, p1, p2, p3, end0, end1, radius, src, sp, SoverD);
}
int
bezierop(Image *dst, Point p0, Point p1, Point p2, Point p3, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
{
Plist l;
l.np = 0;
bezierpts(&l, p0, p1, p2, p3);
if(l.np == -1)
return 0;
if(l.np != 0){
polyop(dst, l.p, l.np, end0, end1, radius, src, addpt(subpt(sp, p0), l.p[0]), op);
free(l.p);
}
return 1;
}
int
bezspline(Image *dst, Point *pt, int npt, int end0, int end1, int radius, Image *src, Point sp)
{
return bezsplineop(dst, pt, npt, end0, end1, radius, src, sp, SoverD);
}
int
bezsplineop(Image *dst, Point *pt, int npt, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
{
Plist l;
l.np = 0;
_bezsplinepts(&l, pt, npt);
if(l.np==-1)
return 0;
if(l.np != 0){
polyop(dst, l.p, l.np, end0, end1, radius, src, addpt(subpt(sp, pt[0]), l.p[0]), op);
free(l.p);
}
return 1;
}
int
fillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3, int w, Image *src, Point sp)
{
return fillbezierop(dst, p0, p1, p2, p3, w, src, sp, SoverD);
}
int
fillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3, int w, Image *src, Point sp, Drawop op)
{
Plist l;
l.np = 0;
bezierpts(&l, p0, p1, p2, p3);
if(l.np == -1)
return 0;
if(l.np != 0){
fillpolyop(dst, l.p, l.np, w, src, addpt(subpt(sp, p0), l.p[0]), op);
free(l.p);
}
return 1;
}
int
fillbezspline(Image *dst, Point *pt, int npt, int w, Image *src, Point sp)
{
return fillbezsplineop(dst, pt, npt, w, src, sp, SoverD);
}
int
fillbezsplineop(Image *dst, Point *pt, int npt, int w, Image *src, Point sp, Drawop op)
{
Plist l;
l.np = 0;
_bezsplinepts(&l, pt, npt);
if(l.np == -1)
return 0;
if(l.np > 0){
fillpolyop(dst, l.p, l.np, w, src, addpt(subpt(sp, pt[0]), l.p[0]), op);
free(l.p);
}
return 1;
}

21
src/libdraw/border.c Normal file
View file

@ -0,0 +1,21 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
void
border(Image *im, Rectangle r, int i, Image *color, Point sp)
{
if(i < 0){
r = insetrect(r, i);
sp = addpt(sp, Pt(i,i));
i = -i;
}
draw(im, Rect(r.min.x, r.min.y, r.max.x, r.min.y+i),
color, nil, sp);
draw(im, Rect(r.min.x, r.max.y-i, r.max.x, r.max.y),
color, nil, Pt(sp.x, sp.y+Dy(r)-i));
draw(im, Rect(r.min.x, r.min.y+i, r.min.x+i, r.max.y-i),
color, nil, Pt(sp.x, sp.y+i));
draw(im, Rect(r.max.x-i, r.min.y+i, r.max.x, r.max.y-i),
color, nil, Pt(sp.x+Dx(r)-i, sp.y+i));
}

49
src/libdraw/cloadimage.c Normal file
View file

@ -0,0 +1,49 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
int
cloadimage(Image *i, Rectangle r, uchar *data, int ndata)
{
int m, nb, miny, maxy, ncblock;
uchar *a;
if(!rectinrect(r, i->r)){
werrstr("cloadimage: bad rectangle");
return -1;
}
miny = r.min.y;
m = 0;
ncblock = _compblocksize(r, i->depth);
while(miny != r.max.y){
maxy = atoi((char*)data+0*12);
nb = atoi((char*)data+1*12);
if(maxy<=miny || r.max.y<maxy){
werrstr("creadimage: bad maxy %d", maxy);
return -1;
}
data += 2*12;
ndata -= 2*12;
m += 2*12;
if(nb<=0 || ncblock<nb || nb>ndata){
werrstr("creadimage: bad count %d", nb);
return -1;
}
a = bufimage(i->display, 21+nb);
if(a == nil)
return -1;
a[0] = 'Y';
BPLONG(a+1, i->id);
BPLONG(a+5, r.min.x);
BPLONG(a+9, miny);
BPLONG(a+13, r.max.x);
BPLONG(a+17, maxy);
memmove(a+21, data, nb);
miny = maxy;
data += nb;
ndata += nb;
m += nb;
}
return m;
}

38
src/libdraw/computil.c Normal file
View file

@ -0,0 +1,38 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/*
* compressed data are seuences of byte codes.
* if the first byte b has the 0x80 bit set, the next (b^0x80)+1 bytes
* are data. otherwise, it's two bytes specifying a previous string to repeat.
*/
void
_twiddlecompressed(uchar *buf, int n)
{
uchar *ebuf;
int j, k, c;
ebuf = buf+n;
while(buf < ebuf){
c = *buf++;
if(c >= 128){
k = c-128+1;
for(j=0; j<k; j++, buf++)
*buf ^= 0xFF;
}else
buf++;
}
}
int
_compblocksize(Rectangle r, int depth)
{
int bpl;
bpl = bytesperline(r, depth);
bpl = 2*bpl; /* add plenty extra for blocking, etc. */
if(bpl < NCBLOCK)
return NCBLOCK;
return bpl;
}

16
src/libdraw/debug.c Normal file
View file

@ -0,0 +1,16 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
void
drawsetdebug(int v)
{
uchar *a;
a = bufimage(display, 1+1);
if(a == 0){
fprint(2, "drawsetdebug: %r\n");
return;
}
a[0] = 'D';
a[1] = v;
}

402
src/libdraw/defont.c Normal file
View file

@ -0,0 +1,402 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/*
* lucm/latin1.9, in uncompressed form
*/
uchar
defontdata[] =
{
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x32,0x33,0x30,0x34,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x35,0x20,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x30,0x06,0x06,0x03,0x42,0x40,0x00,0x00,0x00,0x18,0x03,0x03,
0x02,0x43,0x00,0x60,0x60,0x48,0x00,0x0d,0x0c,0x01,0x81,0x80,0xd0,0x90,0x00,0x00,
0x18,0x01,0x81,0x81,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x7f,0x9c,0x1c,
0x0e,0x07,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x70,
0x38,0x1c,0x0e,0x04,0x81,0xc1,0xc0,0x70,0x00,0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x80,0xc0,0x63,0xe3,
0xf1,0xf8,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x7f,0xff,0xff,0x1f,0x8f,
0xc7,0xe3,0xf1,0xfb,0x7e,0x3e,0x3f,0x8f,0xff,0xe3,0xe3,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0c,0x18,0x09,0x05,0x82,0x40,0xc0,0x00,0x00,0x06,0x0c,0x04,
0x82,0x40,0xc1,0x80,0x90,0x48,0x00,0x16,0x03,0x06,0x02,0x41,0x60,0x90,0x00,0x00,
0x06,0x06,0x02,0x41,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x7f,0xa0,0x10,
0x08,0x04,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x48,
0x24,0x12,0x09,0x06,0x82,0x01,0x00,0x90,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x04,0x80,0x00,0x40,0x00,0x00,0x38,0x06,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x07,0xc6,0x01,0xf0,0x00,0x00,0x0c,0x00,0x18,0x00,0x00,0x30,0x00,0x3c,
0x00,0x60,0x06,0x01,0x8c,0x07,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0xc3,0xc0,0x01,0x54,0x9c,0xc0,0x5f,0xef,
0xf7,0xfb,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0x7f,0xff,0xff,0x6f,0xb7,
0xdb,0xed,0xf6,0xf9,0x7d,0xfe,0xff,0x6f,0xff,0xdf,0xef,0xff,0xff,0xff,0xff,0xff,
0xff,0x00,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x30,0x06,0x06,0x06,0x82,0x80,0xc0,0x00,
0x00,0x18,0x03,0x03,0x02,0x41,0x80,0x30,0x30,0x24,0x76,0x0d,0x0c,0x00,0xc0,0xc0,
0xd0,0x50,0x00,0x00,0x18,0x01,0x81,0x81,0x40,0x30,0x00,0x28,0x0f,0x7f,0xbc,0x1c,
0x0e,0x07,0x03,0xc0,0x10,0x70,0x24,0x10,0x09,0x07,0x03,0x80,0xe0,0x70,0x90,0x48,
0x24,0x12,0x09,0x05,0x81,0x81,0xc0,0x80,0x70,0x18,0x1c,0x07,0x01,0xc1,0xc0,0x90,
0x00,0x0c,0x04,0x84,0x83,0xe1,0xc0,0xe0,0x38,0x0c,0x0c,0x02,0x00,0x00,0x00,0x00,
0x00,0x06,0x1c,0x06,0x0f,0x87,0xc0,0x63,0xf8,0x78,0xfe,0x3e,0x0e,0x00,0x00,0x00,
0x00,0x00,0x00,0x7c,0x1c,0x0c,0x1f,0x03,0xc7,0xc3,0xf1,0xf8,0x3c,0x63,0x3f,0x0f,
0x8c,0x66,0x06,0x19,0x84,0x78,0x7e,0x1e,0x1f,0x07,0xcf,0xf3,0x1b,0x0d,0x86,0x63,
0x61,0x9f,0xc6,0x06,0x00,0x30,0x00,0x00,0x10,0x00,0x18,0x00,0x00,0x30,0x00,0x60,
0x00,0x60,0x06,0x01,0x8c,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xc0,0x60,0x00,0xaa,0xb6,0xc0,0x43,0xe3,
0xf1,0xf8,0xfc,0x3f,0xef,0x8f,0xdb,0xef,0xf6,0xf8,0xfb,0xff,0x1f,0x8f,0x6f,0xb7,
0xdb,0xed,0xf6,0xfa,0x7e,0x7e,0x3f,0x7f,0x8f,0xe7,0xe3,0xf8,0xfe,0x3e,0x3f,0x6f,
0x00,0x00,0x01,0x01,0xc8,0x0b,0x0c,0x30,0x7c,0x14,0x0f,0x0f,0x00,0x00,0x00,0x00,
0x78,0x00,0x1c,0x00,0x0f,0x07,0x81,0x80,0x00,0x7c,0x00,0x00,0x1c,0x0f,0x80,0x04,
0x42,0x23,0x90,0x00,0x18,0x0c,0x06,0x03,0x01,0x80,0xc0,0x3c,0x3c,0x3f,0x1f,0x8f,
0xc7,0xe7,0xe3,0xf1,0xf8,0xfc,0x7c,0x30,0x8f,0x07,0x83,0xc1,0xe0,0xf0,0x00,0x3d,
0x31,0x98,0xcc,0x66,0x36,0x19,0x80,0xcc,0x0c,0x18,0x09,0x0b,0x02,0x81,0x20,0x00,
0x00,0x06,0x0c,0x04,0x82,0x40,0x60,0xc0,0x48,0x24,0x18,0x16,0x03,0x03,0x01,0x21,
0x60,0x50,0x00,0x00,0x06,0x06,0x02,0x41,0x40,0xc1,0x80,0x28,0x87,0x7f,0x84,0x10,
0x08,0x04,0x02,0x40,0x38,0x48,0x24,0x10,0x09,0x04,0x04,0x81,0x00,0x80,0x90,0x48,
0x24,0x12,0x09,0x04,0x80,0x41,0x00,0x80,0x40,0x04,0x10,0x04,0x02,0x01,0x20,0x90,
0x00,0x0c,0x04,0x84,0x86,0x53,0x65,0xb0,0x08,0x18,0x06,0x0a,0x80,0x00,0x00,0x00,
0x00,0x0c,0x36,0x0e,0x19,0xcc,0xe0,0xe3,0xf8,0xcc,0xfe,0x63,0x1b,0x00,0x00,0x00,
0x00,0x00,0x00,0xc6,0x62,0x0c,0x19,0x86,0x66,0x63,0x01,0x80,0x66,0x63,0x0c,0x01,
0x8c,0xc6,0x06,0x19,0xc4,0xcc,0x63,0x33,0x19,0x8c,0x61,0x83,0x1b,0x0d,0x86,0x63,
0x61,0x80,0xc6,0x03,0x00,0x30,0x30,0x00,0x1c,0x00,0x18,0x00,0x00,0x30,0x00,0x60,
0x00,0x60,0x00,0x00,0x0c,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xc0,0x60,0x01,0x54,0x86,0xc0,0x7b,0xef,
0xf7,0xfb,0xfd,0xbf,0xc7,0xb7,0xdb,0xef,0xf6,0xfb,0xfb,0x7e,0xff,0x7f,0x6f,0xb7,
0xdb,0xed,0xf6,0xfb,0x7f,0xbe,0xff,0x7f,0xbf,0xfb,0xef,0xfb,0xfd,0xfe,0xdf,0x6f,
0xff,0x00,0x07,0x83,0x24,0x13,0x0c,0x30,0xc6,0x00,0x10,0x81,0x80,0x00,0x00,0x00,
0x84,0x00,0x22,0x00,0x01,0x80,0xc0,0x00,0x00,0xf4,0x00,0x00,0x2c,0x18,0xc0,0x0c,
0x46,0x20,0x90,0x00,0x18,0x0c,0x06,0x03,0x01,0x80,0xc0,0x70,0x66,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x66,0x38,0x99,0x8c,0xc6,0x63,0x31,0x98,0x00,0x66,
0x31,0x98,0xcc,0x66,0x36,0x19,0x80,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0xff,0x7f,0xb8,0x1c,
0x0e,0x07,0x02,0x40,0x7c,0x70,0x3c,0x10,0x09,0x07,0x04,0x00,0xc0,0x60,0xe0,0x70,
0x38,0x1c,0x0e,0x04,0x83,0x81,0xc0,0x70,0x70,0x38,0x1c,0x07,0x02,0xc1,0xc0,0x90,
0x00,0x0c,0x00,0x04,0x86,0x43,0x69,0xb0,0x30,0x18,0x06,0x07,0x01,0x00,0x00,0x00,
0x00,0x0c,0x63,0x16,0x00,0xc0,0x61,0x62,0x01,0x80,0x06,0x63,0x31,0x80,0x00,0x00,
0x60,0x00,0xc0,0x06,0x43,0x16,0x19,0x8c,0x06,0x33,0x01,0x80,0xc0,0x63,0x0c,0x01,
0x8c,0x86,0x07,0x39,0xc5,0x86,0x63,0x61,0x99,0x8c,0x01,0x83,0x1b,0x0d,0xb6,0x63,
0x31,0x01,0x86,0x03,0x00,0x30,0x30,0x00,0x1c,0x3e,0x1b,0x03,0xc1,0xf0,0xf0,0x60,
0x3e,0x6e,0x3e,0x0f,0x8c,0x60,0xc5,0xb1,0xb8,0x38,0x6c,0x0f,0x8c,0xc7,0xc1,0x83,
0x19,0x8d,0x82,0x63,0x31,0x9f,0xc1,0x80,0xc0,0xc0,0x00,0xaa,0x86,0xc0,0x47,0xe3,
0xf1,0xf8,0xfd,0xbf,0x83,0x8f,0xc3,0xef,0xf6,0xf8,0xfc,0xff,0x3f,0x9f,0x1f,0x8f,
0xc7,0xe3,0xf1,0xfb,0x7c,0x7e,0x3f,0x8f,0x8f,0xc7,0xe3,0xf8,0xfd,0x3e,0x3f,0x6f,
0x00,0x0c,0x0d,0x43,0x03,0xe1,0x88,0x30,0xc0,0x00,0x27,0x41,0x80,0x00,0x00,0x01,
0x72,0x00,0x22,0x04,0x01,0x80,0xc0,0x03,0x18,0xf4,0x00,0x00,0x0c,0x18,0xc0,0x04,
0x82,0x43,0x20,0x18,0x2c,0x16,0x0b,0x05,0x82,0xc1,0x60,0xb0,0xc0,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x38,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x00,0xc7,
0x31,0x98,0xcc,0x66,0x33,0x11,0xf8,0xc8,0x7c,0x3e,0x1f,0x0f,0x87,0xc3,0xe1,0xd8,
0x3c,0x1e,0x0f,0x07,0x83,0xc7,0xc3,0xe1,0xf0,0xf8,0x06,0x37,0x07,0x03,0x81,0xc0,
0xe0,0x70,0x10,0x1d,0x31,0x98,0xcc,0x66,0x33,0x19,0xb0,0xc6,0x8f,0x7f,0x87,0x03,
0x81,0x80,0x90,0x30,0x6c,0x48,0x24,0x10,0x06,0x04,0x04,0x80,0x20,0x10,0x10,0x0e,
0x07,0x03,0x81,0xc0,0x60,0x88,0x38,0x0c,0x40,0x09,0x03,0x84,0x02,0x41,0x40,0x90,
0x00,0x0c,0x00,0x1f,0xe7,0x41,0xd1,0xa0,0x00,0x30,0x03,0x0a,0x81,0x00,0x00,0x00,
0x00,0x18,0x63,0x06,0x00,0xc0,0xc2,0x62,0x01,0xb0,0x0c,0x72,0x31,0x86,0x03,0x00,
0xc0,0x00,0x60,0x06,0x8f,0x16,0x19,0x0c,0x06,0x33,0x01,0x80,0xc0,0x63,0x0c,0x01,
0x8d,0x06,0x07,0x39,0x65,0x86,0x63,0x61,0x99,0x0e,0x01,0x83,0x19,0x89,0xb6,0x32,
0x33,0x03,0x06,0x01,0x80,0x30,0x78,0x00,0x00,0x03,0x1d,0x86,0x23,0x31,0x99,0xfc,
0x66,0x77,0x06,0x01,0x8c,0x40,0xc6,0xd9,0xdc,0x6c,0x76,0x19,0x8d,0xcc,0x27,0xf3,
0x19,0x8d,0x82,0x63,0x31,0x80,0xc0,0x80,0xc0,0x80,0x01,0x54,0x8c,0xc0,0x78,0xfc,
0x7e,0x7f,0x6f,0xcf,0x93,0xb7,0xdb,0xef,0xf9,0xfb,0xff,0xff,0xdf,0xef,0xef,0xf1,
0xf8,0xfc,0x7e,0x3f,0x9f,0x77,0xc7,0xf3,0xbf,0xf6,0xfc,0x7b,0xfd,0xbe,0xbf,0x6f,
0xff,0x0c,0x19,0x03,0x03,0x61,0x98,0x30,0x78,0x00,0x28,0x4f,0x83,0x30,0x00,0x01,
0x4a,0x00,0x1c,0x04,0x03,0x03,0x80,0x03,0x18,0xf4,0x00,0x00,0x0c,0x18,0xd9,0x84,
0x82,0x40,0xa0,0x18,0x2c,0x16,0x0b,0x05,0x82,0xc1,0x60,0xb0,0xc0,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x2c,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x64,0xcb,
0x31,0x98,0xcc,0x66,0x33,0x31,0x8c,0xd8,0x06,0x03,0x01,0x80,0xc0,0x60,0x30,0x6c,
0x62,0x33,0x19,0x8c,0xc6,0x60,0xc0,0x60,0x30,0x18,0x1e,0x3b,0x8d,0x86,0xc3,0x61,
0xb0,0xd8,0x10,0x36,0x31,0x98,0xcc,0x66,0x33,0x19,0xd8,0xc6,0x0f,0x7f,0x82,0x01,
0x02,0x40,0xd0,0x40,0x6c,0x70,0x24,0x1c,0x06,0x04,0x03,0x01,0xc0,0xe0,0x10,0x12,
0x09,0x04,0x82,0x40,0x90,0x50,0x10,0x12,0x70,0x09,0x04,0x04,0x01,0xc1,0x20,0x60,
0x00,0x0c,0x00,0x04,0x83,0xc0,0x20,0xcc,0x00,0x30,0x03,0x02,0x01,0x00,0x00,0x00,
0x00,0x18,0x63,0x06,0x01,0x83,0x84,0x63,0xf1,0xd8,0x18,0x3c,0x31,0x86,0x03,0x01,
0x83,0xf8,0x30,0x1c,0x9b,0x33,0x1e,0x0c,0x06,0x33,0xe1,0x80,0xc0,0x7f,0x0c,0x01,
0x8f,0x06,0x07,0x79,0x65,0x86,0x66,0x61,0x9e,0x07,0x81,0x83,0x19,0x89,0xb6,0x1c,
0x1a,0x03,0x06,0x01,0x80,0x30,0x48,0x00,0x00,0x03,0x18,0xcc,0x06,0x33,0x18,0x60,
0xc6,0x63,0x06,0x01,0x8c,0x80,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8e,0x4c,0x01,0x83,
0x19,0x8d,0x92,0x32,0x31,0x81,0x87,0x00,0xc0,0x70,0xe4,0xaa,0x98,0xc0,0x7d,0xfe,
0xfd,0xbf,0x2f,0xbf,0x93,0x8f,0xdb,0xe3,0xf9,0xfb,0xff,0x1e,0x3f,0x1f,0xef,0xed,
0xf6,0xfb,0x7d,0xbf,0x6f,0xaf,0xef,0xed,0x8f,0xf6,0xfb,0xfb,0xfe,0x3e,0xdf,0x9f,
0x00,0x00,0x19,0x0f,0xc6,0x30,0xd0,0x00,0xcc,0x00,0x28,0x59,0x86,0x67,0xf0,0x01,
0x72,0x00,0x00,0x3f,0x86,0x00,0xc0,0x03,0x18,0xf4,0x00,0x00,0x0c,0x18,0xcc,0xc5,
0x32,0x83,0x4c,0x00,0x66,0x33,0x19,0x8c,0xc6,0x63,0x31,0xbc,0xc0,0x3e,0x1f,0x0f,
0x87,0xc1,0x80,0xc0,0x60,0x30,0xfb,0x2c,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x38,0xcb,
0x31,0x98,0xcc,0x66,0x31,0xa1,0x8c,0xcc,0x06,0x03,0x01,0x80,0xc0,0x60,0x30,0x6c,
0xc0,0x63,0x31,0x98,0xcc,0x60,0xc0,0x60,0x30,0x18,0x37,0x31,0x98,0xcc,0x66,0x33,
0x19,0x8c,0x00,0x67,0x31,0x98,0xcc,0x66,0x33,0x19,0x8c,0xc6,0x1f,0x7f,0x82,0x01,
0x02,0x40,0xb0,0x40,0x6c,0x07,0x03,0x83,0x80,0xe0,0xe0,0x00,0x18,0x0e,0x10,0x10,
0x08,0x04,0x02,0x00,0xf0,0x20,0x10,0x1e,0x08,0x89,0x03,0x00,0xe0,0x38,0x1c,0x0e,
0x00,0x0c,0x00,0x04,0x81,0xe0,0x41,0x6c,0x00,0x30,0x03,0x00,0x0f,0xe0,0x03,0xf8,
0x00,0x30,0x63,0x06,0x03,0x00,0xc7,0xf0,0x39,0x8c,0x30,0x3e,0x1b,0x80,0x00,0x03,
0x00,0x00,0x18,0x30,0x9b,0x23,0x19,0x0c,0x06,0x33,0x01,0xf8,0xc6,0x63,0x0c,0x01,
0x8d,0x86,0x05,0xd9,0x35,0x86,0x7c,0x61,0x9b,0x01,0xc1,0x83,0x19,0x99,0xb4,0x1c,
0x0c,0x06,0x06,0x00,0xc0,0x30,0xcc,0x00,0x00,0x3f,0x18,0xcc,0x06,0x33,0xf8,0x60,
0xc6,0x63,0x06,0x01,0x8f,0x00,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8c,0x0f,0x81,0x83,
0x18,0xd9,0xba,0x1c,0x1b,0x03,0x00,0x80,0xc0,0x81,0x75,0x54,0x98,0xc0,0x7d,0xfe,
0xfd,0xbf,0x4f,0xbf,0x93,0xf8,0xfc,0x7c,0x7f,0x1f,0x1f,0x6f,0xe7,0xf1,0xef,0xef,
0xf7,0xfb,0xfd,0xff,0x0f,0xdf,0xef,0xe1,0xf7,0x76,0xfc,0xff,0x1f,0xc7,0xe3,0xf1,
0xff,0x08,0x19,0x03,0x06,0x31,0xf8,0x00,0xc6,0x00,0x28,0x5b,0x8c,0xc0,0x11,0xf1,
0x4a,0x00,0x00,0x04,0x0c,0x00,0xc0,0x03,0x18,0x74,0x38,0x00,0x0c,0x18,0xc6,0x65,
0x52,0xb8,0x54,0x18,0x46,0x23,0x11,0x88,0xc4,0x62,0x31,0x30,0xc0,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x26,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x10,0xd3,
0x31,0x98,0xcc,0x66,0x30,0xc1,0x8c,0xc6,0x7e,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xfc,
0xc0,0x7f,0x3f,0x9f,0xcf,0xe0,0xc0,0x60,0x30,0x18,0x63,0x31,0x98,0xcc,0x66,0x33,
0x19,0x8c,0xfe,0x6b,0x31,0x98,0xcc,0x66,0x31,0xb1,0x8c,0x6c,0x0e,0x7f,0x82,0x01,
0x01,0x80,0x90,0x30,0xc6,0x08,0x01,0x02,0x00,0x40,0x80,0xe0,0x24,0x04,0x1c,0x10,
0x08,0x04,0x02,0x00,0x90,0x20,0x10,0x12,0x0d,0x86,0x00,0x81,0x00,0x40,0x20,0x10,
0x00,0x04,0x00,0x1f,0xe1,0x70,0xbb,0x28,0x00,0x30,0x03,0x00,0x01,0x00,0x00,0x00,
0x00,0x30,0x63,0x06,0x06,0x00,0x67,0xf0,0x19,0x8c,0x30,0x67,0x0d,0x80,0x00,0x01,
0x83,0xf8,0x30,0x30,0x9b,0x7f,0x19,0x8c,0x06,0x33,0x01,0x80,0xc6,0x63,0x0c,0x01,
0x8c,0xc6,0x05,0xd9,0x35,0x86,0x60,0x61,0x99,0x80,0xe1,0x83,0x18,0xd0,0xdc,0x26,
0x0c,0x0c,0x06,0x00,0xc0,0x30,0x84,0x00,0x00,0x63,0x18,0xcc,0x06,0x33,0x00,0x60,
0xc6,0x63,0x06,0x01,0x8d,0x80,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8c,0x03,0xe1,0x83,
0x18,0xd9,0xba,0x1c,0x1b,0x06,0x01,0x80,0xc0,0xc1,0x38,0xaa,0x80,0xc0,0x7d,0xfe,
0xfe,0x7f,0x6f,0xcf,0x39,0xf7,0xfe,0xfd,0xff,0xbf,0x7f,0x0f,0xdb,0xfb,0xe3,0xef,
0xf7,0xfb,0xfd,0xff,0x6f,0xdf,0xef,0xed,0xf2,0x79,0xff,0x7e,0xff,0xbf,0xdf,0xef,
0x00,0x0c,0x19,0x03,0x03,0x60,0x60,0x30,0x66,0x00,0x28,0x4d,0xc6,0x60,0x10,0x00,
0x84,0x00,0x00,0x04,0x0f,0x87,0x80,0x03,0x18,0x14,0x38,0x00,0x3f,0x0f,0x8c,0xc2,
0x90,0x84,0xa4,0x18,0xfe,0x7f,0x3f,0x9f,0xcf,0xe7,0xf1,0xf0,0xc0,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x26,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x38,0xd3,
0x31,0x98,0xcc,0x66,0x30,0xc1,0x98,0xc6,0xc6,0x63,0x31,0x98,0xcc,0x66,0x33,0x60,
0xc0,0x60,0x30,0x18,0x0c,0x00,0xc0,0x60,0x30,0x18,0x63,0x31,0x98,0xcc,0x66,0x33,
0x19,0x8c,0x00,0x6b,0x31,0x98,0xcc,0x66,0x31,0xb1,0x8c,0x6c,0x1c,0x7f,0x81,0x20,
0x90,0x38,0x18,0x0b,0x83,0x06,0x01,0x03,0x80,0x40,0xe0,0x90,0x24,0x04,0x03,0x8e,
0x86,0xc3,0x61,0x90,0x24,0x12,0x0e,0x04,0x8a,0x81,0xc7,0x70,0xc0,0x30,0x18,0x0c,
0x00,0x00,0x00,0x04,0x81,0x31,0x6f,0x30,0x00,0x18,0x06,0x00,0x01,0x00,0x00,0x00,
0x00,0x60,0x63,0x06,0x0c,0x00,0x60,0x60,0x19,0x8c,0x60,0x63,0x01,0x80,0x00,0x00,
0xc0,0x00,0x60,0x00,0x4d,0xe1,0x99,0x8c,0x06,0x33,0x01,0x80,0xc6,0x63,0x0c,0x01,
0x8c,0xc6,0x04,0x99,0x1d,0x86,0x60,0x61,0x99,0x80,0x61,0x83,0x18,0xd0,0xdc,0x63,
0x0c,0x0c,0x06,0x00,0x60,0x30,0x84,0x00,0x00,0x63,0x18,0xcc,0x06,0x33,0x00,0x60,
0x6e,0x63,0x06,0x01,0x8c,0xc0,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8c,0x00,0x61,0x83,
0x18,0xd0,0xcc,0x26,0x0e,0x0c,0x03,0x00,0xc0,0x60,0x01,0x54,0x98,0xc0,0x7e,0xdf,
0x6f,0xc7,0xe7,0xf4,0x7c,0xf9,0xfe,0xfc,0x7f,0xbf,0x1f,0x5f,0xdb,0xfb,0xfc,0x71,
0x79,0x3c,0x9e,0x6f,0xdb,0xed,0xf1,0xfb,0x75,0x7e,0x38,0x8f,0x3f,0xcf,0xe7,0xf3,
0xff,0x0c,0x0d,0x03,0x03,0xe1,0xf8,0x30,0x3c,0x00,0x27,0x40,0x03,0x30,0x00,0x00,
0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x14,0x00,0x00,0x00,0x00,0x19,0x82,
0xf8,0x98,0xbe,0x70,0xc3,0x61,0xb0,0xd8,0x6c,0x36,0x1b,0x30,0xc0,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x23,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x4c,0xe3,
0x31,0x98,0xcc,0x66,0x30,0xc1,0xf0,0xc6,0xc6,0x63,0x31,0x98,0xcc,0x66,0x33,0x60,
0xc0,0x60,0x30,0x18,0x0c,0x00,0xc0,0x60,0x30,0x18,0x63,0x31,0x98,0xcc,0x66,0x33,
0x19,0x8c,0x10,0x73,0x31,0x98,0xcc,0x66,0x30,0xe1,0x8c,0x38,0x1c,0x7f,0x80,0xa0,
0x50,0x10,0x24,0x0d,0xff,0x01,0x01,0x02,0x00,0x40,0x80,0xf0,0x24,0x04,0x02,0x01,
0x81,0x20,0x10,0x30,0x28,0x1a,0x09,0x06,0x8a,0x81,0x20,0x90,0x20,0x08,0x04,0x02,
0x00,0x0c,0x00,0x04,0x85,0x32,0x6f,0xb8,0x00,0x18,0x06,0x00,0x01,0x01,0xc0,0x00,
0x70,0x60,0x36,0x06,0x1f,0xcc,0xe0,0x63,0x30,0xd8,0x60,0x63,0x33,0x06,0x03,0x00,
0x60,0x00,0xc0,0x30,0x60,0x61,0x99,0x86,0x66,0x63,0x01,0x80,0x66,0x63,0x0c,0x03,
0x0c,0x66,0x04,0x19,0x1c,0xcc,0x60,0x33,0x18,0xcc,0x61,0x81,0xb0,0x60,0xcc,0x63,
0x0c,0x18,0x06,0x00,0x60,0x30,0x00,0x00,0x00,0x67,0x19,0x86,0x23,0x71,0x88,0x60,
0x36,0x63,0x06,0x01,0x8c,0x60,0xc6,0xd9,0x8c,0x6c,0x66,0x1b,0x8c,0x08,0x61,0x83,
0xb8,0x70,0xcc,0x63,0x0c,0x18,0x03,0x00,0xc0,0x60,0x00,0xaa,0x98,0xc0,0x7f,0x5f,
0xaf,0xef,0xdb,0xf2,0x00,0xfe,0xfe,0xfd,0xff,0xbf,0x7f,0x6f,0xdb,0xfb,0xfd,0xfe,
0x7e,0xdf,0xef,0xcf,0xd7,0xe5,0xf6,0xf9,0x75,0x7e,0xdf,0x6f,0xdf,0xf7,0xfb,0xfd,
0x00,0x0c,0x07,0xc6,0x04,0x10,0x60,0x30,0x06,0x00,0x10,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3f,0x80,0x00,0x00,0x03,0xb8,0x14,0x00,0x00,0x00,0x00,0x00,0x04,
0x11,0x21,0x04,0xc0,0xc3,0x61,0xb0,0xd8,0x6c,0x36,0x1b,0x30,0x66,0x30,0x18,0x0c,
0x06,0x01,0x80,0xc0,0x60,0x30,0x66,0x23,0x99,0x8c,0xc6,0x63,0x31,0x98,0x00,0x66,
0x1b,0x0d,0x86,0xc3,0x60,0xc1,0x80,0xc6,0xce,0x67,0x33,0x99,0xcc,0xe6,0x73,0x74,
0x62,0x31,0x18,0x8c,0x46,0x20,0xc0,0x60,0x30,0x18,0x36,0x31,0x8d,0x86,0xc3,0x61,
0xb0,0xd8,0x10,0x36,0x3b,0x9d,0xce,0xe7,0x70,0xc1,0x98,0x30,0x00,0x7f,0x80,0xc0,
0x60,0x10,0x24,0x0c,0x38,0x0e,0x01,0x02,0x00,0x40,0x80,0xa0,0x18,0x0e,0x03,0x00,
0x80,0x40,0x60,0x50,0x30,0x16,0x0e,0x05,0x88,0x81,0xc0,0x81,0xc0,0x70,0x38,0x1c,
0x00,0x0c,0x00,0x04,0x83,0xe0,0x39,0xcc,0x00,0x0c,0x0c,0x00,0x00,0x01,0xc0,0x00,
0x70,0xc0,0x1c,0x06,0x1f,0xc7,0xc0,0x61,0xe0,0x70,0x60,0x3e,0x1e,0x06,0x03,0x00,
0x00,0x00,0x00,0x30,0x1e,0x61,0x9f,0x03,0xc7,0xc3,0xf1,0x80,0x3e,0x63,0x3f,0x1e,
0x0c,0x67,0xe4,0x19,0x0c,0x78,0x60,0x1e,0x18,0xc7,0xc1,0x80,0xe0,0x60,0xcc,0x63,
0x0c,0x1f,0xc6,0x00,0x30,0x30,0x00,0x00,0x00,0x3b,0x9f,0x03,0xc1,0xb0,0xf0,0x60,
0x06,0x63,0x06,0x01,0x8c,0x70,0xc6,0xd9,0x8c,0x38,0x7c,0x0d,0x8c,0x07,0xc0,0xf1,
0xd8,0x60,0xcc,0x63,0x0c,0x1f,0xc3,0x00,0xc0,0x60,0x01,0x54,0x80,0xc0,0x7f,0x3f,
0x9f,0xef,0xdb,0xf3,0xc7,0xf1,0xfe,0xfd,0xff,0xbf,0x7f,0xff,0xe7,0xf1,0xfc,0xff,
0x7f,0xbf,0x9f,0xaf,0xcf,0xe9,0xf1,0xfa,0x77,0x7e,0x3f,0x7e,0x3f,0x8f,0xc7,0xe3,
0xff,0x0c,0x01,0x0f,0xe8,0x08,0x60,0x30,0xc6,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xd8,0x14,0x00,0x00,0x00,0x00,0x00,0x04,
0x11,0x3d,0x04,0xc0,0xc3,0x61,0xb0,0xd8,0x6c,0x36,0x1b,0x3c,0x3c,0x3f,0x1f,0x8f,
0xc7,0xe7,0xe3,0xf1,0xf8,0xfc,0x7c,0x21,0x8f,0x07,0x83,0xc1,0xe0,0xf0,0x00,0xbc,
0x0e,0x07,0x03,0x81,0xc0,0xc1,0x80,0xcc,0x77,0x3b,0x9d,0xce,0xe7,0x73,0xb9,0x98,
0x3c,0x1e,0x0f,0x07,0x83,0xc0,0xc0,0x60,0x30,0x18,0x1c,0x31,0x87,0x03,0x81,0xc0,
0xe0,0x70,0x00,0x5c,0x1d,0x8e,0xc7,0x63,0xb0,0xc1,0xf0,0x30,0x00,0x7f,0x81,0x40,
0xa0,0x10,0x28,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x02,0x00,
0x80,0x80,0x10,0xf8,0x28,0x12,0x09,0x04,0x80,0x01,0x20,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x06,0x18,0x00,0x00,0x00,0x40,0x00,
0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x07,0xc0,0x31,0xf0,0x01,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xcc,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x00,0x01,0xe0,0xc3,0xc0,0x00,0x00,0xff,0xc0,0x7e,0xbf,
0x5f,0xef,0xd7,0xf5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,
0x7f,0x7f,0xef,0x07,0xd7,0xed,0xf6,0xfb,0x7f,0xfe,0xdf,0x7f,0xff,0xff,0xff,0xff,
0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x30,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x80,0x60,0x00,0x7f,0x81,0x20,
0x90,0x10,0x1c,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,
0x81,0xe0,0x60,0x10,0x24,0x12,0x0e,0x04,0x80,0x01,0xc0,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x78,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0xdf,
0x6f,0xef,0xe3,0xf5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x7f,
0x7e,0x1f,0x9f,0xef,0xdb,0xed,0xf1,0xfb,0x7f,0xfe,0x3f,0x8f,0xff,0xff,0xff,0xff,
0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x80,0x60,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x32,0x35,0x36,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x31,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x33,0x20,
0x00,0x00,0x01,0x0c,0x00,0x09,0x09,0x00,0x01,0x0f,0x00,0x09,0x12,0x00,0x01,0x0f,
0x00,0x09,0x1b,0x00,0x01,0x0f,0x00,0x09,0x24,0x00,0x01,0x0f,0x00,0x09,0x2d,0x00,
0x01,0x0f,0x00,0x09,0x36,0x00,0x01,0x0f,0x00,0x09,0x3f,0x00,0x03,0x0d,0x00,0x09,
0x48,0x00,0x03,0x0d,0x00,0x09,0x51,0x00,0x03,0x0d,0x00,0x09,0x5a,0x00,0x03,0x0d,
0x00,0x09,0x63,0x00,0x03,0x0d,0x00,0x09,0x6c,0x00,0x03,0x0d,0x00,0x09,0x75,0x00,
0x03,0x0e,0x00,0x09,0x7e,0x00,0x03,0x0d,0x00,0x09,0x87,0x00,0x03,0x0d,0x00,0x09,
0x90,0x00,0x01,0x0f,0x00,0x09,0x99,0x00,0x01,0x0f,0x00,0x09,0xa2,0x00,0x01,0x0f,
0x00,0x09,0xab,0x00,0x01,0x0f,0x00,0x09,0xb4,0x00,0x01,0x0f,0x00,0x09,0xbd,0x00,
0x01,0x0f,0x00,0x09,0xc6,0x00,0x01,0x0f,0x00,0x09,0xcf,0x00,0x01,0x0f,0x00,0x09,
0xd8,0x00,0x01,0x0f,0x00,0x09,0xe1,0x00,0x03,0x0d,0x00,0x09,0xea,0x00,0x01,0x0f,
0x00,0x09,0xf3,0x00,0x01,0x0f,0x00,0x09,0xfc,0x00,0x03,0x0d,0x00,0x09,0x05,0x01,
0x03,0x0d,0x00,0x09,0x0e,0x01,0x03,0x0d,0x00,0x09,0x17,0x01,0x03,0x0d,0x00,0x09,
0x20,0x01,0x00,0x00,0x00,0x09,0x29,0x01,0x03,0x0d,0x00,0x09,0x32,0x01,0x02,0x05,
0x00,0x09,0x3b,0x01,0x03,0x0d,0x00,0x09,0x44,0x01,0x02,0x0e,0x00,0x09,0x4d,0x01,
0x03,0x0d,0x00,0x09,0x56,0x01,0x03,0x0d,0x00,0x09,0x5f,0x01,0x02,0x06,0x00,0x09,
0x68,0x01,0x02,0x0e,0x00,0x09,0x71,0x01,0x02,0x0e,0x00,0x09,0x7a,0x01,0x03,0x08,
0x00,0x09,0x83,0x01,0x05,0x0c,0x00,0x09,0x8c,0x01,0x0b,0x0f,0x00,0x09,0x95,0x01,
0x08,0x09,0x00,0x09,0x9e,0x01,0x0b,0x0d,0x00,0x09,0xa7,0x01,0x02,0x0e,0x00,0x09,
0xb0,0x01,0x03,0x0d,0x00,0x09,0xb9,0x01,0x03,0x0d,0x00,0x09,0xc2,0x01,0x03,0x0d,
0x00,0x09,0xcb,0x01,0x03,0x0d,0x00,0x09,0xd4,0x01,0x03,0x0d,0x00,0x09,0xdd,0x01,
0x03,0x0d,0x00,0x09,0xe6,0x01,0x03,0x0d,0x00,0x09,0xef,0x01,0x03,0x0d,0x00,0x09,
0xf8,0x01,0x03,0x0d,0x00,0x09,0x01,0x02,0x03,0x0d,0x00,0x09,0x0a,0x02,0x06,0x0d,
0x00,0x09,0x13,0x02,0x06,0x0f,0x00,0x09,0x1c,0x02,0x05,0x0c,0x00,0x09,0x25,0x02,
0x07,0x0a,0x00,0x09,0x2e,0x02,0x05,0x0c,0x00,0x09,0x37,0x02,0x03,0x0d,0x00,0x09,
0x40,0x02,0x03,0x0d,0x00,0x09,0x49,0x02,0x03,0x0d,0x00,0x09,0x52,0x02,0x03,0x0d,
0x00,0x09,0x5b,0x02,0x03,0x0d,0x00,0x09,0x64,0x02,0x03,0x0d,0x00,0x09,0x6d,0x02,
0x03,0x0d,0x00,0x09,0x76,0x02,0x03,0x0d,0x00,0x09,0x7f,0x02,0x03,0x0d,0x00,0x09,
0x88,0x02,0x03,0x0d,0x00,0x09,0x91,0x02,0x03,0x0d,0x00,0x09,0x9a,0x02,0x03,0x0d,
0x00,0x09,0xa3,0x02,0x03,0x0d,0x00,0x09,0xac,0x02,0x03,0x0d,0x00,0x09,0xb5,0x02,
0x03,0x0d,0x00,0x09,0xbe,0x02,0x03,0x0d,0x00,0x09,0xc7,0x02,0x03,0x0d,0x00,0x09,
0xd0,0x02,0x03,0x0d,0x00,0x09,0xd9,0x02,0x03,0x0f,0x00,0x09,0xe2,0x02,0x03,0x0d,
0x00,0x09,0xeb,0x02,0x03,0x0d,0x00,0x09,0xf4,0x02,0x03,0x0d,0x00,0x09,0xfd,0x02,
0x03,0x0d,0x00,0x09,0x06,0x03,0x03,0x0d,0x00,0x09,0x0f,0x03,0x03,0x0d,0x00,0x09,
0x18,0x03,0x03,0x0d,0x00,0x09,0x21,0x03,0x03,0x0d,0x00,0x09,0x2a,0x03,0x03,0x0d,
0x00,0x09,0x33,0x03,0x02,0x0e,0x00,0x09,0x3c,0x03,0x02,0x0e,0x00,0x09,0x45,0x03,
0x02,0x0e,0x00,0x09,0x4e,0x03,0x04,0x0b,0x00,0x09,0x57,0x03,0x0d,0x0e,0x00,0x09,
0x60,0x03,0x02,0x06,0x00,0x09,0x69,0x03,0x05,0x0d,0x00,0x09,0x72,0x03,0x02,0x0d,
0x00,0x09,0x7b,0x03,0x05,0x0d,0x00,0x09,0x84,0x03,0x02,0x0d,0x00,0x09,0x8d,0x03,
0x05,0x0d,0x00,0x09,0x96,0x03,0x02,0x0d,0x00,0x09,0x9f,0x03,0x05,0x0f,0x00,0x09,
0xa8,0x03,0x02,0x0d,0x00,0x09,0xb1,0x03,0x02,0x0d,0x00,0x09,0xba,0x03,0x02,0x0f,
0x00,0x09,0xc3,0x03,0x02,0x0d,0x00,0x09,0xcc,0x03,0x02,0x0d,0x00,0x09,0xd5,0x03,
0x05,0x0d,0x00,0x09,0xde,0x03,0x05,0x0d,0x00,0x09,0xe7,0x03,0x05,0x0d,0x00,0x09,
0xf0,0x03,0x05,0x0f,0x00,0x09,0xf9,0x03,0x05,0x0f,0x00,0x09,0x02,0x04,0x05,0x0d,
0x00,0x09,0x0b,0x04,0x05,0x0d,0x00,0x09,0x14,0x04,0x03,0x0d,0x00,0x09,0x1d,0x04,
0x05,0x0d,0x00,0x09,0x26,0x04,0x05,0x0d,0x00,0x09,0x2f,0x04,0x05,0x0d,0x00,0x09,
0x38,0x04,0x05,0x0d,0x00,0x09,0x41,0x04,0x05,0x0f,0x00,0x09,0x4a,0x04,0x05,0x0d,
0x00,0x09,0x53,0x04,0x02,0x0e,0x00,0x09,0x5c,0x04,0x02,0x0e,0x00,0x09,0x65,0x04,
0x02,0x0e,0x00,0x09,0x6e,0x04,0x07,0x0a,0x00,0x09,0x77,0x04,0x01,0x0d,0x00,0x09,
0x80,0x04,0x00,0x0e,0x00,0x09,0x89,0x04,0x00,0x0f,0x00,0x09,0x92,0x04,0x00,0x0f,
0x00,0x09,0x9b,0x04,0x00,0x0f,0x00,0x09,0xa4,0x04,0x00,0x0f,0x00,0x09,0xad,0x04,
0x00,0x0f,0x00,0x09,0xb6,0x04,0x00,0x0f,0x00,0x09,0xbf,0x04,0x00,0x0f,0x00,0x09,
0xc8,0x04,0x00,0x0f,0x00,0x09,0xd1,0x04,0x00,0x0f,0x00,0x09,0xda,0x04,0x00,0x0f,
0x00,0x09,0xe3,0x04,0x00,0x0f,0x00,0x09,0xec,0x04,0x00,0x0f,0x00,0x09,0xf5,0x04,
0x00,0x0f,0x00,0x09,0xfe,0x04,0x00,0x0f,0x00,0x09,0x07,0x05,0x00,0x0f,0x00,0x09,
0x10,0x05,0x00,0x0f,0x00,0x09,0x19,0x05,0x00,0x0f,0x00,0x09,0x22,0x05,0x00,0x0f,
0x00,0x09,0x2b,0x05,0x00,0x0f,0x00,0x09,0x34,0x05,0x00,0x0f,0x00,0x09,0x3d,0x05,
0x00,0x0f,0x00,0x09,0x46,0x05,0x00,0x0f,0x00,0x09,0x4f,0x05,0x00,0x0f,0x00,0x09,
0x58,0x05,0x00,0x0f,0x00,0x09,0x61,0x05,0x00,0x0f,0x00,0x09,0x6a,0x05,0x00,0x0f,
0x00,0x09,0x73,0x05,0x00,0x0f,0x00,0x09,0x7c,0x05,0x00,0x0f,0x00,0x09,0x85,0x05,
0x00,0x0f,0x00,0x09,0x8e,0x05,0x00,0x0f,0x00,0x09,0x97,0x05,0x00,0x0f,0x00,0x09,
0xa0,0x05,0x00,0x0d,0x00,0x09,0xa9,0x05,0x05,0x0f,0x00,0x09,0xb2,0x05,0x02,0x0e,
0x00,0x09,0xbb,0x05,0x03,0x0d,0x00,0x09,0xc4,0x05,0x03,0x0d,0x00,0x09,0xcd,0x05,
0x03,0x0d,0x00,0x09,0xd6,0x05,0x02,0x0e,0x00,0x09,0xdf,0x05,0x03,0x0e,0x00,0x09,
0xe8,0x05,0x02,0x04,0x00,0x09,0xf1,0x05,0x03,0x0d,0x00,0x09,0xfa,0x05,0x03,0x0a,
0x00,0x09,0x03,0x06,0x06,0x0b,0x00,0x09,0x0c,0x06,0x07,0x0a,0x00,0x09,0x15,0x06,
0x08,0x09,0x00,0x09,0x1e,0x06,0x03,0x0b,0x00,0x09,0x27,0x06,0x02,0x03,0x00,0x09,
0x30,0x06,0x03,0x07,0x00,0x09,0x39,0x06,0x05,0x0c,0x00,0x09,0x42,0x06,0x03,0x0a,
0x00,0x09,0x4b,0x06,0x03,0x0a,0x00,0x09,0x54,0x06,0x02,0x04,0x00,0x09,0x5d,0x06,
0x05,0x0f,0x00,0x09,0x66,0x06,0x03,0x0e,0x00,0x09,0x6f,0x06,0x08,0x0a,0x00,0x09,
0x78,0x06,0x0d,0x0f,0x00,0x09,0x81,0x06,0x03,0x0a,0x00,0x09,0x8a,0x06,0x03,0x0a,
0x00,0x09,0x93,0x06,0x06,0x0b,0x00,0x09,0x9c,0x06,0x03,0x0d,0x00,0x09,0xa5,0x06,
0x03,0x0d,0x00,0x09,0xae,0x06,0x03,0x0d,0x00,0x09,0xb7,0x06,0x05,0x0f,0x00,0x09,
0xc0,0x06,0x00,0x0d,0x00,0x09,0xc9,0x06,0x00,0x0d,0x00,0x09,0xd2,0x06,0x00,0x0d,
0x00,0x09,0xdb,0x06,0x00,0x0d,0x00,0x09,0xe4,0x06,0x00,0x0d,0x00,0x09,0xed,0x06,
0x01,0x0d,0x00,0x09,0xf6,0x06,0x03,0x0d,0x00,0x09,0xff,0x06,0x03,0x0f,0x00,0x09,
0x08,0x07,0x00,0x0d,0x00,0x09,0x11,0x07,0x00,0x0d,0x00,0x09,0x1a,0x07,0x00,0x0d,
0x00,0x09,0x23,0x07,0x00,0x0d,0x00,0x09,0x2c,0x07,0x00,0x0d,0x00,0x09,0x35,0x07,
0x00,0x0d,0x00,0x09,0x3e,0x07,0x00,0x0d,0x00,0x09,0x47,0x07,0x00,0x0d,0x00,0x09,
0x50,0x07,0x03,0x0d,0x00,0x09,0x59,0x07,0x00,0x0d,0x00,0x09,0x62,0x07,0x00,0x0d,
0x00,0x09,0x6b,0x07,0x00,0x0d,0x00,0x09,0x74,0x07,0x00,0x0d,0x00,0x09,0x7d,0x07,
0x00,0x0d,0x00,0x09,0x86,0x07,0x00,0x0d,0x00,0x09,0x8f,0x07,0x06,0x0b,0x00,0x09,
0x98,0x07,0x03,0x0d,0x00,0x09,0xa1,0x07,0x00,0x0d,0x00,0x09,0xaa,0x07,0x00,0x0d,
0x00,0x09,0xb3,0x07,0x00,0x0d,0x00,0x09,0xbc,0x07,0x00,0x0d,0x00,0x09,0xc5,0x07,
0x00,0x0d,0x00,0x09,0xce,0x07,0x03,0x0d,0x00,0x09,0xd7,0x07,0x02,0x0d,0x00,0x09,
0xe0,0x07,0x02,0x0d,0x00,0x09,0xe9,0x07,0x02,0x0d,0x00,0x09,0xf2,0x07,0x02,0x0d,
0x00,0x09,0xfb,0x07,0x02,0x0d,0x00,0x09,0x04,0x08,0x02,0x0d,0x00,0x09,0x0d,0x08,
0x02,0x0d,0x00,0x09,0x16,0x08,0x05,0x0d,0x00,0x09,0x1f,0x08,0x05,0x0f,0x00,0x09,
0x28,0x08,0x02,0x0d,0x00,0x09,0x31,0x08,0x02,0x0d,0x00,0x09,0x3a,0x08,0x02,0x0d,
0x00,0x09,0x43,0x08,0x02,0x0d,0x00,0x09,0x4c,0x08,0x02,0x0d,0x00,0x09,0x55,0x08,
0x02,0x0d,0x00,0x09,0x5e,0x08,0x02,0x0d,0x00,0x09,0x67,0x08,0x02,0x0d,0x00,0x09,
0x70,0x08,0x02,0x0d,0x00,0x09,0x79,0x08,0x02,0x0d,0x00,0x09,0x82,0x08,0x02,0x0d,
0x00,0x09,0x8b,0x08,0x02,0x0d,0x00,0x09,0x94,0x08,0x02,0x0d,0x00,0x09,0x9d,0x08,
0x02,0x0d,0x00,0x09,0xa6,0x08,0x02,0x0d,0x00,0x09,0xaf,0x08,0x05,0x0c,0x00,0x09,
0xb8,0x08,0x05,0x0d,0x00,0x09,0xc1,0x08,0x02,0x0d,0x00,0x09,0xca,0x08,0x02,0x0d,
0x00,0x09,0xd3,0x08,0x02,0x0d,0x00,0x09,0xdc,0x08,0x02,0x0d,0x00,0x09,0xe5,0x08,
0x02,0x0f,0x00,0x09,0xee,0x08,0x03,0x0f,0x00,0x09,0xf7,0x08,0x02,0x0f,0x00,0x09,
0x00,0x09,0x00,0x00,0x00,0x00,
};
int sizeofdefont = sizeof defontdata;
void
_unpackinfo(Fontchar *fc, uchar *p, int n)
{
int j;
for(j=0; j<=n; j++){
fc->x = p[0]|(p[1]<<8);
fc->top = p[2];
fc->bottom = p[3];
fc->left = p[4];
fc->width = p[5];
fc++;
p += 6;
}
}

69
src/libdraw/draw.c Normal file
View file

@ -0,0 +1,69 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
void
_setdrawop(Display *d, Drawop op)
{
uchar *a;
if(op != SoverD){
a = bufimage(d, 1+1);
if(a == 0)
return;
a[0] = 'O';
a[1] = op;
}
}
static void
draw1(Image *dst, Rectangle *r, Image *src, Point *p0, Image *mask, Point *p1, Drawop op)
{
uchar *a;
_setdrawop(dst->display, op);
a = bufimage(dst->display, 1+4+4+4+4*4+2*4+2*4);
if(a == 0)
return;
if(src == nil)
src = dst->display->black;
if(mask == nil)
mask = dst->display->opaque;
a[0] = 'd';
BPLONG(a+1, dst->id);
BPLONG(a+5, src->id);
BPLONG(a+9, mask->id);
BPLONG(a+13, r->min.x);
BPLONG(a+17, r->min.y);
BPLONG(a+21, r->max.x);
BPLONG(a+25, r->max.y);
BPLONG(a+29, p0->x);
BPLONG(a+33, p0->y);
BPLONG(a+37, p1->x);
BPLONG(a+41, p1->y);
}
void
draw(Image *dst, Rectangle r, Image *src, Image *mask, Point p1)
{
draw1(dst, &r, src, &p1, mask, &p1, SoverD);
}
void
drawop(Image *dst, Rectangle r, Image *src, Image *mask, Point p1, Drawop op)
{
draw1(dst, &r, src, &p1, mask, &p1, op);
}
void
gendraw(Image *dst, Rectangle r, Image *src, Point p0, Image *mask, Point p1)
{
draw1(dst, &r, src, &p0, mask, &p1, SoverD);
}
void
gendrawop(Image *dst, Rectangle r, Image *src, Point p0, Image *mask, Point p1, Drawop op)
{
draw1(dst, &r, src, &p0, mask, &p1, op);
}

23
src/libdraw/drawrepl.c Normal file
View file

@ -0,0 +1,23 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
int
drawreplxy(int min, int max, int x)
{
int sx;
sx = (x-min)%(max-min);
if(sx < 0)
sx += max-min;
return sx+min;
}
Point
drawrepl(Rectangle r, Point p)
{
p.x = drawreplxy(r.min.x, r.max.x, p.x);
p.y = drawreplxy(r.min.y, r.max.y, p.y);
return p;
}

116
src/libdraw/egetrect.c Normal file
View file

@ -0,0 +1,116 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <event.h>
#define W Borderwidth
static Image *tmp[4];
static Image *red;
static Cursor sweep={
{-7, -7},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
{0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
};
static
void
brects(Rectangle r, Rectangle rp[4])
{
if(Dx(r) < 2*W)
r.max.x = r.min.x+2*W;
if(Dy(r) < 2*W)
r.max.y = r.min.y+2*W;
rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W);
rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y);
rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W);
rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W);
}
Rectangle
egetrect(int but, Mouse *m)
{
Rectangle r, rc;
but = 1<<(but-1);
esetcursor(&sweep);
while(m->buttons)
*m = emouse();
while(!(m->buttons & but)){
*m = emouse();
if(m->buttons & (7^but))
goto Return;
}
r.min = m->xy;
r.max = m->xy;
do{
rc = canonrect(r);
edrawgetrect(rc, 1);
*m = emouse();
edrawgetrect(rc, 0);
r.max = m->xy;
}while(m->buttons == but);
Return:
esetcursor(0);
if(m->buttons & (7^but)){
rc.min.x = rc.max.x = 0;
rc.min.y = rc.max.y = 0;
while(m->buttons)
*m = emouse();
}
return rc;
}
static
void
freetmp(void)
{
freeimage(tmp[0]);
freeimage(tmp[1]);
freeimage(tmp[2]);
freeimage(tmp[3]);
freeimage(red);
tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil;
}
void
edrawgetrect(Rectangle rc, int up)
{
int i;
Rectangle r, rects[4];
if(up && tmp[0]!=nil)
if(Dx(tmp[0]->r)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
freetmp();
if(tmp[0] == 0){
r = Rect(0, 0, Dx(screen->r), W);
tmp[0] = allocimage(display, r, screen->chan, 0, -1);
tmp[1] = allocimage(display, r, screen->chan, 0, -1);
r = Rect(0, 0, W, Dy(screen->r));
tmp[2] = allocimage(display, r, screen->chan, 0, -1);
tmp[3] = allocimage(display, r, screen->chan, 0, -1);
red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0)
drawerror(display, "getrect: allocimage failed");
}
brects(rc, rects);
if(!up){
for(i=0; i<4; i++)
draw(screen, rects[i], tmp[i], nil, ZP);
return;
}
for(i=0; i<4; i++){
draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min);
draw(screen, rects[i], red, nil, ZP);
}
}

17
src/libdraw/freesubfont.c Normal file
View file

@ -0,0 +1,17 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
void
freesubfont(Subfont *f)
{
if(f == 0)
return;
f->ref--;
if(f->ref > 0)
return;
uninstallsubfont(f);
free(f->info); /* note: f->info must have been malloc'ed! */
freeimage(f->bits);
free(f);
}

60
src/libdraw/getdefont.c Normal file
View file

@ -0,0 +1,60 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
Subfont*
getdefont(Display *d)
{
char *hdr, *p;
int n;
Fontchar *fc;
Subfont *f;
int ld;
Rectangle r;
Image *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);
i = allocimage(d, r, drawld2chan[ld], 0, 0);
if(i == 0)
return 0;
p += 5*12;
n = loadimage(i, r, (uchar*)p, (defontdata+sizeofdefont)-(uchar*)p);
if(n < 0){
freeimage(i);
return 0;
}
hdr = p+n;
n = atoi(hdr);
p = hdr+3*12;
fc = malloc(sizeof(Fontchar)*(n+1));
if(fc == 0){
freeimage(i);
return 0;
}
_unpackinfo(fc, (uchar*)p, n);
f = allocsubfont("*default*", n, atoi(hdr+12), atoi(hdr+24), fc, i);
if(f == 0){
freeimage(i);
free(fc);
return 0;
}
return f;
}

133
src/libdraw/getrect.c Normal file
View file

@ -0,0 +1,133 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#define W Borderwidth
static Image *tmp[4];
static Image *red;
static Cursor sweep={
{-7, -7},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xE3, 0xF7, 0xE3, 0xF7,
0xE3, 0xE7, 0xE3, 0xF7, 0xE3, 0xFF, 0xE3, 0x7F,
0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,},
{0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02,
0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x41, 0xE2,
0x41, 0xC2, 0x41, 0xE2, 0x41, 0x72, 0x40, 0x38,
0x40, 0x1C, 0x40, 0x0E, 0x7F, 0xE6, 0x00, 0x00,}
};
static
void
brects(Rectangle r, Rectangle rp[4])
{
if(Dx(r) < 2*W)
r.max.x = r.min.x+2*W;
if(Dy(r) < 2*W)
r.max.y = r.min.y+2*W;
rp[0] = Rect(r.min.x, r.min.y, r.max.x, r.min.y+W);
rp[1] = Rect(r.min.x, r.max.y-W, r.max.x, r.max.y);
rp[2] = Rect(r.min.x, r.min.y+W, r.min.x+W, r.max.y-W);
rp[3] = Rect(r.max.x-W, r.min.y+W, r.max.x, r.max.y-W);
}
Rectangle
getrect(int but, Mousectl *mc)
{
Rectangle r, rc;
but = 1<<(but-1);
setcursor(mc, &sweep);
while(mc->m.buttons)
readmouse(mc);
while(!(mc->m.buttons & but)){
readmouse(mc);
if(mc->m.buttons & (7^but))
goto Return;
}
r.min = mc->m.xy;
r.max = mc->m.xy;
do{
rc = canonrect(r);
drawgetrect(rc, 1);
readmouse(mc);
drawgetrect(rc, 0);
r.max = mc->m.xy;
}while(mc->m.buttons == but);
Return:
setcursor(mc, nil);
if(mc->m.buttons & (7^but)){
rc.min.x = rc.max.x = 0;
rc.min.y = rc.max.y = 0;
while(mc->m.buttons)
readmouse(mc);
}
return rc;
}
static
void
freetmp(void)
{
freeimage(tmp[0]);
freeimage(tmp[1]);
freeimage(tmp[2]);
freeimage(tmp[3]);
freeimage(red);
tmp[0] = tmp[1] = tmp[2] = tmp[3] = red = nil;
}
static
int
max(int a, int b)
{
if(a > b)
return a;
return b;
}
void
drawgetrect(Rectangle rc, int up)
{
int i;
Rectangle r, rects[4];
/*
* BUG: if for some reason we have two of these going on at once
* when we must grow the tmp buffers, we lose data. Also if tmp
* is unallocated and we ask to restore the screen, it would be nice
* to complain, but we silently make a mess.
*/
if(up && tmp[0]!=nil)
if(Dx(tmp[0]->r)<Dx(rc) || Dy(tmp[2]->r)<Dy(rc))
freetmp();
if(tmp[0] == 0){
r = Rect(0, 0, max(Dx(display->screenimage->r), Dx(rc)), W);
tmp[0] = allocimage(display, r, screen->chan, 0, -1);
tmp[1] = allocimage(display, r, screen->chan, 0, -1);
r = Rect(0, 0, W, max(Dy(display->screenimage->r), Dy(rc)));
tmp[2] = allocimage(display, r, screen->chan, 0, -1);
tmp[3] = allocimage(display, r, screen->chan, 0, -1);
red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
if(tmp[0]==0 || tmp[1]==0 || tmp[2]==0 || tmp[3]==0 || red==0){
freetmp();
drawerror(display, "getrect: allocimage failed");
}
}
brects(rc, rects);
if(!up){
for(i=0; i<4; i++)
draw(screen, rects[i], tmp[i], nil, ZP);
return;
}
for(i=0; i<4; i++){
draw(tmp[i], Rect(0, 0, Dx(rects[i]), Dy(rects[i])), screen, nil, rects[i].min);
draw(screen, rects[i], red, nil, ZP);
}
}

140
src/libdraw/icossin.c Normal file
View file

@ -0,0 +1,140 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/*
* Integer sine and cosine for integral degree argument.
* Tables computed by (sin,cos)(PI*d/180).
*/
static short sinus[91] = {
0, /* 0 */
18, /* 1 */
36, /* 2 */
54, /* 3 */
71, /* 4 */
89, /* 5 */
107, /* 6 */
125, /* 7 */
143, /* 8 */
160, /* 9 */
178, /* 10 */
195, /* 11 */
213, /* 12 */
230, /* 13 */
248, /* 14 */
265, /* 15 */
282, /* 16 */
299, /* 17 */
316, /* 18 */
333, /* 19 */
350, /* 20 */
367, /* 21 */
384, /* 22 */
400, /* 23 */
416, /* 24 */
433, /* 25 */
449, /* 26 */
465, /* 27 */
481, /* 28 */
496, /* 29 */
512, /* 30 */
527, /* 31 */
543, /* 32 */
558, /* 33 */
573, /* 34 */
587, /* 35 */
602, /* 36 */
616, /* 37 */
630, /* 38 */
644, /* 39 */
658, /* 40 */
672, /* 41 */
685, /* 42 */
698, /* 43 */
711, /* 44 */
724, /* 45 */
737, /* 46 */
749, /* 47 */
761, /* 48 */
773, /* 49 */
784, /* 50 */
796, /* 51 */
807, /* 52 */
818, /* 53 */
828, /* 54 */
839, /* 55 */
849, /* 56 */
859, /* 57 */
868, /* 58 */
878, /* 59 */
887, /* 60 */
896, /* 61 */
904, /* 62 */
912, /* 63 */
920, /* 64 */
928, /* 65 */
935, /* 66 */
943, /* 67 */
949, /* 68 */
956, /* 69 */
962, /* 70 */
968, /* 71 */
974, /* 72 */
979, /* 73 */
984, /* 74 */
989, /* 75 */
994, /* 76 */
998, /* 77 */
1002, /* 78 */
1005, /* 79 */
1008, /* 80 */
1011, /* 81 */
1014, /* 82 */
1016, /* 83 */
1018, /* 84 */
1020, /* 85 */
1022, /* 86 */
1023, /* 87 */
1023, /* 88 */
1024, /* 89 */
1024, /* 90 */
};
void
icossin(int deg, int *cosp, int *sinp)
{
int sinsign, cossign;
short *stp, *ctp;
deg %= 360;
if(deg < 0)
deg += 360;
sinsign = 1;
cossign = 1;
stp = 0;
ctp = 0;
switch(deg/90){
case 2:
sinsign = -1;
cossign = -1;
deg -= 180;
/* fall through */
case 0:
stp = &sinus[deg];
ctp = &sinus[90-deg];
break;
case 3:
sinsign = -1;
cossign = -1;
deg -= 180;
/* fall through */
case 1:
deg = 180-deg;
cossign = -cossign;
stp = &sinus[deg];
ctp = &sinus[90-deg];
break;
}
*sinp = sinsign*stp[0];
*cosp = cossign*ctp[0];
}

261
src/libdraw/icossin2.c Normal file
View file

@ -0,0 +1,261 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/*
* Sine and Cosine of arctangents, calculated by
* (sin(atan(index/100.0))*1024.+0.5)
* (cos(atan(index/100.0))*1024.+0.5)
* To use, get rational tangent between 0<=tan<=1, scale by 100,
* and look up sin and cos, and use linear interpolation. divide by 1024.
* Maximum error is 0.0020. Without linear interpolation, it's 0.010.
*/
static
short sinus[] = {
0, /* 0.00 */
10, /* 0.01 */
20, /* 0.02 */
31, /* 0.03 */
41, /* 0.04 */
51, /* 0.05 */
61, /* 0.06 */
72, /* 0.07 */
82, /* 0.08 */
92, /* 0.09 */
102, /* 0.10 */
112, /* 0.11 */
122, /* 0.12 */
132, /* 0.13 */
142, /* 0.14 */
152, /* 0.15 */
162, /* 0.16 */
172, /* 0.17 */
181, /* 0.18 */
191, /* 0.19 */
201, /* 0.20 */
210, /* 0.21 */
220, /* 0.22 */
230, /* 0.23 */
239, /* 0.24 */
248, /* 0.25 */
258, /* 0.26 */
267, /* 0.27 */
276, /* 0.28 */
285, /* 0.29 */
294, /* 0.30 */
303, /* 0.31 */
312, /* 0.32 */
321, /* 0.33 */
330, /* 0.34 */
338, /* 0.35 */
347, /* 0.36 */
355, /* 0.37 */
364, /* 0.38 */
372, /* 0.39 */
380, /* 0.40 */
388, /* 0.41 */
397, /* 0.42 */
405, /* 0.43 */
412, /* 0.44 */
420, /* 0.45 */
428, /* 0.46 */
436, /* 0.47 */
443, /* 0.48 */
451, /* 0.49 */
458, /* 0.50 */
465, /* 0.51 */
472, /* 0.52 */
480, /* 0.53 */
487, /* 0.54 */
493, /* 0.55 */
500, /* 0.56 */
507, /* 0.57 */
514, /* 0.58 */
520, /* 0.59 */
527, /* 0.60 */
533, /* 0.61 */
540, /* 0.62 */
546, /* 0.63 */
552, /* 0.64 */
558, /* 0.65 */
564, /* 0.66 */
570, /* 0.67 */
576, /* 0.68 */
582, /* 0.69 */
587, /* 0.70 */
593, /* 0.71 */
598, /* 0.72 */
604, /* 0.73 */
609, /* 0.74 */
614, /* 0.75 */
620, /* 0.76 */
625, /* 0.77 */
630, /* 0.78 */
635, /* 0.79 */
640, /* 0.80 */
645, /* 0.81 */
649, /* 0.82 */
654, /* 0.83 */
659, /* 0.84 */
663, /* 0.85 */
668, /* 0.86 */
672, /* 0.87 */
676, /* 0.88 */
681, /* 0.89 */
685, /* 0.90 */
689, /* 0.91 */
693, /* 0.92 */
697, /* 0.93 */
701, /* 0.94 */
705, /* 0.95 */
709, /* 0.96 */
713, /* 0.97 */
717, /* 0.98 */
720, /* 0.99 */
724, /* 1.00 */
728, /* 1.01 */
};
static
short cosinus[] = {
1024, /* 0.00 */
1024, /* 0.01 */
1024, /* 0.02 */
1024, /* 0.03 */
1023, /* 0.04 */
1023, /* 0.05 */
1022, /* 0.06 */
1022, /* 0.07 */
1021, /* 0.08 */
1020, /* 0.09 */
1019, /* 0.10 */
1018, /* 0.11 */
1017, /* 0.12 */
1015, /* 0.13 */
1014, /* 0.14 */
1013, /* 0.15 */
1011, /* 0.16 */
1010, /* 0.17 */
1008, /* 0.18 */
1006, /* 0.19 */
1004, /* 0.20 */
1002, /* 0.21 */
1000, /* 0.22 */
998, /* 0.23 */
996, /* 0.24 */
993, /* 0.25 */
991, /* 0.26 */
989, /* 0.27 */
986, /* 0.28 */
983, /* 0.29 */
981, /* 0.30 */
978, /* 0.31 */
975, /* 0.32 */
972, /* 0.33 */
969, /* 0.34 */
967, /* 0.35 */
963, /* 0.36 */
960, /* 0.37 */
957, /* 0.38 */
954, /* 0.39 */
951, /* 0.40 */
947, /* 0.41 */
944, /* 0.42 */
941, /* 0.43 */
937, /* 0.44 */
934, /* 0.45 */
930, /* 0.46 */
927, /* 0.47 */
923, /* 0.48 */
920, /* 0.49 */
916, /* 0.50 */
912, /* 0.51 */
909, /* 0.52 */
905, /* 0.53 */
901, /* 0.54 */
897, /* 0.55 */
893, /* 0.56 */
890, /* 0.57 */
886, /* 0.58 */
882, /* 0.59 */
878, /* 0.60 */
874, /* 0.61 */
870, /* 0.62 */
866, /* 0.63 */
862, /* 0.64 */
859, /* 0.65 */
855, /* 0.66 */
851, /* 0.67 */
847, /* 0.68 */
843, /* 0.69 */
839, /* 0.70 */
835, /* 0.71 */
831, /* 0.72 */
827, /* 0.73 */
823, /* 0.74 */
819, /* 0.75 */
815, /* 0.76 */
811, /* 0.77 */
807, /* 0.78 */
804, /* 0.79 */
800, /* 0.80 */
796, /* 0.81 */
792, /* 0.82 */
788, /* 0.83 */
784, /* 0.84 */
780, /* 0.85 */
776, /* 0.86 */
773, /* 0.87 */
769, /* 0.88 */
765, /* 0.89 */
761, /* 0.90 */
757, /* 0.91 */
754, /* 0.92 */
750, /* 0.93 */
746, /* 0.94 */
742, /* 0.95 */
739, /* 0.96 */
735, /* 0.97 */
731, /* 0.98 */
728, /* 0.99 */
724, /* 1.00 */
720, /* 1.01 */
};
void
icossin2(int x, int y, int *cosp, int *sinp)
{
int sinsign, cossign, tan, tan10, rem;
short *stp, *ctp;
if(x == 0){
if(y >= 0)
*sinp = ICOSSCALE, *cosp = 0;
else
*sinp = -ICOSSCALE, *cosp = 0;
return;
}
sinsign = cossign = 1;
if(x < 0){
cossign = -1;
x = -x;
}
if(y < 0){
sinsign = -1;
y = -y;
}
if(y > x){
tan = 1000*x/y;
tan10 = tan/10;
stp = &cosinus[tan10];
ctp = &sinus[tan10];
}else{
tan = 1000*y/x;
tan10 = tan/10;
stp = &sinus[tan10];
ctp = &cosinus[tan10];
}
rem = tan-(tan10*10);
*sinp = sinsign*(stp[0]+(stp[1]-stp[0])*rem/10);
*cosp = cossign*(ctp[0]+(ctp[1]-ctp[0])*rem/10);
}

35
src/libdraw/line.c Normal file
View file

@ -0,0 +1,35 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
void
line(Image *dst, Point p0, Point p1, int end0, int end1, int radius, Image *src, Point sp)
{
lineop(dst, p0, p1, end0, end1, radius, src, sp, SoverD);
}
void
lineop(Image *dst, Point p0, Point p1, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
{
uchar *a;
_setdrawop(dst->display, op);
a = bufimage(dst->display, 1+4+2*4+2*4+4+4+4+4+2*4);
if(a == 0){
fprint(2, "image line: %r\n");
return;
}
a[0] = 'L';
BPLONG(a+1, dst->id);
BPLONG(a+5, p0.x);
BPLONG(a+9, p0.y);
BPLONG(a+13, p1.x);
BPLONG(a+17, p1.y);
BPLONG(a+21, end0);
BPLONG(a+25, end1);
BPLONG(a+29, radius);
BPLONG(a+33, src->id);
BPLONG(a+37, sp.x);
BPLONG(a+41, sp.y);
}

54
src/libdraw/loadimage.c Normal file
View file

@ -0,0 +1,54 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
int
loadimage(Image *i, Rectangle r, uchar *data, int ndata)
{
long dy;
int n, bpl;
uchar *a;
int chunk;
chunk = i->display->bufsize - 64;
if(!rectinrect(r, i->r)){
werrstr("loadimage: bad rectangle");
return -1;
}
bpl = bytesperline(r, i->depth);
n = bpl*Dy(r);
if(n > ndata){
werrstr("loadimage: insufficient data");
return -1;
}
ndata = 0;
while(r.max.y > r.min.y){
dy = r.max.y - r.min.y;
if(dy*bpl > chunk)
dy = chunk/bpl;
if(dy <= 0){
werrstr("loadimage: image too wide for buffer");
return -1;
}
n = dy*bpl;
a = bufimage(i->display, 21+n);
if(a == nil){
werrstr("bufimage failed");
return -1;
}
a[0] = 'y';
BPLONG(a+1, i->id);
BPLONG(a+5, r.min.x);
BPLONG(a+9, r.min.y);
BPLONG(a+13, r.max.x);
BPLONG(a+17, r.min.y+dy);
memmove(a+21, data, n);
ndata += n;
data += n;
r.min.y += dy;
}
if(flushimage(i->display, 0) < 0)
return -1;
return ndata;
}

55
src/libdraw/mkfont.c Normal file
View file

@ -0,0 +1,55 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/*
* Cobble fake font using existing subfont
*/
Font*
mkfont(Subfont *subfont, Rune min)
{
Font *font;
Cachefont *c;
font = malloc(sizeof(Font));
if(font == 0)
return 0;
memset(font, 0, sizeof(Font));
font->display = subfont->bits->display;
font->name = strdup("<synthetic>");
font->ncache = NFCACHE+NFLOOK;
font->nsubf = NFSUBF;
font->cache = malloc(font->ncache * sizeof(font->cache[0]));
font->subf = malloc(font->nsubf * sizeof(font->subf[0]));
if(font->name==0 || font->cache==0 || font->subf==0){
Err:
free(font->name);
free(font->cache);
free(font->subf);
free(font->sub);
free(font);
return 0;
}
memset(font->cache, 0, font->ncache*sizeof(font->cache[0]));
memset(font->subf, 0, font->nsubf*sizeof(font->subf[0]));
font->height = subfont->height;
font->ascent = subfont->ascent;
font->age = 1;
font->sub = malloc(sizeof(Cachefont*));
if(font->sub == 0)
goto Err;
c = malloc(sizeof(Cachefont));
if(c == 0)
goto Err;
font->nsub = 1;
font->sub[0] = c;
c->min = min;
c->max = min+subfont->n-1;
c->offset = 0;
c->name = 0; /* noticed by freeup() and agefont() */
c->subfontname = 0;
font->subf[0].age = 0;
font->subf[0].cf = c;
font->subf[0].f = subfont;
return font;
}

27
src/libdraw/newwindow.c Normal file
View file

@ -0,0 +1,27 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/* Connect us to new window, if possible */
int
newwindow(char *str)
{
int fd;
char *wsys;
char buf[256];
wsys = getenv("wsys");
if(wsys == nil)
return -1;
fd = open(wsys, ORDWR);
free(wsys);
if(fd < 0)
return -1;
rfork(RFNAMEG);
if(str)
snprint(buf, sizeof buf, "new %s", str);
else
strcpy(buf, "new");
return mount(fd, -1, "/dev", MBEFORE, buf);
}

87
src/libdraw/poly.c Normal file
View file

@ -0,0 +1,87 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
static
uchar*
addcoord(uchar *p, int oldx, int newx)
{
int dx;
dx = newx-oldx;
/* does dx fit in 7 signed bits? */
if((unsigned)(dx - -0x40) <= 0x7F)
*p++ = dx&0x7F;
else{
*p++ = 0x80 | (newx&0x7F);
*p++ = newx>>7;
*p++ = newx>>15;
}
return p;
}
static
void
dopoly(int cmd, Image *dst, Point *pp, int np, int end0, int end1, int radius, Image *src, Point *sp, Drawop op)
{
uchar *a, *t, *u;
int i, ox, oy;
if(np == 0)
return;
t = malloc(np*2*3);
if(t == nil)
return;
u = t;
ox = oy = 0;
for(i=0; i<np; i++){
u = addcoord(u, ox, pp[i].x);
ox = pp[i].x;
u = addcoord(u, oy, pp[i].y);
oy = pp[i].y;
}
_setdrawop(dst->display, op);
a = bufimage(dst->display, 1+4+2+4+4+4+4+2*4+(u-t));
if(a == 0){
free(t);
fprint(2, "image poly: %r\n");
return;
}
a[0] = cmd;
BPLONG(a+1, dst->id);
BPSHORT(a+5, np-1);
BPLONG(a+7, end0);
BPLONG(a+11, end1);
BPLONG(a+15, radius);
BPLONG(a+19, src->id);
BPLONG(a+23, sp->x);
BPLONG(a+27, sp->y);
memmove(a+31, t, u-t);
free(t);
}
void
poly(Image *dst, Point *p, int np, int end0, int end1, int radius, Image *src, Point sp)
{
dopoly('p', dst, p, np, end0, end1, radius, src, &sp, SoverD);
}
void
polyop(Image *dst, Point *p, int np, int end0, int end1, int radius, Image *src, Point sp, Drawop op)
{
dopoly('p', dst, p, np, end0, end1, radius, src, &sp, op);
}
void
fillpoly(Image *dst, Point *p, int np, int wind, Image *src, Point sp)
{
dopoly('P', dst, p, np, wind, 0, 0, src, &sp, SoverD);
}
void
fillpolyop(Image *dst, Point *p, int np, int wind, Image *src, Point sp, Drawop op)
{
dopoly('P', dst, p, np, wind, 0, 0, src, &sp, op);
}

25
src/libdraw/rectclip.c Normal file
View file

@ -0,0 +1,25 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
int
rectclip(Rectangle *rp, Rectangle b) /* first by reference, second by value */
{
Rectangle *bp = &b;
/*
* Expand rectXrect() in line for speed
*/
if((rp->min.x<bp->max.x && bp->min.x<rp->max.x &&
rp->min.y<bp->max.y && bp->min.y<rp->max.y)==0)
return 0;
/* They must overlap */
if(rp->min.x < bp->min.x)
rp->min.x = bp->min.x;
if(rp->min.y < bp->min.y)
rp->min.y = bp->min.y;
if(rp->max.x > bp->max.x)
rp->max.x = bp->max.x;
if(rp->max.y > bp->max.y)
rp->max.y = bp->max.y;
return 1;
}

21
src/libdraw/replclipr.c Normal file
View file

@ -0,0 +1,21 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
void
replclipr(Image *i, int repl, Rectangle clipr)
{
uchar *b;
b = bufimage(i->display, 22);
b[0] = 'c';
BPLONG(b+1, i->id);
repl = repl!=0;
b[5] = repl;
BPLONG(b+6, clipr.min.x);
BPLONG(b+10, clipr.min.y);
BPLONG(b+14, clipr.max.x);
BPLONG(b+18, clipr.max.y);
i->repl = repl;
i->clipr = clipr;
}

99
src/libdraw/rgb.c Normal file
View file

@ -0,0 +1,99 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
/*
* This original version, although fast and a true inverse of
* cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c))
* returned the original color, does a terrible job for RGB
* triples that do not appear in the color map, so it has been
* replaced by the much slower version below, that loops
* over the color map looking for the nearest point in RGB
* space. There is no visual psychology reason for that
* criterion, but it's easy to implement and the results are
* far more pleasing.
*
int
rgb2cmap(int cr, int cg, int cb)
{
int r, g, b, v, cv;
if(cr < 0)
cr = 0;
else if(cr > 255)
cr = 255;
if(cg < 0)
cg = 0;
else if(cg > 255)
cg = 255;
if(cb < 0)
cb = 0;
else if(cb > 255)
cb = 255;
r = cr>>6;
g = cg>>6;
b = cb>>6;
cv = cr;
if(cg > cv)
cv = cg;
if(cb > cv)
cv = cb;
v = (cv>>4)&3;
return ((((r<<2)+v)<<4)+(((g<<2)+b+v-r)&15));
}
*/
int
rgb2cmap(int cr, int cg, int cb)
{
int i, r, g, b, sq;
u32int rgb;
int best, bestsq;
best = 0;
bestsq = 0x7FFFFFFF;
for(i=0; i<256; i++){
rgb = cmap2rgb(i);
r = (rgb>>16) & 0xFF;
g = (rgb>>8) & 0xFF;
b = (rgb>>0) & 0xFF;
sq = (r-cr)*(r-cr)+(g-cg)*(g-cg)+(b-cb)*(b-cb);
if(sq < bestsq){
bestsq = sq;
best = i;
}
}
return best;
}
int
cmap2rgb(int c)
{
int j, num, den, r, g, b, v, rgb;
r = c>>6;
v = (c>>4)&3;
j = (c-v+r)&15;
g = j>>2;
b = j&3;
den=r;
if(g>den)
den=g;
if(b>den)
den=b;
if(den==0) {
v *= 17;
rgb = (v<<16)|(v<<8)|v;
}
else{
num=17*(4*den+v);
rgb = ((r*num/den)<<16)|((g*num/den)<<8)|(b*num/den);
}
return rgb;
}
int
cmap2rgba(int c)
{
return (cmap2rgb(c)<<8)|0xFF;
}

51
src/libdraw/stringbg.c Normal file
View file

@ -0,0 +1,51 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
Point
stringbg(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Image *bg, Point bgp)
{
return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, bg, bgp, SoverD);
}
Point
stringbgop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Image *bg, Point bgp, Drawop op)
{
return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, bg, bgp, op);
}
Point
stringnbg(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len, Image *bg, Point bgp)
{
return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, bg, bgp, SoverD);
}
Point
stringnbgop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len, Image *bg, Point bgp, Drawop op)
{
return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, bg, bgp, op);
}
Point
runestringbg(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, Image *bg, Point bgp)
{
return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, bg, bgp, SoverD);
}
Point
runestringbgop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, Image *bg, Point bgp, Drawop op)
{
return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, bg, bgp, op);
}
Point
runestringnbg(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len, Image *bg, Point bgp)
{
return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, bg, bgp, SoverD);
}
Point
runestringnbgop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len, Image *bg, Point bgp, Drawop op)
{
return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, bg, bgp, op);
}

View file

@ -0,0 +1,65 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
Point
stringsubfont(Image *b, Point p, Image *color, Subfont *f, char *cs)
{
int w, width;
uchar *s;
Rune c;
Fontchar *i;
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;
draw(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, f->bits, Pt(i->x, i->top));
}
return p;
}
Point
strsubfontwidth(Subfont *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;
}

44
src/libdraw/test.c Normal file
View file

@ -0,0 +1,44 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
void
eresized(int new)
{
if(new && getwindow(display, Refnone) < 0){
fprint(2, "colors: can't reattach to window: %r\n");
exits("resized");
}
draw(screen, screen->r, display->white, nil, ZP);
flushimage(display, 1);
}
char *buttons[] =
{
"exit",
0
};
Menu menu =
{
buttons
};
void
main(int argc, char *argv[])
{
Mouse m;
initdraw(0,0,0);
eresized(0);
einit(Emouse);
for(;;){
m = emouse();
if(m.buttons == 4)
switch(emenuhit(3, &m, &menu)){
case 0:
exits(0);
}
}
}

214
src/libdraw/window.c Normal file
View file

@ -0,0 +1,214 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
typedef struct Memimage Memimage;
static int screenid;
Screen*
allocscreen(Image *image, Image *fill, int public)
{
uchar *a;
Screen *s;
int id, try;
Display *d;
d = image->display;
if(d != fill->display){
werrstr("allocscreen: image and fill on different displays");
return 0;
}
s = malloc(sizeof(Screen));
if(s == 0)
return 0;
SET(id);
for(try=0; try<25; try++){
/* loop until find a free id */
a = bufimage(d, 1+4+4+4+1);
if(a == 0){
free(s);
return 0;
}
id = ++screenid;
a[0] = 'A';
BPLONG(a+1, id);
BPLONG(a+5, image->id);
BPLONG(a+9, fill->id);
a[13] = public;
if(flushimage(d, 0) != -1)
break;
}
s->display = d;
s->id = id;
s->image = image;
assert(s->image && s->image->chan != 0);
s->fill = fill;
return s;
}
Screen*
publicscreen(Display *d, int id, u32int chan)
{
uchar *a;
Screen *s;
s = malloc(sizeof(Screen));
if(s == 0)
return 0;
a = bufimage(d, 1+4+4);
if(a == 0){
Error:
free(s);
return 0;
}
a[0] = 'S';
BPLONG(a+1, id);
BPLONG(a+5, chan);
if(flushimage(d, 0) < 0)
goto Error;
s->display = d;
s->id = id;
s->image = 0;
s->fill = 0;
return s;
}
int
freescreen(Screen *s)
{
uchar *a;
Display *d;
if(s == 0)
return 0;
d = s->display;
a = bufimage(d, 1+4);
if(a == 0)
return -1;
a[0] = 'F';
BPLONG(a+1, s->id);
/*
* flush(1) because screen is likely holding last reference to
* window, and want it to disappear visually.
*/
if(flushimage(d, 1) < 0)
return -1;
free(s);
return 1;
}
Image*
allocwindow(Screen *s, Rectangle r, int ref, u32int val)
{
return _allocwindow(nil, s, r, ref, val);
}
Image*
_allocwindow(Image *i, Screen *s, Rectangle r, int ref, u32int val)
{
Display *d;
d = s->display;
i = _allocimage(i, d, r, d->screenimage->chan, 0, val, s->id, ref);
if(i == 0)
return 0;
i->screen = s;
i->next = s->display->windows;
s->display->windows = i;
return i;
}
static
void
topbottom(Image **w, int n, int top)
{
int i;
uchar *b;
Display *d;
if(n < 0){
Ridiculous:
fprint(2, "top/bottom: ridiculous number of windows\n");
return;
}
if(n == 0)
return;
if(n > (w[0]->display->bufsize-100)/4)
goto Ridiculous;
/*
* this used to check that all images were on the same screen.
* we don't know the screen associated with images we acquired
* by name. instead, check that all images are on the same display.
* the display will check that they are all on the same screen.
*/
d = w[0]->display;
for(i=1; i<n; i++)
if(w[i]->display != d){
fprint(2, "top/bottom: windows not on same screen\n");
return;
}
if(n==0)
return;
b = bufimage(d, 1+1+2+4*n);
b[0] = 't';
b[1] = top;
BPSHORT(b+2, n);
for(i=0; i<n; i++)
BPLONG(b+4+4*i, w[i]->id);
}
void
bottomwindow(Image *w)
{
if(w->screen == 0)
return;
topbottom(&w, 1, 0);
}
void
topwindow(Image *w)
{
if(w->screen == 0)
return;
topbottom(&w, 1, 1);
}
void
bottomnwindows(Image **w, int n)
{
topbottom(w, n, 0);
}
void
topnwindows(Image **w, int n)
{
topbottom(w, n, 1);
}
int
originwindow(Image *w, Point log, Point scr)
{
uchar *b;
Point delta;
flushimage(w->display, 0);
b = bufimage(w->display, 1+4+2*4+2*4);
if(b == nil)
return 0;
b[0] = 'o';
BPLONG(b+1, w->id);
BPLONG(b+5, log.x);
BPLONG(b+9, log.y);
BPLONG(b+13, scr.x);
BPLONG(b+17, scr.y);
if(flushimage(w->display, 1) < 0)
return -1;
delta = subpt(log, w->r.min);
w->r = rectaddpt(w->r, delta);
w->clipr = rectaddpt(w->clipr, delta);
return 1;
}

185
src/libdraw/writeimage.c Normal file
View file

@ -0,0 +1,185 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#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
writeimage(int fd, Image *i, int dolock)
{
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 chunk, ncblock;
Rectangle r;
uchar *p, *q, *s, *es, *t;
char hdr[11+5*12+1];
char cbuf[20];
chunk = i->display->bufsize - 32; /* a little room for header */
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;
if(dolock)
lockdisplay(i->display);
nb = unloadimage(i, Rect(r.min.x, miny, r.max.x, miny+dy),
data+(miny-r.min.y)*bpl, dy*bpl);
if(dolock)
unlockdisplay(i->display);
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;
}

View file

@ -0,0 +1,45 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
static
void
packinfo(Fontchar *fc, uchar *p, int n)
{
int j;
for(j=0; j<=n; j++){
p[0] = fc->x;
p[1] = fc->x>>8;
p[2] = fc->top;
p[3] = fc->bottom;
p[4] = fc->left;
p[5] = fc->width;
fc++;
p += 6;
}
}
int
writesubfont(int fd, Subfont *f)
{
char hdr[3*12+1];
uchar *data;
int nb;
sprint(hdr, "%11d %11d %11d ", f->n, f->height, f->ascent);
if(write(fd, hdr, 3*12) != 3*12){
Err:
werrstr("writesubfont: bad write: %r");
return -1;
}
nb = 6*(f->n+1);
data = malloc(nb);
if(data == nil)
return -1;
packinfo(f->info, data, f->n);
if(write(fd, data, nb) != nb)
goto Err;
free(data);
return 0;
}