page: move cmd/page/cache.c to src/cmd/page/cache.c
not sure how the codebot screwed that up.
This commit is contained in:
parent
b3453e08b8
commit
f2887b9de8
1 changed files with 0 additions and 0 deletions
196
src/cmd/page/cache.c
Normal file
196
src/cmd/page/cache.c
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <cursor.h>
|
||||
#include <event.h>
|
||||
#include <bio.h>
|
||||
#include <plumb.h>
|
||||
#include <ctype.h>
|
||||
#include <keyboard.h>
|
||||
#include <thread.h>
|
||||
#include "page.h"
|
||||
|
||||
typedef struct Cached Cached;
|
||||
struct Cached
|
||||
{
|
||||
Document *doc;
|
||||
int page;
|
||||
int angle;
|
||||
Image *im;
|
||||
};
|
||||
|
||||
static Cached cache[5];
|
||||
static int rabusy;
|
||||
|
||||
static Image*
|
||||
questionmark(void)
|
||||
{
|
||||
static Image *im;
|
||||
|
||||
if(im)
|
||||
return im;
|
||||
im = xallocimage(display, Rect(0,0,50,50), GREY1, 1, DBlack);
|
||||
if(im == nil)
|
||||
return nil;
|
||||
string(im, ZP, display->white, ZP, display->defaultfont, "?");
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
cacheflush(void)
|
||||
{
|
||||
int i;
|
||||
Cached *c;
|
||||
|
||||
for(i=0; i<nelem(cache); i++){
|
||||
c = &cache[i];
|
||||
if(c->im)
|
||||
freeimage(c->im);
|
||||
c->im = nil;
|
||||
c->doc = nil;
|
||||
}
|
||||
}
|
||||
|
||||
static Image*
|
||||
_cachedpage(Document *doc, int angle, int page, char *ra)
|
||||
{
|
||||
int i;
|
||||
Cached *c, old;
|
||||
Image *im, *tmp;
|
||||
|
||||
if((page < 0 || page >= doc->npage) && !doc->fwdonly)
|
||||
return nil;
|
||||
|
||||
Again:
|
||||
for(i=0; i<nelem(cache); i++){
|
||||
c = &cache[i];
|
||||
if(c->doc == doc && c->angle == angle && c->page == page){
|
||||
if(chatty) fprint(2, "cache%s hit %d\n", ra, page);
|
||||
goto Found;
|
||||
}
|
||||
if(c->doc == nil)
|
||||
break;
|
||||
}
|
||||
|
||||
if(i >= nelem(cache))
|
||||
i = nelem(cache)-1;
|
||||
c = &cache[i];
|
||||
if(c->im)
|
||||
freeimage(c->im);
|
||||
c->im = nil;
|
||||
c->doc = nil;
|
||||
c->page = -1;
|
||||
|
||||
if(chatty) fprint(2, "cache%s load %d\n", ra, page);
|
||||
im = doc->drawpage(doc, page);
|
||||
if(im == nil){
|
||||
if(doc->fwdonly) /* end of file */
|
||||
wexits(0);
|
||||
im = questionmark();
|
||||
if(im == nil){
|
||||
Flush:
|
||||
if(i > 0){
|
||||
cacheflush();
|
||||
goto Again;
|
||||
}
|
||||
fprint(2, "out of memory: %r\n");
|
||||
wexits("memory");
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
if(im->r.min.x != 0 || im->r.min.y != 0){
|
||||
/* translate to 0,0 */
|
||||
tmp = xallocimage(display, Rect(0, 0, Dx(im->r), Dy(im->r)), im->chan, 0, DNofill);
|
||||
if(tmp == nil){
|
||||
freeimage(im);
|
||||
goto Flush;
|
||||
}
|
||||
drawop(tmp, tmp->r, im, nil, im->r.min, S);
|
||||
freeimage(im);
|
||||
im = tmp;
|
||||
}
|
||||
|
||||
switch(angle){
|
||||
case 90:
|
||||
im = rot90(im);
|
||||
break;
|
||||
case 180:
|
||||
rot180(im);
|
||||
break;
|
||||
case 270:
|
||||
im = rot270(im);
|
||||
break;
|
||||
}
|
||||
if(im == nil)
|
||||
goto Flush;
|
||||
|
||||
c->doc = doc;
|
||||
c->page = page;
|
||||
c->angle = angle;
|
||||
c->im = im;
|
||||
|
||||
Found:
|
||||
if(chatty) fprint(2, "cache%s mtf %d @%d:", ra, c->page, i);
|
||||
old = *c;
|
||||
memmove(cache+1, cache, (c-cache)*sizeof cache[0]);
|
||||
cache[0] = old;
|
||||
if(chatty){
|
||||
for(i=0; i<nelem(cache); i++)
|
||||
fprint(2, " %d", cache[i].page);
|
||||
fprint(2, "\n");
|
||||
}
|
||||
if(chatty) fprint(2, "cache%s return %d %p\n", ra, old.page, old.im);
|
||||
return old.im;
|
||||
}
|
||||
|
||||
static void
|
||||
raproc(void *a)
|
||||
{
|
||||
Cached *c;
|
||||
|
||||
c = a;
|
||||
lockdisplay(display);
|
||||
_cachedpage(c->doc, c->angle, c->page, "-ra");
|
||||
rabusy = 0;
|
||||
unlockdisplay(display);
|
||||
free(c);
|
||||
threadexits(0);
|
||||
}
|
||||
|
||||
Image*
|
||||
cachedpage(Document *doc, int angle, int page)
|
||||
{
|
||||
static int lastpage = -1;
|
||||
Cached *c;
|
||||
Image *im;
|
||||
int ra;
|
||||
|
||||
if(doc->npage < 1)
|
||||
return display->white;
|
||||
|
||||
im = _cachedpage(doc, angle, page, "");
|
||||
if(im == nil)
|
||||
return nil;
|
||||
|
||||
/* readahead */
|
||||
ra = -1;
|
||||
if(!rabusy){
|
||||
if(page == lastpage+1)
|
||||
ra = page+1;
|
||||
else if(page == lastpage-1)
|
||||
ra = page-1;
|
||||
}
|
||||
lastpage = page;
|
||||
if(ra >= 0){
|
||||
c = emalloc(sizeof(*c));
|
||||
c->doc = doc;
|
||||
c->angle = angle;
|
||||
c->page = ra;
|
||||
c->im = nil;
|
||||
rabusy = 1;
|
||||
if(proccreate(raproc, c, mainstacksize) == -1)
|
||||
rabusy = 0;
|
||||
}
|
||||
return im;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue