From 9f78c0dce157d60dae9a87136acd460ef0e04ef4 Mon Sep 17 00:00:00 2001 From: Stefan Kebekus Date: Fri, 6 Jul 2001 10:14:01 +0000 Subject: [PATCH] fixes bug #27164 svn path=/trunk/kdegraphics/kdvi/; revision=105097 --- dviwin.cpp | 13 ++++---- dviwin.h | 16 ++++++---- dviwin_draw.cpp | 75 ++++++++++++++++++++++++++++++++++++---------- kdvi_multipage.cpp | 12 ++++---- kdvi_multipage.h | 4 +-- 5 files changed, 85 insertions(+), 35 deletions(-) diff --git a/dviwin.cpp b/dviwin.cpp index 3b370d7a2..a303c1e70 100644 --- a/dviwin.cpp +++ b/dviwin.cpp @@ -133,7 +133,7 @@ dviWindow::dviWindow(double zoom, int mkpk, QWidget *parent, const char *name ) _postscript = 0; pixmap = 0; - // Storage used for dvips and friends. + // Storage used for dvips and friends, i.e. for the "export" functions. proc = 0; progress = 0; export_printer = 0; @@ -493,6 +493,7 @@ void dviWindow::drawPage() animationCounter = 0; } + // Stop if there is no dvi-file present if (dviFile == NULL) { resize(0, 0); return; @@ -501,12 +502,10 @@ void dviWindow::drawPage() resize(0, 0); return; } - if ( !pixmap ) return; if ( !pixmap->paintingActive() ) { - foreGroundPaint.begin( pixmap ); QApplication::setOverrideCursor( waitCursor ); if (setjmp(dvi_env)) { // dvi_oops called @@ -520,10 +519,10 @@ void dviWindow::drawPage() } else { draw_page(); } + foreGroundPaint.drawRect(0,0,pixmap->width(),pixmap->height()); QApplication::restoreOverrideCursor(); foreGroundPaint.end(); } - resize(pixmap->width(), pixmap->height()); repaint(); emit contents_changed(); } @@ -565,7 +564,7 @@ void dviWindow::changePageSize() resize( page_w, page_h ); currwin.win = mane.win = pixmap->handle(); - PS_interface->setSize( basedpi/mane.shrinkfactor , page_w, page_h); + PS_interface->setSize( basedpi/mane.shrinkfactor, page_w, page_h ); drawPage(); } @@ -635,7 +634,7 @@ bool dviWindow::setFile( const QString & fname ) // specials in PostScriptDirectory, and the headers in the // PostScriptHeaderString. PS_interface->clear(); - + // We will also generate a list of hyperlink-anchors in the // document. So declare the existing list empty. numAnchors = 0; @@ -649,7 +648,7 @@ bool dviWindow::setFile( const QString & fname ) currinf.end = dvi_buffer; currinf.pos = dvi_buffer; currinf._virtual = NULL; - draw_part(current_frame = &frame0, dimconv); + draw_part(current_frame = &frame0, dimconv, false); if (!PostScriptOutPutString->isEmpty()) PS_interface->setPostScript(current_page, *PostScriptOutPutString); diff --git a/dviwin.h b/dviwin.h index 905fd3c1f..90f8596fe 100644 --- a/dviwin.h +++ b/dviwin.h @@ -31,16 +31,17 @@ class KShellProcess; // max. number of hyperlinks per page. This should later be replaced by // a dynamic allocation scheme. -#define MAX_HYPERLINKS 200 +#define MAX_HYPERLINKS 400 // max. number of anchors per document. This should later be replaced by // a dynamic allocation scheme. -#define MAX_ANCHORS 300 +#define MAX_ANCHORS 1000 class DVI_Hyperlink { public: - QRect box; - QString linkText; + unsigned int baseline; + QRect box; + QString linkText; }; @@ -81,7 +82,7 @@ public: void mousePressEvent ( QMouseEvent * e ); void mouseMoveEvent ( QMouseEvent * e ); void read_postamble(void); - void draw_part(struct frame *minframe, double current_dimconv); + void draw_part(struct frame *minframe, double current_dimconv, bool is_vfmacro); void set_vf_char(unsigned int cmd, unsigned int ch); void set_char(unsigned int cmd, unsigned int ch); void set_empty_char(unsigned int cmd, unsigned int ch); @@ -171,6 +172,11 @@ private: DVI_Hyperlink hyperLinkList[MAX_HYPERLINKS]; int num_of_used_hyperlinks; + // This flag is used when rendering a dvi-page. It is set to "true" + // when any dvi-command other than "set" or "put" series of commands + // is encountered. This is considered to mark the end of a word. + bool word_boundary_encountered; + // List of anchors in a document QString AnchorList_String[MAX_ANCHORS]; unsigned int AnchorList_Page[MAX_ANCHORS]; diff --git a/dviwin_draw.cpp b/dviwin_draw.cpp index cac2a541a..b89b0abbb 100644 --- a/dviwin_draw.cpp +++ b/dviwin_draw.cpp @@ -198,16 +198,24 @@ void dviWindow::set_char(unsigned int cmd, unsigned int ch) // Draw the character. foreGroundPaint.drawPixmap(x, y, pix); - // Mark hyperlinks in blue. + + // Are we drawing text for a hyperlink? And are hyperlinks + // enabled? if (HTML_href != NULL && _showHyperLinks != 0) { - int width = (int)(basedpi*0.05/(2.54*shrink_factor) + 0.5); // Line width 0.5 mm - width = (width < 1) ? 1 : width; // but at least one pt. - foreGroundPaint.fillRect(x, PXL_V, pix.width(), width, Qt::blue); - // Tricky task: set up a rectangle which is checked when the mouse... - hyperLinkList[num_of_used_hyperlinks].box.setRect(x, y, pix.width(), pix.height()); - hyperLinkList[num_of_used_hyperlinks].linkText = *HTML_href; - if (num_of_used_hyperlinks < MAX_HYPERLINKS-1) - num_of_used_hyperlinks++; + // Now set up a rectangle which is checked against every mouse + // event. + if (word_boundary_encountered == true) { + hyperLinkList[num_of_used_hyperlinks].baseline = PXL_V; + hyperLinkList[num_of_used_hyperlinks].box.setRect(x, y, pix.width(), pix.height()); + hyperLinkList[num_of_used_hyperlinks].linkText = *HTML_href; + if (num_of_used_hyperlinks < MAX_HYPERLINKS-1) + num_of_used_hyperlinks++; + else + kdError(4300) << "Used more than " << MAX_HYPERLINKS << " on a page. This is currently not supported." << endl; + } else { + QRect dshunion = hyperLinkList[num_of_used_hyperlinks-1].box.unite(QRect(x, y, pix.width(), pix.height())) ; + hyperLinkList[num_of_used_hyperlinks-1].box = dshunion; + } } } if (cmd == PUT1) @@ -215,9 +223,11 @@ void dviWindow::set_char(unsigned int cmd, unsigned int ch) else if (currinf.dir > 0) DVI_H += g->dvi_adv; + + word_boundary_encountered = false; } -void dviWindow::set_empty_char(unsigned int cmd, unsigned int ch) +void dviWindow::set_empty_char(unsigned int, unsigned int) { return; } @@ -253,7 +263,7 @@ void dviWindow::set_vf_char(unsigned int cmd, unsigned int ch) currinf.pos = m->pos; currinf.end = m->end; currinf._virtual = currinf.fontp; - draw_part(current_frame, currinf.fontp->dimconv); + draw_part(current_frame, currinf.fontp->dimconv, true); if (currinf.pos != currinf.end + 1) tell_oops("virtual character macro does not end correctly"); currinf = oldinfo; @@ -326,7 +336,7 @@ void dviWindow::special(long nbytes) #define xspell_conv(n) spell_conv0(n, current_dimconv) -void dviWindow::draw_part(struct frame *minframe, double current_dimconv) +void dviWindow::draw_part(struct frame *minframe, double current_dimconv, bool is_vfmacro) { #ifdef DEBUG_RENDER kdDebug() << "draw_part" << endl; @@ -356,6 +366,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) break; case SETRULE: + if (is_vfmacro == false) + word_boundary_encountered = true; /* Be careful, dvicopy outputs rules with height = 0x80000000. We don't want any SIGFPE here. */ @@ -368,6 +380,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) break; case PUTRULE: + if (is_vfmacro == false) + word_boundary_encountered = true; a = xspell_conv(xsfour()); b = xspell_conv(xsfour()); if (a > 0 && b > 0 && PostScriptOutPutString == NULL) @@ -378,6 +392,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) break; case BOP: + if (is_vfmacro == false) + word_boundary_encountered = true; xskip((long) 11 * 4); DVI_H = basedpi << 16; // Reminder: DVI-coords. start at (1",1") from top of page DVI_V = basedpi << 16; @@ -386,6 +402,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) break; case EOP: + if (is_vfmacro == false) + word_boundary_encountered = true; if (current_frame != minframe) tell_oops("stack not empty at EOP"); return; @@ -437,6 +455,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case DOWN2: case DOWN3: case DOWN4: + if (is_vfmacro == false) + word_boundary_encountered = true; DVI_V += xspell_conv(xsnum(ch - DOWN1 + 1)); PXL_V = pixel_conv(DVI_V); break; @@ -447,6 +467,7 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case Y4: YY = xspell_conv(xsnum(ch - Y0)); case Y0: + word_boundary_encountered = true; DVI_V += YY; PXL_V = pixel_conv(DVI_V); break; @@ -457,6 +478,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case Z4: ZZ = xspell_conv(xsnum(ch - Z0)); case Z0: + if (is_vfmacro == false) + word_boundary_encountered = true; DVI_V += ZZ; PXL_V = pixel_conv(DVI_V); break; @@ -465,6 +488,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case FNT2: case FNT3: case FNT4: + if (is_vfmacro == false) + word_boundary_encountered = true; change_font(xnum(ch - FNT1 + 1)); break; @@ -472,6 +497,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case XXX2: case XXX3: case XXX4: + if (is_vfmacro == false) + word_boundary_encountered = true; a = xnum(ch - XXX1 + 1); if (a > 0) special(a); @@ -481,6 +508,8 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case FNTDEF2: case FNTDEF3: case FNTDEF4: + if (is_vfmacro == false) + word_boundary_encountered = true; xskip((long) (12 + ch - FNTDEF1 + 1)); xskip((long) xone() + (long) xone()); break; @@ -488,10 +517,14 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case PRE: case POST: case POSTPOST: + if (is_vfmacro == false) + word_boundary_encountered = true; tell_oops(QString("shouldn't happen: %1 encountered").arg(dvi_table2[ch - (FNTNUM0 + 64)])); break; default: + if (is_vfmacro == false) + word_boundary_encountered = true; tell_oops(QString("unknown op-code %1").arg(ch)); } /* end switch*/ } /* end else (ch not a SETCHAR or FNTNUM) */ @@ -514,7 +547,7 @@ void dviWindow::draw_page(void) #endif // Render the PostScript background, if there is one. - foreGroundPaint.fillRect(pixmap->rect(), Qt::white ); + foreGroundPaint.fillRect(pixmap->rect(), Qt::white ); if (_postscript) { QPixmap *pxm = PS_interface->graphics(current_page); if (pxm != NULL) { @@ -523,7 +556,7 @@ void dviWindow::draw_page(void) } } - // Step 4: Now really write the text + // Now really write the text (void) lseek(fileno(dviFile->file), dviFile->page_offset[current_page], SEEK_SET); memset((char *) &currinf.data, 0, sizeof(currinf.data)); currinf.fonttable = tn_table; @@ -532,9 +565,21 @@ void dviWindow::draw_page(void) currinf._virtual = NULL; HTML_href = NULL; num_of_used_hyperlinks = 0; - draw_part(current_frame = &frame0, dimconv); + draw_part(current_frame = &frame0, dimconv, false); if (HTML_href != NULL) { delete HTML_href; HTML_href = NULL; } + + // Mark hyperlinks in blue. We draw a blue line under the + // character whose width is equivalent to 0.5 mm, but at least + // one pixel. + int h = (int)(basedpi*0.05/(2.54*shrink_factor) + 0.5); + h = (h < 1) ? 1 : h; + for(int i=0; i #include #include -#include #include #include +// #include "../kviewshell/centeringScrollView.h" #include "fontpool.h" -#include "kdvi_multipage.moc" #include "kviewpart.h" #include "optiondialog.h" - +#include "kdvi_multipage.h" extern "C" { @@ -89,6 +88,7 @@ KDVIMultiPage::KDVIMultiPage(QWidget *parentWidget, const char *widgetName, QObj setXMLFile("kdvi_part.rc"); + //@@@ scrollView()->setPage(window); scrollView()->addChild(window); connect(window, SIGNAL(request_goto_page(int, int)), this, SLOT(goto_page(int, int) ) ); connect(window, SIGNAL(contents_changed(void)), this, SLOT(contents_of_dviwin_changed(void)) ); @@ -241,7 +241,7 @@ void KDVIMultiPage::about() i18n("the KDVI plugin"), KAboutDialog::Close, KAboutDialog::Close); - ab->setProduct("kdvi", "0.9f", QString::null, QString::null); + ab->setProduct("kdvi", "0.9g", QString::null, QString::null); ab->addTextPage (i18n("About"), i18n("A previewer for Device Independent files (DVI files) produced " "by the TeX typesetting system.
" @@ -276,7 +276,7 @@ void KDVIMultiPage::about() void KDVIMultiPage::bugform() { - KAboutData *kab = new KAboutData("kdvi", I18N_NOOP("KDVI"), "0.9f", 0, 0, 0, 0, 0); + KAboutData *kab = new KAboutData("kdvi", I18N_NOOP("KDVI"), "0.9g", 0, 0, 0, 0, 0); KBugReport *kbr = new KBugReport(0, true, kab ); kbr->show(); } @@ -495,3 +495,5 @@ void KDVIMultiPage::enableActions(bool b) exportPSAction->setEnabled(b); exportPDFAction->setEnabled(b); } + +#include "kdvi_multipage.moc" diff --git a/kdvi_multipage.h b/kdvi_multipage.h index 03ff5b774..9c5c1656a 100644 --- a/kdvi_multipage.h +++ b/kdvi_multipage.h @@ -15,9 +15,7 @@ class QLabel; class QPainter; -#include - - +#include "../kviewshell/kmultipage.h" #include "dviwin.h"