From 47f304f415afeb211f3a99ad94c16437d5a29da8 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Wed, 9 Dec 2015 07:58:00 +0000 Subject: Import dvisvgm 1.13. git-svn-id: svn://tug.org/texlive/trunk@39061 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvisvgm/ChangeLog | 5 + Build/source/texk/dvisvgm/configure | 22 +- .../texk/dvisvgm/dvisvgm-src-PATCHES/ChangeLog | 4 + .../texk/dvisvgm/dvisvgm-src-PATCHES/TL-Changes | 3 +- Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog | 62 ++++ Build/source/texk/dvisvgm/dvisvgm-src/NEWS | 9 + Build/source/texk/dvisvgm/dvisvgm-src/configure.ac | 4 +- .../source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 | 21 +- .../texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in | 17 +- .../dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp | 12 +- .../texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h | 3 - .../texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp | 10 +- Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp | 2 +- Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h | 2 +- Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.h | 4 +- .../texk/dvisvgm/dvisvgm-src/src/GraphicPath.h | 395 -------------------- .../texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h | 413 +++++++++++++++++++++ .../texk/dvisvgm/dvisvgm-src/src/Makefile.am | 2 +- .../texk/dvisvgm/dvisvgm-src/src/PathClipper.h | 4 +- .../dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp | 42 ++- .../dvisvgm/dvisvgm-src/src/PsSpecialHandler.h | 4 +- .../texk/dvisvgm/dvisvgm-src/src/ShadingPatch.h | 6 +- .../dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp | 8 +- .../dvisvgm/dvisvgm-src/src/TensorProductPatch.h | 2 +- .../dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp | 4 +- .../dvisvgm/dvisvgm-src/src/TriangularPatch.cpp | 6 +- .../texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h | 2 +- .../source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp | 148 ++++---- .../texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c | 89 +++-- Build/source/texk/dvisvgm/version.ac | 2 +- 30 files changed, 728 insertions(+), 579 deletions(-) delete mode 100644 Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicPath.h create mode 100644 Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h (limited to 'Build') diff --git a/Build/source/texk/dvisvgm/ChangeLog b/Build/source/texk/dvisvgm/ChangeLog index 775e58db480..a78dde5b199 100644 --- a/Build/source/texk/dvisvgm/ChangeLog +++ b/Build/source/texk/dvisvgm/ChangeLog @@ -1,3 +1,8 @@ +2015-12-09 Akira Kakuto + + * Imported release 1.13. + * version.ac: Adapted. + 2015-12-03 Akira Kakuto * Imported release 1.12. diff --git a/Build/source/texk/dvisvgm/configure b/Build/source/texk/dvisvgm/configure index 52540d00020..c48fdc37523 100755 --- a/Build/source/texk/dvisvgm/configure +++ b/Build/source/texk/dvisvgm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for dvisvgm (TeX Live) 1.12. +# Generated by GNU Autoconf 2.69 for dvisvgm (TeX Live) 1.13. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvisvgm (TeX Live)' PACKAGE_TARNAME='dvisvgm--tex-live-' -PACKAGE_VERSION='1.12' -PACKAGE_STRING='dvisvgm (TeX Live) 1.12' +PACKAGE_VERSION='1.13' +PACKAGE_STRING='dvisvgm (TeX Live) 1.13' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1372,7 +1372,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dvisvgm (TeX Live) 1.12 to adapt to many kinds of systems. +\`configure' configures dvisvgm (TeX Live) 1.13 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1443,7 +1443,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dvisvgm (TeX Live) 1.12:";; + short | recursive ) echo "Configuration of dvisvgm (TeX Live) 1.13:";; esac cat <<\_ACEOF @@ -1583,7 +1583,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dvisvgm (TeX Live) configure 1.12 +dvisvgm (TeX Live) configure 1.13 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2451,7 +2451,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dvisvgm (TeX Live) $as_me 1.12, which was +It was created by dvisvgm (TeX Live) $as_me 1.13, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -8137,7 +8137,7 @@ fi # Define the identity of the package. PACKAGE='dvisvgm--tex-live-' - VERSION='1.12' + VERSION='1.13' cat >>confdefs.h <<_ACEOF @@ -18321,7 +18321,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -dvisvgm (TeX Live) config.lt 1.12 +dvisvgm (TeX Live) config.lt 1.13 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -20684,7 +20684,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dvisvgm (TeX Live) $as_me 1.12, which was +This file was extended by dvisvgm (TeX Live) $as_me 1.13, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20750,7 +20750,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dvisvgm (TeX Live) config.status 1.12 +dvisvgm (TeX Live) config.status 1.13 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/ChangeLog index b51282d02f4..0fd128aa0b9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/ChangeLog +++ b/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/ChangeLog @@ -1,3 +1,7 @@ +2015-12-09 Akira Kakuto + + * Import release 1.13. + 2015-12-03 Akira Kakuto * Import release 1.12. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/TL-Changes b/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/TL-Changes index c19886df7a7..49db94bcd99 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/TL-Changes +++ b/Build/source/texk/dvisvgm/dvisvgm-src-PATCHES/TL-Changes @@ -1,4 +1,4 @@ -Changes applied to the dvisvgm-1.12 tree as obtained from: +Changes applied to the dvisvgm-1.13 tree as obtained from: http://dvisvgm.bplaced.net/Downloads Removed: @@ -18,4 +18,3 @@ Removed: Converted Dos/Win line ends to native: clipper/clipper.cpp clipper/clipper.hpp - diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog index ce8772109de..ac9aeaaa2d0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog +++ b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog @@ -1,3 +1,65 @@ +2015-12-08 Martin Gieseking + + * NEWS: + updated NEWS + + * .travis.yml, configure.ac, src/Doxyfile: + set version to 1.13 + +2015-12-02 Martin Gieseking + + * CMakeLists.txt, src/Font.cpp, src/Font.h, src/Glyph.h, + src/GraphicPath.h, src/GraphicsPath.h, src/Makefile.am, + src/PathClipper.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, + src/ShadingPatch.h, src/TensorProductPatch.cpp, src/TensorProductPatch.h, + src/TpicSpecialHandler.cpp, src/TriangularPatch.cpp, + src/TriangularPatch.h, tests/GraphicPathTest.cpp, + tests/GraphicsPathTest.cpp, tests/Makefile.am, + tests/TensorProductPatchTest.cpp, tests/TriangularPatchTest.cpp: + renamed class GraphicPath to GraphicsPath + +2015-11-30 Martin Gieseking + + * src/GraphicPath.h, src/PsSpecialHandler.cpp: + remove redundant moveto commands from graphics paths + + * doc/dvisvgm.txt.in: + added a couple of links to the manpage + +2015-11-27 Martin Gieseking + + * .gitignore, CMakeLists.txt, cmake/FindGhostscript.cmake, + cmake/FindKpathsea.cmake, cmake/FindPotrace.cmake: + added files for cmake + +2015-11-25 Martin Gieseking + + * src/DVIToSVGActions.cpp, src/DVIToSVGActions.h: + removed redundant methods + + * src/DVIToSVGActions.cpp, src/EPSToSVG.cpp: + remove progress message before printing a PS error message + +2015-11-24 Martin Gieseking + + * xxHash/xxhash.c: + updated xxHash to version r42 + + * src/psdefs.cpp, src/psdefs.ps: + added evaluation of PS operators ashow, awidthshow, and widthshow (fixes + #49) + +2015-11-23 Martin Gieseking + + * src/psdefs.cpp, src/psdefs.ps: + propagate call of PS operator 'setcolor' to the PS handler + + * src/psdefs.cpp, src/psdefs.ps: + reduce rounding errors produced by PS operator 'charpath' + + * src/PsSpecialHandler.cpp, src/psdefs.cpp, src/psdefs.ps: + minor code cleanup and reordering + 2015-11-18 Martin Gieseking * NEWS: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS index 495d70c6dff..66d025a2b22 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS +++ b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS @@ -1,3 +1,12 @@ +dvisvgm-1.13 (2015-12-08) +- added evaluation of PS operators 'ashow', 'awidthshow', and widthshow (GH bug #49) +- improved conversion of fonts referenced by PS code to graphics paths +- redundant 'moveto' commands are now removed from paths +- fixed issue concerning evaluation of PS operator 'setcolor' +- fixed output of PS error messages +- updated bundled xxHash library to revision 42 +- minor code refactorings and cleanup + dvisvgm-1.12 (2015-11-18) - added option --colornames to replace RGB values by SVG color names - fixed resolving of character codes for fonts without supported chracater maps diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac index 57586feedc1..03307b31bc3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac +++ b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac @@ -4,8 +4,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([dvisvgm],[1.12],[martin.gieseking@uos.de]) -DATE="November 2015" +AC_INIT([dvisvgm],[1.13],[martin.gieseking@uos.de]) +DATE="December 2015" AC_CONFIG_SRCDIR(src) AC_CONFIG_HEADER(config.h) AC_CONFIG_MACRO_DIR([m4]) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 index bcd2f4d5728..fd1b0d3dd99 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 @@ -2,12 +2,12 @@ .\" Title: dvisvgm .\" Author: Martin Gieseking .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 11/18/2015 +.\" Date: 12/08/2015 .\" Manual: dvisvgm Manual -.\" Source: dvisvgm 1.12 +.\" Source: dvisvgm 1.13 .\" Language: English .\" -.TH "DVISVGM" "1" "11/18/2015" "dvisvgm 1\&.12" "dvisvgm Manual" +.TH "DVISVGM" "1" "12/08/2015" "dvisvgm 1\&.13" "dvisvgm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -972,7 +972,8 @@ The following TeX snippet adds two raw SVG elements to the output and updates th .PP \fBem\fR .RS 4 -These specials were introduced with the emTeX distribution by Eberhard Mattes\&. They provide line drawing statements, instructions for embedding MSP, PCX, and BMP image files, as well as two PCL commands\&. dvisvgm supports only the line drawing statements and ignores all other em specials silently\&. A description of the command syntax can be found in the DVI driver documentation coming with emTeX (see CTAN)\&. +These specials were introduced with the emTeX distribution by Eberhard Mattes\&. They provide line drawing statements, instructions for embedding MSP, PCX, and BMP image files, as well as two PCL commands\&. dvisvgm supports only the line drawing statements and ignores all other em specials silently\&. A description of the command syntax can be found in the DVI driver documentation coming with +emTeX (\m[blue]http://www.ctan.org/pkg/emtex\m[])\&. .RE .PP \fBhtml\fR @@ -980,7 +981,8 @@ These specials were introduced with the emTeX distribution by Eberhard Mattes\&. The hyperref specification defines several variants on how to mark hyperlinked areas in a DVI file\&. dvisvgm supports the plain HyperTeX special constructs as created with hyperref package option \fIhypertex\fR\&. By default, all linked areas of the document are marked by a rectangle\&. Option \fB\-\-linkmark\fR -allows to change this behavior\&. See above for further details\&. Information on syntax and semantics of the HyperTeX specials can be found in the hyperref manual\&. +allows to change this behavior\&. See above for further details\&. Information on syntax and semantics of the HyperTeX specials can be found in the +hyperref manual (\m[blue]http://www.ctan.org/pkg/hyperref\m[])\&. .RE .PP \fBpdf\fR @@ -991,7 +993,8 @@ and \fIpdf:mapline\fR are supported by dvisvgm\&. These specials allow modifying the font map tree during the processing of DVI files\&. They are used by CTeX, for example\&. dvisvgm supports both, the dvips and dvipdfm font map format\&. For further information on the command syntax and semantics, see the documentation of \fB\epdfmapfile\fR -in the pdfTeX user manual\&. +in the +pdfTeX user manual (\m[blue]http://www.ctan.org/pkg/pdftex\m[])\&. .RE .PP \fBps\fR @@ -1016,9 +1019,9 @@ to check whether PostScript support is available, i\&.e\&. entry is present\&. .sp The PostScript handler also recognizes and evaluates bounding box data generated by the -\fIpreview\fR -package with option -\fItightpage\fR\&. If such data is present in a DVI file, dvisvgm adapts the bounding box of the generated SVG file accordingly, and prints a message showing the width, height, and depth of the box in TeX point units\&. Especially, the depth value can be used to vertically align the SVG graphics with the baseline of surrounding text in HTML or XSL\-FO documents, for example\&. +preview package (\m[blue]http://www.ctan.org/pkg/preview\m[]) +with option +\fItightpage\fR\&. If such data is present in the DVI file, dvisvgm adapts the bounding box of the generated SVG file accordingly, and prints a message showing the width, height, and depth of the box in TeX point units\&. Especially, the depth value can be used to vertically align the SVG graphics with the baseline of surrounding text in HTML or XSL\-FO documents, for example\&. .RE .PP \fBtpic\fR diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in index 7189d5c874d..5bf8921fcd7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in @@ -632,21 +632,22 @@ The following TeX snippet adds two raw SVG elements to the output and updates th These specials were introduced with the emTeX distribution by Eberhard Mattes. They provide line drawing statements, instructions for embedding MSP, PCX, and BMP image files, as well as two PCL commands. dvisvgm supports only the line drawing statements and ignores all other em specials silently. -A description of the command syntax can be found in the DVI driver documentation coming with emTeX (see CTAN). +A description of the command syntax can be found in the DVI driver documentation coming with +http://www.ctan.org/pkg/emtex[emTeX]. *html*:: The hyperref specification defines several variants on how to mark hyperlinked areas in a DVI file. dvisvgm supports the plain HyperTeX special constructs as created with hyperref package option 'hypertex'. By default, all linked areas of the document are marked by a rectangle. Option *--linkmark* allows to change this behavior. See above for further details. Information on syntax and semantics of the HyperTeX specials can be -found in the hyperref manual. +found in the http://www.ctan.org/pkg/hyperref[hyperref manual]. *pdf*:: pdfTeX and dvipdfmx introduced several special commands related to the generation of PDF files. Currently, only two of them, 'pdf:mapfile' and 'pdf:mapline' are supported by dvisvgm. These specials allow modifying the font map tree during the processing of DVI files. They are used by CTeX, for example. dvisvgm supports both, the dvips and dvipdfm font map format. For further information on the command syntax and semantics, see the documentation of -+\pdfmapfile+ in the pdfTeX user manual. ++\pdfmapfile+ in the http://www.ctan.org/pkg/pdftex[pdfTeX user manual]. *ps*:: The famous DVI driver dvips introduced its own set of specials in order to embed PostScript code into DVI files, @@ -666,11 +667,11 @@ variable (Windows). Alternatively, the absolute file path can be specified. If t dvisvgm disables the processing of PostScript specials and prints a warning message. Use option *--list-specials* to check whether PostScript support is available, i.e. entry 'ps' is present. + -The PostScript handler also recognizes and evaluates bounding box data generated by the 'preview' package with -option 'tightpage'. If such data is present in a DVI file, dvisvgm adapts the bounding box of the generated SVG file -accordingly, and prints a message showing the width, height, and depth of the box in TeX point units. Especially, -the depth value can be used to vertically align the SVG graphics with the baseline of surrounding text in HTML -or XSL-FO documents, for example. +The PostScript handler also recognizes and evaluates bounding box data generated by the +http://www.ctan.org/pkg/preview[preview package] with option 'tightpage'. If such data is present in the DVI file, +dvisvgm adapts the bounding box of the generated SVG file accordingly, and prints a message showing the width, height, +and depth of the box in TeX point units. Especially, the depth value can be used to vertically align the SVG graphics +with the baseline of surrounding text in HTML or XSL-FO documents, for example. *tpic*:: The TPIC special set defines instructions for drawing simple geometric objects. Some LaTeX packages, like diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp index 9553a9d7846..911ff62eb6c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp @@ -215,16 +215,6 @@ void DVIToSVGActions::special (const string &spc, double dvi2bp, bool preprocess } -/** This method is called when the DVI preamble was read - * @param[in] cmt preamble comment text. */ -void DVIToSVGActions::preamble (const string &cmt) { -} - - -void DVIToSVGActions::postamble () { -} - - /** This method is called when a "begin of page (bop)" command was found in the DVI file. * @param[in] pageno physical page number * @param[in] c array with 10 components representing \\count0 ... \\count9. c[0] contains the @@ -295,7 +285,7 @@ BoundingBox& DVIToSVGActions::bbox(const string& name, bool reset) { void DVIToSVGActions::progress (const char *id) { if (PROGRESSBAR_DELAY < 1000) { static double time=0; - // slow down updating of the progress indicator to prevent flickering + // slow down updating the progress indicator to prevent flickering if (System::time() - time > 0.1) { progress(0, 0, id); time = System::time(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h index 873f104550a..0ed9c2ce54d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h @@ -29,7 +29,6 @@ #include "SpecialActions.h" #include "SpecialManager.h" #include "SVGTree.h" -#include "DVIReader.h" class DVIToSVG; @@ -67,8 +66,6 @@ class DVIToSVGActions : public DVIActions, public SpecialActions void moveToY (double y); void setFont (int num, const Font *font); void special (const std::string &spc, double dvi2bp, bool preprocessing=false); - void preamble (const std::string &cmt); - void postamble (); void beginPage (unsigned pageno, Int32 *c); void endPage (unsigned pageno); void progress (size_t current, size_t total, const char *id=0); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp index 555e3549760..e813d41e1b8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp @@ -57,8 +57,14 @@ void EPSToSVG::convert () { "lly=" << bbox.minY() << " " "urx=" << bbox.maxX() << " " "ury=" << bbox.maxY(); - PsSpecialHandler pshandler; - pshandler.process("psfile=", ss, this); + try { + PsSpecialHandler pshandler; + pshandler.process("psfile=", ss, this); + } + catch (...) { + progress(0); // remove progress message + throw; + } progress(0); // output SVG file _svg.setBBox(_bbox); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp index d09f3c7d334..01cfa77b2ac 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp @@ -312,7 +312,7 @@ int PhysicalFont::descent () const { * @param[out] glyph path segments of the glyph outline * @param[in] cb optional callback object for tracer class * @return true if outline could be computed */ -bool PhysicalFont::getGlyph (int c, GraphicPath &glyph, GFGlyphTracer::Callback *cb) const { +bool PhysicalFont::getGlyph (int c, GraphicsPath &glyph, GFGlyphTracer::Callback *cb) const { if (type() == MF) { const Glyph *cached_glyph=0; if (CACHE_PATH) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h index e1959f202e1..cf7f574b445 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h @@ -33,7 +33,7 @@ #include "FontMetrics.h" #include "GFGlyphTracer.h" #include "Glyph.h" -#include "GraphicPath.h" +#include "GraphicsPath.h" #include "MessageException.h" #include "RangeMap.h" #include "ToUnicodeMap.h" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.h index d19f130ceaf..b0e12b76eb6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.h @@ -21,8 +21,8 @@ #ifndef DVISVGM_GLYPH_H #define DVISVGM_GLYPH_H -#include "GraphicPath.h" +#include "GraphicsPath.h" -typedef GraphicPath Glyph; +typedef GraphicsPath Glyph; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicPath.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicPath.h deleted file mode 100644 index 6d377eb8a59..00000000000 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicPath.h +++ /dev/null @@ -1,395 +0,0 @@ -/************************************************************************* -** GraphicPath.h ** -** ** -** This file is part of dvisvgm -- the DVI to SVG converter ** -** Copyright (C) 2005-2015 Martin Gieseking ** -** ** -** 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 . ** -*************************************************************************/ - -#ifndef DVISVGM_GRAPHICPATH_H -#define DVISVGM_GRAPHICPATH_H - -#include -#include -#include -#include -#include "BoundingBox.h" -#include "Matrix.h" -#include "Pair.h" -#include "XMLString.h" - - -template -class GraphicPath -{ - friend class PathClipper; - public: - enum WindingRule {WR_EVEN_ODD, WR_NON_ZERO}; - typedef Pair Point; - - struct Command { - enum Type {MOVETO, LINETO, CONICTO, CUBICTO, CLOSEPATH}; - - Command (Type t) : type(t) {} - - Command (Type t, const Point &p) : type(t) { - params[0] = p; - } - - Command (Type t, const Point &p1, const Point &p2) : type(t) { - params[0] = p1; - params[1] = p2; - } - - Command (Type t, const Point &p1, const Point &p2, const Point &p3) : type(t) { - params[0] = p1; - params[1] = p2; - params[2] = p3; - } - - int numParams () const { - switch (type) { - case CLOSEPATH : return 0; - case MOVETO : - case LINETO : return 1; - case CONICTO : return 2; - case CUBICTO : return 3; - } - return 0; - } - - void transform (const Matrix &matrix) { - for (int i=0; i < numParams(); i++) - params[i] = matrix * params[i]; - } - - Type type; - Point params[3]; - }; - - struct Actions - { - virtual ~Actions () {} - virtual void moveto (const Point &p) {} - virtual void lineto (const Point &p) {} - virtual void hlineto (const T &y) {} - virtual void vlineto (const T &x) {} - virtual void sconicto (const Point &p) {} - virtual void conicto (const Point &p1, const Point &p2) {} - virtual void scubicto (const Point &p1, const Point &p2) {} - virtual void cubicto (const Point &p1, const Point &p2, const Point &p3) {} - virtual void closepath () {} - virtual void draw (char cmd, const Point *points, int n) {} - virtual bool quit () {return false;} - virtual void finished () {} - }; - - typedef typename std::vector::iterator Iterator; - typedef typename std::vector::const_iterator ConstIterator; - typedef typename std::vector::const_reverse_iterator ConstRevIterator; - - public: - GraphicPath (WindingRule wr=WR_NON_ZERO) : _windingRule(wr) {} - - void setWindingRule (WindingRule wr) {_windingRule = wr;} - WindingRule windingRule () const {return _windingRule;} - - void clear () { - _commands.clear(); - } - - /// Returns true if the path is empty, i.e. there is nothing to draw - bool empty () const { - return _commands.empty(); - } - - /// Returns the number of path commands used to describe the path. - size_t size () const { - return _commands.size(); - } - - /// Insert another path at the beginning of this one. - void prepend (const GraphicPath &path) { - _commands.insert(_commands.begin(), path._commands.begin(), path._commands.end()); - } - - void moveto (const T &x, const T &y) { - moveto(Point(x, y)); - } - - void moveto (const Point &p) { - // avoid sequences of several MOVETOs; always use latest - if (_commands.empty() || _commands.back().type != Command::MOVETO) - _commands.push_back(Command(Command::MOVETO, p)); - else - _commands.back().params[0] = p; - } - - void lineto (const T &x, const T &y) { - lineto(Point(x, y)); - } - - void lineto (const Point &p) { - _commands.push_back(Command(Command::LINETO, p)); - } - - void conicto (const T &x1, const T &y1, const T &x2, const T &y2) { - conicto(Point(x1, y1), Point(x2, y2)); - } - - void conicto (const Point &p1, const Point &p2) { - _commands.push_back(Command(Command::CONICTO, p1, p2)); - } - - void cubicto (const T &x1, const T &y1, const T &x2, const T &y2, const T &x3, const T &y3) { - cubicto(Point(x1, y1), Point(x2, y2), Point(x3, y3)); - } - - void cubicto (const Point &p1, const Point &p2, const Point &p3) { - _commands.push_back(Command(Command::CUBICTO, p1, p2, p3)); - } - - void closepath () { - _commands.push_back(Command(Command::CLOSEPATH)); - } - - - const std::vector& commands () const { - return _commands; - } - - - /** Detects all open subpaths and closes them by adding a closePath command. - * Most font formats only support closed outline paths so there are no explicit closePath statements - * in the glyph's outline description. All open paths are automatically closed by the renderer. - * This method detects all open paths and adds the missing closePath statement. */ - void closeOpenSubPaths () { - Command *prevCommand = 0; - FORALL(_commands, Iterator, it) { - if (it->type == Command::MOVETO && prevCommand && prevCommand->type != Command::CLOSEPATH) { - prevCommand = &(*it); - it = _commands.insert(it, Command(Command::CLOSEPATH))+1; -// ++it; // skip inserted closePath command in next iteration step - } - else - prevCommand = &(*it); - } - if (!_commands.empty() && _commands.back().type != Command::CLOSEPATH) - closepath(); - } - - - /** Writes the path data as SVG path drawing command to a given output stream. - * @param[in] os output stream used to write the SVG commands to - * @param[in] relative if true, create relative rather than absolute coordinate values - * @param[in] sx horizontal scale factor - * @param[in] sy vertical scale factor - * @param[in] dx horizontal translation in PS point units - * @param[in] dy vertical translation in PS point units */ - void writeSVG (std::ostream &os, bool relative, double sx=1.0, double sy=1.0, double dx=0.0, double dy=0.0) const { - struct WriteActions : Actions { - WriteActions (std::ostream &os, bool relative, double sx, double sy, double dx, double dy) - : _os(os), _relative(relative), _sx(sx), _sy(sy), _dx(dx), _dy(dy) {} - - void draw (char cmd, const Point *points, int n) { - if (_relative) - cmd = tolower(cmd); - _os << cmd; - switch (cmd) { - case 'h': _os << XMLString(_sx*(points->x()-_currentPoint.x())+_dx); break; - case 'v': _os << XMLString(_sy*(points->y()-_currentPoint.y())+_dy); break; - case 'z': _currentPoint = _startPoint; break; - case 'H': _os << XMLString(_sx*points->x()+_dx); break; - case 'V': _os << XMLString(_sy*points->y()+_dy); break; - default : - for (int i=0; i < n; i++) { - if (i > 0) - _os << ' '; - Point p = points[i]; - if (_relative) - p -= _currentPoint; - _os << XMLString(_sx*p.x()+_dx) << ' ' << XMLString(_sy*p.y()+_dy); - } - } - if (cmd == 'm') - _startPoint = points[0]; - if (islower(cmd) && n > 0) - _currentPoint = points[n-1]; - } - std::ostream &_os; - bool _relative; - double _sx, _sy, _dx, _dy; - Point _startPoint, _currentPoint; - } actions(os, relative, sx, sy, dx, dy); - iterate(actions, true); - } - -#if 0 - void writePS (std::ostream &os, double sx=1.0, double sy=1.0, double dx=0.0, double dy=0.0) const { - struct WriteActions : Actions { - WriteActions (std::ostream &os, double sx, double sy, double dx, double dy) - : _os(os), _sx(sx), _sy(sy), _dx(dx), _dy(dy) {} - void draw (char cmd, const Point *points, int n) { - for (int i=0; i < n; i++) - _os << _sx*points[i].x()+_dx << ' ' << _sy*points[i].y()+_dy << ' '; - switch (cmd) { - case 'M': _os << "moveto"; break; - case 'L': _os << "lineto"; break; - case 'C': _os << "curveto"; break; - case 'Z': _os << "closepath"; break; - default: ; - } - _os << '\n'; - } - std::ostream &_os; - bool _relative; - double _sx, _sy, _dx, _dy; - } actions(os, sx, sy, dx, dy); - iterate(actions, false); - } -#endif - - - /** Computes the bounding box of the current path. - * @param[out] bbox the computed bounding box */ - void computeBBox (BoundingBox &bbox) const { - struct BBoxActions : Actions { - BBoxActions (BoundingBox &bb) : bbox(bb) {} - void moveto (const Point &p) {bbox.embed(p);} - void lineto (const Point &p) {bbox.embed(p);} - void conicto (const Point &p1, const Point &p2) {bbox.embed(p1); bbox.embed(p2);} - void cubicto (const Point &p1, const Point &p2, const Point &p3) {bbox.embed(p1); bbox.embed(p2); bbox.embed(p3);} - BoundingBox &bbox; - } actions(bbox); - iterate(actions, false); - } - - - /** Checks whether the current path describes a dot/point only (with no extent). - * @param[out] p coordinates of the point if path describes a dot - * @return true if path is a dot/point */ - bool isDot (Point &p) const { - struct DotActions : Actions { - DotActions () : differs(false) {} - void moveto (const Point &p) {point = p;} - void lineto (const Point &p) {differs = (p != point);} - void conicto (const Point &p1, const Point &p2) {differs = (point != p1 || point != p2);} - void cubicto (const Point &p1, const Point &p2, const Point &p3) {differs = (point != p1 || point != p2 || point != p3);} - bool quit () {return differs;} - Point point; - bool differs; - } actions; - iterate(actions, false); - p = actions.point; - return !actions.differs; - } - - - /** Transforms the path according to a given Matrix. - * @param[in] matrix Matrix describing the affine transformation */ - void transform (const Matrix &matrix) { - FORALL(_commands, Iterator, it) - it->transform(matrix); - } - - void iterate (Actions &actions, bool optimize) const; - - private: - std::vector _commands; - WindingRule _windingRule; -}; - - -/** Iterates over all commands defining this path and calls the corresponding template methods. - * In the case of successive bezier curve sequences, control points or tangent slopes are often - * identical so that the path description contains redundant information. SVG provides shorthand - * curve commands that require less parameters. If 'optimize' is true, this method detects such - * command sequences. - * @param[in] actions template methods called by each iteration step - * @param[in] optimize if true, shorthand drawing commands (sconicto, scubicto,...) are considered */ -template -void GraphicPath::iterate (Actions &actions, bool optimize) const { - ConstIterator prev = _commands.end(); // pointer to preceding command - Point fp; // first point of current path - Point cp; // current point - Point pstore[2]; - for (ConstIterator it=_commands.begin(); it != _commands.end() && !actions.quit(); ++it) { - const Point *params = it->params; - switch (it->type) { - case Command::MOVETO: - actions.moveto(params[0]); - actions.draw('M', params, 1); - fp = params[0]; - break; - case Command::LINETO: - if (optimize) { - if (cp.x() == params[0].x()) { - actions.vlineto(params[0].y()); - actions.draw('V', params, 1); - } - else if (cp.y() == params[0].y()) { - actions.hlineto(params[0].x()); - actions.draw('H', params, 1); - } - else { - actions.lineto(params[0]); - actions.draw('L', params, 1); - } - } - else { - actions.lineto(params[0]); - actions.draw('L', params, 1); - } - break; - case Command::CONICTO: - if (optimize && prev != _commands.end() && prev->type == Command::CONICTO && params[0] == pstore[1]*T(2)-pstore[0]) { - actions.sconicto(params[1]); - actions.draw('T', params+1, 1); - } - else { - actions.conicto(params[0], params[1]); - actions.draw('Q', params, 2); - } - pstore[0] = params[0]; // store control point and - pstore[1] = params[1]; // curve endpoint - break; - case Command::CUBICTO: - // is first control point reflection of preceding second control point? - if (optimize && prev != _commands.end() && prev->type == Command::CUBICTO && params[0] == pstore[1]*T(2)-pstore[0]) { - actions.scubicto(params[1], params[2]); - actions.draw('S', params+1, 2); - } - else { - actions.cubicto(params[0], params[1], params[2]); - actions.draw('C', params, 3); - } - pstore[0] = params[1]; // store second control point and - pstore[1] = params[2]; // curve endpoint - break; - case Command::CLOSEPATH: - actions.closepath(); - actions.draw('Z', params, 0); - cp = fp; - } - // update current point - const int np = it->numParams(); - if (np > 0) - cp = it->params[np-1]; - prev = it; - } - actions.finished(); -} - -#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h new file mode 100644 index 00000000000..59b91ae6f3b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.h @@ -0,0 +1,413 @@ +/************************************************************************* +** GraphicsPath.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2015 Martin Gieseking ** +** ** +** 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 . ** +*************************************************************************/ + +#ifndef DVISVGM_GRAPHICPATH_H +#define DVISVGM_GRAPHICPATH_H + +#include +#include +#include +#include +#include "BoundingBox.h" +#include "Matrix.h" +#include "Pair.h" +#include "XMLString.h" + + +template +class GraphicsPath +{ + friend class PathClipper; + public: + enum WindingRule {WR_EVEN_ODD, WR_NON_ZERO}; + typedef Pair Point; + + struct Command { + enum Type {MOVETO, LINETO, CONICTO, CUBICTO, CLOSEPATH}; + + Command (Type t) : type(t) {} + + Command (Type t, const Point &p) : type(t) { + params[0] = p; + } + + Command (Type t, const Point &p1, const Point &p2) : type(t) { + params[0] = p1; + params[1] = p2; + } + + Command (Type t, const Point &p1, const Point &p2, const Point &p3) : type(t) { + params[0] = p1; + params[1] = p2; + params[2] = p3; + } + + int numParams () const { + switch (type) { + case CLOSEPATH : return 0; + case MOVETO : + case LINETO : return 1; + case CONICTO : return 2; + case CUBICTO : return 3; + } + return 0; + } + + void transform (const Matrix &matrix) { + for (int i=0; i < numParams(); i++) + params[i] = matrix * params[i]; + } + + Type type; + Point params[3]; + }; + + struct Actions + { + virtual ~Actions () {} + virtual void moveto (const Point &p) {} + virtual void lineto (const Point &p) {} + virtual void hlineto (const T &y) {} + virtual void vlineto (const T &x) {} + virtual void sconicto (const Point &p) {} + virtual void conicto (const Point &p1, const Point &p2) {} + virtual void scubicto (const Point &p1, const Point &p2) {} + virtual void cubicto (const Point &p1, const Point &p2, const Point &p3) {} + virtual void closepath () {} + virtual void draw (char cmd, const Point *points, int n) {} + virtual bool quit () {return false;} + virtual void finished () {} + }; + + typedef typename std::vector::iterator Iterator; + typedef typename std::vector::const_iterator ConstIterator; + typedef typename std::vector::const_reverse_iterator ConstRevIterator; + + public: + GraphicsPath (WindingRule wr=WR_NON_ZERO) : _windingRule(wr) {} + + void setWindingRule (WindingRule wr) {_windingRule = wr;} + WindingRule windingRule () const {return _windingRule;} + + void clear () { + _commands.clear(); + } + + /// Returns true if the path is empty, i.e. there is nothing to draw + bool empty () const { + return _commands.empty(); + } + + /// Returns the number of path commands used to describe the path. + size_t size () const { + return _commands.size(); + } + + /// Insert another path at the beginning of this one. + void prepend (const GraphicsPath &path) { + _commands.insert(_commands.begin(), path._commands.begin(), path._commands.end()); + } + + void moveto (const T &x, const T &y) { + moveto(Point(x, y)); + } + + void moveto (const Point &p) { + // avoid sequences of several MOVETOs; always use latest + if (_commands.empty() || _commands.back().type != Command::MOVETO) + _commands.push_back(Command(Command::MOVETO, p)); + else + _commands.back().params[0] = p; + } + + void lineto (const T &x, const T &y) { + lineto(Point(x, y)); + } + + void lineto (const Point &p) { + _commands.push_back(Command(Command::LINETO, p)); + } + + void conicto (const T &x1, const T &y1, const T &x2, const T &y2) { + conicto(Point(x1, y1), Point(x2, y2)); + } + + void conicto (const Point &p1, const Point &p2) { + _commands.push_back(Command(Command::CONICTO, p1, p2)); + } + + void cubicto (const T &x1, const T &y1, const T &x2, const T &y2, const T &x3, const T &y3) { + cubicto(Point(x1, y1), Point(x2, y2), Point(x3, y3)); + } + + void cubicto (const Point &p1, const Point &p2, const Point &p3) { + _commands.push_back(Command(Command::CUBICTO, p1, p2, p3)); + } + + void closepath () { + _commands.push_back(Command(Command::CLOSEPATH)); + } + + + const std::vector& commands () const { + return _commands; + } + + + /** Detects all open subpaths and closes them by adding a closePath command. + * Most font formats only support closed outline paths so there are no explicit closePath statements + * in the glyph's outline description. All open paths are automatically closed by the renderer. + * This method detects all open paths and adds the missing closePath statement. */ + void closeOpenSubPaths () { + Command *prevCommand=0; + FORALL(_commands, Iterator, it) { + if (it->type == Command::MOVETO && prevCommand && prevCommand->type != Command::CLOSEPATH) { + prevCommand = &(*it); + it = _commands.insert(it, Command(Command::CLOSEPATH))+1; +// ++it; // skip inserted closePath command in next iteration step + } + else + prevCommand = &(*it); + } + if (!_commands.empty() && _commands.back().type != Command::CLOSEPATH) + closepath(); + } + + + /** 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) + _commands.erase(prev); + prev = it; + } + } + + + /** Writes the path data as SVG path drawing command to a given output stream. + * @param[in] os output stream used to write the SVG commands to + * @param[in] relative if true, create relative rather than absolute coordinate values + * @param[in] sx horizontal scale factor + * @param[in] sy vertical scale factor + * @param[in] dx horizontal translation in PS point units + * @param[in] dy vertical translation in PS point units */ + void writeSVG (std::ostream &os, bool relative, double sx=1.0, double sy=1.0, double dx=0.0, double dy=0.0) const { + struct WriteActions : Actions { + WriteActions (std::ostream &os, bool relative, double sx, double sy, double dx, double dy) + : _os(os), _relative(relative), _sx(sx), _sy(sy), _dx(dx), _dy(dy) {} + + void draw (char cmd, const Point *points, int n) { + if (_relative) + cmd = tolower(cmd); + _os << cmd; + switch (cmd) { + case 'h': _os << XMLString(_sx*(points->x()-_currentPoint.x())+_dx); break; + case 'v': _os << XMLString(_sy*(points->y()-_currentPoint.y())+_dy); break; + case 'z': _currentPoint = _startPoint; break; + case 'H': _os << XMLString(_sx*points->x()+_dx); break; + case 'V': _os << XMLString(_sy*points->y()+_dy); break; + default : + for (int i=0; i < n; i++) { + if (i > 0) + _os << ' '; + Point p = points[i]; + if (_relative) + p -= _currentPoint; + _os << XMLString(_sx*p.x()+_dx) << ' ' << XMLString(_sy*p.y()+_dy); + } + } + if (cmd == 'm') + _startPoint = points[0]; + if (islower(cmd) && n > 0) + _currentPoint = points[n-1]; + } + std::ostream &_os; + bool _relative; + double _sx, _sy, _dx, _dy; + Point _startPoint, _currentPoint; + } actions(os, relative, sx, sy, dx, dy); + iterate(actions, true); + } + +#if 0 + void writePS (std::ostream &os, double sx=1.0, double sy=1.0, double dx=0.0, double dy=0.0) const { + struct WriteActions : Actions { + WriteActions (std::ostream &os, double sx, double sy, double dx, double dy) + : _os(os), _sx(sx), _sy(sy), _dx(dx), _dy(dy) {} + void draw (char cmd, const Point *points, int n) { + for (int i=0; i < n; i++) + _os << _sx*points[i].x()+_dx << ' ' << _sy*points[i].y()+_dy << ' '; + switch (cmd) { + case 'M': _os << "moveto"; break; + case 'L': _os << "lineto"; break; + case 'C': _os << "curveto"; break; + case 'Z': _os << "closepath"; break; + default: ; + } + _os << '\n'; + } + std::ostream &_os; + bool _relative; + double _sx, _sy, _dx, _dy; + } actions(os, sx, sy, dx, dy); + iterate(actions, false); + } +#endif + + + /** Computes the bounding box of the current path. + * @param[out] bbox the computed bounding box */ + void computeBBox (BoundingBox &bbox) const { + struct BBoxActions : Actions { + BBoxActions (BoundingBox &bb) : bbox(bb) {} + void moveto (const Point &p) {bbox.embed(p);} + void lineto (const Point &p) {bbox.embed(p);} + void conicto (const Point &p1, const Point &p2) {bbox.embed(p1); bbox.embed(p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {bbox.embed(p1); bbox.embed(p2); bbox.embed(p3);} + BoundingBox &bbox; + } actions(bbox); + iterate(actions, false); + } + + + /** Checks whether the current path describes a dot/point only (with no extent). + * @param[out] p coordinates of the point if path describes a dot + * @return true if path is a dot/point */ + bool isDot (Point &p) const { + struct DotActions : Actions { + DotActions () : differs(false) {} + void moveto (const Point &p) {point = p;} + void lineto (const Point &p) {differs = (p != point);} + void conicto (const Point &p1, const Point &p2) {differs = (point != p1 || point != p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {differs = (point != p1 || point != p2 || point != p3);} + bool quit () {return differs;} + Point point; + bool differs; + } actions; + iterate(actions, false); + p = actions.point; + return !actions.differs; + } + + + /** Transforms the path according to a given Matrix. + * @param[in] matrix Matrix describing the affine transformation */ + void transform (const Matrix &matrix) { + FORALL(_commands, Iterator, it) + it->transform(matrix); + } + + void iterate (Actions &actions, bool optimize) const; + + private: + std::vector _commands; + WindingRule _windingRule; +}; + + +/** Iterates over all commands defining this path and calls the corresponding template methods. + * In the case of successive bezier curve sequences, control points or tangent slopes are often + * identical so that the path description contains redundant information. SVG provides shorthand + * curve commands that require less parameters. If 'optimize' is true, this method detects such + * command sequences. + * @param[in] actions template methods called by each iteration step + * @param[in] optimize if true, shorthand drawing commands (sconicto, scubicto,...) are considered */ +template +void GraphicsPath::iterate (Actions &actions, bool optimize) const { + ConstIterator prev = _commands.end(); // pointer to preceding command + Point fp; // first point of current path + Point cp; // current point + Point pstore[2]; + for (ConstIterator it=_commands.begin(); it != _commands.end() && !actions.quit(); ++it) { + const Point *params = it->params; + switch (it->type) { + case Command::MOVETO: + actions.moveto(params[0]); + actions.draw('M', params, 1); + fp = params[0]; + break; + case Command::LINETO: + if (optimize) { + if (cp.x() == params[0].x()) { + actions.vlineto(params[0].y()); + actions.draw('V', params, 1); + } + else if (cp.y() == params[0].y()) { + actions.hlineto(params[0].x()); + actions.draw('H', params, 1); + } + else { + actions.lineto(params[0]); + actions.draw('L', params, 1); + } + } + else { + actions.lineto(params[0]); + actions.draw('L', params, 1); + } + break; + case Command::CONICTO: + if (optimize && prev != _commands.end() && prev->type == Command::CONICTO && params[0] == pstore[1]*T(2)-pstore[0]) { + actions.sconicto(params[1]); + actions.draw('T', params+1, 1); + } + else { + actions.conicto(params[0], params[1]); + actions.draw('Q', params, 2); + } + pstore[0] = params[0]; // store control point and + pstore[1] = params[1]; // curve endpoint + break; + case Command::CUBICTO: + // is first control point reflection of preceding second control point? + if (optimize && prev != _commands.end() && prev->type == Command::CUBICTO && params[0] == pstore[1]*T(2)-pstore[0]) { + actions.scubicto(params[1], params[2]); + actions.draw('S', params+1, 2); + } + else { + actions.cubicto(params[0], params[1], params[2]); + actions.draw('C', params, 3); + } + pstore[0] = params[1]; // store second control point and + pstore[1] = params[2]; // curve endpoint + break; + case Command::CLOSEPATH: + actions.closepath(); + actions.draw('Z', params, 0); + cp = fp; + } + // update current point + const int np = it->numParams(); + if (np > 0) + cp = it->params[np-1]; + prev = it; + } + actions.finished(); +} + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am index 837dd0cd633..347862d6619 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -103,7 +103,7 @@ libdvisvgm_a_SOURCES = \ Ghostscript.h \ Glyph.h \ GlyphTracerMessages.h \ - GraphicPath.h \ + GraphicsPath.h \ HtmlSpecialHandler.cpp \ HtmlSpecialHandler.h \ InputBuffer.cpp \ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.h index b9c9158a228..aadf40a6ccf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.h @@ -25,7 +25,7 @@ #include #include #include "Bezier.h" -#include "GraphicPath.h" +#include "GraphicsPath.h" #include "MessageException.h" @@ -34,7 +34,7 @@ using ClipperLib::IntPoint; class PathClipper { public: - typedef GraphicPath CurvedPath; + typedef GraphicsPath CurvedPath; public: PathClipper () : _numLines(0) {} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index 7140b6be270..175a7b065b6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -318,24 +318,25 @@ void PsSpecialHandler::psfile (const string &fname, const map &at _actions->setY(0); moveToDVIPos(); - _xmlnode = new XMLElementNode("g"); + _xmlnode = new XMLElementNode("g"); // append following elements to this group _psi.execute("\n@beginspecial @setspecial "); // enter \special environment _psi.limit(epsfile.pslength()); // limit the number of bytes to be processed _psi.execute(is); // process EPS file _psi.limit(0); // disable limitation _psi.execute("\n@endspecial "); // leave special environment - if (!_xmlnode->empty()) { // has anything been drawn? - Matrix m(1); - m.rotate(angle).scale(hscale/100, vscale/100).translate(hoffset, voffset); - m.translate(-llx, lly); - m.scale(sx, sy); // resize image to width "rwi" and height "rhi" - m.translate(x, y); // move image to current DVI position - _xmlnode->addAttribute("transform", m.getSVG()); + if (_xmlnode->empty()) // nothing been drawn? + delete _xmlnode; // => don't need to add empty group node + else { // has anything been drawn? + Matrix matrix(1); + matrix.rotate(angle).scale(hscale/100, vscale/100).translate(hoffset, voffset); + matrix.translate(-llx, lly); + matrix.scale(sx, sy); // resize image to width "rwi" and height "rhi" + matrix.translate(x, y); // move image to current DVI position + if (!matrix.isIdentity()) + _xmlnode->addAttribute("transform", matrix.getSVG()); _actions->appendToPage(_xmlnode); } - else - delete _xmlnode; - _xmlnode = 0; + _xmlnode = 0; // append following elements to page group again // restore DVI position _actions->setX(x); @@ -415,17 +416,17 @@ void PsSpecialHandler::dviEndPage (unsigned) { /////////////////////////////////////////////////////// -void PsSpecialHandler::gsave (vector &p) { +void PsSpecialHandler::gsave (vector&) { _clipStack.dup(); } -void PsSpecialHandler::grestore (vector &p) { +void PsSpecialHandler::grestore (vector&) { _clipStack.pop(); } -void PsSpecialHandler::grestoreall (vector &p) { +void PsSpecialHandler::grestoreall (vector&) { _clipStack.pop(-1, true); } @@ -455,7 +456,7 @@ void PsSpecialHandler::curveto (vector &p) { } -void PsSpecialHandler::closepath (vector &p) { +void PsSpecialHandler::closepath (vector&) { _path.closepath(); } @@ -463,6 +464,7 @@ void PsSpecialHandler::closepath (vector &p) { /** Draws the current path recorded by previously executed path commands (moveto, lineto,...). * @param[in] p not used */ void PsSpecialHandler::stroke (vector &p) { + _path.removeRedundantCommands(); if ((_path.empty() && !_clipStack.clippathLoaded()) || !_actions) return; @@ -544,6 +546,7 @@ void PsSpecialHandler::stroke (vector &p) { * @param[in] p not used * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ void PsSpecialHandler::fill (vector &p, bool evenodd) { + _path.removeRedundantCommands(); if ((_path.empty() && !_clipStack.clippathLoaded()) || !_actions) return; @@ -705,7 +708,7 @@ void PsSpecialHandler::clippath (std::vector&) { * path (see PS language reference, 3rd edition, pp. 193, 542) * @param[in] p not used * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ -void PsSpecialHandler::clip (vector &, bool evenodd) { +void PsSpecialHandler::clip (vector&, bool evenodd) { clip(_path, evenodd); } @@ -716,7 +719,8 @@ void PsSpecialHandler::clip (vector &, bool evenodd) { * @param[in] path path used to restrict the clipping region * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ void PsSpecialHandler::clip (Path &path, bool evenodd) { - // when this method is called, _path contains the clipping path + // when this method is called, _path contains the clipping path + _path.removeRedundantCommands(); if (path.empty() || !_actions) return; @@ -876,7 +880,7 @@ class ShadingCallback : public ShadingPatch::Callback { _group->addAttribute("clip-path", XMLString("url(#clip")+XMLString(clippathID)+")"); } - void patchSegment (GraphicPath &path, const Color &color) { + void patchSegment (GraphicsPath &path, const Color &color) { if (!_actions->getMatrix().isIdentity()) path.transform(_actions->getMatrix()); @@ -913,7 +917,7 @@ void PsSpecialHandler::processSequentialPatchMesh (int shadingTypeID, ColorSpace #if 0 if (bgcolorGiven) { // fill whole patch area with given background color - GraphicPath outline; + GraphicsPath outline; patch->getBoundaryPath(outline); callback.patchSegment(outline, bgcolor); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h index 38c04c50afa..31436f7aa49 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h @@ -25,7 +25,7 @@ #include #include #include -#include "GraphicPath.h" +#include "GraphicsPath.h" #include "PSInterpreter.h" #include "SpecialHandler.h" #include "PSPattern.h" @@ -37,7 +37,7 @@ class XMLElementNode; class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, protected PSActions { - typedef GraphicPath Path; + typedef GraphicsPath Path; typedef std::vector::const_iterator DoubleVecIt; typedef Color::ColorSpace ColorSpace; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.h index 84c44041e5e..1afb1606fa9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.h @@ -22,7 +22,7 @@ #define DVISVGM_SHADINGPATCH_H #include "Color.h" -#include "GraphicPath.h" +#include "GraphicsPath.h" #include "MessageException.h" @@ -31,7 +31,7 @@ class ShadingPatch public: struct Callback { virtual ~Callback () {} - virtual void patchSegment (GraphicPath &path, const Color &color) =0; + virtual void patchSegment (GraphicsPath &path, const Color &color) =0; }; typedef std::vector PointVec; @@ -43,7 +43,7 @@ class ShadingPatch virtual int psShadingType () const =0; virtual void approximate (int gridsize, bool overlap, double delta, Callback &callback) const =0; virtual void getBBox (BoundingBox &bbox) const =0; - virtual void getBoundaryPath (GraphicPath &path) const =0; + virtual void getBoundaryPath (GraphicsPath &path) const =0; virtual void setPoints (const PointVec &points, int edgeflag, ShadingPatch *patch) =0; virtual void setColors (const ColorVec &colors, int edgeflag, ShadingPatch *patch) =0; virtual int numPoints (int edgeflag) const =0; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp index 2ad8a4c29dc..9d120626465 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp @@ -202,7 +202,7 @@ Color TensorProductPatch::averageColor (const Color &c1, const Color &c2, const } -void TensorProductPatch::getBoundaryPath (GraphicPath &path) const { +void TensorProductPatch::getBoundaryPath (GraphicsPath &path) const { // Simple approach: Use the outer curves as boundary path. This doesn't always lead // to correct results since, depending on the control points, P(u,v) might exceed // the simple boundary. @@ -323,7 +323,7 @@ void TensorProductPatch::approximateRow (double v1, double inc, bool overlap, do Bezier b2(vbeziers[i + (overlap && i < vbeziers.size()-1 ? 1 : 0)], v1, ov2); Bezier b3(hbezier2, u1, ou2); Bezier b4(vbeziers[i-1], v1, ov2); - GraphicPath path; + GraphicsPath path; path.moveto(b1.point(0)); if (inc > delta) { path.cubicto(b1.point(1), b1.point(2), b1.point(3)); @@ -355,7 +355,7 @@ void TensorProductPatch::approximateRow (double v1, double inc, bool overlap, do void TensorProductPatch::approximate (int gridsize, bool overlap, double delta, Callback &callback) const { if (_colors[0] == _colors[1] && _colors[1] == _colors[2] && _colors[2] == _colors[3]) { // simple case: monochromatic patch - GraphicPath path; + GraphicsPath path; getBoundaryPath(path); callback.patchSegment(path, _colors[0]); } @@ -415,7 +415,7 @@ void TensorProductPatch::approximate (int gridsize, Callback &callback) const { // patch boundary are drawn as Bézier curves, all other edges are approximated // with straight lines. This ensures a smooth outline and reduces the number of // time consuming computations. - GraphicPath path; + GraphicsPath path; path.moveto(p0); if (v1 > 0) path.lineto(p1); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h index 50fcac5a1e5..cc9364ca100 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h @@ -53,7 +53,7 @@ class TensorProductPatch : public ShadingPatch Color averageColor () const; void horizontalCurve (double v, Bezier &bezier) const; void verticalCurve (double u, Bezier &bezier) const; - void getBoundaryPath (GraphicPath &path) const; + void getBoundaryPath (GraphicsPath &path) const; void subpatch (double u1, double u2, double v1, double v2, TensorProductPatch &patch) const; DPair blossomValue (double u1, double u2, double u3, double v1, double v2, double v3) const; DPair blossomValue (double u[3], double v[3]) const {return blossomValue(u[0], u[1], u[2], v[0], v[1], v[2]);} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp index 93fe0b19385..044b0ef57d5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp @@ -26,7 +26,7 @@ #include "Color.h" #include "InputBuffer.h" #include "InputReader.h" -#include "GraphicPath.h" +#include "GraphicsPath.h" #include "SpecialActions.h" #include "SVGTree.h" #include "TpicSpecialHandler.h" @@ -128,7 +128,7 @@ void TpicSpecialHandler::drawSplines (double ddist, SpecialActions *actions) { drawLines(true, false, ddist, actions); else { DPair p(actions->getX(), actions->getY()); - GraphicPath path; + GraphicsPath path; path.moveto(p+_points[0]); DPair mid = p+_points[0]+(_points[1]-_points[0])/2.0; path.lineto(mid); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp index 75b3132345b..af8b317b63d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp @@ -161,7 +161,7 @@ static inline double snap (double x) { * @param[in] callback object notified */ void TriangularPatch::approximate (int gridsize, bool overlap, double delta, Callback &callback) const { if (_colors[0] == _colors[1] && _colors[1] == _colors[2]) { - GraphicPath path; + GraphicsPath path; getBoundaryPath(path); callback.patchSegment(path, _colors[0]); } @@ -175,7 +175,7 @@ void TriangularPatch::approximate (int gridsize, bool overlap, double delta, Cal double ov2 = (overlap && snap(v2+inc) <= 1 ? snap(v2+inc) : v2); if (!overlap || (snap(u1+ov2) <= 1 && snap(ou2+v1) <= 1)) { // create triangular segments pointing in the same orientation as the whole patch - GraphicPath path; + GraphicsPath path; path.moveto(valueAt(u1, v1)); path.lineto(valueAt(ou2, v1)); path.lineto(valueAt(u1, ov2)); @@ -197,7 +197,7 @@ void TriangularPatch::approximate (int gridsize, bool overlap, double delta, Cal } -void TriangularPatch::getBoundaryPath(GraphicPath &path) const { +void TriangularPatch::getBoundaryPath(GraphicsPath &path) const { path.clear(); path.moveto(_points[0]); path.lineto(_points[1]); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h index d18d76ebb0a..18f2975f680 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h @@ -41,7 +41,7 @@ class TriangularPatch : public ShadingPatch void setColors (const Color &c1, const Color &c2, const Color &c3); void approximate (int gridsize, bool overlap, double delta, Callback &listener) const; void getBBox (BoundingBox &bbox) const; - void getBoundaryPath(GraphicPath &path) const; + void getBoundaryPath(GraphicsPath &path) const; int numPoints (int edgeflag) const {return edgeflag == 0 ? 3 : 1;} int numColors (int edgeflag) const {return edgeflag == 0 ? 3 : 1;} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp index a9a818a3fe7..e5a03bf41e8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp @@ -21,75 +21,79 @@ #include "PSInterpreter.h" const char *PSInterpreter::PSDEFS = -"3 dict dup begin/Install{matrix setmatrix}def/HWResolution[72 72]def/PageSize[" -"10000 10000]def end setpagedevice/@dodraw true store/@patcnt 0 store/@SD syste" -"mdict def/@UD userdict def true setglobal @SD/:save @SD/save get put @SD/:rest" -"ore @SD/restore get put @SD/:gsave @SD/gsave get put @SD/:grestore @SD/grestor" -"e get put @SD/:grestoreall @SD/grestoreall get put @SD/:newpath @SD/newpath ge" -"t put @SD/:stroke @SD/stroke get put @SD/:fill @SD/fill get put @SD/:eofill @S" -"D/eofill get put @SD/:clip @SD/clip get put @SD/:eoclip @SD/eoclip get put @SD" -"/:charpath @SD/charpath get put @SD/:show @SD/show get put @SD/.setopacityalph" -"a known not{@SD/.setopacityalpha{pop}put}if @SD/prseq{-1 1{-1 roll =only( )pri" -"nt}for(\\n)print}put @SD/prcmd{( )exch(\\ndvi.)3{print}repeat prseq}put @SD/cv" -"xall{{cvx}forall}put @SD/defpr{[exch[/copy @SD]cvxall 5 -1 roll dup 6 1 roll[/" -"get/exec]cvxall 6 -1 roll dup 7 1 roll 4 -1 roll dup 5 1 roll dup length strin" -"g cvs/prcmd cvx]cvx def}put @SD/querypos{{currentpoint}stopped{$error/newerror" -" false put}{2(querypos)prcmd}ifelse}put @SD/applyscalevals{1 0 transform 0 0 t" -"ransform 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt 0 1 transform 0 0" -" transform 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt 1 0 transform d" -"up mul exch dup dup mul 3 -1 roll add sqrt div 3(applyscalevals)prcmd}put @SD/" -"prpath{{2(moveto)prcmd}{2(lineto)prcmd}{6(curveto)prcmd}{0(closepath)prcmd}pat" -"hforall}put @SD/charpath{/@dodraw false store :charpath/@dodraw true store}put" -" @SD/show{@dodraw{dup :gsave currentpoint :newpath moveto true charpath eofill" -" :grestore/@dodraw false store :show/@dodraw true store}if}put @SD/newpath{:ne" -"wpath 0 1(newpath)prcmd}put @SD/stroke{@dodraw{1 1(newpath)prcmd prpath 0(stro" -"ke)prcmd :newpath}{:stroke}ifelse}put @SD/fill{@dodraw{1 1(newpath)prcmd prpat" -"h 0(fill)prcmd :newpath}{:fill}ifelse}put @SD/eofill{@dodraw{1 1(newpath)prcmd" -" prpath 0(eofill)prcmd :newpath}{:eofill}ifelse}put @SD/clip{:clip 0 1(newpath" -")prcmd prpath 0(clip)prcmd}put @SD/eoclip{:eoclip 1 1(newpath)prcmd prpath 0(e" -"oclip)prcmd}put @SD/shfill{begin currentdict/ShadingType known currentdict/Col" -"orSpace known and currentdict/DataSource known and currentdict/Function known " -"not and ShadingType 4 ge and DataSource type/arraytype eq and{<>begin currentdict ColorSpace known{ShadingType ColorSpace load" -" bgknown{1 Background aload pop}{0}ifelse bbknown{1 BBox aload pop}{0}ifelse S" -"hadingType 5 eq{VerticesPerRow}if DataSource aload length 4 add bgknown{ColorS" -"pace load add}if bbknown{4 add}if ShadingType 5 eq{1 add}if(shfill)prcmd}if en" -"d}if end}put/@rect{4 -2 roll moveto exch dup 0 rlineto exch 0 exch rlineto neg" -" 0 rlineto closepath}bind def/@rectcc{4 -2 roll moveto 2 copy 0 lt exch 0 lt x" -"or{dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}{exch dup 0 rlineto ex" -"ch 0 exch rlineto neg 0 rlineto}ifelse closepath}bind def @SD/rectclip{:newpat" -"h dup type/arraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectcc}ifelse cli" -"p :newpath}put @SD/rectfill{gsave :newpath dup type/arraytype eq{aload length " -"4 idiv{@rectcc}repeat}{@rectcc}ifelse fill grestore}put @SD/rectstroke{gsave :" -"newpath dup type/arraytype eq{aload length 4 idiv{@rect}repeat}{@rect}ifelse s" -"troke grestore}put false setglobal @SD readonly pop/initclip 0 defpr/clippath " -"0 defpr/sysexec{@SD exch get exec}def/adddot{dup length 1 add string dup 0 46 " -"put dup 3 -1 roll 1 exch putinterval}def/setlinewidth{dup/setlinewidth sysexec" -" applyscalevals 1(setlinewidth)prcmd}def/setlinecap 1 defpr/setlinejoin 1 defp" -"r/setmiterlimit 1 defpr/setdash{mark 3 1 roll 2 copy/setdash sysexec applyscal" -"evals exch aload length 1 add -1 roll counttomark(setdash)prcmd pop}def/setgst" -"ate{currentlinewidth 1(setlinewidth)prcmd currentlinecap 1(setlinecap)prcmd cu" -"rrentlinejoin 1(setlinejoin)prcmd currentmiterlimit 1(setmiterlimit)prcmd curr" -"entrgbcolor 3(setrgbcolor)prcmd 6 array currentmatrix aload pop 6(setmatrix)pr" -"cmd currentdash mark 3 1 roll exch aload length 1 add -1 roll counttomark(setd" -"ash)prcmd pop}def/save{@UD begin/@saveID vmstatus pop pop def end :save @saveI" -"D 1(save)prcmd}def/restore{:restore setgstate @UD/@saveID known{@UD begin @sav" -"eID end}{0}ifelse 1(restore)prcmd}def/gsave 0 defpr/grestore{:grestore setgsta" -"te 0(grestore)prcmd}def/grestoreall{:grestoreall setstate 0(grestoreall)prcmd}" -"def/rotate{dup type/arraytype ne{dup 1(rotate)prcmd}if/rotate sysexec}def/scal" -"e{dup type/arraytype ne{2 copy 2(scale)prcmd}if/scale sysexec}def/translate{du" -"p type/arraytype ne{2 copy 2(translate)prcmd}if/translate sysexec}def/setmatri" -"x{dup/setmatrix sysexec aload pop 6(setmatrix)prcmd}def/initmatrix{matrix setm" -"atrix}def/concat{matrix currentmatrix matrix concatmatrix setmatrix}def/makepa" -"ttern{gsave<>begin dup/XUID[1000000 @patcnt]put mx/makepattern " -"sysexec dup dup begin PatternType @patcnt BBox aload pop XStep YStep PaintType" -" mx aload pop 15(makepattern)prcmd :newpath matrix setmatrix PaintProc 0 1(mak" -"epattern)prcmd end/@patcnt @patcnt 1 add store end grestore}def/setpattern{beg" -"in PatternType 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[currentco" -"lorspace aload length -1 roll pop]setcolorspace/setcolor sysexec XUID aload po" -"p exch pop currentrgbcolor :grestore 4}ifelse(setpattern)prcmd}{/setpattern sy" -"sexec}ifelse end}def/setcolor{dup type/dicttype eq{setpattern}{/setcolor sysex" -"ec}ifelse}def/setgray 1 defpr/setcmykcolor 4 defpr/sethsbcolor 3 defpr/setrgbc" -"olor 3 defpr/.setopacityalpha{dup/.setopacityalpha sysexec 1(setopacityalpha)p" -"rcmd}def "; +"<>setpagedevice/@dodraw true store/@patcnt 0 store/@SD systemdict def" +"/@UD userdict def true setglobal @SD/:save @SD/save get put @SD/:restore @SD/r" +"estore get put @SD/:gsave @SD/gsave get put @SD/:grestore @SD/grestore get put" +" @SD/:grestoreall @SD/grestoreall get put @SD/:newpath @SD/newpath get put @SD" +"/:stroke @SD/stroke get put @SD/:fill @SD/fill get put @SD/:eofill @SD/eofill " +"get put @SD/:clip @SD/clip get put @SD/:eoclip @SD/eoclip get put @SD/:charpat" +"h @SD/charpath get put @SD/:show @SD/show get put @SD/.setopacityalpha known n" +"ot{@SD/.setopacityalpha{pop}put}if @SD/prseq{-1 1{-1 roll =only( )print}for(\\" +"n)print}put @SD/prcmd{( )exch(\\ndvi.)3{print}repeat prseq}put @SD/cvxall{{cvx" +"}forall}put @SD/defpr{[exch[/copy @SD]cvxall 5 -1 roll dup 6 1 roll[/get/exec]" +"cvxall 6 -1 roll dup 7 1 roll 4 -1 roll dup 5 1 roll dup length string cvs/prc" +"md cvx]cvx def}put @SD/querypos{{currentpoint}stopped{$error/newerror false pu" +"t}{2(querypos)prcmd}ifelse}put @SD/applyscalevals{1 0 transform 0 0 transform " +"3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt 0 1 transform 0 0 transfor" +"m 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt 1 0 transform dup mul ex" +"ch dup dup mul 3 -1 roll add sqrt div 3(applyscalevals)prcmd}put @SD/prpath{{2" +"(moveto)prcmd}{2(lineto)prcmd}{6(curveto)prcmd}{0(closepath)prcmd}pathforall}p" +"ut @SD/charpath{/@dodraw false store :charpath/@dodraw true store}put @SD/show" +"{@dodraw{dup :gsave currentpoint 2{50 mul exch}repeat :newpath moveto 50 50/sc" +"ale sysexec true charpath eofill :grestore/@dodraw false store :show/@dodraw t" +"rue store}{pop}ifelse}put @SD/awidthshow{{1 string dup 0 5 index put :gsave sh" +"ow :grestore pop 0 rmoveto 3 index eq{4 index 4 index rmoveto}if 1 index 1 ind" +"ex rmoveto}exch cshow 5{pop}repeat}put @SD/widthshow{0 0 3 -1 roll pstack awid" +"thshow}put @SD/ashow{0 0 0 6 3 roll awidthshow}put @SD/newpath{:newpath 0 1(ne" +"wpath)prcmd}put @SD/stroke{@dodraw{1 1(newpath)prcmd prpath 0(stroke)prcmd :ne" +"wpath}{:stroke}ifelse}put @SD/fill{@dodraw{1 1(newpath)prcmd prpath 0(fill)prc" +"md :newpath}{:fill}ifelse}put @SD/eofill{@dodraw{1 1(newpath)prcmd prpath 0(eo" +"fill)prcmd :newpath}{:eofill}ifelse}put @SD/clip{:clip 0 1(newpath)prcmd prpat" +"h 0(clip)prcmd}put @SD/eoclip{:eoclip 1 1(newpath)prcmd prpath 0(eoclip)prcmd}" +"put @SD/shfill{begin currentdict/ShadingType known currentdict/ColorSpace know" +"n and currentdict/DataSource known and currentdict/Function known not and Shad" +"ingType 4 ge and DataSource type/arraytype eq and{<>begin currentdict ColorSpace known{ShadingType ColorSpace load bgknown{1 B" +"ackground aload pop}{0}ifelse bbknown{1 BBox aload pop}{0}ifelse ShadingType 5" +" eq{VerticesPerRow}if DataSource aload length 4 add bgknown{ColorSpace load ad" +"d}if bbknown{4 add}if ShadingType 5 eq{1 add}if(shfill)prcmd}if end}if end}put" +"/@rect{4 -2 roll moveto exch dup 0 rlineto exch 0 exch rlineto neg 0 rlineto c" +"losepath}bind def/@rectcc{4 -2 roll moveto 2 copy 0 lt exch 0 lt xor{dup 0 exc" +"h rlineto exch 0 rlineto neg 0 exch rlineto}{exch dup 0 rlineto exch 0 exch rl" +"ineto neg 0 rlineto}ifelse closepath}bind def @SD/rectclip{:newpath dup type/a" +"rraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectcc}ifelse clip :newpath}p" +"ut @SD/rectfill{gsave :newpath dup type/arraytype eq{aload length 4 idiv{@rect" +"cc}repeat}{@rectcc}ifelse fill grestore}put @SD/rectstroke{gsave :newpath dup " +"type/arraytype eq{aload length 4 idiv{@rect}repeat}{@rect}ifelse stroke gresto" +"re}put false setglobal @SD readonly pop/initclip 0 defpr/clippath 0 defpr/syse" +"xec{@SD exch get exec}def/adddot{dup length 1 add string dup 0 46 put dup 3 -1" +" roll 1 exch putinterval}def/setlinewidth{dup/setlinewidth sysexec applyscalev" +"als 1(setlinewidth)prcmd}def/setlinecap 1 defpr/setlinejoin 1 defpr/setmiterli" +"mit 1 defpr/setdash{mark 3 1 roll 2 copy/setdash sysexec applyscalevals exch a" +"load length 1 add -1 roll counttomark(setdash)prcmd pop}def/setgstate{currentl" +"inewidth 1(setlinewidth)prcmd currentlinecap 1(setlinecap)prcmd currentlinejoi" +"n 1(setlinejoin)prcmd currentmiterlimit 1(setmiterlimit)prcmd currentrgbcolor " +"3(setrgbcolor)prcmd 6 array currentmatrix aload pop 6(setmatrix)prcmd currentd" +"ash mark 3 1 roll exch aload length 1 add -1 roll counttomark(setdash)prcmd po" +"p}def/save{@UD begin/@saveID vmstatus pop pop def end :save @saveID 1(save)prc" +"md}def/restore{:restore setgstate @UD/@saveID known{@UD begin @saveID end}{0}i" +"felse 1(restore)prcmd}def/gsave 0 defpr/grestore{:grestore setgstate 0(grestor" +"e)prcmd}def/grestoreall{:grestoreall setstate 0(grestoreall)prcmd}def/rotate{d" +"up type/arraytype ne{dup 1(rotate)prcmd}if/rotate sysexec}def/scale{dup type/a" +"rraytype ne{2 copy 2(scale)prcmd}if/scale sysexec}def/translate{dup type/array" +"type ne{2 copy 2(translate)prcmd}if/translate sysexec}def/setmatrix{dup/setmat" +"rix sysexec aload pop 6(setmatrix)prcmd}def/initmatrix{matrix setmatrix}def/co" +"ncat{matrix currentmatrix matrix concatmatrix setmatrix}def/makepattern{gsave<" +">begin dup/XUID[1000000 @patcnt]put mx/makepattern sysexec dup " +"dup begin PatternType @patcnt BBox aload pop XStep YStep PaintType mx aload po" +"p 15(makepattern)prcmd :newpath matrix setmatrix PaintProc 0 1(makepattern)prc" +"md end/@patcnt @patcnt 1 add store end grestore}def/setpattern{begin PatternTy" +"pe 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[currentcolorspace alo" +"ad length -1 roll pop]setcolorspace/setcolor sysexec XUID aload pop exch pop c" +"urrentrgbcolor :grestore 4}ifelse(setpattern)prcmd}{/setpattern sysexec}ifelse" +" end}def/setcolor{dup type/dicttype eq{setpattern}{/setcolor sysexec/currentrg" +"bcolor sysexec setrgbcolor}ifelse}def/setgray 1 defpr/setcmykcolor 4 defpr/set" +"hsbcolor 3 defpr/setrgbcolor 3 defpr/.setopacityalpha{dup/.setopacityalpha sys" +"exec 1(setopacityalpha)prcmd}def "; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c b/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c index e6fb8f149a5..511d9941a25 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c @@ -35,13 +35,26 @@ You can contact the author at : /************************************** * Tuning parameters **************************************/ -/* Unaligned memory access is automatically enabled for "common" CPU, such as x86. - * For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. - * If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. - * You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). +/* XXH_FORCE_MEMORY_ACCESS + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets which generate assembly depending on alignment. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See http://stackoverflow.com/a/32095106/646947 for details. + * Prefer these methods in priority order (0 > 1 > 2) */ -#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_USE_UNALIGNED_ACCESS 1 +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define XXH_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || \ + (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif #endif /* XXH_ACCEPT_NULL_INPUT_POINTER : @@ -55,12 +68,21 @@ You can contact the author at : * By default, xxHash library provides endian-independant Hash values, based on little-endian convention. * Results are therefore identical for little-endian and big-endian CPU. * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. - * Should endian-independance be of no importance for your application, you may set the #define below to 1. - * It will improve speed for Big-endian CPU. + * Should endian-independance be of no importance for your application, you may set the #define below to 1, + * to improve speed for Big-endian CPU. * This option has no impact on Little_Endian CPU. */ #define XXH_FORCE_NATIVE_FORMAT 0 +/* XXH_USELESS_ALIGN_BRANCH : + * This is a minor performance trick, only useful with lots of very small keys. + * It means : don't make a test between aligned/unaligned, because performance will be the same. + * It saves one initial branch per hash. + */ +#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +# define XXH_USELESS_ALIGN_BRANCH 1 +#endif + /************************************** * Compiler Specific Options @@ -113,20 +135,43 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp typedef unsigned long long U64; #endif + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } +static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign; + +static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } +static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } + +#else + +/* portable and safe solution. Generally efficient. + * see : http://stackoverflow.com/a/32095106/646947 + */ + static U32 XXH_read32(const void* memPtr) { - U32 val32; - memcpy(&val32, memPtr, 4); - return val32; + U32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; } static U64 XXH_read64(const void* memPtr) { - U64 val64; - memcpy(&val64, memPtr, 8); - return val64; + U64 val; + memcpy(&val, memPtr, sizeof(val)); + return val; } +#endif // XXH_FORCE_DIRECT_MEMORY_ACCESS /****************************************** @@ -175,8 +220,10 @@ static U64 XXH_swap64 (U64 x) * Architecture Macros ***************************************/ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; -#ifndef XXH_CPU_LITTLE_ENDIAN /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example using a compiler switch */ -static const int one = 1; + +/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example one the compiler command line */ +#ifndef XXH_CPU_LITTLE_ENDIAN + static const int one = 1; # define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one)) #endif @@ -315,7 +362,7 @@ FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH } -unsigned XXH32 (const void* input, size_t len, unsigned seed) +unsigned int XXH32 (const void* input, size_t len, unsigned int seed) { #if 0 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ @@ -326,7 +373,7 @@ unsigned XXH32 (const void* input, size_t len, unsigned seed) #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; -# if !defined(XXH_USE_UNALIGNED_ACCESS) +# if !defined(XXH_USELESS_ALIGN_BRANCH) if ((((size_t)input) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */ { if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) @@ -466,7 +513,7 @@ unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; -# if !defined(XXH_USE_UNALIGNED_ACCESS) +# if !defined(XXH_USELESS_ALIGN_BRANCH) if ((((size_t)input) & 7)==0) /* Input is aligned, let's leverage the speed advantage */ { if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) @@ -538,7 +585,7 @@ XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) /*** Hash feed ***/ -XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed) +XXH_errorcode XXH32_reset(XXH32_state_t* state_in, unsigned int seed) { XXH_istate32_t* state = (XXH_istate32_t*) state_in; state->seed = seed; @@ -708,7 +755,7 @@ FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endiane } -U32 XXH32_digest (const XXH32_state_t* state_in) +unsigned int XXH32_digest (const XXH32_state_t* state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; diff --git a/Build/source/texk/dvisvgm/version.ac b/Build/source/texk/dvisvgm/version.ac index c48fac49e88..61e0009d87d 100644 --- a/Build/source/texk/dvisvgm/version.ac +++ b/Build/source/texk/dvisvgm/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current dvisvgm version -m4_define([dvisvgm_version], [1.12]) +m4_define([dvisvgm_version], [1.13]) -- cgit v1.2.3