summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/BuffDoc.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/BuffDoc.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-reader/BuffDoc.cpp428
1 files changed, 363 insertions, 65 deletions
diff --git a/noncore/apps/opie-reader/BuffDoc.cpp b/noncore/apps/opie-reader/BuffDoc.cpp
index 68391b8..22934f9 100644
--- a/noncore/apps/opie-reader/BuffDoc.cpp
+++ b/noncore/apps/opie-reader/BuffDoc.cpp
@@ -1,6 +1,20 @@
1#include "static.h"
2#include "names.h"
1 3
2#define NEWLINEBREAK 4#define NEWLINEBREAK
5#define INCREMENTALWIDTH
3 6
7#include "useqpe.h"
8#include "usenef.h"
4#include "BuffDoc.h" 9#include "BuffDoc.h"
5//#include <FL/fl_draw.h> 10#include "config.h"
11#include "CDrawBuffer.h"
12#include "ZText.h"
13#include "ebookcodec.h"
14
15#ifdef __STATIC
16#include "Aportis.h"
17#include "CHM.h"
18#include "ppm_expander.h"
19#include "ztxt.h"
6#include "plucker.h" 20#include "plucker.h"
@@ -10,4 +24,7 @@
10#endif 24#endif
25#include "iSilo.h"
26#endif
27
11 28
12linkType BuffDoc::hyperlink(unsigned int n, QString& wrd) 29linkType BuffDoc::hyperlink(unsigned int n, unsigned int noff, QString& wrd, QString& nm)
13{ 30{
@@ -16,4 +33,4 @@ linkType BuffDoc::hyperlink(unsigned int n, QString& wrd)
16 { 33 {
17 bRet = exp->hyperlink(n, wrd); 34 bRet = filt->hyperlink(n, noff, wrd, nm);
18 if (bRet == eLink) 35 if ((bRet & eLink) != 0)
19 { 36 {
@@ -22,3 +39,3 @@ linkType BuffDoc::hyperlink(unsigned int n, QString& wrd)
22#ifdef NEWLINEBREAK 39#ifdef NEWLINEBREAK
23 lastispara = true; 40 lastispara = false;
24#else 41#else
@@ -34,3 +51,3 @@ void BuffDoc::locate(unsigned int n)
34{ 51{
35 // //odebug << "BuffDoc:locating:" << n << "" << oendl; 52 // //qDebug("BuffDoc:locating:%u",n);
36 lastword.empty(); 53 lastword.empty();
@@ -38,3 +55,3 @@ void BuffDoc::locate(unsigned int n)
38#ifdef NEWLINEBREAK 55#ifdef NEWLINEBREAK
39 lastispara = true; 56 lastispara = false;
40#else 57#else
@@ -43,4 +60,85 @@ void BuffDoc::locate(unsigned int n)
43 // tchar linebuf[1024]; 60 // tchar linebuf[1024];
44 if (exp != NULL) exp->locate(n); 61 if (exp != NULL) filt->locate(n);
45 // //odebug << "BuffDoc:Located" << oendl; 62 // //qDebug("BuffDoc:Located");
63}
64
65static bool isletter(unsigned short c)
66{
67 if ('a' <= c && c <= 'z') return true;
68 if ('A' <= c && c <= 'Z') return true;
69 // Cyrillic letters
70 if (0x400 <= c && c <= 0x52F) return true;
71 return false;
72}
73
74static bool isvowel(unsigned short c) // Only want lower case vowels
75{
76 switch (c)
77 {
78 case 'a':
79 case 'e':
80 case 'i':
81 case 'o':
82 case 'u':
83 // Cyrillic vowels
84 case 0x430:
85 case 0x435:
86 case 0x438:
87 case 0x43E:
88 case 0x443:
89 case 0x44B:
90 case 0x44D:
91 case 0x44E:
92 case 0x44F:
93 case 0x451:
94
95 case 0x450:
96 case 0x454:
97 case 0x456:
98 case 0x457:
99 case 0x45D:
100
101 case 0x463:
102
103 case 0x4AF:
104 case 0x4B1:
105 case 0x4D1:
106 case 0x4D3:
107
108 case 0x4D5:
109 case 0x4D7:
110 case 0x4E3:
111 case 0x4E5:
112 case 0x4E7:
113 case 0x4E9:
114 case 0x4EB:
115 case 0x4ED:
116 case 0x4EF:
117 case 0x4F1:
118 case 0x4F3:
119 case 0x4F9:
120 return true;
121 default:
122 return ((0xe0 <= c) && (c <= 0xfc) && (c != 0xf1) && (c != 0xf7) && (c != 0xe7));
123 }
124}
125
126inline bool isconsonant(unsigned short c)
127{
128 switch( c )
129 {
130 // Some cyrillic letters are neither vowels, nor consonants, or otherwise
131 // the letters no word can start from.
132 case 0x439:
133 case 0x44A:
134 case 0x44C:
135
136 case 0x45E:
137
138 return false;
139
140 default:
141 return (isletter(c) && !isvowel(c));
142 }
143 return (isletter(c) && !isvowel(c));
46} 144}
@@ -48,3 +146,3 @@ void BuffDoc::locate(unsigned int n)
48#ifdef NEWLINEBREAK 146#ifdef NEWLINEBREAK
49bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border) 147bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned short _lborder, unsigned short _rborder, bool hyphenate, int availht)
50{ 148{
@@ -52,3 +150,4 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
52 bool margindone = false; 150 bool margindone = false;
53 int w = wth-2*_border; 151 int isCentred = -1;
152 int w = wth-(_lborder+_rborder);
54 tchar ch = 32; 153 tchar ch = 32;
@@ -65,2 +164,6 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
65 { 164 {
165 if (isCentred < 0)
166 {
167 isCentred = (lastword.firststyle().getJustify() == m_AlignCentre) ? 1 : 0;
168 }
66 *buff = lastword; 169 *buff = lastword;
@@ -73,12 +176,16 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
73 lastword.empty(); 176 lastword.empty();
74 unsigned int slen = buff->width(len); 177 unsigned int slen = buff->width(availht, len);
75 if (lastispara) buff->setstartpara(); 178 if (lastispara) buff->setstartpara();
179 int nospaces = 0;
76 while (1) 180 while (1)
77 { 181 {
78 lastsizes[len] = exp->locate(); 182 getch(ch, cs, lastsizes[len]);
79 getch(ch, cs); 183 if (isCentred < 0)
184 {
185 isCentred = (cs.getJustify() == m_AlignCentre) ? 1 : 0;
186 }
80 if (ch == 10 && len == 0 && !lastispara) 187 if (ch == 10 && len == 0 && !lastispara)
81 { 188 {
82 lastsizes[len] = exp->locate(); 189 getch(ch, cs, lastsizes[len]);
83 getch(ch, cs); 190 buff->setstartpara();
84 } 191 }
@@ -86,2 +193,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
86 { 193 {
194 buff->setendpara(cs);
87 if (len == 0) 195 if (len == 0)
@@ -96,3 +204,11 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
96 { 204 {
97 buff->setendpara(); 205 buff->setendpara(cs);
206 lastispara = true;
207 laststartline = exp->locate();
208 break;
209 }
210 if (ch == 6)
211 {
212 buff->setendpara(cs);
213 buff->setBop();
98 lastispara = true; 214 lastispara = true;
@@ -103,2 +219,6 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
103 buff->addch(ch, cs); 219 buff->addch(ch, cs);
220 if (ch == ' ')
221 {
222 nospaces++;
223 }
104 len++; 224 len++;
@@ -109,3 +229,7 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
109 } 229 }
110 if ((slen = buff->width(len)) > w) 230#ifdef INCREMENTALWIDTH
231 if ((slen += buff->charwidth(len-1, cs)) > w)
232#else
233 if ((slen = buff->width(availht, len)) > w)
234#endif
111 { 235 {
@@ -119,5 +243,11 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
119 { 243 {
244 int lastk = len-4;
120 for (int i = len-2; i > 0; i--) 245 for (int i = len-2; i > 0; i--)
121 { 246 {
122 if ((*buff)[i] == ' ') 247 if (
248 (((*buff)[i] == 0x2014) && isletter((*buff)[i+1]))
249 ||
250 ((*buff)[i] == '-')
251 // ((*buff)[i] == '-' && !(((*buff)[i-1] == '-') || ((*buff)[i+1] == '-')))
252)
123 { 253 {
@@ -125,6 +255,6 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
125 lastword.setright(*buff, i+1); 255 lastword.setright(*buff, i+1);
126 buff->truncate(i); 256 buff->truncate(i+1);
127 (*buff)[i] = '\0'; 257 (*buff)[i+1] = '\0';
128 laststartline = lastsizes[i+1]; 258 laststartline = lastsizes[i+1];
129 buff->resize(); 259 // buff->resize();
130 for (int j = 0; j < lastword.length(); j++) 260 for (int j = 0; j < lastword.length(); j++)
@@ -135,3 +265,116 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
135 } 265 }
136 if ((*buff)[i] == '-' && !(((*buff)[i-1] == '-') || ((*buff)[i+1] == '-'))) 266
267 //if (hyphenate && (m_hyphenthreshold+1)*i < m_hyphenthreshold*len)
268 // We end up with i+1 characters instead of len-1
269 // Thus we are removing len - 1 - (i + 1) = len-i-2
270 // The space characters will be stretched to cover
271 // nospaces to nospaces + len - i - 2
272 // The stretch factor is hence
273 // (nospaces+len-i-2)/nospaces
274 if (hyphenate && !isCentred && ( 100*(nospaces+len-i-2) > (100+m_hyphenthreshold)*nospaces ))
275 {
276 /*
277 if (m_customhyphen)
278 {
279 for (int k = lastk; k >= i && k >= 2; k--)
280 {
281 if (
282 isletter((*buff)[k+3])
283 &&
284 isletter((*buff)[k+2])
285 &&
286 isvowel((*buff)[k+1])
287 &&
288 isconsonant((*buff)[k])
289 &&
290 isletter((*buff)[k-1])
291 &&
292 isletter((*buff)[k-2])
293 )
294 {
295 (*buff)[len] = 0;
296 lastword.setright(*buff, k+1);
297 buff->truncate(k+2);
298 (*buff)[k+1] = '-';
299 (*buff)[k+2] = '\0';
300 laststartline = lastsizes[k+1];
301 buff->resize();
302 for (int j = 0; j < lastword.length(); j++)
303 {
304 lastsizes[j] = lastsizes[j+k+1];
305 }
306 return true;
307 }
308 }
309 }
310 else
311 */
312 {
313 for (int k = lastk; k >= i && k >= 1; k--)
314 {
315 if (
316 /*
317 (
318 k < len-3
319 &&
320 k >= 1
321 &&
322 isletter((*buff)[k+3])
323 &&
324 isletter((*buff)[k+2])
325 &&
326 isconsonant((*buff)[k+1])
327 &&
328 ((*buff)[k+1] != 'y')
329 &&
330 ((*buff)[k+1] != 'h')
331 &&
332 isconsonant((*buff)[k])
333 &&
334 ((*buff)[k] != 'h')
335 &&
336 isletter((*buff)[k-1])
337 )
338 ||
339 */
340 (
341 isletter((*buff)[k+3])
342 &&
343 isletter((*buff)[k+2])
344 &&
345 isconsonant((*buff)[k+1])
346 &&
347 ((*buff)[k+1] != 'y')
348 &&
349 isletter((*buff)[k])
350 &&
351 ((*buff)[k] != 'h')
352 &&
353 isletter((*buff)[k-1])
354 && // Do not hyphenate when the first part ends with a vowel,
355 // and the second starts with the two consonants.
356 // Examples: "co-nsona-nts" -> "con-sonants",
357 // "hy-phenation" -> "hyp-henation" etc.
358 !( isvowel( (*buff)[k] ) && isconsonant( (*buff)[k+2] ) )
359 )
360 )
361 {
362 (*buff)[len] = 0;
363 lastword.setright(*buff, k+1);
364 buff->truncate(k+2);
365 (*buff)[k+1] = '-';
366 (*buff)[k+2] = '\0';
367 laststartline = lastsizes[k+1];
368 // buff->resize();
369 for (int j = 0; j < lastword.length(); j++)
370 {
371 lastsizes[j] = lastsizes[j+k+1];
372 }
373 return true;
374 }
375 }
376 }
377 lastk = i;
378 }
379 if ((*buff)[i] == ' ')
137 { 380 {
@@ -139,6 +382,6 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
139 lastword.setright(*buff, i+1); 382 lastword.setright(*buff, i+1);
140 buff->truncate(i+1); 383 buff->truncate(i);
141 (*buff)[i+1] = '\0'; 384 (*buff)[i] = '\0';
142 laststartline = lastsizes[i+1]; 385 laststartline = lastsizes[i+1];
143 buff->resize(); 386 // buff->resize();
144 for (int j = 0; j < lastword.length(); j++) 387 for (int j = 0; j < lastword.length(); j++)
@@ -164,3 +407,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
164 (*buff)[len] = '\0'; 407 (*buff)[len] = '\0';
165 buff->resize(); 408 // buff->resize();
166 return moreleft; 409 return moreleft;
@@ -168,6 +411,6 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
168#else 411#else
169bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border) 412bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned short _lborder, unsigned short _rborder)
170{ 413{
171 bool margindone = false; 414 bool margindone = false;
172 int w = wth-2*_border; 415 int w = wth-(_lborder+_rborder);
173 tchar ch = 32; 416 tchar ch = 32;
@@ -190,5 +433,5 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
190 else buff->empty(); 433 else buff->empty();
191// //odebug << "Buff:" << toQString(buff->data()) << " Lastword:" << toQString(lastword.data()) << "" << oendl; 434// //qDebug("Buff:%s Lastword:%s", (const char*)toQString(buff->data()), (const char*)toQString(lastword.data()));
192 lastcheck = len = buff->length(); 435 lastcheck = len = buff->length();
193 unsigned int slen = buff->width(len); 436 unsigned int slen = buff->width(availht, len);
194 if (slen > w) 437 if (slen > w)
@@ -197,3 +440,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
197 { 440 {
198 if (buff->width(len) < w) break; 441 if (buff->width(availht, len) < w) break;
199 } 442 }
@@ -216,3 +459,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
216 } 459 }
217 buff->resize(); 460 // buff->resize();
218 return true; 461 return true;
@@ -225,3 +468,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
225 len = buff->length(); 468 len = buff->length();
226 while (buff->width(len) > w) len--; 469 while (buff->width(availht, len) > w) len--;
227// (*buff)[len] = '\0'; 470// (*buff)[len] = '\0';
@@ -229,3 +472,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
229 laststartline = exp->locate(); 472 laststartline = exp->locate();
230 buff->resize(); 473 // buff->resize();
231 return true; 474 return true;
@@ -237,4 +480,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
237 lastcheck = len; 480 lastcheck = len;
238 allsizes[len] = exp->locate(); 481 getch(ch, cs, allsizes[len]);
239 getch(ch, cs);
240 while (ch != ' ' && ch != '\012' && ch != UEOF && len < 128) 482 while (ch != ' ' && ch != '\012' && ch != UEOF && len < 128)
@@ -243,7 +485,6 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
243 buff->addch(ch,cs); 485 buff->addch(ch,cs);
244 allsizes[len] = exp->locate(); 486 getch(ch, cs, allsizes[len]);
245 getch(ch, cs);
246 } 487 }
247 (*buff)[len] = 0; 488 (*buff)[len] = 0;
248 slen = buff->width(len); 489 slen = buff->width(availht, len);
249 len++; 490 len++;
@@ -288,3 +529,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
288// buff->frig(); 529// buff->frig();
289 buff->resize(); 530// buff->resize();
290 if (ch == UEOF && buff->length() == 0) 531 if (ch == UEOF && buff->length() == 0)
@@ -298,5 +539,5 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, unsigned char _border)
298 539
299bool BuffDoc::getline(CDrawBuffer* buff, int wth, int cw, unsigned char _border) 540bool BuffDoc::getline(CDrawBuffer* buff, int wth, int cw, unsigned short _lborder, unsigned short _rborder, int availht)
300{ 541{
301 int w = wth-2*_border; 542 int w = wth-(_lborder+_rborder);
302 buff->empty(); 543 buff->empty();
@@ -309,5 +550,7 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, int cw, unsigned char _border)
309 int i = 1; 550 int i = 1;
310 while (i*cw < w-buff->offset(w,0)) 551 int offset = buff->offset(w,0,0,availht);
552 while (i*cw < w-offset)
311 { 553 {
312 getch(ch, cs); 554 unsigned long dummy;
555 getch(ch, cs, dummy);
313 if (ch == '\12' || ch == UEOF) break; 556 if (ch == '\12' || ch == UEOF) break;
@@ -318,3 +561,3 @@ bool BuffDoc::getline(CDrawBuffer* buff, int wth, int cw, unsigned char _border)
318 laststartline = exp->locate(); 561 laststartline = exp->locate();
319 buff->resize(); 562 // buff->resize();
320 return (ch != UEOF); 563 return (ch != UEOF);
@@ -324,17 +567,6 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
324{ 567{
325 // //odebug << "BuffDoc:Openfile:" << src << "" << oendl;
326 // //odebug << "Trying aportis " << exp << "" << oendl;
327 if (exp != NULL) delete exp; 568 if (exp != NULL) delete exp;
328 lastword.empty(); 569 exp = NULL;
329 lastsizes[0] = laststartline = 0;
330#ifdef NEWLINEBREAK
331 lastispara = true;
332#else
333 lastispara = false;
334#endif
335 /*
336 exp = new Text;
337 int ret = exp->openfile(src);
338 */
339 570
571#ifdef __STATIC
340 exp = new Aportis; 572 exp = new Aportis;
@@ -354,2 +586,12 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
354 } 586 }
587 /*
588 }
589 if (ret != 0)
590 {
591 delete exp;
592 exp = new ebookcodec("Aportis");
593 ret = exp->openfile(src);
594 if (ret == 0) qDebug("Aportis format");
595 }
596 */
355#ifdef USENEF 597#ifdef USENEF
@@ -361,2 +603,3 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
361 ret = exp->openfile(src); 603 ret = exp->openfile(src);
604 if (ret == 0) qDebug("Arriere format");
362 } 605 }
@@ -368,2 +611,3 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
368 ret = exp->openfile(src); 611 ret = exp->openfile(src);
612 if (ret == 0) qDebug("NEF format");
369 } 613 }
@@ -379,4 +623,18 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
379 { 623 {
624
380 delete exp; 625 delete exp;
381 //odebug << "Trying ppms" << oendl; 626 exp = new CHM;
627 ret = exp->openfile(src);
628 }
629 if (ret != 0)
630 {
631
632 delete exp;
633 exp = new iSilo;
634 ret = exp->openfile(src);
635 }
636 if (ret != 0)
637 {
638 delete exp;
639 //qDebug("Trying ppms");
382 exp = new ppm_expander; 640 exp = new ppm_expander;
@@ -388,4 +646,5 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
388 exp = new Text; 646 exp = new Text;
389 // //odebug << "Trying text" << oendl; 647 // //qDebug("Trying text");
390 ret = exp->openfile(src); 648 ret = exp->openfile(src);
649 if (ret == 0) qDebug("Text format");
391 } 650 }
@@ -398,4 +657,38 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
398 } 657 }
399 // //odebug << "Doing final open:" << exp << ":" << filt << "" << oendl; 658 // //qDebug("Doing final open:%x:%x",exp,filt);
659#else
660 QString codecpath(QTReaderUtil::getPluginPath());
661 QDir d(codecpath, "*.so");
662
663 if (d.exists())
664 {
400 665
666 const QFileInfoList *list = d.entryInfoList();
667 QFileInfoListIterator it( *list ); // create list iterator
668 QFileInfo *fi; // pointer for traversing
669
670 int ret = -1;
671 while ( ret != 0 && (fi=it.current()) )
672 { // for each file...
673 if (exp != NULL) delete exp;
674 qDebug("Trying %s", (const char*)fi->fileName());
675 exp = new ebookcodec(fi->fileName());
676 ret = exp->openfile(src);
677 ++it;
678 }
679 qDebug("Buffdoc:Finished opening");
680 if (ret != 0)
681 {
682 if (exp != NULL) delete exp;
683 exp = new Text;
684 ret = exp->openfile(src);
685 }
686 }
687 else
688 {
689 if (exp != NULL) delete exp;
690 exp = new Text;
691 exp->openfile(src);
692 }
693#endif
401 lastword.empty(); 694 lastword.empty();
@@ -403,3 +696,3 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
403#ifdef NEWLINEBREAK 696#ifdef NEWLINEBREAK
404 lastispara = true; 697 lastispara = false;
405#else 698#else
@@ -407,6 +700,11 @@ int BuffDoc::openfile(QWidget* _parent, const char *src)
407#endif 700#endif
408 exp->locate(0); 701 exp->locate(exp->getHome());
409 filt->setsource(exp); 702 filt->setsource(exp);
410 // //odebug << "BuffDoc:file opened" << oendl; 703 qDebug("BuffDoc:file opened");
411 return 0; 704 return 0;
412} 705}
706
707QString BuffDoc::about()
708{
709 return QString("Buffered Decompressor (c) Tim Wentford\nHyphenation algorithm (c) Tim Wentford\n (Cyrillic support by Konstantin Isakov\n")+filt->about();
710}