diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2016-07-04 22:07:54 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2016-07-04 22:07:54 +0000 |
commit | ab399d16f49b986d1de514b2fb8434872decf91d (patch) | |
tree | 6d3d0faca673d7aa1c0f48ca679ce7841a82e3df /Build/source/texk/dvisvgm | |
parent | dd2749b37f7b6a9976869e29a028eeab80d686df (diff) |
dvisvgm 1.16
git-svn-id: svn://tug.org/texlive/trunk@41628 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvisvgm')
110 files changed, 3072 insertions, 2041 deletions
diff --git a/Build/source/texk/dvisvgm/ChangeLog b/Build/source/texk/dvisvgm/ChangeLog index a949ee00430..a1d8173d99a 100644 --- a/Build/source/texk/dvisvgm/ChangeLog +++ b/Build/source/texk/dvisvgm/ChangeLog @@ -1,3 +1,8 @@ +2016-07-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp> + + * Imported release 1.16 + * version.ac, Makefile.am: Adapted. + 2016-04-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp> * Imported release 1.15.1 diff --git a/Build/source/texk/dvisvgm/Makefile.am b/Build/source/texk/dvisvgm/Makefile.am index 8d33b3fa28f..d10a15650be 100644 --- a/Build/source/texk/dvisvgm/Makefile.am +++ b/Build/source/texk/dvisvgm/Makefile.am @@ -100,6 +100,7 @@ nodist_libdvisvgm_a_SOURCES = \ @DVISVGM_TREE@/src/Message.cpp \ @DVISVGM_TREE@/src/MetafontWrapper.cpp \ @DVISVGM_TREE@/src/NoPsSpecialHandler.cpp \ + @DVISVGM_TREE@/src/PapersizeSpecialHandler.cpp \ @DVISVGM_TREE@/src/PSInterpreter.cpp \ @DVISVGM_TREE@/src/PSPattern.cpp \ @DVISVGM_TREE@/src/PSPreviewFilter.cpp \ @@ -112,7 +113,12 @@ nodist_libdvisvgm_a_SOURCES = \ @DVISVGM_TREE@/src/PsSpecialHandler.cpp \ @DVISVGM_TREE@/src/psdefs.cpp \ @DVISVGM_TREE@/src/RangeMap.cpp \ + @DVISVGM_TREE@/src/SVGCharHandler.cpp \ + @DVISVGM_TREE@/src/SVGCharHandlerFactory.cpp \ + @DVISVGM_TREE@/src/SVGCharPathHandler.cpp \ + @DVISVGM_TREE@/src/SVGCharTspanTextHandler.cpp \ @DVISVGM_TREE@/src/SVGOutput.cpp \ + @DVISVGM_TREE@/src/SVGSingleCharTextHandler.cpp \ @DVISVGM_TREE@/src/SVGTree.cpp \ @DVISVGM_TREE@/src/ShadingPatch.cpp \ @DVISVGM_TREE@/src/SignalHandler.cpp \ diff --git a/Build/source/texk/dvisvgm/Makefile.in b/Build/source/texk/dvisvgm/Makefile.in index cd074d8622f..ce3370a4925 100644 --- a/Build/source/texk/dvisvgm/Makefile.in +++ b/Build/source/texk/dvisvgm/Makefile.in @@ -184,6 +184,7 @@ nodist_libdvisvgm_a_OBJECTS = \ @DVISVGM_TREE@/src/Message.$(OBJEXT) \ @DVISVGM_TREE@/src/MetafontWrapper.$(OBJEXT) \ @DVISVGM_TREE@/src/NoPsSpecialHandler.$(OBJEXT) \ + @DVISVGM_TREE@/src/PapersizeSpecialHandler.$(OBJEXT) \ @DVISVGM_TREE@/src/PSInterpreter.$(OBJEXT) \ @DVISVGM_TREE@/src/PSPattern.$(OBJEXT) \ @DVISVGM_TREE@/src/PSPreviewFilter.$(OBJEXT) \ @@ -196,7 +197,12 @@ nodist_libdvisvgm_a_OBJECTS = \ @DVISVGM_TREE@/src/PsSpecialHandler.$(OBJEXT) \ @DVISVGM_TREE@/src/psdefs.$(OBJEXT) \ @DVISVGM_TREE@/src/RangeMap.$(OBJEXT) \ + @DVISVGM_TREE@/src/SVGCharHandler.$(OBJEXT) \ + @DVISVGM_TREE@/src/SVGCharHandlerFactory.$(OBJEXT) \ + @DVISVGM_TREE@/src/SVGCharPathHandler.$(OBJEXT) \ + @DVISVGM_TREE@/src/SVGCharTspanTextHandler.$(OBJEXT) \ @DVISVGM_TREE@/src/SVGOutput.$(OBJEXT) \ + @DVISVGM_TREE@/src/SVGSingleCharTextHandler.$(OBJEXT) \ @DVISVGM_TREE@/src/SVGTree.$(OBJEXT) \ @DVISVGM_TREE@/src/ShadingPatch.$(OBJEXT) \ @DVISVGM_TREE@/src/SignalHandler.$(OBJEXT) \ @@ -769,6 +775,7 @@ nodist_libdvisvgm_a_SOURCES = @DVISVGM_TREE@/src/BasicDVIReader.cpp \ @DVISVGM_TREE@/src/Matrix.cpp @DVISVGM_TREE@/src/Message.cpp \ @DVISVGM_TREE@/src/MetafontWrapper.cpp \ @DVISVGM_TREE@/src/NoPsSpecialHandler.cpp \ + @DVISVGM_TREE@/src/PapersizeSpecialHandler.cpp \ @DVISVGM_TREE@/src/PSInterpreter.cpp \ @DVISVGM_TREE@/src/PSPattern.cpp \ @DVISVGM_TREE@/src/PSPreviewFilter.cpp \ @@ -780,7 +787,12 @@ nodist_libdvisvgm_a_SOURCES = @DVISVGM_TREE@/src/BasicDVIReader.cpp \ @DVISVGM_TREE@/src/Process.cpp \ @DVISVGM_TREE@/src/PsSpecialHandler.cpp \ @DVISVGM_TREE@/src/psdefs.cpp @DVISVGM_TREE@/src/RangeMap.cpp \ + @DVISVGM_TREE@/src/SVGCharHandler.cpp \ + @DVISVGM_TREE@/src/SVGCharHandlerFactory.cpp \ + @DVISVGM_TREE@/src/SVGCharPathHandler.cpp \ + @DVISVGM_TREE@/src/SVGCharTspanTextHandler.cpp \ @DVISVGM_TREE@/src/SVGOutput.cpp \ + @DVISVGM_TREE@/src/SVGSingleCharTextHandler.cpp \ @DVISVGM_TREE@/src/SVGTree.cpp \ @DVISVGM_TREE@/src/ShadingPatch.cpp \ @DVISVGM_TREE@/src/SignalHandler.cpp \ @@ -1024,6 +1036,9 @@ libclipper.a: $(libclipper_a_OBJECTS) $(libclipper_a_DEPENDENCIES) $(EXTRA_libcl @DVISVGM_TREE@/src/NoPsSpecialHandler.$(OBJEXT): \ @DVISVGM_TREE@/src/$(am__dirstamp) \ @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) +@DVISVGM_TREE@/src/PapersizeSpecialHandler.$(OBJEXT): \ + @DVISVGM_TREE@/src/$(am__dirstamp) \ + @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) @DVISVGM_TREE@/src/PSInterpreter.$(OBJEXT): \ @DVISVGM_TREE@/src/$(am__dirstamp) \ @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) @@ -1060,9 +1075,24 @@ libclipper.a: $(libclipper_a_OBJECTS) $(libclipper_a_DEPENDENCIES) $(EXTRA_libcl @DVISVGM_TREE@/src/RangeMap.$(OBJEXT): \ @DVISVGM_TREE@/src/$(am__dirstamp) \ @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) +@DVISVGM_TREE@/src/SVGCharHandler.$(OBJEXT): \ + @DVISVGM_TREE@/src/$(am__dirstamp) \ + @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) +@DVISVGM_TREE@/src/SVGCharHandlerFactory.$(OBJEXT): \ + @DVISVGM_TREE@/src/$(am__dirstamp) \ + @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) +@DVISVGM_TREE@/src/SVGCharPathHandler.$(OBJEXT): \ + @DVISVGM_TREE@/src/$(am__dirstamp) \ + @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) +@DVISVGM_TREE@/src/SVGCharTspanTextHandler.$(OBJEXT): \ + @DVISVGM_TREE@/src/$(am__dirstamp) \ + @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) @DVISVGM_TREE@/src/SVGOutput.$(OBJEXT): \ @DVISVGM_TREE@/src/$(am__dirstamp) \ @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) +@DVISVGM_TREE@/src/SVGSingleCharTextHandler.$(OBJEXT): \ + @DVISVGM_TREE@/src/$(am__dirstamp) \ + @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) @DVISVGM_TREE@/src/SVGTree.$(OBJEXT): \ @DVISVGM_TREE@/src/$(am__dirstamp) \ @DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp) @@ -1260,6 +1290,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/Message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/MetafontWrapper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/NoPsSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PapersizeSpecialHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PSInterpreter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PSPattern.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PSPreviewFilter.Po@am__quote@ @@ -1271,7 +1302,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/Process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PsSpecialHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/RangeMap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharHandlerFactory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharPathHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharTspanTextHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGOutput.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGSingleCharTextHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGTree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/ShadingPatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SignalHandler.Po@am__quote@ diff --git a/Build/source/texk/dvisvgm/configure b/Build/source/texk/dvisvgm/configure index 453689f3ecb..27d7cbebdc8 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.15.1. +# Generated by GNU Autoconf 2.69 for dvisvgm (TeX Live) 1.16. # # Report bugs to <tex-k@tug.org>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvisvgm (TeX Live)' PACKAGE_TARNAME='dvisvgm--tex-live-' -PACKAGE_VERSION='1.15.1' -PACKAGE_STRING='dvisvgm (TeX Live) 1.15.1' +PACKAGE_VERSION='1.16' +PACKAGE_STRING='dvisvgm (TeX Live) 1.16' 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.15.1 to adapt to many kinds of systems. +\`configure' configures dvisvgm (TeX Live) 1.16 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.15.1:";; + short | recursive ) echo "Configuration of dvisvgm (TeX Live) 1.16:";; 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.15.1 +dvisvgm (TeX Live) configure 1.16 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.15.1, which was +It was created by dvisvgm (TeX Live) $as_me 1.16, 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.15.1' + VERSION='1.16' cat >>confdefs.h <<_ACEOF @@ -18321,7 +18321,7 @@ Usage: $0 [OPTIONS] Report bugs to <bug-libtool@gnu.org>." lt_cl_version="\ -dvisvgm (TeX Live) config.lt 1.15.1 +dvisvgm (TeX Live) config.lt 1.16 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.15.1, which was +This file was extended by dvisvgm (TeX Live) $as_me 1.16, 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.15.1 +dvisvgm (TeX Live) config.status 1.16 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog index 543120b2ece..81b1079b62e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog +++ b/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog @@ -1,3 +1,8 @@ +2016-07-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp> + + * Import release 1.16 + * patch-01-process: removed since it is included in the upstream. + 2016-04-25 Karl Berry <karl@tug.org> * patch-01-process: received from dvisvgm author. diff --git a/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes b/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes index 2090d818915..5496c8e2bc5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes +++ b/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes @@ -1,9 +1,6 @@ -Changes applied to the dvisvgm-1.15.1 tree as obtained from: +Changes applied to the dvisvgm-1.16 tree as obtained from: http://dvisvgm.bplaced.net/Downloads -patch-01-process: received from dvisvgm author for TL16, -should be in next release. - Removed: Makefile.in aclocal.m4 diff --git a/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process b/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process deleted file mode 100644 index 3cf8bd39eb1..00000000000 --- a/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/src/Process.cpp b/src/Process.cpp ---- a/src/Process.cpp -+++ b/src/Process.cpp -@@ -173,8 +173,6 @@ - if (pid > 0) { // parent process - for (;;) { - if (out) { -- // -- out->clear(); - char buf[512]; - ssize_t len; - while ((len = read(pipefd[0], buf, sizeof(buf)-1)) > 0) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog index fd37d4d9f83..a166d825993 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog +++ b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog @@ -1,3 +1,58 @@ +2016-04-19 Martin Gieseking <martin.gieseking@uos.de> + + * NEWS, README, README.md: + updated NEWS and README + + * .travis.yml, configure.ac, src/CommandLine.cpp, src/Doxyfile: + set version to 1.15.1 + +2016-04-18 Martin Gieseking <martin.gieseking@uos.de> + + * tests/CMapReaderTest.cpp: + improved CMapReaderTest + + * src/Matrix.cpp: + avoid adding trailing EOF characters when parsing parameters of + transformation commands + + * src/Calculator.cpp, src/Matrix.cpp: + use std::ws to skip whitespace in istreams + +2016-04-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/AGLTable.h, src/Makefile.am, src/Unicode.cpp, tests/Makefile.am, + tests/create-makefile, tests/genhashcheck.py: + moved AGL hash table from Unicode.cpp to a separate file + +2016-04-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/Unicode.cpp, tests/UnicodeTest.cpp: + added support for the AGL character names 'uniFOO' and 'uFOO' + + * src/XMLDocument.cpp: + explicitly specify UTF-8 encoding in XML declaration (closes #54) + +2016-03-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicsPath.h: + renamed GraphicsPath::sconito/scubicto + +2016-03-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/SVGTree.cpp, src/SVGTree.h: + split text and path section of SVGTree::appendChar() into seperate + methods + + * src/DVIActions.h, src/DVIReader.cpp, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.h, src/SVGTree.cpp, src/SVGTree.h: + changed font parameter of setFont() methods from pointer to reference + + * doc/db2html.xsl: + adapted db2html to insert anchors for each option entry + + * transfer-cs: + remove patch files after they've been transferred + 2016-02-27 Martin Gieseking <martin.gieseking@uos.de> * NEWS: @@ -646,9 +701,9 @@ * doc/dvisvgm.txt.in: minor additions and formatting changes of the manpage - * src/DVIToSVG.cpp, src/EPSToSVG.cpp, src/Makefile.am, src/SVGOutput.cpp, - src/SVGOutput.h, src/SVGOutputBase.h, src/dvisvgm.cpp: - moved class SVGOutput to separate compilation unit + * doc/dvisvgm.txt.in, src/SVGOutput.cpp, src/SVGOutput.h, + tests/Makefile.am, tests/SVGOutputTest.cpp, tests/create-makefile: + added width specifiers and exression evaluation to --output patterns 2015-02-19 Martin Gieseking <martin.gieseking@uos.de> @@ -674,6 +729,11 @@ * src/TpicSpecialHandler.cpp: use constant M_PI rather than computing PI locally +2015-02-17 Martin Gieseking <martin.gieseking@uos.de> + + * README, README.md: + updated README and README.md + 2015-01-21 Martin Gieseking <martin.gieseking@uos.de> * src/TensorProductPatch.cpp, src/TriangularPatch.cpp: @@ -989,8 +1049,10 @@ Breaks standard things * src/XMLDocument.cpp, src/XMLDocument.h, src/XMLNode.cpp, src/XMLNode.h: removed unused emit() methods from XML classes - * src/dvisvgm.cpp: - removed old code that moved cache files to new location +2014-08-06 Martin Gieseking <martin.gieseking@uos.de> + + * README.md: + minor fixes to README.md 2014-07-31 Martin Gieseking <martin.gieseking@uos.de> @@ -1632,10 +1694,10 @@ Breaks standard things replaced local std::map tables used in Font classes with new class CharMap -2013-08-23 Martin Gieseking <martin.gieseking@uos.de> +2013-08-22 Martin Gieseking <martin.gieseking@uos.de> - * src/SVGTree.cpp: - appended px unit to font-size attributes in style section + * src/XMLString.cpp: + replace very small floating point numbers by 0 2013-08-20 Martin Gieseking <martin.gieseking@uos.de> @@ -1938,9 +2000,8 @@ Breaks standard things src/VFReader.cpp: added missing member initializations to some classes - * doc/dvisvgm.txt.in, src/CmdLineParserBase.cpp, src/CommandLine.cpp, - src/options.dtd, src/options.xml: - added information about 'dvisvgm -E' to usage line + * src/DVIToSVG.cpp, src/EPSToSVG.cpp, src/dvisvgm.cpp: + avoid output of empty parentheses if TARGET_SYSTEM is not set 2013-04-20 Martin Gieseking <martin.gieseking@uos.de> @@ -2033,21 +2094,11 @@ Breaks standard things added methods to lookup attribute values and selected descendant XML nodes - * src/XMLNode.cpp, src/XMLNode.h: - added virtual constructor XMLNode::clone() - 2013-02-19 Martin Gieseking <martin.gieseking@uos.de> * src/FilePath.cpp: adapt path separators on Windows systems to get the correct output path - * doc/dvisvgm.txt.in, src/CommandLine.cpp, src/CommandLine.h, - src/DVIToSVG.cpp, src/DVIToSVG.h, src/EPSFile.cpp, src/EPSFile.h, - src/EPSToSVG.cpp, src/EPSToSVG.h, src/Makefile.am, - src/PsSpecialHandler.cpp, src/SVGOutputBase.h, src/dvisvgm.cpp, - src/options.xml: - add option to directly convert EPS files to SVG - * src/PSInterpreter.cpp, src/PSInterpreter.h: added PSInterpreter::limit() to limit the number of bytes to be processed @@ -2064,6 +2115,15 @@ Breaks standard things src/CommandLine.cpp, src/CommandLine.h, src/dvisvgm.cpp, src/options.xml: added optional parameter to option --help to specify output format +2013-02-06 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.txt.in, src/BoundingBox.cpp, src/CommandLine.cpp, + src/CommandLine.h, src/EmSpecialHandler.cpp, src/GraphicPath.h, + src/Matrix.cpp, src/PsSpecialHandler.cpp, src/TpicSpecialHandler.cpp, + src/XMLString.cpp, src/XMLString.h, src/dvisvgm.cpp, src/options.xml: + added option --precision to set the number of decimal places applied to + attribute values + 2013-01-30 Martin Gieseking <martin.gieseking@uos.de> * src/CommandLine.cpp: @@ -2300,6 +2360,11 @@ Breaks standard things tests/StreamInputBufferTest.cpp: some refactorings of class InputReader; added InputReader::find() +2012-10-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVG.cpp, src/DVIToSVG.h, src/dvisvgm.cpp: + don't show warning about disabled PS support in list of special handlers + 2012-09-27 Martin Gieseking <martin.gieseking@uos.de> * doc/Makefile.am: @@ -2316,21 +2381,19 @@ Breaks standard things * src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: removed Ghostscript info from ps entry in list of special handlers -2012-09-19 Martin Gieseking <martin.gieseking@uos.de> - - * src/psdefs.ps, src/psdefs.psc: - ignore dvips bop operators that might be present in PS specials - -2012-09-17 Martin Gieseking <martin.gieseking@uos.de> - - * src/StreamReader.cpp: - fixed reading invalid number of string characters + * src/DVIToSVG.cpp: + show warning if processing of PS specials is disabled 2012-06-06 Martin Gieseking <martin.gieseking@uos.de> * src/gfprint.mak: fixed bugs in gfprint, and added gfprint.mak for easier builds +2012-04-17 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am: + keep manpage when calling 'make clean' or 'make distclean' + 2012-04-04 Martin Gieseking <martin.gieseking@uos.de> * src/DVIToSVGActions.cpp, src/SVGTree.cpp, src/SVGTree.h, @@ -2385,6 +2448,15 @@ Breaks standard things * README: updated information about bug reporting +2012-01-26 Martin Gieseking <martin.gieseking@uos.de> + + * src/CmdLineParserBase.h, src/DVIActions.h, src/DVIReader.h, + src/DVIToSVGActions.h, src/FontEngine.h, src/FontManager.h, + src/MetafontWrapper.h, src/SVGTree.h, src/SpecialActions.h, + src/SpecialHandler.h, src/SpecialManager.h, src/TFM.h, src/VFReader.h: + adapt forward declarations of classes and structs to their corresponding + definition (SF bug #3480013) + 2012-01-09 Martin Gieseking <martin.gieseking@uos.de> * src/TpicSpecialHandler.cpp: @@ -3234,10 +3306,6 @@ Breaks standard things src/SVGFontEmitter.cpp, src/SVGFontEmitter.h: removed class Glyph and incorporated its functionality into Font class - * src/Font.h, src/FontEncoding.cpp, src/FontEncoding.h, - src/FontManager.cpp, src/FontManager.h, src/SVGFontEmitter.cpp: - moved method encoding() from class FontManager to class FontEncoding - 2010-02-05 Martin Gieseking <martin.gieseking@uos.de> * src/DVIToSVG.cpp: @@ -3465,10 +3533,10 @@ Breaks standard things * src/GraphicPath.h, src/PsSpecialHandler.cpp: PS handler: replace zero-length paths by dots -2009-10-25 Martin Gieseking <martin.gieseking@uos.de> +2009-10-29 Martin Gieseking <martin.gieseking@uos.de> - * src/DvisvgmSpecialHandler.cpp: - added macro {?nl} to dvisvgm:raw evaluator + * src/DVIToSVGActions.cpp, src/Font.cpp, src/Font.h: + fixed positioning of italic characters 2009-10-18 Martin Gieseking <martin.gieseking@uos.de> @@ -3633,25 +3701,25 @@ Breaks standard things * NEWS, src/PsSpecialHandler.cpp: fixed another positioning bug reported by John Bowman -2009-10-04 Martin Gieseking <martin.gieseking@uos.de> + * src/PsSpecialHandler.cpp: + convert PS path coordinated to TeX point units - * src/Makefile.old, src/Makefile.orig: - renamed the old original Makefile +2009-10-04 Martin Gieseking <martin.gieseking@uos.de> * src/GraphicPath.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: corrected positioning bug introduced with previous PS positioning fix - * src/DVIReader.cpp, src/DVIReader.h, src/DVIToSVGActions.cpp, - src/DVIToSVGActions.h, src/PsSpecialHandler.cpp, src/PsSpecialHandler.h, - src/SpecialActions.h, src/psdefs.ps, src/psdefs.psc: - fixed positioning bug reported by John Bowman - 2009-10-02 Martin Gieseking <martin.gieseking@uos.de> * doc/Makefile.am, doc/dvisvgm.txt.in: generate pdf manpage directly with groff; adapted manpage source to work with latest asciidoc +2009-10-01 Martin Gieseking <martin.gieseking@uos.de> + + * doc/Makefile.am, doc/dvisvgm.txt.in: + replaced backticks in manpage by apostrophes; updated date on homepage + 2009-09-30 Martin Gieseking <martin.gieseking@uos.de> * Makefile.am, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: @@ -3663,17 +3731,13 @@ Breaks standard things * doc/dvisvgm.txt.in: added dvisvgm:raw example to man page - * src/DvisvgmSpecialHandler.cpp: - added optional depth parameter to special dvisvgm:raw - 2009-09-17 Martin Gieseking <martin.gieseking@uos.de> * doc/dvisvgm.txt.in: minor changes of the documentation - * doc/dvisvgm.txt.in: - corrected info about --verbosity in manual page (reported by John - Bowman) + * fedora/dvisvgm.spec: + updated spec file and fixed typo on website * src/PsSpecialHandler.h: increased the default linewidth to 0.5 @@ -3770,21 +3834,14 @@ Breaks standard things src/SpecialManager.cpp, src/SpecialManager.h: PS prologue files referenced in first page are now always loaded - * fedora/dvisvgm-0.8.1-potrace.patch, fedora/dvisvgm-gs.patch, - fedora/dvisvgm-potrace.patch, fedora/dvisvgm.spec: - updated Fedora files - * configure.ac, fedora/dvisvgm.spec, src/Ghostscript.cpp, src/Ghostscript.h, src/Makefile.am: improved Ghostscript and potrace linking checks to simplify usage of external devel files -2009-08-25 Martin Gieseking <martin.gieseking@uos.de> - - * configure.ac, src/DVIToSVGActions.cpp, src/Ghostscript.cpp, - src/Ghostscript.h: - added configuration method to directly bind the Ghostscript shared - library + * fedora/dvisvgm-0.8.1-potrace.patch, fedora/dvisvgm-gs.patch, + fedora/dvisvgm-potrace.patch, fedora/dvisvgm.spec: + updated Fedora files 2009-08-24 Martin Gieseking <martin.gieseking@uos.de> @@ -4169,10 +4226,10 @@ Breaks standard things 2009-02-25 Martin Gieseking <martin.gieseking@uos.de> - * configure.ac, doc/Makefile.am, doc/caution.png, doc/dvisvgm.1.in, - doc/dvisvgm.txt, doc/note.png: - replaced manually written dvisvgm.1.in by an asciidoc file - (dvisvgm.txt.in) + * src/DVIToSVGActions.cpp, src/DVIToSVGActions.h, + src/DvisvgmSpecialHandler.cpp, src/EmSpecialHandler.cpp, + src/SpecialActions.h, src/TpicSpecialHandler.cpp: + renamed appendInPage() to appendToPage 2009-02-24 Martin Gieseking <martin.gieseking@uos.de> @@ -4232,14 +4289,9 @@ Breaks standard things 2009-02-17 Martin Gieseking <martin.gieseking@uos.de> - * src/BoundingBox.cpp, src/ColorSpecialHandler.cpp, - src/ColorSpecialHandler.h, src/DVIToSVGActions.cpp, src/FontGlyph.cpp, - src/InputBuffer.cpp, src/InputBuffer.h, src/Makefile.am, src/Pair.h, - src/SpecialActions.h, src/SpecialColorHandler.cpp, - src/SpecialColorHandler.h, src/SpecialEmHandler.cpp, - src/SpecialEmHandler.h, src/TransformationMatrix.cpp, - src/tests/ColorSpecialTest.h: - added skeleton of em special handler; doesn't work yet + * src/DVIReader.cpp: + made DVICommand local to executeCommand, removed unnecessary if + statement 2009-02-15 Martin Gieseking <martin.gieseking@uos.de> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS index 03e6d8f38c4..297dae9de84 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS +++ b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS @@ -1,3 +1,13 @@ +dvisvgm-1.16 (2016-07-04) +- added support of XDV version 7 introduced by XeTeX 0.99995 +- added optional processing of papersize specials +- added support of length units cc, dd, and sp +- fixed unit conversion in computation of bounding boxes +- fixed propagation of resolution value to the glyph vectorizer +- fixed transformation of background rectangle +- prevent processing of corrupted GF files +- major refactorings of the DVI reader and the SVG backend + dvisvgm-1.15.1 (2016-04-19) - added explicit encoding attribute to the XML declaration again (GH bug #54) - added support for AGL character names of the form 'uFOO' and 'uniFOO' diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac index 02c83516a5d..ecd3830be4e 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.15.1],[martin.gieseking@uos.de]) -DATE="April 2016" +AC_INIT([dvisvgm],[1.16],[martin.gieseking@uos.de]) +DATE="July 2016" 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 39685ee890d..3fa4e8a683f 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 <martin.gieseking@uos.de> .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 04/19/2016 +.\" Date: 07/04/2016 .\" Manual: dvisvgm Manual -.\" Source: dvisvgm 1.15.1 +.\" Source: dvisvgm 1.16 .\" Language: English .\" -.TH "DVISVGM" "1" "04/19/2016" "dvisvgm 1\&.15\&.1" "dvisvgm Manual" +.TH "DVISVGM" "1" "07/04/2016" "dvisvgm 1\&.16" "dvisvgm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -36,7 +36,7 @@ dvisvgm \- converts DVI and EPS files to the XML\-based SVG format \fBdvisvgm\fR \-E [ \fIoptions\fR ] \fIfile\fR [\&.eps] .SH "DESCRIPTION" .sp -The command\-line utility \fBdvisvgm\fR converts DVI files, as generated by TeX/LaTeX, to the XML\-based scalable vector graphics format SVG\&. It supports the classic DVI format 2 as well as format 3 (created by pTeX in vertical mode), and the XeTeX formats 5 and 6 which are also known as XDV\&. Besides the basic DVI commands, dvisvgm also evaluates many so\-called \fIspecials\fR which heavily extend the capabilities of the plain DVI format\&. For a more detailed overview, see section \fBSupported Specials\fR below\&. +The command\-line utility \fBdvisvgm\fR converts DVI files, as generated by TeX/LaTeX, to the XML\-based scalable vector graphics format SVG\&. It supports the classic DVI version 2 as well as version 3 (created by pTeX in vertical mode), and the XeTeX versions 5 to 7 which are also known as XDV\&. Besides the basic DVI commands, dvisvgm also evaluates many so\-called \fIspecials\fR which heavily extend the capabilities of the plain DVI format\&. For a more detailed overview, see section \fBSupported Specials\fR below\&. .sp Since the current SVG standard 1\&.1 doesn\(cqt specify multi\-page graphics, dvisvgm creates separate SVG files for each DVI page\&. Because of compatibility reasons, only the first page is converted by default\&. In order to select a different page or arbitrary page sequences, use option \fB\-p\fR which is described below\&. .sp @@ -89,7 +89,7 @@ takes either one of the format specifiers listed below, or a sequence of four co \fIy1\fR, \fIx2\fR and -\fIy2\fR\&. The latter define the absolute coordinates of two diagonal corners of the bounding box\&. Each length value consists of a floating point number and an optional length unit (pt, bp, cm, mm, in, or pc)\&. If the unit is omitted, TeX points (pt) are assumed\&. +\fIy2\fR\&. The latter define the absolute coordinates of two diagonal corners of the bounding box\&. Each length value consists of a floating point number and an optional length unit (pt, bp, cm, mm, in, pc, dd, cc, or sp)\&. If the unit is omitted, TeX points (pt) are assumed\&. .sp It\(cqs also possible to give only one length value \fIl\fR\&. In this case, the minimal bounding box is computed and enlarged by adding (\-\fIl\fR,\-\fIl\fR) to the upper left and (\fIl\fR,\fIl\fR) to the lower right corner\&. @@ -115,6 +115,7 @@ tab(:); lt lt lt lt lt lt +lt lt lt lt. T{ \fBdvi\fR @@ -132,9 +133,16 @@ T}:T{ no bounding box is assigned T} T{ +\fBpapersize\fR +T}:T{ +box sizes specified by +\fIpapersize\fR +specials present in the DVI file +T} +T{ \fBpreview\fR T}:T{ -bounding box data computed by the preview package (if present in the dvi file) +bounding box data computed by the preview package (if present in the DVI file) T} .TE .sp 1 @@ -998,6 +1006,15 @@ allows to change this behavior\&. See above for further details\&. Information o hyperref manual (\m[blue]http://www.ctan.org/pkg/hyperref\m[])\&. .RE .PP +\fBpapersize\fR +.RS 4 +The +\fIpapersize\fR +special, which is an extension introduced by dvips, can be used to specify the widths and heights of the pages in the DVI file\&. It affects the page it appears on as well as all following pages until another papersize special is found\&. If there is more than one papersize special present on a page, dvisvgm applies the last one\&. However, in order to stay compatible with previous versions of dvisvgm that did not evaluate these specials, their processing must be explicitly enabled by adding option +\fB\-\-bbox=papersize\fR +on the command\-line\&. Otherwise, dvisvgm ignores them and computes tight bounding boxes\&. +.RE +.PP \fBpdf\fR .RS 4 pdfTeX and dvipdfmx introduced several special commands related to the generation of PDF files\&. Currently, only two of them, 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 2142fdfc4bd..acd8f169642 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in @@ -38,8 +38,8 @@ SYNOPSIS DESCRIPTION ----------- The command-line utility *dvisvgm* converts DVI files, as generated by TeX/LaTeX, to the -XML-based scalable vector graphics format SVG. It supports the classic DVI format 2 as -well as format 3 (created by pTeX in vertical mode), and the XeTeX formats 5 and 6 which are +XML-based scalable vector graphics format SVG. It supports the classic DVI version 2 as +well as version 3 (created by pTeX in vertical mode), and the XeTeX versions 5 to 7 which are also known as XDV. Besides the basic DVI commands, dvisvgm also evaluates many so-called 'specials' which heavily extend the capabilities of the plain DVI format. For a more detailed overview, see section <<specials,*Supported Specials*>> below. @@ -99,8 +99,8 @@ Sets the bounding box of the generated graphic to the specified format. The para takes either one of the format specifiers listed below, or a sequence of four comma- or whitespace-separated length values 'x1', 'y1', 'x2' and 'y2'. The latter define the absolute coordinates of two diagonal corners of the bounding box. Each length value consists of a floating -point number and an optional length unit (pt, bp, cm, mm, in, or pc). If the unit is omitted, -TeX points (pt) are assumed. +point number and an optional length unit (pt, bp, cm, mm, in, pc, dd, cc, or sp). If the unit is +omitted, TeX points (pt) are assumed. + It's also possible to give only one length value 'l'. In this case, the minimal bounding box is computed and enlarged by adding (-'l',-'l') to the upper left and ('l','l') to the lower @@ -120,7 +120,8 @@ Additionally, dvisvgm also supports the following format specifiers: *dvi*::: page size stored in the DVI file *min*::: computes the minimal/tightest bounding box *none*::: no bounding box is assigned - *preview*::: bounding box data computed by the preview package (if present in the dvi file) + *papersize*::: box sizes specified by 'papersize' specials present in the DVI file + *preview*::: bounding box data computed by the preview package (if present in the DVI file) // *Page orientation*;; The default page orientation for DIN/ISO and American paper sizes is 'portrait', @@ -654,6 +655,14 @@ By default, all linked areas of the document are marked by a rectangle. Option * this behavior. See above for further details. Information on syntax and semantics of the HyperTeX specials can be found in the http://www.ctan.org/pkg/hyperref[hyperref manual]. +*papersize*:: +The 'papersize' special, which is an extension introduced by dvips, can be used to specify the widths and +heights of the pages in the DVI file. It affects the page it appears on as well as all following pages until +another papersize special is found. If there is more than one papersize special present on a page, dvisvgm +applies the last one. However, in order to stay compatible with previous versions of dvisvgm that did not +evaluate these specials, their processing must be explicitly enabled by adding option *--bbox=papersize* on +the command-line. Otherwise, dvisvgm ignores them and computes tight bounding boxes. + *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 diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp index 5d50d3c9ae1..fa506dbd994 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp @@ -26,7 +26,7 @@ using namespace std; -BasicDVIReader::BasicDVIReader (std::istream &is) : StreamReader(is), _dviFormat(DVI_NONE) +BasicDVIReader::BasicDVIReader (std::istream &is) : StreamReader(is), _dviVersion(DVI_NONE) { } @@ -45,40 +45,40 @@ int BasicDVIReader::evalCommand (CommandHandler &handler, int ¶m) { doesn't need to know the exact DVI command format. Some cmdFOO methods are used for multiple DVI commands because they only differ in length of their parameters. */ static const DVICommand commands[] = { - {&BasicDVIReader::cmdSetChar, 1}, {&BasicDVIReader::cmdSetChar, 2}, // 128-129 - {&BasicDVIReader::cmdSetChar, 3}, {&BasicDVIReader::cmdSetChar, 4}, // 130-131 - {&BasicDVIReader::cmdSetRule, 8}, // 132 - {&BasicDVIReader::cmdPutChar, 1}, {&BasicDVIReader::cmdPutChar, 2}, // 133-134 - {&BasicDVIReader::cmdPutChar, 3}, {&BasicDVIReader::cmdPutChar, 4}, // 135-136 - {&BasicDVIReader::cmdPutRule, 8}, // 137 - {&BasicDVIReader::cmdNop, 0}, // 138 - {&BasicDVIReader::cmdBop, 44}, {&BasicDVIReader::cmdEop, 0}, // 139-140 - {&BasicDVIReader::cmdPush, 0}, {&BasicDVIReader::cmdPop, 0}, // 141-142 - {&BasicDVIReader::cmdRight, 1}, {&BasicDVIReader::cmdRight, 2}, // 143-144 - {&BasicDVIReader::cmdRight, 3}, {&BasicDVIReader::cmdRight, 4}, // 145-146 - {&BasicDVIReader::cmdW0, 0}, // 147 - {&BasicDVIReader::cmdW, 1}, {&BasicDVIReader::cmdW, 2}, // 148-149 - {&BasicDVIReader::cmdW, 3}, {&BasicDVIReader::cmdW, 4}, // 150-151 - {&BasicDVIReader::cmdX0, 0}, // 152 - {&BasicDVIReader::cmdX, 1}, {&BasicDVIReader::cmdX, 2}, // 153-154 - {&BasicDVIReader::cmdX, 3}, {&BasicDVIReader::cmdX, 4}, // 155-156 - {&BasicDVIReader::cmdDown, 1}, {&BasicDVIReader::cmdDown, 2}, // 157-158 - {&BasicDVIReader::cmdDown, 3}, {&BasicDVIReader::cmdDown, 4}, // 159-160 - {&BasicDVIReader::cmdY0, 0}, // 161 - {&BasicDVIReader::cmdY, 1}, {&BasicDVIReader::cmdY, 2}, // 162-163 - {&BasicDVIReader::cmdY, 3}, {&BasicDVIReader::cmdY, 4}, // 164-165 - {&BasicDVIReader::cmdZ0, 0}, // 166 - {&BasicDVIReader::cmdZ, 1}, {&BasicDVIReader::cmdZ, 2}, // 167-168 - {&BasicDVIReader::cmdZ, 3}, {&BasicDVIReader::cmdZ, 4}, // 169-170 - - {&BasicDVIReader::cmdFontNum, 1}, {&BasicDVIReader::cmdFontNum, 2}, // 235-236 - {&BasicDVIReader::cmdFontNum, 3}, {&BasicDVIReader::cmdFontNum, 4}, // 237-238 - {&BasicDVIReader::cmdXXX, 1}, {&BasicDVIReader::cmdXXX, 2}, // 239-240 - {&BasicDVIReader::cmdXXX, 3}, {&BasicDVIReader::cmdXXX, 4}, // 241-242 - {&BasicDVIReader::cmdFontDef, 1}, {&BasicDVIReader::cmdFontDef, 2}, // 243-244 - {&BasicDVIReader::cmdFontDef, 3}, {&BasicDVIReader::cmdFontDef, 4}, // 245-246 - {&BasicDVIReader::cmdPre, 0}, {&BasicDVIReader::cmdPost, 0}, // 247-248 - {&BasicDVIReader::cmdPostPost, 0}, // 249 + {&BasicDVIReader::cmdSetChar, 1}, {&BasicDVIReader::cmdSetChar, 2}, // 128-129 + {&BasicDVIReader::cmdSetChar, 3}, {&BasicDVIReader::cmdSetChar, 4}, // 130-131 + {&BasicDVIReader::cmdSetRule, 8}, // 132 + {&BasicDVIReader::cmdPutChar, 1}, {&BasicDVIReader::cmdPutChar, 2}, // 133-134 + {&BasicDVIReader::cmdPutChar, 3}, {&BasicDVIReader::cmdPutChar, 4}, // 135-136 + {&BasicDVIReader::cmdPutRule, 8}, // 137 + {&BasicDVIReader::cmdNop, 0}, // 138 + {&BasicDVIReader::cmdBop, 44}, {&BasicDVIReader::cmdEop, 0}, // 139-140 + {&BasicDVIReader::cmdPush, 0}, {&BasicDVIReader::cmdPop, 0}, // 141-142 + {&BasicDVIReader::cmdRight, 1}, {&BasicDVIReader::cmdRight, 2}, // 143-144 + {&BasicDVIReader::cmdRight, 3}, {&BasicDVIReader::cmdRight, 4}, // 145-146 + {&BasicDVIReader::cmdW0, 0}, // 147 + {&BasicDVIReader::cmdW, 1}, {&BasicDVIReader::cmdW, 2}, // 148-149 + {&BasicDVIReader::cmdW, 3}, {&BasicDVIReader::cmdW, 4}, // 150-151 + {&BasicDVIReader::cmdX0, 0}, // 152 + {&BasicDVIReader::cmdX, 1}, {&BasicDVIReader::cmdX, 2}, // 153-154 + {&BasicDVIReader::cmdX, 3}, {&BasicDVIReader::cmdX, 4}, // 155-156 + {&BasicDVIReader::cmdDown, 1}, {&BasicDVIReader::cmdDown, 2}, // 157-158 + {&BasicDVIReader::cmdDown, 3}, {&BasicDVIReader::cmdDown, 4}, // 159-160 + {&BasicDVIReader::cmdY0, 0}, // 161 + {&BasicDVIReader::cmdY, 1}, {&BasicDVIReader::cmdY, 2}, // 162-163 + {&BasicDVIReader::cmdY, 3}, {&BasicDVIReader::cmdY, 4}, // 164-165 + {&BasicDVIReader::cmdZ0, 0}, // 166 + {&BasicDVIReader::cmdZ, 1}, {&BasicDVIReader::cmdZ, 2}, // 167-168 + {&BasicDVIReader::cmdZ, 3}, {&BasicDVIReader::cmdZ, 4}, // 169-170 + + {&BasicDVIReader::cmdFontNum, 1}, {&BasicDVIReader::cmdFontNum, 2}, // 235-236 + {&BasicDVIReader::cmdFontNum, 3}, {&BasicDVIReader::cmdFontNum, 4}, // 237-238 + {&BasicDVIReader::cmdXXX, 1}, {&BasicDVIReader::cmdXXX, 2}, // 239-240 + {&BasicDVIReader::cmdXXX, 3}, {&BasicDVIReader::cmdXXX, 4}, // 241-242 + {&BasicDVIReader::cmdFontDef, 1}, {&BasicDVIReader::cmdFontDef, 2}, // 243-244 + {&BasicDVIReader::cmdFontDef, 3}, {&BasicDVIReader::cmdFontDef, 4}, // 245-246 + {&BasicDVIReader::cmdPre, 0}, {&BasicDVIReader::cmdPost, 0}, // 247-248 + {&BasicDVIReader::cmdPostPost, 0}, // 249 }; const int opcode = readByte(); @@ -95,18 +95,9 @@ int BasicDVIReader::evalCommand (CommandHandler &handler, int ¶m) { handler = &BasicDVIReader::cmdFontNum0; param = opcode-171; } - else if ((_dviFormat == DVI_XDVOLD && opcode >= 251 && opcode <= 254) - || (_dviFormat == DVI_XDVNEW && opcode >= 252 && opcode <= 253)) { // XDV command? - static const CommandHandler handlers[] = { - &BasicDVIReader::cmdXPic, - &BasicDVIReader::cmdXFontDef, - &BasicDVIReader::cmdXGlyphArray, - &BasicDVIReader::cmdXGlyphString - }; - handler = handlers[opcode-251]; - param = 0; - } - else if (_dviFormat == DVI_PTEX && opcode == 255) { // direction command set by pTeX? + else if (evalXDVOpcode(opcode, handler)) + num_param_bytes = 0; + else if (_dviVersion == DVI_PTEX && opcode == 255) { // direction command set by pTeX? handler = &BasicDVIReader::cmdDir; num_param_bytes = 1; } @@ -126,6 +117,36 @@ int BasicDVIReader::evalCommand (CommandHandler &handler, int ¶m) { } +/** Checks if a given opcode belongs to an XDV extension. + * @param[in] op the opcode to check + * @param[out] handler corresponding command handler if opcode is valid */ +bool BasicDVIReader::evalXDVOpcode (int op, CommandHandler &handler) const { + static const struct { + int min, max; // minimal and maximal opcode in XDV section + } xdvranges[] = { + {251, 254}, // XDV5 + {252, 253}, // XDV6 + {252, 254}, // XDV7 + }; + int index = _dviVersion-DVI_XDV5; + if (_dviVersion < DVI_XDV5 || _dviVersion > DVI_XDV7 || op < xdvranges[index].min || op > xdvranges[index].max) + return false; + + static const CommandHandler handlers[] = { + &BasicDVIReader::cmdXPic, + &BasicDVIReader::cmdXFontDef, + &BasicDVIReader::cmdXGlyphArray, + &BasicDVIReader::cmdXTextAndGlyphs, + &BasicDVIReader::cmdXGlyphString + }; + index = op-251; + if (_dviVersion == DVI_XDV5 && op == 254) + index++; + handler = handlers[index]; + return true; +} + + /** Reads a single DVI command from the current position of the input stream and calls the * corresponding cmdFOO method. * @return opcode of the executed command */ @@ -152,29 +173,30 @@ void BasicDVIReader::executePostPost () { if (count < 4) // the standard requires at least 4 trailing fill bytes throw DVIException("missing fill bytes at end of file"); - setDVIFormat((DVIFormat)readUnsigned(1)); + setDVIVersion((DVIVersion)readUnsigned(1)); } void BasicDVIReader::executeAllPages () { - if (_dviFormat == DVI_NONE) + if (_dviVersion == DVI_NONE) executePostPost(); // get version ID from post_post seek(0); // go to preamble while (executeCommand() != 248); // execute all commands until postamble is reached } -void BasicDVIReader::setDVIFormat (DVIFormat format) { - _dviFormat = max(_dviFormat, format); - switch (_dviFormat) { +void BasicDVIReader::setDVIVersion (DVIVersion version) { + _dviVersion = max(_dviVersion, version); + switch (_dviVersion) { case DVI_STANDARD: case DVI_PTEX: - case DVI_XDVOLD: - case DVI_XDVNEW: + case DVI_XDV5: + case DVI_XDV6: + case DVI_XDV7: break; default: ostringstream oss; - oss << "DVI format " << _dviFormat << " not supported"; + oss << "DVI version " << _dviVersion << " not supported"; throw DVIException(oss.str()); } } @@ -184,7 +206,7 @@ void BasicDVIReader::setDVIFormat (DVIFormat format) { /** Executes preamble command. * Format: pre i[1] num[4] den[4] mag[4] k[1] x[k] */ void BasicDVIReader::cmdPre (int) { - setDVIFormat((DVIFormat)readUnsigned(1)); // identification number + setDVIVersion((DVIVersion)readUnsigned(1)); // identification number seek(12, ios::cur); // skip numerator, denominator, and mag factor UInt32 k = readUnsigned(1); // length of following comment seek(k, ios::cur); // skip comment @@ -199,10 +221,10 @@ void BasicDVIReader::cmdPost (int) { /** Executes postpost command. - * Format: postpost q[4] i[1] 223’s[>= 4] */ + * Format: postpost q[4] i[1] 223's[>= 4] */ void BasicDVIReader::cmdPostPost (int) { seek(4, ios::cur); - setDVIFormat((DVIFormat)readUnsigned(1)); // identification byte + setDVIVersion((DVIVersion)readUnsigned(1)); // identification byte while (readUnsigned(1) == 223); // skip fill bytes (223), eof bit should be set now } @@ -236,7 +258,7 @@ void BasicDVIReader::cmdXXX (int len) {seek(readUnsigned(len), ios::cur);} /** Executes fontdef command. - * Format fontdef k[len] c[4] s[4] d[4] a[1] l[1] n[a+l] + * Format: fontdef k[len] c[4] s[4] d[4] a[1] l[1] n[a+l] * @param[in] len size of font number variable (in bytes) */ void BasicDVIReader::cmdFontDef (int len) { seek(len+12, ios::cur); // skip font number @@ -259,10 +281,10 @@ void BasicDVIReader::cmdXFontDef (int) { seek(4+4, ios::cur); UInt16 flags = readUnsigned(2); UInt8 len = readUnsigned(1); - if (_dviFormat == DVI_XDVOLD) + if (_dviVersion == DVI_XDV5) len += readUnsigned(1)+readUnsigned(1); seek(len, ios::cur); - if (_dviFormat == DVI_XDVNEW) + if (_dviVersion >= DVI_XDV6) seek(4, ios::cur); // skip subfont index if (flags & 0x0200) // colored? seek(4, ios::cur); @@ -272,13 +294,16 @@ void BasicDVIReader::cmdXFontDef (int) { seek(4, ios::cur); if (flags & 0x4000) // embolden? seek(4, ios::cur); - if ((flags & 0x0800) && (_dviFormat == DVI_XDVOLD)) { // variations? + if ((flags & 0x0800) && (_dviVersion == DVI_XDV5)) { // variations? UInt16 num_variations = readSigned(2); seek(4*num_variations, ios::cur); } } +/** XDV extension: prints an array of characters where each character + * can take independent x and y coordinates. + * parameters: w[4] n[2] xy[(4+4)n] g[2n] */ void BasicDVIReader::cmdXGlyphArray (int) { seek(4, ios::cur); UInt16 num_glyphs = readUnsigned(2); @@ -286,8 +311,24 @@ void BasicDVIReader::cmdXGlyphArray (int) { } +/** XDV extension: prints an array/string of characters where each character + * can take independent x coordinates whereas all share a single y coordinate. + * parameters: w[4] n[2] x[4n] y[4] g[2n] */ void BasicDVIReader::cmdXGlyphString (int) { seek(4, ios::cur); UInt16 num_glyphs = readUnsigned(2); seek(6*num_glyphs, ios::cur); } + + +/** XDV extension: Same as cmdXGlyphArray plus a leading array of UTF-16 characters + * that specify the "actual text" represented by the glyphs to be printed. It usually + * contains the text with special characters (like ligatures) expanded so that it + * can be used for text search, plain text copy & paste etc. This XDV command was + * introduced with XeTeX 0.99995 and can be triggered by <tt>\\XeTeXgenerateactualtext1</tt>. + * parameters: l[2] t[2l] w[4] n[2] xy[8n] g[2n] */ +void BasicDVIReader::cmdXTextAndGlyphs (int) { + UInt16 l = readUnsigned(2); + seek(2*l, ios::cur); + cmdXGlyphArray(0); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h index f572a97a58a..e96df470b06 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h @@ -26,25 +26,32 @@ struct DVIException : public MessageException { - DVIException (const std::string &msg) : MessageException(msg) {} + explicit DVIException (const std::string &msg) : MessageException(msg) {} }; struct InvalidDVIFileException : public DVIException { - InvalidDVIFileException(const std::string &msg) : DVIException(msg) {} + explicit InvalidDVIFileException (const std::string &msg) : DVIException(msg) {} }; class Matrix; +/** This class provides the basic functionality to read a DVI file. + * It just skips all DVI commands and apply any semantic to it. The latter must + * be realized by deriving a separate class that implements the cmdXXX template + * methods. These are low-level functions that represent the DVI commands and + * require to read and evaluate the correct portion of data from the DVI stream. + * Since the DVI commands are almost skipped by advancing the file pointer, + * running through a DVI file is pretty fast. */ class BasicDVIReader : public StreamReader { protected: typedef void (BasicDVIReader::*CommandHandler)(int); - enum DVIFormat {DVI_NONE=0, DVI_STANDARD=2, DVI_PTEX=3, DVI_XDVOLD=5, DVI_XDVNEW=6}; + enum DVIVersion {DVI_NONE=0, DVI_STANDARD=2, DVI_PTEX=3, DVI_XDV5=5, DVI_XDV6=6, DVI_XDV7=7}; public: - BasicDVIReader (std::istream &is); + explicit BasicDVIReader (std::istream &is); virtual ~BasicDVIReader () {} virtual void executeAllPages (); virtual double getXPos () const {return 0;} @@ -52,19 +59,21 @@ class BasicDVIReader : public StreamReader virtual void finishLine () {} virtual void translateToX (double x) {} virtual void translateToY (double y) {} - virtual int getStackDepth () const {return 0;} + virtual int stackDepth () const {return 0;} virtual void getPageTransformation (Matrix &matrix) const {} - virtual unsigned getCurrentPageNumber () const {return 0;} + virtual unsigned currentPageNumber () const {return 0;} protected: - void setDVIFormat (DVIFormat format); - DVIFormat getDVIFormat () const {return _dviFormat;} + void setDVIVersion (DVIVersion version); + DVIVersion getDVIVersion () const {return _dviVersion;} virtual int evalCommand (CommandHandler &handler, int ¶m); virtual int executeCommand (); void executePostPost (); + bool evalXDVOpcode (int op, CommandHandler &handler) const; - // the following methods represent the DVI commands - // they are called by executeCommand and should not be used directly + // The following template methods represent the single DVI commands. They + // must read the correct chunk of data from the input stream in order to + // process the DVI file correctly. virtual void cmdSetChar0 (int c); virtual void cmdSetChar (int len); virtual void cmdPutChar (int len); @@ -93,13 +102,14 @@ class BasicDVIReader : public StreamReader virtual void cmdPre (int len); virtual void cmdPost (int len); virtual void cmdPostPost (int len); - virtual void cmdXFontDef (int len); // XDV only - virtual void cmdXGlyphArray (int len); // XDV only - virtual void cmdXGlyphString (int len); // XDV format 5 only - virtual void cmdXPic (int len); // XDV format 5 only + virtual void cmdXFontDef (int len); // XDV only + virtual void cmdXGlyphArray (int len); // XDV only + virtual void cmdXGlyphString (int len); // XDV version 5 only + virtual void cmdXPic (int len); // XDV version 5 only + virtual void cmdXTextAndGlyphs (int len); // XDV version 7 only private: - DVIFormat _dviFormat; ///< format of DVI file being processed + DVIVersion _dviVersion; ///< DVI version of file being processed }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h index d64e660b3f1..d95794c27fe 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h @@ -45,7 +45,7 @@ class Bezier protected: int approximate (double delta, double t0, double t1, std::vector<DPair> &p, std::vector<double> *t) const; - private: + private: DPair _points[4]; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp index f1f19cc7691..46902a2d567 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp @@ -30,20 +30,19 @@ using namespace std; /** Collect all background color changes while preprocessing the DVI file. * We need them in order to apply the correct background colors even if * not all but only selected DVI pages are converted. */ -void BgColorSpecialHandler::preprocess (const char*, std::istream &is, SpecialActions *actions) { +void BgColorSpecialHandler::preprocess (const char*, std::istream &is, SpecialActions &actions) { Color color = ColorSpecialHandler::readColor(is); - unsigned pageno = actions->getCurrentPageNumber(); + unsigned pageno = actions.getCurrentPageNumber(); if (_pageColors.empty() || _pageColors.back().second != color) { if (!_pageColors.empty() && _pageColors.back().first == pageno) _pageColors.back().second = color; else _pageColors.push_back(PageColor(pageno, color)); } - _actions = actions; } -bool BgColorSpecialHandler::process (const char*, istream&, SpecialActions*) { +bool BgColorSpecialHandler::process (const char*, istream &, SpecialActions&) { return true; } @@ -54,7 +53,7 @@ static bool operator < (const pair<unsigned,Color> &pc1, const pair<unsigned,Col } -void BgColorSpecialHandler::dviBeginPage (unsigned pageno) { +void BgColorSpecialHandler::dviBeginPage (unsigned pageno, SpecialActions &actions) { // Ensure that the background color of the preceeding page is set as the // default background color of the current page because this special affects // the current and all subsequent pages until the next change. @@ -64,9 +63,9 @@ void BgColorSpecialHandler::dviBeginPage (unsigned pageno) { // find number of page with bg color change not lower than the current one vector<PageColor>::iterator it = lower_bound(_pageColors.begin(), _pageColors.end(), PageColor(pageno, Color::BLACK)); if (it != _pageColors.end() && it->first == pageno) - _actions->setBgColor(it->second); + actions.setBgColor(it->second); else if (it != _pageColors.begin()) - _actions->setBgColor((--it)->second); + actions.setBgColor((--it)->second); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h index 772e41541f5..b6af8147658 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h @@ -29,17 +29,17 @@ class BgColorSpecialHandler : public SpecialHandler, public DVIBeginPageListener { public: - BgColorSpecialHandler () : _actions(0) {} - void preprocess (const char *prefix, std::istream &is, SpecialActions *actions); - bool process (const char *prefix, std::istream &is, SpecialActions *actions); - void dviBeginPage (unsigned pageno); + void preprocess (const char *prefix, std::istream &is, SpecialActions &actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); const char* info () const {return "background color special";} const char* name () const {return "bgcolor";} const char** prefixes () const; + protected: + void dviBeginPage (unsigned pageno, SpecialActions &actions); + private: typedef std::pair<unsigned,Color> PageColor; // page number and color - SpecialActions *_actions; std::vector<PageColor> _pageColors; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp index eca7142dbf0..f4fc6f7ca71 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp @@ -52,8 +52,8 @@ BoundingBox::BoundingBox (const DPair &p1, const DPair &p2) BoundingBox::BoundingBox (const Length &ulxx, const Length &ulyy, const Length &lrxx, const Length &lryy) - : _ulx(min(ulxx.pt(),lrxx.pt())), _uly(min(ulyy.pt(),lryy.pt())), - _lrx(max(ulxx.pt(),lrxx.pt())), _lry(max(ulyy.pt(),lryy.pt())), + : _ulx(min(ulxx.bp(),lrxx.bp())), _uly(min(ulyy.bp(),lryy.bp())), + _lrx(max(ulxx.bp(),lrxx.bp())), _lry(max(ulyy.bp(),lryy.bp())), _valid(true), _locked(false) { } @@ -80,13 +80,10 @@ static string& strip (string &str) { } -/** Sets or modifies the bounding box. If 'boxstr' consists of 4 length values, - * they denote the absolute position of two diagonal corners of the box. In case - * of a single length value l the current box is enlarged by adding (-l,-l) the upper - * left and (l,l) to the lower right corner. - * @param[in] boxstr whitespace and/or comma separated string of lengths. */ -void BoundingBox::set (string boxstr) { - vector<Length> coord; +/** Extracts a sequence of length values from a given string. + * @param[in] boxstr whitespace and/or comma separated string of lengths. + * @param[out] the extracted lengths */ +void BoundingBox::extractLengths (string boxstr, vector<Length> &lengths) { const size_t len = boxstr.length(); size_t l=0; strip(boxstr); @@ -99,31 +96,46 @@ void BoundingBox::set (string boxstr) { r++; lenstr = boxstr.substr(l, r-l); if (!lenstr.empty()) { - coord.push_back(Length(lenstr)); + lengths.push_back(Length(lenstr)); if (boxstr[r] == ',') r++; l = r; } - } while (!lenstr.empty() && coord.size() < 4); + } while (!lenstr.empty() && lengths.size() < 4); +} + +/** Sets or modifies the bounding box. If 'boxstr' consists of 4 length values, + * they denote the absolute position of two diagonal corners of the box. In case + * of a single length value l the current box is enlarged by adding (-l,-l) the upper + * left and (l,l) to the lower right corner. + * @param[in] boxstr whitespace and/or comma separated string of lengths. */ +void BoundingBox::set (const string &boxstr) { + vector<Length> coord; + extractLengths(boxstr, coord); + set(coord); +} + + +void BoundingBox::set (const std::vector<Length> &coord) { switch (coord.size()) { case 1: - _ulx -= coord[0].pt(); - _uly -= coord[0].pt(); - _lrx += coord[0].pt(); - _lry += coord[0].pt(); + _ulx -= coord[0].bp(); + _uly -= coord[0].bp(); + _lrx += coord[0].bp(); + _lry += coord[0].bp(); break; case 2: - _ulx -= coord[0].pt(); - _uly -= coord[1].pt(); - _lrx += coord[0].pt(); - _lry += coord[1].pt(); + _ulx -= coord[0].bp(); + _uly -= coord[1].bp(); + _lrx += coord[0].bp(); + _lry += coord[1].bp(); break; case 4: - _ulx = min(coord[0].pt(), coord[2].pt()); - _uly = min(coord[1].pt(), coord[3].pt()); - _lrx = max(coord[0].pt(), coord[2].pt()); - _lry = max(coord[1].pt(), coord[3].pt()); + _ulx = min(coord[0].bp(), coord[2].bp()); + _uly = min(coord[1].bp(), coord[3].bp()); + _lrx = max(coord[0].bp(), coord[2].bp()); + _lry = max(coord[1].bp(), coord[3].bp()); break; default: throw BoundingBoxException("1, 2 or 4 length parameters expected"); @@ -218,21 +230,17 @@ void BoundingBox::operator += (const BoundingBox &bbox) { } -bool BoundingBox::operator == (const BoundingBox &bbox) const { - return _valid && bbox._valid - && _ulx == bbox._ulx - && _uly == bbox._uly - && _lrx == bbox._lrx - && _lry == bbox._lry; +static inline bool almost_equal (double v1, double v2) { + return fabs(v1-v2) < 1e-10; } -bool BoundingBox::operator != (const BoundingBox &bbox) const { - return !_valid || !bbox._valid - || _ulx != bbox._ulx - || _uly != bbox._uly - || _lrx != bbox._lrx - || _lry != bbox._lry; +bool BoundingBox::operator == (const BoundingBox &bbox) const { + return _valid && bbox._valid + && almost_equal(_ulx, bbox._ulx) + && almost_equal(_uly, bbox._uly) + && almost_equal(_lrx, bbox._lrx) + && almost_equal(_lry, bbox._lry); } @@ -270,8 +278,10 @@ string BoundingBox::toSVGViewBox () const { ostream& BoundingBox::write (ostream &os) const { - return os << '(' << _ulx << ", " << _uly - << ", " << _lrx << ", " << _lry << ')'; + os << '(' << _ulx << ", " << _uly << ", " << _lrx << ", " << _lry << ')'; + if (!_valid) + os << " (invalid)"; + return os; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h index d092251581a..9d7dff1b888 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h @@ -23,6 +23,7 @@ #include <ostream> #include <string> +#include <vector> #include "Length.h" #include "MessageException.h" #include "Pair.h" @@ -48,12 +49,15 @@ class BoundingBox BoundingBox (const DPair &p1, const DPair &p2); BoundingBox (const Length &ulxx, const Length &ulyy, const Length &lrxx, const Length &lryy); BoundingBox (const std::string &boxstr); - void set (std::string boxstr); + void set (const std::string &boxstr); + void set (const std::vector<Length> &lengths); void embed (double x, double y); void embed (const BoundingBox &bb); void embed (const DPair &p) {embed(p.x(), p.y());} void embed (const DPair &c, double r); + static void extractLengths (std::string boxstr, std::vector<Length> &lengths); + template <typename T> void embed (const Pair<T> &p) {embed(p.x(), p.y());} @@ -72,7 +76,7 @@ class BoundingBox void invalidate () {_valid = false;} void operator += (const BoundingBox &bbox); bool operator == (const BoundingBox &bbox) const; - bool operator != (const BoundingBox &bbox) const; + bool operator != (const BoundingBox &bbox) const {return !(*this == bbox);} void scale (double sx, double sy); void transform (const Matrix &tm); std::string toSVGViewBox () const; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h index ee080638d2c..c6a3e2c0c3b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h @@ -89,8 +89,8 @@ class SegmentedCMap : public CMap friend class CMapReader; public: - SegmentedCMap (const std::string &name) : _name(name), _basemap(0), _vertical(false), _mapsToCID(true) {} - const char* name () const {return _name.c_str();} + SegmentedCMap (const std::string &fname) : _filename(fname), _basemap(0), _vertical(false), _mapsToCID(true) {} + const char* name () const {return _filename.c_str();} UInt32 cid (UInt32 c) const; UInt32 bfcode (UInt32 cid) const; void addCIDRange (UInt32 first, UInt32 last, UInt32 cid) {_cidranges.addRange(first, last, cid);} @@ -103,7 +103,7 @@ class SegmentedCMap : public CMap std::string getROString () const; private: - std::string _name; + std::string _filename; std::string _registry; std::string _ordering; CMap *_basemap; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp index 2f360d7331d..b10e7c0c9da 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp @@ -24,6 +24,7 @@ #include "CMapManager.h" #include "CMapReader.h" #include "FileFinder.h" +#include "Font.h" #include "Message.h" using namespace std; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h index 862a8a298ca..8b226a47a9c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h @@ -25,11 +25,11 @@ #include <set> #include <string> #include "CharMapID.h" -#include "Font.h" struct CMap; struct FontEncoding; class FontEncodingPair; +class PhysicalFont; class CMapManager { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp index 63a58775521..e9c49c573b6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp @@ -109,11 +109,7 @@ void CMapReader::op_def (InputReader&) { if (size >= 2) { const string val = popToken().strvalue(); const string name = popToken().strvalue(); - if (name == "CMapName") { - if (val != _cmap->_name) - throw CMapReaderException("CMapName doesn't match filename"); - } - else if (name == "WMode") { + if (name == "WMode") { if (val == "0" || val == "1") _cmap->_vertical = (val == "1"); else diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp index f61de4768ca..07426645cbe 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp @@ -92,7 +92,7 @@ Color ColorSpecialHandler::readColor (istream &is) { } -bool ColorSpecialHandler::process (const char*, istream &is, SpecialActions *actions) { +bool ColorSpecialHandler::process (const char *, istream &is, SpecialActions &actions) { string cmd; is >> cmd; if (cmd == "push") // color push <model> <params> @@ -106,12 +106,10 @@ bool ColorSpecialHandler::process (const char*, istream &is, SpecialActions *act _colorStack.pop(); _colorStack.push(readColor(cmd, is)); } - if (actions) { - if (_colorStack.empty()) - actions->setColor(Color::BLACK); - else - actions->setColor(_colorStack.top()); - } + if (_colorStack.empty()) + actions.setColor(Color::BLACK); + else + actions.setColor(_colorStack.top()); return true; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h index d1bbd2e0c95..bec15f6c53a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h @@ -31,7 +31,7 @@ class ColorSpecialHandler : public SpecialHandler { public: - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); static Color readColor (std::istream &is); static Color readColor (const std::string &model, std::istream &is); const char* name () const {return "color";} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp index ba052631c8d..5618d1fa3cf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp @@ -6,8 +6,6 @@ #include <config.h> #include <cstdio> -#include <iostream> -#include <iomanip> #include "InputReader.h" #include "CommandLine.h" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp index af65460ac46..e679e7469da 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp @@ -25,7 +25,7 @@ DLLoader::DLLoader (const char *dlname) : _handle(0) { if (dlname && *dlname) { -#ifdef __WIN32__ +#ifdef _WIN32 _handle = LoadLibrary(dlname); #else _handle = dlopen(dlname, RTLD_LAZY); @@ -36,7 +36,7 @@ DLLoader::DLLoader (const char *dlname) : _handle(0) DLLoader::~DLLoader () { if (_handle) { -#ifdef __WIN32__ +#ifdef _WIN32 FreeLibrary(_handle); #else dlclose(_handle); @@ -50,7 +50,7 @@ DLLoader::~DLLoader () { * @return pointer to loaded symbol, or 0 if the symbol could not be loaded */ void* DLLoader::loadSymbol (const char *name) { if (_handle) { -#ifdef __WIN32__ +#ifdef _WIN32 return (void*)GetProcAddress(_handle, name); #else return dlsym(_handle, name); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h index 42ef6df72b3..5a5b27271d9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h @@ -21,7 +21,7 @@ #ifndef DVISVGM_DLLOADER_H #define DVISVGM_DLLOADER_H -#ifdef __WIN32__ +#ifdef _WIN32 #include <windows.h> #else #include <dlfcn.h> @@ -40,7 +40,7 @@ class DLLoader void* loadSymbol (const char *name); private: -#ifdef __WIN32__ +#ifdef _WIN32 HINSTANCE _handle; #else void *_handle; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h index fd28d25b6b9..5e3254656bf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h @@ -22,28 +22,24 @@ #define DVISVGM_DVIACTIONS_H #include <string> -#include "Message.h" +#include <vector> #include "types.h" -class BoundingBox; -struct Font; -class SpecialManager; +class BoundingBox; +class Font; struct DVIActions { virtual ~DVIActions () {} - virtual void setChar (double x, double y, unsigned c, bool vertical, const Font *f) {} + virtual void setChar (double x, double y, unsigned c, bool vertical, const Font &f) {} virtual void setRule (double x, double y, double height, double width) {} virtual void setTextOrientation (bool vertical) {} virtual void moveToX (double x) {} virtual void moveToY (double y) {} - virtual void defineFont (int num, const Font *font) {} virtual void setFont (int num, const Font &font) {} virtual void special (const std::string &s, double dvi2bp, bool preprocessing=false) {} - virtual void preamble (const std::string &cmt) {} - virtual void postamble () {} - virtual void beginPage (unsigned pageno, Int32 *c) {} + virtual void beginPage (unsigned pageno, const std::vector<Int32> &c) {} virtual void endPage (unsigned pageno) {} virtual BoundingBox& bbox () =0; virtual void progress (size_t current, size_t total, const char *id=0) {} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp index deacce1871c..3c6c2c1d284 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp @@ -28,26 +28,17 @@ #include "DVIReader.h" #include "Font.h" #include "FontManager.h" -#include "SignalHandler.h" #include "VectorStream.h" - using namespace std; -bool DVIReader::COMPUTE_PROGRESS = false; - - -DVIReader::DVIReader (istream &is, DVIActions *a) : BasicDVIReader(is), _actions(a) +DVIReader::DVIReader (istream &is) : BasicDVIReader(is) { _inPage = false; - _pageHeight = _pageWidth = 0; _dvi2bp = 0.0; - _tx = _ty = 0; // no cursor translation - _prevYPos = numeric_limits<double>::min(); _inPostamble = false; _currFontNum = 0; _currPageNum = 0; - _pagePos = 0; _mag = 1; executePreamble(); collectBopOffsets(); @@ -55,39 +46,9 @@ DVIReader::DVIReader (istream &is, DVIActions *a) : BasicDVIReader(is), _actions } -DVIActions* DVIReader::replaceActions (DVIActions *a) { - DVIActions *prev_actions = _actions; - _actions = a; - return prev_actions; -} - - -/** Reads a single DVI command from the current position of the input stream and calls the - * corresponding cmdFOO method. - * @return opcode of the command executed */ int DVIReader::executeCommand () { - SignalHandler::instance().check(); - CommandHandler handler; - int param; // parameter of handler - const streampos cmdpos = tell(); - int opcode = evalCommand(handler, param); - (this->*handler)(param); - if (_dviState.v+_ty != _prevYPos) { - _tx = _ty = 0; - _prevYPos = _dviState.v; - } - if (COMPUTE_PROGRESS && _inPage && _actions) { - size_t pagelen = numberOfPageBytes(_currPageNum-1); - // ensure progress() is called at 0% - if (opcode == 139) // bop? - _actions->progress(0, pagelen); - // ensure progress() is called at 100% - if (peek() == 140) // eop reached? - _pagePos = pagelen; - else - _pagePos += tell()-cmdpos; - _actions->progress(_pagePos, pagelen); - } + _prevDviState = _currDviState; + int opcode = BasicDVIReader::executeCommand(); return opcode; } @@ -181,65 +142,48 @@ void DVIReader::collectBopOffsets () { reverse(_bopOffsets.begin(), _bopOffsets.end()); } - -/** Returns the current x coordinate in PS point units. - * This is the horizontal position where the next output would be placed. */ -double DVIReader::getXPos () const { - return _dviState.h+_tx; -} - - -/** Returns the current y coordinate in PS point units. - * This is the vertical position where the next output would be placed. */ -double DVIReader::getYPos () const { - return _dviState.v+_ty; -} - - ///////////////////////////////////// /** Reads and executes DVI preamble command. * Format: pre ver[1] num[4] den[4] mag[4] cmtlen[1] cmt[cmtlen] */ void DVIReader::cmdPre (int) { - setDVIFormat((DVIFormat)readUnsigned(1)); // identification number - UInt32 num = readUnsigned(4); // numerator units of measurement - UInt32 den = readUnsigned(4); // denominator units of measurement - if (den == 0) + UInt8 id = readUnsigned(1); + setDVIVersion(DVIVersion(id)); // identification number + UInt32 numer = readUnsigned(4); // numerator units of measurement + UInt32 denom = readUnsigned(4); // denominator units of measurement + if (denom == 0) throw DVIException("denominator of measurement unit is zero"); _mag = readUnsigned(4); // magnification - UInt32 k = readUnsigned(1); // length of following comment - string cmt = readString(k); // comment + UInt32 k = readUnsigned(1); // length of following comment + string comment = readString(k); // 1 dviunit * num/den == multiples of 0.0000001m // 1 dviunit * _dvibp: length of 1 dviunit in PS points * _mag/1000 - _dvi2bp = num/254000.0*72.0/den*_mag/1000.0; - if (_actions) - _actions->preamble(cmt); + _dvi2bp = numer/254000.0*72.0/denom*_mag/1000.0; + dviPre(id, numer, denom, _mag, comment); } /** Reads and executes DVI postamble command. * Format: post p[4] num[4] den[4] mag[4] ph[4] pw[4] sd[2] np[2] */ void DVIReader::cmdPost (int) { - readUnsigned(4); // skip pointer to previous bop - UInt32 num = readUnsigned(4); - UInt32 den = readUnsigned(4); - if (den == 0) + UInt32 prevBopOffset = readUnsigned(4); + UInt32 numer = readUnsigned(4); + UInt32 denom = readUnsigned(4); + if (denom == 0) throw DVIException("denominator of measurement unit is zero"); _mag = readUnsigned(4); - _pageHeight = readUnsigned(4); // height of tallest page in dvi units - _pageWidth = readUnsigned(4); // width of widest page in dvi units - readUnsigned(2); // skip max. stack depth - if (readUnsigned(2) != numberOfPages()) - throw DVIException("page count entry doesn't match actual number of pages"); + UInt32 pageHeight = readUnsigned(4); // height of tallest page in dvi units + UInt32 pageWidth = readUnsigned(4); // width of widest page in dvi units + UInt16 stackDepth = readUnsigned(2); // max. stack depth required + UInt16 numPages = readUnsigned(2); + if (numPages != numberOfPages()) + throw DVIException("page count in postamble doesn't match actual number of pages"); // 1 dviunit * num/den == multiples of 0.0000001m // 1 dviunit * _dvi2bp: length of 1 dviunit in PS points * _mag/1000 - _dvi2bp = num/254000.0*72.0/den*_mag/1000.0; - _pageHeight *= _dvi2bp; // to pt units - _pageWidth *= _dvi2bp; + _dvi2bp = numer/254000.0*72.0/denom*_mag/1000.0; _inPostamble = true; - if (_actions) - _actions->postamble(); + dviPost(stackDepth, numPages, pageWidth*_dvi2bp, pageHeight*_dvi2bp, _mag, numer, denom, prevBopOffset); } @@ -247,28 +191,27 @@ void DVIReader::cmdPost (int) { * Format: post_post q[4] i[1] 223[>=4] */ void DVIReader::cmdPostPost (int) { _inPostamble = false; - readUnsigned(4); // pointer to begin of postamble - setDVIFormat((DVIFormat)readUnsigned(1)); // identification byte + UInt32 postOffset = readUnsigned(4); // pointer to begin of postamble + UInt8 id = readUnsigned(1); + setDVIVersion(DVIVersion(id)); // identification byte while (readUnsigned(1) == 223); // skip fill bytes (223), eof bit should be set now + dviPostPost(DVIVersion(id), postOffset); } /** Reads and executes Begin-Of-Page command. * Format: bop c0[+4] ... c9[+4] p[+4] */ void DVIReader::cmdBop (int) { - Int32 c[10]; + vector<Int32> c(10); for (int i=0; i < 10; i++) c[i] = readSigned(4); - readSigned(4); // pointer to peceeding bop (-1 in case of first page) - _dviState.reset(); // set all DVI registers to 0 + Int32 prevBopOffset = readSigned(4); // pointer to peceeding bop (-1 in case of first page) + _currDviState.reset(); // set all DVI registers to 0 while (!_stateStack.empty()) _stateStack.pop(); _currFontNum = 0; _inPage = true; - _pagePos = 0; - beginPage(_currPageNum, c); - if (_actions) - _actions->beginPage(_currPageNum, c); + dviBop(c, prevBopOffset); } @@ -277,15 +220,14 @@ void DVIReader::cmdEop (int) { if (!_stateStack.empty()) throw DVIException("stack not empty at end of page"); _inPage = false; - endPage(_currPageNum); - if (_actions) - _actions->endPage(_currPageNum); + dviEop(); } /** Reads and executes push command. */ void DVIReader::cmdPush (int) { - _stateStack.push(_dviState); + _stateStack.push(_currDviState); + dviPush(); } @@ -293,72 +235,41 @@ void DVIReader::cmdPush (int) { void DVIReader::cmdPop (int) { if (_stateStack.empty()) throw DVIException("stack empty at pop command"); - else { - DVIState prevState = _dviState; - _dviState = _stateStack.top(); - _stateStack.pop(); - if (_actions) { - if (prevState.h != _dviState.h) - _actions->moveToX(_dviState.h + _tx); - if (prevState.v != _dviState.v) - _actions->moveToY(_dviState.v + _ty); - if (prevState.d != _dviState.d) - _actions->setTextOrientation(_dviState.d != WMODE_LR); - } - } -} - - -/** Helper function that actually sets/puts a charater. It is called by the - * cmdSetChar and cmdPutChar methods. - * @param[in] c character to typeset - * @param[in] moveCursor if true, register h is increased by the character width - * @throw DVIException if method is called ouside a bop/eop pair */ -void DVIReader::putChar (UInt32 c, bool moveCursor) { - if (!_inPage) - throw DVIException("set_char/put_char outside of page"); - - FontManager &fm = FontManager::instance(); - Font *font = fm.getFont(_currFontNum); - if (!font) - throw DVIException("no font selected"); - - if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { // is current font a virtual font? - vector<UInt8> *dvi = const_cast<vector<UInt8>*>(vf->getDVI(c)); // get DVI snippet that describes character c - if (dvi) { - DVIState pos = _dviState; // save current cursor position - _dviState.x = _dviState.y = _dviState.w = _dviState.z = 0; - int save_fontnum = _currFontNum; // save current font number - fm.enterVF(vf); // new font number context - cmdFontNum0(fm.vfFirstFontNum(vf)); - double save_scale = _dvi2bp; + _currDviState = _stateStack.top(); + _stateStack.pop(); + dviPop(); +} + + +/** Helper function that handles charaters from virtual fonts (VF). + * It is called by the cmdSetChar and cmdPutChar methods. + * @param[in] font current font (corresponding to _currFontNum) + * @param[in] c character to typeset */ +void DVIReader::putVFChar (Font *font, UInt32 c) { + if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { // is current font a virtual font? + if (const vector<UInt8> *dvi = vf->getDVI(c)) { // try to get DVI snippet that represents character c + FontManager &fm = FontManager::instance(); + DVIState pos = _currDviState; // save current cursor position + _currDviState.x = _currDviState.y = _currDviState.w = _currDviState.z = 0; + int savedFontNum = _currFontNum; // save current font number + fm.enterVF(vf); // enter VF font number context + setFont(fm.vfFirstFontNum(vf), VF_ENTER); + double savedScale = _dvi2bp; // DVI units in virtual fonts are multiples of 1^(-20) times the scaled size of the VF _dvi2bp = vf->scaledSize()/(1 << 20); - VectorInputStream<UInt8> vis(*dvi); istream &is = replaceStream(vis); try { - executeAll(); // execute DVI fragment + executeAll(); // execute DVI fragment } catch (const DVIException &e) { - // Message::estream(true) << "invalid dvi in vf: " << e.getMessage() << endl; // @@ + // Message::estream(true) << "invalid dvi in vf: " << e.getMessage() << endl; // @@ } - replaceStream(is); // restore previous input stream - _dvi2bp = save_scale; // restore previous scale factor - fm.leaveVF(); // restore previous font number context - cmdFontNum0(save_fontnum); // restore previous font number - _dviState = pos; // restore previous cursor position - } - } - else if (_actions) - _actions->setChar(_dviState.h+_tx, _dviState.v+_ty, c, _dviState.d != WMODE_LR, font); - - if (moveCursor) { - double dist = font->charWidth(c) * font->scaleFactor() * _mag/1000.0; - switch (_dviState.d) { - case WMODE_LR: _dviState.h += dist; break; - case WMODE_TB: _dviState.v += dist; break; - case WMODE_BT: _dviState.v -= dist; break; + replaceStream(is); // restore previous input stream + _dvi2bp = savedScale; // restore previous scale factor + fm.leaveVF(); // restore previous font number context + setFont(savedFontNum, VF_LEAVE); // restore previous font number + _currDviState = pos; // restore previous cursor position } } } @@ -369,7 +280,12 @@ void DVIReader::putChar (UInt32 c, bool moveCursor) { * @param[in] c character to set * @throw DVIException if method is called ouside a bop/eop pair */ void DVIReader::cmdSetChar0 (int c) { - putChar(c, true); + if (!_inPage) + throw DVIException("setchar outside of page"); + Font *font = FontManager::instance().getFont(_currFontNum); + moveRight(font->charWidth(c)*font->scaleFactor()*_mag/1000.0); + dviSetChar0(c, font); + putVFChar(font, c); } @@ -378,10 +294,15 @@ void DVIReader::cmdSetChar0 (int c) { * @param[in] len number of parameter bytes (possible values: 1-4) * @throw DVIException if method is called ouside a bop/eop pair */ void DVIReader::cmdSetChar (int len) { + if (!_inPage) + throw DVIException("setchar outside of page"); // According to the dvi specification all character codes are unsigned // except len == 4. At the moment all char codes are treated as unsigned... UInt32 c = readUnsigned(len); // if len == 4 c may be signed - putChar(c, true); + Font *font = FontManager::instance().getFont(_currFontNum); + moveRight(font->charWidth(c)*font->scaleFactor()*_mag/1000.0); + dviSetChar(c, font); + putVFChar(font, c); } @@ -390,10 +311,14 @@ void DVIReader::cmdSetChar (int len) { * @param[in] len number of parameter bytes (possible values: 1-4) * @throw DVIException if method is called ouside a bop/eop pair */ void DVIReader::cmdPutChar (int len) { + if (!_inPage) + throw DVIException("putchar outside of page"); // According to the dvi specification all character codes are unsigned // except len == 4. At the moment all char codes are treated as unsigned... Int32 c = readUnsigned(len); - putChar(c, false); + Font *font = FontManager::instance().getFont(_currFontNum); + dviPutChar(c, font); + putVFChar(font, c); } @@ -406,9 +331,8 @@ void DVIReader::cmdSetRule (int) { throw DVIException("set_rule outside of page"); double height = _dvi2bp*readSigned(4); double width = _dvi2bp*readSigned(4); - if (_actions && height > 0 && width > 0) - _actions->setRule(_dviState.h+_tx, _dviState.v+_ty, height, width); moveRight(width); + dviSetRule(height, width); } @@ -421,68 +345,94 @@ void DVIReader::cmdPutRule (int) { throw DVIException("put_rule outside of page"); double height = _dvi2bp*readSigned(4); double width = _dvi2bp*readSigned(4); - if (_actions && height > 0 && width > 0) - _actions->setRule(_dviState.h+_tx, _dviState.v+_ty, height, width); + dviPutRule(height, width); } void DVIReader::moveRight (double dx) { - switch (_dviState.d) { - case WMODE_LR: _dviState.h += dx; break; - case WMODE_TB: _dviState.v += dx; break; - case WMODE_BT: _dviState.v -= dx; break; - } - if (_actions) { - if (_dviState.d == WMODE_LR) - _actions->moveToX(_dviState.h+_tx); - else - _actions->moveToY(_dviState.v+_ty); + switch (_currDviState.d) { + case WMODE_LR: _currDviState.h += dx; break; + case WMODE_TB: _currDviState.v += dx; break; + case WMODE_BT: _currDviState.v -= dx; break; } } void DVIReader::moveDown (double dy) { - switch (_dviState.d) { - case WMODE_LR: _dviState.v += dy; break; - case WMODE_TB: _dviState.h -= dy; break; - case WMODE_BT: _dviState.h += dy; break; - } - if (_actions) { - if (_dviState.d == WMODE_LR) - _actions->moveToY(_dviState.v+_ty); - else - _actions->moveToX(_dviState.h+_tx); + switch (_currDviState.d) { + case WMODE_LR: _currDviState.v += dy; break; + case WMODE_TB: _currDviState.h -= dy; break; + case WMODE_BT: _currDviState.h += dy; break; } } -void DVIReader::cmdRight (int len) {moveRight(_dvi2bp*readSigned(len));} -void DVIReader::cmdDown (int len) {moveDown(_dvi2bp*readSigned(len));} -void DVIReader::cmdX0 (int) {moveRight(_dviState.x);} -void DVIReader::cmdY0 (int) {moveDown(_dviState.y);} -void DVIReader::cmdW0 (int) {moveRight(_dviState.w);} -void DVIReader::cmdZ0 (int) {moveDown(_dviState.z);} -void DVIReader::cmdX (int len) {_dviState.x = _dvi2bp*readSigned(len); cmdX0(0);} -void DVIReader::cmdY (int len) {_dviState.y = _dvi2bp*readSigned(len); cmdY0(0);} -void DVIReader::cmdW (int len) {_dviState.w = _dvi2bp*readSigned(len); cmdW0(0);} -void DVIReader::cmdZ (int len) {_dviState.z = _dvi2bp*readSigned(len); cmdZ0(0);} -void DVIReader::cmdNop (int) {} +void DVIReader::cmdRight (int len) { + Int32 dx = _dvi2bp*readSigned(len); + moveRight(dx); + dviRight(dx); +} + + +void DVIReader::cmdDown (int len) { + Int32 dy = _dvi2bp*readSigned(len); + moveDown(dy); + dviDown(dy); +} + + +void DVIReader::cmdNop (int) {} +void DVIReader::cmdX0 (int) {moveRight(_currDviState.x); dviX0();} +void DVIReader::cmdY0 (int) {moveDown(_currDviState.y); dviY0();} +void DVIReader::cmdW0 (int) {moveRight(_currDviState.w); dviW0();} +void DVIReader::cmdZ0 (int) {moveDown(_currDviState.z); dviZ0();} + + +void DVIReader::cmdX (int len) { + Int32 dx = _dvi2bp*readSigned(len); + _currDviState.x = dx; + moveRight(dx); + dviX(dx); +} + + +void DVIReader::cmdY (int len) { + Int32 dy = _dvi2bp*readSigned(len); + _currDviState.y = dy; + moveDown(dy); + dviY(dy); +} + + +void DVIReader::cmdW (int len) { + Int32 dx = _dvi2bp*readSigned(len); + _currDviState.w = dx; + moveRight(dx); + dviW(dx); +} + + +void DVIReader::cmdZ (int len) { + Int32 dy = _dvi2bp*readSigned(len); + _currDviState.z = dy; + moveDown(dy); + dviZ(dy); +} /** Sets the text orientation (horizontal, vertical). - * This command is only available in DVI files of format 3 (created by pTeX) */ + * This command is only available in DVI version 3 (created by pTeX) */ void DVIReader::cmdDir (int) { UInt8 wmode = readUnsigned(1); if (wmode == 4) // yoko mode (4) equals default LR mode (0) wmode = 0; if (wmode == 2 || wmode > 3) { ostringstream oss; - oss << "invalid writing mode value " << wmode << " (0, 1, or 3 expected)"; + oss << "invalid writing mode value " << wmode << " (0, 1, 3, or 4 expected)"; throw DVIException(oss.str()); } - _dviState.d = (WritingMode)wmode; - if (_actions) - _actions->setTextOrientation(_dviState.d != WMODE_LR); + _currDviState.d = (WritingMode)wmode; + dviDir(_currDviState.d); } @@ -490,35 +440,42 @@ void DVIReader::cmdXXX (int len) { if (!_inPage) throw DVIException("special outside of page"); UInt32 numBytes = readUnsigned(len); - string s = readString(numBytes); - if (_actions) - _actions->special(s, _dvi2bp); + string str = readString(numBytes); + dviXXX(str); } -/** Selects a previously defined font by its number. - * @param[in] num font number - * @throw DVIException if font number is undefined */ -void DVIReader::cmdFontNum0 (int num) { - if (Font *font = FontManager::instance().getFont(num)) { - _currFontNum = num; - if (_actions && !dynamic_cast<VirtualFont*>(font)) - _actions->setFont(FontManager::instance().fontID(num), *font); // all fonts get a recomputed ID +/** Change the current font. + * @param[in] fontnum local number of font to select + * @param[in] mode info on command that triggered the font change + * @throw DVIException if font number is undefined */ +void DVIReader::setFont (int fontnum, SetFontMode mode) { + if (const Font *font = FontManager::instance().getFont(fontnum)) { + _currFontNum = fontnum; + dviFontNum(UInt32(fontnum), mode, font); } else { ostringstream oss; - oss << "undefined font number " << num; + oss << "undefined font number " << fontnum; throw DVIException(oss.str()); } } +/** Selects a previously defined font by its number. + * @param[in] fontnum font number + * @throw DVIException if font number is undefined */ +void DVIReader::cmdFontNum0 (int fontnum) { + setFont(fontnum, SF_SHORT); +} + + /** Selects a previously defined font. - * @param[in] len size of font number variable (in bytes) - * @throw DVIException if font number is undefined */ + * @param[in] len size of font number variable (in bytes) + * @throw DVIException if font number is undefined */ void DVIReader::cmdFontNum (int len) { - UInt32 num = readUnsigned(len); - cmdFontNum0(num); + UInt32 fontnum = readUnsigned(len); + setFont(fontnum, SF_LONG); } @@ -528,29 +485,28 @@ void DVIReader::cmdFontNum (int len) { * @param[in] cs checksum to be compared with TFM checksum * @param[in] ds design size in PS point units * @param[in] ss scaled size in PS point units */ -void DVIReader::defineFont (UInt32 fontnum, const string &name, UInt32 cs, double ds, double ss) { - if (!_inPostamble) // only process font definitions collected in the postamble; skip all others - return; - +const Font* DVIReader::defineFont (UInt32 fontnum, const string &name, UInt32 cs, double ds, double ss) { FontManager &fm = FontManager::instance(); - int id = fm.registerFont(fontnum, name, cs, ds, ss); - Font *font = fm.getFontById(id); - if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { - // read vf file, register its font and character definitions - fm.enterVF(vf); - ifstream ifs(vf->path(), ios::binary); - VFReader vfReader(ifs); - vfReader.replaceActions(this); - vfReader.executeAll(); - fm.leaveVF(); + Font *font = fm.getFont(fontnum); + if (!font) { + int id = fm.registerFont(fontnum, name, cs, ds, ss); + font = fm.getFontById(id); + if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { + // read vf file, register its font and character definitions + fm.enterVF(vf); + ifstream ifs(vf->path(), ios::binary); + VFReader vfReader(ifs); + vfReader.replaceActions(this); + vfReader.executeAll(); + fm.leaveVF(); + } } - if (_actions) - _actions->defineFont(id, font); + return font; } /** Defines a new font. - * @param[in] len size of font number variable (in bytes) */ + * @param[in] len size of font number variable (in bytes) */ void DVIReader::cmdFontDef (int len) { UInt32 fontnum = readUnsigned(len); // font number UInt32 checksum = readUnsigned(4); // font checksum (to be compared with corresponding TFM checksum) @@ -558,10 +514,10 @@ void DVIReader::cmdFontDef (int len) { UInt32 dsize = readUnsigned(4); // design size of font in DVI units UInt32 pathlen = readUnsigned(1); // length of font path UInt32 namelen = readUnsigned(1); // length of font name - readString(pathlen); // skip font path + string path = readString(pathlen); // path to font file string fontname = readString(namelen); - - defineFont(fontnum, fontname, checksum, dsize*_dvi2bp, ssize*_dvi2bp); + const Font *font = defineFont(fontnum, fontname, checksum, dsize*_dvi2bp, ssize*_dvi2bp); + dviFontDef(fontnum, checksum, font); } @@ -573,7 +529,7 @@ void DVIReader::cmdFontDef (int len) { * @param[in] dsize design size in PS point units * @param[in] ssize scaled size in PS point units */ void DVIReader::defineVFFont (UInt32 fontnum, string path, string name, UInt32 checksum, double dsize, double ssize) { - if (VirtualFont *vf = FontManager::instance().getVF()) + if (const VirtualFont *vf = FontManager::instance().getVF()) defineFont(fontnum, name, checksum, dsize, ssize * vf->scaleFactor()); } @@ -589,13 +545,14 @@ void DVIReader::defineVFChar (UInt32 c, vector<UInt8> *dvi) { /** XDV extension: includes image or pdf file. * parameters: box[1] matrix[4][6] p[2] len[2] path[l] */ void DVIReader::cmdXPic (int) { - // just skip the parameters - readUnsigned(1); // box - for (int i=0; i < 6; i++) // matrix - readSigned(4); - readSigned(2); // page number + UInt8 box = readUnsigned(1); // box + vector<Int32> matrix(6); + for (int i=0; i < 6; i++) // matrix + matrix[i] = readSigned(4); + Int16 page = readSigned(2); // page number UInt16 len = readUnsigned(2); - readString(len); // path to image/pdf file + string path = readString(len); // path to image/pdf file + dviXPic(box, matrix, page, path); } @@ -605,11 +562,11 @@ void DVIReader::cmdXFontDef (int) { double ptsize = _dvi2bp*readUnsigned(4); UInt16 flags = readUnsigned(2); UInt8 psname_len = readUnsigned(1); - UInt8 fmname_len = getDVIFormat() == DVI_XDVOLD ? readUnsigned(1) : 0; - UInt8 stname_len = getDVIFormat() == DVI_XDVOLD ? readUnsigned(1) : 0; + UInt8 fmname_len = getDVIVersion() == DVI_XDV5 ? readUnsigned(1) : 0; // length of family name + UInt8 stname_len = getDVIVersion() == DVI_XDV5 ? readUnsigned(1) : 0; // length of style name string fontname = readString(psname_len); UInt32 fontIndex=0; - if (getDVIFormat() == DVI_XDVOLD) + if (getDVIVersion() == DVI_XDV5) seek(fmname_len+stname_len, ios::cur); else fontIndex = readUnsigned(4); @@ -630,54 +587,85 @@ void DVIReader::cmdXFontDef (int) { style.slant = _dvi2bp*readSigned(4); if (flags & 0x4000) // embolden? style.bold = _dvi2bp*readSigned(4); - if ((flags & 0x0800) && (getDVIFormat() == DVI_XDVOLD)) { // variations? + if ((flags & 0x0800) && (getDVIVersion() == DVI_XDV5)) { // variations? UInt16 num_variations = readSigned(2); for (int i=0; i < num_variations; i++) readUnsigned(4); } - if (_inPage) + const Font *font = FontManager::instance().getFont(fontnum); + if (!font) { FontManager::instance().registerFont(fontnum, fontname, fontIndex, ptsize, style, color); + font = FontManager::instance().getFont(fontnum); + } + dviXFontDef(fontnum, dynamic_cast<const NativeFont*>(font)); } /** XDV extension: prints an array of characters where each character * can take independent x and y coordinates. - * parameters: w[4] n[2] x[4][n] y[4][n] c[2][n] */ + * parameters: w[4] n[2] (dx,dy)[(4+4)n] glyphs[2n] */ void DVIReader::cmdXGlyphArray (int) { - putGlyphArray(false); + vector<double> dx, dy; + vector<UInt16> glyphs; + putGlyphArray(false, dx, dy, glyphs); + if (Font *font = FontManager::instance().getFont(_currFontNum)) + dviXGlyphArray(dx, dy, glyphs, *font); + else + throw DVIException("missing setfont prior to xglypharray"); } /** XDV extension: prints an array/string of characters where each character * can take independent x coordinates whereas all share a single y coordinate. - * parameters: w[4] n[2] x[4][n] y[4] c[2][n] */ + * parameters: w[4] n[2] dx[4n] dy[4] glyphs[2n] */ void DVIReader::cmdXGlyphString (int) { - putGlyphArray(true); + vector<double> dx, dy; + vector<UInt16> glyphs; + putGlyphArray(true, dx, dy, glyphs); + if (Font *font = FontManager::instance().getFont(_currFontNum)) + dviXGlyphString(dx, glyphs, *font); + else + throw DVIException("missing setfont prior to xglyphstring"); +} + + +/** XDV extension: Same as cmdXGlyphArray plus a leading array of UTF-16 characters + * that specify the "actual text" represented by the glyphs to be printed. It usually + * contains the text with special characters (like ligatures) expanded so that it + * can be used for text search, plain text copy & paste etc. This XDV command was + * introduced with XeTeX 0.99995 and can be triggered by <tt>\\XeTeXgenerateactualtext1</tt>. + * parameters: l[2] chars[2l] w[4] n[2] (dx,dy)[8n] glyphs[2n] */ +void DVIReader::cmdXTextAndGlyphs (int) { + UInt16 l = readUnsigned(2); // number of chars + vector<UInt16> chars(l); + for (int i=0; i < l; i++) + chars[i] = readUnsigned(2); + vector<double> x, y; + vector<UInt16> glyphs; + putGlyphArray(false, x, y, glyphs); + if (Font *font = FontManager::instance().getFont(_currFontNum)) + dviXTextAndGlyphs(x, y, chars, glyphs, *font); + else + throw DVIException("missing setfont prior to xtextandglyphs"); } -/** Implements the common functionality of cmdXGlyphA and cmdXGlyphS. - * @param[in] xonly indicates if the characters share a single y coordinate (xonly==true) */ -void DVIReader::putGlyphArray (bool xonly) { +/** Implements the common functionality of cmdXGlyphArray, cmdXGlyphString, and cmdXTextAndGlyphs. + * @param[in] xonly indicates if the characters share a single y coordinate (xonly==true) + * @param[out] dx relative horizontal positions of each glyph + * @param[out] dy relative vertical positions of each glyph + * @param[out] glyphs FreeType indices of the glyphs to typeset */ +void DVIReader::putGlyphArray (bool xonly, vector<double> &dx, vector<double> &dy, vector<UInt16> &glyphs) { double strwidth = _dvi2bp*readSigned(4); UInt16 num_glyphs = readUnsigned(2); - vector<Int32> x(num_glyphs); - vector<Int32> y(num_glyphs); + dx.resize(num_glyphs); + dy.resize(num_glyphs); + glyphs.resize(num_glyphs); for (int i=0; i < num_glyphs; i++) { - x[i] = readSigned(4); - y[i] = xonly ? 0 : readSigned(4); - } - if (!_actions) - seek(2*num_glyphs, ios::cur); - else { - if (Font *font = FontManager::instance().getFont(_currFontNum)) { - for (int i=0; i < num_glyphs; i++) { - UInt16 glyph_index = readUnsigned(2); - double xx = _dviState.h + x[i]*_dvi2bp + _tx; - double yy = _dviState.v + y[i]*_dvi2bp + _ty; - _actions->setChar(xx, yy, glyph_index, false, font); - } - } + dx[i] = readSigned(4)*_dvi2bp; + dy[i] = xonly ? 0 : readSigned(4)*_dvi2bp; } + for (int i=0; i < num_glyphs; i++) + glyphs[i] = readUnsigned(2); moveRight(strwidth); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h index 19a5042625a..97d297adc55 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h @@ -26,68 +26,105 @@ #include <stack> #include <string> #include "BasicDVIReader.h" -#include "MessageException.h" -#include "StreamReader.h" +#include "Color.h" #include "VFActions.h" #include "types.h" +class Font; +class FontStyle; +class NativeFont; +class VirtualFont; -struct DVIActions; - -class DVIReader : public BasicDVIReader, protected VFActions +class DVIReader : public BasicDVIReader, public VFActions { - enum WritingMode {WMODE_LR=0, WMODE_TB=1, WMODE_BT=3}; + protected: + enum WritingMode {WMODE_LR=0, WMODE_TB=1, WMODE_BT=3}; + enum SetFontMode {SF_SHORT, SF_LONG, VF_ENTER, VF_LEAVE}; - struct DVIState - { - double h, v; ///< horizontal and vertical cursor position - double x, w, y, z; ///< additional registers to store horizontal (x, w) and vertical (y, z) positions - WritingMode d; ///< direction: 0: horizontal, 1: vertical(top->bottom), 3: vertical (bottom->top) - DVIState () {reset();} - void reset () {h = v = x = w = y = z = 0.0; d=WMODE_LR;} - }; + struct DVIState + { + double h, v; ///< horizontal and vertical cursor position + double x, w, y, z; ///< additional registers to store horizontal (x, w) and vertical (y, z) positions + WritingMode d; ///< direction: 0: horizontal, 1: vertical(top->bottom), 3: vertical (bottom->top) + DVIState () {reset();} + void reset () {h = v = x = w = y = z = 0.0; d=WMODE_LR;} + }; public: - DVIReader (std::istream &is, DVIActions *a=0); - + explicit DVIReader (std::istream &is); bool executeDocument (); void executeAll (); void executePreamble (); void executePostamble (); bool executePage (unsigned n); - bool inPostamble () const {return _inPostamble;} - double getXPos () const; - double getYPos () const; - void finishLine () {_prevYPos = std::numeric_limits<double>::min();} - void translateToX (double x) {_tx = x-_dviState.h-_tx;} - void translateToY (double y) {_ty = y-_dviState.v-_ty;} - double getPageWidth () const {return _pageWidth;} - double getPageHeight () const {return _pageHeight;} - int getStackDepth () const {return _stateStack.size();} - int getCurrentFontNumber () const {return _currFontNum;} - unsigned getCurrentPageNumber () const {return _currPageNum;} - unsigned numberOfPages () const {return _bopOffsets.empty() ? 0 : _bopOffsets.size()-1;} - DVIActions* getActions () const {return _actions;} - DVIActions* replaceActions (DVIActions *a); + bool inPostamble () const {return _inPostamble;} + double getXPos () const {return _currDviState.h;} + double getYPos () const {return _currDviState.v;} + int stackDepth () const {return _stateStack.size();} + int currentFontNumber () const {return _currFontNum;} + unsigned currentPageNumber () const {return _currPageNum;} + unsigned numberOfPages () const {return _bopOffsets.empty() ? 0 : _bopOffsets.size()-1;} protected: + int executeCommand (); void collectBopOffsets (); size_t numberOfPageBytes (int n) const {return _bopOffsets.size() > 1 ? _bopOffsets[n+1]-_bopOffsets[n] : 0;} - int executeCommand (); - void moveRight (double dx); - void moveDown (double dy); - void putChar (UInt32 c, bool moveCursor); - void putGlyphArray (bool xonly); - void defineFont (UInt32 fontnum, const std::string &name, UInt32 cs, double ds, double ss); - virtual void beginPage (unsigned pageno, Int32 *c) {} - virtual void endPage (unsigned pageno) {} + virtual void moveRight (double dx); + virtual void moveDown (double dy); + void putVFChar (Font *font, UInt32 c); + void putGlyphArray (bool xonly, std::vector<double> &dx, std::vector<double> &dy, std::vector<UInt16> &glyphs); + const Font* defineFont (UInt32 fontnum, const std::string &name, UInt32 cs, double ds, double ss); + void setFont (int num, SetFontMode mode); + const DVIState& currState() const {return _currDviState;} + const DVIState& prevState() const {return _prevDviState;} + double dvi2bp () const {return _dvi2bp;} + bool inPage () const {return _inPage;} // VFAction methods void defineVFFont (UInt32 fontnum, std::string path, std::string name, UInt32 checksum, double dsize, double ssize); void defineVFChar (UInt32 c, std::vector<UInt8> *dvi); - // the following methods represent the DVI commands - // they are called by executeCommand and should not be used directly + // The following template methods provide higher-level access to the DVI commands. + // In contrast to their cmdXXX pendants, they don't require any handling of the input stream. + // All command arguments are delivered as function parameters. These methods are called after + // the DVI registers have been updated, i.e. currState() represents the state after executing + // the command. If the previous register state is required, prevState() can be used. + virtual void dviPre (UInt8 id, UInt32 numer, UInt32 denom, UInt32 mag, const std::string &comment) {} + virtual void dviPost (UInt16 stdepth, UInt16 pages, UInt32 pw, UInt32 ph, UInt32 mag, UInt32 num, UInt32 den, UInt32 lbopofs) {} + virtual void dviPostPost (UInt8 id, UInt32 postOffset) {} + virtual void dviBop (const std::vector<Int32> &c, Int32 prevBopOffset) {} + virtual void dviEop () {} + virtual void dviSetChar0 (UInt32 c, const Font *font) {} + virtual void dviSetChar (UInt32 c, const Font *font) {} + virtual void dviPutChar (UInt32 c, const Font *font) {} + virtual void dviSetRule (double h, double w) {} + virtual void dviPutRule (double h, double w) {} + virtual void dviNop () {} + virtual void dviPush () {} + virtual void dviPop () {} + virtual void dviRight (double dx) {} + virtual void dviDown (double dy) {} + virtual void dviX0 () {} + virtual void dviY0 () {} + virtual void dviW0 () {} + virtual void dviZ0 () {} + virtual void dviX (double x) {} + virtual void dviY (double y) {} + virtual void dviW (double w) {} + virtual void dviZ (double z) {} + virtual void dviFontDef (UInt32 fontnum, UInt32 checksum, const Font *font) {} + virtual void dviFontNum (UInt32 fontnum, SetFontMode mode, const Font *font) {} + virtual void dviDir (WritingMode dir) {} + virtual void dviXXX (const std::string &str) {} + virtual void dviXPic (UInt8 box, const std::vector<Int32> &matrix, Int16 page, const std::string &path) {} + virtual void dviXFontDef (UInt32 fontnum, const NativeFont *font) {} + virtual void dviXGlyphArray (std::vector<double> &dx, std::vector<double> &dy, std::vector<UInt16> &glyphs, const Font &font) {} + virtual void dviXGlyphString (std::vector<double> &dx, std::vector<UInt16> &glyphs, const Font &font) {} + virtual void dviXTextAndGlyphs (std::vector<double> &dx, std::vector<double> &dy, std::vector<UInt16> &chars, std::vector<UInt16> &glyphs, const Font &font) {} + + private: + // The following low-level methods evaluate the DVI commands read from + // the input stream and call the corresponding dviXXX methods. void cmdSetChar0 (int c); void cmdSetChar (int len); void cmdPutChar (int len); @@ -120,26 +157,19 @@ class DVIReader : public BasicDVIReader, protected VFActions void cmdXFontDef (int len); void cmdXGlyphArray (int len); void cmdXGlyphString (int len); + void cmdXTextAndGlyphs (int len); private: - DVIActions *_actions; ///< actions to be performed on various DVI events - bool _inPage; ///< true if between bop and eop + bool _inPage; ///< true if stream pointer is between bop and eop unsigned _currPageNum; ///< current page number (1 is first page) int _currFontNum; ///< current font number double _dvi2bp; ///< factor to convert dvi units to PS points UInt32 _mag; ///< magnification factor * 1000 bool _inPostamble; ///< true if stream pointer is inside the postamble - double _pageHeight; ///< page height in PS points - double _pageWidth; ///< page width in PS points - DVIState _dviState; ///< registers of the DVI processor + DVIState _currDviState; ///< current state of the DVI registers + DVIState _prevDviState; ///< previous state of the DVI registers std::stack<DVIState> _stateStack; std::vector<UInt32> _bopOffsets; - double _prevYPos; ///< previous vertical cursor position - double _tx, _ty; ///< tranlation of cursor position - std::streampos _pagePos; ///< distance of current DVI command from bop (in bytes) - - public: - static bool COMPUTE_PROGRESS; ///< if true, an action to handle the progress ratio of a page is triggered }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp index 5582eb59989..ed292354485 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp @@ -34,8 +34,10 @@ #include "InputReader.h" #include "PageRanges.h" #include "PageSize.h" +#include "PreScanDVIReader.h" +#include "SignalHandler.h" #include "SVGOutput.h" -// + /////////////////////////////////// // special handlers @@ -43,8 +45,9 @@ #include "ColorSpecialHandler.h" #include "DvisvgmSpecialHandler.h" #include "EmSpecialHandler.h" -#include "PdfSpecialHandler.h" #include "HtmlSpecialHandler.h" +#include "PapersizeSpecialHandler.h" +#include "PdfSpecialHandler.h" #ifndef HAVE_LIBGS #include "NoPsSpecialHandler.h" #endif @@ -52,27 +55,30 @@ #include "PsSpecialHandler.h" #endif #include "TpicSpecialHandler.h" -#include "PreScanDVIReader.h" /////////////////////////////////// using namespace std; - /** 'a': trace all glyphs even if some of them are already cached * 'm': trace missing glyphs, i.e. glyphs not yet cached * 0 : only trace actually required glyphs */ char DVIToSVG::TRACE_MODE = 0; +bool DVIToSVG::COMPUTE_PROGRESS = false; DVIToSVG::DVIToSVG (istream &is, SVGOutputBase &out) : DVIReader(is), _out(out) { - replaceActions(new DVIToSVGActions(*this, _svg)); + _pageHeight = _pageWidth = 0; + _tx = _ty = 0; // no cursor translation + _pageByte = 0; + _prevYPos = numeric_limits<double>::min(); + _actions = new DVIToSVGActions(*this, _svg); } DVIToSVG::~DVIToSVG () { - delete replaceActions(0); + delete _actions; } @@ -96,11 +102,11 @@ void DVIToSVG::convert (unsigned first, unsigned last, pair<int,int> *pageinfo) executePage(i); _svg.removeRedundantElements(); embedFonts(_svg.rootNode()); - _svg.write(_out.getPageStream(getCurrentPageNumber(), numberOfPages())); + _svg.write(_out.getPageStream(currentPageNumber(), numberOfPages())); string fname = _out.filename(i, numberOfPages()); - Message::mstream(false, Message::MC_PAGE_WRITTEN) << "\npage written to " << (fname.empty() ? "<stdout>" : fname) << '\n'; + Message::mstream(false, Message::MC_PAGE_WRITTEN) << "\noutput written to " << (fname.empty() ? "<stdout>" : fname) << '\n'; _svg.reset(); - static_cast<DVIToSVGActions*>(getActions())->reset(); + static_cast<DVIToSVGActions*>(_actions)->reset(); } if (pageinfo) { pageinfo->first = last-first+1; @@ -117,8 +123,8 @@ void DVIToSVG::convert (const string &rangestr, pair<int,int> *pageinfo) { if (!ranges.parse(rangestr, numberOfPages())) throw MessageException("invalid page range format"); - Message::mstream(false, Message::MC_PAGE_NUMBER) << "pre-processing DVI file (format " << getDVIFormat() << ")\n"; - if (DVIToSVGActions *actions = dynamic_cast<DVIToSVGActions*>(getActions())) { + Message::mstream(false, Message::MC_PAGE_NUMBER) << "pre-processing DVI file (format version " << getDVIVersion() << ")\n"; + if (DVIToSVGActions *actions = dynamic_cast<DVIToSVGActions*>(_actions)) { PreScanDVIReader prescan(getInputStream(), actions); actions->setDVIReader(prescan); prescan.executeAllPages(); @@ -135,42 +141,56 @@ void DVIToSVG::convert (const string &rangestr, pair<int,int> *pageinfo) { } +int DVIToSVG::executeCommand () { + SignalHandler::instance().check(); + const streampos cmdpos = tell(); + int opcode = DVIReader::executeCommand(); + if (currState().v+_ty != _prevYPos) { + _tx = _ty = 0; + _prevYPos = currState().v; + } + if (COMPUTE_PROGRESS && inPage() && _actions) { + size_t pagelen = numberOfPageBytes(currentPageNumber()-1); + _pageByte += tell()-cmdpos; + _actions->progress(_pageByte, pagelen); + } + return opcode; +} + + /** This template method is called by parent class DVIReader before * executing the BOP actions. * @param[in] pageno physical page number (1 = first page) * @param[in] c contains information about the page (page number etc.) */ -void DVIToSVG::beginPage (unsigned pageno, Int32 *c) { - if (dynamic_cast<DVIToSVGActions*>(getActions())) { +void DVIToSVG::enterBeginPage (unsigned pageno, const vector<Int32> &c) { + if (dynamic_cast<DVIToSVGActions*>(_actions)) { Message::mstream().indent(0); Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing page " << pageno; if (pageno != (unsigned)c[0]) // Does page number shown on page differ from physical page number? Message::mstream(false) << " [" << c[0] << ']'; Message::mstream().indent(1); _svg.appendToDoc(new XMLCommentNode(" This file was generated by dvisvgm " VERSION " ")); - SpecialManager::instance().notifyBeginPage(pageno); } } -/** This template method is called by parent class DVIReader before +/** This template method is called by DVIReader::cmdEop() after * executing the EOP actions. */ -void DVIToSVG::endPage (unsigned pageno) { - if (!dynamic_cast<DVIToSVGActions*>(getActions())) +void DVIToSVG::leaveEndPage (unsigned) { + if (!dynamic_cast<DVIToSVGActions*>(_actions)) return; - SpecialManager::instance().notifyEndPage(pageno); // set bounding box and apply page transformations - BoundingBox &bbox = getActions()->bbox(); - bbox.unlock(); - Matrix matrix; - getPageTransformation(matrix); - static_cast<DVIToSVGActions*>(getActions())->setPageMatrix(matrix); - if (_bboxFormatString == "min" || _bboxFormatString == "preview") + BoundingBox bbox = _actions->bbox(); // bounding box derived from the DVI commands executed + if (_bboxFormatString == "min" || _bboxFormatString == "preview" || _bboxFormatString == "papersize") { + Matrix matrix; + getPageTransformation(matrix); bbox.transform(matrix); + } else if (_bboxFormatString == "dvi") { // center page content - double dx = (getPageWidth()-bbox.width())/2; - double dy = (getPageHeight()-bbox.height())/2; + double dx = (_pageWidth-bbox.width())/2; + double dy = (_pageHeight-bbox.height())/2; bbox += BoundingBox(-dx, -dy, dx, dy); } else if (_bboxFormatString != "none") { @@ -189,7 +209,15 @@ void DVIToSVG::endPage (unsigned pageno) { } else { // set/modify bounding box by explicitly given values try { - bbox.set(_bboxFormatString); + vector<Length> lengths; + BoundingBox::extractLengths(_bboxFormatString, lengths); + if (lengths.size() == 1 || lengths.size() == 2) { // relative box size? + // apply the page transformation and adjust the bbox afterwards + Matrix matrix; + getPageTransformation(matrix); + bbox.transform(matrix); + } + bbox.set(lengths); } catch (const MessageException &e) { } @@ -199,11 +227,10 @@ void DVIToSVG::endPage (unsigned pageno) { Message::wstream(false) << "\npage is empty\n"; if (_bboxFormatString != "none") { _svg.setBBox(bbox); - const double bp2pt = 72.27/72; const double bp2mm = 25.4/72; Message::mstream(false) << '\n'; - Message::mstream(false, Message::MC_PAGE_SIZE) << "page size: " << XMLString(bbox.width()*bp2pt) << "pt" + Message::mstream(false, Message::MC_PAGE_SIZE) << "graphic size: " << XMLString(bbox.width()*bp2pt) << "pt" " x " << XMLString(bbox.height()*bp2pt) << "pt" " (" << XMLString(bbox.width()*bp2mm) << "mm" " x " << XMLString(bbox.height()*bp2mm) << "mm)"; @@ -217,9 +244,9 @@ void DVIToSVG::getPageTransformation(Matrix &matrix) const { matrix.set(1); // unity matrix else { Calculator calc; - if (getActions()) { + if (_actions) { const double bp2pt = 72.27/72; - BoundingBox &bbox = getActions()->bbox(); + BoundingBox &bbox = _actions->bbox(); calc.setVariable("ux", bbox.minX()*bp2pt); calc.setVariable("uy", bbox.minY()*bp2pt); calc.setVariable("w", bbox.width()*bp2pt); @@ -250,11 +277,11 @@ static void collect_chars (map<const Font*, set<int> > &fm) { void DVIToSVG::embedFonts (XMLElementNode *svgElement) { if (!svgElement) return; - if (!getActions()) // no dvi actions => no chars written => no fonts to embed + if (!_actions) // no dvi actions => no chars written => no fonts to embed return; typedef map<const Font*, set<int> > UsedCharsMap; - const DVIToSVGActions *svgActions = static_cast<DVIToSVGActions*>(getActions()); + const DVIToSVGActions *svgActions = static_cast<DVIToSVGActions*>(_actions); UsedCharsMap &usedChars = svgActions->getUsedChars(); collect_chars(usedChars); @@ -297,14 +324,15 @@ void DVIToSVG::setProcessSpecials (const char *ignorelist, bool pswarning) { else { // add special handlers SpecialHandler *handlers[] = { - 0, // placeholder for PsSpecialHandler - new BgColorSpecialHandler, // handles background color special - new ColorSpecialHandler, // handles color specials - new DvisvgmSpecialHandler, // handles raw SVG embeddings - new EmSpecialHandler, // handles emTeX specials - new HtmlSpecialHandler, // handles hyperref specials - new PdfSpecialHandler, // handles pdf specials - new TpicSpecialHandler, // handles tpic specials + 0, // placeholder for PsSpecialHandler + new BgColorSpecialHandler, // handles background color special + new ColorSpecialHandler, // handles color specials + new DvisvgmSpecialHandler, // handles raw SVG embeddings + new EmSpecialHandler, // handles emTeX specials + new HtmlSpecialHandler, // handles hyperref specials + new PapersizeSpecialHandler, // handles papersize special + new PdfSpecialHandler, // handles pdf specials + new TpicSpecialHandler, // handles tpic specials 0 }; SpecialHandler **p = handlers; @@ -334,3 +362,131 @@ void DVIToSVG::setProcessSpecials (const char *ignorelist, bool pswarning) { string DVIToSVG::getSVGFilename (unsigned pageno) const { return _out.filename(pageno, numberOfPages()); } + + +void DVIToSVG::moveRight (double dx) { + DVIReader::moveRight(dx); + if (_actions) { + if (currState().d == WMODE_LR) + _actions->moveToX(currState().h+_tx); + else + _actions->moveToY(currState().v+_ty); + } +} + + +void DVIToSVG::moveDown (double dy) { + DVIReader::moveDown(dy); + if (_actions) { + if (currState().d == WMODE_LR) + _actions->moveToY(currState().v+_ty); + else + _actions->moveToX(currState().h+_tx); + } +} + + +void DVIToSVG::dviPost (UInt16, UInt16 pages, UInt32 pw, UInt32 ph, UInt32, UInt32, UInt32, UInt32) { + _pageHeight = ph; // height of tallest page in dvi units + _pageWidth = pw; // width of widest page in dvi units +} + + +void DVIToSVG::dviBop (const std::vector<Int32> &c, Int32) { + _pageByte = 0; + enterBeginPage(currentPageNumber(), c); + if (_actions) { + _actions->progress(0, 1); // ensure that progress is called at 0% + _actions->beginPage(currentPageNumber(), c); + } +} + + +void DVIToSVG::dviEop () { + if (_actions) { + _actions->endPage(currentPageNumber()); + _pageByte = numberOfPageBytes(currentPageNumber()-1); + _actions->progress(_pageByte, _pageByte); // ensure that progress is called at 100% + } + leaveEndPage(currentPageNumber()); +} + + +void DVIToSVG::dviSetChar0 (UInt32 c, const Font *font) { + if (_actions && !dynamic_cast<const VirtualFont*>(font)) + _actions->setChar(prevState().h+_tx, prevState().v+_ty, c, prevState().d != WMODE_LR, *font); +} + + +void DVIToSVG::dviSetChar (UInt32 c, const Font *font) { + dviSetChar0(c, font); +} + + +void DVIToSVG::dviPutChar (UInt32 c, const Font *font) { + dviSetChar0(c, font); +} + + +void DVIToSVG::dviSetRule (double height, double width) { + if (_actions && height > 0 && width > 0) + _actions->setRule(currState().h+_tx, currState().v+_ty, height, width); +} + + +void DVIToSVG::dviPutRule (double height, double width) { + dviSetRule(height, width); +} + + +void DVIToSVG::dviPop () { + if (_actions) { + if (prevState().h != currState().h) + _actions->moveToX(currState().h + _tx); + if (prevState().v != currState().v) + _actions->moveToY(currState().v + _ty); + if (prevState().d != currState().d) + _actions->setTextOrientation(currState().d != WMODE_LR); + } +} + + +void DVIToSVG::dviFontNum (UInt32 fontnum, SetFontMode, const Font *font) { + if (_actions && font && !dynamic_cast<const VirtualFont*>(font)) + _actions->setFont(FontManager::instance().fontID(fontnum), *font); // all fonts get a recomputed ID +} + + +void DVIToSVG::dviDir (WritingMode dir) { + if (_actions) + _actions->setTextOrientation(dir != WMODE_LR); +} + + +void DVIToSVG::dviXXX (const std::string &str) { + if (_actions) + _actions->special(str, dvi2bp()); +} + + +void DVIToSVG::dviXGlyphArray (std::vector<double> &dx, vector<double> &dy, vector<UInt16> &glyphs, const Font &font) { + if (_actions) { + for (size_t i=0; i < glyphs.size(); i++) + _actions->setChar(prevState().h+dx[i]+_tx, prevState().v+dy[i]+_ty, glyphs[i], false, font); + } +} + + +void DVIToSVG::dviXGlyphString (vector<double> &dx, vector<UInt16> &glyphs, const Font &font) { + if (_actions) { + for (size_t i=0; i < glyphs.size(); i++) + _actions->setChar(prevState().h+dx[i]+_tx, prevState().v+_ty, glyphs[i], false, font); + } +} + + +void DVIToSVG::dviXTextAndGlyphs (vector<double> &dx, vector<double> &dy, vector<UInt16>&, vector<UInt16> &glyphs, const Font &font) { + dviXGlyphArray(dx, dy, glyphs, font); +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h index deb8d1c4039..623056ae0ea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h @@ -24,40 +24,71 @@ #include <string> #include <utility> #include "DVIReader.h" -#include "SpecialManager.h" #include "SVGTree.h" +struct DVIActions; class Matrix; struct SVGOutputBase; class DVIToSVG : public DVIReader { public: - DVIToSVG (std::istream &is, SVGOutputBase &out); + explicit DVIToSVG (std::istream &is, SVGOutputBase &out); ~DVIToSVG (); void convert (const std::string &range, std::pair<int,int> *pageinfo=0); void setPageSize (const std::string &format) {_bboxFormatString = format;} void setPageTransformation (const std::string &cmds) {_transCmds = cmds;} void getPageTransformation (Matrix &matrix) const; + void translateToX (double x) {_tx = x-currState().h-_tx;} + void translateToY (double y) {_ty = y-currState().v-_ty;} + double getXPos() const {return currState().h+_tx;} + double getYPos() const {return currState().v+_ty;} + void finishLine () {_prevYPos = std::numeric_limits<double>::min();} + std::string getSVGFilename (unsigned pageno) const; - std::string getUserBBoxString () const {return _bboxFormatString;} + std::string getUserBBoxString () const {return _bboxFormatString;} static void setProcessSpecials (const char *ignorelist=0, bool pswarning=false); public: + static bool COMPUTE_PROGRESS; ///< if true, an action to handle the progress ratio of a page is triggered static char TRACE_MODE; protected: - DVIToSVG (const DVIToSVG &); + DVIToSVG (const DVIToSVG&); void convert (unsigned firstPage, unsigned lastPage, std::pair<int,int> *pageinfo=0); - void beginPage (unsigned pageno, Int32 *c); - void endPage (unsigned pageno); + int executeCommand (); + void enterBeginPage (unsigned pageno, const std::vector<Int32> &c); + void leaveEndPage (unsigned pageno); void embedFonts (XMLElementNode *svgElement); + void moveRight (double dx); + void moveDown (double dy); + + void dviPost (UInt16 stdepth, UInt16 pages, UInt32 pw, UInt32 ph, UInt32 mag, UInt32 num, UInt32 den, UInt32 lbopofs); + void dviBop (const std::vector<Int32> &c, Int32 prevBopOffset); + void dviEop (); + void dviSetChar0 (UInt32 c, const Font *font); + void dviSetChar (UInt32 c, const Font *font); + void dviPutChar (UInt32 c, const Font *font); + void dviSetRule (double h, double w); + void dviPutRule (double h, double w); + void dviPop (); + void dviFontNum (UInt32 fontnum, SetFontMode mode, const Font *font); + void dviDir (WritingMode dir); + void dviXXX (const std::string &str); + void dviXGlyphArray (std::vector<double> &dx, std::vector<double> &dy, std::vector<UInt16> &glyphs, const Font &font); + void dviXGlyphString (std::vector<double> &dx, std::vector<UInt16> &glyphs, const Font &font); + void dviXTextAndGlyphs (std::vector<double> &dx, std::vector<double> &dy, std::vector<UInt16> &chars, std::vector<UInt16> &glyphs, const Font &font); private: SVGTree _svg; SVGOutputBase &_out; + DVIActions *_actions; std::string _bboxFormatString; ///< bounding box size/format set by the user std::string _transCmds; ///< page transformation commands set by the user + double _pageHeight, _pageWidth; ///< global page height and width stored in the postamble + double _tx, _ty; ///< translation of cursor position + double _prevYPos; ///< previous vertical cursor position + std::streampos _pageByte; ///< position of the stream pointer relative to the preceding bop (in bytes) }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp index 3cff2c8c8c6..2b774ca80d0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp @@ -34,7 +34,7 @@ using namespace std; DVIToSVGActions::DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg) - : _svg(svg), _dvireader(&dvisvg), _pageMatrix(0), _bgcolor(Color::TRANSPARENT), _boxes(0) + : _svg(svg), _dvireader(&dvisvg), _bgcolor(Color::TRANSPARENT), _boxes(0) { _currentFontNum = -1; _pageCount = 0; @@ -42,7 +42,6 @@ DVIToSVGActions::DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg) DVIToSVGActions::~DVIToSVGActions () { - delete _pageMatrix; delete _boxes; } @@ -56,20 +55,14 @@ void DVIToSVGActions::reset() { } -void DVIToSVGActions::setPageMatrix (const Matrix &matrix) { - delete _pageMatrix; - _pageMatrix = new Matrix(matrix); -} - - void DVIToSVGActions::moveToX (double x) { - SpecialManager::instance().notifyPositionChange(getX(), getY()); + SpecialManager::instance().notifyPositionChange(getX(), getY(), *this); _svg.setX(x); } void DVIToSVGActions::moveToY (double y) { - SpecialManager::instance().notifyPositionChange(getX(), getY()); + SpecialManager::instance().notifyPositionChange(getX(), getY(), *this); _svg.setY(y); } @@ -95,25 +88,25 @@ string DVIToSVGActions::getBBoxFormatString () const { * @param[in] c character code relative to the current font * @param[in] vertical true if we're in vertical mode * @param[in] font font to be used */ -void DVIToSVGActions::setChar (double x, double y, unsigned c, bool vertical, const Font *font) { +void DVIToSVGActions::setChar (double x, double y, unsigned c, bool vertical, const Font &font) { // If we use SVG fonts there is no need to record all font name/char/size combinations // because the SVG font mechanism handles this automatically. It's sufficient to // record font names and chars. The various font sizes can be ignored here. // For a given font object, Font::uniqueFont() returns the same unique font object for // all fonts with the same name. - _usedChars[SVGTree::USE_FONTS ? font->uniqueFont() : font].insert(c); + _usedChars[SVGTree::USE_FONTS ? font.uniqueFont() : &font].insert(c); // However, we record all required fonts - _usedFonts.insert(font); - _svg.appendChar(c, x, y, *font); + _usedFonts.insert(&font); + _svg.appendChar(c, x, y); static string fontname; - GlyphTracerMessages callback(fontname != font->name(), false); - fontname = font->name(); + GlyphTracerMessages callback(fontname != font.name(), false); + fontname = font.name(); GlyphMetrics metrics; - font->getGlyphMetrics(c, vertical, metrics); - const PhysicalFont* pf = dynamic_cast<const PhysicalFont*>(font); + font.getGlyphMetrics(c, vertical, metrics); + const PhysicalFont* pf = dynamic_cast<const PhysicalFont*>(&font); if (PhysicalFont::EXACT_BBOX && pf) { GlyphMetrics exact_metrics; pf->getExactGlyphBox(c, exact_metrics, vertical, &callback); @@ -207,9 +200,9 @@ void DVIToSVGActions::setFont (int num, const Font &font) { void DVIToSVGActions::special (const string &spc, double dvi2bp, bool preprocessing) { try { if (preprocessing) - SpecialManager::instance().preprocess(spc, this); + SpecialManager::instance().preprocess(spc, *this); else - SpecialManager::instance().process(spc, dvi2bp, this); + SpecialManager::instance().process(spc, dvi2bp, *this); // @@ output message in case of unsupported specials? } catch (const SpecialException &e) { @@ -222,7 +215,8 @@ void DVIToSVGActions::special (const string &spc, double dvi2bp, bool preprocess * @param[in] pageno physical page number * @param[in] c array with 10 components representing \\count0 ... \\count9. c[0] contains the * current (printed) page number (may differ from page count) */ -void DVIToSVGActions::beginPage (unsigned pageno, Int32 *c) { +void DVIToSVGActions::beginPage (unsigned pageno, const vector<Int32>&) { + SpecialManager::instance().notifyBeginPage(pageno, *this); _svg.newPage(++_pageCount); _bbox = BoundingBox(); // clear bounding box if (_boxes) @@ -232,7 +226,10 @@ void DVIToSVGActions::beginPage (unsigned pageno, Int32 *c) { /** This method is called when an "end of page (eop)" command was found in the DVI file. */ void DVIToSVGActions::endPage (unsigned pageno) { - _svg.transformPage(_pageMatrix); + SpecialManager::instance().notifyEndPage(pageno, *this); + Matrix matrix; + _dvireader->getPageTransformation(matrix); + _svg.transformPage(matrix); if (_bgcolor != Color::TRANSPARENT) { // create a rectangle filled with the background color XMLElementNode *r = new XMLElementNode("rect"); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h index 70024237f2a..fb2ca03f29b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h @@ -33,8 +33,8 @@ class DVIToSVG; struct FileFinder; -struct Font; -struct XMLNode; +class Font; +class XMLNode; class DVIToSVGActions : public DVIActions, public SpecialActions { @@ -46,7 +46,7 @@ class DVIToSVGActions : public DVIActions, public SpecialActions DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg); ~DVIToSVGActions (); void reset (); - void setChar (double x, double y, unsigned c, bool vertical, const Font *f); + void setChar (double x, double y, unsigned c, bool vertical, const Font &f); void setRule (double x, double y, double height, double width); void setBgColor (const Color &color); void setColor (const Color &color) {_svg.setColor(color);} @@ -54,8 +54,8 @@ class DVIToSVGActions : public DVIActions, public SpecialActions const Matrix& getMatrix () const {return _svg.getMatrix();} void getPageTransform (Matrix &matrix) const {_dvireader->getPageTransformation(matrix);} Color getColor () const {return _svg.getColor();} - int getDVIStackDepth() const {return _dvireader->getStackDepth();} - unsigned getCurrentPageNumber() const {return _dvireader->getCurrentPageNumber();} + int getDVIStackDepth() const {return _dvireader->stackDepth();} + unsigned getCurrentPageNumber() const {return _dvireader->currentPageNumber();} void appendToPage (XMLNode *node) {_svg.appendToPage(node);} void appendToDefs (XMLNode *node) {_svg.appendToDefs(node);} void prependToPage (XMLNode *node) {_svg.prependToPage(node);} @@ -66,14 +66,13 @@ 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 beginPage (unsigned pageno, Int32 *c); + void beginPage (unsigned pageno, const std::vector<Int32> &c); void endPage (unsigned pageno); void progress (size_t current, size_t total, const char *id=0); void progress (const char *id); CharMap& getUsedChars () const {return _usedChars;} const FontSet& getUsedFonts () const {return _usedFonts;} void setDVIReader (BasicDVIReader &r) {_dvireader = &r;} - void setPageMatrix (const Matrix &tm); double getX() const {return _dvireader->getXPos();} double getY() const {return _dvireader->getYPos();} void setX (double x) {_dvireader->translateToX(x); _svg.setX(x);} @@ -94,7 +93,6 @@ class DVIToSVGActions : public DVIActions, public SpecialActions int _currentFontNum; mutable CharMap _usedChars; FontSet _usedFonts; - Matrix *_pageMatrix; // transformation of whole page Color _bgcolor; BoxMap *_boxes; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp index 1a878568cae..6bb48bb343f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp @@ -23,7 +23,7 @@ using namespace std; -#ifdef __WIN32__ +#ifdef _WIN32 #include <windows.h> #else #include <errno.h> @@ -32,7 +32,7 @@ using namespace std; Directory::Directory () { -#if __WIN32__ +#if _WIN32 handle = INVALID_HANDLE_VALUE; firstread = true; memset(&fileData, 0, sizeof(WIN32_FIND_DATA)); @@ -44,7 +44,7 @@ Directory::Directory () { Directory::Directory (string dirname) { -#if __WIN32__ +#if _WIN32 handle = INVALID_HANDLE_VALUE; firstread = true; memset(&fileData, 0, sizeof(WIN32_FIND_DATA)); @@ -63,7 +63,7 @@ Directory::~Directory () { bool Directory::open (string dname) { _dirname = dname; -#ifdef __WIN32__ +#ifdef _WIN32 firstread = true; if (dname[dname.length()-1] == '/' || dname[dname.length()-1] == '\\') dname = dname.substr(0, dname.length()-1); @@ -78,7 +78,7 @@ bool Directory::open (string dname) { void Directory::close () { -#ifdef __WIN32__ +#ifdef _WIN32 FindClose(handle); #else closedir(_dir); @@ -90,7 +90,7 @@ void Directory::close () { * @param[in] type type of entry to return (a: file or dir, f: file, d: dir) * @return name of entry */ const char* Directory::read (EntryType type) { -#ifdef __WIN32__ +#ifdef _WIN32 if (handle == INVALID_HANDLE_VALUE) return 0; while (firstread || FindNextFile(handle, &fileData)) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h index 8e317eb5240..0356e4951b4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h @@ -22,7 +22,7 @@ #define DVISVGM_DIRECTORY_H #include <string> -#ifdef __WIN32__ +#ifdef _WIN32 #include <windows.h> #else #include <dirent.h> @@ -43,7 +43,7 @@ class Directory private: std::string _dirname; -#ifdef __WIN32__ +#ifdef _WIN32 bool firstread; HANDLE handle; WIN32_FIND_DATA fileData; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp index 60027d05c28..34efddfac4e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp @@ -24,6 +24,7 @@ #include "DvisvgmSpecialHandler.h" #include "InputBuffer.h" #include "InputReader.h" +#include "Length.h" #include "SpecialActions.h" #include "XMLNode.h" #include "XMLString.h" @@ -37,7 +38,7 @@ DvisvgmSpecialHandler::DvisvgmSpecialHandler () } -void DvisvgmSpecialHandler::preprocess (const char*, istream &is, SpecialActions*) { +void DvisvgmSpecialHandler::preprocess (const char*, istream &is, SpecialActions&) { struct Command { const char *name; void (DvisvgmSpecialHandler::*handler)(InputReader&); @@ -114,13 +115,10 @@ void DvisvgmSpecialHandler::preprocessRawPut (InputReader &ir) { * @param[in] prefix special prefix read by the SpecialManager * @param[in] is the special statement is read from this stream * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ -bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { - if (!actions) - return true; - +bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { struct Command { const char *name; - void (DvisvgmSpecialHandler::*handler)(InputReader&, SpecialActions*); + void (DvisvgmSpecialHandler::*handler)(InputReader&, SpecialActions&); } commands[] = { {"raw", &DvisvgmSpecialHandler::processRaw}, {"rawdef", &DvisvgmSpecialHandler::processRawDef}, @@ -146,15 +144,15 @@ bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialAct /** Replaces constants of the form {?name} by their corresponding value. * @param[in,out] str text to expand * @param[in] actions interfcae to the world outside the special handler */ -static void expand_constants (string &str, SpecialActions *actions) { +static void expand_constants (string &str, SpecialActions &actions) { struct Constant { const char *name; string val; } constants[] = { - {"x", XMLString(actions->getX())}, - {"y", XMLString(actions->getY())}, - {"color", actions->getColor().svgColorString()}, + {"x", XMLString(actions.getX())}, + {"y", XMLString(actions.getY())}, + {"color", actions.getColor().svgColorString()}, {"nl", "\n"}, {0, ""} }; @@ -168,7 +166,7 @@ static void expand_constants (string &str, SpecialActions *actions) { while (endpos < str.length() && isalnum(str[endpos])) ++endpos; if (str[endpos] == '}') { - BoundingBox &box=actions->bbox(str.substr(pos+7, endpos-pos-7)); + BoundingBox &box=actions.bbox(str.substr(pos+7, endpos-pos-7)); str.replace(pos, endpos-pos+1, box.toSVGViewBox()); } else @@ -186,40 +184,40 @@ static void expand_constants (string &str, SpecialActions *actions) { } -void DvisvgmSpecialHandler::processRaw (InputReader &ir, SpecialActions *actions) { +void DvisvgmSpecialHandler::processRaw (InputReader &ir, SpecialActions &actions) { if (_nestingLevel == 0) { string str = ir.getLine(); if (!str.empty()) { expand_constants(str, actions); - actions->appendToPage(new XMLTextNode(str)); + actions.appendToPage(new XMLTextNode(str)); } } } -void DvisvgmSpecialHandler::processRawDef (InputReader &ir, SpecialActions *actions) { +void DvisvgmSpecialHandler::processRawDef (InputReader &ir, SpecialActions &actions) { if (_nestingLevel == 0) { string str = ir.getLine(); if (!str.empty()) { expand_constants(str, actions); - actions->appendToDefs(new XMLTextNode(str)); + actions.appendToDefs(new XMLTextNode(str)); } } } -void DvisvgmSpecialHandler::processRawSet (InputReader&, SpecialActions*) { +void DvisvgmSpecialHandler::processRawSet (InputReader&, SpecialActions&) { _nestingLevel++; } -void DvisvgmSpecialHandler::processEndRawSet (InputReader&, SpecialActions*) { +void DvisvgmSpecialHandler::processEndRawSet (InputReader&, SpecialActions&) { if (_nestingLevel > 0) _nestingLevel--; } -void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions *actions) { +void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &actions) { if (_nestingLevel > 0) return; string id = ir.getString(); @@ -234,9 +232,9 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions *acti if ((type == 'P' || type == 'D') && !def.empty()) { expand_constants(def, actions); if (type == 'P') - actions->appendToPage(new XMLTextNode(def)); + actions.appendToPage(new XMLTextNode(def)); else { // type == 'D' - actions->appendToDefs(new XMLTextNode(def)); + actions.appendToDefs(new XMLTextNode(def)); type = 'L'; // locked } } @@ -250,11 +248,11 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions *acti * @param[in] h height of the rectangle in PS point units * @param[in] d depth of the rectangle in PS point units * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ -static void update_bbox (double w, double h, double d, SpecialActions *actions) { - double x = actions->getX(); - double y = actions->getY(); - actions->embed(BoundingBox(x, y, x+w, y-h)); - actions->embed(BoundingBox(x, y, x+w, y+d)); +static void update_bbox (double w, double h, double d, SpecialActions &actions) { + double x = actions.getX(); + double y = actions.getY(); + actions.embed(BoundingBox(x, y, x+w, y-h)); + actions.embed(BoundingBox(x, y, x+w, y+d)); } @@ -263,8 +261,7 @@ static void update_bbox (double w, double h, double d, SpecialActions *actions) * variant 2: dvisvgm:bbox a[bs] <x1> <y1> <x2> <y2> * variant 3: dvisvgm:bbox f[ix] <x1> <y1> <x2> <y2> * variant 4: dvisvgm:bbox n[ew] <name> */ -void DvisvgmSpecialHandler::processBBox (InputReader &ir, SpecialActions *actions) { - const double pt2bp = 72/72.27; +void DvisvgmSpecialHandler::processBBox (InputReader &ir, SpecialActions &actions) { ir.skipSpace(); int c = ir.peek(); if (isalpha(c)) { @@ -277,18 +274,18 @@ void DvisvgmSpecialHandler::processBBox (InputReader &ir, SpecialActions *action name += char(ir.get()); ir.skipSpace(); if (!name.empty() && ir.eof()) - actions->bbox(name, true); // create new user box + actions.bbox(name, true); // create new user box } else if (c == 'a' || c == 'f') { double p[4]; for (int i=0; i < 4; i++) - p[i] = ir.getDouble()*pt2bp; + p[i] = ir.getDouble()*Length::pt2bp; BoundingBox b(p[0], p[1], p[2], p[3]); if (c == 'a') - actions->embed(b); + actions.embed(b); else { - actions->bbox() = b; - actions->bbox().lock(); + actions.bbox() = b; + actions.bbox().lock(); } } } @@ -296,31 +293,28 @@ void DvisvgmSpecialHandler::processBBox (InputReader &ir, SpecialActions *action c = 'r'; // no mode specifier => relative box parameters if (c == 'r') { - double w = ir.getDouble()*pt2bp; - double h = ir.getDouble()*pt2bp; - double d = ir.getDouble()*pt2bp; + double w = ir.getDouble()*Length::pt2bp; + double h = ir.getDouble()*Length::pt2bp; + double d = ir.getDouble()*Length::pt2bp; update_bbox(w, h, d, actions); } } -void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions *actions) { - if (actions) { - const double pt2bp = 72/72.27; - double w = ir.getDouble()*pt2bp; - double h = ir.getDouble()*pt2bp; - string f = ir.getString(); - update_bbox(w, h, 0, actions); - XMLElementNode *img = new XMLElementNode("image"); - img->addAttribute("x", actions->getX()); - img->addAttribute("y", actions->getY()); - img->addAttribute("width", w); - img->addAttribute("height", h); - img->addAttribute("xlink:href", f); - if (!actions->getMatrix().isIdentity()) - img->addAttribute("transform", actions->getMatrix().getSVG()); - actions->appendToPage(img); - } +void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions &actions) { + double w = ir.getDouble()*Length::pt2bp; + double h = ir.getDouble()*Length::pt2bp; + string f = ir.getString(); + update_bbox(w, h, 0, actions); + XMLElementNode *img = new XMLElementNode("image"); + img->addAttribute("x", actions.getX()); + img->addAttribute("y", actions.getY()); + img->addAttribute("width", w); + img->addAttribute("height", h); + img->addAttribute("xlink:href", f); + if (!actions.getMatrix().isIdentity()) + img->addAttribute("transform", actions.getMatrix().getSVG()); + actions.appendToPage(img); } @@ -336,7 +330,7 @@ void DvisvgmSpecialHandler::dviPreprocessingFinished () { } -void DvisvgmSpecialHandler::dviEndPage (unsigned) { +void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions&) { for (MacroMap::iterator map_it=_macros.begin(); map_it != _macros.end(); ++map_it) { StringVector &vec = map_it->second; for (StringVector::iterator str_it=vec.begin(); str_it != vec.end(); ++str_it) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h index 3eadf703ba8..d02f6057eb7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h @@ -27,7 +27,7 @@ #include "SpecialHandler.h" class InputReader; -struct SpecialActions; +class SpecialActions; class DvisvgmSpecialHandler : public SpecialHandler, public DVIPreprocessingListener, public DVIEndPageListener { @@ -39,8 +39,8 @@ class DvisvgmSpecialHandler : public SpecialHandler, public DVIPreprocessingList const char* name () const {return "dvisvgm";} const char* info () const {return "special set for embedding raw SVG snippets";} const char** prefixes () const; - void preprocess (const char *prefix, std::istream &is, SpecialActions *actions); - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + void preprocess (const char *prefix, std::istream &is, SpecialActions &actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); protected: void preprocessRaw (InputReader &ir); @@ -48,15 +48,15 @@ class DvisvgmSpecialHandler : public SpecialHandler, public DVIPreprocessingList void preprocessRawSet (InputReader &ir); void preprocessEndRawSet (InputReader &ir); void preprocessRawPut (InputReader &ir); - void processRaw (InputReader &ir, SpecialActions *actions); - void processRawDef (InputReader &ir, SpecialActions *actions); - void processRawSet (InputReader &ir, SpecialActions *actions); - void processEndRawSet (InputReader &ir, SpecialActions *actions); - void processRawPut (InputReader &ir, SpecialActions *actions); - void processBBox (InputReader &ir, SpecialActions *actions); - void processImg (InputReader &ir, SpecialActions *actions); + void processRaw (InputReader &ir, SpecialActions &actions); + void processRawDef (InputReader &ir, SpecialActions &actions); + void processRawSet (InputReader &ir, SpecialActions &actions); + void processEndRawSet (InputReader &ir, SpecialActions &actions); + void processRawPut (InputReader &ir, SpecialActions &actions); + void processBBox (InputReader &ir, SpecialActions &actions); + void processImg (InputReader &ir, SpecialActions &actions); void dviPreprocessingFinished (); - void dviEndPage (unsigned pageno); + void dviEndPage (unsigned pageno, SpecialActions &actions); private: MacroMap _macros; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp index 05392bb6473..0fb638b6667 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp @@ -58,7 +58,7 @@ void EPSToSVG::convert () { "ury=" << bbox.maxY(); try { PsSpecialHandler pshandler; - pshandler.process("psfile=", ss, this); + pshandler.process("psfile=", ss, *this); } catch (...) { progress(0); // remove progress message @@ -76,7 +76,7 @@ void EPSToSVG::convert () { " x " << XMLString(bbox.height()*bp2pt) << "pt" " (" << XMLString(bbox.width()*bp2mm) << "mm" " x " << XMLString(bbox.height()*bp2mm) << "mm)\n"; - Message::mstream(false, Message::MC_PAGE_WRITTEN) << "graphic written to " << (svgfname.empty() ? "<stdout>" : svgfname) << '\n'; + Message::mstream(false, Message::MC_PAGE_WRITTEN) << "output written to " << (svgfname.empty() ? "<stdout>" : svgfname) << '\n'; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp index 81b291a7993..bdd4b12670a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp @@ -23,6 +23,7 @@ #include "EmSpecialHandler.h" #include "InputBuffer.h" #include "InputReader.h" +#include "Length.h" #include "SpecialActions.h" #include "XMLNode.h" #include "XMLString.h" @@ -30,7 +31,7 @@ using namespace std; -EmSpecialHandler::EmSpecialHandler () : _linewidth(0.4*72/72.27), _actions(0) { +EmSpecialHandler::EmSpecialHandler () : _linewidth(0.4*72/72.27) { } @@ -40,24 +41,31 @@ EmSpecialHandler::EmSpecialHandler () : _linewidth(0.4*72/72.27), _actions(0) { * a horizontal, vertical or orthogonal cut of a line end. Depending on c and the * line's slope a cut vector v can be computed that, relatively to endpoint p, denotes * the 2 vertices of that line end: v1=p+v and v2=p-v. - * @param[in] c cut direction ('h', 'v' or 'p') - * @param[in] v direction vector of line to be drawn + * @param[in] cuttype character identifying the cut direction ('h', 'v' or 'p') + * @param[in] linedir direction vector of line to be drawn * @param[in] lw width of line to be drawn * @return the "cut vector" */ -static DPair cut_vector (char c, const DPair &v, double lw) { - if (c == 'p') - return v.ortho()/v.length() * (lw/2); +static DPair cut_vector (char cuttype, const DPair &linedir, double linewidth) { DPair cut; - if (c == 'v' && v.x() != 0) { - double slope = v.y()/v.x(); - double h = sqrt(lw*lw*(1+slope*slope)); - cut.y(0.5*h); - } - else if (v.y() != 0) { // c == 'h' - double slope = v.x()/v.y(); - double h = sqrt(lw*lw*(1+slope*slope)); - double sgn = slope < 0 ? 1.0 : -1.0; - cut.x(0.5*h*sgn); + switch (cuttype) { + case 'v': // vertical + if (linedir.x() != 0) { + double slope = linedir.y()/linedir.x(); + double h = sqrt(linewidth*linewidth*(1+slope*slope)); + cut.y(h/2); + } + break; + case 'h': // horizontal + if (linedir.y() != 0) { + double slope = linedir.x()/linedir.y(); + double h = sqrt(linewidth*linewidth*(1+slope*slope)); + double sgn = slope < 0 ? 1.0 : -1.0; + cut.x(h*sgn/2); + } + break; + default: // c == 'p': perpendicular to the line vector + if (linedir.x() != 0 && linedir.y() != 0) + return linedir.ortho()/linedir.length() * (linewidth/2); } return cut; } @@ -70,7 +78,7 @@ static DPair cut_vector (char c, const DPair &v, double lw) { * @param[in] c2 cut method of second endpoint ('h', 'v' or 'p') * @param[in] lw line width in PS point units * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ -static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, double lw, SpecialActions *actions) { +static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, double lw, SpecialActions &actions) { XMLElementNode *node=0; DPair dir = p2-p1; if (dir.x() == 0 || dir.y() == 0 || (c1 == 'p' && c2 == 'p')) { @@ -81,10 +89,13 @@ static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, dou node->addAttribute("x2", p2.x()); node->addAttribute("y2", p2.y()); node->addAttribute("stroke-width", lw); - node->addAttribute("stroke", actions->getColor().svgColorString()); + node->addAttribute("stroke", actions.getColor().svgColorString()); // update bounding box - actions->embed(p1); - actions->embed(p2); + DPair cv = cut_vector('p', dir, lw); + actions.embed(p1+cv); + actions.embed(p1-cv); + actions.embed(p2+cv); + actions.embed(p2-cv); } else { // draw polygon @@ -92,56 +103,45 @@ static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, dou DPair cv2 = cut_vector(c2, dir, lw); DPair q11 = p1+cv1, q12 = p1-cv1; DPair q21 = p2+cv2, q22 = p2-cv2; - node = new XMLElementNode("polygon"); ostringstream oss; oss << XMLString(q11.x()) << ',' << XMLString(q11.y()) << ' ' << XMLString(q12.x()) << ',' << XMLString(q12.y()) << ' ' << XMLString(q22.x()) << ',' << XMLString(q22.y()) << ' ' << XMLString(q21.x()) << ',' << XMLString(q21.y()); + node = new XMLElementNode("polygon"); node->addAttribute("points", oss.str()); - if (actions->getColor() != Color::BLACK) - node->addAttribute("fill", actions->getColor().svgColorString()); + if (actions.getColor() != Color::BLACK) + node->addAttribute("fill", actions.getColor().svgColorString()); // update bounding box - actions->embed(q11); - actions->embed(q12); - actions->embed(q21); - actions->embed(q22); + actions.embed(q11); + actions.embed(q12); + actions.embed(q21); + actions.embed(q22); } - actions->appendToPage(node); + actions.appendToPage(node); } +/** Reads a length (value + unit) and returns its value in PS points (bp). + * If no unit is specified, TeX points are assumed. */ static double read_length (InputReader &in) { - struct Unit { - const char *name; - double factor; + double val = in.getDouble(); + string unitstr; + if (isalpha(in.peek())) unitstr += in.get(); + if (isalpha(in.peek())) unitstr += in.get(); + Length::Unit unit = Length::PT; + try { + unit = Length::stringToUnit(unitstr); } - units[] = { - {"pt", 1.0}, - {"pc", 12.0}, - {"in", 72.27}, - {"bp", 72.27/72}, - {"cm", 72.27/2.54}, - {"mm", 72.27/25.4}, - {"dd", 1238.0/1157}, - {"cc", 1238.0/1157*12}, - {"sp", 1.0/65536}, - {0, 0} - }; - double len = in.getDouble(); - in.skipSpace(); - for (Unit *p=units; p->name; p++) - if (in.check(p->name)) { - len *= p->factor; - break; - } - return len*72/72.27; + catch (UnitException &e) { + } + return Length(val, unit).bp(); } -bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { - // em:moveto => move graphic cursor to dvi cursor - // em:lineto => draw line from graphic cursor to dvi cursor, move graphic cursor to dvi cursor +bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { + // em:moveto => move graphic cursor to dvi position + // em:lineto => draw line from graphic cursor to dvi cursor, then move graphic cursor to dvi position // em:linewidth <w> => set line width to <w> // em:point <n>[,<x>[,<y>]] => defines point <n> as (<x>,<y>); if <x> and/or <y> is missing, // the corresponding dvi cursor coordinate is inserted @@ -155,71 +155,103 @@ bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions // // supported length units: pt, pc, in, bp, cm, mm, dd, cc, sp // default line width: 0.4pt + struct Command { + const char *name; + void (EmSpecialHandler::*handler)(InputReader&, SpecialActions&); + } commands[] = { + {"point", &EmSpecialHandler::point}, + {"line", &EmSpecialHandler::line}, + {"moveto", &EmSpecialHandler::moveto}, + {"lineto", &EmSpecialHandler::lineto}, + {"linewidth", &EmSpecialHandler::linewidth}, + {0, 0} + }; - if (actions) { - _actions = actions; // save pointer to SpecialActions for later use in endPage - StreamInputBuffer ib(is, 128); - BufferInputReader in(ib); - string cmd = in.getWord(); - if (cmd == "moveto") - _pos = DPair(actions->getX(), actions->getY()); - else if (cmd == "lineto") { - DPair p(actions->getX(), actions->getY()); - create_line(_pos, p, 'p', 'p', _linewidth, actions); - _pos = p; - } - else if (cmd == "linewidth") - _linewidth = read_length(in); - else if (cmd == "point") { - DPair p(actions->getX(), actions->getY()); - int n = in.getInt(); - if (in.getPunct() == ',') { - p.x(in.getDouble()); - if (in.getPunct() == ',') - p.y(in.getDouble()); - } - _points[n] = p; - } - else if (cmd == "line") { - int n1 = in.getInt(); - int c1 = 'p'; - if (isalpha(in.peek())) - c1 = in.get(); - in.getPunct(); - int n2 = in.getInt(); - int c2 = 'p'; - if (isalpha(in.peek())) - c2 = in.get(); - double lw = _linewidth; - if (in.getPunct() == ',') - lw = read_length(in); - map<int,DPair>::iterator it1=_points.find(n1); - map<int,DPair>::iterator it2=_points.find(n2); - if (it1 != _points.end() && it2 != _points.end()) - create_line(it1->second, it2->second, char(c1), char(c2), lw, actions); - else { - // Line endpoints havn't necessarily to be defined before - // a line definition. If a point wasn't defined yet we push the line - // in a wait list and process the lines at the end of the page. - _lines.push_back(Line(n1, n2, char(c1), char(c2), lw)); - } + StreamInputReader ir(is); + string cmdstr = ir.getWord(); + for (Command *cmd=commands; cmd->name; cmd++) { + if (cmdstr == cmd->name) { + (this->*cmd->handler)(ir, actions); + break; } } return true; } +/** Handles the "moveto" command that sets the drawing position to the current DVI position. */ +void EmSpecialHandler::moveto (InputReader&, SpecialActions &actions) { + _pos.x(actions.getX()); + _pos.y(actions.getY()); +} + + +/** Handles the "lineto" command that sraws a straight line from the current drawing position + * to the current DVI position, and sets the drawing position to the DVI position afterwards. */ +void EmSpecialHandler::lineto (InputReader&, SpecialActions &actions) { + DPair currpos(actions.getX(), actions.getY()); + create_line(_pos, currpos, 'p', 'p', _linewidth, actions); + _pos = currpos; +} + + +/** Handles the "linewidth" command that changes the line width which affects all following + * drawing commands. */ +void EmSpecialHandler::linewidth (InputReader &ir, SpecialActions&) { + _linewidth = read_length(ir); +} + + +/** Handles the "point" command that adds a point to the point list. */ +void EmSpecialHandler::point (InputReader &ir, SpecialActions &actions) { + DPair pos(actions.getX(), actions.getY()); + int n = ir.getInt(); + if (ir.getPunct() == ',') { + pos.x(ir.getDouble()); + if (ir.getPunct() == ',') + pos.y(ir.getDouble()); + } + _points[n] = pos; +} + + +/** Handles the "line" command that draws a straight line between two points + * from the point list. */ +void EmSpecialHandler::line (InputReader &ir, SpecialActions& actions) { + int pointnum1 = ir.getInt(); + int cut1 = 'p'; + if (isalpha(ir.peek())) + cut1 = ir.get(); + ir.getPunct(); + int pointnum2 = ir.getInt(); + int cut2 = 'p'; + if (isalpha(ir.peek())) + cut2 = ir.get(); + double linewidth = _linewidth; + if (ir.getPunct() == ',') + linewidth = read_length(ir); + map<int,DPair>::iterator it1=_points.find(pointnum1); + map<int,DPair>::iterator it2=_points.find(pointnum2); + if (it1 != _points.end() && it2 != _points.end()) + create_line(it1->second, it2->second, char(cut1), char(cut2), linewidth, actions); + else { + // Line endpoints don't necessarily have to be defined before + // a line definition. If a point isn't defined yet, we put the line + // in a wait list and process the lines at the end of the page. + _lines.push_back(Line(pointnum1, pointnum2, char(cut1), char(cut2), linewidth)); + } +} + + /** This method is called at the end of a DVI page. Here we have to draw all pending * lines that are still in the line list. All line endpoints must be defined until here. */ -void EmSpecialHandler::dviEndPage (unsigned pageno) { - if (_actions) { - FORALL(_lines, list<Line>::iterator, it) { - map<int,DPair>::iterator pit1=_points.find(it->p1); - map<int,DPair>::iterator pit2=_points.find(it->p2); - if (pit1 != _points.end() && pit2 != _points.end()) - create_line(pit1->second, pit2->second, it->c1, it->c2, it->width, _actions); - // all lines with still undefined points are ignored - } +void EmSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { + FORALL(_lines, list<Line>::iterator, it) { + map<int,DPair>::iterator pit1=_points.find(it->p1); + map<int,DPair>::iterator pit2=_points.find(it->p2); + if (pit1 != _points.end() && pit2 != _points.end()) + create_line(pit1->second, pit2->second, it->c1, it->c2, it->width, actions); + // all lines with still undefined points are ignored } // line and point definitions are local to a page _lines.clear(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h index 0d55e243f49..689ea5a39b8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h @@ -26,6 +26,8 @@ #include "Pair.h" #include "SpecialHandler.h" +class InputReader; +class SpecialActions; class EmSpecialHandler : public SpecialHandler, public DVIEndPageListener { @@ -41,17 +43,21 @@ class EmSpecialHandler : public SpecialHandler, public DVIEndPageListener const char* name () const {return "em";} const char* info () const {return "line drawing statements of the emTeX special set";} const char** prefixes () const; - bool process (const char *prefix, std::istream &in, SpecialActions *actions); + bool process (const char *prefix, std::istream &in, SpecialActions &actions); protected: - void dviEndPage (unsigned pageno); + void dviEndPage (unsigned pageno, SpecialActions &actions); + void linewidth (InputReader &ir, SpecialActions &actions); + void moveto (InputReader &ir, SpecialActions &actions); + void lineto (InputReader &ir, SpecialActions &actions); + void line (InputReader &ir, SpecialActions &actions); + void point (InputReader &ir, SpecialActions &actions); private: std::map<int, DPair> _points; ///< points defined by special em:point std::list<Line> _lines; ///< list of lines with undefined end points double _linewidth; ///< global line width DPair _pos; ///< current position of "graphic cursor" - SpecialActions *_actions; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp index a01cf28bb64..30b32f81d1f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp @@ -37,7 +37,7 @@ static string& single_slashes (string &str) { } -#ifdef __WIN32__ +#ifdef _WIN32 static char strip_drive_letter (string &path) { char letter = 0; if (path.length() >= 2 && path[1] == ':' && isalpha(path[0])) { @@ -98,7 +98,7 @@ FilePath::FilePath (const string &path, bool isfile, string current_dir) { void FilePath::init (string path, bool isfile, string current_dir) { single_slashes(path); single_slashes(current_dir); -#ifdef __WIN32__ +#ifdef _WIN32 tolower(path); path = FileSystem::adaptPathSeperators(path); _drive = strip_drive_letter(path); @@ -113,7 +113,7 @@ void FilePath::init (string path, bool isfile, string current_dir) { } if (current_dir.empty()) current_dir = FileSystem::getcwd(); -#ifdef __WIN32__ +#ifdef _WIN32 tolower(current_dir); _drive = adapt_current_path(current_dir, _drive); #endif @@ -125,7 +125,7 @@ void FilePath::init (string path, bool isfile, string current_dir) { else { FilePath curr(current_dir, false, "/"); current_dir = curr.absolute(); -#ifdef __WIN32__ +#ifdef _WIN32 adapt_current_path(current_dir, _drive); #endif } @@ -207,7 +207,7 @@ string FilePath::absolute (bool with_filename) const { path = "/"; if (with_filename && !_fname.empty()) path += "/"+_fname; -#ifdef __WIN32__ +#ifdef _WIN32 if (_drive) path.insert(0, string(1, _drive) + ":"); #endif @@ -225,14 +225,14 @@ string FilePath::absolute (bool with_filename) const { string FilePath::relative (string reldir, bool with_filename) const { if (reldir.empty()) reldir = FileSystem::getcwd(); -#ifdef __WIN32__ +#ifdef _WIN32 adapt_current_path(reldir, _drive); #endif if (reldir[0] != '/') return absolute(); FilePath rel(reldir, false); string path; -#ifdef __WIN32__ +#ifdef _WIN32 if (rel._drive && _drive && rel._drive != _drive) path += string(1, _drive) + ":"; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h index e411d685326..368c92585fa 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h @@ -50,7 +50,7 @@ class FilePath private: Directories _dirs; std::string _fname; -#ifdef __WIN32__ +#ifdef _WIN32 char _drive; #endif }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp index 0d3f04277bd..a78eeaa0776 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp @@ -32,7 +32,7 @@ using namespace std; -#ifdef __WIN32__ +#ifdef _WIN32 #include <direct.h> #include <windows.h> const char *FileSystem::DEVNULL = "nul"; @@ -81,7 +81,7 @@ bool FileSystem::rename (const string &oldname, const string &newname) { UInt64 FileSystem::filesize (const string &fname) { -#ifdef __WIN32__ +#ifdef _WIN32 // unfortunately, stat doesn't work properly under Windows // so we have to use this freaky code WIN32_FILE_ATTRIBUTE_DATA attr; @@ -104,7 +104,7 @@ string FileSystem::adaptPathSeperators (string path) { string FileSystem::getcwd () { char buf[1024]; -#ifdef __WIN32__ +#ifdef _WIN32 return adaptPathSeperators(_getcwd(buf, 1024)); #else return ::getcwd(buf, 1024); @@ -118,7 +118,7 @@ string FileSystem::getcwd () { bool FileSystem::chdir (const std::string &dirname) { bool success = false; if (const char *cdirname = dirname.c_str()) { -#ifdef __WIN32__ +#ifdef _WIN32 success = (_chdir(cdirname) == 0); #else success = (chdir(cdirname) == 0); @@ -130,7 +130,7 @@ bool FileSystem::chdir (const std::string &dirname) { /** Returns the user's home directory. */ const char* FileSystem::userdir () { -#ifdef __WIN32__ +#ifdef _WIN32 const char *drive=getenv("HOMEDRIVE"); const char *path=getenv("HOMEPATH"); if (drive && path) { @@ -158,7 +158,7 @@ const char* FileSystem::userdir () { static bool s_mkdir (const string &dirname) { bool success = true; if (!FileSystem::exists(dirname)) { -#ifdef __WIN32__ +#ifdef _WIN32 success = (_mkdir(dirname.c_str()) == 0); #else success = (mkdir(dirname.c_str(), 0775) == 0); @@ -169,7 +169,7 @@ static bool s_mkdir (const string &dirname) { static bool inline s_rmdir (const string &dirname) { -#ifdef __WIN32__ +#ifdef _WIN32 return (_rmdir(dirname.c_str()) == 0); #else return (rmdir(dirname.c_str()) == 0); @@ -212,7 +212,7 @@ bool FileSystem::rmdir (const string &dirname) { bool ok = false; if (isDirectory(dirname)) { ok = true; -#ifdef __WIN32__ +#ifdef _WIN32 string pattern = dirname + "/*"; WIN32_FIND_DATA data; HANDLE h = FindFirstFile(pattern.c_str(), &data); @@ -259,7 +259,7 @@ bool FileSystem::rmdir (const string &dirname) { bool FileSystem::exists (const string &fname) { if (const char *cfname = fname.c_str()) { -#ifdef __WIN32__ +#ifdef _WIN32 return GetFileAttributes(cfname) != INVALID_FILE_ATTRIBUTES; #else struct stat attr; @@ -273,7 +273,7 @@ bool FileSystem::exists (const string &fname) { /** Returns true if 'fname' references a directory. */ bool FileSystem::isDirectory (const string &fname) { if (const char *cfname = fname.c_str()) { -#ifdef __WIN32__ +#ifdef _WIN32 return GetFileAttributes(cfname) & FILE_ATTRIBUTE_DIRECTORY; #else struct stat attr; @@ -287,7 +287,7 @@ bool FileSystem::isDirectory (const string &fname) { /** Returns true if 'fname' references a file. */ bool FileSystem::isFile (const string &fname) { if (const char *cfname = fname.c_str()) { -#ifdef __WIN32__ +#ifdef _WIN32 ifstream ifs(cfname); return (bool)ifs; #else @@ -301,7 +301,7 @@ bool FileSystem::isFile (const string &fname) { int FileSystem::collect (const char *dirname, vector<string> &entries) { entries.clear(); -#ifdef __WIN32__ +#ifdef _WIN32 string pattern = string(dirname) + "/*"; WIN32_FIND_DATA data; HANDLE h = FindFirstFile(pattern.c_str(), &data); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp index af1c8d4c9b1..062f1a640bb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp @@ -31,7 +31,6 @@ #include "MetafontWrapper.h" #include "SignalHandler.h" #include "Subfont.h" -#include "SVGTree.h" #include "Unicode.h" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h index f4d828eb977..0a1c707cda6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h @@ -54,41 +54,41 @@ struct GlyphMetrics /** Abstract base for all font classes. */ -struct Font { - virtual ~Font () {} - virtual Font* clone (double ds, double sc) const =0; - virtual const Font* uniqueFont () const =0; - virtual std::string name () const =0; - virtual double designSize () const =0; - virtual double scaledSize () const =0; - virtual double scaleFactor () const {return scaledSize()/designSize();} - virtual double charWidth (int c) const =0; - virtual double charDepth (int c) const =0; - virtual double charHeight (int c) const =0; - virtual double italicCorr (int c) const =0; - virtual const FontMetrics* getMetrics () const =0; - virtual const char* path () const =0; - virtual const char* filename () const; - virtual const FontEncoding* encoding () const; - virtual bool getGlyph (int c, Glyph &glyph, GFGlyphTracer::Callback *cb=0) const =0; - virtual void getGlyphMetrics (int c, bool vertical, GlyphMetrics &metrics) const; - virtual UInt32 unicode (UInt32 c) const; - virtual void tidy () const {} - virtual bool findAndAssignBaseFontMap () {return true;} - virtual bool verticalLayout () const {return getMetrics() ? getMetrics()->verticalLayout() : false;} - virtual bool verifyChecksums () const {return true;} - virtual int fontIndex () const {return 0;} - virtual const FontStyle* style () const {return 0;} - virtual Color color () const {return Color::BLACK;} - virtual const FontMap::Entry* fontMapEntry () const; +class Font { + public: + virtual ~Font () {} + virtual Font* clone (double ds, double sc) const =0; + virtual const Font* uniqueFont () const =0; + virtual std::string name () const =0; + virtual double designSize () const =0; + virtual double scaledSize () const =0; + virtual double scaleFactor () const {return scaledSize()/designSize();} + virtual double charWidth (int c) const =0; + virtual double charDepth (int c) const =0; + virtual double charHeight (int c) const =0; + virtual double italicCorr (int c) const =0; + virtual const FontMetrics* getMetrics () const =0; + virtual const char* path () const =0; + virtual const char* filename () const; + virtual const FontEncoding* encoding () const; + virtual bool getGlyph (int c, Glyph &glyph, GFGlyphTracer::Callback *cb=0) const =0; + virtual void getGlyphMetrics (int c, bool vertical, GlyphMetrics &metrics) const; + virtual UInt32 unicode (UInt32 c) const; + virtual void tidy () const {} + virtual bool findAndAssignBaseFontMap () {return true;} + virtual bool verticalLayout () const {return getMetrics() ? getMetrics()->verticalLayout() : false;} + virtual bool verifyChecksums () const {return true;} + virtual int fontIndex () const {return 0;} + virtual const FontStyle* style () const {return 0;} + virtual Color color () const {return Color::BLACK;} + virtual const FontMap::Entry* fontMapEntry () const; }; /** Empty font without any glyphs. Instances of this class are used * if no physical or virtual font file can be found. * The metric values returned by the member functions are based on cmr10. */ -struct EmptyFont : public Font -{ +class EmptyFont : public Font { public: EmptyFont (std::string name) : _fontname(name) {} Font* clone (double ds, double sc) const {return new EmptyFont(*this);} @@ -110,8 +110,7 @@ struct EmptyFont : public Font /** Interface for all physical fonts. */ -class PhysicalFont : public virtual Font -{ +class PhysicalFont : public virtual Font { public: enum Type {MF, OTF, PFB, TTC, TTF, UNKNOWN}; @@ -154,8 +153,7 @@ class PhysicalFont : public virtual Font /** Interface for all virtual fonts. */ -class VirtualFont : public virtual Font -{ +class VirtualFont : public virtual Font { friend class FontManager; public: typedef std::vector<UInt8> DVIVector; @@ -170,8 +168,7 @@ class VirtualFont : public virtual Font }; -class TFMFont : public virtual Font -{ +class TFMFont : public virtual Font { public: TFMFont (std::string name, UInt32 checksum, double dsize, double ssize); ~TFMFont (); @@ -194,8 +191,7 @@ class TFMFont : public virtual Font }; -class PhysicalFontProxy : public PhysicalFont -{ +class PhysicalFontProxy : public PhysicalFont { friend class PhysicalFontImpl; public: Font* clone (double ds, double sc) const {return new PhysicalFontProxy(*this, ds, sc);} @@ -228,8 +224,7 @@ class PhysicalFontProxy : public PhysicalFont }; -class PhysicalFontImpl : public PhysicalFont, public TFMFont -{ +class PhysicalFontImpl : public PhysicalFont, public TFMFont { friend class PhysicalFont; public: ~PhysicalFontImpl(); @@ -258,8 +253,7 @@ class PhysicalFontImpl : public PhysicalFont, public TFMFont }; -class NativeFont : public PhysicalFont -{ +class NativeFont : public PhysicalFont { public: virtual NativeFont* clone (double ptsize, const FontStyle &style, Color color) const =0; virtual Font* clone (double ds, double sc) const =0; @@ -287,8 +281,7 @@ class NativeFont : public PhysicalFont }; -class NativeFontProxy : public NativeFont -{ +class NativeFontProxy : public NativeFont { friend class NativeFontImpl; public: NativeFont* clone (double ptsize, const FontStyle &style, Color color) const { @@ -312,8 +305,7 @@ class NativeFontProxy : public NativeFont }; -class NativeFontImpl : public NativeFont -{ +class NativeFontImpl : public NativeFont { public: NativeFontImpl (const std::string &fname, int fontIndex, double ptsize, const FontStyle &style, Color color) : NativeFont(ptsize, style, color), _path(fname), _fontIndex(fontIndex) {} @@ -339,8 +331,7 @@ class NativeFontImpl : public NativeFont }; -class VirtualFontProxy : public VirtualFont -{ +class VirtualFontProxy : public VirtualFont { friend class VirtualFontImpl; public: Font* clone (double ds, double ss) const {return new VirtualFontProxy(*this, ds, ss);} @@ -368,8 +359,7 @@ class VirtualFontProxy : public VirtualFont }; -class VirtualFontImpl : public VirtualFont, public TFMFont -{ +class VirtualFontImpl : public VirtualFont, public TFMFont { friend class VirtualFont; public: ~VirtualFontImpl (); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h index a5edea81879..499c0c7450a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h @@ -29,11 +29,11 @@ #include <vector> #include "Character.h" #include "CharMapID.h" -#include "Font.h" #include "Glyph.h" #include "RangeMap.h" #include "types.h" +class Font; /** This class provides methods to handle font files and font data. * It's a wrapper for the Freetype font library. */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp index 91e61fba3b8..546d5ca646d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp @@ -108,7 +108,7 @@ int FontManager::fontnum (int id) const { } -int FontManager::vfFirstFontNum (VirtualFont *vf) const { +int FontManager::vfFirstFontNum (const VirtualFont *vf) const { VfFirstFontMap::const_iterator it = _vfFirstFontMap.find(vf); return (it == _vfFirstFontMap.end()) ? -1 : (int) it->second; } @@ -139,7 +139,7 @@ Font* FontManager::getFontById (int id) const { /** Returns the current active virtual font. */ -VirtualFont* FontManager::getVF () const { +const VirtualFont* FontManager::getVF () const { return _vfStack.empty() ? 0 : _vfStack.top(); } @@ -236,11 +236,28 @@ int FontManager::registerFont (UInt32 fontnum, string name, UInt32 checksum, dou } +/** Registers a new native font to be managed by the FontManager. If there is + * already a registered font assigned to number n, nothing happens. + * @param[in] fontnum local font number used in DVI file + * @param[in] filename name/path of font file + * @param[in] ptsize font size in PS points + * @param[in] style font style parameters + * @param[in] color global font color + * @return global font id */ int FontManager::registerFont (UInt32 fontnum, string filename, double ptsize, const FontStyle &style, Color color) { return registerFont(fontnum, filename, 0, ptsize, style, color); } +/** Registers a new native font to be managed by the FontManager. If there is + * already a registered font assigned to number n, nothing happens. + * @param[in] fontnum local font number used in DVI file + * @param[in] filename name/path of font file + * @param[in] fontIndex subfont index + * @param[in] ptsize font size in PS points + * @param[in] style font style parameters + * @param[in] color global font color + * @return global font id */ int FontManager::registerFont (UInt32 fontnum, string filename, int fontIndex, double ptsize, const FontStyle &style, Color color) { int id = fontID(fontnum); if (id >= 0) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h index b33cc08ee13..7e249a9b9da 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h @@ -33,7 +33,7 @@ struct FileFinder; -struct Font; +class Font; class VirtualFont; /** This class provides methods for easy DVI font handling. @@ -45,8 +45,8 @@ class FontManager { typedef std::map<UInt32,int> Num2IdMap; typedef std::map<std::string,int> Name2IdMap; - typedef std::map<VirtualFont*,Num2IdMap> VfNum2IdMap; - typedef std::map<VirtualFont*, UInt32> VfFirstFontMap; + typedef std::map<const VirtualFont*,Num2IdMap> VfNum2IdMap; + typedef std::map<const VirtualFont*, UInt32> VfFirstFontMap; typedef std::stack<VirtualFont*> VfStack; public: @@ -58,12 +58,12 @@ class FontManager Font* getFont (int n) const; Font* getFont (const std::string &name) const; Font* getFontById (int id) const; - VirtualFont* getVF () const; + const VirtualFont* getVF () const; int fontID (int n) const; int fontID (const Font *font) const; int fontID (const std::string &name) const; int fontnum (int id) const; - int vfFirstFontNum (VirtualFont *vf) const; + int vfFirstFontNum (const VirtualFont *vf) const; void enterVF (VirtualFont *vf); void leaveVF (); void assignVfChar (int c, std::vector<UInt8> *dvi); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h index cc09be79894..07c4d7e69cb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h @@ -33,6 +33,10 @@ struct FontMetrics virtual double getCharHeight (int c) const =0; virtual double getCharDepth (int c) const =0; virtual double getItalicCorr (int c) const =0; + virtual double getSpace () const =0; + virtual double getSpaceStretch () const =0; + virtual double getSpaceShrink () const =0; + virtual double getQuad () const =0; virtual bool verticalLayout () const =0; virtual UInt32 getChecksum () const =0; virtual UInt16 firstChar () const =0; @@ -48,6 +52,10 @@ struct NullFontMetric : public FontMetrics double getCharHeight (int c) const {return 0;} double getCharDepth (int c) const {return 0;} double getItalicCorr (int c) const {return 0;} + double getSpace () const {return 0;} + double getSpaceStretch () const {return 0;} + double getSpaceShrink () const {return 0;} + double getQuad () const {return 0;} bool verticalLayout () const {return false;} UInt32 getChecksum () const {return 0;} UInt16 firstChar () const {return 0;} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp index d305431d5b4..e44b3548b67 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp @@ -172,7 +172,11 @@ bool GFReader::executePostamble () { _in.seekg(-1, ios::end); while (_in.peek() == 223) // skip fill bytes _in.seekg(-1, ios::cur); - _in.seekg(-4, ios::cur); + if (_in.peek() != 131) + throw GFException("invalid identification byte in postpost"); + _in.seekg(-5, ios::cur); // now on postpost + if (_in.get() != 249) + throw GFException("invalid GF file"); UInt32 q = readUnsigned(4); // pointer to begin of postamble _in.seekg(q); // now on begin of postamble while (executeCommand() != 249); // execute all commands until postpost is reached @@ -208,7 +212,7 @@ double GFReader::getCharWidth (UInt32 c) const { void GFReader::cmdPre (int) { UInt32 i = readUnsigned(1); if (i != 131) - throw GFException("invalid identification number in GF preamble"); + throw GFException("invalid identification byte in preamble"); else { UInt32 k = readUnsigned(1); string s = readString(k); @@ -234,7 +238,7 @@ void GFReader::cmdPostPost (int) { readUnsigned(4); // pointer to begin of postamble UInt32 i = readUnsigned(1); if (i != 131) - throw GFException("invalid identification number in GF preamble"); + throw GFException("invalid identification byte in postpost"); while (readUnsigned(1) == 223); // skip fill bytes } @@ -373,4 +377,3 @@ void GFReader::cmdCharLoc (int) { Int32 p = readSigned(4); // pointer to begin of (last) character data _charInfoMap[c] = CharInfo(dx, dy, w, p); } - diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp index d18741ba82d..87518f872c8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp @@ -20,18 +20,11 @@ #include <config.h> #include <fstream> +#include <potracelib.h> #include "GFTracer.h" #include "Glyph.h" #include "Message.h" -#ifdef __MSVC__ -#include <potracelib.h> -#else -extern "C" { -#include <potracelib.h> -} -#endif - using namespace std; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp index 0ba2b6a0c00..2388f737bb2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp @@ -38,7 +38,7 @@ string Ghostscript::LIBGS_NAME; #ifndef HAVE_LIBGS -#ifdef __WIN32__ +#ifdef _WIN32 /** Looks up the path of the Ghostscript DLL in the Windows registry and returns it. * If there is no proper registry entry, the returned string is empty. */ static string get_path_from_registry () { @@ -79,7 +79,7 @@ static string get_path_from_registry () { #endif // RRF_RT_REG_SZ return ""; } -#endif // __WIN32__ +#endif // _WIN32 /** Try to detect name of the Ghostscript shared library depending on the user settings. @@ -98,7 +98,7 @@ static string get_libgs (const string &fname) { if (const char *gsdll_path = FileFinder::lookup(gsdll)) return gsdll_path; #endif // MIKTEX -#if defined(__WIN32__) +#if defined(_WIN32) // try to look up the path of the Ghostscript DLL in the Windows registry string gsdll_path = get_path_from_registry(); if (!gsdll_path.empty()) @@ -106,7 +106,7 @@ static string get_libgs (const string &fname) { #endif #if defined(__WIN64__) return "gsdll64.dll"; -#elif defined(__WIN32__) +#elif defined(_WIN32) return "gsdll32.dll"; #else // try to find libgs.so.X on the user's system @@ -340,7 +340,7 @@ const char* Ghostscript::error_name (int code) { #if defined(HAVE_LIBGS) // use array defined in libgs to avoid linking the error strings into the binary return gs_error_names[code-1]; -#elif defined(__WIN32__) +#elif defined(_WIN32) // gs_error_names is private in the Ghostscript DLL so we can't access it here return error_names[code-1]; #else diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h index ae83fd67144..82522489104 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h @@ -33,7 +33,7 @@ #include "iapi.h" #endif -#if defined(__WIN32__) && !defined(_Windows) +#if defined(_WIN32) && !defined(_Windows) #define _Windows #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp index 55ca1e5a46f..a58e08bca5c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp @@ -24,6 +24,7 @@ #include "HtmlSpecialHandler.h" #include "InputReader.h" #include "Message.h" +#include "SpecialActions.h" #include "SVGTree.h" using namespace std; @@ -35,10 +36,7 @@ Color HtmlSpecialHandler::LINK_LINECOLOR; bool HtmlSpecialHandler::USE_LINECOLOR = false; -void HtmlSpecialHandler::preprocess (const char *prefix, istream &is, SpecialActions *actions) { - if (!actions) - return; - _actions = actions; +void HtmlSpecialHandler::preprocess (const char *, istream &is, SpecialActions &actions) { StreamInputReader ir(is); ir.skipSpace(); // collect page number and ID of named anchors @@ -46,22 +44,22 @@ void HtmlSpecialHandler::preprocess (const char *prefix, istream &is, SpecialAct if (ir.check("<a ") && ir.parseAttributes(attribs, '"') > 0) { map<string,string>::iterator it; if ((it = attribs.find("name")) != attribs.end()) - preprocessNameAnchor(it->second); + preprocessNameAnchor(it->second, actions); else if ((it = attribs.find("href")) != attribs.end()) preprocessHrefAnchor(it->second); } } -void HtmlSpecialHandler::preprocessNameAnchor (const string &name) { +void HtmlSpecialHandler::preprocessNameAnchor (const string &name, SpecialActions &actions) { NamedAnchors::iterator it = _namedAnchors.find(name); if (it == _namedAnchors.end()) { // anchor completely undefined? int id = static_cast<int>(_namedAnchors.size())+1; - _namedAnchors[name] = NamedAnchor(_actions->getCurrentPageNumber(), id, 0); + _namedAnchors[name] = NamedAnchor(actions.getCurrentPageNumber(), id, 0); } else if (it->second.id < 0) { // anchor referenced but not defined yet? it->second.id *= -1; - it->second.pageno = _actions->getCurrentPageNumber(); + it->second.pageno = actions.getCurrentPageNumber(); } else Message::wstream(true) << "named hyperref anchor '" << name << "' redefined\n"; @@ -82,24 +80,22 @@ void HtmlSpecialHandler::preprocessHrefAnchor (const string &uri) { } -bool HtmlSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { - if (!actions) - return true; - _actions = actions; +bool HtmlSpecialHandler::process (const char *, istream &is, SpecialActions &actions) { + _active = true; StreamInputReader ir(is); ir.skipSpace(); map<string,string> attribs; map<string,string>::iterator it; if (ir.check("<a ") && ir.parseAttributes(attribs, '"') > 0) { if ((it = attribs.find("href")) != attribs.end()) // <a href="URI"> - processHrefAnchor(it->second); + processHrefAnchor(it->second, actions); else if ((it = attribs.find("name")) != attribs.end()) // <a name="ID"> - processNameAnchor(it->second); + processNameAnchor(it->second, actions); else return false; // none or only invalid attributes } else if (ir.check("</a>")) - closeAnchor(); + closeAnchor(actions); else if (ir.check("<img src=")) { } else if (ir.check("<base ") && ir.parseAttributes(attribs, '"') > 0 && (it = attribs.find("href")) != attribs.end()) @@ -110,8 +106,8 @@ bool HtmlSpecialHandler::process (const char *prefix, istream &is, SpecialAction /** Handles anchors with href attribute: <a href="URI">...</a> * @param uri value of href attribute */ -void HtmlSpecialHandler::processHrefAnchor (string uri) { - closeAnchor(); +void HtmlSpecialHandler::processHrefAnchor (string uri, SpecialActions &actions) { + closeAnchor(actions); string name; if (uri[0] == '#') { // reference to named anchor? name = uri.substr(1); @@ -121,9 +117,9 @@ void HtmlSpecialHandler::processHrefAnchor (string uri) { else { int id = it->second.id; uri = "#loc"+XMLString(id); - if (_actions->getCurrentPageNumber() != it->second.pageno) { + if (actions.getCurrentPageNumber() != it->second.pageno) { ostringstream oss; - oss << _actions->getSVGFilename(it->second.pageno) << uri; + oss << actions.getSVGFilename(it->second.pageno) << uri; uri = oss.str(); } } @@ -136,29 +132,29 @@ void HtmlSpecialHandler::processHrefAnchor (string uri) { XMLElementNode *anchor = new XMLElementNode("a"); anchor->addAttribute("xlink:href", uri); anchor->addAttribute("xlink:title", XMLString(name.empty() ? uri : name, false)); - _actions->pushContextElement(anchor); - _actions->bbox("{anchor}", true); // start computing the bounding box of the linked area - _depthThreshold = _actions->getDVIStackDepth(); + actions.pushContextElement(anchor); + actions.bbox("{anchor}", true); // start computing the bounding box of the linked area + _depthThreshold = actions.getDVIStackDepth(); _anchorType = AT_HREF; } /** Handles anchors with name attribute: <a name="NAME">...</a> * @param name value of name attribute */ -void HtmlSpecialHandler::processNameAnchor (const string &name) { - closeAnchor(); +void HtmlSpecialHandler::processNameAnchor (const string &name, SpecialActions &actions) { + closeAnchor(actions); NamedAnchors::iterator it = _namedAnchors.find(name); assert(it != _namedAnchors.end()); - it->second.pos = _actions->getY(); + it->second.pos = actions.getY(); _anchorType = AT_NAME; } /** Handles the closing tag (</a> of the current anchor element. */ -void HtmlSpecialHandler::closeAnchor () { +void HtmlSpecialHandler::closeAnchor (SpecialActions &actions) { if (_anchorType == AT_HREF) { - markLinkedBox(); - _actions->popContextElement(); + markLinkedBox(actions); + actions.popContextElement(); _depthThreshold = 0; } _anchorType = AT_NONE; @@ -169,8 +165,8 @@ void HtmlSpecialHandler::closeAnchor () { * a box so that it's noticeable by the user. Additionally, an invisible rectangle is * placed over this area in order to avoid flickering of the mouse cursor when moving * it over the hyperlinked area. */ -void HtmlSpecialHandler::markLinkedBox () { - const BoundingBox &bbox = _actions->bbox("{anchor}"); +void HtmlSpecialHandler::markLinkedBox (SpecialActions &actions) { + const BoundingBox &bbox = actions.bbox("{anchor}"); if (bbox.width() > 0 && bbox.height() > 0) { // does the bounding box extend in both dimensions? if (MARKER_TYPE != MT_NONE) { const double linewidth = min(0.5, bbox.height()/15); @@ -179,7 +175,7 @@ void HtmlSpecialHandler::markLinkedBox () { double y = bbox.maxY()+linewidth; double w = bbox.width(); double h = linewidth; - const Color &linecolor = USE_LINECOLOR ? LINK_LINECOLOR : _actions->getColor(); + const Color &linecolor = USE_LINECOLOR ? LINK_LINECOLOR : actions.getColor(); if (MARKER_TYPE == MT_LINE) rect->addAttribute("fill", linecolor.svgColorString()); else { @@ -204,7 +200,7 @@ void HtmlSpecialHandler::markLinkedBox () { rect->addAttribute("y", y); rect->addAttribute("width", w); rect->addAttribute("height", h); - _actions->prependToPage(rect); + actions.prependToPage(rect); if (MARKER_TYPE == MT_BOX || MARKER_TYPE == MT_BGCOLOR) { // slightly enlarge the boxed area x -= linewidth; @@ -212,7 +208,7 @@ void HtmlSpecialHandler::markLinkedBox () { w += 2*linewidth; h += 2*linewidth; } - _actions->embed(BoundingBox(x, y, x+w, y+h)); + actions.embed(BoundingBox(x, y, x+w, y+h)); } // Create an invisible rectangle around the linked area so that it's easier to access. // This is only necessary when using paths rather than real text elements together with fonts. @@ -224,30 +220,30 @@ void HtmlSpecialHandler::markLinkedBox () { rect->addAttribute("height", bbox.height()); rect->addAttribute("fill", "white"); rect->addAttribute("fill-opacity", 0); - _actions->appendToPage(rect); + actions.appendToPage(rect); } } } /** This method is called every time the DVI position changes. */ -void HtmlSpecialHandler::dviMovedTo (double x, double y) { - if (_actions && _anchorType != AT_NONE) { +void HtmlSpecialHandler::dviMovedTo (double x, double y, SpecialActions &actions) { + if (_active && _anchorType != AT_NONE) { // Start a new box if the current depth of the DVI stack underruns // the initial threshold which indicates a line break. - if (_actions->getDVIStackDepth() < _depthThreshold) { - markLinkedBox(); - _depthThreshold = _actions->getDVIStackDepth(); - _actions->bbox("{anchor}", true); // start a new box on the new line + if (actions.getDVIStackDepth() < _depthThreshold) { + markLinkedBox(actions); + _depthThreshold = actions.getDVIStackDepth(); + actions.bbox("{anchor}", true); // start a new box on the new line } } } -void HtmlSpecialHandler::dviEndPage (unsigned pageno) { - if (_actions) { +void HtmlSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { + if (_active) { // create views for all collected named anchors defined on the recent page - const BoundingBox &pagebox = _actions->bbox(); + const BoundingBox &pagebox = actions.bbox(); for (NamedAnchors::iterator it=_namedAnchors.begin(); it != _namedAnchors.end(); ++it) { if (it->second.pageno == pageno && it->second.referenced) { // current anchor referenced? ostringstream oss; @@ -256,11 +252,11 @@ void HtmlSpecialHandler::dviEndPage (unsigned pageno) { XMLElementNode *view = new XMLElementNode("view"); view->addAttribute("id", "loc"+XMLString(it->second.id)); view->addAttribute("viewBox", oss.str()); - _actions->appendToDefs(view); + actions.appendToDefs(view); } } - closeAnchor(); - _actions = 0; + closeAnchor(actions); + _active = false; } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h index 6cf97a3ff06..6c17f4541ca 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h @@ -26,7 +26,7 @@ #include "Color.h" #include "SpecialHandler.h" -struct SpecialActions; +class SpecialActions; class HtmlSpecialHandler : public SpecialHandler, public DVIEndPageListener, public DVIPositionListener { @@ -43,9 +43,9 @@ class HtmlSpecialHandler : public SpecialHandler, public DVIEndPageListener, pub typedef std::map<std::string, NamedAnchor> NamedAnchors; public: - HtmlSpecialHandler () : _actions(0), _anchorType(AT_NONE), _depthThreshold(0) {} - void preprocess(const char *prefix, std::istream &is, SpecialActions *actions); - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + HtmlSpecialHandler () : _active(false), _anchorType(AT_NONE), _depthThreshold(0) {} + void preprocess (const char *prefix, std::istream &is, SpecialActions &actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); const char* name () const {return "html";} const char* info () const {return "hyperref specials";} const char** prefixes () const; @@ -54,13 +54,13 @@ class HtmlSpecialHandler : public SpecialHandler, public DVIEndPageListener, pub protected: void preprocessHrefAnchor (const std::string &uri); - void preprocessNameAnchor (const std::string &name); - void processHrefAnchor (std::string uri); - void processNameAnchor (const std::string &name); - void dviEndPage (unsigned pageno); - void dviMovedTo (double x, double y); - void closeAnchor (); - void markLinkedBox (); + void preprocessNameAnchor (const std::string &name, SpecialActions &actions); + void processHrefAnchor (std::string uri, SpecialActions &actions); + void processNameAnchor (const std::string &name, SpecialActions &actions); + void dviEndPage (unsigned pageno, SpecialActions &actions); + void dviMovedTo (double x, double y, SpecialActions &actions); + void closeAnchor (SpecialActions &actions); + void markLinkedBox (SpecialActions &actions); enum MarkerType {MT_NONE, MT_LINE, MT_BOX, MT_BGCOLOR}; static MarkerType MARKER_TYPE; ///< selects how to mark linked areas @@ -69,7 +69,7 @@ class HtmlSpecialHandler : public SpecialHandler, public DVIEndPageListener, pub static bool USE_LINECOLOR; ///< if true, LINK_LINECOLOR is applied private: - SpecialActions *_actions; + bool _active; AnchorType _anchorType; ///< type of active anchor int _depthThreshold; ///< break anchor box if the DVI stack depth underruns this threshold std::string _base; ///< base URL that is prepended to all relative targets diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp index 665d874de19..d6f97eb0377 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp @@ -31,44 +31,46 @@ using namespace std; JFM::JFM (istream &is) { is.seekg(0); - StreamReader sr(is); - UInt16 id = UInt16(sr.readUnsigned(2)); // JFM ID (9 or 11) + StreamReader reader(is); + UInt16 id = UInt16(reader.readUnsigned(2)); // JFM ID (9 or 11) if (id != 9 && id != 11) { ostringstream oss; oss << "invalid JFM identifier " << id << " (9 or 11 expected)"; throw FontMetricException(oss.str()); } _vertical = (id == 9); - UInt16 nt = UInt16(sr.readUnsigned(2)); // length of character type table - UInt16 lf = UInt16(sr.readUnsigned(2)); // length of entire file in 4 byte words - UInt16 lh = UInt16(sr.readUnsigned(2)); // length of header in 4 byte words - UInt16 bc = UInt16(sr.readUnsigned(2)); // smallest character code in font - UInt16 ec = UInt16(sr.readUnsigned(2)); // largest character code in font - UInt16 nw = UInt16(sr.readUnsigned(2)); // number of words in width table - UInt16 nh = UInt16(sr.readUnsigned(2)); // number of words in height table - UInt16 nd = UInt16(sr.readUnsigned(2)); // number of words in depth table - UInt16 ni = UInt16(sr.readUnsigned(2)); // number of words in italic corr. table - UInt16 nl = UInt16(sr.readUnsigned(2)); // number of words in glue/kern table - UInt16 nk = UInt16(sr.readUnsigned(2)); // number of words in kern table - UInt16 ng = UInt16(sr.readUnsigned(2)); // number of words in glue table - UInt16 np = UInt16(sr.readUnsigned(2)); // number of font parameter words + UInt16 nt = UInt16(reader.readUnsigned(2)); // length of character type table + UInt16 lf = UInt16(reader.readUnsigned(2)); // length of entire file in 4 byte words + UInt16 lh = UInt16(reader.readUnsigned(2)); // length of header in 4 byte words + UInt16 bc = UInt16(reader.readUnsigned(2)); // smallest character code in font + UInt16 ec = UInt16(reader.readUnsigned(2)); // largest character code in font + UInt16 nw = UInt16(reader.readUnsigned(2)); // number of words in width table + UInt16 nh = UInt16(reader.readUnsigned(2)); // number of words in height table + UInt16 nd = UInt16(reader.readUnsigned(2)); // number of words in depth table + UInt16 ni = UInt16(reader.readUnsigned(2)); // number of words in italic corr. table + UInt16 nl = UInt16(reader.readUnsigned(2)); // number of words in glue/kern table + UInt16 nk = UInt16(reader.readUnsigned(2)); // number of words in kern table + UInt16 ng = UInt16(reader.readUnsigned(2)); // number of words in glue table + UInt16 np = UInt16(reader.readUnsigned(2)); // number of font parameter words if (7+nt+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ng+np != lf) throw FontMetricException("inconsistent length values"); setCharRange(bc, ec); - readHeader(sr); + readHeader(reader); is.seekg(28+lh*4); - readTables(sr, nt, nw, nh, nd, ni); + readTables(reader, nt, nw, nh, nd, ni); + is.seekg(4*(lf-np), ios::beg); + readParameters(reader, np); // JFM files provide 9 parameters but we don't need all of them } -void JFM::readTables (StreamReader &sr, int nt, int nw, int nh, int nd, int ni) { +void JFM::readTables (StreamReader &reader, int nt, int nw, int nh, int nd, int ni) { // determine smallest charcode with chartype > 0 UInt16 minchar=0xFFFF, maxchar=0; for (int i=0; i < nt; i++) { - UInt16 c = (UInt16)sr.readUnsigned(2); - UInt16 t = (UInt16)sr.readUnsigned(2); + UInt16 c = (UInt16)reader.readUnsigned(2); + UInt16 t = (UInt16)reader.readUnsigned(2); if (t > 0) { minchar = min(minchar, c); maxchar = max(maxchar, c); @@ -79,15 +81,15 @@ void JFM::readTables (StreamReader &sr, int nt, int nw, int nh, int nd, int ni) _minchar = minchar; _charTypeTable.resize(maxchar-minchar+1); memset(&_charTypeTable[0], 0, nt*sizeof(UInt16)); - sr.seek(-nt*4, ios::cur); + reader.seek(-nt*4, ios::cur); for (int i=0; i < nt; i++) { - UInt16 c = (UInt16)sr.readUnsigned(2); - UInt16 t = (UInt16)sr.readUnsigned(2); + UInt16 c = (UInt16)reader.readUnsigned(2); + UInt16 t = (UInt16)reader.readUnsigned(2); if (c >= minchar) _charTypeTable[c-minchar] = t; } } - TFM::readTables(sr, nw, nh, nd, ni); + TFM::readTables(reader, nw, nh, nd, ni); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h index 42e4deb3dd8..0046fad0557 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h @@ -34,7 +34,7 @@ class JFM : public TFM UInt16 maxChar () const {return static_cast<UInt16>(_minchar+_charTypeTable.size()-1);} protected: - void readTables (StreamReader &sr, int nt, int nw, int nh, int nd, int ni); + void readTables (StreamReader &reader, int nt, int nw, int nh, int nd, int ni); int charIndex (int c) const; private: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp index 8036e1e7b9b..8ab8120daab 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp @@ -18,33 +18,39 @@ ** along with this program; if not, see <http://www.gnu.org/licenses/>. ** *************************************************************************/ -#include <config.h> #include <sstream> #include "InputReader.h" #include "Length.h" -#define UNIT(c1,c2) ((c1 << 8)|c2) - using namespace std; +const double Length::pt2in = 1.0/72.27; +const double Length::pt2bp = pt2in*72; +const double Length::pt2cm = pt2in*2.54; +const double Length::pt2mm = pt2cm*10; +const double Length::pt2pc = 1.0/12; +const double Length::pt2dd = 1157.0/1238; +const double Length::pt2cc = pt2dd/12; +const double Length::pt2sp = 65536.0; + -void Length::set (const string &len) { - switch (len.length()) { +void Length::set (const string &lenstr) { + switch (lenstr.length()) { case 0: _pt = 0; break; case 1: - if (isdigit(len[0])) - _pt = len[0] - '0'; + if (isdigit(lenstr[0])) + _pt = lenstr[0] - '0'; else - throw UnitException("invalid length: "+len); + throw UnitException(string("invalid length: ")+lenstr); break; default: - istringstream iss(len); + istringstream iss(lenstr); StreamInputReader ir(iss); double val; if (!ir.parseDouble(val)) - throw UnitException("invalid length: "+len); + throw UnitException(string("invalid length: ")+lenstr); string unit = ir.getWord(); set(val, unit); } @@ -54,12 +60,83 @@ void Length::set (const string &len) { void Length::set (double val, Unit unit) { switch (unit) { case PT: _pt = val; break; - case BP: _pt = val*72.27/72; break; - case IN: _pt = val*72.27; break; - case CM: _pt = val/2.54*72.27; break; - case MM: _pt = val/25.4*72.27; break; - case PC: _pt = val/12*72.27; break; + case BP: _pt = val/pt2bp; break; + case IN: _pt = val/pt2in; break; + case CM: _pt = val/pt2cm; break; + case MM: _pt = val/pt2mm; break; + case PC: _pt = val/pt2pc; break; + case DD: _pt = val/pt2dd; break; + case CC: _pt = val/pt2cc; break; + case SP: _pt = val/pt2sp; break; + default: + // this isn't supposed to happen + ostringstream oss; + oss << "invalid length unit: (" << unit << ")"; + throw UnitException(oss.str()); + } +} + + +double Length::get (Unit unit) const { + switch (unit) { + case PT: return pt(); + case BP: return bp(); + case IN: return in(); + case CM: return cm(); + case MM: return mm(); + case PC: return pc(); + case DD: return dd(); + case CC: return cc(); + case SP: return sp(); + } + // this isn't supposed to happen + ostringstream oss; + oss << "invalid length unit: (" << unit << ")"; + throw UnitException(oss.str()); +} + + +string Length::toString (Unit unit) const { + ostringstream oss; + oss << get(unit) << unitToString(unit); + return oss.str(); +} + + +#define UNIT(c1, c2) ((c1 << 8)|c2) + +Length::Unit Length::stringToUnit (const std::string &unitstr) { + if (unitstr.length() == 2) { + switch (UNIT(unitstr[0], unitstr[1])) { + case UNIT('p','t'): return PT; + case UNIT('b','p'): return BP; + case UNIT('i','n'): return IN; + case UNIT('c','m'): return CM; + case UNIT('m','m'): return MM; + case UNIT('p','c'): return PC; + case UNIT('d','d'): return DD; + case UNIT('c','c'): return CC; + case UNIT('s','p'): return SP; + } + } + throw UnitException(string("invalid length unit: ")+unitstr); +} + + +string Length::unitToString (Unit unit) { + switch (unit) { + case PT: return "pt"; + case BP: return "bp"; + case IN: return "in"; + case CM: return "cm"; + case MM: return "mm"; + case PC: return "pc"; + case DD: return "dd"; + case CC: return "cc"; + case SP: return "sp"; } + // this isn't supposed to happen + return "??"; } @@ -67,19 +144,6 @@ void Length::set (double val, string unitstr) { if (unitstr.empty()) unitstr = "pt"; else if (unitstr.length() != 2) - throw UnitException("invalid length unit: "+unitstr); - - Unit unit; - switch (UNIT(unitstr[0], unitstr[1])) { - case UNIT('p','t'): unit = PT; break; - case UNIT('b','p'): unit = BP; break; - case UNIT('i','n'): unit = IN; break; - case UNIT('c','m'): unit = CM; break; - case UNIT('m','m'): unit = MM; break; - case UNIT('p','c'): unit = PC; break; - default: - throw UnitException("invalid length unit: "+unitstr); - } - set(val, unit); + throw UnitException(string("invalid length unit: ")+unitstr); + set(val, stringToUnit(unitstr)); } - diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h index a0faacded7f..e9cd5aca788 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h @@ -37,26 +37,43 @@ struct UnitException : MessageException class Length { public: - enum Unit {PT, BP, CM, MM, IN, PC}; + enum Unit {PT, BP, CM, MM, IN, PC, DD, CC, SP}; public: Length () : _pt(0) {} - Length (double val, Unit unit=PT) {set(val, unit);} - Length (double val, const std::string &unit) {set(val, unit);} - Length (const std::string &len) {set(len);} + Length (double val, Unit unit=PT) {set(val, unit);} + Length (double val, const std::string &unitstr) {set(val, unitstr);} + Length (const std::string &lenstr) {set(lenstr);} void set (double val, Unit unit); void set (double val, std::string unit); - void set (const std::string &len); - + void set (const std::string &lenstr); double pt () const {return _pt;} - double in () const {return _pt/72.27;} - double bp () const {return in()*72;} - double cm () const {return in()*2.54;} - double mm () const {return cm()*10;} - double pc () const {return in()*12;} + double in () const {return _pt*pt2in;} + double bp () const {return _pt*pt2bp;} + double cm () const {return _pt*pt2cm;} + double mm () const {return _pt*pt2mm;} + double pc () const {return _pt*pt2pc;} + double dd () const {return _pt*pt2dd;} + double cc () const {return _pt*pt2cc;} + double sp () const {return _pt*pt2sp;} + double get (Unit unit) const; + std::string toString (Unit unit) const; + + static Unit stringToUnit (const std::string &unitstr); + static std::string unitToString (Unit unit); + + public: + static const double pt2bp; + static const double pt2in; + static const double pt2cm; + static const double pt2mm; + static const double pt2pc; + static const double pt2dd; + static const double pt2cc; + static const double pt2sp; private: - double _pt; // length in TeX point units + double _pt; // length in TeX point units (72.27pt = 1in) }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am index 0600651f7ee..90ef96d98c5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -133,6 +133,8 @@ libdvisvgm_a_SOURCES = \ PageSize.cpp \ PageSize.h \ Pair.h \ + PapersizeSpecialHandler.cpp \ + PapersizeSpecialHandler.h \ PathClipper.cpp \ PathClipper.h \ PdfSpecialHandler.cpp \ @@ -167,8 +169,18 @@ libdvisvgm_a_SOURCES = \ StreamWriter.h \ Subfont.cpp \ Subfont.h \ + SVGCharHandler.cpp \ + SVGCharHandler.h \ + SVGCharHandlerFactory.cpp \ + SVGCharHandlerFactory.h \ + SVGCharPathHandler.cpp \ + SVGCharPathHandler.h \ + SVGCharTspanTextHandler.cpp \ + SVGCharTspanTextHandler.h \ SVGOutput.cpp \ SVGOutput.h \ + SVGSingleCharTextHandler.cpp \ + SVGSingleCharTextHandler.h \ SVGTree.cpp \ SVGTree.h \ System.cpp \ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp index 36304fa5723..40b0909f173 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp @@ -68,7 +68,7 @@ void MessageStream::putChar (const char c, ostream &os) { else { const int cols = Terminal::columns(); if (cols > 0 && _col >= cols) { -#ifndef __WIN32__ +#ifndef _WIN32 // move cursor to next line explicitly (not necessary in Windows/DOS terminal) os << '\n'; #endif @@ -92,7 +92,7 @@ MessageStream& MessageStream::operator << (const char *str) { const char *last = strchr(first, '\n'); if (!last) last = first+strlen(first)-1; -#ifndef __WIN32__ +#ifndef _WIN32 // move cursor to next line explicitly (not necessary in Windows/DOS terminal) const int cols = Terminal::columns(); int len = last-first+1; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp index e60a66d1cb6..26f43984679 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp @@ -49,7 +49,7 @@ bool MetafontWrapper::call (const string &mode, double mag) { return false; // mf file not available => no need to call the "slow" Metafont FileSystem::remove(_fontname+".gf"); -#ifdef __WIN32__ +#ifdef _WIN32 #ifdef TEXLIVEWIN32 const char *mfname = "mf-nowin.exe"; #else diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp index cea39c5d637..fd85cc0ffac 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp @@ -25,13 +25,13 @@ using namespace std; -bool NoPsSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { +bool NoPsSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { _count++; return true; } -void NoPsSpecialHandler::dviEndPage (unsigned pageno) { +void NoPsSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { if (_count > 0) { string suffix = (_count > 1 ? "s" : ""); Message::wstream(true) << _count << " PostScript special" << suffix << " ignored. The resulting SVG might look wrong.\n"; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h index cd924198e6c..777656e8ad3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h @@ -27,13 +27,13 @@ class NoPsSpecialHandler : public SpecialHandler, public DVIEndPageListener { public: NoPsSpecialHandler () : _count(0) {} - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); const char* name () const {return 0;} const char* info () const {return 0;} const char** prefixes () const; protected: - void dviEndPage (unsigned pageno); + void dviEndPage (unsigned pageno, SpecialActions &actions); private: unsigned _count; // number of PS specials skipped diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp index 5bb48cf94f4..47e151dd90a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp @@ -36,9 +36,9 @@ string PSPattern::svgID () const { /** Appends the definition of this pattern to the "def" section of the SVG tree. */ -void PSPattern::apply (SpecialActions *actions) { +void PSPattern::apply (SpecialActions &actions) { if (XMLElementNode *pattern = createPatternNode()) - actions->appendToDefs(pattern); + actions.appendToDefs(pattern); } @@ -107,7 +107,7 @@ XMLElementNode* PSTilingPattern::createGroupNode () const { } -void PSTilingPattern::apply (SpecialActions *actions) { +void PSTilingPattern::apply (SpecialActions &actions) { PSPattern::apply(actions); _groupNode = 0; } @@ -145,7 +145,7 @@ string PSUncoloredTilingPattern::svgID () const { /** Appends the definition of this pattern with the current color applied * to the "def" section of the SVG tree. */ -void PSUncoloredTilingPattern::apply (SpecialActions* actions) { +void PSUncoloredTilingPattern::apply (SpecialActions &actions) { set<Color>::iterator it=_colors.find(_currentColor); if (it == _colors.end()) { if (_applied) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h index f2802777c4a..594e819049c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h @@ -28,7 +28,7 @@ #include "Matrix.h" -struct SpecialActions; +class SpecialActions; class SVGTree; class XMLElementNode; @@ -38,7 +38,7 @@ class PSPattern virtual ~PSPattern () {} virtual int psID () const {return _id;} virtual std::string svgID () const; - virtual void apply (SpecialActions *actions); + virtual void apply (SpecialActions &actions); protected: PSPattern (int id) : _id(id) {} @@ -54,7 +54,7 @@ class PSTilingPattern : public PSPattern public: ~PSTilingPattern (); virtual XMLElementNode* getContainerNode () {return _groupNode;} - void apply (SpecialActions *actions); + void apply (SpecialActions &actions); protected: PSTilingPattern (int id, BoundingBox &bbox, Matrix &matrix, double xstep, double ystep); @@ -86,7 +86,7 @@ class PSUncoloredTilingPattern : public PSTilingPattern ~PSUncoloredTilingPattern (); std::string svgID () const; void setColor (Color color) {_currentColor = color;} - void apply (SpecialActions *actions); + void apply (SpecialActions &actions); protected: XMLElementNode* createClipNode () const; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h index 671fa8c395a..89470250821 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h @@ -26,7 +26,7 @@ #include "BoundingBox.h" #include "PSFilter.h" -struct SpecialActions; +class SpecialActions; class PSPreviewFilter : public PSFilter { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp new file mode 100644 index 00000000000..23462182e6a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp @@ -0,0 +1,68 @@ +#include "Length.h" +#include "Message.h" +#include "PapersizeSpecialHandler.h" +#include "SpecialActions.h" + +using namespace std; + +void PapersizeSpecialHandler::preprocess (const char*, std::istream &is, SpecialActions &actions) { + string params; + is >> params; + Length w, h; + size_t splitpos = params.find(','); + if (splitpos == string::npos) { + w.set(params); + h.set(params); + } + else { + w.set(params.substr(0, splitpos)); + h.set(params.substr(splitpos+1)); + } + DoublePair whpair(w.bp(), h.bp()); + if (_pageSizes.empty() || _pageSizes.back().second != whpair) { + unsigned pageno = actions.getCurrentPageNumber(); + if (!_pageSizes.empty() && _pageSizes.back().first == pageno) + _pageSizes.back().second = whpair; + else + _pageSizes.push_back(PageSize(pageno, whpair)); + } +} + + +bool PapersizeSpecialHandler::process (const char *, std::istream &, SpecialActions&) { + return true; +} + + +bool PapersizeSpecialHandler::isLess (const PageSize &ps1, const PageSize &ps2) { + // order PageSize objects by page number + return ps1.first < ps2.first; +} + + +void PapersizeSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { + if (actions.getBBoxFormatString() != "papersize") + return; + + // find number of page with size change not lower than the current one + typedef vector<PageSize>::iterator Iterator; + Iterator lb_it = lower_bound(_pageSizes.begin(), _pageSizes.end(), PageSize(pageno, DoublePair()), isLess); + Iterator it = _pageSizes.end(); + if (lb_it != _pageSizes.end() && lb_it->first == pageno) + it = lb_it; + else if (lb_it != _pageSizes.begin()) + it = lb_it-1; + if (it == _pageSizes.end()) + Message::wstream(true) << "no valid papersize special found\n"; + else { + DoublePair size = it->second; + const double border = -72; + actions.bbox() = BoundingBox(border, border, size.first+border, size.second+border); + } +} + + +const char** PapersizeSpecialHandler::prefixes () const { + static const char *pfx[] = {"papersize=", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h new file mode 100644 index 00000000000..e22f1612237 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h @@ -0,0 +1,28 @@ +#ifndef PAPERSIZESPECIALHANDLER_H +#define PAPERSIZESPECIALHANDLER_H + +#include <utility> +#include <vector> +#include "SpecialHandler.h" + +class PapersizeSpecialHandler : public SpecialHandler, public DVIEndPageListener { + typedef std::pair<double,double> DoublePair; + typedef std::pair<unsigned,DoublePair> PageSize; + + public: + void preprocess (const char *prefix, std::istream &is, SpecialActions &actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); + const char* info () const {return "special to set the page size";} + const char* name () const {return "papersize";} + const char** prefixes () const; + + protected: + void dviEndPage (unsigned pageno, SpecialActions &actions); + static bool isLess (const PageSize &ps1, const PageSize &ps2); + + private: + std::vector<PageSize> _pageSizes; +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp index ee278d10f05..d55e95a9247 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp @@ -34,9 +34,7 @@ PdfSpecialHandler::PdfSpecialHandler () : _maplineProcessed(false) } -bool PdfSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { - if (!actions) - return true; +bool PdfSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { StreamInputReader ir(is); ir.skipSpace(); string cmd = ir.getWord(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h index d722f2c9f6c..0608f347a89 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h @@ -30,7 +30,7 @@ class PdfSpecialHandler : public SpecialHandler const char* info () const {return "pdfTeX font map specials";} const char* name () const {return "pdf";} const char** prefixes () const; - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); private: bool _maplineProcessed; ///< true if a mapline or mapfile special has already been processed diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h index 77cb0e5f7fe..c54cbe10fe9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h @@ -29,7 +29,7 @@ class PreScanDVIReader : public BasicDVIReader { public: PreScanDVIReader (std::istream &is, DVIActions *actions); - unsigned getCurrentPageNumber () const {return _currentPageNumber;} + unsigned currentPageNumber () const {return _currentPageNumber;} protected: void cmdBop (int); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp index 09540568b6b..753ebfec253 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp @@ -20,7 +20,7 @@ #include <config.h> -#ifdef __WIN32__ +#ifdef _WIN32 #include <windows.h> #else #include <fcntl.h> @@ -43,7 +43,7 @@ Process::Process (const string &cmd, const string ¶mstr) } -#ifdef __WIN32__ +#ifdef _WIN32 static void pipe_read (HANDLE handle, string &out) { char buf[4096]; out.clear(); @@ -108,7 +108,7 @@ static void split_paramstr (string ¶mstr, vector<const char*> ¶ms) { * @return true if process terminated properly * @throw SignalException if CTRL-C was pressed during execution */ bool Process::run (string *out) { -#ifdef __WIN32__ +#ifdef _WIN32 SECURITY_ATTRIBUTES sa; ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index 7f909ba17b5..d4bee4a600b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -174,12 +174,12 @@ void PsSpecialHandler::executeAndSync (istream &is, bool updatePos) { } -void PsSpecialHandler::preprocess (const char *prefix, istream &is, SpecialActions *actions) { +void PsSpecialHandler::preprocess (const char *prefix, istream &is, SpecialActions &actions) { initialize(); if (_psSection != PS_HEADERS) return; - _actions = actions; + _actions = &actions; if (*prefix == '!') { _headerCode += "\n"; _headerCode += string(istreambuf_iterator<char>(is), istreambuf_iterator<char>()); @@ -193,12 +193,12 @@ void PsSpecialHandler::preprocess (const char *prefix, istream &is, SpecialActio } -bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { +bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { // process PS headers only once (in prescan) if (*prefix == '!' || strcmp(prefix, "header=") == 0) return true; - _actions = actions; + _actions = &actions; initialize(); if (_psSection != PS_BODY) enterBodySection(); @@ -385,73 +385,73 @@ static bool transform_box_extents (const Matrix &matrix, double &w, double &h, d } -void PsSpecialHandler::dviEndPage (unsigned) { +void PsSpecialHandler::dviEndPage (unsigned, SpecialActions &actions) { BoundingBox bbox; if (_previewFilter.getBoundingBox(bbox)) { // is there any data written by preview package? double w = max(0.0, _previewFilter.width()); double h = max(0.0, _previewFilter.height()); double d = max(0.0, _previewFilter.depth()); - if (_actions && (_actions->getBBoxFormatString() == "preview" || _actions->getBBoxFormatString() == "min")) { - if (_actions->getBBoxFormatString() == "preview") { - _actions->bbox() = bbox; + if (actions.getBBoxFormatString() == "preview" || actions.getBBoxFormatString() == "min") { + if (actions.getBBoxFormatString() == "preview") { + actions.bbox() = bbox; Message::mstream() << "\napplying bounding box set by"; } else { // compute height, depth and width depending on the // tight bounding box derived from the objects on the page double y0 = bbox.maxY()-h; // y coordinate of the baseline - h = _actions->bbox().maxY()-y0; + h = actions.bbox().maxY()-y0; if (h < 0) { h = 0; - d = _actions->bbox().height(); + d = actions.bbox().height(); } else { - d = y0-_actions->bbox().minY(); + d = y0-actions.bbox().minY(); if (d < 0) { - h = _actions->bbox().height(); + h = actions.bbox().height(); d = 0; } } - w = _actions->bbox().width(); + w = actions.bbox().width(); Message::mstream() << "\ncomputing extents based on data set by"; } Message::mstream() << " preview package (version " << _previewFilter.version() << ")\n"; // apply page transformations to box extents Matrix pagetrans; - _actions->getPageTransform(pagetrans); + actions.getPageTransform(pagetrans); bool isBaselineHorizontal = transform_box_extents(pagetrans, w, h, d); - _actions->bbox().lock(); + actions.bbox().lock(); - if (isBaselineHorizontal) { + if (!isBaselineHorizontal) + Message::mstream() << "can't determine height, width, and depth due to non-horizontal baseline\n"; + else { const double bp2pt = 72.27/72.0; Message::mstream() << "width=" << XMLString(w*bp2pt) << "pt, " "height=" << XMLString(h*bp2pt) << "pt, " "depth=" << XMLString(d*bp2pt) << "pt\n"; } - else - Message::mstream() << "can't determine height, width, and depth due to non-horizontal baseline\n"; } #if 0 XMLElementNode *rect = new XMLElementNode("rect"); - rect->addAttribute("x", _actions->bbox().minX()); - rect->addAttribute("y", _actions->bbox().minY()); + rect->addAttribute("x", actions.bbox().minX()); + rect->addAttribute("y", actions.bbox().minY()); rect->addAttribute("width", w); rect->addAttribute("height", h+d); rect->addAttribute("fill", "none"); rect->addAttribute("stroke", "red"); rect->addAttribute("stroke-width", "0.5"); - _actions->appendToPage(rect); + actions.appendToPage(rect); if (d > 0) { XMLElementNode *line = new XMLElementNode("line"); - line->addAttribute("x1", _actions->bbox().minX()); - line->addAttribute("y1", _actions->bbox().minY()+h); - line->addAttribute("x2", _actions->bbox().maxX()); - line->addAttribute("y2", _actions->bbox().minY()+h); + line->addAttribute("x1", actions.bbox().minX()); + line->addAttribute("y1", actions.bbox().minY()+h); + line->addAttribute("x2", actions.bbox().maxX()); + line->addAttribute("y2", actions.bbox().minY()+h); line->addAttribute("stroke", "blue"); line->addAttribute("stroke-width", "0.5"); - _actions->appendToPage(line); + actions.appendToPage(line); } #endif } @@ -726,7 +726,7 @@ void PsSpecialHandler::setpattern (vector<double> &p) { else { if (PSUncoloredTilingPattern *pattern = dynamic_cast<PSUncoloredTilingPattern*>(it->second)) pattern->setColor(color); - it->second->apply(_actions); + it->second->apply(*_actions); if (PSTilingPattern *pattern = dynamic_cast<PSTilingPattern*>(it->second)) _pattern = pattern; else @@ -917,20 +917,20 @@ static void read_patch_data (ShadingPatch &patch, int edgeflag, class ShadingCallback : public ShadingPatch::Callback { public: - ShadingCallback (SpecialActions *actions, XMLElementNode *parent, int clippathID) + ShadingCallback (SpecialActions &actions, XMLElementNode *parent, int clippathID) : _actions(actions), _group(new XMLElementNode("g")) { if (parent) parent->append(_group); else - actions->appendToPage(_group); + actions.appendToPage(_group); if (clippathID > 0) _group->addAttribute("clip-path", XMLString("url(#clip")+XMLString(clippathID)+")"); } void patchSegment (GraphicsPath<double> &path, const Color &color) { - if (!_actions->getMatrix().isIdentity()) - path.transform(_actions->getMatrix()); + if (!_actions.getMatrix().isIdentity()) + path.transform(_actions.getMatrix()); // draw a single patch segment ostringstream oss; @@ -942,7 +942,7 @@ class ShadingCallback : public ShadingPatch::Callback { } private: - SpecialActions *_actions; + SpecialActions &_actions; XMLElementNode *_group; }; @@ -961,7 +961,7 @@ void PsSpecialHandler::processSequentialPatchMesh (int shadingTypeID, ColorSpace read_patch_data(*patch, edgeflag, it, points, colors); patch->setPoints(points, edgeflag, previousPatch.get()); patch->setColors(colors, edgeflag, previousPatch.get()); - ShadingCallback callback(_actions, _xmlnode, _clipStack.topID()); + ShadingCallback callback(*_actions, _xmlnode, _clipStack.topID()); #if 0 if (bgcolorGiven) { // fill whole patch area with given background color @@ -1007,7 +1007,7 @@ void PsSpecialHandler::processLatticeTriangularPatchMesh (ColorSpace colorSpace, vertex.color.set(colorSpace, it); } LatticeTriangularPatch patch(colorSpace); - ShadingCallback callback(_actions, _xmlnode, _clipStack.topID()); + ShadingCallback callback(*_actions, _xmlnode, _clipStack.topID()); while (it.valid()) { // read next row for (int i=0; i < verticesPerRow; i++) { @@ -1237,6 +1237,16 @@ void PsSpecialHandler::ClippingStack::dup (int saveID) { const char** PsSpecialHandler::prefixes () const { - static const char *pfx[] = {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\"", "pst:", "PST:", 0}; + static const char *pfx[] = { + "header=", // read and execute PS header file prior to the following PS statements + "psfile=", // read and execute PS file + "PSfile=", // dito + "ps:", // execute literal PS code wrapped by @beginspecial and @endspecial + "ps::", // execute literal PS code without additional adaption of the drawing position + "!", // execute literal PS header code following this prefix + "\"", // execute literal PS code following this prefix + "pst:", // dito + "PST:", // same as "ps:" + 0}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h index 0c3c2bd5e98..7c2f79009be 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h @@ -76,8 +76,8 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote const char* name () const {return "ps";} const char* info () const {return "dvips PostScript specials";} const char** prefixes () const; - void preprocess (const char *prefix, std::istream &is, SpecialActions *actions); - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + void preprocess (const char *prefix, std::istream &is, SpecialActions &actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); void setDviScaleFactor (double dvi2bp) {_previewFilter.setDviScaleFactor(dvi2bp);} void enterBodySection (); @@ -94,7 +94,7 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote void executeAndSync (std::istream &is, bool updatePos); void processHeaderFile (const char *fname); void psfile (const std::string &fname, const std::map<std::string,std::string> &attr); - void dviEndPage (unsigned pageno); + void dviEndPage (unsigned pageno, SpecialActions &actions); void clip (Path &path, bool evenodd); void processSequentialPatchMesh (int shadingTypeID, ColorSpace cspace, VectorIterator<double> &it); void processLatticeTriangularPatchMesh (ColorSpace colorSpace, VectorIterator<double> &it); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp new file mode 100644 index 00000000000..98fd59f1523 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp @@ -0,0 +1,86 @@ +/************************************************************************* +** SVGCharHandler.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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 "SVGCharHandler.h" +#include "XMLNode.h" + +using namespace std; + + +void SVGCharHandler::setInitialContextNode (XMLElementNode *node) { + resetContextNode(); + _initialContextNode = node; +} + + +/** Changes the context element. All following nodes will be appended to this node. */ +void SVGCharHandler::pushContextNode (XMLElementNode *node) { + if (node && (_contextNodeStack.empty() || node != _contextNodeStack.top())) { + contextNode()->append(node); + _contextNodeStack.push(node); + } +} + + +void SVGCharHandler::popContextNode () { + if (!_contextNodeStack.empty()) + _contextNodeStack.pop(); +} + + +/** Resets the context node to the initial element node. */ +void SVGCharHandler::resetContextNode () { + while (!_contextNodeStack.empty()) + _contextNodeStack.pop(); +} + + +/** Creates and returns a new SVG text element. + * @param[in] x current x coordinate + * @param[in] y current y coordinate */ +XMLElementNode* SVGCharTextHandler::createTextNode (double x, double y) const { + const Font *font = _font.get(); + if (!font) + return 0; + XMLElementNode *textNode = new XMLElementNode("text"); + if (_selectFontByClass) + textNode->addAttribute("class", string("f")+XMLString(_fontnum)); + else { + + textNode->addAttribute("font-family", font->name()); + textNode->addAttribute("font-size", XMLString(font->scaledSize())); + if (font->color() != Color::BLACK) + textNode->addAttribute("fill", font->color().svgColorString()); + } + if (_vertical) { + textNode->addAttribute("writing-mode", "tb"); + // align glyphs designed for horizontal layout properly + if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(font)) + if (!pf->getMetrics()->verticalLayout()) { // alphabetic text designed for horizontal layout? + x += pf->scaledAscent()/2.5; // move vertical baseline to the right by strikethrough offset + textNode->addAttribute("glyph-orientation-vertical", 90); // ensure rotation + } + } + textNode->addAttribute("x", x); + textNode->addAttribute("y", y); + if (!_matrix.get().isIdentity()) + textNode->addAttribute("transform", _matrix.get().getSVG()); + return textNode; +}
\ No newline at end of file diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h new file mode 100644 index 00000000000..9b222f7c10d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h @@ -0,0 +1,108 @@ +/************************************************************************* +** SVGCharHandler.h ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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/>. ** +*************************************************************************/ + +#ifndef SVGCHARHANDLER_H +#define SVGCHARHANDLER_H + +#include <stack> +#include "Color.h" +#include "Font.h" +#include "Matrix.h" +#include "types.h" + + +template <typename T> +class CharProperty { + public: + CharProperty (const T &v) : _value(v), _changed(false) {} + + void set (const T &v) { + if (v != _value) { + _value = v; + _changed = true; + } + } + + const T& get () const {return _value;} + operator const T& () const {return _value;} + bool changed () const {return _changed;} + void changed (bool c) {_changed = c;} + + private: + T _value; + bool _changed; +}; + + +class XMLElementNode; + + +/** Base class for all character handlers. These handlers create SVG representations + * for the added characters and append them to the SVG tree. */ +class SVGCharHandler { + public: + SVGCharHandler () : _color(Color::BLACK), _font(0), _fontnum(0), _matrix(1), _vertical(false), _initialContextNode(0) {} + virtual ~SVGCharHandler() {} + virtual void setInitialContextNode (XMLElementNode *node); + virtual void appendChar (UInt32 c, double x, double y) =0; + virtual void notifyXAdjusted () {} + virtual void notifyYAdjusted () {} + void setColor (const Color &color) {_color.set(color);} + void setFont (const Font &font, int id) {_font.set(&font); _fontnum = id;} + void setMatrix (const Matrix &matrix) {_matrix.set(matrix);} + void setVertical (bool vertical) {_vertical.set(vertical);} + Color getColor () const {return _color.get();} + const Font* getFont () const {return _font.get();} + const Matrix& getMatrix () const {return _matrix.get();} + + protected: + virtual void resetContextNode (); + void pushContextNode (XMLElementNode *node); + void popContextNode (); + + XMLElementNode* contextNode () const { + return _contextNodeStack.empty() ? _initialContextNode : _contextNodeStack.top(); + } + + CharProperty<Color> _color; ///< current color + CharProperty<const Font*> _font; ///< current font + int _fontnum; ///< current font ID + CharProperty<Matrix> _matrix; ///< current transformation + CharProperty<bool> _vertical; ///< current writing mode + + private: + XMLElementNode *_initialContextNode; ///< SVG element the generated character nodes are attached to + std::stack<XMLElementNode*> _contextNodeStack; +}; + + +/** Base class for all character handlers that create SVG <text> elements. */ +class SVGCharTextHandler : public SVGCharHandler { + public: + SVGCharTextHandler (bool selectFontByClass) : _selectFontByClass(selectFontByClass) {} + + protected: + XMLElementNode* createTextNode (double x, double y) const; + + private: + bool _selectFontByClass; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp new file mode 100644 index 00000000000..2f7b8b219e6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp @@ -0,0 +1,36 @@ +/************************************************************************* +** SVGCharHandlerFactory.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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 "SVGCharHandlerFactory.h" +#include "SVGCharPathHandler.h" +#include "SVGSingleCharTextHandler.h" +#include "SVGCharTspanTextHandler.h" +#include "SVGTree.h" + + +SVGCharHandler* SVGCharHandlerFactory::createHandler () { + if (!SVGTree::USE_FONTS) + return new SVGCharPathHandler(SVGTree::CREATE_USE_ELEMENTS, SVGTree::RELATIVE_PATH_CMDS); + if (SVGTree::MERGE_CHARS) + return new SVGCharTspanTextHandler(SVGTree::CREATE_CSS); + else + return new SVGSingleCharTextHandler(SVGTree::CREATE_CSS); + return 0; +}
\ No newline at end of file diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h new file mode 100644 index 00000000000..9fc3199b185 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h @@ -0,0 +1,33 @@ +/************************************************************************* +** SVGCharHandlerFactory.h ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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/>. ** +*************************************************************************/ + +#ifndef SVGCHARHANDLERFACTORY_H +#define SVGCHARHANDLERFACTORY_H + +#include "SVGCharHandler.h" + + +struct SVGCharHandlerFactory +{ + static SVGCharHandler* createHandler (); +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp new file mode 100644 index 00000000000..5793cf389bc --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp @@ -0,0 +1,137 @@ +/************************************************************************* +** SVGCharPathHandler.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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 <sstream> +#include "Font.h" +#include "FontManager.h" +#include "SVGCharPathHandler.h" +#include "XMLNode.h" + +using namespace std; + +/** Constructs a new path builder. + * @param[in] createUseElements determines whether to create "use" elements to reference previous paths or not + * @param[in] relativePathCommands determines whether to create relative or absolute SVG path commands */ +SVGCharPathHandler::SVGCharPathHandler (bool createUseElements, bool relativePathCommands) + : _relativePathCommands(relativePathCommands), _groupNode(0), _fontColor(Color::BLACK) +{ + if (createUseElements) + _appendChar = &SVGCharPathHandler::appendUseElement; + else + _appendChar = &SVGCharPathHandler::appendPathElement; +} + + +void SVGCharPathHandler::resetContextNode () { + SVGCharHandler::resetContextNode(); + _groupNode = 0; +} + + +/** Appends the path representation of a single character to the context element. + * @param[in] c code of the character to be appended + * @param[in] x horizontal position of the character (in bp units) + * @param[in] y vertical position of the character (in bp units) */ +void SVGCharPathHandler::appendChar (UInt32 c, double x, double y) { + if (_font.changed()) { + _fontColor.set(_font.get()->color()); + if (_fontColor.changed() && _fontColor.get() != Color::BLACK) + _color.changed(true); // ensure application of text color when resetting the font color to black + _font.changed(false); + } + // Apply text color changes only if the color of the entire font is black. + // Glyphs of non-black fonts (e.g. defined in a XeTeX document) can't change their color. + CharProperty<Color> &color = (_fontColor.get() != Color::BLACK) ? _fontColor : _color; + bool applyColor = color.get() != Color::BLACK; + bool applyMatrix = !_matrix.get().isIdentity(); + if (!_groupNode) { + color.changed(applyColor); + _matrix.changed(applyMatrix); + } + if (color.changed() || _matrix.changed()) { + resetContextNode(); + if (applyColor || applyMatrix) { + _groupNode = new XMLElementNode("g"); + pushContextNode(_groupNode); + if (applyColor) + contextNode()->addAttribute("fill", color.get().svgColorString()); + if (applyMatrix) + contextNode()->addAttribute("transform", _matrix.get().getSVG()); + } + color.changed(false); + _matrix.changed(false); + } + const Font *font = _font.get(); + if (font->verticalLayout()) { + // move glyph graphics so that its origin is located at the top center position + GlyphMetrics metrics; + font->getGlyphMetrics(c, _vertical, metrics); + x -= metrics.wl; + if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(font)) { + // Center glyph between top and bottom border of the TFM box. + // This is just an approximation used until I find a way to compute + // the exact location in vertical mode. + GlyphMetrics exact_metrics; + pf->getExactGlyphBox(c, exact_metrics, false); + y += exact_metrics.h+(metrics.d-exact_metrics.h-exact_metrics.d)/2; + } + else + y += metrics.d; + } + Matrix rotation(1); + if (_vertical && !font->verticalLayout()) { + // alphabetic text designed for horizontal mode + // must be rotated by 90 degrees if in vertical mode + rotation.translate(-x, -y); + rotation.rotate(90); + rotation.translate(x, y); + } + (this->*_appendChar)(c, x, y, rotation); +} + + +void SVGCharPathHandler::appendUseElement (UInt32 c, double x, double y, const Matrix &matrix) { + ostringstream oss; + oss << "#g" << FontManager::instance().fontID(_font) << '-' << c; + XMLElementNode *useNode = new XMLElementNode("use"); + useNode->addAttribute("x", XMLString(x)); + useNode->addAttribute("y", XMLString(y)); + useNode->addAttribute("xlink:href", oss.str()); + if (!matrix.isIdentity()) + useNode->addAttribute("transform", matrix.getSVG()); + contextNode()->append(useNode); +} + + +void SVGCharPathHandler::appendPathElement (UInt32 c, double x, double y, const Matrix &matrix) { + Glyph glyph; + const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(_font.get()); + if (pf && pf->getGlyph(c, glyph)) { + double sx = pf->scaledSize()/pf->unitsPerEm(); + double sy = -sx; + ostringstream oss; + glyph.writeSVG(oss, _relativePathCommands, sx, sy, x, y); + XMLElementNode *glyphNode = new XMLElementNode("path"); + glyphNode->addAttribute("d", oss.str()); + if (!matrix.isIdentity()) + glyphNode->addAttribute("transform", matrix.getSVG()); + contextNode()->append(glyphNode); + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h new file mode 100644 index 00000000000..0acd9693a1f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h @@ -0,0 +1,46 @@ +/************************************************************************* +** SVGCharPathHandler.h ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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/>. ** +*************************************************************************/ + +#ifndef SVGCHARPATHHANDLER_H +#define SVGCHARPATHHANDLER_H + +#include "SVGCharHandler.h" + +/** Creates SVG path elements for all characters. */ +class SVGCharPathHandler : public SVGCharHandler { + typedef void (SVGCharPathHandler::*AppendMethod)(UInt32 c, double x, double y, const Matrix &matrix); + + public: + SVGCharPathHandler (bool createUseElements, bool relativePathsCommands); + void appendChar (UInt32 c, double x, double y); + + protected: + void appendUseElement (UInt32 c, double x, double y, const Matrix &matrix); + void appendPathElement (UInt32 c, double x, double y, const Matrix &matrix); + void resetContextNode (); + + private: + AppendMethod _appendChar; ///< method called to append a single character + bool _relativePathCommands; ///< if true, create relative rather than absolute SVG path commands + XMLElementNode *_groupNode; ///< current group node taking the path elements + CharProperty<Color> _fontColor; ///< color of current font +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp new file mode 100644 index 00000000000..0153bacd05d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp @@ -0,0 +1,88 @@ +/************************************************************************* +** SVGCharTspanTextHandler.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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 "SVGCharTspanTextHandler.h" +#include "XMLNode.h" + +using namespace std; + +SVGCharTspanTextHandler::SVGCharTspanTextHandler (bool selectFontByClass) + : SVGCharTextHandler(selectFontByClass) +{ + resetContextNode(); +} + + +void SVGCharTspanTextHandler::appendChar (UInt32 c, double x, double y) { + // changes of fonts and transformations require a new text element + if (!_textNode || _font.changed() || _matrix.changed() || _vertical.changed()) { + resetContextNode(); + _textNode = createTextNode(x, y); + pushContextNode(_textNode); + _color.changed(true); // force creating tspan with color attribute if current color differs from font color + } + if (_tspanNode && (_xchanged || _ychanged || _color.changed())) { + // if drawing position or color was explicitly changed, finish current tspan element + popContextNode(); + _tspanNode = 0; + } + // Apply text color changes only if the color of the entire font is black. + // Glyphs of non-black fonts (e.g. defined in a XeTeX document) can't change their color. + bool applyColor = _color.get() != Color::BLACK && _font.get()->color() == Color::BLACK; + if (_xchanged || _ychanged || (_color.changed() && applyColor)) { + _tspanNode = new XMLElementNode("tspan"); + pushContextNode(_tspanNode); + if (applyColor) + _tspanNode->addAttribute("fill", _color.get().svgColorString()); + _color.changed(false); + if (_xchanged) { + if (_vertical) { + // align glyphs designed for horizontal layout properly + if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(_font.get())) + if (!pf->getMetrics()->verticalLayout()) + x += pf->scaledAscent()/2.5; // move vertical baseline to the right by strikethrough offset + } + _tspanNode->addAttribute("x", x); + _xchanged = false; + } + if (_ychanged) { + _tspanNode->addAttribute("y", y); + _ychanged = false; + } + } + contextNode()->append(XMLString(_font.get()->unicode(c), false)); +} + + +void SVGCharTspanTextHandler::setInitialContextNode (XMLElementNode *node) { + SVGCharHandler::setInitialContextNode(node); + _textNode = _tspanNode = 0; + _xchanged = _ychanged = false; +} + + +void SVGCharTspanTextHandler::resetContextNode () { + SVGCharHandler::resetContextNode(); + _textNode = _tspanNode = 0; + _xchanged = _ychanged = false; + _font.changed(false); + _matrix.changed(false); + _vertical.changed(false); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h new file mode 100644 index 00000000000..19825036e02 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h @@ -0,0 +1,43 @@ +/************************************************************************* +** SVGCharTspanTextHandler.h ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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/>. ** +*************************************************************************/ + +#ifndef SVGCHARTSPANTEXTHANDLER_H +#define SVGCHARTSPANTEXTHANDLER_H + +#include "SVGCharHandler.h" + +class SVGCharTspanTextHandler : public SVGCharTextHandler { + public: + SVGCharTspanTextHandler (bool selectFontByClass); + void notifyXAdjusted () {_xchanged = true;} + void notifyYAdjusted() {_ychanged = true;} + void appendChar (UInt32 c, double x, double y); + void setInitialContextNode (XMLElementNode *node); + + protected: + void resetContextNode (); + + private: + bool _xchanged, _ychanged; + XMLElementNode *_textNode; + XMLElementNode *_tspanNode; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp new file mode 100644 index 00000000000..8d5a26ddb9b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp @@ -0,0 +1,37 @@ +/************************************************************************* +** SVGSingleCharTextHandler.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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 "SVGSingleCharTextHandler.h" +#include "XMLNode.h" + +using namespace std; + +void SVGSingleCharTextHandler::appendChar (UInt32 c, double x, double y) { + const Font *font = _font.get(); + XMLElementNode *textNode = createTextNode(x, y); + textNode->append(XMLString(font->unicode(c), false)); + // Apply color changes only if the color differs from black and if the font color itself is black. + // Glyphs from non-black fonts (e.g. defined in a XeTeX document) can't change their color. + if (_color.get() != Color::BLACK && font->color() == Color::BLACK) { + textNode->addAttribute("fill", _color.get().svgColorString()); + _color.changed(false); + } + contextNode()->append(textNode); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h new file mode 100644 index 00000000000..0c4a26a4048 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h @@ -0,0 +1,35 @@ +/************************************************************************* +** SVGSingleCharTextHandler.h ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2016 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/>. ** +*************************************************************************/ + +#ifndef SVGSINGLECHARTEXTHANDLER_H +#define SVGSINGLECHARTEXTHANDLER_H + +#include "SVGCharHandler.h" + + +class SVGSingleCharTextHandler : public SVGCharTextHandler +{ + public: + SVGSingleCharTextHandler (bool createStyleElements) : SVGCharTextHandler(createStyleElements) {} + void appendChar (UInt32 c, double x, double y); +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp index 4d41b003ee7..2e4ac726ded 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp @@ -26,6 +26,7 @@ #include "DVIToSVG.h" #include "Font.h" #include "FontManager.h" +#include "SVGCharHandlerFactory.h" #include "SVGTree.h" #include "XMLDocument.h" #include "XMLNode.h" @@ -35,7 +36,7 @@ using namespace std; // static class variables -bool SVGTree::CREATE_STYLE=true; +bool SVGTree::CREATE_CSS=true; bool SVGTree::USE_FONTS=true; bool SVGTree::CREATE_USE_ELEMENTS=false; bool SVGTree::RELATIVE_PATH_CMDS=false; @@ -44,13 +45,17 @@ bool SVGTree::ADD_COMMENTS=false; double SVGTree::ZOOM_FACTOR=1.0; -SVGTree::SVGTree () : _vertical(false), _font(0), _color(Color::BLACK), _matrix(1) { - _xchanged = _ychanged = false; - _fontnum = 0; +SVGTree::SVGTree () { + _charHandler = SVGCharHandlerFactory::createHandler(); reset(); } +SVGTree::~SVGTree () { + delete _charHandler; +} + + /** Clears the SVG tree and initializes the root element. */ void SVGTree::reset () { _doc.clear(); @@ -59,7 +64,7 @@ void SVGTree::reset () { _root->addAttribute("xmlns", "http://www.w3.org/2000/svg"); _root->addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); _doc.setRootNode(_root); - _page = _text = _span = _defs = 0; + _page = _defs = 0; } @@ -75,17 +80,17 @@ void SVGTree::setBBox (const BoundingBox &bbox) { void SVGTree::setColor (const Color &c) { - if (!_font.get() || _font.get()->color() == Color::BLACK) - _color.set(c); + const Font *font = _charHandler->getFont(); + if (!font || font->color() == Color::BLACK) + _charHandler->setColor(c); } void SVGTree::setFont (int num, const Font &font) { - _font.set(&font); - _fontnum = num; + _charHandler->setFont(font, num); // set default color assigned to the font - if (font.color() != Color::BLACK && _color.get() != font.color()) - _color.set(font.color()); + if (font.color() != Color::BLACK && getColor() != font.color()) + setColor(font.color()); } @@ -96,9 +101,9 @@ void SVGTree::newPage (int pageno) { if (pageno >= 0) _page->addAttribute("id", string("page")+XMLString(pageno)); _root->append(_page); - _text = _span = 0; - while (!_pageContainerStack.empty()) - _pageContainerStack.pop(); + _charHandler->setInitialContextNode(_page); + while (!_contextElementStack.empty()) + _contextElementStack.pop(); } @@ -112,210 +117,23 @@ void SVGTree::appendToDefs (XMLNode *node) { void SVGTree::appendToPage (XMLNode *node) { - if (_pageContainerStack.empty()) - _page->append(node); - else - _pageContainerStack.top()->append(node); - if (node != _text) // if the appended node differs from the text element currently in use, - _text = 0; // then force creating a new text element for the following characters + XMLElementNode *parent = _contextElementStack.empty() ? _page : _contextElementStack.top(); + parent->append(node); + _charHandler->setInitialContextNode(parent); } void SVGTree::prependToPage (XMLNode *node) { - if (_pageContainerStack.empty()) + if (_contextElementStack.empty()) _page->prepend(node); else - _pageContainerStack.top()->prepend(node); + _contextElementStack.top()->prepend(node); } -/** Appends a single character or its path represenatation to the current context node. - * If necessary, and depending on the selected output mode and further output states, - * new XML elements (text, tspan, g, use, ...) are created. - * @param[in] c character to be added - * @param[in] x x coordinate - * @param[in] y y coordinate - * @param[in] font font to be used */ -void SVGTree::appendChar (int c, double x, double y, const Font &font) { - if (USE_FONTS) - appendCharAsText(c, x, y, font); - else - appendCharAsPath(c, x, y, font); -} - - -/** Appends a single text character to the current context node. - * @param[in] c character to be added - * @param[in] x x coordinate - * @param[in] y y coordinate - * @param[in] font font to be used */ -void SVGTree::appendCharAsText (int c, double x, double y, const Font &font) { - XMLElementNode *node=_span; - // changes of fonts and transformations require a new text element - if (!MERGE_CHARS || !_text || _font.changed() || _matrix.changed() || _vertical.changed()) { - newTextNode(x, y); - node = _text; - _color.changed(true); - } - if (MERGE_CHARS && (_xchanged || _ychanged || (_color.changed() && _color.get() != Color::BLACK))) { - // if drawing position was explicitly changed, create a new tspan element - _span = new XMLElementNode("tspan"); - if (_xchanged) { - if (_vertical) { - // align glyphs designed for horizontal layout properly - if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(_font.get())) - if (!pf->getMetrics()->verticalLayout()) - x += pf->scaledAscent()/2.5; // move vertical baseline to the right by strikethrough offset - } - _span->addAttribute("x", x); - _xchanged = false; - } - if (_ychanged) { - _span->addAttribute("y", y); - _ychanged = false; - } - if (_color.get() != font.color()) { - _span->addAttribute("fill", _color.get().svgColorString()); - _color.changed(false); - } - _text->append(_span); - node = _span; - } - if (!node) { - if (!_text) - newTextNode(x, y); - node = _text; - } - node->append(XMLString(font.unicode(c), false)); - if (!MERGE_CHARS && _color.get() != font.color()) { - node->addAttribute("fill", _color.get().svgColorString()); - _color.changed(false); - } -} - - -/** Appends a reference to the path representation of a single character to - * the current context node. - * @param[in] c character to be added - * @param[in] x x coordinate - * @param[in] y y coordinate - * @param[in] font font to be used */ -void SVGTree::appendCharAsPath (int c, double x, double y, const Font &font) { - XMLElementNode *node=_span; - if (_color.changed() || _matrix.changed()) { - bool set_color = (_color.changed() && _color.get() != Color::BLACK); - bool set_matrix = (_matrix.changed() && !_matrix.get().isIdentity()); - if (set_color || set_matrix) { - _span = new XMLElementNode("g"); - if (_color.get() != Color::BLACK) - _span->addAttribute("fill", _color.get().svgColorString()); - if (!_matrix.get().isIdentity()) - _span->addAttribute("transform", _matrix.get().getSVG()); - appendToPage(_span); - node = _span; - _color.changed(false); - _matrix.changed(false); - } - else if (_color.get() == Color::BLACK && _matrix.get().isIdentity()) - node = _span = 0; - } - if (!node) - node = _pageContainerStack.empty() ? _page : _pageContainerStack.top(); - if (font.verticalLayout()) { - // move glyph graphics so that its origin is located at the top center position - GlyphMetrics metrics; - font.getGlyphMetrics(c, _vertical, metrics); - x -= metrics.wl; - if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(&font)) { - // Center glyph between top and bottom border of the TFM box. - // This is just an approximation used until I find a way to compute - // the exact location in vertical mode. - GlyphMetrics exact_metrics; - pf->getExactGlyphBox(c, exact_metrics, false); - y += exact_metrics.h+(metrics.d-exact_metrics.h-exact_metrics.d)/2; - } - else - y += metrics.d; - } - Matrix rotation(1); - if (_vertical && !font.verticalLayout()) { - // alphabetic text designed for horizontal mode - // must be rotated by 90 degrees if in vertical mode - rotation.translate(-x, -y); - rotation.rotate(90); - rotation.translate(x, y); - } - if (CREATE_USE_ELEMENTS) { - ostringstream oss; - oss << "#g" << FontManager::instance().fontID(_font) << '-' << c; - XMLElementNode *use = new XMLElementNode("use"); - use->addAttribute("x", XMLString(x)); - use->addAttribute("y", XMLString(y)); - use->addAttribute("xlink:href", oss.str()); - if (!rotation.isIdentity()) - use->addAttribute("transform", rotation.getSVG()); - node->append(use); - } - else { - Glyph glyph; - const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(&font); - if (pf && pf->getGlyph(c, glyph)) { - double sx = pf->scaledSize()/pf->unitsPerEm(); - double sy = -sx; - ostringstream oss; - glyph.writeSVG(oss, RELATIVE_PATH_CMDS, sx, sy, x, y); - XMLElementNode *glyph_node = new XMLElementNode("path"); - glyph_node->addAttribute("d", oss.str()); - if (!rotation.isIdentity()) - glyph_node->addAttribute("transform", rotation.getSVG()); - node->append(glyph_node); - } - } -} - - -/** Creates a new text element. This is a helper function used by appendChar(). - * @param[in] x current x coordinate - * @param[in] y current y coordinate */ -void SVGTree::newTextNode (double x, double y) { - _text = new XMLElementNode("text"); - _span = 0; // no tspan in text element yet - if (USE_FONTS) { - const Font *font = _font.get(); - if (CREATE_STYLE || !font) - _text->addAttribute("class", string("f")+XMLString(_fontnum)); - else { - _text->addAttribute("font-family", font->name()); - _text->addAttribute("font-size", XMLString(font->scaledSize())); - if (font->color() != Color::BLACK) - _text->addAttribute("fill", font->color().svgColorString()); - } - if (_vertical) { - _text->addAttribute("writing-mode", "tb"); - // align glyphs designed for horizontal layout properly - if (const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(_font.get())) - if (!pf->getMetrics()->verticalLayout()) { // alphabetic text designed for horizontal layout? - x += pf->scaledAscent()/2.5; // move vertical baseline to the right by strikethrough offset - _text->addAttribute("glyph-orientation-vertical", 90); // ensure rotation - } - } - } - _text->addAttribute("x", x); - _text->addAttribute("y", y); - if (!_matrix.get().isIdentity()) - _text->addAttribute("transform", _matrix.get().getSVG()); - appendToPage(_text); - _vertical.changed(false); - _font.changed(false); - _matrix.changed(false); - _xchanged = false; - _ychanged = false; -} - - -void SVGTree::transformPage (const Matrix *usermatrix) { - if (usermatrix && !usermatrix->isIdentity()) - _page->addAttribute("transform", usermatrix->getSVG()); +void SVGTree::transformPage (const Matrix &usermatrix) { + if (!usermatrix.isIdentity()) + _page->addAttribute("transform", usermatrix.getSVG()); } @@ -375,7 +193,7 @@ static string font_info (const Font &font) { void SVGTree::appendFontStyles (const set<const Font*> &fonts) { - if (CREATE_STYLE && USE_FONTS && !fonts.empty() && _defs) { + if (CREATE_CSS && USE_FONTS && !fonts.empty() && _defs) { XMLElementNode *styleNode = new XMLElementNode("style"); styleNode->addAttribute("type", "text/css"); _root->insertAfter(styleNode, _defs); @@ -468,21 +286,20 @@ void SVGTree::append (const PhysicalFont &font, const set<int> &chars, GFGlyphTr /** Pushes a new context element that will take all following nodes added to the page. */ void SVGTree::pushContextElement (XMLElementNode *node) { - if (_pageContainerStack.empty()) + if (_contextElementStack.empty()) _page->append(node); else - _pageContainerStack.top()->append(node); - _pageContainerStack.push(node); - _text = _span = 0; // ensure the creation of a new text element for the following characters added + _contextElementStack.top()->append(node); + _contextElementStack.push(node); + _charHandler->setInitialContextNode(node); } /** Pops the current context element and restored the previous one. */ void SVGTree::popContextElement () { - if (!_pageContainerStack.empty()) { - _pageContainerStack.pop(); - _text = _span = 0; // ensure the creation of a new text element for the following characters added - } + if (!_contextElementStack.empty()) + _contextElementStack.pop(); + _charHandler->setInitialContextNode(_page); } @@ -525,4 +342,3 @@ void SVGTree::removeRedundantElements () { _defs->remove(node); } } - diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h index 5188616e768..278d386e254 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h @@ -27,41 +27,20 @@ #include "Color.h" #include "GFGlyphTracer.h" #include "Matrix.h" +#include "SVGCharHandler.h" #include "XMLDocument.h" #include "XMLNode.h" class BoundingBox; class Color; -struct Font; +class Font; class Matrix; class PhysicalFont; -class SVGTree -{ - template <typename T> - class Property { - public: - Property (const T &v) : _value(v), _changed(false) {} - - void set (const T &v) { - if (v != _value) { - _value = v; - _changed = true; - } - } - - const T& get () const {return _value;} - operator const T& () {return _value;} - bool changed () const {return _changed;} - void changed (bool c) {_changed = c;} - - private: - T _value; - bool _changed; - }; - +class SVGTree { public: SVGTree (); + ~SVGTree (); void reset (); void write (std::ostream &os) const {_doc.write(os);} void newPage (int pageno); @@ -70,7 +49,7 @@ class SVGTree void prependToPage (XMLNode *node); void appendToDoc (XMLNode *node) {_doc.append(node);} void appendToRoot (XMLNode *node) {_root->append(node);} - void appendChar (int c, double x, double y, const Font &font); + void appendChar (int c, double x, double y) {_charHandler->appendChar(c, x, y);} void appendFontStyles (const std::set<const Font*> &fonts); void append (const PhysicalFont &font, const std::set<int> &chars, GFGlyphTracer::Callback *cb=0); void pushContextElement (XMLElementNode *node); @@ -78,40 +57,30 @@ class SVGTree void removeRedundantElements (); void setBBox (const BoundingBox &bbox); void setFont (int id, const Font &font); - void setX (double x) {_xchanged = true;} - void setY (double y) {_ychanged = true;} - void setMatrix (const Matrix &m) {_matrix.set(m);} + void setX (double x) {_charHandler->notifyXAdjusted();} + void setY (double y) {_charHandler->notifyYAdjusted();} + void setMatrix (const Matrix &m) {_charHandler->setMatrix(m);} void setColor (const Color &c); - void setVertical (bool state) {_vertical.set(state);} - void transformPage (const Matrix *m); - const Color& getColor () const {return _color.get();} - const Matrix& getMatrix () const {return _matrix.get();} + void setVertical (bool state) {_charHandler->setVertical(state);} + void transformPage (const Matrix &m); + Color getColor () const {return _charHandler->getColor();} + const Matrix& getMatrix () const {return _charHandler->getMatrix();} XMLElementNode* rootNode () const {return _root;} public: static bool USE_FONTS; ///< if true, create font references and don't draw paths directly - static bool CREATE_STYLE; ///< use style elements and class attributes to reference fonts? + static bool CREATE_CSS; ///< define and use CSS classes to reference fonts? static bool CREATE_USE_ELEMENTS; ///< allow generation of <use/> elements? static bool RELATIVE_PATH_CMDS; ///< relative path commands rather than absolute ones? static bool MERGE_CHARS; ///< whether to merge chars with common properties into the same <text> tag static bool ADD_COMMENTS; ///< add comments with additional information static double ZOOM_FACTOR; ///< factor applied to width/height attribute - protected: - void newTextNode (double x, double y); - void appendCharAsText (int c, double x, double y, const Font &font); - void appendCharAsPath (int c, double x, double y, const Font &font); - private: XMLDocument _doc; - XMLElementNode *_root, *_page, *_text, *_span, *_defs; - bool _xchanged, _ychanged; - Property<bool> _vertical; ///< true if in vertical writing mode - Property<const Font*> _font; - Property<Color> _color; - Property<Matrix> _matrix; - int _fontnum; - std::stack<XMLElementNode*> _pageContainerStack; + XMLElementNode *_root, *_page, *_defs; + SVGCharHandler *_charHandler; + std::stack<XMLElementNode*> _contextElementStack; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h index ded506efd91..23548a2370f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h @@ -26,40 +26,40 @@ #include "Color.h" #include "Matrix.h" - -struct XMLNode; +class XMLNode; class XMLElementNode; -struct SpecialActions +class SpecialActions { - virtual ~SpecialActions () {} - virtual double getX () const =0; - virtual double getY () const =0; - virtual void setX (double x) =0; - virtual void setY (double y) =0; - virtual void finishLine () =0; - virtual void setColor (const Color &color) =0; - virtual Color getColor () const =0; - virtual void setMatrix (const Matrix &m) =0; - virtual const Matrix& getMatrix () const =0; - virtual void getPageTransform (Matrix &matrix) const =0; - virtual void setBgColor (const Color &color) =0; - virtual void appendToPage (XMLNode *node) =0; - virtual void appendToDefs (XMLNode *node) =0; - virtual void prependToPage (XMLNode *node) =0; - virtual void pushContextElement (XMLElementNode *node) =0; - virtual void popContextElement () =0; - virtual BoundingBox& bbox () =0; - virtual BoundingBox& bbox (const std::string &name, bool reset=false) =0; - virtual void embed (const BoundingBox &bbox) =0; - virtual void embed (const DPair &p, double r=0) =0; - virtual unsigned getCurrentPageNumber () const =0; - virtual std::string getSVGFilename (unsigned pageno) const =0; - virtual std::string getBBoxFormatString () const =0; - virtual void progress (const char *id) {} - virtual int getDVIStackDepth () const {return 0;} + public: + virtual ~SpecialActions () {} + virtual double getX () const =0; + virtual double getY () const =0; + virtual void setX (double x) =0; + virtual void setY (double y) =0; + virtual void finishLine () =0; + virtual void setColor (const Color &color) =0; + virtual Color getColor () const =0; + virtual void setMatrix (const Matrix &m) =0; + virtual const Matrix& getMatrix () const =0; + virtual void getPageTransform (Matrix &matrix) const =0; + virtual void setBgColor (const Color &color) =0; + virtual void appendToPage (XMLNode *node) =0; + virtual void appendToDefs (XMLNode *node) =0; + virtual void prependToPage (XMLNode *node) =0; + virtual void pushContextElement (XMLElementNode *node) =0; + virtual void popContextElement () =0; + virtual BoundingBox& bbox () =0; + virtual BoundingBox& bbox (const std::string &name, bool reset=false) =0; + virtual void embed (const BoundingBox &bbox) =0; + virtual void embed (const DPair &p, double r=0) =0; + virtual unsigned getCurrentPageNumber () const =0; + virtual std::string getSVGFilename (unsigned pageno) const =0; + virtual std::string getBBoxFormatString () const =0; + virtual void progress (const char *id) {} + virtual int getDVIStackDepth () const {return 0;} - static double PROGRESSBAR_DELAY; ///< progress bar doesn't appear before this time has elapsed (in sec) + static double PROGRESSBAR_DELAY; ///< progress bar doesn't appear before this time has elapsed (in sec) }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h index 94d39835e5a..a55a865a117 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h @@ -26,8 +26,8 @@ #include "MessageException.h" -struct SpecialActions; -class SpecialManager; +class SpecialActions; +class SpecialManager; struct SpecialException : public MessageException @@ -46,35 +46,35 @@ struct DVIPreprocessingListener struct DVIBeginPageListener { virtual ~DVIBeginPageListener () {} - virtual void dviBeginPage (unsigned pageno) =0; + virtual void dviBeginPage (unsigned pageno, SpecialActions &actions) =0; }; struct DVIEndPageListener { virtual ~DVIEndPageListener () {} - virtual void dviEndPage (unsigned pageno) =0; + virtual void dviEndPage (unsigned pageno, SpecialActions &actions) =0; }; struct DVIPositionListener { virtual ~DVIPositionListener () {} - virtual void dviMovedTo (double x, double y) =0; + virtual void dviMovedTo (double x, double y, SpecialActions &actions) =0; }; -struct SpecialHandler +class SpecialHandler { friend class SpecialManager; - - virtual ~SpecialHandler () {} - virtual const char** prefixes () const=0; - virtual const char* info () const=0; - virtual const char* name () const=0; - virtual void setDviScaleFactor (double dvi2bp) {} - virtual void preprocess (const char *prefix, std::istream &is, SpecialActions *actions) {} - virtual bool process (const char *prefix, std::istream &is, SpecialActions *actions)=0; + public: + virtual ~SpecialHandler () {} + virtual const char** prefixes () const=0; + virtual const char* info () const=0; + virtual const char* name () const=0; + virtual void setDviScaleFactor (double dvi2bp) {} + virtual void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) {} + virtual bool process (const char *prefix, std::istream &is, SpecialActions &actions)=0; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp index 76e300773af..db4bd42b3d0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp @@ -122,7 +122,7 @@ static string extract_prefix (istream &is) { } -void SpecialManager::preprocess (const string &special, SpecialActions *actions) const { +void SpecialManager::preprocess (const string &special, SpecialActions &actions) const { istringstream iss(special); string prefix = extract_prefix(iss); if (SpecialHandler *handler = findHandler(prefix)) @@ -136,7 +136,7 @@ void SpecialManager::preprocess (const string &special, SpecialActions *actions) * @param[in] actions actions the special handlers can perform * @return true if the special could be processed successfully * @throw SpecialException in case of errors during special processing */ -bool SpecialManager::process (const string &special, double dvi2bp, SpecialActions *actions) const { +bool SpecialManager::process (const string &special, double dvi2bp, SpecialActions &actions) const { istringstream iss(special); string prefix = extract_prefix(iss); bool success=false; @@ -154,21 +154,21 @@ void SpecialManager::notifyPreprocessingFinished () const { } -void SpecialManager::notifyBeginPage (unsigned pageno) const { +void SpecialManager::notifyBeginPage (unsigned pageno, SpecialActions &actions) const { FORALL(_beginPageListeners, vector<DVIBeginPageListener*>::const_iterator, it) - (*it)->dviBeginPage(pageno); + (*it)->dviBeginPage(pageno, actions); } -void SpecialManager::notifyEndPage (unsigned pageno) const { +void SpecialManager::notifyEndPage (unsigned pageno, SpecialActions &actions) const { FORALL(_endPageListeners, vector<DVIEndPageListener*>::const_iterator, it) - (*it)->dviEndPage(pageno); + (*it)->dviEndPage(pageno, actions); } -void SpecialManager::notifyPositionChange (double x, double y) const { +void SpecialManager::notifyPositionChange (double x, double y, SpecialActions &actions) const { FORALL(_positionListeners, vector<DVIPositionListener*>::const_iterator, it) - (*it)->dviMovedTo(x, y); + (*it)->dviMovedTo(x, y, actions); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h index c8f5d6ad446..a06ea5899e3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h @@ -27,7 +27,7 @@ #include <vector> #include "SpecialHandler.h" -struct SpecialActions; +class SpecialActions; class SpecialManager { @@ -43,12 +43,12 @@ class SpecialManager void registerHandler (SpecialHandler *handler); void registerHandlers (SpecialHandler **handlers, const char *ignorelist); void unregisterHandlers (); - void preprocess (const std::string &special, SpecialActions *actions) const; - bool process (const std::string &special, double dvi2bp, SpecialActions *actions) const; + void preprocess (const std::string &special, SpecialActions &actions) const; + bool process (const std::string &special, double dvi2bp, SpecialActions &actions) const; void notifyPreprocessingFinished () const; - void notifyBeginPage (unsigned pageno) const; - void notifyEndPage (unsigned pageno) const; - void notifyPositionChange (double x, double y) const; + void notifyBeginPage (unsigned pageno, SpecialActions &actions) const; + void notifyEndPage (unsigned pageno, SpecialActions &actions) const; + void notifyPositionChange (double x, double y, SpecialActions &actions) const; void writeHandlerInfo (std::ostream &os) const; protected: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp index dbb8658069e..66042f70263 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp @@ -22,6 +22,7 @@ #include <fstream> #include <vector> #include "FileFinder.h" +#include "Length.h" #include "Message.h" #include "StreamReader.h" #include "TFM.h" @@ -30,70 +31,104 @@ using namespace std; /** Reads a sequence of n TFM words (4 Bytes each). - * @param[in] sr the TFM data is read from this object + * @param[in] reader the TFM data is read from this object * @param[out] v the read words * @param[in] n number of words to be read */ template <typename T> -static void read_words (StreamReader &sr, vector<T> &v, unsigned n) { +static void read_words (StreamReader &reader, vector<T> &v, unsigned n) { v.clear(); v.resize(n); for (unsigned i=0; i < n; i++) - v[i] = sr.readUnsigned(4); + v[i] = reader.readUnsigned(4); } -/** Converts a TFM fix point value to double (PS point units). */ -static double fix2double (FixWord fix) { - const double pt2bp = 72/72.27; - return double(fix)/(1 << 20)*pt2bp; +/** Converts a TFM fix point value to double. */ +static inline double fix2double (FixWord fix) { + return double(fix)/(1 << 20); } -TFM::TFM (istream &is) { +TFM::TFM (istream &is) : _checksum(0), _firstChar(0), _lastChar(0), _designSize(0) { + if (!is) + return; is.seekg(0); - StreamReader sr(is); - UInt16 lf = UInt16(sr.readUnsigned(2)); // length of entire file in 4 byte words - UInt16 lh = UInt16(sr.readUnsigned(2)); // length of header in 4 byte words - _firstChar= UInt16(sr.readUnsigned(2)); // smallest character code in font - _lastChar = UInt16(sr.readUnsigned(2)); // largest character code in font - UInt16 nw = UInt16(sr.readUnsigned(2)); // number of words in width table - UInt16 nh = UInt16(sr.readUnsigned(2)); // number of words in height table - UInt16 nd = UInt16(sr.readUnsigned(2)); // number of words in depth table - UInt16 ni = UInt16(sr.readUnsigned(2)); // number of words in italic corr. table - UInt16 nl = UInt16(sr.readUnsigned(2)); // number of words in lig/kern table - UInt16 nk = UInt16(sr.readUnsigned(2)); // number of words in kern table - UInt16 ne = UInt16(sr.readUnsigned(2)); // number of words in ext. char table - UInt16 np = UInt16(sr.readUnsigned(2)); // number of font parameter words + StreamReader reader(is); + UInt16 lf = UInt16(reader.readUnsigned(2)); // length of entire file in 4 byte words + UInt16 lh = UInt16(reader.readUnsigned(2)); // length of header in 4 byte words + _firstChar= UInt16(reader.readUnsigned(2)); // smallest character code in font + _lastChar = UInt16(reader.readUnsigned(2)); // largest character code in font + UInt16 nw = UInt16(reader.readUnsigned(2)); // number of words in width table + UInt16 nh = UInt16(reader.readUnsigned(2)); // number of words in height table + UInt16 nd = UInt16(reader.readUnsigned(2)); // number of words in depth table + UInt16 ni = UInt16(reader.readUnsigned(2)); // number of words in italic corr. table + UInt16 nl = UInt16(reader.readUnsigned(2)); // number of words in lig/kern table + UInt16 nk = UInt16(reader.readUnsigned(2)); // number of words in kern table + UInt16 ne = UInt16(reader.readUnsigned(2)); // number of words in ext. char table + UInt16 np = UInt16(reader.readUnsigned(2)); // number of font parameter words if (6+lh+(_lastChar-_firstChar+1)+nw+nh+nd+ni+nl+nk+ne+np != lf) throw FontMetricException("inconsistent length values"); if (_firstChar >= _lastChar || _lastChar > 255 || ne > 256) throw FontMetricException("character codes out of range"); - readHeader(sr); + readHeader(reader); is.seekg(24+lh*4); // move to char info table - readTables(sr, nw, nh, nd, ni); + readTables(reader, nw, nh, nd, ni); + is.seekg(4*(lf-np), ios::beg); // move to param section + readParameters(reader, np); } -void TFM::readHeader (StreamReader &sr) { - _checksum = sr.readUnsigned(4); - _designSize = sr.readUnsigned(4); +void TFM::readHeader (StreamReader &reader) { + _checksum = reader.readUnsigned(4); + _designSize = fix2double(reader.readUnsigned(4))*Length::pt2bp; } -void TFM::readTables (StreamReader &sr, int nw, int nh, int nd, int ni) { - read_words(sr, _charInfoTable, _lastChar-_firstChar+1); - read_words(sr, _widthTable, nw); - read_words(sr, _heightTable, nh); - read_words(sr, _depthTable, nd); - read_words(sr, _italicTable, ni); +void TFM::readTables (StreamReader &reader, int nw, int nh, int nd, int ni) { + read_words(reader, _charInfoTable, _lastChar-_firstChar+1); + read_words(reader, _widthTable, nw); + read_words(reader, _heightTable, nh); + read_words(reader, _depthTable, nd); + read_words(reader, _italicTable, ni); } -/** Returns the design size of this font in PS point units. */ -double TFM::getDesignSize () const { - return fix2double(_designSize); +/** Read the values from the param section of the TFM file. + * @param[in] reader read from this stream + * @param[in] np number of paramaters to read */ +void TFM::readParameters (StreamReader &reader, int np) { + _params.resize(7); + np = min(np, 7); + for (int i=0; i < np; i++) + _params[i] = reader.readUnsigned(4); + for (int i=np; i < 7; i++) + _params[i] = 0; +} + + +/** Returns the optimal space width between words (in PS point units). */ +double TFM::getSpace () const { + return _params.empty() ? 0 : fix2double(_params[1])*_designSize; +} + + +/** Returns the amount of glue stretching between words (in PS point units). */ +double TFM::getSpaceStretch () const { + return _params.empty() ? 0 : fix2double(_params[2])*_designSize; +} + + +/** Returns the amount of glue shrinking between words (in PS point units). */ +double TFM::getSpaceShrink () const { + return _params.empty() ? 0 : fix2double(_params[3])*_designSize; +} + + +/** Returns the size of one EM unit (in PS point units). */ +double TFM::getQuad () const { + return _params.empty() ? 0 : fix2double(_params[5])*_designSize; } @@ -121,7 +156,7 @@ double TFM::getCharWidth (int c) const { if (index < 0) return 0; index = (_charInfoTable[index] >> 24) & 0xFF; - return fix2double(_widthTable[index]) * fix2double(_designSize); + return fix2double(_widthTable[index]) * _designSize; } @@ -131,7 +166,7 @@ double TFM::getCharHeight (int c) const { if (index < 0) return 0; index = (_charInfoTable[index] >> 20) & 0x0F; - return fix2double(_heightTable[index]) * fix2double(_designSize); + return fix2double(_heightTable[index]) * _designSize; } @@ -141,7 +176,7 @@ double TFM::getCharDepth (int c) const { if (index < 0) return 0; index = (_charInfoTable[index] >> 16) & 0x0F; - return fix2double(_depthTable[index]) * fix2double(_designSize); + return fix2double(_depthTable[index]) * _designSize; } @@ -151,5 +186,5 @@ double TFM::getItalicCorr (int c) const { if (index < 0) return 0; index = (_charInfoTable[index] >> 10) & 0x3F; - return fix2double(_italicTable[index]) * fix2double(_designSize); + return fix2double(_italicTable[index]) * _designSize; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h index 11848e39b64..d4136f20d17 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h @@ -33,34 +33,39 @@ class StreamReader; class TFM : public FontMetrics { public: -// TFM (const char *fname); TFM (std::istream &is); - double getDesignSize () const; double getCharWidth (int c) const; double getCharHeight (int c) const; double getCharDepth (int c) const; double getItalicCorr (int c) const; - bool verticalLayout () const {return false;} - UInt32 getChecksum () const {return _checksum;} - UInt16 firstChar () const {return _firstChar;} - UInt16 lastChar () const {return _lastChar;} + double getDesignSize () const {return _designSize;} + double getSpace () const; + double getSpaceStretch () const; + double getSpaceShrink () const; + double getQuad () const; + bool verticalLayout () const {return false;} + UInt32 getChecksum () const {return _checksum;} + UInt16 firstChar () const {return _firstChar;} + UInt16 lastChar () const {return _lastChar;} protected: - TFM () : _checksum(0), _firstChar(0), _lastChar(0), _designSize(0) {} - void readHeader (StreamReader &sr); - void readTables (StreamReader &sr, int nw, int nh, int nd, int ni); + TFM () : _checksum(0), _firstChar(0), _lastChar(0), _designSize(0), _params(7) {} + void readHeader (StreamReader &reader); + void readTables (StreamReader &reader, int nw, int nh, int nd, int ni); + void readParameters (StreamReader &reader, int np); virtual int charIndex (int c) const; void setCharRange (int firstchar, int lastchar) {_firstChar=firstchar; _lastChar=lastchar;} private: UInt32 _checksum; UInt16 _firstChar, _lastChar; - FixWord _designSize; ///< design size of the font in TeX points (7227 pt = 254 cm) + double _designSize; ///< design size of the font in PS points (72bp = 1in) std::vector<UInt32> _charInfoTable; std::vector<FixWord> _widthTable; ///< character widths in design size units std::vector<FixWord> _heightTable; ///< character height in design size units std::vector<FixWord> _depthTable; ///< character depth in design size units std::vector<FixWord> _italicTable; ///< italic corrections in design size units + std::vector<FixWord> _params; ///< values of the TFM's param section }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h index 704e031780a..6b766dae0e7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h @@ -40,7 +40,7 @@ class TensorProductPatch : public ShadingPatch { friend class CoonsPatch; - public: + public: TensorProductPatch () : ShadingPatch(Color::RGB_SPACE) {} TensorProductPatch (Color::ColorSpace cspace) : ShadingPatch(cspace) {} TensorProductPatch (const PointVec &points, const ColorVec &colors, Color::ColorSpace cspace, int edgeflag, TensorProductPatch *patch); @@ -68,7 +68,7 @@ class TensorProductPatch : public ShadingPatch void setFirstMatrixColumn (const DPair source[4], bool reverse); void setFirstMatrixColumn (DPair source[4][4], int col, bool reverse); - private: + private: DPair _points[4][4]; ///< control point matrix defining the patch surface Color _colors[4]; ///< vertex colors cK (c0->p00, c1->p03, c2->p30, c3->p33) }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp index 81794346af9..c3527046585 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp @@ -29,7 +29,7 @@ #include <sys/ioctl.h> #endif -#ifdef __WIN32__ +#ifdef _WIN32 #include <windows.h> #endif @@ -50,7 +50,7 @@ const int Terminal::WHITE = RED|GREEN|BLUE; const int Terminal::DEFAULT = -1; const int Terminal::BLACK = 0; -#ifdef __WIN32__ +#ifdef _WIN32 int Terminal::_defaultColor; int Terminal::_cursorHeight; #endif @@ -62,7 +62,7 @@ int Terminal::_bgcolor = Terminal::DEFAULT; /** Initializes the terminal. This method should be called before any of the others. * @param[in,out] os terminal output stream (currently unused) */ void Terminal::init (ostream &os) { -#ifdef __WIN32__ +#ifdef _WIN32 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h != INVALID_HANDLE_VALUE) { CONSOLE_SCREEN_BUFFER_INFO buffer_info; @@ -93,7 +93,7 @@ int Terminal::columns () { if (ioctl(fileno(stderr), TIOCGWINSZ, &ws) < 0) return 0; return ws.ws_col; -#elif defined(__WIN32__) +#elif defined(_WIN32) CONSOLE_SCREEN_BUFFER_INFO info; if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &info)) return 0; @@ -112,7 +112,7 @@ int Terminal::rows () { if (ioctl(fileno(stderr), TIOCGWINSZ, &ws) < 0) return 0; return ws.ws_row; -#elif defined(__WIN32__) +#elif defined(_WIN32) CONSOLE_SCREEN_BUFFER_INFO info; if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &info)) return 0; @@ -129,7 +129,7 @@ int Terminal::rows () { void Terminal::fgcolor (int color, ostream &os) { _fgcolor = color; -#ifdef __WIN32__ +#ifdef _WIN32 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h != INVALID_HANDLE_VALUE) { CONSOLE_SCREEN_BUFFER_INFO info; @@ -165,7 +165,7 @@ void Terminal::fgcolor (int color, ostream &os) { * @param[in] os terminal output stream */ void Terminal::bgcolor (int color, ostream &os) { _bgcolor = color; -#ifdef __WIN32__ +#ifdef _WIN32 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h != INVALID_HANDLE_VALUE) { CONSOLE_SCREEN_BUFFER_INFO info; @@ -196,7 +196,7 @@ void Terminal::bgcolor (int color, ostream &os) { /** Disables or enables the console cursor * @param[in] visible if false, the cursor is disabled, and enabled otherwise */ void Terminal::cursor (bool visible) { -#ifdef __WIN32__ +#ifdef _WIN32 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h != INVALID_HANDLE_VALUE) { CONSOLE_CURSOR_INFO cursor_info; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h index a8710ad3a0d..1beeb6f1558 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h @@ -49,7 +49,7 @@ class Terminal static int _fgcolor; ///< current foreground color static int _bgcolor; ///< current background color -#ifdef __WIN32__ +#ifdef _WIN32 static int _defaultColor; static int _cursorHeight; ///< current height of the cursor in percent #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp index 4992209449f..60d877df45a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp @@ -40,7 +40,7 @@ TpicSpecialHandler::TpicSpecialHandler () { } -void TpicSpecialHandler::dviEndPage (unsigned pageno) { +void TpicSpecialHandler::dviEndPage (unsigned pageno, SpecialActions&) { reset(); } @@ -58,16 +58,16 @@ void TpicSpecialHandler::reset () { * @param[in] ddist dash/dot distance of line in PS point units * (0:solid line, >0:dashed line, <0:dotted line) * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ -void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, SpecialActions *actions) { - if (actions && !_points.empty()) { +void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, SpecialActions &actions) { + if (!_points.empty()) { XMLElementNode *elem=0; if (_points.size() == 1) { const DPair &p = _points.back(); elem = new XMLElementNode("circle"); - elem->addAttribute("cx", p.x()+actions->getX()); - elem->addAttribute("cy", p.y()+actions->getY()); + elem->addAttribute("cx", p.x()+actions.getX()); + elem->addAttribute("cy", p.y()+actions.getY()); elem->addAttribute("r", _penwidth/2.0); - actions->embed(p, _penwidth/2.0); + actions.embed(p, _penwidth/2.0); } else { if (_points.size() == 2 || (!fill && _points.front() != _points.back())) { @@ -80,7 +80,7 @@ void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, Specia _points.pop_back(); if (_fill < 0) _fill = 1; - Color color = actions->getColor(); + Color color = actions.getColor(); color *= _fill; elem = new XMLElementNode("polygon"); elem->addAttribute("fill", fill ? color.svgColorString() : "none"); @@ -89,10 +89,10 @@ void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, Specia FORALL(_points, vector<DPair>::iterator, it) { if (it != _points.begin()) oss << ' '; - double x = it->x()+actions->getX(); - double y = it->y()+actions->getY(); + double x = it->x()+actions.getX(); + double y = it->y()+actions.getY(); oss << XMLString(x) << ',' << XMLString(y); - actions->embed(DPair(x, y)); + actions.embed(DPair(x, y)); } elem->addAttribute("points", oss.str()); if (stroke) { // draw outline? @@ -104,7 +104,7 @@ void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, Specia elem->addAttribute("stroke-dasharray", XMLString(ddist)); else if (ddist < 0) elem->addAttribute("stroke-dasharray", XMLString(_penwidth) + ' ' + XMLString(-ddist)); - actions->appendToPage(elem); + actions.appendToPage(elem); } reset(); } @@ -118,36 +118,36 @@ void TpicSpecialHandler::drawLines (bool stroke, bool fill, double ddist, Specia * of the dashes and the gaps inbetween. * @param[in] ddist length of dashes and gaps * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ -void TpicSpecialHandler::drawSplines (double ddist, SpecialActions *actions) { - if (!actions || _points.empty()) +void TpicSpecialHandler::drawSplines (double ddist, SpecialActions &actions) { + if (_points.empty()) return; const size_t size = _points.size(); if (size < 3) drawLines(true, false, ddist, actions); else { - DPair p(actions->getX(), actions->getY()); + DPair p(actions.getX(), actions.getY()); GraphicsPath<double> path; path.moveto(p+_points[0]); DPair mid = p+_points[0]+(_points[1]-_points[0])/2.0; path.lineto(mid); - actions->embed(p+_points[0]); + actions.embed(p+_points[0]); for (size_t i=1; i < size-1; i++) { const DPair p0 = p+_points[i-1]; const DPair p1 = p+_points[i]; const DPair p2 = p+_points[i+1]; mid = p1+(p2-p1)/2.0; path.conicto(p1, mid); - actions->embed(mid); - actions->embed((p0+p1*6.0+p2)/8.0, _penwidth); + actions.embed(mid); + actions.embed((p0+p1*6.0+p2)/8.0, _penwidth); } if (_points[0] == _points[size-1]) // closed path? path.closepath(); else { path.lineto(p+_points[size-1]); - actions->embed(p+_points[size-1]); + actions.embed(p+_points[size-1]); } - Color color = actions->getColor(); + Color color = actions.getColor(); color *= _fill; XMLElementNode *pathElem = new XMLElementNode("path"); if (_fill >= 0) { @@ -161,13 +161,13 @@ void TpicSpecialHandler::drawSplines (double ddist, SpecialActions *actions) { ostringstream oss; path.writeSVG(oss, SVGTree::RELATIVE_PATH_CMDS); pathElem->addAttribute("d", oss.str()); - pathElem->addAttribute("stroke", actions->getColor().svgColorString()); + pathElem->addAttribute("stroke", actions.getColor().svgColorString()); pathElem->addAttribute("stroke-width", XMLString(_penwidth)); if (ddist > 0) pathElem->addAttribute("stroke-dasharray", XMLString(ddist)); else if (ddist < 0) pathElem->addAttribute("stroke-dasharray", XMLString(_penwidth) + ' ' + XMLString(-ddist)); - actions->appendToPage(pathElem); + actions.appendToPage(pathElem); } reset(); } @@ -181,70 +181,68 @@ void TpicSpecialHandler::drawSplines (double ddist, SpecialActions *actions) { * @param[in] angle1 starting angle (clockwise) relative to x-axis * @param[in] angle2 ending angle (clockwise) relative to x-axis * @param[in] actions object providing the actions that can be performed by the SpecialHandler */ -void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions *actions) { - if (actions) { - const double PI2 = 2*M_PI; - angle1 *= -1; - angle2 *= -1; - if (fabs(angle1) > PI2) { - int n = (int)(angle1/PI2); - angle1 = angle1 - n*PI2; - angle2 = angle2 - n*PI2; - } +void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions &actions) { + const double PI2 = 2*M_PI; + angle1 *= -1; + angle2 *= -1; + if (fabs(angle1) > PI2) { + int n = (int)(angle1/PI2); + angle1 = angle1 - n*PI2; + angle2 = angle2 - n*PI2; + } - double x = cx + actions->getX(); - double y = cy + actions->getY(); - XMLElementNode *elem=0; - if (fabs(angle1-angle2) >= PI2) { // closed ellipse? - elem = new XMLElementNode("ellipse"); - elem->addAttribute("cx", XMLString(x)); - elem->addAttribute("cy", XMLString(y)); - elem->addAttribute("rx", XMLString(rx)); - elem->addAttribute("ry", XMLString(ry)); - } - else { - if (angle1 < 0) - angle1 = PI2+angle1; - if (angle2 < 0) - angle2 = PI2+angle2; - elem = new XMLElementNode("path"); - int large_arg = fabs(angle1-angle2) > M_PI ? 0 : 1; - int sweep_flag = angle1 > angle2 ? 0 : 1; - if (angle1 > angle2) { - large_arg = 1-large_arg; - sweep_flag = 1-sweep_flag; - } - ostringstream oss; - oss << 'M' << XMLString(x+rx*cos(angle1)) << ',' << XMLString(y+ry*sin(-angle1)) - << 'A' << XMLString(rx) << ',' << XMLString(ry) - << " 0 " - << large_arg << ' ' << sweep_flag << ' ' - << XMLString(x+rx*cos(angle2)) << ',' << XMLString(y-ry*sin(angle2)); - if (_fill >= 0) - oss << 'Z'; - elem->addAttribute("d", oss.str()); - } - elem->addAttribute("stroke-width", _penwidth); - elem->addAttribute("stroke", actions->getColor().svgColorString()); - elem->addAttribute("stroke-linecap", "round"); - elem->addAttribute("fill", "none"); - if (_fill >= 0) { - Color color=actions->getColor(); - color *= _fill; - elem->addAttribute("fill", color.svgColorString()); + double x = cx + actions.getX(); + double y = cy + actions.getY(); + XMLElementNode *elem=0; + if (fabs(angle1-angle2) >= PI2) { // closed ellipse? + elem = new XMLElementNode("ellipse"); + elem->addAttribute("cx", XMLString(x)); + elem->addAttribute("cy", XMLString(y)); + elem->addAttribute("rx", XMLString(rx)); + elem->addAttribute("ry", XMLString(ry)); + } + else { + if (angle1 < 0) + angle1 = PI2+angle1; + if (angle2 < 0) + angle2 = PI2+angle2; + elem = new XMLElementNode("path"); + int large_arg = fabs(angle1-angle2) > M_PI ? 0 : 1; + int sweep_flag = angle1 > angle2 ? 0 : 1; + if (angle1 > angle2) { + large_arg = 1-large_arg; + sweep_flag = 1-sweep_flag; } - else - elem->addAttribute("fill", "none"); - actions->appendToPage(elem); - actions->embed(BoundingBox(cx-rx, cy-ry, cx+rx, cy+ry)); + ostringstream oss; + oss << 'M' << XMLString(x+rx*cos(angle1)) << ',' << XMLString(y+ry*sin(-angle1)) + << 'A' << XMLString(rx) << ',' << XMLString(ry) + << " 0 " + << large_arg << ' ' << sweep_flag << ' ' + << XMLString(x+rx*cos(angle2)) << ',' << XMLString(y-ry*sin(angle2)); + if (_fill >= 0) + oss << 'Z'; + elem->addAttribute("d", oss.str()); + } + elem->addAttribute("stroke-width", _penwidth); + elem->addAttribute("stroke", actions.getColor().svgColorString()); + elem->addAttribute("stroke-linecap", "round"); + elem->addAttribute("fill", "none"); + if (_fill >= 0) { + Color color=actions.getColor(); + color *= _fill; + elem->addAttribute("fill", color.svgColorString()); } + else + elem->addAttribute("fill", "none"); + actions.appendToPage(elem); + actions.embed(BoundingBox(cx-rx, cy-ry, cx+rx, cy+ry)); reset(); } #define cmd_id(c1,c2) ((c1 << 8) | c2) -bool TpicSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { +bool TpicSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { if (!prefix || strlen(prefix) != 2) return false; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h index 2b58418d9f6..a9896cfdb07 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h @@ -32,14 +32,14 @@ class TpicSpecialHandler : public SpecialHandler, public DVIEndPageListener const char* info () const {return "TPIC specials";} const char* name () const {return "tpic";} const char** prefixes () const; - bool process (const char *prefix, std::istream &is, SpecialActions *actions); + bool process (const char *prefix, std::istream &is, SpecialActions &actions); protected: - void dviEndPage (unsigned pageno); + void dviEndPage (unsigned pageno, SpecialActions &actions); void reset (); - void drawLines (bool stroke, bool fill, double ddist, SpecialActions *actions); - void drawSplines (double ddist, SpecialActions *actions); - void drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions *actions); + void drawLines (bool stroke, bool fill, double ddist, SpecialActions &actions); + void drawSplines (double ddist, SpecialActions &actions); + void drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions &actions); private: double _penwidth; ///< pen width in PS point units diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h index 281487a68c0..e63c5cdfd41 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h @@ -27,8 +27,8 @@ class TriangularPatch : public ShadingPatch { - public: - TriangularPatch (); + public: + TriangularPatch (); TriangularPatch (Color::ColorSpace cspace) : ShadingPatch(cspace) {} TriangularPatch (const PointVec &points, const ColorVec &colors, Color::ColorSpace cspace, int edgeflag, TriangularPatch *patch); int psShadingType() const {return 4;} @@ -48,7 +48,7 @@ class TriangularPatch : public ShadingPatch protected: Color averageColor (const Color &c1, const Color &c2, const Color &c3) const; - private: + private: DPair _points[3]; Color _colors[3]; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp index 286f0513a55..3998b7146a1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp @@ -21,6 +21,7 @@ #include <config.h> #include <sstream> #include "Font.h" +#include "Length.h" #include "VFActions.h" #include "VFReader.h" @@ -29,8 +30,7 @@ using namespace std; /** Converts a TFM fix point value to double (PS point units). */ static inline double fix2double (FixWord fix) { - const double pt2bp = 72/72.27; - return double(fix)/(1 << 20)*pt2bp; + return double(fix)/(1 << 20)*Length::pt2bp; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h index 03d9651e57e..a6bfeed562d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h @@ -24,13 +24,41 @@ #include <istream> #include <vector> - template <typename T> -struct VectorStreamBuffer : public std::streambuf +class VectorStreamBuffer : public std::streambuf { - VectorStreamBuffer (std::vector<T> &source) { - setg((char*)&source[0], (char*)&source[0], (char*)&source[0]+source.size()); - } + public: + VectorStreamBuffer (const std::vector<T> &v) : _begin(&v[0]), _end(&v[0]+v.size()), _curr(&v[0]) {} + + protected: + int_type underflow () {return _curr == _end ? traits_type::eof() : traits_type::to_int_type(*_curr);} + int_type uflow() {return _curr == _end ? traits_type::eof() : traits_type::to_int_type(*_curr++);} + std::streamsize showmanyc () {return _end-_curr;} + + int_type pbackfail (int_type c) { + if (_curr == _begin || (c != traits_type::eof() && c != _curr[-1])) + return traits_type::eof(); + return traits_type::to_int_type(*--_curr); + } + + pos_type seekoff (off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which=std::ios_base::in) { + switch (dir) { + case std::ios_base::cur: + _curr += off; break; + case std::ios_base::beg: + _curr = _begin+off; break; + case std::ios_base::end: + _curr = _end-off; break; + default: + break; + } + return _curr-_begin; + } + + private: + const T *_begin; + const T *_end; + const T *_curr; }; @@ -38,7 +66,8 @@ template <typename T> class VectorInputStream : public std::istream { public: - VectorInputStream (std::vector<T> &source) : std::istream(&_buf), _buf(source) {} + VectorInputStream (const std::vector<T> &source) : std::istream(&_buf), _buf(source) {} + private: VectorStreamBuffer<T> _buf; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp index f906a11f33d..6b43d717090 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp @@ -19,6 +19,7 @@ *************************************************************************/ #include <config.h> +#include "macros.h" #include "XMLDocument.h" using namespace std; @@ -65,8 +66,10 @@ void XMLDocument::setRootNode (XMLElementNode *root) { ostream& XMLDocument::write (ostream &os) const { if (_rootElement) { // no root element => no output os << "<?xml version='1.0' encoding='UTF-8'?>\n"; - FORALL(_nodes, list<XMLNode*>::const_iterator, i) + FORALL(_nodes, list<XMLNode*>::const_iterator, i) { (*i)->write(os); + os << '\n'; + } _rootElement->write(os); } return os; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp index c8beab36bb5..ed12f9e1814 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp @@ -180,17 +180,25 @@ XMLElementNode* XMLElementNode::getFirstDescendant (const char *name, const char ostream& XMLElementNode::write (ostream &os) const { os << '<' << _name; - FORALL(_attributes, AttribMap::const_iterator, i) - os << ' ' << i->first << "='" << i->second << '\''; + FORALL(_attributes, AttribMap::const_iterator, it) + os << ' ' << it->first << "='" << it->second << '\''; if (_children.empty()) - os << "/>\n"; + os << "/>"; else { os << '>'; - if (dynamic_cast<XMLElementNode*>(_children.front())) + // Insert newlines around children except text nodes. According to the + // SVG specification, pure whitespace nodes are ignored by the SVG renderer. + if (!dynamic_cast<XMLTextNode*>(_children.front())) os << '\n'; - FORALL(_children, ChildList::const_iterator, i) - (*i)->write(os); - os << "</" << _name << ">\n"; + FORALL(_children, ChildList::const_iterator, it) { + (*it)->write(os); + if (!dynamic_cast<XMLTextNode*>(*it)) { + ChildList::const_iterator next=it; + if (++next == _children.end() || !dynamic_cast<XMLTextNode*>(*next)) + os << '\n'; + } + } + os << "</" << _name << '>'; } return os; } @@ -255,7 +263,7 @@ void XMLTextNode::prepend (XMLNode *node) { ostream& XMLCDataNode::write (ostream &os) const { if (!_data.empty()) - os << "<![CDATA[\n" << _data << "]]>\n"; + os << "<![CDATA[\n" << _data << "]]>"; return os; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h index 0fec435e778..db45152dde9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h @@ -25,16 +25,16 @@ #include <map> #include <ostream> #include <string> +#include <vector> -#include "SpecialActions.h" - -struct XMLNode +class XMLNode { - virtual ~XMLNode () {} - virtual XMLNode* clone () const =0; - virtual void clear () =0; - virtual std::ostream& write (std::ostream &os) const =0; + public: + virtual ~XMLNode () {} + virtual XMLNode* clone () const =0; + virtual void clear () =0; + virtual std::ostream& write (std::ostream &os) const =0; }; @@ -96,7 +96,7 @@ class XMLCommentNode : public XMLNode XMLCommentNode (const std::string &str) : _text(str) {} XMLCommentNode* clone () const {return new XMLCommentNode(*this);} void clear () {_text.clear();} - std::ostream& write (std::ostream &os) const {return os << "<!--" << _text << "-->\n";} + std::ostream& write (std::ostream &os) const {return os << "<!--" << _text << "-->";} private: std::string _text; @@ -115,4 +115,10 @@ class XMLCDataNode : public XMLNode std::string _data; }; + +inline std::ostream& operator << (std::ostream &os, const XMLElementNode &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLTextNode &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLCommentNode &node) {return node.write(os);} +inline std::ostream& operator << (std::ostream &os, const XMLCDataNode &node) {return node.write(os);} + #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index a3bb950f07e..03d6463cf33 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -22,6 +22,7 @@ #include <clipper.hpp> #include <fstream> #include <iostream> +#include <potracelib.h> #include <sstream> #include <xxhash.h> #include "gzstream.h" @@ -35,6 +36,7 @@ #include "FontEngine.h" #include "Ghostscript.h" #include "HtmlSpecialHandler.h" +#include "Message.h" #include "PageSize.h" #include "PSInterpreter.h" #include "PsSpecialHandler.h" @@ -42,14 +44,6 @@ #include "SVGOutput.h" #include "System.h" -#ifdef __MSVC__ -#include <potracelib.h> -#else -extern "C" { -#include <potracelib.h> -} -#endif - using namespace std; @@ -120,7 +114,12 @@ static bool set_cache_dir (const CommandLine &args) { } 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); + try { + FontCache::fontinfo(PhysicalFont::CACHE_PATH, cout, true); + } + catch (StreamReaderException &e) { + Message::wstream(true) << "failed reading cache data"; + } return false; } return true; @@ -128,7 +127,7 @@ static bool set_cache_dir (const CommandLine &args) { static bool check_bbox (const string &bboxstr) { - const char *formats[] = {"none", "min", "preview", "dvi", 0}; + const char *formats[] = {"none", "min", "preview", "papersize", "dvi", 0}; for (const char **p=formats; *p; ++p) if (bboxstr == *p) return true; @@ -143,6 +142,7 @@ static bool check_bbox (const string &bboxstr) { } } try { + // check if given bbox argument is valid, i.e. doesn't throw an exception BoundingBox bbox; bbox.set(bboxstr); return true; @@ -249,11 +249,11 @@ int main (int argc, char *argv[]) { return 1; if (args.progress_given()) { - DVIReader::COMPUTE_PROGRESS = args.progress_given(); + DVIToSVG::COMPUTE_PROGRESS = args.progress_given(); SpecialActions::PROGRESSBAR_DELAY = args.progress_arg(); } Color::SUPPRESS_COLOR_NAMES = !args.colornames_given(); - SVGTree::CREATE_STYLE = !args.no_styles_given(); + SVGTree::CREATE_CSS = !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(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c b/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c index 35f53155a66..9238b159624 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c @@ -1,41 +1,42 @@ /* -xxHash - Fast Hash algorithm -Copyright (C) 2012-2016, Yann Collet - -BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You can contact the author at : -- xxHash source repository : https://github.com/Cyan4973/xxHash +* xxHash - Fast Hash algorithm +* Copyright (C) 2012-2016, Yann Collet +* +* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* You can contact the author at : +* - xxHash homepage: http://www.xxhash.com +* - xxHash source repository : https://github.com/Cyan4973/xxHash */ /* ************************************* * Tuning parameters ***************************************/ -/*!XXH_FORCE_MEMORY_ACCESS +/*!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. @@ -72,19 +73,42 @@ You can contact the author at : * to improve speed for Big-endian CPU. * This option has no impact on Little_Endian CPU. */ -#define XXH_FORCE_NATIVE_FORMAT 0 +#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ +# define XXH_FORCE_NATIVE_FORMAT 0 +#endif -/*!XXH_USELESS_ALIGN_BRANCH : +/*!XXH_FORCE_ALIGN_CHECK : * This is a minor performance trick, only useful with lots of very small keys. - * It means : don't check for aligned/unaligned input, because performance will be the same. - * It saves one initial branch per hash. + * It means : check for aligned/unaligned input. + * The check costs one initial branch per hash; set to 0 when the input data + * is guaranteed to be aligned. */ -#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_USELESS_ALIGN_BRANCH 1 +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif #endif /* ************************************* +* Includes & Memory related functions +***************************************/ +/* Modify the local functions below should you wish to use some other memory routines */ +/* for malloc(), free() */ +#include <stdlib.h> +static void* XXH_malloc(size_t s) { return malloc(s); } +static void XXH_free (void* p) { free(p); } +/* for memcpy() */ +#include <string.h> +static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + + +/* ************************************* * Compiler Specific Options ***************************************/ #ifdef _MSC_VER /* Visual Studio */ @@ -104,21 +128,6 @@ You can contact the author at : /* ************************************* -* Includes & Memory related functions -***************************************/ -/* Modify the local functions below should you wish to use some other memory routines */ -/* for malloc(), free() */ -#include <stdlib.h> -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/* for memcpy() */ -#include <string.h> -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } - -#include "xxhash.h" - - -/* ************************************* * Basic Types ***************************************/ #ifndef MEM_MODULE @@ -283,24 +292,47 @@ static U64 XXH_readBE64(const void* ptr) /* ************************************* * Constants ***************************************/ -#define PRIME32_1 2654435761U -#define PRIME32_2 2246822519U -#define PRIME32_3 3266489917U -#define PRIME32_4 668265263U -#define PRIME32_5 374761393U - -#define PRIME64_1 11400714785074694791ULL -#define PRIME64_2 14029467366897019727ULL -#define PRIME64_3 1609587929392839161ULL -#define PRIME64_4 9650029242287828579ULL -#define PRIME64_5 2870177450012600261ULL +static const U32 PRIME32_1 = 2654435761U; +static const U32 PRIME32_2 = 2246822519U; +static const U32 PRIME32_3 = 3266489917U; +static const U32 PRIME32_4 = 668265263U; +static const U32 PRIME32_5 = 374761393U; + +static const U64 PRIME64_1 = 11400714785074694791ULL; +static const U64 PRIME64_2 = 14029467366897019727ULL; +static const U64 PRIME64_3 = 1609587929392839161ULL; +static const U64 PRIME64_4 = 9650029242287828579ULL; +static const U64 PRIME64_5 = 2870177450012600261ULL; XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } +/* ************************** +* Utils +****************************/ +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + + /* *************************** * Simple Hash Functions *****************************/ + +static U32 XXH32_round(U32 seed, U32 input) +{ + seed += input * PRIME32_2; + seed = XXH_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)input; @@ -309,60 +341,40 @@ FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) #ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { + if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)16; } #endif - if (len>=16) - { + if (len>=16) { const BYTE* const limit = bEnd - 16; U32 v1 = seed + PRIME32_1 + PRIME32_2; U32 v2 = seed + PRIME32_2; U32 v3 = seed + 0; U32 v4 = seed - PRIME32_1; - do - { - v1 += XXH_get32bits(p) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_get32bits(p) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_get32bits(p) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_get32bits(p) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); + do { + v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; + v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; + v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; + v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; + } while (p<=limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } - else - { + } else { h32 = seed + PRIME32_5; } h32 += (U32) len; - while (p+4<=bEnd) - { + while (p+4<=bEnd) { h32 += XXH_get32bits(p) * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; p+=4; } - while (p<bEnd) - { + while (p<bEnd) { h32 += (*p) * PRIME32_5; h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; p++; @@ -389,15 +401,13 @@ XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int s #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; -# 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) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); @@ -406,103 +416,77 @@ XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int s #endif } + +static U64 XXH64_round(U64 acc, U64 input) +{ + acc += input * PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= PRIME64_1; + return acc; +} + +static U64 XXH64_mergeRound(U64 acc, U64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * PRIME64_1 + PRIME64_4; + return acc; +} + FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; + const BYTE* const bEnd = p + len; U64 h64; #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) #ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { + if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)32; } #endif - if (len>=32) - { + if (len>=32) { const BYTE* const limit = bEnd - 32; U64 v1 = seed + PRIME64_1 + PRIME64_2; U64 v2 = seed + PRIME64_2; U64 v3 = seed + 0; U64 v4 = seed - PRIME64_1; - do - { - v1 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - v2 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - v3 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - v4 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - } - while (p<=limit); + do { + v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; + v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; + v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; + v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; + } while (p<=limit); h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64 * PRIME64_1 + PRIME64_4; - } - else - { + } else { h64 = seed + PRIME64_5; } h64 += (U64) len; - while (p+8<=bEnd) - { - U64 k1 = XXH_get64bits(p); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_get64bits(p)); h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; p+=8; } - if (p+4<=bEnd) - { + if (p+4<=bEnd) { h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; p+=4; } - while (p<bEnd) - { + while (p<bEnd) { h64 ^= (*p) * PRIME64_5; h64 = XXH_rotl64(h64, 11) * PRIME64_1; p++; @@ -529,15 +513,13 @@ XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; -# 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) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); @@ -546,39 +528,13 @@ XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned #endif } + /* ************************************************** * Advanced Hash Functions ****************************************************/ -/*** Allocation ***/ -struct XXH32_state_s -{ - U64 total_len; - U32 seed; - U32 v1; - U32 v2; - U32 v3; - U32 v4; - U32 mem32[4]; /* defined as U32 for alignment */ - U32 memsize; -}; /* typedef'd to XXH32_state_t within xxhash.h */ - -struct XXH64_state_s -{ - U64 total_len; - U64 seed; - U64 v1; - U64 v2; - U64 v3; - U64 v4; - U64 mem64[4]; /* defined as U64 for alignment */ - U32 memsize; -}; /* typedef'd to XXH64_state_t within xxhash.h */ - - XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) { - XXH_STATIC_ASSERT(sizeof(XXH32_stateBody_t) >= sizeof(XXH32_state_t)); /* A compilation error here means XXH32_state_t is not large enough */ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) @@ -589,7 +545,6 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) { - XXH_STATIC_ASSERT(sizeof(XXH64_stateBody_t) >= sizeof(XXH64_state_t)); /* A compilation error here means XXH64_state_t is not large enough */ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) @@ -640,67 +595,37 @@ FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void state->total_len += len; - if (state->memsize + len < 16) /* fill in tmp buffer */ - { + if (state->memsize + len < 16) { /* fill in tmp buffer */ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); state->memsize += (U32)len; return XXH_OK; } - if (state->memsize) /* some data left from previous update */ - { + if (state->memsize) { /* some data left from previous update */ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { - const U32* p32 = state->mem32; - state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v1 = XXH_rotl32(state->v1, 13); - state->v1 *= PRIME32_1; - p32++; - state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v2 = XXH_rotl32(state->v2, 13); - state->v2 *= PRIME32_1; - p32++; - state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v3 = XXH_rotl32(state->v3, 13); - state->v3 *= PRIME32_1; - p32++; - state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v4 = XXH_rotl32(state->v4, 13); - state->v4 *= PRIME32_1; - p32++; + { const U32* p32 = state->mem32; + state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; + state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; + state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; + state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; } p += 16-state->memsize; state->memsize = 0; } - if (p <= bEnd-16) - { + if (p <= bEnd-16) { const BYTE* const limit = bEnd - 16; U32 v1 = state->v1; U32 v2 = state->v2; U32 v3 = state->v3; U32 v4 = state->v4; - do - { - v1 += XXH_readLE32(p, endian) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_readLE32(p, endian) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_readLE32(p, endian) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_readLE32(p, endian) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); + do { + v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; + v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; + v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; + v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; + } while (p<=limit); state->v1 = v1; state->v2 = v2; @@ -708,8 +633,7 @@ FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void state->v4 = v4; } - if (p < bEnd) - { + if (p < bEnd) { XXH_memcpy(state->mem32, p, bEnd-p); state->memsize = (int)(bEnd-p); } @@ -732,31 +656,26 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) { const BYTE * p = (const BYTE*)state->mem32; - const BYTE* bEnd = (const BYTE*)(state->mem32) + state->memsize; + const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; U32 h32; - if (state->total_len >= 16) - { + if (state->total_len >= 16) { h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } - else - { - h32 = state->seed + PRIME32_5; + } else { + h32 = state->seed + PRIME32_5; } h32 += (U32) state->total_len; - while (p+4<=bEnd) - { + while (p+4<=bEnd) { h32 += XXH_readLE32(p, endian) * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4; p+=4; } - while (p<bEnd) - { + while (p<bEnd) { h32 += (*p) * PRIME32_5; - h32 = XXH_rotl32(h32, 11) * PRIME32_1; + h32 = XXH_rotl32(h32, 11) * PRIME32_1; p++; } @@ -795,67 +714,35 @@ FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void state->total_len += len; - if (state->memsize + len < 32) /* fill in tmp buffer */ - { + if (state->memsize + len < 32) { /* fill in tmp buffer */ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); state->memsize += (U32)len; return XXH_OK; } - if (state->memsize) /* some data left from previous update */ - { + if (state->memsize) { /* tmp buffer is full */ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - { - const U64* p64 = state->mem64; - state->v1 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v1 = XXH_rotl64(state->v1, 31); - state->v1 *= PRIME64_1; - p64++; - state->v2 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v2 = XXH_rotl64(state->v2, 31); - state->v2 *= PRIME64_1; - p64++; - state->v3 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v3 = XXH_rotl64(state->v3, 31); - state->v3 *= PRIME64_1; - p64++; - state->v4 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v4 = XXH_rotl64(state->v4, 31); - state->v4 *= PRIME64_1; - p64++; - } + state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); + state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); + state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); + state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); p += 32-state->memsize; state->memsize = 0; } - if (p+32 <= bEnd) - { + if (p+32 <= bEnd) { const BYTE* const limit = bEnd - 32; U64 v1 = state->v1; U64 v2 = state->v2; U64 v3 = state->v3; U64 v4 = state->v4; - do - { - v1 += XXH_readLE64(p, endian) * PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - p+=8; - v2 += XXH_readLE64(p, endian) * PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - p+=8; - v3 += XXH_readLE64(p, endian) * PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - p+=8; - v4 += XXH_readLE64(p, endian) * PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - p+=8; - } - while (p<=limit); + do { + v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; + v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; + v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; + v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; + } while (p<=limit); state->v1 = v1; state->v2 = v2; @@ -863,8 +750,7 @@ FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void state->v4 = v4; } - if (p < bEnd) - { + if (p < bEnd) { XXH_memcpy(state->mem64, p, bEnd-p); state->memsize = (int)(bEnd-p); } @@ -887,71 +773,42 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) { const BYTE * p = (const BYTE*)state->mem64; - const BYTE* bEnd = (const BYTE*)state->mem64 + state->memsize; + const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; U64 h64; - if (state->total_len >= 32) - { - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; + if (state->total_len >= 32) { + U64 const v1 = state->v1; + U64 const v2 = state->v2; + U64 const v3 = state->v3; + U64 const v4 = state->v4; h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64*PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64*PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64*PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64*PRIME64_1 + PRIME64_4; - } - else - { + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + } else { h64 = state->seed + PRIME64_5; } h64 += (U64) state->total_len; - while (p+8<=bEnd) - { - U64 k1 = XXH_readLE64(p, endian); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; p+=8; } - if (p+4<=bEnd) - { + if (p+4<=bEnd) { h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; p+=4; } - while (p<bEnd) - { + while (p<bEnd) { h64 ^= (*p) * PRIME64_5; - h64 = XXH_rotl64(h64, 11) * PRIME64_1; + h64 = XXH_rotl64(h64, 11) * PRIME64_1; p++; } @@ -1009,4 +866,3 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src { return XXH_readBE64(src); } - diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h b/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h index 8fa3da6424e..4d7feffcd84 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h @@ -82,16 +82,19 @@ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; /* **************************** * API modifier ******************************/ -/*!XXH_PRIVATE_API -* Transforms all publics symbols within `xxhash.c` into private ones. -* Methodology : -* instead of : #include "xxhash.h" -* do : +/** XXH_PRIVATE_API +* This is useful if you want to include xxhash functions in `static` mode +* in order to inline them, and remove their symbol from the public list. +* Methodology : * #define XXH_PRIVATE_API -* #include "xxhash.c" // note the .c , instead of .h -* also : don't compile and link xxhash.c separately +* #include "xxhash.h" +* `xxhash.c` is automatically included, so the file is still needed, +* but it's not useful to compile and link it anymore. */ #ifdef XXH_PRIVATE_API +# ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY +# endif # if defined(__GNUC__) # define XXH_PUBLIC_API static __attribute__((unused)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) @@ -103,17 +106,17 @@ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; # endif #else # define XXH_PUBLIC_API /* do nothing */ -#endif +#endif /* XXH_PRIVATE_API */ /*!XXH_NAMESPACE, aka Namespace Emulation : If you want to include _and expose_ xxHash functions from within your own library, but also want to avoid symbol collisions with another library which also includes xxHash, -you can use XXH_NAMESPACE, to automatically prefix any public symbol from `xxhash.c` +you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values). -Note that no change is required within the calling program as long as it also includes `xxhash.h` : +Note that no change is required within the calling program as long as it includes `xxhash.h` : regular symbol name will be automatically translated by this header. */ #ifdef XXH_NAMESPACE @@ -132,6 +135,8 @@ regular symbol name will be automatically translated by this header. # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) #endif @@ -139,8 +144,8 @@ regular symbol name will be automatically translated by this header. * Version ***************************************/ #define XXH_VERSION_MAJOR 0 -#define XXH_VERSION_MINOR 5 -#define XXH_VERSION_RELEASE 0 +#define XXH_VERSION_MINOR 6 +#define XXH_VERSION_RELEASE 1 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) XXH_PUBLIC_API unsigned XXH_versionNumber (void); @@ -163,7 +168,7 @@ XXH32() : XXH64() : Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". "seed" can be used to alter the result predictably. - This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark). + This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark). */ @@ -173,22 +178,7 @@ XXH64() : typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ - -/*! Static allocation - For static linking only, do not use in the context of DLL ! - XXHnn_CREATESTATE_STATIC(name); - is static-allocation equivalent of : - XXHnn_state_t* name = XXHnn_createState(); -*/ -typedef struct { long long ll[ 6]; } XXH32_stateBody_t; -typedef struct { long long ll[11]; } XXH64_stateBody_t; - -#define XXH32_CREATESTATE_STATIC(name) XXH32_stateBody_t name##xxhbody; void* name##xxhvoid = &(name##xxhbody); XXH32_state_t* name = (XXH32_state_t*)(name##xxhvoid) /* no final ; */ -#define XXH64_CREATESTATE_STATIC(name) XXH64_stateBody_t name##xxhbody; void* name##xxhvoid = &(name##xxhbody); XXH64_state_t* name = (XXH64_state_t*)(name##xxhvoid) /* no final ; */ - - -/*!Dynamic allocation - To be preferred in the context of DLL */ +/*! State allocation, compatible with dynamic libraries */ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); @@ -207,29 +197,41 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned lon XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); -/*! -These functions generate the xxHash of an input provided in multiple segments, -as opposed to provided as a single block. +/* +These functions generate the xxHash of an input provided in multiple segments. +Note that, for small input, they are slower than single-call functions, due to state management. +For small input, prefer `XXH32()` and `XXH64()` . -XXH state must first be allocated, using either static or dynamic method provided above. +XXH state must first be allocated, using XXH*_createState() . -Start a new hash by initializing state with a seed, using XXHnn_reset(). +Start a new hash by initializing state with a seed, using XXH*_reset(). -Then, feed the hash state by calling XXHnn_update() as many times as necessary. -Obviously, input must be valid, hence allocated and read accessible. +Then, feed the hash state by calling XXH*_update() as many times as necessary. +Obviously, input must be allocated and read accessible. The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. -Finally, a hash value can be produced anytime, by using XXHnn_digest(). +Finally, a hash value can be produced anytime, by using XXH*_digest(). This function returns the nn-bits hash as an int or long long. It's still possible to continue inserting input into the hash state after a digest, -and later on generate some new hashes, by calling again XXHnn_digest(). +and generate some new hashes later on, by calling again XXH*_digest(). When done, free XXH state space if it was allocated dynamically. */ /* ************************** +* Utils +****************************/ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */ +# define restrict /* disable restrict */ +#endif + +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state); +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state); + + +/* ************************** * Canonical representation ****************************/ typedef struct { unsigned char digest[4]; } XXH32_canonical_t; @@ -241,13 +243,53 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); -/*! Default result type for XXH functions are primitive unsigned 32 and 64 bits. -* The canonical representation uses human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. +/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. +* The canonical representation uses human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. */ +#ifdef XXH_STATIC_LINKING_ONLY + +/* ================================================================================================ + This section contains definitions which are not guaranteed to remain stable. + They could change in a future version, becoming incompatible with a different version of the library. + They shall only be used with static linking. +=================================================================================================== */ + +/* These definitions allow allocating XXH state statically (on stack) */ + + struct XXH32_state_s { + unsigned long long total_len; + unsigned seed; + unsigned v1; + unsigned v2; + unsigned v3; + unsigned v4; + unsigned mem32[4]; /* buffer defined as U32 for alignment */ + unsigned memsize; + }; /* typedef'd to XXH32_state_t */ + + struct XXH64_state_s { + unsigned long long total_len; + unsigned long long seed; + unsigned long long v1; + unsigned long long v2; + unsigned long long v3; + unsigned long long v4; + unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ + unsigned memsize; + }; /* typedef'd to XXH64_state_t */ + + +# ifdef XXH_PRIVATE_API +# include "xxhash.c" /* include xxhash functions as `static`, for inlining */ +# endif + +#endif /* XXH_STATIC_LINKING_ONLY */ + + #if defined (__cplusplus) } #endif diff --git a/Build/source/texk/dvisvgm/version.ac b/Build/source/texk/dvisvgm/version.ac index 69e6099ec4d..2cc5cceb035 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.15.1]) +m4_define([dvisvgm_version], [1.16]) |