// special.cpp // Methods for dviwin which deal with "\special" commands found in the // DVI file // Copyright 2000--2001, Stefan Kebekus (stefan.kebekus@uni-bayreuth.de). #include #include #include #include #include #include #include "dviwin.h" #include "kdvi.h" #include #include #include "oconfig.h" extern QPainter foreGroundPaint; void dviWindow::html_anchor_special(QString cp) { if (PostScriptOutPutString != NULL) { // only during scanning, not during rendering cp.truncate(cp.find('"')); #ifdef DEBUG_SPECIAL kdDebug(4300) << "HTML-special, anchor " << cp.latin1() << endl; kdDebug(4300) << "page " << current_page << endl; #endif AnchorList_String[numAnchors] = cp; AnchorList_Page[numAnchors] = current_page; AnchorList_Vert[numAnchors] = DVI_V/65536; // multiply with zoom to get pixel coords if (numAnchors < MAX_ANCHORS-2) numAnchors++; } } void dviWindow::html_href_special(QString cp) { cp.truncate(cp.find('"')); #ifdef DEBUG_SPECIAL kdDebug(4300) << "HTML-special, href " << cp.latin1() << endl; #endif if (!PostScriptOutPutString) { // only when rendering really takes place HTML_href = new QString(cp); } } void dviWindow::html_anchor_end(void) { #ifdef DEBUG_SPECIAL kdDebug(4300) << "HTML-special, anchor-end" << endl; #endif if (HTML_href != NULL) { delete HTML_href; HTML_href = NULL; } } void dviWindow::header_special(QString cp) { #ifdef DEBUG_SPECIAL kdDebug(4300) << "PostScript-special, header " << cp.latin1() << endl; #endif if (PostScriptOutPutString && QFile::exists(cp)) { PS_interface->PostScriptHeaderString->append( QString(" (%1) run\n").arg(cp) ); } } static void parse_special_argument(QString strg, const char *argument_name, int *variable) { bool OK; int index = strg.find(argument_name); if (index >= 0) { QString tmp = strg.mid(index + strlen(argument_name)); tmp.truncate(tmp.find(' ')); int tmp_int = tmp.toUInt(&OK); if (OK) *variable = tmp_int; else // Maybe we should open a dialog here. kdError(4300) << i18n("Malformed parameter in the epsf special command.") << endl; } } void dviWindow::epsf_special(QString cp) { #ifdef DEBUG_SPECIAL kdDebug(4300) << "epsf-special: psfile=" << cp <filename); QFileInfo fi2(fi1.dir(),EPSfilename); if (fi2.exists()) EPSfilename = fi2.absFilePath(); else if (QFile::exists(EPSfilename + QString::fromLatin1(".gz"))) { //try harder to find a gzipped file EPSfilename = EPSfilename + QString::fromLatin1(".gz"); //kdDebug(4300) << "gzEps=" << EPSfilename <append( "@beginspecial " ); PostScriptOutPutString->append( QString(" %1 @llx").arg(llx) ); PostScriptOutPutString->append( QString(" %1 @lly").arg(lly) ); PostScriptOutPutString->append( QString(" %1 @urx").arg(urx) ); PostScriptOutPutString->append( QString(" %1 @ury").arg(ury) ); if (rwi != 0) PostScriptOutPutString->append( QString(" %1 @rwi").arg(rwi) ); if (rhi != 0) PostScriptOutPutString->append( QString(" %1 @rhi").arg(rhi) ); if (angle != 0) PostScriptOutPutString->append( QString(" %1 @angle").arg(angle) ); PostScriptOutPutString->append( " @setspecial \n" ); PostScriptOutPutString->append( QString(" (%1) run\n").arg(EPSfilename) ); PostScriptOutPutString->append( "@endspecial \n" ); } } else { if (!_postscript || !QFile::exists(EPSfilename)) { // Don't show PostScript, just draw the bounding box. For this, // calculate the size of the bounding box in Pixels. double bbox_width = urx - llx; double bbox_height = ury - lly; if ((rwi != 0)&&(bbox_width != 0)) { bbox_height *= rwi/bbox_width; bbox_width = rwi; } if ((rhi != 0)&&(bbox_height != 0)) { bbox_width *= rhi/bbox_height; bbox_height = rhi; } bbox_width *= 0.1 * dviFile->dimconv / shrink_factor; bbox_height *= 0.1 * dviFile->dimconv / shrink_factor; QRect bbox(PXL_H - currwin.base_x, PXL_V - currwin.base_y - (int)bbox_height, (int)bbox_width, (int)bbox_height); foreGroundPaint.save(); if (QFile::exists(EPSfilename)) foreGroundPaint.setBrush(Qt::lightGray); else foreGroundPaint.setBrush(Qt::red); foreGroundPaint.setPen(Qt::black); foreGroundPaint.drawRoundRect(bbox, 2, 2); if (QFile::exists(EPSfilename)) foreGroundPaint.drawText (bbox, (int)(Qt::AlignCenter), EPSfilename, -1, &bbox); else foreGroundPaint.drawText (bbox, (int)(Qt::AlignCenter), QString(i18n("File not found:\n %1")).arg(EPSfilename), -1, &bbox); foreGroundPaint.restore(); } } return; } void dviWindow::bang_special(QString cp) { #ifdef DEBUG_SPECIAL kdDebug(4300) << "PostScript-special, literal header " << cp.latin1() << endl; #endif if (currwin.win == mane.win && PostScriptOutPutString) { PS_interface->PostScriptHeaderString->append( " @defspecial \n" ); PS_interface->PostScriptHeaderString->append( cp ); PS_interface->PostScriptHeaderString->append( " @fedspecial \n" ); } } void dviWindow::quote_special(QString cp) { #ifdef DEBUG_SPECIAL kdError(4300) << "PostScript-special, literal PostScript " << cp.latin1() << endl; #endif if (currwin.win == mane.win && PostScriptOutPutString) { double PS_H = (DVI_H*300.0)/(65536*basedpi)-300; double PS_V = (DVI_V*300.0)/(65536*basedpi)-300; PostScriptOutPutString->append( QString(" %1 %2 moveto\n").arg(PS_H).arg(PS_V) ); PostScriptOutPutString->append( " @beginspecial @setspecial \n" ); PostScriptOutPutString->append( cp ); PostScriptOutPutString->append( " @endspecial \n" ); } } void dviWindow::ps_special(QString cp) { #ifdef DEBUG_SPECIAL kdError(4300) << "PostScript-special, direct PostScript " << cp.latin1() << endl; #endif if (currwin.win == mane.win && PostScriptOutPutString) { double PS_H = (DVI_H*300.0)/(65536*basedpi)-300; double PS_V = (DVI_V*300.0)/(65536*basedpi)-300; if (cp.find("ps::[begin]", 0, false) == 0) { PostScriptOutPutString->append( QString(" %1 %2 moveto\n").arg(PS_H).arg(PS_V) ); PostScriptOutPutString->append( QString(" %1\n").arg(cp.mid(11)) ); } else { if (cp.find("ps::[end]", 0, false) == 0) { PostScriptOutPutString->append( QString(" %1\n").arg(cp.mid(9)) ); } else { if (cp.find("ps::", 0, false) == 0) { PostScriptOutPutString->append( QString(" %1\n").arg(cp.mid(4)) ); } else { PostScriptOutPutString->append( QString(" %1 %2 moveto\n").arg(PS_H).arg(PS_V) ); PostScriptOutPutString->append( QString(" %1\n").arg(cp.mid(3)) ); } } } } } void dviWindow::applicationDoSpecial(char *cp) { QString special_command(cp); // Literal Postscript inclusion if (special_command[0] == '"') { quote_special(special_command.mid(1)); return; } // PS-Postscript inclusion if (special_command.find("ps:", 0, false) == 0) { ps_special(special_command); return; } // Literal Postscript Header if (special_command[0] == '!') { bang_special(special_command.mid(1)); return; } // Encapsulated Postscript File if (special_command.find("PSfile=", 0, false) == 0) { epsf_special(special_command.mid(7)); return; } // Postscript Header File if (special_command.find("header=", 0, false) == 0) { header_special(special_command.mid(7)); return; } // HTML reference if (special_command.find("html:", 0, false) == 0) { html_anchor_end(); return; } // HTML anchor special if (special_command.find("html: