📄 special.cpp.svn-base
字号:
parse_special_argument(include_command, "rwi=", &rwi); parse_special_argument(include_command, "rhi=", &rhi); parse_special_argument(include_command, "angle=", &angle); // If we have a png, gif, jpeg or mng file, we need to draw it here. KMimeType::Ptr const mime_type = KMimeType::findByFileContent(EPSfilename); QString const & mime_type_name = mime_type?mime_type->name():""; bool const isGFX = (mime_type_name == "image/png" || mime_type_name == "image/gif" || mime_type_name == "image/jpeg" || mime_type_name == "video/x-mng"); // So, if we do not have a PostScript file, but a graphics file, and // if that file exists, we draw it here. if (isGFX && 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; } double fontPixelPerDVIunit = dviFile->getCmPerDVIunit() * 1200.0/2.54; bbox_width *= 0.1 * 65536.0*fontPixelPerDVIunit / shrinkfactor; bbox_height *= 0.1 * 65536.0*fontPixelPerDVIunit / shrinkfactor; QImage image(EPSfilename); image = image.scaled((int)(bbox_width), (int)(bbox_height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); foreGroundPainter->drawImage( ((int) ((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - (int)bbox_height, image); return; } 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; } double fontPixelPerDVIunit = dviFile->getCmPerDVIunit() * 1200.0/2.54; bbox_width *= 0.1 * 65536.0*fontPixelPerDVIunit / shrinkfactor; bbox_height *= 0.1 * 65536.0*fontPixelPerDVIunit / shrinkfactor; QRect bbox(((int) ((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - (int)bbox_height, (int)bbox_width, (int)bbox_height); foreGroundPainter->save(); if (QFile::exists(EPSfilename)) foreGroundPainter->setBrush(Qt::lightGray); else foreGroundPainter->setBrush(Qt::red); foreGroundPainter->setPen(Qt::black); foreGroundPainter->drawRoundRect(bbox, 2, 2); QFont f = foreGroundPainter->font(); f.setPointSize(8); foreGroundPainter->setFont(f); if (QFile::exists(EPSfilename)) foreGroundPainter->drawText (bbox, (int)(Qt::AlignCenter), EPSfilename); else foreGroundPainter->drawText (bbox, (int)(Qt::AlignCenter), i18n("File not found: \n %1", EPSfilename_orig)); foreGroundPainter->restore(); } return;}void dviRenderer::TPIC_flushPath_special(){#ifdef DEBUG_SPECIAL kDebug(kvs::dvi) << "TPIC special flushPath" << endl;#endif if (number_of_elements_in_path == 0) { printErrorMsgForSpecials("TPIC special flushPath called when path was empty."); return; } QPen pen(Qt::black, (int)(penWidth_in_mInch*resolutionInDPI/1000.0 + 0.5)); // Sets the pen size in milli-inches foreGroundPainter->setPen(pen); foreGroundPainter->drawPolyline(TPIC_path.constData(), number_of_elements_in_path); number_of_elements_in_path = 0;}void dviRenderer::TPIC_addPath_special(const QString& cp){#ifdef DEBUG_SPECIAL kDebug(kvs::dvi) << "TPIC special addPath: " << cp << endl;#endif // Adds a point to the path list QString cp_noWhiteSpace = cp.trimmed(); bool ok; float xKoord = cp_noWhiteSpace.section(' ', 0, 0).toFloat(&ok); if (ok == false) { printErrorMsgForSpecials( QString("TPIC special; cannot parse first argument in 'pn %1'.").arg(cp) ); return; } float yKoord = cp_noWhiteSpace.section(' ', 1, 1).toFloat(&ok); if (ok == false) { printErrorMsgForSpecials( QString("TPIC special; cannot parse second argument in 'pn %1'.").arg(cp) ); return; } float mag = dviFile->getMagnification()/1000.0; int x = (int)( currinf.data.dvi_h/(shrinkfactor*65536.0) + mag*xKoord*resolutionInDPI/1000.0 + 0.5 ); int y = (int)( currinf.data.pxl_v + mag*yKoord*resolutionInDPI/1000.0 + 0.5 ); // Initialize the point array used to store the path if (TPIC_path.size() == 0) number_of_elements_in_path = 0; if (TPIC_path.size() == number_of_elements_in_path) TPIC_path.resize(number_of_elements_in_path+100); TPIC_path.setPoint(number_of_elements_in_path++, x, y);}void dviRenderer::TPIC_setPen_special(const QString& cp){#ifdef DEBUG_SPECIAL kDebug(kvs::dvi) << "TPIC special setPen: " << cp << endl;#endif // Sets the pen size in milli-inches bool ok; penWidth_in_mInch = cp.trimmed().toFloat(&ok); if (ok == false) { printErrorMsgForSpecials( QString("TPIC special; cannot parse argument in 'pn %1'.").arg(cp) ); penWidth_in_mInch = 0.0; return; }}void dviRenderer::applicationDoSpecial(char *cp){ QString special_command(cp); // First come specials which is only interpreted during rendering, // and NOT during the prescan phase // font color specials if (strncasecmp(cp, "color", 5) == 0) { color_special(special_command.mid(5)); return; } // HTML reference if (strncasecmp(cp, "html:<A href=", 13) == 0) { html_href_special(special_command.mid(14)); return; } // HTML anchor end if (strncasecmp(cp, "html:</A>", 9) == 0) { html_anchor_end(); return; } // TPIC specials if (strncasecmp(cp, "pn", 2) == 0) { TPIC_setPen_special(special_command.mid(2)); return; } if (strncasecmp(cp, "pa ", 3) == 0) { TPIC_addPath_special(special_command.mid(3)); return; } if (strncasecmp(cp, "fp", 2) == 0) { TPIC_flushPath_special(); return; } // Encapsulated Postscript File if (strncasecmp(cp, "PSfile=", 7) == 0) { epsf_special(special_command.mid(7)); return; } // source special if (strncasecmp(cp, "src:", 4) == 0) { source_special(special_command.mid(4)); return; } // Unfortunately, in some TeX distribution the hyperref package uses // the dvips driver by default, rather than the hypertex driver. As // a result, the DVI files produced are full of PostScript that // specifies links and anchors, and KDVI would call the ghostscript // interpreter for every page which makes it really slow. This is a // major nuisance, so that we try to filter and interpret the // hypertex generated PostScript here. if (special_command.startsWith("ps:SDict begin")) { // Hyperref: start of hyperref rectangle. At this stage it is not // yet clear if the rectangle will conain a hyperlink, an anchor, // or another type of object. We suspect that this rectangle will // define a hyperlink, allocate a QString and set HTML_href to // point to this string. The string contains the name of the // destination which ---due to the nature of the PostScript // language--- will be defined only after characters are drawn and // the hyperref rectangle has been closed. We use "glopglyph" as a // temporary name. Since the pointer HTML_href is not NULL, the // chracter drawing routines will now underline all characters in // blue to point out that they correspond to a hyperlink. Also, as // soon as characters are drawn, the drawing routines will // allocate a Hyperlink and add it to the top of the vector // currentlyDrawnPage->hyperLinkList. if (special_command == "ps:SDict begin H.S end") { // At this stage, the vector 'hyperLinkList' should not contain // links with unspecified destinations (i.e. destination set to // 'glopglyph'). As a protection against bad DVI files, we make // sure to remove all link rectangles which point to // 'glopglyph'. while (!currentlyDrawnPage->hyperLinkList.isEmpty()) if (currentlyDrawnPage->hyperLinkList.last().linkText == "glopglyph") currentlyDrawnPage->hyperLinkList.pop_back(); else break; HTML_href = new QString("glopglyph"); return; } // Hyperref: end of hyperref rectangle of unknown type or hyperref // link rectangle. In these cases we set HTML_href to NULL, which // causes the character drawing routines to stop drawing // characters underlined in blue. Note that the name of the // destination is still set to "glopglyph". In a well-formed DVI // file, this special command is immediately followed by another // special, where the destination is specified. This special is // treated below. if ((special_command == "ps:SDict begin H.R end") || special_command.endsWith("H.L end")) { if (HTML_href != NULL) { delete HTML_href; HTML_href = NULL; } return; // end of hyperref rectangle } // Hyperref: end of anchor rectangle. If this special is // encountered, the rectangle, which was started with "ps:SDict // begin H.S end" does not contain a link, but an anchor for a // link. Anchors, however, have already been dealt with in the // prescan phase and will not be considered here. Thus, we set // HTML_href to NULL so that character drawing routines will no // longer underline hyperlinks in blue, and remove the link from // the hyperLinkList. NOTE: in a well-formed DVI file, the "H.A" // special comes directly after the "H.S" special. A // hyperlink-anchor rectangle therefore never contains characters, // so no character will by accidentally underlined in blue. if (special_command.endsWith("H.A end")) { if (HTML_href != NULL) { delete HTML_href; HTML_href = NULL; } while (!currentlyDrawnPage->hyperLinkList.isEmpty()) if (currentlyDrawnPage->hyperLinkList.last().linkText == "glopglyph") currentlyDrawnPage->hyperLinkList.pop_back(); else break; return; // end of hyperref anchor } // Hyperref: specification of a hyperref link rectangle's // destination. As mentioned above, the destination of a hyperlink // is specified only AFTER the rectangle has been specified. We // will therefore go through the list of rectangles stored in // currentlyDrawnPage->hyperLinkList, find those whose destination // is open and fill in the value found here. NOTE: the character // drawing routines sometimes split a single hyperlink rectangle // into several rectangles (e.g. if the font changes, or when a // line break is encountered) if (special_command.startsWith("ps:SDict begin [") && special_command.endsWith(" pdfmark end")) { if (!currentlyDrawnPage->hyperLinkList.isEmpty()) { QString targetName = special_command.section('(', 1, 1).section(')', 0, 0); QVector<Hyperlink>::iterator it; for( it = currentlyDrawnPage->hyperLinkList.begin(); it != currentlyDrawnPage->hyperLinkList.end(); ++it ) if (it->linkText == "glopglyph") it->linkText = targetName; } return; // hyperref definition of link/anchor/bookmark/etc } } // Detect text rotation specials that are included by the graphicx // package. If one of these specials is found, the state of the // painter is saved, and the coordinate system is rotated // accordingly if (special_command.startsWith("ps: gsave currentpoint currentpoint translate ") && special_command.endsWith(" neg rotate neg exch neg exch translate") ) { bool ok; double angle = special_command.section(' ', 5, 5).toDouble(&ok); if (ok == true) { int x = ((int) ((currinf.data.dvi_h) / (shrinkfactor * 65536))); int y = currinf.data.pxl_v; foreGroundPainter->save(); // Rotate about the current point foreGroundPainter->translate(x,y); foreGroundPainter->rotate(-angle); foreGroundPainter->translate(-x,-y); } else printErrorMsgForSpecials( i18n("Error in DVIfile '%1', page %2. Could not interpret angle in text rotation special." , dviFile->filename, current_page)); } // The graphicx package marks the end of rotated text with this // special. The state of the painter is restored. if (special_command == "ps: currentpoint grestore moveto") { foreGroundPainter->restore(); } // The following special commands are not used here; they are of // interest only during the prescan phase. We recognize them here // anyway, to make sure that KDVI doesn't complain about // unrecognized special commands. if ((cp[0] == '!') || (cp[0] == '"') || (strncasecmp(cp, "html:<A name=", 13) == 0) || (strncasecmp(cp, "ps:", 3) == 0) || (strncasecmp(cp, "papersize", 9) == 0) || (strncasecmp(cp, "header", 6) == 0) || (strncasecmp(cp, "background", 10) == 0) ) return; printErrorMsgForSpecials(i18n("The special command '%1' is not implemented.", special_command)); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -