summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@centraldogma>2011-09-12 01:47:32 +0200
committercinap_lenrek <cinap_lenrek@centraldogma>2011-09-12 01:47:32 +0200
commit8243c0e80bdcc6ac6afd906095e23490815af2c4 (patch)
tree76aa751ff56902b9293bdb75badce8ed881ee2aa
parent97f742c860b78599342caca96e43f608a7c34a5d (diff)
downloadplan9front-8243c0e80bdcc6ac6afd906095e23490815af2c4.tar.xz
npage: zoom and enhance
-rw-r--r--sys/src/cmd/npage.c197
1 files changed, 142 insertions, 55 deletions
diff --git a/sys/src/cmd/npage.c b/sys/src/cmd/npage.c
index 6bec8ec60..1b28d8f1f 100644
--- a/sys/src/cmd/npage.c
+++ b/sys/src/cmd/npage.c
@@ -25,6 +25,7 @@ struct Page {
Page *tail;
};
+int zoom = 1;
int ppi = 100;
int imode;
int newwin;
@@ -55,6 +56,9 @@ char *menuitems[] = {
"fit width",
"fit height",
"",
+ "zoom in",
+ "zoom out",
+ "",
"next",
"prev",
"zerox",
@@ -87,8 +91,9 @@ Cursor reading = {
0x00, 0x00, 0x01, 0xb6, 0x01, 0xb6, 0x00, 0x00, }
};
-void
-showpage(Page *);
+void showpage(Page *);
+void drawpage(Page *);
+Point pagesize(Page *);
Page*
addpage(Page *up, char *label, int (*popen)(Page *), void *pdata, int fd)
@@ -639,7 +644,6 @@ unloadpages(int age)
void
loadpages(Page *p, int ahead, int oviewgen)
{
- Point size;
int i;
ahead++; /* load at least one */
@@ -654,16 +658,20 @@ loadpages(Page *p, int ahead, int oviewgen)
qunlock(p);
break;
}
- size = p->image ? subpt(p->image->r.max, p->image->r.min) : ZP;
- qunlock(p);
-
if(p == current){
+ Point size;
+
+ esetcursor(nil);
+ size = pagesize(p);
if(size.x && size.y && newwin){
newwin = 0;
resizewin(size);
}
- eresized(0);
+ lockdisplay(display);
+ drawpage(p);
+ unlockdisplay(display);
}
+ qunlock(p);
}
}
}
@@ -731,23 +739,64 @@ gendrawdiff(Image *dst, Rectangle bot, Rectangle top,
}
void
-eresized(int new)
+zoomdraw(Image *d, Rectangle r, Rectangle top, Image *s, Point sp, int f)
{
- Rectangle r;
- Image *i;
- Page *p;
+ int w, x, y;
+ Image *t;
+ Point a;
- if(new){
- lockdisplay(display);
- if(getwindow(display, Refnone) == -1)
- sysfatal("getwindow: %r");
- unlockdisplay(display);
+ if(f <= 1){
+ gendrawdiff(d, r, top, s, sp, nil, ZP, S);
+ return;
+ }
+ a = ZP;
+ if(r.min.x < d->r.min.x){
+ sp.x += (d->r.min.x - r.min.x)/f;
+ a.x = (d->r.min.x - r.min.x)%f;
+ r.min.x = d->r.min.x;
}
- if((p = current) == nil)
+ if(r.min.y < d->r.min.y){
+ sp.y += (d->r.min.y - r.min.y)/f;
+ a.y = (d->r.min.y - r.min.y)%f;
+ r.min.y = d->r.min.y;
+ }
+ rectclip(&r, d->r);
+ w = s->r.max.x - sp.x;
+ if(w > Dx(r))
+ w = Dx(r);
+ t = allocimage(display, Rect(r.min.x, r.min.y, r.min.x+w, r.max.y), s->chan, 0, DNofill);
+ if(t == nil)
return;
+ for(y=r.min.y; y<r.max.y; y++){
+ draw(t, Rect(r.min.x, y, r.min.x+w, y+1), s, nil, sp);
+ if(++a.y == zoom){
+ a.y = 0;
+ sp.y++;
+ }
+ }
+ sp = t->r.min;
+ for(x=r.min.x; x<r.max.x; x++){
+ gendrawdiff(d, Rect(x, r.min.y, x+1, r.max.y), top, t, sp, nil, ZP, S);
+ if(++a.x == f){
+ a.x = 0;
+ sp.x++;
+ }
+ }
+ freeimage(t);
+}
+
+Point
+pagesize(Page *p)
+{
+ return p->image ? mulpt(subpt(p->image->r.max, p->image->r.min), zoom) : ZP;
+}
+
+void
+drawpage(Page *p)
+{
+ Rectangle r;
+ Image *i;
- qlock(p);
- lockdisplay(display);
if((i = p->image) == nil){
char *s;
@@ -760,15 +809,12 @@ eresized(int new)
draw(screen, r, display->white, nil, ZP);
string(screen, r.min, display->black, ZP, font, s);
} else {
- r = rectaddpt(rectaddpt(Rpt(ZP, subpt(i->r.max, i->r.min)), screen->r.min), pos);
- draw(screen, r, i, nil, i->r.min);
+ r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
+ zoomdraw(screen, r, ZR, i, i->r.min, zoom);
}
gendrawdiff(screen, screen->r, r, display->white, ZP, nil, ZP, S);
border(screen, r, -Borderwidth, display->black, ZP);
flushimage(display, 1);
- esetcursor(nil);
- unlockdisplay(display);
- qunlock(p);
}
void
@@ -777,35 +823,19 @@ translate(Page *p, Point d)
Rectangle r, or, nr;
Image *i;
- if(p == nil || d.x==0 && d.y==0)
- return;
- if(!canqlock(p))
+ i = p->image;
+ if((i==0) || (d.x==0 && d.y==0))
return;
- if(i = p->image){
- r = rectaddpt(rectaddpt(Rpt(ZP, subpt(i->r.max, i->r.min)), screen->r.min), pos);
- pos = addpt(pos, d);
- nr = rectaddpt(r, d);
- or = r;
- rectclip(&or, screen->r);
- draw(screen, rectaddpt(or, d), screen, nil, or.min);
- gendrawdiff(screen, nr, rectaddpt(or, d), i, i->r.min, nil, ZP, S);
- gendrawdiff(screen, screen->r, nr, display->white, ZP, nil, ZP, S);
- border(screen, nr, -Borderwidth, display->black, ZP);
- flushimage(display, 1);
- }
- qunlock(p);
-}
-
-Point
-pagesize(Page *p)
-{
- Point t = ZP;
- if(p && canqlock(p)){
- if(p->image)
- t = subpt(p->image->r.max, p->image->r.min);
- qunlock(p);
- }
- return t;
+ r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
+ pos = addpt(pos, d);
+ nr = rectaddpt(r, d);
+ or = r;
+ rectclip(&or, screen->r);
+ draw(screen, rectaddpt(or, d), screen, nil, or.min);
+ zoomdraw(screen, nr, rectaddpt(or, d), i, i->r.min, zoom);
+ gendrawdiff(screen, screen->r, nr, display->white, ZP, nil, ZP, S);
+ border(screen, nr, -Borderwidth, display->black, ZP);
+ flushimage(display, 1);
}
Page*
@@ -890,6 +920,23 @@ Out:
esetcursor(nil);
}
+void
+eresized(int new)
+{
+ Page *p;
+
+ lockdisplay(display);
+ if(new && getwindow(display, Refnone) == -1)
+ sysfatal("getwindow: %r");
+ if(p = current){
+ if(canqlock(p)){
+ drawpage(p);
+ qunlock(p);
+ }
+ }
+ unlockdisplay(display);
+}
+
void killcohort(void)
{
int i;
@@ -898,6 +945,7 @@ void killcohort(void)
sleep(1);
}
}
+
void drawerr(Display *, char *msg)
{
sysfatal("draw: %s", msg);
@@ -985,6 +1033,8 @@ main(int argc, char *argv[])
lockdisplay(display);
m = e.mouse;
if(m.buttons & 1){
+ if(current == nil || !canqlock(current))
+ goto Unlock;
for(;;) {
o = m.xy;
m = emouse();
@@ -992,6 +1042,7 @@ main(int argc, char *argv[])
break;
translate(current, subpt(m.xy, o));
}
+ qunlock(current);
goto Unlock;
}
if(m.buttons & 2){
@@ -1001,6 +1052,7 @@ main(int argc, char *argv[])
s = menuitems[i];
if(strcmp(s, "orig size")==0){
pos = ZP;
+ zoom = 1;
resize = ZP;
rotate = 0;
Unload:
@@ -1022,16 +1074,36 @@ main(int argc, char *argv[])
}
if(strcmp(s, "fit width")==0){
pos = ZP;
+ zoom = 1;
resize = subpt(screen->r.max, screen->r.min);
resize.y = 0;
goto Unload;
}
if(strcmp(s, "fit height")==0){
pos = ZP;
+ zoom = 1;
resize = subpt(screen->r.max, screen->r.min);
resize.x = 0;
goto Unload;
}
+ if(strncmp(s, "zoom", 4)==0){
+ if(current && canqlock(current)){
+ o = subpt(m.xy, screen->r.min);
+ if(strstr(s, "in")){
+ if(zoom < 0x40000000){
+ zoom *= 2;
+ pos = addpt(mulpt(subpt(pos, o), 2), o);
+ }
+ }else{
+ if(zoom > 1){
+ zoom /= 2;
+ pos = addpt(divpt(subpt(pos, o), 2), o);
+ }
+ }
+ drawpage(current);
+ qunlock(current);
+ }
+ }
unlockdisplay(display);
if(strcmp(s, "next")==0)
showpage(nextpage(current));
@@ -1062,30 +1134,45 @@ main(int argc, char *argv[])
case Kdel:
case Keof:
exits(0);
+ case 'd':
+ qlock(current);
+ lockdisplay(display);
+ translate(current, Pt(-1, -1));
+ unlockdisplay(display);
+ qunlock(current);
+ break;
case Kup:
+ if(current == nil || !canqlock(current))
+ break;
lockdisplay(display);
if(pos.y < 0){
translate(current, Pt(0, Dy(screen->r)/2));
unlockdisplay(display);
+ qunlock(current);
continue;
}
+ unlockdisplay(display);
+ qunlock(current);
if(prevpage(current))
pos.y = 0;
- unlockdisplay(display);
case Kleft:
showpage(prevpage(current));
break;
case Kdown:
- lockdisplay(display);
+ if(current == nil || !canqlock(current))
+ break;
o = addpt(pos, pagesize(current));
+ lockdisplay(display);
if(o.y > Dy(screen->r)){
translate(current, Pt(0, -Dy(screen->r)/2));
unlockdisplay(display);
+ qunlock(current);
continue;
}
+ unlockdisplay(display);
+ qunlock(current);
if(nextpage(current))
pos.y = 0;
- unlockdisplay(display);
case ' ':
case Kright:
showpage(nextpage(current));