diff options
author | Hironobu Yamashita <h.y.acetaminophen@gmail.com> | 2022-08-29 13:52:14 +0000 |
---|---|---|
committer | Hironobu Yamashita <h.y.acetaminophen@gmail.com> | 2022-08-29 13:52:14 +0000 |
commit | 4c5fc2acc23b0715c5cc5aa4adc87c8b998a0cab (patch) | |
tree | a9d9e4ade07bf8a5b82c2a582885324300040c90 /Build/source/texk/dvisvgm/dvisvgm-src | |
parent | d6b263980d8d5e05e039587454b7d30c438ff05c (diff) |
dvisvgm 2.14
git-svn-id: svn://tug.org/texlive/trunk@64224 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src')
67 files changed, 1244 insertions, 399 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog index d426c377561..2533c9a1e00 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog +++ b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog @@ -1,3 +1,167 @@ +2022-08-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontWriter.cpp, src/HashFunction.hpp, src/HyperlinkManager.hpp, + src/Opacity.hpp, src/SVGElement.hpp, src/TFM.cpp, + src/optimizer/Makefile.am, src/utility.hpp: + fixed indentations + +2022-08-09 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, + src/version.hpp: + set version to 2.14 + + * configure.ac: + removed redundant macros from configure.ac + +2022-07-28 Martin Gieseking <martin.gieseking@uos.de> + + * src/CLCommandLine.cpp, src/CMap.cpp, src/DVIReader.cpp, + src/DvisvgmSpecialHandler.cpp, src/FileFinder.cpp, src/FilePath.cpp, + src/Font.cpp, src/FontMap.cpp, src/HyperlinkManager.cpp, src/MapLine.cpp, + src/MetafontWrapper.cpp, src/PDFParser.cpp, src/PageSize.cpp, + src/PapersizeSpecialHandler.cpp, src/PsSpecialHandler.cpp, + src/SVGOutput.cpp, src/SVGTree.cpp, src/Unicode.cpp, src/XMLNode.cpp, + src/XMLParser.cpp, src/XMLString.cpp, src/dvisvgm.cpp, src/utility.cpp: + adapted types of variables used for string positions + + * src/DvisvgmSpecialHandler.cpp: + reordered if/else statement + + * src/MiKTeXCom.cpp: + replaced C-style cast + +2022-07-22 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicsPathParser.hpp: + updated year in copyright statement + + * src/XMLParser.cpp: + handle GraphicsPathParserExceptions in XMLParser + + * src/GraphicsPathParser.hpp: + improved position information of GraphicsPathParserException + +2022-07-18 Martin Gieseking <martin.gieseking@uos.de> + + * libs/woff2/include/woff2/encode.h, libs/woff2/include/woff2/output.h, + libs/woff2/src/font.cc, libs/woff2/src/glyph.cc, libs/woff2/src/glyph.h, + libs/woff2/src/normalize.cc, libs/woff2/src/transform.cc, + libs/woff2/src/woff2_enc.cc, libs/woff2/src/woff2_out.cc: + applied latest upstream changes to woff2 + library +https://github.com/google/woff2/commit/62ae7a4c1ec7fb38adbf1294924db5924489889a + + * libs/woff2/src/normalize.cc, libs/woff2/src/woff2_enc.cc: + woff2: removed unused variables to prevent compiler warnings + + * libs/woff2/src/font.cc, libs/woff2/src/normalize.cc: + woff2: adapted variable types to prevent warnings + + * src/dvisvgm.cpp: + added prefix to XML error messages + +2022-07-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/MiKTeXCom.cpp: + updated output of MiKTeX version number + + * src/PDFParser.cpp: + prevent warning about [[nodiscard]] return value + +2022-07-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicsPathParser.hpp: + minor code tweaks in GraphicsPathParser + + * src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.hpp, + src/Makefile.am, src/XMLParser.cpp, src/XMLParser.hpp, + tests/DvisvgmSpecialTest.cpp: + moved XMLParser from DvisvgmSpecialHandler to separate class + + * src/XMLParser.cpp: + parse and reformat definitions of raw graphics paths + +2022-06-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/XMLNode.cpp, src/XMLNode.hpp, src/optimizer/GroupCollapser.cpp: + optimizer: improved removal of redundant group elements + + * src/XMLNode.cpp, src/XMLNode.hpp, src/optimizer/AttributeExtractor.cpp, + src/optimizer/AttributeExtractor.hpp, src/optimizer/GroupCollapser.cpp, + src/optimizer/TextSimplifier.cpp: + moved inheritability check of attributes to Attribute struct + +2022-06-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontWriter.cpp: + ensure proper representation of empty glyphs in SFD files + +2022-06-25 Martin Gieseking <martin.gieseking@uos.de> + + * src/FileFinder.cpp, src/FontManager.cpp: + ignore letter case when looking up file suffixes + + * src/FileFinder.cpp: + MiKTeX: handle lookup of TrueType files similar to kpathsea +Look for + .ttf, .ttc, and .dfont suffixes + + * src/FontManager.cpp: + XFontDef: lookup font formats rather than specific suffixes + +2022-06-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontManager.cpp: + XFontDef: added support for font filenames without suffix + +2022-05-18 Martin Gieseking <martin.gieseking@uos.de> + + * README.md: + Removed paragraph about Ghostscript's new PDF interpreter + +because the + old interpreter is still available in recent GS releases and can be + reactivated by dvisvgm. + +2022-04-20 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, + src/version.hpp: + set version to 2.13.4 + + * NEWS: + updated NEWS + +2022-04-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSInterpreter.cpp: + updated URL to GS documentation of -dNEWPDF + +2022-04-01 Martin Gieseking <martin.gieseking@uos.de> + + * m4/ax_cxx_compile_stdcxx.m4: + updated ax_cxx_compile_stdcxx.m4 to version 14 + +2022-03-31 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml: + updated FreeType to version 2.12 + +2022-03-30 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml: + updated zlib to version 1.2.12 + + * src/PSInterpreter.cpp: + disable new PDF interpreter when using GS >= 9.56.0 + +2022-03-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/ImageToSVG.cpp: + reset bounding box before converting next PDF page +closes #182 + 2022-02-27 Martin Gieseking <martin.gieseking@uos.de> * .appveyor.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, @@ -1341,6 +1505,12 @@ image processing is stopped now instead of leaving GS with an * doc/dvisvgm.txt.in: manpage: added info on default values listed by --help +2020-01-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/GraphicsPathParser.hpp, src/Makefile.am, + tests/GraphicsPathParserTest.cpp, tests/Makefile.am: + added class to parse SVG path commands + 2020-01-17 Martin Gieseking <martin.gieseking@uos.de> * src/GraphicsPath.hpp: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS index a0cc6867abd..526c45d3677 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS +++ b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS @@ -1,3 +1,18 @@ +dvisvgm-2.14 (2022-08-12) +- added processing of SVG path elements inserted by "raw" specials in order to + treat them similar to generated ones +- added support for native font references lacking a file name suffix +- improved lookup of native fonts +- improved the removal of redundant SVG group elements +- fixed conversion of empty glyphs to TTF/WOFF +- updated bundled WOFF2 library + +dvisvgm-2.13.4 (2022-04-20) +- fixed the size of bounding boxes applied when converting multiple pages + (GH issue #182) +- try to enable old PDF interpreter when using Ghostscript >= 9.56.0 + (dvisvgm does not work with Ghostscript's new PDF interpreter) + dvisvgm-2.13.3 (2022-02-27) - added SVG optimizer module 'reassign-clippaths' that searches for duplicate clipPath elements, removes them, and updates the clip-path references diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/config.h.in b/Build/source/texk/dvisvgm/dvisvgm-src/config.h.in index a794f4e6744..a853374f69d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/config.h.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/config.h.in @@ -46,9 +46,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H @@ -68,6 +65,9 @@ /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H +/* Define to 1 if you have the <stdio.h> header file. */ +#undef HAVE_STDIO_H + /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H @@ -146,7 +146,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Define to 1 if you have the ANSI C header files. */ +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* The machine triplet of the target system */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac index 5c25b9a4259..b64216e5c73 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac +++ b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac @@ -4,8 +4,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([dvisvgm],[2.13.3],[martin.gieseking@uos.de]) -DATE="February 2022" +AC_INIT([dvisvgm],[2.14],[martin.gieseking@uos.de]) +DATE="August 2022" AC_CONFIG_SRCDIR(src) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in index f4ca0d3ef25..0bb4ef65463 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -94,12 +94,7 @@ host_triplet = @host@ target_triplet = @target@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -184,6 +179,8 @@ CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ @@ -199,8 +196,10 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ FREETYPE_LIBS = @FREETYPE_LIBS@ GCOV = @GCOV@ @@ -349,9 +348,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign doc/Makefile + $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -425,7 +424,6 @@ ctags CTAGS: cscope cscopelist: @BUILD_MANPAGE_TRUE@dist-hook: - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 index 9356f2910e0..abf067f3aac 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 @@ -4,10 +4,10 @@ .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 2022-02-26 .\" Manual: dvisvgm Manual -.\" Source: dvisvgm 2.13.3 +.\" Source: dvisvgm 2.14 .\" Language: English .\" -.TH "DVISVGM" "1" "2022\-02\-26" "dvisvgm 2\&.13\&.3" "dvisvgm Manual" +.TH "DVISVGM" "1" "2022\-02\-26" "dvisvgm 2\&.14" "dvisvgm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/Makefile.in index 3cd2af7d34b..f8e69f3dcbc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/Makefile.in @@ -267,7 +267,7 @@ am__define_uniq_tagged_files = \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ - $(top_srcdir)/../../build-aux/depcomp + $(top_srcdir)/../../build-aux/depcomp README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/README.md b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/README.md new file mode 100644 index 00000000000..28f094d9be6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/README.md @@ -0,0 +1,11 @@ +# Reduced FontForge library for dvisvgm + +This is a radically reduced version of the [FontForge](http://fontforge.org) library required to natively +build [dvisvgm](https://dvisvgm.de) on Windows. Most of the code not needed to create autohinted +TrueType and WOFF fonts from [SFD](https://fontforge.github.io/sfdformat.html) files has been removed. + +The reduced library depends on [zlib](http://www.zlib.net). + +--- +Thanks to George Williams and the FontForge project contributors for developing this great font editor and for +providing it as open source. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/encode.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/encode.h index 34b77229749..2ac563032d1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/encode.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/encode.h @@ -26,8 +26,8 @@ struct WOFF2Params { // Returns an upper bound on the size of the compressed file. size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length); -size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length, - const std::string& extended_metadata); +size_t MaxWOFF2CompressedSize(const uint8_t *data, size_t length, + const std::string &extended_metadata); // Compresses the font into the target buffer. *result_length should be at least // the value returned by MaxWOFF2CompressedSize(), upon return, it is set to the diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/output.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/output.h index c325f67be72..dc78ccf8267 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/output.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/include/woff2/output.h @@ -51,7 +51,7 @@ class WOFF2StringOut : public WOFF2Out { // Create a writer that writes its data to buf. // buf->size() will grow to at most max_size // buf may be sized (e.g. using EstimateWOFF2FinalSize) or empty. - explicit WOFF2StringOut(std::string* buf); + explicit WOFF2StringOut(std::string *buf); bool Write(const void *buf, size_t n) override; bool Write(const void *buf, size_t offset, size_t n) override; @@ -59,7 +59,7 @@ class WOFF2StringOut : public WOFF2Out { size_t MaxSize() { return max_size_; } void SetMaxSize(size_t max_size); private: - std::string* buf_; + std::string *buf_; size_t max_size_; size_t offset_; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.cc b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.cc index 1b4408b924c..5b4948679c7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.cc +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.cc @@ -21,6 +21,7 @@ static const int32_t kFLAG_YSHORT = 1 << 2; static const int32_t kFLAG_REPEAT = 1 << 3; static const int32_t kFLAG_XREPEATSIGN = 1 << 4; static const int32_t kFLAG_YREPEATSIGN = 1 << 5; +static const int32_t kFLAG_OVERLAP_SIMPLE = 1 << 6; static const int32_t kFLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0; static const int32_t kFLAG_WE_HAVE_A_SCALE = 1 << 3; static const int32_t kFLAG_MORE_COMPONENTS = 1 << 5; @@ -134,6 +135,10 @@ bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) { } } + if (!flags.empty() && !flags[0].empty()) { + glyph->overlap_simple_flag_set = (flags[0][0] & kFLAG_OVERLAP_SIMPLE); + } + // Read the x coordinates. int prev_x = 0; for (int i = 0; i < num_contours; ++i) { @@ -239,7 +244,7 @@ bool StoreEndPtsOfContours(const Glyph& glyph, size_t* offset, uint8_t* dst) { bool StorePoints(const Glyph& glyph, size_t* offset, uint8_t* dst, size_t dst_size) { - int last_flag = -1; + int previous_flag = -1; int repeat_count = 0; int last_x = 0; int last_y = 0; @@ -250,6 +255,10 @@ bool StorePoints(const Glyph& glyph, size_t* offset, for (const auto& contour : glyph.contours) { for (const auto& point : contour) { int flag = point.on_curve ? kFLAG_ONCURVE : 0; + if (previous_flag == -1 && glyph.overlap_simple_flag_set) { + // First flag needs to have overlap simple bit set. + flag = flag | kFLAG_OVERLAP_SIMPLE; + } int dx = point.x - last_x; int dy = point.y - last_y; if (dx == 0) { @@ -268,7 +277,7 @@ bool StorePoints(const Glyph& glyph, size_t* offset, } else { y_bytes += 2; } - if (flag == last_flag && repeat_count != 255) { + if (flag == previous_flag && repeat_count != 255) { dst[*offset - 1] |= kFLAG_REPEAT; repeat_count++; } else { @@ -286,7 +295,7 @@ bool StorePoints(const Glyph& glyph, size_t* offset, } last_x = point.x; last_y = point.y; - last_flag = flag; + previous_flag = flag; } } if (repeat_count != 0) { @@ -350,7 +359,7 @@ bool StoreGlyph(const Glyph& glyph, uint8_t* dst, size_t* dst_size) { } } else if (glyph.contours.size() > 0) { // Simple glyph. - if (glyph.contours.size() > size_t(std::numeric_limits<int16_t>::max())) { + if (glyph.contours.size() > std::numeric_limits<int16_t>::max()) { return FONT_COMPRESSION_FAILURE(); } if (*dst_size < ((12ULL + 2 * glyph.contours.size()) + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.h index f24056f4c8c..c38eb5f2bc4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/glyph.h @@ -10,8 +10,10 @@ #ifndef WOFF2_GLYPH_H_ #define WOFF2_GLYPH_H_ -#include <stddef.h> #include <inttypes.h> +#include <stddef.h> + +#include <cstdint> #include <vector> namespace woff2 { @@ -22,7 +24,10 @@ namespace woff2 { // is around. class Glyph { public: - Glyph() : instructions_size(0), composite_data_size(0) {} + Glyph() + : instructions_size(0), + overlap_simple_flag_set(false), + composite_data_size(0) {} // Bounding box. int16_t x_min; @@ -34,6 +39,9 @@ class Glyph { uint16_t instructions_size; const uint8_t* instructions_data; + // Flags. + bool overlap_simple_flag_set; + // Data model for simple glyphs. struct Point { int x; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc index dc4bfe6c5c7..f7538a1ef31 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc @@ -93,7 +93,7 @@ bool MakeEditableBuffer(Font* font, int tableTag) { if (table->IsReused()) { return true; } - uint32_t sz = Round4(table->length); + unsigned sz = Round4(table->length); table->buffer.resize(sz); uint8_t* buf = &table->buffer[0]; memcpy(buf, table->data, table->length); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/transform.cc b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/transform.cc index 999bef37458..1016efcd2bb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/transform.cc +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/transform.cc @@ -22,6 +22,7 @@ namespace { const int FLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0; const int FLAG_WE_HAVE_INSTRUCTIONS = 1 << 8; +const int FLAG_OVERLAP_SIMPLE_BITMAP = 1 << 0; void WriteBytes(std::vector<uint8_t>* out, const uint8_t* data, size_t len) { if (len == 0) return; @@ -69,7 +70,10 @@ class GlyfEncoder { } void GetTransformedGlyfBytes(std::vector<uint8_t>* result) { - WriteLong(result, 0); // version + WriteUShort(result, 0); // Version + WriteUShort(result, overlap_bitmap_.empty() + ? 0x00 + : FLAG_OVERLAP_SIMPLE_BITMAP); // Flags WriteUShort(result, n_glyphs_); WriteUShort(result, 0); // index_format, will be set later WriteLong(result, n_contour_stream_.size()); @@ -87,6 +91,9 @@ class GlyfEncoder { WriteBytes(result, bbox_bitmap_); WriteBytes(result, bbox_stream_); WriteBytes(result, instruction_stream_); + if (!overlap_bitmap_.empty()) { + WriteBytes(result, overlap_bitmap_); + } } private: @@ -127,6 +134,10 @@ class GlyfEncoder { } void WriteSimpleGlyph(int glyph_id, const Glyph& glyph) { + if (glyph.overlap_simple_flag_set) { + EnsureOverlapBitmap(); + overlap_bitmap_[glyph_id >> 3] |= 0x80 >> (glyph_id & 7); + } int num_contours = glyph.contours.size(); WriteUShort(&n_contour_stream_, num_contours); if (ShouldWriteSimpleGlyphBbox(glyph)) { @@ -214,6 +225,12 @@ class GlyfEncoder { } } + void EnsureOverlapBitmap() { + if (overlap_bitmap_.empty()) { + overlap_bitmap_.resize((n_glyphs_ + 7) >> 3); + } + } + std::vector<uint8_t> n_contour_stream_; std::vector<uint8_t> n_points_stream_; std::vector<uint8_t> flag_byte_stream_; @@ -222,6 +239,7 @@ class GlyfEncoder { std::vector<uint8_t> bbox_stream_; std::vector<uint8_t> glyph_stream_; std::vector<uint8_t> instruction_stream_; + std::vector<uint8_t> overlap_bitmap_; int n_glyphs_; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_enc.cc b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_enc.cc index 9f32df90ee4..43c8bdc9d82 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_enc.cc +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_enc.cc @@ -28,12 +28,8 @@ namespace woff2 { -namespace { - - -using std::string; -using std::vector; +namespace { const size_t kWoff2HeaderSize = 48; const size_t kWoff2EntrySize = 20; @@ -183,7 +179,7 @@ size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length) { } size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length, - const string& extended_metadata) { + const std::string& extended_metadata) { // Except for the header size, which is 32 bytes larger in woff2 format, // all other parts should be smaller (table header in short format, // transformations and compression). Just to be sure, we will give some diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_out.cc b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_out.cc index 8ab32681f1d..a22d3bf8bed 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_out.cc +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/woff2_out.cc @@ -8,14 +8,10 @@ #include <woff2/output.h> -using std::string; - namespace woff2 { -WOFF2StringOut::WOFF2StringOut(string* buf) - : buf_(buf), - max_size_(kDefaultMaxSize), - offset_(0) {} +WOFF2StringOut::WOFF2StringOut(std::string *buf) + : buf_(buf), max_size_(kDefaultMaxSize), offset_(0) {} bool WOFF2StringOut::Write(const void *buf, size_t n) { return Write(buf, offset_, n); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp index 17ba2c2d1f3..e8b538e7837 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp @@ -154,7 +154,7 @@ void CommandLine::parseLongOption (istream &is) { /** Returns all options that match the given long name. */ vector<Option*> CommandLine::lookupOption (const string &optname) const { vector<Option*> matches; - int len = optname.length(); + auto len = optname.length(); for (OptSectPair optsect : options()) { if (optsect.first->longName() == optname) { // exact match? matches.clear(); @@ -187,7 +187,7 @@ void CommandLine::help (ostream &os, int mode) const { string usage = _usage; int count=0; while (!usage.empty()) { - size_t pos = usage.find('\n'); + auto pos = usage.find('\n'); os << (count++ == 0 ? "Usage: " : " ") << PROGRAM_NAME << ' ' << usage.substr(0, pos) << '\n'; if (pos != string::npos) usage = usage.substr(pos+1); @@ -201,7 +201,7 @@ void CommandLine::help (ostream &os, int mode) const { unordered_map<Option*, pair<string,string>> linecols; size_t col1width=0; for (const OptSectPair &ospair : options()) { - size_t pos; + string::size_type pos; string line = ospair.first->helpline(); if ((pos = line.find('\t')) != string::npos) { linecols.emplace(ospair.first, pair<string,string>(line.substr(0, pos), line.substr(pos+1))); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp index 5979745e4c3..cedc1a7c57e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp @@ -66,7 +66,7 @@ string SegmentedCMap::getROString() const { bool SegmentedCMap::mapsToUnicode () const { vector<string> encstrings = {"UTF8", "UTF16", "UCS2", "UCS4", "UCS32"}; for (const string &encstr : encstrings) { - size_t pos = _filename.find(encstr); + auto pos = _filename.find(encstr); if (pos != string::npos && (pos == 0 || _filename[pos-1] == '-')) return true; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp index 094dd6e499b..b8c5bc449e7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp @@ -460,7 +460,7 @@ const Font* DVIReader::defineFont (uint32_t fontnum, const string &name, uint32_ Font *font = fm.getFont(fontnum); if (!font && !name.empty()) { // font not registered yet? if (name[0] == '[') { // LuaTeX native font reference? - size_t last = name.rfind(']'); + auto last = name.rfind(']'); if (last != string::npos) { string path = name.substr(1, last-1); FontStyle style; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp index 077e030776d..1acef64f0ee 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp @@ -153,19 +153,19 @@ bool DvisvgmSpecialHandler::process (const string &prefix, istream &is, SpecialA static void expand_constants (string &str, SpecialActions &actions) { bool repl_bbox = true; while (repl_bbox) { - size_t pos = str.find("{?bbox "); + const auto pos = str.find("{?bbox "); if (pos == string::npos) repl_bbox = false; else { - size_t endpos = pos+7; + auto endpos = pos+7; while (endpos < str.length() && isalnum(str[endpos])) ++endpos; - if (str[endpos] == '}') { - BoundingBox &box=actions.bbox(str.substr(pos+7, endpos-pos-7)); + if (str[endpos] != '}') + repl_bbox = false; + else { + BoundingBox &box = actions.bbox(str.substr(pos+7, endpos-pos-7)); str.replace(pos, endpos-pos+1, box.svgViewBoxString()); } - else - repl_bbox = false; } } struct Constant { @@ -181,7 +181,7 @@ static void expand_constants (string &str, SpecialActions &actions) { }}; for (const Constant &constant : constants) { const string pattern = string("{?")+constant.name+"}"; - size_t pos = str.find(pattern); + auto pos = str.find(pattern); while (pos != string::npos) { str.replace(pos, strlen(constant.name)+3, constant.val); pos = str.find(pattern, pos+constant.val.length()); // look for further matches @@ -194,9 +194,9 @@ static void expand_constants (string &str, SpecialActions &actions) { * and replaces the substring by the computed value. * @param[in,out] str string to scan for expressions */ static void evaluate_expressions (string &str, const SpecialActions &actions) { - size_t left = str.find("{?("); // start position of expression macro + auto left = str.find("{?("); // start position of expression macro while (left != string::npos) { - size_t right = str.find(")}", left+2); // end position of expression macro + auto right = str.find(")}", left+2); // end position of expression macro if (right == string::npos) break; Calculator calc; @@ -232,7 +232,7 @@ void DvisvgmSpecialHandler::processRaw (InputReader &ir, SpecialActions &actions if (!xml.empty()) { evaluate_expressions(xml, actions); expand_constants(xml, actions); - _pageParser.parse(xml, actions); + _pageParser.parse(xml, actions.svgTree()); } } } @@ -244,7 +244,7 @@ void DvisvgmSpecialHandler::processRawDef (InputReader &ir, SpecialActions &acti if (!xml.empty()) { evaluate_expressions(xml, actions); expand_constants(xml, actions); - _defsParser.parse(xml, actions); + _defsParser.parse(xml, actions.svgTree()); } } } @@ -276,9 +276,9 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &acti if ((type == 'P' || type == 'D') && !def.empty()) { expand_constants(def, actions); if (type == 'P') - _pageParser.parse(def, actions); + _pageParser.parse(def, actions.svgTree()); else { // type == 'D' - _defsParser.parse(def, actions); + _defsParser.parse(def, actions.svgTree()); type = 'L'; // locked } } @@ -414,8 +414,8 @@ void DvisvgmSpecialHandler::dviPreprocessingFinished () { void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions &actions) { - _defsParser.finish(actions); - _pageParser.finish(actions); + _defsParser.finish(actions.svgTree()); + _pageParser.finish(actions.svgTree()); actions.bbox().unlock(); for (auto &strvecpair : _macros) { StringVector &vec = strvecpair.second; @@ -432,147 +432,3 @@ vector<const char*> DvisvgmSpecialHandler::prefixes() const { vector<const char*> pfx {"dvisvgm:"}; return pfx; } - -//////////////////////////////////////////////////////////////////////////////// - -/** Parses a fragment of XML code, creates corresponding XML nodes and adds them - * to the SVG tree. The code may be split and processed by several calls of this - * function. Incomplete chunks that can't be processed yet are stored and picked - * up again together with the next incoming XML fragment. If a call of this function - * is supposed to finish the parsing of an XML subtree, parameter 'finish' must be set. - * @param[in] xml XML fragment to parse - * @param[in] actions object providing the SVG tree functions - * @param[in] finish if true, no more XML is expected and parsing is finished */ -void DvisvgmSpecialHandler::XMLParser::parse (const string &xml, SpecialActions &actions, bool finish) { - // collect/extract an XML fragment that only contains complete tags - // incomplete tags are held back - _xmlbuf += xml; - size_t left=0; - try { - while (left != string::npos) { - size_t right = _xmlbuf.find('<', left); - if (left < right && left < _xmlbuf.length()) // plain text found? - (actions.svgTree().*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right-left))); - if (right != string::npos) { - left = right; - if (_xmlbuf.compare(left, 9, "<![CDATA[") == 0) { - right = _xmlbuf.find("]]>", left+9); - if (right == string::npos) { - if (finish) throw SpecialException("expected ']]>' at end of CDATA block"); - break; - } - (actions.svgTree().*_append)(util::make_unique<XMLCData>(_xmlbuf.substr(left+9, right-left-9))); - right += 2; - } - else if (_xmlbuf.compare(left, 4, "<!--") == 0) { - right = _xmlbuf.find("-->", left+4); - if (right == string::npos) { - if (finish) throw SpecialException("expected '-->' at end of comment"); - break; - } - (actions.svgTree().*_append)(util::make_unique<XMLComment>(_xmlbuf.substr(left+4, right-left-4))); - right += 2; - } - else if (_xmlbuf.compare(left, 2, "<?") == 0) { - right = _xmlbuf.find("?>", left+2); - if (right == string::npos) { - if (finish) throw SpecialException("expected '?>' at end of processing instruction"); - break; - } - (actions.svgTree().*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right-left+2))); - right++; - } - else if (_xmlbuf.compare(left, 2, "</") == 0) { - right = _xmlbuf.find('>', left+2); - if (right == string::npos) { - if (finish) throw SpecialException("missing '>' at end of closing XML tag"); - break; - } - closeElement(_xmlbuf.substr(left+2, right-left-2), actions); - } - else { - right = _xmlbuf.find('>', left+1); - if (right == string::npos) { - if (finish) throw SpecialException("missing '>' or '/>' at end of opening XML tag"); - break; - } - openElement(_xmlbuf.substr(left+1, right-left-1), actions); - } - } - left = right; - if (right != string::npos) - left++; - } - } - catch (const SpecialException &e) { - _error = true; - throw; - } - if (left == string::npos) - _xmlbuf.clear(); - else - _xmlbuf.erase(0, left); -} - - -/** Processes an opening element tag. - * @param[in] tag tag without leading and trailing angle brackets */ -void DvisvgmSpecialHandler::XMLParser::openElement (const string &tag, SpecialActions &actions) { - StringInputBuffer ib(tag); - BufferInputReader ir(ib); - string name = ir.getString("/ \t\n\r"); - ir.skipSpace(); - auto elemNode = util::make_unique<SVGElement>(name); - map<string, string> attribs; - if (ir.parseAttributes(attribs, true, "\"'")) { - for (const auto &attrpair : attribs) - elemNode->addAttribute(attrpair.first, attrpair.second); - } - ir.skipSpace(); - if (ir.peek() == '/') // end of empty element tag - (actions.svgTree().*_append)(std::move(elemNode)); - else if (ir.peek() < 0) { // end of opening tag - _nameStack.push_back(name); - (actions.svgTree().*_pushContext)(std::move(elemNode)); - } - else - throw SpecialException("'>' or '/>' expected at end of opening tag <"+name); -} - - -/** Processes a closing element tag. - * @param[in] tag tag without leading and trailing angle brackets */ -void DvisvgmSpecialHandler::XMLParser::closeElement (const string &tag, SpecialActions &actions) { - StringInputBuffer ib(tag); - BufferInputReader ir(ib); - string name = ir.getString(" \t\n\r"); - ir.skipSpace(); - if (ir.peek() >= 0) - throw SpecialException("'>' expected at end of closing tag </"+name); - if (_nameStack.empty()) - throw SpecialException("spurious closing tag </" + name + ">"); - if (_nameStack.back() != name) - throw SpecialException("expected </" + _nameStack.back() + "> but found </" + name + ">"); - (actions.svgTree().*_popContext)(); - _nameStack.pop_back(); -} - - -/** Processes any remaining XML fragments, checks for missing closing tags, - * and resets the parser state. */ -void DvisvgmSpecialHandler::XMLParser::finish (SpecialActions &actions) { - if (!_xmlbuf.empty()) { - if (!_error) - parse("", actions, true); - _xmlbuf.clear(); - } - string tags; - while (!_nameStack.empty()) { - tags += "</"+_nameStack.back()+">, "; - _nameStack.pop_back(); - } - if (!tags.empty() && !_error) { - tags.resize(tags.length()-2); - throw SpecialException("missing closing tag(s): "+tags); - } -} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp index f5ae43f4118..7d1ad20cfed 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp @@ -26,6 +26,7 @@ #include <unordered_map> #include <vector> #include "SpecialHandler.hpp" +#include "XMLParser.hpp" class InputReader; class SpecialActions; @@ -43,32 +44,6 @@ class XMLNode; #endif class DvisvgmSpecialHandler : public SpecialHandler { - class XMLParser { - using AppendFunc = void (SVGTree::*)(std::unique_ptr<XMLNode>); - using PushFunc = void (SVGTree::*)(std::unique_ptr<SVGElement>); - using PopFunc = void (SVGTree::*)(); - using NameStack = std::vector<std::string>; - - public: - XMLParser (AppendFunc append, PushFunc push, PopFunc pop) - : _append(append), _pushContext(push), _popContext(pop) {} - - void parse (const std::string &xml, SpecialActions &actions, bool finish=false); - void finish (SpecialActions &actions); - - protected: - void openElement (const std::string &tag, SpecialActions &actions); - void closeElement (const std::string &tag, SpecialActions &actions); - - private: - AppendFunc _append; - PushFunc _pushContext; - PopFunc _popContext; - std::string _xmlbuf; - NameStack _nameStack; ///< names of nested elements still missing a closing tag - bool _error=false; - }; - using StringVector = std::vector<std::string>; using MacroMap = std::unordered_map<std::string, StringVector>; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp index e7efe2786f3..c95ab1023f8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp @@ -21,7 +21,6 @@ #include <config.h> #ifdef MIKTEX #include "MiKTeXCom.hpp" - #include "utility.hpp" #else #ifdef KPSE_CXX_UNSAFE extern "C" { @@ -43,6 +42,7 @@ #include "Message.hpp" #include "MessageException.hpp" #include "Process.hpp" +#include "utility.hpp" std::string FileFinder::_argv0; std::string FileFinder::_progname; @@ -120,12 +120,12 @@ const char* FileFinder::findFile (const std::string &fname, const char *ftype) c if (ftype) ext = ftype; else { - size_t pos = fname.rfind('.'); + auto pos = fname.rfind('.'); if (pos == std::string::npos) return nullptr; // no extension and no file type => no search ext = fname.substr(pos+1); } - + ext = util::tolower(ext); #ifdef _WIN32 if (ext == "dll" || ext == "exe") return lookupExecutable(fname); @@ -140,7 +140,18 @@ const char* FileFinder::findFile (const std::string &fname, const char *ftype) c return _pathbuf.empty() ? nullptr : _pathbuf.c_str(); } try { - return _miktex->findFile(fname.c_str()); + if (!ftype) // no file type given? + return _miktex->findFile(fname.c_str()); // lookup given filename + // handle file type "ttf" similar to kpathsea and look for .ttf, .ttc, and .dfont + std::vector<std::string> suffixes{ext}; + if (ext == "ttf") { + suffixes.emplace_back("ttc"); + suffixes.emplace_back("dfont"); + } + for (const auto &suffix : suffixes) { + if (const char *path = _miktex->findFile((fname+"."+suffix).c_str())) + return path; + } } catch (const MessageException &e) { return nullptr; @@ -181,8 +192,8 @@ const char* FileFinder::findFile (const std::string &fname, const char *ftype) c std::free(path); return _pathbuf.c_str(); } - return nullptr; #endif // !MIKTEX + return nullptr; } @@ -191,7 +202,7 @@ const char* FileFinder::findFile (const std::string &fname, const char *ftype) c * @param[in] fname name of file to look up * @return file path on success, 0 otherwise */ const char* FileFinder::findMappedFile (std::string fname) const { - size_t pos = fname.rfind('.'); + auto pos = fname.rfind('.'); if (pos == std::string::npos) return nullptr; const std::string ext = fname.substr(pos+1); // file extension @@ -214,7 +225,7 @@ const char* FileFinder::findMappedFile (std::string fname) const { * @param[in] fname name of file to build * @return file path on success, 0 otherwise */ const char* FileFinder::mktex (const std::string &fname) const { - size_t pos = fname.rfind('.'); + auto pos = fname.rfind('.'); if (!_enableMktex || pos == std::string::npos) return nullptr; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp index 998204b6840..3c89c2c3ea0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp @@ -29,7 +29,7 @@ using namespace std; /** Removes redundant slashes from a given path. */ static string& single_slashes (string &str) { - size_t pos=0; + string::size_type pos=0; while ((pos = str.find("//", pos)) != string::npos) str.replace(pos, 2, "/"); return str; @@ -124,7 +124,7 @@ void FilePath::init (string path, bool isfile, string current_dir) { path = FileSystem::ensureForwardSlashes(path); #endif if (isfile) { - size_t pos = path.rfind('/'); + auto pos = path.rfind('/'); _fname = path.substr((pos == string::npos) ? 0 : pos+1); // remove filename from path if (pos == 0 && _fname.length() > 1) // file in root directory? @@ -163,12 +163,12 @@ void FilePath::add (const string &dir) { * location of a directory (and not of a file) an empty string * is returned. */ string FilePath::suffix () const { - size_t start = 0; + string::size_type start = 0; // ignore leading dots while (start < _fname.length() && _fname[start] == '.') start++; string sub = _fname.substr(start); - size_t pos = sub.rfind('.'); + auto pos = sub.rfind('.'); if (pos != string::npos && pos < sub.length()-1) return sub.substr(pos+1); return ""; @@ -194,7 +194,7 @@ void FilePath::suffix (const string &newSuffix) { * Example: FilePath("/a/b/c.def", true) == "c" */ string FilePath::basename () const { if (!_fname.empty()) { - size_t len = suffix().length(); + auto len = suffix().length(); if (len > 0) len++; // strip dot too return _fname.substr(0, _fname.length()-len); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp index 9627c421e21..2fa4ce5be98 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp @@ -54,7 +54,7 @@ const FontEncoding* Font::encoding () const { const FontMap::Entry* Font::fontMapEntry () const { string fontname = name(); - size_t pos = fontname.rfind('.'); + auto pos = fontname.rfind('.'); if (pos != string::npos) fontname = fontname.substr(0, pos); // strip extension return FontMap::instance().lookup(fontname); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp index 2262346c60d..e85a9dc5283 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp @@ -145,7 +145,7 @@ const VirtualFont* FontManager::getVF () const { static unique_ptr<Font> create_font (const string &filename, const string &fontname, int fontindex, uint32_t checksum, double dsize, double ssize) { string ext; if (const char *dot = strrchr(filename.c_str(), '.')) - ext = dot+1; + ext = util::tolower(dot+1); if (!ext.empty() && FileFinder::instance().lookup(filename)) { if (ext == "pfb") return PhysicalFont::create(fontname, checksum, dsize, ssize, PhysicalFont::Type::PFB); @@ -271,8 +271,13 @@ int FontManager::registerFont (uint32_t fontnum, string filename, int fontIndex, newfont = font->clone(ptsize, style, color); } else { - if (!FileSystem::exists(path)) - path = FileFinder::instance().lookup(filename, false); + if (!FileSystem::exists(path)) { + const char *fontFormats[] = {nullptr, "otf", "ttf"}; + for (const char *format : fontFormats) { + if ((path = FileFinder::instance().lookup(filename, format, false)) != nullptr) + break; + } + } if (path) { newfont.reset(new NativeFontImpl(path, fontIndex, ptsize, style, color)); newfont->findAndAssignBaseFontMap(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp index e5c0caef5de..c9e2f8912c2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp @@ -125,13 +125,13 @@ bool FontMap::apply (const MapLine& mapline, char modechar) { * @return true if at least one of the given map files was found */ bool FontMap::read (const string &fname_seq) { bool found = false; - size_t left=0; + string::size_type left=0; while (left < fname_seq.length()) { const char modechar = fname_seq[left]; if (strchr("+-=", modechar)) left++; string fname; - size_t right = fname_seq.find(',', left); + auto right = fname_seq.find(',', left); if (right != string::npos) fname = fname_seq.substr(left, right-left); else { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp index b05f63c3dff..0f7946f5677 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp @@ -128,7 +128,7 @@ struct SFDActions : Glyph::IterationActions { } ostream &_os; - Glyph::Point _startPoint, _currentPoint; + Glyph::Point _startPoint, _currentPoint; }; @@ -174,8 +174,12 @@ static void writeSFD (const string &sfdname, const PhysicalFont &font, const set "SplineSet\n"; Glyph glyph; if (font.getGlyph(c, glyph, cb)) { - SFDActions actions(sfd); - glyph.iterate(actions, false); + if (glyph.empty()) + sfd << "0 0 m 0\n"; + else { + SFDActions actions(sfd); + glyph.iterate(actions, false); + } } sfd << "EndSplineSet\n" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp new file mode 100644 index 00000000000..0106f21a522 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPathParser.hpp @@ -0,0 +1,299 @@ +/************************************************************************* +** GraphicsPathParser.hpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2022 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** This program is free software; you can redistribute it and/or ** +** modify it under the terms of the GNU General Public License as ** +** published by the Free Software Foundation; either version 3 of ** +** the License, or (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, but ** +** WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program; if not, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#pragma once + +#include <cctype> +#include <cstring> +#include <istream> +#include <sstream> +#include "GraphicsPath.hpp" +#include "MessageException.hpp" + + +struct GraphicsPathParserException : public MessageException { + explicit GraphicsPathParserException (const std::string &msg) : MessageException(msg) {} +}; + + +template <typename T> +class GraphicsPathParser { + public: + GraphicsPath<T> parse (std::istream &is); + + GraphicsPath<T> parse (const std::string &str) { + std::istringstream iss(str); + return parse(iss); + } + + protected: + template <typename NumType> + NumType parseNumberOfType (std::istream &is) const { + is >> std::ws; + NumType number; + is >> number; + if (is.fail()) + error("number expected", is); + is >> std::ws; + return number; + } + + T parseNumber (std::istream &is) const { + return parseNumberOfType<T>(is); + } + + Pair<T> parsePair (std::istream &is) { + T x = parseNumber(is); + skipCommaAndWhitespace(is); + T y = parseNumber(is); + return Pair<T>(x, y); + } + + void skipCommaAndWhitespace (std::istream &is) { + is >> std::ws; + if (is.peek() == ',') { + is.get(); + is >> std::ws; + } + } + + void parseMoveTo (std::istream &is, bool relative); + void parseClosePath (); + void parseLineTo (std::istream &is, bool relative); + void parseHorizontalLineTo (std::istream &is, bool relative); + void parseVerticalLineTo (std::istream &is, bool relative); + void parseCubicTo (std::istream &is, bool relative); + void parseShortCubicTo (std::istream &is, bool relative); + void parseQuadraticTo (std::istream &is, bool relative); + void parseShortQuadraticTo (std::istream &is, bool relative); + void parseArcTo (std::istream &is, bool relative); + + void error (const std::string &msg, std::istream &is) const { + std::string postext; + if (_startpos >= 0) { // valid start position? + if (is) + postext = " at position "+ std::to_string(is.tellg()-_startpos); + else + postext = " (premature end of data)"; + } + throw GraphicsPathParserException(msg + postext); + } + + private: + std::istream::pos_type _startpos=0; ///< stream position where the parsing started + GraphicsPath<T> *_path=nullptr; ///< path being parsed + Pair<T> _startPoint; ///< start point of current subpath + Pair<T> _currentPoint; ///< current point reached by last path command + Pair<T> _prevCtrlPoint; ///< last control point of preceding curve command +}; + + +/** Creates a GraphicsPath object from a SVG path data string read from a given input stream. + * @param[in] is stream to read from + * @return GraphicsPath object created from the SVG path description + * @throw GraphicsPathParserException if the path data contains syntax error */ +template <typename T> +GraphicsPath<T> GraphicsPathParser<T>::parse (std::istream &is) { + GraphicsPath<T> path; + _path = &path; + _startpos = is.tellg(); + _currentPoint = _startPoint = _prevCtrlPoint = Pair<T>(0, 0); + int cmd=0; + while (!is.eof()) { + is >> std::ws; + if (is.peek() < 0) + break; + if (isalpha(is.peek())) + cmd = is.get(); + else { + // further set of parameters appended to preceding command (command letter omitted) + skipCommaAndWhitespace(is); + // subsequent coordinate pairs of a "moveto" command lead to implicit "lineto" commands + // https://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands + if (cmd == 'M') + cmd = 'L'; + else if (cmd == 'm') + cmd = 'l'; + } + int lower_cmd = std::tolower(cmd); + bool relative = (cmd == lower_cmd); + switch (lower_cmd) { + case 'm': parseMoveTo(is, relative); break; + case 'z': parseClosePath(); break; + case 'l': parseLineTo(is, relative); break; + case 'h': parseHorizontalLineTo(is, relative); break; + case 'v': parseVerticalLineTo(is, relative); break; + case 'c': parseCubicTo(is, relative); break; + case 's': parseShortCubicTo(is, relative); break; + case 'q': parseQuadraticTo(is, relative); break; + case 't': parseShortQuadraticTo(is, relative); break; + case 'a': parseArcTo(is, relative); break; + case 0 : error("missing command at beginning of SVG path", is); + default : error("invalid SVG path command '"+std::string(1, char(cmd))+"'", is); + } + if (strchr("csqt", lower_cmd) == nullptr) // not a Bézier curve command? + _prevCtrlPoint = _currentPoint; // => no control point, use current point + } + _path = nullptr; + return path; +} + + +/** Parses a single parameter pair of a "moveto" command. */ +template <typename T> +void GraphicsPathParser<T>::parseMoveTo (std::istream &is, bool relative) { + Pair<T> p = parsePair(is); + if (!relative || _path->empty()) + _currentPoint = p; + else + _currentPoint += p; + _path->moveto(_currentPoint); + _startPoint = _currentPoint; +} + + +/** Handles a "closepath" command. */ +template <typename T> +void GraphicsPathParser<T>::parseClosePath () { + _path->closepath(); + _currentPoint = _startPoint; +} + + +/** Parses a single parameter pair of a "lineto" command. */ +template <typename T> +void GraphicsPathParser<T>::parseLineTo (std::istream &is, bool relative) { + Pair<T> p = parsePair(is); + if (relative) + _currentPoint += p; + else + _currentPoint = p; + _path->lineto(_currentPoint); +} + + +/** Parses a single parameter of a horizontal "lineto" command. */ +template <typename T> +void GraphicsPathParser<T>::parseHorizontalLineTo (std::istream &is, bool relative) { + T x = parseNumber(is); + if (relative) + _currentPoint += Pair<T>(x, 0); + else + _currentPoint = Pair<T>(x, _currentPoint.y()); + _path->lineto(_currentPoint); +} + + +/** Parses a single parameter of a vertical "lineto" command. */ +template <typename T> +void GraphicsPathParser<T>::parseVerticalLineTo (std::istream &is, bool relative) { + T y = parseNumber(is); + if (relative) + _currentPoint += Pair<T>(0, y); + else + _currentPoint = Pair<T>(_currentPoint.x(), y); + _path->lineto(_currentPoint); +} + + +/** Parses a single parameter set a "cubicto" (cubic Bézier curve) command. */ +template <typename T> +void GraphicsPathParser<T>::parseCubicTo (std::istream &is, bool relative) { + Pair<T> p1 = parsePair(is); + Pair<T> p2 = parsePair(is); + Pair<T> pe = parsePair(is); + if (!relative) + _currentPoint = pe; + else { + p1 += _currentPoint; + p2 += _currentPoint; + _currentPoint += pe; + } + _path->cubicto(p1, p2, _currentPoint); + _prevCtrlPoint = p2; +} + + +/** Parses a single parameter set a shorthand "cubicto" (cubic Bézier curve) command. */ +template <typename T> +void GraphicsPathParser<T>::parseShortCubicTo (std::istream &is, bool relative) { + Pair<T> p1 = _prevCtrlPoint + (_currentPoint-_prevCtrlPoint)*T(2); + Pair<T> p2 = parsePair(is); + Pair<T> pe = parsePair(is); + if (!relative) + _currentPoint = pe; + else { + p2 += _currentPoint; + _currentPoint += pe; + } + _path->cubicto(p1, p2, _currentPoint); + _prevCtrlPoint = p2; +} + + +/** Parses a single parameter set a "quadto" (quadratic Bézier curve) command. */ +template <typename T> +void GraphicsPathParser<T>::parseQuadraticTo (std::istream &is, bool relative) { + Pair<T> p1 = parsePair(is); + Pair<T> pe = parsePair(is); + if (!relative) + _currentPoint = pe; + else { + p1 += _currentPoint; + _currentPoint += pe; + } + _path->quadto(p1, _currentPoint); + _prevCtrlPoint = p1; +} + + +/** Parses a single parameter set a shorthand "quadto" (quadratic Bézier curve) command. */ +template <typename T> +void GraphicsPathParser<T>::parseShortQuadraticTo (std::istream &is, bool relative) { + Pair<T> p1 = _prevCtrlPoint + (_currentPoint-_prevCtrlPoint)*T(2); + Pair<T> pe = parsePair(is); + if (relative) + _currentPoint += pe; + else + _currentPoint = pe; + _path->quadto(p1, _currentPoint); + _prevCtrlPoint = p1; +} + + +/** Parses a single parameter set an "arcto" command. */ +template <typename T> +void GraphicsPathParser<T>::parseArcTo (std::istream &is, bool relative) { + Pair<T> r = parsePair(is); + double xrot = parseNumberOfType<double>(is); + int largeArgFlag = parseNumberOfType<int>(is); + if (largeArgFlag != 0 && largeArgFlag != 1) + error("large-arc-flag must be 0 or 1", is); + int sweepFlag = parseNumberOfType<int>(is); + if (sweepFlag != 0 && sweepFlag != 1) + error("sweep-flag must be 0 or 1", is); + T x = parseNumber(is); + T y = parseNumber(is); + Pair<T> p(x, y); + if (relative) + p += _currentPoint; + _currentPoint = p; + _path->arcto(r.x(), r.y(), xrot, bool(largeArgFlag), bool(sweepFlag), _currentPoint); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp index 15f7725543a..ecd938bcbb4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp @@ -28,7 +28,7 @@ /** Common base class for all hash functions. */ class HashFunction { - public: + public: virtual ~HashFunction () =default; virtual int digestSize () const =0; virtual void reset () =0; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp index 2371234499b..65ee534a32a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp @@ -229,7 +229,7 @@ void HyperlinkManager::createViews (unsigned pageno, SpecialActions &actions) { bool HyperlinkManager::setLinkMarker (const string &marker) { string type; // "none", "box", "line", or a background color specifier string color; // optional line color specifier - size_t seppos = marker.find(':'); + auto seppos = marker.find(':'); if (seppos == string::npos) type = marker; else { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp index 3e7ba17373e..99151db0e5a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp @@ -42,7 +42,7 @@ class HyperlinkManager { enum class ColorSource {DEFAULT, LINKMARKER, STATIC}; using NamedAnchors = std::unordered_map<std::string, NamedAnchor>; - public: + public: HyperlinkManager (const HyperlinkManager&) =delete; HyperlinkManager (HyperlinkManager&&) =delete; void addHrefAnchor (const std::string &uri); @@ -68,7 +68,7 @@ class HyperlinkManager { static Color LINK_LINECOLOR; ///< line color if linkmark type is LM_LINE or LM_BOX static ColorSource COLORSOURCE; ///< if true, LINK_LINECOLOR is applied - private: + private: AnchorType _anchorType=AnchorType::NONE; ///< type of active anchor int _depthThreshold=0; ///< break anchor box if the DVI stack depth underruns this threshold double _linewidth=-1; ///< line width of link marker (-1 => compute individual value per link) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp index e810f32e664..c38d3cc9b9b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp @@ -100,6 +100,7 @@ void ImageToSVG::convert (int pageno) { " x " << XMLString(_bbox.height()*bp2mm) << "mm)\n"; Message::mstream(false, Message::MC_PAGE_WRITTEN) << "output written to " << svgfname << '\n'; } + _bbox.invalidate(); _svg.reset(); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am index 065b869d72e..428be753b90 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -93,6 +93,7 @@ libdvisvgm_a_SOURCES = \ Glyph.hpp \ GlyphTracerMessages.hpp \ GraphicsPath.hpp \ + GraphicsPathParser.hpp \ HashFunction.hpp HashFunction.cpp \ HtmlSpecialHandler.hpp HtmlSpecialHandler.cpp \ HyperlinkManager.hpp HyperlinkManager.cpp \ @@ -163,6 +164,7 @@ libdvisvgm_a_SOURCES = \ windows.hpp \ XMLDocument.hpp XMLDocument.cpp \ XMLNode.hpp XMLNode.cpp \ + XMLParser.hpp XMLParser.cpp \ XMLString.hpp XMLString.cpp \ XXHashFunction.hpp \ ZLibOutputStream.hpp diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in index 450ad7a4570..8cd34c93625 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in @@ -170,8 +170,9 @@ am__libdvisvgm_a_SOURCES_DIST = AGLTable.hpp BasicDVIReader.hpp \ FontStyle.hpp FontWriter.hpp FontWriter.cpp GFGlyphTracer.hpp \ GFGlyphTracer.cpp GFReader.hpp GFReader.cpp GFTracer.hpp \ GFTracer.cpp Ghostscript.hpp Ghostscript.cpp Glyph.hpp \ - GlyphTracerMessages.hpp GraphicsPath.hpp HashFunction.hpp \ - HashFunction.cpp HtmlSpecialHandler.hpp HtmlSpecialHandler.cpp \ + GlyphTracerMessages.hpp GraphicsPath.hpp \ + GraphicsPathParser.hpp HashFunction.hpp HashFunction.cpp \ + HtmlSpecialHandler.hpp HtmlSpecialHandler.cpp \ HyperlinkManager.hpp HyperlinkManager.cpp ImageToSVG.hpp \ ImageToSVG.cpp InputBuffer.hpp InputBuffer.cpp InputReader.hpp \ InputReader.cpp JFM.hpp JFM.cpp Length.hpp Length.cpp \ @@ -209,8 +210,9 @@ am__libdvisvgm_a_SOURCES_DIST = AGLTable.hpp BasicDVIReader.hpp \ Unicode.cpp utility.hpp utility.cpp VectorIterator.hpp \ VectorStream.hpp VFActions.hpp VFReader.hpp VFReader.cpp \ windows.hpp XMLDocument.hpp XMLDocument.cpp XMLNode.hpp \ - XMLNode.cpp XMLString.hpp XMLString.cpp XXHashFunction.hpp \ - ZLibOutputStream.hpp ffwrapper.c ffwrapper.h + XMLNode.cpp XMLParser.hpp XMLParser.cpp XMLString.hpp \ + XMLString.cpp XXHashFunction.hpp ZLibOutputStream.hpp \ + ffwrapper.c ffwrapper.h @ENABLE_WOFF_TRUE@am__objects_1 = ffwrapper.$(OBJEXT) am_libdvisvgm_a_OBJECTS = BasicDVIReader.$(OBJEXT) Bezier.$(OBJEXT) \ BgColorSpecialHandler.$(OBJEXT) Bitmap.$(OBJEXT) \ @@ -252,7 +254,8 @@ am_libdvisvgm_a_OBJECTS = BasicDVIReader.$(OBJEXT) Bezier.$(OBJEXT) \ TpicSpecialHandler.$(OBJEXT) TriangularPatch.$(OBJEXT) \ TrueTypeFont.$(OBJEXT) TTFAutohint.$(OBJEXT) Unicode.$(OBJEXT) \ utility.$(OBJEXT) VFReader.$(OBJEXT) XMLDocument.$(OBJEXT) \ - XMLNode.$(OBJEXT) XMLString.$(OBJEXT) $(am__objects_1) + XMLNode.$(OBJEXT) XMLParser.$(OBJEXT) XMLString.$(OBJEXT) \ + $(am__objects_1) libdvisvgm_a_OBJECTS = $(am_libdvisvgm_a_OBJECTS) am_dvisvgm_OBJECTS = dvisvgm.$(OBJEXT) dvisvgm_OBJECTS = $(am_dvisvgm_OBJECTS) @@ -330,9 +333,9 @@ am__depfiles_remade = ./$(DEPDIR)/BasicDVIReader.Po \ ./$(DEPDIR)/TriangularPatch.Po ./$(DEPDIR)/TrueTypeFont.Po \ ./$(DEPDIR)/Unicode.Po ./$(DEPDIR)/VFReader.Po \ ./$(DEPDIR)/XMLDocument.Po ./$(DEPDIR)/XMLNode.Po \ - ./$(DEPDIR)/XMLString.Po ./$(DEPDIR)/dvisvgm.Po \ - ./$(DEPDIR)/ffwrapper.Po ./$(DEPDIR)/psdefs.Po \ - ./$(DEPDIR)/utility.Po + ./$(DEPDIR)/XMLParser.Po ./$(DEPDIR)/XMLString.Po \ + ./$(DEPDIR)/dvisvgm.Po ./$(DEPDIR)/ffwrapper.Po \ + ./$(DEPDIR)/psdefs.Po ./$(DEPDIR)/utility.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -636,8 +639,9 @@ libdvisvgm_a_SOURCES = AGLTable.hpp BasicDVIReader.hpp \ FontStyle.hpp FontWriter.hpp FontWriter.cpp GFGlyphTracer.hpp \ GFGlyphTracer.cpp GFReader.hpp GFReader.cpp GFTracer.hpp \ GFTracer.cpp Ghostscript.hpp Ghostscript.cpp Glyph.hpp \ - GlyphTracerMessages.hpp GraphicsPath.hpp HashFunction.hpp \ - HashFunction.cpp HtmlSpecialHandler.hpp HtmlSpecialHandler.cpp \ + GlyphTracerMessages.hpp GraphicsPath.hpp \ + GraphicsPathParser.hpp HashFunction.hpp HashFunction.cpp \ + HtmlSpecialHandler.hpp HtmlSpecialHandler.cpp \ HyperlinkManager.hpp HyperlinkManager.cpp ImageToSVG.hpp \ ImageToSVG.cpp InputBuffer.hpp InputBuffer.cpp InputReader.hpp \ InputReader.cpp JFM.hpp JFM.cpp Length.hpp Length.cpp \ @@ -675,8 +679,9 @@ libdvisvgm_a_SOURCES = AGLTable.hpp BasicDVIReader.hpp \ Unicode.cpp utility.hpp utility.cpp VectorIterator.hpp \ VectorStream.hpp VFActions.hpp VFReader.hpp VFReader.cpp \ windows.hpp XMLDocument.hpp XMLDocument.cpp XMLNode.hpp \ - XMLNode.cpp XMLString.hpp XMLString.cpp XXHashFunction.hpp \ - ZLibOutputStream.hpp $(am__append_8) + XMLNode.cpp XMLParser.hpp XMLParser.cpp XMLString.hpp \ + XMLString.cpp XXHashFunction.hpp ZLibOutputStream.hpp \ + $(am__append_8) EXTRA_DIST = options.xml options.dtd iapi.h ierrors.h MiKTeXCom.hpp MiKTeXCom.cpp AM_CFLAGS = $(WARNING_CFLAGS) $(ZLIB_INCLUDES) $(CODE_COVERAGE_CFLAGS) \ $(am__append_10) @@ -885,6 +890,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VFReader.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLDocument.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLNode.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLParser.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLString.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvisvgm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffwrapper.Po@am__quote@ # am--include-marker @@ -1245,6 +1251,7 @@ distclean: distclean-recursive -rm -f ./$(DEPDIR)/VFReader.Po -rm -f ./$(DEPDIR)/XMLDocument.Po -rm -f ./$(DEPDIR)/XMLNode.Po + -rm -f ./$(DEPDIR)/XMLParser.Po -rm -f ./$(DEPDIR)/XMLString.Po -rm -f ./$(DEPDIR)/dvisvgm.Po -rm -f ./$(DEPDIR)/ffwrapper.Po @@ -1388,6 +1395,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/VFReader.Po -rm -f ./$(DEPDIR)/XMLDocument.Po -rm -f ./$(DEPDIR)/XMLNode.Po + -rm -f ./$(DEPDIR)/XMLParser.Po -rm -f ./$(DEPDIR)/XMLString.Po -rm -f ./$(DEPDIR)/dvisvgm.Po -rm -f ./$(DEPDIR)/ffwrapper.Po diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp index 531550788d4..0c432cab237 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp @@ -37,7 +37,7 @@ MapLine::MapLine (istream &is) : MapLine() { MapLine::MapLine (string str) : MapLine() { - size_t pos = str.rfind('\n'); + auto pos = str.rfind('\n'); if (pos != string::npos) str = str.substr(0, pos); parse(str.c_str()); @@ -75,9 +75,9 @@ bool MapLine::isDVIPSFormat (const char *line) const { * @param[out] sfdname name of subfont definition * @return true on success */ static bool split_fontname (string &fontname, string &sfdname) { - size_t pos1; // index of first '@' + string::size_type pos1; // index of first '@' if ((pos1 = fontname.find('@')) != string::npos && pos1 > 0) { - size_t pos2; // index of second '@' + string::size_type pos2; // index of second '@' if ((pos2 = fontname.find('@', pos1+1)) != string::npos && pos2 > pos1+1) { sfdname = fontname.substr(pos1+1, pos2-pos1-1); fontname = fontname.substr(0, pos1) + fontname.substr(pos2+1); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp index bf1bbf1ba49..03c3e2b5ef9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp @@ -118,7 +118,7 @@ int MetafontWrapper::getResolution (const string &mfMessage) const { string line = buf; if (line.substr(0, 18) == "Output written on ") { line = line.substr(18); - size_t pos = line.find(' '); + auto pos = line.find(' '); line = line.substr(0, pos); pos = line.rfind('.'); if (pos != string::npos && line.substr(line.length()-2) == "gf") { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp index 7da0342f9f6..6f9d6f6e13b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp @@ -66,8 +66,7 @@ string MiKTeXCom::getVersion () { MiKTeXSetupInfo info; _session->GetMiKTeXSetupInfo(&info); #endif - _bstr_t version = info.version; - return string(version); + return to_string(info.series/100)+"."+ to_string(info.series%100); } @@ -105,6 +104,6 @@ const char* MiKTeXCom::findFile (const char *fname) { return nullptr; } catch (_com_error &e) { - throw MessageException((const char*)e.Description()); + throw MessageException(static_cast<const char*>(e.Description())); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp index 3d211b82bc3..84880e7b66d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Opacity.hpp @@ -48,11 +48,11 @@ class Opacity { BM_HUE, BM_SATURATION, BM_COLOR, BM_LUMINOSITY }; - public: + public: Opacity () =default; Opacity (OpacityAlpha fillalpha, OpacityAlpha strokealpha, BlendMode bm) : _fillalpha(fillalpha), _strokealpha(strokealpha), _blendMode(bm) {} Opacity (OpacityAlpha fillalpha, OpacityAlpha strokealpha) : Opacity(fillalpha, strokealpha, BM_NORMAL) {} - explicit Opacity (BlendMode bm) : _blendMode(bm) {} + explicit Opacity (BlendMode bm) : _blendMode(bm) {} OpacityAlpha& fillalpha () {return _fillalpha;} OpacityAlpha& strokealpha () {return _strokealpha;} const OpacityAlpha& fillalpha () const {return _fillalpha;} @@ -66,7 +66,7 @@ class Opacity { bool operator == (const Opacity &opacity) const; bool operator != (const Opacity &opacity) const; - private: + private: OpacityAlpha _fillalpha; OpacityAlpha _strokealpha; BlendMode _blendMode=BM_NORMAL; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp index 04b9fe661ca..5d00a5da58d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp @@ -207,7 +207,7 @@ static bool parse_number (const string &str, NumberVariant &nv) { if (str.empty()) return false; try { - size_t dotpos = str.find('.'); + auto dotpos = str.find('.'); if (dotpos == string::npos) { // not a real number? size_t count; nv = NumberVariant(stoi(str, &count, 10)); // then try to convert str to int @@ -218,7 +218,7 @@ static bool parse_number (const string &str, NumberVariant &nv) { // which is not allowed in PDF real number constants if (!postdot.empty() && isdigit(postdot[0])) { size_t count; - stoi(postdot, &count, 10); + static_cast<void>(stoi(postdot, &count, 10)); if (count != postdot.length()) return false; } @@ -310,7 +310,7 @@ static PDFObjectRef parse_object_ref (vector<PDFObject> &objects) { /** Replaces all occurences of "#XX" (XX are two hex digits) with the corresponding character. */ static string& subst_numeric_chars (string &str) { - for (size_t pos=str.find('#'); pos != string::npos; pos=str.find('#', pos+1)) { + for (auto pos=str.find('#'); pos != string::npos; pos=str.find('#', pos+1)) { if (pos > str.length()-3) throw PDFException("sign character # must be followed by two hexadecimal digits"); if (isxdigit(str[pos+1]) && isxdigit(str[pos+2])) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp index e796c760e33..cb74120309b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp @@ -63,6 +63,12 @@ void PSInterpreter::init () { gsargs.emplace_back("-dDELAYSAFER"); gsargs.emplace_back("-dALLOWPSTRANSPARENCY"); } + // GS 9.55.0 introduced a new, C-based PDF interpreter which is enabled by default + // as of GS 9.56.0. Since dvisvgm relies on the old PS-based interpreter for its + // PDF support, we try to disable the new one. + // https://www.ghostscript.com/doc/9.56.0/Use.htm#PDF_switches + if (gsrev >= 9560) + gsargs.emplace_back("-dNEWPDF=false"); } _gs.init(gsargs.size(), gsargs.data(), this); _gs.set_stdio(input, output, error); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp index 2fcdd917fb6..a1d29bfcb6e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp @@ -96,7 +96,7 @@ void PageSize::resize (string name) { name = util::tolower(name); // extract optional suffix - size_t pos = name.rfind('-'); + auto pos = name.rfind('-'); bool landscape = false; if (pos != string::npos) { string suffix = name.substr(pos); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp index 42a9fcbc1a0..557bea86798 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp @@ -28,7 +28,7 @@ void PapersizeSpecialHandler::preprocess (const string&, std::istream &is, Speci string params; is >> params; Length w, h; - const size_t splitpos = params.find(','); + const auto splitpos = params.find(','); try { if (splitpos == string::npos) { w.set(params); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index 45328fbd182..7ece9b16bad 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -190,7 +190,7 @@ void PsSpecialHandler::preprocess (const string &prefix, istream &is, SpecialAct static string filename_suffix (const string &fname) { string ret; - size_t pos = fname.rfind('.'); + auto pos = fname.rfind('.'); if (pos != string::npos) ret = util::tolower(fname.substr(pos+1)); return ret; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp index c326b79f879..d1103a8551d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGElement.hpp @@ -33,7 +33,7 @@ class SVGElement : public XMLElement { enum LineCap {LC_BUTT, LC_ROUND, LC_SQUARE}; enum LineJoin {LJ_BEVEL, LJ_MITER, LJ_ROUND}; - public: + public: explicit SVGElement (std::string name) : XMLElement(std::move(name)) {} explicit SVGElement (const XMLElement &node) : XMLElement(node) {} explicit SVGElement (XMLElement &&node) noexcept : XMLElement(std::move(node)) {} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp index 6ba41f1c7d3..013dd8f8f9f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp @@ -108,7 +108,7 @@ FilePath SVGOutput::filepath (int page, int numPages, const HashTriple &hashes) string SVGOutput::expandFormatString (string str, int page, int numPages, const HashTriple &hashes) const { string result; while (!str.empty()) { - size_t pos = str.find('%'); + auto pos = str.find('%'); if (pos == string::npos) { result += str; str.clear(); @@ -150,7 +150,7 @@ string SVGOutput::expandFormatString (string str, int page, int numPages, const result += oss.str(); break; case '(': { - size_t endpos = str.find(')', pos); + auto endpos = str.find(')', pos); if (endpos == string::npos) throw MessageException("missing ')' in filename pattern"); else if (endpos-pos-1 > 1) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp index f4cd9a85ef8..1fed40b443a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp @@ -92,7 +92,7 @@ void SVGTree::setFont (int num, const Font &font) { bool SVGTree::setFontFormat (string formatstr) { - size_t pos = formatstr.find(','); + auto pos = formatstr.find(','); string opt; if (pos != string::npos) { opt = formatstr.substr(pos+1); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp index 37da112757a..a5b88f180d8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp @@ -43,8 +43,8 @@ static void read_words (StreamReader &reader, vector<T> &v, unsigned n) { TFM::TFM (istream &is) : _checksum(0), _firstChar(0), _lastChar(0), _designSize(0), _ascent(0), _descent(0) { - if (!is) - return; + if (!is) + return; is.seekg(0); StreamReader reader(is); uint16_t lf = uint16_t(reader.readUnsigned(2)); // length of entire file in 4 byte words diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp index af35bdf9bd5..2293be03992 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp @@ -189,7 +189,7 @@ static const char* get_suffix (const string &name) { "small", "swash", "superior", "inferior", "numerator", "denominator", "oldstyle", "display", "text", "big", "bigg", "Big", "Bigg", 0 }; - size_t pos = name.rfind('.'); + auto pos = name.rfind('.'); if (pos != string::npos) { string suffix = name.substr(pos+1); for (const char **p=suffixes; *p; p++) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp index 743da58b93d..0f2602f8f06 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp @@ -103,6 +103,19 @@ void XMLElement::clear () { } +/** Returns true if element has no child nodes or, alternatively, only whitespace children. + * @param[in] ignoreWhitespace if true and if there are only whitespace children, the functions returns true */ +bool XMLElement::empty (bool ignoreWhitespace) const { + if (!_firstChild || !ignoreWhitespace) + return _firstChild == nullptr; + for (const XMLNode *node : *this) { + if (!node->toWSNode()) + return false; + } + return true; +} + + void XMLElement::addAttribute (const string &name, const string &value) { if (Attribute *attr = getAttribute(name)) attr->value = value; @@ -363,7 +376,7 @@ ostream& XMLElement::write (ostream &os) const { os << attrib.name << "='" << attrib.value << '\''; else { os << attrib.name.substr(1) << "='"; - size_t pos = attrib.value.find("base64,"); + auto pos = attrib.value.find("base64,"); if (pos == string::npos) os << attrib.value; else { @@ -434,6 +447,29 @@ const XMLElement::Attribute* XMLElement::getAttribute (const string &name) const } +/** Checks whether an SVG attribute A of an element E implicitly propagates its properties + * to all child elements of E that don't specify A. For now we only consider a subset of + * the inheritable properties. + * @return true if the attribute is inheritable */ +bool XMLElement::Attribute::inheritable () const { + // subset of inheritable properties listed on https://www.w3.org/TR/SVG11/propidx.html + // clip-path is not inheritable but can be moved to the parent element as long as + // no child gets an different clip-path attribute + // https://www.w3.org/TR/SVG11/styling.html#Inheritance + static const char *names[] = { + "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", + "color-rendering", "direction", "fill", "fill-opacity", "fill-rule", "font", "font-family", "font-size", + "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "glyph-orientation-horizontal", + "glyph-orientation-vertical", "letter-spacing", "paint-order", "stroke", "stroke-dasharray", "stroke-dashoffset", + "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "transform", + "visibility", "word-spacing", "writing-mode" + }; + return binary_search(std::begin(names), std::end(names), name, [](const string &name1, const string &name2) { + return name1 < name2; + }); +} + + ////////////////////// void XMLText::append (unique_ptr<XMLNode> node) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp index f1880352f20..fc34f05db85 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp @@ -118,6 +118,7 @@ class XMLElement : public XMLNode { public: struct Attribute { Attribute (std::string nam, std::string val) : name(std::move(nam)), value(std::move(val)) {} + bool inheritable () const; std::string name; std::string value; }; @@ -146,7 +147,7 @@ class XMLElement : public XMLNode { XMLNode* firstChild () const {return _firstChild.get();} XMLNode* lastChild () const {return _lastChild;} std::ostream& write (std::ostream &os) const override; - bool empty () const {return !_firstChild;} + bool empty (bool ignoreWhitespace=false) const; Attributes& attributes () {return _attributes;} const Attributes& attributes () const {return _attributes;} XMLNodeIterator begin () {return XMLNodeIterator(_firstChild.get());} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp new file mode 100644 index 00000000000..166a49e0cf3 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLParser.cpp @@ -0,0 +1,182 @@ +/************************************************************************* +** XMLParser.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2022 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** This program is free software; you can redistribute it and/or ** +** modify it under the terms of the GNU General Public License as ** +** published by the Free Software Foundation; either version 3 of ** +** the License, or (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, but ** +** WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program; if not, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include "InputReader.hpp" +#include "GraphicsPathParser.hpp" +#include "XMLParser.hpp" + +using namespace std; + +/** Parses a fragment of XML code, creates corresponding XML nodes and adds them + * to an SVG tree. The code may be split and processed by several calls of this + * function. Incomplete chunks that can't be processed yet are stored and picked + * up again together with the next incoming XML fragment. If a call of this function + * is supposed to finish the parsing of an XML subtree, parameter 'finish' must be set. + * @param[in] xml XML fragment to parse + * @param[in] svgTree the parsed nodes are added to this SVG tree + * @param[in] finish if true, no more XML is expected and parsing is finished */ +void XMLParser::parse (const string &xml, SVGTree &svgTree, bool finish) { + // collect/extract an XML fragment that only contains complete tags + // incomplete tags are held back + _xmlbuf += xml; + string::size_type left=0; + try { + while (left != string::npos) { + auto right = _xmlbuf.find('<', left); + if (left < right && left < _xmlbuf.length()) // plain text found? + (svgTree.*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right - left))); + if (right != string::npos) { + left = right; + if (_xmlbuf.compare(left, 9, "<![CDATA[") == 0) { + right = _xmlbuf.find("]]>", left+9); + if (right == string::npos) { + if (finish) throw XMLParserException("expected ']]>' at end of CDATA block"); + break; + } + (svgTree.*_append)(util::make_unique<XMLCData>(_xmlbuf.substr(left + 9, right - left - 9))); + right += 2; + } + else if (_xmlbuf.compare(left, 4, "<!--") == 0) { + right = _xmlbuf.find("-->", left+4); + if (right == string::npos) { + if (finish) throw XMLParserException("expected '-->' at end of comment"); + break; + } + (svgTree.*_append)(util::make_unique<XMLComment>(_xmlbuf.substr(left + 4, right - left - 4))); + right += 2; + } + else if (_xmlbuf.compare(left, 2, "<?") == 0) { + right = _xmlbuf.find("?>", left+2); + if (right == string::npos) { + if (finish) throw XMLParserException("expected '?>' at end of processing instruction"); + break; + } + (svgTree.*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right - left + 2))); + right++; + } + else if (_xmlbuf.compare(left, 2, "</") == 0) { + right = _xmlbuf.find('>', left+2); + if (right == string::npos) { + if (finish) throw XMLParserException("missing '>' at end of closing XML tag"); + break; + } + closeElement(_xmlbuf.substr(left+2, right-left-2), svgTree); + } + else { + right = _xmlbuf.find('>', left+1); + if (right == string::npos) { + if (finish) throw XMLParserException("missing '>' or '/>' at end of opening XML tag"); + break; + } + openElement(_xmlbuf.substr(left+1, right-left-1), svgTree); + } + } + left = right; + if (right != string::npos) + left++; + } + } + catch (const XMLParserException &e) { + _error = true; + throw; + } + if (left == string::npos) + _xmlbuf.clear(); + else + _xmlbuf.erase(0, left); +} + + +/** Processes an opening element tag. + * @param[in] tag tag without leading and trailing angle brackets */ +void XMLParser::openElement (const string &tag, SVGTree &svgTree) { + StringInputBuffer ib(tag); + BufferInputReader ir(ib); + string name = ir.getString("/ \t\n\r"); + bool isPathElement = (name == "path" || name == "svg:path"); + ir.skipSpace(); + auto elemNode = util::make_unique<SVGElement>(name); + map<string, string> attribs; + if (ir.parseAttributes(attribs, true, "\"'")) { + for (const auto &attrpair : attribs) { + if (!isPathElement || attrpair.first != "d") + elemNode->addAttribute(attrpair.first, attrpair.second); + else { + try { + // parse and reformat path definition + auto path = GraphicsPathParser<double>().parse(attrpair.second); + ostringstream oss; + path.writeSVG(oss, SVGTree::RELATIVE_PATH_CMDS); + elemNode->addAttribute("d", oss.str()); + } + catch (const GraphicsPathParserException &e) { + throw XMLParserException(string("error in path data: ")+e.what()); + } + } + } + } + ir.skipSpace(); + if (ir.peek() == '/') // end of empty element tag + (svgTree.*_append)(std::move(elemNode)); + else if (ir.peek() < 0) { // end of opening tag + _nameStack.push_back(name); + (svgTree.*_pushContext)(std::move(elemNode)); + } + else + throw XMLParserException("'>' or '/>' expected at end of opening tag <"+name); +} + + +/** Processes a closing element tag. + * @param[in] tag tag without leading and trailing angle brackets */ +void XMLParser::closeElement (const string &tag, SVGTree &svgTree) { + StringInputBuffer ib(tag); + BufferInputReader ir(ib); + string name = ir.getString(" \t\n\r"); + ir.skipSpace(); + if (ir.peek() >= 0) + throw XMLParserException("'>' expected at end of closing tag </"+name); + if (_nameStack.empty()) + throw XMLParserException("spurious closing tag </" + name + ">"); + if (_nameStack.back() != name) + throw XMLParserException("expected </" + _nameStack.back() + "> but found </" + name + ">"); + (svgTree.*_popContext)(); + _nameStack.pop_back(); +} + + +/** Processes any remaining XML fragments, checks for missing closing tags, + * and resets the parser state. */ +void XMLParser::finish (SVGTree &svgTree) { + if (!_xmlbuf.empty()) { + if (!_error) + parse("", svgTree, true); + _xmlbuf.clear(); + } + string tags; + while (!_nameStack.empty()) { + tags += "</"+_nameStack.back()+">, "; + _nameStack.pop_back(); + } + if (!tags.empty() && !_error) { + tags.resize(tags.length()-2); + throw XMLParserException("missing closing tag(s): "+tags); + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp new file mode 100644 index 00000000000..51f6a62544c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLParser.hpp @@ -0,0 +1,58 @@ +/************************************************************************* +** XMLParser.hpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2022 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** This program is free software; you can redistribute it and/or ** +** modify it under the terms of the GNU General Public License as ** +** published by the Free Software Foundation; either version 3 of ** +** the License, or (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, but ** +** WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program; if not, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#ifndef XMLPARSER_HPP +#define XMLPARSER_HPP + +#include <string> +#include "MessageException.hpp" +#include "SVGTree.hpp" + +struct XMLParserException : MessageException { + explicit XMLParserException (const std::string &msg) : MessageException(msg) {} +}; + +class XMLParser { + using AppendFunc = void (SVGTree::*)(std::unique_ptr<XMLNode>); + using PushFunc = void (SVGTree::*)(std::unique_ptr<SVGElement>); + using PopFunc = void (SVGTree::*)(); + using NameStack = std::vector<std::string>; + + public: + XMLParser (AppendFunc append, PushFunc push, PopFunc pop) + : _append(append), _pushContext(push), _popContext(pop) {} + + void parse (const std::string &xml, SVGTree &svgTree, bool finish=false); + void finish (SVGTree &svgTree); + + protected: + void openElement (const std::string &tag, SVGTree &svgTree); + void closeElement (const std::string &tag, SVGTree &svgTree); + + private: + AppendFunc _append; + PushFunc _pushContext; + PopFunc _popContext; + std::string _xmlbuf; + NameStack _nameStack; ///< names of nested elements still missing a closing tag + bool _error=false; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp index 6ce89b3d869..ae489ea16cc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp @@ -91,7 +91,7 @@ XMLString::XMLString (double x) { if (std::abs(x) < 1e-6) x = 0; assign(util::to_string(x)); - size_t pos = find("0."); + auto pos = find("0."); if (pos != string::npos && (pos == 0 || at(pos-1) == '-')) erase(pos, 1); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index 089064a1b98..488e9e2b479 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -48,6 +48,7 @@ #include "optimizer/SVGOptimizer.hpp" #include "SVGOutput.hpp" #include "System.hpp" +#include "XMLParser.hpp" #include "XXHashFunction.hpp" #include "utility.hpp" #include "version.hpp" @@ -65,7 +66,7 @@ using namespace std; static string remove_path (string fname) { fname = FileSystem::ensureForwardSlashes(fname); - size_t slashpos = fname.rfind('/'); + auto slashpos = fname.rfind('/'); if (slashpos == string::npos) return fname; return fname.substr(slashpos+1); @@ -74,7 +75,7 @@ static string remove_path (string fname) { static string ensure_suffix (string fname, const string &suffix) { if (!fname.empty()) { - size_t dotpos = remove_path(fname).rfind('.'); + auto dotpos = remove_path(fname).rfind('.'); if (dotpos == string::npos) fname += "." + suffix; } @@ -494,6 +495,10 @@ int main (int argc, char *argv[]) { Message::estream() << "\nPostScript error: " << e.what() << '\n'; return -2; } + catch (XMLParserException &e) { + Message::estream() << "\nXML error: " << e.what() << '\n'; + return -5; + } catch (SignalException &e) { Message::wstream().clearline(); Message::wstream(true) << "execution interrupted by user\n"; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp index d36314aae41..1d1c6579b86 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp @@ -82,7 +82,7 @@ void AttributeExtractor::execute (XMLElement *context, bool recurse) { * @return the new group element if attributes could be grouped, 'elem' otherwise */ XMLNode* AttributeExtractor::extractAttribute (XMLElement *elem) { for (const auto ¤tAttribute : elem->attributes()) { - if (!inheritable(currentAttribute) || extracted(currentAttribute)) + if (!currentAttribute.inheritable() || extracted(currentAttribute)) continue; AttributeRun run(currentAttribute, elem); if (run.length() >= MIN_RUN_LENGTH) { @@ -126,30 +126,6 @@ bool AttributeExtractor::groupable (const XMLElement &elem) { } -/** Checks whether an SVG attribute A of an element E implicitly propagates its properties - * to all child elements of E that don't specify A. For now we only consider a subset of - * the inheritable properties. - * @param[in] attrib name of attribute to check - * @return true if the attribute is inheritable */ -bool AttributeExtractor::inheritable (const Attribute &attrib) { - // subset of inheritable properties listed on https://www.w3.org/TR/SVG11/propidx.html - // clip-path is not inheritable but can be moved to the parent element as long as - // no child gets an different clip-path attribute - // https://www.w3.org/TR/SVG11/styling.html#Inheritance - static const char *names[] = { - "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", - "color-rendering", "direction", "fill", "fill-opacity", "fill-rule", "font", "font-family", "font-size", - "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "glyph-orientation-horizontal", - "glyph-orientation-vertical", "letter-spacing", "paint-order", "stroke", "stroke-dasharray", "stroke-dashoffset", - "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "transform", - "visibility", "word-spacing", "writing-mode" - }; - return binary_search(begin(names), end(names), attrib.name, [](const string &name1, const string &name2) { - return name1 < name2; - }); -} - - /** Checks whether an attribute is allowed to be removed from a given element. */ bool AttributeExtractor::extractable (const Attribute &attrib, XMLElement &element) { if (element.hasAttribute("id")) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp index 19cd4f0fed3..4b53b665513 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp @@ -46,7 +46,6 @@ class AttributeExtractor : public OptimizerModule { void execute (XMLElement*, XMLElement *context) override {execute(context, true);}; const char* info () const override; static bool groupable (const XMLElement &elem); - static bool inheritable (const Attribute &attrib); static bool extractable (const Attribute &attr, XMLElement &element); protected: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp index 03fc3ac1855..e86313e74bd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp @@ -22,7 +22,6 @@ #include <array> #include <string> #include <vector> -#include "AttributeExtractor.hpp" #include "GroupCollapser.hpp" #include "TransformSimplifier.hpp" #include "../XMLNode.hpp" @@ -83,8 +82,8 @@ void GroupCollapser::execute (XMLElement *context, int depth) { XMLNode *next=child->next(); if (XMLElement *childElement = child->toElement()) { execute(childElement, depth+1); - // check for groups without attributes and remove them - if (childElement->name() == "g" && childElement->attributes().empty()) { + // remove empty groups and groups without attributes + if (childElement->name() == "g" && (childElement->attributes().empty() || (!childElement->hasAttribute("id") && childElement->empty(true)))) { remove_ws_nodes(childElement); if (XMLNode *firstUnwrappedNode = XMLElement::unwrap(childElement)) next = firstUnwrappedNode; @@ -127,7 +126,7 @@ bool GroupCollapser::moveAttributes (XMLElement &source, XMLElement &dest) { dest.addAttribute("transform", transform); movedAttributes.emplace_back("transform"); } - else if (AttributeExtractor::inheritable(attr)) { + else if (attr.inheritable()) { dest.addAttribute(attr.name, attr.value); movedAttributes.emplace_back(attr.name); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.am index 1b8444c09a4..df3724cfc7d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.am @@ -10,7 +10,7 @@ liboptimizer_a_SOURCES = \ SVGOptimizer.hpp SVGOptimizer.cpp \ TextSimplifier.hpp TextSimplifier.cpp \ TransformSimplifier.hpp TransformSimplifier.cpp \ - WSNodeRemover.hpp WSNodeRemover.cpp + WSNodeRemover.hpp WSNodeRemover.cpp include ../../libs/defs.am diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.in index 84aa9616d18..0ea9495b6b0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/Makefile.in @@ -386,7 +386,7 @@ liboptimizer_a_SOURCES = \ SVGOptimizer.hpp SVGOptimizer.cpp \ TextSimplifier.hpp TextSimplifier.cpp \ TransformSimplifier.hpp TransformSimplifier.cpp \ - WSNodeRemover.hpp WSNodeRemover.cpp + WSNodeRemover.hpp WSNodeRemover.cpp @HAVE_POTRACE_FALSE@POTRACE_CFLAGS = $(POTRACE_INCLUDES) @HAVE_XXHASH_FALSE@XXHASH_CFLAGS = -I$(dvisvgm_srcdir)/libs/xxHash diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp index b07db7701b6..855d88c1014 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp @@ -40,7 +40,7 @@ static XMLElement::Attributes common_inheritable_attributes (const vector<XMLEle if (intersected) break; for (const auto &attrib : elem->attributes()) { - if (AttributeExtractor::inheritable(attrib)) + if (attrib.inheritable()) commonAttribs.push_back(attrib); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp index 56f2c17ae7c..4877690ef4b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp @@ -84,10 +84,10 @@ double math::normalize_0_2pi (double rad) { * @param[in] ws characters treated as whitespace * @return the trimmed string */ string util::trim (const std::string &str, const char *ws) { - size_t first = str.find_first_not_of(ws); + auto first = str.find_first_not_of(ws); if (first == string::npos) return ""; - size_t last = str.find_last_not_of(ws); + auto last = str.find_last_not_of(ws); return str.substr(first, last-first+1); } @@ -99,9 +99,9 @@ string util::trim (const std::string &str, const char *ws) { * @return the normalized string */ string util::normalize_space (string str, const char *ws) { str = trim(str); - size_t first = str.find_first_of(ws); + auto first = str.find_first_of(ws); while (first != string::npos) { - size_t last = str.find_first_not_of(ws, first); + auto last = str.find_first_not_of(ws, first); str.replace(first, last-first, " "); first = str.find_first_of(ws, first+1); } @@ -116,7 +116,7 @@ string util::normalize_space (string str, const char *ws) { * @return the resulting string */ string util::replace (string str, const string &find, const string &repl) { if (!find.empty() && !repl.empty()) { - size_t first = str.find(find); + auto first = str.find(find); while (first != string::npos) { str.replace(first, find.length(), repl); first = str.find(find, first+repl.length()); @@ -136,9 +136,9 @@ vector<string> util::split (const string &str, const string &sep) { if (str.empty() || sep.empty()) parts.push_back(str); else { - size_t left=0; + string::size_type left=0; while (left <= str.length()) { - size_t right = str.find(sep, left); + auto right = str.find(sep, left); if (right == string::npos) { parts.push_back(str.substr(left)); left = string::npos; @@ -164,7 +164,7 @@ string util::tolower (const string &str) { string util::to_string (double val) { string str = std::to_string(val); if (str.find('.') != string::npos) { // double value and not an integer? - size_t pos = str.find_last_not_of('0'); + auto pos = str.find_last_not_of('0'); if (pos != string::npos) // trailing zeros str.erase(pos+1, string::npos); if (str.back() == '.') // trailing dot? diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp index 9ab0d605420..b8a36daceb2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp @@ -137,17 +137,17 @@ inline void base64_copy (std::istream &is, std::ostream &os, int wrap=0) { * @param[in] args arguments forwarded to an constructor of T */ template<typename T, typename... Args> std::unique_ptr<T> make_unique (Args&&... args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } template<typename T, typename U> std::unique_ptr<T> static_unique_ptr_cast (std::unique_ptr<U> &&old){ - return std::unique_ptr<T>{static_cast<T*>(old.release())}; + return std::unique_ptr<T>{static_cast<T*>(old.release())}; } template <typename T> -struct set_const_of { +struct set_const_of { template <typename U> struct by { using type = typename std::conditional< @@ -155,7 +155,7 @@ struct set_const_of { typename std::add_const<T>::type, typename std::remove_const<T>::type >::type; - }; + }; }; } // namespace util diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp index ebd2020b822..abc8535221e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp @@ -189,21 +189,21 @@ TEST_F(DvisvgmSpecialTest, rawPI) { TEST_F(DvisvgmSpecialTest, rawPageFail) { istringstream iss("raw <elem attr1='1' attr2='20'"); - EXPECT_THROW({handler.process("", iss, recorder); handler.finishPage();}, SpecialException); // incomplete opening tag + EXPECT_THROW({handler.process("", iss, recorder); handler.finishPage();}, XMLParserException); // incomplete opening tag iss.clear(); iss.str("raw </elem>"); - EXPECT_THROW(handler.process("", iss, recorder), SpecialException); // spurious closing tag + EXPECT_THROW(handler.process("", iss, recorder), XMLParserException); // spurious closing tag iss.clear(); iss.str("raw <open>text</close>"); - EXPECT_THROW(handler.process("", iss, recorder), SpecialException); // mismatching tags + EXPECT_THROW(handler.process("", iss, recorder), XMLParserException); // mismatching tags } TEST_F(DvisvgmSpecialTest, rawDefsFail) { istringstream iss("rawdef <elem attr1='1' attr2='20'"); - EXPECT_THROW({handler.process("", iss, recorder); handler.finishPage();}, SpecialException); // incomplete opening tag + EXPECT_THROW({handler.process("", iss, recorder); handler.finishPage();}, XMLParserException); // incomplete opening tag iss.clear(); iss.str("rawdef </elem>"); - EXPECT_THROW(handler.process("", iss, recorder), SpecialException); // spurious closing tag + EXPECT_THROW(handler.process("", iss, recorder), XMLParserException); // spurious closing tag iss.clear(); iss.str("rawdef <open>text</close>"); - EXPECT_THROW(handler.process("", iss, recorder), SpecialException); // mismatching tags + EXPECT_THROW(handler.process("", iss, recorder), XMLParserException); // mismatching tags } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp new file mode 100644 index 00000000000..15298c299f4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathParserTest.cpp @@ -0,0 +1,163 @@ +/************************************************************************* +** GraphicsPathParserTest.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** This program is free software; you can redistribute it and/or ** +** modify it under the terms of the GNU General Public License as ** +** published by the Free Software Foundation; either version 3 of ** +** the License, or (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, but ** +** WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program; if not, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <gtest/gtest.h> +#include <sstream> +#include "GraphicsPathParser.hpp" + +using namespace std; + +TEST(GraphicsPathParserTest, empty) { + GraphicsPathParser<int> parser; + auto path = parser.parse(""); + EXPECT_TRUE(path.empty()); + path = parser.parse(" \n\t \r "); + EXPECT_TRUE(path.empty()); +} + + +TEST(GraphicsPathParserTest, moveto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("M10 10 20 20 ,30 0 -10 10"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "M10 10L20 20L30 0L-10 10"); + oss.str(""); + path = parser.parse("m10 -10 20, 20 ,30 0 -10 10"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "M10-10L30 10H60L50 20"); +} + + +TEST(GraphicsPathParserTest, lineto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("L10 10 20 20 ,30 0 -10 10"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "L10 10L20 20L30 0L-10 10"); + oss.str(""); + path = parser.parse("l10 -10 20, 20 ,30 0 -10 10"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "L10-10L30 10H60L50 20"); +} + + +TEST(GraphicsPathParserTest, hvlineto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("H 10 20 V10 20"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "H10H20V10V20"); + oss.str(""); + path = parser.parse("h 10 20 v10 20"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "H10H30V10V30"); +} + + +TEST(GraphicsPathParserTest, cubicto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("C 10 20 30 40 50 60 -100 -200 -300 -400 -500 -600"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "C10 20 30 40 50 60C-100-200-300-400-500-600"); + oss.str(""); + path = parser.parse("c 10 20 30 40 50 60 -100 -200 -300 -400 -500 -600"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "C10 20 30 40 50 60C-50-140-250-340-450-540"); +} + + +TEST(GraphicsPathParserTest, quadto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("Q 10 20 30 40 -100 -200 -300 -400"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "Q10 20 30 40Q-100-200-300-400"); + oss.str(""); + path = parser.parse("q 10 20 30 40 -100 -200 -300 -400"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "Q10 20 30 40Q-70-160-270-360"); +} + + +TEST(GraphicsPathParserTest, scubicto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("S 10 20 30 40 -100 -200 -300 -400"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "C0 0 10 20 30 40S-100-200-300-400"); + oss.str(""); + path = parser.parse("s 10 20 30 40 -100 -200 -300 -400"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "C0 0 10 20 30 40S-70-160-270-360"); +} + + +TEST(GraphicsPathParserTest, squadto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("T 10 20 -100 -200"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "Q0 0 10 20T-100-200"); + oss.str(""); + path = parser.parse("t 10 20 -100 -200"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "Q0 0 10 20T-90-180"); +} + + +TEST(GraphicsPathParserTest, arcto) { + GraphicsPathParser<int> parser; + auto path = parser.parse("A 10 20 90 1 0 100 200, -10 -20 45 0 1 -100 -200"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "A10 20 90 1 0 100 200A10 20 45 0 1-100-200"); + oss.str(""); + path = parser.parse("a 10 20 90 1 0 100 200, -10 -20 45 0 1 -100 -200"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "A10 20 90 1 0 100 200A10 20 45 0 1 0 0"); +} + + +TEST(GraphicsPathParserTest, combined) { + GraphicsPathParser<int> parser; + auto path = parser.parse("M10 10L20 50Q 100 100 -10 -10 Z C 10 20 30 40 50 60Z"); + ostringstream oss; + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "M10 10L20 50Q100 100-10-10ZC10 20 30 40 50 60Z"); + oss.str(""); + path = parser.parse("m10 10l20 50q 100 100 -10 -10 z c 10 20 30 40 50 60 z"); + path.writeSVG(oss, false); + EXPECT_EQ(oss.str(), "M10 10L30 60Q130 160 20 50ZC20 30 40 50 60 70Z"); +} + + +TEST(GraphicsPathParserTest, error) { + GraphicsPathParser<int> parser; + EXPECT_THROW(parser.parse("10 20"), GraphicsPathParserException); // missing command + EXPECT_THROW(parser.parse("M10 "), GraphicsPathParserException); // missing y-coordinate + EXPECT_THROW(parser.parse("M10 20.5"), GraphicsPathParserException); // invalid number type + EXPECT_THROW(parser.parse("J 10 20.5"), GraphicsPathParserException); // unknown command + EXPECT_THROW(parser.parse("M,10 20"), GraphicsPathParserException); // invalid comma + EXPECT_THROW(parser.parse("M10 20,"), GraphicsPathParserException); // missing parameters + EXPECT_THROW(parser.parse("A 10 20 45 2 0 100 100"), GraphicsPathParserException); // invalid large-arc-flag + EXPECT_THROW(parser.parse("A 10 20 45 0 5 100 100"), GraphicsPathParserException); // invalid sweep-flag +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am index 5582eaf412f..2faaacf3530 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am @@ -208,6 +208,12 @@ GhostscriptTest_SOURCES = GhostscriptTest.cpp testutil.hpp GhostscriptTest_CPPFLAGS = -I$(dvisvgm_srcdir)/tests/gtest/include $(LIBS_CFLAGS) GhostscriptTest_LDADD = $(TESTLIBS) +TESTS += GraphicsPathParserTest +check_PROGRAMS += GraphicsPathParserTest +GraphicsPathParserTest_SOURCES = GraphicsPathParserTest.cpp testutil.hpp +GraphicsPathParserTest_CPPFLAGS = -I$(dvisvgm_srcdir)/tests/gtest/include $(LIBS_CFLAGS) +GraphicsPathParserTest_LDADD = $(TESTLIBS) + TESTS += GraphicsPathTest check_PROGRAMS += GraphicsPathTest GraphicsPathTest_SOURCES = GraphicsPathTest.cpp testutil.hpp diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in index d6007f031be..f6359bad6cb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -109,9 +109,9 @@ TESTS = hashcheck$(EXEEXT) BezierTest$(EXEEXT) BitmapTest$(EXEEXT) \ FontCacheTest$(EXEEXT) FontManagerTest$(EXEEXT) \ FontMapTest$(EXEEXT) GFGlyphTracerTest$(EXEEXT) \ GFReaderTest$(EXEEXT) GhostscriptTest$(EXEEXT) \ - GraphicsPathTest$(EXEEXT) HashFunctionTest$(EXEEXT) \ - JFMReaderTest$(EXEEXT) LengthTest$(EXEEXT) \ - MapLineTest$(EXEEXT) MatrixTest$(EXEEXT) \ + GraphicsPathParserTest$(EXEEXT) GraphicsPathTest$(EXEEXT) \ + HashFunctionTest$(EXEEXT) JFMReaderTest$(EXEEXT) \ + LengthTest$(EXEEXT) MapLineTest$(EXEEXT) MatrixTest$(EXEEXT) \ MessageExceptionTest$(EXEEXT) PageRagesTest$(EXEEXT) \ PageSizeTest$(EXEEXT) PairTest$(EXEEXT) \ PapersizeSpecialTest$(EXEEXT) PDFParserTest$(EXEEXT) \ @@ -140,9 +140,9 @@ check_PROGRAMS = hashcheck$(EXEEXT) BezierTest$(EXEEXT) \ FontCacheTest$(EXEEXT) FontManagerTest$(EXEEXT) \ FontMapTest$(EXEEXT) GFGlyphTracerTest$(EXEEXT) \ GFReaderTest$(EXEEXT) GhostscriptTest$(EXEEXT) \ - GraphicsPathTest$(EXEEXT) HashFunctionTest$(EXEEXT) \ - JFMReaderTest$(EXEEXT) LengthTest$(EXEEXT) \ - MapLineTest$(EXEEXT) MatrixTest$(EXEEXT) \ + GraphicsPathParserTest$(EXEEXT) GraphicsPathTest$(EXEEXT) \ + HashFunctionTest$(EXEEXT) JFMReaderTest$(EXEEXT) \ + LengthTest$(EXEEXT) MapLineTest$(EXEEXT) MatrixTest$(EXEEXT) \ MessageExceptionTest$(EXEEXT) PageRagesTest$(EXEEXT) \ PageSizeTest$(EXEEXT) PairTest$(EXEEXT) \ PapersizeSpecialTest$(EXEEXT) PDFParserTest$(EXEEXT) \ @@ -161,12 +161,7 @@ check_PROGRAMS = hashcheck$(EXEEXT) BezierTest$(EXEEXT) \ @ENABLE_WOFF_TRUE@am__append_10 = ../libs/ff-woff/libfontforge.a subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -281,6 +276,10 @@ am_GhostscriptTest_OBJECTS = \ GhostscriptTest-GhostscriptTest.$(OBJEXT) GhostscriptTest_OBJECTS = $(am_GhostscriptTest_OBJECTS) GhostscriptTest_DEPENDENCIES = $(am__DEPENDENCIES_7) +am_GraphicsPathParserTest_OBJECTS = \ + GraphicsPathParserTest-GraphicsPathParserTest.$(OBJEXT) +GraphicsPathParserTest_OBJECTS = $(am_GraphicsPathParserTest_OBJECTS) +GraphicsPathParserTest_DEPENDENCIES = $(am__DEPENDENCIES_7) am_GraphicsPathTest_OBJECTS = \ GraphicsPathTest-GraphicsPathTest.$(OBJEXT) GraphicsPathTest_OBJECTS = $(am_GraphicsPathTest_OBJECTS) @@ -444,6 +443,7 @@ am__depfiles_remade = ./$(DEPDIR)/BezierTest-BezierTest.Po \ ./$(DEPDIR)/GFGlyphTracerTest-GFGlyphTracerTest.Po \ ./$(DEPDIR)/GFReaderTest-GFReaderTest.Po \ ./$(DEPDIR)/GhostscriptTest-GhostscriptTest.Po \ + ./$(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Po \ ./$(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Po \ ./$(DEPDIR)/HashFunctionTest-HashFunctionTest.Po \ ./$(DEPDIR)/JFMReaderTest-JFMReaderTest.Po \ @@ -531,15 +531,15 @@ SOURCES = $(libgtest_la_SOURCES) $(BezierTest_SOURCES) \ $(FontCacheTest_SOURCES) $(FontManagerTest_SOURCES) \ $(FontMapTest_SOURCES) $(GFGlyphTracerTest_SOURCES) \ $(GFReaderTest_SOURCES) $(GhostscriptTest_SOURCES) \ - $(GraphicsPathTest_SOURCES) $(HashFunctionTest_SOURCES) \ - $(JFMReaderTest_SOURCES) $(LengthTest_SOURCES) \ - $(MapLineTest_SOURCES) $(MatrixTest_SOURCES) \ - $(MessageExceptionTest_SOURCES) $(PDFParserTest_SOURCES) \ - $(PSInterpreterTest_SOURCES) $(PageRagesTest_SOURCES) \ - $(PageSizeTest_SOURCES) $(PairTest_SOURCES) \ - $(PapersizeSpecialTest_SOURCES) $(RangeMapTest_SOURCES) \ - $(SVGOutputTest_SOURCES) $(ShadingPatchTest_SOURCES) \ - $(SpecialManagerTest_SOURCES) \ + $(GraphicsPathParserTest_SOURCES) $(GraphicsPathTest_SOURCES) \ + $(HashFunctionTest_SOURCES) $(JFMReaderTest_SOURCES) \ + $(LengthTest_SOURCES) $(MapLineTest_SOURCES) \ + $(MatrixTest_SOURCES) $(MessageExceptionTest_SOURCES) \ + $(PDFParserTest_SOURCES) $(PSInterpreterTest_SOURCES) \ + $(PageRagesTest_SOURCES) $(PageSizeTest_SOURCES) \ + $(PairTest_SOURCES) $(PapersizeSpecialTest_SOURCES) \ + $(RangeMapTest_SOURCES) $(SVGOutputTest_SOURCES) \ + $(ShadingPatchTest_SOURCES) $(SpecialManagerTest_SOURCES) \ $(SplittedCharInputBufferTest_SOURCES) \ $(StreamInputBufferTest_SOURCES) $(StreamReaderTest_SOURCES) \ $(StreamWriterTest_SOURCES) $(StringMatcherTest_SOURCES) \ @@ -563,15 +563,15 @@ DIST_SOURCES = $(libgtest_la_SOURCES) $(BezierTest_SOURCES) \ $(FontCacheTest_SOURCES) $(FontManagerTest_SOURCES) \ $(FontMapTest_SOURCES) $(GFGlyphTracerTest_SOURCES) \ $(GFReaderTest_SOURCES) $(GhostscriptTest_SOURCES) \ - $(GraphicsPathTest_SOURCES) $(HashFunctionTest_SOURCES) \ - $(JFMReaderTest_SOURCES) $(LengthTest_SOURCES) \ - $(MapLineTest_SOURCES) $(MatrixTest_SOURCES) \ - $(MessageExceptionTest_SOURCES) $(PDFParserTest_SOURCES) \ - $(PSInterpreterTest_SOURCES) $(PageRagesTest_SOURCES) \ - $(PageSizeTest_SOURCES) $(PairTest_SOURCES) \ - $(PapersizeSpecialTest_SOURCES) $(RangeMapTest_SOURCES) \ - $(SVGOutputTest_SOURCES) $(ShadingPatchTest_SOURCES) \ - $(SpecialManagerTest_SOURCES) \ + $(GraphicsPathParserTest_SOURCES) $(GraphicsPathTest_SOURCES) \ + $(HashFunctionTest_SOURCES) $(JFMReaderTest_SOURCES) \ + $(LengthTest_SOURCES) $(MapLineTest_SOURCES) \ + $(MatrixTest_SOURCES) $(MessageExceptionTest_SOURCES) \ + $(PDFParserTest_SOURCES) $(PSInterpreterTest_SOURCES) \ + $(PageRagesTest_SOURCES) $(PageSizeTest_SOURCES) \ + $(PairTest_SOURCES) $(PapersizeSpecialTest_SOURCES) \ + $(RangeMapTest_SOURCES) $(SVGOutputTest_SOURCES) \ + $(ShadingPatchTest_SOURCES) $(SpecialManagerTest_SOURCES) \ $(SplittedCharInputBufferTest_SOURCES) \ $(StreamInputBufferTest_SOURCES) $(StreamReaderTest_SOURCES) \ $(StreamWriterTest_SOURCES) $(StringMatcherTest_SOURCES) \ @@ -619,8 +619,6 @@ am__define_uniq_tagged_files = \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no @@ -803,6 +801,7 @@ am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test @@ -877,6 +876,8 @@ CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ @@ -892,8 +893,10 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ FREETYPE_LIBS = @FREETYPE_LIBS@ GCOV = @GCOV@ @@ -1116,6 +1119,9 @@ GFReaderTest_LDADD = $(TESTLIBS) GhostscriptTest_SOURCES = GhostscriptTest.cpp testutil.hpp GhostscriptTest_CPPFLAGS = -I$(dvisvgm_srcdir)/tests/gtest/include $(LIBS_CFLAGS) GhostscriptTest_LDADD = $(TESTLIBS) +GraphicsPathParserTest_SOURCES = GraphicsPathParserTest.cpp testutil.hpp +GraphicsPathParserTest_CPPFLAGS = -I$(dvisvgm_srcdir)/tests/gtest/include $(LIBS_CFLAGS) +GraphicsPathParserTest_LDADD = $(TESTLIBS) GraphicsPathTest_SOURCES = GraphicsPathTest.cpp testutil.hpp GraphicsPathTest_CPPFLAGS = -I$(dvisvgm_srcdir)/tests/gtest/include $(LIBS_CFLAGS) GraphicsPathTest_LDADD = $(TESTLIBS) @@ -1232,9 +1238,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../libs/defs.am $(am__co exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign tests/Makefile + $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -1385,6 +1391,10 @@ GhostscriptTest$(EXEEXT): $(GhostscriptTest_OBJECTS) $(GhostscriptTest_DEPENDENC @rm -f GhostscriptTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(GhostscriptTest_OBJECTS) $(GhostscriptTest_LDADD) $(LIBS) +GraphicsPathParserTest$(EXEEXT): $(GraphicsPathParserTest_OBJECTS) $(GraphicsPathParserTest_DEPENDENCIES) $(EXTRA_GraphicsPathParserTest_DEPENDENCIES) + @rm -f GraphicsPathParserTest$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(GraphicsPathParserTest_OBJECTS) $(GraphicsPathParserTest_LDADD) $(LIBS) + GraphicsPathTest$(EXEEXT): $(GraphicsPathTest_OBJECTS) $(GraphicsPathTest_DEPENDENCIES) $(EXTRA_GraphicsPathTest_DEPENDENCIES) @rm -f GraphicsPathTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(GraphicsPathTest_OBJECTS) $(GraphicsPathTest_LDADD) $(LIBS) @@ -1558,6 +1568,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFGlyphTracerTest-GFGlyphTracerTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFReaderTest-GFReaderTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GhostscriptTest-GhostscriptTest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HashFunctionTest-HashFunctionTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JFMReaderTest-JFMReaderTest.Po@am__quote@ # am--include-marker @@ -1990,6 +2001,20 @@ GhostscriptTest-GhostscriptTest.obj: GhostscriptTest.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GhostscriptTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GhostscriptTest-GhostscriptTest.obj `if test -f 'GhostscriptTest.cpp'; then $(CYGPATH_W) 'GhostscriptTest.cpp'; else $(CYGPATH_W) '$(srcdir)/GhostscriptTest.cpp'; fi` +GraphicsPathParserTest-GraphicsPathParserTest.o: GraphicsPathParserTest.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GraphicsPathParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GraphicsPathParserTest-GraphicsPathParserTest.o -MD -MP -MF $(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Tpo -c -o GraphicsPathParserTest-GraphicsPathParserTest.o `test -f 'GraphicsPathParserTest.cpp' || echo '$(srcdir)/'`GraphicsPathParserTest.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Tpo $(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GraphicsPathParserTest.cpp' object='GraphicsPathParserTest-GraphicsPathParserTest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GraphicsPathParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GraphicsPathParserTest-GraphicsPathParserTest.o `test -f 'GraphicsPathParserTest.cpp' || echo '$(srcdir)/'`GraphicsPathParserTest.cpp + +GraphicsPathParserTest-GraphicsPathParserTest.obj: GraphicsPathParserTest.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GraphicsPathParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GraphicsPathParserTest-GraphicsPathParserTest.obj -MD -MP -MF $(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Tpo -c -o GraphicsPathParserTest-GraphicsPathParserTest.obj `if test -f 'GraphicsPathParserTest.cpp'; then $(CYGPATH_W) 'GraphicsPathParserTest.cpp'; else $(CYGPATH_W) '$(srcdir)/GraphicsPathParserTest.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Tpo $(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GraphicsPathParserTest.cpp' object='GraphicsPathParserTest-GraphicsPathParserTest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GraphicsPathParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GraphicsPathParserTest-GraphicsPathParserTest.obj `if test -f 'GraphicsPathParserTest.cpp'; then $(CYGPATH_W) 'GraphicsPathParserTest.cpp'; else $(CYGPATH_W) '$(srcdir)/GraphicsPathParserTest.cpp'; fi` + GraphicsPathTest-GraphicsPathTest.o: GraphicsPathTest.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GraphicsPathTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GraphicsPathTest-GraphicsPathTest.o -MD -MP -MF $(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Tpo -c -o GraphicsPathTest-GraphicsPathTest.o `test -f 'GraphicsPathTest.cpp' || echo '$(srcdir)/'`GraphicsPathTest.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Tpo $(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Po @@ -2717,7 +2742,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ @@ -2933,6 +2958,13 @@ GhostscriptTest.log: GhostscriptTest$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +GraphicsPathParserTest.log: GraphicsPathParserTest$(EXEEXT) + @p='GraphicsPathParserTest$(EXEEXT)'; \ + b='GraphicsPathParserTest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) GraphicsPathTest.log: GraphicsPathTest$(EXEEXT) @p='GraphicsPathTest$(EXEEXT)'; \ b='GraphicsPathTest'; \ @@ -3192,7 +3224,6 @@ check-conv.log: check-conv @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am @@ -3325,6 +3356,7 @@ distclean: distclean-recursive -rm -f ./$(DEPDIR)/GFGlyphTracerTest-GFGlyphTracerTest.Po -rm -f ./$(DEPDIR)/GFReaderTest-GFReaderTest.Po -rm -f ./$(DEPDIR)/GhostscriptTest-GhostscriptTest.Po + -rm -f ./$(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Po -rm -f ./$(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Po -rm -f ./$(DEPDIR)/HashFunctionTest-HashFunctionTest.Po -rm -f ./$(DEPDIR)/JFMReaderTest-JFMReaderTest.Po @@ -3432,6 +3464,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/GFGlyphTracerTest-GFGlyphTracerTest.Po -rm -f ./$(DEPDIR)/GFReaderTest-GFReaderTest.Po -rm -f ./$(DEPDIR)/GhostscriptTest-GhostscriptTest.Po + -rm -f ./$(DEPDIR)/GraphicsPathParserTest-GraphicsPathParserTest.Po -rm -f ./$(DEPDIR)/GraphicsPathTest-GraphicsPathTest.Po -rm -f ./$(DEPDIR)/HashFunctionTest-HashFunctionTest.Po -rm -f ./$(DEPDIR)/JFMReaderTest-JFMReaderTest.Po diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in index 3b44c55df08..631a6a51acf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -90,12 +90,7 @@ host_triplet = @host@ target_triplet = @target@ subdir = tests/data ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -149,6 +144,8 @@ CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ @@ -164,8 +161,10 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ FREETYPE_LIBS = @FREETYPE_LIBS@ GCOV = @GCOV@ @@ -315,9 +314,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/data/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/data/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign tests/data/Makefile + $(AUTOMAKE) --gnu tests/data/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -347,7 +346,6 @@ ctags CTAGS: cscope cscopelist: - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am |