ref: 527b4239947e30e85d1853cd2b01a0640e5397fb
parent: 8d3156dba0a65a232a063eb45d82c3c67d55c17b
author: qwx <qwx@sciops.net>
date: Thu Jan 13 19:21:49 EST 2022
split source sorry, lilu dallas sam mooltizerox isn't enough for my caveman brain
--- /dev/null
+++ b/canvas.c
@@ -1,0 +1,102 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+Image *back;
+Image *canvas;
+Point spos; /* position on screen */
+Point cpos; /* position on canvas */
+
+static Image **pages;
+static int npages;
+
+static int nundo = 0;
+static Image *undo[1024];
+
+Point
+s2c(Point p)
+{+ p = subpt(p, spos);
+ if(p.x < 0) p.x -= zoom-1;
+ if(p.y < 0) p.y -= zoom-1;
+ return addpt(divpt(p, zoom), cpos);
+}
+
+Point
+c2s(Point p)
+{+ return addpt(mulpt(subpt(p, cpos), zoom), spos);
+}
+
+Rectangle
+c2sr(Rectangle r)
+{+ return Rpt(c2s(r.min), c2s(r.max));
+}
+
+void
+save(Rectangle r, int mark)
+{+ Image *tmp;
+ int x;
+
+ if(mark){+ x = nundo++ % nelem(undo);
+ if(undo[x])
+ freeimage(undo[x]);
+ undo[x] = nil;
+ }
+ if(canvas==nil || nundo<0)
+ return;
+ if(!rectclip(&r, canvas->r))
+ return;
+ if((tmp = allocimage(display, r, canvas->chan, 0, DNofill)) == nil)
+ return;
+ draw(tmp, r, canvas, nil, r.min);
+ x = nundo++ % nelem(undo);
+ if(undo[x])
+ freeimage(undo[x]);
+ undo[x] = tmp;
+}
+
+void
+restore(int n)
+{+ Image *tmp;
+ int x;
+
+ while(nundo > 0){+ if(n-- == 0)
+ return;
+ x = --nundo % nelem(undo);
+ if((tmp = undo[x]) == nil)
+ return;
+ undo[x] = nil;
+ if(canvas == nil || canvas->chan != tmp->chan){+ freeimage(canvas);
+ canvas = tmp;
+ update(nil);
+ } else {+ expand(tmp->r);
+ draw(canvas, tmp->r, tmp, nil, tmp->r.min);
+ update(&tmp->r);
+ freeimage(tmp);
+ }
+ }
+}
+
+void
+initcnv(char *file)
+{+ int fd;
+
+ if(file == nil)
+ return;
+ if((fd = open(file, OREAD)) < 0)
+ sysfatal("open: %r");+ if((canvas = readimage(display, fd, 0)) == nil)
+ sysfatal("readimage: %r");+ close(fd);
+}
--- /dev/null
+++ b/cmd.c
@@ -1,0 +1,48 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <mouse.h>
+
+
+static void
+catch(void *, char *msg)
+{+ if(strstr(msg, "closed pipe"))
+ noted(NCONT);
+ noted(NDFLT);
+}
+
+int
+pipeline(char *fmt, ...)
+{+ char buf[1024];
+ va_list a;
+ int p[2];
+
+ va_start(a, fmt);
+ vsnprint(buf, sizeof(buf), fmt, a);
+ va_end(a);
+ if(pipe(p) < 0)
+ return -1;
+ switch(rfork(RFPROC|RFMEM|RFFDG|RFNOTEG|RFREND)){+ case -1:
+ close(p[0]);
+ close(p[1]);
+ return -1;
+ case 0:
+ close(p[1]);
+ dup(p[0], 0);
+ dup(p[0], 1);
+ close(p[0]);
+ execl("/bin/rc", "rc", "-c", buf, nil);+ exits("exec");+ }
+ close(p[0]);
+ return p[1];
+}
+
+void
+initcmd(void)
+{+ notify(catch);
+}
--- /dev/null
+++ b/dat.h
@@ -1,0 +1,14 @@
+enum{+ NBRUSH = 10+1,
+};
+
+extern Image *ink;
+
+extern Image *back;
+extern Image *canvas;
+extern Point spos;
+extern Point cpos;
+
+extern int brush;
+
+extern int zoom;
--- /dev/null
+++ b/draw.c
@@ -1,0 +1,7 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+int brush = 1;
--- /dev/null
+++ b/fns.h
@@ -1,0 +1,14 @@
+void initpal(int);
+void drawpal(void);
+void initcnv(char*);
+Point s2c(Point);
+Point c2s(Point);
+Rectangle c2sr(Rectangle);
+void save(Rectangle, int);
+void restore(int);
+void initcmd(void);
+void update(Rectangle*);
+Rectangle strokerect(Rectangle, int);
+void strokedraw(Image*, Rectangle, Image*, int);
+void gendrawdiff(Image*, Rectangle, Rectangle, Image*, Point, Image*, Point, int);
+void expand(Rectangle);
--- a/mkfile
+++ b/mkfile
@@ -1,6 +1,12 @@
</$objtype/mkfile
BIN=$home/bin/$objtype
TARG=prez
-OFILES=prez.$O
-HFILES=
+OFILES=\
+ canvas.$O\
+ cmd.$O\
+ draw.$O\
+ pal.$O\
+ prez.$O\
+
+HFILES=dat.h fns.h
</sys/src/cmd/mkone
--- /dev/null
+++ b/pal.c
@@ -1,0 +1,140 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <mouse.h>
+#include "dat.h"
+#include "fns.h"
+
+Image *ink;
+
+static int palcol[] = {+ 0x000000,
+ 0xFFFFFF, 0xC0C0C0, 0x7F7F7F,
+ 0xFF0000, 0xC00000, 0x7F0000,
+ 0xFF7F00, 0xC06000, 0x7F3F00,
+ 0xFFFF00, 0xC0C000, 0x7F7F00,
+ 0x00FF00, 0x00C000, 0x007F00,
+ 0x00FFFF, 0x00C0C0, 0x007F7F,
+ 0x0000FF, 0x0000C0, 0x00007F,
+ 0x7F00FF, 0x6000C0, 0x3F007F,
+ 0xFF00FF, 0xC000C0, 0x7F007F,
+};
+static Image *pal[nelem(palcol)];
+static Rectangle palr, penr;
+
+void
+drawpal(void)
+{+ Rectangle r, rr;
+ int i;
+
+ r = screen->r;
+ r.min.y = r.max.y - 20;
+ replclipr(screen, 0, r);
+
+ penr = r;
+ penr.min.x = r.max.x - NBRUSH*Dy(r);
+
+ palr = r;
+ palr.max.x = penr.min.x;
+
+ r = penr;
+ draw(screen, r, back, nil, ZP);
+ for(i=0; i<NBRUSH; i++){+ r.max.x = penr.min.x + (i+1)*Dx(penr) / NBRUSH;
+ rr = r;
+ if(i == brush)
+ rr.min.y += Dy(r)/3;
+ if(i == NBRUSH-1){+ /* last is special brush for fill draw */
+ draw(screen, rr, ink, nil, ZP);
+ } else {+ rr.min = addpt(rr.min, divpt(subpt(rr.max, rr.min), 2));
+ rr.max = rr.min;
+ strokedraw(screen, rr, ink, i);
+ }
+ r.min.x = r.max.x;
+ }
+
+ r = palr;
+ for(i=1; i<=nelem(pal); i++){+ r.max.x = palr.min.x + i*Dx(palr) / nelem(pal);
+ rr = r;
+ if(ink == pal[i-1])
+ rr.min.y += Dy(r)/3;
+ draw(screen, rr, pal[i-1], nil, ZP);
+ gendrawdiff(screen, r, rr, back, ZP, nil, ZP, SoverD);
+ r.min.x = r.max.x;
+ }
+
+ r = screen->r;
+ r.max.y -= Dy(palr);
+ replclipr(screen, 0, r);
+}
+
+int
+hitpal(Mouse m)
+{+ int i;
+
+ if(ptinrect(m.xy, penr)){+ if(m.buttons & 7){+ brush = ((m.xy.x - penr.min.x) * NBRUSH) / Dx(penr);
+ drawpal();
+ }
+ return 1;
+ }
+ if(ptinrect(m.xy, palr)){+ Image *col;
+
+ i = (m.xy.x - palr.min.x) * nelem(pal) / Dx(palr);
+ col = pal[i];
+ switch(m.buttons & 7){+ case 1:
+ ink = col;
+ drawpal();
+ break;
+ case 2:
+ back = col;
+ drawpal();
+ update(nil);
+ break;
+ /* -> picker
+ case 4:
+ snprint(buf, sizeof(buf), "%06x", palcol[i]);
+ if(eenter("Hex", buf, sizeof(buf), &m) == 6){+ c = strtoll(buf, &e, 16);
+ if(*e == 0){+ palcol[i] = c;
+ freeimage(pal[i]);
+ pal[i] = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, c<<8|0xff);
+ drawpal();
+ }
+ }
+ break;
+ */
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void
+initpal(int invbg)
+{+ int i;
+
+ for(i=0; i<nelem(pal); i++){+ pal[i] = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1,
+ palcol[i % nelem(palcol)]<<8 | 0xFF);
+ if(pal[i] == nil)
+ sysfatal("allocimage: %r");+ }
+ if(invbg){+ ink = pal[1];
+ back = pal[0];
+ }else{+ ink = pal[0];
+ back = pal[1];
+ }
+}
--- a/prez.c
+++ b/prez.c
@@ -3,44 +3,16 @@
#include <draw.h>
#include <event.h>
#include <keyboard.h>
+#include "dat.h"
+#include "fns.h"
-char *filename;
int zoom = 1;
-int brush = 1;
-Point spos; /* position on screen */
-Point cpos; /* position on canvas */
-Image *canvas;
-Image *ink;
-Image *back;
-Rectangle palr; /* palette rect on screen */
-Rectangle penr; /* pen size rect on screen */
-enum {- NBRUSH = 10+1,
-};
-
-int nundo = 0;
-Image *undo[1024];
-
-int c64[] = { /* c64 color palette */- 0x000000,
- 0xFFFFFF, 0xC0C0C0, 0x7F7F7F,
- 0xFF0000, 0xC00000, 0x7F0000,
- 0xFF7F00, 0xC06000, 0x7F3F00,
- 0xFFFF00, 0xC0C000, 0x7F7F00,
- 0x00FF00, 0x00C000, 0x007F00,
- 0x00FFFF, 0x00C0C0, 0x007F7F,
- 0x0000FF, 0x0000C0, 0x00007F,
- 0x7F00FF, 0x6000C0, 0x3F007F,
- 0xFF00FF, 0xC000C0, 0x7F007F,
-};
-Image *pal[nelem(c64)]; /* palette */
-
/*
- * get bounding rectnagle for stroke from r.min to r.max with
+ * get bounding rectangle for stroke from r.min to r.max with
* specified brush (size).
*/
-static Rectangle
+Rectangle
strokerect(Rectangle r, int brush)
{r = canonrect(r);
@@ -51,7 +23,7 @@
* draw stroke from r.min to r.max to dst with color ink and
* brush (size).
*/
-static void
+void
strokedraw(Image *dst, Rectangle r, Image *ink, int brush)
{if(!eqpt(r.min, r.max))
@@ -63,7 +35,7 @@
* A draw operation that touches only the area contained in bot but not in top.
* mp and sp get aligned with bot.min.
*/
-static void
+void
gendrawdiff(Image *dst, Rectangle bot, Rectangle top,
Image *src, Point sp, Image *mask, Point mp, int op)
{@@ -184,24 +156,6 @@
freeimage(t);
}
-Point
-s2c(Point p){- p = subpt(p, spos);
- if(p.x < 0) p.x -= zoom-1;
- if(p.y < 0) p.y -= zoom-1;
- return addpt(divpt(p, zoom), cpos);
-}
-
-Point
-c2s(Point p){- return addpt(mulpt(subpt(p, cpos), zoom), spos);
-}
-
-Rectangle
-c2sr(Rectangle r){- return Rpt(c2s(r.min), c2s(r.max));
-}
-
void
update(Rectangle *rp){if(canvas==nil)
@@ -239,57 +193,6 @@
canvas = tmp;
}
-void
-save(Rectangle r, int mark)
-{- Image *tmp;
- int x;
-
- if(mark){- x = nundo++ % nelem(undo);
- if(undo[x])
- freeimage(undo[x]);
- undo[x] = nil;
- }
- if(canvas==nil || nundo<0)
- return;
- if(!rectclip(&r, canvas->r))
- return;
- if((tmp = allocimage(display, r, canvas->chan, 0, DNofill)) == nil)
- return;
- draw(tmp, r, canvas, nil, r.min);
- x = nundo++ % nelem(undo);
- if(undo[x])
- freeimage(undo[x]);
- undo[x] = tmp;
-}
-
-void
-restore(int n)
-{- Image *tmp;
- int x;
-
- while(nundo > 0){- if(n-- == 0)
- return;
- x = --nundo % nelem(undo);
- if((tmp = undo[x]) == nil)
- return;
- undo[x] = nil;
- if(canvas == nil || canvas->chan != tmp->chan){- freeimage(canvas);
- canvas = tmp;
- update(nil);
- } else {- expand(tmp->r);
- draw(canvas, tmp->r, tmp, nil, tmp->r.min);
- update(&tmp->r);
- freeimage(tmp);
- }
- }
-}
-
typedef struct {Rectangle r;
Rectangle r0;
@@ -456,141 +359,7 @@
update(nil);
}
-void
-drawpal(void)
-{- Rectangle r, rr;
- int i;
-
- r = screen->r;
- r.min.y = r.max.y - 20;
- replclipr(screen, 0, r);
-
- penr = r;
- penr.min.x = r.max.x - NBRUSH*Dy(r);
-
- palr = r;
- palr.max.x = penr.min.x;
-
- r = penr;
- draw(screen, r, back, nil, ZP);
- for(i=0; i<NBRUSH; i++){- r.max.x = penr.min.x + (i+1)*Dx(penr) / NBRUSH;
- rr = r;
- if(i == brush)
- rr.min.y += Dy(r)/3;
- if(i == NBRUSH-1){- /* last is special brush for fill draw */
- draw(screen, rr, ink, nil, ZP);
- } else {- rr.min = addpt(rr.min, divpt(subpt(rr.max, rr.min), 2));
- rr.max = rr.min;
- strokedraw(screen, rr, ink, i);
- }
- r.min.x = r.max.x;
- }
-
- r = palr;
- for(i=1; i<=nelem(pal); i++){- r.max.x = palr.min.x + i*Dx(palr) / nelem(pal);
- rr = r;
- if(ink == pal[i-1])
- rr.min.y += Dy(r)/3;
- draw(screen, rr, pal[i-1], nil, ZP);
- gendrawdiff(screen, r, rr, back, ZP, nil, ZP, SoverD);
- r.min.x = r.max.x;
- }
-
- r = screen->r;
- r.max.y -= Dy(palr);
- replclipr(screen, 0, r);
-}
-
-int
-hitpal(Mouse m)
-{- int i;
- u32int c;
- char buf[16], *e;
-
- if(ptinrect(m.xy, penr)){- if(m.buttons & 7){- brush = ((m.xy.x - penr.min.x) * NBRUSH) / Dx(penr);
- drawpal();
- }
- return 1;
- }
- if(ptinrect(m.xy, palr)){- Image *col;
-
- i = (m.xy.x - palr.min.x) * nelem(pal) / Dx(palr);
- col = pal[i];
- switch(m.buttons & 7){- case 1:
- ink = col;
- drawpal();
- break;
- case 2:
- back = col;
- drawpal();
- update(nil);
- break;
- case 4:
- snprint(buf, sizeof(buf), "%06x", c64[i]);
- if(eenter("Hex", buf, sizeof(buf), &m) == 6){- c = strtoll(buf, &e, 16);
- if(*e == 0){- c64[i] = c;
- freeimage(pal[i]);
- pal[i] = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, c<<8|0xff);
- drawpal();
- }
- }
- break;
- }
- return 1;
- }
- return 0;
-}
-
-void
-catch(void *, char *msg)
-{- if(strstr(msg, "closed pipe"))
- noted(NCONT);
- noted(NDFLT);
-}
-
-int
-pipeline(char *fmt, ...)
-{- char buf[1024];
- va_list a;
- int p[2];
-
- va_start(a, fmt);
- vsnprint(buf, sizeof(buf), fmt, a);
- va_end(a);
- if(pipe(p) < 0)
- return -1;
- switch(rfork(RFPROC|RFMEM|RFFDG|RFNOTEG|RFREND)){- case -1:
- close(p[0]);
- close(p[1]);
- return -1;
- case 0:
- close(p[1]);
- dup(p[0], 0);
- dup(p[0], 1);
- close(p[0]);
- execl("/bin/rc", "rc", "-c", buf, nil);- exits("exec");- }
- close(p[0]);
- return p[1];
-}
-
-void
+static void
usage(void)
{fprint(2, "usage: %s [-b] [file]\n", argv0);
@@ -597,17 +366,22 @@
exits("usage");}
+/* FIXME */
+int pipeline(char*,...); // cmd.c
+int hitpal(Mouse);
+
void
main(int argc, char *argv[])
{- char *s, buf[1024];
+ char *filename, *s, buf[1024];
Rectangle r;
Image *img;
- int i, invbg, fd;
+ int invbg, fd;
Event e;
Mouse m;
Point p, d;
+ filename = nil;
invbg = 0;
ARGBEGIN {case 'b': invbg = 1; break;
@@ -614,43 +388,18 @@
default:
usage();
} ARGEND;
-
if(argc == 1)
filename = strdup(argv[0]);
else if(argc != 0)
usage();
-
if(initdraw(0, 0, "paint") < 0)
sysfatal("initdraw: %r");-
- if(filename){- if((fd = open(filename, OREAD)) < 0)
- sysfatal("open: %r");- if((canvas = readimage(display, fd, 0)) == nil)
- sysfatal("readimage: %r");- close(fd);
- }
-
- /* palette initialization */
- for(i=0; i<nelem(pal); i++){- pal[i] = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1,
- c64[i % nelem(c64)]<<8 | 0xFF);
- if(pal[i] == nil)
- sysfatal("allocimage: %r");- }
- if(invbg){- ink = pal[1];
- back = pal[0];
- }else{- ink = pal[0];
- back = pal[1];
- }
+ initcnv(filename);
+ initpal(invbg);
drawpal();
center();
-
einit(Emouse | Ekeyboard);
-
- notify(catch);
+ initcmd();
for(;;) { switch(event(&e)){case Emouse:
--
⑨