Blame


1 f2887b9d 2009-08-11 rsc #include <u.h>
2 f2887b9d 2009-08-11 rsc #include <libc.h>
3 f2887b9d 2009-08-11 rsc #include <draw.h>
4 f2887b9d 2009-08-11 rsc #include <cursor.h>
5 f2887b9d 2009-08-11 rsc #include <event.h>
6 f2887b9d 2009-08-11 rsc #include <bio.h>
7 f2887b9d 2009-08-11 rsc #include <plumb.h>
8 f2887b9d 2009-08-11 rsc #include <ctype.h>
9 f2887b9d 2009-08-11 rsc #include <keyboard.h>
10 f2887b9d 2009-08-11 rsc #include <thread.h>
11 f2887b9d 2009-08-11 rsc #include "page.h"
12 f2887b9d 2009-08-11 rsc
13 f2887b9d 2009-08-11 rsc typedef struct Cached Cached;
14 f2887b9d 2009-08-11 rsc struct Cached
15 f2887b9d 2009-08-11 rsc {
16 f2887b9d 2009-08-11 rsc Document *doc;
17 f2887b9d 2009-08-11 rsc int page;
18 f2887b9d 2009-08-11 rsc int angle;
19 f2887b9d 2009-08-11 rsc Image *im;
20 d9e047e5 2010-02-04 rsc int ppi;
21 f2887b9d 2009-08-11 rsc };
22 f2887b9d 2009-08-11 rsc
23 f2887b9d 2009-08-11 rsc static Cached cache[5];
24 f2887b9d 2009-08-11 rsc static int rabusy;
25 f2887b9d 2009-08-11 rsc
26 f2887b9d 2009-08-11 rsc static Image*
27 f2887b9d 2009-08-11 rsc questionmark(void)
28 f2887b9d 2009-08-11 rsc {
29 f2887b9d 2009-08-11 rsc static Image *im;
30 f2887b9d 2009-08-11 rsc
31 f2887b9d 2009-08-11 rsc if(im)
32 fa325e9b 2020-01-10 cross return im;
33 f2887b9d 2009-08-11 rsc im = xallocimage(display, Rect(0,0,50,50), GREY1, 1, DBlack);
34 f2887b9d 2009-08-11 rsc if(im == nil)
35 f2887b9d 2009-08-11 rsc return nil;
36 f2887b9d 2009-08-11 rsc string(im, ZP, display->white, ZP, display->defaultfont, "?");
37 f2887b9d 2009-08-11 rsc return im;
38 f2887b9d 2009-08-11 rsc }
39 f2887b9d 2009-08-11 rsc
40 f2887b9d 2009-08-11 rsc void
41 f2887b9d 2009-08-11 rsc cacheflush(void)
42 f2887b9d 2009-08-11 rsc {
43 f2887b9d 2009-08-11 rsc int i;
44 f2887b9d 2009-08-11 rsc Cached *c;
45 f2887b9d 2009-08-11 rsc
46 f2887b9d 2009-08-11 rsc for(i=0; i<nelem(cache); i++){
47 f2887b9d 2009-08-11 rsc c = &cache[i];
48 f2887b9d 2009-08-11 rsc if(c->im)
49 f2887b9d 2009-08-11 rsc freeimage(c->im);
50 f2887b9d 2009-08-11 rsc c->im = nil;
51 f2887b9d 2009-08-11 rsc c->doc = nil;
52 f2887b9d 2009-08-11 rsc }
53 f2887b9d 2009-08-11 rsc }
54 f2887b9d 2009-08-11 rsc
55 f2887b9d 2009-08-11 rsc static Image*
56 f2887b9d 2009-08-11 rsc _cachedpage(Document *doc, int angle, int page, char *ra)
57 f2887b9d 2009-08-11 rsc {
58 f2887b9d 2009-08-11 rsc int i;
59 f2887b9d 2009-08-11 rsc Cached *c, old;
60 f2887b9d 2009-08-11 rsc Image *im, *tmp;
61 d9e047e5 2010-02-04 rsc int ppi = 100;
62 d9e047e5 2010-02-04 rsc PDFInfo *pdf;
63 d9e047e5 2010-02-04 rsc PSInfo *ps;
64 f2887b9d 2009-08-11 rsc
65 f2887b9d 2009-08-11 rsc if((page < 0 || page >= doc->npage) && !doc->fwdonly)
66 f2887b9d 2009-08-11 rsc return nil;
67 f2887b9d 2009-08-11 rsc
68 d9e047e5 2010-02-04 rsc if (doc->type == Tpdf){
69 d9e047e5 2010-02-04 rsc pdf = (PDFInfo *) doc->extra;
70 d9e047e5 2010-02-04 rsc ppi = pdf->gs.ppi;
71 d9e047e5 2010-02-04 rsc }
72 d9e047e5 2010-02-04 rsc else{
73 d9e047e5 2010-02-04 rsc if (doc->type == Tps){
74 d9e047e5 2010-02-04 rsc ps = (PSInfo *) doc->extra;
75 d9e047e5 2010-02-04 rsc ppi = ps->gs.ppi;
76 d9e047e5 2010-02-04 rsc }
77 d9e047e5 2010-02-04 rsc }
78 d9e047e5 2010-02-04 rsc
79 f2887b9d 2009-08-11 rsc Again:
80 f2887b9d 2009-08-11 rsc for(i=0; i<nelem(cache); i++){
81 f2887b9d 2009-08-11 rsc c = &cache[i];
82 d9e047e5 2010-02-04 rsc if(c->doc == doc && c->angle == angle && c->page == page && c->ppi == ppi){
83 f2887b9d 2009-08-11 rsc if(chatty) fprint(2, "cache%s hit %d\n", ra, page);
84 f2887b9d 2009-08-11 rsc goto Found;
85 f2887b9d 2009-08-11 rsc }
86 f2887b9d 2009-08-11 rsc if(c->doc == nil)
87 f2887b9d 2009-08-11 rsc break;
88 f2887b9d 2009-08-11 rsc }
89 f2887b9d 2009-08-11 rsc
90 f2887b9d 2009-08-11 rsc if(i >= nelem(cache))
91 f2887b9d 2009-08-11 rsc i = nelem(cache)-1;
92 f2887b9d 2009-08-11 rsc c = &cache[i];
93 f2887b9d 2009-08-11 rsc if(c->im)
94 f2887b9d 2009-08-11 rsc freeimage(c->im);
95 f2887b9d 2009-08-11 rsc c->im = nil;
96 f2887b9d 2009-08-11 rsc c->doc = nil;
97 f2887b9d 2009-08-11 rsc c->page = -1;
98 d9e047e5 2010-02-04 rsc c->ppi = -1;
99 f2887b9d 2009-08-11 rsc
100 f2887b9d 2009-08-11 rsc if(chatty) fprint(2, "cache%s load %d\n", ra, page);
101 f2887b9d 2009-08-11 rsc im = doc->drawpage(doc, page);
102 f2887b9d 2009-08-11 rsc if(im == nil){
103 f2887b9d 2009-08-11 rsc if(doc->fwdonly) /* end of file */
104 f2887b9d 2009-08-11 rsc wexits(0);
105 f2887b9d 2009-08-11 rsc im = questionmark();
106 f2887b9d 2009-08-11 rsc if(im == nil){
107 f2887b9d 2009-08-11 rsc Flush:
108 f2887b9d 2009-08-11 rsc if(i > 0){
109 f2887b9d 2009-08-11 rsc cacheflush();
110 f2887b9d 2009-08-11 rsc goto Again;
111 f2887b9d 2009-08-11 rsc }
112 f2887b9d 2009-08-11 rsc fprint(2, "out of memory: %r\n");
113 f2887b9d 2009-08-11 rsc wexits("memory");
114 f2887b9d 2009-08-11 rsc }
115 f2887b9d 2009-08-11 rsc return im;
116 f2887b9d 2009-08-11 rsc }
117 f2887b9d 2009-08-11 rsc
118 f2887b9d 2009-08-11 rsc if(im->r.min.x != 0 || im->r.min.y != 0){
119 f2887b9d 2009-08-11 rsc /* translate to 0,0 */
120 f2887b9d 2009-08-11 rsc tmp = xallocimage(display, Rect(0, 0, Dx(im->r), Dy(im->r)), im->chan, 0, DNofill);
121 f2887b9d 2009-08-11 rsc if(tmp == nil){
122 f2887b9d 2009-08-11 rsc freeimage(im);
123 f2887b9d 2009-08-11 rsc goto Flush;
124 f2887b9d 2009-08-11 rsc }
125 f2887b9d 2009-08-11 rsc drawop(tmp, tmp->r, im, nil, im->r.min, S);
126 f2887b9d 2009-08-11 rsc freeimage(im);
127 f2887b9d 2009-08-11 rsc im = tmp;
128 f2887b9d 2009-08-11 rsc }
129 f2887b9d 2009-08-11 rsc
130 f2887b9d 2009-08-11 rsc switch(angle){
131 f2887b9d 2009-08-11 rsc case 90:
132 f2887b9d 2009-08-11 rsc im = rot90(im);
133 f2887b9d 2009-08-11 rsc break;
134 f2887b9d 2009-08-11 rsc case 180:
135 f2887b9d 2009-08-11 rsc rot180(im);
136 f2887b9d 2009-08-11 rsc break;
137 f2887b9d 2009-08-11 rsc case 270:
138 f2887b9d 2009-08-11 rsc im = rot270(im);
139 f2887b9d 2009-08-11 rsc break;
140 f2887b9d 2009-08-11 rsc }
141 f2887b9d 2009-08-11 rsc if(im == nil)
142 f2887b9d 2009-08-11 rsc goto Flush;
143 f2887b9d 2009-08-11 rsc
144 f2887b9d 2009-08-11 rsc c->doc = doc;
145 f2887b9d 2009-08-11 rsc c->page = page;
146 f2887b9d 2009-08-11 rsc c->angle = angle;
147 f2887b9d 2009-08-11 rsc c->im = im;
148 d9e047e5 2010-02-04 rsc c->ppi = ppi;
149 f2887b9d 2009-08-11 rsc
150 f2887b9d 2009-08-11 rsc Found:
151 f2887b9d 2009-08-11 rsc if(chatty) fprint(2, "cache%s mtf %d @%d:", ra, c->page, i);
152 f2887b9d 2009-08-11 rsc old = *c;
153 f2887b9d 2009-08-11 rsc memmove(cache+1, cache, (c-cache)*sizeof cache[0]);
154 f2887b9d 2009-08-11 rsc cache[0] = old;
155 f2887b9d 2009-08-11 rsc if(chatty){
156 f2887b9d 2009-08-11 rsc for(i=0; i<nelem(cache); i++)
157 f2887b9d 2009-08-11 rsc fprint(2, " %d", cache[i].page);
158 f2887b9d 2009-08-11 rsc fprint(2, "\n");
159 f2887b9d 2009-08-11 rsc }
160 f2887b9d 2009-08-11 rsc if(chatty) fprint(2, "cache%s return %d %p\n", ra, old.page, old.im);
161 f2887b9d 2009-08-11 rsc return old.im;
162 f2887b9d 2009-08-11 rsc }
163 f2887b9d 2009-08-11 rsc
164 f2887b9d 2009-08-11 rsc static void
165 f2887b9d 2009-08-11 rsc raproc(void *a)
166 f2887b9d 2009-08-11 rsc {
167 f2887b9d 2009-08-11 rsc Cached *c;
168 fa325e9b 2020-01-10 cross
169 f2887b9d 2009-08-11 rsc c = a;
170 f2887b9d 2009-08-11 rsc lockdisplay(display);
171 46606276 2019-11-14 crossd /*
172 46606276 2019-11-14 crossd * If there is only one page in a fwdonly file, we may reach EOF
173 46606276 2019-11-14 crossd * while doing readahead and page will exit without showing anything.
174 46606276 2019-11-14 crossd */
175 46606276 2019-11-14 crossd if(!c->doc->fwdonly)
176 46606276 2019-11-14 crossd _cachedpage(c->doc, c->angle, c->page, "-ra");
177 f2887b9d 2009-08-11 rsc rabusy = 0;
178 f2887b9d 2009-08-11 rsc unlockdisplay(display);
179 f2887b9d 2009-08-11 rsc free(c);
180 f2887b9d 2009-08-11 rsc threadexits(0);
181 f2887b9d 2009-08-11 rsc }
182 f2887b9d 2009-08-11 rsc
183 f2887b9d 2009-08-11 rsc Image*
184 f2887b9d 2009-08-11 rsc cachedpage(Document *doc, int angle, int page)
185 f2887b9d 2009-08-11 rsc {
186 f2887b9d 2009-08-11 rsc static int lastpage = -1;
187 f2887b9d 2009-08-11 rsc Cached *c;
188 f2887b9d 2009-08-11 rsc Image *im;
189 f2887b9d 2009-08-11 rsc int ra;
190 fa325e9b 2020-01-10 cross
191 f2887b9d 2009-08-11 rsc if(doc->npage < 1)
192 f2887b9d 2009-08-11 rsc return display->white;
193 f2887b9d 2009-08-11 rsc
194 f2887b9d 2009-08-11 rsc im = _cachedpage(doc, angle, page, "");
195 f2887b9d 2009-08-11 rsc if(im == nil)
196 f2887b9d 2009-08-11 rsc return nil;
197 f2887b9d 2009-08-11 rsc
198 f2887b9d 2009-08-11 rsc /* readahead */
199 f2887b9d 2009-08-11 rsc ra = -1;
200 f2887b9d 2009-08-11 rsc if(!rabusy){
201 f2887b9d 2009-08-11 rsc if(page == lastpage+1)
202 f2887b9d 2009-08-11 rsc ra = page+1;
203 f2887b9d 2009-08-11 rsc else if(page == lastpage-1)
204 f2887b9d 2009-08-11 rsc ra = page-1;
205 f2887b9d 2009-08-11 rsc }
206 f2887b9d 2009-08-11 rsc lastpage = page;
207 f2887b9d 2009-08-11 rsc if(ra >= 0){
208 f2887b9d 2009-08-11 rsc c = emalloc(sizeof(*c));
209 f2887b9d 2009-08-11 rsc c->doc = doc;
210 f2887b9d 2009-08-11 rsc c->angle = angle;
211 f2887b9d 2009-08-11 rsc c->page = ra;
212 f2887b9d 2009-08-11 rsc c->im = nil;
213 f2887b9d 2009-08-11 rsc rabusy = 1;
214 f2887b9d 2009-08-11 rsc if(proccreate(raproc, c, mainstacksize) == -1)
215 f2887b9d 2009-08-11 rsc rabusy = 0;
216 f2887b9d 2009-08-11 rsc }
217 f2887b9d 2009-08-11 rsc return im;
218 f2887b9d 2009-08-11 rsc }