-rw-r--r-- | noncore/apps/opie-reader/CDrawBuffer.cpp | 211 | ||||
-rw-r--r-- | noncore/apps/opie-reader/plucker.cpp | 579 |
2 files changed, 790 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/CDrawBuffer.cpp b/noncore/apps/opie-reader/CDrawBuffer.cpp new file mode 100644 index 0000000..2ceb2d5 --- a/dev/null +++ b/noncore/apps/opie-reader/CDrawBuffer.cpp | |||
@@ -0,0 +1,211 @@ | |||
1 | |||
2 | #include "CDrawBuffer.h" | ||
3 | #include "FontControl.h" | ||
4 | #include <qfontmetrics.h> | ||
5 | #include <qpainter.h> | ||
6 | |||
7 | void CDrawBuffer::setright(CDrawBuffer& rhs, int f) | ||
8 | { | ||
9 | int i; | ||
10 | // qDebug("Trying 1:%d:%s", f, (const char*)toQString(rhs.data())); | ||
11 | len = rhs.len; | ||
12 | m_maxstyle = rhs.m_maxstyle; | ||
13 | m_ascent = rhs.m_ascent; | ||
14 | m_descent = rhs.m_descent; | ||
15 | m_lineSpacing = rhs.m_lineSpacing; | ||
16 | while (!segs.isEmpty()) segs.erase(0); | ||
17 | for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); ) | ||
18 | { | ||
19 | CList<textsegment>::iterator next = iter; | ||
20 | iter++; | ||
21 | if (iter == rhs.segs.end() || iter->start > f) | ||
22 | { | ||
23 | int st = next->start-f; | ||
24 | if (st < 0) st = 0; | ||
25 | segs.push_back(textsegment(st,next->style)); | ||
26 | } | ||
27 | } | ||
28 | for (i = f; rhs[i] != '\0'; i++) (*this)[i-f] = rhs[i]; | ||
29 | (*this)[i-f] = '\0'; | ||
30 | len = i; | ||
31 | // qDebug("Tried 1"); | ||
32 | } | ||
33 | |||
34 | CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs) | ||
35 | { | ||
36 | int i; | ||
37 | // qDebug("Trying 2"); | ||
38 | len = rhs.len; | ||
39 | m_maxstyle = rhs.m_maxstyle; | ||
40 | m_ascent = rhs.m_ascent; | ||
41 | m_descent = rhs.m_descent; | ||
42 | m_lineSpacing = rhs.m_lineSpacing; | ||
43 | while (!segs.isEmpty()) segs.erase(0); | ||
44 | for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); iter++) | ||
45 | { | ||
46 | segs.push_back(*iter); | ||
47 | } | ||
48 | for (i = 0; rhs[i] != '\0'; i++) (*this)[i] = rhs[i]; | ||
49 | (*this)[i] = '\0'; | ||
50 | len = i; | ||
51 | // qDebug("Tried 2"); | ||
52 | return *this; | ||
53 | } | ||
54 | |||
55 | CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp) | ||
56 | { | ||
57 | int i; | ||
58 | while (!segs.isEmpty()) segs.erase(0); | ||
59 | segs.push_back(textsegment(0, CStyle())); | ||
60 | for (i = 0; sztmp[i] != '\0'; i++) (*this)[i] = sztmp[i]; | ||
61 | (*this)[i] = '\0'; | ||
62 | len = i; | ||
63 | return *this; | ||
64 | } | ||
65 | |||
66 | void CDrawBuffer::empty() | ||
67 | { | ||
68 | len = 0; | ||
69 | (*this)[0] = 0; | ||
70 | while (!segs.isEmpty()) segs.erase(0); | ||
71 | segs.push_back(textsegment(0,CStyle())); | ||
72 | m_maxstyle = m_ascent = m_descent = m_lineSpacing = 0; | ||
73 | } | ||
74 | |||
75 | void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/) | ||
76 | { | ||
77 | if (len == 0) | ||
78 | { | ||
79 | int thissize = fc->getsize(_style); | ||
80 | m_maxstyle = thissize; | ||
81 | m_ascent = fc->ascent(_style); | ||
82 | m_descent = fc->descent(_style); | ||
83 | m_lineSpacing = fc->lineSpacing(_style); | ||
84 | segs.first().start = 0; | ||
85 | segs.first().style = _style; | ||
86 | } | ||
87 | else if (_style != segs.last().style) | ||
88 | { | ||
89 | int thissize = fc->getsize(_style); | ||
90 | if (thissize > m_maxstyle) | ||
91 | { | ||
92 | m_maxstyle = thissize; | ||
93 | m_ascent = fc->ascent(_style); | ||
94 | m_descent = fc->descent(_style); | ||
95 | m_lineSpacing = fc->lineSpacing(_style); | ||
96 | } | ||
97 | segs.push_back(textsegment(len, _style)); | ||
98 | } | ||
99 | (*this)[len++] = ch; | ||
100 | } | ||
101 | |||
102 | void CDrawBuffer::truncate(int n) | ||
103 | { | ||
104 | len = n; | ||
105 | (*this)[n] = 0; | ||
106 | } | ||
107 | |||
108 | int CDrawBuffer::width(int numchars = -1) | ||
109 | { | ||
110 | int currentx = 0, end = 0; | ||
111 | QString text = toQString(data()); | ||
112 | CList<textsegment>::iterator textstart = segs.begin(); | ||
113 | CList<textsegment>::iterator textend = textstart; | ||
114 | do | ||
115 | { | ||
116 | textend++; | ||
117 | end = (textend != segs.end()) ? textend->start : length(); | ||
118 | if (numchars >= 0 && end > numchars) | ||
119 | { | ||
120 | end = numchars; | ||
121 | } | ||
122 | CStyle currentstyle = textstart->style; | ||
123 | QFont f(fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) ); | ||
124 | QString str = text.mid(textstart->start, end-textstart->start); | ||
125 | QFontMetrics fm(f); | ||
126 | currentx += fm.width(str); | ||
127 | textstart = textend; | ||
128 | } | ||
129 | while (textend != segs.end() && end != numchars); | ||
130 | return currentx; | ||
131 | } | ||
132 | |||
133 | void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth) | ||
134 | { | ||
135 | int currentx = 0; | ||
136 | QString text = toQString(data()); | ||
137 | CList<textsegment>::iterator textstart = segs.begin(); | ||
138 | StyleType align = textstart->style.getJustify(); | ||
139 | switch (align) | ||
140 | { | ||
141 | case CStyle::m_AlignRight: | ||
142 | { | ||
143 | // int linelength = width(); | ||
144 | currentx = scwidth - width(); | ||
145 | } | ||
146 | break; | ||
147 | case CStyle::m_AlignCentre: | ||
148 | { | ||
149 | // int linelength = width(); | ||
150 | currentx = (scwidth - width())/2; | ||
151 | } | ||
152 | break; | ||
153 | case CStyle::m_AlignJustify: | ||
154 | case CStyle::m_AlignLeft: | ||
155 | break; | ||
156 | } | ||
157 | CList<textsegment>::iterator textend = textstart; | ||
158 | do | ||
159 | { | ||
160 | textend++; | ||
161 | int end = (textend != segs.end()) ? textend->start : length(); | ||
162 | CStyle currentstyle = textstart->style; | ||
163 | QFont f(fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) ); | ||
164 | _p->setFont(f); | ||
165 | QString str = text.mid(textstart->start, end-textstart->start); | ||
166 | _p->setPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue())); | ||
167 | if (_bMono) | ||
168 | { | ||
169 | for (int i = 0; i < str.length(); i++) | ||
170 | { | ||
171 | _p->drawText( currentx + i*_charWidth, _y, QString(str[i])); | ||
172 | } | ||
173 | currentx += str.length()*_charWidth; | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | _p->drawText( currentx, _y, str); | ||
178 | QFontMetrics fm(f); | ||
179 | currentx += fm.width(str); | ||
180 | } | ||
181 | textstart = textend; | ||
182 | } | ||
183 | while (textend != segs.end()); | ||
184 | } | ||
185 | |||
186 | CStyle CDrawBuffer::laststyle() | ||
187 | { | ||
188 | return segs.last().style; | ||
189 | } | ||
190 | |||
191 | bool CDrawBuffer::isLink(int numchars, size_t& tgt) | ||
192 | { | ||
193 | int end = 0; | ||
194 | CStyle currentstyle; | ||
195 | CList<textsegment>::iterator textstart = segs.begin(); | ||
196 | CList<textsegment>::iterator textend = textstart; | ||
197 | do | ||
198 | { | ||
199 | textend++; | ||
200 | end = (textend != segs.end()) ? textend->start : length(); | ||
201 | if (numchars >= 0 && end > numchars) | ||
202 | { | ||
203 | end = numchars; | ||
204 | } | ||
205 | currentstyle = textstart->style; | ||
206 | textstart = textend; | ||
207 | } | ||
208 | while (textend != segs.end() && end != numchars); | ||
209 | tgt = currentstyle.getData(); | ||
210 | return currentstyle.getLink(); | ||
211 | } | ||
diff --git a/noncore/apps/opie-reader/plucker.cpp b/noncore/apps/opie-reader/plucker.cpp new file mode 100644 index 0000000..ddda4bc --- a/dev/null +++ b/noncore/apps/opie-reader/plucker.cpp | |||
@@ -0,0 +1,579 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | #include <qmessagebox.h> | ||
4 | #include "plucker.h" | ||
5 | |||
6 | #include "Aportis.h" | ||
7 | |||
8 | CPlucker::CPlucker() : expandedtextbuffer(NULL), compressedtextbuffer(NULL) { /*printf("constructing:%x\n",fin);*/ } | ||
9 | |||
10 | |||
11 | int CPlucker::openfile(const char *src) | ||
12 | { | ||
13 | if (!Cpdb::openfile(src)) | ||
14 | { | ||
15 | return -1; | ||
16 | } | ||
17 | |||
18 | //printf("Okay %u\n", 4); | ||
19 | |||
20 | if (memcmp(&head.type, "DataPlkr", 8) != 0) return -1; | ||
21 | |||
22 | // qDebug("Cool - this IS plucker"); | ||
23 | |||
24 | textlength = 0; | ||
25 | for (int recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++) | ||
26 | { | ||
27 | CPlucker_dataRecord thisHdr; | ||
28 | gotorecordnumber(recptr); | ||
29 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
30 | if (thisHdr.type < 2) textlength += htons(thisHdr.size); | ||
31 | } | ||
32 | |||
33 | gotorecordnumber(0); | ||
34 | fread(&hdr0, 1, sizeof(hdr0), fin); | ||
35 | //printf("Okay %u\n", 5); | ||
36 | buffersize = 32*1024; | ||
37 | compressedtextbuffer = new UInt8[buffersize]; | ||
38 | expandedtextbuffer = new UInt8[buffersize]; | ||
39 | |||
40 | // qDebug("Total number of records:%u", ntohs(head.recordList.numRecords)); | ||
41 | |||
42 | unsigned int nrecs = ntohs(hdr0.nRecords); | ||
43 | // qDebug("Version %u, no. res %u", ntohs(hdr0.version), nrecs); | ||
44 | for (unsigned int i = 0; i < 4*nrecs; i++) | ||
45 | { | ||
46 | UInt8 id; | ||
47 | fread(&id, 1, sizeof(id), fin); | ||
48 | // qDebug("%x", id); | ||
49 | } | ||
50 | home(); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | int CPlucker::bgetch() | ||
55 | { | ||
56 | int ch = EOF; | ||
57 | if (bufferpos >= buffercontent) | ||
58 | { | ||
59 | if (bufferrec >= ntohs(head.recordList.numRecords) - 1) return EOF; | ||
60 | // qDebug("Passing through %u", currentpos); | ||
61 | if (!expand(bufferrec+1)) return EOF; | ||
62 | mystyle.unset(); | ||
63 | } | ||
64 | |||
65 | if (bufferpos == m_nextPara) | ||
66 | { | ||
67 | UInt16 attr = m_ParaAttrs[m_nextParaIndex]; | ||
68 | m_nextParaIndex++; | ||
69 | if (m_nextParaIndex == m_nParas) | ||
70 | { | ||
71 | m_nextPara = -1; | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | m_nextPara += m_ParaOffsets[m_nextParaIndex]; | ||
76 | } | ||
77 | // qDebug("New paragraph"); | ||
78 | ch = 10; | ||
79 | } | ||
80 | else | ||
81 | { | ||
82 | currentpos++; | ||
83 | ch = expandedtextbuffer[bufferpos++]; | ||
84 | } | ||
85 | return ch; | ||
86 | } | ||
87 | |||
88 | int CPlucker::getch() | ||
89 | { | ||
90 | int ch = bgetch(); | ||
91 | while (ch == 0) | ||
92 | { | ||
93 | ch = bgetch(); | ||
94 | // qDebug("Function:%x", ch); | ||
95 | switch (ch) | ||
96 | { | ||
97 | case 0x38: | ||
98 | ch = 10; | ||
99 | break; | ||
100 | case 0x0a: | ||
101 | case 0x0c: | ||
102 | { | ||
103 | unsigned long ln = 0; | ||
104 | int skip = ch & 7; | ||
105 | for (int i = 0; i < 2; i++) | ||
106 | { | ||
107 | int ch = bgetch(); | ||
108 | ln = (ln << 8) + ch; | ||
109 | // qDebug("ch:%d, ln:%u", ch, ln); | ||
110 | } | ||
111 | if (skip == 2) | ||
112 | { | ||
113 | ln <<= 16; | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | for (int i = 0; i < 2; i++) | ||
118 | { | ||
119 | int ch = bgetch(); | ||
120 | ln = (ln << 8) + ch; | ||
121 | // qDebug("ch:%d, ln:%u", ch, ln); | ||
122 | } | ||
123 | } | ||
124 | // qDebug("ln:%u", ln); | ||
125 | mystyle.setLink(true); | ||
126 | mystyle.setData(ln); | ||
127 | mystyle.setColour(255, 0, 0); | ||
128 | ch = bgetch(); | ||
129 | } | ||
130 | break; | ||
131 | case 0x08: | ||
132 | ch = bgetch(); | ||
133 | mystyle.setColour(0, 0, 0); | ||
134 | mystyle.setLink(false); | ||
135 | mystyle.setData(0); | ||
136 | break; | ||
137 | case 0x40: | ||
138 | mystyle.setItalic(); | ||
139 | ch = bgetch(); | ||
140 | break; | ||
141 | case 0x48: | ||
142 | mystyle.unsetItalic(); | ||
143 | ch = bgetch(); | ||
144 | break; | ||
145 | case 0x11: | ||
146 | { | ||
147 | ch = bgetch(); | ||
148 | qDebug("Font:%d",ch); | ||
149 | switch (ch) | ||
150 | { | ||
151 | case 0: | ||
152 | mystyle.unsetBold(); | ||
153 | mystyle.setFontSize(0); | ||
154 | break; | ||
155 | case 1: | ||
156 | mystyle.setBold(); | ||
157 | mystyle.setFontSize(1); | ||
158 | break; | ||
159 | case 2: | ||
160 | mystyle.setBold(); | ||
161 | mystyle.setFontSize(1); | ||
162 | break; | ||
163 | case 3: | ||
164 | // mystyle.setBold(); | ||
165 | mystyle.setFontSize(1); | ||
166 | break; | ||
167 | case 4: | ||
168 | // mystyle.setBold(); | ||
169 | mystyle.setFontSize(1); | ||
170 | break; | ||
171 | case 5: | ||
172 | mystyle.setBold(); | ||
173 | mystyle.setFontSize(0); | ||
174 | break; | ||
175 | case 6: | ||
176 | mystyle.setBold(); | ||
177 | mystyle.setFontSize(0); | ||
178 | break; | ||
179 | case 7: | ||
180 | mystyle.setBold(); | ||
181 | mystyle.setFontSize(0); | ||
182 | break; | ||
183 | case 8: // should be fixed width | ||
184 | mystyle.unsetBold(); | ||
185 | mystyle.setFontSize(0); | ||
186 | break; | ||
187 | default: | ||
188 | mystyle.unsetBold(); | ||
189 | mystyle.setFontSize(0); | ||
190 | break; | ||
191 | } | ||
192 | ch = bgetch(); | ||
193 | } | ||
194 | break; | ||
195 | case 0x29: | ||
196 | ch = bgetch(); | ||
197 | switch (ch) | ||
198 | { | ||
199 | case 0: | ||
200 | mystyle.setLeftJustify(); | ||
201 | // qDebug("left"); | ||
202 | break; | ||
203 | case 1: | ||
204 | mystyle.setRightJustify(); | ||
205 | // qDebug("right"); | ||
206 | break; | ||
207 | case 2: | ||
208 | mystyle.setCentreJustify(); | ||
209 | // qDebug("centre"); | ||
210 | break; | ||
211 | case 3: | ||
212 | mystyle.setFullJustify(); | ||
213 | // qDebug("full"); | ||
214 | break; | ||
215 | |||
216 | } | ||
217 | ch = bgetch(); | ||
218 | break; | ||
219 | case 0x53: | ||
220 | { | ||
221 | int r = bgetch(); | ||
222 | int g = bgetch(); | ||
223 | int b = bgetch(); | ||
224 | mystyle.setColour(r,g,b); | ||
225 | ch = bgetch(); | ||
226 | } | ||
227 | break; | ||
228 | case 0x1a: | ||
229 | /* | ||
230 | { | ||
231 | UInt16 ir = bgetch(); | ||
232 | ir = (ir << 8) + bgetch(); | ||
233 | expandimg(ir); | ||
234 | } | ||
235 | ch = bgetch(); | ||
236 | break; | ||
237 | */ | ||
238 | case 0x33: | ||
239 | case 0x22: | ||
240 | case 0x5c: | ||
241 | case 0x60: | ||
242 | case 0x68: | ||
243 | case 0x70: | ||
244 | case 0x78: | ||
245 | case 0x83: | ||
246 | case 0x85: | ||
247 | default: | ||
248 | qDebug("Function:%x NOT IMPLEMENTED", ch); | ||
249 | { | ||
250 | int skip = ch & 7; | ||
251 | for (int i = 0; i < skip; i++) | ||
252 | { | ||
253 | ch = bgetch(); | ||
254 | qDebug("Arg %d, %d", i, ch); | ||
255 | } | ||
256 | ch = bgetch(); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | return ch; | ||
261 | } | ||
262 | |||
263 | void CPlucker::getch(int& ch, CStyle& sty) | ||
264 | { | ||
265 | ch = getch(); | ||
266 | sty = mystyle; | ||
267 | } | ||
268 | |||
269 | unsigned int CPlucker::locate() | ||
270 | { | ||
271 | return currentpos; | ||
272 | /* | ||
273 | UInt16 thisrec = 1; | ||
274 | unsigned long locpos = 0; | ||
275 | gotorecordnumber(thisrec); | ||
276 | CPlucker_dataRecord thisHdr; | ||
277 | while (thisrec < bufferrec) | ||
278 | { | ||
279 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
280 | if (thisHdr.type < 2) locpos += htons(thisHdr.size); | ||
281 | thisrec++; | ||
282 | gotorecordnumber(thisrec); | ||
283 | } | ||
284 | return locpos+bufferpos; | ||
285 | */ | ||
286 | } | ||
287 | |||
288 | void CPlucker::locate(unsigned int n) | ||
289 | { | ||
290 | UInt16 thisrec = 0; | ||
291 | unsigned long locpos = 0; | ||
292 | unsigned long bs = 0; | ||
293 | CPlucker_dataRecord thisHdr; | ||
294 | do | ||
295 | { | ||
296 | thisrec++; | ||
297 | locpos += bs; | ||
298 | gotorecordnumber(thisrec); | ||
299 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
300 | if (thisHdr.type < 2) | ||
301 | { | ||
302 | bs = htons(thisHdr.size); | ||
303 | } | ||
304 | else | ||
305 | { | ||
306 | bs = 0; | ||
307 | } | ||
308 | } while (locpos + bs < n); | ||
309 | currentpos = locpos; | ||
310 | expand(thisrec); | ||
311 | while (currentpos < n && bufferpos < buffercontent) bgetch(); | ||
312 | } | ||
313 | |||
314 | bool CPlucker::hyperlink(unsigned int n) | ||
315 | { | ||
316 | UInt16 tuid = (n >> 16); | ||
317 | n &= 0xffff; | ||
318 | UInt16 thisrec = 1; | ||
319 | currentpos = 0; | ||
320 | gotorecordnumber(thisrec); | ||
321 | CPlucker_dataRecord thisHdr; | ||
322 | while (1) | ||
323 | { | ||
324 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
325 | if (tuid <= htons(thisHdr.uid)) break; | ||
326 | if (thisHdr.type < 2) currentpos += htons(thisHdr.size); | ||
327 | // qDebug("hyper-cp:%u", currentpos); | ||
328 | thisrec++; | ||
329 | gotorecordnumber(thisrec); | ||
330 | } | ||
331 | if (thisHdr.type > 1) | ||
332 | { | ||
333 | QMessageBox::information(NULL, | ||
334 | QString("OpieReader"), | ||
335 | QString("External links\nnot yet supported") | ||
336 | ); | ||
337 | return false; | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | expand(thisrec); | ||
342 | while (bufferpos < n && bufferpos < buffercontent) getch(); | ||
343 | } | ||
344 | return true; | ||
345 | } | ||
346 | |||
347 | bool CPlucker::expand(int thisrec) | ||
348 | { | ||
349 | mystyle.unset(); | ||
350 | size_t reclen = recordlength(thisrec); | ||
351 | gotorecordnumber(thisrec); | ||
352 | CPlucker_dataRecord thisHdr; | ||
353 | while (1) | ||
354 | { | ||
355 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
356 | // qDebug("This (%d) type is %d, uid is %u", thisrec, thisHdr.type, ntohs(thisHdr.uid)); | ||
357 | if (thisHdr.type < 2) break; | ||
358 | qDebug("Skipping paragraph of type %d", thisHdr.type); | ||
359 | if (++thisrec >= ntohs(head.recordList.numRecords) - 1) return false; | ||
360 | reclen = recordlength(thisrec); | ||
361 | gotorecordnumber(thisrec); | ||
362 | } | ||
363 | m_nParas = ntohs(thisHdr.nParagraphs); | ||
364 | // qDebug("It has %u paragraphs and is %u bytes", htons(thisHdr.nParagraphs), htons(thisHdr.size)); | ||
365 | uid = ntohs(thisHdr.uid); | ||
366 | for (int i = 0; i < m_nParas; i++) | ||
367 | { | ||
368 | UInt16 ubytes, attrs; | ||
369 | fread(&ubytes, 1, sizeof(ubytes), fin); | ||
370 | fread(&attrs, 1, sizeof(attrs), fin); | ||
371 | m_ParaOffsets[i] = ntohs(ubytes); | ||
372 | m_ParaAttrs[i] = ntohs(attrs); | ||
373 | // qDebug("Bytes %u, Attr %x", ntohs(ubytes), attrs); | ||
374 | } | ||
375 | if (m_nParas > 0) | ||
376 | { | ||
377 | m_nextPara = m_ParaOffsets[0]; | ||
378 | // qDebug("First offset = %u", m_nextPara); | ||
379 | m_nextParaIndex = 0; | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | m_nextPara = -1; | ||
384 | } | ||
385 | |||
386 | reclen -= sizeof(thisHdr)+4*m_nParas; | ||
387 | |||
388 | buffercontent = htons(thisHdr.size); | ||
389 | |||
390 | if (thisHdr.type == 0) | ||
391 | { | ||
392 | fread(expandedtextbuffer, reclen, sizeof(char), fin); | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | fread(compressedtextbuffer, reclen, sizeof(char), fin); | ||
397 | switch (ntohs(hdr0.version)) | ||
398 | { | ||
399 | case 2: | ||
400 | UnZip(reclen, expandedtextbuffer, buffercontent); | ||
401 | break; | ||
402 | case 1: | ||
403 | UnDoc(reclen, expandedtextbuffer, buffercontent); | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | bufferpos = 0; | ||
408 | bufferrec = thisrec; | ||
409 | // qDebug("BC:%u, HS:%u", buffercontent, ntohs(thisHdr.size)); | ||
410 | return true; | ||
411 | } | ||
412 | |||
413 | void CPlucker::UnZip(size_t reclen, UInt8* tgtbuffer, UInt16 bsize) | ||
414 | { | ||
415 | z_stream zstream; | ||
416 | memset(&zstream,sizeof(zstream),0); | ||
417 | zstream.next_in = compressedtextbuffer; | ||
418 | zstream.next_out = tgtbuffer; | ||
419 | zstream.avail_out = bsize; | ||
420 | zstream.avail_in = reclen; | ||
421 | |||
422 | int keylen = 0; | ||
423 | |||
424 | zstream.zalloc = Z_NULL; | ||
425 | zstream.zfree = Z_NULL; | ||
426 | zstream.opaque = Z_NULL; | ||
427 | |||
428 | // printf("Initialising\n"); | ||
429 | |||
430 | inflateInit(&zstream); | ||
431 | int err = 0; | ||
432 | do { | ||
433 | if ( zstream.avail_in == 0 && 0 < keylen ) { | ||
434 | zstream.next_in = compressedtextbuffer + keylen; | ||
435 | zstream.avail_in = reclen - keylen; | ||
436 | keylen = 0; | ||
437 | } | ||
438 | zstream.next_out = tgtbuffer; | ||
439 | zstream.avail_out = bsize; | ||
440 | |||
441 | err = inflate( &zstream, Z_SYNC_FLUSH ); | ||
442 | |||
443 | } while ( err == Z_OK ); | ||
444 | |||
445 | inflateEnd(&zstream); | ||
446 | } | ||
447 | |||
448 | void CPlucker::UnDoc(size_t reclen, UInt8* tgtbuffer, UInt16 bsize) | ||
449 | { | ||
450 | // UInt16 headerSize; | ||
451 | UInt16 docSize; | ||
452 | UInt16 i; | ||
453 | UInt16 j; | ||
454 | UInt16 k; | ||
455 | |||
456 | UInt8 *inBuf = compressedtextbuffer; | ||
457 | UInt8 *outBuf = tgtbuffer; | ||
458 | |||
459 | // headerSize = sizeof( Header ) + record->paragraphs * sizeof( Paragraph ); | ||
460 | docSize = reclen; | ||
461 | |||
462 | j = 0; | ||
463 | k = 0; | ||
464 | while ( j < docSize ) { | ||
465 | i = 0; | ||
466 | while ( i < bsize && j < docSize ) { | ||
467 | UInt16 c; | ||
468 | |||
469 | c = (UInt16) inBuf[ j++ ]; | ||
470 | if ( 0 < c && c < 9 ) { | ||
471 | while ( 0 < c-- ) | ||
472 | outBuf[ i++ ] = inBuf[ j++ ]; | ||
473 | } | ||
474 | else if ( c < 0x80 ) | ||
475 | outBuf[ i++ ] = c; | ||
476 | else if ( 0xc0 <= c ) { | ||
477 | outBuf[ i++ ] = ' '; | ||
478 | outBuf[ i++ ] = c ^ 0x80; | ||
479 | } | ||
480 | else { | ||
481 | Int16 m; | ||
482 | Int16 n; | ||
483 | |||
484 | c <<= 8; | ||
485 | c += inBuf[ j++ ]; | ||
486 | |||
487 | m = ( c & 0x3fff ) >> COUNT_BITS; | ||
488 | n = c & ( ( 1 << COUNT_BITS ) - 1 ); | ||
489 | n += 2; | ||
490 | |||
491 | do { | ||
492 | outBuf[ i ] = outBuf[ i - m ]; | ||
493 | i++; | ||
494 | } while ( 0 < n-- ); | ||
495 | } | ||
496 | } | ||
497 | k += bsize; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | void CPlucker::home() | ||
502 | { | ||
503 | currentpos = 0; | ||
504 | expand(1); | ||
505 | } | ||
506 | |||
507 | CList<Bkmk>* CPlucker::getbkmklist() | ||
508 | { | ||
509 | /* | ||
510 | CPlucker_dataRecord thisHdr; | ||
511 | |||
512 | for (int i = 1; i < ntohs(head.recordList.numRecords); i++) | ||
513 | { | ||
514 | gotorecordnumber(i); | ||
515 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
516 | if (thisHdr.type == 8) | ||
517 | { | ||
518 | UInt16 n; | ||
519 | fread(&n, 1, sizeof(n), fin); | ||
520 | n = ntohs(n); | ||
521 | qDebug("Found %u bookmarks", n); | ||
522 | } | ||
523 | qDebug("Found:%d, %u", i , thisHdr.type); | ||
524 | } | ||
525 | */ | ||
526 | return NULL; | ||
527 | } | ||
528 | |||
529 | void CPlucker::expandimg(UInt16 tgt) | ||
530 | { | ||
531 | qDebug("Image:%u", tgt); | ||
532 | CPlucker_dataRecord thisHdr; | ||
533 | size_t reclen; | ||
534 | UInt16 thisrec = 0; | ||
535 | do | ||
536 | { | ||
537 | thisrec++; | ||
538 | reclen = recordlength(thisrec); | ||
539 | gotorecordnumber(thisrec); | ||
540 | qDebug("thisrec:%u.%u", ftell(fin),thisrec); | ||
541 | fread(&thisHdr, 1, sizeof(thisHdr), fin); | ||
542 | } | ||
543 | while (ntohs(thisHdr.uid) != tgt); | ||
544 | |||
545 | reclen -= sizeof(thisHdr); | ||
546 | |||
547 | UInt16 imgsize = htons(thisHdr.size); | ||
548 | UInt8* imgbuffer = new UInt8[imgsize]; | ||
549 | |||
550 | qDebug("type:%u", thisHdr.type); | ||
551 | |||
552 | if (thisHdr.type == 2) | ||
553 | { | ||
554 | qDebug("Not compressed:%u.%u", ftell(fin),reclen); | ||
555 | fread(imgbuffer, reclen, sizeof(char), fin); | ||
556 | qDebug("Not compressed:%u.%u", ftell(fin),reclen); | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | qDebug("Compressed"); | ||
561 | fread(compressedtextbuffer, reclen, sizeof(char), fin); | ||
562 | switch (ntohs(hdr0.version)) | ||
563 | { | ||
564 | case 2: | ||
565 | UnZip(reclen, imgbuffer, imgsize); | ||
566 | break; | ||
567 | case 1: | ||
568 | UnDoc(reclen, imgbuffer, imgsize); | ||
569 | break; | ||
570 | } | ||
571 | } | ||
572 | FILE* imgfile = fopen("/home/tim/newreader/imagefile.tbmp", "w"); | ||
573 | if (imgfile != NULL) | ||
574 | { | ||
575 | fwrite(imgbuffer, 1, imgsize, imgfile); | ||
576 | fclose(imgfile); | ||
577 | } | ||
578 | delete [] imgbuffer; | ||
579 | } | ||