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 + -
显示快捷键?