From 76b8ec2c0d77737e11762ec8ad59e477b509d0a9 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Mon, 28 Dec 2015 23:25:11 +0000 Subject: dvisvgm-1.14 git-svn-id: svn://tug.org/texlive/trunk@39217 c570f23f-e606-0410-a88d-b1316a301751 --- .../texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp | 50 ++++++------- .../source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h | 7 +- .../dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp | 7 ++ .../texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h | 1 + .../source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.h | 1 + .../texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp | 11 ++- .../texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h | 31 ++++---- .../dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp | 5 +- .../texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h | 2 +- .../dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp | 85 +++++++++++++++++----- .../texk/dvisvgm/dvisvgm-src/src/SpecialActions.h | 2 + .../texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp | 2 +- 12 files changed, 135 insertions(+), 69 deletions(-) (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src') diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp index 00becb10aeb..8ade555ad06 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp @@ -167,15 +167,21 @@ void DVIToSVG::endPage (unsigned pageno) { Matrix matrix; getPageTransformation(matrix); static_cast(getActions())->setPageMatrix(matrix); - if (_bboxString == "min") + if (_bboxFormatString == "min" || _bboxFormatString == "preview") bbox.transform(matrix); - if (string("dvi none min").find(_bboxString) == string::npos) { - istringstream iss(_bboxString); + else if (_bboxFormatString == "dvi") { + // center page content + double dx = (getPageWidth()-bbox.width())/2; + double dy = (getPageHeight()-bbox.height())/2; + bbox += BoundingBox(-dx, -dy, dx, dy); + } + else if (_bboxFormatString != "none") { + istringstream iss(_bboxFormatString); StreamInputReader ir(iss); ir.skipSpace(); if (isalpha(ir.peek())) { // set explicitly given page format - PageSize size(_bboxString); + PageSize size(_bboxFormatString); if (size.valid()) { // convention: DVI position (0,0) equals (1in, 1in) relative // to the upper left vertex of the page (see DVI specification) @@ -185,33 +191,25 @@ void DVIToSVG::endPage (unsigned pageno) { } else { // set/modify bounding box by explicitly given values try { - bbox.set(_bboxString); + bbox.set(_bboxFormatString); } catch (const MessageException &e) { } } } - else if (_bboxString == "dvi") { - // center page content - double dx = (getPageWidth()-bbox.width())/2; - double dy = (getPageHeight()-bbox.height())/2; - bbox += BoundingBox(-dx, -dy, dx, dy); - } - if (_bboxString != "none") { - if (bbox.width() == 0) - Message::wstream(false) << "\npage is empty\n"; - else { - _svg.setBBox(bbox); - - const double bp2pt = 72.27/72; - const double bp2mm = 25.4/72; - Message::mstream(false) << '\n'; - Message::mstream(false, Message::MC_PAGE_SIZE) << "page size: " << XMLString(bbox.width()*bp2pt) << "pt" - " x " << XMLString(bbox.height()*bp2pt) << "pt" - " (" << XMLString(bbox.width()*bp2mm) << "mm" - " x " << XMLString(bbox.height()*bp2mm) << "mm)"; - Message::mstream(false) << '\n'; - } + if (bbox.width() == 0) + Message::wstream(false) << "\npage is empty\n"; + if (_bboxFormatString != "none") { + _svg.setBBox(bbox); + + const double bp2pt = 72.27/72; + const double bp2mm = 25.4/72; + Message::mstream(false) << '\n'; + Message::mstream(false, Message::MC_PAGE_SIZE) << "page size: " << XMLString(bbox.width()*bp2pt) << "pt" + " x " << XMLString(bbox.height()*bp2pt) << "pt" + " (" << XMLString(bbox.width()*bp2mm) << "mm" + " x " << XMLString(bbox.height()*bp2mm) << "mm)"; + Message::mstream(false) << '\n'; } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h index 9e3f5d659ca..9e6019acfc7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h @@ -37,10 +37,11 @@ class DVIToSVG : public DVIReader DVIToSVG (std::istream &is, SVGOutputBase &out); ~DVIToSVG (); void convert (const std::string &range, std::pair *pageinfo=0); - void setPageSize (const std::string &name) {_bboxString = name;} + void setPageSize (const std::string &format) {_bboxFormatString = format;} void setPageTransformation (const std::string &cmds) {_transCmds = cmds;} void getPageTransformation (Matrix &matrix) const; std::string getSVGFilename (unsigned pageno) const; + std::string getUserBBoxString () const {return _bboxFormatString;} static void setProcessSpecials (const char *ignorelist=0, bool pswarning=false); public: @@ -56,8 +57,8 @@ class DVIToSVG : public DVIReader private: SVGTree _svg; SVGOutputBase &_out; - std::string _bboxString; - std::string _transCmds; + std::string _bboxFormatString; ///< bounding box size/format set by the user + std::string _transCmds; ///< page transformation commands set by the user }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp index 911ff62eb6c..a709a52a8bd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp @@ -84,6 +84,13 @@ string DVIToSVGActions::getSVGFilename (unsigned pageno) const { } +string DVIToSVGActions::getBBoxFormatString () const { + if (DVIToSVG *dvi2svg = dynamic_cast(_dvireader)) + return dvi2svg->getUserBBoxString(); + return ""; +} + + /** This method is called when a "set char" command was found in the DVI file. * It draws a character of the current font. * @param[in] x horizontal position of left bounding box edge diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h index 0ed9c2ce54d..2c0712e61e7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h @@ -84,6 +84,7 @@ class DVIToSVGActions : public DVIActions, public SpecialActions void embed (const BoundingBox &bbox); void embed (const DPair &p, double r=0); std::string getSVGFilename (unsigned pageno) const; + std::string getBBoxFormatString () const; private: SVGTree &_svg; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.h index 841ffe5d0a9..f6f69c1823e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.h @@ -60,6 +60,7 @@ class EPSToSVG : protected SpecialActions BoundingBox& bbox () {return _bbox;} BoundingBox& bbox (const std::string &name, bool reset=false) {return _bbox;} std::string getSVGFilename (unsigned pageno) const; + std::string getBBoxFormatString () const {return "";} private: std::string _fname; ///< name of EPS file diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp index 2418c8fb786..0c3ea270add 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp @@ -115,7 +115,9 @@ std::string FileFinder::version () { } #else if (const char *v = strrchr(KPSEVERSION, ' ')) - return v+1; + return (std::string(KPSEVERSION).substr(0, 9) == "kpathsea ") ? v+1 : KPSEVERSION; + if (strlen(KPSEVERSION) > 0) + return KPSEVERSION; #endif return "unknown"; } @@ -130,6 +132,12 @@ static const char* find_file (const std::string &fname, const char *ftype) { if (!_initialized || fname.empty()) return 0; + static std::string buf; + // try to lookup the file in the current working directory + buf = FileSystem::getcwd()+"/"+fname; + if (FileSystem::exists(buf.c_str())) + return buf.c_str(); + std::string ext; if (ftype) ext = ftype; @@ -140,7 +148,6 @@ static const char* find_file (const std::string &fname, const char *ftype) { ext = fname.substr(pos+1); } - static std::string buf; #ifdef MIKTEX if (ext == "dll" || ext == "exe") { // lookup dll and exe files in the MiKTeX bin directory first diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h index 59b91ae6f3b..fa30a512673 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h @@ -191,22 +191,23 @@ class GraphicsPath } - /** Removes redundant path commands commands. Currently, it only removes movetos. */ - void removeRedundantCommands () { - // remove trailing moveto commands - while (_commands.back().type == Command::MOVETO) - _commands.pop_back(); - // resolve intermediate sequences of moveto commands - Iterator it=_commands.begin(); - if (it == _commands.end()) - return; - Iterator prev = it; - for (++it; it != _commands.end(); ++it) { - if (prev->type == Command::MOVETO && it->type == Command::MOVETO) + /** Removes redundant path commands commands. Currently, it only removes movetos. */ + void removeRedundantCommands () { + // remove trailing moveto commands + while (!_commands.empty() && _commands.back().type == Command::MOVETO) + _commands.pop_back(); + // resolve intermediate sequences of moveto commands + Iterator it=_commands.begin(); + if (it == _commands.end()) + return; + Iterator prev = it++; + while (it != _commands.end()) { + if (prev->type == Command::MOVETO && it->type == Command::MOVETO) _commands.erase(prev); - prev = it; - } - } + else + prev = it++; + } + } /** Writes the path data as SVG path drawing command to a given output stream. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp index 5029874c681..9994520e723 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp @@ -64,6 +64,9 @@ void PSPreviewFilter::execute (const char *code, size_t len) { if (!_tightpage) psInterpreter().execute(code, len); else { + // Read bounding box information pushed on the operand stack by the preview package. + // It consists of 7 values in DVI units: + // llx, lly, urx, ury, height, depth, width CharInputBuffer ib(code, len); BufferInputReader ir(ib); ir.skipSpace(); @@ -87,7 +90,7 @@ bool PSPreviewFilter::getBoundingBox (BoundingBox &bbox) const { } -/** Gets the 4 border values set by the preview package. +/** Gets the 4 border position values set by the preview package (in bp units). * @return true if the border data is available */ bool PSPreviewFilter::getBorders (double &left, double &right, double &top, double &bottom) const { if (_boxExtents.size() < 4) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h index 3e9f9ad2052..fdc4a48b9e9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h @@ -50,7 +50,7 @@ class PSPreviewFilter : public PSFilter bool _active; ///< true if filter is active bool _tightpage; ///< true if tightpage option was given double _dvi2bp; ///< factor to convert dvi units to PS points - std::vector _boxExtents; + std::vector _boxExtents; ///< bounding box data set by the preview package (in DVI units) }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index 175a7b065b6..a712603dc89 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -199,7 +199,7 @@ bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions if (_psSection != PS_BODY) enterBodySection(); - if (*prefix == '"') { + if (*prefix == '"' || strcmp(prefix, "pst:") == 0) { // read and execute literal PostScript code (isolated by a wrapping save/restore pair) moveToDVIPos(); _psi.execute("\n@beginspecial @setspecial "); @@ -242,7 +242,7 @@ bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions executeAndSync(is, true); } } - else { // ps: ... + else { // ps: ... or PST: ... if (_actions) _actions->finishLine(); moveToDVIPos(); @@ -383,29 +383,74 @@ static bool transform_box_extents (const Matrix &matrix, double &w, double &h, d void PsSpecialHandler::dviEndPage (unsigned) { BoundingBox bbox; - if (_previewFilter.getBoundingBox(bbox)) { - double w = _previewFilter.width(); - double h = _previewFilter.height(); - double d = _previewFilter.depth(); - bool horiz_baseline = true; - if (_actions) { - _actions->bbox() = bbox; + if (_previewFilter.getBoundingBox(bbox)) { // is there any data written by preview package? + double w = max(0.0, _previewFilter.width()); + double h = max(0.0, _previewFilter.height()); + double d = max(0.0, _previewFilter.depth()); + bool isBaselineHorizontal = true; + if (_actions && (_actions->getBBoxFormatString() == "preview" || _actions->getBBoxFormatString() == "min")) { + if (_actions->getBBoxFormatString() == "preview") { + _actions->bbox() = bbox; + Message::mstream() << "\napplying bounding box set by"; + } + else { + // compute height, depth and width depending on the + // tight bounding box derived from the objects on the page + double y0 = bbox.maxY()-h; // y coordinate of the baseline + h = _actions->bbox().maxY()-y0; + if (h < 0) { + h = 0; + d = _actions->bbox().height(); + } + else { + d = y0-_actions->bbox().minY(); + if (d < 0) { + h = _actions->bbox().height(); + d = 0; + } + } + w = _actions->bbox().width(); + Message::mstream() << "\ncomputing extents based on data set by"; + } + Message::mstream() << " preview package (version " << _previewFilter.version() << ")\n"; + // apply page transformations to box extents Matrix pagetrans; _actions->getPageTransform(pagetrans); - horiz_baseline = transform_box_extents(pagetrans, w, h, d); + isBaselineHorizontal = transform_box_extents(pagetrans, w, h, d); _actions->bbox().lock(); + + if (isBaselineHorizontal) { + const double bp2pt = 72.27/72.0; + Message::mstream() << + "width=" << XMLString(w*bp2pt) << "pt, " + "height=" << XMLString(h*bp2pt) << "pt, " + "depth=" << XMLString(d*bp2pt) << "pt\n"; + } + else + Message::mstream() << "can't determine height, width, and depth due to non-horizontal baseline\n"; } - Message::mstream() << "\napplying bounding box set by preview package (version " << _previewFilter.version() << ")\n"; - if (horiz_baseline) { - const double bp2pt = 72.27/72.0; - Message::mstream() << - "width=" << XMLString(w*bp2pt) << "pt, " - "height=" << XMLString(h*bp2pt) << "pt, " - "depth=" << XMLString(d*bp2pt) << "pt\n"; +#if 0 + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", _actions->bbox().minX()); + rect->addAttribute("y", _actions->bbox().minY()); + rect->addAttribute("width", w); + rect->addAttribute("height", h+d); + rect->addAttribute("fill", "none"); + rect->addAttribute("stroke", "red"); + rect->addAttribute("stroke-width", "0.5"); + _actions->appendToPage(rect); + if (d > 0) { + XMLElementNode *line = new XMLElementNode("line"); + line->addAttribute("x1", _actions->bbox().minX()); + line->addAttribute("y1", _actions->bbox().minY()+h); + line->addAttribute("x2", _actions->bbox().maxX()); + line->addAttribute("y2", _actions->bbox().minY()+h); + line->addAttribute("stroke", "blue"); + line->addAttribute("stroke-width", "0.5"); + _actions->appendToPage(line); } - else - Message::mstream() << "can't determine height, width, and depth due to non-horizontal baseline\n"; +#endif } // close dictionary TeXDict and execute end-hook if defined if (_psSection == PS_BODY) { @@ -1189,6 +1234,6 @@ void PsSpecialHandler::ClippingStack::dup (int saveID) { const char** PsSpecialHandler::prefixes () const { - static const char *pfx[] = {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\"", 0}; + static const char *pfx[] = {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\"", "pst:", "PST:", 0}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h index e0f35c78738..81faba9a6fc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h @@ -55,6 +55,7 @@ struct SpecialActions virtual void embed (const DPair &p, double r=0) =0; virtual unsigned getCurrentPageNumber () const =0; virtual std::string getSVGFilename (unsigned pageno) const =0; + virtual std::string getBBoxFormatString () const =0; virtual void progress (const char *id) {} virtual int getDVIStackDepth () const {return 0;} @@ -87,6 +88,7 @@ class EmptySpecialActions : public SpecialActions void embed (const DPair &p, double r=0) {} unsigned getCurrentPageNumber() const {return 0;} std::string getSVGFilename (unsigned pageno) const {return "";} + std::string getBBoxFormatString () const {return "";} private: BoundingBox _bbox; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index db0dd86fd69..8b809111f45 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -134,7 +134,7 @@ static bool set_cache_dir (const CommandLine &args) { static bool check_bbox (const string &bboxstr) { - const char *formats[] = {"none", "min", "dvi", 0}; + const char *formats[] = {"none", "min", "preview", "dvi", 0}; for (const char **p=formats; *p; ++p) if (bboxstr == *p) return true; -- cgit v1.2.3