File indexing completed on 2024-05-12 16:06:36
0001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- 0002 // 0003 // Class: dviRenderer 0004 // 0005 // Class for rendering TeX DVI files. 0006 // Part of KDVI- A previewer for TeX DVI files. 0007 // 0008 // SPDX-FileCopyrightText: 2001-2006 Stefan Kebekus 0009 // SPDX-License-Identifier: GPL-2.0-or-later 0010 0011 #ifndef _dvirenderer_h_ 0012 #define _dvirenderer_h_ 0013 0014 #include "bigEndianByteReader.h" 0015 //#include "documentRenderer.h" 0016 #include "dviexport.h" 0017 //#include "dvisourceeditor.h" 0018 #include "anchor.h" 0019 #include "dviPageInfo.h" 0020 #include "fontpool.h" 0021 #include "pageSize.h" 0022 #include "prebookmark.h" 0023 0024 #include <QExplicitlySharedDataPointer> 0025 #include <QHash> 0026 #include <QMutex> 0027 #include <QPolygon> 0028 #include <QPrinter> 0029 #include <QProgressDialog> 0030 #include <QStack> 0031 #include <QTimer> 0032 #include <QUrl> 0033 #include <QVector> 0034 0035 class Anchor; 0036 class DocumentWidget; 0037 class dvifile; 0038 class dviRenderer; 0039 class ghostscript_interface; 0040 class QEventLoop; 0041 class QProgressDialog; 0042 class PreBookmark; 0043 class TeXFontDefinition; 0044 0045 extern const int MFResolutions[]; 0046 0047 class DVI_SourceFileAnchor 0048 { 0049 public: 0050 DVI_SourceFileAnchor() 0051 { 0052 } 0053 DVI_SourceFileAnchor(const QString &name, quint32 ln, quint32 pg, const Length _distance_from_top) 0054 : fileName(name) 0055 , line(ln) 0056 , page(pg) 0057 , distance_from_top(_distance_from_top) 0058 { 0059 } 0060 0061 QString fileName; 0062 quint32 line; 0063 quint32 page; 0064 Length distance_from_top; 0065 }; 0066 0067 /** Compound of registers, as defined in section 2.6.2 of the DVI 0068 driver standard, Level 0, published by the TUG DVI driver 0069 standards committee. */ 0070 0071 struct framedata { 0072 long dvi_h; 0073 long dvi_v; 0074 long w; 0075 long x; 0076 long y; 0077 long z; 0078 int pxl_v; 0079 }; 0080 0081 /* this information is saved when using virtual fonts */ 0082 0083 typedef void (dviRenderer::*set_char_proc)(unsigned int, unsigned int); 0084 typedef void (dviRenderer::*parseSpecials)(char *, quint8 *); 0085 0086 struct drawinf { 0087 struct framedata data; 0088 TeXFontDefinition *fontp; 0089 set_char_proc set_char_p; 0090 0091 QHash<int, TeXFontDefinition *> *fonttable; 0092 TeXFontDefinition *_virtual; 0093 }; 0094 0095 class dviRenderer : public QObject /*: public DocumentRenderer*/, bigEndianByteReader 0096 { 0097 Q_OBJECT 0098 0099 public: 0100 explicit dviRenderer(bool useFontHinting); 0101 ~dviRenderer() override; 0102 0103 virtual bool setFile(const QString &fname, const QUrl &base); 0104 0105 dvifile *dviFile; 0106 0107 virtual bool supportsTextSearch() const 0108 { 0109 return true; 0110 } 0111 0112 bool showPS() 0113 { 0114 return _postscript; 0115 } 0116 int curr_page() 0117 { 0118 return current_page + 1; 0119 } 0120 virtual bool isValidFile(const QString &fileName) const; 0121 0122 /** This method will try to parse the reference part of the DVI 0123 file's URL, (either a number, which is supposed to be a page 0124 number, or src:\<line\>\<filename\>) and see if a corresponding 0125 section of the DVI file can be found. If so, it returns an 0126 anchor to that section. If not, it returns an invalid anchor. */ 0127 virtual Anchor parseReference(const QString &reference); 0128 0129 Anchor findAnchor(const QString &); 0130 0131 virtual PageNumber totalPages() const; 0132 0133 void setEventLoop(QEventLoop *el); 0134 0135 // These should not be public... only for the moment 0136 void read_postamble(); 0137 void draw_part(double current_dimconv, bool is_vfmacro); 0138 void set_vf_char(unsigned int cmd, unsigned int ch); 0139 void set_char(unsigned int cmd, unsigned int ch); 0140 void set_empty_char(unsigned int cmd, unsigned int ch); 0141 void set_no_char(unsigned int cmd, unsigned int ch); 0142 void applicationDoSpecial(char *cp); 0143 0144 void special(long nbytes); 0145 void printErrorMsgForSpecials(const QString &msg); 0146 void color_special(const QString &msg); 0147 void html_href_special(const QString &msg); 0148 void html_anchor_end(); 0149 void draw_page(); 0150 void export_finished(const DVIExport *); 0151 // void editor_finished(const DVISourceEditor*); 0152 0153 QVector<PreBookmark> getPrebookmarks() const 0154 { 0155 return prebookmarks; 0156 } 0157 0158 Q_SIGNALS: 0159 /** 0160 * The following three signals are modeleed on the corresponding signals 0161 * of the Document class. 0162 */ 0163 void error(const QString &message, int duration); 0164 void warning(const QString &message, int duration); 0165 void notice(const QString &message, int duration); 0166 0167 public Q_SLOTS: 0168 void exportPS(const QString &fname = QString(), const QStringList &options = QStringList(), QPrinter *printer = nullptr, QPageLayout::Orientation orientation = QPageLayout::Portrait); 0169 void exportPDF(); 0170 0171 void handleSRCLink(const QString &linkText, const QPoint point, DocumentWidget *widget); 0172 0173 void embedPostScript(); 0174 0175 virtual void drawPage(RenderedDocumentPagePixmap *page); 0176 virtual void getText(RenderedDocumentPagePixmap *page); 0177 0178 SimplePageSize sizeOfPage(const PageNumber page); 0179 0180 const QVector<DVI_SourceFileAnchor> &sourceAnchors() 0181 { 0182 return sourceHyperLinkAnchors; 0183 } 0184 0185 private Q_SLOTS: 0186 /** This method shows a dialog that tells the user that source 0187 information is present, and gives the opportunity to open the 0188 manual and learn more about forward and inverse search */ 0189 // void showThatSourceInformationIsPresent(); 0190 0191 private: 0192 friend class DVIExportToPS; 0193 friend class DVIExport; 0194 // friend class DVISourceEditor; 0195 0196 /** URL to the DVI file 0197 This field is initialized by the setFile() method. See the 0198 explanation there. */ 0199 QUrl baseURL; 0200 0201 /** This method parses a color specification of type "gray 0.5", "rgb 0202 0.5 0.7 1.0", "hsb ...", "cmyk .." or "PineGreen". See the source 0203 code for details. */ 0204 QColor parseColorSpecification(const QString &colorSpec); 0205 0206 /** This map contains the colors which are known by name. This field 0207 is initialized in the method parseColorSpecification() as soon as 0208 it is needed. */ 0209 QMap<QString, QColor> namedColors; 0210 0211 /** This method locates special PDF characters in a string and 0212 replaces them by UTF8. See Section 3.2.3 of the PDF reference 0213 guide for information */ 0214 QString PDFencodingToQString(const QString &pdfstring); 0215 0216 void setResolution(double resolution_in_DPI); 0217 0218 fontPool font_pool; 0219 0220 double resolutionInDPI; 0221 0222 // @@@ explanation 0223 void prescan(parseSpecials specialParser); 0224 void prescan_embedPS(char *cp, quint8 *); 0225 void prescan_removePageSizeInfo(char *cp, quint8 *); 0226 void prescan_parseSpecials(char *cp, quint8 *); 0227 void prescan_ParsePapersizeSpecial(const QString &cp); 0228 void prescan_ParseBackgroundSpecial(const QString &cp); 0229 void prescan_ParseHTMLAnchorSpecial(const QString &cp); 0230 void prescan_ParsePSHeaderSpecial(const QString &cp); 0231 void prescan_ParsePSBangSpecial(const QString &cp); 0232 void prescan_ParsePSQuoteSpecial(const QString &cp); 0233 void prescan_ParsePSSpecial(const QString &cp); 0234 void prescan_ParsePSFileSpecial(const QString &cp); 0235 void prescan_ParseSourceSpecial(QStringView cp); 0236 void prescan_setChar(unsigned int ch); 0237 0238 /* */ 0239 QVector<PreBookmark> prebookmarks; 0240 0241 /** Utility fields used by the embedPostScript method*/ 0242 QProgressDialog *embedPS_progress; 0243 quint16 embedPS_numOfProgressedFiles; 0244 0245 /** Shrink factor. Units are not quite clear */ 0246 double shrinkfactor; 0247 0248 QString errorMsg; 0249 0250 /** Methods which handle certain special commands. */ 0251 void epsf_special(const QString &cp); 0252 void source_special(const QString &cp); 0253 0254 /** TPIC specials */ 0255 void TPIC_setPen_special(const QString &cp); 0256 void TPIC_addPath_special(const QString &cp); 0257 void TPIC_flushPath_special(); 0258 0259 // List of source-hyperlinks on all pages. This vector is generated 0260 // when the DVI-file is first loaded, i.e. when draw_part is called 0261 // with PostScriptOutPutString != NULL 0262 QVector<DVI_SourceFileAnchor> sourceHyperLinkAnchors; 0263 0264 // If not NULL, the text currently drawn represents a source 0265 // hyperlink to the (relative) URL given in the string; 0266 QString *source_href; 0267 0268 // If not NULL, the text currently drawn represents a hyperlink to 0269 // the (relative) URL given in the string; 0270 QString *HTML_href; 0271 0272 QString editorCommand; 0273 0274 /** Stack for register compounds, used for the DVI-commands PUSH/POP 0275 as explained in section 2.5 and 2.6.2 of the DVI driver standard, 0276 Level 0, published by the TUG DVI driver standards committee. */ 0277 QStack<framedata> stack; 0278 0279 /** A stack where color are stored, according to the documentation of 0280 DVIPS */ 0281 QStack<QColor> colorStack; 0282 0283 /** The global color is to be used when the color stack is empty */ 0284 QColor globalColor; 0285 0286 /** If PostScriptOutPutFile is non-zero, then no rendering takes 0287 place. Instead, the PostScript code which is generated by the 0288 \special-commands is written to the PostScriptString */ 0289 QString *PostScriptOutPutString; 0290 0291 ghostscript_interface *PS_interface; 0292 0293 /** true, if gs should be used, otherwise, only bounding boxes are 0294 drawn. */ 0295 bool _postscript; 0296 0297 /** This flag is used when rendering a dvi-page. It is set to "true" 0298 when any dvi-command other than "set" or "put" series of commands 0299 is encountered. This is considered to mark the end of a word. */ 0300 bool line_boundary_encountered; 0301 bool word_boundary_encountered; 0302 0303 unsigned int current_page; 0304 0305 /** Data required for handling TPIC specials */ 0306 float penWidth_in_mInch; 0307 QPolygon TPIC_path; 0308 quint16 number_of_elements_in_path; 0309 0310 drawinf currinf; 0311 RenderedDocumentPagePixmap *currentlyDrawnPage; 0312 QMap<const DVIExport *, QExplicitlySharedDataPointer<DVIExport>> all_exports_; 0313 // QExplicitlySharedDataPointer<DVISourceEditor> editor_; 0314 0315 /** Flag if document is modified 0316 0317 This flag indicates if the document was modified after it was 0318 loaded. It is set to 'false' in the constructor, in the clear() and 0319 setFile() method. It can be set to 'true' be methods that modify the 0320 document (e.g. the deletePages() method of the djvu implementation 0321 of this class). 0322 */ 0323 bool _isModified; 0324 0325 QMutex mutex; 0326 quint16 numPages; 0327 0328 // TODO: merge into dviPageInfo 0329 QVector<SimplePageSize> pageSizes; 0330 0331 QMap<QString, Anchor> anchorList; 0332 0333 QEventLoop *m_eventLoop; 0334 0335 QPainter *foreGroundPainter; 0336 0337 // was the locateFonts method of font pool executed? 0338 bool fontpoolLocateFontsDone; 0339 }; 0340 0341 #endif