npage: zoom and enhance
This commit is contained in:
parent
97f742c860
commit
8243c0e80b
1 changed files with 143 additions and 56 deletions
|
@ -25,6 +25,7 @@ struct Page {
|
||||||
Page *tail;
|
Page *tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int zoom = 1;
|
||||||
int ppi = 100;
|
int ppi = 100;
|
||||||
int imode;
|
int imode;
|
||||||
int newwin;
|
int newwin;
|
||||||
|
@ -55,6 +56,9 @@ char *menuitems[] = {
|
||||||
"fit width",
|
"fit width",
|
||||||
"fit height",
|
"fit height",
|
||||||
"",
|
"",
|
||||||
|
"zoom in",
|
||||||
|
"zoom out",
|
||||||
|
"",
|
||||||
"next",
|
"next",
|
||||||
"prev",
|
"prev",
|
||||||
"zerox",
|
"zerox",
|
||||||
|
@ -87,8 +91,9 @@ Cursor reading = {
|
||||||
0x00, 0x00, 0x01, 0xb6, 0x01, 0xb6, 0x00, 0x00, }
|
0x00, 0x00, 0x01, 0xb6, 0x01, 0xb6, 0x00, 0x00, }
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void showpage(Page *);
|
||||||
showpage(Page *);
|
void drawpage(Page *);
|
||||||
|
Point pagesize(Page *);
|
||||||
|
|
||||||
Page*
|
Page*
|
||||||
addpage(Page *up, char *label, int (*popen)(Page *), void *pdata, int fd)
|
addpage(Page *up, char *label, int (*popen)(Page *), void *pdata, int fd)
|
||||||
|
@ -639,7 +644,6 @@ unloadpages(int age)
|
||||||
void
|
void
|
||||||
loadpages(Page *p, int ahead, int oviewgen)
|
loadpages(Page *p, int ahead, int oviewgen)
|
||||||
{
|
{
|
||||||
Point size;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ahead++; /* load at least one */
|
ahead++; /* load at least one */
|
||||||
|
@ -654,16 +658,20 @@ loadpages(Page *p, int ahead, int oviewgen)
|
||||||
qunlock(p);
|
qunlock(p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size = p->image ? subpt(p->image->r.max, p->image->r.min) : ZP;
|
|
||||||
qunlock(p);
|
|
||||||
|
|
||||||
if(p == current){
|
if(p == current){
|
||||||
|
Point size;
|
||||||
|
|
||||||
|
esetcursor(nil);
|
||||||
|
size = pagesize(p);
|
||||||
if(size.x && size.y && newwin){
|
if(size.x && size.y && newwin){
|
||||||
newwin = 0;
|
newwin = 0;
|
||||||
resizewin(size);
|
resizewin(size);
|
||||||
}
|
}
|
||||||
eresized(0);
|
lockdisplay(display);
|
||||||
|
drawpage(p);
|
||||||
|
unlockdisplay(display);
|
||||||
}
|
}
|
||||||
|
qunlock(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -731,23 +739,64 @@ gendrawdiff(Image *dst, Rectangle bot, Rectangle top,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eresized(int new)
|
zoomdraw(Image *d, Rectangle r, Rectangle top, Image *s, Point sp, int f)
|
||||||
|
{
|
||||||
|
int w, x, y;
|
||||||
|
Image *t;
|
||||||
|
Point a;
|
||||||
|
|
||||||
|
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(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;
|
Rectangle r;
|
||||||
Image *i;
|
Image *i;
|
||||||
Page *p;
|
|
||||||
|
|
||||||
if(new){
|
|
||||||
lockdisplay(display);
|
|
||||||
if(getwindow(display, Refnone) == -1)
|
|
||||||
sysfatal("getwindow: %r");
|
|
||||||
unlockdisplay(display);
|
|
||||||
}
|
|
||||||
if((p = current) == nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qlock(p);
|
|
||||||
lockdisplay(display);
|
|
||||||
if((i = p->image) == nil){
|
if((i = p->image) == nil){
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
|
@ -760,15 +809,12 @@ eresized(int new)
|
||||||
draw(screen, r, display->white, nil, ZP);
|
draw(screen, r, display->white, nil, ZP);
|
||||||
string(screen, r.min, display->black, ZP, font, s);
|
string(screen, r.min, display->black, ZP, font, s);
|
||||||
} else {
|
} else {
|
||||||
r = rectaddpt(rectaddpt(Rpt(ZP, subpt(i->r.max, i->r.min)), screen->r.min), pos);
|
r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
|
||||||
draw(screen, r, i, nil, i->r.min);
|
zoomdraw(screen, r, ZR, i, i->r.min, zoom);
|
||||||
}
|
}
|
||||||
gendrawdiff(screen, screen->r, r, display->white, ZP, nil, ZP, S);
|
gendrawdiff(screen, screen->r, r, display->white, ZP, nil, ZP, S);
|
||||||
border(screen, r, -Borderwidth, display->black, ZP);
|
border(screen, r, -Borderwidth, display->black, ZP);
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
esetcursor(nil);
|
|
||||||
unlockdisplay(display);
|
|
||||||
qunlock(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -777,35 +823,19 @@ translate(Page *p, Point d)
|
||||||
Rectangle r, or, nr;
|
Rectangle r, or, nr;
|
||||||
Image *i;
|
Image *i;
|
||||||
|
|
||||||
if(p == nil || d.x==0 && d.y==0)
|
i = p->image;
|
||||||
|
if((i==0) || (d.x==0 && d.y==0))
|
||||||
return;
|
return;
|
||||||
if(!canqlock(p))
|
r = rectaddpt(Rpt(ZP, pagesize(p)), addpt(pos, screen->r.min));
|
||||||
return;
|
pos = addpt(pos, d);
|
||||||
if(i = p->image){
|
nr = rectaddpt(r, d);
|
||||||
r = rectaddpt(rectaddpt(Rpt(ZP, subpt(i->r.max, i->r.min)), screen->r.min), pos);
|
or = r;
|
||||||
pos = addpt(pos, d);
|
rectclip(&or, screen->r);
|
||||||
nr = rectaddpt(r, d);
|
draw(screen, rectaddpt(or, d), screen, nil, or.min);
|
||||||
or = r;
|
zoomdraw(screen, nr, rectaddpt(or, d), i, i->r.min, zoom);
|
||||||
rectclip(&or, screen->r);
|
gendrawdiff(screen, screen->r, nr, display->white, ZP, nil, ZP, S);
|
||||||
draw(screen, rectaddpt(or, d), screen, nil, or.min);
|
border(screen, nr, -Borderwidth, display->black, ZP);
|
||||||
gendrawdiff(screen, nr, rectaddpt(or, d), i, i->r.min, nil, ZP, S);
|
flushimage(display, 1);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Page*
|
Page*
|
||||||
|
@ -890,6 +920,23 @@ Out:
|
||||||
esetcursor(nil);
|
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)
|
void killcohort(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -898,6 +945,7 @@ void killcohort(void)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawerr(Display *, char *msg)
|
void drawerr(Display *, char *msg)
|
||||||
{
|
{
|
||||||
sysfatal("draw: %s", msg);
|
sysfatal("draw: %s", msg);
|
||||||
|
@ -985,6 +1033,8 @@ main(int argc, char *argv[])
|
||||||
lockdisplay(display);
|
lockdisplay(display);
|
||||||
m = e.mouse;
|
m = e.mouse;
|
||||||
if(m.buttons & 1){
|
if(m.buttons & 1){
|
||||||
|
if(current == nil || !canqlock(current))
|
||||||
|
goto Unlock;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
o = m.xy;
|
o = m.xy;
|
||||||
m = emouse();
|
m = emouse();
|
||||||
|
@ -992,6 +1042,7 @@ main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
translate(current, subpt(m.xy, o));
|
translate(current, subpt(m.xy, o));
|
||||||
}
|
}
|
||||||
|
qunlock(current);
|
||||||
goto Unlock;
|
goto Unlock;
|
||||||
}
|
}
|
||||||
if(m.buttons & 2){
|
if(m.buttons & 2){
|
||||||
|
@ -1001,6 +1052,7 @@ main(int argc, char *argv[])
|
||||||
s = menuitems[i];
|
s = menuitems[i];
|
||||||
if(strcmp(s, "orig size")==0){
|
if(strcmp(s, "orig size")==0){
|
||||||
pos = ZP;
|
pos = ZP;
|
||||||
|
zoom = 1;
|
||||||
resize = ZP;
|
resize = ZP;
|
||||||
rotate = 0;
|
rotate = 0;
|
||||||
Unload:
|
Unload:
|
||||||
|
@ -1022,16 +1074,36 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if(strcmp(s, "fit width")==0){
|
if(strcmp(s, "fit width")==0){
|
||||||
pos = ZP;
|
pos = ZP;
|
||||||
|
zoom = 1;
|
||||||
resize = subpt(screen->r.max, screen->r.min);
|
resize = subpt(screen->r.max, screen->r.min);
|
||||||
resize.y = 0;
|
resize.y = 0;
|
||||||
goto Unload;
|
goto Unload;
|
||||||
}
|
}
|
||||||
if(strcmp(s, "fit height")==0){
|
if(strcmp(s, "fit height")==0){
|
||||||
pos = ZP;
|
pos = ZP;
|
||||||
|
zoom = 1;
|
||||||
resize = subpt(screen->r.max, screen->r.min);
|
resize = subpt(screen->r.max, screen->r.min);
|
||||||
resize.x = 0;
|
resize.x = 0;
|
||||||
goto Unload;
|
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);
|
unlockdisplay(display);
|
||||||
if(strcmp(s, "next")==0)
|
if(strcmp(s, "next")==0)
|
||||||
showpage(nextpage(current));
|
showpage(nextpage(current));
|
||||||
|
@ -1062,30 +1134,45 @@ main(int argc, char *argv[])
|
||||||
case Kdel:
|
case Kdel:
|
||||||
case Keof:
|
case Keof:
|
||||||
exits(0);
|
exits(0);
|
||||||
|
case 'd':
|
||||||
|
qlock(current);
|
||||||
|
lockdisplay(display);
|
||||||
|
translate(current, Pt(-1, -1));
|
||||||
|
unlockdisplay(display);
|
||||||
|
qunlock(current);
|
||||||
|
break;
|
||||||
case Kup:
|
case Kup:
|
||||||
|
if(current == nil || !canqlock(current))
|
||||||
|
break;
|
||||||
lockdisplay(display);
|
lockdisplay(display);
|
||||||
if(pos.y < 0){
|
if(pos.y < 0){
|
||||||
translate(current, Pt(0, Dy(screen->r)/2));
|
translate(current, Pt(0, Dy(screen->r)/2));
|
||||||
unlockdisplay(display);
|
unlockdisplay(display);
|
||||||
|
qunlock(current);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
unlockdisplay(display);
|
||||||
|
qunlock(current);
|
||||||
if(prevpage(current))
|
if(prevpage(current))
|
||||||
pos.y = 0;
|
pos.y = 0;
|
||||||
unlockdisplay(display);
|
|
||||||
case Kleft:
|
case Kleft:
|
||||||
showpage(prevpage(current));
|
showpage(prevpage(current));
|
||||||
break;
|
break;
|
||||||
case Kdown:
|
case Kdown:
|
||||||
lockdisplay(display);
|
if(current == nil || !canqlock(current))
|
||||||
|
break;
|
||||||
o = addpt(pos, pagesize(current));
|
o = addpt(pos, pagesize(current));
|
||||||
|
lockdisplay(display);
|
||||||
if(o.y > Dy(screen->r)){
|
if(o.y > Dy(screen->r)){
|
||||||
translate(current, Pt(0, -Dy(screen->r)/2));
|
translate(current, Pt(0, -Dy(screen->r)/2));
|
||||||
unlockdisplay(display);
|
unlockdisplay(display);
|
||||||
|
qunlock(current);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
unlockdisplay(display);
|
||||||
|
qunlock(current);
|
||||||
if(nextpage(current))
|
if(nextpage(current))
|
||||||
pos.y = 0;
|
pos.y = 0;
|
||||||
unlockdisplay(display);
|
|
||||||
case ' ':
|
case ' ':
|
||||||
case Kright:
|
case Kright:
|
||||||
showpage(nextpage(current));
|
showpage(nextpage(current));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue