dvirenderer.cpp.svn-base
来自「okular」· SVN-BASE 代码 · 共 801 行 · 第 1/2 页
SVN-BASE
801 行
//kDebug(kvs::dvi) << "Time required for prescan phase: " << preScanTimer.restart() << "ms" << endl;#endif current_page = currPageSav; _isModified = true;}bool dviRenderer::isValidFile(const QString& filename) const{ QFile f(filename); if (!f.open(QIODevice::ReadOnly)) return false; unsigned char test[4]; if ( f.read( (char *)test,2)<2 || test[0] != 247 || test[1] != 2 ) return false; int n = f.size(); if ( n < 134 ) // Too short for a dvi file return false; f.seek( n-4 ); unsigned char trailer[4] = { 0xdf,0xdf,0xdf,0xdf }; if ( f.read( (char *)test, 4 )<4 || strncmp( (char *)test, (char *) trailer, 4 ) ) return false; // We suppose now that the dvi file is complete and OK return true;}bool dviRenderer::setFile(const QString &fname, const KUrl &base){#ifdef DEBUG_DVIRENDERER kDebug(kvs::dvi) << "dviRenderer::setFile( fname='" << fname << "' )"<<endl; //, ref='" << ref << "', sourceMarker=" << sourceMarker << " )" << endl;#endif //QMutexLocker lock(&mutex); QFileInfo fi(fname); QString filename = fi.absoluteFilePath(); // If fname is the empty string, then this means: "close". Delete // the dvifile and the pixmap. if (fname.isEmpty()) { // Delete DVI file/* if(info) info->setDVIData(0);*/ delete dviFile; dviFile = 0; return true; } // Make sure the file actually exists. if (!fi.exists() || fi.isDir()) {#if 0 KMessageBox::error( parentWidget, i18n("<qt><strong>File error.</strong> The specified file '%1' does not exist. " "KDVI already tried to add the ending '.dvi'.</qt>", filename), i18n("File Error"));#endif return false; } QApplication::setOverrideCursor( Qt::WaitCursor ); dvifile *dviFile_new = new dvifile(filename, &font_pool); if ((dviFile == 0) || (dviFile->filename != filename)) dviFile_new->sourceSpecialMarker = true; else dviFile_new->sourceSpecialMarker = false; if ((dviFile_new->dvi_Data() == NULL)||(dviFile_new->errorMsg.isEmpty() != true)) { QApplication::restoreOverrideCursor(); if (dviFile_new->errorMsg.isEmpty() != true)/* KMessageBox::detailedError(parentWidget, i18n("<qt>File corruption. KDVI could not interprete your DVI file. This is " "most commonly caused by a corrupted file.</qt>"), dviFile_new->errorMsg, i18n("DVI File Error"));*/ delete dviFile_new; return false; } delete dviFile; dviFile = dviFile_new; numPages = dviFile->total_pages; /* if(info) info->setDVIData(dviFile); */ _isModified = false; baseURL = base; font_pool.setExtraSearchPath( fi.absolutePath() ); font_pool.setCMperDVIunit( dviFile->getCmPerDVIunit() ); // Extract PostScript from the DVI file, and store the PostScript // specials in PostScriptDirectory, and the headers in the // PostScriptHeaderString. PS_interface->clear(); // If the DVI file comes from a remote URL (e.g. downloaded from a // web server), we limit the PostScript files that can be accessed // by this file to the download directory, in order to limit the // possibilities of a denial of service attack. QString includePath; if (!baseURL.isLocalFile()) { includePath = filename; includePath.truncate(includePath.lastIndexOf('/')); } PS_interface->setIncludePath(includePath); // We will also generate a list of hyperlink-anchors and source-file // anchors in the document. So declare the existing lists empty. //anchorList.clear(); sourceHyperLinkAnchors.clear(); //bookmarks.clear(); prebookmarks.clear(); if (dviFile->page_offset.isEmpty() == true) return false; // Locate fonts. font_pool.locateFonts(); // Update the list of fonts in the info window //if (info != 0) //info->setFontInfo(&font_pool); // We should pre-scan the document now (to extract embedded, // PostScript, Hyperlinks, ets). // PRESCAN STARTS HERE#ifdef PERFORMANCE_MEASUREMENT //kDebug(kvs::dvi) << "Time elapsed till prescan phase starts " << performanceTimer.elapsed() << "ms" << endl; //QTime preScanTimer; //preScanTimer.start();#endif dviFile->numberOfExternalPSFiles = 0; quint16 currPageSav = current_page; prebookmarks.clear(); for(current_page=0; current_page < dviFile->total_pages; current_page++) { PostScriptOutPutString = new QString(); if (current_page < dviFile->total_pages) { command_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page)]; end_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page+1)]; } else command_pointer = end_pointer = 0; memset((char *) &currinf.data, 0, sizeof(currinf.data)); currinf.fonttable = &(dviFile->tn_table); currinf._virtual = NULL; prescan(&dviRenderer::prescan_parseSpecials); if (!PostScriptOutPutString->isEmpty()) PS_interface->setPostScript(current_page, *PostScriptOutPutString); delete PostScriptOutPutString; } PostScriptOutPutString = NULL;#if 0 // Generate the list of bookmarks bookmarks.clear(); Q3PtrStack<Bookmark> stack; stack.setAutoDelete (false); QVector<PreBookmark>::iterator it; for( it = prebookmarks.begin(); it != prebookmarks.end(); ++it ) { Bookmark *bmk = new Bookmark((*it).title, findAnchor((*it).anchorName)); if (stack.isEmpty()) bookmarks.append(bmk); else { stack.top()->subordinateBookmarks.append(bmk); stack.remove(); } for(int i=0; i<(*it).noOfChildren; i++) stack.push(bmk); } prebookmarks.clear();#endif#ifdef PERFORMANCE_MEASUREMENT //kDebug(kvs::dvi) << "Time required for prescan phase: " << preScanTimer.restart() << "ms" << endl;#endif current_page = currPageSav; // PRESCAN ENDS HERE pageSizes.resize(0); if (dviFile->suggestedPageSize != 0) { // Fill the vector pageSizes with total_pages identical entries pageSizes.fill(*(dviFile->suggestedPageSize), dviFile->total_pages); } QApplication::restoreOverrideCursor(); return true;}Anchor dviRenderer::parseReference(const QString &reference){ QMutexLocker locker(&mutex);#ifdef DEBUG_DVIRENDERER kError(kvs::dvi) << "dviRenderer::parseReference( " << reference << " ) called" << endl;#endif if (dviFile == 0) return Anchor(); // case 1: The reference is a number, which we'll interpret as a // page number. bool ok; int page = reference.toInt ( &ok ); if (ok == true) { if (page < 0) page = 0; if (page > dviFile->total_pages) page = dviFile->total_pages; return Anchor(page, Length() ); } // case 2: The reference is of form "src:1111Filename", where "1111" // points to line number 1111 in the file "Filename". KDVI then // looks for source specials of the form "src:xxxxFilename", and // tries to find the special with the biggest xxxx if (reference.indexOf("src:", 0, Qt::CaseInsensitive) == 0) { // Extract the file name and the numeral part from the reference string DVI_SourceFileSplitter splitter(reference, dviFile->filename); quint32 refLineNumber = splitter.line(); QString refFileName = splitter.filePath(); if (sourceHyperLinkAnchors.isEmpty()) {#if 0 KMessageBox::sorry(parentWidget, i18n("<qt>You have asked KDVI to locate the place in the DVI file which corresponds to " "line %1 in the TeX-file <strong>%2</strong>. It seems, however, that the DVI file " "does not contain the necessary source file information. " "We refer to the manual of KDVI for a detailed explanation on how to include this " "information. Press the F1 key to open the manual.</qt>", refLineNumber, refFileName), i18n("Could Not Find Reference"));#endif return Anchor(); } // Go through the list of source file anchors, and find the anchor // whose line number is the biggest among those that are smaller // than the refLineNumber. That way, the position in the DVI file // which is highlighted is always a little further up than the // position in the editor, e.g. if the DVI file contains // positional information at the beginning of every paragraph, // KDVI jumps to the beginning of the paragraph that the cursor is // in, and never to the next paragraph. If source file anchors for // the refFileName can be found, but none of their line numbers is // smaller than the refLineNumber, the reason is most likely, that // the cursor in the editor stands somewhere in the preamble of // the LaTeX file. In that case, we jump to the beginning of the // document. bool anchorForRefFileFound = false; // Flag that is set if source file anchors for the refFileName could be found at all QVector<DVI_SourceFileAnchor>::iterator bestMatch = sourceHyperLinkAnchors.end(); QVector<DVI_SourceFileAnchor>::iterator it; for( it = sourceHyperLinkAnchors.begin(); it != sourceHyperLinkAnchors.end(); ++it ) if (refFileName.trimmed() == it->fileName.trimmed() || refFileName.trimmed() == it->fileName.trimmed() + ".tex" ) { anchorForRefFileFound = true; if ( (it->line <= refLineNumber) && ( (bestMatch == sourceHyperLinkAnchors.end()) || (it->line > bestMatch->line) ) ) bestMatch = it; } if (bestMatch != sourceHyperLinkAnchors.end()) return Anchor(bestMatch->page, bestMatch->distance_from_top); else if (anchorForRefFileFound == false) {#if 0 KMessageBox::sorry(parentWidget, i18n("<qt>KDVI was not able to locate the place in the DVI file which corresponds to " "line %1 in the TeX-file <strong>%2</strong>.</qt>", refLineNumber, refFileName), i18n( "Could Not Find Reference" ));#endif } else return Anchor(); return Anchor(); } return Anchor();}void dviRenderer::setResolution(double resolution_in_DPI){ // Ignore minute changes. The difference to the current value would // hardly be visible anyway. That saves a lot of re-painting, // e.g. when the user resizes the window, and a flickery mouse // changes the window size by 1 pixel all the time. if (fabs(resolutionInDPI-resolution_in_DPI) < 1) return; resolutionInDPI = resolution_in_DPI; // Pass the information on to the font pool. font_pool.setDisplayResolution( resolutionInDPI ); shrinkfactor = 1200/resolutionInDPI; return;}void dviRenderer::clearStatusBar(){ //emit setStatusBarText( QString::null );}void dviRenderer::handleSRCLink(const QString &linkText, const QPoint& point, DocumentWidget *win){#if 0 KSharedPtr<DVISourceEditor> editor(new DVISourceEditor(*this, parentWidget, linkText, point, win)); if (editor->started()) editor_ = editor;#endif}QString dviRenderer::PDFencodingToQString(const QString& _pdfstring){ // This method locates special PDF characters in a string and // replaces them by UTF8. See Section 3.2.3 of the PDF reference // guide for information. QString pdfstring = _pdfstring; pdfstring = pdfstring.replace("\\n", "\n"); pdfstring = pdfstring.replace("\\r", "\n"); pdfstring = pdfstring.replace("\\t", "\t"); pdfstring = pdfstring.replace("\\f", "\f"); pdfstring = pdfstring.replace("\\(", "("); pdfstring = pdfstring.replace("\\)", ")"); pdfstring = pdfstring.replace("\\\\", "\\"); // Now replace octal character codes with the characters they encode int pos; QRegExp rx( "(\\\\)(\\d\\d\\d)" ); // matches "\xyz" where x,y,z are numbers while((pos = rx.indexIn( pdfstring )) != -1) { pdfstring = pdfstring.replace(pos, 4, QChar(rx.cap(2).toInt(0,8))); } rx.setPattern( "(\\\\)(\\d\\d)" ); // matches "\xy" where x,y are numbers while((pos = rx.indexIn( pdfstring )) != -1) { pdfstring = pdfstring.replace(pos, 3, QChar(rx.cap(2).toInt(0,8))); } rx.setPattern( "(\\\\)(\\d)" ); // matches "\x" where x is a number while((pos = rx.indexIn( pdfstring )) != -1) { pdfstring = pdfstring.replace(pos, 4, QChar(rx.cap(2).toInt(0,8))); } return pdfstring;}void dviRenderer::exportPDF(){#if 0 KSharedPtr<DVIExport> exporter(new DVIExportToPDF(*this, parentWidget)); if (exporter->started()) all_exports_[exporter.data()] = exporter;#endif}void dviRenderer::exportPS(const QString& fname, const QStringList& options, KPrinter* printer){#if 0 KSharedPtr<DVIExport> exporter(new DVIExportToPS(*this, parentWidget, fname, options, printer)); if (exporter->started()) all_exports_[exporter.data()] = exporter;#endif}#if 0void dviRenderer::update_info_dialog(const QString& text, bool clear){ if (clear) info->clear(text); else info->outputReceiver(text);}void dviRenderer::editor_finished(const DVISourceEditor*){ editor_.attach(0);}#endif#if 0void dviRenderer::export_finished(const DVIExport* key){ typedef QMap<const DVIExport*, KSharedPtr<DVIExport> > ExportMap; ExportMap::iterator it = all_exports_.find(key); if (it != all_exports_.end()) all_exports_.remove(key);}#endif#include "dviRenderer.moc"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?