monochromey+nudraw
This commit is contained in:
parent
7982b261b9
commit
135a436d10
65 changed files with 7070 additions and 27 deletions
|
@ -2,4 +2,5 @@
|
|||
Rio is a rectangle multiplexer.
|
||||
This rio has 2 spicy additions, though:
|
||||
- different scrollbar reminiscent of the one found in _mux_.
|
||||
- reads background in from `$home/lib/riobg.bit`. if it is not present, background is 0x777777ff
|
||||
- reads background in from `$home/lib/riobg.bit`. if it is not present, background is stiple
|
||||
- monochromey! some like this. some do not. you do you, i guess (please build nudraw)
|
||||
|
|
39
data.c
39
data.c
|
@ -196,35 +196,24 @@ iconinit(void)
|
|||
buf = smprint("%s/lib/riobg.bit", h);
|
||||
fd = open(buf, OREAD);
|
||||
free(buf);
|
||||
if(fd<0)
|
||||
background = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x777777FF);
|
||||
else{
|
||||
if(fd<0){
|
||||
background = allocimage(display, Rect(0,0,4,2), RGB24, 1, 0xFFFFFFFF);
|
||||
draw(background, Rect(1,1,2,2), display->black, nil, ZP);
|
||||
draw(background, Rect(3,0,4,1), display->black, nil, ZP);
|
||||
}else{
|
||||
background = readimage(display, fd, 0);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* greys are multiples of 0x11111100+0xFF, 14* being palest */
|
||||
cols[BACK] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xFFFFFFFF^reverse);
|
||||
cols[BORD] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x999999FF^reverse);
|
||||
cols[TEXT] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x000000FF^reverse);
|
||||
cols[HTEXT] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x000000FF);
|
||||
if(!reverse) {
|
||||
cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);
|
||||
titlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreygreen);
|
||||
lighttitlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreygreen);
|
||||
} else {
|
||||
cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPurpleblue);
|
||||
titlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPurpleblue);
|
||||
lighttitlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x222222FF);
|
||||
}
|
||||
dholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DMedblue);
|
||||
cols[BACK] = display->white;
|
||||
cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x000000FF);
|
||||
cols[BORD] = allocimage(display, Rect(0,0,4,2), CMAP8, 1, 0x000000FF);
|
||||
draw(cols[BORD], Rect(1,0,2,1), display->white, nil, ZP);
|
||||
draw(cols[BORD], Rect(3,1,4,2), display->white, nil, ZP);
|
||||
cols[TEXT] = cols[HIGH];
|
||||
cols[HTEXT] = cols[BACK];
|
||||
lightholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreyblue);
|
||||
paleholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreyblue);
|
||||
paletextcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x666666FF^reverse);
|
||||
sizecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DRed);
|
||||
|
||||
if(reverse == 0)
|
||||
holdcol = dholdcol;
|
||||
else
|
||||
holdcol = paleholdcol;
|
||||
sizecol = display->black;
|
||||
holdcol = display->black;
|
||||
}
|
||||
|
|
2
mkfile
2
mkfile
|
@ -18,7 +18,7 @@ HFILES=dat.h\
|
|||
|
||||
</sys/src/cmd/mkone
|
||||
|
||||
$O.out: /$objtype/lib/libdraw.a /$objtype/lib/libframe.a \
|
||||
$O.out: `{pwd}/nudraw/libnudraw.a /$objtype/lib/libframe.a \
|
||||
/$objtype/lib/libthread.a /$objtype/lib/libplumb.a /$objtype/lib/libc.a
|
||||
syms:V:
|
||||
$CC -a $CFLAGS rio.c > syms
|
||||
|
|
235
nudraw/alloc.c
Normal file
235
nudraw/alloc.c
Normal file
|
@ -0,0 +1,235 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Image*
|
||||
allocimage(Display *d, Rectangle r, ulong chan, int repl, ulong col)
|
||||
{
|
||||
Image *i;
|
||||
|
||||
i = _allocimage(nil, d, r, chan, repl, col, 0, 0);
|
||||
if(i != nil)
|
||||
setmalloctag(i, getcallerpc(&d));
|
||||
return i;
|
||||
}
|
||||
|
||||
Image*
|
||||
_allocimage(Image *ai, Display *d, Rectangle r, ulong chan, int repl, ulong col, int screenid, int refresh)
|
||||
{
|
||||
uchar *a;
|
||||
char *err;
|
||||
Image *i;
|
||||
Rectangle clipr;
|
||||
int id;
|
||||
int depth;
|
||||
|
||||
err = nil;
|
||||
i = nil;
|
||||
|
||||
if(badrect(r)){
|
||||
werrstr("bad rectangle");
|
||||
return nil;
|
||||
}
|
||||
if(chan == 0){
|
||||
werrstr("bad channel descriptor");
|
||||
return nil;
|
||||
}
|
||||
|
||||
depth = chantodepth(chan);
|
||||
if(depth == 0){
|
||||
err = "bad channel descriptor";
|
||||
Error:
|
||||
if(err != nil)
|
||||
werrstr("allocimage: %s", err);
|
||||
else
|
||||
werrstr("allocimage: %r");
|
||||
free(i);
|
||||
return nil;
|
||||
}
|
||||
|
||||
a = bufimage(d, 1+4+4+1+4+1+4*4+4*4+4);
|
||||
if(a == nil)
|
||||
goto Error;
|
||||
d->imageid++;
|
||||
id = d->imageid;
|
||||
a[0] = 'b';
|
||||
BPLONG(a+1, id);
|
||||
BPLONG(a+5, screenid);
|
||||
a[9] = refresh;
|
||||
BPLONG(a+10, chan);
|
||||
a[14] = repl;
|
||||
BPLONG(a+15, r.min.x);
|
||||
BPLONG(a+19, r.min.y);
|
||||
BPLONG(a+23, r.max.x);
|
||||
BPLONG(a+27, r.max.y);
|
||||
if(repl)
|
||||
/* huge but not infinite, so various offsets will leave it huge, not overflow */
|
||||
clipr = Rect(-0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
|
||||
else
|
||||
clipr = r;
|
||||
BPLONG(a+31, clipr.min.x);
|
||||
BPLONG(a+35, clipr.min.y);
|
||||
BPLONG(a+39, clipr.max.x);
|
||||
BPLONG(a+43, clipr.max.y);
|
||||
BPLONG(a+47, col);
|
||||
|
||||
if(ai != nil)
|
||||
i = ai;
|
||||
else{
|
||||
i = malloc(sizeof(Image));
|
||||
if(i == nil){
|
||||
a = bufimage(d, 1+4);
|
||||
if(a != nil){
|
||||
a[0] = 'f';
|
||||
BPLONG(a+1, id);
|
||||
flushimage(d, 0);
|
||||
}
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
i->display = d;
|
||||
i->id = id;
|
||||
i->depth = depth;
|
||||
i->chan = chan;
|
||||
i->r = r;
|
||||
i->clipr = clipr;
|
||||
i->repl = repl;
|
||||
i->screen = nil;
|
||||
i->next = nil;
|
||||
return i;
|
||||
}
|
||||
|
||||
Image*
|
||||
namedimage(Display *d, char *name)
|
||||
{
|
||||
uchar *a;
|
||||
char *err, buf[12*12+1];
|
||||
Image *i;
|
||||
int id, n;
|
||||
ulong chan;
|
||||
|
||||
err = nil;
|
||||
i = nil;
|
||||
|
||||
n = strlen(name);
|
||||
if(n >= 256){
|
||||
err = "name too long";
|
||||
Error:
|
||||
if(err != nil)
|
||||
werrstr("namedimage: %s", err);
|
||||
else
|
||||
werrstr("namedimage: %r");
|
||||
free(i);
|
||||
return nil;
|
||||
}
|
||||
/* flush pending data so we don't get error allocating the image */
|
||||
flushimage(d, 0);
|
||||
a = bufimage(d, 1+4+1+n);
|
||||
if(a == nil)
|
||||
goto Error;
|
||||
d->imageid++;
|
||||
id = d->imageid;
|
||||
a[0] = 'n';
|
||||
BPLONG(a+1, id);
|
||||
a[5] = n;
|
||||
memmove(a+6, name, n);
|
||||
if(flushimage(d, 0) < 0)
|
||||
goto Error;
|
||||
|
||||
if(pread(d->ctlfd, buf, sizeof buf, 0) < 12*12)
|
||||
goto Error;
|
||||
buf[12*12] = '\0';
|
||||
|
||||
i = malloc(sizeof(Image));
|
||||
if(i == nil){
|
||||
Error1:
|
||||
a = bufimage(d, 1+4);
|
||||
if(a != nil){
|
||||
a[0] = 'f';
|
||||
BPLONG(a+1, id);
|
||||
flushimage(d, 0);
|
||||
}
|
||||
goto Error;
|
||||
}
|
||||
i->display = d;
|
||||
i->id = id;
|
||||
if((chan=strtochan(buf+2*12))==0){
|
||||
werrstr("bad channel '%.12s' from devdraw", buf+2*12);
|
||||
goto Error1;
|
||||
}
|
||||
i->chan = chan;
|
||||
i->depth = chantodepth(chan);
|
||||
i->repl = atoi(buf+3*12);
|
||||
i->r.min.x = atoi(buf+4*12);
|
||||
i->r.min.y = atoi(buf+5*12);
|
||||
i->r.max.x = atoi(buf+6*12);
|
||||
i->r.max.y = atoi(buf+7*12);
|
||||
i->clipr.min.x = atoi(buf+8*12);
|
||||
i->clipr.min.y = atoi(buf+9*12);
|
||||
i->clipr.max.x = atoi(buf+10*12);
|
||||
i->clipr.max.y = atoi(buf+11*12);
|
||||
i->screen = nil;
|
||||
i->next = nil;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
nameimage(Image *i, char *name, int in)
|
||||
{
|
||||
uchar *a;
|
||||
int n;
|
||||
|
||||
n = strlen(name);
|
||||
a = bufimage(i->display, 1+4+1+1+n);
|
||||
if(a == nil)
|
||||
return 0;
|
||||
a[0] = 'N';
|
||||
BPLONG(a+1, i->id);
|
||||
a[5] = in;
|
||||
a[6] = n;
|
||||
memmove(a+7, name, n);
|
||||
if(flushimage(i->display, 0) < 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
_freeimage1(Image *i)
|
||||
{
|
||||
uchar *a;
|
||||
Display *d;
|
||||
Image *w;
|
||||
|
||||
if(i == nil || i->display == nil)
|
||||
return 0;
|
||||
d = i->display;
|
||||
if(i->screen != nil){
|
||||
w = d->windows;
|
||||
if(w == i)
|
||||
d->windows = i->next;
|
||||
else
|
||||
while(w != nil){
|
||||
if(w->next == i){
|
||||
w->next = i->next;
|
||||
break;
|
||||
}
|
||||
w = w->next;
|
||||
}
|
||||
}
|
||||
a = bufimage(d, 1+4);
|
||||
if(a == nil)
|
||||
return -1;
|
||||
a[0] = 'f';
|
||||
BPLONG(a+1, i->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
freeimage(Image *i)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _freeimage1(i);
|
||||
free(i);
|
||||
return ret;
|
||||
}
|
43
nudraw/allocimagemix.c
Normal file
43
nudraw/allocimagemix.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Image*
|
||||
allocimagemix(Display *d, ulong color1, ulong 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;
|
||||
}
|
||||
}
|
185
nudraw/arith.c
Normal file
185
nudraw/arith.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Point
|
||||
Pt(int x, int y)
|
||||
{
|
||||
Point p;
|
||||
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
return p;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
Rect(int x, int y, int bx, int by)
|
||||
{
|
||||
Rectangle r;
|
||||
|
||||
r.min.x = x;
|
||||
r.min.y = y;
|
||||
r.max.x = bx;
|
||||
r.max.y = by;
|
||||
return r;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
Rpt(Point min, Point max)
|
||||
{
|
||||
Rectangle r;
|
||||
|
||||
r.min = min;
|
||||
r.max = max;
|
||||
return r;
|
||||
}
|
||||
|
||||
Point
|
||||
addpt(Point a, Point b)
|
||||
{
|
||||
a.x += b.x;
|
||||
a.y += b.y;
|
||||
return a;
|
||||
}
|
||||
|
||||
Point
|
||||
subpt(Point a, Point b)
|
||||
{
|
||||
a.x -= b.x;
|
||||
a.y -= b.y;
|
||||
return a;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
insetrect(Rectangle r, int n)
|
||||
{
|
||||
r.min.x += n;
|
||||
r.min.y += n;
|
||||
r.max.x -= n;
|
||||
r.max.y -= n;
|
||||
return r;
|
||||
}
|
||||
|
||||
Point
|
||||
divpt(Point a, int b)
|
||||
{
|
||||
a.x /= b;
|
||||
a.y /= b;
|
||||
return a;
|
||||
}
|
||||
|
||||
Point
|
||||
mulpt(Point a, int b)
|
||||
{
|
||||
a.x *= b;
|
||||
a.y *= b;
|
||||
return a;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
rectsubpt(Rectangle r, Point p)
|
||||
{
|
||||
r.min.x -= p.x;
|
||||
r.min.y -= p.y;
|
||||
r.max.x -= p.x;
|
||||
r.max.y -= p.y;
|
||||
return r;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
rectaddpt(Rectangle r, Point p)
|
||||
{
|
||||
r.min.x += p.x;
|
||||
r.min.y += p.y;
|
||||
r.max.x += p.x;
|
||||
r.max.y += p.y;
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
eqpt(Point p, Point q)
|
||||
{
|
||||
return p.x==q.x && p.y==q.y;
|
||||
}
|
||||
|
||||
int
|
||||
eqrect(Rectangle r, Rectangle s)
|
||||
{
|
||||
return r.min.x==s.min.x && r.max.x==s.max.x &&
|
||||
r.min.y==s.min.y && r.max.y==s.max.y;
|
||||
}
|
||||
|
||||
int
|
||||
rectXrect(Rectangle r, Rectangle s)
|
||||
{
|
||||
return r.min.x<s.max.x && s.min.x<r.max.x &&
|
||||
r.min.y<s.max.y && s.min.y<r.max.y;
|
||||
}
|
||||
|
||||
int
|
||||
rectinrect(Rectangle r, Rectangle s)
|
||||
{
|
||||
return s.min.x<=r.min.x && r.max.x<=s.max.x && s.min.y<=r.min.y && r.max.y<=s.max.y;
|
||||
}
|
||||
|
||||
int
|
||||
ptinrect(Point p, Rectangle r)
|
||||
{
|
||||
return p.x>=r.min.x && p.x<r.max.x &&
|
||||
p.y>=r.min.y && p.y<r.max.y;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
canonrect(Rectangle r)
|
||||
{
|
||||
int t;
|
||||
if (r.max.x < r.min.x) {
|
||||
t = r.min.x;
|
||||
r.min.x = r.max.x;
|
||||
r.max.x = t;
|
||||
}
|
||||
if (r.max.y < r.min.y) {
|
||||
t = r.min.y;
|
||||
r.min.y = r.max.y;
|
||||
r.max.y = t;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
combinerect(Rectangle *r1, Rectangle r2)
|
||||
{
|
||||
if(r1->min.x > r2.min.x)
|
||||
r1->min.x = r2.min.x;
|
||||
if(r1->min.y > r2.min.y)
|
||||
r1->min.y = r2.min.y;
|
||||
if(r1->max.x < r2.max.x)
|
||||
r1->max.x = r2.max.x;
|
||||
if(r1->max.y < r2.max.y)
|
||||
r1->max.y = r2.max.y;
|
||||
}
|
||||
|
||||
ulong drawld2chan[] = {
|
||||
GREY1,
|
||||
GREY2,
|
||||
GREY4,
|
||||
CMAP8,
|
||||
};
|
||||
|
||||
ulong
|
||||
setalpha(ulong color, uchar alpha)
|
||||
{
|
||||
int red, green, blue;
|
||||
|
||||
red = (color >> 3*8) & 0xFF;
|
||||
green = (color >> 2*8) & 0xFF;
|
||||
blue = (color >> 1*8) & 0xFF;
|
||||
/* ignore incoming alpha */
|
||||
red = (red * alpha)/255;
|
||||
green = (green * alpha)/255;
|
||||
blue = (blue * alpha)/255;
|
||||
return (red<<3*8) | (green<<2*8) | (blue<<1*8) | (alpha<<0*8);
|
||||
}
|
||||
|
||||
Point ZP;
|
||||
Rectangle ZR;
|
22
nudraw/badrect.c
Normal file
22
nudraw/badrect.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
/*
|
||||
* check for zero, negative size or insanely huge rectangle.
|
||||
*/
|
||||
int
|
||||
badrect(Rectangle r)
|
||||
{
|
||||
int x, y;
|
||||
uint z;
|
||||
|
||||
x = Dx(r);
|
||||
y = Dy(r);
|
||||
if(x > 0 && y > 0){
|
||||
z = x*y;
|
||||
if(z/x == y && z < 0x10000000)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
255
nudraw/bezier.c
Normal file
255
nudraw/bezier.c
Normal file
|
@ -0,0 +1,255 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
int
|
||||
bezierpts(Point p0, Point p1, Point p2, Point p3, Point **pp)
|
||||
{
|
||||
Plist l;
|
||||
l.p = nil;
|
||||
l.np = 0;
|
||||
_bezierpts(&l, p0, p1, p2, p3);
|
||||
*pp = l.p;
|
||||
return l.np;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
27
nudraw/border.c
Normal file
27
nudraw/border.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
void
|
||||
borderop(Image *im, Rectangle r, int i, Image *color, Point sp, Drawop op)
|
||||
{
|
||||
if(i < 0){
|
||||
r = insetrect(r, i);
|
||||
sp = addpt(sp, Pt(i,i));
|
||||
i = -i;
|
||||
}
|
||||
drawop(im, Rect(r.min.x, r.min.y, r.max.x, r.min.y+i),
|
||||
color, nil, sp, op);
|
||||
drawop(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), op);
|
||||
drawop(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), op);
|
||||
drawop(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), op);
|
||||
}
|
||||
|
||||
void
|
||||
border(Image *im, Rectangle r, int i, Image *color, Point sp)
|
||||
{
|
||||
borderop(im, r, i, color, sp, SoverD);
|
||||
}
|
140
nudraw/buildfont.c
Normal file
140
nudraw/buildfont.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
static char*
|
||||
skip(char *s)
|
||||
{
|
||||
while(*s==' ' || *s=='\n' || *s=='\t')
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
Font*
|
||||
buildfont(Display *d, char *buf, char *name)
|
||||
{
|
||||
Font *fnt;
|
||||
Cachefont *c, **sub;
|
||||
char *s, *t;
|
||||
ulong min, max;
|
||||
int offset;
|
||||
char badform[] = "bad font format: number expected (char position %d)";
|
||||
|
||||
s = buf;
|
||||
fnt = malloc(sizeof(Font));
|
||||
if(fnt == nil)
|
||||
return nil;
|
||||
memset(fnt, 0, sizeof(Font));
|
||||
fnt->display = d;
|
||||
fnt->name = strdup(name);
|
||||
fnt->ncache = NFCACHE+NFLOOK;
|
||||
fnt->nsubf = NFSUBF;
|
||||
fnt->cache = malloc(fnt->ncache * sizeof(fnt->cache[0]));
|
||||
fnt->subf = malloc(fnt->nsubf * sizeof(fnt->subf[0]));
|
||||
if(fnt->name==nil || fnt->cache==nil || fnt->subf==nil){
|
||||
Err2:
|
||||
free(fnt->name);
|
||||
free(fnt->cache);
|
||||
free(fnt->subf);
|
||||
free(fnt->sub);
|
||||
free(fnt);
|
||||
return nil;
|
||||
}
|
||||
fnt->height = strtol(s, &s, 0);
|
||||
s = skip(s);
|
||||
fnt->ascent = strtol(s, &s, 0);
|
||||
s = skip(s);
|
||||
if(fnt->height<=0 || fnt->ascent<=0){
|
||||
werrstr("bad height or ascent in font file");
|
||||
goto Err2;
|
||||
}
|
||||
fnt->width = 0;
|
||||
fnt->nsub = 0;
|
||||
fnt->sub = nil;
|
||||
|
||||
memset(fnt->subf, 0, fnt->nsubf * sizeof(fnt->subf[0]));
|
||||
memset(fnt->cache, 0, fnt->ncache*sizeof(fnt->cache[0]));
|
||||
fnt->age = 1;
|
||||
do{
|
||||
/* must be looking at a number now */
|
||||
if(*s<'0' || '9'<*s){
|
||||
werrstr(badform, s-buf);
|
||||
goto Err3;
|
||||
}
|
||||
min = strtol(s, &s, 0);
|
||||
s = skip(s);
|
||||
/* must be looking at a number now */
|
||||
if(*s<'0' || '9'<*s){
|
||||
werrstr(badform, s-buf);
|
||||
goto Err3;
|
||||
}
|
||||
max = strtol(s, &s, 0);
|
||||
s = skip(s);
|
||||
if(*s==0 || min>Runemax || max>Runemax || min>max){
|
||||
werrstr("illegal subfont range");
|
||||
Err3:
|
||||
freefont(fnt);
|
||||
return 0;
|
||||
}
|
||||
t = s;
|
||||
offset = strtol(s, &t, 0);
|
||||
if(t>s && (*t==' ' || *t=='\t' || *t=='\n'))
|
||||
s = skip(t);
|
||||
else
|
||||
offset = 0;
|
||||
sub = realloc(fnt->sub, (fnt->nsub+1)*sizeof(Cachefont*));
|
||||
if(sub == nil)
|
||||
goto Err3;
|
||||
fnt->sub = sub;
|
||||
c = malloc(sizeof(Cachefont));
|
||||
if(c == nil)
|
||||
goto Err3;
|
||||
c->min = min;
|
||||
c->max = max;
|
||||
c->offset = offset;
|
||||
t = s;
|
||||
while(*s && *s!=' ' && *s!='\n' && *s!='\t')
|
||||
s++;
|
||||
*s++ = 0;
|
||||
c->subfontname = nil;
|
||||
c->name = strdup(t);
|
||||
if(c->name == nil){
|
||||
free(c);
|
||||
goto Err3;
|
||||
}
|
||||
sub[fnt->nsub++] = c;
|
||||
s = skip(s);
|
||||
}while(*s);
|
||||
return fnt;
|
||||
}
|
||||
|
||||
void
|
||||
freefont(Font *f)
|
||||
{
|
||||
int i;
|
||||
Cachefont *c;
|
||||
Subfont *s;
|
||||
|
||||
if(f == nil)
|
||||
return;
|
||||
|
||||
for(i=0; i<f->nsub; i++){
|
||||
c = f->sub[i];
|
||||
free(c->subfontname);
|
||||
free(c->name);
|
||||
free(c);
|
||||
}
|
||||
for(i=0; i<f->nsubf; i++){
|
||||
s = f->subf[i].f;
|
||||
if(s != nil){
|
||||
if(f->display == nil || s != f->display->defaultsubfont)
|
||||
freesubfont(s);
|
||||
}
|
||||
}
|
||||
freeimage(f->cacheimage);
|
||||
free(f->name);
|
||||
free(f->cache);
|
||||
free(f->subf);
|
||||
free(f->sub);
|
||||
free(f);
|
||||
}
|
24
nudraw/bytesperline.c
Normal file
24
nudraw/bytesperline.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
static
|
||||
int
|
||||
unitsperline(Rectangle r, int d, int bitsperunit)
|
||||
{
|
||||
if(d <= 0 || d > 32) /* being called wrong. d is image depth. */
|
||||
abort();
|
||||
return (r.max.x*d - (r.min.x*d & -bitsperunit) + bitsperunit - 1) / bitsperunit;
|
||||
}
|
||||
|
||||
int
|
||||
wordsperline(Rectangle r, int d)
|
||||
{
|
||||
return unitsperline(r, d, 8*sizeof(ulong));
|
||||
}
|
||||
|
||||
int
|
||||
bytesperline(Rectangle r, int d)
|
||||
{
|
||||
return unitsperline(r, d, 8);
|
||||
}
|
81
nudraw/chan.c
Normal file
81
nudraw/chan.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
static char channames[] = "rgbkamx";
|
||||
char*
|
||||
chantostr(char *buf, ulong cc)
|
||||
{
|
||||
ulong c, rc;
|
||||
char *p;
|
||||
|
||||
if(chantodepth(cc) == 0)
|
||||
return nil;
|
||||
|
||||
/* reverse the channel descriptor so we can easily generate the string in the right order */
|
||||
rc = 0;
|
||||
for(c=cc; c; c>>=8){
|
||||
rc <<= 8;
|
||||
rc |= c&0xFF;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
for(c=rc; c; c>>=8) {
|
||||
*p++ = channames[TYPE(c)];
|
||||
*p++ = '0'+NBITS(c);
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* avoid pulling in ctype when using with drawterm etc. */
|
||||
static int
|
||||
isspace(char c)
|
||||
{
|
||||
return c==' ' || c== '\t' || c=='\r' || c=='\n';
|
||||
}
|
||||
|
||||
ulong
|
||||
strtochan(char *s)
|
||||
{
|
||||
char *p, *q;
|
||||
ulong c;
|
||||
int t, n, d;
|
||||
|
||||
c = 0;
|
||||
d = 0;
|
||||
p=s;
|
||||
while(*p && isspace(*p))
|
||||
p++;
|
||||
|
||||
while(*p && !isspace(*p)){
|
||||
if((q = strchr(channames, p[0])) == nil)
|
||||
return 0;
|
||||
t = q-channames;
|
||||
if(p[1] < '0' || p[1] > '9')
|
||||
return 0;
|
||||
n = p[1]-'0';
|
||||
d += n;
|
||||
c = (c<<8) | __DC(t, n);
|
||||
p += 2;
|
||||
}
|
||||
if(d==0 || (d>8 && d%8) || (d<8 && 8%d))
|
||||
return 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
chantodepth(ulong c)
|
||||
{
|
||||
int n;
|
||||
|
||||
for(n=0; c; c>>=8){
|
||||
if(TYPE(c) >= NChan || NBITS(c) > 8 || NBITS(c) <= 0)
|
||||
return 0;
|
||||
n += NBITS(c);
|
||||
}
|
||||
if(n==0 || (n>8 && n%8) || (n<8 && 8%n))
|
||||
return 0;
|
||||
return n;
|
||||
}
|
49
nudraw/cloadimage.c
Normal file
49
nudraw/cloadimage.c
Normal 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("cloadimage: bad maxy %d", maxy);
|
||||
return -1;
|
||||
}
|
||||
data += 2*12;
|
||||
ndata -= 2*12;
|
||||
m += 2*12;
|
||||
if(nb<=0 || ncblock<nb || nb>ndata){
|
||||
werrstr("cloadimage: 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
nudraw/computil.c
Normal file
38
nudraw/computil.c
Normal 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;
|
||||
}
|
122
nudraw/creadimage.c
Normal file
122
nudraw/creadimage.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Image *
|
||||
creadimage(Display *d, int fd, int dolock)
|
||||
{
|
||||
char hdr[5*12+1];
|
||||
Rectangle r;
|
||||
int m, nb, miny, maxy, new, ldepth, ncblock;
|
||||
uchar *buf, *a;
|
||||
Image *i;
|
||||
ulong chan;
|
||||
|
||||
if(readn(fd, hdr, 5*12) != 5*12)
|
||||
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;
|
||||
}
|
||||
|
||||
if(d != nil){
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
i = allocimage(d, r, chan, 0, 0);
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
}else{
|
||||
i = mallocz(sizeof(Image), 1);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
}
|
||||
setmalloctag(i, getcallerpc(&d));
|
||||
ncblock = _compblocksize(r, chantodepth(chan));
|
||||
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){
|
||||
Errout:
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
Erroutlock:
|
||||
freeimage(i);
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
free(buf);
|
||||
return nil;
|
||||
}
|
||||
maxy = atoi(hdr+0*12);
|
||||
nb = atoi(hdr+1*12);
|
||||
if(maxy<=miny || r.max.y<maxy){
|
||||
werrstr("creadimage: bad maxy %d", maxy);
|
||||
goto Errout;
|
||||
}
|
||||
if(nb<=0 || ncblock<nb){
|
||||
werrstr("creadimage: bad count %d", nb);
|
||||
goto Errout;
|
||||
}
|
||||
if(readn(fd, buf, nb)!=nb)
|
||||
goto Errout;
|
||||
if(d != nil){
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
a = bufimage(i->display, 21+nb);
|
||||
if(a == nil)
|
||||
goto Erroutlock;
|
||||
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);
|
||||
if(!new) /* old image: flip the data bits */
|
||||
_twiddlecompressed(buf, nb);
|
||||
memmove(a+21, buf, nb);
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
}
|
||||
miny = maxy;
|
||||
}
|
||||
free(buf);
|
||||
return i;
|
||||
}
|
16
nudraw/debug.c
Normal file
16
nudraw/debug.c
Normal 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 == nil){
|
||||
fprint(2, "drawsetdebug: %r\n");
|
||||
return;
|
||||
}
|
||||
a[0] = 'D';
|
||||
a[1] = v;
|
||||
}
|
388
nudraw/defont.c
Normal file
388
nudraw/defont.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
/*
|
||||
* vga/vga00, 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,0x30,0x34,0x38,0x20,
|
||||
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x36,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,
|
||||
0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,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,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x0c,0x10,0x76,
|
||||
0x6c,0x38,0x00,0x00,0x30,0x0c,0x10,0x6c,0x30,0x0c,0x18,0x66,0x00,0x76,0x60,0x0c,
|
||||
0x10,0x76,0x6c,0x00,0x00,0x60,0x0c,0x10,0x6c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xe0,
|
||||
0xe0,0xe0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xe0,0xe0,0xe0,
|
||||
0xe0,0x90,0x70,0xe0,0x70,0x00,0x70,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x00,
|
||||
0x18,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,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,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,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,0x38,
|
||||
0x00,0x00,0x00,0x7c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x70,0x70,
|
||||
0x00,0x00,0x00,0x00,0x00,0x30,0x38,0x00,0xc0,0xc0,0xe0,0x00,0x30,0x18,0x38,0xdc,
|
||||
0x6c,0x6c,0x00,0x00,0x18,0x18,0x38,0x6c,0x18,0x18,0x3c,0x66,0x00,0xdc,0x30,0x18,
|
||||
0x38,0xdc,0x6c,0x00,0x00,0x30,0x18,0x38,0x6c,0x18,0x00,0x00,0x00,0x00,0x10,0x00,
|
||||
0x00,0x38,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
||||
0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0xda,0x00,0x80,0x80,
|
||||
0x80,0x80,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0x90,0x90,
|
||||
0x90,0xd0,0x80,0x80,0x90,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x18,0x66,0x00,
|
||||
0x7c,0x00,0x38,0x30,0x0c,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x18,0x7c,0x7c,
|
||||
0x0c,0xfe,0x38,0xfe,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x10,0xfc,0x3c,
|
||||
0xf8,0xfe,0xfe,0x3c,0xc6,0x3c,0x1e,0xe6,0xf0,0xc6,0xc6,0x7c,0xfc,0x7c,0xfc,0x7c,
|
||||
0x7e,0xc6,0xc6,0xc6,0xc6,0x66,0xfe,0x3c,0x00,0x3c,0x6c,0x00,0x18,0x00,0xe0,0x00,
|
||||
0x1c,0x00,0x38,0x00,0xe0,0x18,0x06,0xe0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x18,0x70,0x76,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,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,0x18,0x6c,
|
||||
0x00,0x66,0x18,0xc6,0x6c,0x3c,0x6c,0x00,0x00,0x00,0x38,0x00,0x6c,0x00,0xd8,0xd8,
|
||||
0x0c,0x00,0x7f,0x00,0x00,0x70,0x6c,0x00,0xc0,0xc0,0x30,0x30,0x00,0x00,0x6c,0x00,
|
||||
0x00,0x38,0x3e,0x3c,0x00,0x00,0x44,0x00,0x00,0x00,0x42,0x00,0xf8,0x00,0x00,0x00,
|
||||
0x44,0x00,0x00,0x00,0x7a,0x00,0x00,0x44,0x00,0x00,0xf0,0x3c,0x60,0x18,0x38,0x76,
|
||||
0x6c,0x6c,0x00,0x00,0x60,0x0c,0x38,0x6c,0x30,0x0c,0x38,0x66,0x76,0x76,0x60,0x0c,
|
||||
0x38,0x76,0x6c,0x00,0x00,0x60,0x18,0x38,0xcc,0x0c,0xe0,0x6c,0x02,0x00,0xe0,0xe0,
|
||||
0xe0,0xe0,0xf0,0x18,0x70,0x48,0x20,0x48,0x70,0x38,0x38,0x38,0x90,0x90,0x90,0x90,
|
||||
0x90,0xb0,0x60,0xe0,0x80,0xe0,0x60,0xe0,0x70,0x38,0x70,0x48,0x00,0x3c,0x66,0x6c,
|
||||
0xc6,0x00,0x6c,0x30,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x38,0xc6,0xc6,
|
||||
0x1c,0xc0,0x60,0xc6,0xc6,0xc6,0x00,0x00,0x06,0x00,0x60,0xc6,0x7c,0x38,0x66,0x66,
|
||||
0x6c,0x66,0x66,0x66,0xc6,0x18,0x0c,0x66,0x60,0xee,0xe6,0xc6,0x66,0xc6,0x66,0xc6,
|
||||
0x7e,0xc6,0xc6,0xc6,0xc6,0x66,0xc6,0x30,0x80,0x0c,0xc6,0x00,0x00,0x00,0x60,0x00,
|
||||
0x0c,0x00,0x6c,0x00,0x60,0x18,0x06,0x60,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xdc,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,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,0x3c,0x64,
|
||||
0x00,0x66,0x18,0x60,0x6c,0x42,0x6c,0x00,0x00,0x00,0x44,0x7c,0x6c,0x00,0x30,0x30,
|
||||
0x18,0x00,0xdb,0x00,0x00,0x30,0x6c,0x00,0xc2,0xc2,0x62,0x30,0x10,0x10,0x10,0x10,
|
||||
0x10,0x10,0x6c,0x66,0xfe,0xfe,0xfe,0xfe,0x3c,0x3c,0x3c,0x3c,0x6c,0xc6,0x7c,0x7c,
|
||||
0x7c,0x7c,0x7c,0x00,0xc4,0xc6,0xc6,0xc6,0xc6,0x66,0x60,0x66,0x30,0x30,0x6c,0xdc,
|
||||
0x6c,0x38,0x00,0x00,0x30,0x18,0x6c,0x6c,0x18,0x18,0x6c,0x66,0x1c,0xdc,0x30,0x18,
|
||||
0x6c,0xdc,0x6c,0x00,0x00,0x30,0x30,0x6c,0xcc,0x18,0x60,0x6c,0x80,0x00,0x10,0x80,
|
||||
0x80,0x80,0x90,0x3c,0x48,0x48,0x20,0x48,0x40,0x48,0x40,0x40,0x90,0x90,0x90,0x90,
|
||||
0x90,0x90,0x10,0x80,0x80,0x80,0x10,0x80,0x40,0x40,0x48,0x48,0x00,0x3c,0x24,0x6c,
|
||||
0xc2,0xc2,0x6c,0x20,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0xc6,0x78,0x06,0x06,
|
||||
0x3c,0xc0,0xc0,0x06,0xc6,0xc6,0x18,0x18,0x0c,0x00,0x30,0xc6,0xc6,0x6c,0x66,0xc2,
|
||||
0x66,0x62,0x62,0xc2,0xc6,0x18,0x0c,0x66,0x60,0xfe,0xf6,0xc6,0x66,0xc6,0x66,0xc6,
|
||||
0x5a,0xc6,0xc6,0xc6,0x6c,0x66,0x86,0x30,0xc0,0x0c,0x00,0x00,0x00,0x00,0x60,0x00,
|
||||
0x0c,0x00,0x64,0x00,0x60,0x00,0x00,0x60,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x10,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,
|
||||
0x66,0x3c,0x18,0x38,0x00,0x99,0x3e,0x00,0x00,0x00,0xba,0x00,0x38,0x18,0x60,0x18,
|
||||
0x00,0x00,0xdb,0x00,0x00,0x30,0x38,0x00,0xc6,0xc6,0x36,0x00,0x38,0x38,0x38,0x38,
|
||||
0x38,0x38,0xcc,0xc2,0x66,0x66,0x66,0x66,0x18,0x18,0x18,0x18,0x66,0xe6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x00,0xce,0xc6,0xc6,0xc6,0xc6,0x66,0x7c,0x66,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x82,0x00,0xe0,0xe0,
|
||||
0xe0,0xe0,0x90,0x3c,0x70,0x78,0x20,0x48,0x70,0x40,0x30,0x30,0xe0,0xe0,0xe0,0xe0,
|
||||
0xe0,0x90,0xe0,0xe0,0x70,0xe0,0xe0,0xe0,0x70,0x58,0x70,0x48,0x00,0x3c,0x00,0xfe,
|
||||
0xc0,0xc6,0x38,0x00,0x30,0x0c,0x66,0x18,0x00,0x00,0x00,0x06,0xc6,0x18,0x0c,0x06,
|
||||
0x6c,0xc0,0xc0,0x06,0xc6,0xc6,0x18,0x18,0x18,0x7e,0x18,0x0c,0xc6,0xc6,0x66,0xc0,
|
||||
0x66,0x68,0x68,0xc0,0xc6,0x18,0x0c,0x6c,0x60,0xfe,0xfe,0xc6,0x66,0xc6,0x66,0x60,
|
||||
0x18,0xc6,0xc6,0xc6,0x7c,0x66,0x0c,0x30,0xe0,0x0c,0x00,0x00,0x00,0x78,0x78,0x7c,
|
||||
0x3c,0x7c,0x60,0x76,0x6c,0x38,0x0e,0x66,0x18,0xec,0xdc,0x7c,0xdc,0x76,0xdc,0x7c,
|
||||
0xfc,0xcc,0x66,0xc6,0xc6,0xc6,0xfe,0x18,0x18,0x18,0x00,0x38,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,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,0x60,0xf0,
|
||||
0x3c,0x18,0x18,0x6c,0x00,0xa5,0x00,0x36,0x00,0x00,0xb2,0x00,0x00,0x18,0xc8,0xd8,
|
||||
0x00,0xcc,0xdb,0x00,0x00,0x30,0x00,0xd8,0xcc,0xcc,0xec,0x30,0x6c,0x6c,0x6c,0x6c,
|
||||
0x6c,0x6c,0xcc,0xc0,0x62,0x62,0x62,0x62,0x18,0x18,0x18,0x18,0x66,0xf6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x66,0xce,0xc6,0xc6,0xc6,0xc6,0x66,0x66,0x66,0x78,0x78,0x78,0x78,
|
||||
0x78,0x78,0xcc,0x7c,0x7c,0x7c,0x7c,0x7c,0x38,0x38,0x38,0x38,0x06,0xdc,0x7c,0x7c,
|
||||
0x7c,0x7c,0x7c,0x18,0x7a,0xcc,0xcc,0xcc,0xcc,0xc6,0x7c,0xc6,0x02,0x00,0x1c,0x1c,
|
||||
0x18,0x24,0x1c,0x3c,0x48,0x48,0x20,0x30,0x40,0x40,0x08,0x08,0x10,0x1c,0x1c,0x1c,
|
||||
0x1c,0x0c,0x44,0x1c,0x0c,0x80,0x24,0x1c,0x40,0x48,0x50,0x48,0x00,0x18,0x00,0x6c,
|
||||
0x7c,0x0c,0x76,0x00,0x30,0x0c,0x3c,0x18,0x00,0x00,0x00,0x0c,0xd6,0x18,0x18,0x3c,
|
||||
0xcc,0xfc,0xfc,0x0c,0x7c,0x7e,0x00,0x00,0x30,0x00,0x0c,0x18,0xde,0xc6,0x7c,0xc0,
|
||||
0x66,0x78,0x78,0xc0,0xfe,0x18,0x0c,0x78,0x60,0xd6,0xde,0xc6,0x7c,0xc6,0x7c,0x38,
|
||||
0x18,0xc6,0xc6,0xd6,0x38,0x3c,0x18,0x30,0x70,0x0c,0x00,0x00,0x00,0x0c,0x6c,0xc6,
|
||||
0x6c,0xc6,0xf0,0xcc,0x76,0x18,0x06,0x6c,0x18,0xfe,0x66,0xc6,0x66,0xcc,0x76,0xc6,
|
||||
0x30,0xcc,0x66,0xc6,0x6c,0xc6,0xcc,0x70,0x00,0x0e,0x00,0x6c,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,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,0x60,0x60,
|
||||
0x66,0x7e,0x00,0xc6,0x00,0xa1,0x7e,0x6c,0xfe,0x00,0xaa,0x00,0x00,0x7e,0xf8,0x70,
|
||||
0x00,0xcc,0x7b,0x00,0x00,0x78,0x7c,0x6c,0x18,0x18,0x18,0x30,0xc6,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xfe,0xc0,0x68,0x68,0x68,0x68,0x18,0x18,0x18,0x18,0xf6,0xfe,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x3c,0xd6,0xc6,0xc6,0xc6,0xc6,0x3c,0x66,0x6c,0x0c,0x0c,0x0c,0x0c,
|
||||
0x0c,0x0c,0x76,0xc6,0xc6,0xc6,0xc6,0xc6,0x18,0x18,0x18,0x18,0x7e,0x66,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x00,0xc4,0xcc,0xcc,0xcc,0xcc,0xc6,0x66,0xc6,0x80,0x00,0x08,0x08,
|
||||
0x24,0x34,0x24,0x3c,0x70,0x48,0x38,0x30,0x40,0x38,0x70,0x70,0x10,0x24,0x24,0x24,
|
||||
0x24,0x12,0x28,0x08,0x12,0xe0,0x24,0x20,0x40,0x38,0x48,0x30,0x00,0x18,0x00,0x6c,
|
||||
0x06,0x18,0xdc,0x00,0x30,0x0c,0xff,0x7e,0x00,0xfe,0x00,0x18,0xd6,0x18,0x30,0x06,
|
||||
0xfe,0x06,0xc6,0x18,0xc6,0x06,0x00,0x00,0x60,0x00,0x06,0x18,0xde,0xfe,0x66,0xc0,
|
||||
0x66,0x68,0x68,0xde,0xc6,0x18,0x0c,0x78,0x60,0xc6,0xce,0xc6,0x60,0xc6,0x6c,0x0c,
|
||||
0x18,0xc6,0xc6,0xd6,0x38,0x18,0x30,0x30,0x38,0x0c,0x00,0x00,0x00,0x7c,0x66,0xc0,
|
||||
0xcc,0xfe,0x60,0xcc,0x66,0x18,0x06,0x78,0x18,0xd6,0x66,0xc6,0x66,0xcc,0x66,0x60,
|
||||
0x30,0xcc,0x66,0xd6,0x38,0xc6,0x18,0x18,0x18,0x18,0x00,0xc6,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,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,0x60,0x60,
|
||||
0x66,0x18,0x18,0xc6,0x00,0xa1,0x00,0xd8,0x06,0x3c,0x44,0x00,0x00,0x18,0x00,0x00,
|
||||
0x00,0xcc,0x1b,0x00,0x00,0x00,0x00,0x36,0x30,0x30,0x30,0x60,0xc6,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xcc,0xc0,0x78,0x78,0x78,0x78,0x18,0x18,0x18,0x18,0x66,0xde,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x18,0xd6,0xc6,0xc6,0xc6,0xc6,0x18,0x66,0x66,0x7c,0x7c,0x7c,0x7c,
|
||||
0x7c,0x7c,0x36,0xc0,0xfe,0xfe,0xfe,0xfe,0x18,0x18,0x18,0x18,0xc6,0x66,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x7e,0xce,0xcc,0xcc,0xcc,0xcc,0xc6,0x66,0xc6,0x82,0x00,0x08,0x08,
|
||||
0x24,0x2c,0x20,0x66,0x07,0x07,0x07,0x07,0x0e,0x00,0x06,0x07,0x10,0x20,0x20,0x20,
|
||||
0x20,0x1e,0x10,0x08,0x1e,0x11,0x24,0x18,0x0e,0x07,0x07,0x07,0x00,0x18,0x00,0x6c,
|
||||
0x06,0x30,0xcc,0x00,0x30,0x0c,0x3c,0x18,0x00,0x00,0x00,0x30,0xc6,0x18,0x60,0x06,
|
||||
0x0c,0x06,0xc6,0x30,0xc6,0x06,0x00,0x00,0x30,0x7e,0x0c,0x18,0xde,0xc6,0x66,0xc0,
|
||||
0x66,0x60,0x60,0xc6,0xc6,0x18,0xcc,0x6c,0x60,0xc6,0xc6,0xc6,0x60,0xc6,0x66,0x06,
|
||||
0x18,0xc6,0xc6,0xd6,0x7c,0x18,0x60,0x30,0x1c,0x0c,0x00,0x00,0x00,0xcc,0x66,0xc0,
|
||||
0xcc,0xc0,0x60,0xcc,0x66,0x18,0x06,0x78,0x18,0xd6,0x66,0xc6,0x66,0xcc,0x60,0x38,
|
||||
0x30,0xcc,0x66,0xd6,0x38,0xc6,0x30,0x18,0x18,0x18,0x00,0xc6,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x60,
|
||||
0x66,0x7e,0x18,0x6c,0x00,0xa5,0x00,0x6c,0x06,0x00,0x38,0x00,0x00,0x18,0x00,0x00,
|
||||
0x00,0xcc,0x1b,0x18,0x00,0x00,0x00,0x6c,0x66,0x60,0x66,0xc0,0xfe,0xfe,0xfe,0xfe,
|
||||
0xfe,0xfe,0xcc,0xc0,0x68,0x68,0x68,0x68,0x18,0x18,0x18,0x18,0x66,0xce,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x3c,0xe6,0xc6,0xc6,0xc6,0xc6,0x18,0x66,0x66,0xcc,0xcc,0xcc,0xcc,
|
||||
0xcc,0xcc,0x7e,0xc0,0xc0,0xc0,0xc0,0xc0,0x18,0x18,0x18,0x18,0xc6,0x66,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x00,0xd6,0xcc,0xcc,0xcc,0xcc,0xc6,0x66,0xc6,0x02,0x00,0x08,0x08,
|
||||
0x24,0x24,0x20,0xc3,0x08,0x02,0x04,0x02,0x08,0x0e,0x09,0x02,0x10,0x20,0x20,0x20,
|
||||
0x20,0x12,0x10,0x08,0x12,0x1b,0x24,0x04,0x10,0x08,0x08,0x08,0x00,0x00,0x00,0xfe,
|
||||
0x86,0x60,0xcc,0x00,0x30,0x0c,0x66,0x18,0x18,0x00,0x00,0x60,0xc6,0x18,0xc0,0x06,
|
||||
0x0c,0x06,0xc6,0x30,0xc6,0x06,0x18,0x18,0x18,0x00,0x18,0x00,0xdc,0xc6,0x66,0xc2,
|
||||
0x66,0x62,0x60,0xc6,0xc6,0x18,0xcc,0x66,0x62,0xc6,0xc6,0xc6,0x60,0xd6,0x66,0xc6,
|
||||
0x18,0xc6,0x6c,0xfe,0x6c,0x18,0xc2,0x30,0x0e,0x0c,0x00,0x00,0x00,0xcc,0x66,0xc0,
|
||||
0xcc,0xc0,0x60,0xcc,0x66,0x18,0x06,0x6c,0x18,0xd6,0x66,0xc6,0x66,0xcc,0x60,0x0c,
|
||||
0x30,0xcc,0x66,0xd6,0x38,0xc6,0x60,0x18,0x18,0x18,0x00,0xc6,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x60,
|
||||
0x3c,0x18,0x18,0x38,0x00,0x99,0x00,0x36,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0xcc,0x1b,0x00,0x00,0x00,0x00,0xd8,0xce,0xdc,0xce,0xc6,0xc6,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xcc,0xc2,0x62,0x62,0x62,0x62,0x18,0x18,0x18,0x18,0x66,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x66,0xe6,0xc6,0xc6,0xc6,0xc6,0x18,0x7c,0x66,0xcc,0xcc,0xcc,0xcc,
|
||||
0xcc,0xcc,0xd8,0xc0,0xc0,0xc0,0xc0,0xc0,0x18,0x18,0x18,0x18,0xc6,0x66,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x18,0xe6,0xcc,0xcc,0xcc,0xcc,0xc6,0x66,0xc6,0x80,0x00,0x08,0x08,
|
||||
0x18,0x24,0x1c,0xff,0x06,0x02,0x07,0x02,0x0e,0x09,0x09,0x02,0x1c,0x1c,0x1c,0x1c,
|
||||
0x1c,0x12,0x10,0x08,0x12,0x15,0x18,0x38,0x0c,0x06,0x06,0x06,0x00,0x18,0x00,0x6c,
|
||||
0xc6,0xc6,0xcc,0x00,0x18,0x18,0x00,0x00,0x18,0x00,0x18,0xc0,0x6c,0x18,0xc6,0xc6,
|
||||
0x0c,0xc6,0xc6,0x30,0xc6,0x0c,0x18,0x18,0x0c,0x00,0x30,0x18,0xc0,0xc6,0x66,0x66,
|
||||
0x6c,0x66,0x60,0x66,0xc6,0x18,0xcc,0x66,0x66,0xc6,0xc6,0xc6,0x60,0xde,0x66,0xc6,
|
||||
0x18,0xc6,0x38,0xee,0xc6,0x18,0xc6,0x30,0x06,0x0c,0x00,0x00,0x00,0xcc,0x66,0xc6,
|
||||
0xcc,0xc6,0x60,0xcc,0x66,0x18,0x06,0x66,0x18,0xd6,0x66,0xc6,0x66,0xcc,0x60,0xc6,
|
||||
0x36,0xcc,0x3c,0xfe,0x6c,0xc6,0xc6,0x18,0x18,0x18,0x00,0xfe,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x18,0xe6,
|
||||
0x66,0x18,0x18,0x0c,0x00,0x42,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,
|
||||
0x00,0xcc,0x1b,0x00,0x00,0x00,0x00,0x00,0x9e,0x86,0x9e,0xc6,0xc6,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xcc,0x66,0x66,0x66,0x66,0x66,0x18,0x18,0x18,0x18,0x6c,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x00,0x46,0xc6,0xc6,0xc6,0xc6,0x18,0x60,0x66,0xcc,0xcc,0xcc,0xcc,
|
||||
0xcc,0xcc,0xd8,0xc6,0xc6,0xc6,0xc6,0xc6,0x18,0x18,0x18,0x18,0xc6,0x66,0xc6,0xc6,
|
||||
0xc6,0xc6,0xc6,0x18,0x46,0xcc,0xcc,0xcc,0xcc,0xc6,0x66,0xc6,0xb6,0x00,0x05,0x05,
|
||||
0x07,0x0c,0x09,0x18,0x01,0x02,0x04,0x02,0x08,0x0e,0x09,0x02,0x07,0x02,0x06,0x06,
|
||||
0x02,0x09,0x09,0x0e,0x09,0x15,0x0e,0x07,0x02,0x01,0x01,0x01,0x00,0x18,0x00,0x6c,
|
||||
0x7c,0x86,0x76,0x00,0x0c,0x30,0x00,0x00,0x18,0x00,0x18,0x80,0x38,0x7e,0xfe,0x7c,
|
||||
0x1e,0x7c,0x7c,0x30,0x7c,0x78,0x00,0x30,0x06,0x00,0x60,0x18,0x7c,0xc6,0xfc,0x3c,
|
||||
0xf8,0xfe,0xf0,0x3a,0xc6,0x3c,0x78,0xe6,0xfe,0xc6,0xc6,0x7c,0xf0,0x7c,0xe6,0x7c,
|
||||
0x3c,0x7c,0x10,0x6c,0xc6,0x3c,0xfe,0x3c,0x02,0x3c,0x00,0x00,0x00,0x76,0x7c,0x7c,
|
||||
0x76,0x7c,0xf0,0x7c,0xe6,0x3c,0x06,0xe6,0x3c,0xc6,0x66,0x7c,0x7c,0x7c,0xf0,0x7c,
|
||||
0x1c,0x76,0x18,0x6c,0xc6,0x7e,0xfe,0x0e,0x18,0x70,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,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,0x18,0xfc,
|
||||
0x00,0x18,0x18,0xc6,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0xf6,0x1b,0x00,0x00,0x00,0x00,0x00,0x3e,0x0c,0x3e,0x7c,0xc6,0xc6,0xc6,0xc6,
|
||||
0xc6,0xc6,0xce,0x3c,0xfe,0xfe,0xfe,0xfe,0x3c,0x3c,0x3c,0x3c,0xf8,0xc6,0x7c,0x7c,
|
||||
0x7c,0x7c,0x7c,0x00,0xbc,0x7c,0x7c,0x7c,0x7c,0x3c,0xf0,0xec,0x76,0x76,0x76,0x76,
|
||||
0x76,0x76,0x6e,0x7c,0x7c,0x7c,0x7c,0x7c,0x3c,0x3c,0x3c,0x3c,0x7c,0x66,0x7c,0x7c,
|
||||
0x7c,0x7c,0x7c,0x00,0xbc,0x76,0x76,0x76,0x76,0x7e,0x7c,0x7e,0x00,0x00,0x05,0x05,
|
||||
0x02,0x12,0x0a,0x00,0x0e,0x02,0x04,0x02,0x08,0x0a,0x06,0x07,0x04,0x06,0x09,0x01,
|
||||
0x06,0x0a,0x0d,0x09,0x0d,0x11,0x09,0x09,0x1c,0x0e,0x0e,0x0e,0x00,0x00,0x00,0x00,
|
||||
0x18,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,0x00,0x0c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x0c,0x00,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x60,0x0c,0x00,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,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0xc0,0x00,0x00,0x18,0x00,0x00,0x00,0x06,0x18,0x06,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x06,0x00,0x00,0x02,0x02,
|
||||
0x02,0x12,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x00,0x07,0x02,0x02,0x06,
|
||||
0x0a,0x0c,0x0b,0x0e,0x0b,0x00,0x0e,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0xcc,0x00,0x00,0x66,0x00,0x00,0x00,0x00,0x00,0x60,0x0c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0xc0,0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x3e,0x06,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x60,0x0c,0x00,0x00,0x05,0x05,
|
||||
0x02,0x16,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x04,0x01,
|
||||
0x1f,0x0a,0x09,0x09,0x09,0x00,0x09,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,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x1e,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0xc0,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xf0,0xf8,0x00,0x00,0x05,0x05,
|
||||
0x02,0x0d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x0f,0x06,
|
||||
0x02,0x09,0x09,0x0e,0x09,0x00,0x0e,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x35,0x36,0x20,
|
||||
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x36,0x20,0x20,0x20,0x20,0x20,0x20,
|
||||
0x20,0x20,0x20,0x20,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
||||
0x00,0x00,0x00,0x0f,0x00,0x08,0x08,0x00,0x00,0x0f,0x00,0x08,0x10,0x00,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x00,0x00,0x0f,0x00,0x08,0x20,0x00,0x00,0x0f,0x00,0x08,0x28,0x00,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x00,0x00,0x0f,0x00,0x08,0x38,0x00,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x00,0x00,0x0f,0x00,0x08,0x48,0x00,0x00,0x0f,0x00,0x08,0x50,0x00,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x00,0x00,0x0f,0x00,0x08,0x60,0x00,0x00,0x0f,0x00,0x08,0x68,0x00,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x00,0x00,0x0f,0x00,0x08,0x78,0x00,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x00,0x00,0x0f,0x00,0x08,0x88,0x00,0x00,0x0f,0x00,0x08,0x90,0x00,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x00,0x00,0x0f,0x00,0x08,0xa0,0x00,0x00,0x0f,0x00,0x08,0xa8,0x00,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x00,0x00,0x0f,0x00,0x08,0xb8,0x00,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x00,0x00,0x0f,0x00,0x08,0xc8,0x00,0x00,0x0f,0x00,0x08,0xd0,0x00,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x00,0x00,0x0f,0x00,0x08,0xe0,0x00,0x00,0x0f,0x00,0x08,0xe8,0x00,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x00,0x00,0x0f,0x00,0x08,0xf8,0x00,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x01,0x00,0x0f,0x00,0x08,0x08,0x01,0x00,0x0f,0x00,0x08,0x10,0x01,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x01,0x00,0x0f,0x00,0x08,0x20,0x01,0x00,0x0f,0x00,0x08,0x28,0x01,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x01,0x00,0x0f,0x00,0x08,0x38,0x01,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x01,0x00,0x0f,0x00,0x08,0x48,0x01,0x00,0x0f,0x00,0x08,0x50,0x01,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x01,0x00,0x0f,0x00,0x08,0x60,0x01,0x00,0x0f,0x00,0x08,0x68,0x01,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x01,0x00,0x0f,0x00,0x08,0x78,0x01,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x01,0x00,0x0f,0x00,0x08,0x88,0x01,0x00,0x0f,0x00,0x08,0x90,0x01,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x01,0x00,0x0f,0x00,0x08,0xa0,0x01,0x00,0x0f,0x00,0x08,0xa8,0x01,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x01,0x00,0x0f,0x00,0x08,0xb8,0x01,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x01,0x00,0x0f,0x00,0x08,0xc8,0x01,0x00,0x0f,0x00,0x08,0xd0,0x01,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x01,0x00,0x0f,0x00,0x08,0xe0,0x01,0x00,0x0f,0x00,0x08,0xe8,0x01,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x01,0x00,0x0f,0x00,0x08,0xf8,0x01,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x02,0x00,0x0f,0x00,0x08,0x08,0x02,0x00,0x0f,0x00,0x08,0x10,0x02,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x02,0x00,0x0f,0x00,0x08,0x20,0x02,0x00,0x0f,0x00,0x08,0x28,0x02,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x02,0x00,0x0f,0x00,0x08,0x38,0x02,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x02,0x00,0x0f,0x00,0x08,0x48,0x02,0x00,0x0f,0x00,0x08,0x50,0x02,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x02,0x00,0x0f,0x00,0x08,0x60,0x02,0x00,0x0f,0x00,0x08,0x68,0x02,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x02,0x00,0x0f,0x00,0x08,0x78,0x02,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x02,0x00,0x0f,0x00,0x08,0x88,0x02,0x00,0x0f,0x00,0x08,0x90,0x02,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x02,0x00,0x0f,0x00,0x08,0xa0,0x02,0x00,0x0f,0x00,0x08,0xa8,0x02,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x02,0x00,0x0f,0x00,0x08,0xb8,0x02,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x02,0x00,0x0f,0x00,0x08,0xc8,0x02,0x00,0x0f,0x00,0x08,0xd0,0x02,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x02,0x00,0x0f,0x00,0x08,0xe0,0x02,0x00,0x0f,0x00,0x08,0xe8,0x02,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x02,0x00,0x0f,0x00,0x08,0xf8,0x02,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x03,0x00,0x0f,0x00,0x08,0x08,0x03,0x00,0x0f,0x00,0x08,0x10,0x03,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x03,0x00,0x0f,0x00,0x08,0x20,0x03,0x00,0x0f,0x00,0x08,0x28,0x03,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x03,0x00,0x0f,0x00,0x08,0x38,0x03,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x03,0x00,0x0f,0x00,0x08,0x48,0x03,0x00,0x0f,0x00,0x08,0x50,0x03,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x03,0x00,0x0f,0x00,0x08,0x60,0x03,0x00,0x0f,0x00,0x08,0x68,0x03,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x03,0x00,0x0f,0x00,0x08,0x78,0x03,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x03,0x00,0x0f,0x00,0x08,0x88,0x03,0x00,0x0f,0x00,0x08,0x90,0x03,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x03,0x00,0x0f,0x00,0x08,0xa0,0x03,0x00,0x0f,0x00,0x08,0xa8,0x03,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x03,0x00,0x0f,0x00,0x08,0xb8,0x03,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x03,0x00,0x0f,0x00,0x08,0xc8,0x03,0x00,0x0f,0x00,0x08,0xd0,0x03,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x03,0x00,0x0f,0x00,0x08,0xe0,0x03,0x00,0x0f,0x00,0x08,0xe8,0x03,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x03,0x00,0x0f,0x00,0x08,0xf8,0x03,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x04,0x00,0x0f,0x00,0x08,0x08,0x04,0x00,0x0f,0x00,0x08,0x10,0x04,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x04,0x00,0x0f,0x00,0x08,0x20,0x04,0x00,0x0f,0x00,0x08,0x28,0x04,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x04,0x00,0x0f,0x00,0x08,0x38,0x04,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x04,0x00,0x0f,0x00,0x08,0x48,0x04,0x00,0x0f,0x00,0x08,0x50,0x04,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x04,0x00,0x0f,0x00,0x08,0x60,0x04,0x00,0x0f,0x00,0x08,0x68,0x04,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x04,0x00,0x0f,0x00,0x08,0x78,0x04,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x04,0x00,0x0f,0x00,0x08,0x88,0x04,0x00,0x0f,0x00,0x08,0x90,0x04,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x04,0x00,0x0f,0x00,0x08,0xa0,0x04,0x00,0x0f,0x00,0x08,0xa8,0x04,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x04,0x00,0x0f,0x00,0x08,0xb8,0x04,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x04,0x00,0x0f,0x00,0x08,0xc8,0x04,0x00,0x0f,0x00,0x08,0xd0,0x04,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x04,0x00,0x0f,0x00,0x08,0xe0,0x04,0x00,0x0f,0x00,0x08,0xe8,0x04,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x04,0x00,0x0f,0x00,0x08,0xf8,0x04,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x05,0x00,0x0f,0x00,0x08,0x08,0x05,0x00,0x0f,0x00,0x08,0x10,0x05,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x05,0x00,0x0f,0x00,0x08,0x20,0x05,0x00,0x0f,0x00,0x08,0x28,0x05,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x05,0x00,0x0f,0x00,0x08,0x38,0x05,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x05,0x00,0x0f,0x00,0x08,0x48,0x05,0x00,0x0f,0x00,0x08,0x50,0x05,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x05,0x00,0x0f,0x00,0x08,0x60,0x05,0x00,0x0f,0x00,0x08,0x68,0x05,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x05,0x00,0x0f,0x00,0x08,0x78,0x05,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x05,0x00,0x0f,0x00,0x08,0x88,0x05,0x00,0x0f,0x00,0x08,0x90,0x05,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x05,0x00,0x0f,0x00,0x08,0xa0,0x05,0x00,0x0f,0x00,0x08,0xa8,0x05,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x05,0x00,0x0f,0x00,0x08,0xb8,0x05,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x05,0x00,0x0f,0x00,0x08,0xc8,0x05,0x00,0x0f,0x00,0x08,0xd0,0x05,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x05,0x00,0x0f,0x00,0x08,0xe0,0x05,0x00,0x0f,0x00,0x08,0xe8,0x05,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x05,0x00,0x0f,0x00,0x08,0xf8,0x05,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x06,0x00,0x0f,0x00,0x08,0x08,0x06,0x00,0x0f,0x00,0x08,0x10,0x06,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x06,0x00,0x0f,0x00,0x08,0x20,0x06,0x00,0x0f,0x00,0x08,0x28,0x06,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x06,0x00,0x0f,0x00,0x08,0x38,0x06,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x06,0x00,0x0f,0x00,0x08,0x48,0x06,0x00,0x0f,0x00,0x08,0x50,0x06,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x06,0x00,0x0f,0x00,0x08,0x60,0x06,0x00,0x0f,0x00,0x08,0x68,0x06,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x06,0x00,0x0f,0x00,0x08,0x78,0x06,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x06,0x00,0x0f,0x00,0x08,0x88,0x06,0x00,0x0f,0x00,0x08,0x90,0x06,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x06,0x00,0x0f,0x00,0x08,0xa0,0x06,0x00,0x0f,0x00,0x08,0xa8,0x06,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x06,0x00,0x0f,0x00,0x08,0xb8,0x06,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x06,0x00,0x0f,0x00,0x08,0xc8,0x06,0x00,0x0f,0x00,0x08,0xd0,0x06,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x06,0x00,0x0f,0x00,0x08,0xe0,0x06,0x00,0x0f,0x00,0x08,0xe8,0x06,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x06,0x00,0x0f,0x00,0x08,0xf8,0x06,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x07,0x00,0x0f,0x00,0x08,0x08,0x07,0x00,0x0f,0x00,0x08,0x10,0x07,0x00,0x0f,
|
||||
0x00,0x08,0x18,0x07,0x00,0x0f,0x00,0x08,0x20,0x07,0x00,0x0f,0x00,0x08,0x28,0x07,
|
||||
0x00,0x0f,0x00,0x08,0x30,0x07,0x00,0x0f,0x00,0x08,0x38,0x07,0x00,0x0f,0x00,0x08,
|
||||
0x40,0x07,0x00,0x0f,0x00,0x08,0x48,0x07,0x00,0x0f,0x00,0x08,0x50,0x07,0x00,0x0f,
|
||||
0x00,0x08,0x58,0x07,0x00,0x0f,0x00,0x08,0x60,0x07,0x00,0x0f,0x00,0x08,0x68,0x07,
|
||||
0x00,0x0f,0x00,0x08,0x70,0x07,0x00,0x0f,0x00,0x08,0x78,0x07,0x00,0x0f,0x00,0x08,
|
||||
0x80,0x07,0x00,0x0f,0x00,0x08,0x88,0x07,0x00,0x0f,0x00,0x08,0x90,0x07,0x00,0x0f,
|
||||
0x00,0x08,0x98,0x07,0x00,0x0f,0x00,0x08,0xa0,0x07,0x00,0x0f,0x00,0x08,0xa8,0x07,
|
||||
0x00,0x0f,0x00,0x08,0xb0,0x07,0x00,0x0f,0x00,0x08,0xb8,0x07,0x00,0x0f,0x00,0x08,
|
||||
0xc0,0x07,0x00,0x0f,0x00,0x08,0xc8,0x07,0x00,0x0f,0x00,0x08,0xd0,0x07,0x00,0x0f,
|
||||
0x00,0x08,0xd8,0x07,0x00,0x0f,0x00,0x08,0xe0,0x07,0x00,0x0f,0x00,0x08,0xe8,0x07,
|
||||
0x00,0x0f,0x00,0x08,0xf0,0x07,0x00,0x0f,0x00,0x08,0xf8,0x07,0x00,0x0f,0x00,0x08,
|
||||
0x00,0x08,0x00,0x0f,0x00,0x08,
|
||||
};
|
||||
|
||||
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
nudraw/draw.c
Normal file
69
nudraw/draw.c
Normal 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 == nil)
|
||||
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 == nil)
|
||||
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
nudraw/drawrepl.c
Normal file
23
nudraw/drawrepl.c
Normal 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;
|
||||
}
|
||||
|
227
nudraw/eenter.c
Normal file
227
nudraw/eenter.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <event.h>
|
||||
#include <keyboard.h>
|
||||
|
||||
int
|
||||
eenter(char *ask, char *buf, int len, Mouse *m)
|
||||
{
|
||||
int done, down, tick, n, h, w, l, i;
|
||||
Image *b, *save, *backcol, *bordcol;
|
||||
Point p, o, t;
|
||||
Rectangle r, sc;
|
||||
Event ev;
|
||||
Rune k;
|
||||
|
||||
o = screen->r.min;
|
||||
backcol = allocimagemix(display, DPurpleblue, DWhite);
|
||||
bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
|
||||
if(backcol == nil || bordcol == nil)
|
||||
return -1;
|
||||
|
||||
while(ecankbd())
|
||||
ekbd();
|
||||
|
||||
if(m) o = m->xy;
|
||||
|
||||
if(buf && len > 0)
|
||||
n = strlen(buf);
|
||||
else {
|
||||
buf = nil;
|
||||
len = 0;
|
||||
n = 0;
|
||||
}
|
||||
|
||||
k = -1;
|
||||
tick = n;
|
||||
save = nil;
|
||||
done = down = 0;
|
||||
|
||||
p = stringsize(font, " ");
|
||||
h = p.y;
|
||||
w = p.x;
|
||||
|
||||
b = screen;
|
||||
sc = b->clipr;
|
||||
replclipr(b, 0, b->r);
|
||||
|
||||
while(!done){
|
||||
p = stringsize(font, buf ? buf : "");
|
||||
if(ask && ask[0]){
|
||||
if(buf) p.x += w;
|
||||
p.x += stringwidth(font, ask);
|
||||
}
|
||||
r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
|
||||
p.x = 0;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
p = ZP;
|
||||
if(r.min.x < screen->r.min.x)
|
||||
p.x = screen->r.min.x - r.min.x;
|
||||
if(r.min.y < screen->r.min.y)
|
||||
p.y = screen->r.min.y - r.min.y;
|
||||
r = rectaddpt(r, p);
|
||||
p = ZP;
|
||||
if(r.max.x > screen->r.max.x)
|
||||
p.x = r.max.x - screen->r.max.x;
|
||||
if(r.max.y > screen->r.max.y)
|
||||
p.y = r.max.y - screen->r.max.y;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
r = insetrect(r, -2);
|
||||
if(save == nil){
|
||||
save = allocimage(display, r, b->chan, 0, DNofill);
|
||||
if(save == nil){
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
draw(save, r, b, nil, r.min);
|
||||
}
|
||||
draw(b, r, backcol, nil, ZP);
|
||||
border(b, r, 2, bordcol, ZP);
|
||||
p = addpt(r.min, Pt(6, 6));
|
||||
if(ask && ask[0]){
|
||||
p = string(b, p, bordcol, ZP, font, ask);
|
||||
if(buf) p.x += w;
|
||||
}
|
||||
if(buf){
|
||||
t = p;
|
||||
p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick));
|
||||
draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
|
||||
p = string(b, p, display->black, ZP, font, buf+tick);
|
||||
}
|
||||
flushimage(display, 1);
|
||||
|
||||
nodraw:
|
||||
i = Ekeyboard;
|
||||
if(m != nil)
|
||||
i |= Emouse;
|
||||
|
||||
replclipr(b, 0, sc);
|
||||
i = eread(i, &ev);
|
||||
|
||||
/* screen might have been resized */
|
||||
if(b != screen || !eqrect(screen->clipr, sc)){
|
||||
freeimage(save);
|
||||
save = nil;
|
||||
}
|
||||
b = screen;
|
||||
sc = b->clipr;
|
||||
replclipr(b, 0, b->r);
|
||||
|
||||
switch(i){
|
||||
default:
|
||||
done = 1;
|
||||
n = -1;
|
||||
break;
|
||||
case Ekeyboard:
|
||||
k = ev.kbdc;
|
||||
if(buf == nil || k == Keof || k == '\n'){
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
if(k == Knack || k == Kesc){
|
||||
done = !n;
|
||||
buf[n = tick = 0] = 0;
|
||||
break;
|
||||
}
|
||||
if(k == Ksoh || k == Khome){
|
||||
tick = 0;
|
||||
continue;
|
||||
}
|
||||
if(k == Kenq || k == Kend){
|
||||
tick = n;
|
||||
continue;
|
||||
}
|
||||
if(k == Kright){
|
||||
if(tick < n)
|
||||
tick += chartorune(&k, buf+tick);
|
||||
continue;
|
||||
}
|
||||
if(k == Kleft){
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
if(i+l >= tick){
|
||||
tick = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(k == Ketb){
|
||||
l = tick;
|
||||
while(tick > 0){
|
||||
tick--;
|
||||
if(tick == 0 ||
|
||||
strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1]))
|
||||
break;
|
||||
}
|
||||
memmove(buf+tick, buf+l, n-l);
|
||||
buf[n -= l-tick] = 0;
|
||||
break;
|
||||
}
|
||||
if(k == Kbs){
|
||||
if(tick <= 0)
|
||||
continue;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
if(i+l >= tick){
|
||||
memmove(buf+i, buf+i+l, n - (i+l));
|
||||
buf[n -= l] = 0;
|
||||
tick -= l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
|
||||
continue;
|
||||
if((len-n) <= (l = runelen(k)))
|
||||
continue;
|
||||
memmove(buf+tick+l, buf+tick, n - tick);
|
||||
runetochar(buf+tick, &k);
|
||||
buf[n += l] = 0;
|
||||
tick += l;
|
||||
break;
|
||||
case Emouse:
|
||||
*m = ev.mouse;
|
||||
if(!ptinrect(m->xy, r)){
|
||||
down = 0;
|
||||
goto nodraw;
|
||||
}
|
||||
if(m->buttons & 7){
|
||||
down = 1;
|
||||
if(buf && m->xy.x >= (t.x - w)){
|
||||
down = 0;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
t.x += stringnwidth(font, buf+i, 1);
|
||||
if(t.x > m->xy.x)
|
||||
break;
|
||||
}
|
||||
tick = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = down;
|
||||
break;
|
||||
}
|
||||
if(save){
|
||||
draw(b, save->r, save, nil, save->r.min);
|
||||
freeimage(save);
|
||||
save = nil;
|
||||
}
|
||||
}
|
||||
|
||||
replclipr(b, 0, sc);
|
||||
|
||||
freeimage(backcol);
|
||||
freeimage(bordcol);
|
||||
flushimage(display, 1);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
116
nudraw/egetrect.c
Normal file
116
nudraw/egetrect.c
Normal 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);
|
||||
}
|
||||
}
|
82
nudraw/ellipse.c
Normal file
82
nudraw/ellipse.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
static
|
||||
void
|
||||
doellipse(int cmd, Image *dst, Point *c, int xr, int yr, int thick, Image *src, Point *sp, int alpha, int phi, Drawop op)
|
||||
{
|
||||
uchar *a;
|
||||
|
||||
_setdrawop(dst->display, op);
|
||||
|
||||
a = bufimage(dst->display, 1+4+4+2*4+4+4+4+2*4+2*4);
|
||||
if(a == nil){
|
||||
fprint(2, "image ellipse: %r\n");
|
||||
return;
|
||||
}
|
||||
a[0] = cmd;
|
||||
BPLONG(a+1, dst->id);
|
||||
BPLONG(a+5, src->id);
|
||||
BPLONG(a+9, c->x);
|
||||
BPLONG(a+13, c->y);
|
||||
BPLONG(a+17, xr);
|
||||
BPLONG(a+21, yr);
|
||||
BPLONG(a+25, thick);
|
||||
BPLONG(a+29, sp->x);
|
||||
BPLONG(a+33, sp->y);
|
||||
BPLONG(a+37, alpha);
|
||||
BPLONG(a+41, phi);
|
||||
}
|
||||
|
||||
void
|
||||
ellipse(Image *dst, Point c, int a, int b, int thick, Image *src, Point sp)
|
||||
{
|
||||
doellipse('e', dst, &c, a, b, thick, src, &sp, 0, 0, SoverD);
|
||||
}
|
||||
|
||||
void
|
||||
ellipseop(Image *dst, Point c, int a, int b, int thick, Image *src, Point sp, Drawop op)
|
||||
{
|
||||
doellipse('e', dst, &c, a, b, thick, src, &sp, 0, 0, op);
|
||||
}
|
||||
|
||||
void
|
||||
fillellipse(Image *dst, Point c, int a, int b, Image *src, Point sp)
|
||||
{
|
||||
doellipse('E', dst, &c, a, b, 0, src, &sp, 0, 0, SoverD);
|
||||
}
|
||||
|
||||
void
|
||||
fillellipseop(Image *dst, Point c, int a, int b, Image *src, Point sp, Drawop op)
|
||||
{
|
||||
doellipse('E', dst, &c, a, b, 0, src, &sp, 0, 0, op);
|
||||
}
|
||||
|
||||
void
|
||||
arc(Image *dst, Point c, int a, int b, int thick, Image *src, Point sp, int alpha, int phi)
|
||||
{
|
||||
alpha |= 1<<31;
|
||||
doellipse('e', dst, &c, a, b, thick, src, &sp, alpha, phi, SoverD);
|
||||
}
|
||||
|
||||
void
|
||||
arcop(Image *dst, Point c, int a, int b, int thick, Image *src, Point sp, int alpha, int phi, Drawop op)
|
||||
{
|
||||
alpha |= 1<<31;
|
||||
doellipse('e', dst, &c, a, b, thick, src, &sp, alpha, phi, op);
|
||||
}
|
||||
|
||||
void
|
||||
fillarc(Image *dst, Point c, int a, int b, Image *src, Point sp, int alpha, int phi)
|
||||
{
|
||||
alpha |= 1<<31;
|
||||
doellipse('E', dst, &c, a, b, 0, src, &sp, alpha, phi, SoverD);
|
||||
}
|
||||
|
||||
void
|
||||
fillarcop(Image *dst, Point c, int a, int b, Image *src, Point sp, int alpha, int phi, Drawop op)
|
||||
{
|
||||
alpha |= 1<<31;
|
||||
doellipse('E', dst, &c, a, b, 0, src, &sp, alpha, phi, op);
|
||||
}
|
269
nudraw/emenuhit.c
Normal file
269
nudraw/emenuhit.c
Normal file
|
@ -0,0 +1,269 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <event.h>
|
||||
|
||||
enum
|
||||
{
|
||||
Margin = 4, /* outside to text */
|
||||
Border = 2, /* outside to selection boxes */
|
||||
Blackborder = 2, /* width of outlining border */
|
||||
Vspacing = 2, /* extra spacing between lines of text */
|
||||
Maxunscroll = 25, /* maximum #entries before scrolling turns on */
|
||||
Nscroll = 20, /* number entries in scrolling part */
|
||||
Scrollwid = 14, /* width of scroll bar */
|
||||
Gap = 4, /* between text and scroll bar */
|
||||
};
|
||||
|
||||
static Image *menutxt;
|
||||
static Image *back;
|
||||
static Image *high;
|
||||
static Image *bord;
|
||||
static Image *text;
|
||||
static Image *htext;
|
||||
|
||||
static
|
||||
void
|
||||
menucolors(void)
|
||||
{
|
||||
/* Main tone is greenish, with negative selection */
|
||||
back = allocimagemix(display, DPalegreen, DWhite);
|
||||
high = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen); /* dark green */
|
||||
bord = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DMedgreen); /* not as dark green */
|
||||
if(back==nil || high==nil || bord==nil)
|
||||
goto Error;
|
||||
text = display->black;
|
||||
htext = back;
|
||||
return;
|
||||
|
||||
Error:
|
||||
freeimage(back);
|
||||
freeimage(high);
|
||||
freeimage(bord);
|
||||
back = display->white;
|
||||
high = display->black;
|
||||
bord = display->black;
|
||||
text = display->black;
|
||||
htext = display->white;
|
||||
}
|
||||
|
||||
/*
|
||||
* r is a rectangle holding the text elements.
|
||||
* return the rectangle, including its black edge, holding element i.
|
||||
*/
|
||||
static Rectangle
|
||||
menurect(Rectangle r, int i)
|
||||
{
|
||||
if(i < 0)
|
||||
return Rect(0, 0, 0, 0);
|
||||
r.min.y += (font->height+Vspacing)*i;
|
||||
r.max.y = r.min.y+font->height+Vspacing;
|
||||
return insetrect(r, Border-Margin);
|
||||
}
|
||||
|
||||
/*
|
||||
* r is a rectangle holding the text elements.
|
||||
* return the element number containing p.
|
||||
*/
|
||||
static int
|
||||
menusel(Rectangle r, Point p)
|
||||
{
|
||||
if(!ptinrect(p, r))
|
||||
return -1;
|
||||
return (p.y-r.min.y)/(font->height+Vspacing);
|
||||
}
|
||||
|
||||
static void
|
||||
paintitem(Menu *menu, Rectangle textr, int off, int i, int highlight, Image *save, Image *restore)
|
||||
{
|
||||
char *item;
|
||||
Rectangle r;
|
||||
Point pt;
|
||||
|
||||
if(i < 0)
|
||||
return;
|
||||
r = menurect(textr, i);
|
||||
if(restore){
|
||||
draw(screen, r, restore, nil, restore->r.min);
|
||||
return;
|
||||
}
|
||||
if(save)
|
||||
draw(save, save->r, screen, nil, r.min);
|
||||
item = menu->item? menu->item[i+off] : (*menu->gen)(i+off);
|
||||
pt.x = (textr.min.x+textr.max.x-stringwidth(font, item))/2;
|
||||
pt.y = textr.min.y+i*(font->height+Vspacing);
|
||||
draw(screen, r, highlight? high : back, nil, pt);
|
||||
string(screen, pt, highlight? htext : text, pt, font, item);
|
||||
}
|
||||
|
||||
/*
|
||||
* menur is a rectangle holding all the highlightable text elements.
|
||||
* track mouse while inside the box, return what's selected when button
|
||||
* is raised, -1 as soon as it leaves box.
|
||||
* invariant: nothing is highlighted on entry or exit.
|
||||
*/
|
||||
static int
|
||||
menuscan(Menu *menu, int but, Mouse *m, Rectangle textr, int off, int lasti, Image *save)
|
||||
{
|
||||
int i;
|
||||
|
||||
paintitem(menu, textr, off, lasti, 1, save, nil);
|
||||
flushimage(display, 1); /* in case display->locking is set */
|
||||
*m = emouse();
|
||||
while(m->buttons & (1<<(but-1))){
|
||||
flushimage(display, 1); /* in case display->locking is set */
|
||||
*m = emouse();
|
||||
i = menusel(textr, m->xy);
|
||||
if(i != -1 && i == lasti)
|
||||
continue;
|
||||
paintitem(menu, textr, off, lasti, 0, nil, save);
|
||||
if(i == -1)
|
||||
return i;
|
||||
lasti = i;
|
||||
paintitem(menu, textr, off, lasti, 1, save, nil);
|
||||
}
|
||||
return lasti;
|
||||
}
|
||||
|
||||
static void
|
||||
menupaint(Menu *menu, Rectangle textr, int off, int nitemdrawn)
|
||||
{
|
||||
int i;
|
||||
|
||||
draw(screen, insetrect(textr, Border-Margin), back, nil, ZP);
|
||||
for(i = 0; i<nitemdrawn; i++)
|
||||
paintitem(menu, textr, off, i, 0, nil, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
menuscrollpaint(Rectangle scrollr, int off, int nitem, int nitemdrawn)
|
||||
{
|
||||
Rectangle r;
|
||||
|
||||
draw(screen, scrollr, back, nil, ZP);
|
||||
r.min.x = scrollr.min.x;
|
||||
r.max.x = scrollr.max.x;
|
||||
r.min.y = scrollr.min.y + (Dy(scrollr)*off)/nitem;
|
||||
r.max.y = scrollr.min.y + (Dy(scrollr)*(off+nitemdrawn))/nitem;
|
||||
if(r.max.y < r.min.y+2)
|
||||
r.max.y = r.min.y+2;
|
||||
border(screen, r, 1, bord, ZP);
|
||||
if(menutxt == 0)
|
||||
menutxt = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, DDarkgreen);
|
||||
if(menutxt)
|
||||
draw(screen, insetrect(r, 1), menutxt, nil, ZP);
|
||||
}
|
||||
|
||||
int
|
||||
emenuhit(int but, Mouse *m, Menu *menu)
|
||||
{
|
||||
int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem;
|
||||
int scrolling;
|
||||
Rectangle r, menur, sc, textr, scrollr;
|
||||
Image *b, *save;
|
||||
Point pt;
|
||||
char *item;
|
||||
|
||||
if(back == nil)
|
||||
menucolors();
|
||||
sc = screen->clipr;
|
||||
replclipr(screen, 0, screen->r);
|
||||
maxwid = 0;
|
||||
for(nitem = 0;
|
||||
item = menu->item? menu->item[nitem] : (*menu->gen)(nitem);
|
||||
nitem++){
|
||||
i = stringwidth(font, item);
|
||||
if(i > maxwid)
|
||||
maxwid = i;
|
||||
}
|
||||
if(menu->lasthit<0 || menu->lasthit>=nitem)
|
||||
menu->lasthit = 0;
|
||||
screenitem = (Dy(screen->r)-10)/(font->height+Vspacing);
|
||||
if(nitem>Maxunscroll || nitem>screenitem){
|
||||
scrolling = 1;
|
||||
nitemdrawn = Nscroll;
|
||||
if(nitemdrawn > screenitem)
|
||||
nitemdrawn = screenitem;
|
||||
wid = maxwid + Gap + Scrollwid;
|
||||
off = menu->lasthit - nitemdrawn/2;
|
||||
if(off < 0)
|
||||
off = 0;
|
||||
if(off > nitem-nitemdrawn)
|
||||
off = nitem-nitemdrawn;
|
||||
lasti = menu->lasthit-off;
|
||||
}else{
|
||||
scrolling = 0;
|
||||
nitemdrawn = nitem;
|
||||
wid = maxwid;
|
||||
off = 0;
|
||||
lasti = menu->lasthit;
|
||||
}
|
||||
r = insetrect(Rect(0, 0, wid, nitemdrawn*(font->height+Vspacing)), -Margin);
|
||||
r = rectsubpt(r, Pt(wid/2, lasti*(font->height+Vspacing)+font->height/2));
|
||||
r = rectaddpt(r, m->xy);
|
||||
pt = ZP;
|
||||
if(r.max.x>screen->r.max.x)
|
||||
pt.x = screen->r.max.x-r.max.x;
|
||||
if(r.max.y>screen->r.max.y)
|
||||
pt.y = screen->r.max.y-r.max.y;
|
||||
if(r.min.x<screen->r.min.x)
|
||||
pt.x = screen->r.min.x-r.min.x;
|
||||
if(r.min.y<screen->r.min.y)
|
||||
pt.y = screen->r.min.y-r.min.y;
|
||||
menur = rectaddpt(r, pt);
|
||||
textr.max.x = menur.max.x-Margin;
|
||||
textr.min.x = textr.max.x-maxwid;
|
||||
textr.min.y = menur.min.y+Margin;
|
||||
textr.max.y = textr.min.y + nitemdrawn*(font->height+Vspacing);
|
||||
if(scrolling){
|
||||
scrollr = insetrect(menur, Border);
|
||||
scrollr.max.x = scrollr.min.x+Scrollwid;
|
||||
}else
|
||||
scrollr = Rect(0, 0, 0, 0);
|
||||
|
||||
b = allocimage(display, menur, screen->chan, 0, 0);
|
||||
if(b == 0)
|
||||
b = screen;
|
||||
draw(b, menur, screen, nil, menur.min);
|
||||
draw(screen, menur, back, nil, ZP);
|
||||
border(screen, menur, Blackborder, bord, ZP);
|
||||
save = allocimage(display, menurect(textr, 0), screen->chan, 0, -1);
|
||||
r = menurect(textr, lasti);
|
||||
if(pt.x || pt.y)
|
||||
emoveto(divpt(addpt(r.min, r.max), 2));
|
||||
menupaint(menu, textr, off, nitemdrawn);
|
||||
if(scrolling)
|
||||
menuscrollpaint(scrollr, off, nitem, nitemdrawn);
|
||||
while(m->buttons & (1<<(but-1))){
|
||||
lasti = menuscan(menu, but, m, textr, off, lasti, save);
|
||||
if(lasti >= 0)
|
||||
break;
|
||||
while(!ptinrect(m->xy, textr) && (m->buttons & (1<<(but-1)))){
|
||||
if(scrolling && ptinrect(m->xy, scrollr)){
|
||||
noff = ((m->xy.y-scrollr.min.y)*nitem)/Dy(scrollr);
|
||||
noff -= nitemdrawn/2;
|
||||
if(noff < 0)
|
||||
noff = 0;
|
||||
if(noff > nitem-nitemdrawn)
|
||||
noff = nitem-nitemdrawn;
|
||||
if(noff != off){
|
||||
off = noff;
|
||||
menupaint(menu, textr, off, nitemdrawn);
|
||||
menuscrollpaint(scrollr, off, nitem, nitemdrawn);
|
||||
}
|
||||
}
|
||||
flushimage(display, 1); /* in case display->locking is set */
|
||||
*m = emouse();
|
||||
}
|
||||
}
|
||||
draw(screen, menur, b, nil, menur.min);
|
||||
if(b != screen)
|
||||
freeimage(b);
|
||||
freeimage(save);
|
||||
replclipr(screen, 0, sc);
|
||||
if(lasti >= 0){
|
||||
menu->lasthit = lasti+off;
|
||||
return menu->lasthit;
|
||||
}
|
||||
return -1;
|
||||
}
|
237
nudraw/enter.c
Normal file
237
nudraw/enter.c
Normal file
|
@ -0,0 +1,237 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <thread.h>
|
||||
#include <mouse.h>
|
||||
#include <keyboard.h>
|
||||
|
||||
int
|
||||
enter(char *ask, char *buf, int len, Mousectl *mc, Keyboardctl *kc, Screen *scr)
|
||||
{
|
||||
int done, down, tick, n, h, w, l, i;
|
||||
Image *b, *save, *backcol, *bordcol;
|
||||
Point p, o, t;
|
||||
Rectangle r, sc;
|
||||
Alt a[3];
|
||||
Mouse m;
|
||||
Rune k;
|
||||
|
||||
o = screen->r.min;
|
||||
backcol = allocimagemix(display, DPurpleblue, DWhite);
|
||||
bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
|
||||
if(backcol == nil || bordcol == nil)
|
||||
return -1;
|
||||
|
||||
sc = screen->clipr;
|
||||
replclipr(screen, 0, screen->r);
|
||||
|
||||
n = 0;
|
||||
if(kc){
|
||||
while(nbrecv(kc->c, nil) == 1)
|
||||
;
|
||||
a[n].op = CHANRCV;
|
||||
a[n].c = kc->c;
|
||||
a[n].v = &k;
|
||||
n++;
|
||||
}
|
||||
if(mc){
|
||||
o = mc->xy;
|
||||
a[n].op = CHANRCV;
|
||||
a[n].c = mc->c;
|
||||
a[n].v = &m;
|
||||
n++;
|
||||
}
|
||||
a[n].op = CHANEND;
|
||||
a[n].c = nil;
|
||||
a[n].v = nil;
|
||||
|
||||
if(buf && len > 0)
|
||||
n = strlen(buf);
|
||||
else {
|
||||
buf = nil;
|
||||
len = 0;
|
||||
n = 0;
|
||||
}
|
||||
|
||||
k = -1;
|
||||
b = nil;
|
||||
tick = n;
|
||||
save = nil;
|
||||
done = down = 0;
|
||||
|
||||
p = stringsize(font, " ");
|
||||
h = p.y;
|
||||
w = p.x;
|
||||
|
||||
while(!done){
|
||||
p = stringsize(font, buf ? buf : "");
|
||||
if(ask && ask[0]){
|
||||
if(buf) p.x += w;
|
||||
p.x += stringwidth(font, ask);
|
||||
}
|
||||
r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
|
||||
p.x = 0;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
p = ZP;
|
||||
if(r.min.x < screen->r.min.x)
|
||||
p.x = screen->r.min.x - r.min.x;
|
||||
if(r.min.y < screen->r.min.y)
|
||||
p.y = screen->r.min.y - r.min.y;
|
||||
r = rectaddpt(r, p);
|
||||
p = ZP;
|
||||
if(r.max.x > screen->r.max.x)
|
||||
p.x = r.max.x - screen->r.max.x;
|
||||
if(r.max.y > screen->r.max.y)
|
||||
p.y = r.max.y - screen->r.max.y;
|
||||
r = rectsubpt(r, p);
|
||||
|
||||
r = insetrect(r, -2);
|
||||
if(scr){
|
||||
if(b == nil)
|
||||
b = allocwindow(scr, r, Refbackup, DWhite);
|
||||
if(b == nil)
|
||||
scr = nil;
|
||||
}
|
||||
if(scr == nil && save == nil){
|
||||
if(b == nil)
|
||||
b = screen;
|
||||
save = allocimage(display, r, b->chan, 0, DNofill);
|
||||
if(save == nil){
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
draw(save, r, b, nil, r.min);
|
||||
}
|
||||
draw(b, r, backcol, nil, ZP);
|
||||
border(b, r, 2, bordcol, ZP);
|
||||
p = addpt(r.min, Pt(6, 6));
|
||||
if(ask && ask[0]){
|
||||
p = string(b, p, bordcol, ZP, font, ask);
|
||||
if(buf) p.x += w;
|
||||
}
|
||||
if(buf){
|
||||
t = p;
|
||||
p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick));
|
||||
draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
|
||||
draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
|
||||
p = string(b, p, display->black, ZP, font, buf+tick);
|
||||
}
|
||||
flushimage(display, 1);
|
||||
|
||||
nodraw:
|
||||
switch(alt(a)){
|
||||
case -1:
|
||||
done = 1;
|
||||
n = -1;
|
||||
break;
|
||||
case 0:
|
||||
if(buf == nil || k == Keof || k == '\n'){
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
if(k == Knack || k == Kesc){
|
||||
done = !n;
|
||||
buf[n = tick = 0] = 0;
|
||||
break;
|
||||
}
|
||||
if(k == Ksoh || k == Khome){
|
||||
tick = 0;
|
||||
continue;
|
||||
}
|
||||
if(k == Kenq || k == Kend){
|
||||
tick = n;
|
||||
continue;
|
||||
}
|
||||
if(k == Kright){
|
||||
if(tick < n)
|
||||
tick += chartorune(&k, buf+tick);
|
||||
continue;
|
||||
}
|
||||
if(k == Kleft){
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
if(i+l >= tick){
|
||||
tick = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(k == Ketb){
|
||||
l = tick;
|
||||
while(tick > 0){
|
||||
tick--;
|
||||
if(tick == 0 ||
|
||||
strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1]))
|
||||
break;
|
||||
}
|
||||
memmove(buf+tick, buf+l, n-l);
|
||||
buf[n -= l-tick] = 0;
|
||||
break;
|
||||
}
|
||||
if(k == Kbs){
|
||||
if(tick <= 0)
|
||||
continue;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
if(i+l >= tick){
|
||||
memmove(buf+i, buf+i+l, n - (i+l));
|
||||
buf[n -= l] = 0;
|
||||
tick -= l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
|
||||
continue;
|
||||
if((len-n) <= (l = runelen(k)))
|
||||
continue;
|
||||
memmove(buf+tick+l, buf+tick, n - tick);
|
||||
runetochar(buf+tick, &k);
|
||||
buf[n += l] = 0;
|
||||
tick += l;
|
||||
break;
|
||||
case 1:
|
||||
if(!ptinrect(m.xy, r)){
|
||||
down = 0;
|
||||
goto nodraw;
|
||||
}
|
||||
if(m.buttons & 7){
|
||||
down = 1;
|
||||
if(buf && m.xy.x >= (t.x - w)){
|
||||
down = 0;
|
||||
for(i = 0; i < n; i += l){
|
||||
l = chartorune(&k, buf+i);
|
||||
t.x += stringnwidth(font, buf+i, 1);
|
||||
if(t.x > m.xy.x)
|
||||
break;
|
||||
}
|
||||
tick = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = down;
|
||||
break;
|
||||
}
|
||||
|
||||
if(b != screen) {
|
||||
freeimage(b);
|
||||
b = nil;
|
||||
} else {
|
||||
draw(b, save->r, save, nil, save->r.min);
|
||||
freeimage(save);
|
||||
save = nil;
|
||||
}
|
||||
}
|
||||
|
||||
replclipr(screen, 0, sc);
|
||||
|
||||
freeimage(backcol);
|
||||
freeimage(bordcol);
|
||||
flushimage(display, 1);
|
||||
|
||||
return n;
|
||||
}
|
472
nudraw/event.c
Normal file
472
nudraw/event.c
Normal file
|
@ -0,0 +1,472 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <cursor.h>
|
||||
#include <event.h>
|
||||
|
||||
typedef struct Slave Slave;
|
||||
typedef struct Ebuf Ebuf;
|
||||
|
||||
struct Slave
|
||||
{
|
||||
int pid;
|
||||
Ebuf *head; /* queue of messages for this descriptor */
|
||||
Ebuf *tail;
|
||||
int (*fn)(int, Event*, uchar*, int);
|
||||
};
|
||||
|
||||
struct Ebuf
|
||||
{
|
||||
Ebuf *next;
|
||||
int n; /* number of bytes in buf */
|
||||
uchar buf[EMAXMSG];
|
||||
};
|
||||
|
||||
static Slave eslave[MAXSLAVE];
|
||||
static int Skeyboard = -1;
|
||||
static int Smouse = -1;
|
||||
static int Stimer = -1;
|
||||
static int logfid;
|
||||
|
||||
static int nslave;
|
||||
static int parentpid;
|
||||
static int epipe[2];
|
||||
|
||||
static int eforkslave(ulong);
|
||||
static void extract(void);
|
||||
static void ekill(void);
|
||||
static int enote(void *, char *);
|
||||
|
||||
static int mousefd;
|
||||
static int cursorfd;
|
||||
|
||||
static
|
||||
Ebuf*
|
||||
ebread(Slave *s)
|
||||
{
|
||||
Ebuf *eb;
|
||||
|
||||
while((eb = s->head) == 0)
|
||||
extract();
|
||||
s->head = eb->next;
|
||||
if(s->head == 0)
|
||||
s->tail = 0;
|
||||
return eb;
|
||||
}
|
||||
|
||||
ulong
|
||||
event(Event *e)
|
||||
{
|
||||
return eread(~0UL, e);
|
||||
}
|
||||
|
||||
ulong
|
||||
eread(ulong keys, Event *e)
|
||||
{
|
||||
Ebuf *eb;
|
||||
int i, id;
|
||||
|
||||
if(keys == 0)
|
||||
return 0;
|
||||
for(;;){
|
||||
for(i=0; i<nslave; i++)
|
||||
if((keys & (1<<i)) && eslave[i].head){
|
||||
id = 1<<i;
|
||||
if(i == Smouse)
|
||||
e->mouse = emouse();
|
||||
else if(i == Skeyboard)
|
||||
e->kbdc = ekbd();
|
||||
else if(i == Stimer)
|
||||
eslave[i].head = 0;
|
||||
else{
|
||||
eb = ebread(&eslave[i]);
|
||||
e->n = eb->n;
|
||||
if(eslave[i].fn)
|
||||
id = (*eslave[i].fn)(id, e, eb->buf, eb->n);
|
||||
else
|
||||
memmove(e->data, eb->buf, eb->n);
|
||||
free(eb);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
extract();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ecanmouse(void)
|
||||
{
|
||||
if(Smouse < 0)
|
||||
drawerror(display, "events: mouse not initialized");
|
||||
return ecanread(Emouse);
|
||||
}
|
||||
|
||||
int
|
||||
ecankbd(void)
|
||||
{
|
||||
if(Skeyboard < 0)
|
||||
drawerror(display, "events: keyboard not initialzed");
|
||||
return ecanread(Ekeyboard);
|
||||
}
|
||||
|
||||
int
|
||||
ecanread(ulong keys)
|
||||
{
|
||||
Dir *d;
|
||||
int i;
|
||||
ulong l;
|
||||
|
||||
for(;;){
|
||||
for(i=0; i<nslave; i++)
|
||||
if((keys & (1<<i)) && eslave[i].head)
|
||||
return 1;
|
||||
d = dirfstat(epipe[0]);
|
||||
if(d == nil)
|
||||
drawerror(display, "events: ecanread stat error");
|
||||
l = d->length;
|
||||
free(d);
|
||||
if(l == 0)
|
||||
return 0;
|
||||
extract();
|
||||
}
|
||||
}
|
||||
|
||||
ulong
|
||||
estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
|
||||
{
|
||||
char buf[EMAXMSG+1];
|
||||
int i, r;
|
||||
|
||||
if(fd < 0)
|
||||
drawerror(display, "events: bad file descriptor");
|
||||
if(n <= 0 || n > EMAXMSG)
|
||||
n = EMAXMSG;
|
||||
i = eforkslave(key);
|
||||
if(i < MAXSLAVE){
|
||||
eslave[i].fn = fn;
|
||||
return 1<<i;
|
||||
}
|
||||
buf[0] = i - MAXSLAVE;
|
||||
while((r = read(fd, buf+1, n))>0)
|
||||
if(write(epipe[1], buf, r+1)!=r+1)
|
||||
break;
|
||||
buf[0] = MAXSLAVE;
|
||||
write(epipe[1], buf, 1);
|
||||
_exits(0);
|
||||
}
|
||||
|
||||
ulong
|
||||
estart(ulong key, int fd, int n)
|
||||
{
|
||||
return estartfn(key, fd, n, nil);
|
||||
}
|
||||
|
||||
ulong
|
||||
etimer(ulong key, int n)
|
||||
{
|
||||
char t[2];
|
||||
|
||||
if(Stimer != -1)
|
||||
drawerror(display, "events: timer started twice");
|
||||
Stimer = eforkslave(key);
|
||||
if(Stimer < MAXSLAVE)
|
||||
return 1<<Stimer;
|
||||
if(n <= 0)
|
||||
n = 1000;
|
||||
t[0] = t[1] = Stimer - MAXSLAVE;
|
||||
do
|
||||
sleep(n);
|
||||
while(write(epipe[1], t, 2) == 2);
|
||||
t[0] = MAXSLAVE;
|
||||
write(epipe[1], t, 1);
|
||||
_exits(0);
|
||||
}
|
||||
|
||||
static void
|
||||
ekeyslave(int fd)
|
||||
{
|
||||
Rune r;
|
||||
char t[1+UTFmax], k[10];
|
||||
int kr, kn, w;
|
||||
|
||||
if(eforkslave(Ekeyboard) < MAXSLAVE)
|
||||
return;
|
||||
kn = 0;
|
||||
t[0] = Skeyboard;
|
||||
for(;;){
|
||||
while(!fullrune(k, kn)){
|
||||
kr = read(fd, k+kn, sizeof k - kn);
|
||||
if(kr <= 0)
|
||||
goto breakout;
|
||||
kn += kr;
|
||||
}
|
||||
w = chartorune(&r, k);
|
||||
kn -= w;
|
||||
memmove(t+1, k, w);
|
||||
memmove(k, &k[w], kn);
|
||||
if(write(epipe[1], t, sizeof(t)) != sizeof(t))
|
||||
break;
|
||||
}
|
||||
breakout:;
|
||||
t[0] = MAXSLAVE;
|
||||
write(epipe[1], t, 1);
|
||||
_exits(0);
|
||||
}
|
||||
|
||||
void
|
||||
einit(ulong keys)
|
||||
{
|
||||
int ctl, fd;
|
||||
char buf[256];
|
||||
|
||||
parentpid = getpid();
|
||||
if(pipe(epipe) < 0)
|
||||
drawerror(display, "events: einit pipe");
|
||||
atexit(ekill);
|
||||
atnotify(enote, 1);
|
||||
snprint(buf, sizeof buf, "%s/mouse", display->devdir);
|
||||
mousefd = open(buf, ORDWR|OCEXEC);
|
||||
if(mousefd < 0)
|
||||
drawerror(display, "einit: can't open mouse\n");
|
||||
snprint(buf, sizeof buf, "%s/cursor", display->devdir);
|
||||
cursorfd = open(buf, ORDWR|OCEXEC);
|
||||
if(cursorfd < 0)
|
||||
drawerror(display, "einit: can't open cursor\n");
|
||||
if(keys&Ekeyboard){
|
||||
snprint(buf, sizeof buf, "%s/cons", display->devdir);
|
||||
fd = open(buf, OREAD);
|
||||
if(fd < 0)
|
||||
drawerror(display, "events: can't open console");
|
||||
snprint(buf, sizeof buf, "%s/consctl", display->devdir);
|
||||
ctl = open("/dev/consctl", OWRITE|OCEXEC);
|
||||
if(ctl < 0)
|
||||
drawerror(display, "events: can't open consctl");
|
||||
write(ctl, "rawon", 5);
|
||||
for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
|
||||
;
|
||||
ekeyslave(fd);
|
||||
}
|
||||
if(keys&Emouse){
|
||||
estart(Emouse, mousefd, 1+4*12);
|
||||
for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
extract(void)
|
||||
{
|
||||
Slave *s;
|
||||
Ebuf *eb;
|
||||
int i, n;
|
||||
uchar ebuf[EMAXMSG+1];
|
||||
|
||||
/* avoid generating a message if there's nothing to show. */
|
||||
/* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
|
||||
/* also: make sure we don't interfere if we're multiprocessing the display */
|
||||
if(display->locking){
|
||||
/* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
|
||||
if(canqlock(&display->qlock)){
|
||||
if(display->bufp > display->buf)
|
||||
flushimage(display, 1);
|
||||
unlockdisplay(display);
|
||||
}
|
||||
}else
|
||||
if(display->bufp > display->buf)
|
||||
flushimage(display, 1);
|
||||
loop:
|
||||
if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0
|
||||
|| ebuf[0] >= MAXSLAVE)
|
||||
drawerror(display, "eof on event pipe");
|
||||
if(n == 0)
|
||||
goto loop;
|
||||
i = ebuf[0];
|
||||
if(i >= nslave || n <= 1)
|
||||
drawerror(display, "events: protocol error: short read");
|
||||
s = &eslave[i];
|
||||
if(i == Stimer){
|
||||
s->head = (Ebuf *)1;
|
||||
return;
|
||||
}
|
||||
if(i == Skeyboard && n != (1+UTFmax))
|
||||
drawerror(display, "events: protocol error: keyboard");
|
||||
if(i == Smouse){
|
||||
if(n < 1+1+2*12)
|
||||
drawerror(display, "events: protocol error: mouse");
|
||||
if(ebuf[1] == 'r')
|
||||
eresized(1);
|
||||
/* squash extraneous mouse events */
|
||||
if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){
|
||||
memmove(eb->buf, &ebuf[1], n - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* try to save space by only allocating as much buffer as we need */
|
||||
eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1);
|
||||
if(eb == 0)
|
||||
drawerror(display, "events: protocol error 4");
|
||||
eb->n = n - 1;
|
||||
memmove(eb->buf, &ebuf[1], n - 1);
|
||||
eb->next = 0;
|
||||
if(s->head)
|
||||
s->tail->next = eb;
|
||||
else
|
||||
s->head = eb;
|
||||
s->tail = eb;
|
||||
}
|
||||
|
||||
static int
|
||||
eforkslave(ulong key)
|
||||
{
|
||||
int i, pid;
|
||||
|
||||
for(i=0; i<MAXSLAVE; i++)
|
||||
if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){
|
||||
if(nslave <= i)
|
||||
nslave = i + 1;
|
||||
/*
|
||||
* share the file descriptors so the last child
|
||||
* out closes all connections to the window server.
|
||||
*/
|
||||
switch(pid = rfork(RFPROC)){
|
||||
case 0:
|
||||
return MAXSLAVE+i;
|
||||
case -1:
|
||||
fprint(2, "events: fork error\n");
|
||||
exits("fork");
|
||||
}
|
||||
eslave[i].pid = pid;
|
||||
eslave[i].head = eslave[i].tail = 0;
|
||||
return i;
|
||||
}
|
||||
drawerror(display, "events: bad slave assignment");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
enote(void*, char *s)
|
||||
{
|
||||
int i, pid;
|
||||
|
||||
if(strncmp(s, "sys:", 4) == 0 || strcmp(s, "alarm") == 0)
|
||||
return 0;
|
||||
pid = getpid();
|
||||
for(i=0; i<nslave; i++)
|
||||
if(pid == eslave[i].pid)
|
||||
return 1;
|
||||
if(pid != parentpid)
|
||||
return 0;
|
||||
exits("killed");
|
||||
}
|
||||
|
||||
static void
|
||||
ekill(void)
|
||||
{
|
||||
int i, pid;
|
||||
|
||||
pid = getpid();
|
||||
for(i=0; i<nslave; i++){
|
||||
if(eslave[i].pid == 0 || pid == eslave[i].pid)
|
||||
continue; /* don't kill myself */
|
||||
postnote(PNPROC, eslave[i].pid, "die");
|
||||
}
|
||||
}
|
||||
|
||||
Mouse
|
||||
emouse(void)
|
||||
{
|
||||
Mouse m;
|
||||
Ebuf *eb;
|
||||
static int lastb;
|
||||
int b;
|
||||
|
||||
if(Smouse < 0)
|
||||
drawerror(display, "events: mouse not initialized");
|
||||
for(;;){
|
||||
eb = ebread(&eslave[Smouse]);
|
||||
b = atoi((char*)eb->buf+1+2*12);
|
||||
if(b != lastb || !ecanmouse())
|
||||
break;
|
||||
free(eb); /* drop queued mouse events */
|
||||
}
|
||||
lastb = b;
|
||||
m.buttons = b;
|
||||
m.xy.x = atoi((char*)eb->buf+1+0*12);
|
||||
m.xy.y = atoi((char*)eb->buf+1+1*12);
|
||||
m.msec = (ulong)atoll((char*)eb->buf+1+3*12);
|
||||
if (logfid)
|
||||
fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy);
|
||||
free(eb);
|
||||
return m;
|
||||
}
|
||||
|
||||
int
|
||||
ekbd(void)
|
||||
{
|
||||
Ebuf *eb;
|
||||
Rune r;
|
||||
|
||||
if(Skeyboard < 0)
|
||||
drawerror(display, "events: keyboard not initialzed");
|
||||
eb = ebread(&eslave[Skeyboard]);
|
||||
chartorune(&r, (char*)eb->buf);
|
||||
free(eb);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
emoveto(Point pt)
|
||||
{
|
||||
char buf[2*12+2];
|
||||
int n;
|
||||
|
||||
n = sprint(buf, "m%d %d", pt.x, pt.y);
|
||||
write(mousefd, buf, n);
|
||||
}
|
||||
|
||||
void
|
||||
esetcursor(Cursor *c)
|
||||
{
|
||||
uchar curs[2*4+2*2*16];
|
||||
|
||||
if(c == 0)
|
||||
write(cursorfd, curs, 0);
|
||||
else{
|
||||
BPLONG(curs+0*4, c->offset.x);
|
||||
BPLONG(curs+1*4, c->offset.y);
|
||||
memmove(curs+2*4, c->clr, 2*2*16);
|
||||
write(cursorfd, curs, sizeof curs);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ereadmouse(Mouse *m)
|
||||
{
|
||||
int n;
|
||||
char buf[128];
|
||||
|
||||
do{
|
||||
n = read(mousefd, buf, sizeof(buf));
|
||||
if(n < 0) /* probably interrupted */
|
||||
return -1;
|
||||
n = eatomouse(m, buf, n);
|
||||
}while(n == 0);
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
eatomouse(Mouse *m, char *buf, int n)
|
||||
{
|
||||
if(n != 1+4*12){
|
||||
werrstr("eatomouse: bad count");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(buf[0] == 'r')
|
||||
eresized(1);
|
||||
m->xy.x = atoi(buf+1+0*12);
|
||||
m->xy.y = atoi(buf+1+1*12);
|
||||
m->buttons = atoi(buf+1+2*12);
|
||||
m->msec = (ulong)atoll(buf+1+3*12);
|
||||
return n;
|
||||
}
|
22
nudraw/fmt.c
Normal file
22
nudraw/fmt.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
int
|
||||
Rfmt(Fmt *f)
|
||||
{
|
||||
Rectangle r;
|
||||
|
||||
r = va_arg(f->args, Rectangle);
|
||||
return fmtprint(f, "%P %P", r.min, r.max);
|
||||
}
|
||||
|
||||
int
|
||||
Pfmt(Fmt *f)
|
||||
{
|
||||
Point p;
|
||||
|
||||
p = va_arg(f->args, Point);
|
||||
return fmtprint(f, "[%d %d]", p.x, p.y);
|
||||
}
|
||||
|
360
nudraw/font.c
Normal file
360
nudraw/font.c
Normal file
|
@ -0,0 +1,360 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
static int fontresize(Font*, int, int, int);
|
||||
|
||||
#define PJW 0 /* use NUL==pjw for invisible characters */
|
||||
|
||||
/* return number of translated cache indices, 0 must retry, -1 on error */
|
||||
int
|
||||
cachechars(Font *f, char **ss, Rune **rr, ushort *cp, int max, int *wp, char **subfontname)
|
||||
{
|
||||
int i, j, h, w, rw, wid, nc;
|
||||
char *sp;
|
||||
Rune r, *rp, vr;
|
||||
ulong a;
|
||||
Cacheinfo *c, *tc, *ec;
|
||||
|
||||
if(ss){
|
||||
sp = *ss;
|
||||
rp = L"";
|
||||
}else{
|
||||
sp = "";
|
||||
rp = *rr;
|
||||
}
|
||||
wid = 0;
|
||||
*subfontname = nil;
|
||||
for(i=0; i<max && (*sp || *rp); sp+=w, rp+=rw){
|
||||
if(ss){
|
||||
r = *(uchar*)sp;
|
||||
if(r < Runeself)
|
||||
w = 1;
|
||||
else{
|
||||
w = chartorune(&vr, sp);
|
||||
r = vr;
|
||||
}
|
||||
rw = 0;
|
||||
}else{
|
||||
r = *rp;
|
||||
w = 0;
|
||||
rw = 1;
|
||||
}
|
||||
|
||||
a = ~0;
|
||||
h = (17 * (uint)r) & (f->ncache-NFLOOK-1);
|
||||
c = &f->cache[h];
|
||||
tc = c;
|
||||
ec = c+NFLOOK;
|
||||
while(c < ec){
|
||||
if(c->value==r && c->age)
|
||||
goto Found;
|
||||
if(c->age < a){
|
||||
a = c->age;
|
||||
tc = c;
|
||||
}
|
||||
c++;
|
||||
h++;
|
||||
}
|
||||
/* Not found; use oldest entry */
|
||||
c = tc;
|
||||
h = tc - f->cache;
|
||||
|
||||
if(a && (f->age-a)<500){ /* kicking out too recent; resize */
|
||||
nc = 2*(f->ncache-NFLOOK) + NFLOOK;
|
||||
if(nc <= MAXFCACHE){
|
||||
if(i == 0)
|
||||
fontresize(f, f->width, nc, f->maxdepth);
|
||||
/* else flush first; retry will resize */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i > 0 && c->age == f->age) /* flush pending string output */
|
||||
break;
|
||||
|
||||
j = loadchar(f, r, c, h, i, subfontname);
|
||||
if(j <= 0){
|
||||
if(j < 0 || i > 0) /* flush output or retry */
|
||||
break;
|
||||
return -1; /* stop retrying */
|
||||
}
|
||||
|
||||
Found:
|
||||
wid += c->width;
|
||||
c->age = f->age;
|
||||
cp[i] = h;
|
||||
i++;
|
||||
}
|
||||
if(ss)
|
||||
*ss = sp;
|
||||
else
|
||||
*rr = rp;
|
||||
*wp = wid;
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
agefont(Font *f)
|
||||
{
|
||||
Cacheinfo *c, *ec;
|
||||
Cachesubf *s, *es;
|
||||
|
||||
f->age++;
|
||||
if(f->age == 65536){
|
||||
/*
|
||||
* Renormalize ages
|
||||
*/
|
||||
c = f->cache;
|
||||
ec = c+f->ncache;
|
||||
while(c < ec){
|
||||
if(c->age){
|
||||
c->age >>= 2;
|
||||
c->age++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
s = f->subf;
|
||||
es = s+f->nsubf;
|
||||
while(s < es){
|
||||
if(s->age){
|
||||
if(s->age<SUBFAGE && s->cf->name != nil){
|
||||
/* clean up */
|
||||
if(f->display == nil || s->f != f->display->defaultsubfont)
|
||||
freesubfont(s->f);
|
||||
s->cf = nil;
|
||||
s->f = nil;
|
||||
s->age = 0;
|
||||
}else{
|
||||
s->age >>= 2;
|
||||
s->age++;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
}
|
||||
f->age = (65536>>2) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static Subfont*
|
||||
cf2subfont(Cachefont *cf, Font *f)
|
||||
{
|
||||
int depth;
|
||||
char *name;
|
||||
Subfont *sf;
|
||||
|
||||
name = cf->subfontname;
|
||||
if(name == nil){
|
||||
if(f->display != nil && f->display->screenimage != nil)
|
||||
depth = f->display->screenimage->depth;
|
||||
else
|
||||
depth = 8;
|
||||
name = subfontname(cf->name, f->name, depth);
|
||||
if(name == nil)
|
||||
return nil;
|
||||
cf->subfontname = name;
|
||||
}
|
||||
sf = lookupsubfont(f->display, name);
|
||||
return sf;
|
||||
}
|
||||
|
||||
/* return 1 if load succeeded, 0 if failed, -1 if must retry */
|
||||
int
|
||||
loadchar(Font *f, Rune r, Cacheinfo *c, int h, int noflush, char **subfontname)
|
||||
{
|
||||
int i, oi, wid, top, bottom;
|
||||
Rune pic;
|
||||
Fontchar *fi;
|
||||
Cachefont *cf;
|
||||
Cachesubf *subf, *of;
|
||||
uchar *b;
|
||||
|
||||
pic = r;
|
||||
Again:
|
||||
for(i=0; i<f->nsub; i++){
|
||||
cf = f->sub[i];
|
||||
if(cf->min<=pic && pic<=cf->max)
|
||||
goto Found;
|
||||
}
|
||||
TryPJW:
|
||||
if(pic != PJW){
|
||||
pic = PJW;
|
||||
goto Again;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Found:
|
||||
/*
|
||||
* Choose exact or oldest
|
||||
*/
|
||||
oi = 0;
|
||||
subf = &f->subf[0];
|
||||
for(i=0; i<f->nsubf; i++){
|
||||
if(cf == subf->cf)
|
||||
goto Found2;
|
||||
if(subf->age < f->subf[oi].age)
|
||||
oi = i;
|
||||
subf++;
|
||||
}
|
||||
subf = &f->subf[oi];
|
||||
|
||||
if(subf->f){
|
||||
if(f->age-subf->age>SUBFAGE || f->nsubf>MAXSUBF){
|
||||
Toss:
|
||||
/* ancient data; toss */
|
||||
freesubfont(subf->f);
|
||||
subf->cf = nil;
|
||||
subf->f = nil;
|
||||
subf->age = 0;
|
||||
}else{ /* too recent; grow instead */
|
||||
of = f->subf;
|
||||
f->subf = realloc(of, (f->nsubf+DSUBF)*sizeof *subf);
|
||||
if(f->subf == nil){
|
||||
f->subf = of;
|
||||
goto Toss;
|
||||
}
|
||||
subf = &f->subf[f->nsubf];
|
||||
memset(subf, 0, DSUBF*sizeof *subf);
|
||||
f->nsubf += DSUBF;
|
||||
}
|
||||
}
|
||||
subf->age = 0;
|
||||
subf->cf = nil;
|
||||
subf->f = cf2subfont(cf, f);
|
||||
if(subf->f == nil){
|
||||
if(cf->subfontname == nil)
|
||||
goto TryPJW;
|
||||
*subfontname = cf->subfontname;
|
||||
return -1;
|
||||
}
|
||||
|
||||
subf->cf = cf;
|
||||
if(subf->f->ascent > f->ascent && f->display){
|
||||
/* should print something? this is a mistake in the font file */
|
||||
/* must prevent c->top from going negative when loading cache */
|
||||
Image *b;
|
||||
int d, t;
|
||||
d = subf->f->ascent - f->ascent;
|
||||
b = subf->f->bits;
|
||||
draw(b, b->r, b, nil, addpt(b->r.min, Pt(0, d)));
|
||||
draw(b, Rect(b->r.min.x, b->r.max.y-d, b->r.max.x, b->r.max.y), f->display->black, nil, b->r.min);
|
||||
for(i=0; i<subf->f->n; i++){
|
||||
t = subf->f->info[i].top-d;
|
||||
if(t < 0)
|
||||
t = 0;
|
||||
subf->f->info[i].top = t;
|
||||
t = subf->f->info[i].bottom-d;
|
||||
if(t < 0)
|
||||
t = 0;
|
||||
subf->f->info[i].bottom = t;
|
||||
}
|
||||
subf->f->ascent = f->ascent;
|
||||
}
|
||||
|
||||
Found2:
|
||||
subf->age = f->age;
|
||||
|
||||
/* possible overflow here, but works out okay */
|
||||
pic += cf->offset;
|
||||
pic -= cf->min;
|
||||
if(pic >= subf->f->n)
|
||||
goto TryPJW;
|
||||
fi = &subf->f->info[pic];
|
||||
if(fi->width == 0)
|
||||
goto TryPJW;
|
||||
wid = (fi+1)->x - fi->x;
|
||||
if(f->width < wid || f->width == 0 || f->maxdepth < subf->f->bits->depth
|
||||
|| (f->display != nil && f->cacheimage == nil)){
|
||||
/*
|
||||
* Flush, free, reload (easier than reformatting f->b)
|
||||
*/
|
||||
if(noflush)
|
||||
return -1;
|
||||
if(f->width < wid)
|
||||
f->width = wid;
|
||||
if(f->maxdepth < subf->f->bits->depth)
|
||||
f->maxdepth = subf->f->bits->depth;
|
||||
if(fontresize(f, f->width, f->ncache, f->maxdepth) <= 0)
|
||||
return -1;
|
||||
/* c is still valid as didn't reallocate f->cache */
|
||||
}
|
||||
c->value = r;
|
||||
c->width = fi->width;
|
||||
c->x = h*f->width;
|
||||
c->left = fi->left;
|
||||
if(f->display == nil)
|
||||
return 1;
|
||||
b = bufimage(f->display, 37);
|
||||
if(b == nil)
|
||||
return 0;
|
||||
top = fi->top + (f->ascent-subf->f->ascent);
|
||||
bottom = fi->bottom + (f->ascent-subf->f->ascent);
|
||||
b[0] = 'l';
|
||||
BPLONG(b+1, f->cacheimage->id);
|
||||
BPLONG(b+5, subf->f->bits->id);
|
||||
BPSHORT(b+9, h);
|
||||
BPLONG(b+11, c->x);
|
||||
BPLONG(b+15, top);
|
||||
BPLONG(b+19, c->x+wid);
|
||||
BPLONG(b+23, bottom);
|
||||
BPLONG(b+27, fi->x);
|
||||
BPLONG(b+31, fi->top);
|
||||
b[35] = fi->left;
|
||||
b[36] = fi->width;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns whether resize succeeded && f->cache is unchanged */
|
||||
static int
|
||||
fontresize(Font *f, int wid, int ncache, int depth)
|
||||
{
|
||||
Cacheinfo *i;
|
||||
int ret;
|
||||
Image *new;
|
||||
uchar *b;
|
||||
Display *d;
|
||||
|
||||
ret = 0;
|
||||
if(depth <= 0)
|
||||
depth = 1;
|
||||
if(wid <= 0)
|
||||
wid = 1;
|
||||
|
||||
d = f->display;
|
||||
if(d == nil)
|
||||
goto Nodisplay;
|
||||
|
||||
new = allocimage(d, Rect(0, 0, ncache*wid, f->height), CHAN1(CGrey, depth), 0, 0);
|
||||
if(new == nil){
|
||||
fprint(2, "font cache resize failed: %r\n");
|
||||
goto Return;
|
||||
}
|
||||
b = bufimage(d, 1+4+4+1);
|
||||
if(b == nil){
|
||||
freeimage(new);
|
||||
goto Return;
|
||||
}
|
||||
b[0] = 'i';
|
||||
BPLONG(b+1, new->id);
|
||||
BPLONG(b+5, ncache);
|
||||
b[9] = f->ascent;
|
||||
freeimage(f->cacheimage);
|
||||
f->cacheimage = new;
|
||||
Nodisplay:
|
||||
f->width = wid;
|
||||
f->maxdepth = depth;
|
||||
ret = 1;
|
||||
if(f->ncache != ncache){
|
||||
i = malloc(ncache*sizeof f->cache[0]);
|
||||
if(i != nil){
|
||||
ret = 0;
|
||||
free(f->cache);
|
||||
f->ncache = ncache;
|
||||
f->cache = i;
|
||||
}
|
||||
/* else just wipe the cache clean and things will be ok */
|
||||
}
|
||||
Return:
|
||||
memset(f->cache, 0, f->ncache*sizeof f->cache[0]);
|
||||
return ret;
|
||||
}
|
15
nudraw/freesubfont.c
Normal file
15
nudraw/freesubfont.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
void
|
||||
freesubfont(Subfont *f)
|
||||
{
|
||||
if(f == nil || --f->ref)
|
||||
return;
|
||||
uninstallsubfont(f);
|
||||
free(f->name);
|
||||
free(f->info); /* note: f->info must have been malloc'ed! */
|
||||
freeimage(f->bits);
|
||||
free(f);
|
||||
}
|
60
nudraw/getdefont.c
Normal file
60
nudraw/getdefont.c
Normal 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 = (int)(uvlong)p & 3; /* stupid ape */
|
||||
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
nudraw/getrect.c
Normal file
133
nudraw/getrect.c
Normal 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->buttons)
|
||||
readmouse(mc);
|
||||
while(!(mc->buttons & but)){
|
||||
readmouse(mc);
|
||||
if(mc->buttons & (7^but))
|
||||
goto Return;
|
||||
}
|
||||
r.min = mc->xy;
|
||||
r.max = mc->xy;
|
||||
do{
|
||||
rc = canonrect(r);
|
||||
drawgetrect(rc, 1);
|
||||
readmouse(mc);
|
||||
drawgetrect(rc, 0);
|
||||
r.max = mc->xy;
|
||||
}while(mc->buttons == but);
|
||||
|
||||
Return:
|
||||
setcursor(mc, nil);
|
||||
if(mc->buttons & (7^but)){
|
||||
rc.min.x = rc.max.x = 0;
|
||||
rc.min.y = rc.max.y = 0;
|
||||
while(mc->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);
|
||||
}
|
||||
}
|
40
nudraw/getsubfont.c
Normal file
40
nudraw/getsubfont.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
/*
|
||||
* Default version: treat as file name
|
||||
*/
|
||||
|
||||
Subfont*
|
||||
_getsubfont(Display *d, char *name)
|
||||
{
|
||||
int dolock, fd;
|
||||
Subfont *f;
|
||||
|
||||
/*
|
||||
* unlock display so i/o happens with display released, unless
|
||||
* user is doing his own locking, in which case this could break things.
|
||||
* _getsubfont is called only from string.c and stringwidth.c,
|
||||
* which are known to be safe to have this done.
|
||||
*/
|
||||
dolock = d != nil && d->locking == 0;
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
|
||||
fd = open(name, OREAD|OCEXEC);
|
||||
if(fd < 0) {
|
||||
fprint(2, "getsubfont: can't open %s: %r\n", name);
|
||||
f = nil;
|
||||
} else {
|
||||
f = readsubfont(d, name, fd, dolock);
|
||||
if(f == nil)
|
||||
fprint(2, "getsubfont: can't read %s: %r\n", name);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
|
||||
return f;
|
||||
}
|
140
nudraw/icossin.c
Normal file
140
nudraw/icossin.c
Normal 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
nudraw/icossin2.c
Normal file
261
nudraw/icossin2.c
Normal 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);
|
||||
}
|
456
nudraw/init.c
Normal file
456
nudraw/init.c
Normal file
|
@ -0,0 +1,456 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Display *display;
|
||||
Font *font;
|
||||
Image *screen;
|
||||
|
||||
static char deffontname[] = "*default*";
|
||||
Screen *_screen;
|
||||
|
||||
int debuglockdisplay = 0;
|
||||
|
||||
static void _closedisplay(Display*, int);
|
||||
|
||||
/* note handler */
|
||||
static void
|
||||
drawshutdown(void)
|
||||
{
|
||||
Display *d;
|
||||
|
||||
d = display;
|
||||
if(d != nil){
|
||||
display = nil;
|
||||
_closedisplay(d, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *label, char *windir, int ref)
|
||||
{
|
||||
int fd, n;
|
||||
Subfont *df;
|
||||
char buf[128];
|
||||
|
||||
display = initdisplay(devdir, windir, error);
|
||||
if(display == nil)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Set up default font
|
||||
*/
|
||||
df = getdefont(display);
|
||||
display->defaultsubfont = df;
|
||||
if(df == nil){
|
||||
Error:
|
||||
closedisplay(display);
|
||||
display = nil;
|
||||
return -1;
|
||||
}
|
||||
if(fontname == nil){
|
||||
fd = open("/env/font", OREAD|OCEXEC);
|
||||
if(fd >= 0){
|
||||
n = read(fd, buf, sizeof(buf));
|
||||
if(n>0 && n<sizeof buf-1){
|
||||
buf[n] = 0;
|
||||
fontname = buf;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Build fonts with caches==depth of screen, for speed.
|
||||
* If conversion were faster, we'd use 0 and save memory.
|
||||
*/
|
||||
if(fontname == nil){
|
||||
snprint(buf, sizeof buf, "%d %d\n0 %d\t%s\n", df->height, df->ascent,
|
||||
df->n-1, deffontname);
|
||||
//BUG: Need something better for this installsubfont("*default*", df);
|
||||
font = buildfont(display, buf, deffontname);
|
||||
if(font == nil)
|
||||
goto Error;
|
||||
}else{
|
||||
font = openfont(display, fontname); /* BUG: grey fonts */
|
||||
if(font == nil)
|
||||
goto Error;
|
||||
}
|
||||
display->defaultfont = font;
|
||||
|
||||
/*
|
||||
* Write label; ignore errors (we might not be running under rio)
|
||||
*/
|
||||
if(label != nil){
|
||||
snprint(buf, sizeof buf, "%s/label", display->windir);
|
||||
fd = open(buf, OREAD|OCEXEC);
|
||||
if(fd >= 0){
|
||||
read(fd, display->oldlabel, (sizeof display->oldlabel)-1);
|
||||
close(fd);
|
||||
fd = create(buf, OWRITE|OCEXEC, 0666);
|
||||
if(fd >= 0){
|
||||
write(fd, label, strlen(label));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprint(buf, sizeof buf, "%s/winname", display->windir);
|
||||
if(gengetwindow(display, buf, &screen, &_screen, ref) < 0)
|
||||
goto Error;
|
||||
|
||||
atexit(drawshutdown);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
initdraw(void(*error)(Display*, char*), char *fontname, char *label)
|
||||
{
|
||||
static char dev[] = "/dev";
|
||||
|
||||
return geninitdraw(dev, error, fontname, label, dev, Refnone);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach, or possibly reattach, to window.
|
||||
* If reattaching, maintain value of screen pointer.
|
||||
*/
|
||||
int
|
||||
gengetwindow(Display *d, char *winname, Image **winp, Screen **scrp, int ref)
|
||||
{
|
||||
int n, fd;
|
||||
char buf[64+1], obuf[64+1];
|
||||
Image *image;
|
||||
Rectangle r;
|
||||
|
||||
obuf[0] = 0;
|
||||
retry:
|
||||
fd = open(winname, OREAD|OCEXEC);
|
||||
if(fd<0 || (n=read(fd, buf, sizeof buf-1))<=0){
|
||||
if(fd >= 0) close(fd);
|
||||
strcpy(buf, "noborder");
|
||||
image = d->image;
|
||||
}else{
|
||||
close(fd);
|
||||
buf[n] = '\0';
|
||||
image = namedimage(d, buf);
|
||||
if(image == nil){
|
||||
/*
|
||||
* theres a race where the winname can change after
|
||||
* we read it, so keep trying as long as the name
|
||||
* keeps changing.
|
||||
*/
|
||||
if(strcmp(buf, obuf) != 0){
|
||||
strcpy(obuf, buf);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(*winp != nil){
|
||||
_freeimage1(*winp);
|
||||
if((*scrp)->image != d->image)
|
||||
freeimage((*scrp)->image);
|
||||
freescreen(*scrp);
|
||||
*scrp = nil;
|
||||
}
|
||||
if(image == nil){
|
||||
*winp = nil;
|
||||
d->screenimage = nil;
|
||||
return -1;
|
||||
}
|
||||
d->screenimage = image;
|
||||
*scrp = allocscreen(image, d->white, 0);
|
||||
if(*scrp == nil){
|
||||
*winp = nil;
|
||||
d->screenimage = nil;
|
||||
if(image != d->image)
|
||||
freeimage(image);
|
||||
return -1;
|
||||
}
|
||||
r = image->r;
|
||||
if(strncmp(buf, "noborder", 8) != 0)
|
||||
r = insetrect(r, Borderwidth);
|
||||
*winp = _allocwindow(*winp, *scrp, r, ref, DWhite);
|
||||
if(*winp == nil){
|
||||
freescreen(*scrp);
|
||||
*scrp = nil;
|
||||
d->screenimage = nil;
|
||||
if(image != d->image)
|
||||
freeimage(image);
|
||||
return -1;
|
||||
}
|
||||
d->screenimage = *winp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
getwindow(Display *d, int ref)
|
||||
{
|
||||
char winname[128];
|
||||
|
||||
snprint(winname, sizeof winname, "%s/winname", d->windir);
|
||||
return gengetwindow(d, winname, &screen, &_screen, ref);
|
||||
}
|
||||
|
||||
#define NINFO 12*12
|
||||
|
||||
Display*
|
||||
initdisplay(char *dev, char *win, void(*error)(Display*, char*))
|
||||
{
|
||||
char buf[128], info[NINFO+1], *t, isnew;
|
||||
int n, datafd, ctlfd, reffd;
|
||||
Display *disp;
|
||||
Dir *dir;
|
||||
Image *image;
|
||||
|
||||
fmtinstall('P', Pfmt);
|
||||
fmtinstall('R', Rfmt);
|
||||
if(dev == nil)
|
||||
dev = "/dev";
|
||||
if(win == nil)
|
||||
win = "/dev";
|
||||
if(strlen(dev)>sizeof buf-25 || strlen(win)>sizeof buf-25){
|
||||
werrstr("initdisplay: directory name too long");
|
||||
return nil;
|
||||
}
|
||||
t = strdup(win);
|
||||
if(t == nil)
|
||||
return nil;
|
||||
|
||||
sprint(buf, "%s/draw/new", dev);
|
||||
ctlfd = open(buf, ORDWR|OCEXEC);
|
||||
if(ctlfd < 0){
|
||||
Error1:
|
||||
free(t);
|
||||
werrstr("initdisplay: %s: %r", buf);
|
||||
return nil;
|
||||
}
|
||||
if((n=read(ctlfd, info, sizeof info)) < 12){
|
||||
Error2:
|
||||
close(ctlfd);
|
||||
goto Error1;
|
||||
}
|
||||
if(n==NINFO+1)
|
||||
n = NINFO;
|
||||
info[n] = '\0';
|
||||
isnew = 0;
|
||||
if(n < NINFO) /* this will do for now, we need something better here */
|
||||
isnew = 1;
|
||||
sprint(buf, "%s/draw/%d/data", dev, atoi(info+0*12));
|
||||
datafd = open(buf, ORDWR|OCEXEC);
|
||||
if(datafd < 0)
|
||||
goto Error2;
|
||||
sprint(buf, "%s/draw/%d/refresh", dev, atoi(info+0*12));
|
||||
reffd = open(buf, OREAD|OCEXEC);
|
||||
if(reffd < 0){
|
||||
Error3:
|
||||
close(datafd);
|
||||
goto Error2;
|
||||
}
|
||||
disp = mallocz(sizeof(Display), 1);
|
||||
if(disp == nil){
|
||||
Error4:
|
||||
close(reffd);
|
||||
goto Error3;
|
||||
}
|
||||
image = nil;
|
||||
if(0){
|
||||
Error5:
|
||||
free(image);
|
||||
free(disp);
|
||||
goto Error4;
|
||||
}
|
||||
if(n >= NINFO){
|
||||
image = mallocz(sizeof(Image), 1);
|
||||
if(image == nil)
|
||||
goto Error5;
|
||||
image->display = disp;
|
||||
image->id = 0;
|
||||
image->chan = strtochan(info+2*12);
|
||||
image->depth = chantodepth(image->chan);
|
||||
image->repl = atoi(info+3*12);
|
||||
image->r.min.x = atoi(info+4*12);
|
||||
image->r.min.y = atoi(info+5*12);
|
||||
image->r.max.x = atoi(info+6*12);
|
||||
image->r.max.y = atoi(info+7*12);
|
||||
image->clipr.min.x = atoi(info+8*12);
|
||||
image->clipr.min.y = atoi(info+9*12);
|
||||
image->clipr.max.x = atoi(info+10*12);
|
||||
image->clipr.max.y = atoi(info+11*12);
|
||||
}
|
||||
|
||||
disp->_isnewdisplay = isnew;
|
||||
disp->bufsize = iounit(datafd);
|
||||
if(disp->bufsize <= 0)
|
||||
disp->bufsize = 8000;
|
||||
if(disp->bufsize < 512){
|
||||
werrstr("iounit %d too small", disp->bufsize);
|
||||
goto Error5;
|
||||
}
|
||||
disp->buf = malloc(disp->bufsize+5); /* +5 for flush message */
|
||||
if(disp->buf == nil)
|
||||
goto Error5;
|
||||
|
||||
disp->image = image;
|
||||
disp->dirno = atoi(info+0*12);
|
||||
disp->fd = datafd;
|
||||
disp->ctlfd = ctlfd;
|
||||
disp->reffd = reffd;
|
||||
disp->bufp = disp->buf;
|
||||
disp->error = error;
|
||||
disp->windir = t;
|
||||
disp->devdir = strdup(dev);
|
||||
qlock(&disp->qlock);
|
||||
disp->white = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DWhite);
|
||||
disp->black = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DBlack);
|
||||
if(disp->white == nil || disp->black == nil){
|
||||
free(disp->devdir);
|
||||
free(disp->white);
|
||||
free(disp->black);
|
||||
goto Error5;
|
||||
}
|
||||
disp->opaque = disp->white;
|
||||
disp->transparent = disp->black;
|
||||
dir = dirfstat(ctlfd);
|
||||
if(dir!=nil && dir->type=='i'){
|
||||
disp->local = 1;
|
||||
disp->dataqid = dir->qid.path;
|
||||
}
|
||||
if(dir!=nil && dir->qid.vers==1) /* other way to tell */
|
||||
disp->_isnewdisplay = 1;
|
||||
free(dir);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call with d unlocked.
|
||||
* Note that disp->defaultfont and defaultsubfont are not freed here.
|
||||
*/
|
||||
void
|
||||
closedisplay(Display *disp)
|
||||
{
|
||||
_closedisplay(disp, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_closedisplay(Display *disp, int isshutdown)
|
||||
{
|
||||
int fd;
|
||||
char buf[128];
|
||||
|
||||
if(disp == nil)
|
||||
return;
|
||||
if(disp == display)
|
||||
display = nil;
|
||||
if(disp->oldlabel[0]){
|
||||
snprint(buf, sizeof buf, "%s/label", disp->windir);
|
||||
fd = open(buf, OWRITE|OCEXEC);
|
||||
if(fd >= 0){
|
||||
write(fd, disp->oldlabel, strlen(disp->oldlabel));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if we're shutting down, don't free all the resources.
|
||||
* if other procs are getting shot down by notes too,
|
||||
* one might get shot down while holding the malloc lock.
|
||||
* just let the kernel clean things up when we exit.
|
||||
*/
|
||||
if(isshutdown)
|
||||
return;
|
||||
|
||||
free(disp->devdir);
|
||||
free(disp->windir);
|
||||
freeimage(disp->white);
|
||||
freeimage(disp->black);
|
||||
close(disp->fd);
|
||||
close(disp->ctlfd);
|
||||
/* should cause refresh slave to shut down */
|
||||
close(disp->reffd);
|
||||
qunlock(&disp->qlock);
|
||||
free(disp);
|
||||
}
|
||||
|
||||
void
|
||||
lockdisplay(Display *disp)
|
||||
{
|
||||
if(debuglockdisplay){
|
||||
/* avoid busy looping; it's rare we collide anyway */
|
||||
while(!canqlock(&disp->qlock))
|
||||
sleep(1000);
|
||||
}else
|
||||
qlock(&disp->qlock);
|
||||
}
|
||||
|
||||
void
|
||||
unlockdisplay(Display *disp)
|
||||
{
|
||||
qunlock(&disp->qlock);
|
||||
}
|
||||
|
||||
void
|
||||
drawerror(Display *d, char *s)
|
||||
{
|
||||
char err[ERRMAX];
|
||||
|
||||
if(d != nil && d->error != nil)
|
||||
(*d->error)(d, s);
|
||||
else{
|
||||
errstr(err, sizeof err);
|
||||
fprint(2, "draw: %s: %s\n", s, err);
|
||||
exits(s);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
doflush(Display *d)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = d->bufp-d->buf;
|
||||
if(n <= 0)
|
||||
return 1;
|
||||
|
||||
if(write(d->fd, d->buf, n) != n){
|
||||
d->bufp = d->buf; /* might as well; chance of continuing */
|
||||
return -1;
|
||||
}
|
||||
d->bufp = d->buf;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
flushimage(Display *d, int visible)
|
||||
{
|
||||
if(d == nil)
|
||||
return 0;
|
||||
if(visible){
|
||||
*d->bufp++ = 'v'; /* five bytes always reserved for this */
|
||||
if(d->_isnewdisplay){
|
||||
BPLONG(d->bufp, d->screenimage->id);
|
||||
d->bufp += 4;
|
||||
}
|
||||
}
|
||||
return doflush(d);
|
||||
}
|
||||
|
||||
uchar*
|
||||
bufimage(Display *d, int n)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
if(n<0 || n>d->bufsize){
|
||||
werrstr("bad count in bufimage");
|
||||
return nil;
|
||||
}
|
||||
if(d->bufp+n > d->buf+d->bufsize)
|
||||
if(doflush(d) < 0)
|
||||
return nil;
|
||||
p = d->bufp;
|
||||
d->bufp += n;
|
||||
return p;
|
||||
}
|
||||
|
100
nudraw/keyboard.c
Normal file
100
nudraw/keyboard.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <thread.h>
|
||||
#include <keyboard.h>
|
||||
|
||||
void
|
||||
closekeyboard(Keyboardctl *kc)
|
||||
{
|
||||
if(kc == nil)
|
||||
return;
|
||||
close(kc->ctlfd);
|
||||
close(kc->consfd);
|
||||
kc->consfd = kc->ctlfd = -1;
|
||||
threadint(kc->pid);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
_ioproc(void *arg)
|
||||
{
|
||||
int m, n, nerr;
|
||||
char buf[20];
|
||||
Rune r;
|
||||
Keyboardctl *kc;
|
||||
|
||||
kc = arg;
|
||||
threadsetname("kbdproc");
|
||||
n = 0;
|
||||
nerr = 0;
|
||||
while(kc->consfd >= 0){
|
||||
m = read(kc->consfd, buf+n, sizeof buf-n);
|
||||
if(m <= 0){
|
||||
yield(); /* if error is due to exiting, we'll exit here */
|
||||
if(kc->consfd < 0)
|
||||
break;
|
||||
fprint(2, "keyboard: short read: %r\n");
|
||||
if(m<0 || ++nerr>10)
|
||||
threadexits("read error");
|
||||
continue;
|
||||
}
|
||||
nerr = 0;
|
||||
n += m;
|
||||
while(n>0 && fullrune(buf, n)){
|
||||
m = chartorune(&r, buf);
|
||||
n -= m;
|
||||
memmove(buf, buf+m, n);
|
||||
if(send(kc->c, &r) < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
chanfree(kc->c);
|
||||
free(kc->file);
|
||||
free(kc);
|
||||
}
|
||||
|
||||
Keyboardctl*
|
||||
initkeyboard(char *file)
|
||||
{
|
||||
Keyboardctl *kc;
|
||||
char *t;
|
||||
|
||||
kc = mallocz(sizeof(Keyboardctl), 1);
|
||||
if(kc == nil)
|
||||
return nil;
|
||||
if(file == nil)
|
||||
file = "/dev/cons";
|
||||
kc->file = strdup(file);
|
||||
kc->consfd = open(file, ORDWR|OCEXEC);
|
||||
t = malloc(strlen(file)+16);
|
||||
if(kc->consfd<0 || t==nil){
|
||||
Error1:
|
||||
free(kc);
|
||||
return nil;
|
||||
}
|
||||
sprint(t, "%sctl", file);
|
||||
kc->ctlfd = open(t, OWRITE|OCEXEC);
|
||||
if(kc->ctlfd < 0){
|
||||
fprint(2, "initkeyboard: can't open %s: %r\n", t);
|
||||
Error2:
|
||||
close(kc->consfd);
|
||||
free(t);
|
||||
goto Error1;
|
||||
}
|
||||
if(ctlkeyboard(kc, "rawon") < 0){
|
||||
fprint(2, "initkeyboard: can't turn on raw mode on %s: %r\n", t);
|
||||
close(kc->ctlfd);
|
||||
goto Error2;
|
||||
}
|
||||
free(t);
|
||||
kc->c = chancreate(sizeof(Rune), 20);
|
||||
kc->pid = proccreate(_ioproc, kc, 4096);
|
||||
return kc;
|
||||
}
|
||||
|
||||
int
|
||||
ctlkeyboard(Keyboardctl *kc, char *m)
|
||||
{
|
||||
return write(kc->ctlfd, m, strlen(m));
|
||||
}
|
35
nudraw/line.c
Normal file
35
nudraw/line.c
Normal 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 == nil){
|
||||
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);
|
||||
}
|
56
nudraw/loadimage.c
Normal file
56
nudraw/loadimage.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
int
|
||||
loadimage(Image *i, Rectangle r, uchar *data, int ndata)
|
||||
{
|
||||
long dx, 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 = Dy(r);
|
||||
dx = Dx(r);
|
||||
if(dy*bpl > chunk)
|
||||
dy = chunk/bpl;
|
||||
if(dy <= 0){
|
||||
dy = 1;
|
||||
dx = ((chunk*dx)/bpl) & ~7;
|
||||
n = bytesperline(Rect(r.min.x, r.min.y, r.min.x+dx, r.min.y+dy), i->depth);
|
||||
if(loadimage(i, Rect(r.min.x+dx, r.min.y, r.max.x, r.min.y+dy), data+n, bpl-n) < 0)
|
||||
return -1;
|
||||
} else
|
||||
n = dy*bpl;
|
||||
a = bufimage(i->display, 21+n);
|
||||
if(a == nil){
|
||||
werrstr("loadimage: %r");
|
||||
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.min.x+dx);
|
||||
BPLONG(a+17, r.min.y+dy);
|
||||
memmove(a+21, data, n);
|
||||
ndata += dy*bpl;
|
||||
data += dy*bpl;
|
||||
r.min.y += dy;
|
||||
}
|
||||
return ndata;
|
||||
}
|
44
nudraw/makefile
Normal file
44
nudraw/makefile
Normal file
|
@ -0,0 +1,44 @@
|
|||
!include "..\mkconfig.nmk"
|
||||
!include "..\$(SYSHOST)\mkhost"
|
||||
!include "..\$(OBJDIR)\makefile"
|
||||
|
||||
LIB=libimage.$A
|
||||
OFILES_C= \
|
||||
alloc.$O\
|
||||
arith.$O\
|
||||
bezier.$O\
|
||||
buildfont.$O\
|
||||
bytesperline.$O\
|
||||
creadimage.$O\
|
||||
cursor.$O\
|
||||
defont.$O\
|
||||
draw.$O\
|
||||
ellipse.$O\
|
||||
font.$O\
|
||||
freesubfont.$O\
|
||||
getsubfont.$O\
|
||||
init.$O\
|
||||
line.$O\
|
||||
loadimage.$O\
|
||||
mkfont.$O\
|
||||
openfont.$O\
|
||||
poly.$O\
|
||||
readimage.$O\
|
||||
readsubfont.$O\
|
||||
rectclip.$O\
|
||||
replclipr.$O\
|
||||
rgb.$O\
|
||||
string.$O\
|
||||
stringsubfont.$O\
|
||||
stringwidth.$O\
|
||||
subfont.$O\
|
||||
subfontcache.$O\
|
||||
subfontname.$O\
|
||||
unloadimage.$O\
|
||||
window.$O\
|
||||
writeimage.$O\
|
||||
|
||||
HFILES=\
|
||||
../include/memimage.h
|
||||
|
||||
!include <..\$(SYSTARG)\mksyslib.nmk>
|
278
nudraw/menuhit.c
Normal file
278
nudraw/menuhit.c
Normal file
|
@ -0,0 +1,278 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <thread.h>
|
||||
#include <mouse.h>
|
||||
|
||||
enum
|
||||
{
|
||||
Margin = 4, /* outside to text */
|
||||
Border = 2, /* outside to selection boxes */
|
||||
Blackborder = 2, /* width of outlining border */
|
||||
Vspacing = 2, /* extra spacing between lines of text */
|
||||
Maxunscroll = 25, /* maximum #entries before scrolling turns on */
|
||||
Nscroll = 20, /* number entries in scrolling part */
|
||||
Scrollwid = 14, /* width of scroll bar */
|
||||
Gap = 4, /* between text and scroll bar */
|
||||
};
|
||||
|
||||
static Image *menutxt;
|
||||
static Image *back;
|
||||
static Image *high;
|
||||
static Image *bord;
|
||||
static Image *text;
|
||||
static Image *htext;
|
||||
|
||||
static
|
||||
void
|
||||
menucolors(void)
|
||||
{
|
||||
goto Error;
|
||||
/* Main tone is greenish, with negative selection */
|
||||
/* please disregard */
|
||||
back = allocimagemix(display, DPalegreen, DWhite);
|
||||
high = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkgreen); /* dark green */
|
||||
bord = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedgreen); /* not as dark green */
|
||||
if(back==nil || high==nil || bord==nil)
|
||||
goto Error;
|
||||
text = display->black;
|
||||
htext = back;
|
||||
return;
|
||||
|
||||
Error:
|
||||
freeimage(back);
|
||||
freeimage(high);
|
||||
freeimage(bord);
|
||||
back = display->white;
|
||||
high = display->black;
|
||||
bord = display->black;
|
||||
text = display->black;
|
||||
htext = display->white;
|
||||
}
|
||||
|
||||
/*
|
||||
* r is a rectangle holding the text elements.
|
||||
* return the rectangle, including its black edge, holding element i.
|
||||
*/
|
||||
static Rectangle
|
||||
menurect(Rectangle r, int i)
|
||||
{
|
||||
if(i < 0)
|
||||
return Rect(0, 0, 0, 0);
|
||||
r.min.y += (font->height+Vspacing)*i;
|
||||
r.max.y = r.min.y+font->height+Vspacing;
|
||||
return insetrect(r, Border-Margin);
|
||||
}
|
||||
|
||||
/*
|
||||
* r is a rectangle holding the text elements.
|
||||
* return the element number containing p.
|
||||
*/
|
||||
static int
|
||||
menusel(Rectangle r, Point p)
|
||||
{
|
||||
if(!ptinrect(p, r))
|
||||
return -1;
|
||||
return (p.y-r.min.y)/(font->height+Vspacing);
|
||||
}
|
||||
|
||||
static void
|
||||
paintitem(Image *m, Menu *menu, Rectangle textr, int off, int i, int highlight, Image *save, Image *restore)
|
||||
{
|
||||
char *item;
|
||||
Rectangle r;
|
||||
Point pt;
|
||||
|
||||
if(i < 0)
|
||||
return;
|
||||
r = menurect(textr, i);
|
||||
if(restore){
|
||||
draw(m, r, restore, nil, restore->r.min);
|
||||
return;
|
||||
}
|
||||
if(save)
|
||||
draw(save, save->r, m, nil, r.min);
|
||||
item = menu->item? menu->item[i+off] : (*menu->gen)(i+off);
|
||||
pt.x = (textr.min.x+textr.max.x-stringwidth(font, item))/2;
|
||||
pt.y = textr.min.y+i*(font->height+Vspacing);
|
||||
draw(m, r, highlight? high : back, nil, pt);
|
||||
string(m, pt, highlight? htext : text, pt, font, item);
|
||||
}
|
||||
|
||||
/*
|
||||
* menur is a rectangle holding all the highlightable text elements.
|
||||
* track mouse while inside the box, return what's selected when button
|
||||
* is raised, -1 as soon as it leaves box.
|
||||
* invariant: nothing is highlighted on entry or exit.
|
||||
*/
|
||||
static int
|
||||
menuscan(Image *m, Menu *menu, int but, Mousectl *mc, Rectangle textr, int off, int lasti, Image *save)
|
||||
{
|
||||
int i;
|
||||
|
||||
paintitem(m, menu, textr, off, lasti, 1, save, nil);
|
||||
for(readmouse(mc); mc->buttons & (1<<(but-1)); readmouse(mc)){
|
||||
i = menusel(textr, mc->xy);
|
||||
if(i != -1 && i == lasti)
|
||||
continue;
|
||||
paintitem(m, menu, textr, off, lasti, 0, nil, save);
|
||||
if(i == -1)
|
||||
return i;
|
||||
lasti = i;
|
||||
paintitem(m, menu, textr, off, lasti, 1, save, nil);
|
||||
}
|
||||
return lasti;
|
||||
}
|
||||
|
||||
static void
|
||||
menupaint(Image *m, Menu *menu, Rectangle textr, int off, int nitemdrawn)
|
||||
{
|
||||
int i;
|
||||
|
||||
draw(m, insetrect(textr, Border-Margin), back, nil, ZP);
|
||||
for(i = 0; i<nitemdrawn; i++)
|
||||
paintitem(m, menu, textr, off, i, 0, nil, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
menuscrollpaint(Image *m, Rectangle scrollr, int off, int nitem, int nitemdrawn)
|
||||
{
|
||||
Rectangle r;
|
||||
|
||||
draw(m, scrollr, back, nil, ZP);
|
||||
r.min.x = scrollr.min.x;
|
||||
r.max.x = scrollr.max.x;
|
||||
r.min.y = scrollr.min.y + (Dy(scrollr)*off)/nitem;
|
||||
r.max.y = scrollr.min.y + (Dy(scrollr)*(off+nitemdrawn))/nitem;
|
||||
if(r.max.y < r.min.y+2)
|
||||
r.max.y = r.min.y+2;
|
||||
border(m, r, 1, bord, ZP);
|
||||
if(menutxt == 0)
|
||||
menutxt = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DDarkgreen); /* border color; BUG? */
|
||||
if(menutxt)
|
||||
draw(m, insetrect(r, 1), menutxt, nil, ZP);
|
||||
}
|
||||
|
||||
int
|
||||
menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr)
|
||||
{
|
||||
int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem;
|
||||
int scrolling;
|
||||
Rectangle r, menur, sc, textr, scrollr;
|
||||
Image *b, *save, *backup;
|
||||
Point pt;
|
||||
char *item;
|
||||
|
||||
if(back == nil)
|
||||
menucolors();
|
||||
sc = screen->clipr;
|
||||
replclipr(screen, 0, screen->r);
|
||||
maxwid = 0;
|
||||
for(nitem = 0;
|
||||
item = menu->item? menu->item[nitem] : (*menu->gen)(nitem);
|
||||
nitem++){
|
||||
i = stringwidth(font, item);
|
||||
if(i > maxwid)
|
||||
maxwid = i;
|
||||
}
|
||||
if(menu->lasthit<0 || menu->lasthit>=nitem)
|
||||
menu->lasthit = 0;
|
||||
screenitem = (Dy(screen->r)-10)/(font->height+Vspacing);
|
||||
if(nitem>Maxunscroll || nitem>screenitem){
|
||||
scrolling = 1;
|
||||
nitemdrawn = Nscroll;
|
||||
if(nitemdrawn > screenitem)
|
||||
nitemdrawn = screenitem;
|
||||
wid = maxwid + Gap + Scrollwid;
|
||||
off = menu->lasthit - nitemdrawn/2;
|
||||
if(off < 0)
|
||||
off = 0;
|
||||
if(off > nitem-nitemdrawn)
|
||||
off = nitem-nitemdrawn;
|
||||
lasti = menu->lasthit-off;
|
||||
}else{
|
||||
scrolling = 0;
|
||||
nitemdrawn = nitem;
|
||||
wid = maxwid;
|
||||
off = 0;
|
||||
lasti = menu->lasthit;
|
||||
}
|
||||
r = insetrect(Rect(0, 0, wid, nitemdrawn*(font->height+Vspacing)), -Margin);
|
||||
r = rectsubpt(r, Pt(wid/2, lasti*(font->height+Vspacing)+font->height/2));
|
||||
r = rectaddpt(r, mc->xy);
|
||||
pt = ZP;
|
||||
if(r.max.x>screen->r.max.x)
|
||||
pt.x = screen->r.max.x-r.max.x;
|
||||
if(r.max.y>screen->r.max.y)
|
||||
pt.y = screen->r.max.y-r.max.y;
|
||||
if(r.min.x<screen->r.min.x)
|
||||
pt.x = screen->r.min.x-r.min.x;
|
||||
if(r.min.y<screen->r.min.y)
|
||||
pt.y = screen->r.min.y-r.min.y;
|
||||
menur = rectaddpt(r, pt);
|
||||
textr.max.x = menur.max.x-Margin;
|
||||
textr.min.x = textr.max.x-maxwid;
|
||||
textr.min.y = menur.min.y+Margin;
|
||||
textr.max.y = textr.min.y + nitemdrawn*(font->height+Vspacing);
|
||||
if(scrolling){
|
||||
scrollr = insetrect(menur, Border);
|
||||
scrollr.max.x = scrollr.min.x+Scrollwid;
|
||||
}else
|
||||
scrollr = Rect(0, 0, 0, 0);
|
||||
|
||||
if(scr){
|
||||
b = allocwindow(scr, menur, Refbackup, DWhite);
|
||||
if(b == nil)
|
||||
b = screen;
|
||||
backup = nil;
|
||||
}else{
|
||||
b = screen;
|
||||
backup = allocimage(display, menur, screen->chan, 0, -1);
|
||||
if(backup)
|
||||
draw(backup, menur, screen, nil, menur.min);
|
||||
}
|
||||
draw(b, menur, back, nil, ZP);
|
||||
border(b, menur, Blackborder, bord, ZP);
|
||||
save = allocimage(display, menurect(textr, 0), screen->chan, 0, -1);
|
||||
r = menurect(textr, lasti);
|
||||
if(pt.x || pt.y)
|
||||
moveto(mc, divpt(addpt(r.min, r.max), 2));
|
||||
menupaint(b, menu, textr, off, nitemdrawn);
|
||||
if(scrolling)
|
||||
menuscrollpaint(b, scrollr, off, nitem, nitemdrawn);
|
||||
while(mc->buttons & (1<<(but-1))){
|
||||
lasti = menuscan(b, menu, but, mc, textr, off, lasti, save);
|
||||
if(lasti >= 0)
|
||||
break;
|
||||
while(!ptinrect(mc->xy, textr) && (mc->buttons & (1<<(but-1)))){
|
||||
if(scrolling && ptinrect(mc->xy, scrollr)){
|
||||
noff = ((mc->xy.y-scrollr.min.y)*nitem)/Dy(scrollr);
|
||||
noff -= nitemdrawn/2;
|
||||
if(noff < 0)
|
||||
noff = 0;
|
||||
if(noff > nitem-nitemdrawn)
|
||||
noff = nitem-nitemdrawn;
|
||||
if(noff != off){
|
||||
off = noff;
|
||||
menupaint(b, menu, textr, off, nitemdrawn);
|
||||
menuscrollpaint(b, scrollr, off, nitem, nitemdrawn);
|
||||
}
|
||||
}
|
||||
readmouse(mc);
|
||||
}
|
||||
}
|
||||
if(b != screen)
|
||||
freeimage(b);
|
||||
if(backup){
|
||||
draw(screen, menur, backup, nil, menur.min);
|
||||
freeimage(backup);
|
||||
}
|
||||
freeimage(save);
|
||||
replclipr(screen, 0, sc);
|
||||
flushimage(display, 1);
|
||||
if(lasti >= 0){
|
||||
menu->lasthit = lasti+off;
|
||||
return menu->lasthit;
|
||||
}
|
||||
return -1;
|
||||
}
|
72
nudraw/mkfile
Normal file
72
nudraw/mkfile
Normal file
|
@ -0,0 +1,72 @@
|
|||
</$objtype/mkfile
|
||||
|
||||
LIB=`{pwd}/libnudraw.a
|
||||
|
||||
OFILES=\
|
||||
alloc.$O\
|
||||
allocimagemix.$O\
|
||||
arith.$O\
|
||||
badrect.$O\
|
||||
bezier.$O\
|
||||
border.$O\
|
||||
buildfont.$O\
|
||||
bytesperline.$O\
|
||||
chan.$O\
|
||||
cloadimage.$O\
|
||||
computil.$O\
|
||||
creadimage.$O\
|
||||
debug.$O\
|
||||
defont.$O\
|
||||
draw.$O\
|
||||
drawrepl.$O\
|
||||
eenter.$O\
|
||||
egetrect.$O\
|
||||
ellipse.$O\
|
||||
emenuhit.$O\
|
||||
enter.$O\
|
||||
event.$O\
|
||||
fmt.$O\
|
||||
font.$O\
|
||||
freesubfont.$O\
|
||||
getdefont.$O\
|
||||
getrect.$O\
|
||||
getsubfont.$O\
|
||||
icossin.$O\
|
||||
icossin2.$O\
|
||||
init.$O\
|
||||
keyboard.$O\
|
||||
line.$O\
|
||||
menuhit.$O\
|
||||
mkfont.$O\
|
||||
mouse.$O\
|
||||
newwindow.$O\
|
||||
openfont.$O\
|
||||
poly.$O\
|
||||
loadimage.$O\
|
||||
readcolmap.$O\
|
||||
readimage.$O\
|
||||
readsubfont.$O\
|
||||
rectclip.$O\
|
||||
replclipr.$O\
|
||||
rgb.$O\
|
||||
scroll.$O\
|
||||
string.$O\
|
||||
stringbg.$O\
|
||||
stringsubfont.$O\
|
||||
stringwidth.$O\
|
||||
subfont.$O\
|
||||
subfontcache.$O\
|
||||
subfontname.$O\
|
||||
unloadimage.$O\
|
||||
window.$O\
|
||||
writecolmap.$O\
|
||||
writeimage.$O\
|
||||
writesubfont.$O\
|
||||
|
||||
HFILES=\
|
||||
/sys/include/draw.h\
|
||||
/sys/include/event.h\
|
||||
/sys/include/mouse.h\
|
||||
/sys/include/keyboard.h
|
||||
|
||||
</sys/src/cmd/mksyslib
|
55
nudraw/mkfont.c
Normal file
55
nudraw/mkfont.c
Normal 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 == nil)
|
||||
return nil;
|
||||
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==nil || font->cache==nil || font->subf==nil){
|
||||
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 == nil)
|
||||
goto Err;
|
||||
c = malloc(sizeof(Cachefont));
|
||||
if(c == nil)
|
||||
goto Err;
|
||||
font->nsub = 1;
|
||||
font->sub[0] = c;
|
||||
c->min = min;
|
||||
c->max = min+subfont->n-1;
|
||||
c->offset = 0;
|
||||
c->name = nil; /* noticed by agefont() */
|
||||
c->subfontname = nil;
|
||||
font->subf[0].age = 0;
|
||||
font->subf[0].cf = c;
|
||||
font->subf[0].f = subfont;
|
||||
return font;
|
||||
}
|
143
nudraw/mouse.c
Normal file
143
nudraw/mouse.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <thread.h>
|
||||
#include <cursor.h>
|
||||
#include <mouse.h>
|
||||
|
||||
void
|
||||
moveto(Mousectl *m, Point pt)
|
||||
{
|
||||
fprint(m->mfd, "m%d %d", pt.x, pt.y);
|
||||
m->xy = pt;
|
||||
}
|
||||
|
||||
void
|
||||
closemouse(Mousectl *mc)
|
||||
{
|
||||
if(mc == nil)
|
||||
return;
|
||||
close(mc->mfd);
|
||||
close(mc->cfd);
|
||||
mc->mfd = mc->cfd = -1;
|
||||
threadint(mc->pid);
|
||||
}
|
||||
|
||||
int
|
||||
readmouse(Mousectl *mc)
|
||||
{
|
||||
if(mc->image){
|
||||
Display *d = mc->image->display;
|
||||
if(d->bufp > d->buf)
|
||||
flushimage(d, 1);
|
||||
}
|
||||
if(recv(mc->c, &mc->Mouse) < 0){
|
||||
fprint(2, "readmouse: %r\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
_ioproc(void *arg)
|
||||
{
|
||||
int n, nerr, one;
|
||||
char buf[1+5*12];
|
||||
Mouse m;
|
||||
Mousectl *mc;
|
||||
|
||||
mc = arg;
|
||||
threadsetname("mouseproc");
|
||||
memset(&m, 0, sizeof m);
|
||||
nerr = 0;
|
||||
while(mc->mfd >= 0){
|
||||
n = read(mc->mfd, buf, sizeof buf);
|
||||
if(n != 1+4*12){
|
||||
yield(); /* if error is due to exiting, we'll exit here */
|
||||
if(mc->mfd < 0)
|
||||
break;
|
||||
fprint(2, "mouse: bad count %d not 49: %r\n", n);
|
||||
if(n<0 || ++nerr>10)
|
||||
threadexits("read error");
|
||||
continue;
|
||||
}
|
||||
nerr = 0;
|
||||
switch(buf[0]){
|
||||
case 'r':
|
||||
one = 1;
|
||||
if(nbsend(mc->resizec, &one) < 0)
|
||||
continue;
|
||||
/* fall through */
|
||||
case 'm':
|
||||
m.xy.x = atoi(buf+1+0*12);
|
||||
m.xy.y = atoi(buf+1+1*12);
|
||||
m.buttons = atoi(buf+1+2*12);
|
||||
m.msec = (ulong)atoll(buf+1+3*12);
|
||||
if(send(mc->c, &m) < 0)
|
||||
continue;
|
||||
/*
|
||||
* mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
|
||||
* This means that programs should receive into mc->Mouse (see readmouse() above) if
|
||||
* they want full synchrony.
|
||||
*/
|
||||
mc->Mouse = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(mc->file);
|
||||
chanfree(mc->c);
|
||||
chanfree(mc->resizec);
|
||||
free(mc);
|
||||
}
|
||||
|
||||
Mousectl*
|
||||
initmouse(char *file, Image *i)
|
||||
{
|
||||
Mousectl *mc;
|
||||
char *t, *sl;
|
||||
|
||||
mc = mallocz(sizeof(Mousectl), 1);
|
||||
if(file == nil)
|
||||
file = "/dev/mouse";
|
||||
mc->file = strdup(file);
|
||||
mc->mfd = open(file, ORDWR|OCEXEC);
|
||||
if(mc->mfd < 0){
|
||||
free(mc);
|
||||
return nil;
|
||||
}
|
||||
t = malloc(strlen(file)+16);
|
||||
if (t == nil) {
|
||||
close(mc->mfd);
|
||||
free(mc);
|
||||
return nil;
|
||||
}
|
||||
strcpy(t, file);
|
||||
sl = utfrrune(t, '/');
|
||||
if(sl)
|
||||
strcpy(sl, "/cursor");
|
||||
else
|
||||
strcpy(t, "/dev/cursor");
|
||||
mc->cfd = open(t, ORDWR|OCEXEC);
|
||||
free(t);
|
||||
mc->image = i;
|
||||
mc->c = chancreate(sizeof(Mouse), 0);
|
||||
mc->resizec = chancreate(sizeof(int), 1);
|
||||
mc->pid = proccreate(_ioproc, mc, 4096);
|
||||
return mc;
|
||||
}
|
||||
|
||||
void
|
||||
setcursor(Mousectl *mc, Cursor *c)
|
||||
{
|
||||
char curs[2*4+2*2*16];
|
||||
|
||||
if(c == nil)
|
||||
write(mc->cfd, curs, 0);
|
||||
else{
|
||||
BPLONG(curs+0*4, c->offset.x);
|
||||
BPLONG(curs+1*4, c->offset.y);
|
||||
memmove(curs+2*4, c->clr, 2*2*16);
|
||||
write(mc->cfd, curs, sizeof curs);
|
||||
}
|
||||
}
|
39
nudraw/newwindow.c
Normal file
39
nudraw/newwindow.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#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);
|
||||
if(fd < 0){
|
||||
free(wsys);
|
||||
return -1;
|
||||
}
|
||||
rfork(RFNAMEG);
|
||||
unmount(wsys, "/dev"); /* drop reference to old window */
|
||||
free(wsys);
|
||||
if(str)
|
||||
snprint(buf, sizeof buf, "new %s", str);
|
||||
else
|
||||
strcpy(buf, "new");
|
||||
if(mount(fd, -1, "/mnt/wsys", MREPL, buf) == -1){
|
||||
if(mount(fd, -1, "/dev", MBEFORE, buf) == -1){
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if(bind("/mnt/wsys", "/dev", MBEFORE) == -1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
47
nudraw/openfont.c
Normal file
47
nudraw/openfont.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
static char*
|
||||
readfile(char *name)
|
||||
{
|
||||
enum { HUNK = 8*1024, };
|
||||
int f, n, r;
|
||||
char *s, *p;
|
||||
|
||||
n = 0;
|
||||
r = -1;
|
||||
if((s = malloc(HUNK)) != nil){
|
||||
if((f = open(name, OREAD|OCEXEC)) >= 0){
|
||||
while((r = read(f, s+n, HUNK)) > 0){
|
||||
n += r;
|
||||
r = -1;
|
||||
if((p = realloc(s, n+HUNK)) == nil)
|
||||
break;
|
||||
s = p;
|
||||
}
|
||||
close(f);
|
||||
}
|
||||
}
|
||||
if(r < 0 || (p = realloc(s, n+1)) == nil){
|
||||
free(s);
|
||||
return nil;
|
||||
}
|
||||
p[n] = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
Font*
|
||||
openfont(Display *d, char *name)
|
||||
{
|
||||
Font *fnt;
|
||||
char *buf;
|
||||
|
||||
if((buf = readfile(name)) == nil){
|
||||
werrstr("openfont: %r");
|
||||
return nil;
|
||||
}
|
||||
fnt = buildfont(d, buf, name);
|
||||
free(buf);
|
||||
return fnt;
|
||||
}
|
87
nudraw/poly.c
Normal file
87
nudraw/poly.c
Normal 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 == nil){
|
||||
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);
|
||||
}
|
49
nudraw/readcolmap.c
Normal file
49
nudraw/readcolmap.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <bio.h>
|
||||
|
||||
static ulong
|
||||
getval(char **p)
|
||||
{
|
||||
ulong v;
|
||||
char *q;
|
||||
|
||||
v = strtoul(*p, &q, 0);
|
||||
v |= v<<8;
|
||||
v |= v<<16;
|
||||
*p = q;
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
readcolmap(Display *d, RGB *colmap)
|
||||
{
|
||||
int i;
|
||||
char *p, *q;
|
||||
Biobuf *b;
|
||||
char buf[128];
|
||||
|
||||
USED(screen);
|
||||
|
||||
sprint(buf, "/dev/draw/%d/colormap", d->dirno);
|
||||
b = Bopen(buf, OREAD|OCEXEC);
|
||||
if(b == nil)
|
||||
drawerror(d, "rdcolmap: can't open colormap device");
|
||||
|
||||
for(;;) {
|
||||
p = Brdline(b, '\n');
|
||||
if(p == 0)
|
||||
break;
|
||||
i = strtoul(p, &q, 0);
|
||||
if(i < 0 || i > 255) {
|
||||
fprint(2, "rdcolmap: bad index\n");
|
||||
exits("bad");
|
||||
}
|
||||
p = q;
|
||||
colmap[255-i].red = getval(&p);
|
||||
colmap[255-i].green = getval(&p);
|
||||
colmap[255-i].blue = getval(&p);
|
||||
}
|
||||
Bterm(b);
|
||||
}
|
136
nudraw/readimage.c
Normal file
136
nudraw/readimage.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Image*
|
||||
readimage(Display *d, int fd, int dolock)
|
||||
{
|
||||
char hdr[5*12+1];
|
||||
int dy;
|
||||
int new;
|
||||
uint l, n;
|
||||
int m, j, chunk;
|
||||
int miny, maxy;
|
||||
Rectangle r;
|
||||
int ldepth;
|
||||
ulong chan;
|
||||
uchar *tmp;
|
||||
Image *i;
|
||||
|
||||
if(readn(fd, hdr, 11) != 11)
|
||||
return nil;
|
||||
if(memcmp(hdr, "compressed\n", 11) == 0){
|
||||
if(i = creadimage(d, fd, dolock))
|
||||
goto Done;
|
||||
return nil;
|
||||
}
|
||||
|
||||
if(readn(fd, hdr+11, 5*12-11) != 5*12-11)
|
||||
return nil;
|
||||
if(d != nil)
|
||||
chunk = d->bufsize - 32; /* a little room for header */
|
||||
else {
|
||||
chunk = iounit(fd);
|
||||
if(chunk <= 0)
|
||||
chunk = IOUNIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
if(l > chunk)
|
||||
chunk = l;
|
||||
if(d != nil){
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
i = allocimage(d, r, chan, 0, -1);
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
}else{
|
||||
i = mallocz(sizeof(Image), 1);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
}
|
||||
tmp = malloc(chunk);
|
||||
if(tmp == nil)
|
||||
goto Err;
|
||||
while(maxy > miny){
|
||||
dy = maxy - miny;
|
||||
if(dy*l > chunk)
|
||||
dy = chunk/l;
|
||||
n = dy*l;
|
||||
m = readn(fd, tmp, n);
|
||||
if(m != n){
|
||||
werrstr("readimage: read count %d not %d: %r", m, n);
|
||||
Err:
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
Err1:
|
||||
freeimage(i);
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
free(tmp);
|
||||
return nil;
|
||||
}
|
||||
if(!new) /* an old image: must flip all the bits */
|
||||
for(j=0; j<chunk; j++)
|
||||
tmp[j] ^= 0xFF;
|
||||
|
||||
if(d != nil){
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
if(loadimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
|
||||
goto Err1;
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
}
|
||||
miny += dy;
|
||||
}
|
||||
free(tmp);
|
||||
Done:
|
||||
setmalloctag(i, getcallerpc(&d));
|
||||
return i;
|
||||
}
|
64
nudraw/readsubfont.c
Normal file
64
nudraw/readsubfont.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Subfont*
|
||||
readsubfonti(Display*d, char *name, int fd, Image *ai, int dolock)
|
||||
{
|
||||
char hdr[3*12+4+1];
|
||||
int n;
|
||||
uchar *p;
|
||||
Fontchar *fc;
|
||||
Subfont *f;
|
||||
Image *i;
|
||||
|
||||
i = ai;
|
||||
if(i == nil){
|
||||
i = readimage(d, fd, dolock);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
}
|
||||
p = nil;
|
||||
if(readn(fd, hdr, 3*12) != 3*12){
|
||||
werrstr("readsubfont: header read error: %r");
|
||||
goto Err;
|
||||
}
|
||||
n = atoi(hdr);
|
||||
if(n <= 0 || n > 0x7fff){
|
||||
werrstr("readsubfont: bad fontchar count %d", n);
|
||||
goto Err;
|
||||
}
|
||||
p = malloc(6*(n+1));
|
||||
if(p == nil)
|
||||
goto Err;
|
||||
if(readn(fd, p, 6*(n+1)) != 6*(n+1)){
|
||||
werrstr("readsubfont: fontchar read error: %r");
|
||||
goto Err;
|
||||
}
|
||||
fc = malloc(sizeof(Fontchar)*(n+1));
|
||||
if(fc == nil)
|
||||
goto Err;
|
||||
_unpackinfo(fc, p, n);
|
||||
if(dolock)
|
||||
lockdisplay(d);
|
||||
f = allocsubfont(name, n, atoi(hdr+12), atoi(hdr+24), fc, i);
|
||||
if(dolock)
|
||||
unlockdisplay(d);
|
||||
if(f == nil){
|
||||
free(fc);
|
||||
goto Err;
|
||||
}
|
||||
free(p);
|
||||
return f;
|
||||
Err:
|
||||
if(ai == nil)
|
||||
freeimage(i);
|
||||
free(p);
|
||||
return nil;
|
||||
}
|
||||
|
||||
Subfont*
|
||||
readsubfont(Display *d, char *name, int fd, int dolock)
|
||||
{
|
||||
return readsubfonti(d, name, fd, nil, dolock);
|
||||
}
|
25
nudraw/rectclip.c
Normal file
25
nudraw/rectclip.c
Normal 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;
|
||||
}
|
25
nudraw/replclipr.c
Normal file
25
nudraw/replclipr.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
void
|
||||
replclipr(Image *i, int repl, Rectangle clipr)
|
||||
{
|
||||
uchar *b;
|
||||
|
||||
b = bufimage(i->display, 22);
|
||||
if(b == nil){
|
||||
fprint(2, "replclipr: %r\n");
|
||||
return;
|
||||
}
|
||||
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
nudraw/rgb.c
Normal file
99
nudraw/rgb.c
Normal 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;
|
||||
ulong 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;
|
||||
}
|
29
nudraw/scroll.c
Normal file
29
nudraw/scroll.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
int
|
||||
mousescrollsize(int maxlines)
|
||||
{
|
||||
static int lines, pcnt;
|
||||
char *mss;
|
||||
|
||||
if(lines == 0 && pcnt == 0){
|
||||
mss = getenv("mousescrollsize");
|
||||
if(mss){
|
||||
if(strchr(mss, '%') != nil)
|
||||
pcnt = atof(mss);
|
||||
else
|
||||
lines = atoi(mss);
|
||||
free(mss);
|
||||
}
|
||||
if(lines == 0 && pcnt == 0)
|
||||
lines = 1;
|
||||
if(pcnt>=100)
|
||||
pcnt = 100;
|
||||
}
|
||||
|
||||
if(lines)
|
||||
return lines;
|
||||
return pcnt * maxlines/100.0;
|
||||
}
|
152
nudraw/string.c
Normal file
152
nudraw/string.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
enum
|
||||
{
|
||||
Max = 100
|
||||
};
|
||||
|
||||
Point
|
||||
string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, nil, ZP, SoverD);
|
||||
}
|
||||
|
||||
Point
|
||||
stringop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Drawop op)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, nil, ZP, op);
|
||||
}
|
||||
|
||||
Point
|
||||
stringn(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP, SoverD);
|
||||
}
|
||||
|
||||
Point
|
||||
stringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len, Drawop op)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP, op);
|
||||
}
|
||||
|
||||
Point
|
||||
runestring(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP, SoverD);
|
||||
}
|
||||
|
||||
Point
|
||||
runestringop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, Drawop op)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP, op);
|
||||
}
|
||||
|
||||
Point
|
||||
runestringn(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP, SoverD);
|
||||
}
|
||||
|
||||
Point
|
||||
runestringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len, Drawop op)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP, op);
|
||||
}
|
||||
|
||||
Point
|
||||
_string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, int len, Rectangle clipr, Image *bg, Point bgp, Drawop op)
|
||||
{
|
||||
int m, n, wid, max, try;
|
||||
ushort cbuf[Max], *c, *ec;
|
||||
uchar *b;
|
||||
char *subfontname;
|
||||
char **sptr;
|
||||
Rune **rptr, rune;
|
||||
Subfont *sf;
|
||||
|
||||
if(s == nil){
|
||||
s = "";
|
||||
sptr = nil;
|
||||
}else
|
||||
sptr = &s;
|
||||
if(r == nil){
|
||||
r = (Rune*) L"";
|
||||
rptr = nil;
|
||||
}else
|
||||
rptr = &r;
|
||||
subfontname = nil;
|
||||
sf = nil;
|
||||
try = 0;
|
||||
while((*s || *r) && len > 0){
|
||||
max = Max;
|
||||
if(len < max)
|
||||
max = len;
|
||||
if(subfontname){
|
||||
freesubfont(sf);
|
||||
if((sf=_getsubfont(f->display, subfontname)) == nil){
|
||||
if(f->display->defaultfont == nil || f->display->defaultfont == f)
|
||||
break;
|
||||
f = f->display->defaultfont;
|
||||
}
|
||||
}
|
||||
if((n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){
|
||||
if(n == 0){
|
||||
if(++try > 10)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if(*r)
|
||||
r++;
|
||||
else
|
||||
s += chartorune(&rune, s);
|
||||
len--;
|
||||
continue;
|
||||
}
|
||||
try = 0;
|
||||
|
||||
_setdrawop(dst->display, op);
|
||||
|
||||
m = 47+2*n;
|
||||
if(bg)
|
||||
m += 4+2*4;
|
||||
b = bufimage(dst->display, m);
|
||||
if(b == nil){
|
||||
fprint(2, "string: %r\n");
|
||||
break;
|
||||
}
|
||||
if(bg)
|
||||
b[0] = 'x';
|
||||
else
|
||||
b[0] = 's';
|
||||
BPLONG(b+1, dst->id);
|
||||
BPLONG(b+5, src->id);
|
||||
BPLONG(b+9, f->cacheimage->id);
|
||||
BPLONG(b+13, pt.x);
|
||||
BPLONG(b+17, pt.y+f->ascent);
|
||||
BPLONG(b+21, clipr.min.x);
|
||||
BPLONG(b+25, clipr.min.y);
|
||||
BPLONG(b+29, clipr.max.x);
|
||||
BPLONG(b+33, clipr.max.y);
|
||||
BPLONG(b+37, sp.x);
|
||||
BPLONG(b+41, sp.y);
|
||||
BPSHORT(b+45, n);
|
||||
b += 47;
|
||||
if(bg){
|
||||
BPLONG(b, bg->id);
|
||||
BPLONG(b+4, bgp.x);
|
||||
BPLONG(b+8, bgp.y);
|
||||
b += 12;
|
||||
}
|
||||
ec = &cbuf[n];
|
||||
for(c=cbuf; c<ec; c++, b+=2)
|
||||
BPSHORT(b, *c);
|
||||
pt.x += wid;
|
||||
bgp.x += wid;
|
||||
agefont(f);
|
||||
len -= n;
|
||||
}
|
||||
freesubfont(sf);
|
||||
return pt;
|
||||
}
|
51
nudraw/stringbg.c
Normal file
51
nudraw/stringbg.c
Normal 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, int 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, int 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, int 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, int op)
|
||||
{
|
||||
return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, bg, bgp, op);
|
||||
}
|
65
nudraw/stringsubfont.c
Normal file
65
nudraw/stringsubfont.c
Normal 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;
|
||||
}
|
98
nudraw/stringwidth.c
Normal file
98
nudraw/stringwidth.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
int
|
||||
_stringnwidth(Font *f, char *s, Rune *r, int len)
|
||||
{
|
||||
int wid, twid, n, max, try;
|
||||
enum { Max = 64 };
|
||||
ushort cbuf[Max];
|
||||
Rune rune, **rptr;
|
||||
char *subfontname, **sptr;
|
||||
Subfont *sf;
|
||||
|
||||
if(s == nil){
|
||||
s = "";
|
||||
sptr = nil;
|
||||
}else
|
||||
sptr = &s;
|
||||
if(r == nil){
|
||||
r = L"";
|
||||
rptr = nil;
|
||||
}else
|
||||
rptr = &r;
|
||||
subfontname = nil;
|
||||
sf = nil;
|
||||
twid = 0;
|
||||
try = 0;
|
||||
while((*s || *r) && len > 0){
|
||||
max = Max;
|
||||
if(len < max)
|
||||
max = len;
|
||||
if(subfontname){
|
||||
freesubfont(sf);
|
||||
if((sf=_getsubfont(f->display, subfontname)) == nil){
|
||||
if(f->display == nil || f->display->defaultfont == nil || f->display->defaultfont == f)
|
||||
break;
|
||||
f = f->display->defaultfont;
|
||||
}
|
||||
}
|
||||
if((n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){
|
||||
if(n == 0){
|
||||
if(++try > 10)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if(*r)
|
||||
r++;
|
||||
else
|
||||
s += chartorune(&rune, s);
|
||||
len--;
|
||||
continue;
|
||||
}
|
||||
try = 0;
|
||||
|
||||
agefont(f);
|
||||
twid += wid;
|
||||
len -= n;
|
||||
}
|
||||
freesubfont(sf);
|
||||
return twid;
|
||||
}
|
||||
|
||||
int
|
||||
stringnwidth(Font *f, char *s, int len)
|
||||
{
|
||||
return _stringnwidth(f, s, nil, len);
|
||||
}
|
||||
|
||||
int
|
||||
stringwidth(Font *f, char *s)
|
||||
{
|
||||
return _stringnwidth(f, s, nil, 1<<24);
|
||||
}
|
||||
|
||||
Point
|
||||
stringsize(Font *f, char *s)
|
||||
{
|
||||
return Pt(_stringnwidth(f, s, nil, 1<<24), f->height);
|
||||
}
|
||||
|
||||
int
|
||||
runestringnwidth(Font *f, Rune *r, int len)
|
||||
{
|
||||
return _stringnwidth(f, nil, r, len);
|
||||
}
|
||||
|
||||
int
|
||||
runestringwidth(Font *f, Rune *r)
|
||||
{
|
||||
return _stringnwidth(f, nil, r, 1<<24);
|
||||
}
|
||||
|
||||
Point
|
||||
runestringsize(Font *f, Rune *r)
|
||||
{
|
||||
return Pt(_stringnwidth(f, nil, r, 1<<24), f->height);
|
||||
}
|
31
nudraw/subfont.c
Normal file
31
nudraw/subfont.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
Subfont*
|
||||
allocsubfont(char *name, int n, int height, int ascent, Fontchar *info, Image *i)
|
||||
{
|
||||
Subfont *f;
|
||||
|
||||
assert(height != 0 /* allocsubfont */);
|
||||
|
||||
f = malloc(sizeof(Subfont));
|
||||
if(f == nil)
|
||||
return nil;
|
||||
f->n = n;
|
||||
f->height = height;
|
||||
f->ascent = ascent;
|
||||
f->info = info;
|
||||
f->bits = i;
|
||||
f->ref = 1;
|
||||
if(name){
|
||||
f->name = strdup(name);
|
||||
if(f->name == nil){
|
||||
free(f);
|
||||
return nil;
|
||||
}
|
||||
installsubfont(name, f);
|
||||
}else
|
||||
f->name = nil;
|
||||
return f;
|
||||
}
|
41
nudraw/subfontcache.c
Normal file
41
nudraw/subfontcache.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
/*
|
||||
* Easy versions of the cache routines; may be substituted by fancier ones for other purposes
|
||||
*/
|
||||
|
||||
static char *lastname;
|
||||
static Subfont *lastsubfont;
|
||||
|
||||
Subfont*
|
||||
lookupsubfont(Display *d, char *name)
|
||||
{
|
||||
if(d && strcmp(name, "*default*") == 0)
|
||||
return d->defaultsubfont;
|
||||
if(lastname && strcmp(name, lastname)==0)
|
||||
if(d==lastsubfont->bits->display){
|
||||
lastsubfont->ref++;
|
||||
return lastsubfont;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
installsubfont(char *name, Subfont *subfont)
|
||||
{
|
||||
free(lastname);
|
||||
lastname = strdup(name);
|
||||
lastsubfont = subfont; /* notice we don't free the old one; that's your business */
|
||||
}
|
||||
|
||||
void
|
||||
uninstallsubfont(Subfont *subfont)
|
||||
{
|
||||
if(subfont == lastsubfont){
|
||||
free(lastname);
|
||||
lastname = 0;
|
||||
lastsubfont = 0;
|
||||
}
|
||||
}
|
52
nudraw/subfontname.c
Normal file
52
nudraw/subfontname.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
/*
|
||||
* Default version: convert to file name
|
||||
*/
|
||||
|
||||
char*
|
||||
subfontname(char *cfname, char *fname, int maxdepth)
|
||||
{
|
||||
char *t, *u, *tmp1, *tmp2;
|
||||
int i;
|
||||
|
||||
t = strdup(cfname); /* t is the return string */
|
||||
if(strcmp(cfname, "*default*") == 0)
|
||||
return t;
|
||||
if(t[0] != '/'){
|
||||
tmp2 = strdup(fname);
|
||||
u = utfrrune(tmp2, '/');
|
||||
if(u)
|
||||
u[0] = 0;
|
||||
else
|
||||
strcpy(tmp2, ".");
|
||||
tmp1 = smprint("%s/%s", tmp2, t);
|
||||
free(tmp2);
|
||||
free(t);
|
||||
t = tmp1;
|
||||
}
|
||||
|
||||
if(maxdepth > 8)
|
||||
maxdepth = 8;
|
||||
|
||||
for(i=3; i>=0; i--){
|
||||
if((1<<i) > maxdepth)
|
||||
continue;
|
||||
/* try i-bit grey */
|
||||
tmp2 = smprint("%s.%d", t, i);
|
||||
if(access(tmp2, AREAD) == 0) {
|
||||
free(t);
|
||||
return tmp2;
|
||||
}
|
||||
free(tmp2);
|
||||
}
|
||||
|
||||
/* try default */
|
||||
if(access(t, AREAD) == 0)
|
||||
return t;
|
||||
|
||||
free(t);
|
||||
return nil;
|
||||
}
|
10
nudraw/test.c
Normal file
10
nudraw/test.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
print("%dn", wordsperline(Rect(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), atoi(argv[4])), atoi(argv[5])));
|
||||
}
|
58
nudraw/unloadimage.c
Normal file
58
nudraw/unloadimage.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
int
|
||||
unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
|
||||
{
|
||||
int bpl, n, chunk, dx, dy;
|
||||
uchar *a, *start;
|
||||
Display *d;
|
||||
|
||||
if(!rectinrect(r, i->r)){
|
||||
werrstr("unloadimage: bad rectangle");
|
||||
return -1;
|
||||
}
|
||||
bpl = bytesperline(r, i->depth);
|
||||
if(ndata < bpl*Dy(r)){
|
||||
werrstr("unloadimage: buffer too small");
|
||||
return -1;
|
||||
}
|
||||
start = data;
|
||||
d = i->display;
|
||||
chunk = d->bufsize;
|
||||
flushimage(d, 0); /* make sure subsequent flush is for us only */
|
||||
while(r.min.y < r.max.y){
|
||||
dx = Dx(r);
|
||||
dy = chunk/bpl;
|
||||
if(dy <= 0){
|
||||
dy = 1;
|
||||
dx = ((chunk*dx)/bpl) & ~7;
|
||||
n = bytesperline(Rect(r.min.x, r.min.y, r.min.x+dx, r.min.y+dy), i->depth);
|
||||
if(unloadimage(i, Rect(r.min.x+dx, r.min.y, r.max.x, r.min.y+dy), data+n, bpl-n) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if(dy > Dy(r))
|
||||
dy = Dy(r);
|
||||
n = bpl*dy;
|
||||
}
|
||||
a = bufimage(d, 1+4+4*4);
|
||||
if(a == nil){
|
||||
werrstr("unloadimage: %r");
|
||||
return -1;
|
||||
}
|
||||
a[0] = 'r';
|
||||
BPLONG(a+1, i->id);
|
||||
BPLONG(a+5, r.min.x);
|
||||
BPLONG(a+9, r.min.y);
|
||||
BPLONG(a+13, r.min.x+dx);
|
||||
BPLONG(a+17, r.min.y+dy);
|
||||
if(flushimage(d, 0) < 0)
|
||||
return -1;
|
||||
if(read(d->fd, data, n) < 0)
|
||||
return -1;
|
||||
data += bpl*dy;
|
||||
r.min.y += dy;
|
||||
}
|
||||
return data - start;
|
||||
}
|
210
nudraw/window.c
Normal file
210
nudraw/window.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
#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 nil;
|
||||
}
|
||||
s = malloc(sizeof(Screen));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
if(!screenid)
|
||||
screenid = getpid();
|
||||
for(try=0; try<25; try++){
|
||||
/* loop until find a free id */
|
||||
a = bufimage(d, 1+4+4+4+1);
|
||||
if(a == nil)
|
||||
break;
|
||||
id = ++screenid & 0xffff; /* old devdraw bug */
|
||||
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)
|
||||
goto Found;
|
||||
}
|
||||
free(s);
|
||||
return nil;
|
||||
|
||||
Found:
|
||||
s->display = d;
|
||||
s->id = id;
|
||||
s->image = image;
|
||||
assert(s->image != nil && s->image->chan != 0);
|
||||
|
||||
s->fill = fill;
|
||||
return s;
|
||||
}
|
||||
|
||||
Screen*
|
||||
publicscreen(Display *d, int id, ulong chan)
|
||||
{
|
||||
uchar *a;
|
||||
Screen *s;
|
||||
|
||||
s = malloc(sizeof(Screen));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
a = bufimage(d, 1+4+4);
|
||||
if(a == nil){
|
||||
Error:
|
||||
free(s);
|
||||
return nil;
|
||||
}
|
||||
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 = nil;
|
||||
s->fill = nil;
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
freescreen(Screen *s)
|
||||
{
|
||||
uchar *a;
|
||||
Display *d;
|
||||
|
||||
if(s == nil)
|
||||
return 0;
|
||||
d = s->display;
|
||||
a = bufimage(d, 1+4);
|
||||
if(a == nil){
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
a[0] = 'F';
|
||||
BPLONG(a+1, s->id);
|
||||
free(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Image*
|
||||
allocwindow(Screen *s, Rectangle r, int ref, ulong col)
|
||||
{
|
||||
return _allocwindow(nil, s, r, ref, col);
|
||||
}
|
||||
|
||||
Image*
|
||||
_allocwindow(Image *i, Screen *s, Rectangle r, int ref, ulong col)
|
||||
{
|
||||
Display *d;
|
||||
|
||||
d = s->display;
|
||||
i = _allocimage(i, d, r, d->screenimage->chan, 0, col, s->id, ref);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
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);
|
||||
if(b == nil)
|
||||
return;
|
||||
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 != nil)
|
||||
topbottom(&w, 1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
topwindow(Image *w)
|
||||
{
|
||||
if(w->screen != nil)
|
||||
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;
|
||||
|
||||
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);
|
||||
delta = subpt(log, w->r.min);
|
||||
w->r = rectaddpt(w->r, delta);
|
||||
w->clipr = rectaddpt(w->clipr, delta);
|
||||
return 1;
|
||||
}
|
37
nudraw/writecolmap.c
Normal file
37
nudraw/writecolmap.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
|
||||
/*
|
||||
* This code (and the devdraw interface) will have to change
|
||||
* if we ever get bitmaps with ldepth > 3, because the
|
||||
* colormap will have to be written in chunks
|
||||
*/
|
||||
|
||||
void
|
||||
writecolmap(Display *d, RGB *m)
|
||||
{
|
||||
int i, n, fd;
|
||||
char buf[64], *t;
|
||||
ulong r, g, b;
|
||||
|
||||
sprint(buf, "/dev/draw/%d/colormap", d->dirno);
|
||||
fd = open(buf, OWRITE|OCEXEC);
|
||||
if(fd < 0)
|
||||
drawerror(d, "writecolmap: open colormap failed");
|
||||
t = malloc(8192);
|
||||
if (t == nil)
|
||||
drawerror(d, "writecolmap: no memory");
|
||||
n = 0;
|
||||
for(i = 0; i < 256; i++) {
|
||||
r = m[i].red>>24;
|
||||
g = m[i].green>>24;
|
||||
b = m[i].blue>>24;
|
||||
n += sprint(t+n, "%d %lud %lud %lud\n", 255-i, r, g, b);
|
||||
}
|
||||
i = write(fd, t, n);
|
||||
free(t);
|
||||
close(fd);
|
||||
if(i != n)
|
||||
drawerror(d, "writecolmap: bad write");
|
||||
}
|
213
nudraw/writeimage.c
Normal file
213
nudraw/writeimage.c
Normal file
|
@ -0,0 +1,213 @@
|
|||
#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);
|
||||
ncblock = _compblocksize(r, i->depth);
|
||||
if(ncblock > chunk){
|
||||
sprint(hdr, "%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, 5*12) != 5*12)
|
||||
return -1;
|
||||
data = malloc(bpl);
|
||||
for(miny = r.min.y; miny != r.max.y; miny++){
|
||||
if(dolock)
|
||||
lockdisplay(i->display);
|
||||
nb = unloadimage(i, Rect(r.min.x, miny, r.max.x, miny+1), data, bpl);
|
||||
if(dolock)
|
||||
unlockdisplay(i->display);
|
||||
if(nb != bpl)
|
||||
goto ErrOut0;
|
||||
if(write(fd, data, nb) != nb)
|
||||
goto ErrOut0;
|
||||
}
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = Dy(r)*bpl;
|
||||
data = malloc(n);
|
||||
if(data == 0){
|
||||
ErrOut0:
|
||||
free(data);
|
||||
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(dy <= 0)
|
||||
dy = 1;
|
||||
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 ErrOut0;
|
||||
}
|
||||
|
||||
outbuf = malloc(ncblock);
|
||||
hash = malloc(NHASH*sizeof(Hlist));
|
||||
chain = malloc(NMEM*sizeof(Hlist));
|
||||
if(outbuf == 0 || hash == 0 || chain == 0){
|
||||
ErrOut:
|
||||
free(outbuf);
|
||||
free(hash);
|
||||
free(chain);
|
||||
goto ErrOut0;
|
||||
}
|
||||
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;
|
||||
}
|
45
nudraw/writesubfont.c
Normal file
45
nudraw/writesubfont.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue