diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-1.9.2/src/dvisvgm.cpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-1.9.2/src/dvisvgm.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.9.2/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.9.2/src/dvisvgm.cpp new file mode 100644 index 00000000000..02ba1ae4cf9 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-1.9.2/src/dvisvgm.cpp @@ -0,0 +1,334 @@ +/************************************************************************* +** dvisvgm.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2015 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** This program is free software; you can redistribute it and/or ** +** modify it under the terms of the GNU General Public License as ** +** published by the Free Software Foundation; either version 3 of ** +** the License, or (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, but ** +** WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program; if not, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <config.h> +#include <clipper.hpp> +#include <fstream> +#include <iostream> +#include <sstream> +#include <string> +#include "gzstream.h" +#include "CommandLine.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "EPSToSVG.h" +#include "FileFinder.h" +#include "FilePath.h" +#include "FileSystem.h" +#include "Font.h" +#include "FontCache.h" +#include "FontEngine.h" +#include "FontMap.h" +#include "Ghostscript.h" +#include "HtmlSpecialHandler.h" +#include "InputReader.h" +#include "Message.h" +#include "PageSize.h" +#include "PSInterpreter.h" +#include "PsSpecialHandler.h" +#include "SignalHandler.h" +#include "SpecialManager.h" +#include "SVGOutput.h" +#include "System.h" + +#ifdef __MSVC__ +#include <potracelib.h> +#else +extern "C" { +#include <potracelib.h> +} +#endif + +using namespace std; + + +//////////////////////////////////////////////////////////////////////////////// + +static void show_help (const CommandLine &cmd) { + cout << PACKAGE_STRING "\n\n"; + cmd.help(cmd.help_arg()); + cout << "\nCopyright (C) 2005-2015 Martin Gieseking <martin.gieseking@uos.de> \n\n"; +} + + +static string remove_path (string fname) { + fname = FileSystem::adaptPathSeperators(fname); + size_t slashpos = fname.rfind('/'); + if (slashpos == string::npos) + return fname; + return fname.substr(slashpos+1); +} + + +static string ensure_suffix (string fname, bool eps) { + size_t dotpos = remove_path(fname).rfind('.'); + if (dotpos == string::npos) + fname += (eps ? ".eps" : ".dvi"); + return fname; +} + + +static string get_transformation_string (const CommandLine &args) { + ostringstream oss; + if (args.rotate_given()) + oss << 'R' << args.rotate_arg() << ",w/2,h/2"; + if (args.translate_given()) + oss << 'T' << args.translate_arg(); + if (args.scale_given()) + oss << 'S' << args.scale_arg(); + if (args.transform_given()) + oss << args.transform_arg(); + return oss.str(); +} + + +static void set_libgs (CommandLine &args) { +#if !defined(DISABLE_GS) && !defined(HAVE_LIBGS) + if (args.libgs_given()) + Ghostscript::LIBGS_NAME = args.libgs_arg(); + else if (getenv("LIBGS")) + Ghostscript::LIBGS_NAME = getenv("LIBGS"); +#endif +} + + +static bool set_cache_dir (const CommandLine &args) { + if (args.cache_given() && !args.cache_arg().empty()) { + if (args.cache_arg() == "none") + PhysicalFont::CACHE_PATH = 0; + else if (FileSystem::exists(args.cache_arg().c_str())) + PhysicalFont::CACHE_PATH = args.cache_arg().c_str(); + else + Message::wstream(true) << "cache directory '" << args.cache_arg() << "' does not exist (caching disabled)\n"; + } + else if (const char *userdir = FileSystem::userdir()) { + static string cachepath = userdir + string("/.dvisvgm/cache"); + if (!FileSystem::exists(cachepath.c_str())) + FileSystem::mkdir(cachepath.c_str()); + PhysicalFont::CACHE_PATH = cachepath.c_str(); + } + if (args.cache_given() && args.cache_arg().empty()) { + cout << "cache directory: " << (PhysicalFont::CACHE_PATH ? PhysicalFont::CACHE_PATH : "(none)") << '\n'; + FontCache::fontinfo(PhysicalFont::CACHE_PATH, cout, true); + return false; + } + return true; +} + + +static bool check_bbox (const string &bboxstr) { + const char *formats[] = {"none", "min", "dvi", 0}; + for (const char **p=formats; *p; ++p) + if (bboxstr == *p) + return true; + if (isalpha(bboxstr[0])) { + try { + PageSize size(bboxstr); + return true; + } + catch (const PageSizeException &e) { + Message::estream(true) << "invalid bounding box format '" << bboxstr << "'\n"; + return false; + } + } + try { + BoundingBox bbox; + bbox.set(bboxstr); + return true; + } + catch (const MessageException &e) { + Message::estream(true) << e.what() << '\n'; + return false; + } +} + + +static void print_version (bool extended) { + ostringstream oss; + oss << PACKAGE_STRING; + if (extended) { + if (strlen(TARGET_SYSTEM) > 0) + oss << " (" TARGET_SYSTEM ")"; + int len = oss.str().length(); + oss << "\n" << string(len, '-') << "\n" + "clipper: " << CLIPPER_VERSION "\n" + "freetype: " << FontEngine::version() << "\n"; + + Ghostscript gs; + string gsver = gs.revision(true); + if (!gsver.empty()) + oss << "Ghostscript: " << gsver + "\n"; + oss << +#ifdef MIKTEX + "MiKTeX: " << FileFinder::version() << "\n" +#else + "kpathsea: " << FileFinder::version() << "\n" +#endif + "potrace: " << (strchr(potrace_version(), ' ') ? strchr(potrace_version(), ' ')+1 : "unknown") << "\n" + "zlib: " << zlibVersion(); + } + cout << oss.str() << endl; +} + + +static void init_fontmap (const CommandLine &args) { + const char *mapseq = args.fontmap_given() ? args.fontmap_arg().c_str() : 0; + bool additional = mapseq && strchr("+-=", *mapseq); + if (!mapseq || additional) { + const char *mapfiles[] = {"ps2pk.map", "dvipdfm.map", "psfonts.map", 0}; + bool found = false; + for (const char **p=mapfiles; *p && !found; p++) + found = FontMap::instance().read(*p); + if (!found) + Message::wstream(true) << "none of the default map files could be found"; + } + if (mapseq) + FontMap::instance().read(mapseq); +} + + +int main (int argc, char *argv[]) { + CommandLine args; + args.parse(argc, argv); + if (args.error()) + return 1; + + Message::COLORIZE = args.color_given(); + + try { + FileFinder::init(argv[0], "dvisvgm", !args.no_mktexmf_given()); + } + catch (MessageException &e) { + Message::estream(true) << e.what() << '\n'; + return 0; + } + + set_libgs(args); + if (args.version_given()) { + print_version(args.version_arg()); + return 0; + } + if (args.list_specials_given()) { + DVIToSVG::setProcessSpecials(); + SpecialManager::instance().writeHandlerInfo(cout); + return 0; + } + + if (!set_cache_dir(args)) + return 0; + + if (argc == 1 || args.help_given()) { + show_help(args); + return 0; + } + + if (argc > 1 && args.numFiles() < 1) { + Message::estream(true) << "no input file given\n"; + return 1; + } + + if (args.stdout_given() && args.zip_given()) { + Message::estream(true) << "writing SVGZ files to stdout is not supported\n"; + return 1; + } + + if (!check_bbox(args.bbox_arg())) + return 1; + + if (args.progress_given()) { + DVIReader::COMPUTE_PROGRESS = args.progress_given(); + SpecialActions::PROGRESSBAR_DELAY = args.progress_arg(); + } + SVGTree::CREATE_STYLE = !args.no_styles_given(); + SVGTree::USE_FONTS = !args.no_fonts_given(); + SVGTree::CREATE_USE_ELEMENTS = args.no_fonts_arg() < 1; + SVGTree::ZOOM_FACTOR = args.zoom_arg(); + SVGTree::RELATIVE_PATH_CMDS = args.relative_given(); + SVGTree::MERGE_CHARS = !args.no_merge_given(); + DVIToSVG::TRACE_MODE = args.trace_all_given() ? (args.trace_all_arg() ? 'a' : 'm') : 0; + Message::LEVEL = args.verbosity_arg(); + PhysicalFont::EXACT_BBOX = args.exact_given(); + PhysicalFont::KEEP_TEMP_FILES = args.keep_given(); + PhysicalFont::METAFONT_MAG = max(1.0, args.mag_arg()); + XMLString::DECIMAL_PLACES = max(0, min(6, args.precision_arg())); + if (!HtmlSpecialHandler::setLinkMarker(args.linkmark_arg())) + Message::wstream(true) << "invalid argument '"+args.linkmark_arg()+"' supplied for option --linkmark\n"; + double start_time = System::time(); + bool eps_given=false; +#ifndef DISABLE_GS + eps_given = args.eps_given(); + PsSpecialHandler::COMPUTE_CLIPPATHS_INTERSECTIONS = args.clipjoin_given(); + PsSpecialHandler::SHADING_SEGMENT_OVERLAP = args.grad_overlap_given(); + PsSpecialHandler::SHADING_SEGMENT_SIZE = max(1, args.grad_segments_arg()); + PsSpecialHandler::SHADING_SIMPLIFY_DELTA = args.grad_simplify_arg(); +#endif + string inputfile = ensure_suffix(args.file(0), eps_given); + ifstream ifs(inputfile.c_str(), ios::binary|ios::in); + if (!ifs) { + Message::estream(true) << "can't open file '" << inputfile << "' for reading\n"; + return 0; + } + try { + SVGOutput out(args.stdout_given() ? 0 : inputfile.c_str(), args.output_arg(), args.zip_given() ? args.zip_arg() : 0); + SignalHandler::instance().start(); +#ifndef DISABLE_GS + if (args.eps_given()) { + EPSToSVG eps2svg(inputfile, out); + eps2svg.convert(); + Message::mstream().indent(0); + Message::mstream(false, Message::MC_PAGE_NUMBER) + << "file converted in " << (System::time()-start_time) << " seconds\n"; + } + else +#endif + { + init_fontmap(args); + DVIToSVG dvi2svg(ifs, out); + const char *ignore_specials = args.no_specials_given() ? (args.no_specials_arg().empty() ? "*" : args.no_specials_arg().c_str()) : 0; + dvi2svg.setProcessSpecials(ignore_specials, true); + dvi2svg.setPageTransformation(get_transformation_string(args)); + dvi2svg.setPageSize(args.bbox_arg()); + + pair<int,int> pageinfo; + dvi2svg.convert(args.page_arg(), &pageinfo); + Message::mstream().indent(0); + Message::mstream(false, Message::MC_PAGE_NUMBER) << "\n" << pageinfo.first << " of " << pageinfo.second << " page"; + if (pageinfo.second > 1) + Message::mstream(false, Message::MC_PAGE_NUMBER) << 's'; + Message::mstream(false, Message::MC_PAGE_NUMBER) << " converted in " << (System::time()-start_time) << " seconds\n"; + } + } + catch (DVIException &e) { + Message::estream() << "\nDVI error: " << e.what() << '\n'; + } + catch (PSException &e) { + Message::estream() << "\nPostScript error: " << e.what() << '\n'; + } + catch (SignalException &e) { + Message::wstream().clearline(); + Message::wstream(true) << "execution interrupted by user\n"; + } + catch (MessageException &e) { + Message::estream(true) << e.what() << '\n'; + } + FileFinder::finish(); + return 0; +} + |