texlive[41628] Build/source/texk/dvisvgm: dvisvgm 1.16

commits+kakuto at tug.org commits+kakuto at tug.org
Tue Jul 5 00:07:55 CEST 2016


Revision: 41628
          http://tug.org/svn/texlive?view=revision&revision=41628
Author:   kakuto
Date:     2016-07-05 00:07:54 +0200 (Tue, 05 Jul 2016)
Log Message:
-----------
dvisvgm 1.16

Modified Paths:
--------------
    trunk/Build/source/texk/dvisvgm/ChangeLog
    trunk/Build/source/texk/dvisvgm/Makefile.am
    trunk/Build/source/texk/dvisvgm/Makefile.in
    trunk/Build/source/texk/dvisvgm/configure
    trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog
    trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/NEWS
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h
    trunk/Build/source/texk/dvisvgm/version.ac

Added Paths:
-----------
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp
    trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h

Removed Paths:
-------------
    trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process

Modified: trunk/Build/source/texk/dvisvgm/ChangeLog
===================================================================
--- trunk/Build/source/texk/dvisvgm/ChangeLog	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/ChangeLog	2016-07-04 22:07:54 UTC (rev 41628)
@@ -1,3 +1,8 @@
+2016-07-04  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	* Imported release 1.16
+	* version.ac, Makefile.am: Adapted.
+
 2016-04-20  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	* Imported release 1.15.1

Modified: trunk/Build/source/texk/dvisvgm/Makefile.am
===================================================================
--- trunk/Build/source/texk/dvisvgm/Makefile.am	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/Makefile.am	2016-07-04 22:07:54 UTC (rev 41628)
@@ -100,6 +100,7 @@
 	@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 @@
 	@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 \

Modified: trunk/Build/source/texk/dvisvgm/Makefile.in
===================================================================
--- trunk/Build/source/texk/dvisvgm/Makefile.in	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/Makefile.in	2016-07-04 22:07:54 UTC (rev 41628)
@@ -184,6 +184,7 @@
 	@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 @@
 	@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 @@
 	@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 @@
 	@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 @@
 @DVISVGM_TREE@/src/NoPsSpecialHandler.$(OBJEXT):  \
 	@DVISVGM_TREE@/src/$(am__dirstamp) \
 	@DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at 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 @@
 @DVISVGM_TREE@/src/RangeMap.$(OBJEXT):  \
 	@DVISVGM_TREE@/src/$(am__dirstamp) \
 	@DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at DVISVGM_TREE@/src/SVGCharHandler.$(OBJEXT):  \
+	@DVISVGM_TREE@/src/$(am__dirstamp) \
+	@DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at DVISVGM_TREE@/src/SVGCharHandlerFactory.$(OBJEXT):  \
+	@DVISVGM_TREE@/src/$(am__dirstamp) \
+	@DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at DVISVGM_TREE@/src/SVGCharPathHandler.$(OBJEXT):  \
+	@DVISVGM_TREE@/src/$(am__dirstamp) \
+	@DVISVGM_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at 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)
+ at 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 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/Message.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/MetafontWrapper.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/NoPsSpecialHandler.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PapersizeSpecialHandler.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PSInterpreter.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PSPattern.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PSPreviewFilter.Po at am__quote@
@@ -1271,7 +1302,12 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/Process.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/PsSpecialHandler.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/RangeMap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharHandler.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharHandlerFactory.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharPathHandler.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGCharTspanTextHandler.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGOutput.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGSingleCharTextHandler.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SVGTree.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/ShadingPatch.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@@DVISVGM_TREE@/src/$(DEPDIR)/SignalHandler.Po at am__quote@

Modified: trunk/Build/source/texk/dvisvgm/configure
===================================================================
--- trunk/Build/source/texk/dvisvgm/configure	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/configure	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at tug.org>.
 #
@@ -590,8 +590,8 @@
 # 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 at tug.org'
 PACKAGE_URL=''
 
@@ -1372,7 +1372,7 @@
   # 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 @@
 
 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 @@
 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 @@
 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 @@
 
 # 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 @@
 Report bugs to <bug-libtool at 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 @@
 # 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 @@
 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\\"
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/ChangeLog	2016-07-04 22:07:54 UTC (rev 41628)
@@ -1,3 +1,8 @@
+2016-07-04  Akira Kakuto  <kakuto at 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 at tug.org>
 
 	* patch-01-process: received from dvisvgm author.

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/TL-Changes	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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

Deleted: trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-PATCHES/patch-01-process	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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) {

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog	2016-07-04 22:07:54 UTC (rev 41628)
@@ -1,3 +1,58 @@
+2016-04-19  Martin Gieseking  <martin.gieseking at 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 at 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 at 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 at 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 at uos.de>
+
+  * src/GraphicsPath.h: 
+  renamed GraphicsPath::sconito/scubicto 
+
+2016-03-14  Martin Gieseking  <martin.gieseking at 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 at 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 at 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 at uos.de>
+
+  * README, README.md: 
+  updated README and README.md 
+
 2015-01-21  Martin Gieseking  <martin.gieseking at uos.de>
 
   * src/TensorProductPatch.cpp, src/TriangularPatch.cpp: 
@@ -989,9 +1049,11 @@
   * 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 at uos.de>
 
+  * README.md: 
+  minor fixes to README.md 
+
 2014-07-31  Martin Gieseking  <martin.gieseking at uos.de>
 
   * src/PsSpecialHandler.cpp, src/psdefs.cpp, src/psdefs.ps: 
@@ -1632,10 +1694,10 @@
   replaced local std::map tables used in Font classes with new class 
   CharMap 
 
-2013-08-23  Martin Gieseking  <martin.gieseking at uos.de>
+2013-08-22  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 
@@ -1938,9 +2000,8 @@
     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 at uos.de>
 
@@ -2033,21 +2094,11 @@
   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 at 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 @@
     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 at 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 at uos.de>
 
   * src/CommandLine.cpp: 
@@ -2300,6 +2360,11 @@
     tests/StreamInputBufferTest.cpp: 
   some refactorings of class InputReader; added InputReader::find() 
 
+2012-10-24  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 
   * doc/Makefile.am: 
@@ -2316,21 +2381,19 @@
   * src/PsSpecialHandler.cpp, src/PsSpecialHandler.h: 
   removed Ghostscript info from ps entry in list of special handlers 
 
-2012-09-19  Martin Gieseking  <martin.gieseking at uos.de>
+  * src/DVIToSVG.cpp: 
+  show warning if processing of PS specials is disabled 
 
-  * src/psdefs.ps, src/psdefs.psc: 
-  ignore dvips bop operators that might be present in PS specials 
-
-2012-09-17  Martin Gieseking  <martin.gieseking at uos.de>
-
-  * src/StreamReader.cpp: 
-  fixed reading invalid number of string characters 
-
 2012-06-06  Martin Gieseking  <martin.gieseking at uos.de>
 
   * src/gfprint.mak: 
   fixed bugs in gfprint, and added gfprint.mak for easier builds 
 
+2012-04-17  Martin Gieseking  <martin.gieseking at uos.de>
+
+  * doc/Makefile.am: 
+  keep manpage when calling 'make clean' or 'make distclean' 
+
 2012-04-04  Martin Gieseking  <martin.gieseking at uos.de>
 
   * src/DVIToSVGActions.cpp, src/SVGTree.cpp, src/SVGTree.h, 
@@ -2385,6 +2448,15 @@
   * README: 
   updated information about bug reporting 
 
+2012-01-26  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 
   * src/TpicSpecialHandler.cpp: 
@@ -3234,10 +3306,6 @@
     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 at uos.de>
 
   * src/DVIToSVG.cpp: 
@@ -3465,10 +3533,10 @@
   * src/GraphicPath.h, src/PsSpecialHandler.cpp: 
   PS handler: replace zero-length paths by dots 
 
-2009-10-25  Martin Gieseking  <martin.gieseking at uos.de>
+2009-10-29  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 
@@ -3633,19 +3701,14 @@
   * NEWS, src/PsSpecialHandler.cpp: 
   fixed another positioning bug reported by John Bowman 
 
+  * src/PsSpecialHandler.cpp: 
+  convert PS path coordinated to TeX point units 
+
 2009-10-04  Martin Gieseking  <martin.gieseking at uos.de>
 
-  * src/Makefile.old, src/Makefile.orig: 
-  renamed the old original Makefile 
-
   * 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 at uos.de>
 
   * doc/Makefile.am, doc/dvisvgm.txt.in: 
@@ -3652,6 +3715,11 @@
   generate pdf manpage directly with groff; adapted manpage source to work 
   with latest asciidoc 
 
+2009-10-01  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 
   * Makefile.am, configure.ac, fedora/dvisvgm.spec, src/Doxyfile: 
@@ -3663,17 +3731,13 @@
   * 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 at 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,22 +3834,15 @@
     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 at uos.de>
+  * fedora/dvisvgm-0.8.1-potrace.patch, fedora/dvisvgm-gs.patch, 
+    fedora/dvisvgm-potrace.patch, fedora/dvisvgm.spec: 
+  updated Fedora files 
 
-  * configure.ac, src/DVIToSVGActions.cpp, src/Ghostscript.cpp, 
-    src/Ghostscript.h: 
-  added configuration method to directly bind the Ghostscript shared 
-  library 
-
 2009-08-24  Martin Gieseking  <martin.gieseking at uos.de>
 
   * src/CommandLine.cpp, src/CommandLine.h: 
@@ -4169,10 +4226,10 @@
 
 2009-02-25  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 
@@ -4232,14 +4289,9 @@
 
 2009-02-17  Martin Gieseking  <martin.gieseking at 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 at uos.de>
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/NEWS
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/NEWS	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/NEWS	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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'

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at uos.de])
-DATE="April 2016"
+AC_INIT([dvisvgm],[1.16],[martin.gieseking at uos.de])
+DATE="July 2016"
 AC_CONFIG_SRCDIR(src)
 AC_CONFIG_HEADER(config.h)
 AC_CONFIG_MACRO_DIR([m4])

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1	2016-07-04 22:07:54 UTC (rev 41628)
@@ -2,12 +2,12 @@
 .\"     Title: dvisvgm
 .\"    Author: Martin Gieseking <martin.gieseking at 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 @@
 \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 @@
 \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 @@
 lt lt
 lt lt
 lt lt
+lt lt
 lt lt.
 T{
 \fBdvi\fR
@@ -132,9 +133,16 @@
 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 @@
 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,

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in	2016-07-04 22:07:54 UTC (rev 41628)
@@ -38,8 +38,8 @@
 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 @@
 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 @@
    *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 @@
 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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 	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::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::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 @@
 		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 @@
 }
 
 
+/** 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,12 +173,12 @@
 	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
@@ -164,17 +185,18 @@
 }
 
 
-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 @@
 /** 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 @@
 
 
 /** 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 @@
 
 
 /** 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 @@
 	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,7 +294,7 @@
 		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);
 	}
@@ -279,6 +301,9 @@
 }
 
 
+/** 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 @@
 }
 
 
+/** 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);
+}

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		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 &param);
 		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 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -45,7 +45,7 @@
 	protected:
 		int approximate (double delta, double t0, double t1, std::vector<DPair> &p, std::vector<double> *t) const;
 
-   private:
+	private:
 		DPair _points[4];
 };
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -30,9 +30,9 @@
 /** 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;
@@ -39,11 +39,10 @@
 		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 @@
 }
 
 
-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 @@
 	// 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);
 }
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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;
 };
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -52,8 +52,8 @@
 
 
 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 @@
 }
 
 
-/** 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 @@
 			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 @@
 }
 
 
-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 @@
 
 
 ostream& BoundingBox::write (ostream &os) const {
-	return os << '('  << _ulx << ", " << _uly
-				 << ", " << _lrx << ", " << _lry << ')';
+	os << '('  << _ulx << ", " << _uly << ", " << _lrx << ", " << _lry << ')';
+	if (!_valid)
+		os << " (invalid)";
+	return os;
 }
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -23,6 +23,7 @@
 
 #include <ostream>
 #include <string>
+#include <vector>
 #include "Length.h"
 #include "MessageException.h"
 #include "Pair.h"
@@ -48,12 +49,15 @@
 		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 @@
 		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;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -89,8 +89,8 @@
 	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 @@
 		std::string getROString () const;
 
 	private:
-		std::string _name;
+		std::string _filename;
 		std::string _registry;
 		std::string _ordering;
 		CMap *_basemap;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -24,6 +24,7 @@
 #include "CMapManager.h"
 #include "CMapReader.h"
 #include "FileFinder.h"
+#include "Font.h"
 #include "Message.h"
 
 using namespace std;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -25,11 +25,11 @@
 #include <set>
 #include <string>
 #include "CharMapID.h"
-#include "Font.h"
 
 struct CMap;
 struct FontEncoding;
 class FontEncodingPair;
+class PhysicalFont;
 
 class CMapManager
 {

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -109,11 +109,7 @@
 	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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -92,7 +92,7 @@
 }
 
 
-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 @@
 			_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;
 }
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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";}

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -6,8 +6,6 @@
 
 #include <config.h>
 #include <cstdio>
-#include <iostream>
-#include <iomanip>
 #include "InputReader.h"
 #include "CommandLine.h"
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 () {
 	if (_handle) {
-#ifdef __WIN32__
+#ifdef _WIN32
 		FreeLibrary(_handle);
 #else
 		dlclose(_handle);
@@ -50,7 +50,7 @@
  *  @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);

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		void* loadSymbol (const char *name);
 
 	private:
-#ifdef __WIN32__
+#ifdef _WIN32
 		HINSTANCE _handle;
 #else
 		void *_handle;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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) {}

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 }
 
 
-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,39 +142,24 @@
 	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);
 }
 
 
@@ -220,26 +166,24 @@
 /** 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,9 +191,11 @@
  *  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);
 }
 
 
@@ -256,19 +202,16 @@
 /** 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 @@
 	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,74 +235,43 @@
 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);
-		}
-	}
+	_currDviState = _stateStack.top();
+	_stateStack.pop();
+	dviPop();
 }
 
 
-/** 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;
+/** 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
+			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
 		}
 	}
-	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;
-		}
-	}
 }
 
 
@@ -369,7 +280,12 @@
  *  @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 @@
  *  @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 @@
  *  @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 @@
 		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,56 +345,83 @@
 		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;
+	switch (_currDviState.d) {
+		case WMODE_LR: _currDviState.h += dx; break;
+		case WMODE_TB: _currDviState.v += dx; break;
+		case WMODE_BT: _currDviState.v -= dx; break;
 	}
-	if (_actions) {
-		if (_dviState.d == WMODE_LR)
-			_actions->moveToX(_dviState.h+_tx);
-		else
-			_actions->moveToY(_dviState.v+_ty);
-	}
 }
 
 
 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;
+	switch (_currDviState.d) {
+		case WMODE_LR: _currDviState.v += dy; break;
+		case WMODE_TB: _currDviState.h -= dy; break;
+		case WMODE_BT: _currDviState.h += dy; break;
 	}
-	if (_actions) {
-		if (_dviState.d == WMODE_LR)
-			_actions->moveToY(_dviState.v+_ty);
-		else
-			_actions->moveToX(_dviState.h+_tx);
-	}
 }
 
 
-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)
@@ -477,12 +428,11 @@
 		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 @@
 	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 @@
  *  @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 @@
 	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 @@
  *  @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 @@
 /** 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 @@
 	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 @@
 		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");
 }
 
 
-/** 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) {
+/** 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 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);
+		dx[i] = readSigned(4)*_dvi2bp;
+		dy[i] = xonly ? 0 : readSigned(4)*_dvi2bp;
 	}
-	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);
-			}
-		}
-	}
+	for (int i=0; i < num_glyphs; i++)
+		glyphs[i] = readUnsigned(2);
 	moveRight(strwidth);
 }

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 "HtmlSpecialHandler.h"
+#include "PapersizeSpecialHandler.h"
 #include "PdfSpecialHandler.h"
-#include "HtmlSpecialHandler.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 @@
 		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 @@
 	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,12 +141,29 @@
 }
 
 
+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?
@@ -147,30 +170,27 @@
 			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 @@
 		}
 		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 @@
 		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 @@
 		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 @@
 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 @@
 	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 @@
 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);
+}
+
+

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -24,9 +24,9 @@
 #include <string>
 #include <utility>
 #include "DVIReader.h"
-#include "SpecialManager.h"
 #include "SVGTree.h"
 
+struct DVIActions;
 class Matrix;
 struct SVGOutputBase;
 
@@ -33,31 +33,62 @@
 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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -34,7 +34,7 @@
 
 
 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 () {
-	delete _pageMatrix;
 	delete _boxes;
 }
 
@@ -56,20 +55,14 @@
 }
 
 
-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 @@
  *  @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::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 @@
  *  @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 @@
 
 /** 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");

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		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 @@
 		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,7 +66,7 @@
 		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);
@@ -73,7 +73,6 @@
 		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 @@
 		int _currentFontNum;
 		mutable CharMap _usedChars;
 		FontSet _usedFonts;
-		Matrix *_pageMatrix;  // transformation of whole page
 		Color _bgcolor;
 		BoxMap *_boxes;
 };

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -23,7 +23,7 @@
 
 using namespace std;
 
-#ifdef __WIN32__
+#ifdef _WIN32
 	#include <windows.h>
 #else
 	#include <errno.h>
@@ -32,7 +32,7 @@
 
 
 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 (string dirname) {
-#if __WIN32__
+#if _WIN32
 	handle = INVALID_HANDLE_VALUE;
 	firstread = true;
 	memset(&fileData, 0, sizeof(WIN32_FIND_DATA));
@@ -63,7 +63,7 @@
 
 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 @@
 
 
 void Directory::close () {
-#ifdef __WIN32__
+#ifdef _WIN32
 	FindClose(handle);
 #else
 	closedir(_dir);
@@ -90,7 +90,7 @@
  *  @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)) {

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 
 	private:
 		std::string _dirname;
-#ifdef __WIN32__
+#ifdef _WIN32
 		bool firstread;
 		HANDLE handle;
 		WIN32_FIND_DATA fileData;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 }
 
 
-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 @@
  *  @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 @@
 /** 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 @@
 			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 @@
 }
 
 
-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 @@
 		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 @@
  *  @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 @@
  *  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 @@
 				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 @@
 		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::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) {

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		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 @@
 		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;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -58,7 +58,7 @@
 			"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 @@
 		" 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';
 }
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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,25 +41,32 @@
  *  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);
+	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);
 	}
-	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);
-	}
 	return cut;
 }
 
@@ -70,7 +78,7 @@
  * @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 @@
 		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 @@
 		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 @@
 	//
 	// 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;
+	StreamInputReader ir(is);
+	string cmdstr = ir.getWord();
+	for (Command *cmd=commands; cmd->name; cmd++) {
+		if (cmdstr == cmd->name) {
+			(this->*cmd->handler)(ir, actions);
+			break;
 		}
-		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));
-			}
-		}
 	}
 	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();

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -26,6 +26,8 @@
 #include "Pair.h"
 #include "SpecialHandler.h"
 
+class InputReader;
+class SpecialActions;
 
 class EmSpecialHandler : public SpecialHandler, public DVIEndPageListener
 {
@@ -41,10 +43,15 @@
 		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
@@ -51,7 +58,6 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -37,7 +37,7 @@
 }
 
 
-#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 @@
 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 @@
 	}
 	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 @@
 		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 @@
 		path = "/";
 	if (with_filename && !_fname.empty())
 		path += "/"+_fname;
-#ifdef __WIN32__
+#ifdef _WIN32
 	if (_drive)
 		path.insert(0, string(1, _drive) + ":");
 #endif
@@ -225,7 +225,7 @@
 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] != '/')
@@ -232,7 +232,7 @@
 		return absolute();
 	FilePath rel(reldir, false);
 	string path;
-#ifdef __WIN32__
+#ifdef _WIN32
 	if (rel._drive && _drive && rel._drive != _drive)
 		path += string(1, _drive) + ":";
 #endif

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -50,7 +50,7 @@
 	private:
 		Directories _dirs;
 		std::string _fname;
-#ifdef __WIN32__
+#ifdef _WIN32
 		char _drive;
 #endif
 };

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 
 
 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::getcwd () {
 	char buf[1024];
-#ifdef __WIN32__
+#ifdef _WIN32
 	return adaptPathSeperators(_getcwd(buf, 1024));
 #else
 	return ::getcwd(buf, 1024);
@@ -118,7 +118,7 @@
 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 @@
 
 /** 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 @@
 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 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 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::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 @@
 /** 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 @@
 /** 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 @@
 
 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);

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -31,7 +31,6 @@
 #include "MetafontWrapper.h"
 #include "SignalHandler.h"
 #include "Subfont.h"
-#include "SVGTree.h"
 #include "Unicode.h"
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -54,33 +54,34 @@
 
 
 /** 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;
 };
 
 
@@ -87,8 +88,7 @@
 /** 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 @@
 
 
 /** 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 @@
 
 
 /** 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 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 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 PhysicalFontImpl : public PhysicalFont, public TFMFont
-{
+class PhysicalFontImpl : public PhysicalFont, public TFMFont {
 	friend class PhysicalFont;
 	public:
 		~PhysicalFontImpl();
@@ -258,8 +253,7 @@
 };
 
 
-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 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 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 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 VirtualFontImpl : public VirtualFont, public TFMFont
-{
+class VirtualFontImpl : public VirtualFont, public TFMFont {
 	friend class VirtualFont;
 	public:
 		~VirtualFontImpl ();

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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. */

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -108,7 +108,7 @@
 }
 
 
-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 @@
 
 
 /** 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 @@
 }
 
 
+/** 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)

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 {
 	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 @@
 		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);

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -33,6 +33,10 @@
 	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 @@
 	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;}

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -172,7 +172,11 @@
 	_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 @@
 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 @@
 	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 @@
 	Int32 p  = readSigned(4);   // pointer to begin of (last) character data
 	_charInfoMap[c] = CharInfo(dx, dy, w, p);
 }
-

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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;
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -38,7 +38,7 @@
 
 #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 @@
 #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 @@
 	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 @@
 #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 @@
 #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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -33,7 +33,7 @@
 	#include "iapi.h"
 #endif
 
-#if defined(__WIN32__) && !defined(_Windows)
+#if defined(_WIN32) && !defined(_Windows)
 	#define _Windows
 #endif
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 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,7 +44,7 @@
 	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);
 	}
@@ -53,15 +51,15 @@
 }
 
 
-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,10 +80,8 @@
 }
 
 
-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;
@@ -92,14 +88,14 @@
 	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 @@
 
 /** 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 @@
 		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,9 +132,9 @@
 	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;
 }
 
@@ -145,20 +141,20 @@
 
 /** 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 @@
  *  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 @@
 			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 @@
 			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 @@
 				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,7 +220,7 @@
 			rect->addAttribute("height", bbox.height());
 			rect->addAttribute("fill", "white");
 			rect->addAttribute("fill-opacity", 0);
-			_actions->appendToPage(rect);
+			actions.appendToPage(rect);
 		}
 	}
 }
@@ -231,23 +227,23 @@
 
 
 /** 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 @@
 				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;
 	}
 }
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 	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 @@
 
 	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 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -31,8 +31,8 @@
 
 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)";
@@ -39,36 +39,38 @@
 		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 @@
 		_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);
 }
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -34,7 +34,7 @@
 		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:

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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,32 +60,90 @@
 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 "??";
+}
+
+
 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));
 }
-

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -37,26 +37,43 @@
 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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am	2016-07-04 22:07:54 UTC (rev 41628)
@@ -133,6 +133,8 @@
 	PageSize.cpp \
 	PageSize.h \
 	Pair.h \
+	PapersizeSpecialHandler.cpp \
+	PapersizeSpecialHandler.h \
 	PathClipper.cpp \
 	PathClipper.h \
 	PdfSpecialHandler.cpp \
@@ -167,8 +169,18 @@
 	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 \

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -68,7 +68,7 @@
 			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 @@
 			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;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -49,7 +49,7 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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";

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -27,13 +27,13 @@
 {
 	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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -36,9 +36,9 @@
 
 
 /** 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 @@
 }
 
 
-void PSTilingPattern::apply (SpecialActions *actions) {
+void PSTilingPattern::apply (SpecialActions &actions) {
 	PSPattern::apply(actions);
 	_groupNode = 0;
 }
@@ -145,7 +145,7 @@
 
 /** 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)

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -28,7 +28,7 @@
 #include "Matrix.h"
 
 
-struct SpecialActions;
+class SpecialActions;
 class SVGTree;
 class XMLElementNode;
 
@@ -38,7 +38,7 @@
 		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 @@
 	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 @@
 		~PSUncoloredTilingPattern ();
 		std::string svgID () const;
 		void setColor (Color color) {_currentColor = color;}
-		void apply (SpecialActions *actions);
+		void apply (SpecialActions &actions);
 
 	protected:
 		XMLElementNode* createClipNode () const;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -26,7 +26,7 @@
 #include "BoundingBox.h"
 #include "PSFilter.h"
 
-struct SpecialActions;
+class SpecialActions;
 
 class PSPreviewFilter : public PSFilter
 {

Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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;
+}


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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
+


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -34,9 +34,7 @@
 }
 
 
-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();

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -30,7 +30,7 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -29,7 +29,7 @@
 {
 	public:
 		PreScanDVIReader (std::istream &is, DVIActions *actions);
-		unsigned getCurrentPageNumber () const {return _currentPageNumber;}
+		unsigned currentPageNumber () const {return _currentPageNumber;}
 
 	protected:
 		void cmdBop (int);

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -20,7 +20,7 @@
 
 #include <config.h>
 
-#ifdef __WIN32__
+#ifdef _WIN32
 	#include <windows.h>
 #else
 	#include <fcntl.h>
@@ -43,7 +43,7 @@
 }
 
 
-#ifdef __WIN32__
+#ifdef _WIN32
 static void pipe_read (HANDLE handle, string &out) {
 	char buf[4096];
 	out.clear();
@@ -108,7 +108,7 @@
  *  @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);

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -174,12 +174,12 @@
 }
 
 
-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 @@
 }
 
 
-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,15 +385,15 @@
 }
 
 
-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 {
@@ -400,19 +400,19 @@
 				// 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";
@@ -419,11 +419,13 @@
 
 			// 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, "
@@ -430,28 +432,26 @@
 					"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 @@
 	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 @@
 
 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 @@
 		}
 
 	private:
-		SpecialActions *_actions;
+		SpecialActions &_actions;
 		XMLElementNode *_group;
 };
 
@@ -961,7 +961,7 @@
 		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 @@
 		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 @@
 
 
 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;
 }

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -76,8 +76,8 @@
 		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 @@
 		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);

Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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
+


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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);
+	}
+}


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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);
+}


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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);
+}


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h	                        (rev 0)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 at 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
+


Property changes on: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 
 
 // 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 @@
 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 @@
 	_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::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 @@
 	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,213 +117,26 @@
 
 
 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);
+void SVGTree::transformPage (const Matrix &usermatrix) {
+	if (!usermatrix.isIdentity())
+		_page->addAttribute("transform", usermatrix.getSVG());
 }
 
 
-/** 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());
-}
-
-
 /** Creates an SVG element for a single glyph.
  *  @param[in] c character number
  *  @param[in] font font to extract the glyph from
@@ -375,7 +193,7 @@
 
 
 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 @@
 
 /** 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 @@
 		_defs->remove(node);
 	}
 }
-

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		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,19 +57,19 @@
 		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
@@ -97,21 +76,11 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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)
 };
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -26,8 +26,8 @@
 #include "MessageException.h"
 
 
-struct SpecialActions;
-class  SpecialManager;
+class SpecialActions;
+class SpecialManager;
 
 
 struct SpecialException : public MessageException
@@ -46,7 +46,7 @@
 struct DVIBeginPageListener
 {
 	virtual ~DVIBeginPageListener () {}
-	virtual void dviBeginPage (unsigned pageno) =0;
+	virtual void dviBeginPage (unsigned pageno, SpecialActions &actions) =0;
 };
 
 
@@ -53,7 +53,7 @@
 struct DVIEndPageListener
 {
 	virtual ~DVIEndPageListener () {}
-	virtual void dviEndPage (unsigned pageno) =0;
+	virtual void dviEndPage (unsigned pageno, SpecialActions &actions) =0;
 };
 
 
@@ -60,21 +60,21 @@
 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;
 };
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -122,7 +122,7 @@
 }
 
 
-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 @@
  *  @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::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);
 }
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -27,7 +27,7 @@
 #include <vector>
 #include "SpecialHandler.h"
 
-struct SpecialActions;
+class SpecialActions;
 
 class SpecialManager
 {
@@ -43,12 +43,12 @@
 		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:

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -22,6 +22,7 @@
 #include <fstream>
 #include <vector>
 #include "FileFinder.h"
+#include "Length.h"
 #include "Message.h"
 #include "StreamReader.h"
 #include "TFM.h"
@@ -30,40 +31,41 @@
 
 
 /** 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");
@@ -70,33 +72,66 @@
 	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;
+}
+
+
 /** Returns the index to the entry of the character info table that describes the metric of a given character.
  *  @param[in] c character whose index is retrieved
  *  @return table index for character c, or -1 if there's no entry */
@@ -121,7 +156,7 @@
 	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 @@
 	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 @@
 	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 @@
 	if (index < 0)
 		return 0;
 	index = (_charInfoTable[index] >> 10) & 0x3F;
-	return fix2double(_italicTable[index]) * fix2double(_designSize);
+	return fix2double(_italicTable[index]) * _designSize;
 }

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -33,22 +33,26 @@
 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;}
 
@@ -55,12 +59,13 @@
 	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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -40,7 +40,7 @@
 {
 	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 @@
 		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)
 };

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -29,7 +29,7 @@
 #include <sys/ioctl.h>
 #endif
 
-#ifdef __WIN32__
+#ifdef _WIN32
 #include <windows.h>
 #endif
 
@@ -50,7 +50,7 @@
 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 @@
 /** 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 @@
 	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 @@
 	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 @@
 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 @@
  *  @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 @@
 /** 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;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -49,7 +49,7 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -40,7 +40,7 @@
 }
 
 
-void TpicSpecialHandler::dviEndPage (unsigned pageno) {
+void TpicSpecialHandler::dviEndPage (unsigned pageno, SpecialActions&) {
 	reset();
 }
 
@@ -58,16 +58,16 @@
  *  @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 @@
 					_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 @@
 			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 @@
 			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,19 +118,19 @@
  *  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];
@@ -137,17 +137,17 @@
 			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 @@
 		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,63 +181,61 @@
  *  @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));
+	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 {
-			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");
+		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");
-		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));
-	}
+	actions.appendToPage(elem);
+	actions.embed(BoundingBox(cx-rx, cy-ry, cx+rx, cy+ry));
 	reset();
 }
 
@@ -244,7 +242,7 @@
 
 #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;
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -32,14 +32,14 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 	protected:
 		Color averageColor (const Color &c1, const Color &c2, const Color &c3) const;
 
-   private:
+	private:
 		DPair _points[3];
 		Color _colors[3];
 };

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 
 /** 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;
 }
 
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 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;
 };

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -19,6 +19,7 @@
 *************************************************************************/
 
 #include <config.h>
+#include "macros.h"
 #include "XMLDocument.h"
 
 using namespace std;
@@ -65,8 +66,10 @@
 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;

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -180,17 +180,25 @@
 
 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 @@
 
 ostream& XMLCDataNode::write (ostream &os) const {
 	if (!_data.empty())
-		os << "<![CDATA[\n" << _data << "]]>\n";
+		os << "<![CDATA[\n" << _data << "]]>";
 	return os;
 }
 

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 		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 @@
 		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

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp	2016-07-04 22:07:54 UTC (rev 41628)
@@ -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 @@
 	}
 	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 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 @@
 		}
 	}
 	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 @@
 		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();

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.c	2016-07-04 22:07:54 UTC (rev 41628)
@@ -1,34 +1,35 @@
 /*
-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
 */
 
 
@@ -35,7 +36,7 @@
 /* *************************************
 *  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 @@
  * 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 @@
 
 
 /* *************************************
-*  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 @@
 /* *************************************
 *  Constants
 ***************************************/
-#define PRIME32_1   2654435761U
-#define PRIME32_2   2246822519U
-#define PRIME32_3   3266489917U
-#define PRIME32_4    668265263U
-#define PRIME32_5    374761393U
+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;
 
-#define PRIME64_1 11400714785074694791ULL
-#define PRIME64_2 14029467366897019727ULL
-#define PRIME64_3  1609587929392839161ULL
-#define PRIME64_4  9650029242287828579ULL
-#define PRIME64_5  2870177450012600261ULL
+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,15 +341,13 @@
 #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;
@@ -324,45 +354,27 @@
         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 @@
 #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,23 +416,38 @@
 #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;
@@ -429,80 +454,39 @@
         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 @@
 #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 @@
 #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 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,41 +595,25 @@
 
     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;
@@ -681,26 +620,12 @@
         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 @@
         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 @@
 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,41 +714,23 @@
 
     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;
@@ -836,26 +737,12 @@
         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 @@
         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 @@
 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 @@
 {
     return XXH_readBE64(src);
 }
-

Modified: trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h
===================================================================
--- trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/dvisvgm-src/xxHash/xxhash.h	2016-07-04 22:07:54 UTC (rev 41628)
@@ -82,16 +82,19 @@
 /* ****************************
 *  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,7 +106,7 @@
 #  endif
 #else
 #  define XXH_PUBLIC_API   /* do nothing */
-#endif
+#endif /* XXH_PRIVATE_API */
 
 /*!XXH_NAMESPACE, aka Namespace Emulation :
 
@@ -110,10 +113,10 @@
 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 @@
 #  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 @@
 *  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 @@
 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,23 +178,8 @@
 typedef struct XXH32_state_s XXH32_state_t;   /* incomplete type */
 typedef struct XXH64_state_s XXH64_state_t;   /* incomplete type */
 
+/*! State allocation, compatible with dynamic libraries */
 
-/*! 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 */
-
 XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
 XXH_PUBLIC_API XXH_errorcode  XXH32_freeState(XXH32_state_t* statePtr);
 
@@ -207,23 +197,24 @@
 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.
 */
@@ -230,6 +221,17 @@
 
 
 /* **************************
+*  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 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

Modified: trunk/Build/source/texk/dvisvgm/version.ac
===================================================================
--- trunk/Build/source/texk/dvisvgm/version.ac	2016-07-04 21:58:07 UTC (rev 41627)
+++ trunk/Build/source/texk/dvisvgm/version.ac	2016-07-04 22:07:54 UTC (rev 41628)
@@ -8,4 +8,4 @@
 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])



More information about the tex-live-commits mailing list