From a962a7d36195d88f6e41bda96fdce65a4d306058 Mon Sep 17 00:00:00 2001 From: Luigi Scarso <luigi.scarso@gmail.com> Date: Wed, 12 Mar 2025 00:34:53 +0100 Subject: [PATCH] Sync with TeXLive rev. 74578. --- source/ChangeLog | 8 + source/README | 31 +- source/configure | 5439 +++++------------ source/libs/README | 6 +- source/libs/configure | 20 +- source/libs/harfbuzz/ChangeLog | 5 + source/libs/harfbuzz/TLpatches/ChangeLog | 5 + source/libs/harfbuzz/TLpatches/TL-Changes | 4 +- source/libs/harfbuzz/configure | 24 +- .../libs/harfbuzz/harfbuzz-src/CMakeLists.txt | 8 +- source/libs/harfbuzz/harfbuzz-src/NEWS | 66 +- source/libs/harfbuzz/harfbuzz-src/README.md | 6 +- source/libs/harfbuzz/harfbuzz-src/meson.build | 11 +- .../harfbuzz-src/src/OT/Color/CBDT/CBDT.hh | 4 +- .../harfbuzz-src/src/OT/Color/COLR/COLR.hh | 67 +- .../harfbuzz-src/src/OT/Color/CPAL/CPAL.hh | 8 + .../src/OT/Layout/Common/Coverage.hh | 22 + .../src/OT/Layout/Common/CoverageFormat1.hh | 2 + .../src/OT/Layout/Common/CoverageFormat2.hh | 2 + .../src/OT/Layout/GPOS/PairPosFormat1.hh | 44 +- .../src/OT/Layout/GPOS/PairPosFormat2.hh | 58 +- .../src/OT/Layout/GPOS/SinglePosFormat1.hh | 2 +- .../src/OT/Layout/GPOS/SinglePosFormat2.hh | 2 +- .../OT/Layout/GSUB/AlternateSubstFormat1.hh | 2 +- .../OT/Layout/GSUB/LigatureSubstFormat1.hh | 45 +- .../OT/Layout/GSUB/MultipleSubstFormat1.hh | 2 +- .../GSUB/ReverseChainSingleSubstFormat1.hh | 2 +- .../src/OT/Layout/GSUB/SingleSubstFormat1.hh | 2 +- .../src/OT/Layout/GSUB/SingleSubstFormat2.hh | 2 +- .../harfbuzz-src/src/OT/Layout/types.hh | 3 + .../harfbuzz-src/src/OT/Var/VARC/VARC.cc | 104 +- .../harfbuzz-src/src/OT/Var/VARC/VARC.hh | 165 +- .../src/OT/Var/VARC/coord-setter.hh | 40 +- .../src/OT/glyf/CompositeGlyph.hh | 2 +- .../harfbuzz-src/src/OT/glyf/Glyph.hh | 66 +- .../harfbuzz-src/src/OT/glyf/SimpleGlyph.hh | 18 +- .../harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh | 163 +- .../harfbuzz-src/src/OT/glyf/path-builder.hh | 100 +- .../harfbuzz/harfbuzz-src/src/OT/name/name.hh | 10 +- .../harfbuzz-src/src/gen-vowel-constraints.py | 2 +- .../harfbuzz-src/src/hb-aat-layout-common.hh | 243 +- .../src/hb-aat-layout-kerx-table.hh | 124 +- .../src/hb-aat-layout-morx-table.hh | 395 +- .../src/hb-aat-layout-trak-table.hh | 184 +- .../harfbuzz-src/src/hb-aat-layout.cc | 46 +- .../harfbuzz-src/src/hb-aat-layout.hh | 8 +- .../harfbuzz/harfbuzz-src/src/hb-aat-map.cc | 15 +- .../libs/harfbuzz/harfbuzz-src/src/hb-algs.hh | 10 +- .../harfbuzz/harfbuzz-src/src/hb-array.hh | 3 +- .../harfbuzz/harfbuzz-src/src/hb-atomic.hh | 1 + .../harfbuzz/harfbuzz-src/src/hb-bit-page.hh | 55 +- .../harfbuzz-src/src/hb-bit-set-invertible.hh | 4 + .../harfbuzz/harfbuzz-src/src/hb-bit-set.hh | 65 +- .../src/hb-buffer-deserialize-json.hh | 434 +- .../src/hb-buffer-deserialize-json.rl | 7 +- .../harfbuzz/harfbuzz-src/src/hb-buffer.cc | 8 +- .../harfbuzz/harfbuzz-src/src/hb-buffer.hh | 17 +- .../harfbuzz-src/src/hb-cff-interp-common.hh | 2 +- .../harfbuzz/harfbuzz-src/src/hb-config.hh | 1 + .../harfbuzz-src/src/hb-coretext-font.cc | 102 +- .../harfbuzz-src/src/hb-coretext-shape.cc | 48 +- .../harfbuzz-src/src/hb-directwrite.cc | 115 +- .../harfbuzz-src/src/hb-directwrite.h | 16 +- .../libs/harfbuzz/harfbuzz-src/src/hb-face.cc | 46 +- .../libs/harfbuzz/harfbuzz-src/src/hb-face.h | 9 +- .../harfbuzz/harfbuzz-src/src/hb-ft-colr.hh | 30 +- .../libs/harfbuzz/harfbuzz-src/src/hb-ft.cc | 77 +- source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h | 9 +- .../harfbuzz/harfbuzz-src/src/hb-geometry.hh | 9 + .../harfbuzz/harfbuzz-src/src/hb-open-type.hh | 194 +- .../harfbuzz-src/src/hb-ot-cff1-table.cc | 9 - .../harfbuzz-src/src/hb-ot-cff1-table.hh | 1 - .../harfbuzz-src/src/hb-ot-cff2-table.cc | 9 - .../harfbuzz-src/src/hb-ot-cff2-table.hh | 1 - .../harfbuzz-src/src/hb-ot-face-table-list.hh | 5 +- .../harfbuzz/harfbuzz-src/src/hb-ot-face.cc | 1 + .../harfbuzz/harfbuzz-src/src/hb-ot-font.cc | 60 +- .../harfbuzz-src/src/hb-ot-hdmx-table.hh | 2 +- .../harfbuzz-src/src/hb-ot-hmtx-table.hh | 2 +- .../harfbuzz-src/src/hb-ot-kern-table.hh | 4 +- .../src/hb-ot-layout-base-table.hh | 2 +- .../harfbuzz-src/src/hb-ot-layout-common.hh | 63 +- .../harfbuzz-src/src/hb-ot-layout-gsubgpos.hh | 169 +- .../harfbuzz/harfbuzz-src/src/hb-ot-layout.cc | 18 +- .../harfbuzz/harfbuzz-src/src/hb-ot-layout.hh | 10 +- .../harfbuzz/harfbuzz-src/src/hb-ot-map.cc | 14 + .../harfbuzz/harfbuzz-src/src/hb-ot-map.hh | 3 + .../harfbuzz/harfbuzz-src/src/hb-ot-shape.cc | 51 +- .../harfbuzz/harfbuzz-src/src/hb-ot-shape.h | 6 + .../harfbuzz/harfbuzz-src/src/hb-ot-shape.hh | 15 +- .../src/hb-ot-shaper-arabic-fallback.hh | 2 + .../src/hb-ot-shaper-vowel-constraints.cc | 2 +- .../harfbuzz-src/src/hb-ot-tag-table.hh | 202 +- .../harfbuzz-src/src/hb-ot-var-common.hh | 40 +- .../harfbuzz-src/src/hb-ot-var-cvar-table.hh | 26 +- .../harfbuzz-src/src/hb-ot-var-gvar-table.hh | 141 +- .../harfbuzz/harfbuzz-src/src/hb-serialize.hh | 6 +- .../harfbuzz-src/src/hb-set-digest.hh | 167 +- .../libs/harfbuzz/harfbuzz-src/src/hb-set.hh | 4 + .../harfbuzz-src/src/hb-shape-plan.cc | 10 +- .../harfbuzz-src/src/hb-subset-cff-common.hh | 2 +- .../harfbuzz-src/src/hb-subset-cff1.cc | 2 +- .../harfbuzz-src/src/hb-subset-plan.hh | 17 +- .../harfbuzz/harfbuzz-src/src/hb-subset.cc | 2 +- .../harfbuzz/harfbuzz-src/src/hb-vector.hh | 99 +- source/libs/harfbuzz/harfbuzz-src/src/hb.hh | 5 +- .../harfbuzz/harfbuzz-src/src/meson.build | 2 + .../harfbuzz-src/src/test-tuple-varstore.cc | 16 +- source/libs/harfbuzz/version.ac | 2 +- source/libs/libpng/ChangeLog | 5 + source/libs/libpng/README | 4 +- source/libs/libpng/TLpatches/ChangeLog | 4 + source/libs/libpng/TLpatches/TL-Changes | 4 +- source/libs/libpng/configure | 20 +- source/libs/libpng/libpng-src/ANNOUNCE | 30 +- source/libs/libpng/libpng-src/CHANGES | 12 + source/libs/libpng/libpng-src/CMakeLists.txt | 2 +- source/libs/libpng/libpng-src/README | 2 +- .../libpng/libpng-src/ci/ci_verify_cmake.sh | 11 +- .../libpng-src/ci/ci_verify_configure.sh | 7 +- .../libpng-src/ci/ci_verify_makefiles.sh | 11 +- .../libs/libpng/libpng-src/ci/lib/ci.lib.sh | 9 + source/libs/libpng/libpng-src/configure.ac | 6 +- .../libpng-src/contrib/libtests/pngimage.c | 19 +- .../libs/libpng/libpng-src/libpng-manual.txt | 2 +- source/libs/libpng/libpng-src/libpng.3 | 6 +- source/libs/libpng/libpng-src/libpngpf.3 | 4 +- source/libs/libpng/libpng-src/png.5 | 6 +- source/libs/libpng/libpng-src/png.c | 1133 +--- source/libs/libpng/libpng-src/png.h | 14 +- source/libs/libpng/libpng-src/pngconf.h | 2 +- source/libs/libpng/libpng-src/pngerror.c | 26 +- source/libs/libpng/libpng-src/pngget.c | 178 +- source/libs/libpng/libpng-src/pnginfo.h | 30 +- source/libs/libpng/libpng-src/pnglibconf.h | 2 +- source/libs/libpng/libpng-src/pngmem.c | 37 +- source/libs/libpng/libpng-src/pngpread.c | 192 +- source/libs/libpng/libpng-src/pngpriv.h | 408 +- source/libs/libpng/libpng-src/pngread.c | 379 +- source/libs/libpng/libpng-src/pngrtran.c | 337 +- source/libs/libpng/libpng-src/pngrutil.c | 1843 +++--- source/libs/libpng/libpng-src/pngset.c | 142 +- source/libs/libpng/libpng-src/pngstruct.h | 96 +- source/libs/libpng/libpng-src/pngtest.c | 4 +- source/libs/libpng/libpng-src/pngwrite.c | 39 +- source/libs/libpng/libpng-src/pngwutil.c | 8 +- .../libpng-src/scripts/libpng-config-head.in | 2 +- .../libpng/libpng-src/scripts/libpng.pc.in | 2 +- .../libpng/libpng-src/scripts/pnglibconf.dfa | 11 +- .../libpng-src/scripts/pnglibconf.h.prebuilt | 2 +- source/libs/libpng/version.ac | 2 +- source/tardate.ac | 6 +- source/texk/README | 4 +- source/texk/configure | 20 +- source/texk/kpathsea/ChangeLog | 8 + source/texk/kpathsea/NEWS | 4 +- source/texk/kpathsea/c-auto.in | 2 +- source/texk/kpathsea/configure | 26 +- source/texk/kpathsea/version.ac | 4 +- source/texk/texlive/configure | 20 +- source/texk/web2c/ChangeLog | 14 + source/texk/web2c/NEWS | 2 +- source/texk/web2c/configure | 24 +- source/texk/web2c/cwebdir/ChangeLog | 8 + source/texk/web2c/lib/ChangeLog | 9 + source/texk/web2c/lib/texmfmp.c | 2 +- .../texk/web2c/luatexdir/luatex_svnversion.h | 2 +- source/texk/web2c/man/ChangeLog | 4 + source/texk/web2c/synctexdir/ChangeLog | 9 + source/texk/web2c/synctexdir/synctex.c | 7 +- source/texk/web2c/tangle.ch | 19 +- source/texk/web2c/tangleboot.pin | 28 +- source/texk/web2c/web2c/ChangeLog | 4 + source/texk/web2c/web2c/configure | 20 +- source/utils/README | 7 +- source/utils/configure | 20 +- source/version.ac | 4 +- 177 files changed, 6796 insertions(+), 8575 deletions(-) diff --git a/source/ChangeLog b/source/ChangeLog index 0443f2888..32cc7d789 100644 --- a/source/ChangeLog +++ b/source/ChangeLog @@ -1,3 +1,11 @@ +2025-03-08 Karl Berry <karl@tug.org> + + * version.ac: 2026/dev. + +2025-03-07 Karl Berry <karl@tug.org> + + * TL'25 release. + 2025-01-12 Karl Berry <karl@tug.org> * Build: also support --debug-more for -g -Og -ggdb3, diff --git a/source/README b/source/README index 38acb0274..8b440c126 100644 --- a/source/README +++ b/source/README @@ -1,4 +1,4 @@ -$Id: README 73833 2025-02-09 23:41:13Z karl $ +$Id: README 74435 2025-03-04 17:01:16Z karl $ Public domain. Originally written 2005 by Karl Berry. For a high-level overview of building TeX Live, see @@ -27,30 +27,20 @@ that document). Build information for some of the platforms. See also Master/tlpkg/bin/tl-update-bindir. -aarch64-linux: - Built on contextgarden, see below, except for asy: - aarch64 Debian GNU/Linux 10 (buster) - gcc (Debian 8.3.0-6) 8.3.0 +aarch64-linux: Built on github, see below; + except for asy, by jhielscher on Fedora 41 (glibc 2.40, GCC 14.2.1). ./Build --enable-arm-neon=on -armhf-linux: - Built on contextgarden, see below. - Raspbian/Raspberry Pi OS (Debian Buster) - Previously, built by Simon Dales: - gcc version 10.2.1 20210110 (Raspbian 10.2.1-6+rpi1) - ./Build --enable-xindy CLISP=${BUILD_ROOT_DIR}/clisp/clisp-build/clisp} - armhf-linux binaries are created and tested on RPi; - they run on RPi, as well as ARMv7 CPUs, but are untested on non-RPi - ARMv6 machines. +armhf-linux: github, see below. x86_64-cygwin: gcc-10.2.0, cygwin-3.1.7 TL_CONFIGURE_ARGS="--enable-xindy --enable-shared CLISP=/path/to/clisp.exe LDFLAGS='-Wl,--no-insert-timestamp -Wl,--stack,0x800000'" \ ./Build -i386-freebsd amd64-freebsd: see info at end. +i386-freebsd amd64-freebsd: github, see below. -i386-linux: see info at end. +i386-linux: github, see below. i386-netbsd, amd64-netbsd: NetBSD/amd64 10.1 @@ -60,7 +50,7 @@ i386-netbsd, amd64-netbsd: LDFLAGS='-L/usr/X11R7/lib -Wl,-rpath,/usr/X11R7/lib' \ ./Build --enable-xindy CLISP=/usr/local/bin/clisp -i386-solaris, x86_64-solaris: see info at end. +i386-solaris, x86_64-solaris: github, see below. universal-darwin: See Master/source/mactexdoc.tar.xz. @@ -68,7 +58,7 @@ windows: Makefiles written by hand, see Master/source/windows-src.tar.xz. Visual Studio 2010 and Visual Studio 2015. -x86_64-darwinlegacy: +x86_64-darwinlegacy: Built on ConTeXtGarden. Mac OS X 10.6, clang 5.0, libc++ required auxiliary installer binaries: Mac OS X 10.6, gcc -std=c99. https://github.com/TeXLive-M/texlive-buildbot @@ -77,6 +67,7 @@ x86_64-darwinlegacy: x86_64-linux, x86_64-linuxmusl, -and others noted above: +and others noted above for github: built at https://github.com/TeX-Live/texlive-source/releases. - see ./github/scripts/build-tl.sh (and workflows/main.yml). + see ./github/scripts/build-tl.sh and workflows/main.yml. + Some asy binaries are also built here; see */build-asy.*. diff --git a/source/configure b/source/configure index 878dd9bc7..5c2735663 100755 --- a/source/configure +++ b/source/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for TeX Live 2024-03-10. +# Generated by GNU Autoconf 2.72 for TeX Live 2025-03-07. # # Report bugs to <tex-k@tug.org>. # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='TeX Live' PACKAGE_TARNAME='tex-live' -PACKAGE_VERSION='2024-03-10' -PACKAGE_STRING='TeX Live 2024-03-10' +PACKAGE_VERSION='2025-03-07' +PACKAGE_STRING='TeX Live 2025-03-07' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -813,23 +813,6 @@ enable_native_texlive_build enable_multiplatform enable_cxx_runtime_hack enable_libtool_hack -enable_autosp -enable_axodraw2 -enable_devnag -enable_lacheck -enable_m_tx -enable_pmx -enable_ps2eps -enable_t1utils -enable_texdoctk -enable_tpic2pdftex -enable_vlna -enable_xindy -enable_xindy_rules -enable_xindy_docs -with_clisp_runtime -enable_xml2pmx -enable_xpdfopen enable_web2c with_banner_add with_editor @@ -877,88 +860,16 @@ enable_tektronixwin enable_unitermwin enable_web_progs enable_synctex -enable_afm2pl -enable_bibtex_x -enable_bibtex8 -enable_bibtexu -enable_chktex -enable_cjkutils -enable_detex -enable_dtl -enable_dvi2tty -enable_dvidvi -enable_dviljk -enable_dviout_util -enable_dvipdfm_x -enable_dvipng -enable_debug -enable_timing -with_gs -enable_dvipos -enable_dvipsk -enable_dvisvgm -enable_gregorio -enable_gsftopk -enable_lcdf_typetools -enable_cfftot1 -enable_mmafm -enable_mmpfb -enable_otfinfo -enable_otftotfm -enable_t1dotlessj -enable_t1lint -enable_t1rawafm -enable_t1reencode -enable_t1testpage -enable_ttftotype42 -enable_updmap -enable_makeindexk -enable_makejvf -enable_mendexk -enable_musixtnt -enable_ps2pk -enable_psutils -enable_seetexk -enable_tex4htk -enable_ttf2pk2 -enable_ttfdump -enable_upmendex -enable_xdvik -with_xdvi_x_toolkit enable_texlive enable_linked_scripts with_system_harfbuzz -with_system_icu -with_system_teckit with_system_graphite2 with_system_zziplib -with_system_mpfi -with_mpfi_includes -with_mpfi_libdir -with_system_mpfr -with_mpfr_includes -with_mpfr_libdir -with_system_gmp -with_gmp_includes -with_gmp_libdir -with_system_cairo -with_system_pixman -with_system_gd -with_gd_includes -with_gd_libdir -with_system_potrace -with_potrace_includes -with_potrace_libdir -with_system_freetype2 with_system_libpng -with_system_libpaper -with_libpaper_includes -with_libpaper_libdir with_system_luajit with_system_zlib with_zlib_includes with_zlib_libdir -with_system_ptexenc with_system_kpathsea enable_mktexmf_default enable_mktexpk_default @@ -1549,7 +1460,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures TeX Live 2024-03-10 to adapt to many kinds of systems. +'configure' configures TeX Live 2025-03-07 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1624,7 +1535,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of TeX Live 2024-03-10:";; + short | recursive ) echo "Configuration of TeX Live 2025-03-07:";; esac cat <<\_ACEOF @@ -1641,22 +1552,6 @@ Optional Features: lib/PLATFORM --enable-cxx-runtime-hack link C++ runtime statically --enable-libtool-hack ignore libtool dependency_libs - --disable-autosp do not build the autosp package - --disable-axodraw2 do not build the axodraw2 package - --disable-devnag do not build the devnag package - --disable-lacheck do not build the lacheck package - --disable-m-tx do not build the m-tx package - --disable-pmx do not build the pmx package - --disable-ps2eps do not build the ps2eps package - --disable-t1utils do not build the t1utils package - --disable-texdoctk do not build the texdoctk package - --disable-tpic2pdftex do not build the tpic2pdftex package - --disable-vlna do not build the vlna package - --enable-xindy build the xindy package - --enable-xindy-rules build and install make-rules package - --enable-xindy-docs build and install documentation - --disable-xml2pmx do not build the xml2pmx package - --disable-xpdfopen do not build the xpdfopen package --disable-web2c do not build the web2c (TeX & Co.) package --enable-auto-core cause TeX&MF to dump core, given a certain filename @@ -1704,57 +1599,6 @@ Optional Features: --enable-unitermwin include Uniterm window support --disable-web-progs do not build WEB programs bibtex ... weave --disable-synctex do not build the SyncTeX library and tool - --disable-afm2pl do not build the afm2pl package - --disable-bibtex-x do not build the bibtex-x package - --disable-bibtex8 do not build the bibtex8 program - --disable-bibtexu do not build the bibtexu program - --disable-chktex do not build the chktex package - --disable-cjkutils do not build the cjkutils package - --disable-detex do not build the detex package - --disable-dtl do not build the dtl package - --disable-dvi2tty do not build the dvi2tty package - --disable-dvidvi do not build the dvidvi package - --disable-dviljk do not build the dviljk package - --disable-dviout-util do not build the dviout-util package - --disable-dvipdfm-x do not build the dvipdfm-x package - --disable-dvipng do not build the dvipng package - --disable-debug Compile without debug (-d) option - --enable-timing Output execution time of dvipng - --disable-dvipos do not build the dvipos package - --disable-dvipsk do not build the dvipsk package - --disable-dvisvgm do not build the dvisvgm package - --disable-gregorio do not build the gregorio package - --disable-gsftopk do not build the gsftopk package - --disable-lcdf-typetools - do not build the lcdf-typetools package - --disable-cfftot1 do not build the cfftot1 program - --disable-mmafm do not build the mmafm program - --disable-mmpfb do not build the mmpfb program - --disable-otfinfo do not build the otfinfo program - --disable-otftotfm do not build the otftotfm program - --disable-t1dotlessj do not build the t1dotlessj program - --disable-t1lint do not build the t1lint program - --disable-t1rawafm do not build the t1rawafm program - --disable-t1reencode do not build the t1reencode program - --disable-t1testpage do not build the t1testpage program - --disable-ttftotype42 do not build the ttftotype42 program - --disable-auto-cfftot1 disable running cfftot1 from otftotfm - --disable-auto-t1dotlessj disable running t1dotlessj from otftotfm - --disable-auto-ttftotype42 - disable running ttftotype42 from otftotfm - --disable-auto-updmap disable running updmap from otftotfm - --disable-makeindexk do not build the makeindexk package - --disable-makejvf do not build the makejvf package - --disable-mendexk do not build the mendexk package - --disable-musixtnt do not build the musixtnt package - --disable-ps2pk do not build the ps2pk package - --disable-psutils do not build the psutils package - --disable-seetexk do not build the seetexk package - --disable-tex4htk do not build the tex4htk package - --disable-ttf2pk2 do not build the ttf2pk2 package - --disable-ttfdump do not build the ttfdump package - --disable-upmendex do not build the upmendex package - --disable-xdvik do not build the xdvik package --disable-texlive do not build the texlive (TeX Live scripts) package --disable-linked-scripts do not install the linked scripts --disable-mktexmf-default do not run mktexmf if MF source missing @@ -1792,68 +1636,24 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-clisp-runtime=PATH - pathname of clisp runtime to install for `xindy', - `default' to derive from clisp, or `system' to use - installed version --with-banner-add=STR add STR to version string appended to banner lines --with-editor=CMD invoke CMD from the `e' option [vi +%d '%s'] or [texworks --position=%d "%s"] --with-mf-x-toolkit use X toolkit for METAFONT - --with-gs=/PATH/TO/gs Hard-wire the location of GhostScript - --with-xdvi-x-toolkit=KIT - Use toolkit KIT (xaw/motif/xaw3d/neXtaw) for xdvi - [default: Xaw] --with-system-harfbuzz use installed harfbuzz headers and library (requires pkg-config) - --with-system-icu use installed ICU headers and libraries (requires - pkg-config or icu-config) - --with-system-teckit use installed teckit headers and library (requires - pkg-config) --with-system-graphite2 use installed graphite2 headers and library (requires pkg-config) --with-system-zziplib use installed zziplib headers and library (requires pkg-config) - --with-system-mpfi use installed mpfi headers and library - --with-mpfi-includes=DIR - mpfi headers installed in DIR - --with-mpfi-libdir=DIR mpfi library installed in DIR - --with-system-mpfr use installed mpfr headers and library - --with-mpfr-includes=DIR - mpfr headers installed in DIR - --with-mpfr-libdir=DIR mpfr library installed in DIR - --with-system-gmp use installed gmp headers and library - --with-gmp-includes=DIR gmp headers installed in DIR - --with-gmp-libdir=DIR gmp library installed in DIR - --with-system-cairo use installed cairo headers and library (requires - pkg-config) - --with-system-pixman use installed pixman headers and library (requires - pkg-config) - --with-system-gd use installed gd headers and library - --with-gd-includes=DIR gd headers installed in DIR - --with-gd-libdir=DIR gd library installed in DIR - --with-system-potrace use installed potrace headers and library - --with-potrace-includes=DIR - potrace headers installed in DIR - --with-potrace-libdir=DIR - potrace library installed in DIR - --with-system-freetype2 use installed freetype2 headers and library - (requires freetype-config) --with-system-libpng use installed libpng headers and library (requires pkg-config) - --with-system-libpaper use installed libpaper headers and library - --with-libpaper-includes=DIR - libpaper headers installed in DIR - --with-libpaper-libdir=DIR - libpaper library installed in DIR --with-system-luajit use installed luajit headers and library (requires pkg-config) --with-system-zlib use installed zlib headers and library --with-zlib-includes=DIR zlib headers installed in DIR --with-zlib-libdir=DIR zlib library installed in DIR - --with-system-ptexenc use installed ptexenc headers and library (requires - pkg-config) --with-system-kpathsea use installed kpathsea headers and library (requires pkg-config) --with-gnu-ld assume the C compiler uses GNU ld [default=no] @@ -1945,7 +1745,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -TeX Live configure 2024-03-10 +TeX Live configure 2025-03-07 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2653,7 +2453,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by TeX Live $as_me 2024-03-10, which was +It was created by TeX Live $as_me 2025-03-07, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -5265,333 +5065,6 @@ printf "%s\n" "$as_me: $host -> \`--disable-mfluajit-nowin'" >&6;} esac ;; esac -## utils/autosp/ac/withenable.ac: configure.ac fragment for Tl subdir -## configure options and TL libraries required for autosp. -# Check whether --enable-autosp was given. -if test ${enable_autosp+y} -then : - enableval=$enable_autosp; -fi -case $enable_autosp in #( - yes|no) : - ;; #( - *) : - - enable_autosp=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-autosp=$enable_autosp'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-autosp=$enable_autosp'" >&6;} - ac_configure_args="$ac_configure_args '--enable-autosp=$enable_autosp'" - ;; -esac - -## utils/axodraw2/ac/withenable.ac: configure.ac fragment for TL subdir -## configure options and TL libraries for axodraw2. -# Check whether --enable-axodraw2 was given. -if test ${enable_axodraw2+y} -then : - enableval=$enable_axodraw2; -fi -case $enable_axodraw2 in #( - yes|no) : - ;; #( - *) : - - enable_axodraw2=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-axodraw2=$enable_axodraw2'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-axodraw2=$enable_axodraw2'" >&6;} - ac_configure_args="$ac_configure_args '--enable-axodraw2=$enable_axodraw2'" - ;; -esac - -## utils/devnag/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/devnag/ -## configure options and TL libraries required for devnag -# Check whether --enable-devnag was given. -if test ${enable_devnag+y} -then : - enableval=$enable_devnag; -fi -case $enable_devnag in #( - yes|no) : - ;; #( - *) : - - enable_devnag=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-devnag=$enable_devnag'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-devnag=$enable_devnag'" >&6;} - ac_configure_args="$ac_configure_args '--enable-devnag=$enable_devnag'" - ;; -esac - -## utils/lacheck/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/lacheck/ -## configure options and TL libraries required for lacheck -# Check whether --enable-lacheck was given. -if test ${enable_lacheck+y} -then : - enableval=$enable_lacheck; -fi -case $enable_lacheck in #( - yes|no) : - ;; #( - *) : - - enable_lacheck=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-lacheck=$enable_lacheck'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-lacheck=$enable_lacheck'" >&6;} - ac_configure_args="$ac_configure_args '--enable-lacheck=$enable_lacheck'" - ;; -esac - -## utils/m-tx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/m-tx/ -## configure options and TL libraries required for mtx -# Check whether --enable-m-tx was given. -if test ${enable_m_tx+y} -then : - enableval=$enable_m_tx; -fi -case $enable_m_tx in #( - yes|no) : - ;; #( - *) : - - enable_m_tx=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-m-tx=$enable_m_tx'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-m-tx=$enable_m_tx'" >&6;} - ac_configure_args="$ac_configure_args '--enable-m-tx=$enable_m_tx'" - ;; -esac - -## utils/pmx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/pmx/ -## configure options and TL libraries required for pmx -# Check whether --enable-pmx was given. -if test ${enable_pmx+y} -then : - enableval=$enable_pmx; -fi -case $enable_pmx in #( - yes|no) : - ;; #( - *) : - - enable_pmx=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-pmx=$enable_pmx'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-pmx=$enable_pmx'" >&6;} - ac_configure_args="$ac_configure_args '--enable-pmx=$enable_pmx'" - ;; -esac - -## utils/ps2eps/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/ps2eps/ -## configure options and TL libraries required for ps2eps -# Check whether --enable-ps2eps was given. -if test ${enable_ps2eps+y} -then : - enableval=$enable_ps2eps; -fi -case $enable_ps2eps in #( - yes|no) : - ;; #( - *) : - - enable_ps2eps=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ps2eps=$enable_ps2eps'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-ps2eps=$enable_ps2eps'" >&6;} - ac_configure_args="$ac_configure_args '--enable-ps2eps=$enable_ps2eps'" - ;; -esac - -## utils/t1utils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/t1utils/ -## configure options and TL libraries required for t1utils -# Check whether --enable-t1utils was given. -if test ${enable_t1utils+y} -then : - enableval=$enable_t1utils; -fi -case $enable_t1utils in #( - yes|no) : - ;; #( - *) : - - enable_t1utils=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-t1utils=$enable_t1utils'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-t1utils=$enable_t1utils'" >&6;} - ac_configure_args="$ac_configure_args '--enable-t1utils=$enable_t1utils'" - ;; -esac - -## utils/texdoctk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/texdoctk/ -## configure options and TL libraries required for texdoctk -# Check whether --enable-texdoctk was given. -if test ${enable_texdoctk+y} -then : - enableval=$enable_texdoctk; -fi -case $enable_texdoctk in #( - yes|no) : - ;; #( - *) : - - enable_texdoctk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texdoctk=$enable_texdoctk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-texdoctk=$enable_texdoctk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-texdoctk=$enable_texdoctk'" - ;; -esac - -## utils/tpic2pdftex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/tpic2pdftex/ -## configure options and TL libraries required for tpic2pdftex -# Check whether --enable-tpic2pdftex was given. -if test ${enable_tpic2pdftex+y} -then : - enableval=$enable_tpic2pdftex; -fi -case $enable_tpic2pdftex in #( - yes|no) : - ;; #( - *) : - - enable_tpic2pdftex=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-tpic2pdftex=$enable_tpic2pdftex'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-tpic2pdftex=$enable_tpic2pdftex'" >&6;} - ac_configure_args="$ac_configure_args '--enable-tpic2pdftex=$enable_tpic2pdftex'" - ;; -esac - -## utils/vlna/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/vlna/ -## configure options and TL libraries required for vlna -# Check whether --enable-vlna was given. -if test ${enable_vlna+y} -then : - enableval=$enable_vlna; -fi -case $enable_vlna in #( - yes|no) : - ;; #( - *) : - - enable_vlna=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-vlna=$enable_vlna'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-vlna=$enable_vlna'" >&6;} - ac_configure_args="$ac_configure_args '--enable-vlna=$enable_vlna'" - ;; -esac - -## utils/xindy/ac/withenable.ac: configure.ac fragment for TL subdir -## configure options and TL libraries required for xindy. -# Check whether --enable-xindy was given. -if test ${enable_xindy+y} -then : - enableval=$enable_xindy; -fi -case $enable_xindy in #( - yes|no) : - ;; #( - *) : - - enable_xindy=no - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xindy=$enable_xindy'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-xindy=$enable_xindy'" >&6;} - ac_configure_args="$ac_configure_args '--enable-xindy=$enable_xindy'" - ;; -esac - -## utils/xindy/ac/xindy.ac: configure.ac fragment for the TeX Live subdirectory utils/xindy/ -## configure options for xindy -# Check whether --enable-xindy-rules was given. -if test ${enable_xindy_rules+y} -then : - enableval=$enable_xindy_rules; -fi -# Check whether --enable-xindy-docs was given. -if test ${enable_xindy_docs+y} -then : - enableval=$enable_xindy_docs; -fi - -# Check whether --with-clisp-runtime was given. -if test ${with_clisp_runtime+y} -then : - withval=$with_clisp_runtime; -fi - -## utils/xindy/ac/clisp.ac: configure.ac fragment for the TeX Live subdirectory utils/xindy/ -## configure checks for xindy and clisp -case $with_clisp_runtime in #( - default) : - ;; #( - system) : - if test "x$enable_native_texlive_build" = xyes -then : - as_fn_error $? "you can not use the installed clisp for a native TeX Live build" "$LINENO" 5 -fi ;; #( - "") : - if test "x$enable_native_texlive_build" = xyes -then : - with_clisp_runtime=default -else case e in #( - e) with_clisp_runtime=system ;; -esac -fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--with-clisp-runtime=$with_clisp_runtime'" >&5 -printf "%s\n" "$as_me: Assuming \`--with-clisp-runtime=$with_clisp_runtime'" >&6;} - ac_configure_args="$ac_configure_args '--with-clisp-runtime=$with_clisp_runtime'" ;; #( - *) : - if test ! -f "$with_clisp_runtime" -then : - as_fn_error $? "no such file: \"$with_clisp_runtime\"" "$LINENO" 5 -fi ;; -esac - -## utils/xml2pmx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/xml2pmx/ -## configure options and TL libraries required for xml2pmx -# Check whether --enable-xml2pmx was given. -if test ${enable_xml2pmx+y} -then : - enableval=$enable_xml2pmx; -fi -case $enable_xml2pmx in #( - yes|no) : - ;; #( - *) : - - enable_xml2pmx=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xml2pmx=$enable_xml2pmx'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-xml2pmx=$enable_xml2pmx'" >&6;} - ac_configure_args="$ac_configure_args '--enable-xml2pmx=$enable_xml2pmx'" - ;; -esac - -## utils/xpdfopen/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/xpdfopen/ -## configure options and TL libraries required for xpdfopen -# Check whether --enable-xpdfopen was given. -if test ${enable_xpdfopen+y} -then : - enableval=$enable_xpdfopen; -fi -if test "x$with_x" = xno -then : - case $enable_xpdfopen in #( - "") : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \`--without-x' -> \`--disable-xpdfopen'" >&5 -printf "%s\n" "$as_me: \`--without-x' -> \`--disable-xpdfopen'" >&6;} - enable_xpdfopen=no - ac_configure_args="$ac_configure_args '--disable-xpdfopen'" ;; #( - yes) : - as_fn_error $? "Sorry, incompatible options \`--without-x' and \`--enable-xpdfopen'" "$LINENO" 5 ;; #( - *) : - ;; -esac -fi -case $enable_xpdfopen in #( - yes|no) : - ;; #( - *) : - - enable_xpdfopen=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xpdfopen=$enable_xpdfopen'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-xpdfopen=$enable_xpdfopen'" >&6;} - ac_configure_args="$ac_configure_args '--enable-xpdfopen=$enable_xpdfopen'" - ;; -esac - ## texk/web2c/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/web2c/ ## configure options and TL libraries required for web2c @@ -6106,1839 +5579,1236 @@ then : fi -## texk/afm2pl/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/afm2pl/ -## configure options and TL libraries required for afm2pl -# Check whether --enable-afm2pl was given. -if test ${enable_afm2pl+y} +## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ +## configure options and TL libraries required for texlive +# Check whether --enable-texlive was given. +if test ${enable_texlive+y} then : - enableval=$enable_afm2pl; + enableval=$enable_texlive; fi -case $enable_afm2pl in #( +case $enable_texlive in #( yes|no) : ;; #( *) : - enable_afm2pl=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-afm2pl=$enable_afm2pl'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-afm2pl=$enable_afm2pl'" >&6;} - ac_configure_args="$ac_configure_args '--enable-afm2pl=$enable_afm2pl'" + enable_texlive=$enable_all_pkgs + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texlive=$enable_texlive'" >&5 +printf "%s\n" "$as_me: Assuming \`--enable-texlive=$enable_texlive'" >&6;} + ac_configure_args="$ac_configure_args '--enable-texlive=$enable_texlive'" ;; esac -test "x$enable_afm2pl" = xno || { - need_kpathsea=yes -} - -## texk/bibtex-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/bibtex-x/ -## configure options and TL libraries required for bibtex-x -# Check whether --enable-bibtex-x was given. -if test ${enable_bibtex_x+y} +## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ +## configure options for texlive +# Check whether --enable-linked-scripts was given. +if test ${enable_linked_scripts+y} then : - enableval=$enable_bibtex_x; + enableval=$enable_linked_scripts; fi -case $enable_bibtex_x in #( - yes|no) : - ;; #( - *) : - enable_bibtex_x=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-bibtex-x=$enable_bibtex_x'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-bibtex-x=$enable_bibtex_x'" >&6;} - ac_configure_args="$ac_configure_args '--enable-bibtex-x=$enable_bibtex_x'" - ;; -esac -test "x$enable_bibtex_x" = xno || { - need_kpathsea=yes +## libs/pplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pplib/ +## configure options and TL libraries required for pplib + +test "x$need_pplib" = xyes && { + need_zlib=yes } -## texk/bibtex-x/ac/bibtex-x.ac: configure.ac fragment for the TeX Live subdirectory texk/bibtex-x/ -## configure options for bibtex-x -# Check whether --enable-bibtex8 was given. -if test ${enable_bibtex8+y} -then : - enableval=$enable_bibtex8; -fi +## libs/harfbuzz/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/ +## configure options and TL libraries required for harfbuzz -case $enable_bibtex8 in #( - yes | no) : - ;; #( - *) : - enable_bibtex8=yes ;; -esac -# Check whether --enable-bibtexu was given. -if test ${enable_bibtexu+y} +# Check whether --with-system-harfbuzz was given. +if test ${with_system_harfbuzz+y} then : - enableval=$enable_bibtexu; + withval=$with_system_harfbuzz; +fi +if test "x$with_system_harfbuzz" = x; then + if test -f $srcdir/libs/harfbuzz/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`harfbuzz' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`harfbuzz' headers and library from TL tree" >&6;} + with_system_harfbuzz=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`harfbuzz' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`harfbuzz' headers and library" >&6;} + with_system_harfbuzz=yes + fi + ac_configure_args="$ac_configure_args '--with-system-harfbuzz=$with_system_harfbuzz'" +elif test "x$with_system_harfbuzz" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`harfbuzz' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`harfbuzz' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`harfbuzz' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`harfbuzz' headers and library from TL tree" >&6;} + if test "x$with_system_harfbuzz" != xno; then + with_system_harfbuzz=no + ac_configure_args="$ac_configure_args '--without-system-harfbuzz'" + fi +fi +if test "x$with_system_harfbuzz" = xyes; then + if test "x$with_system_graphite2" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`graphite2' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`graphite2' headers and library" >&6;} + with_system_graphite2=yes + ac_configure_args="$ac_configure_args '--with-system-graphite2'" + elif test "x$with_system_graphite2" != xyes; then + as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-graphite2'" "$LINENO" 5 + fi + if test "x$with_system_icu" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`icu' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`icu' headers and library" >&6;} + with_system_icu=yes + ac_configure_args="$ac_configure_args '--with-system-icu'" + elif test "x$with_system_icu" != xyes; then + as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-icu'" "$LINENO" 5 + fi fi -case $enable_bibtexu in #( - yes | no) : - ;; #( - *) : - enable_bibtexu=yes ;; -esac +test "x$need_harfbuzz" = xyes && { + need_graphite2=yes + need_icu=yes +} -test "x$enable_bibtex_x:$enable_bibtexu" = xyes:yes && need_icu=yes +## libs/graphite2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/graphite2/ +## configure options and TL libraries required for graphite2 -## texk/chktex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/chktex/ -## configure options and TL libraries required for chktex -# Check whether --enable-chktex was given. -if test ${enable_chktex+y} +# Check whether --with-system-graphite2 was given. +if test ${with_system_graphite2+y} then : - enableval=$enable_chktex; + withval=$with_system_graphite2; fi -case $enable_chktex in #( - yes|no) : - ;; #( - *) : - - enable_chktex=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-chktex=$enable_chktex'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-chktex=$enable_chktex'" >&6;} - ac_configure_args="$ac_configure_args '--enable-chktex=$enable_chktex'" - ;; -esac - -test "x$enable_chktex" = xno || { - need_kpathsea=yes -} - -## texk/cjkutils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/cjkutils/ -## configure options and TL libraries required for cjkutils -# Check whether --enable-cjkutils was given. -if test ${enable_cjkutils+y} -then : - enableval=$enable_cjkutils; +if test "x$with_system_graphite2" = x; then + if test -f $srcdir/libs/graphite2/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`graphite2' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`graphite2' headers and library from TL tree" >&6;} + with_system_graphite2=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`graphite2' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`graphite2' headers and library" >&6;} + with_system_graphite2=yes + fi + ac_configure_args="$ac_configure_args '--with-system-graphite2=$with_system_graphite2'" +elif test "x$with_system_graphite2" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`graphite2' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`graphite2' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`graphite2' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`graphite2' headers and library from TL tree" >&6;} + if test "x$with_system_graphite2" != xno; then + with_system_graphite2=no + ac_configure_args="$ac_configure_args '--without-system-graphite2'" + fi fi -case $enable_cjkutils in #( - yes|no) : - ;; #( - *) : - - enable_cjkutils=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-cjkutils=$enable_cjkutils'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-cjkutils=$enable_cjkutils'" >&6;} - ac_configure_args="$ac_configure_args '--enable-cjkutils=$enable_cjkutils'" - ;; -esac -test "x$enable_cjkutils" = xno || { - need_kpathsea=yes -} +## libs/zziplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/ +## configure options and TL libraries required for zziplib -## texk/detex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/detex/ -## configure options and TL libraries required for detex -# Check whether --enable-detex was given. -if test ${enable_detex+y} +# Check whether --with-system-zziplib was given. +if test ${with_system_zziplib+y} then : - enableval=$enable_detex; + withval=$with_system_zziplib; fi -case $enable_detex in #( - yes|no) : - ;; #( - *) : - - enable_detex=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-detex=$enable_detex'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-detex=$enable_detex'" >&6;} - ac_configure_args="$ac_configure_args '--enable-detex=$enable_detex'" - ;; -esac - -test "x$enable_detex" = xno || { - need_kpathsea=yes -} - -## texk/dtl/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dtl/ -## configure options and TL libraries required for dtl -# Check whether --enable-dtl was given. -if test ${enable_dtl+y} -then : - enableval=$enable_dtl; +if test "x$with_system_zziplib" = x; then + if test -f $srcdir/libs/zziplib/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zziplib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`zziplib' headers and library from TL tree" >&6;} + with_system_zziplib=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zziplib' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`zziplib' headers and library" >&6;} + with_system_zziplib=yes + fi + ac_configure_args="$ac_configure_args '--with-system-zziplib=$with_system_zziplib'" +elif test "x$with_system_zziplib" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zziplib' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`zziplib' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zziplib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`zziplib' headers and library from TL tree" >&6;} + if test "x$with_system_zziplib" != xno; then + with_system_zziplib=no + ac_configure_args="$ac_configure_args '--without-system-zziplib'" + fi fi -case $enable_dtl in #( - yes|no) : - ;; #( - *) : - - enable_dtl=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dtl=$enable_dtl'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dtl=$enable_dtl'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dtl=$enable_dtl'" - ;; -esac - -test "x$enable_dtl" = xno || { - need_kpathsea=yes -} - -## texk/dvi2tty/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvi2tty/ -## configure options and TL libraries required for dvi2tty -# Check whether --enable-dvi2tty was given. -if test ${enable_dvi2tty+y} -then : - enableval=$enable_dvi2tty; +if test "x$with_system_zziplib" = xyes; then + if test "x$with_system_zlib" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + ac_configure_args="$ac_configure_args '--with-system-zlib'" + elif test "x$with_system_zlib" != xyes; then + as_fn_error $? "Sorry, \`--with-system-zziplib' requires \`--with-system-zlib'" "$LINENO" 5 + fi fi -case $enable_dvi2tty in #( - yes|no) : - ;; #( - *) : - - enable_dvi2tty=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvi2tty=$enable_dvi2tty'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvi2tty=$enable_dvi2tty'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvi2tty=$enable_dvi2tty'" - ;; -esac -test "x$enable_dvi2tty" = xno || { - need_ptexenc=yes +test "x$need_zziplib" = xyes && { + need_zlib=yes } -## texk/dvidvi/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvidvi/ -## configure options and TL libraries required for dvidvi -# Check whether --enable-dvidvi was given. -if test ${enable_dvidvi+y} -then : - enableval=$enable_dvidvi; -fi -case $enable_dvidvi in #( - yes|no) : - ;; #( - *) : - - enable_dvidvi=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvidvi=$enable_dvidvi'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvidvi=$enable_dvidvi'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvidvi=$enable_dvidvi'" - ;; -esac - -test "x$enable_dvidvi" = xno || { - need_kpathsea=yes -} +## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ +## configure options and TL libraries required for libpng -## texk/dviljk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dviljk/ -## configure options and TL libraries required for dviljk -# Check whether --enable-dviljk was given. -if test ${enable_dviljk+y} +# Check whether --with-system-libpng was given. +if test ${with_system_libpng+y} then : - enableval=$enable_dviljk; + withval=$with_system_libpng; fi -case $enable_dviljk in #( - yes|no) : - ;; #( - *) : - - enable_dviljk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dviljk=$enable_dviljk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dviljk=$enable_dviljk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dviljk=$enable_dviljk'" - ;; -esac - -test "x$enable_dviljk" = xno || { - need_kpathsea=yes -} - -## texk/dviout-util/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dviout-util/ -## configure options and TL libraries required for dviout-util -# Check whether --enable-dviout-util was given. -if test ${enable_dviout_util+y} -then : - enableval=$enable_dviout_util; +if test "x$with_system_libpng" = x; then + if test -f $srcdir/libs/libpng/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpng' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`libpng' headers and library from TL tree" >&6;} + with_system_libpng=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpng' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`libpng' headers and library" >&6;} + with_system_libpng=yes + fi + ac_configure_args="$ac_configure_args '--with-system-libpng=$with_system_libpng'" +elif test "x$with_system_libpng" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpng' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`libpng' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpng' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`libpng' headers and library from TL tree" >&6;} + if test "x$with_system_libpng" != xno; then + with_system_libpng=no + ac_configure_args="$ac_configure_args '--without-system-libpng'" + fi fi -case $enable_dviout_util in #( - yes|no) : - ;; #( - *) : - - enable_dviout_util=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dviout-util=$enable_dviout_util'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dviout-util=$enable_dviout_util'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dviout-util=$enable_dviout_util'" - ;; -esac - -test "x$enable_dviout_util" = xno || { - need_ptexenc=yes -} - -## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/ -## configure options and TL libraries required for dvipdfm-x -# Check whether --enable-dvipdfm-x was given. -if test ${enable_dvipdfm_x+y} -then : - enableval=$enable_dvipdfm_x; +if test "x$with_system_libpng" = xyes; then + if test "x$with_system_zlib" = x; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + ac_configure_args="$ac_configure_args '--with-system-zlib'" + elif test "x$with_system_zlib" != xyes; then + as_fn_error $? "Sorry, \`--with-system-libpng' requires \`--with-system-zlib'" "$LINENO" 5 + fi fi -case $enable_dvipdfm_x in #( - yes|no) : - ;; #( - *) : - enable_dvipdfm_x=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdfm-x=$enable_dvipdfm_x'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvipdfm-x=$enable_dvipdfm_x'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvipdfm-x=$enable_dvipdfm_x'" - ;; -esac - -test "x$enable_dvipdfm_x" = xno || { - need_kpathsea=yes - need_libpng=yes - need_libpaper=yes +test "x$need_libpng" = xyes && { + need_zlib=yes } -## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ -## configure options and TL libraries required for dvipng -# Check whether --enable-dvipng was given. -if test ${enable_dvipng+y} +## libs/luajit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ +## configure options and TL libraries required for luajit + +# Check whether --with-system-luajit was given. +if test ${with_system_luajit+y} then : - enableval=$enable_dvipng; + withval=$with_system_luajit; +fi +if test "x$with_system_luajit" = x; then + if test -f $srcdir/libs/luajit/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`luajit' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`luajit' headers and library from TL tree" >&6;} + with_system_luajit=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`luajit' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`luajit' headers and library" >&6;} + with_system_luajit=yes + fi + ac_configure_args="$ac_configure_args '--with-system-luajit=$with_system_luajit'" +elif test "x$with_system_luajit" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`luajit' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`luajit' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`luajit' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`luajit' headers and library from TL tree" >&6;} + if test "x$with_system_luajit" != xno; then + with_system_luajit=no + ac_configure_args="$ac_configure_args '--without-system-luajit'" + fi fi -case $enable_dvipng in #( - yes|no) : - ;; #( - *) : - enable_dvipng=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipng=$enable_dvipng'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvipng=$enable_dvipng'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvipng=$enable_dvipng'" - ;; -esac +## libs/lua53/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/lua53/ +## configure options and TL libraries required for lua53 -test "x$enable_dvipng" = xno || { - need_kpathsea=yes - need_gd=yes -} +## libs/zlib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ +## configure options and TL libraries required for zlib -## texk/dvipng/ac/dvipng.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ -## configure options for dvipng -# Check whether --enable-debug was given. -if test ${enable_debug+y} +# Check whether --with-system-zlib was given. +if test ${with_system_zlib+y} then : - enableval=$enable_debug; + withval=$with_system_zlib; fi -# Check whether --enable-timing was given. -if test ${enable_timing+y} +# Check whether --with-zlib-includes was given. +if test ${with_zlib_includes+y} then : - enableval=$enable_timing; + withval=$with_zlib_includes; fi - -# Check whether --with-gs was given. -if test ${with_gs+y} +# Check whether --with-zlib-libdir was given. +if test ${with_zlib_libdir+y} then : - withval=$with_gs; + withval=$with_zlib_libdir; +fi +if test "x$with_system_zlib" = x; then + if test -f $srcdir/libs/zlib/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zlib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`zlib' headers and library from TL tree" >&6;} + with_system_zlib=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`zlib' headers and library" >&6;} + with_system_zlib=yes + fi + ac_configure_args="$ac_configure_args '--with-system-zlib=$with_system_zlib'" +elif test "x$with_system_zlib" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zlib' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`zlib' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zlib' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`zlib' headers and library from TL tree" >&6;} + if test "x$with_system_zlib" != xno; then + with_system_zlib=no + ac_configure_args="$ac_configure_args '--without-system-zlib'" + fi fi -## texk/dvipos/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipos/ -## configure options and TL libraries required for dvipos -# Check whether --enable-dvipos was given. -if test ${enable_dvipos+y} +## texk/kpathsea/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ +## configure options and TL libraries required for kpathsea + +# Check whether --with-system-kpathsea was given. +if test ${with_system_kpathsea+y} then : - enableval=$enable_dvipos; + withval=$with_system_kpathsea; fi -case $enable_dvipos in #( - yes|no) : - ;; #( - *) : - - enable_dvipos=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipos=$enable_dvipos'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvipos=$enable_dvipos'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvipos=$enable_dvipos'" - ;; -esac - -test "x$enable_dvipos" = xno || { - need_kpathsea=yes -} - -## texk/dvipsk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipsk/ -## configure options and TL libraries required for dvipsk -# Check whether --enable-dvipsk was given. -if test ${enable_dvipsk+y} -then : - enableval=$enable_dvipsk; -fi -case $enable_dvipsk in #( - yes|no) : - ;; #( - *) : - - enable_dvipsk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipsk=$enable_dvipsk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvipsk=$enable_dvipsk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvipsk=$enable_dvipsk'" - ;; -esac - -test "x$enable_dvipsk" = xno || { - need_kpathsea=yes -} - -# texk/dvisvgm/ac/withenable.ac: configure.ac fragment -## configure options and TL libraries required for dvisvgm -# Check whether --enable-dvisvgm was given. -if test ${enable_dvisvgm+y} -then : - enableval=$enable_dvisvgm; -fi -case $enable_dvisvgm in #( - yes|no) : - ;; #( - *) : - - enable_dvisvgm=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvisvgm=$enable_dvisvgm'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-dvisvgm=$enable_dvisvgm'" >&6;} - ac_configure_args="$ac_configure_args '--enable-dvisvgm=$enable_dvisvgm'" - ;; -esac - -test "x$enable_dvisvgm" = xno || { - need_kpathsea=yes - need_potrace=yes - need_freetype2=yes - need_zlib=yes -} - -## texk/gregorio/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/gregorio/ -## configure options and TL libraries required for gregorio -# Check whether --enable-gregorio was given. -if test ${enable_gregorio+y} -then : - enableval=$enable_gregorio; -fi -case $enable_gregorio in #( - yes|no) : - ;; #( - *) : - - enable_gregorio=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-gregorio=$enable_gregorio'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-gregorio=$enable_gregorio'" >&6;} - ac_configure_args="$ac_configure_args '--enable-gregorio=$enable_gregorio'" - ;; -esac - -test "x$enable_gregorio" = xno || { - need_kpathsea=yes -} - -## texk/gsftopk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/gsftopk/ -## configure options and TL libraries required for gsftopk -# Check whether --enable-gsftopk was given. -if test ${enable_gsftopk+y} -then : - enableval=$enable_gsftopk; -fi -case $enable_gsftopk in #( - yes|no) : - ;; #( - *) : - - enable_gsftopk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-gsftopk=$enable_gsftopk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-gsftopk=$enable_gsftopk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-gsftopk=$enable_gsftopk'" - ;; -esac - -test "x$enable_gsftopk" = xno || { - need_kpathsea=yes -} - -## texk/lcdf-typetools/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/lcdf-typetools/ -## configure options and TL libraries required for lcdf-typetools -# Check whether --enable-lcdf-typetools was given. -if test ${enable_lcdf_typetools+y} -then : - enableval=$enable_lcdf_typetools; +if test "x$with_system_kpathsea" = x; then + if test -f $srcdir/texk/kpathsea/configure; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`kpathsea' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Assuming \`kpathsea' headers and library from TL tree" >&6;} + with_system_kpathsea=no + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`kpathsea' headers and library" >&5 +printf "%s\n" "$as_me: Assuming installed \`kpathsea' headers and library" >&6;} + with_system_kpathsea=yes + fi + ac_configure_args="$ac_configure_args '--with-system-kpathsea=$with_system_kpathsea'" +elif test "x$with_system_kpathsea" = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`kpathsea' headers and library" >&5 +printf "%s\n" "$as_me: Using installed \`kpathsea' headers and library" >&6;} +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`kpathsea' headers and library from TL tree" >&5 +printf "%s\n" "$as_me: Using \`kpathsea' headers and library from TL tree" >&6;} + if test "x$with_system_kpathsea" != xno; then + with_system_kpathsea=no + ac_configure_args="$ac_configure_args '--without-system-kpathsea'" + fi fi -case $enable_lcdf_typetools in #( - yes|no) : - ;; #( - *) : - - enable_lcdf_typetools=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-lcdf-typetools=$enable_lcdf_typetools'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-lcdf-typetools=$enable_lcdf_typetools'" >&6;} - ac_configure_args="$ac_configure_args '--enable-lcdf-typetools=$enable_lcdf_typetools'" - ;; -esac - -test "x$enable_lcdf_typetools" = xno || { - need_kpathsea=yes -} -# Define configure options for lcdf-typetools. Extracted from configure.ac -# for ease of building TeX Live. -# -# -# Check whether --enable-cfftot1 was given. -if test ${enable_cfftot1+y} -then : - enableval=$enable_cfftot1; -fi -# Check whether --enable-mmafm was given. -if test ${enable_mmafm+y} -then : - enableval=$enable_mmafm; -fi -# Check whether --enable-mmpfb was given. -if test ${enable_mmpfb+y} -then : - enableval=$enable_mmpfb; -fi -# Check whether --enable-otfinfo was given. -if test ${enable_otfinfo+y} -then : - enableval=$enable_otfinfo; -fi -# Check whether --enable-otftotfm was given. -if test ${enable_otftotfm+y} +## texk/kpathsea/ac/mktex.ac: configure.ac fragment for the TeX Live +## subdirectory texk/kpathsea. +## configure defaults for mktexfmt & Co. +# Check whether --enable-mktexmf-default was given. +if test ${enable_mktexmf_default+y} then : - enableval=$enable_otftotfm; + enableval=$enable_mktexmf_default; fi -# Check whether --enable-t1dotlessj was given. -if test ${enable_t1dotlessj+y} +# Check whether --enable-mktexpk-default was given. +if test ${enable_mktexpk_default+y} then : - enableval=$enable_t1dotlessj; + enableval=$enable_mktexpk_default; fi -# Check whether --enable-t1lint was given. -if test ${enable_t1lint+y} +# Check whether --enable-mktextfm-default was given. +if test ${enable_mktextfm_default+y} then : - enableval=$enable_t1lint; + enableval=$enable_mktextfm_default; fi -# Check whether --enable-t1rawafm was given. -if test ${enable_t1rawafm+y} +# Check whether --enable-mkocp-default was given. +if test ${enable_mkocp_default+y} then : - enableval=$enable_t1rawafm; + enableval=$enable_mkocp_default; fi -# Check whether --enable-t1reencode was given. -if test ${enable_t1reencode+y} +# Check whether --enable-mkofm-default was given. +if test ${enable_mkofm_default+y} then : - enableval=$enable_t1reencode; + enableval=$enable_mkofm_default; fi -# Check whether --enable-t1testpage was given. -if test ${enable_t1testpage+y} +# Check whether --enable-mktexfmt-default was given. +if test ${enable_mktexfmt_default+y} then : - enableval=$enable_t1testpage; + enableval=$enable_mktexfmt_default; fi -# Check whether --enable-ttftotype42 was given. -if test ${enable_ttftotype42+y} +# Check whether --enable-mktextex-default was given. +if test ${enable_mktextex_default+y} then : - enableval=$enable_ttftotype42; + enableval=$enable_mktextex_default; fi -# -# Check whether --enable-cfftot1 was given. -if test ${enable_cfftot1+y} -then : - enableval=$enable_cfftot1; -fi -# Check whether --enable-t1dotlessj was given. -if test ${enable_t1dotlessj+y} -then : - enableval=$enable_t1dotlessj; -fi -# Check whether --enable-ttftotype42 was given. -if test ${enable_ttftotype42+y} -then : - enableval=$enable_ttftotype42; -fi -# Check whether --enable-updmap was given. -if test ${enable_updmap+y} -then : - enableval=$enable_updmap; -fi -## texk/makeindexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/makeindexk/ -## configure options and TL libraries required for makeindexk -# Check whether --enable-makeindexk was given. -if test ${enable_makeindexk+y} -then : - enableval=$enable_makeindexk; -fi -case $enable_makeindexk in #( - yes|no) : - ;; #( - *) : +# end of kpse_setup macro. +echo 'tldbg:KPSE_SETUP done (toplevel=)' >&5 - enable_makeindexk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-makeindexk=$enable_makeindexk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-makeindexk=$enable_makeindexk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-makeindexk=$enable_makeindexk'" - ;; -esac -test "x$enable_makeindexk" = xno || { - need_kpathsea=yes -} +am__api_version='1.17' -## texk/makejvf/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/makejvf/ -## configure options and TL libraries required for makejvf -# Check whether --enable-makejvf was given. -if test ${enable_makejvf+y} -then : - enableval=$enable_makejvf; -fi -case $enable_makejvf in #( - yes|no) : - ;; #( - *) : - enable_makejvf=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-makejvf=$enable_makejvf'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-makejvf=$enable_makejvf'" >&6;} - ac_configure_args="$ac_configure_args '--enable-makejvf=$enable_makejvf'" + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done ;; esac -test "x$enable_makejvf" = xno || { - need_ptexenc=yes -} + done +IFS=$as_save_IFS -## texk/mendexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/mendexk/ -## configure options and TL libraries required for mendexk -# Check whether --enable-mendexk was given. -if test ${enable_mendexk+y} -then : - enableval=$enable_mendexk; +rm -rf conftest.one conftest.two conftest.dir + ;; +esac fi -case $enable_mendexk in #( - yes|no) : - ;; #( - *) : + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } - enable_mendexk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-mendexk=$enable_mendexk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-mendexk=$enable_mendexk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-mendexk=$enable_mendexk'" - ;; -esac +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' -test "x$enable_mendexk" = xno || { - need_ptexenc=yes -} +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -## texk/musixtnt/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/musixtnt/ -## configure options and TL libraries required for musixtnt -# Check whether --enable-musixtnt was given. -if test ${enable_musixtnt+y} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5 +printf %s "checking whether sleep supports fractional seconds... " >&6; } +if test ${am_cv_sleep_fractional_seconds+y} then : - enableval=$enable_musixtnt; -fi -case $enable_musixtnt in #( - yes|no) : - ;; #( - *) : - - enable_musixtnt=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-musixtnt=$enable_musixtnt'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-musixtnt=$enable_musixtnt'" >&6;} - ac_configure_args="$ac_configure_args '--enable-musixtnt=$enable_musixtnt'" - ;; -esac - -test "x$enable_musixtnt" = xno || { - need_kpathsea=yes -} - -## texk/ps2pk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ps2pk/ -## configure options and TL libraries required for ps2pk -# Check whether --enable-ps2pk was given. -if test ${enable_ps2pk+y} + printf %s "(cached) " >&6 +else case e in #( + e) if sleep 0.001 2>/dev/null then : - enableval=$enable_ps2pk; + am_cv_sleep_fractional_seconds=yes +else case e in #( + e) am_cv_sleep_fractional_seconds=no ;; +esac fi -case $enable_ps2pk in #( - yes|no) : - ;; #( - *) : - - enable_ps2pk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ps2pk=$enable_ps2pk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-ps2pk=$enable_ps2pk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-ps2pk=$enable_ps2pk'" - ;; + ;; esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_sleep_fractional_seconds" >&5 +printf "%s\n" "$am_cv_sleep_fractional_seconds" >&6; } -test "x$enable_ps2pk" = xno || { - need_kpathsea=yes -} - -## texk/psutils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/psutils/ -## configure options and TL libraries required for psutils -# Check whether --enable-psutils was given. -if test ${enable_psutils+y} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking filesystem timestamp resolution" >&5 +printf %s "checking filesystem timestamp resolution... " >&6; } +if test ${am_cv_filesystem_timestamp_resolution+y} then : - enableval=$enable_psutils; -fi -case $enable_psutils in #( - yes|no) : - ;; #( - *) : + printf %s "(cached) " >&6 +else case e in #( + e) # Default to the worst case. +am_cv_filesystem_timestamp_resolution=2 - enable_psutils=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-psutils=$enable_psutils'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-psutils=$enable_psutils'" >&6;} - ac_configure_args="$ac_configure_args '--enable-psutils=$enable_psutils'" - ;; -esac +# Only try to go finer than 1 sec if sleep can do it. +# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, +# - 1 sec is not much of a win compared to 2 sec, and +# - it takes 2 seconds to perform the test whether 1 sec works. +# +# Instead, just use the default 2s on platforms that have 1s resolution, +# accept the extra 1s delay when using $sleep in the Automake tests, in +# exchange for not incurring the 2s delay for running the test for all +# packages. +# +am_try_resolutions= +if test "$am_cv_sleep_fractional_seconds" = yes; then + # Even a millisecond often causes a bunch of false positives, + # so just try a hundredth of a second. The time saved between .001 and + # .01 is not terribly consequential. + am_try_resolutions="0.01 0.1 $am_try_resolutions" +fi -test "x$enable_psutils" = xno || { - need_kpathsea=yes - need_libpaper=yes -} +# In order to catch current-generation FAT out, we must *modify* files +# that already exist; the *creation* timestamp is finer. Use names +# that make ls -t sort them differently when they have equal +# timestamps than when they have distinct timestamps, keeping +# in mind that ls -t prints the *newest* file first. +rm -f conftest.ts? +: > conftest.ts1 +: > conftest.ts2 +: > conftest.ts3 -## texk/seetexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/seetexk/ -## configure options and TL libraries required for seetexk -# Check whether --enable-seetexk was given. -if test ${enable_seetexk+y} -then : - enableval=$enable_seetexk; +# Make sure ls -t actually works. Do 'set' in a subshell so we don't +# clobber the current shell's arguments. (Outer-level square brackets +# are removed by m4; they're present so that m4 does not expand +# <dollar><star>; be careful, easy to get confused.) +if ( + set X `ls -t conftest.ts[12]` && + { + test "$*" != "X conftest.ts1 conftest.ts2" || + test "$*" != "X conftest.ts2 conftest.ts1"; + } +); then :; else + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + printf "%s\n" ""Bad output from ls -t: \"`ls -t conftest.ts[12]`\""" >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "ls -t produces unexpected output. +Make sure there is not a broken ls alias in your environment. +See 'config.log' for more details" "$LINENO" 5; } fi -case $enable_seetexk in #( - yes|no) : - ;; #( - *) : - enable_seetexk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-seetexk=$enable_seetexk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-seetexk=$enable_seetexk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-seetexk=$enable_seetexk'" - ;; -esac - -test "x$enable_seetexk" = xno || { - need_kpathsea=yes -} +for am_try_res in $am_try_resolutions; do + # Any one fine-grained sleep might happen to cross the boundary + # between two values of a coarser actual resolution, but if we do + # two fine-grained sleeps in a row, at least one of them will fall + # entirely within a coarse interval. + echo alpha > conftest.ts1 + sleep $am_try_res + echo beta > conftest.ts2 + sleep $am_try_res + echo gamma > conftest.ts3 -## texk/tex4htk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/tex4htk/ -## configure options and TL libraries required for tex4htk -# Check whether --enable-tex4htk was given. -if test ${enable_tex4htk+y} -then : - enableval=$enable_tex4htk; + # We assume that 'ls -t' will make use of high-resolution + # timestamps if the operating system supports them at all. + if (set X `ls -t conftest.ts?` && + test "$2" = conftest.ts3 && + test "$3" = conftest.ts2 && + test "$4" = conftest.ts1); then + # + # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, + # because we don't need to test make. + make_ok=true + if test $am_try_res != 1; then + # But if we've succeeded so far with a subsecond resolution, we + # have one more thing to check: make. It can happen that + # everything else supports the subsecond mtimes, but make doesn't; + # notably on macOS, which ships make 3.81 from 2006 (the last one + # released under GPLv2). https://bugs.gnu.org/68808 + # + # We test $MAKE if it is defined in the environment, else "make". + # It might get overridden later, but our hope is that in practice + # it does not matter: it is the system "make" which is (by far) + # the most likely to be broken, whereas if the user overrides it, + # probably they did so with a better, or at least not worse, make. + # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html + # + # Create a Makefile (real tab character here): + rm -f conftest.mk + echo 'conftest.ts1: conftest.ts2' >conftest.mk + echo ' touch conftest.ts2' >>conftest.mk + # + # Now, running + # touch conftest.ts1; touch conftest.ts2; make + # should touch ts1 because ts2 is newer. This could happen by luck, + # but most often, it will fail if make's support is insufficient. So + # test for several consecutive successes. + # + # (We reuse conftest.ts[12] because we still want to modify existing + # files, not create new ones, per above.) + n=0 + make=${MAKE-make} + until test $n -eq 3; do + echo one > conftest.ts1 + sleep $am_try_res + echo two > conftest.ts2 # ts2 should now be newer than ts1 + if $make -f conftest.mk | grep 'up to date' >/dev/null; then + make_ok=false + break # out of $n loop + fi + n=`expr $n + 1` + done + fi + # + if $make_ok; then + # Everything we know to check worked out, so call this resolution good. + am_cv_filesystem_timestamp_resolution=$am_try_res + break # out of $am_try_res loop + fi + # Otherwise, we'll go on to check the next resolution. + fi +done +rm -f conftest.ts? +# (end _am_filesystem_timestamp_resolution) + ;; +esac fi -case $enable_tex4htk in #( - yes|no) : - ;; #( - *) : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_filesystem_timestamp_resolution" >&5 +printf "%s\n" "$am_cv_filesystem_timestamp_resolution" >&6; } - enable_tex4htk=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-tex4htk=$enable_tex4htk'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-tex4htk=$enable_tex4htk'" >&6;} - ac_configure_args="$ac_configure_args '--enable-tex4htk=$enable_tex4htk'" - ;; +# This check should not be cached, as it may vary across builds of +# different projects. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +printf %s "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -test "x$enable_tex4htk" = xno || { - need_kpathsea=yes -} +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +am_build_env_is_sane=no +am_has_slept=no +rm -f conftest.file +for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + test "$2" = conftest.file + ); then + am_build_env_is_sane=yes + break + fi + # Just in case. + sleep "$am_cv_filesystem_timestamp_resolution" + am_has_slept=yes +done -## texk/ttf2pk2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttf2pk2/ -## configure options and TL libraries required for ttf2pk -# Check whether --enable-ttf2pk2 was given. -if test ${enable_ttf2pk2+y} -then : - enableval=$enable_ttf2pk2; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_build_env_is_sane" >&5 +printf "%s\n" "$am_build_env_is_sane" >&6; } +if test "$am_build_env_is_sane" = no; then + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 fi -case $enable_ttf2pk2 in #( - yes|no) : - ;; #( - *) : - enable_ttf2pk2=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ttf2pk2=$enable_ttf2pk2'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-ttf2pk2=$enable_ttf2pk2'" >&6;} - ac_configure_args="$ac_configure_args '--enable-ttf2pk2=$enable_ttf2pk2'" - ;; -esac - -test "x$enable_ttf2pk2" = xno || { - need_kpathsea=yes - need_freetype2=yes -} - -## texk/ttfdump/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttfdump/ -## configure options and TL libraries required for ttfdump -# Check whether --enable-ttfdump was given. -if test ${enable_ttfdump+y} +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1 then : - enableval=$enable_ttfdump; -fi -case $enable_ttfdump in #( - yes|no) : - ;; #( - *) : - enable_ttfdump=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ttfdump=$enable_ttfdump'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-ttfdump=$enable_ttfdump'" >&6;} - ac_configure_args="$ac_configure_args '--enable-ttfdump=$enable_ttfdump'" - ;; +else case e in #( + e) ( sleep "$am_cv_filesystem_timestamp_resolution" ) & + am_sleep_pid=$! + ;; esac +fi -test "x$enable_ttfdump" = xno || { - need_kpathsea=yes -} +rm -f conftest.file -## texk/upmendex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/upmendex/ -## configure options and TL libraries required for upmendex -# Check whether --enable-upmendex was given. -if test ${enable_upmendex+y} -then : - enableval=$enable_upmendex; -fi -case $enable_upmendex in #( - yes|no) : - ;; #( - *) : - - enable_upmendex=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-upmendex=$enable_upmendex'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-upmendex=$enable_upmendex'" >&6;} - ac_configure_args="$ac_configure_args '--enable-upmendex=$enable_upmendex'" - ;; -esac +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was 's,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` -test "x$enable_upmendex" = xno || { - need_kpathsea=yes - need_icu=yes -} -## texk/xdvik/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/xdvik/ -## configure options and TL libraries required for xdvik -# Check whether --enable-xdvik was given. -if test ${enable_xdvik+y} -then : - enableval=$enable_xdvik; + if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" fi -if test "x$with_x" = xno -then : - case $enable_xdvik in #( - "") : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \`--without-x' -> \`--disable-xdvik'" >&5 -printf "%s\n" "$as_me: \`--without-x' -> \`--disable-xdvik'" >&6;} - enable_xdvik=no - ac_configure_args="$ac_configure_args '--disable-xdvik'" ;; #( - yes) : - as_fn_error $? "Sorry, incompatible options \`--without-x' and \`--enable-xdvik'" "$LINENO" 5 ;; #( - *) : - ;; -esac +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi -case $enable_xdvik in #( - yes|no) : - ;; #( - *) : - - enable_xdvik=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xdvik=$enable_xdvik'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-xdvik=$enable_xdvik'" >&6;} - ac_configure_args="$ac_configure_args '--enable-xdvik=$enable_xdvik'" - ;; -esac - -test "x$enable_xdvik" = xno || { - need_kpathsea=yes - need_freetype2=yes -} - -## texk/xdvik/ac/xdvik.ac: configure.ac fragment for the TeX Live subdirectory texk/xdvik/ -## configure options for xdvik -# Check whether --with-xdvi-x-toolkit was given. -if test ${with_xdvi_x_toolkit+y} -then : - withval=$with_xdvi_x_toolkit; +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac fi - -## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ -## configure options and TL libraries required for texlive -# Check whether --enable-texlive was given. -if test ${enable_texlive+y} +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} then : - enableval=$enable_texlive; -fi -case $enable_texlive in #( - yes|no) : - ;; #( - *) : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS - enable_texlive=$enable_all_pkgs - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texlive=$enable_texlive'" >&5 -printf "%s\n" "$as_me: Assuming \`--enable-texlive=$enable_texlive'" >&6;} - ac_configure_args="$ac_configure_args '--enable-texlive=$enable_texlive'" - ;; +fi ;; esac - -## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/ -## configure options for texlive -# Check whether --enable-linked-scripts was given. -if test ${enable_linked_scripts+y} -then : - enableval=$enable_linked_scripts; +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/pplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pplib/ -## configure options and TL libraries required for pplib - -test "x$need_pplib" = xyes && { - need_zlib=yes -} - -## libs/harfbuzz/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/ -## configure options and TL libraries required for harfbuzz - -# Check whether --with-system-harfbuzz was given. -if test ${with_system_harfbuzz+y} -then : - withval=$with_system_harfbuzz; fi -if test "x$with_system_harfbuzz" = x; then - if test -f $srcdir/libs/harfbuzz/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`harfbuzz' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`harfbuzz' headers and library from TL tree" >&6;} - with_system_harfbuzz=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`harfbuzz' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`harfbuzz' headers and library" >&6;} - with_system_harfbuzz=yes - fi - ac_configure_args="$ac_configure_args '--with-system-harfbuzz=$with_system_harfbuzz'" -elif test "x$with_system_harfbuzz" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`harfbuzz' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`harfbuzz' headers and library" >&6;} +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`harfbuzz' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`harfbuzz' headers and library from TL tree" >&6;} - if test "x$with_system_harfbuzz" != xno; then - with_system_harfbuzz=no - ac_configure_args="$ac_configure_args '--without-system-harfbuzz'" - fi -fi -if test "x$with_system_harfbuzz" = xyes; then - if test "x$with_system_graphite2" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`graphite2' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`graphite2' headers and library" >&6;} - with_system_graphite2=yes - ac_configure_args="$ac_configure_args '--with-system-graphite2'" - elif test "x$with_system_graphite2" != xyes; then - as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-graphite2'" "$LINENO" 5 - fi - if test "x$with_system_icu" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`icu' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`icu' headers and library" >&6;} - with_system_icu=yes - ac_configure_args="$ac_configure_args '--with-system-icu'" - elif test "x$with_system_icu" != xyes; then - as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-icu'" "$LINENO" 5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 fi -fi - -test "x$need_harfbuzz" = xyes && { - need_graphite2=yes - need_icu=yes -} - -## libs/icu/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/icu/ -## configure options and TL libraries required for icu (modified for XeTeX) +done + done +IFS=$as_save_IFS -# Check whether --with-system-icu was given. -if test ${with_system_icu+y} -then : - withval=$with_system_icu; +fi ;; +esac fi -if test "x$with_system_icu" = x; then - if test -f $srcdir/libs/icu/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`icu' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`icu' headers and library from TL tree" >&6;} - with_system_icu=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`icu' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`icu' headers and library" >&6;} - with_system_icu=yes - fi - ac_configure_args="$ac_configure_args '--with-system-icu=$with_system_icu'" -elif test "x$with_system_icu" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`icu' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`icu' headers and library" >&6;} +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`icu' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`icu' headers and library from TL tree" >&6;} - if test "x$with_system_icu" != xno; then - with_system_icu=no - ac_configure_args="$ac_configure_args '--without-system-icu'" - fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/teckit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/teckit/ -## configure options and TL libraries required for teckit - -# Check whether --with-system-teckit was given. -if test ${with_system_teckit+y} -then : - withval=$with_system_teckit; -fi -if test "x$with_system_teckit" = x; then - if test -f $srcdir/libs/teckit/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`teckit' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`teckit' headers and library from TL tree" >&6;} - with_system_teckit=no + if test "x$ac_ct_STRIP" = x; then + STRIP=":" else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`teckit' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`teckit' headers and library" >&6;} - with_system_teckit=yes + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP fi - ac_configure_args="$ac_configure_args '--with-system-teckit=$with_system_teckit'" -elif test "x$with_system_teckit" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`teckit' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`teckit' headers and library" >&6;} else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`teckit' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`teckit' headers and library from TL tree" >&6;} - if test "x$with_system_teckit" != xno; then - with_system_teckit=no - ac_configure_args="$ac_configure_args '--without-system-teckit'" - fi -fi -if test "x$with_system_teckit" = xyes; then - if test "x$with_system_zlib" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - ac_configure_args="$ac_configure_args '--with-system-zlib'" - elif test "x$with_system_zlib" != xyes; then - as_fn_error $? "Sorry, \`--with-system-teckit' requires \`--with-system-zlib'" "$LINENO" 5 - fi + STRIP="$ac_cv_prog_STRIP" fi -test "x$need_teckit" = xyes && { - need_zlib=yes -} +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -## libs/graphite2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/graphite2/ -## configure options and TL libraries required for graphite2 -# Check whether --with-system-graphite2 was given. -if test ${with_system_graphite2+y} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test ${ac_cv_path_mkdir+y} then : - withval=$with_system_graphite2; -fi -if test "x$with_system_graphite2" = x; then - if test -f $srcdir/libs/graphite2/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`graphite2' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`graphite2' headers and library from TL tree" >&6;} - with_system_graphite2=no + printf %s "(cached) " >&6 +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + *'BusyBox '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + ;; +esac +fi + + test -d ./--version && rmdir ./--version + if test ${ac_cv_path_mkdir+y}; then + MKDIR_P="$ac_cv_path_mkdir -p" else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`graphite2' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`graphite2' headers and library" >&6;} - with_system_graphite2=yes - fi - ac_configure_args="$ac_configure_args '--with-system-graphite2=$with_system_graphite2'" -elif test "x$with_system_graphite2" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`graphite2' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`graphite2' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`graphite2' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`graphite2' headers and library from TL tree" >&6;} - if test "x$with_system_graphite2" != xno; then - with_system_graphite2=no - ac_configure_args="$ac_configure_args '--without-system-graphite2'" + # As a last resort, use plain mkdir -p, + # in the hope it doesn't have the bugs of ancient mkdir. + MKDIR_P='mkdir -p' fi fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } -## libs/zziplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/ -## configure options and TL libraries required for zziplib - -# Check whether --with-system-zziplib was given. -if test ${with_system_zziplib+y} +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} then : - withval=$with_system_zziplib; -fi -if test "x$with_system_zziplib" = x; then - if test -f $srcdir/libs/zziplib/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zziplib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`zziplib' headers and library from TL tree" >&6;} - with_system_zziplib=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zziplib' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`zziplib' headers and library" >&6;} - with_system_zziplib=yes - fi - ac_configure_args="$ac_configure_args '--with-system-zziplib=$with_system_zziplib'" -elif test "x$with_system_zziplib" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zziplib' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`zziplib' headers and library" >&6;} + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zziplib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`zziplib' headers and library from TL tree" >&6;} - if test "x$with_system_zziplib" != xno; then - with_system_zziplib=no - ac_configure_args="$ac_configure_args '--without-system-zziplib'" - fi -fi -if test "x$with_system_zziplib" = xyes; then - if test "x$with_system_zlib" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - ac_configure_args="$ac_configure_args '--with-system-zlib'" - elif test "x$with_system_zlib" != xyes; then - as_fn_error $? "Sorry, \`--with-system-zziplib' requires \`--with-system-zlib'" "$LINENO" 5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 fi -fi - -test "x$need_zziplib" = xyes && { - need_zlib=yes -} +done + done +IFS=$as_save_IFS -## libs/xpdf/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/xpdf/ -## configure options and TL libraries required for xpdf -: "kpse_xpdf_options - no-op" -if test "x$with_system_xpdf" = x; then - if test -f $srcdir/libs/xpdf/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`xpdf' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`xpdf' headers and library from TL tree" >&6;} - with_system_xpdf=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`xpdf' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`xpdf' headers and library" >&6;} - with_system_xpdf=yes - fi - ac_configure_args="$ac_configure_args '--with-system-xpdf=$with_system_xpdf'" -elif test "x$with_system_xpdf" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`xpdf' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`xpdf' headers and library" >&6;} +fi ;; +esac +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`xpdf' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`xpdf' headers and library from TL tree" >&6;} - if test "x$with_system_xpdf" != xno; then - with_system_xpdf=no - ac_configure_args="$ac_configure_args '--without-system-xpdf'" - fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/mpfi/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfi/ -## configure options and TL libraries required for mpfi - -# Check whether --with-system-mpfi was given. -if test ${with_system_mpfi+y} -then : - withval=$with_system_mpfi; -fi -# Check whether --with-mpfi-includes was given. -if test ${with_mpfi_includes+y} -then : - withval=$with_mpfi_includes; -fi + test -n "$AWK" && break +done -# Check whether --with-mpfi-libdir was given. -if test ${with_mpfi_libdir+y} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : - withval=$with_mpfi_libdir; + printf %s "(cached) " >&6 +else case e in #( + e) cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make ;; +esac fi -if test "x$with_system_mpfi" = x; then - if test -f $srcdir/libs/mpfi/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`mpfi' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`mpfi' headers and library from TL tree" >&6;} - with_system_mpfi=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`mpfi' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`mpfi' headers and library" >&6;} - with_system_mpfi=yes - fi - ac_configure_args="$ac_configure_args '--with-system-mpfi=$with_system_mpfi'" -elif test "x$with_system_mpfi" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`mpfi' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`mpfi' headers and library" >&6;} +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SET_MAKE= else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`mpfi' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`mpfi' headers and library from TL tree" >&6;} - if test "x$with_system_mpfi" != xno; then - with_system_mpfi=no - ac_configure_args="$ac_configure_args '--without-system-mpfi'" - fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" fi -if test "x$with_system_mpfi" = xyes; then - if test "x$with_system_mpfr" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`mpfr' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`mpfr' headers and library" >&6;} - with_system_mpfr=yes - ac_configure_args="$ac_configure_args '--with-system-mpfr'" - elif test "x$with_system_mpfr" != xyes; then - as_fn_error $? "Sorry, \`--with-system-mpfi' requires \`--with-system-mpfr'" "$LINENO" 5 - fi - if test "x$with_system_gmp" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`gmp' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`gmp' headers and library" >&6;} - with_system_gmp=yes - ac_configure_args="$ac_configure_args '--with-system-gmp'" - elif test "x$with_system_gmp" != xyes; then - as_fn_error $? "Sorry, \`--with-system-mpfi' requires \`--with-system-gmp'" "$LINENO" 5 - fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ fi +rmdir .tst 2>/dev/null -test "x$need_mpfi" = xyes && { - need_mpfr=yes - need_gmp=yes -} +DEPDIR="${am__leading_dot}deps" -## libs/mpfr/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfr/ -## configure options and TL libraries required for mpfr +ac_config_commands="$ac_config_commands depfiles" -# Check whether --with-system-mpfr was given. -if test ${with_system_mpfr+y} -then : - withval=$with_system_mpfr; -fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +printf "%s\n" "${_am_result}" >&6; } -# Check whether --with-mpfr-includes was given. -if test ${with_mpfr_includes+y} +# Check whether --enable-dependency-tracking was given. +if test ${enable_dependency_tracking+y} then : - withval=$with_mpfr_includes; + enableval=$enable_dependency_tracking; fi -# Check whether --with-mpfr-libdir was given. -if test ${with_mpfr_libdir+y} -then : - withval=$with_mpfr_libdir; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' fi -if test "x$with_system_mpfr" = x; then - if test -f $srcdir/libs/mpfr/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`mpfr' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`mpfr' headers and library from TL tree" >&6;} - with_system_mpfr=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`mpfr' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`mpfr' headers and library" >&6;} - with_system_mpfr=yes - fi - ac_configure_args="$ac_configure_args '--with-system-mpfr=$with_system_mpfr'" -elif test "x$with_system_mpfr" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`mpfr' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`mpfr' headers and library" >&6;} + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`mpfr' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`mpfr' headers and library from TL tree" >&6;} - if test "x$with_system_mpfr" != xno; then - with_system_mpfr=no - ac_configure_args="$ac_configure_args '--without-system-mpfr'" - fi -fi -if test "x$with_system_mpfr" = xyes; then - if test "x$with_system_gmp" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`gmp' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`gmp' headers and library" >&6;} - with_system_gmp=yes - ac_configure_args="$ac_configure_args '--with-system-gmp'" - elif test "x$with_system_gmp" != xyes; then - as_fn_error $? "Sorry, \`--with-system-mpfr' requires \`--with-system-gmp'" "$LINENO" 5 - fi + AMDEP_TRUE='#' + AMDEP_FALSE= fi -test "x$need_mpfr" = xyes && { - need_gmp=yes -} - -## libs/gmp/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/ -## configure options and TL libraries required for gmp -# Check whether --with-system-gmp was given. -if test ${with_system_gmp+y} +AM_DEFAULT_VERBOSITY=1 +# Check whether --enable-silent-rules was given. +if test ${enable_silent_rules+y} then : - withval=$with_system_gmp; + enableval=$enable_silent_rules; fi -# Check whether --with-gmp-includes was given. -if test ${with_gmp_includes+y} -then : - withval=$with_gmp_includes; -fi - -# Check whether --with-gmp-libdir was given. -if test ${with_gmp_libdir+y} +am_make=${MAKE-make} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} then : - withval=$with_gmp_libdir; -fi -if test "x$with_system_gmp" = x; then - if test -f $srcdir/libs/gmp/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`gmp' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`gmp' headers and library from TL tree" >&6;} - with_system_gmp=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`gmp' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`gmp' headers and library" >&6;} - with_system_gmp=yes - fi - ac_configure_args="$ac_configure_args '--with-system-gmp=$with_system_gmp'" -elif test "x$with_system_gmp" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`gmp' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`gmp' headers and library" >&6;} + printf %s "(cached) " >&6 +else case e in #( + e) if printf "%s\n" 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`gmp' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`gmp' headers and library from TL tree" >&6;} - if test "x$with_system_gmp" != xno; then - with_system_gmp=no - ac_configure_args="$ac_configure_args '--without-system-gmp'" - fi + am_cv_make_support_nested_variables=no +fi ;; +esac fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } +AM_BACKSLASH='\' -## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## configure options and TL libraries required for cairo - -# Check whether --with-system-cairo was given. -if test ${with_system_cairo+y} +am__rm_f_notfound= +if (rm -f && rm -fr && rm -rf) 2>/dev/null then : - withval=$with_system_cairo; -fi -if test "x$with_system_cairo" = x; then - if test -f $srcdir/libs/cairo/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;} - with_system_cairo=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`cairo' headers and library" >&6;} - with_system_cairo=yes - fi - ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'" -elif test "x$with_system_cairo" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`cairo' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`cairo' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`cairo' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`cairo' headers and library from TL tree" >&6;} - if test "x$with_system_cairo" != xno; then - with_system_cairo=no - ac_configure_args="$ac_configure_args '--without-system-cairo'" - fi -fi -if test "x$with_system_cairo" = xyes; then - if test "x$with_system_pixman" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`pixman' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - ac_configure_args="$ac_configure_args '--with-system-pixman'" - elif test "x$with_system_pixman" != xyes; then - as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5 - fi -fi -test "x$need_cairo" = xyes && { - need_pixman=yes -} - -## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## configure options and TL libraries required for pixman - -# Check whether --with-system-pixman was given. -if test ${with_system_pixman+y} -then : - withval=$with_system_pixman; -fi -if test "x$with_system_pixman" = x; then - if test -f $srcdir/libs/pixman/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;} - with_system_pixman=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - fi - ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'" -elif test "x$with_system_pixman" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`pixman' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`pixman' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`pixman' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`pixman' headers and library from TL tree" >&6;} - if test "x$with_system_pixman" != xno; then - with_system_pixman=no - ac_configure_args="$ac_configure_args '--without-system-pixman'" - fi +else case e in #( + e) am__rm_f_notfound='""' ;; +esac fi -## libs/gd/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/gd/ -## configure options and TL libraries required for gd -# Check whether --with-system-gd was given. -if test ${with_system_gd+y} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking xargs -n works" >&5 +printf %s "checking xargs -n works... " >&6; } +if test ${am_cv_xargs_n_works+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 +3" then : - withval=$with_system_gd; + am_cv_xargs_n_works=yes +else case e in #( + e) am_cv_xargs_n_works=no ;; +esac +fi ;; +esac fi - -# Check whether --with-gd-includes was given. -if test ${with_gd_includes+y} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_xargs_n_works" >&5 +printf "%s\n" "$am_cv_xargs_n_works" >&6; } +if test "$am_cv_xargs_n_works" = yes then : - withval=$with_gd_includes; + am__xargs_n='xargs -n' +else case e in #( + e) am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "" "$am__xargs_n_arg"; done; }' + ;; +esac fi -# Check whether --with-gd-libdir was given. -if test ${with_gd_libdir+y} +# Check whether --enable-compiler-warnings was given. +if test ${enable_compiler_warnings+y} then : - withval=$with_gd_libdir; -fi -if test "x$with_system_gd" = x; then - if test -f $srcdir/libs/gd/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`gd' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`gd' headers and library from TL tree" >&6;} - with_system_gd=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`gd' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`gd' headers and library" >&6;} - with_system_gd=yes - fi - ac_configure_args="$ac_configure_args '--with-system-gd=$with_system_gd'" -elif test "x$with_system_gd" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`gd' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`gd' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`gd' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`gd' headers and library from TL tree" >&6;} - if test "x$with_system_gd" != xno; then - with_system_gd=no - ac_configure_args="$ac_configure_args '--without-system-gd'" - fi -fi -if test "x$with_system_gd" = xyes; then - if test "x$with_system_libpng" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`libpng' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`libpng' headers and library" >&6;} - with_system_libpng=yes - ac_configure_args="$ac_configure_args '--with-system-libpng'" - elif test "x$with_system_libpng" != xyes; then - as_fn_error $? "Sorry, \`--with-system-gd' requires \`--with-system-libpng'" "$LINENO" 5 - fi - if test "x$with_system_freetype2" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`freetype2' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`freetype2' headers and library" >&6;} - with_system_freetype2=yes - ac_configure_args="$ac_configure_args '--with-system-freetype2'" - elif test "x$with_system_freetype2" != xyes; then - as_fn_error $? "Sorry, \`--with-system-gd' requires \`--with-system-freetype2'" "$LINENO" 5 - fi + enableval=$enable_compiler_warnings; fi +case $enable_compiler_warnings in #( + no | min | yes | max | all) : + ;; #( + *) : + if test "x$enable_maintainer_mode" = xyes +then : + enable_compiler_warnings=yes +else case e in #( + e) enable_compiler_warnings=min ;; +esac +fi ;; +esac -test "x$need_gd" = xyes && { - need_libpng=yes - need_freetype2=yes -} +case `pwd` in + *\ * | *\ *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac -## libs/potrace/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/potrace/ -## configure options and TL libraries required for potrace -# Check whether --with-system-potrace was given. -if test ${with_system_potrace+y} -then : - withval=$with_system_potrace; -fi -# Check whether --with-potrace-includes was given. -if test ${with_potrace_includes+y} -then : - withval=$with_potrace_includes; -fi +macro_version='2.5.4' +macro_revision='2.5.4' -# Check whether --with-potrace-libdir was given. -if test ${with_potrace_libdir+y} -then : - withval=$with_potrace_libdir; -fi -if test "x$with_system_potrace" = x; then - if test -f $srcdir/libs/potrace/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`potrace' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`potrace' headers and library from TL tree" >&6;} - with_system_potrace=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`potrace' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`potrace' headers and library" >&6;} - with_system_potrace=yes - fi - ac_configure_args="$ac_configure_args '--with-system-potrace=$with_system_potrace'" -elif test "x$with_system_potrace" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`potrace' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`potrace' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`potrace' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`potrace' headers and library from TL tree" >&6;} - if test "x$with_system_potrace" != xno; then - with_system_potrace=no - ac_configure_args="$ac_configure_args '--without-system-potrace'" - fi -fi -## libs/freetype2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/freetype2/ -## configure options and TL libraries required for freetype2 -# Check whether --with-system-freetype2 was given. -if test ${with_system_freetype2+y} -then : - withval=$with_system_freetype2; -fi -if test "x$with_system_freetype2" = x; then - if test -f $srcdir/libs/freetype2/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`freetype2' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`freetype2' headers and library from TL tree" >&6;} - with_system_freetype2=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`freetype2' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`freetype2' headers and library" >&6;} - with_system_freetype2=yes - fi - ac_configure_args="$ac_configure_args '--with-system-freetype2=$with_system_freetype2'" -elif test "x$with_system_freetype2" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`freetype2' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`freetype2' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`freetype2' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`freetype2' headers and library from TL tree" >&6;} - if test "x$with_system_freetype2" != xno; then - with_system_freetype2=no - ac_configure_args="$ac_configure_args '--without-system-freetype2'" - fi -fi -if test "x$with_system_freetype2" = xyes; then - if test "x$with_system_zlib" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - ac_configure_args="$ac_configure_args '--with-system-zlib'" - elif test "x$with_system_zlib" != xyes; then - as_fn_error $? "Sorry, \`--with-system-freetype2' requires \`--with-system-zlib'" "$LINENO" 5 - fi -fi -test "x$need_freetype2" = xyes && { - need_zlib=yes -} -## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ -## configure options and TL libraries required for libpng -# Check whether --with-system-libpng was given. -if test ${with_system_libpng+y} -then : - withval=$with_system_libpng; -fi -if test "x$with_system_libpng" = x; then - if test -f $srcdir/libs/libpng/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpng' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`libpng' headers and library from TL tree" >&6;} - with_system_libpng=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpng' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`libpng' headers and library" >&6;} - with_system_libpng=yes - fi - ac_configure_args="$ac_configure_args '--with-system-libpng=$with_system_libpng'" -elif test "x$with_system_libpng" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpng' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`libpng' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpng' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`libpng' headers and library from TL tree" >&6;} - if test "x$with_system_libpng" != xno; then - with_system_libpng=no - ac_configure_args="$ac_configure_args '--without-system-libpng'" - fi -fi -if test "x$with_system_libpng" = xyes; then - if test "x$with_system_zlib" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - ac_configure_args="$ac_configure_args '--with-system-zlib'" - elif test "x$with_system_zlib" != xyes; then - as_fn_error $? "Sorry, \`--with-system-libpng' requires \`--with-system-zlib'" "$LINENO" 5 - fi -fi -test "x$need_libpng" = xyes && { - need_zlib=yes -} -## libs/libpaper/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpaper/ -## configure options and TL libraries required for libpaper -# Check whether --with-system-libpaper was given. -if test ${with_system_libpaper+y} -then : - withval=$with_system_libpaper; -fi -# Check whether --with-libpaper-includes was given. -if test ${with_libpaper_includes+y} -then : - withval=$with_libpaper_includes; -fi -# Check whether --with-libpaper-libdir was given. -if test ${with_libpaper_libdir+y} -then : - withval=$with_libpaper_libdir; -fi -if test "x$with_system_libpaper" = x; then - if test -f $srcdir/libs/libpaper/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpaper' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`libpaper' headers and library from TL tree" >&6;} - with_system_libpaper=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpaper' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`libpaper' headers and library" >&6;} - with_system_libpaper=yes - fi - ac_configure_args="$ac_configure_args '--with-system-libpaper=$with_system_libpaper'" -elif test "x$with_system_libpaper" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpaper' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`libpaper' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpaper' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`libpaper' headers and library from TL tree" >&6;} - if test "x$with_system_libpaper" != xno; then - with_system_libpaper=no - ac_configure_args="$ac_configure_args '--without-system-libpaper'" - fi -fi -## libs/luajit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ -## configure options and TL libraries required for luajit -# Check whether --with-system-luajit was given. -if test ${with_system_luajit+y} -then : - withval=$with_system_luajit; -fi -if test "x$with_system_luajit" = x; then - if test -f $srcdir/libs/luajit/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`luajit' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`luajit' headers and library from TL tree" >&6;} - with_system_luajit=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`luajit' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`luajit' headers and library" >&6;} - with_system_luajit=yes - fi - ac_configure_args="$ac_configure_args '--with-system-luajit=$with_system_luajit'" -elif test "x$with_system_luajit" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`luajit' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`luajit' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`luajit' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`luajit' headers and library from TL tree" >&6;} - if test "x$with_system_luajit" != xno; then - with_system_luajit=no - ac_configure_args="$ac_configure_args '--without-system-luajit'" - fi -fi -## libs/lua53/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/lua53/ -## configure options and TL libraries required for lua53 +ltmain=$ac_aux_dir/ltmain.sh -## libs/zlib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ -## configure options and TL libraries required for zlib +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' -# Check whether --with-system-zlib was given. -if test ${with_system_zlib+y} -then : - withval=$with_system_zlib; -fi +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' -# Check whether --with-zlib-includes was given. -if test ${with_zlib_includes+y} -then : - withval=$with_zlib_includes; -fi +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' -# Check whether --with-zlib-libdir was given. -if test ${with_zlib_libdir+y} -then : - withval=$with_zlib_libdir; -fi -if test "x$with_system_zlib" = x; then - if test -f $srcdir/libs/zlib/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`zlib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`zlib' headers and library from TL tree" >&6;} - with_system_zlib=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`zlib' headers and library" >&6;} - with_system_zlib=yes - fi - ac_configure_args="$ac_configure_args '--with-system-zlib=$with_system_zlib'" -elif test "x$with_system_zlib" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`zlib' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`zlib' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`zlib' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`zlib' headers and library from TL tree" >&6;} - if test "x$with_system_zlib" != xno; then - with_system_zlib=no - ac_configure_args="$ac_configure_args '--without-system-zlib'" - fi -fi +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' -## texk/ptexenc/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ptexenc/ -## configure options and TL libraries required for ptexenc +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO -# Check whether --with-system-ptexenc was given. -if test ${with_system_ptexenc+y} -then : - withval=$with_system_ptexenc; -fi -if test "x$with_system_ptexenc" = x; then - if test -f $srcdir/texk/ptexenc/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`ptexenc' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`ptexenc' headers and library from TL tree" >&6;} - with_system_ptexenc=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`ptexenc' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`ptexenc' headers and library" >&6;} - with_system_ptexenc=yes - fi - ac_configure_args="$ac_configure_args '--with-system-ptexenc=$with_system_ptexenc'" -elif test "x$with_system_ptexenc" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`ptexenc' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`ptexenc' headers and library" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +printf %s "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`ptexenc' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`ptexenc' headers and library from TL tree" >&6;} - if test "x$with_system_ptexenc" != xno; then - with_system_ptexenc=no - ac_configure_args="$ac_configure_args '--without-system-ptexenc'" - fi -fi -if test "x$with_system_ptexenc" = xyes; then - if test "x$with_system_kpathsea" = x; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: -> installed \`kpathsea' headers and library" >&5 -printf "%s\n" "$as_me: -> installed \`kpathsea' headers and library" >&6;} - with_system_kpathsea=yes - ac_configure_args="$ac_configure_args '--with-system-kpathsea'" - elif test "x$with_system_kpathsea" != xyes; then - as_fn_error $? "Sorry, \`--with-system-ptexenc' requires \`--with-system-kpathsea'" "$LINENO" 5 - fi + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' fi -test "x$need_ptexenc" = xyes && { - need_kpathsea=yes +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" } -## texk/kpathsea/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ -## configure options and TL libraries required for kpathsea +case $ECHO in + printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +printf "%s\n" "printf" >&6; } ;; + print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +printf "%s\n" "print -r" >&6; } ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +printf "%s\n" "cat" >&6; } ;; +esac -# Check whether --with-system-kpathsea was given. -if test ${with_system_kpathsea+y} -then : - withval=$with_system_kpathsea; -fi -if test "x$with_system_kpathsea" = x; then - if test -f $srcdir/texk/kpathsea/configure; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`kpathsea' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Assuming \`kpathsea' headers and library from TL tree" >&6;} - with_system_kpathsea=no - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`kpathsea' headers and library" >&5 -printf "%s\n" "$as_me: Assuming installed \`kpathsea' headers and library" >&6;} - with_system_kpathsea=yes - fi - ac_configure_args="$ac_configure_args '--with-system-kpathsea=$with_system_kpathsea'" -elif test "x$with_system_kpathsea" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`kpathsea' headers and library" >&5 -printf "%s\n" "$as_me: Using installed \`kpathsea' headers and library" >&6;} -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`kpathsea' headers and library from TL tree" >&5 -printf "%s\n" "$as_me: Using \`kpathsea' headers and library from TL tree" >&6;} - if test "x$with_system_kpathsea" != xno; then - with_system_kpathsea=no - ac_configure_args="$ac_configure_args '--without-system-kpathsea'" - fi -fi -## texk/kpathsea/ac/mktex.ac: configure.ac fragment for the TeX Live -## subdirectory texk/kpathsea. -## configure defaults for mktexfmt & Co. -# Check whether --enable-mktexmf-default was given. -if test ${enable_mktexmf_default+y} -then : - enableval=$enable_mktexmf_default; -fi -# Check whether --enable-mktexpk-default was given. -if test ${enable_mktexpk_default+y} -then : - enableval=$enable_mktexpk_default; -fi -# Check whether --enable-mktextfm-default was given. -if test ${enable_mktextfm_default+y} -then : - enableval=$enable_mktextfm_default; -fi -# Check whether --enable-mkocp-default was given. -if test ${enable_mkocp_default+y} -then : - enableval=$enable_mkocp_default; -fi -# Check whether --enable-mkofm-default was given. -if test ${enable_mkofm_default+y} -then : - enableval=$enable_mkofm_default; -fi -# Check whether --enable-mktexfmt-default was given. -if test ${enable_mktexfmt_default+y} -then : - enableval=$enable_mktexfmt_default; -fi -# Check whether --enable-mktextex-default was given. -if test ${enable_mktextex_default+y} -then : - enableval=$enable_mktextex_default; -fi -# end of kpse_setup macro. -echo 'tldbg:KPSE_SETUP done (toplevel=)' >&5 -am__api_version='1.17' - # Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -printf %s "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test ${ac_cv_path_install+y} + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else case e in #( - e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS @@ -7947,892 +6817,51 @@ do */) ;; *) as_dir=$as_dir/ ;; esac - # Account for fact that we put trailing slashes in our PATH walk. -case $as_dir in #(( - ./ | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in #( +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +#( +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac + $ac_path_SED_found && break 3 + done + done done IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - ;; -esac -fi - if test ${ac_cv_path_install+y}; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -printf "%s\n" "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5 -printf %s "checking whether sleep supports fractional seconds... " >&6; } -if test ${am_cv_sleep_fractional_seconds+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if sleep 0.001 2>/dev/null -then : - am_cv_sleep_fractional_seconds=yes -else case e in #( - e) am_cv_sleep_fractional_seconds=no ;; -esac -fi - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_sleep_fractional_seconds" >&5 -printf "%s\n" "$am_cv_sleep_fractional_seconds" >&6; } - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking filesystem timestamp resolution" >&5 -printf %s "checking filesystem timestamp resolution... " >&6; } -if test ${am_cv_filesystem_timestamp_resolution+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) # Default to the worst case. -am_cv_filesystem_timestamp_resolution=2 - -# Only try to go finer than 1 sec if sleep can do it. -# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, -# - 1 sec is not much of a win compared to 2 sec, and -# - it takes 2 seconds to perform the test whether 1 sec works. -# -# Instead, just use the default 2s on platforms that have 1s resolution, -# accept the extra 1s delay when using $sleep in the Automake tests, in -# exchange for not incurring the 2s delay for running the test for all -# packages. -# -am_try_resolutions= -if test "$am_cv_sleep_fractional_seconds" = yes; then - # Even a millisecond often causes a bunch of false positives, - # so just try a hundredth of a second. The time saved between .001 and - # .01 is not terribly consequential. - am_try_resolutions="0.01 0.1 $am_try_resolutions" -fi - -# In order to catch current-generation FAT out, we must *modify* files -# that already exist; the *creation* timestamp is finer. Use names -# that make ls -t sort them differently when they have equal -# timestamps than when they have distinct timestamps, keeping -# in mind that ls -t prints the *newest* file first. -rm -f conftest.ts? -: > conftest.ts1 -: > conftest.ts2 -: > conftest.ts3 - -# Make sure ls -t actually works. Do 'set' in a subshell so we don't -# clobber the current shell's arguments. (Outer-level square brackets -# are removed by m4; they're present so that m4 does not expand -# <dollar><star>; be careful, easy to get confused.) -if ( - set X `ls -t conftest.ts[12]` && - { - test "$*" != "X conftest.ts1 conftest.ts2" || - test "$*" != "X conftest.ts2 conftest.ts1"; - } -); then :; else - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - printf "%s\n" ""Bad output from ls -t: \"`ls -t conftest.ts[12]`\""" >&5 - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} -as_fn_error $? "ls -t produces unexpected output. -Make sure there is not a broken ls alias in your environment. -See 'config.log' for more details" "$LINENO" 5; } -fi - -for am_try_res in $am_try_resolutions; do - # Any one fine-grained sleep might happen to cross the boundary - # between two values of a coarser actual resolution, but if we do - # two fine-grained sleeps in a row, at least one of them will fall - # entirely within a coarse interval. - echo alpha > conftest.ts1 - sleep $am_try_res - echo beta > conftest.ts2 - sleep $am_try_res - echo gamma > conftest.ts3 - - # We assume that 'ls -t' will make use of high-resolution - # timestamps if the operating system supports them at all. - if (set X `ls -t conftest.ts?` && - test "$2" = conftest.ts3 && - test "$3" = conftest.ts2 && - test "$4" = conftest.ts1); then - # - # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, - # because we don't need to test make. - make_ok=true - if test $am_try_res != 1; then - # But if we've succeeded so far with a subsecond resolution, we - # have one more thing to check: make. It can happen that - # everything else supports the subsecond mtimes, but make doesn't; - # notably on macOS, which ships make 3.81 from 2006 (the last one - # released under GPLv2). https://bugs.gnu.org/68808 - # - # We test $MAKE if it is defined in the environment, else "make". - # It might get overridden later, but our hope is that in practice - # it does not matter: it is the system "make" which is (by far) - # the most likely to be broken, whereas if the user overrides it, - # probably they did so with a better, or at least not worse, make. - # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html - # - # Create a Makefile (real tab character here): - rm -f conftest.mk - echo 'conftest.ts1: conftest.ts2' >conftest.mk - echo ' touch conftest.ts2' >>conftest.mk - # - # Now, running - # touch conftest.ts1; touch conftest.ts2; make - # should touch ts1 because ts2 is newer. This could happen by luck, - # but most often, it will fail if make's support is insufficient. So - # test for several consecutive successes. - # - # (We reuse conftest.ts[12] because we still want to modify existing - # files, not create new ones, per above.) - n=0 - make=${MAKE-make} - until test $n -eq 3; do - echo one > conftest.ts1 - sleep $am_try_res - echo two > conftest.ts2 # ts2 should now be newer than ts1 - if $make -f conftest.mk | grep 'up to date' >/dev/null; then - make_ok=false - break # out of $n loop - fi - n=`expr $n + 1` - done - fi - # - if $make_ok; then - # Everything we know to check worked out, so call this resolution good. - am_cv_filesystem_timestamp_resolution=$am_try_res - break # out of $am_try_res loop - fi - # Otherwise, we'll go on to check the next resolution. - fi -done -rm -f conftest.ts? -# (end _am_filesystem_timestamp_resolution) - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_filesystem_timestamp_resolution" >&5 -printf "%s\n" "$am_cv_filesystem_timestamp_resolution" >&6; } - -# This check should not be cached, as it may vary across builds of -# different projects. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -printf %s "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -am_build_env_is_sane=no -am_has_slept=no -rm -f conftest.file -for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - test "$2" = conftest.file - ); then - am_build_env_is_sane=yes - break - fi - # Just in case. - sleep "$am_cv_filesystem_timestamp_resolution" - am_has_slept=yes -done - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_build_env_is_sane" >&5 -printf "%s\n" "$am_build_env_is_sane" >&6; } -if test "$am_build_env_is_sane" = no; then - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi - -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1 -then : - -else case e in #( - e) ( sleep "$am_cv_filesystem_timestamp_resolution" ) & - am_sleep_pid=$! - ;; -esac -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was 's,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` - - - if test x"${MISSING+set}" != xset; then - MISSING="\${SHELL} '$am_aux_dir/missing'" -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_STRIP+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; -esac -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -printf "%s\n" "$STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_STRIP+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; -esac -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -printf "%s\n" "$ac_ct_STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 -printf %s "checking for a race-free mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if test ${ac_cv_path_mkdir+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue - case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir ('*'coreutils) '* | \ - *'BusyBox '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - ;; -esac -fi - - test -d ./--version && rmdir ./--version - if test ${ac_cv_path_mkdir+y}; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use plain mkdir -p, - # in the hope it doesn't have the bugs of ancient mkdir. - MKDIR_P='mkdir -p' - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -printf "%s\n" "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_AWK+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; -esac -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -printf "%s\n" "$AWK" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval test \${ac_cv_prog_make_${ac_make}_set+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make ;; -esac -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - SET_MAKE= -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 -printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } -cat > confinc.mk << 'END' -am__doit: - @echo this is the am__doit target >confinc.out -.PHONY: am__doit -END -am__include="#" -am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 - (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - case $?:`cat confinc.out 2>/dev/null` in #( - '0:this is the am__doit target') : - case $s in #( - BSD) : - am__include='.include' am__quote='"' ;; #( - *) : - am__include='include' am__quote='' ;; -esac ;; #( - *) : - ;; -esac - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 -printf "%s\n" "${_am_result}" >&6; } - -# Check whether --enable-dependency-tracking was given. -if test ${enable_dependency_tracking+y} -then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -AM_DEFAULT_VERBOSITY=1 -# Check whether --enable-silent-rules was given. -if test ${enable_silent_rules+y} -then : - enableval=$enable_silent_rules; -fi - -am_make=${MAKE-make} -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -printf %s "checking whether $am_make supports nested variables... " >&6; } -if test ${am_cv_make_support_nested_variables+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if printf "%s\n" 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -AM_BACKSLASH='\' - -am__rm_f_notfound= -if (rm -f && rm -fr && rm -rf) 2>/dev/null -then : - -else case e in #( - e) am__rm_f_notfound='""' ;; -esac -fi - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking xargs -n works" >&5 -printf %s "checking xargs -n works... " >&6; } -if test ${am_cv_xargs_n_works+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 -3" -then : - am_cv_xargs_n_works=yes -else case e in #( - e) am_cv_xargs_n_works=no ;; -esac -fi ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_xargs_n_works" >&5 -printf "%s\n" "$am_cv_xargs_n_works" >&6; } -if test "$am_cv_xargs_n_works" = yes -then : - am__xargs_n='xargs -n' -else case e in #( - e) am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "" "$am__xargs_n_arg"; done; }' - ;; -esac -fi - -# Check whether --enable-compiler-warnings was given. -if test ${enable_compiler_warnings+y} -then : - enableval=$enable_compiler_warnings; -fi -case $enable_compiler_warnings in #( - no | min | yes | max | all) : - ;; #( - *) : - if test "x$enable_maintainer_mode" = xyes -then : - enable_compiler_warnings=yes -else case e in #( - e) enable_compiler_warnings=min ;; -esac -fi ;; -esac - -case `pwd` in - *\ * | *\ *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.5.4' -macro_revision='2.5.4' - - - - - - - - - - - - - - -ltmain=$ac_aux_dir/ltmain.sh - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -printf %s "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case $ECHO in - printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -printf "%s\n" "printf" >&6; } ;; - print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -printf "%s\n" "print -r" >&6; } ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -printf "%s\n" "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -printf %s "checking for a sed that does not truncate output... " >&6; } -if test ${ac_cv_path_SED+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in sed gsed - do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in #( -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -#( -*) - ac_count=0 - printf %s 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - printf "%s\n" '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi ;; esac fi @@ -12549,7 +10578,7 @@ fi # Define the identity of the package. PACKAGE='tex-live' - VERSION='2024-03-10' + VERSION='2025-03-07' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -24669,397 +22698,129 @@ if test -n "$hardcode_libdir_flag_spec_CXX" || hardcode_action_CXX=immediate fi else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_CXX=unsupported -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 -printf "%s\n" "$hardcode_action_CXX" >&6; } - -if test relink = "$hardcode_action_CXX" || - test yes = "$inherit_rpath_CXX"; then - # Fast installation is not supported - enable_fast_install=no -elif test yes = "$shlibpath_overrides_runpath" || - test no = "$enable_shared"; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test yes != "$_lt_caught_CXX_error" - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -printf %s "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -printf "%s\n" "no, using $LN_S" >&6; } -fi - - -# Check whether --with-ln-s was given. -if test ${with_ln_s+y} -then : - withval=$with_ln_s; -fi -if test "x$LN_S" != "xln -s" && test "x$kpse_cv_have_win32" = xno && test "x$with_ln_s" != xno; then - as_fn_error $? "You could use \`--without-ln-s' to build without working \`ln -s'" "$LINENO" 5 -fi - -if test "x$enable_native_texlive_build" = xyes; then - if test "x$datarootdir" = 'x${prefix}/share'; then - datarootdir='${prefix}' - ac_configure_args="$ac_configure_args '--datarootdir=$datarootdir'" - fi - if test "x$mandir" = 'x${datarootdir}/man'; then - mandir='${prefix}/texmf-dist/doc/man' - ac_configure_args="$ac_configure_args '--mandir=$mandir'" - fi - if test "x$infodir" = 'x${datarootdir}/info'; then - infodir='${prefix}/texmf-dist/doc/info' - ac_configure_args="$ac_configure_args '--infodir=$infodir'" - fi -fi - -if test "x$enable_web2c" = xyes && test "x$with_system_kpathsea" = xyes; then - if test "x$with_kpathsea_includes" = x; then - list="/usr/include /usr/local/include" - else - list=$with_kpathsea_includes - fi - found=no - for ac_dir in $list; do - if test -r "$ac_dir/kpathsea/paths.h"; then - found=yes - break - fi - done - if test "x$found" = xno; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: You requested to build \`web2c' using an installed \`kpathsea' version," >&5 -printf "%s\n" "$as_me: You requested to build \`web2c' using an installed \`kpathsea' version," >&6;} - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: which requires to locate the <kpathsea/paths.h> header file." >&5 -printf "%s\n" "$as_me: which requires to locate the <kpathsea/paths.h> header file." >&6;} - as_fn_error $? "Sorry, not found under any of: $list *****" "$LINENO" 5 - fi -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for TeX specific libraries to build" >&5 -printf %s "checking for TeX specific libraries to build... " >&6; } -echo 'tldbg:_KPSE_RECURSE called: list=texlibs, text=TeX specific libraries, cond=test "x$with_system_[]Kpse_pkg" != xyes && test "x$need_[]Kpse_pkg" = xyes, prefix=texk/.' >&5 -MAKE_SUBDIRS= -CONF_SUBDIRS= -if test -x $srcdir/texk/ptexenc/configure; then - test "x$with_system_ptexenc" != xyes && test "x$need_ptexenc" = xyes && MAKE_SUBDIRS="texk/ptexenc $MAKE_SUBDIRS" - CONF_SUBDIRS="texk/ptexenc $CONF_SUBDIRS" -else - echo 'tldbg:_KPSE_RECURSE skipping subdir, no (executable) configure: '"$srcdir"'/texk/ptexenc/configure' >&5 -fi -if test -x $srcdir/texk/kpathsea/configure; then - test "x$with_system_kpathsea" != xyes && test "x$need_kpathsea" = xyes && MAKE_SUBDIRS="texk/kpathsea $MAKE_SUBDIRS" - CONF_SUBDIRS="texk/kpathsea $CONF_SUBDIRS" -else - echo 'tldbg:_KPSE_RECURSE skipping subdir, no (executable) configure: '"$srcdir"'/texk/kpathsea/configure' >&5 -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAKE_SUBDIRS" >&5 -printf "%s\n" "$MAKE_SUBDIRS" >&6; } - -kpse_save_CPPFLAGS=$CPPFLAGS -kpse_save_LIBS=$LIBS - -syslib_status=yes -syslib_used=no -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_PKG_CONFIG+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$PKG_CONFIG"; then - ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; -esac -fi -PKG_CONFIG=$ac_cv_prog_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -printf "%s\n" "$PKG_CONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_PKG_CONFIG"; then - ac_ct_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$ac_ct_PKG_CONFIG"; then - ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; -esac -fi -ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG -if test -n "$ac_ct_PKG_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 -printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_PKG_CONFIG" = x; then - PKG_CONFIG="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_ct_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +printf "%s\n" "$hardcode_action_CXX" >&6; } -if $PKG_CONFIG kpathsea; then - KPATHSEA_INCLUDES=`$PKG_CONFIG kpathsea --cflags` - KPATHSEA_LIBS=`$PKG_CONFIG kpathsea --libs` -elif test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then - as_fn_error $? "did not find kpathsea" "$LINENO" 5 +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless fi -if $PKG_CONFIG ptexenc; then - PTEXENC_INCLUDES=`$PKG_CONFIG ptexenc --cflags` - PTEXENC_LIBS=`$PKG_CONFIG ptexenc --libs` -elif test "x$need_ptexenc:$with_system_ptexenc" = xyes:yes; then - as_fn_error $? "did not find ptexenc" "$LINENO" 5 -fi -##tldbg _KPSE_LIB_FLAGS_SYSTEM: zlib (z). -if test "x$with_zlib_includes" != x && test "x$with_zlib_includes" != xyes; then - ZLIB_INCLUDES="-I$with_zlib_includes" -fi -ZLIB_LIBS="-lz" -if test "x$with_zlib_libdir" != x && test "x$with_zlib_libdir" != xyes; then - ZLIB_LIBS="-L$with_zlib_libdir $ZLIB_LIBS" -fi -if $PKG_CONFIG PPLIB; then - PPLIB_INCLUDES=`$PKG_CONFIG PPLIB --cflags` - PPLIB_LIBS=`$PKG_CONFIG PPLIB --libs` -elif test "x$need_PPLIB:$with_system_PPLIB" = xyes:yes; then - as_fn_error $? "did not find PPLIB" "$LINENO" 5 -fi -##tldbg _KPSE_LIB_FLAGS_SYSTEM: potrace (potrace). -if test "x$with_potrace_includes" != x && test "x$with_potrace_includes" != xyes; then - POTRACE_INCLUDES="-I$with_potrace_includes" -fi -POTRACE_LIBS="-lpotrace" -if test "x$with_potrace_libdir" != x && test "x$with_potrace_libdir" != xyes; then - POTRACE_LIBS="-L$with_potrace_libdir $POTRACE_LIBS" -fi -##tldbg _KPSE_LIB_FLAGS_SYSTEM: libpaper (paper). -if test "x$with_libpaper_includes" != x && test "x$with_libpaper_includes" != xyes; then - LIBPAPER_INCLUDES="-I$with_libpaper_includes" -fi -LIBPAPER_LIBS="-lpaper" -if test "x$with_libpaper_libdir" != x && test "x$with_libpaper_libdir" != xyes; then - LIBPAPER_LIBS="-L$with_libpaper_libdir $LIBPAPER_LIBS" -fi -if $PKG_CONFIG libpng; then - LIBPNG_INCLUDES=`$PKG_CONFIG libpng --cflags` - LIBPNG_LIBS=`$PKG_CONFIG libpng --libs` -elif test "x$need_libpng:$with_system_libpng" = xyes:yes; then - as_fn_error $? "did not find libpng" "$LINENO" 5 -fi -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}freetype-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}freetype-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_FT2_CONFIG+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$FT2_CONFIG"; then - ac_cv_prog_FT2_CONFIG="$FT2_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_FT2_CONFIG="${ac_tool_prefix}freetype-config" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS + fi # test -n "$compiler" -fi ;; -esac -fi -FT2_CONFIG=$ac_cv_prog_FT2_CONFIG -if test -n "$FT2_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FT2_CONFIG" >&5 -printf "%s\n" "$FT2_CONFIG" >&6; } + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +printf %s "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +printf "%s\n" "no, using $LN_S" >&6; } fi -fi -if test -z "$ac_cv_prog_FT2_CONFIG"; then - ac_ct_FT2_CONFIG=$FT2_CONFIG - # Extract the first word of "freetype-config", so it can be a program name with args. -set dummy freetype-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_FT2_CONFIG+y} +# Check whether --with-ln-s was given. +if test ${with_ln_s+y} then : - printf %s "(cached) " >&6 -else case e in #( - e) if test -n "$ac_ct_FT2_CONFIG"; then - ac_cv_prog_ac_ct_FT2_CONFIG="$ac_ct_FT2_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_FT2_CONFIG="freetype-config" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi ;; -esac + withval=$with_ln_s; fi -ac_ct_FT2_CONFIG=$ac_cv_prog_ac_ct_FT2_CONFIG -if test -n "$ac_ct_FT2_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FT2_CONFIG" >&5 -printf "%s\n" "$ac_ct_FT2_CONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +if test "x$LN_S" != "xln -s" && test "x$kpse_cv_have_win32" = xno && test "x$with_ln_s" != xno; then + as_fn_error $? "You could use \`--without-ln-s' to build without working \`ln -s'" "$LINENO" 5 fi - if test "x$ac_ct_FT2_CONFIG" = x; then - FT2_CONFIG="false" +if test "x$enable_native_texlive_build" = xyes; then + if test "x$datarootdir" = 'x${prefix}/share'; then + datarootdir='${prefix}' + ac_configure_args="$ac_configure_args '--datarootdir=$datarootdir'" + fi + if test "x$mandir" = 'x${datarootdir}/man'; then + mandir='${prefix}/texmf-dist/doc/man' + ac_configure_args="$ac_configure_args '--mandir=$mandir'" + fi + if test "x$infodir" = 'x${datarootdir}/info'; then + infodir='${prefix}/texmf-dist/doc/info' + ac_configure_args="$ac_configure_args '--infodir=$infodir'" + fi +fi + +if test "x$enable_web2c" = xyes && test "x$with_system_kpathsea" = xyes; then + if test "x$with_kpathsea_includes" = x; then + list="/usr/include /usr/local/include" else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - FT2_CONFIG=$ac_ct_FT2_CONFIG + list=$with_kpathsea_includes + fi + found=no + for ac_dir in $list; do + if test -r "$ac_dir/kpathsea/paths.h"; then + found=yes + break + fi + done + if test "x$found" = xno; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: You requested to build \`web2c' using an installed \`kpathsea' version," >&5 +printf "%s\n" "$as_me: You requested to build \`web2c' using an installed \`kpathsea' version," >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: which requires to locate the <kpathsea/paths.h> header file." >&5 +printf "%s\n" "$as_me: which requires to locate the <kpathsea/paths.h> header file." >&6;} + as_fn_error $? "Sorry, not found under any of: $list *****" "$LINENO" 5 fi +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for TeX specific libraries to build" >&5 +printf %s "checking for TeX specific libraries to build... " >&6; } +echo 'tldbg:_KPSE_RECURSE called: list=texlibs, text=TeX specific libraries, cond=test "x$with_system_[]Kpse_pkg" != xyes && test "x$need_[]Kpse_pkg" = xyes, prefix=texk/.' >&5 +MAKE_SUBDIRS= +CONF_SUBDIRS= +if test -x $srcdir/texk/kpathsea/configure; then + test "x$with_system_kpathsea" != xyes && test "x$need_kpathsea" = xyes && MAKE_SUBDIRS="texk/kpathsea $MAKE_SUBDIRS" + CONF_SUBDIRS="texk/kpathsea $CONF_SUBDIRS" else - FT2_CONFIG="$ac_cv_prog_FT2_CONFIG" + echo 'tldbg:_KPSE_RECURSE skipping subdir, no (executable) configure: '"$srcdir"'/texk/kpathsea/configure' >&5 fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAKE_SUBDIRS" >&5 +printf "%s\n" "$MAKE_SUBDIRS" >&6; } + +kpse_save_CPPFLAGS=$CPPFLAGS +kpse_save_LIBS=$LIBS + +syslib_status=yes +syslib_used=no if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 @@ -25163,101 +22924,73 @@ esac else PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" fi -if $FT2_CONFIG --ftversion >/dev/null 2>&1; then - FREETYPE2_INCLUDES=`$FT2_CONFIG --cflags` - FREETYPE2_LIBS=`$FT2_CONFIG --libs` -elif $PKG_CONFIG --libs freetype2 >/dev/null 2>&1; then - FREETYPE2_INCLUDES=`$PKG_CONFIG --cflags freetype2` - FREETYPE2_LIBS=`$PKG_CONFIG --libs freetype2` -elif test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then - as_fn_error $? "did not find freetype-config required for system freetype2 library" "$LINENO" 5 -fi - -##tldbg _KPSE_LIB_FLAGS_SYSTEM: gd (gd). -if test "x$with_gd_includes" != x && test "x$with_gd_includes" != xyes; then - GD_INCLUDES="-I$with_gd_includes" -fi -GD_LIBS="-lgd" -if test "x$with_gd_libdir" != x && test "x$with_gd_libdir" != xyes; then - GD_LIBS="-L$with_gd_libdir $GD_LIBS" -fi -if $PKG_CONFIG pixman-1 --atleast-version=0.18; then - PIXMAN_INCLUDES=`$PKG_CONFIG pixman-1 --cflags` - PIXMAN_LIBS=`$PKG_CONFIG pixman-1 --libs` -elif test "x$need_pixman:$with_system_pixman" = xyes:yes; then - as_fn_error $? "did not find pixman-1 0.18 or better" "$LINENO" 5 +if $PKG_CONFIG kpathsea; then + KPATHSEA_INCLUDES=`$PKG_CONFIG kpathsea --cflags` + KPATHSEA_LIBS=`$PKG_CONFIG kpathsea --libs` +elif test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then + as_fn_error $? "did not find kpathsea" "$LINENO" 5 fi -if $PKG_CONFIG cairo --atleast-version=1.12; then - CAIRO_INCLUDES=`$PKG_CONFIG cairo --cflags` - CAIRO_LIBS=`$PKG_CONFIG cairo --libs` -elif test "x$need_cairo:$with_system_cairo" = xyes:yes; then - as_fn_error $? "did not find cairo 1.12 or better" "$LINENO" 5 +if $PKG_CONFIG ptexenc; then + PTEXENC_INCLUDES=`$PKG_CONFIG ptexenc --cflags` + PTEXENC_LIBS=`$PKG_CONFIG ptexenc --libs` +elif test "x$need_ptexenc:$with_system_ptexenc" = xyes:yes; then + as_fn_error $? "did not find ptexenc" "$LINENO" 5 fi -##tldbg _KPSE_LIB_FLAGS_SYSTEM: gmp (gmp). -if test "x$with_gmp_includes" != x && test "x$with_gmp_includes" != xyes; then - GMP_INCLUDES="-I$with_gmp_includes" +##tldbg _KPSE_LIB_FLAGS_SYSTEM: zlib (z). +if test "x$with_zlib_includes" != x && test "x$with_zlib_includes" != xyes; then + ZLIB_INCLUDES="-I$with_zlib_includes" fi -GMP_LIBS="-lgmp" -if test "x$with_gmp_libdir" != x && test "x$with_gmp_libdir" != xyes; then - GMP_LIBS="-L$with_gmp_libdir $GMP_LIBS" +ZLIB_LIBS="-lz" +if test "x$with_zlib_libdir" != x && test "x$with_zlib_libdir" != xyes; then + ZLIB_LIBS="-L$with_zlib_libdir $ZLIB_LIBS" fi -##tldbg _KPSE_LIB_FLAGS_SYSTEM: mpfr (mpfr). -if test "x$with_mpfr_includes" != x && test "x$with_mpfr_includes" != xyes; then - MPFR_INCLUDES="-I$with_mpfr_includes" -fi -MPFR_LIBS="-lmpfr" -if test "x$with_mpfr_libdir" != x && test "x$with_mpfr_libdir" != xyes; then - MPFR_LIBS="-L$with_mpfr_libdir $MPFR_LIBS" +if $PKG_CONFIG PPLIB; then + PPLIB_INCLUDES=`$PKG_CONFIG PPLIB --cflags` + PPLIB_LIBS=`$PKG_CONFIG PPLIB --libs` +elif test "x$need_PPLIB:$with_system_PPLIB" = xyes:yes; then + as_fn_error $? "did not find PPLIB" "$LINENO" 5 fi -##tldbg _KPSE_LIB_FLAGS_SYSTEM: mpfi (mpfi). -if test "x$with_mpfi_includes" != x && test "x$with_mpfi_includes" != xyes; then - MPFI_INCLUDES="-I$with_mpfi_includes" +##tldbg _KPSE_LIB_FLAGS_SYSTEM: potrace (potrace). +if test "x$with_potrace_includes" != x && test "x$with_potrace_includes" != xyes; then + POTRACE_INCLUDES="-I$with_potrace_includes" fi -MPFI_LIBS="-lmpfi" -if test "x$with_mpfi_libdir" != x && test "x$with_mpfi_libdir" != xyes; then - MPFI_LIBS="-L$with_mpfi_libdir $MPFI_LIBS" +POTRACE_LIBS="-lpotrace" +if test "x$with_potrace_libdir" != x && test "x$with_potrace_libdir" != xyes; then + POTRACE_LIBS="-L$with_potrace_libdir $POTRACE_LIBS" fi -: "kpse_xpdf_system_flags - no-op" - -if $PKG_CONFIG zziplib --atleast-version=0.12; then - ZZIPLIB_INCLUDES=`$PKG_CONFIG zziplib --cflags` - ZZIPLIB_LIBS=`$PKG_CONFIG zziplib --libs` -elif test "x$need_zziplib:$with_system_zziplib" = xyes:yes; then - as_fn_error $? "did not find zziplib 0.12 or better" "$LINENO" 5 +##tldbg _KPSE_LIB_FLAGS_SYSTEM: libpaper (paper). +if test "x$with_libpaper_includes" != x && test "x$with_libpaper_includes" != xyes; then + LIBPAPER_INCLUDES="-I$with_libpaper_includes" fi - -if $PKG_CONFIG graphite2; then - GRAPHITE2_INCLUDES=`$PKG_CONFIG graphite2 --cflags` - GRAPHITE2_LIBS=`$PKG_CONFIG graphite2 --libs` -elif test "x$need_graphite2:$with_system_graphite2" = xyes:yes; then - as_fn_error $? "did not find graphite2" "$LINENO" 5 +LIBPAPER_LIBS="-lpaper" +if test "x$with_libpaper_libdir" != x && test "x$with_libpaper_libdir" != xyes; then + LIBPAPER_LIBS="-L$with_libpaper_libdir $LIBPAPER_LIBS" fi -if $PKG_CONFIG teckit; then - TECKIT_INCLUDES=`$PKG_CONFIG teckit --cflags` - TECKIT_LIBS=`$PKG_CONFIG teckit --libs` -elif test "x$need_teckit:$with_system_teckit" = xyes:yes; then - as_fn_error $? "did not find teckit" "$LINENO" 5 +if $PKG_CONFIG libpng; then + LIBPNG_INCLUDES=`$PKG_CONFIG libpng --cflags` + LIBPNG_LIBS=`$PKG_CONFIG libpng --libs` +elif test "x$need_libpng:$with_system_libpng" = xyes:yes; then + as_fn_error $? "did not find libpng" "$LINENO" 5 fi -echo 'tldbg:KPSE_ICU_SYSTEM_FLAGS called.' >&5 if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}icu-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}icu-config; ac_word=$2 + # Extract the first word of "${ac_tool_prefix}freetype-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}freetype-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ICU_CONFIG+y} +if test ${ac_cv_prog_FT2_CONFIG+y} then : printf %s "(cached) " >&6 else case e in #( - e) if test -n "$ICU_CONFIG"; then - ac_cv_prog_ICU_CONFIG="$ICU_CONFIG" # Let the user override the test. + e) if test -n "$FT2_CONFIG"; then + ac_cv_prog_FT2_CONFIG="$FT2_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -25270,7 +23003,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ICU_CONFIG="${ac_tool_prefix}icu-config" + ac_cv_prog_FT2_CONFIG="${ac_tool_prefix}freetype-config" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -25281,10 +23014,10 @@ IFS=$as_save_IFS fi ;; esac fi -ICU_CONFIG=$ac_cv_prog_ICU_CONFIG -if test -n "$ICU_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ICU_CONFIG" >&5 -printf "%s\n" "$ICU_CONFIG" >&6; } +FT2_CONFIG=$ac_cv_prog_FT2_CONFIG +if test -n "$FT2_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FT2_CONFIG" >&5 +printf "%s\n" "$FT2_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } @@ -25292,18 +23025,18 @@ fi fi -if test -z "$ac_cv_prog_ICU_CONFIG"; then - ac_ct_ICU_CONFIG=$ICU_CONFIG - # Extract the first word of "icu-config", so it can be a program name with args. -set dummy icu-config; ac_word=$2 +if test -z "$ac_cv_prog_FT2_CONFIG"; then + ac_ct_FT2_CONFIG=$FT2_CONFIG + # Extract the first word of "freetype-config", so it can be a program name with args. +set dummy freetype-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_ICU_CONFIG+y} +if test ${ac_cv_prog_ac_ct_FT2_CONFIG+y} then : printf %s "(cached) " >&6 else case e in #( - e) if test -n "$ac_ct_ICU_CONFIG"; then - ac_cv_prog_ac_ct_ICU_CONFIG="$ac_ct_ICU_CONFIG" # Let the user override the test. + e) if test -n "$ac_ct_FT2_CONFIG"; then + ac_cv_prog_ac_ct_FT2_CONFIG="$ac_ct_FT2_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -25316,7 +23049,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_ICU_CONFIG="icu-config" + ac_cv_prog_ac_ct_FT2_CONFIG="freetype-config" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -25327,17 +23060,17 @@ IFS=$as_save_IFS fi ;; esac fi -ac_ct_ICU_CONFIG=$ac_cv_prog_ac_ct_ICU_CONFIG -if test -n "$ac_ct_ICU_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_ICU_CONFIG" >&5 -printf "%s\n" "$ac_ct_ICU_CONFIG" >&6; } +ac_ct_FT2_CONFIG=$ac_cv_prog_ac_ct_FT2_CONFIG +if test -n "$ac_ct_FT2_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FT2_CONFIG" >&5 +printf "%s\n" "$ac_ct_FT2_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi - if test "x$ac_ct_ICU_CONFIG" = x; then - ICU_CONFIG="false" + if test "x$ac_ct_FT2_CONFIG" = x; then + FT2_CONFIG="false" else case $cross_compiling:$ac_tool_warned in yes:) @@ -25345,10 +23078,10 @@ yes:) printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac - ICU_CONFIG=$ac_ct_ICU_CONFIG + FT2_CONFIG=$ac_ct_FT2_CONFIG fi else - ICU_CONFIG="$ac_cv_prog_ICU_CONFIG" + FT2_CONFIG="$ac_cv_prog_FT2_CONFIG" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. @@ -25453,368 +23186,341 @@ esac else PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" fi -if $ICU_CONFIG --version >/dev/null 2>&1; then - ICU_INCLUDES=`$ICU_CONFIG --cppflags` - ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly --ldflags-system` -elif $PKG_CONFIG --libs icu-uc icu-io >/dev/null 2>&1; then - ICU_INCLUDES=`$PKG_CONFIG --cflags icu-uc icu-io` - ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io` -elif test "x$need_icu:$with_system_icu" = xyes:yes; then - as_fn_error $? "did not find either pkg-config or icu-config; one is required for system icu library support" "$LINENO" 5 +if $FT2_CONFIG --ftversion >/dev/null 2>&1; then + FREETYPE2_INCLUDES=`$FT2_CONFIG --cflags` + FREETYPE2_LIBS=`$FT2_CONFIG --libs` +elif $PKG_CONFIG --libs freetype2 >/dev/null 2>&1; then + FREETYPE2_INCLUDES=`$PKG_CONFIG --cflags freetype2` + FREETYPE2_LIBS=`$PKG_CONFIG --libs freetype2` +elif test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then + as_fn_error $? "did not find freetype-config required for system freetype2 library" "$LINENO" 5 fi -if $PKG_CONFIG harfbuzz; then - HARFBUZZ_INCLUDES=`$PKG_CONFIG harfbuzz --cflags` - HARFBUZZ_LIBS=`$PKG_CONFIG harfbuzz --libs` -elif test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then - as_fn_error $? "did not find harfbuzz" "$LINENO" 5 +##tldbg _KPSE_LIB_FLAGS_SYSTEM: gd (gd). +if test "x$with_gd_includes" != x && test "x$with_gd_includes" != xyes; then + GD_INCLUDES="-I$with_gd_includes" fi - -if $PKG_CONFIG luajit; then - LUAJIT_INCLUDES=`$PKG_CONFIG luajit --cflags` - LUAJIT_LIBS=`$PKG_CONFIG luajit --libs` -elif test "x$need_luajit:$with_system_luajit" = xyes:yes; then - as_fn_error $? "did not find luajit" "$LINENO" 5 +GD_LIBS="-lgd" +if test "x$with_gd_libdir" != x && test "x$with_gd_libdir" != xyes; then + GD_LIBS="-L$with_gd_libdir $GD_LIBS" fi +if $PKG_CONFIG pixman-1 --atleast-version=0.18; then + PIXMAN_INCLUDES=`$PKG_CONFIG pixman-1 --cflags` + PIXMAN_LIBS=`$PKG_CONFIG pixman-1 --libs` +elif test "x$need_pixman:$with_system_pixman" = xyes:yes; then + as_fn_error $? "did not find pixman-1 0.18 or better" "$LINENO" 5 +fi +if $PKG_CONFIG cairo --atleast-version=1.12; then + CAIRO_INCLUDES=`$PKG_CONFIG cairo --cflags` + CAIRO_LIBS=`$PKG_CONFIG cairo --libs` +elif test "x$need_cairo:$with_system_cairo" = xyes:yes; then + as_fn_error $? "did not find cairo 1.12 or better" "$LINENO" 5 +fi +##tldbg _KPSE_LIB_FLAGS_SYSTEM: gmp (gmp). +if test "x$with_gmp_includes" != x && test "x$with_gmp_includes" != xyes; then + GMP_INCLUDES="-I$with_gmp_includes" +fi +GMP_LIBS="-lgmp" +if test "x$with_gmp_libdir" != x && test "x$with_gmp_libdir" != xyes; then + GMP_LIBS="-L$with_gmp_libdir $GMP_LIBS" +fi - - -## texk/kpathsea/ac/kpathsea.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ -## basic check of system kpathsea -if test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`kpathsea' library" >&5 -printf %s "checking requested system \`kpathsea' library... " >&6; } - CPPFLAGS="$KPATHSEA_INCLUDES $CPPFLAGS" - LIBS="$KPATHSEA_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <kpathsea/kpathsea.h> -#include <kpathsea/version.h> -int -main (void) -{ -const char *version = kpathsea_version_string; -kpse_set_program_name("prog", "name"); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; -esac +##tldbg _KPSE_LIB_FLAGS_SYSTEM: mpfr (mpfr). +if test "x$with_mpfr_includes" != x && test "x$with_mpfr_includes" != xyes; then + MPFR_INCLUDES="-I$with_mpfr_includes" fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +MPFR_LIBS="-lmpfr" +if test "x$with_mpfr_libdir" != x && test "x$with_mpfr_libdir" != xyes; then + MPFR_LIBS="-L$with_mpfr_libdir $MPFR_LIBS" fi -## texk/ptexenc/ac/ptexenc.ac: configure.ac fragment for the TeX Live subdirectory texk/ptexenc/ -## basic check of system ptexenc -if test "x$need_ptexenc:$with_system_ptexenc" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`ptexenc' library" >&5 -printf %s "checking requested system \`ptexenc' library... " >&6; } - CPPFLAGS="$PTEXENC_INCLUDES $CPPFLAGS" - LIBS="$PTEXENC_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ptexenc/ptexenc.h> -int -main (void) -{ -const char *version = ptexenc_version_string; -set_enc_string("prog", "name"); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; -esac +##tldbg _KPSE_LIB_FLAGS_SYSTEM: mpfi (mpfi). +if test "x$with_mpfi_includes" != x && test "x$with_mpfi_includes" != xyes; then + MPFI_INCLUDES="-I$with_mpfi_includes" fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +MPFI_LIBS="-lmpfi" +if test "x$with_mpfi_libdir" != x && test "x$with_mpfi_libdir" != xyes; then + MPFI_LIBS="-L$with_mpfi_libdir $MPFI_LIBS" +fi + +: "kpse_xpdf_system_flags - no-op" + +if $PKG_CONFIG zziplib --atleast-version=0.12; then + ZZIPLIB_INCLUDES=`$PKG_CONFIG zziplib --cflags` + ZZIPLIB_LIBS=`$PKG_CONFIG zziplib --libs` +elif test "x$need_zziplib:$with_system_zziplib" = xyes:yes; then + as_fn_error $? "did not find zziplib 0.12 or better" "$LINENO" 5 fi -## libs/zlib/ac/zlib.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ -## basic check of system zlib -if test "x$need_zlib:$with_system_zlib" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`zlib' library" >&5 -printf %s "checking requested system \`zlib' library... " >&6; } - CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS" - LIBS="$ZLIB_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <zlib.h> -int -main (void) -{ -z_stream stream; -const char *version = zlibVersion(); -deflate(&stream, 0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; -esac +if $PKG_CONFIG graphite2; then + GRAPHITE2_INCLUDES=`$PKG_CONFIG graphite2 --cflags` + GRAPHITE2_LIBS=`$PKG_CONFIG graphite2 --libs` +elif test "x$need_graphite2:$with_system_graphite2" = xyes:yes; then + as_fn_error $? "did not find graphite2" "$LINENO" 5 fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } + +if $PKG_CONFIG teckit; then + TECKIT_INCLUDES=`$PKG_CONFIG teckit --cflags` + TECKIT_LIBS=`$PKG_CONFIG teckit --libs` +elif test "x$need_teckit:$with_system_teckit" = xyes:yes; then + as_fn_error $? "did not find teckit" "$LINENO" 5 fi -## libs/luajit/ac/luajit.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ -## basic check of system luajit -if test "x$need_luajit:$with_system_luajit" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`luajit' library" >&5 -printf %s "checking requested system \`luajit' library... " >&6; } - CPPFLAGS="$LUAJIT_INCLUDES $CPPFLAGS" - LIBS="$LUAJIT_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <luajit.h> -int -main (void) -{ -const char *v = LUAJIT_VERSION; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" +echo 'tldbg:KPSE_ICU_SYSTEM_FLAGS called.' >&5 +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}icu-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}icu-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ICU_CONFIG+y} then : - syslib_used=yes kpse_res=ok + printf %s "(cached) " >&6 else case e in #( - e) syslib_status=no kpse_res=failed ;; + e) if test -n "$ICU_CONFIG"; then + ac_cv_prog_ICU_CONFIG="$ICU_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ICU_CONFIG="${ac_tool_prefix}icu-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +ICU_CONFIG=$ac_cv_prog_ICU_CONFIG +if test -n "$ICU_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ICU_CONFIG" >&5 +printf "%s\n" "$ICU_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/libpaper/ac/libpaper.ac: configure.ac fragment for the TeX Live subdirectory libs/libpaper/ -## basic check of system libpaper -if test "x$need_libpaper:$with_system_libpaper" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpaper' library" >&5 -printf %s "checking requested system \`libpaper' library... " >&6; } - CPPFLAGS="$LIBPAPER_INCLUDES $CPPFLAGS" - LIBS="$LIBPAPER_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <paper.h> -int -main (void) -{ -const char *v = defaultpapername(); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" + +fi +if test -z "$ac_cv_prog_ICU_CONFIG"; then + ac_ct_ICU_CONFIG=$ICU_CONFIG + # Extract the first word of "icu-config", so it can be a program name with args. +set dummy icu-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_ICU_CONFIG+y} then : - syslib_used=yes kpse_res=ok + printf %s "(cached) " >&6 else case e in #( - e) syslib_status=no kpse_res=failed ;; + e) if test -n "$ac_ct_ICU_CONFIG"; then + ac_cv_prog_ac_ct_ICU_CONFIG="$ac_ct_ICU_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_ICU_CONFIG="icu-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +ac_ct_ICU_CONFIG=$ac_cv_prog_ac_ct_ICU_CONFIG +if test -n "$ac_ct_ICU_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_ICU_CONFIG" >&5 +printf "%s\n" "$ac_ct_ICU_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/libpng/ac/libpng.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ -## basic check of system libpng -if test "x$need_libpng:$with_system_libpng" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpng' library" >&5 -printf %s "checking requested system \`libpng' library... " >&6; } - CPPFLAGS="$LIBPNG_INCLUDES $CPPFLAGS" - LIBS="$LIBPNG_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <png.h> -int -main (void) -{ -png_structp png; png_voidp io; png_rw_ptr fn; -png_set_read_fn(png, io, fn); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; + if test "x$ac_ct_ICU_CONFIG" = x; then + ICU_CONFIG="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; esac + ICU_CONFIG=$ac_ct_ICU_CONFIG + fi +else + ICU_CONFIG="$ac_cv_prog_ICU_CONFIG" fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } -fi - -## libs/freetype2/ac/freetype2.ac: configure.ac fragment for the TeX Live subdirectory libs/freetype2/ -## basic check of system freetype2 -if test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`freetype2' library" >&5 -printf %s "checking requested system \`freetype2' library... " >&6; } - CPPFLAGS="$FREETYPE2_INCLUDES $CPPFLAGS" - LIBS="$FREETYPE2_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ft2build.h> -#include FT_FREETYPE_H -int -main (void) -{ -FT_Library library; FT_Init_FreeType(&library); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PKG_CONFIG+y} then : - syslib_used=yes kpse_res=ok + printf %s "(cached) " >&6 else case e in #( - e) syslib_status=no kpse_res=failed ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } -fi + e) if test -n "$PKG_CONFIG"; then + ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS -## libs/potrace/ac/potrace.ac: configure.ac fragment for the TeX Live subdirectory libs/potrace/ -## basic check of system potrace -if test "x$need_potrace:$with_system_potrace" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`potrace' library" >&5 -printf %s "checking requested system \`potrace' library... " >&6; } - CPPFLAGS="$POTRACE_INCLUDES $CPPFLAGS" - LIBS="$POTRACE_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <potracelib.h> -int -main (void) -{ -potrace_state_t st; -const char *version = potrace_version(); -potrace_state_free(&st); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; +fi ;; esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +PKG_CONFIG=$ac_cv_prog_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/gd/ac/gd.ac: configure.ac fragment for the TeX Live subdirectory libs/gd/ -## basic check of system gd -if test "x$need_gd:$with_system_gd" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`gd' library" >&5 -printf %s "checking requested system \`gd' library... " >&6; } - CPPFLAGS="$GD_INCLUDES $CPPFLAGS" - LIBS="$GD_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <gd.h> -int -main (void) -{ -gdImageCreate(1, 2); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" + +fi +if test -z "$ac_cv_prog_PKG_CONFIG"; then + ac_ct_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} then : - syslib_used=yes kpse_res=ok + printf %s "(cached) " >&6 else case e in #( - e) syslib_status=no kpse_res=failed ;; + e) if test -n "$ac_ct_PKG_CONFIG"; then + ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG +if test -n "$ac_ct_PKG_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 +printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -## libs/pixman/ac/pixman.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## basic check of system pixman -if test "x$need_pixman:$with_system_pixman" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`pixman' library" >&5 -printf %s "checking requested system \`pixman' library... " >&6; } - CPPFLAGS="$PIXMAN_INCLUDES $CPPFLAGS" - LIBS="$PIXMAN_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <pixman.h> -int -main (void) -{ -const char *s = pixman_version_string(); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; + if test "x$ac_ct_PKG_CONFIG" = x; then + PKG_CONFIG="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; esac + PKG_CONFIG=$ac_ct_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } +if $ICU_CONFIG --version >/dev/null 2>&1; then + ICU_INCLUDES=`$ICU_CONFIG --cppflags` + ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly --ldflags-system` +elif $PKG_CONFIG --libs icu-uc icu-io >/dev/null 2>&1; then + ICU_INCLUDES=`$PKG_CONFIG --cflags icu-uc icu-io` + ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io` +elif test "x$need_icu:$with_system_icu" = xyes:yes; then + as_fn_error $? "did not find either pkg-config or icu-config; one is required for system icu library support" "$LINENO" 5 +fi + +if $PKG_CONFIG harfbuzz; then + HARFBUZZ_INCLUDES=`$PKG_CONFIG harfbuzz --cflags` + HARFBUZZ_LIBS=`$PKG_CONFIG harfbuzz --libs` +elif test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then + as_fn_error $? "did not find harfbuzz" "$LINENO" 5 +fi + +if $PKG_CONFIG luajit; then + LUAJIT_INCLUDES=`$PKG_CONFIG luajit --cflags` + LUAJIT_LIBS=`$PKG_CONFIG luajit --libs` +elif test "x$need_luajit:$with_system_luajit" = xyes:yes; then + as_fn_error $? "did not find luajit" "$LINENO" 5 fi -## libs/cairo/ac/cairo.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## basic check of system cairo -if test "x$need_cairo:$with_system_cairo" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`cairo' library" >&5 -printf %s "checking requested system \`cairo' library... " >&6; } - CPPFLAGS="$CAIRO_INCLUDES $CPPFLAGS" - LIBS="$CAIRO_LIBS $LIBS" + + + + + +## texk/kpathsea/ac/kpathsea.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/ +## basic check of system kpathsea +if test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`kpathsea' library" >&5 +printf %s "checking requested system \`kpathsea' library... " >&6; } + CPPFLAGS="$KPATHSEA_INCLUDES $CPPFLAGS" + LIBS="$KPATHSEA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <cairo.h> +#include <kpathsea/kpathsea.h> +#include <kpathsea/version.h> int main (void) { -const char *s = cairo_version_string(); +const char *version = kpathsea_version_string; +kpse_set_program_name("prog", "name"); ; return 0; } @@ -25832,20 +23538,22 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/gmp/ac/gmp.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/ -## basic check of system gmp -if test "x$need_gmp:$with_system_gmp" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`gmp' library" >&5 -printf %s "checking requested system \`gmp' library... " >&6; } - CPPFLAGS="$GMP_INCLUDES $CPPFLAGS" - LIBS="$GMP_LIBS $LIBS" +## libs/zlib/ac/zlib.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/ +## basic check of system zlib +if test "x$need_zlib:$with_system_zlib" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`zlib' library" >&5 +printf %s "checking requested system \`zlib' library... " >&6; } + CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS" + LIBS="$ZLIB_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <gmp.h> +#include <zlib.h> int main (void) { -const char *s = gmp_version; +z_stream stream; +const char *version = zlibVersion(); +deflate(&stream, 0); ; return 0; } @@ -25863,20 +23571,20 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/mpfr/ac/mpfr.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfr/ -## basic check of system mpfr -if test "x$need_mpfr:$with_system_mpfr" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`mpfr' library" >&5 -printf %s "checking requested system \`mpfr' library... " >&6; } - CPPFLAGS="$MPFR_INCLUDES $CPPFLAGS" - LIBS="$MPFR_LIBS $LIBS" +## libs/luajit/ac/luajit.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/ +## basic check of system luajit +if test "x$need_luajit:$with_system_luajit" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`luajit' library" >&5 +printf %s "checking requested system \`luajit' library... " >&6; } + CPPFLAGS="$LUAJIT_INCLUDES $CPPFLAGS" + LIBS="$LUAJIT_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <mpfr.h> +#include <luajit.h> int main (void) { -const char *s = mpfr_get_version(); +const char *v = LUAJIT_VERSION; ; return 0; } @@ -25894,31 +23602,26 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/xpdf/ac/xpdf.ac: configure.ac fragment for the TeX Live subdirectory libs/xpdf/ -## basic check of system xpdf (a.k.a. poppler, no longer supported in -## TL sources) -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test "x$need_xpdf:$with_system_xpdf" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`xpdf' library" >&5 -printf %s "checking requested system \`xpdf' library... " >&6; } - CPPFLAGS="$XPDF_INCLUDES $CPPFLAGS" - LIBS="$XPDF_LIBS $LIBS" +## libs/libpng/ac/libpng.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ +## basic check of system libpng +if test "x$need_libpng:$with_system_libpng" = xyes:yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpng' library" >&5 +printf %s "checking requested system \`libpng' library... " >&6; } + CPPFLAGS="$LIBPNG_INCLUDES $CPPFLAGS" + LIBS="$LIBPNG_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <GfxFont.h> +#include <png.h> int main (void) { -GfxFont *gfxFont; gfxFont->isOk(); +png_structp png; png_voidp io; png_rw_ptr fn; +png_set_read_fn(png, io, fn); ; return 0; } _ACEOF -if ac_fn_cxx_try_link "$LINENO" +if ac_fn_c_try_link "$LINENO" then : syslib_used=yes kpse_res=ok else case e in #( @@ -25930,11 +23633,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 printf "%s\n" "$kpse_res" >&6; } fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu ## libs/zziplib/ac/zziplib.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/ ## basic check of system zziplib @@ -25999,89 +23697,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ printf "%s\n" "$kpse_res" >&6; } fi -## libs/teckit/ac/teckit.ac: configure.ac fragment for the TeX Live subdirectory libs/teckit/ -## basic check of system teckit -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test "x$need_teckit:$with_system_teckit" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`teckit' library" >&5 -printf %s "checking requested system \`teckit' library... " >&6; } - CPPFLAGS="$TECKIT_INCLUDES $CPPFLAGS" - LIBS="$TECKIT_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <teckit/TECkit_Engine.h> -int -main (void) -{ -TECkit_Converter converter; TECkit_DisposeConverter(converter); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -## libs/icu/ac/icu.ac: configure.ac fragment for the TeX Live subdirectory libs/icu/ -## basic check of system icu -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test "x$need_icu:$with_system_icu" = xyes:yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`icu' library" >&5 -printf %s "checking requested system \`icu' library... " >&6; } - CPPFLAGS="$ICU_INCLUDES $CPPFLAGS" - LIBS="$ICU_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <unicode/ustring.h> -int -main (void) -{ -UErrorCode code; const UChar *src; UChar *dst; -u_strToLower(dst, -1, src, -1, NULL, &code); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO" -then : - syslib_used=yes kpse_res=ok -else case e in #( - e) syslib_status=no kpse_res=failed ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -printf "%s\n" "$kpse_res" >&6; } -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - ## libs/harfbuzz/ac/harfbuzz.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/ ## basic check of system harfbuzz if test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then @@ -26733,7 +24348,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by TeX Live $as_me 2024-03-10, which was +This file was extended by TeX Live $as_me 2025-03-07, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -26792,7 +24407,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -TeX Live config.status 2024-03-10 +TeX Live config.status 2025-03-07 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" @@ -28759,11 +26374,11 @@ msg_compiling="$msg_compiling test "x$srcdir" = x. || msg_compiling="$msg_compiling from sources in $kpse_src" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: -** Configuration summary for $PACKAGE_STRING (2025$with_banner_add): +** Configuration summary for $PACKAGE_STRING (2026/dev$with_banner_add): $msg_compiling" >&5 printf "%s\n" " -** Configuration summary for $PACKAGE_STRING (2025$with_banner_add): +** Configuration summary for $PACKAGE_STRING (2026/dev$with_banner_add): $msg_compiling" >&6; } case $kpse_src$kpse_bld in diff --git a/source/libs/README b/source/libs/README index 8a661b213..be663eb9b 100644 --- a/source/libs/README +++ b/source/libs/README @@ -1,4 +1,4 @@ -$Id: README 74131 2025-02-19 04:34:49Z kakuto $ +$Id: README 74540 2025-03-08 22:22:06Z kakuto $ Public domain. Originally created by Karl Berry, 2005. Libraries we compile for TeX Live. @@ -28,7 +28,7 @@ graphite2 1.3.14 - checked 10apr20 https://sourceforge.net/projects/silgraphite/files/graphite2/ (requires C++11) -harfbuzz 10.2.0 - checked 12jan25 +harfbuzz 10.4.0 - checked 09mar25 https://github.com/harfbuzz/harfbuzz/releases/latest icu 76.1 - checked 27oct24 (requires C++17, e.g., g++13) @@ -37,7 +37,7 @@ icu 76.1 - checked 27oct24 (requires C++17, e.g., g++13) libpaper 1.1.29 - checked 07jan24 https://ftp.debian.org/debian/pool/main/libp/libpaper/ -libpng 1.6.46 - checked 25jan25 +libpng 1.6.47 - checked 09mar25 https://sourceforge.net/projects/libpng/files/ - used by many lua 5.3.6 - checked 04oct20 diff --git a/source/libs/configure b/source/libs/configure index 4bcbb6e01..43447b388 100755 --- a/source/libs/configure +++ b/source/libs/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for TeX Live libs 2025. +# Generated by GNU Autoconf 2.72 for TeX Live libs 2026/dev. # # Report bugs to <tex-k@tug.org>. # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='TeX Live libs' PACKAGE_TARNAME='tex-live-libs' -PACKAGE_VERSION='2025' -PACKAGE_STRING='TeX Live libs 2025' +PACKAGE_VERSION='2026/dev' +PACKAGE_STRING='TeX Live libs 2026/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1382,7 +1382,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures TeX Live libs 2025 to adapt to many kinds of systems. +'configure' configures TeX Live libs 2026/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1453,7 +1453,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of TeX Live libs 2025:";; + short | recursive ) echo "Configuration of TeX Live libs 2026/dev:";; esac cat <<\_ACEOF @@ -1639,7 +1639,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -TeX Live libs configure 2025 +TeX Live libs configure 2026/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1799,7 +1799,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by TeX Live libs $as_me 2025, which was +It was created by TeX Live libs $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -5776,7 +5776,7 @@ fi # Define the identity of the package. PACKAGE='tex-live-libs' - VERSION='2025' + VERSION='2026/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -6737,7 +6737,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by TeX Live libs $as_me 2025, which was +This file was extended by TeX Live libs $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6796,7 +6796,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -TeX Live libs config.status 2025 +TeX Live libs config.status 2026/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/libs/harfbuzz/ChangeLog b/source/libs/harfbuzz/ChangeLog index a4a3938e1..49a13b5b4 100644 --- a/source/libs/harfbuzz/ChangeLog +++ b/source/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Import harfbuzz-10.4.0. + * version.ac: Adjusted. + 2025-01-12 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Import harfbuzz-10.2.0. diff --git a/source/libs/harfbuzz/TLpatches/ChangeLog b/source/libs/harfbuzz/TLpatches/ChangeLog index 3f77b7feb..32f6c06d4 100644 --- a/source/libs/harfbuzz/TLpatches/ChangeLog +++ b/source/libs/harfbuzz/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Imported harfbuzz-10.4.0 source tree from: + https://github.com/harfbuzz/harfbuzz/releases/download/10.4.0/ + 2025-01-12 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Imported harfbuzz-10.2.0 source tree from: diff --git a/source/libs/harfbuzz/TLpatches/TL-Changes b/source/libs/harfbuzz/TLpatches/TL-Changes index ccbddc86b..91b5aa943 100644 --- a/source/libs/harfbuzz/TLpatches/TL-Changes +++ b/source/libs/harfbuzz/TLpatches/TL-Changes @@ -1,5 +1,5 @@ -Changes applied to the harfbuzz-10.2.0/ tree as obtained from: - https://github.com/harfbuzz/harfbuzz/releases/download/10.2.0/ +Changes applied to the harfbuzz-10.4.0/ tree as obtained from: + https://github.com/harfbuzz/harfbuzz/releases/download/10.4.0/ Removed: .clang-format diff --git a/source/libs/harfbuzz/configure b/source/libs/harfbuzz/configure index 746df925c..43d9ee0e2 100755 --- a/source/libs/harfbuzz/configure +++ b/source/libs/harfbuzz/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 10.2.0. +# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 10.4.0. # # Report bugs to <tex-k@tug.org>. # @@ -604,8 +604,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='harfbuzz (TeX Live)' PACKAGE_TARNAME='harfbuzz--tex-live-' -PACKAGE_VERSION='10.2.0' -PACKAGE_STRING='harfbuzz (TeX Live) 10.2.0' +PACKAGE_VERSION='10.4.0' +PACKAGE_STRING='harfbuzz (TeX Live) 10.4.0' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1341,7 +1341,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures harfbuzz (TeX Live) 10.2.0 to adapt to many kinds of systems. +'configure' configures harfbuzz (TeX Live) 10.4.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1413,7 +1413,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 10.2.0:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 10.4.0:";; esac cat <<\_ACEOF @@ -1518,7 +1518,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 10.2.0 +harfbuzz (TeX Live) configure 10.4.0 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2075,7 +2075,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by harfbuzz (TeX Live) $as_me 10.2.0, which was +It was created by harfbuzz (TeX Live) $as_me 10.4.0, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -5252,7 +5252,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='10.2.0' + VERSION='10.4.0' # Some tools Automake needs. @@ -5441,9 +5441,9 @@ echo 'tldbg:KPSE_BASIC done (pkg=harfbuzz, amopt=no-define)' >&5 HB_VERSION_MAJOR=10 -HB_VERSION_MINOR=2 +HB_VERSION_MINOR=4 HB_VERSION_MICRO=0 -HB_VERSION=10.2.0 +HB_VERSION=10.4.0 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -9292,7 +9292,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by harfbuzz (TeX Live) $as_me 10.2.0, which was +This file was extended by harfbuzz (TeX Live) $as_me 10.4.0, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -9360,7 +9360,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -harfbuzz (TeX Live) config.status 10.2.0 +harfbuzz (TeX Live) config.status 10.4.0 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt b/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt index c3e568fe3..3b4f5aa61 100644 --- a/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt +++ b/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt @@ -334,15 +334,15 @@ endif () if (WIN32 AND HB_HAVE_GDI) add_definitions(-DHAVE_GDI) list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h) - list(APPEND THIRD_PARTY_LIBS gdi32) - list(APPEND PC_LIBS_PRIV -lgdi32) + list(APPEND THIRD_PARTY_LIBS gdi32 user32) + list(APPEND PC_LIBS_PRIV -lgdi32 -luser32) endif () if (WIN32 AND HB_HAVE_UNISCRIBE) add_definitions(-DHAVE_UNISCRIBE) list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h) - list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4) - list(APPEND PC_LIBS_PRIV -lusp10 -lgdi32 -lrpcrt4) + list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4 user32) + list(APPEND PC_LIBS_PRIV -lusp10 -lgdi32 -lrpcrt4 -luser32) endif () if (WIN32 AND HB_HAVE_DIRECTWRITE) diff --git a/source/libs/harfbuzz/harfbuzz-src/NEWS b/source/libs/harfbuzz/harfbuzz-src/NEWS index ce123f2a5..4e7dbe0d9 100644 --- a/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,65 @@ +Overview of changes leading to 10.4.0 +Saturday, March 1, 2025 +==================================== +- Drawing glyphs using hb-draw API now avoids any “malloc†calls, which + improves drawing performance by 10+%. +- Add support new “GVAR†table fonts with more than 65535 glyphs. Support is + currently behind a compilation flag and is disabled by default. +- Some hb-directwrite and hb-ft APIs got renamed with more clear names and the + old names are deprecated. +- Various build and fuzzing fixes. + +- New API: ++hb_directwrite_face_get_dw_font_face() ++hb_ft_font_get_ft_face() + +- Deprecated API: ++hb_directwrite_face_get_font_face() ++hb_ft_font_get_face() + + +Overview of changes leading to 10.3.0 +Thursday, February 11, 2025 +==================================== +- Vastly improved “AAT†shaping performance. LucidaGrande benchmark-shape + before: 14.6ms after: 5.9ms. +- Improved OpenType shaping performance (kerning / ligature), at the expense of + ~1kb per face allocated cache memory. Roboto-Regular benchmark-shape before: + 10.3ms after: 9.4ms. +- Improved “COLRv1†benchmark-font paint performance. Before: 7.85ms after + 4.85ms. +- Don’t apply glyph substitutions in “morx†table of a font with known broken + “morx†table (AALMAGHRIBI.ttf font). +- Update IANA and OT language registries. +- Various documentation updates. +- Various build improvements, and test speed-ups. +- The “hb_face_reference_blob()†API now works for faces created with + “hb_face_create_for_tables()†if the face sets “get_table_tags†callback. + This constructs a new face blob from individual table blobs. +- Various fixes to how “trak†table is handled to bring it closer to Core Text + behaviour. Particularly, the tracking values for sizes not explicitly set in + the table are now properly interpolated, and the tracking is applied to glyph + advances when they are returned by ot-font functions, instead of applying + them during shaping. The “trak†pseudo OpenType feature that could be used to + disable “trak†table application have been dropped. +- Core Text font functions now support non-BMP code points. +- The drawing algorithm used by hb-draw for “glyf†table now match the + algorithm used by FreeType and Core Text. +- The “hb_coretext_font_create()†API now copy font variations from Core Text + font to the created HarfBuzz font. +- Add an API to get the feature tags enabled on a given shape-plan after + executing it, which can be used to applications to show in the UI what + features are applied by default (which can vary based on the font, the + script, the language, and the direction set on the buffer). +- Add APIs to created HarfBuzz font from DirectWrite font, and copy the font + variations. + +- New API: ++hb_directwrite_font_create() ++hb_directwrite_font_get_dw_font() ++hb_ot_shape_plan_get_feature_tags() + + Overview of changes leading to 10.2.0 Saturday, January 11, 2025 ==================================== @@ -183,10 +245,10 @@ Saturday, November 11, 2023 tools. Old option is kept as an alias. - New API: -HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION ++HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION - Deprecated API: -HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION ++HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION Overview of changes leading to 8.2.2 Wednesday, October 18, 2023 diff --git a/source/libs/harfbuzz/harfbuzz-src/README.md b/source/libs/harfbuzz/harfbuzz-src/README.md index 2cd8b4068..02c1554bd 100644 --- a/source/libs/harfbuzz/harfbuzz-src/README.md +++ b/source/libs/harfbuzz/harfbuzz-src/README.md @@ -1,9 +1,9 @@ -[](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg) +[](https://github.com/harfbuzz/harfbuzz/actions/workflows/linux-ci.yml) +[](https://github.com/harfbuzz/harfbuzz/actions/workflows/macos-ci.yml) +[](https://github.com/harfbuzz/harfbuzz/actions/workflows/msvc-ci.yml) [](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main) [](https://oss-fuzz-build-logs.storage.googleapis.com/index.html) [](https://scan.coverity.com/projects/harfbuzz) -[](https://app.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) -[](https://codecov.io/gh/harfbuzz/harfbuzz) [](https://repology.org/project/harfbuzz/versions) [](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz) diff --git a/source/libs/harfbuzz/harfbuzz-src/meson.build b/source/libs/harfbuzz/harfbuzz-src/meson.build index f3e43b595..1460c2a9d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/meson.build +++ b/source/libs/harfbuzz/harfbuzz-src/meson.build @@ -1,6 +1,6 @@ project('harfbuzz', 'c', 'cpp', meson_version: '>= 0.55.0', - version: '10.2.0', + version: '10.4.0', default_options: [ 'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway # 'cpp_rtti=false', # Do NOT enable, wraps inherit it and ICU needs RTTI @@ -321,7 +321,7 @@ if host_machine.system() == 'windows' and not get_option('gdi').disabled() endif gdi_deps_found = true - foreach usplib : ['usp10', 'gdi32', 'rpcrt4'] + foreach usplib : ['usp10', 'gdi32', 'rpcrt4', 'user32'] dep = cpp.find_library(usplib, required: get_option('gdi')) gdi_deps_found = gdi_deps_found and dep.found() gdi_uniscribe_deps += dep @@ -464,6 +464,13 @@ configure_file(output: 'config.h', configuration: conf) alias_target('lib', libharfbuzz) alias_target('libs', libharfbuzz, libharfbuzz_subset) +if meson.version().version_compare('>=0.57.0') + # Re glib, see https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646347531 + add_test_setup('default', + exclude_suites: ['google-benchmark'], + is_default: glib_dep.type_name() != 'internal' and not meson.is_subproject()) +endif + build_summary = { 'Directories': {'prefix': get_option('prefix'), diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh index bcf1848f4..50550e811 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh @@ -941,10 +941,12 @@ struct CBDT } } - bool has_data () const { return cbdt.get_length (); } + bool has_data () const { return cbdt->version.major; } bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + if (!has_data ()) return false; + hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; hb_blob_t *blob = reference_png (font, glyph); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh index d227768d5..cf10e894a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh @@ -29,11 +29,14 @@ #define OT_COLOR_COLR_COLR_HH #include "../../../hb.hh" +#include "../../../hb-decycler.hh" #include "../../../hb-open-type.hh" #include "../../../hb-ot-var-common.hh" #include "../../../hb-paint.hh" #include "../../../hb-paint-extents.hh" +#include "../CPAL/CPAL.hh" + /* * COLR -- Color * https://docs.microsoft.com/en-us/typography/opentype/spec/colr @@ -66,11 +69,11 @@ public: hb_paint_funcs_t *funcs; void *data; hb_font_t *font; - unsigned int palette_index; + hb_array_t<const BGRAColor> palette; hb_color_t foreground; ItemVarStoreInstancer &instancer; - hb_map_t current_glyphs; - hb_map_t current_layers; + hb_decycler_t glyphs_decycler; + hb_decycler_t layers_decycler; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_MAX_GRAPH_EDGE_COUNT; @@ -85,7 +88,11 @@ public: funcs (funcs_), data (data_), font (font_), - palette_index (palette_), + palette ( +#ifndef HB_NO_COLOR + font->face->table.CPAL->get_palette_colors (palette_) +#endif + ), foreground (foreground_), instancer (instancer_) { } @@ -99,12 +106,7 @@ public: if (color_index != 0xffff) { if (!funcs->custom_palette_color (data, color_index, &color)) - { - unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (font); - - hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color); - } + color = palette[color_index]; *is_foreground = false; } @@ -2134,12 +2136,16 @@ struct COLR const ItemVariationStore &get_var_store () const { return colr->get_var_store (); } + const ItemVariationStore *get_var_store_ptr () const + { return colr->get_var_store_ptr (); } bool has_delta_set_index_map () const { return colr->has_delta_set_index_map (); } const DeltaSetIndexMap &get_delta_set_index_map () const { return colr->get_delta_set_index_map (); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return colr->get_delta_set_index_map_ptr (); } private: hb_blob_ptr_t<COLR> colr; @@ -2232,9 +2238,13 @@ struct COLR const DeltaSetIndexMap &get_delta_set_index_map () const { return has_delta_set_index_map () && hb_barrier () ? this+varIdxMap : Null (DeltaSetIndexMap); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return has_delta_set_index_map () && hb_barrier () ? &(this+varIdxMap) : nullptr; } const ItemVariationStore &get_var_store () const { return has_var_store () && hb_barrier () ? this+varStore : Null (ItemVariationStore); } + const ItemVariationStore *get_var_store_ptr () const + { return has_var_store () && hb_barrier () ? &(this+varStore) : nullptr; } const ClipList &get_clip_list () const { return has_clip_list () && hb_barrier () ? this+clipList : Null (ClipList); } @@ -2482,9 +2492,9 @@ struct COLR * after instancing */ if (!subset_varstore (c, colr_prime)) return_trace (false); - ItemVarStoreInstancer instancer (&(get_var_store ()), - &(get_delta_set_index_map ()), - c->plan->normalized_coords.as_array ()); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + c->plan->normalized_coords.as_array ()); if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) return_trace (false); @@ -2513,8 +2523,8 @@ struct COLR get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - ItemVarStoreInstancer instancer (&(get_var_store ()), - &(get_delta_set_index_map ()), + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), hb_array (font->coords, font->num_coords)); if (get_clip (glyph, extents, instancer)) @@ -2575,11 +2585,13 @@ struct COLR bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const { - ItemVarStoreInstancer instancer (&(get_var_store ()), - &(get_delta_set_index_map ()), - hb_array (font->coords, font->num_coords)); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); - c.current_glyphs.add (glyph); + + hb_decycler_node_t node (c.glyphs_decycler); + node.visit (glyph); if (version >= 1) { @@ -2695,19 +2707,16 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); + hb_decycler_node_t node (c->layers_decycler); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { - if (unlikely (c->current_layers.has (i))) - continue; - - c->current_layers.add (i); + if (unlikely (!node.visit (i))) + return; const Paint &paint = paint_offset_lists.get_paint (i); c->funcs->push_group (c->data); c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); - - c->current_layers.del (i); } } @@ -2715,16 +2724,14 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - if (unlikely (c->current_glyphs.has (gid))) + hb_decycler_node_t node (c->glyphs_decycler); + if (unlikely (!node.visit (gid))) return; - c->current_glyphs.add (gid); - c->funcs->push_inverse_root_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->funcs->pop_transform (c->data); - c->current_glyphs.del (gid); return; } c->funcs->pop_transform (c->data); @@ -2747,8 +2754,6 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (has_clip_box) c->funcs->pop_clip (c->data); - - c->current_glyphs.del (gid); } } /* namespace OT */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh index 2821334db..940126a86 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh @@ -187,6 +187,14 @@ struct CPAL hb_ot_name_id_t get_color_name_id (unsigned int color_index) const { return v1 ().get_color_name_id (this, color_index, numColors); } + hb_array_t<const BGRAColor> get_palette_colors (unsigned int palette_index) const + { + if (unlikely (palette_index >= numPalettes)) + return hb_array_t<const BGRAColor> (); + unsigned int start_index = colorRecordIndicesZ[palette_index]; + hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); + return all_colors.sub_array (start_index, numColors); + } unsigned int get_palette_colors (unsigned int palette_index, unsigned int start_offset, unsigned int *color_count, /* IN/OUT. May be NULL. */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh index 344e87afb..daa197954 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh @@ -96,6 +96,15 @@ struct Coverage default:return NOT_COVERED; } } + unsigned int get_coverage (hb_codepoint_t glyph_id, + hb_ot_lookup_cache_t *cache) const + { + unsigned coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage; + coverage = get_coverage (glyph_id); + if (cache) cache->set (glyph_id, coverage); + return coverage; + } unsigned get_population () const { @@ -201,6 +210,19 @@ struct Coverage } } + unsigned cost () const + { + switch (u.format) { + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); +#ifndef HB_NO_BEYOND_64K + case 3: hb_barrier (); return u.format3.cost (); + case 4: hb_barrier (); return u.format4.cost (); +#endif + default:return 0u; + } + } + /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template <typename set_t> diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh index 3f598d40e..cdba7a505 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh @@ -103,6 +103,8 @@ struct CoverageFormat1_3 intersect_glyphs << glyphArray[i]; } + unsigned cost () const { return hb_bit_storage ((unsigned) glyphArray.len); /* bsearch cost */ } + template <typename set_t> bool collect_coverage (set_t *glyphs) const { return glyphs->add_sorted_array (glyphArray.as_array ()); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh index 9c8754235..dd577fd90 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh @@ -157,6 +157,8 @@ struct CoverageFormat2_4 } } + unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ } + template <typename set_t> bool collect_coverage (set_t *glyphs) const { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh index ac2774a76..de67548c4 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -103,12 +103,50 @@ struct PairPosFormat1_3 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const + { + return (this+coverage).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); + if (likely (cache)) + cache->clear (); + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } + + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -156,7 +194,7 @@ struct PairPosFormat1_3 strip = true; newFormats = compute_effective_value_formats (glyphset, strip, true); } - + out->valueFormat[0] = newFormats.first; out->valueFormat[1] = newFormats.second; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh index 5ffeb5d0c..f30148ab6 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -123,12 +123,61 @@ struct PairPosFormat2_4 : ValueBase const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + struct pair_pos_cache_t + { + hb_ot_lookup_cache_t coverage; + hb_ot_lookup_cache_t first; + hb_ot_lookup_cache_t second; + }; + + unsigned cache_cost () const + { + return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + cache->first.clear (); + cache->second.clear (); + } + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + pair_pos_cache_t *cache = (pair_pos_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } + + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -139,8 +188,13 @@ struct PairPosFormat2_4 : ValueBase return_trace (false); } +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint, cache ? &cache->first : nullptr); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint, cache ? &cache->second : nullptr); +#else unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); +#endif if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) { buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh index b2d151d44..e9fe39231 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -67,7 +67,7 @@ struct SinglePosFormat1 : ValueBase TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh index ae4a5ed75..2fb710589 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -66,7 +66,7 @@ struct SinglePosFormat2 : ValueBase TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= valueCount)) return_trace (false); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh index adec65d58..421a6e066 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -74,7 +74,7 @@ struct AlternateSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+alternateSet[index]).apply (c)); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh index 5c7df97d1..2ef46145e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -78,12 +78,49 @@ struct LigatureSubstFormat1_2 return lig_set.would_apply (c); } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const { - TRACE_APPLY (this); + return (this+coverage).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); + if (likely (cache)) + cache->clear (); + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); +#else + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); +#endif + if (index == NOT_COVERED) return_trace (false); const auto &lig_set = this+ligatureSet[index]; return_trace (lig_set.apply (c)); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh index 3b4bd1169..441d4dee0 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh @@ -66,7 +66,7 @@ struct MultipleSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+sequence[index]).apply (c)); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index ec374f2f0..1f598cc40 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -112,7 +112,7 @@ struct ReverseChainSingleSubstFormat1 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) return_trace (false); /* No chaining to this type */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 850be86c0..550d8f04e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -128,7 +128,7 @@ struct SingleSubstFormat1_3 TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); hb_codepoint_t d = deltaGlyphID; hb_codepoint_t mask = get_mask (); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh index 9c651abe7..dce28b672 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -104,7 +104,7 @@ struct SingleSubstFormat2_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= substitute.len)) return_trace (false); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/types.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/types.hh index 3840db059..527f64114 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/types.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/types.hh @@ -29,6 +29,9 @@ #ifndef OT_LAYOUT_TYPES_HH #define OT_LAYOUT_TYPES_HH +using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_ot_lookup_cache_t) == 256, ""); + namespace OT { namespace Layout { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc index 1afb57111..3b9eec4fb 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.cc @@ -3,7 +3,6 @@ #ifndef HB_NO_VAR_COMPOSITES #include "../../../hb-draw.hh" -#include "../../../hb-geometry.hh" #include "../../../hb-ot-layout-common.hh" #include "../../../hb-ot-layout-gdef-table.hh" @@ -133,18 +132,19 @@ VarComponent::get_path_at (hb_font_t *font, hb_codepoint_t parent_gid, hb_draw_session_t &draw_session, hb_array_t<const int> coords, + hb_transform_t total_transform, hb_ubytes_t total_record, - hb_set_t *visited, + hb_decycler_t *decycler, signed *edges_left, signed depth_left, + hb_glyf_scratch_t &scratch, VarRegionList::cache_t *cache) const { const unsigned char *end = total_record.arrayZ + total_record.length; const unsigned char *record = total_record.arrayZ; - auto &VARC = *font->face->table.VARC; + auto &VARC = *font->face->table.VARC->table; auto &varStore = &VARC+VARC.varStore; - auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache); #define READ_UINT32VAR(name) \ HB_STMT_START { \ @@ -187,22 +187,25 @@ VarComponent::get_path_at (hb_font_t *font, unsigned conditionIndex; READ_UINT32VAR (conditionIndex); const auto &condition = (&VARC+VARC.conditionList)[conditionIndex]; + auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache); show = condition.evaluate (coords.arrayZ, coords.length, &instancer); } // Axis values - hb_vector_t<unsigned> axisIndices; - hb_vector_t<float> axisValues; + auto &axisIndices = scratch.axisIndices; + axisIndices.clear (); + auto &axisValues = scratch.axisValues; + axisValues.clear (); if (flags & (unsigned) flags_t::HAVE_AXES) { unsigned axisIndicesIndex; READ_UINT32VAR (axisIndicesIndex); - axisIndices = (&VARC+VARC.axisIndicesList)[axisIndicesIndex]; + axisIndices.extend ((&VARC+VARC.axisIndicesList)[axisIndicesIndex]); axisValues.resize (axisIndices.length); const HBUINT8 *p = (const HBUINT8 *) record; TupleValues::decompile (p, axisValues, (const HBUINT8 *) end); - record += (const unsigned char *) p - record; + record = (const unsigned char *) p; } // Apply variations if any @@ -312,32 +315,87 @@ VarComponent::get_path_at (hb_font_t *font, if (!(flags & (unsigned) flags_t::HAVE_SCALE_Y)) transform.scaleY = transform.scaleX; - // Scale the transform by the font's scale - float x_scale = font->x_multf; - float y_scale = font->y_multf; - transform.translateX *= x_scale; - transform.translateY *= y_scale; - transform.tCenterX *= x_scale; - transform.tCenterY *= y_scale; + total_transform.transform (transform.to_transform ()); + total_transform.scale (font->x_mult ? 1.f / font->x_multf : 0.f, + font->y_mult ? 1.f / font->y_multf : 0.f); + VARC.get_path_at (font, gid, + draw_session, component_coords, total_transform, + parent_gid, + decycler, edges_left, depth_left - 1, + scratch); + } + +#undef PROCESS_TRANSFORM_COMPONENTS +#undef READ_UINT32VAR + + return hb_ubytes_t (record, end - record); +} + +bool +VARC::get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t<const int> coords, + hb_transform_t transform, + hb_codepoint_t parent_glyph, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch) const +{ + // Don't recurse on the same glyph. + unsigned idx = glyph == parent_glyph ? + NOT_COVERED : + (this+coverage).get_coverage (glyph); + if (idx == NOT_COVERED) + { // Build a transforming pen to apply the transform. hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); - hb_transforming_pen_context_t context {transform.to_transform (), + hb_transforming_pen_context_t context {transform, draw_session.funcs, draw_session.draw_data, &draw_session.st}; hb_draw_session_t transformer_session {transformer_funcs, &context}; + hb_draw_session_t &shape_draw_session = transform.is_identity () ? draw_session : transformer_session; - VARC.get_path_at (font, gid, - transformer_session, component_coords, - parent_gid, - visited, edges_left, depth_left - 1); + if (!font->face->table.glyf->get_path_at (font, glyph, shape_draw_session, coords, scratch)) +#ifndef HB_NO_CFF + if (!font->face->table.cff2->get_path_at (font, glyph, shape_draw_session, coords)) + if (!font->face->table.cff1->get_path (font, glyph, shape_draw_session)) // Doesn't have variations +#endif + return false; + return true; } -#undef PROCESS_TRANSFORM_COMPONENTS -#undef READ_UINT32VAR + if (depth_left <= 0) + return true; - return hb_ubytes_t (record, end - record); + if (*edges_left <= 0) + return true; + (*edges_left)--; + + hb_decycler_node_t node (*decycler); + if (unlikely (!node.visit (glyph))) + return true; + + hb_ubytes_t record = (this+glyphRecords)[idx]; + + float static_cache[sizeof (void *) * 16]; + VarRegionList::cache_t *cache = (this+varStore).create_cache (hb_array (static_cache)); + + transform.scale (font->x_multf, font->y_multf); + + VarCompositeGlyph::get_path_at (font, glyph, + draw_session, coords, transform, + record, + decycler, edges_left, depth_left, + scratch, + cache); + + (this+varStore).destroy_cache (cache, hb_array (static_cache)); + + return true; } //} // namespace Var diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh index d60f7b0c2..30e54b6bd 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh @@ -1,6 +1,8 @@ #ifndef OT_VAR_VARC_VARC_HH #define OT_VAR_VARC_VARC_HH +#include "../../../hb-decycler.hh" +#include "../../../hb-geometry.hh" #include "../../../hb-ot-layout-common.hh" #include "../../../hb-ot-glyf-table.hh" #include "../../../hb-ot-cff2-table.hh" @@ -46,10 +48,12 @@ struct VarComponent hb_codepoint_t parent_gid, hb_draw_session_t &draw_session, hb_array_t<const int> coords, + hb_transform_t transform, hb_ubytes_t record, - hb_set_t *visited, + hb_decycler_t *decycler, signed *edges_left, signed depth_left, + hb_glyf_scratch_t &scratch, VarRegionList::cache_t *cache = nullptr) const; }; @@ -60,19 +64,21 @@ struct VarCompositeGlyph hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t<const int> coords, + hb_transform_t transform, hb_ubytes_t record, - hb_set_t *visited, + hb_decycler_t *decycler, signed *edges_left, signed depth_left, + hb_glyf_scratch_t &scratch, VarRegionList::cache_t *cache = nullptr) { while (record) { const VarComponent &comp = * (const VarComponent *) (record.arrayZ); record = comp.get_path_at (font, glyph, - draw_session, coords, + draw_session, coords, transform, record, - visited, edges_left, depth_left, cache); + decycler, edges_left, depth_left, scratch, cache); } } }; @@ -85,79 +91,37 @@ struct VARC static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); - bool + HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t<const int> coords, - hb_codepoint_t parent_glyph = HB_CODEPOINT_INVALID, - hb_set_t *visited = nullptr, - signed *edges_left = nullptr, - signed depth_left = HB_MAX_NESTING_LEVEL) const - { - hb_set_t stack_set; - if (visited == nullptr) - visited = &stack_set; - signed stack_edges = HB_MAX_GRAPH_EDGE_COUNT; - if (edges_left == nullptr) - edges_left = &stack_edges; - - // Don't recurse on the same glyph. - unsigned idx = glyph == parent_glyph ? - NOT_COVERED : - (this+coverage).get_coverage (glyph); - if (idx == NOT_COVERED) - { - if (!font->face->table.glyf->get_path_at (font, glyph, draw_session, coords)) -#ifndef HB_NO_CFF - if (!font->face->table.cff2->get_path_at (font, glyph, draw_session, coords)) - if (!font->face->table.cff1->get_path (font, glyph, draw_session)) // Doesn't have variations -#endif - return false; - return true; - } - - if (depth_left <= 0) - return true; - - if (*edges_left <= 0) - return true; - (*edges_left)--; - - if (visited->has (glyph) || visited->in_error ()) - return true; - visited->add (glyph); - - hb_ubytes_t record = (this+glyphRecords)[idx]; - - VarRegionList::cache_t *cache = record.length >= 64 ? // Heuristic - (this+varStore).create_cache () - : nullptr; - - VarCompositeGlyph::get_path_at (font, glyph, - draw_session, coords, - record, - visited, edges_left, depth_left, - cache); - - (this+varStore).destroy_cache (cache); - - visited->del (glyph); - - return true; - } + hb_transform_t transform, + hb_codepoint_t parent_glyph, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch) const; bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_path_at (font, gid, draw_session, hb_array (font->coords, font->num_coords)); } - - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const + get_path (hb_font_t *font, + hb_codepoint_t gid, + hb_draw_session_t &draw_session, + hb_glyf_scratch_t &scratch) const { - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; + hb_decycler_t decycler; + signed edges = HB_MAX_GRAPH_EDGE_COUNT; + + return get_path_at (font, + gid, + draw_session, + hb_array (font->coords, font->num_coords), + HB_TRANSFORM_IDENTITY, + HB_CODEPOINT_INVALID, + &decycler, + &edges, + HB_MAX_NESTING_LEVEL, + scratch); } bool sanitize (hb_sanitize_context_t *c) const @@ -173,6 +137,63 @@ struct VARC glyphRecords.sanitize (c, this)); } + struct accelerator_t + { + friend struct VarComponent; + + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table<VARC> (face); + } + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + table.destroy (); + } + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + { + if (!table->has_data ()) return false; + + hb_glyf_scratch_t *scratch; + + // Borrow the cached strach buffer. + { + scratch = cached_scratch.get_acquire (); + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return true; + } + } + + bool ret = table->get_path (font, gid, draw_session, *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } + + private: + hb_blob_ptr_t<VARC> table; + hb_atomic_ptr_t<hb_glyf_scratch_t> cached_scratch; + }; + + bool has_data () const { return version.major != 0; } + protected: FixedVersion<> version; /* Version identifier */ Offset32To<Coverage> coverage; @@ -184,6 +205,10 @@ struct VARC DEFINE_SIZE_STATIC (24); }; +struct VARC_accelerator_t : VARC::accelerator_t { + VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {} +}; + #endif //} diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/coord-setter.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/coord-setter.hh index a2b483ce2..0df524ed2 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/coord-setter.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/coord-setter.hh @@ -11,22 +11,48 @@ namespace OT { struct coord_setter_t { - coord_setter_t (hb_array_t<const int> coords) : - coords (coords) {} + coord_setter_t (hb_array_t<const int> coords_) + { + length = coords_.length; + if (length <= ARRAY_LENGTH (static_coords)) + hb_memcpy (static_coords, coords_.arrayZ, length * sizeof (int)); + else + dynamic_coords.extend (coords_); + } int& operator [] (unsigned idx) { if (unlikely (idx >= HB_VAR_COMPOSITE_MAX_AXES)) return Crap(int); - if (coords.length < idx + 1) - coords.resize (idx + 1); - return coords[idx]; + + if (length <= ARRAY_LENGTH (static_coords)) + { + if (idx < ARRAY_LENGTH (static_coords)) + { + while (length <= idx) + static_coords[length++] = 0; + return static_coords[idx]; + } + else + dynamic_coords.extend (hb_array (static_coords, length)); + } + + if (dynamic_coords.length <= idx) + { + if (unlikely (!dynamic_coords.resize (idx + 1))) + return Crap(int); + length = idx + 1; + } + return dynamic_coords.arrayZ[idx]; } hb_array_t<int> get_coords () - { return coords.as_array (); } + { return length <= ARRAY_LENGTH (static_coords) ? hb_array (static_coords, length) : dynamic_coords.as_array (); } - hb_vector_t<int> coords; + private: + hb_vector_t<int> dynamic_coords; + unsigned length; + int static_coords[sizeof (void *) * 8]; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh index 5c0ecd513..e2ec4a80e 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh @@ -143,7 +143,7 @@ struct CompositeGlyphRecord float matrix[4]; contour_point_t trans; get_transformation (matrix, trans); - if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points + if (unlikely (!points.alloc (points.length + 1 + 4))) return false; // For phantom points points.push (trans); return true; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh index 7772597e5..2c289d511 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh @@ -251,7 +251,8 @@ struct Glyph composite_contours_p = nullptr; } - if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) + hb_glyf_scratch_t scratch; + if (!get_points (font, glyf, all_points, scratch, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) return false; // .notdef, set type to empty so we only update metrics and don't compile bytes for @@ -305,6 +306,7 @@ struct Glyph template <typename accelerator_t> bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, + hb_glyf_scratch_t &scratch, contour_point_vector_t *points_with_deltas = nullptr, /* OUT */ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ unsigned *composite_contours = nullptr, /* OUT */ @@ -312,7 +314,6 @@ struct Glyph bool use_my_metrics = true, bool phantom_only = false, hb_array_t<const int> coords = hb_array_t<const int> (), - hb_map_t *current_glyphs = nullptr, unsigned int depth = 0, unsigned *edge_count = nullptr) const { @@ -322,10 +323,6 @@ struct Glyph if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false; (*edge_count)++; - hb_map_t current_glyphs_stack; - if (current_glyphs == nullptr) - current_glyphs = ¤t_glyphs_stack; - if (head_maxp_info) { head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); @@ -334,8 +331,7 @@ struct Glyph if (!coords) coords = hb_array (font->coords, font->num_coords); - contour_point_vector_t stack_points; - contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points; + contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; unsigned old_length = points.length; switch (type) { @@ -388,36 +384,53 @@ struct Glyph #ifndef HB_NO_VAR if (coords) - glyf_accelerator.gvar->apply_deltas_to_points (gid, - coords, - points.as_array ().sub_array (old_length), - phantom_only && type == SIMPLE); + { +#ifndef HB_NO_BEYOND_64K + if (glyf_accelerator.GVAR->has_data ()) + glyf_accelerator.GVAR->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + phantom_only && type == SIMPLE); + else +#endif + glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + phantom_only && type == SIMPLE); + } #endif // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it // with child glyphs' points if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE) { - if (unlikely (!points_with_deltas->resize (points.length))) return false; + assert (old_length == 0); *points_with_deltas = points; } + float shift = 0; switch (type) { case SIMPLE: if (depth == 0 && head_maxp_info) head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4); + shift = phantoms[PHANTOM_LEFT].x; break; case COMPOSITE: { + hb_decycler_node_t decycler_node (scratch.decycler); + unsigned int comp_index = 0; for (auto &item : get_composite_iterator ()) { hb_codepoint_t item_gid = item.get_gid (); - if (unlikely (current_glyphs->has (item_gid))) + if (unlikely (!decycler_node.visit (item_gid))) + { + comp_index++; continue; - - current_glyphs->add (item_gid); + } unsigned old_count = all_points.length; @@ -426,6 +439,7 @@ struct Glyph .get_points (font, glyf_accelerator, all_points, + scratch, points_with_deltas, head_maxp_info, composite_contours, @@ -433,14 +447,16 @@ struct Glyph use_my_metrics, phantom_only, coords, - current_glyphs, depth + 1, edge_count))) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } + // points might have been reallocated. Relocate phantoms. + phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + auto comp_points = all_points.as_array ().sub_array (old_count); /* Copy phantom points from component if USE_MY_METRICS flag set */ @@ -455,7 +471,7 @@ struct Glyph item.get_transformation (matrix, default_trans); /* Apply component transformation & translation (with deltas applied) */ - item.transform_points (comp_points, matrix, points[comp_index]); + item.transform_points (comp_points, matrix, points[old_length + comp_index]); } if (item.is_anchored () && !phantom_only) @@ -476,12 +492,11 @@ struct Glyph if (all_points.length > HB_GLYF_MAX_POINTS) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } comp_index++; - current_glyphs->del (item_gid); } if (head_maxp_info && depth == 0) @@ -492,9 +507,13 @@ struct Glyph head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index); } all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); } break; case EMPTY: all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); break; } @@ -503,10 +522,9 @@ struct Glyph /* Undocumented rasterizer behavior: * Shift points horizontally by the updated left side bearing */ - float v = -phantoms[PHANTOM_LEFT].x; - if (v) + if (shift) for (auto &point : all_points) - point.x += v; + point.x -= shift; } return !all_points.in_error (); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh index 1d42cc292..c0f01405c 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh @@ -127,19 +127,20 @@ struct SimpleGlyph hb_array_t<contour_point_t> points_ /* IN/OUT */, const HBUINT8 *end) { + auto *points = points_.arrayZ; unsigned count = points_.length; for (unsigned int i = 0; i < count;) { if (unlikely (p + 1 > end)) return false; uint8_t flag = *p++; - points_.arrayZ[i++].flag = flag; + points[i++].flag = flag; if (flag & FLAG_REPEAT) { if (unlikely (p + 1 > end)) return false; unsigned int repeat_count = *p++; unsigned stop = hb_min (i + repeat_count, count); for (; i < stop; i++) - points_.arrayZ[i].flag = flag; + points[i].flag = flag; } } return true; @@ -160,10 +161,7 @@ struct SimpleGlyph if (flag & short_flag) { if (unlikely (p + 1 > end)) return false; - if (flag & same_flag) - v += *p++; - else - v -= *p++; + v += (bool(flag & same_flag) * 2 - 1) * *p++; } else { @@ -190,7 +188,7 @@ struct SimpleGlyph unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; unsigned old_length = points.length; - points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy + points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy if (unlikely (!points.resize (points.length + num_points, false))) return false; auto points_ = points.as_array ().sub_array (old_length); if (!phantom_only) @@ -281,9 +279,9 @@ struct SimpleGlyph unsigned num_points = all_points.length - 4; hb_vector_t<uint8_t> flags, x_coords, y_coords; - if (unlikely (!flags.alloc (num_points, true))) return false; - if (unlikely (!x_coords.alloc (2*num_points, true))) return false; - if (unlikely (!y_coords.alloc (2*num_points, true))) return false; + if (unlikely (!flags.alloc_exact (num_points))) return false; + if (unlikely (!x_coords.alloc_exact (2*num_points))) return false; + if (unlikely (!y_coords.alloc_exact (2*num_points))) return false; unsigned lastflag = 255, repeat = 0; int prev_x = 0, prev_y = 0; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh index f346ae05d..fe4ae7b8c 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh @@ -94,7 +94,7 @@ struct glyf } hb_vector_t<unsigned> padded_offsets; - if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true))) + if (unlikely (!padded_offsets.alloc_exact (c->plan->new_to_old_gid_list.length))) return_trace (false); hb_vector_t<glyf_impl::SubsetGlyph> glyphs; @@ -172,6 +172,9 @@ struct glyf_accelerator_t glyf_table = nullptr; #ifndef HB_NO_VAR gvar = nullptr; +#ifndef HB_NO_BEYOND_64K + GVAR = nullptr; +#endif #endif hmtx = nullptr; #ifndef HB_NO_VERTICAL @@ -187,6 +190,9 @@ struct glyf_accelerator_t glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face); #ifndef HB_NO_VAR gvar = face->table.gvar; +#ifndef HB_NO_BEYOND_64K + GVAR = face->table.GVAR; +#endif #endif hmtx = face->table.hmtx; #ifndef HB_NO_VERTICAL @@ -198,6 +204,13 @@ struct glyf_accelerator_t } ~glyf_accelerator_t () { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + glyf_table.destroy (); } @@ -206,21 +219,16 @@ struct glyf_accelerator_t protected: template<typename T> bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, - hb_array_t<const int> coords = hb_array_t<const int> ()) const + hb_array_t<const int> coords, + hb_glyf_scratch_t &scratch) const { - if (!coords) - coords = hb_array (font->coords, font->num_coords); - if (gid >= num_glyphs) return false; - /* Making this allocfree is not that easy - https://github.com/harfbuzz/harfbuzz/issues/2095 - mostly because of gvar handling in VF fonts, - perhaps a separate path for non-VF fonts can be considered */ - contour_point_vector_t all_points; + auto &all_points = scratch.all_points; + all_points.resize (0); bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) return false; unsigned count = all_points.length; @@ -229,8 +237,61 @@ struct glyf_accelerator_t if (consumer.is_consuming_contour_points ()) { - for (auto &point : all_points.as_array ().sub_array (0, count)) - consumer.consume_point (point); + auto *points = all_points.arrayZ; + + if (false) + { + /* Our path-builder was designed to work with this simple loop. + * But FreeType and CoreText do it differently, so we match those + * with the other, more complicated, code branch below. */ + for (unsigned i = 0; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + consumer.contour_end (); + } + } + else + { + for (unsigned i = 0; i < count; i++) + { + // Start of a contour. + if (points[i].flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE) + { + // First point is on-curve. Draw the contour. + for (; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + { + consumer.contour_end (); + break; + } + } + } + else + { + unsigned start = i; + + // Find end of the contour. + for (; i < count; i++) + if (points[i].is_end_point) + break; + + unsigned end = i; + + // Enough to start from the end. Our path-builder takes care of the rest. + if (likely (end < count)) // Can only fail in case of alloc failure *maybe*. + consumer.consume_point (points[end]); + + for (i = start; i < end; i++) + consumer.consume_point (points[i]); + + consumer.contour_end (); + } + } + } + consumer.points_end (); } @@ -303,6 +364,7 @@ struct glyf_accelerator_t HB_ALWAYS_INLINE void consume_point (const contour_point_t &point) { bounds.add (point); } + void contour_end () {} void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } @@ -318,7 +380,12 @@ struct glyf_accelerator_t contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; if (font->num_coords) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); + { + hb_glyf_scratch_t scratch; + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, font->num_coords), + scratch); + } if (unlikely (!success)) return @@ -338,9 +405,11 @@ struct glyf_accelerator_t if (unlikely (gid >= num_glyphs)) return false; hb_glyph_extents_t extents; - + hb_glyf_scratch_t scratch; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false)))) + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false), + hb_array (font->coords, font->num_coords), + scratch))) return false; *lsb = is_vertical @@ -366,20 +435,16 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); + { + hb_glyf_scratch_t scratch; + return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true), + hb_array (font->coords, font->num_coords), + scratch); + } #endif return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const - { - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; - } - const glyf_impl::Glyph glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const { @@ -410,15 +475,52 @@ struct glyf_accelerator_t bool get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); } + { + if (!has_data ()) return false; + + hb_glyf_scratch_t *scratch; + + // Borrow the cached strach buffer. + { + scratch = cached_scratch.get_acquire (); + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return true; + } + } + + bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + hb_array (font->coords, font->num_coords), + *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } bool get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, - hb_array_t<const int> coords) const - { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), coords); } + hb_array_t<const int> coords, + hb_glyf_scratch_t &scratch) const + { + if (!has_data ()) return false; + return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + coords, + scratch); + } #ifndef HB_NO_VAR const gvar_accelerator_t *gvar; +#ifndef HB_NO_BEYOND_64K + const GVAR_accelerator_t *GVAR; +#endif #endif const hmtx_accelerator_t *hmtx; #ifndef HB_NO_VERTICAL @@ -430,6 +532,7 @@ struct glyf_accelerator_t unsigned int num_glyphs; hb_blob_ptr_t<loca> loca_table; hb_blob_ptr_t<glyf> glyf_table; + hb_atomic_ptr_t<hb_glyf_scratch_t> cached_scratch; }; @@ -439,7 +542,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); - if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false; + if (!glyphs.alloc_exact (plan->new_to_old_gid_list.length)) return false; for (const auto &pair : plan->new_to_old_gid_list) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh index f55052450..859cd577f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh @@ -42,7 +42,7 @@ struct path_builder_t { bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; #ifdef HB_NO_CUBIC_GLYF - bool is_cubic = false; + constexpr bool is_cubic = false; #else bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC); #endif @@ -124,58 +124,60 @@ struct path_builder_t } } - if (unlikely (point.is_end_point)) - { - if (first_offcurve && last_offcurve) - { - optional_point_t mid = last_offcurve.mid (first_offcurve2 ? - first_offcurve2 : - first_offcurve); - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - last_offcurve = optional_point_t (); - } - /* now check the rest */ + } - if (first_offcurve && first_oncurve) - { - if (first_offcurve2) - draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, - first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (last_offcurve && first_oncurve) - { - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (first_oncurve) - draw_session->line_to (first_oncurve.x, first_oncurve.y); - else if (first_offcurve) - { - float x = first_offcurve.x, y = first_offcurve.y; - draw_session->move_to (x, y); - draw_session->quadratic_to (x, y, x, y); - } + void contour_end () + { + if (first_offcurve && last_offcurve) + { + optional_point_t mid = last_offcurve.mid (first_offcurve2 ? + first_offcurve2 : + first_offcurve); + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve = optional_point_t (); + } + /* now check the rest */ - /* Getting ready for the next contour */ - first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); - draw_session->close_path (); + if (first_offcurve && first_oncurve) + { + if (first_offcurve2) + draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, + first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); } + else if (last_offcurve && first_oncurve) + { + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + } + else if (first_oncurve) + draw_session->line_to (first_oncurve.x, first_oncurve.y); + else if (first_offcurve) + { + float x = first_offcurve.x, y = first_offcurve.y; + draw_session->move_to (x, y); + draw_session->quadratic_to (x, y, x, y); + } + + /* Getting ready for the next contour */ + first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); + draw_session->close_path (); } + void points_end () {} bool is_consuming_contour_points () { return true; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh index e2a25d4a0..33de82d35 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh @@ -163,7 +163,7 @@ struct NameRecord if (platformID != 1) { unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr); - + text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf() unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; name_str_utf16_be = (char *) hb_calloc (byte_len, 1); @@ -174,14 +174,14 @@ struct NameRecord } hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size, (hb_utf16_be_t::codepoint_t *) name_str_utf16_be); - + unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { c->revert (snap); hb_free (name_str_utf16_be); return_trace (nullptr); } - + encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len); } else @@ -392,7 +392,7 @@ struct name const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides = &c->plan->name_table_overrides; #endif - + auto it = + nameRecordZ.as_array (count) | hb_filter (c->plan->name_ids, &NameRecord::nameID) @@ -485,7 +485,7 @@ struct name const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ, this->table->count); - this->names.alloc (all_names.length, true); + this->names.alloc_exact (all_names.length); for (unsigned int i = 0; i < all_names.length; i++) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py b/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py index 3c1f6211e..adb0cc043 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py +++ b/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py @@ -172,7 +172,7 @@ print ('static void') print ('_output_dotted_circle (hb_buffer_t *buffer)') print ('{') print (' (void) buffer->output_glyph (0x25CCu);') -print (' _hb_glyph_info_reset_continuation (&buffer->prev());') +print (' _hb_glyph_info_clear_continuation (&buffer->prev());') print ('}') print () print ('static void') diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh index 2ea86a2a1..d2626b45f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh @@ -30,6 +30,10 @@ #include "hb-aat-layout.hh" #include "hb-aat-map.hh" #include "hb-open-type.hh" +#include "hb-cache.hh" +#include "hb-bit-set.hh" +#include "hb-bit-page.hh" + namespace OT { struct GDEF; @@ -39,10 +43,11 @@ namespace AAT { using namespace OT; -#define HB_AAT_BUFFER_DIGEST_THRESHOLD 32 - struct ankr; +using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); + struct hb_aat_apply_context_t : hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY> { @@ -61,10 +66,12 @@ struct hb_aat_apply_context_t : const ankr *ankr_table; const OT::GDEF *gdef_table; const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr; - hb_set_digest_t buffer_digest = hb_set_digest_t::full (); - hb_set_digest_t machine_glyph_set = hb_set_digest_t::full (); - hb_set_digest_t left_set = hb_set_digest_t::full (); - hb_set_digest_t right_set = hb_set_digest_t::full (); + bool using_buffer_glyph_set = false; + hb_bit_set_t buffer_glyph_set; + const hb_bit_set_t *left_set = nullptr; + const hb_bit_set_t *right_set = nullptr; + const hb_bit_set_t *machine_glyph_set = nullptr; + hb_aat_class_cache_t *machine_class_cache = nullptr; hb_mask_t subtable_flags = 0; /* Unused. For debug tracing only. */ @@ -80,6 +87,25 @@ struct hb_aat_apply_context_t : HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); void set_lookup_index (unsigned int i) { lookup_index = i; } + + void setup_buffer_glyph_set () + { + using_buffer_glyph_set = buffer->len >= 4; + + if (using_buffer_glyph_set) + buffer->collect_codepoints (buffer_glyph_set); + } + bool buffer_intersects_machine () const + { + if (using_buffer_glyph_set) + return buffer_glyph_set.intersects (*machine_glyph_set); + + // Faster for shorter buffers. + for (unsigned i = 0; i < buffer->len; i++) + if (machine_glyph_set->has (buffer->info[i].codepoint)) + return true; + return false; + } }; @@ -108,6 +134,13 @@ struct LookupFormat0 { glyphs.add_range (0, num_glyphs - 1); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < num_glyphs; i++) + if (filter (arrayZ[i])) + glyphs.add (i); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -140,8 +173,13 @@ struct LookupSegmentSingle template <typename set_t> void collect_glyphs (set_t &glyphs) const { - if (first == DELETED_GLYPH) - return; + if (first == DELETED_GLYPH) return; + glyphs.add_range (first, last); + } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (!filter (value)) return; glyphs.add_range (first, last); } @@ -182,6 +220,13 @@ struct LookupFormat2 for (unsigned int i = 0; i < count; i++) segments[i].collect_glyphs (glyphs); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, filter); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -217,10 +262,17 @@ struct LookupSegmentArray template <typename set_t> void collect_glyphs (set_t &glyphs) const { - if (first == DELETED_GLYPH) - return; + if (first == DELETED_GLYPH) return; glyphs.add_range (first, last); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const + { + const auto &values = base+valuesZ; + for (hb_codepoint_t i = first; i <= last; i++) + if (filter (values[i - first])) + glyphs.add (i); + } int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1; } @@ -271,6 +323,13 @@ struct LookupFormat4 for (unsigned i = 0; i < count; i++) segments[i].collect_glyphs (glyphs); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, this, filter); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -303,8 +362,13 @@ struct LookupSingle template <typename set_t> void collect_glyphs (set_t &glyphs) const { - if (glyph == DELETED_GLYPH) - return; + if (glyph == DELETED_GLYPH) return; + glyphs.add (glyph); + } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (!filter (value)) return; glyphs.add (glyph); } @@ -344,6 +408,13 @@ struct LookupFormat6 for (unsigned i = 0; i < count; i++) entries[i].collect_glyphs (glyphs); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs_filtered (glyphs, filter); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -379,12 +450,20 @@ struct LookupFormat8 template <typename set_t> void collect_glyphs (set_t &glyphs) const { - if (unlikely (!glyphCount)) - return; - if (firstGlyph == DELETED_GLYPH) - return; + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const T *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + if (filter (p[i])) + glyphs.add (firstGlyph + i); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -433,10 +512,8 @@ struct LookupFormat10 template <typename set_t> void collect_glyphs (set_t &glyphs) const { - if (unlikely (!glyphCount)) - return; - if (firstGlyph == DELETED_GLYPH) - return; + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); } @@ -501,6 +578,18 @@ struct Lookup default:return; } } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + switch (u.format) { + case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return; + case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return; + case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; + case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; + case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; + default:return; + } + } typename T::type get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, @@ -563,7 +652,7 @@ DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); template <typename T> struct Entry { - // This does seem like it's ever called. + // This doesn't seem like it's ever called. bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -632,18 +721,47 @@ struct StateTable { (this+classTable).collect_glyphs (glyphs, num_glyphs); } + template <typename set_t, typename table_t> + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const + { + unsigned num_classes = nClasses; + + if (unlikely (num_classes > hb_bit_page_t::BITS)) + { + (this+classTable).collect_glyphs (glyphs, num_glyphs); + return; + } + + // Collect all classes going out from the start state. + hb_bit_page_t filter; + + for (unsigned i = 0; i < num_classes; i++) + { + const auto &entry = get_entry (STATE_START_OF_TEXT, i); + if (new_state (entry.newState) == STATE_START_OF_TEXT && + !table.is_action_initiable (entry) && !table.is_actionable (entry)) + continue; + + filter.add (i); + } + + // And glyphs in those classes. + (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter); + } int new_state (unsigned int newState) const { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; } - template <typename set_t> unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, - const set_t &glyphs) const + hb_aat_class_cache_t *cache = nullptr) const { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; - if (!glyphs[glyph_id]) return CLASS_OUT_OF_BOUNDS; - return (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS); + klass = (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS); + if (cache) cache->set (glyph_id, klass); + return klass; } const Entry<Extra> *get_entries () const @@ -651,13 +769,14 @@ struct StateTable const Entry<Extra> &get_entry (int state, unsigned int klass) const { - if (unlikely (klass >= nClasses)) + unsigned n_classes = nClasses; + if (unlikely (klass >= n_classes)) klass = CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry<Extra> *entries = (this+entryTable).arrayZ; - unsigned int entry = states[state * nClasses + klass]; + unsigned int entry = states[state * n_classes + klass]; DEBUG_MSG (APPLY, nullptr, "e%u", entry); return entries[entry]; @@ -803,6 +922,13 @@ struct ClassTable if (classArray.arrayZ[i] != CLASS_OUT_OF_BOUNDS) glyphs.add (firstGlyph + i); } + template <typename set_t, typename filter_t> + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < classArray.len; i++) + if (filter (classArray.arrayZ[i])) + glyphs.add (firstGlyph + i); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -918,7 +1044,7 @@ struct ExtendedTypes } }; -template <typename Types, typename EntryData> +template <typename Types, typename EntryData, typename Flags> struct StateTableDriver { using StateTableT = StateTable<Types, EntryData>; @@ -929,14 +1055,6 @@ struct StateTableDriver machine (machine_), num_glyphs (face_->get_num_glyphs ()) {} - template <typename context_t> - bool is_idempotent_on_all_out_of_bounds (context_t *c, hb_aat_apply_context_t *ac) - { - const auto entry = machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_OUT_OF_BOUNDS); - return !c->is_actionable (ac->buffer, this, entry) && - machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT; - } - template <typename context_t> void drive (context_t *c, hb_aat_apply_context_t *ac) { @@ -977,7 +1095,7 @@ struct StateTableDriver } unsigned int klass = likely (buffer->idx < buffer->len) ? - machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_glyph_set) : + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : (unsigned) CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const EntryT &entry = machine.get_entry (state, klass); @@ -1011,41 +1129,36 @@ struct StateTableDriver * * https://github.com/harfbuzz/harfbuzz/issues/2860 */ - - const auto is_safe_to_break_extra = [&]() - { - /* 2c. */ - const auto &wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass); - - /* 2c'. */ - if (c->is_actionable (buffer, this, wouldbe_entry)) - return false; - - /* 2c". */ - return next_state == machine.new_state(wouldbe_entry.newState) - && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance); - }; - - const auto is_safe_to_break = [&]() - { + const EntryT *wouldbe_entry; + bool is_safe_to_break = + ( /* 1. */ - if (c->is_actionable (buffer, this, entry)) - return false; + !c->table->is_actionable (entry) && /* 2. */ // This one is meh, I know... - const auto ok = + ( state == StateTableT::STATE_START_OF_TEXT - || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) - || is_safe_to_break_extra(); - if (!ok) - return false; + || ((entry.flags & Flags::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) + || ( + /* 2c. */ + wouldbe_entry = &machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass) + , + /* 2c'. */ + !c->table->is_actionable (*wouldbe_entry) && + /* 2c". */ + ( + next_state == machine.new_state(wouldbe_entry->newState) && + (entry.flags & Flags::DontAdvance) == (wouldbe_entry->flags & Flags::DontAdvance) + ) + ) + ) && /* 3. */ - return !c->is_actionable (buffer, this, machine.get_entry (state, CLASS_END_OF_TEXT)); - }; + !c->table->is_actionable (machine.get_entry (state, CLASS_END_OF_TEXT)) + ); - if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len) + if (!is_safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); c->transition (buffer, this, entry); @@ -1056,7 +1169,7 @@ struct StateTableDriver if (buffer->idx == buffer->len || unlikely (!buffer->successful)) break; - if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) + if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0) (void) buffer->next_glyph (); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh index c01c31d73..4b980ca89 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh @@ -112,10 +112,6 @@ struct KerxSubTableFormat0 if (header.coverage & header.Backwards) return_trace (false); - if (!(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); - accelerator_t accel (*this, c); hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -144,7 +140,7 @@ struct KerxSubTableFormat0 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!c->left_set[left] || !c->right_set[right]) return 0; + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -211,6 +207,9 @@ struct Format1Entry<false> typedef void EntryData; + static bool initiateAction (const Entry<EntryData> &entry) + { return entry.flags & Push; } + static bool performAction (const Entry<EntryData> &entry) { return entry.flags & Offset; } @@ -227,13 +226,23 @@ struct KerxSubTableFormat1 typedef Format1Entry<Types::extended> Format1EntryT; typedef typename Format1EntryT::EntryData EntryData; + enum Flags + { + DontAdvance = Format1EntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry<EntryData> &entry) const + { + return Format1EntryT::initiateAction (entry); + } + bool is_actionable (const Entry<EntryData> &entry) const + { + return Format1EntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = true; - enum - { - DontAdvance = Format1EntryT::DontAdvance, - }; driver_context_t (const KerxSubTableFormat1 *table_, hb_aat_apply_context_t *c_) : @@ -246,12 +255,8 @@ struct KerxSubTableFormat1 depth (0), crossStream (table->header.coverage & table->header.CrossStream) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver<Types, EntryData> *driver HB_UNUSED, - const Entry<EntryData> &entry) - { return Format1EntryT::performAction (entry); } void transition (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, + StateTableDriver<Types, EntryData, Flags> *driver, const Entry<EntryData> &entry) { unsigned int flags = entry.flags; @@ -351,9 +356,10 @@ struct KerxSubTableFormat1 } } - private: + public: hb_aat_apply_context_t *c; const KerxSubTableFormat1 *table; + private: const UnsizedArrayOf<FWORD> &kernAction; unsigned int stack[8]; unsigned int depth; @@ -370,12 +376,7 @@ struct KerxSubTableFormat1 driver_context_t dc (this, c); - StateTableDriver<Types, EntryData> driver (machine, c->font->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); + StateTableDriver<Types, EntryData, Flags> driver (machine, c->font->face); driver.drive (&dc, c); @@ -440,10 +441,6 @@ struct KerxSubTableFormat2 if (header.coverage & header.Backwards) return_trace (false); - if (!(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); - accelerator_t accel (*this, c); hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -469,7 +466,7 @@ struct KerxSubTableFormat2 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!c->left_set[left] || !c->right_set[right]) return 0; + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -513,17 +510,26 @@ struct KerxSubTableFormat4 DEFINE_SIZE_STATIC (2); }; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before * going to the new state. */ - Reserved = 0x3FFF, /* Not used; set to 0. */ - }; + Reserved = 0x3FFF, /* Not used; set to 0. */ + }; + + bool is_action_initiable (const Entry<EntryData> &entry) const + { + return (entry.flags & Mark); + } + bool is_actionable (const Entry<EntryData> &entry) const + { + return entry.data.ankrActionIndex != 0xFFFF; + } + struct driver_context_t + { + static constexpr bool in_place = true; enum SubTableFlags { ActionType = 0xC0000000, /* A two-bit field containing the action type. */ @@ -533,20 +539,17 @@ struct KerxSubTableFormat4 * point table. */ }; - driver_context_t (const KerxSubTableFormat4 *table, + driver_context_t (const KerxSubTableFormat4 *table_, hb_aat_apply_context_t *c_) : c (c_), + table (table_), action_type ((table->flags & ActionType) >> 30), ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))), mark_set (false), mark (0) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver<Types, EntryData> *driver HB_UNUSED, - const Entry<EntryData> &entry) - { return entry.data.ankrActionIndex != 0xFFFF; } void transition (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, + StateTableDriver<Types, EntryData, Flags> *driver, const Entry<EntryData> &entry) { if (mark_set && entry.data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len) @@ -634,8 +637,10 @@ struct KerxSubTableFormat4 } } - private: + public: hb_aat_apply_context_t *c; + const KerxSubTableFormat4 *table; + private: unsigned int action_type; const HBUINT16 *ankrData; bool mark_set; @@ -648,12 +653,7 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); - StateTableDriver<Types, EntryData> driver (machine, c->font->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); + StateTableDriver<Types, EntryData, Flags> driver (machine, c->font->face); driver.drive (&dc, c); @@ -735,10 +735,6 @@ struct KerxSubTableFormat6 if (header.coverage & header.Backwards) return_trace (false); - if (!(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); - accelerator_t accel (*this, c); hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -793,7 +789,7 @@ struct KerxSubTableFormat6 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!c->left_set[left] || !c->right_set[right]) return 0; + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -925,7 +921,7 @@ struct KerxSubTable * The 'kerx' Table */ -using kern_accelerator_data_t = hb_vector_t<hb_pair_t<hb_set_digest_t, hb_set_digest_t>>; +using kern_accelerator_data_t = hb_vector_t<hb_pair_t<hb_bit_set_t, hb_bit_set_t>>; template <typename T> struct KerxTable @@ -985,15 +981,10 @@ struct KerxTable } bool apply (AAT::hb_aat_apply_context_t *c, - const kern_accelerator_data_t *accel_data = nullptr) const + const kern_accelerator_data_t &accel_data) const { c->buffer->unsafe_to_concat (); - if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) - c->buffer_digest = c->buffer->digest (); - else - c->buffer_digest = hb_set_digest_t::full (); - typedef typename T::SubTable SubTable; bool ret = false; @@ -1037,15 +1028,8 @@ struct KerxTable if (reverse) c->buffer->reverse (); - if (accel_data) - { - c->left_set = (*accel_data)[i].first; - c->right_set = (*accel_data)[i].second; - } - else - { - c->left_set = c->right_set = hb_set_digest_t::full (); - } + c->left_set = &accel_data[i].first; + c->right_set = &accel_data[i].second; { /* See comment in sanitize() for conditional here. */ @@ -1122,7 +1106,7 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - hb_set_digest_t left_set, right_set; + hb_bit_set_t left_set, right_set; st->collect_glyphs (left_set, right_set, num_glyphs); accel_data.push (hb_pair (left_set, right_set)); st = &StructAfter<SubTable> (*st); @@ -1148,7 +1132,7 @@ struct KerxTable bool apply (AAT::hb_aat_apply_context_t *c) const { - return table->apply (c, &accel_data); + return table->apply (c, accel_data); } hb_blob_ptr_t<T> table; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh index d31834402..617a239fe 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh @@ -29,6 +29,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" +#include "hb-ot-layout.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-aat-map.hh" @@ -53,35 +54,40 @@ struct RearrangementSubtable typedef void EntryData; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - MarkFirst = 0x8000, /* If set, make the current glyph the first + MarkFirst = 0x8000, /* If set, make the current glyph the first * glyph to be rearranged. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph + DontAdvance = 0x4000, /* If set, don't advance to the next glyph * before going to the new state. This means * that the glyph index doesn't change, even * if the glyph at that index has changed. */ - MarkLast = 0x2000, /* If set, make the current glyph the last + MarkLast = 0x2000, /* If set, make the current glyph the last * glyph to be rearranged. */ - Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ - Verb = 0x000F, /* The type of rearrangement specified. */ - }; + Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ + Verb = 0x000F, /* The type of rearrangement specified. */ + }; + + bool is_action_initiable (const Entry<EntryData> &entry) const + { + return (entry.flags & MarkFirst); + } + bool is_actionable (const Entry<EntryData> &entry) const + { + return (entry.flags & Verb); + } + + struct driver_context_t + { + static constexpr bool in_place = true; - driver_context_t (const RearrangementSubtable *table HB_UNUSED) : + driver_context_t (const RearrangementSubtable *table_) : ret (false), + table (table_), start (0), end (0) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver<Types, EntryData> *driver HB_UNUSED, - const Entry<EntryData> &entry) const - { - return (entry.flags & Verb) && start < end; - } void transition (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, + StateTableDriver<Types, EntryData, Flags> *driver, const Entry<EntryData> &entry) { unsigned int flags = entry.flags; @@ -158,6 +164,7 @@ struct RearrangementSubtable public: bool ret; + const RearrangementSubtable *table; private: unsigned int start; unsigned int end; @@ -169,11 +176,13 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver<Types, EntryData> driver (machine, c->face); + StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -207,39 +216,40 @@ struct ContextualSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ + }; + + bool is_action_initiable (const Entry<EntryData> &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry<EntryData> &entry) const + { + return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; + } + struct driver_context_t { static constexpr bool in_place = true; - enum Flags - { - SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. */ - Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ - }; driver_context_t (const ContextualSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), gdef (*c->gdef_table), mark_set (false), has_glyph_classes (gdef.has_glyph_classes ()), mark (0), - table (table_), subs (table+table->substitutionTables) {} - bool is_actionable (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, - const Entry<EntryData> &entry) const - { - if (buffer->idx == buffer->len && !mark_set) - return false; - - return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; - } void transition (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, + StateTableDriver<Types, EntryData, Flags> *driver, const Entry<EntryData> &entry) { /* Looks like CoreText applies neither mark nor current substitution for @@ -271,8 +281,9 @@ struct ContextualSubtable if (replacement) { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); - buffer->info[mark].codepoint = *replacement; - c->buffer_digest.add (*replacement); + hb_codepoint_t glyph = *replacement; + buffer->info[mark].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[mark], gdef.get_glyph_props (*replacement)); @@ -301,8 +312,9 @@ struct ContextualSubtable } if (replacement) { - buffer->info[idx].codepoint = *replacement; - c->buffer_digest.add (*replacement); + hb_codepoint_t glyph = *replacement; + buffer->info[idx].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[idx], gdef.get_glyph_props (*replacement)); @@ -318,13 +330,13 @@ struct ContextualSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const ContextualSubtable *table; + private: const OT::GDEF &gdef; bool mark_set; bool has_glyph_classes; unsigned int mark; - const ContextualSubtable *table; const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, void, false> &subs; }; @@ -334,11 +346,13 @@ struct ContextualSubtable driver_context_t dc (this, c); - StateTableDriver<Types, EntryData> driver (machine, c->face); + StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -389,6 +403,16 @@ struct LigatureEntry; template <> struct LigatureEntry<true> { + + struct EntryData + { + HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry + * for processing this group, if indicated + * by the flags. */ + public: + DEFINE_SIZE_STATIC (2); + }; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -400,14 +424,8 @@ struct LigatureEntry<true> Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ }; - struct EntryData - { - HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry - * for processing this group, if indicated - * by the flags. */ - public: - DEFINE_SIZE_STATIC (2); - }; + static bool initiateAction (const Entry<EntryData> &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry<EntryData> &entry) { return entry.flags & PerformAction; } @@ -418,6 +436,8 @@ struct LigatureEntry<true> template <> struct LigatureEntry<false> { + typedef void EntryData; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -429,7 +449,8 @@ struct LigatureEntry<false> * multiple of 4. */ }; - typedef void EntryData; + static bool initiateAction (const Entry<EntryData> &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry<EntryData> &entry) { return entry.flags & Offset; } @@ -447,13 +468,23 @@ struct LigatureSubtable typedef LigatureEntry<Types::extended> LigatureEntryT; typedef typename LigatureEntryT::EntryData EntryData; + enum Flags + { + DontAdvance = LigatureEntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry<EntryData> &entry) const + { + return LigatureEntryT::initiateAction (entry); + } + bool is_actionable (const Entry<EntryData> &entry) const + { + return LigatureEntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = false; - enum - { - DontAdvance = LigatureEntryT::DontAdvance, - }; enum LigActionFlags { LigActionLast = 0x80000000, /* This is the last action in the list. This also @@ -476,14 +507,8 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver<Types, EntryData> *driver HB_UNUSED, - const Entry<EntryData> &entry) const - { - return LigatureEntryT::performAction (entry); - } void transition (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, + StateTableDriver<Types, EntryData, Flags> *driver, const Entry<EntryData> &entry) { DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx); @@ -564,7 +589,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; - buffer->cur().unicode_props() |= UPROPS_MASK_IGNORABLE; + _hb_glyph_info_set_default_ignorable (&buffer->cur()); if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } @@ -581,9 +606,9 @@ struct LigatureSubtable public: bool ret; - private: hb_aat_apply_context_t *c; const LigatureSubtable *table; + private: const UnsizedArrayOf<HBUINT32> &ligAction; const UnsizedArrayOf<HBUINT16> &component; const UnsizedArrayOf<HBGlyphID16> &ligature; @@ -597,11 +622,13 @@ struct LigatureSubtable driver_context_t dc (this, c); - StateTableDriver<Types, EntryData> driver (machine, c->face); + StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -638,6 +665,12 @@ struct NoncontextualSubtable { TRACE_APPLY (this); + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + const OT::GDEF &gdef (*c->gdef_table); bool has_glyph_classes = gdef.has_glyph_classes (); @@ -670,8 +703,9 @@ struct NoncontextualSubtable const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { - info[i].codepoint = *replacement; - c->buffer_digest.add (*replacement); + hb_codepoint_t glyph = *replacement; + info[i].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (*replacement)); @@ -682,6 +716,12 @@ struct NoncontextualSubtable return_trace (ret); } + template <typename set_t> + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + substitute.collect_glyphs (glyphs, num_glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -715,73 +755,78 @@ struct InsertionSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, mark the current glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. This does not mean + * that the glyph pointed to is the same one as + * before. If you've made insertions immediately + * downstream of the current glyph, the next glyph + * processed would in fact be the first one + * inserted. */ + CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). If clear, and + * the currentInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). */ + MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). If clear, and + * the markedInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). */ + CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made + * to the left of the current glyph. If clear, + * they're made to the right of the current glyph. */ + MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be + * made to the left of the marked glyph. If clear, + * they're made to the right of the marked glyph. */ + CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the current + * position. Since zero means no insertions, the + * largest number of insertions at any given + * current location is 31 glyphs. */ + MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the marked + * position. Since zero means no insertions, the + * largest number of insertions at any given + * marked location is 31 glyphs. */ + }; + + bool is_action_initiable (const Entry<EntryData> &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry<EntryData> &entry) const + { + return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && + (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); + } + struct driver_context_t { static constexpr bool in_place = false; - enum Flags - { - SetMark = 0x8000, /* If set, mark the current glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. This does not mean - * that the glyph pointed to is the same one as - * before. If you've made insertions immediately - * downstream of the current glyph, the next glyph - * processed would in fact be the first one - * inserted. */ - CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). If clear, and - * the currentInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). */ - MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). If clear, and - * the markedInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). */ - CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made - * to the left of the current glyph. If clear, - * they're made to the right of the current glyph. */ - MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be - * made to the left of the marked glyph. If clear, - * they're made to the right of the marked glyph. */ - CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the current - * position. Since zero means no insertions, the - * largest number of insertions at any given - * current location is 31 glyphs. */ - MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the marked - * position. Since zero means no insertions, the - * largest number of insertions at any given - * marked location is 31 glyphs. */ - }; - driver_context_t (const InsertionSubtable *table, + driver_context_t (const InsertionSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), mark (0), insertionAction (table+table->insertionAction) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver<Types, EntryData> *driver HB_UNUSED, - const Entry<EntryData> &entry) const - { - return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && - (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); - } void transition (hb_buffer_t *buffer, - StateTableDriver<Types, EntryData> *driver, + StateTableDriver<Types, EntryData, Flags> *driver, const Entry<EntryData> &entry) { unsigned int flags = entry.flags; @@ -807,7 +852,7 @@ struct InsertionSubtable /* TODO We ignore KashidaLike setting. */ if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; for (unsigned int i = 0; i < count; i++) - c->buffer_digest.add (glyphs[i]); + c->buffer_glyph_set.add (glyphs[i]); ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -861,8 +906,9 @@ struct InsertionSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const InsertionSubtable *table; + private: unsigned int mark; const UnsizedArrayOf<HBGlyphID16> &insertionAction; }; @@ -873,11 +919,13 @@ struct InsertionSubtable driver_context_t dc (this, c); - StateTableDriver<Types, EntryData> driver (machine, c->face); + StateTableDriver<Types, EntryData, Flags> driver (machine, c->face); - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -935,24 +983,33 @@ struct hb_accelerate_subtables_context_t : friend struct hb_aat_layout_lookup_accelerator_t; public: - hb_set_digest_t digest; + hb_bit_set_t glyph_set; + mutable hb_aat_class_cache_t class_cache; template <typename T> auto init_ (const T &obj_, unsigned num_glyphs, hb_priority<1>) HB_AUTO_RETURN ( - obj_.machine.collect_glyphs (this->digest, num_glyphs) + obj_.machine.collect_initial_glyphs (glyph_set, num_glyphs, obj_) ) template <typename T> void init_ (const T &obj_, unsigned num_glyphs, hb_priority<0>) { - digest = digest.full (); + obj_.collect_initial_glyphs (glyph_set, num_glyphs); } template <typename T> void init (const T &obj_, unsigned num_glyphs) { + glyph_set.init (); init_ (obj_, num_glyphs, hb_prioritize); + class_cache.clear (); + } + + void + fini () + { + glyph_set.fini (); } }; @@ -999,12 +1056,21 @@ struct hb_aat_layout_chain_accelerator_t if (unlikely (!thiz)) return nullptr; + thiz->count = count; + hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables, num_glyphs); chain.dispatch (&c_accelerate_subtables); return thiz; } + void destroy () + { + for (unsigned i = 0; i < count; i++) + subtables[i].fini (); + } + + unsigned count; hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; @@ -1152,15 +1218,19 @@ struct Chain { bool reverse; + auto coverage = subtable->get_coverage (); + + hb_mask_t subtable_flags = subtable->subFeatureFlags; if (hb_none (hb_iter (c->range_flags) | - hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); }))) + hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; - c->subtable_flags = subtable->subFeatureFlags; - c->machine_glyph_set = accel ? accel->subtables[i].digest : hb_set_digest_t::full (); + c->subtable_flags = subtable_flags; + c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); + c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; - if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) && + if (!(coverage & ChainSubtable<Types>::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (subtable->get_coverage() & ChainSubtable<Types>::Vertical)) + bool (coverage & ChainSubtable<Types>::Vertical)) goto skip; /* Buffer contents is always in logical direction. Determine if @@ -1190,9 +1260,9 @@ struct Chain (the order opposite that of the characters, which may be right-to-left or left-to-right). */ - reverse = subtable->get_coverage () & ChainSubtable<Types>::Logical ? - bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) : - bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) != + reverse = coverage & ChainSubtable<Types>::Logical ? + bool (coverage & ChainSubtable<Types>::Backwards) : + bool (coverage & ChainSubtable<Types>::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) @@ -1298,6 +1368,12 @@ struct mortmorx hb_sanitize_context_t sc; this->table = sc.reference_table<T> (face); + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } + this->chain_count = table->get_chain_count (); this->accels = (hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *) hb_calloc (this->chain_count, sizeof (*accels)); @@ -1311,7 +1387,11 @@ struct mortmorx ~accelerator_t () { for (unsigned int i = 0; i < this->chain_count; i++) + { + if (this->accels[i]) + this->accels[i]->destroy (); hb_free (this->accels[i]); + } hb_free (this->accels); this->table.destroy (); } @@ -1365,9 +1445,8 @@ struct mortmorx unsigned get_chain_count () const { - return chainCount; + return chainCount; } - void apply (hb_aat_apply_context_t *c, const hb_aat_map_t &map, const accelerator_t &accel) const @@ -1376,10 +1455,7 @@ struct mortmorx c->buffer->unsafe_to_concat (); - if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) - c->buffer_digest = c->buffer->digest (); - else - c->buffer_digest = hb_set_digest_t::full (); + c->setup_buffer_glyph_set (); c->set_lookup_index (0); const Chain<Types> *chain = &firstChain; @@ -1428,8 +1504,17 @@ struct mortmorx DEFINE_SIZE_MIN (8); }; -struct morx : mortmorx<morx, ExtendedTypes, HB_AAT_TAG_morx> {}; -struct mort : mortmorx<mort, ObsoleteTypes, HB_AAT_TAG_mort> {}; +struct morx : mortmorx<morx, ExtendedTypes, HB_AAT_TAG_morx> +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; + +struct mort : mortmorx<mort, ObsoleteTypes, HB_AAT_TAG_mort> +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; struct morx_accelerator_t : morx::accelerator_t { morx_accelerator_t (hb_face_t *face) : morx::accelerator_t (face) {} diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh index 345a236e9..508606037 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh @@ -48,17 +48,69 @@ struct TrackTableEntry float get_track_value () const { return track.to_float (); } - int get_value (const void *base, unsigned int index, - unsigned int table_size) const - { return (base+valuesZ).as_array (table_size)[index]; } + float interpolate_at (unsigned int idx, + float ptem, + const void *base, + hb_array_t<const F16DOT16> size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + float s0 = size_table[idx].to_float (); + float s1 = size_table[idx + 1].to_float (); + int v0 = values[idx]; + int v1 = values[idx + 1]; + + // Deal with font bugs. + if (unlikely (s1 < s0)) + { hb_swap (s0, s1); hb_swap (v0, v1); } + if (unlikely (ptem < s0)) return v0; + if (unlikely (ptem > s1)) return v1; + if (unlikely (s0 == s1)) return (v0 + v1) * 0.5f; + + float t = (ptem - s0) / (s1 - s0); + return v0 + t * (v1 - v0); + } + + float get_value (float ptem, + const void *base, + hb_array_t<const F16DOT16> size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + unsigned int n_sizes = size_table.length; + + /* + * Choose size. + */ + if (!n_sizes) return 0.f; + if (n_sizes == 1) return values[0]; + + // At least two entries. + + unsigned i; + for (i = 0; i < n_sizes; i++) + if (size_table[i].to_float () >= ptem) + break; + + // Boundary conditions. + if (i == 0) return values[0]; + if (i == n_sizes) return values[n_sizes - 1]; + + // Exact match. + if (size_table[i].to_float () == ptem) return values[i]; + + // Interpolate. + return interpolate_at (i - 1, ptem, base, size_table); + } public: - bool sanitize (hb_sanitize_context_t *c, const void *base, - unsigned int table_size) const + bool sanitize (hb_sanitize_context_t *c, + const void *base, + unsigned int n_sizes) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (valuesZ.sanitize (c, base, table_size)))); + (valuesZ.sanitize (c, base, n_sizes)))); } protected: @@ -76,58 +128,38 @@ struct TrackTableEntry struct TrackData { - float interpolate_at (unsigned int idx, - float target_size, - const TrackTableEntry &trackTableEntry, - const void *base) const + float get_tracking (const void *base, float ptem, float track = 0.f) const { - unsigned int sizes = nSizes; - hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes); + unsigned count = nTracks; + hb_array_t<const F16DOT16> size_table = (base+sizeTable).as_array (nSizes); - float s0 = size_table[idx].to_float (); - float s1 = size_table[idx + 1].to_float (); - float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0); - return t * trackTableEntry.get_value (base, idx + 1, sizes) + - (1.f - t) * trackTableEntry.get_value (base, idx, sizes); - } + if (!count) return 0.f; + if (count == 1) return trackTable[0].get_value (ptem, base, size_table); - int get_tracking (const void *base, float ptem) const - { - /* - * Choose track. - */ - const TrackTableEntry *trackTableEntry = nullptr; - unsigned int count = nTracks; - for (unsigned int i = 0; i < count; i++) - { - /* Note: Seems like the track entries are sorted by values. But the - * spec doesn't explicitly say that. It just mentions it in the example. */ - - /* For now we only seek for track entries with zero tracking value */ - - if (trackTable[i].get_track_value () == 0.f) - { - trackTableEntry = &trackTable[i]; - break; - } - } - if (!trackTableEntry) return 0; + // At least two entries. - /* - * Choose size. - */ - unsigned int sizes = nSizes; - if (!sizes) return 0; - if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - - hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes); - unsigned int size_index; - for (size_index = 0; size_index < sizes - 1; size_index++) - if (size_table[size_index].to_float () >= ptem) - break; + unsigned i = 0; + unsigned j = count - 1; + + // Find the two entries that track is between. + while (i + 1 < count && trackTable[i + 1].get_track_value () < track) + i++; + while (j > 0 && trackTable[j - 1].get_track_value () > track) + j--; + + // Exact match. + if (i == j) return trackTable[i].get_value (ptem, base, size_table); + + // Interpolate. - return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem, - *trackTableEntry, base)); + float t0 = trackTable[i].get_track_value (); + float t1 = trackTable[j].get_track_value (); + + float t = (track - t0) / (t1 - t0); + + float a = trackTable[i].get_value (ptem, base, size_table); + float b = trackTable[j].get_value (ptem, base, size_table); + return a + t * (b - a); } bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -158,45 +190,15 @@ struct trak bool has_data () const { return version.to_int (); } - bool apply (hb_aat_apply_context_t *c) const + hb_position_t get_h_tracking (hb_font_t *font, float track = 0.f) const + { + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_x ((this+horizData).get_tracking (this, ptem, track)); + } + hb_position_t get_v_tracking (hb_font_t *font, float track = 0.f) const { - TRACE_APPLY (this); - - hb_mask_t trak_mask = c->plan->trak_mask; - - const float ptem = c->font->ptem; - if (unlikely (ptem <= 0.f)) - return_trace (false); - - hb_buffer_t *buffer = c->buffer; - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { - const TrackData &trackData = this+horizData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_x (tracking); - foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; - buffer->pos[start].x_advance += advance_to_add; - buffer->pos[start].x_offset += offset_to_add; - } - } - else - { - const TrackData &trackData = this+vertData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_y (tracking); - foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; - buffer->pos[start].y_advance += advance_to_add; - buffer->pos[start].y_offset += offset_to_add; - } - } - - return_trace (true); + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track)); } bool sanitize (hb_sanitize_context_t *c) const diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc index 9da29e51c..9fe77a575 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc @@ -34,9 +34,12 @@ #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" -#include "hb-aat-layout-trak-table.hh" +#include "hb-aat-layout-trak-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-ltag-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gdef-table.hh" + /* * hb_aat_apply_context_t @@ -207,6 +210,36 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) */ +bool +AAT::morx::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + + switch HB_CODEPOINT_ENCODE3 (blob->length, + face->table.GSUB->table.get_length (), + face->table.GDEF->table.get_length ()) + { + /* https://github.com/harfbuzz/harfbuzz/issues/4108 + sha1sum:a71ca6813b7e56a772cffff7c24a5166b087197c AALMAGHRIBI.ttf */ + case HB_CODEPOINT_ENCODE3 (19892, 2794, 340): + return true; + } + return false; +} + +bool +AAT::mort::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + return false; +} + void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) @@ -361,17 +394,6 @@ hb_aat_layout_has_tracking (hb_face_t *face) return face->table.trak->has_data (); } -void -hb_aat_layout_track (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) -{ - const AAT::trak& trak = *font->face->table.trak; - - AAT::hb_aat_apply_context_t c (plan, font, buffer); - trak.apply (&c); -} - /** * hb_aat_layout_get_feature_types: * @face: #hb_face_t to work upon diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh index 15c382aa9..c5d6ecb10 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh @@ -32,6 +32,9 @@ #include "hb-ot-shape.hh" #include "hb-aat-ltag-table.hh" +/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ +#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f + struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; @@ -68,10 +71,5 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL void -hb_aat_layout_track (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); - #endif /* HB_AAT_LAYOUT_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc index 5bdb8004f..1a0dee022 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc @@ -88,22 +88,23 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) /* Sort features by start/end events. */ hb_vector_t<feature_event_t> feature_events; + feature_events.alloc_exact (features.length * 2 + 1); for (unsigned int i = 0; i < features.length; i++) { - auto &feature = features[i]; + auto &feature = features.arrayZ[i]; - if (features[i].start == features[i].end) + if (feature.start == feature.end) continue; feature_event_t *event; event = feature_events.push (); - event->index = features[i].start; + event->index = feature.start; event->start = true; event->feature = feature.info; event = feature_events.push (); - event->index = features[i].end; + event->index = feature.end; event->start = false; event->feature = feature.info; } @@ -139,12 +140,12 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) current_features.qsort (); unsigned int j = 0; for (unsigned int i = 1; i < current_features.length; i++) - if (current_features[i].type != current_features[j].type || + if (current_features.arrayZ[i].type != current_features.arrayZ[j].type || /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off * respectively, so we mask out the low-order bit when checking for "duplicates" * (selectors referring to the same feature setting) here. */ - (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1)))) - current_features[++j] = current_features[i]; + (!current_features.arrayZ[i].is_exclusive && ((current_features.arrayZ[i].setting & ~1) != (current_features.arrayZ[j].setting & ~1)))) + current_features.arrayZ[++j] = current_features.arrayZ[i]; current_features.shrink (j + 1); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh index b02793a09..0252fa7df 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh @@ -286,7 +286,7 @@ HB_FUNCOBJ (hb_bool); // Compression function for Merkle-Damgard construction. // This function is generated using the framework provided. -#define mix(h) ( \ +#define fasthash_mix(h) ( \ (void) ((h) ^= (h) >> 23), \ (void) ((h) *= 0x2127599bf4325c37ULL), \ (h) ^= (h) >> 47) @@ -310,7 +310,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) #pragma GCC diagnostic ignored "-Wcast-align" v = * (const uint64_t *) (pos++); #pragma GCC diagnostic pop - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -320,7 +320,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) while (pos != end) { v = pos++->v; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -336,11 +336,11 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH; case 2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH; case 1: v ^= (uint64_t)pos2[0]; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } - return mix(h); + return fasthash_mix(h); } static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh index 9037179bc..6e458ffd8 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh @@ -251,7 +251,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + unsigned stop = start + (end - start) / 2; + for (unsigned lhs = start, rhs = end - 1; lhs < stop; lhs++, rhs--) hb_swap (arrayZ[rhs], arrayZ[lhs]); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh index 366fb32b7..121c463a5 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh @@ -212,6 +212,7 @@ struct hb_atomic_ptr_t T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } template <typename C> operator C * () const { return get_acquire (); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh index 869c67895..1941009f8 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh @@ -78,6 +78,28 @@ struct hb_vector_size_t hb_vector_size_t operator ~ () const { return process (hb_bitwise_neg); } + operator bool () const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i]) + return true; + return false; + } + operator unsigned int () const + { + unsigned int r = 0; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r += hb_popcount (v[i]); + return r; + } + bool operator == (const hb_vector_size_t &o) const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i] != o.v[i]) + return false; + return true; + } + hb_array_t<const elt_t> iter () const { return hb_array (v); } @@ -89,6 +111,8 @@ struct hb_vector_size_t struct hb_bit_page_t { + hb_bit_page_t () { init0 (); } + void init0 () { v.init0 (); population = 0; } void init1 () { v.init1 (); population = PAGE_BITS; } @@ -101,10 +125,9 @@ struct hb_bit_page_t bool is_empty () const { if (has_population ()) return !population; - return - + hb_iter (v) - | hb_none - ; + bool empty = !v; + if (empty) population = 0; + return empty; } uint32_t hash () const { @@ -115,6 +138,10 @@ struct hb_bit_page_t void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); } void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -220,13 +247,17 @@ struct hb_bit_page_t } bool operator == (const hb_bit_page_t &other) const { return is_equal (other); } - bool is_equal (const hb_bit_page_t &other) const + bool is_equal (const hb_bit_page_t &other) const { return v == other.v; } + bool intersects (const hb_bit_page_t &other) const { for (unsigned i = 0; i < len (); i++) - if (v[i] != other.v[i]) - return false; - return true; + if (v[i] & other.v[i]) + return true; + return false; } + bool may_intersect (const hb_bit_page_t &other) const + { return intersects (other); } + bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); } bool is_subset (const hb_bit_page_t &larger_page) const { @@ -241,14 +272,10 @@ struct hb_bit_page_t } bool has_population () const { return population != UINT_MAX; } - unsigned int get_population () const + unsigned get_population () const { if (has_population ()) return population; - population = - + hb_iter (v) - | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u) - ; - return population; + return population = v; } bool next (hb_codepoint_t *codepoint) const diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh index d5d1326d9..034772344 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh @@ -126,6 +126,7 @@ struct hb_bit_set_invertible_t { unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -139,6 +140,9 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_bit_set_invertible_t &other) const + { return inverted || other.inverted || s.intersects (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh index 5f4c6f0af..4607b884d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh @@ -88,10 +88,11 @@ struct hb_bit_set_t { if (unlikely (!successful)) return false; - if (pages.length == 0 && count == 1) + if (pages.length < count && count <= 2) exact_size = true; // Most sets are small and local - if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size))) + if (unlikely (!pages.resize (count, clear, exact_size) || + !page_map.resize (count, clear))) { pages.resize (page_map.length, clear, exact_size); successful = false; @@ -297,9 +298,9 @@ struct hb_bit_set_t unsigned int write_index = 0; for (unsigned int i = 0; i < page_map.length; i++) { - int m = (int) page_map[i].major; + int m = (int) page_map.arrayZ[i].major; if (m < ds || de < m) - page_map[write_index++] = page_map[i]; + page_map.arrayZ[write_index++] = page_map.arrayZ[i]; } compact (compact_workspace, write_index); resize (write_index); @@ -345,6 +346,7 @@ struct hb_bit_set_t return false; return page->get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -358,6 +360,31 @@ struct hb_bit_set_t hb_bit_set_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool intersects (const hb_bit_set_t &other) const + { + unsigned int na = pages.length; + unsigned int nb = other.pages.length; + + unsigned int a = 0, b = 0; + for (; a < na && b < nb; ) + { + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) + { + if (page_at (a).intersects (other.page_at (b))) + return true; + a++; + b++; + } + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) + a++; + else + b++; + } + return false; + } + bool may_intersect (const hb_bit_set_t &other) const + { return intersects (other); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -389,7 +416,7 @@ struct hb_bit_set_t { if (page_at (a).is_empty ()) { a++; continue; } if (other.page_at (b).is_empty ()) { b++; continue; } - if (page_map[a].major != other.page_map[b].major || + if (page_map.arrayZ[a].major != other.page_map.arrayZ[b].major || !page_at (a).is_equal (other.page_at (b))) return false; a++; @@ -412,8 +439,8 @@ struct hb_bit_set_t uint32_t spi = 0; for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++) { - uint32_t spm = page_map[spi].major; - uint32_t lpm = larger_set.page_map[lpi].major; + uint32_t spm = page_map.arrayZ[spi].major; + uint32_t lpm = larger_set.page_map.arrayZ[lpi].major; auto sp = page_at (spi); if (spm < lpm && !sp.is_empty ()) @@ -503,7 +530,7 @@ struct hb_bit_set_t for (; a < na && b < nb; ) { - if (page_map[a].major == other.page_map[b].major) + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) { if (!passthru_left) { @@ -512,7 +539,7 @@ struct hb_bit_set_t // passthru_left is set since no left side pages will be removed // in that case. if (write_index < a) - page_map[write_index] = page_map[a]; + page_map.arrayZ[write_index] = page_map.arrayZ[a]; write_index++; } @@ -520,7 +547,7 @@ struct hb_bit_set_t a++; b++; } - else if (page_map[a].major < other.page_map[b].major) + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) { if (passthru_left) count++; @@ -765,8 +792,8 @@ struct hb_bit_set_t unsigned int initial_size = size; for (unsigned int i = start_page; i < page_map.length && size; i++) { - uint32_t base = major_start (page_map[i].major); - unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size); + uint32_t base = major_start (page_map.arrayZ[i].major); + unsigned int n = pages[page_map.arrayZ[i].index].write (base, start_page_value, out, size); out += n; size -= n; start_page_value = 0; @@ -814,8 +841,8 @@ struct hb_bit_set_t hb_codepoint_t next_value = codepoint + 1; for (unsigned int i=start_page; i<page_map.length && size; i++) { - uint32_t base = major_start (page_map[i].major); - unsigned int n = pages[page_map[i].index].write_inverted (base, start_page_value, out, size, &next_value); + uint32_t base = major_start (page_map.arrayZ[i].major); + unsigned int n = pages[page_map.arrayZ[i].index].write_inverted (base, start_page_value, out, size, &next_value); out += n; size -= n; start_page_value = 0; @@ -846,8 +873,8 @@ struct hb_bit_set_t unsigned count = pages.length; for (unsigned i = 0; i < count; i++) { - const auto& map = page_map[i]; - const auto& page = pages[map.index]; + const auto& map = page_map.arrayZ[i]; + const auto& page = pages.arrayZ[map.index]; if (!page.is_empty ()) return map.major * page_t::PAGE_BITS + page.get_min (); @@ -859,8 +886,8 @@ struct hb_bit_set_t unsigned count = pages.length; for (signed i = count - 1; i >= 0; i--) { - const auto& map = page_map[(unsigned) i]; - const auto& page = pages[map.index]; + const auto& map = page_map.arrayZ[(unsigned) i]; + const auto& page = pages.arrayZ[map.index]; if (!page.is_empty ()) return map.major * page_t::PAGE_BITS + page.get_max (); @@ -961,7 +988,7 @@ struct hb_bit_set_t return nullptr; last_page_lookup = i; - return &pages.arrayZ[page_map[i].index]; + return &pages.arrayZ[page_map.arrayZ[i].index]; } page_t &page_at (unsigned int i) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh index 1deaaafd8..471bbb93f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh @@ -34,36 +34,36 @@ #line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 0u, 0u, 9u, 123u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, + 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 123u, 0u, 0u, 0 + 9u, 93u, 9u, 123u, 0u, 0u, 0 }; static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 21, 2, 1, 50, 49, - 10, 117, 117, 85, 117, 1, 50, 49, + 0, 115, 115, 26, 21, 2, 1, 50, + 49, 10, 117, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 2, 1, 50, 49, 10, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 1, 50, 49, 59, 117, 59, 117, 117, 1, 50, 49, 117, - 115, 0 + 85, 115, 0 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 165, 168, 170, 221, - 271, 282, 400, 518, 604, 722, 724, 775, - 825, 836, 954, 1072, 1074, 1076, 1127, 1177, - 1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648, - 1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118, - 2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560, - 2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137, - 3255, 3371 + 0, 0, 116, 232, 259, 281, 284, 286, + 337, 387, 398, 516, 634, 752, 754, 805, + 855, 866, 984, 1102, 1104, 1106, 1157, 1207, + 1325, 1443, 1446, 1448, 1499, 1549, 1560, 1678, + 1796, 1798, 1849, 1899, 1910, 2028, 2146, 2148, + 2150, 2201, 2251, 2369, 2487, 2489, 2540, 2590, + 2650, 2768, 2828, 2946, 3064, 3066, 3117, 3167, + 3285, 3371, 3487 }; static const char _deserialize_json_indicies[] = { @@ -77,51 +77,51 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 10, 1, 11, 12, - 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 14, 1, 14, 14, - 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 15, 1, 1, 16, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 1, - 18, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 20, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 21, 1, + 1, 1, 1, 1, 1, 1, 1, 3, + 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 5, 1, 6, 1, 7, 8, + 1, 9, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 12, 13, 1, 14, 1, 14, + 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 15, 1, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 22, - 1, 23, 23, 23, 23, 23, 1, 1, + 1, 15, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 16, 1, + 1, 17, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 1, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 1, 21, + 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -131,94 +131,99 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 24, 1, 25, - 25, 25, 25, 25, 1, 1, 1, 1, + 1, 1, 1, 23, 1, 24, 24, 24, + 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 25, 1, + 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 26, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 27, 1, 20, 20, 20, - 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 21, 1, 1, 1, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 22, 1, + 1, 1, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 22, 1, 28, 1, 28, 28, 28, - 28, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 29, 29, 29, 29, 29, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 23, + 1, 26, 1, 26, 26, 26, 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 30, 1, 1, 31, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 1, 33, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 35, 35, 35, - 35, 35, 1, 1, 1, 1, 1, 1, + 1, 1, 26, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 1, 1, 1, + 1, 1, 1, 1, 27, 1, 27, 27, + 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 36, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 28, 1, 1, 29, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 1, + 31, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 1, 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 36, 1, - 1, 1, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 35, + 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 33, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 34, 1, 1, 1, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 37, - 1, 38, 1, 39, 1, 39, 39, 39, - 39, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 40, 1, - 40, 40, 40, 40, 40, 1, 1, 1, + 1, 1, 1, 1, 1, 35, 1, 36, + 1, 37, 1, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 37, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 38, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 39, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 1, + 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 41, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 1, 43, 43, 43, 43, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 43, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -227,15 +232,14 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 41, 41, + 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 45, 1, - 43, 43, 43, 43, 43, 1, 1, 1, + 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 43, + 1, 42, 1, 1, 1, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 44, 1, 1, 1, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -243,26 +247,26 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 45, 1, 47, 48, - 1, 49, 1, 49, 49, 49, 49, 49, + 1, 1, 43, 1, 45, 46, 1, 47, + 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 1, 1, 1, 1, + 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 50, 50, - 50, 50, 50, 1, 1, 1, 1, 1, + 1, 1, 48, 1, 48, 48, 48, 48, + 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 50, 1, 1, + 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 52, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 1, - 54, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 56, 56, 56, 56, 56, + 49, 1, 1, 50, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 1, 52, 53, + 53, 53, 53, 53, 53, 53, 53, 53, + 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, + 54, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -272,14 +276,13 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 58, - 1, 56, 56, 56, 56, 56, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 54, + 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 56, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 57, 1, 1, 1, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 1, 1, 1, 1, 1, + 1, 1, 55, 1, 1, 1, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -287,119 +290,120 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 59, - 1, 59, 59, 59, 59, 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 56, 1, 57, 1, 57, + 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 57, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 58, 1, 58, 58, 58, 58, 58, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 58, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 59, 1, + 1, 60, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 1, 62, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 1, 64, + 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 60, 1, 60, 60, 60, 60, - 60, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 61, 1, 1, 62, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 1, 64, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 1, 66, 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 66, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 64, 64, 64, + 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 65, 1, 1, 1, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 68, 1, 66, - 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 67, 1, 1, 1, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 66, 1, 67, 1, 68, 1, 68, + 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 1, 69, 1, 70, - 1, 70, 70, 70, 70, 70, 1, 1, + 69, 1, 69, 69, 69, 69, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 70, 1, 1, 1, 1, 1, 1, 1, + 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 70, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 1, 72, 72, 72, 72, + 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 71, 1, 71, 71, 71, 71, - 71, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 72, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 1, 74, 74, - 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 72, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 73, 1, 1, + 1, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 76, 1, 74, 74, 74, 74, - 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 74, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 75, - 1, 1, 1, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 74, 1, + 76, 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 78, 1, 78, 78, 78, 78, - 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 1, 1, 1, + 1, 1, 1, 77, 1, 77, 77, 77, + 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 79, - 79, 79, 79, 79, 1, 1, 1, 1, + 1, 1, 1, 1, 79, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 1, 82, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 83, 81, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 79, 1, - 80, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 81, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 1, 84, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 85, 83, 86, 86, 86, - 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 86, 1, 1, 1, + 1, 1, 84, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -408,20 +412,21 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 86, + 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 88, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 81, 1, 87, 87, 87, + 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 83, 1, 89, - 89, 89, 89, 89, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 89, 1, + 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -430,97 +435,107 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 89, 1, 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 91, 1, 89, 89, 89, - 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 89, 1, 1, 1, + 1, 1, 87, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 88, 1, + 1, 1, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 90, 1, 1, 1, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 89, + 1, 91, 1, 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 91, 1, 93, 1, 93, 93, 93, - 93, 93, 1, 1, 1, 1, 1, 1, + 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 92, 1, 92, 92, + 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 94, 1, - 94, 94, 94, 94, 94, 1, 1, 1, + 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 94, + 1, 1, 1, 1, 1, 93, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 1, + 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 95, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 1, 89, 89, 89, 89, 89, 1, + 1, 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 88, 1, 1, 1, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 89, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 90, 1, 1, - 1, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 89, 1, 96, 96, + 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 91, 1, - 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, + 1, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 98, 1, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 1, 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, + 1, 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 19, 25, - 38, 44, 52, 5, 13, 6, 7, 8, - 9, 12, 9, 12, 10, 2, 11, 10, - 11, 11, 56, 57, 14, 15, 16, 17, - 18, 17, 18, 10, 2, 11, 20, 21, - 22, 23, 24, 10, 2, 11, 24, 26, - 32, 27, 28, 29, 30, 31, 30, 31, - 10, 2, 11, 33, 34, 35, 36, 37, - 36, 37, 10, 2, 11, 39, 40, 41, - 42, 43, 10, 2, 11, 43, 45, 46, - 47, 50, 51, 47, 48, 49, 10, 2, - 11, 10, 2, 11, 51, 53, 54, 50, - 55, 55 + 1, 0, 2, 3, 3, 4, 5, 19, + 25, 38, 44, 52, 6, 13, 7, 8, + 9, 10, 12, 10, 12, 11, 3, 56, + 11, 56, 14, 15, 16, 17, 18, 17, + 18, 11, 3, 56, 20, 21, 22, 23, + 24, 11, 3, 56, 24, 26, 32, 27, + 28, 29, 30, 31, 30, 31, 11, 3, + 56, 33, 34, 35, 36, 37, 36, 37, + 11, 3, 56, 39, 40, 41, 42, 43, + 11, 3, 56, 43, 45, 46, 47, 50, + 51, 47, 48, 49, 11, 3, 56, 11, + 3, 56, 51, 53, 54, 50, 55, 55, + 56, 57, 58 }; static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 0, 0, 3, 3, 4, 0, - 5, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 6, 6, 7, 0, 0, - 0, 2, 2, 8, 8, 9, 0, 0, - 0, 0, 0, 2, 2, 2, 0, 0, - 10, 10, 11, 0, 0, 2, 2, 2, - 0, 0, 12, 12, 13, 0, 0, 0, - 2, 2, 14, 14, 15, 0, 0, 0, - 2, 16, 16, 0, 17, 0, 18, 18, - 19, 20, 20, 21, 17, 0, 0, 22, - 22, 23 + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 0, 0, 3, 3, 4, + 0, 5, 0, 0, 2, 2, 2, 0, + 0, 6, 6, 7, 0, 0, 0, 2, + 2, 8, 8, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 10, 10, + 11, 0, 0, 2, 2, 2, 0, 0, + 12, 12, 13, 0, 0, 0, 2, 2, + 14, 14, 15, 0, 0, 0, 2, 16, + 16, 0, 17, 0, 18, 18, 19, 20, + 20, 21, 17, 0, 0, 22, 22, 23, + 0, 0, 0 }; static const int deserialize_json_start = 1; @@ -545,22 +560,17 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - *end_ptr = ++p; - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 559 "hb-buffer-deserialize-json.hh" +#line 569 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 564 "hb-buffer-deserialize-json.hh" +#line 574 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -772,7 +782,7 @@ _resume: *end_ptr = p; } break; -#line 776 "hb-buffer-deserialize-json.hh" +#line 786 "hb-buffer-deserialize-json.hh" } _again: @@ -784,7 +794,7 @@ _again: _out: {} } -#line 137 "hb-buffer-deserialize-json.rl" +#line 132 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl index b12dd0f1a..2f1ad9118 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl @@ -106,7 +106,7 @@ item = @add_item ; -main := space* item (comma item)* space* (','|']'); +main := space* '['? space* item (comma item)* space* (','|']')?; }%% @@ -122,11 +122,6 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - *end_ptr = ++p; - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index 3fc869887..d0c40664a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -860,7 +860,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the specified buffer. + * Attaches a user-data key/data pair to the specified buffer. * * Return value: `true` if success, `false` otherwise * @@ -1209,7 +1209,7 @@ hb_buffer_get_flags (const hb_buffer_t *buffer) * @cluster_level: The cluster level to set on the buffer * * Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t - * dictates one aspect of how HarfBuzz will treat non-base characters + * dictates one aspect of how HarfBuzz will treat non-base characters * during shaping. * * Since: 0.9.42 @@ -1229,7 +1229,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * * Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t - * dictates one aspect of how HarfBuzz will treat non-base characters + * dictates one aspect of how HarfBuzz will treat non-base characters * during shaping. * * Return value: The cluster level of @buffer @@ -1983,7 +1983,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @source: source #hb_buffer_t * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. - * @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer. + * @end: end index into source buffer to copy. Use @UINT_MAX (or ((unsigned int) -1)) to copy to end of buffer. * * Append (part of) contents of another buffer to this buffer. * diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh index 2a6ad6128..b353b06c7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh @@ -32,7 +32,6 @@ #include "hb.hh" #include "hb-unicode.hh" -#include "hb-set-digest.hh" static_assert ((sizeof (hb_glyph_info_t) == 20), ""); @@ -182,22 +181,24 @@ struct hb_buffer_t allocated_var_bits = 0; } + HB_ALWAYS_INLINE hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } + HB_ALWAYS_INLINE hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } - hb_set_digest_t digest () const - { - hb_set_digest_t d; - d.init (); - d.add_array (&info[0].codepoint, len, sizeof (info[0])); - return d; - } + template <typename set_t> + void collect_codepoints (set_t &d) const + { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh index 6ca7500af..b0491385f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh @@ -522,7 +522,7 @@ struct parsed_values_t void alloc (unsigned n) { - values.alloc (n, true); + values.alloc_exact (n); } void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ()) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh index 09f669567..40cc2403c 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh @@ -157,6 +157,7 @@ #define HB_NO_FALLBACK_SHAPE #define HB_NO_OT_KERN #define HB_NO_OT_LAYOUT_BLOCKLIST +#define HB_NO_AAT_LAYOUT_BLOCKLIST #define HB_NO_OT_SHAPE_FALLBACK #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc index 92194ea0a..b9726373d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc @@ -60,11 +60,25 @@ hb_coretext_get_nominal_glyph (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { CTFontRef ct_font = (CTFontRef) font_data; - UniChar ch = unicode; - CGGlyph cg_glyph; - if (CTFontGetGlyphsForCharacters (ct_font, &ch, &cg_glyph, 1)) + UniChar ch[2]; + CGGlyph cg_glyph[2]; + unsigned count = 0; + + if (unicode <= 0xFFFF) + { + ch[count++] = unicode; + } + else if (unicode <= 0x10FFFF) { - *glyph = cg_glyph; + ch[count++] = (unicode >> 10) + 0xD7C0; + ch[count++] = (unicode & 0x3FF) + 0xDC00; + } + else + ch[count++] = 0xFFFD; + + if (CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, count)) + { + *glyph = cg_glyph[0]; return true; } return false; @@ -80,6 +94,31 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, unsigned int glyph_stride, void *user_data HB_UNUSED) { + // If any non-BMP codepoint is requested, use the slow path. + bool slow_path = false; + auto *unicode = first_unicode; + for (unsigned i = 0; i < count; i++) + { + if (*unicode > 0xFFFF) + { + slow_path = true; + break; + } + unicode = &StructAtOffset<const hb_codepoint_t> (unicode, unicode_stride); + } + + if (unlikely (slow_path)) + { + for (unsigned i = 0; i < count; i++) + { + if (!hb_coretext_get_nominal_glyph (font, font_data, *first_unicode, first_glyph, nullptr)) + return i; + first_unicode = &StructAtOffset<const hb_codepoint_t> (first_unicode, unicode_stride); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + return count; + } + CTFontRef ct_font = (CTFontRef) font_data; UniChar ch[MAX_GLYPHS]; @@ -92,7 +131,16 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, ch[j] = *first_unicode; first_unicode = &StructAtOffset<const hb_codepoint_t> (first_unicode, unicode_stride); } - CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, c); + if (unlikely (!CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, c))) + { + // Use slow path partially and return at first failure. + for (unsigned j = 0; j < c; j++) + { + if (!hb_coretext_get_nominal_glyph (font, font_data, ch[j], first_glyph, nullptr)) + return i + j; + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + } for (unsigned j = 0; j < c; j++) { *first_glyph = cg_glyph[j]; @@ -113,13 +161,38 @@ hb_coretext_get_variation_glyph (hb_font_t *font HB_UNUSED, { CTFontRef ct_font = (CTFontRef) font_data; - UniChar ch[2] = { unicode, variation_selector }; - CGGlyph cg_glyph[2]; + UniChar ch[4]; + CGGlyph cg_glyph[4]; + unsigned count = 0; + + // Add Unicode, then variation selector. Ugly, but works. + // + if (unicode <= 0xFFFF) + ch[count++] = unicode; + else if (unicode <= 0x10FFFF) + { + ch[count++] = (unicode >> 10) + 0xD7C0; + ch[count++] = (unicode & 0x3FF) + 0xDC00; + } + else + ch[count++] = 0xFFFD; - CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, 2); + if (variation_selector <= 0xFFFF) + ch[count++] = variation_selector; + else if (variation_selector <= 0x10FFFF) + { + ch[count++] = (variation_selector >> 10) + 0xD7C0; + ch[count++] = (variation_selector & 0x3FF) + 0xDC00; + } + else + ch[count++] = 0xFFFD; - if (cg_glyph[1]) - return false; + CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, count); + + // All except for first should be zero if we succeeded + for (unsigned i = 1; i < count; i++) + if (cg_glyph[i]) + return false; *glyph = cg_glyph[0]; return true; @@ -438,10 +511,6 @@ _hb_coretext_get_font_funcs () * created with hb_face_create(), and therefore was not * initially configured to use CoreText font functions. * - * An #hb_font_t object created with hb_coretext_font_create() - * is preconfigured for CoreText font functions and does not - * require this function to be used. - * * <note>Note: Internally, this function creates a CTFont. * </note> * @@ -452,7 +521,12 @@ hb_coretext_font_set_funcs (hb_font_t *font) { CTFontRef ct_font = hb_coretext_font_get_ct_font (font); if (unlikely (!ct_font)) + { + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); return; + } hb_font_set_funcs (font, _hb_coretext_get_font_funcs (), diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc index 73443796d..0bb235f6d 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc @@ -45,9 +45,6 @@ * Functions for using HarfBuzz with the CoreText fonts. **/ -/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ -#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f - static CTFontRef create_ct_font (CGFontRef cg_font, CGFloat font_size); static void @@ -384,9 +381,9 @@ hb_coretext_face_create_from_file_or_fail (const char *file_name, (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, index) : nullptr; if (unlikely (!ct_font_desc)) { - CFRelease (ct_font_desc_array); - CFRelease (url); - return nullptr; + CFRelease (ct_font_desc_array); + CFRelease (url); + return nullptr; } CFRelease (url); auto ct_font = ct_font_desc ? CTFontCreateWithFontDescriptor (ct_font_desc, 0, nullptr) : nullptr; @@ -400,6 +397,7 @@ hb_coretext_face_create_from_file_or_fail (const char *file_name, return nullptr; hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); if (unlikely (hb_face_is_immutable (face))) return nullptr; @@ -432,7 +430,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) if (unlikely (!face_data)) return nullptr; CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; - CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem); + CGFloat font_size = (CGFloat) (font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE); CTFontRef ct_font = create_ct_font (cg_font, font_size); if (unlikely (!ct_font)) @@ -451,11 +449,11 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) for (unsigned i = 0; i < font->num_coords; i++) { - if (font->coords[i] == 0.) continue; - hb_ot_var_axis_info_t info; unsigned int c = 1; hb_ot_var_get_axis_infos (font->face, i, &c, &info); + if (font->design_coords[i] == info.default_value) + continue; float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value); CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag); @@ -499,7 +497,7 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data) * CTFontRef. * * The created font uses the default font functions implemented - * navitely by HarfBuzz. If you want to use the CoreText font functions + * natively by HarfBuzz. If you want to use the CoreText font functions * instead (rarely needed), you can do so by calling * by hb_coretext_font_set_funcs(). * @@ -521,6 +519,36 @@ hb_coretext_font_create (CTFontRef ct_font) hb_font_set_ptem (font, CTFontGetSize (ct_font)); + /* Copy font variations */ + CFDictionaryRef variations = CTFontCopyVariation (ct_font); + if (variations) + { + hb_vector_t<hb_variation_t> vars; + hb_vector_t<CFTypeRef> keys; + hb_vector_t<CFTypeRef> values; + + CFIndex count = CFDictionaryGetCount (variations); + if (unlikely (!vars.alloc_exact (count) || !keys.resize_exact (count) || !values.resize_exact (count))) + goto done; + + // Fetch them one by one and collect in a vector of our own. + CFDictionaryGetKeysAndValues (variations, keys.arrayZ, values.arrayZ); + for (CFIndex i = 0; i < count; i++) + { + int tag; + float value; + CFNumberGetValue ((CFNumberRef) keys.arrayZ[i], kCFNumberIntType, &tag); + CFNumberGetValue ((CFNumberRef) values.arrayZ[i], kCFNumberFloatType, &value); + + hb_variation_t var = {tag, value}; + vars.push (var); + } + hb_font_set_variations (font, vars.arrayZ, vars.length); + +done: + CFRelease (variations); + } + /* Let there be dragons here... */ font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc index 6c90265d0..5b191262a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc @@ -29,6 +29,7 @@ #include "hb-shaper-impl.hh" #include <dwrite_1.h> +#include <dwrite_3.h> #include "hb-directwrite.h" @@ -275,6 +276,8 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font) void _hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) { + if (data != HB_SHAPER_DATA_SUCCEEDED) + ((IDWriteFont *) (const void *) data)->Release(); } @@ -839,7 +842,7 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * } static void -_hb_directwrite_font_release (void *data) +_hb_directwrite_face_release (void *data) { if (data) ((IDWriteFontFace *) data)->Release (); @@ -847,7 +850,7 @@ _hb_directwrite_font_release (void *data) /** * hb_directwrite_face_create: - * @font_face: a DirectWrite IDWriteFontFace object. + * @dw_face: a DirectWrite IDWriteFontFace object. * * Constructs a new face object from the specified DirectWrite IDWriteFontFace. * @@ -856,14 +859,32 @@ _hb_directwrite_font_release (void *data) * Since: 2.4.0 **/ hb_face_t * -hb_directwrite_face_create (IDWriteFontFace *font_face) +hb_directwrite_face_create (IDWriteFontFace *dw_face) { - if (font_face) - font_face->AddRef (); - return hb_face_create_for_tables (_hb_directwrite_reference_table, font_face, - _hb_directwrite_font_release); + if (dw_face) + dw_face->AddRef (); + return hb_face_create_for_tables (_hb_directwrite_reference_table, dw_face, + _hb_directwrite_face_release); } +/** +* hb_directwrite_face_get_dw_font_face: +* @face: a #hb_face_t object +* +* Gets the DirectWrite IDWriteFontFace associated with @face. +* +* Return value: DirectWrite IDWriteFontFace object corresponding to the given input +* +* Since: 10.4.0 +**/ +IDWriteFontFace * +hb_directwrite_face_get_dw_font_face (hb_face_t *face) +{ + return face->data.directwrite->fontFace; +} + +#ifndef HB_DISABLE_DEPRECATED + /** * hb_directwrite_face_get_font_face: * @face: a #hb_face_t object @@ -873,12 +894,90 @@ hb_directwrite_face_create (IDWriteFontFace *font_face) * Return value: DirectWrite IDWriteFontFace object corresponding to the given input * * Since: 2.5.0 +* Deprecated: 10.4.0: Use hb_directwrite_face_get_dw_font_face() instead **/ IDWriteFontFace * hb_directwrite_face_get_font_face (hb_face_t *face) { - return face->data.directwrite->fontFace; + return hb_directwrite_face_get_dw_font_face (face); +} + +#endif + +/** + * hb_directwrite_font_create: + * @dw_font: a DirectWrite IDWriteFont object. + * + * Constructs a new font object from the specified DirectWrite IDWriteFont. + * + * Return value: #hb_font_t object corresponding to the given input + * + * Since: 10.3.0 + **/ +hb_font_t * +hb_directwrite_font_create (IDWriteFont *dw_font) +{ + IDWriteFontFace *dw_face = nullptr; + IDWriteFontFace5 *dw_face5 = nullptr; + + if (FAILED (dw_font->CreateFontFace (&dw_face))) + return hb_font_get_empty (); + + hb_face_t *face = hb_directwrite_face_create (dw_face); + hb_font_t *font = hb_font_create (face); + hb_face_destroy (face); + + if (unlikely (hb_object_is_immutable (font))) + goto done; + + /* Copy font variations */ + if (SUCCEEDED (dw_face->QueryInterface (__uuidof (IDWriteFontFace5), (void**) &dw_face5))) + { + if (dw_face5->HasVariations ()) + { + hb_vector_t<DWRITE_FONT_AXIS_VALUE> values; + uint32_t count = dw_face5->GetFontAxisValueCount (); + if (likely (values.resize_exact (count)) && + SUCCEEDED (dw_face5->GetFontAxisValues (values.arrayZ, count))) + { + hb_vector_t<hb_variation_t> vars; + if (likely (vars.resize_exact (count))) + { + for (uint32_t i = 0; i < count; ++i) + { + hb_tag_t tag = values[i].axisTag; + float value = values[i].value; + vars[i] = {tag, value}; + } + hb_font_set_variations (font, vars.arrayZ, vars.length); + } + } + } + dw_face5->Release (); + } + + dw_font->AddRef (); + font->data.directwrite.cmpexch (nullptr, (hb_directwrite_font_data_t *) dw_font); + +done: + dw_face->Release (); + return font; } +/** +* hb_directwrite_font_get_dw_font: +* @font: a #hb_font_t object +* +* Gets the DirectWrite IDWriteFont associated with @font. +* +* Return value: DirectWrite IDWriteFont object corresponding to the given input +* +* Since: 10.3.0 +**/ +IDWriteFont * +hb_directwrite_font_get_dw_font (hb_font_t *font) +{ + return (IDWriteFont *) (const void *) font->data.directwrite; +} #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h index f837627a2..121569c15 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h @@ -30,11 +30,25 @@ HB_BEGIN_DECLS HB_EXTERN hb_face_t * -hb_directwrite_face_create (IDWriteFontFace *font_face); +hb_directwrite_face_create (IDWriteFontFace *dw_face); +HB_EXTERN IDWriteFontFace * +hb_directwrite_face_get_dw_font_face (hb_face_t *face); + +HB_EXTERN hb_font_t * +hb_directwrite_font_create (IDWriteFont *dw_font); + +HB_EXTERN IDWriteFont * +hb_directwrite_font_get_dw_font (hb_font_t *font); + +#ifndef HB_DISABLE_DEPRECATED + +HB_DEPRECATED_FOR (hb_directwrite_face_get_dw_font_face) HB_EXTERN IDWriteFontFace * hb_directwrite_face_get_font_face (hb_face_t *face); +#endif + HB_END_DECLS #endif /* HB_DIRECTWRITE_H */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index c7dbf7966..002bb37d4 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -291,6 +291,7 @@ hb_face_create_or_fail (hb_blob_t *blob, return face; } +#ifndef HB_NO_OPEN /** * hb_face_create_from_file_or_fail: * @file_name: A font filename @@ -317,6 +318,7 @@ hb_face_create_from_file_or_fail (const char *file_name, return face; } +#endif /** * hb_face_get_empty: @@ -491,9 +493,10 @@ hb_face_reference_table (const hb_face_t *face, * hb_face_reference_blob: * @face: A face object * - * Fetches a pointer to the binary blob that contains the - * specified face. Returns an empty blob if referencing face data is not - * possible. + * Fetches a pointer to the binary blob that contains the specified face. + * If referencing the face data is not possible, this function creates a blob + * out of individual table blobs if hb_face_get_table_tags() works with this + * face, otherwise it returns an empty blob. * * Return value: (transfer full): A pointer to the blob for @face * @@ -502,7 +505,41 @@ hb_face_reference_table (const hb_face_t *face, hb_blob_t * hb_face_reference_blob (hb_face_t *face) { - return face->reference_table (HB_TAG_NONE); + hb_blob_t *blob = face->reference_table (HB_TAG_NONE); + + if (blob == hb_blob_get_empty ()) + { + // If referencing the face blob is not possible (e.g. not implemented by the + // font functions), use face builder to create a blob out of individual + // table blobs. + unsigned total_count = hb_face_get_table_tags (face, 0, nullptr, nullptr); + if (total_count) + { + hb_tag_t tags[64]; + unsigned count = ARRAY_LENGTH (tags); + hb_face_t* builder = hb_face_builder_create (); + + for (unsigned offset = 0; offset < total_count; offset += count) + { + hb_face_get_table_tags (face, offset, &count, tags); + if (unlikely (!count)) + break; // Allocation error + for (unsigned i = 0; i < count; i++) + { + if (unlikely (!tags[i])) + continue; + hb_blob_t *table = hb_face_reference_table (face, tags[i]); + hb_face_builder_add_table (builder, tags[i], table); + hb_blob_destroy (table); + } + } + + blob = hb_face_reference_blob (builder); + hb_face_destroy (builder); + } + } + + return blob; } /** @@ -644,6 +681,7 @@ hb_face_set_get_table_tags_func (hb_face_t *face, { if (destroy) destroy (user_data); + return; } if (face->get_table_tags_destroy) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h index 8aec681cf..afc198547 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h @@ -73,9 +73,14 @@ hb_face_create_from_file_or_fail (const char *file_name, * @tag: the tag of the table to reference * @user_data: User data pointer passed by the caller * - * Callback function for hb_face_create_for_tables(). + * Callback function for hb_face_create_for_tables(). The @tag is the tag of the + * table to reference, and the special tag #HB_TAG_NONE is used to reference the + * blob of the face itself. If referencing the face blob is not possible, it is + * recommended to set hb_get_table_tags_func_t on the @face to allow + * hb_face_reference_blob() to create a face blob out of individual table blobs. * - * Return value: (transfer full): A pointer to the @tag table within @face + * Return value: (transfer full): A pointer to the @tag table within @face or + * `NULL` if the table is not found or cannot be referenced. * * Since: 0.9.2 */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh index 7d8ed4a6f..c96698369 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh @@ -27,6 +27,7 @@ #include "hb.hh" +#include "hb-decycler.hh" #include "hb-paint-extents.hh" #include FT_COLOR_H @@ -105,8 +106,8 @@ struct hb_ft_paint_context_t FT_Color *palette; unsigned palette_index; hb_color_t foreground; - hb_map_t current_glyphs; - hb_map_t current_layers; + hb_decycler_t glyphs_decycler; + hb_decycler_t layers_decycler; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_MAX_GRAPH_EDGE_COUNT; }; @@ -218,22 +219,19 @@ _hb_ft_paint (hb_ft_paint_context_t *c, case FT_COLR_PAINTFORMAT_COLR_LAYERS: { FT_OpaquePaint other_paint = {0}; + hb_decycler_node_t node (c->layers_decycler); while (FT_Get_Paint_Layers (ft_face, &paint.u.colr_layers.layer_iterator, &other_paint)) { - unsigned i = paint.u.colr_layers.layer_iterator.layer; - - if (unlikely (c->current_layers.has (i))) + // FreeType doesn't provide a way to get the layer index, so we use the pointer + // for cycle detection. + if (unlikely (!node.visit ((uintptr_t) other_paint.p))) continue; - c->current_layers.add (i); - c->funcs->push_group (c->data); c->recurse (other_paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); - - c->current_layers.del (i); } } break; @@ -333,18 +331,16 @@ _hb_ft_paint (hb_ft_paint_context_t *c, { hb_codepoint_t gid = paint.u.colr_glyph.glyphID; - if (unlikely (c->current_glyphs.has (gid))) + hb_decycler_node_t node (c->glyphs_decycler); + if (unlikely (!node.visit (gid))) return; - c->current_glyphs.add (gid); - c->funcs->push_inverse_root_transform (c->data, c->font); c->ft_font->lock.unlock (); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->ft_font->lock.lock (); c->funcs->pop_transform (c->data); - c->current_glyphs.del (gid); return; } c->ft_font->lock.lock (); @@ -380,8 +376,6 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (has_clip_box) c->funcs->pop_clip (c->data); - - c->current_glyphs.del (gid); } } break; @@ -506,7 +500,8 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t c (ft_font, font, paint_funcs, paint_data, palette, palette_index, foreground); - c.current_glyphs.add (gid); + hb_decycler_node_t node (c.glyphs_decycler); + node.visit (gid); bool is_bounded = true; FT_ClipBox clip_box; @@ -530,7 +525,8 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t ce (ft_font, font, extents_funcs, &extents_data, palette, palette_index, foreground); - ce.current_glyphs.add (gid); + hb_decycler_node_t node2 (ce.glyphs_decycler); + node2.visit (gid); ce.funcs->push_root_transform (ce.data, font); ce.recurse (paint); ce.funcs->pop_transform (ce.data); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index 7e65277d1..efb4b7d24 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -37,7 +37,11 @@ #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" +#ifndef HB_NO_AAT +#include "hb-aat-layout-trak-table.hh" +#endif #include "hb-ot-os2-table.hh" +#include "hb-ot-stat-table.hh" #include "hb-ot-shaper-arabic-pua.hh" #include "hb-paint.hh" @@ -275,7 +279,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) } /** - * hb_ft_font_get_face: (skip) + * hb_ft_font_get_ft_face: (skip) * @font: #hb_font_t to work upon * * Fetches the FT_Face associated with the specified #hb_font_t @@ -286,10 +290,10 @@ hb_ft_font_get_load_flags (hb_font_t *font) * * Return value: (nullable): the FT_Face found or `NULL` * - * Since: 0.9.2 + * Since: 10.4.0 **/ FT_Face -hb_ft_font_get_face (hb_font_t *font) +hb_ft_font_get_ft_face (hb_font_t *font) { if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return nullptr; @@ -299,6 +303,31 @@ hb_ft_font_get_face (hb_font_t *font) return ft_font->ft_face; } +#ifndef HB_DISABLE_DEPRECATED + +/** + * hb_ft_font_get_face: (skip) + * @font: #hb_font_t to work upon + * + * Fetches the FT_Face associated with the specified #hb_font_t + * font object. + * + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: (nullable): the FT_Face found or `NULL` + * + * Since: 0.9.2 + * Deprecated: 10.4.0: Use hb_ft_font_get_ft_face() instead. + **/ +FT_Face +hb_ft_font_get_face (hb_font_t *font) +{ + return hb_ft_font_get_ft_face (font); +} + +#endif + /** * hb_ft_font_lock_face: (skip) * @font: #hb_font_t to work upon @@ -502,6 +531,26 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + bool apply_trak = false; +#endif + if (apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_h_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); + } + } +#endif } #ifndef HB_NO_VERTICAL @@ -538,7 +587,20 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, * have a Y growing upward. Hence the extra negation. */ hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + v = ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + bool apply_trak = false; +#endif + if (apply_trak) + v += font->face->table.trak->get_v_tracking (font); +#endif + + return v; } #endif @@ -1290,7 +1352,7 @@ hb_ft_face_create_cached (FT_Face ft_face) * * If you know you have valid reasons not to use hb_ft_font_create_referenced(), * then it is the client program's responsibility to destroy @ft_face - * after the #hb_font_t font object has been destroyed. + * only after the #hb_font_t font object has been destroyed. * * HarfBuzz will use the @destroy callback on the #hb_font_t font object * if it is supplied when you use this function. However, even if @destroy @@ -1598,6 +1660,11 @@ _release_blob (void *arg) void hb_ft_font_set_funcs (hb_font_t *font) { + // In case of failure... + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); + hb_blob_t *blob = hb_face_reference_blob (font->face); unsigned int blob_length; const char *blob_data = hb_blob_get_data (blob, &blob_length); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h index 8cf14dc39..42bfb4f46 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h @@ -111,7 +111,7 @@ HB_EXTERN hb_font_t * hb_ft_font_create_referenced (FT_Face ft_face); HB_EXTERN FT_Face -hb_ft_font_get_face (hb_font_t *font); +hb_ft_font_get_ft_face (hb_font_t *font); HB_EXTERN FT_Face hb_ft_font_lock_face (hb_font_t *font); @@ -142,6 +142,13 @@ hb_ft_hb_font_changed (hb_font_t *font); HB_EXTERN void hb_ft_font_set_funcs (hb_font_t *font); +#ifndef HB_DISABLE_DEPRECATED + +HB_DEPRECATED_FOR (hb_ft_font_get_ft_face) +HB_EXTERN FT_Face +hb_ft_font_get_face (hb_font_t *font); + +#endif HB_END_DECLS diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh index 7777ff9ac..2f7fcb328 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-geometry.hh @@ -83,6 +83,13 @@ struct hb_transform_t float x0, float y0) : xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} + bool is_identity () const + { + return xx == 1.f && yx == 0.f && + xy == 0.f && yy == 1.f && + x0 == 0.f && y0 == 0.f; + } + void multiply (const hb_transform_t &o) { /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ @@ -201,6 +208,8 @@ struct hb_transform_t float y0 = 0.f; }; +#define HB_TRANSFORM_IDENTITY hb_transform_t{1.f, 0.f, 0.f, 1.f, 0.f, 0.f} + struct hb_bounds_t { enum status_t { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh index 6655259b7..7437fddfa 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh @@ -86,21 +86,12 @@ struct IntType return pb->cmp (*pa); } - template <typename Type2, - hb_enable_if (std::is_integral<Type2>::value && - sizeof (Type2) < sizeof (int) && - sizeof (Type) < sizeof (int))> - int cmp (Type2 a) const - { - Type b = v; - return (int) a - (int) b; - } template <typename Type2, hb_enable_if (hb_is_convertible (Type2, Type))> int cmp (Type2 a) const { Type b = v; - return a < b ? -1 : a == b ? 0 : +1; + return (a > b) - (a < b); } bool sanitize (hb_sanitize_context_t *c) const { @@ -299,11 +290,6 @@ typedef Index NameID; struct VarIdx : HBUINT32 { static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, ""); - static uint32_t add (uint32_t i, unsigned short v) - { - if (i == NO_VARIATION) return i; - return i + v; - } VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } }; DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); @@ -1747,6 +1733,19 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) { if (unlikely (p + run_count * HBINT16::static_size > end)) return false; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 1] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 2] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 3] = * (const HBINT16 *) p; + p += HBINT16::static_size; + } +#endif for (; i < stop; i++) { values.arrayZ[i] = * (const HBINT16 *) p; @@ -1765,10 +1764,17 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) { if (unlikely (p + run_count > end)) return false; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT8 *) p++; + values.arrayZ[i + 1] = * (const HBINT8 *) p++; + values.arrayZ[i + 2] = * (const HBINT8 *) p++; + values.arrayZ[i + 3] = * (const HBINT8 *) p++; + } +#endif for (; i < stop; i++) - { values.arrayZ[i] = * (const HBINT8 *) p++; - } } } return true; @@ -1777,12 +1783,12 @@ struct TupleValues struct iter_t : hb_iter_with_fallback_t<iter_t, int> { iter_t (const unsigned char *p_, unsigned len_) - : p (p_), end (p_ + len_) + : p (p_), endp (p_ + len_) { if (ensure_run ()) read_value (); } private: const unsigned char *p; - const unsigned char * const end; + const unsigned char * const endp; int current_value = 0; signed run_count = 0; unsigned width = 0; @@ -1791,7 +1797,7 @@ struct TupleValues { if (likely (run_count > 0)) return true; - if (unlikely (p >= end)) + if (unlikely (p >= endp)) { run_count = 0; current_value = 0; @@ -1810,7 +1816,7 @@ struct TupleValues default: assert (false); } - if (unlikely (p + run_count * width > end)) + if (unlikely (p + run_count * width > endp)) { run_count = 0; current_value = 0; @@ -1837,7 +1843,7 @@ struct TupleValues __item_t__ __item__ () const { return current_value; } - bool __more__ () const { return run_count || p < end; } + bool __more__ () const { return run_count || p < endp; } void __next__ () { run_count--; @@ -1864,10 +1870,146 @@ struct TupleValues { return p != o.p || run_count != o.run_count; } iter_t __end__ () const { - iter_t it (end, 0); + iter_t it (endp, 0); return it; } }; + + struct fetcher_t + { + fetcher_t (const unsigned char *p_, unsigned len_) + : p (p_), end (p_ + len_) {} + + private: + const unsigned char *p; + const unsigned char * const end; + signed run_count = 0; + unsigned width = 0; + + bool ensure_run () + { + if (likely (run_count > 0)) return true; + + if (unlikely (p >= end)) + { + run_count = 0; + return false; + } + + unsigned control = *p++; + run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + width = control & VALUES_SIZE_MASK; + switch (width) + { + case VALUES_ARE_ZEROS: width = 0; break; + case VALUES_ARE_BYTES: width = HBINT8::static_size; break; + case VALUES_ARE_WORDS: width = HBINT16::static_size; break; + case VALUES_ARE_LONGS: width = HBINT32::static_size; break; + default: assert (false); + } + + if (unlikely (p + run_count * width > end)) + { + run_count = 0; + return false; + } + + return true; + } + + void skip (unsigned n) + { + while (n) + { + if (unlikely (!ensure_run ())) + return; + unsigned i = hb_min (n, (unsigned) run_count); + run_count -= i; + n -= i; + p += i * width; + } + } + + template <bool scaled> + void _add_to (hb_array_t<float> out, float scale = 1.0f) + { + unsigned n = out.length; + float *arrayZ = out.arrayZ; + + for (unsigned i = 0; i < n;) + { + if (unlikely (!ensure_run ())) + break; + unsigned count = hb_min (n - i, (unsigned) run_count); + switch (width) + { + case 1: + { + const auto *pp = (const HBINT8 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + case 2: + { + const auto *pp = (const HBINT16 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + case 4: + { + const auto *pp = (const HBINT32 *) p; + for (unsigned j = 0; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + } + p += count * width; + run_count -= count; + i += count; + } + } + + public: + void add_to (hb_array_t<float> out, float scale = 1.0f) + { + unsigned n = out.length; + + if (scale == 0.0f) + { + skip (n); + return; + } + +#ifndef HB_OPTIMIZE_SIZE + if (scale == 1.0f) + _add_to<false> (out); + else +#endif + _add_to<true> (out, scale); + } + }; }; struct TupleList : CFF2Index @@ -1877,6 +2019,12 @@ struct TupleList : CFF2Index auto bytes = CFF2Index::operator [] (i); return TupleValues::iter_t (bytes.arrayZ, bytes.length); } + + TupleValues::fetcher_t fetcher (unsigned i) const + { + auto bytes = CFF2Index::operator [] (i); + return TupleValues::fetcher_t (bytes.arrayZ, bytes.length); + } }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc index 66df28aae..8b666a3d0 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc @@ -553,15 +553,6 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin return true; } -bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const { #ifdef HB_NO_OT_FONT_CFF diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh index b84d896e3..666efeb92 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh @@ -1462,7 +1462,6 @@ struct cff1 } HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; private: diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc index e42217b4e..57023cb91 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc @@ -143,15 +143,6 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, return true; } -bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - struct cff2_path_param_t { cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh index c52c0511c..0074d5bd8 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh @@ -518,7 +518,6 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t<const int> coords) const; }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh index dd4befffa..97825f4d1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh @@ -95,9 +95,12 @@ HB_OT_CORE_TABLE (OT, fvar) HB_OT_CORE_TABLE (OT, avar) HB_OT_CORE_TABLE (OT, cvar) HB_OT_ACCELERATOR (OT, gvar) +#ifndef HB_NO_BEYOND_64K +HB_OT_ACCELERATOR (OT, GVAR) +#endif HB_OT_CORE_TABLE (OT, MVAR) #ifndef HB_NO_VAR_COMPOSITES -HB_OT_CORE_TABLE (OT, VARC) +HB_OT_ACCELERATOR (OT, VARC) #endif #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc index b0c927979..1cf14f3eb 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc @@ -41,6 +41,7 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-var-varc-table.hh" #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index 7b4724710..edfece170 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -36,13 +36,16 @@ #include "hb-ot-face.hh" #include "hb-outline.hh" +#ifndef HB_NO_AAT +#include "hb-aat-layout-trak-table.hh" +#endif #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-stat-table.hh" #include "hb-ot-var-varc-table.hh" #include "hb-ot-vorg-table.hh" #include "OT/Color/CBDT/CBDT.hh" @@ -73,6 +76,10 @@ struct hb_ot_font_t { const hb_ot_face_t *ot_face; +#ifndef HB_NO_AAT + bool apply_trak; +#endif + #ifndef HB_NO_OT_FONT_CMAP_CACHE hb_ot_font_cmap_cache_t *cmap_cache; #endif @@ -91,6 +98,15 @@ _hb_ot_font_create (hb_font_t *font) ot_font->ot_face = &font->face->table; +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + ot_font->apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + ot_font->apply_trak = false; +#endif +#endif + #ifndef HB_NO_OT_FONT_CMAP_CACHE // retry: auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face, @@ -200,7 +216,6 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; @@ -292,6 +307,20 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + if (ot_font->apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_h_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); + } + } +#endif } #ifndef HB_NO_VERTICAL @@ -356,6 +385,20 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + if (ot_font->apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_v_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); + } + } +#endif } #endif @@ -568,14 +611,11 @@ hb_ot_paint_glyph (hb_font_t *font, if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #endif #endif -#ifndef HB_NO_VAR_COMPOSITES - if (font->face->table.VARC->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#endif - if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#ifndef HB_NO_CFF - if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; - if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#endif + + // Outline glyph + paint_funcs->push_clip_glyph (paint_data, glyph, font); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); } #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh index 8582dbe27..5c187ebbb 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh @@ -95,7 +95,7 @@ struct hdmx bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it, - const hb_vector_t<hb_codepoint_pair_t> &new_to_old_gid_list, + hb_array_t<const hb_codepoint_pair_t> new_to_old_gid_list, unsigned num_glyphs) { TRACE_SERIALIZE (this); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index 493bc6e7a..8e44f143b 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh @@ -182,7 +182,7 @@ struct hmtxvmtx hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, Iterator it, - const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list, + hb_array_t<const hb_codepoint_pair_t> new_to_old_gid_list, unsigned num_long_metrics, unsigned total_num_metrics) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index 2abda78af..d11a913c7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh @@ -342,7 +342,7 @@ struct kern } bool apply (AAT::hb_aat_apply_context_t *c, - const AAT::kern_accelerator_data_t *accel_data = nullptr) const + const AAT::kern_accelerator_data_t &accel_data) const { return dispatch (c, accel_data); } template <typename context_t, typename ...Ts> @@ -395,7 +395,7 @@ struct kern bool apply (AAT::hb_aat_apply_context_t *c) const { - return table->apply (c, &accel_data); + return table->apply (c, accel_data); } hb_blob_ptr_t<kern> table; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh index 68a4e7cba..d98ad6012 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh @@ -460,7 +460,7 @@ struct BaseScript { return (this+baseValues).get_base_coord (baseline_tag_index); } bool has_values () const { return baseValues; } - bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } + bool has_min_max () const { return defaultMinMax || baseLangSysRecords; } void collect_variation_indices (const hb_subset_plan_t* plan, hb_set_t& varidx_set /* OUT */) const diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index 757b05031..f9a5c1b9c 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -34,6 +34,7 @@ #include "hb-open-type.hh" #include "hb-set.hh" #include "hb-bimap.hh" +#include "hb-cache.hh" #include "OT/Layout/Common/Coverage.hh" #include "OT/Layout/types.hh" @@ -2076,6 +2077,15 @@ struct ClassDef default:return 0; } } + unsigned int get_class (hb_codepoint_t glyph_id, + hb_ot_lookup_cache_t *cache) const + { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; + klass = get_class (glyph_id); + if (cache) cache->set (glyph_id, klass); + return klass; + } unsigned get_population () const { @@ -3137,23 +3147,14 @@ struct MultiVarData { auto &deltaSets = StructAfter<decltype (deltaSetsX)> (regionIndices); - auto values_iter = deltaSets[inner]; - + auto values_iter = deltaSets.fetcher (inner); unsigned regionCount = regionIndices.len; - unsigned count = out.length; for (unsigned regionIndex = 0; regionIndex < regionCount; regionIndex++) { float scalar = regions.evaluate (regionIndices.arrayZ[regionIndex], coords, coord_count, cache); - if (scalar == 1.f) - for (unsigned i = 0; i < count; i++) - out.arrayZ[i] += *values_iter++; - else if (scalar) - for (unsigned i = 0; i < count; i++) - out.arrayZ[i] += *values_iter++ * scalar; - else - values_iter += count; + values_iter.add_to (out, scalar); } } @@ -3439,7 +3440,7 @@ struct MultiItemVariationStore { using cache_t = SparseVarRegionList::cache_t; - cache_t *create_cache () const + cache_t *create_cache (hb_array_t<float> static_cache = hb_array_t<float> ()) const { #ifdef HB_NO_VAR return nullptr; @@ -3447,8 +3448,14 @@ struct MultiItemVariationStore auto &r = this+regions; unsigned count = r.regions.len; - float *cache = (float *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; + float *cache; + if (count <= static_cache.length) + cache = static_cache.arrayZ; + else + { + cache = (float *) hb_malloc (sizeof (float) * count); + if (unlikely (!cache)) return nullptr; + } for (unsigned i = 0; i < count; i++) cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; @@ -3456,7 +3463,12 @@ struct MultiItemVariationStore return cache; } - static void destroy_cache (cache_t *cache) { hb_free (cache); } + static void destroy_cache (cache_t *cache, + hb_array_t<float> static_cache = hb_array_t<float> ()) + { + if (cache != static_cache.arrayZ) + hb_free (cache); + } private: void get_delta (unsigned int outer, unsigned int inner, @@ -3731,11 +3743,13 @@ struct ItemVarStoreInstancer float operator() (uint32_t varIdx, unsigned short offset = 0) const { + if (!coords || varIdx == VarIdx::NO_VARIATION) + return 0.f; + + varIdx += offset; if (varIdxMap) - varIdx = varIdxMap->map (VarIdx::add (varIdx, offset)); - else - varIdx += offset; - return coords ? varStore->get_delta (varIdx, coords, cache) : 0.f; + varIdx = varIdxMap->map (varIdx); + return varStore->get_delta (varIdx, coords, cache); } const ItemVariationStore *varStore; @@ -3767,12 +3781,11 @@ struct MultiItemVarStoreInstancer void operator() (hb_array_t<float> out, uint32_t varIdx, unsigned short offset = 0) const { - if (coords) + if (coords && varIdx != VarIdx::NO_VARIATION) { + varIdx += offset; if (varIdxMap) - varIdx = varIdxMap->map (VarIdx::add (varIdx, offset)); - else - varIdx += offset; + varIdx = varIdxMap->map (varIdx); varStore->get_delta (varIdx, coords, out, cache); } else @@ -3890,8 +3903,8 @@ struct ConditionAxisRange { // add axisIndex->value into the hashmap so we can check if the record is // unique with variations - int16_t int_filter_max_val = filterRangeMaxValue.to_int (); - int16_t int_filter_min_val = filterRangeMinValue.to_int (); + uint16_t int_filter_max_val = (uint16_t) filterRangeMaxValue.to_int (); + uint16_t int_filter_min_val = (uint16_t) filterRangeMinValue.to_int (); hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val; condition_map->set (axisIndex, val); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index 966fa06c1..183e08ccc 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -713,6 +713,7 @@ struct hb_ot_apply_context_t : recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; + const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; const ItemVariationStore &var_store; ItemVariationStore::cache_t *var_store_cache; hb_set_digest_t digest; @@ -762,10 +763,12 @@ struct hb_ot_apply_context_t : nullptr #endif ), - digest (buffer_->digest ()), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) - { init_iters (); } + { + init_iters (); + buffer->collect_codepoints (digest); + } ~hb_ot_apply_context_t () { @@ -899,6 +902,13 @@ struct hb_ot_apply_context_t : } }; +enum class hb_ot_lookup_cache_op_t +{ + CREATE, + ENTER, + LEAVE, + DESTROY, +}; struct hb_accelerate_subtables_context_t : hb_dispatch_context_t<hb_accelerate_subtables_context_t> @@ -923,19 +933,23 @@ struct hb_accelerate_subtables_context_t : } template <typename T> - static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) - template <typename T> - static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } + static inline auto cache_func_ (void *p, + hb_ot_lookup_cache_op_t op, + hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) ) + template <typename T=void> + static inline void * cache_func_ (void *p, + hb_ot_lookup_cache_op_t op HB_UNUSED, + hb_priority<0>) { return (void *) false; } template <typename Type> - static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter) + static inline void * cache_func_to (void *p, + hb_ot_lookup_cache_op_t op) { - const Type *typed_obj = (const Type *) obj; - return cache_func_ (typed_obj, c, enter, hb_prioritize); + return cache_func_<Type> (p, op, hb_prioritize); } #endif typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); - typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter); + typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op); struct hb_applicable_t { @@ -972,11 +986,11 @@ struct hb_accelerate_subtables_context_t : } bool cache_enter (hb_ot_apply_context_t *c) const { - return cache_func (obj, c, true); + return (bool) cache_func (c, hb_ot_lookup_cache_op_t::ENTER); } void cache_leave (hb_ot_apply_context_t *c) const { - cache_func (obj, c, false); + cache_func (c, hb_ot_lookup_cache_op_t::LEAVE); } #endif @@ -2623,25 +2637,35 @@ struct ContextFormat2_5 unsigned c = (this+classDef).cost () * ruleSet.len; return c >= 4 ? c : 0; } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) { - if (enter) + switch (op) { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else - { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + case hb_ot_lookup_cache_op_t::CREATE: + return (void *) true; + case hb_ot_lookup_cache_op_t::ENTER: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return (void *) false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return (void *) true; + } + case hb_ot_lookup_cache_op_t::LEAVE: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return nullptr; + } + case hb_ot_lookup_cache_op_t::DESTROY: + return nullptr; } + return nullptr; } bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } @@ -2650,7 +2674,7 @@ struct ContextFormat2_5 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ClassDef &class_def = this+classDef; @@ -2836,7 +2860,7 @@ struct ContextFormat3 { TRACE_APPLY (this); unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); struct ContextApplyLookupContext lookup_context = { @@ -3650,7 +3674,7 @@ struct ChainContextFormat1_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { @@ -3861,28 +3885,37 @@ struct ChainContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+lookaheadClassDef).cost () * ruleSet.len; } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) { - if (enter) + switch (op) { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else - { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + case hb_ot_lookup_cache_op_t::CREATE: + return (void *) true; + case hb_ot_lookup_cache_op_t::ENTER: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return (void *) false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return (void *) true; + } + case hb_ot_lookup_cache_op_t::LEAVE: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return nullptr; + } + case hb_ot_lookup_cache_op_t::DESTROY: + return nullptr; } + return nullptr; } bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } @@ -3891,7 +3924,7 @@ struct ChainContextFormat2_5 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -4137,7 +4170,7 @@ struct ChainContextFormat3 const auto &input = StructAfter<decltype (inputX)> (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); @@ -4408,7 +4441,18 @@ struct hb_ot_layout_lookup_accelerator_t thiz->digest.union_ (subtable.digest); #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (c_accelerate_subtables.cache_user_cost < 4) + c_accelerate_subtables.cache_user_idx = (unsigned) -1; + thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; + + if (thiz->cache_user_idx != (unsigned) -1) + { + thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE); + if (!thiz->cache) + thiz->cache_user_idx = (unsigned) -1; + } + for (unsigned i = 0; i < count; i++) if (i != thiz->cache_user_idx) thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; @@ -4417,6 +4461,17 @@ struct hb_ot_layout_lookup_accelerator_t return thiz; } + void fini () + { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (cache) + { + assert (cache_user_idx != (unsigned) -1); + subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY); + } +#endif + } + bool may_have (hb_codepoint_t g) const { return digest.may_have (g); } @@ -4425,6 +4480,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const { + c->lookup_accel = this; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { @@ -4464,10 +4520,13 @@ struct hb_ot_layout_lookup_accelerator_t hb_set_digest_t digest; - private: #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + public: + void *cache = nullptr; + private: unsigned cache_user_idx = (unsigned) -1; #endif + private: hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; @@ -4852,7 +4911,12 @@ struct GSUBGPOS ~accelerator_t () { for (unsigned int i = 0; i < this->lookup_count; i++) - hb_free (this->accels[i]); + { + auto *accel = this->accels[i].get_relaxed (); + if (accel) + accel->fini (); + hb_free (accel); + } hb_free (this->accels); this->table.destroy (); } @@ -4873,6 +4937,7 @@ struct GSUBGPOS if (unlikely (!accels[lookup_index].cmpexch (nullptr, accel))) { + accel->fini (); hb_free (accel); goto retry; } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index d26f094ba..f7ad72fd4 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -1923,9 +1923,10 @@ apply_forward (OT::hb_ot_apply_context_t *c, while (buffer->idx < buffer->len && buffer->successful) { bool applied = false; - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) { applied = accel.apply (c, subtable_count, use_cache); } @@ -1951,9 +1952,10 @@ apply_backward (OT::hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; do { - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) ret |= accel.apply (c, subtable_count, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ @@ -2033,7 +2035,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, * (plus some past glyphs). * * Only try applying the lookup if there is any overlap. */ - if (accel->digest.may_have (c.digest)) + if (accel->digest.may_intersect (c.digest)) { c.set_lookup_index (lookup_index); c.set_lookup_mask (lookup.mask, false); @@ -2059,7 +2061,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (stage->pause_func (plan, font, buffer)) { /* Refresh working buffer digest since buffer changed. */ - c.digest = buffer->digest (); + buffer->collect_codepoints (c.digest); } } } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh index f26bf51ab..52dafbba4 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh @@ -339,6 +339,11 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) !_hb_glyph_info_substituted (info); } static inline void +_hb_glyph_info_set_default_ignorable (hb_glyph_info_t *info) +{ + info->unicode_props() |= UPROPS_MASK_IGNORABLE; +} +static inline void _hb_glyph_info_clear_default_ignorable (hb_glyph_info_t *info) { info->unicode_props() &= ~ UPROPS_MASK_IGNORABLE; @@ -360,7 +365,7 @@ _hb_glyph_info_set_continuation (hb_glyph_info_t *info) info->unicode_props() |= UPROPS_MASK_CONTINUATION; } static inline void -_hb_glyph_info_reset_continuation (hb_glyph_info_t *info) +_hb_glyph_info_clear_continuation (hb_glyph_info_t *info) { info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION; } @@ -633,8 +638,7 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) } /* Make sure no one directly touches our props... */ -#undef unicode_props0 -#undef unicode_props1 +#undef unicode_props #undef lig_props #undef glyph_props diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc index fac73eb34..952ab3eb1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc @@ -390,5 +390,19 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } } +unsigned int hb_ot_map_t::get_feature_tags (unsigned int start_offset, unsigned int *tag_count, hb_tag_t *tags) const +{ + if (tag_count) + { + auto sub_features = features.as_array ().sub_array (start_offset, tag_count); + if (tags) + { + for (unsigned int i = 0; i < sub_features.length; i++) + tags[i] = sub_features[i].tag; + } + } + + return features.length; +} #endif diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh index 8af8129ce..185d133d7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh @@ -166,6 +166,9 @@ struct hb_ot_map_t const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; + HB_INTERNAL unsigned int get_feature_tags (unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) const; public: hb_tag_t chosen_script[2]; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 59b97a799..c9defc49a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -46,6 +46,8 @@ #include "hb-set.hh" #include "hb-aat-layout.hh" +#include "hb-ot-stat-table.hh" + static inline bool _hb_codepoint_is_regional_indicator (hb_codepoint_t u) @@ -121,10 +123,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.kern_mask = plan.map.get_mask (kern_tag); plan.requested_kerning = !!plan.kern_mask; #endif -#ifndef HB_NO_AAT_SHAPE - plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k')); - plan.requested_tracking = !!plan.trak_mask; -#endif bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX; bool disable_gpos = plan.shaper->gpos_tag && @@ -207,9 +205,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, https://github.com/harfbuzz/harfbuzz/issues/2967. */ if (plan.apply_morx) plan.adjust_mark_positioning_when_zeroing = false; - - /* Currently we always apply trak. */ - plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); #endif } @@ -274,11 +269,6 @@ hb_ot_shape_plan_t::position (hb_font_t *font, #endif else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); - -#ifndef HB_NO_AAT_SHAPE - if (this->apply_trak) - hb_aat_layout_track (this, font, buffer); -#endif } @@ -346,13 +336,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, /* Random! */ map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE); -#ifndef HB_NO_AAT_SHAPE - /* Tracking. We enable dummy feature here just to allow disabling - * AAT 'trak' table using features. - * https://github.com/harfbuzz/harfbuzz/issues/1303 */ - map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK); -#endif - map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */ map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ @@ -1277,6 +1260,36 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, } +/** + * hb_ot_shape_plan_get_feature_tags: + * @shape_plan: A shaping plan + * @start_offset: The index of first feature to retrieve + * @tag_count: (inout): Input = the maximum number of features to return; + * Output = the actual number of features returned (may be zero) + * @tags: (out) (array length=tag_count): The array of enabled feature + * + * Fetches the list of OpenType feature tags enabled for a shaping plan, if possible. + * + * Return value: Total number of feature tagss. + * + * Since: 10.3.0 + */ +unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) +{ +#ifndef HB_NO_OT_SHAPE + return shape_plan->ot.map.get_feature_tags (start_offset, tag_count, tags); +#else + if (tag_count) + *tag_count = 0; + return 0; +#endif +} + + /* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */ static void add_char (hb_font_t *font, diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.h index afdff7283..80063f775 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.h +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.h @@ -48,6 +48,12 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, hb_set_t *lookup_indexes /* OUT */); +HB_EXTERN unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */); + HB_END_DECLS #endif /* HB_OT_SHAPE_H */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh index f84aa5c49..791bc6896 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh @@ -51,7 +51,8 @@ struct hb_ot_shape_plan_key_t bool equal (const hb_ot_shape_plan_key_t *other) { - return 0 == hb_memcmp (this, other, sizeof (*this)); + return variations_index[0] == other->variations_index[0] && + variations_index[1] == other->variations_index[1]; } }; @@ -79,22 +80,12 @@ struct hb_ot_shape_plan_t #else static constexpr hb_mask_t kern_mask = 0; #endif -#ifndef HB_NO_AAT_SHAPE - hb_mask_t trak_mask; -#else - static constexpr hb_mask_t trak_mask = 0; -#endif #ifndef HB_NO_OT_KERN bool requested_kerning : 1; #else static constexpr bool requested_kerning = false; #endif -#ifndef HB_NO_AAT_SHAPE - bool requested_tracking : 1; -#else - static constexpr bool requested_tracking = false; -#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS bool has_frac : 1; #else @@ -117,11 +108,9 @@ struct hb_ot_shape_plan_t #ifndef HB_NO_AAT_SHAPE bool apply_kerx : 1; bool apply_morx : 1; - bool apply_trak : 1; #else static constexpr bool apply_kerx = false; static constexpr bool apply_morx = false; - static constexpr bool apply_trak = false; #endif void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh index 66a8bfbd2..b82de35aa 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh @@ -355,6 +355,8 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) { + if (fallback_plan->accel_array[i]) + fallback_plan->accel_array[i]->fini (); hb_free (fallback_plan->accel_array[i]); if (fallback_plan->free_lookups) hb_free (fallback_plan->lookup_array[i]); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.cc index dbe781e56..a48b9b9ae 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.cc @@ -24,7 +24,7 @@ static void _output_dotted_circle (hb_buffer_t *buffer) { (void) buffer->output_glyph (0x25CCu); - _hb_glyph_info_reset_continuation (&buffer->prev()); + _hb_glyph_info_clear_continuation (&buffer->prev()); } static void diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh index 26eb34f5c..3d4ebddd8 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * <meta name="updated_at" content="2024-12-05 07:13 PM" /> - * File-Date: 2024-11-19 + * <meta name="updated_at" content="2024-12-06 06:35 AM" /> + * File-Date: 2025-01-21 */ #ifndef HB_OT_TAG_TABLE_HH @@ -745,6 +745,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('h','n','d',' '), HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */ {HB_TAG('h','n','e',' '), HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ {HB_TAG('h','n','j',' '), HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ + {HB_TAG('h','n','m',' '), HB_TAG('Z','H','S',' ')}, /* Hainanese -> Chinese, Simplified */ {HB_TAG('h','n','o',' '), HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ {HB_TAG('h','o','c',' '), HB_TAG('H','O',' ',' ')}, /* Ho */ {HB_TAG('h','o','i',' '), HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */ @@ -981,9 +982,11 @@ static const LangTag ot_languages3[] = { {HB_TAG('l','t','o',' '), HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ {HB_TAG('l','t','s',' '), HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ /*{HB_TAG('l','u','a',' '), HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ + {HB_TAG('l','u','h',' '), HB_TAG('Z','H','S',' ')}, /* Leizhou Chinese -> Chinese, Simplified */ /*{HB_TAG('l','u','o',' '), HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */ {HB_TAG('l','u','s',' '), HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ {HB_TAG('l','u','s',' '), HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */ +/*{HB_TAG('l','u','t',' '), HB_TAG('L','U','T',' ')},*/ /* Lushootseed */ {HB_TAG('l','u','y',' '), HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ {HB_TAG('l','u','z',' '), HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ {HB_TAG('l','v','i',' '), HB_TAG_NONE }, /* Lavi != Latvian */ @@ -1404,6 +1407,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('s','i','g',' '), HB_TAG_NONE }, /* Paasaal != Silte Gurage */ {HB_TAG('s','i','z',' '), HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */ /*{HB_TAG('s','j','a',' '), HB_TAG('S','J','A',' ')},*/ /* Epena */ + {HB_TAG('s','j','c',' '), HB_TAG('Z','H','S',' ')}, /* Shaojiang Chinese -> Chinese, Simplified */ {HB_TAG('s','j','d',' '), HB_TAG('K','S','M',' ')}, /* Kildin Sami */ /*{HB_TAG('s','j','e',' '), HB_TAG('S','J','E',' ')},*/ /* Pite Sami */ {HB_TAG('s','j','o',' '), HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ @@ -2386,6 +2390,26 @@ out: *count = i; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hant-hk", 10)) + { + /* Hainanese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant-mo", 10)) + { + /* Hainanese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hant-hk", 10)) { /* Xiang Chinese; Han (Traditional variant); Hong Kong */ @@ -2420,6 +2444,20 @@ out: *count = 1; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hans", 7)) + { + /* Hainanese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant", 7)) + { + /* Hainanese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hans", 7)) { /* Xiang Chinese; Han (Simplified variant) */ @@ -2464,6 +2502,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Hainanese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Hainanese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Hainanese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (0 == strncmp (&lang_str[1], "sn-", 3) && subtag_matches (lang_str, limit, "-hk", 3)) { @@ -2525,6 +2593,40 @@ out: } break; case 'l': + if (lang_matches (&lang_str[1], limit, "uh-hant-hk", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant-mo", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hans", 7)) + { + /* Leizhou Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant", 7)) + { + /* Leizhou Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "zh-hans", 7)) { /* Literary Chinese; Han (Simplified variant) */ @@ -2532,6 +2634,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Leizhou Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Leizhou Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Leizhou Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } break; case 'm': if (lang_matches (&lang_str[1], limit, "np-hant-hk", 10)) @@ -2703,6 +2835,72 @@ out: return true; } break; + case 's': + if (lang_matches (&lang_str[1], limit, "jc-hant-hk", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant-mo", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hans", 7)) + { + /* Shaojiang Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant", 7)) + { + /* Shaojiang Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Shaojiang Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Shaojiang Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Shaojiang Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + break; case 'w': if (lang_matches (&lang_str[1], limit, "uu-hant-hk", 10)) { diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh index 3ab58ae30..8eec5195a 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh @@ -231,9 +231,9 @@ struct tuple_delta_t /* indices_length = point_count, indice[i] = 1 means point i is referenced */ hb_vector_t<bool> indices; - hb_vector_t<double> deltas_x; + hb_vector_t<float> deltas_x; /* empty for cvar tuples */ - hb_vector_t<double> deltas_y; + hb_vector_t<float> deltas_y; /* compiled data: header and deltas * compiled point data is saved in a hashmap within tuple_variations_t cause @@ -299,9 +299,9 @@ struct tuple_delta_t return *this; } - tuple_delta_t& operator *= (double scalar) + tuple_delta_t& operator *= (float scalar) { - if (scalar == 1.0) + if (scalar == 1.0f) return *this; unsigned num = indices.length; @@ -514,9 +514,9 @@ struct tuple_delta_t bool compile_deltas () { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } - static bool compile_deltas (const hb_vector_t<bool> &point_indices, - const hb_vector_t<double> &x_deltas, - const hb_vector_t<double> &y_deltas, + static bool compile_deltas (hb_array_t<const bool> point_indices, + hb_array_t<const float> x_deltas, + hb_array_t<const float> y_deltas, hb_vector_t<unsigned char> &compiled_deltas /* OUT */) { hb_vector_t<int> rounded_deltas; @@ -629,11 +629,11 @@ struct tuple_delta_t deltas_x.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].x, (double) orig_points.arrayZ[prev].x, (double) orig_points.arrayZ[next].x, - deltas_x.arrayZ[prev], deltas_x.arrayZ[next]); + (double) deltas_x.arrayZ[prev], (double) deltas_x.arrayZ[next]); deltas_y.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].y, (double) orig_points.arrayZ[prev].y, (double) orig_points.arrayZ[next].y, - deltas_y.arrayZ[prev], deltas_y.arrayZ[next]); + (double) deltas_y.arrayZ[prev], (double) deltas_y.arrayZ[next]); inferred_idxes.add (i); if (--unref_count == 0) goto no_more_gaps; } @@ -692,7 +692,7 @@ struct tuple_delta_t if (ref_count == count) return true; - hb_vector_t<double> opt_deltas_x, opt_deltas_y; + hb_vector_t<float> opt_deltas_x, opt_deltas_y; bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); if (is_comp_glyph_wo_deltas) { @@ -841,6 +841,7 @@ struct tuple_delta_t { return (i >= end) ? start : (i + 1); } }; +template <typename OffType = HBUINT16> struct TupleVariationData { bool sanitize (hb_sanitize_context_t *c) const @@ -875,7 +876,7 @@ struct TupleVariationData private: /* referenced point set->compiled point data map */ - hb_hashmap_t<const hb_vector_t<bool>*, hb_vector_t<char>> point_data_map; + hb_hashmap_t<const hb_vector_t<bool>*, hb_vector_t<unsigned char>> point_data_map; /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map; @@ -883,7 +884,7 @@ struct TupleVariationData * shared_points_bytes is a pointer to some value in the point_data_map, * which will be freed during map destruction. Save it for serialization, so * no need to do find_shared_points () again */ - hb_vector_t<char> *shared_points_bytes = nullptr; + hb_vector_t<unsigned char> *shared_points_bytes = nullptr; /* total compiled byte size as TupleVariationData format, initialized to 0 */ unsigned compiled_byte_size = 0; @@ -1244,7 +1245,7 @@ struct TupleVariationData for (auto& tuple: tuple_vars) { const hb_vector_t<bool>* points_set = &(tuple.indices); - hb_vector_t<char> *points_data; + hb_vector_t<unsigned char> *points_data; if (unlikely (!point_data_map.has (points_set, &points_data))) return false; @@ -1289,20 +1290,20 @@ struct TupleVariationData TRACE_SERIALIZE (this); if (is_gvar && shared_points_bytes) { - hb_bytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); + hb_ubytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); s.copy (c); } for (const auto& tuple: tuple_vars) { const hb_vector_t<bool>* points_set = &(tuple.indices); - hb_vector_t<char> *point_data; + hb_vector_t<unsigned char> *point_data; if (!point_data_map.has (points_set, &point_data)) return_trace (false); if (!is_gvar || point_data != shared_points_bytes) { - hb_bytes_t s (point_data->arrayZ, point_data->length); + hb_ubytes_t s (point_data->arrayZ, point_data->length); s.copy (c); } @@ -1521,15 +1522,16 @@ struct TupleVariationData * low 12 bits are the number of tuple variation tables * for this glyph. The number of tuple variation tables * can be any number between 1 and 4095. */ - Offset16To<HBUINT8> + OffsetTo<HBUINT8, OffType> data; /* Offset from the start of the base table * to the serialized data. */ /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */ public: - DEFINE_SIZE_MIN (4); + DEFINE_SIZE_MIN (2 + OffType::static_size); }; -using tuple_variations_t = TupleVariationData::tuple_variations_t; +// TODO: Move tuple_variations_t to outside of TupleVariationData +using tuple_variations_t = TupleVariationData<HBUINT16>::tuple_variations_t; struct item_variations_t { using region_t = const hb_hashmap_t<hb_tag_t, Triple>*; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh index 3931382f1..f8ae0c803 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh @@ -50,7 +50,7 @@ struct cvar tupleVariationData.sanitize (c)); } - const TupleVariationData* get_tuple_var_data (void) const + const TupleVariationData<>* get_tuple_var_data (void) const { return &tupleVariationData; } bool decompile_tuple_variations (unsigned axis_count, @@ -58,12 +58,12 @@ struct cvar hb_blob_t *blob, bool is_gvar, const hb_map_t *axes_old_index_tag_map, - TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const + TupleVariationData<>::tuple_variations_t& tuple_variations /* OUT */) const { hb_vector_t<unsigned> shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, this, shared_indices, &iterator)) return false; @@ -77,16 +77,16 @@ struct cvar static bool calculate_cvt_deltas (unsigned axis_count, hb_array_t<int> coords, unsigned num_cvt_item, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base, hb_vector_t<float>& cvt_deltas /* OUT */) { if (!coords) return true; hb_vector_t<unsigned> shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; unsigned var_data_length = tuple_var_data->get_size (axis_count); hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast<const char*> (tuple_var_data), var_data_length); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, base, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base, shared_indices, &iterator)) return true; /* isn't applied at all */ @@ -107,14 +107,14 @@ struct cvar bool has_private_points = iterator.current_tuple->has_private_points (); if (has_private_points && - !TupleVariationData::decompile_points (p, private_indices, end)) + !TupleVariationData<>::decompile_points (p, private_indices, end)) return false; const hb_vector_t<unsigned int> &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; - if (unlikely (!TupleVariationData::decompile_deltas (p, unpacked_deltas, end))) return false; + if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; for (unsigned int i = 0; i < num_deltas; i++) { @@ -129,7 +129,7 @@ struct cvar } bool serialize (hb_serialize_context_t *c, - TupleVariationData::tuple_variations_t& tuple_variations) const + TupleVariationData<>::tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); if (!tuple_variations) return_trace (false); @@ -144,7 +144,7 @@ struct cvar if (c->plan->all_axes_pinned) return_trace (false); - OT::TupleVariationData::tuple_variations_t tuple_variations; + OT::TupleVariationData<>::tuple_variations_t tuple_variations; unsigned axis_count = c->plan->axes_old_index_tag_map.get_population (); const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -169,7 +169,7 @@ struct cvar } static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base) { const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -209,7 +209,7 @@ struct cvar protected: FixedVersion<>version; /* Version of the CVT variation table * initially set to 0x00010000u */ - TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */ + TupleVariationData<> tupleVariationData; /* TupleVariationDate for cvar table */ public: DEFINE_SIZE_MIN (8); }; diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh index 96cc2e887..b388c7143 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh @@ -28,6 +28,7 @@ #ifndef HB_OT_VAR_GVAR_TABLE_HH #define HB_OT_VAR_GVAR_TABLE_HH +#include "hb-decycler.hh" #include "hb-open-type.hh" #include "hb-ot-var-common.hh" @@ -36,15 +37,37 @@ * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar */ #define HB_OT_TAG_gvar HB_TAG('g','v','a','r') +#define HB_OT_TAG_GVAR HB_TAG('G','V','A','R') -namespace OT { +struct hb_glyf_scratch_t +{ + // glyf + contour_point_vector_t all_points; + contour_point_vector_t comp_points; + hb_decycler_t decycler; + + // gvar + contour_point_vector_t orig_points; + hb_vector_t<int> x_deltas; + hb_vector_t<int> y_deltas; + contour_point_vector_t deltas; + hb_vector_t<unsigned int> shared_indices; + hb_vector_t<unsigned int> private_indices; + + // VARC + hb_vector_t<unsigned> axisIndices; + hb_vector_t<float> axisValues; +}; -struct GlyphVariationData : TupleVariationData -{}; +namespace OT { +template <typename OffsetType> struct glyph_variations_t { - using tuple_variations_t = TupleVariationData::tuple_variations_t; + // TODO: Move tuple_variations_t to outside of TupleVariationData + using tuple_variations_t = typename TupleVariationData<OffsetType>::tuple_variations_t; + using GlyphVariationData = TupleVariationData<OffsetType>; + hb_vector_t<tuple_variations_t> glyph_variations; hb_vector_t<char> compiled_shared_tuples; @@ -72,7 +95,7 @@ struct glyph_variations_t const hb_subset_plan_t *plan, const hb_hashmap_t<hb_codepoint_t, hb_bytes_t>& new_gid_var_data_map) { - if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true))) + if (unlikely (!glyph_variations.alloc_exact (plan->new_to_old_gid_list.length))) return false; auto it = hb_iter (plan->new_to_old_gid_list); @@ -86,10 +109,11 @@ struct glyph_variations_t hb_bytes_t var_data = new_gid_var_data_map.get (new_gid); const GlyphVariationData* p = reinterpret_cast<const GlyphVariationData*> (var_data.arrayZ); - hb_vector_t<unsigned> shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + typename GlyphVariationData::tuple_iterator_t iterator; tuple_variations_t tuple_vars; + hb_vector_t<unsigned> shared_indices; + /* in case variation data is empty, push an empty struct into the vector, * keep the vector in sync with the new_to_old_gid_list */ if (!var_data || ! p->has_data () || !all_contour_points->length || @@ -259,7 +283,7 @@ struct glyph_variations_t hb_codepoint_t last_gid = 0; unsigned idx = 0; - TupleVariationData* cur_glyph = c->start_embed<TupleVariationData> (); + GlyphVariationData* cur_glyph = c->start_embed<GlyphVariationData> (); if (!cur_glyph) return_trace (false); for (auto &_ : it) { @@ -273,7 +297,7 @@ struct glyph_variations_t if (idx >= glyph_variations.length) return_trace (false); if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false); - TupleVariationData* next_glyph = c->start_embed<TupleVariationData> (); + GlyphVariationData* next_glyph = c->start_embed<GlyphVariationData> (); glyph_offset += (char *) next_glyph - (char *) cur_glyph; if (long_offset) @@ -296,9 +320,14 @@ struct glyph_variations_t } }; -struct gvar +template <typename GidOffsetType, unsigned TableTag> +struct gvar_GVAR { - static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar; + static constexpr hb_tag_t tableTag = TableTag; + + using GlyphVariationData = TupleVariationData<GidOffsetType>; + + bool has_data () const { return version.to_int () != 0; } bool sanitize_shallow (hb_sanitize_context_t *c) const { @@ -317,7 +346,7 @@ struct gvar { return sanitize_shallow (c); } bool decompile_glyph_variations (hb_subset_context_t *c, - glyph_variations_t& glyph_vars /* OUT */) const + glyph_variations_t<GidOffsetType>& glyph_vars /* OUT */) const { hb_hashmap_t<hb_codepoint_t, hb_bytes_t> new_gid_var_data_map; auto it = hb_iter (c->plan->new_to_old_gid_list); @@ -344,14 +373,14 @@ struct gvar template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> bool serialize (hb_serialize_context_t *c, - const glyph_variations_t& glyph_vars, + const glyph_variations_t<GidOffsetType>& glyph_vars, Iterator it, unsigned axis_count, unsigned num_glyphs, bool force_long_offsets) const { TRACE_SERIALIZE (this); - gvar *out = c->allocate_min<gvar> (); + gvar_GVAR *out = c->allocate_min<gvar_GVAR> (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -393,7 +422,7 @@ struct gvar bool instantiate (hb_subset_context_t *c) const { TRACE_SUBSET (this); - glyph_variations_t glyph_vars; + glyph_variations_t<GidOffsetType> glyph_vars; if (!decompile_glyph_variations (c, glyph_vars)) return_trace (false); @@ -423,7 +452,7 @@ struct gvar unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; - gvar *out = c->serializer->allocate_min<gvar> (); + gvar_GVAR *out = c->serializer->allocate_min<gvar_GVAR> (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -557,9 +586,11 @@ struct gvar public: struct accelerator_t { + bool has_data () const { return table->has_data (); } + accelerator_t (hb_face_t *face) { - table = hb_sanitize_context_t ().reference_table<gvar> (face); + table = hb_sanitize_context_t ().reference_table<gvar_GVAR> (face); /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; @@ -627,35 +658,40 @@ struct gvar bool apply_deltas_to_points (hb_codepoint_t glyph, hb_array_t<const int> coords, const hb_array_t<contour_point_t> points, + hb_glyf_scratch_t &scratch, bool phantom_only = false) const { if (unlikely (glyph >= glyphCount)) return true; hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph); if (!var_data_bytes.as<GlyphVariationData> ()->has_data ()) return true; - hb_vector_t<unsigned int> shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + + auto &shared_indices = scratch.shared_indices; + shared_indices.clear (); + + typename GlyphVariationData::tuple_iterator_t iterator; if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount, var_data_bytes.arrayZ, shared_indices, &iterator)) return true; /* so isn't applied at all */ /* Save original points for inferred delta calculation */ - contour_point_vector_t orig_points_vec; // Populated lazily + auto &orig_points_vec = scratch.orig_points; + orig_points_vec.clear (); // Populated lazily auto orig_points = orig_points_vec.as_array (); /* flag is used to indicate referenced point */ - contour_point_vector_t deltas_vec; // Populated lazily + auto &deltas_vec = scratch.deltas; + deltas_vec.clear (); // Populated lazily auto deltas = deltas_vec.as_array (); - hb_vector_t<unsigned> end_points; // Populated lazily - unsigned num_coords = table->axisCount; hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords); - hb_vector_t<unsigned int> private_indices; - hb_vector_t<int> x_deltas; - hb_vector_t<int> y_deltas; + auto &private_indices = scratch.private_indices; + auto &x_deltas = scratch.x_deltas; + auto &y_deltas = scratch.y_deltas; + unsigned count = points.length; bool flush = false; do @@ -726,8 +762,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -738,10 +774,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -751,8 +786,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -760,10 +795,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -773,8 +807,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } } } @@ -782,17 +816,14 @@ struct gvar /* infer deltas for unreferenced points */ if (!apply_to_all && !phantom_only) { - if (!end_points) - { - for (unsigned i = 0; i < count; ++i) - if (points.arrayZ[i].is_end_point) - end_points.push (i); - if (unlikely (end_points.in_error ())) return false; - } - unsigned start_point = 0; - for (unsigned end_point : end_points) + unsigned end_point = 0; + while (true) { + while (end_point < count && !points.arrayZ[end_point].is_end_point) + end_point++; + if (unlikely (end_point == count)) break; + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ unsigned unref_count = 0; for (unsigned i = start_point; i < end_point + 1; i++) @@ -835,7 +866,7 @@ struct gvar } } no_more_gaps: - start_point = end_point + 1; + start_point = end_point = end_point + 1; } } @@ -855,7 +886,7 @@ struct gvar unsigned int get_axis_count () const { return table->axisCount; } private: - hb_blob_ptr_t<gvar> table; + hb_blob_ptr_t<gvar_GVAR> table; unsigned glyphCount; hb_vector_t<hb_pair_t<int, int>> shared_tuple_active_idx; }; @@ -873,7 +904,7 @@ struct gvar NNOffset32To<UnsizedArrayOf<F2DOT14>> sharedTuples; /* Offset from the start of this table to the shared tuple records. * Array of tuple records shared across all glyph variation data tables. */ - HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of + GidOffsetType glyphCountX; /* The number of glyphs in this font. This must match the number of * glyphs stored elsewhere in the font. */ HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the @@ -888,9 +919,15 @@ struct gvar DEFINE_SIZE_ARRAY (20, offsetZ); }; +using gvar = gvar_GVAR<HBUINT16, HB_OT_TAG_gvar>; +using GVAR = gvar_GVAR<HBUINT24, HB_OT_TAG_GVAR>; + struct gvar_accelerator_t : gvar::accelerator_t { gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {} }; +struct GVAR_accelerator_t : GVAR::accelerator_t { + GVAR_accelerator_t (hb_face_t *face) : GVAR::accelerator_t (face) {} +}; } /* namespace OT */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh index f066d0e31..63ab18586 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh @@ -78,11 +78,11 @@ struct hb_serialize_context_t head = o.head; tail = o.tail; next = nullptr; - real_links.alloc (o.num_real_links, true); + real_links.alloc_exact (o.num_real_links); for (unsigned i = 0 ; i < o.num_real_links; i++) real_links.push (o.real_links[i]); - virtual_links.alloc (o.num_virtual_links, true); + virtual_links.alloc_exact (o.num_virtual_links); for (unsigned i = 0; i < o.num_virtual_links; i++) virtual_links.push (o.virtual_links[i]); } @@ -172,7 +172,7 @@ struct hb_serialize_context_t auto all_links () const HB_AUTO_RETURN (( hb_concat (real_links, virtual_links) )); auto all_links_writer () HB_AUTO_RETURN - (( hb_concat (real_links.writer (), virtual_links.writer ()) )); + (( hb_concat (real_links.writer (), virtual_links.writer ()) )); }; struct snapshot_t diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh index b718b94e6..0d05e72c1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh @@ -56,7 +56,7 @@ * - For each glyph, if it doesn't match the subtable digest, * skip it. * - * The main filter we use is a combination of three bits-pattern + * The main filter we use is a combination of four bits-pattern * filters. A bits-pattern filter checks a number of bits (5 or 6) * of the input number (glyph-id in this case) and checks whether * its pattern is amongst the patterns of any of the accepted values. @@ -64,45 +64,60 @@ * check is done using four bitwise operations only. */ -template <typename mask_t, unsigned int shift> -struct hb_set_digest_bits_pattern_t +static constexpr unsigned hb_set_digest_shifts[] = {4, 0, 6}; + +struct hb_set_digest_t { + // No science in these. Intuition and testing only. + using mask_t = uint64_t; + + static constexpr unsigned n = ARRAY_LENGTH_CONST (hb_set_digest_shifts); static constexpr unsigned mask_bytes = sizeof (mask_t); static constexpr unsigned mask_bits = sizeof (mask_t) * 8; - static constexpr unsigned num_bits = 0 - + (mask_bytes >= 1 ? 3 : 0) - + (mask_bytes >= 2 ? 1 : 0) - + (mask_bytes >= 4 ? 1 : 0) - + (mask_bytes >= 8 ? 1 : 0) - + (mask_bytes >= 16? 1 : 0) - + 0; + static constexpr hb_codepoint_t mb1 = mask_bits - 1; + static constexpr mask_t one = 1; + static constexpr mask_t all = (mask_t) -1; - static_assert ((shift < sizeof (hb_codepoint_t) * 8), ""); - static_assert ((shift + num_bits <= sizeof (hb_codepoint_t) * 8), ""); - - void init () { mask = 0; } + void init () + { for (unsigned i = 0; i < n; i++) masks[i] = 0; } - static hb_set_digest_bits_pattern_t full () { hb_set_digest_bits_pattern_t d; d.mask = (mask_t) -1; return d; } + void clear () { init (); } - void union_ (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; } + static hb_set_digest_t full () + { + hb_set_digest_t d; + for (unsigned i = 0; i < n; i++) d.masks[i] = all; + return d; + } - void add (hb_codepoint_t g) { mask |= mask_for (g); } + void union_ (const hb_set_digest_t &o) + { for (unsigned i = 0; i < n; i++) masks[i] |= o.masks[i]; } bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (mask == (mask_t) -1) return false; - if ((b >> shift) - (a >> shift) >= mask_bits - 1) - { - mask = (mask_t) -1; - return false; - } - else + bool ret; + + ret = false; + for (unsigned i = 0; i < n; i++) + if (masks[i] != all) + ret = true; + if (!ret) return false; + + ret = false; + for (unsigned i = 0; i < n; i++) { - mask_t ma = mask_for (a); - mask_t mb = mask_for (b); - mask |= mb + (mb - ma) - (mb < ma); - return true; + mask_t shift = hb_set_digest_shifts[i]; + if ((b >> shift) - (a >> shift) >= mb1) + masks[i] = all; + else + { + mask_t ma = one << ((a >> shift) & mb1); + mask_t mb = one << ((b >> shift) & mb1); + masks[i] |= mb + (mb - ma) - (mb < ma); + ret = true; + } } + return ret; } template <typename T> @@ -125,103 +140,37 @@ struct hb_set_digest_bits_pattern_t template <typename T> bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_bits_pattern_t &o) const - { return mask & o.mask; } - - bool may_have (hb_codepoint_t g) const - { return mask & mask_for (g); } - bool operator [] (hb_codepoint_t g) const { return may_have (g); } - private: - - static mask_t mask_for (hb_codepoint_t g) - { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); } - mask_t mask = 0; -}; - -template <typename head_t, typename tail_t> -struct hb_set_digest_combiner_t -{ - void init () - { - head.init (); - tail.init (); - } - - static hb_set_digest_combiner_t full () { hb_set_digest_combiner_t d; d.head = head_t::full(); d.tail = tail_t::full (); return d; } - - void union_ (const hb_set_digest_combiner_t &o) - { - head.union_ (o.head); - tail.union_(o.tail); - } void add (hb_codepoint_t g) { - head.add (g); - tail.add (g); - } - - bool add_range (hb_codepoint_t a, hb_codepoint_t b) - { - return (int) head.add_range (a, b) | (int) tail.add_range (a, b); - } - template <typename T> - void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - head.add_array (array, count, stride); - tail.add_array (array, count, stride); - } - template <typename T> - void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); } - template <typename T> - bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - return head.add_sorted_array (array, count, stride) && - tail.add_sorted_array (array, count, stride); + for (unsigned i = 0; i < n; i++) + masks[i] |= one << ((g >> hb_set_digest_shifts[i]) & mb1); } - template <typename T> - bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_combiner_t &o) const + HB_ALWAYS_INLINE + bool may_have (hb_codepoint_t g) const { - return head.may_have (o.head) && tail.may_have (o.tail); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & (one << ((g >> hb_set_digest_shifts[i]) & mb1)))) + return false; + return true; } - bool may_have (hb_codepoint_t g) const + bool may_intersect (const hb_set_digest_t &o) const { - return head.may_have (g) && tail.may_have (g); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & o.masks[i])) + return false; + return true; } - bool operator [] (hb_codepoint_t g) const - { return may_have (g); } - private: - head_t head; - tail_t tail; -}; - -/* - * hb_set_digest_t - * - * This is a combination of digests that performs "best". - * There is not much science to this: it's a result of intuition - * and testing. - */ -using hb_set_digest_t = - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t<unsigned long, 4>, - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t<unsigned long, 0>, - hb_set_digest_bits_pattern_t<unsigned long, 9> - > - > -; + mask_t masks[n] = {}; +}; #endif /* HB_SET_DIGEST_HH */ diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh index f6013a414..f098bd4c1 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh @@ -106,6 +106,7 @@ struct hb_sparseset_t void del_range (hb_codepoint_t a, hb_codepoint_t b) { s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -120,6 +121,9 @@ struct hb_sparseset_t hb_sparseset_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_sparseset_t &other) const + { return s.may_intersect (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { return s.intersects (first, last); } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc index 312eeb653..47eb690a7 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc @@ -209,7 +209,7 @@ hb_shape_plan_create (hb_face_t *face, * @num_coords: The number of variation-space coordinates * @shaper_list: (array zero-terminated=1): List of shapers to try * - * The variable-font version of #hb_shape_plan_create. + * The variable-font version of #hb_shape_plan_create. * Constructs a shaping plan for a combination of @face, @user_features, @props, * and @shaper_list, plus the variation-space coordinates @coords. * @@ -233,7 +233,7 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); - if (unlikely (props->direction == HB_DIRECTION_INVALID)) + if (unlikely (!HB_DIRECTION_IS_VALID (props->direction))) return hb_shape_plan_get_empty (); hb_shape_plan_t *shape_plan; @@ -331,7 +331,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the given shaping plan. + * Attaches a user-data key/data pair to the given shaping plan. * * Return value: `true` if success, `false` otherwise. * @@ -352,7 +352,7 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, * @shape_plan: A shaping plan * @key: The user-data key to query * - * Fetches the user data associated with the specified key, + * Fetches the user data associated with the specified key, * attached to the specified shaping plan. * * Return value: (transfer none): A pointer to the user data @@ -501,7 +501,7 @@ hb_shape_plan_create_cached (hb_face_t *face, * @num_coords: The number of variation-space coordinates * @shaper_list: (array zero-terminated=1): List of shapers to try * - * The variable-font version of #hb_shape_plan_create_cached. + * The variable-font version of #hb_shape_plan_create_cached. * Creates a cached shaping plan suitable for reuse, for a combination * of @face, @user_features, @props, and @shaper_list, plus the * variation-space coordinates @coords. diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh index 4039f9c95..c3f7b40c8 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh @@ -1128,7 +1128,7 @@ struct subr_subsetter_t if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr) size += 3; } - if (!buff.alloc (buff.length + size, true)) + if (!buff.alloc_exact (buff.length + size)) return false; for (auto &opstr : str.values) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc index e9dd5d642..d080e0a27 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc @@ -45,7 +45,7 @@ struct remap_sid_t void alloc (unsigned size) { map.alloc (size); - vector.alloc (size, true); + vector.alloc_exact (size); } bool in_error () const diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index fe80c08bc..214ea9341 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -95,7 +95,6 @@ struct contour_point_t HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } - float x; float y; uint8_t flag; @@ -104,19 +103,9 @@ struct contour_point_t struct contour_point_vector_t : hb_vector_t<contour_point_t> { - void extend (const hb_array_t<contour_point_t> &a) - { - unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length, false))) - return; - auto arrayZ = this->arrayZ + old_len; - unsigned count = a.length; - hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); - } - - bool add_deltas (const hb_vector_t<float> deltas_x, - const hb_vector_t<float> deltas_y, - const hb_vector_t<bool> indices) + bool add_deltas (hb_array_t<const float> deltas_x, + hb_array_t<const float> deltas_y, + hb_array_t<const bool> indices) { if (indices.length != deltas_x.length || indices.length != deltas_y.length) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index 4e96c9853..fbdf1b4f9 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -296,7 +296,7 @@ _try_subset (const TableType *table, HB_UNTAG (c->table_tag), buf_size); if (unlikely (buf_size > c->source_blob->length * 256 || - !buf->alloc (buf_size, true))) + !buf->alloc_exact (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (c->table_tag), buf_size); diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh index c0cc7063f..0e01d010f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh @@ -53,28 +53,25 @@ struct hb_vector_t } template <typename Iterable, hb_requires (hb_is_iterable (Iterable))> - hb_vector_t (const Iterable &o) : hb_vector_t () + explicit hb_vector_t (const Iterable &o) : hb_vector_t () { - auto iter = hb_iter (o); - if (iter.is_random_access_iterator || iter.has_fast_len) - alloc (hb_len (iter), true); - hb_copy (iter, *this); + extend (o); } hb_vector_t (const hb_vector_t &o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o.as_array ()); } hb_vector_t (array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } hb_vector_t (c_array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } @@ -87,6 +84,35 @@ struct hb_vector_t } ~hb_vector_t () { fini (); } + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + void extend (const Iterable &o) + { + auto iter = hb_iter (o); + if (iter.is_random_access_iterator || iter.has_fast_len) + alloc (hb_len (iter), true); + while (iter) + { + if (unlikely (!alloc (length + 1))) + return; + unsigned room = allocated - length; + for (unsigned i = 0; i < room && iter; i++) + push_has_room (*iter++); + } + } + void extend (array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } + void extend (c_array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } + public: int allocated = 0; /* < 0 means allocation failed. */ unsigned int length = 0; @@ -132,9 +158,10 @@ struct hb_vector_t hb_vector_t& operator = (const hb_vector_t &o) { reset (); - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return *this; + length = 0; copy_array (o.as_array ()); return *this; @@ -218,6 +245,10 @@ struct hb_vector_t // reference to it. return std::addressof (Crap (Type)); + return push_has_room (std::forward<Args> (args)...); + } + template <typename... Args> Type *push_has_room (Args&&... args) + { /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward<Args> (args)...); @@ -311,18 +342,23 @@ struct hb_vector_t length = size; } + template <typename T = Type, + hb_enable_if (hb_is_trivially_copyable (T))> + void + copy_array (hb_array_t<Type> other) + { + assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; + } template <typename T = Type, hb_enable_if (hb_is_trivially_copyable (T))> void copy_array (hb_array_t<const Type> other) { - length = other.length; - if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long)) - /* This runs faster because of alignment. */ - for (unsigned i = 0; i < length; i++) - arrayZ[i] = other.arrayZ[i]; - else - hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size); + assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; } template <typename T = Type, hb_enable_if (!hb_is_trivially_copyable (T) && @@ -330,12 +366,10 @@ struct hb_vector_t void copy_array (hb_array_t<const Type> other) { - length = 0; - while (length < other.length) - { - length++; - new (std::addressof (arrayZ[length - 1])) Type (other.arrayZ[length - 1]); - } + assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) + new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); + length += other.length; } template <typename T = Type, hb_enable_if (!hb_is_trivially_copyable (T) && @@ -345,13 +379,13 @@ struct hb_vector_t void copy_array (hb_array_t<const Type> other) { - length = 0; - while (length < other.length) + assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) { - length++; - new (std::addressof (arrayZ[length - 1])) Type (); - arrayZ[length - 1] = other.arrayZ[length - 1]; + new (std::addressof (arrayZ[length + i])) Type (); + arrayZ[length + i] = other.arrayZ[i]; } + length += other.length; } void @@ -432,6 +466,15 @@ struct hb_vector_t return true; } + bool alloc_exact (unsigned int size) + { + return alloc (size, true); + } + + void clear () + { + resize (0); + } bool resize (int size_, bool initialize = true, bool exact = false) { @@ -497,7 +540,7 @@ struct hb_vector_t shrink_vector (size); if (shrink_memory) - alloc (size, true); /* To force shrinking memory if needed. */ + alloc_exact (size); /* To force shrinking memory if needed. */ } diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb.hh index fe466fe1f..7c265483f 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/source/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -131,6 +131,7 @@ #pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126 #pragma GCC diagnostic ignored "-Wdangling-reference" // https://github.com/harfbuzz/harfbuzz/issues/4043 +#pragma GCC diagnostic ignored "-Wdangling-pointer" // Trigerred by hb_decycler_node_t(). #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -281,7 +282,9 @@ extern "C" void hb_free_impl(void *ptr); #define __attribute__(x) #endif -#if defined(__GNUC__) && (__GNUC__ >= 3) +#if defined(__MINGW32__) && (__GNUC__ >= 3) +#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (gnu_printf, format_idx, arg_idx))) +#elif defined(__GNUC__) && (__GNUC__ >= 3) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else #define HB_PRINTF_FUNC(format_idx, arg_idx) diff --git a/source/libs/harfbuzz/harfbuzz-src/src/meson.build b/source/libs/harfbuzz/harfbuzz-src/src/meson.build index b9daabf01..8e40e0498 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/meson.build +++ b/source/libs/harfbuzz/harfbuzz-src/src/meson.build @@ -43,6 +43,7 @@ hb_base_sources = files( 'hb-common.cc', 'hb-config.hh', 'hb-debug.hh', + 'hb-decycler.hh', 'hb-dispatch.hh', 'hb-draw.cc', 'hb-draw.hh', @@ -725,6 +726,7 @@ if get_option('tests').enabled() 'test-bimap': ['test-bimap.cc', 'hb-static.cc'], 'test-cff': ['test-cff.cc', 'hb-static.cc'], 'test-classdef-graph': ['graph/test-classdef-graph.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], + 'test-decycler': ['test-decycler.cc', 'hb-static.cc'], 'test-iter': ['test-iter.cc', 'hb-static.cc'], 'test-machinery': ['test-machinery.cc', 'hb-static.cc'], 'test-map': ['test-map.cc', 'hb-static.cc'], diff --git a/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc b/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc index 1e07d27d3..9fdbacafa 100644 --- a/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc +++ b/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc @@ -38,15 +38,15 @@ test_decompile_cvar () hb_map_t axis_idx_tag_map; axis_idx_tag_map.set (0, axis_tag); - OT::TupleVariationData::tuple_variations_t tuple_variations; + OT::TupleVariationData<>::tuple_variations_t tuple_variations; hb_vector_t<unsigned> shared_indices; - OT::TupleVariationData::tuple_iterator_t iterator; + OT::TupleVariationData<>::tuple_iterator_t iterator; - const OT::TupleVariationData* tuple_var_data = reinterpret_cast<const OT::TupleVariationData*> (cvar_data + 4); + const OT::TupleVariationData<>* tuple_var_data = reinterpret_cast<const OT::TupleVariationData<>*> (cvar_data + 4); unsigned len = sizeof (cvar_data); hb_bytes_t var_data_bytes{(const char* ) cvar_data + 4, len - 4}; - bool result = OT::TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, cvar_table, + bool result = OT::TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, cvar_table, shared_indices, &iterator); assert (result); @@ -66,7 +66,7 @@ test_decompile_cvar () assert (tuple_variations.tuple_vars[0].axis_tuples.get (axis_tag) == Triple (-1.0, -1.0, 0.0)); assert (tuple_variations.tuple_vars[1].axis_tuples.get (axis_tag) == Triple (0.0, 1.0, 1.0)); - hb_vector_t<double> deltas_1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -3.0, 1.0, 0.0, -1.0, 0.0, -3.0, 1.0, 0.0, -37.0, -37.0, -26.0, -26.0, 0.0, 0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.0, 0.0, 2.0, -29.0, -29.0, -20.0, -20.0, 0.0, 0.0, 0.0, 1.0, -29.0, -29.0, -20.0, -20.0, 0.0, 0.0, 0.0, 1.0}; + hb_vector_t<float> deltas_1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -3.0, 1.0, 0.0, -1.0, 0.0, -3.0, 1.0, 0.0, -37.0, -37.0, -26.0, -26.0, 0.0, 0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.0, 0.0, 2.0, -29.0, -29.0, -20.0, -20.0, 0.0, 0.0, 0.0, 1.0, -29.0, -29.0, -20.0, -20.0, 0.0, 0.0, 0.0, 1.0}; for (unsigned i = 0; i < 65; i++) { if (i < 23) @@ -78,7 +78,7 @@ test_decompile_cvar () } } - hb_vector_t<double> deltas_2 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 5.0, -3.0, 0.0, 1.0, 0.0, 5.0, -3.0, 0.0, 97.0, 97.0, 68.0, 68.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 1.0, -1.0, 1.0, 7.0, -1.0, -5.0, 73.0, 73.0, 53.0, 53.0, 0.0, 0.0, 0.0, -1.0, 73.0, 73.0, 53.0, 53.0, 0.0, 0.0, 0.0, -1.0}; + hb_vector_t<float> deltas_2 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 5.0, -3.0, 0.0, 1.0, 0.0, 5.0, -3.0, 0.0, 97.0, 97.0, 68.0, 68.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 1.0, -1.0, 1.0, 7.0, -1.0, -5.0, 73.0, 73.0, 53.0, 53.0, 0.0, 0.0, 0.0, -1.0, 73.0, 73.0, 53.0, 53.0, 0.0, 0.0, 0.0, -1.0}; for (unsigned i = 0 ; i < 65; i++) { if (i < 23) @@ -106,9 +106,9 @@ test_decompile_cvar () assert (tuple_variations.tuple_vars[0].axis_tuples.get (axis_tag) == Triple (-1.0, -1.0, 0.0)); assert (tuple_variations.tuple_vars[1].axis_tuples.get (axis_tag) == Triple (0.0, 1.0, 1.0)); - hb_vector_t<double> rounded_deltas_1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1, 0.0, -2, 1, 0.0, -1, 0.0, -2, 1, 0.0, -19, -19, -13, -13, 0.0, 0.0, 0.0, -2, 0.0, 0.0, 0.0, 0.0, 0.0, -2, 0.0, 1, -15, -15, -10.0, -10.0, 0.0, 0.0, 0.0, 1, -15, -15, -10.0, -10.0, 0.0, 0.0, 0.0, 1}; + hb_vector_t<float> rounded_deltas_1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1, 0.0, -2, 1, 0.0, -1, 0.0, -2, 1, 0.0, -19, -19, -13, -13, 0.0, 0.0, 0.0, -2, 0.0, 0.0, 0.0, 0.0, 0.0, -2, 0.0, 1, -15, -15, -10.0, -10.0, 0.0, 0.0, 0.0, 1, -15, -15, -10.0, -10.0, 0.0, 0.0, 0.0, 1}; - hb_vector_t<double> rounded_deltas_2 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, 0.0, 4, -2, 0.0, 1, 0.0, 4, -2, 0.0, 68, 68, 48, 48, 0.0, 0.0, 0.0, 4, 0.0, 0.0, 1, -1, 1, 5, -1, -4, 51, 51, 37, 37, 0.0, 0.0, 0.0, -1, 51, 51, 37, 37, 0.0, 0.0, 0.0, -1}; + hb_vector_t<float> rounded_deltas_2 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, 0.0, 4, -2, 0.0, 1, 0.0, 4, -2, 0.0, 68, 68, 48, 48, 0.0, 0.0, 0.0, 4, 0.0, 0.0, 1, -1, 1, 5, -1, -4, 51, 51, 37, 37, 0.0, 0.0, 0.0, -1, 51, 51, 37, 37, 0.0, 0.0, 0.0, -1}; for (unsigned i = 0; i < 65; i++) { diff --git a/source/libs/harfbuzz/version.ac b/source/libs/harfbuzz/version.ac index 27b278353..c52799ab6 100644 --- a/source/libs/harfbuzz/version.ac +++ b/source/libs/harfbuzz/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current harfbuzz version -m4_define([harfbuzz_version], [10.2.0]) +m4_define([harfbuzz_version], [10.4.0]) diff --git a/source/libs/libpng/ChangeLog b/source/libs/libpng/ChangeLog index 949797268..e43efc31a 100644 --- a/source/libs/libpng/ChangeLog +++ b/source/libs/libpng/ChangeLog @@ -1,3 +1,8 @@ +2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Import libpng-1.6.47. + * version.ac: Adjust. + 2025-01-25 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Import libpng-1.6.46. diff --git a/source/libs/libpng/README b/source/libs/libpng/README index 22781cdc7..92e4f1aed 100644 --- a/source/libs/libpng/README +++ b/source/libs/libpng/README @@ -1,4 +1,4 @@ - Building libpng-1.6.45 as part of the TL tree + Building libpng-1.6.47 as part of the TL tree ============================================= This directory libs/libpng/ uses a proxy Makefile.am to build the libpng library @@ -14,4 +14,4 @@ copied to libs/libpng/configure.ac. ============================= 2009-07-23 Peter Breitenlohner <peb@mppmu.mpg.de> -2025-01-25 Akira Kakuto <kakuto@jcom.zaq.ne.jp> +2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> diff --git a/source/libs/libpng/TLpatches/ChangeLog b/source/libs/libpng/TLpatches/ChangeLog index efd1df78f..b189fe224 100644 --- a/source/libs/libpng/TLpatches/ChangeLog +++ b/source/libs/libpng/TLpatches/ChangeLog @@ -1,3 +1,7 @@ +2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Import libpng-1.6.47. + 2025-01-25 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Import libpng-1.6.46. diff --git a/source/libs/libpng/TLpatches/TL-Changes b/source/libs/libpng/TLpatches/TL-Changes index 2a3cfe306..938aed4ac 100644 --- a/source/libs/libpng/TLpatches/TL-Changes +++ b/source/libs/libpng/TLpatches/TL-Changes @@ -1,5 +1,5 @@ -Changes applied to the libpng-1.6.46/ tree as obtained from: - https://sourceforge.net/projects/libpng/files/libpng16/1.6.46/ +Changes applied to the libpng-1.6.47/ tree as obtained from: + https://sourceforge.net/projects/libpng/files/libpng16/1.6.47/ Copied: scripts/pnglibconf.h.prebuilt -> pnglibconf.h diff --git a/source/libs/libpng/configure b/source/libs/libpng/configure index 73550681c..88ce80b06 100755 --- a/source/libs/libpng/configure +++ b/source/libs/libpng/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for libpng (TeX Live) 1.6.46. +# Generated by GNU Autoconf 2.72 for libpng (TeX Live) 1.6.47. # # Report bugs to <tex-k@tug.org>. # @@ -604,8 +604,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libpng (TeX Live)' PACKAGE_TARNAME='libpng--tex-live-' -PACKAGE_VERSION='1.6.46' -PACKAGE_STRING='libpng (TeX Live) 1.6.46' +PACKAGE_VERSION='1.6.47' +PACKAGE_STRING='libpng (TeX Live) 1.6.47' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1342,7 +1342,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures libpng (TeX Live) 1.6.46 to adapt to many kinds of systems. +'configure' configures libpng (TeX Live) 1.6.47 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1414,7 +1414,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libpng (TeX Live) 1.6.46:";; + short | recursive ) echo "Configuration of libpng (TeX Live) 1.6.47:";; esac cat <<\_ACEOF @@ -1534,7 +1534,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libpng (TeX Live) configure 1.6.46 +libpng (TeX Live) configure 1.6.47 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1861,7 +1861,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libpng (TeX Live) $as_me 1.6.46, which was +It was created by libpng (TeX Live) $as_me 1.6.47, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -4822,7 +4822,7 @@ fi # Define the identity of the package. PACKAGE='libpng--tex-live-' - VERSION='1.6.46' + VERSION='1.6.47' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -7996,7 +7996,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libpng (TeX Live) $as_me 1.6.46, which was +This file was extended by libpng (TeX Live) $as_me 1.6.47, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8064,7 +8064,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -libpng (TeX Live) config.status 1.6.46 +libpng (TeX Live) config.status 1.6.47 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/libs/libpng/libpng-src/ANNOUNCE b/source/libs/libpng/libpng-src/ANNOUNCE index 579824fbe..603b2df48 100644 --- a/source/libs/libpng/libpng-src/ANNOUNCE +++ b/source/libs/libpng/libpng-src/ANNOUNCE @@ -1,5 +1,5 @@ -libpng 1.6.46 - January 23, 2025 -================================ +libpng 1.6.47 - February 18, 2025 +================================= This is a public release of libpng, intended for use in production code. @@ -9,13 +9,13 @@ Files available for download Source files with LF line endings (for Unix/Linux): - * libpng-1.6.46.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.46.tar.gz (deflate-compressed) + * libpng-1.6.47.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.47.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): - * lpng1646.7z (LZMA-compressed, recommended) - * lpng1646.zip (deflate-compressed) + * lpng1647.7z (LZMA-compressed, recommended) + * lpng1647.zip (deflate-compressed) Other information: @@ -25,17 +25,19 @@ Other information: * TRADEMARK.md -Changes from version 1.6.45 to version 1.6.46 +Changes from version 1.6.46 to version 1.6.47 --------------------------------------------- - * Added support for the mDCV and cLLI chunks. + * Modified the behaviour of colorspace chunks in order to adhere + to the new precedence rules formulated in the latest draft of + the PNG Specification. (Contributed by John Bowler) - * Fixed a build issue affecting C89 compilers. - This was a regression introduced in libpng-1.6.45. - (Contributed by John Bowler) - * Added makefile.c89, specifically for testing C89 compilers. - * Cleaned up contrib/pngminus: corrected an old typo, removed an old - workaround, and updated the CMake file. + * Fixed a latent bug in `png_write_iCCP`. + This would have been a read-beyond-end-of-malloc vulnerability, + introduced early in the libpng-1.6.0 development, yet (fortunately!) + it was inaccessible before the above-mentioned modification of the + colorspace precedence rules, due to pre-existing colorspace checks. + (Reported by Bob Friesenhahn; fixed by John Bowler) Send comments/corrections/commendations to png-mng-implement at lists.sf.net. diff --git a/source/libs/libpng/libpng-src/CHANGES b/source/libs/libpng/libpng-src/CHANGES index e6aa1db13..834b5e192 100644 --- a/source/libs/libpng/libpng-src/CHANGES +++ b/source/libs/libpng/libpng-src/CHANGES @@ -6239,6 +6239,18 @@ Version 1.6.46 [January 23, 2025] Cleaned up contrib/pngminus: corrected an old typo, removed an old workaround, and updated the CMake file. +Version 1.6.47 [February 18, 2025] + Modified the behaviour of colorspace chunks in order to adhere + to the new precedence rules formulated in the latest draft of + the PNG Specification. + (Contributed by John Bowler) + Fixed a latent bug in `png_write_iCCP`. + This would have been a read-beyond-end-of-malloc vulnerability, + introduced early in the libpng-1.6.0 development, yet (fortunately!) + it was inaccessible before the above-mentioned modification of the + colorspace precedence rules, due to pre-existing colorspace checks. + (Reported by Bob Friesenhahn; fixed by John Bowler) + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/source/libs/libpng/libpng-src/CMakeLists.txt b/source/libs/libpng/libpng-src/CMakeLists.txt index 99d028a13..4a97bd50e 100644 --- a/source/libs/libpng/libpng-src/CMakeLists.txt +++ b/source/libs/libpng/libpng-src/CMakeLists.txt @@ -18,7 +18,7 @@ cmake_minimum_required(VERSION 3.14) set(PNGLIB_MAJOR 1) set(PNGLIB_MINOR 6) -set(PNGLIB_REVISION 46) +set(PNGLIB_REVISION 47) set(PNGLIB_SUBREVISION 0) #set(PNGLIB_SUBREVISION "git") set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION}) diff --git a/source/libs/libpng/libpng-src/README b/source/libs/libpng/libpng-src/README index 3f3f02023..57952fb21 100644 --- a/source/libs/libpng/libpng-src/README +++ b/source/libs/libpng/libpng-src/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.46 +README for libpng version 1.6.47 ================================ See the note about version numbers near the top of `png.h`. diff --git a/source/libs/libpng/libpng-src/ci/ci_verify_cmake.sh b/source/libs/libpng/libpng-src/ci/ci_verify_cmake.sh index d48062cf5..3e05ec309 100644 --- a/source/libs/libpng/libpng-src/ci/ci_verify_cmake.sh +++ b/source/libs/libpng/libpng-src/ci/ci_verify_cmake.sh @@ -64,6 +64,7 @@ function ci_trace_build { ci_info "environment option: \$CI_RANLIB: '$CI_RANLIB'" ci_info "environment option: \$CI_SANITIZERS: '$CI_SANITIZERS'" ci_info "environment option: \$CI_FORCE: '$CI_FORCE'" + ci_info "environment option: \$CI_NO_BUILD: '$CI_NO_BUILD'" ci_info "environment option: \$CI_NO_TEST: '$CI_NO_TEST'" ci_info "environment option: \$CI_NO_INSTALL: '$CI_NO_INSTALL'" ci_info "environment option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" @@ -148,10 +149,12 @@ function ci_build { -S . \ -DCMAKE_INSTALL_PREFIX="$CI_INSTALL_DIR" \ "${all_cmake_vars[@]}" - # Spawn "cmake --build ...". - ci_spawn "$CI_CMAKE" --build "$CI_BUILD_DIR" \ - --config "$CI_CMAKE_BUILD_TYPE" \ - "${all_cmake_build_flags[@]}" + ci_expr $((CI_NO_BUILD)) || { + # Spawn "cmake --build ...". + ci_spawn "$CI_CMAKE" --build "$CI_BUILD_DIR" \ + --config "$CI_CMAKE_BUILD_TYPE" \ + "${all_cmake_build_flags[@]}" + } ci_expr $((CI_NO_TEST)) || { # Spawn "ctest" if testing is not disabled. ci_spawn pushd "$CI_BUILD_DIR" diff --git a/source/libs/libpng/libpng-src/ci/ci_verify_configure.sh b/source/libs/libpng/libpng-src/ci/ci_verify_configure.sh index b0e4d4944..9c3a28809 100644 --- a/source/libs/libpng/libpng-src/ci/ci_verify_configure.sh +++ b/source/libs/libpng/libpng-src/ci/ci_verify_configure.sh @@ -58,6 +58,7 @@ function ci_trace_build { ci_info "environment option: \$CI_LD_FLAGS: '$CI_LD_FLAGS'" ci_info "environment option: \$CI_SANITIZERS: '$CI_SANITIZERS'" ci_info "environment option: \$CI_FORCE: '$CI_FORCE'" + ci_info "environment option: \$CI_NO_BUILD: '$CI_NO_BUILD'" ci_info "environment option: \$CI_NO_TEST: '$CI_NO_TEST'" ci_info "environment option: \$CI_NO_INSTALL: '$CI_NO_INSTALL'" ci_info "environment option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" @@ -131,8 +132,10 @@ function ci_build { ci_spawn cd "$CI_BUILD_DIR" # Spawn "configure". ci_spawn "$CI_SRC_DIR/configure" --prefix="$CI_INSTALL_DIR" $CI_CONFIGURE_FLAGS - # Spawn "make". - ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS + ci_expr $((CI_NO_BUILD)) || { + # Spawn "make". + ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS + } ci_expr $((CI_NO_TEST)) || { # Spawn "make test" if testing is not disabled. ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS test diff --git a/source/libs/libpng/libpng-src/ci/ci_verify_makefiles.sh b/source/libs/libpng/libpng-src/ci/ci_verify_makefiles.sh index e0681b4d8..2d3ec72ec 100644 --- a/source/libs/libpng/libpng-src/ci/ci_verify_makefiles.sh +++ b/source/libs/libpng/libpng-src/ci/ci_verify_makefiles.sh @@ -51,6 +51,7 @@ function ci_trace_build { ci_info "environment option: \$CI_LIBS: '$CI_LIBS'" ci_info "environment option: \$CI_SANITIZERS: '$CI_SANITIZERS'" ci_info "environment option: \$CI_FORCE: '$CI_FORCE'" + ci_info "environment option: \$CI_NO_BUILD: '$CI_NO_BUILD'" ci_info "environment option: \$CI_NO_TEST: '$CI_NO_TEST'" ci_info "environment option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" ci_info "executable: \$CI_MAKE: $(command -V "$CI_MAKE")" @@ -145,10 +146,12 @@ function ci_build { for my_makefile in $CI_MAKEFILES do ci_info "using makefile: $my_makefile" - # Spawn "make". - ci_spawn "$CI_MAKE" -f "$my_makefile" \ - "${all_make_flags[@]}" \ - "${all_make_vars[@]}" + ci_expr $((CI_NO_BUILD)) || { + # Spawn "make". + ci_spawn "$CI_MAKE" -f "$my_makefile" \ + "${all_make_flags[@]}" \ + "${all_make_vars[@]}" + } ci_expr $((CI_NO_TEST)) || { # Spawn "make test" if testing is not disabled. ci_spawn "$CI_MAKE" -f "$my_makefile" \ diff --git a/source/libs/libpng/libpng-src/ci/lib/ci.lib.sh b/source/libs/libpng/libpng-src/ci/lib/ci.lib.sh index 03e866b5c..692851fc0 100644 --- a/source/libs/libpng/libpng-src/ci/lib/ci.lib.sh +++ b/source/libs/libpng/libpng-src/ci/lib/ci.lib.sh @@ -91,6 +91,9 @@ function ci_spawn { [[ ${CI_FORCE:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_FORCE: '$CI_FORCE'" } +[[ ${CI_NO_BUILD:-0} == [01] ]] || { + ci_err "bad boolean option: \$CI_NO_BUILD: '$CI_NO_BUILD'" +} [[ ${CI_NO_TEST:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_NO_TEST: '$CI_NO_TEST'" } @@ -100,3 +103,9 @@ function ci_spawn { [[ ${CI_NO_CLEAN:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" } +if ci_expr $((CI_NO_BUILD)) +then + ci_expr $((CI_NO_TEST && CI_NO_INSTALL)) || { + ci_err "\$CI_NO_BUILD requires \$CI_NO_TEST and \$CI_NO_INSTALL" + } +fi diff --git a/source/libs/libpng/libpng-src/configure.ac b/source/libs/libpng/libpng-src/configure.ac index 735b55a95..df48325e0 100644 --- a/source/libs/libpng/libpng-src/configure.ac +++ b/source/libs/libpng/libpng-src/configure.ac @@ -25,7 +25,7 @@ AC_PREREQ([2.68]) dnl Version number stuff here: -AC_INIT([libpng],[1.6.46],[png-mng-implement@lists.sourceforge.net]) +AC_INIT([libpng],[1.6.47],[png-mng-implement@lists.sourceforge.net]) AC_CONFIG_MACRO_DIR([scripts/autoconf]) # libpng does not follow GNU file name conventions (hence 'foreign') @@ -46,10 +46,10 @@ dnl automake, so the following is not necessary (and is not defined anyway): dnl AM_PREREQ([1.11.2]) dnl stop configure from automagically running automake -PNGLIB_VERSION=1.6.46 +PNGLIB_VERSION=1.6.47 PNGLIB_MAJOR=1 PNGLIB_MINOR=6 -PNGLIB_RELEASE=46 +PNGLIB_RELEASE=47 dnl End of version number stuff diff --git a/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c b/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c index d22f7bcd0..2e2dd0894 100644 --- a/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c +++ b/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c @@ -542,6 +542,7 @@ typedef enum struct display { jmp_buf error_return; /* Where to go to on error */ + error_level error_code; /* Set before longjmp */ const char *filename; /* The name of the original file */ const char *operation; /* Operation being performed */ @@ -762,7 +763,10 @@ display_log(struct display *dp, error_level level, const char *fmt, ...) /* Errors cause this routine to exit to the fail code */ if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE))) + { + dp->error_code = level; longjmp(dp->error_return, level); + } } /* error handler callbacks for libpng */ @@ -1570,18 +1574,19 @@ static int do_test(struct display *dp, const char *file) /* Exists solely to isolate the setjmp clobbers */ { - int ret = setjmp(dp->error_return); + dp->error_code = VERBOSE; /* The "lowest" level */ - if (ret == 0) + if (setjmp(dp->error_return) == 0) { test_one_file(dp, file); return 0; } - else if (ret < ERRORS) /* shouldn't longjmp on warnings */ - display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret); + else if (dp->error_code < ERRORS) /* shouldn't longjmp on warnings */ + display_log(dp, INTERNAL_ERROR, "unexpected return code %d", + dp->error_code); - return ret; + return dp->error_code; } int @@ -1681,7 +1686,11 @@ main(int argc, char **argv) int ret = do_test(&d, argv[i]); if (ret > QUIET) /* abort on user or internal error */ + { + display_clean(&d); + display_destroy(&d); return 99; + } } /* Here on any return, including failures, except user/internal issues diff --git a/source/libs/libpng/libpng-src/libpng-manual.txt b/source/libs/libpng/libpng-src/libpng-manual.txt index e81e477c1..862fe2c5d 100644 --- a/source/libs/libpng/libpng-src/libpng-manual.txt +++ b/source/libs/libpng/libpng-src/libpng-manual.txt @@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.46 - January 2025 + libpng version 1.6.36, December 2018, through 1.6.47 - February 2025 Updated and distributed by Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta diff --git a/source/libs/libpng/libpng-src/libpng.3 b/source/libs/libpng/libpng-src/libpng.3 index a23193be1..923b6772e 100644 --- a/source/libs/libpng/libpng-src/libpng.3 +++ b/source/libs/libpng/libpng-src/libpng.3 @@ -1,6 +1,6 @@ -.TH LIBPNG 3 "January 23, 2025" +.TH LIBPNG 3 "February 18, 2025" .SH NAME -libpng \- Portable Network Graphics (PNG) Reference Library 1.6.46 +libpng \- Portable Network Graphics (PNG) Reference Library 1.6.47 .SH SYNOPSIS \fB#include <png.h>\fP @@ -528,7 +528,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.46 - January 2025 + libpng version 1.6.36, December 2018, through 1.6.47 - February 2025 Updated and distributed by Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta diff --git a/source/libs/libpng/libpng-src/libpngpf.3 b/source/libs/libpng/libpng-src/libpngpf.3 index d5262c4b0..9c4dda2a6 100644 --- a/source/libs/libpng/libpng-src/libpngpf.3 +++ b/source/libs/libpng/libpng-src/libpngpf.3 @@ -1,6 +1,6 @@ -.TH LIBPNGPF 3 "January 23, 2025" +.TH LIBPNGPF 3 "February 18, 2025" .SH NAME -libpng \- Portable Network Graphics (PNG) Reference Library 1.6.46 +libpng \- Portable Network Graphics (PNG) Reference Library 1.6.47 (private functions) .SH SYNOPSIS diff --git a/source/libs/libpng/libpng-src/png.5 b/source/libs/libpng/libpng-src/png.5 index 16c1032fb..ee4a2b20d 100644 --- a/source/libs/libpng/libpng-src/png.5 +++ b/source/libs/libpng/libpng-src/png.5 @@ -1,4 +1,4 @@ -.TH PNG 5 "January 23, 2025" +.TH PNG 5 "February 18, 2025" .SH NAME png \- Portable Network Graphics (PNG) format @@ -20,10 +20,10 @@ matching on heterogeneous platforms. .SH "SEE ALSO" .BR "libpng"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5) .LP -PNG Specification (Third Edition) Candidate Recommendation Draft, July 2024: +PNG Specification (Third Edition) Candidate Recommendation Draft, January 2025: .IP .br -https://www.w3.org/TR/2024/CRD-png-3-20240718/ +https://www.w3.org/TR/2025/CRD-png-3-20250121/ .LP PNG Specification (Second Edition), November 2003: .IP diff --git a/source/libs/libpng/libpng-src/png.c b/source/libs/libpng/libpng-src/png.c index cbd54e1af..6d533ec40 100644 --- a/source/libs/libpng/libpng-src/png.c +++ b/source/libs/libpng/libpng-src/png.c @@ -13,7 +13,34 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_46 Your_png_h_is_not_version_1_6_46; +typedef png_libpng_version_1_6_47 Your_png_h_is_not_version_1_6_47; + +/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the + * corresponding macro definitions. This causes a compile time failure if + * something is wrong but generates no code. + * + * (1) The first check is that the PNG_CHUNK(cHNK, index) 'index' values must + * increment from 0 to the last value. + */ +#define PNG_CHUNK(cHNK, index) != (index) || ((index)+1) + +#if 0 PNG_KNOWN_CHUNKS < 0 +# error PNG_KNOWN_CHUNKS chunk definitions are not in order +#endif + +#undef PNG_CHUNK + +/* (2) The chunk name macros, png_cHNK, must all be valid and defined. Since + * this is a preprocessor test undefined pp-tokens come out as zero and will + * fail this test. + */ +#define PNG_CHUNK(cHNK, index) !PNG_CHUNK_NAME_VALID(png_ ## cHNK) || + +#if PNG_KNOWN_CHUNKS 0 +# error png_cHNK not defined for some known cHNK +#endif + +#undef PNG_CHUNK /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -241,21 +268,23 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, */ memset(&create_struct, 0, (sizeof create_struct)); - /* Added at libpng-1.2.6 */ # ifdef PNG_USER_LIMITS_SUPPORTED create_struct.user_width_max = PNG_USER_WIDTH_MAX; create_struct.user_height_max = PNG_USER_HEIGHT_MAX; # ifdef PNG_USER_CHUNK_CACHE_MAX - /* Added at libpng-1.2.43 and 1.4.0 */ create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; # endif -# ifdef PNG_USER_CHUNK_MALLOC_MAX - /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists - * in png_struct regardless. - */ +# if PNG_USER_CHUNK_MALLOC_MAX > 0 /* default to compile-time limit */ create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; + + /* No compile-time limit, so initialize to the system limit: */ +# elif defined PNG_MAX_MALLOC_64K /* legacy system limit */ + create_struct.user_chunk_malloc_max = 65536U; + +# else /* modern system limit SIZE_MAX (C99) */ + create_struct.user_chunk_malloc_max = PNG_SIZE_MAX; # endif # endif @@ -597,13 +626,6 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, /* Free any eXIf entry */ if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0) { -# ifdef PNG_READ_eXIf_SUPPORTED - if (info_ptr->eXIf_buf) - { - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - } -# endif if (info_ptr->exif) { png_free(png_ptr, info_ptr->exif); @@ -793,7 +815,7 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.46" PNG_STRING_NEWLINE \ + "libpng version 1.6.47" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ @@ -1038,169 +1060,6 @@ png_zstream_error(png_structrp png_ptr, int ret) } } -/* png_convert_size: a PNGAPI but no longer in png.h, so deleted - * at libpng 1.5.5! - */ - -/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ -static int -png_colorspace_check_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA, int from) - /* This is called to check a new gamma value against an existing one. The - * routine returns false if the new gamma value should not be written. - * - * 'from' says where the new gamma value comes from: - * - * 0: the new gamma value is the libpng estimate for an ICC profile - * 1: the new gamma value comes from a gAMA chunk - * 2: the new gamma value comes from an sRGB chunk - */ -{ - png_fixed_point gtest; - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || - png_gamma_significant(gtest) != 0)) - { - /* Either this is an sRGB image, in which case the calculated gamma - * approximation should match, or this is an image with a profile and the - * value libpng calculates for the gamma of the profile does not match the - * value recorded in the file. The former, sRGB, case is an error, the - * latter is just a warning. - */ - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) - { - png_chunk_report(png_ptr, "gamma value does not match sRGB", - PNG_CHUNK_ERROR); - /* Do not overwrite an sRGB value */ - return from == 2; - } - - else /* sRGB tag not involved */ - { - png_chunk_report(png_ptr, "gamma value does not match libpng estimate", - PNG_CHUNK_WARNING); - return from == 1; - } - } - - return 1; -} - -void /* PRIVATE */ -png_colorspace_set_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA) -{ - /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is asymmetrical it is - * possible for 1/gamma to overflow the limit of 21474 and this means the - * gamma value must be at least 5/100000 and hence at most 20000.0. For - * safety the limits here are a little narrower. The values are 0.00016 to - * 6250.0, which are truly ridiculous gamma values (and will produce - * displays that are all black or all white.) - * - * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk - * handling code, which only required the value to be >0. - */ - png_const_charp errmsg; - - if (gAMA < 16 || gAMA > 625000000) - errmsg = "gamma value out of range"; - -# ifdef PNG_READ_gAMA_SUPPORTED - /* Allow the application to set the gamma value more than once */ - else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) - errmsg = "duplicate"; -# endif - - /* Do nothing if the colorspace is already invalid */ - else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return; - - else - { - if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, - 1/*from gAMA*/) != 0) - { - /* Store this gamma value. */ - colorspace->gamma = gAMA; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); - } - - /* At present if the check_gamma test fails the gamma of the colorspace is - * not updated however the colorspace is not invalidated. This - * corresponds to the case where the existing gamma comes from an sRGB - * chunk or profile. An error message has already been output. - */ - return; - } - - /* Error exit - errmsg has been set. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); -} - -void /* PRIVATE */ -png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - /* Everything is invalid */ - info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| - PNG_INFO_iCCP); - -# ifdef PNG_COLORSPACE_SUPPORTED - /* Clean up the iCCP profile now if it won't be used. */ - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); -# else - PNG_UNUSED(png_ptr) -# endif - } - - else - { -# ifdef PNG_COLORSPACE_SUPPORTED - /* Leave the INFO_iCCP flag set if the pngset.c code has already set - * it; this allows a PNG to contain a profile which matches sRGB and - * yet still have that profile retrievable by the application. - */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) - info_ptr->valid |= PNG_INFO_sRGB; - - else - info_ptr->valid &= ~PNG_INFO_sRGB; - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - info_ptr->valid |= PNG_INFO_cHRM; - - else - info_ptr->valid &= ~PNG_INFO_cHRM; -# endif - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) - info_ptr->valid |= PNG_INFO_gAMA; - - else - info_ptr->valid &= ~PNG_INFO_gAMA; - } -} - -#ifdef PNG_READ_SUPPORTED -void /* PRIVATE */ -png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if (info_ptr == NULL) /* reduce code size; check here not in the caller */ - return; - - info_ptr->colorspace = png_ptr->colorspace; - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif -#endif /* GAMMA */ - #ifdef PNG_COLORSPACE_SUPPORTED static png_int_32 png_fp_add(png_int_32 addend0, png_int_32 addend1, int *error) @@ -1269,9 +1128,10 @@ png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1, * non-zero on a parameter error. The X, Y and Z values are required to be * positive and less than 1.0. */ -static int +int /* PRIVATE */ png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) { + /* NOTE: returns 0 on success, 1 means error. */ png_int_32 d, dred, dgreen, dblue, dwhite, whiteX, whiteY; /* 'd' in each of the blocks below is just X+Y+Z for each component, @@ -1334,9 +1194,10 @@ png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) return 0; } -static int +int /* PRIVATE */ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) { + /* NOTE: returns 0 on success, 1 means error. */ png_fixed_point red_inverse, green_inverse, blue_scale; png_fixed_point left, right, denominator; @@ -1628,239 +1489,9 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) return 0; /*success*/ } +#endif /* COLORSPACE */ -static int -png_XYZ_normalize(png_XYZ *XYZ) -{ - png_int_32 Y, Ytemp; - - /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. */ - Ytemp = XYZ->red_Y; - if (png_safe_add(&Ytemp, XYZ->green_Y, XYZ->blue_Y)) - return 1; - - Y = Ytemp; - - if (Y != PNG_FP_1) - { - if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) - return 1; - } - - return 0; -} - -static int -png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) -{ - /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ - if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || - PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || - PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || - PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || - PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || - PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || - PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || - PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) - return 0; - return 1; -} - -/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM - * chunk chromaticities. Earlier checks used to simply look for the overflow - * condition (where the determinant of the matrix to solve for XYZ ends up zero - * because the chromaticity values are not all distinct.) Despite this it is - * theoretically possible to produce chromaticities that are apparently valid - * but that rapidly degrade to invalid, potentially crashing, sets because of - * arithmetic inaccuracies when calculations are performed on them. The new - * check is to round-trip xy -> XYZ -> xy and then check that the result is - * within a small percentage of the original. - */ -static int -png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) -{ - int result; - png_xy xy_test; - - /* As a side-effect this routine also returns the XYZ endpoints. */ - result = png_XYZ_from_xy(XYZ, xy); - if (result != 0) - return result; - - result = png_xy_from_XYZ(&xy_test, XYZ); - if (result != 0) - return result; - - if (png_colorspace_endpoints_match(xy, &xy_test, - 5/*actually, the math is pretty accurate*/) != 0) - return 0; - - /* Too much slip */ - return 1; -} - -/* This is the check going the other way. The XYZ is modified to normalize it - * (another side-effect) and the xy chromaticities are returned. - */ -static int -png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) -{ - int result; - png_XYZ XYZtemp; - - result = png_XYZ_normalize(XYZ); - if (result != 0) - return result; - - result = png_xy_from_XYZ(xy, XYZ); - if (result != 0) - return result; - - XYZtemp = *XYZ; - return png_colorspace_check_xy(&XYZtemp, xy); -} - -/* Used to check for an endpoint match against sRGB */ -static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ -{ - /* color x y */ - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000, - /* white */ 31270, 32900 -}; - -static int -png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, - int preferred) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* The consistency check is performed on the chromaticities; this factors out - * variations because of the normalization (or not) of the end point Y - * values. - */ - if (preferred < 2 && - (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* The end points must be reasonably close to any we already have. The - * following allows an error of up to +/-.001 - */ - if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, - 100) == 0) - { - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "inconsistent chromaticities"); - return 0; /* failed */ - } - - /* Only overwrite with preferred values */ - if (preferred == 0) - return 1; /* ok, but no change */ - } - - colorspace->end_points_xy = *xy; - colorspace->end_points_XYZ = *XYZ; - colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; - - /* The end points are normally quoted to two decimal digits, so allow +/-0.01 - * on this test. - */ - if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) - colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; - - else - colorspace->flags &= PNG_COLORSPACE_CANCEL( - PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - return 2; /* ok and changed */ -} - -int /* PRIVATE */ -png_colorspace_set_chromaticities(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, int preferred) -{ - /* We must check the end points to ensure they are reasonable - in the past - * color management systems have crashed as a result of getting bogus - * colorant values, while this isn't the fault of libpng it is the - * responsibility of libpng because PNG carries the bomb and libpng is in a - * position to protect against it. - */ - png_XYZ XYZ; - - switch (png_colorspace_check_xy(&XYZ, xy)) - { - case 0: /* success */ - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, - preferred); - - case 1: - /* We can't invert the chromaticities so we can't produce value XYZ - * values. Likely as not a color management system will fail too. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid chromaticities"); - break; - - default: - /* libpng is broken; this should be a warning but if it happens we - * want error reports so for the moment it is an error. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_error(png_ptr, "internal error checking chromaticities"); - } - - return 0; /* failed */ -} - -int /* PRIVATE */ -png_colorspace_set_endpoints(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) -{ - png_XYZ XYZ = *XYZ_in; - png_xy xy; - - switch (png_colorspace_check_XYZ(&xy, &XYZ)) - { - case 0: - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, - preferred); - - case 1: - /* End points are invalid. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid end points"); - break; - - default: - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_error(png_ptr, "internal error checking chromaticities"); - } - - return 0; /* failed */ -} - -#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) +#ifdef PNG_iCCP_SUPPORTED /* Error message generation */ static char png_icc_tag_char(png_uint_32 byte) @@ -1900,15 +1531,12 @@ is_ICC_signature(png_alloc_size_t it) } static int -png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_alloc_size_t value, png_const_charp reason) +png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name, + png_alloc_size_t value, png_const_charp reason) { size_t pos; char message[196]; /* see below for calculation */ - if (colorspace != NULL) - colorspace->flags |= PNG_COLORSPACE_INVALID; - pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ @@ -1935,109 +1563,13 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, pos = png_safecat(message, (sizeof message), pos, reason); PNG_UNUSED(pos) - /* This is recoverable, but make it unconditionally an app_error on write to - * avoid writing invalid ICC profiles into PNG files (i.e., we handle them - * on read, with a warning, but on write unless the app turns off - * application errors the PNG won't be written.) - */ - png_chunk_report(png_ptr, message, - (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); + png_chunk_benign_error(png_ptr, message); return 0; } -#endif /* sRGB || iCCP */ - -#ifdef PNG_sRGB_SUPPORTED -int /* PRIVATE */ -png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, - int intent) -{ - /* sRGB sets known gamma, end points and (from the chunk) intent. */ - /* IMPORTANT: these are not necessarily the values found in an ICC profile - * because ICC profiles store values adapted to a D50 environment; it is - * expected that the ICC profile mediaWhitePointTag will be D50; see the - * checks and code elsewhere to understand this better. - * - * These XYZ values, which are accurate to 5dp, produce rgb to gray - * coefficients of (6968,23435,2366), which are reduced (because they add up - * to 32769 not 32768) to (6968,23434,2366). These are the values that - * libpng has traditionally used (and are the best values given the 15bit - * algorithm used by the rgb to gray code.) - */ - static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ - { - /* color X Y Z */ - /* red */ 41239, 21264, 1933, - /* green */ 35758, 71517, 11919, - /* blue */ 18048, 7219, 95053 - }; - - /* Do nothing if the colorspace is already invalidated. */ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* Check the intent, then check for existing settings. It is valid for the - * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must - * be consistent with the correct values. If, however, this function is - * called below because an iCCP chunk matches sRGB then it is quite - * conceivable that an older app recorded incorrect gAMA and cHRM because of - * an incorrect calculation based on the values in the profile - this does - * *not* invalidate the profile (though it still produces an error, which can - * be ignored.) - */ - if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (png_alloc_size_t)intent, "invalid sRGB rendering intent"); - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && - colorspace->rendering_intent != intent) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (png_alloc_size_t)intent, "inconsistent rendering intents"); - - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) - { - png_benign_error(png_ptr, "duplicate sRGB information ignored"); - return 0; - } - - /* If the standard sRGB cHRM chunk does not match the one from the PNG file - * warn but overwrite the value with the correct one. - */ - if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && - !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, - 100)) - png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", - PNG_CHUNK_ERROR); - - /* This check is just done for the error reporting - the routine always - * returns true when the 'from' argument corresponds to sRGB (2). - */ - (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, - 2/*from sRGB*/); - - /* intent: bugs in GCC force 'int' to be used as the parameter type. */ - colorspace->rendering_intent = (png_uint_16)intent; - colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; - - /* endpoints */ - colorspace->end_points_xy = sRGB_xy; - colorspace->end_points_XYZ = sRGB_XYZ; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - /* gamma */ - colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; - colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Finally record that we have an sRGB profile */ - colorspace->flags |= - (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); - - return 1; /* set */ -} -#endif /* sRGB */ +#endif /* iCCP */ -#ifdef PNG_iCCP_SUPPORTED +#ifdef PNG_READ_iCCP_SUPPORTED /* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value * is XYZ(0.9642,1.0,0.8249), which scales to: * @@ -2047,21 +1579,19 @@ static const png_byte D50_nCIEXYZ[12] = { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; static int /* bool */ -icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) +icc_check_length(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length) { if (profile_length < 132) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "too short"); + return png_icc_profile_error(png_ptr, name, profile_length, "too short"); return 1; } -#ifdef PNG_READ_iCCP_SUPPORTED int /* PRIVATE */ -png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) +png_icc_check_length(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length) { - if (!icc_check_length(png_ptr, colorspace, name, profile_length)) + if (!icc_check_length(png_ptr, name, profile_length)) return 0; /* This needs to be here because the 'normal' check is in @@ -2070,30 +1600,17 @@ png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, * the caller supplies the profile buffer so libpng doesn't allocate it. See * the call to icc_check_length below (the write case). */ -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - else if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds application limits"); -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds libpng limits"); -# else /* !SET_USER_LIMITS */ - /* This will get compiled out on all 32-bit and better systems. */ - else if (PNG_SIZE_MAX < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds system limits"); -# endif /* !SET_USER_LIMITS */ + if (profile_length > png_chunk_max(png_ptr)) + return png_icc_profile_error(png_ptr, name, profile_length, + "profile too long"); return 1; } -#endif /* READ_iCCP */ int /* PRIVATE */ -png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile/* first 132 bytes only */, int color_type) +png_icc_check_header(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length, + png_const_bytep profile/* first 132 bytes only */, int color_type) { png_uint_32 temp; @@ -2104,18 +1621,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, */ temp = png_get_uint_32(profile); if (temp != profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "length does not match profile"); temp = (png_uint_32) (*(profile+8)); if (temp > 3 && (profile_length & 3)) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, + return png_icc_profile_error(png_ptr, name, profile_length, "invalid length"); temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ profile_length < 132+12*temp) /* truncated tag table */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "tag count too large"); /* The 'intent' must be valid or we can't store it, ICC limits the intent to @@ -2123,14 +1640,14 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, */ temp = png_get_uint_32(profile+64); if (temp >= 0xffff) /* The ICC limit */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "invalid rendering intent"); /* This is just a warning because the profile may be valid in future * versions. */ if (temp >= PNG_sRGB_INTENT_LAST) - (void)png_icc_profile_error(png_ptr, NULL, name, temp, + (void)png_icc_profile_error(png_ptr, name, temp, "intent outside defined range"); /* At this point the tag table can't be checked because it hasn't necessarily @@ -2147,7 +1664,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, */ temp = png_get_uint_32(profile+36); /* signature 'ascp' */ if (temp != 0x61637370) - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "invalid signature"); /* Currently the PCS illuminant/adopted white point (the computational @@ -2158,7 +1675,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, * following is just a warning. */ if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) - (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, + (void)png_icc_profile_error(png_ptr, name, 0/*no tag value*/, "PCS illuminant is not D50"); /* The PNG spec requires this: @@ -2186,18 +1703,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, { case 0x52474220: /* 'RGB ' */ if ((color_type & PNG_COLOR_MASK_COLOR) == 0) - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "RGB color space not permitted on grayscale PNG"); break; case 0x47524159: /* 'GRAY' */ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "Gray color space not permitted on RGB PNG"); break; default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "invalid ICC profile color space"); } @@ -2222,7 +1739,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, case 0x61627374: /* 'abst' */ /* May not be embedded in an image */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "invalid embedded Abstract ICC profile"); case 0x6c696e6b: /* 'link' */ @@ -2232,7 +1749,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, * therefore a DeviceLink profile should not be found embedded in a * PNG. */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "unexpected DeviceLink ICC profile class"); case 0x6e6d636c: /* 'nmcl' */ @@ -2240,7 +1757,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, * contain an AToB0 tag that is open to misinterpretation. Almost * certainly it will fail the tests below. */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, + (void)png_icc_profile_error(png_ptr, name, temp, "unexpected NamedColor ICC profile class"); break; @@ -2250,7 +1767,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, * tag content to ensure they are backward compatible with one of the * understood profiles. */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, + (void)png_icc_profile_error(png_ptr, name, temp, "unrecognized ICC profile class"); break; } @@ -2266,7 +1783,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, break; default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, + return png_icc_profile_error(png_ptr, name, temp, "unexpected ICC PCS encoding"); } @@ -2274,9 +1791,9 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, } int /* PRIVATE */ -png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */) +png_icc_check_tag_table(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length, + png_const_bytep profile /* header plus whole tag table */) { png_uint_32 tag_count = png_get_uint_32(profile+128); png_uint_32 itag; @@ -2302,7 +1819,7 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, * profile. */ if (tag_start > profile_length || tag_length > profile_length - tag_start) - return png_icc_profile_error(png_ptr, colorspace, name, tag_id, + return png_icc_profile_error(png_ptr, name, tag_id, "ICC profile tag outside profile"); if ((tag_start & 3) != 0) @@ -2311,307 +1828,132 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, * only a warning here because libpng does not care about the * alignment. */ - (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, + (void)png_icc_profile_error(png_ptr, name, tag_id, "ICC profile tag start not a multiple of 4"); } } return 1; /* success, maybe with warnings */ } +#endif /* READ_iCCP */ -#ifdef PNG_sRGB_SUPPORTED -#if PNG_sRGB_PROFILE_CHECKS >= 0 -/* Information about the known ICC sRGB profiles */ -static const struct -{ - png_uint_32 adler, crc, length; - png_uint_32 md5[4]; - png_byte have_md5; - png_byte is_broken; - png_uint_16 intent; - -# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) -# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ - { adler, crc, length, md5, broke, intent }, - -} png_sRGB_checks[] = -{ - /* This data comes from contrib/tools/checksum-icc run on downloads of - * all four ICC sRGB profiles from www.color.org. - */ - /* adler32, crc32, MD5[4], intent, date, length, file-name */ - PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, - PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, - "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") - - /* ICC sRGB v2 perceptual no black-compensation: */ - PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, - PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, - "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") - - PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, - PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, - "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") - - /* ICC sRGB v4 perceptual */ - PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, - PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, - "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") - - /* The following profiles have no known MD5 checksum. If there is a match - * on the (empty) MD5 the other fields are used to attempt a match and - * a warning is produced. The first two of these profiles have a 'cprt' tag - * which suggests that they were also made by Hewlett Packard. - */ - PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, - "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") - - /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not - * match the D50 PCS illuminant in the header (it is in fact the D65 values, - * so the white point is recorded as the un-adapted value.) The profiles - * below only differ in one byte - the intent - and are basically the same as - * the previous profile except for the mediaWhitePointTag error and a missing - * chromaticAdaptationTag. - */ - PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") - - PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") -}; - +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +#if (defined PNG_READ_mDCV_SUPPORTED) || (defined PNG_READ_cHRM_SUPPORTED) static int -png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, - png_const_bytep profile, uLong adler) +have_chromaticities(png_const_structrp png_ptr) { - /* The quick check is to verify just the MD5 signature and trust the - * rest of the data. Because the profile has already been verified for - * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' - * field too, so if the profile has been edited with an intent not defined - * by sRGB (but maybe defined by a later ICC specification) the read of - * the profile will fail at that point. + /* Handle new PNGv3 chunks and the precedence rules to determine whether + * png_struct::chromaticities must be processed. Only required for RGB to + * gray. + * + * mDCV: this is the mastering colour space and it is independent of the + * encoding so it needs to be used regardless of the encoded space. + * + * cICP: first in priority but not yet implemented - the chromaticities come + * from the 'primaries'. + * + * iCCP: not supported by libpng (so ignored) + * + * sRGB: the defaults match sRGB + * + * cHRM: calculate the coefficients */ +# ifdef PNG_READ_mDCV_SUPPORTED + if (png_has_chunk(png_ptr, mDCV)) + return 1; +# define check_chromaticities 1 +# endif /*mDCV*/ - png_uint_32 length = 0; - png_uint_32 intent = 0x10000; /* invalid */ -#if PNG_sRGB_PROFILE_CHECKS > 1 - uLong crc = 0; /* the value for 0 length data */ -#endif - unsigned int i; - -#ifdef PNG_SET_OPTION_SUPPORTED - /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ - if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) == - PNG_OPTION_ON) - return 0; -#endif - - for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) - { - if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && - png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && - png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && - png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) - { - /* This may be one of the old HP profiles without an MD5, in that - * case we can only use the length and Adler32 (note that these - * are not used by default if there is an MD5!) - */ -# if PNG_sRGB_PROFILE_CHECKS == 0 - if (png_sRGB_checks[i].have_md5 != 0) - return 1+png_sRGB_checks[i].is_broken; -# endif - - /* Profile is unsigned or more checks have been configured in. */ - if (length == 0) - { - length = png_get_uint_32(profile); - intent = png_get_uint_32(profile+64); - } - - /* Length *and* intent must match */ - if (length == (png_uint_32) png_sRGB_checks[i].length && - intent == (png_uint_32) png_sRGB_checks[i].intent) - { - /* Now calculate the adler32 if not done already. */ - if (adler == 0) - { - adler = adler32(0, NULL, 0); - adler = adler32(adler, profile, length); - } - - if (adler == png_sRGB_checks[i].adler) - { - /* These basic checks suggest that the data has not been - * modified, but if the check level is more than 1 perform - * our own crc32 checksum on the data. - */ -# if PNG_sRGB_PROFILE_CHECKS > 1 - if (crc == 0) - { - crc = crc32(0, NULL, 0); - crc = crc32(crc, profile, length); - } - - /* So this check must pass for the 'return' below to happen. - */ - if (crc == png_sRGB_checks[i].crc) -# endif - { - if (png_sRGB_checks[i].is_broken != 0) - { - /* These profiles are known to have bad data that may cause - * problems if they are used, therefore attempt to - * discourage their use, skip the 'have_md5' warning below, - * which is made irrelevant by this error. - */ - png_chunk_report(png_ptr, "known incorrect sRGB profile", - PNG_CHUNK_ERROR); - } - - /* Warn that this being done; this isn't even an error since - * the profile is perfectly valid, but it would be nice if - * people used the up-to-date ones. - */ - else if (png_sRGB_checks[i].have_md5 == 0) - { - png_chunk_report(png_ptr, - "out-of-date sRGB profile with no signature", - PNG_CHUNK_WARNING); - } +# ifdef PNG_READ_sRGB_SUPPORTED + if (png_has_chunk(png_ptr, sRGB)) + return 0; +# endif /*sRGB*/ - return 1+png_sRGB_checks[i].is_broken; - } - } - -# if PNG_sRGB_PROFILE_CHECKS > 0 - /* The signature matched, but the profile had been changed in some - * way. This probably indicates a data error or uninformed hacking. - * Fall through to "no match". - */ - png_chunk_report(png_ptr, - "Not recognizing known sRGB profile that has been edited", - PNG_CHUNK_WARNING); - break; -# endif - } - } - } +# ifdef PNG_READ_cHRM_SUPPORTED + if (png_has_chunk(png_ptr, cHRM)) + return 1; +# define check_chromaticities 1 +# endif /*cHRM*/ - return 0; /* no match */ + return 0; /* sRGB defaults */ } +#endif /* READ_mDCV || READ_cHRM */ void /* PRIVATE */ -png_icc_set_sRGB(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_bytep profile, uLong adler) +png_set_rgb_coefficients(png_structrp png_ptr) { - /* Is this profile one of the known ICC sRGB profiles? If it is, just set - * the sRGB information. + /* Set the rgb_to_gray coefficients from the colorspace if available. Note + * that '_set' means that png_rgb_to_gray was called **and** it successfully + * set up the coefficients. */ - if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) - (void)png_colorspace_set_sRGB(png_ptr, colorspace, - (int)/*already checked*/png_get_uint_32(profile+64)); -} -#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ -#endif /* sRGB */ - -int /* PRIVATE */ -png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, - int color_type) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && - png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, - color_type) != 0 && - png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, - profile) != 0) + if (png_ptr->rgb_to_gray_coefficients_set == 0) { -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* If no sRGB support, don't try storing sRGB information */ - png_icc_set_sRGB(png_ptr, colorspace, profile, 0); -# endif - return 1; - } +# if check_chromaticities + png_XYZ xyz; - /* Failure case */ - return 0; -} -#endif /* iCCP */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void /* PRIVATE */ -png_colorspace_set_rgb_coefficients(png_structrp png_ptr) -{ - /* Set the rgb_to_gray coefficients from the colorspace. */ - if (png_ptr->rgb_to_gray_coefficients_set == 0 && - (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* png_set_background has not been called, get the coefficients from the Y - * values of the colorspace colorants. - */ - png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; - png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; - png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; - png_fixed_point total = r+g+b; - - if (total > 0 && - r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && - g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && - b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && - r+g+b <= 32769) + if (have_chromaticities(png_ptr) && + png_XYZ_from_xy(&xyz, &png_ptr->chromaticities) == 0) { - /* We allow 0 coefficients here. r+g+b may be 32769 if two or - * all of the coefficients were rounded up. Handle this by - * reducing the *largest* coefficient by 1; this matches the - * approach used for the default coefficients in pngrtran.c + /* png_set_rgb_to_gray has not set the coefficients, get them from the + * Y * values of the colorspace colorants. */ - int add = 0; + png_fixed_point r = xyz.red_Y; + png_fixed_point g = xyz.green_Y; + png_fixed_point b = xyz.blue_Y; + png_fixed_point total = r+g+b; + + if (total > 0 && + r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && + g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && + b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && + r+g+b <= 32769) + { + /* We allow 0 coefficients here. r+g+b may be 32769 if two or + * all of the coefficients were rounded up. Handle this by + * reducing the *largest* coefficient by 1; this matches the + * approach used for the default coefficients in pngrtran.c + */ + int add = 0; - if (r+g+b > 32768) - add = -1; - else if (r+g+b < 32768) - add = 1; + if (r+g+b > 32768) + add = -1; + else if (r+g+b < 32768) + add = 1; - if (add != 0) - { - if (g >= r && g >= b) - g += add; - else if (r >= g && r >= b) - r += add; - else - b += add; - } + if (add != 0) + { + if (g >= r && g >= b) + g += add; + else if (r >= g && r >= b) + r += add; + else + b += add; + } - /* Check for an internal error. */ - if (r+g+b != 32768) - png_error(png_ptr, - "internal error handling cHRM coefficients"); + /* Check for an internal error. */ + if (r+g+b != 32768) + png_error(png_ptr, + "internal error handling cHRM coefficients"); - else - { - png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; - png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; + else + { + png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; + png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; + } } } - - /* This is a png_error at present even though it could be ignored - - * it should never happen, but it is important that if it does, the - * bug is fixed. - */ else - png_error(png_ptr, "internal error handling cHRM->XYZ"); +# endif /* check_chromaticities */ + { + /* Use the historical REC 709 (etc) values: */ + png_ptr->rgb_to_gray_red_coeff = 6968; + png_ptr->rgb_to_gray_green_coeff = 23434; + /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ + } } } #endif /* READ_RGB_TO_GRAY */ -#endif /* COLORSPACE */ - void /* PRIVATE */ png_check_IHDR(png_const_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, @@ -3413,7 +2755,7 @@ png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text) #endif -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) /* muldiv functions */ /* This API takes signed arguments and rounds the result to the nearest @@ -3421,7 +2763,7 @@ png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text) * the nearest .00001). Overflow and divide by zero are signalled in * the result, a boolean - true on success, false on overflow. */ -int +int /* PRIVATE */ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, png_int_32 divisor) { @@ -3535,27 +2877,7 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, return 0; } -#endif /* READ_GAMMA || INCH_CONVERSIONS */ - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* The following is for when the caller doesn't much care about the - * result. - */ -png_fixed_point -png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - png_fixed_point result; - if (png_muldiv(&result, a, times, divisor) != 0) - return result; - - png_warning(png_ptr, "fixed point overflow ignored"); - return 0; -} -#endif - -#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ png_fixed_point png_reciprocal(png_fixed_point a) @@ -3574,26 +2896,38 @@ png_reciprocal(png_fixed_point a) return 0; /* error/overflow */ } +#endif /* READ_GAMMA || COLORSPACE || INCH_CONVERSIONS || READ_pHYS */ +#ifdef PNG_READ_GAMMA_SUPPORTED /* This is the shared test on whether a gamma value is 'significant' - whether * it is worth doing gamma correction. */ int /* PRIVATE */ png_gamma_significant(png_fixed_point gamma_val) { + /* sRGB: 1/2.2 == 0.4545(45) + * AdobeRGB: 1/(2+51/256) ~= 0.45471 5dp + * + * So the correction from AdobeRGB to sRGB (output) is: + * + * 2.2/(2+51/256) == 1.00035524 + * + * I.e. vanishly small (<4E-4) but still detectable in 16-bit linear (+/- + * 23). Note that the Adobe choice seems to be something intended to give an + * exact number with 8 binary fractional digits - it is the closest to 2.2 + * that is possible a base 2 .8p representation. + */ return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; } -#endif -#ifdef PNG_READ_GAMMA_SUPPORTED -#ifdef PNG_16BIT_SUPPORTED +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED /* A local convenience routine. */ static png_fixed_point png_product2(png_fixed_point a, png_fixed_point b) { - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* The required result is a * b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* Should now be unused */ double r = a * 1E-5; r *= b; r = floor(r+.5); @@ -3609,9 +2943,8 @@ png_product2(png_fixed_point a, png_fixed_point b) return 0; /* overflow */ } -#endif /* 16BIT */ +#endif /* FLOATING_ARITHMETIC */ -/* The inverse of the above. */ png_fixed_point png_reciprocal2(png_fixed_point a, png_fixed_point b) { @@ -4264,10 +3597,27 @@ png_destroy_gamma_table(png_structrp png_ptr) * tables, we don't make a full table if we are reducing to 8-bit in * the future. Note also how the gamma_16 tables are segmented so that * we don't need to allocate > 64K chunks for a full 16-bit table. + * + * TODO: move this to pngrtran.c and make it static. Better yet create + * pngcolor.c and put all the PNG_COLORSPACE stuff in there. */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +# define GAMMA_TRANSFORMS 1 /* #ifdef CSE */ +#else +# define GAMMA_TRANSFORMS 0 +#endif + void /* PRIVATE */ png_build_gamma_table(png_structrp png_ptr, int bit_depth) { + png_fixed_point file_gamma, screen_gamma; + png_fixed_point correction; +# if GAMMA_TRANSFORMS + png_fixed_point file_to_linear, linear_to_screen; +# endif + png_debug(1, "in png_build_gamma_table"); /* Remove any existing table; this copes with multiple calls to @@ -4282,27 +3632,44 @@ png_build_gamma_table(png_structrp png_ptr, int bit_depth) png_destroy_gamma_table(png_ptr); } + /* The following fields are set, finally, in png_init_read_transformations. + * If file_gamma is 0 (unset) nothing can be done otherwise if screen_gamma + * is 0 (unset) there is no gamma correction but to/from linear is possible. + */ + file_gamma = png_ptr->file_gamma; + screen_gamma = png_ptr->screen_gamma; +# if GAMMA_TRANSFORMS + file_to_linear = png_reciprocal(file_gamma); +# endif + + if (screen_gamma > 0) + { +# if GAMMA_TRANSFORMS + linear_to_screen = png_reciprocal(screen_gamma); +# endif + correction = png_reciprocal2(screen_gamma, file_gamma); + } + else /* screen gamma unknown */ + { +# if GAMMA_TRANSFORMS + linear_to_screen = file_gamma; +# endif + correction = PNG_FP_1; + } + if (bit_depth <= 8) { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, - png_ptr->screen_gamma > 0 ? - png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, correction); -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +#if GAMMA_TRANSFORMS if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->colorspace.gamma)); + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, file_to_linear); png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? - png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + linear_to_screen); } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#endif /* GAMMA_TRANSFORMS */ } #ifdef PNG_16BIT_SUPPORTED else @@ -4368,32 +3735,26 @@ png_build_gamma_table(png_structrp png_ptr, int bit_depth) * reduced to 8 bits. */ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_reciprocal(correction)); else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + correction); -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +# if GAMMA_TRANSFORMS if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) { png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->colorspace.gamma)); + file_to_linear); /* Notice that the '16 from 1' table should be full precision, however * the lookup on this table still uses gamma_shift, so it can't be. * TODO: fix this. */ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + linear_to_screen); } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#endif /* GAMMA_TRANSFORMS */ } #endif /* 16BIT */ } diff --git a/source/libs/libpng/libpng-src/png.h b/source/libs/libpng/libpng-src/png.h index 6fd6129b9..9b069e4ee 100644 --- a/source/libs/libpng/libpng-src/png.h +++ b/source/libs/libpng/libpng-src/png.h @@ -1,6 +1,6 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.46 + * libpng version 1.6.47 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson @@ -14,7 +14,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.46, January 2025: + * libpng versions 1.6.36, December 2018, through 1.6.47, February 2025: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -238,7 +238,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.46 16 10646 16.so.16.46[.0] + * 1.6.47 16 10647 16.so.16.47[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -274,7 +274,7 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.46" +#define PNG_LIBPNG_VER_STRING "1.6.47" #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" /* The versions of shared library builds should stay in sync, going forward */ @@ -285,7 +285,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 46 +#define PNG_LIBPNG_VER_RELEASE 47 /* This should be zero for a public release, or non-zero for a * development version. @@ -316,7 +316,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10646 /* 1.6.46 */ +#define PNG_LIBPNG_VER 10647 /* 1.6.47 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -426,7 +426,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_46; +typedef char* png_libpng_version_1_6_47; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * diff --git a/source/libs/libpng/libpng-src/pngconf.h b/source/libs/libpng/libpng-src/pngconf.h index 6bc46bcfc..42fa973c2 100644 --- a/source/libs/libpng/libpng-src/pngconf.h +++ b/source/libs/libpng/libpng-src/pngconf.h @@ -1,6 +1,6 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.46 + * libpng version 1.6.47 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson diff --git a/source/libs/libpng/libpng-src/pngerror.c b/source/libs/libpng/libpng-src/pngerror.c index aa0ae58e1..275b188d0 100644 --- a/source/libs/libpng/libpng-src/pngerror.c +++ b/source/libs/libpng/libpng-src/pngerror.c @@ -935,23 +935,37 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) int /* PRIVATE */ png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg) { - png_voidp saved_error_buf = image->opaque->error_buf; + const png_voidp saved_error_buf = image->opaque->error_buf; jmp_buf safe_jmpbuf; - int result; /* Safely execute function(arg), with png_error returning back here. */ if (setjmp(safe_jmpbuf) == 0) { + int result; + image->opaque->error_buf = safe_jmpbuf; result = function(arg); image->opaque->error_buf = saved_error_buf; - return result; + + if (result) + return 1; /* success */ } - /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */ + /* The function failed either because of a caught png_error and a regular + * return of false above or because of an uncaught png_error from the + * function itself. Ensure that the error_buf is always set back to the + * value saved above: + */ image->opaque->error_buf = saved_error_buf; - png_image_free(image); - return 0; + + /* On the final false return, when about to return control to the caller, the + * image is freed (png_image_free does this check but it is duplicated here + * for clarity: + */ + if (saved_error_buf == NULL) + png_image_free(image); + + return 0; /* failure */ } #endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ #endif /* READ || WRITE */ diff --git a/source/libs/libpng/libpng-src/pngget.c b/source/libs/libpng/libpng-src/pngget.c index 2c646aee1..3623c5c7c 100644 --- a/source/libs/libpng/libpng-src/pngget.c +++ b/source/libs/libpng/libpng-src/pngget.c @@ -380,7 +380,13 @@ png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) * Notice that this can overflow - a warning is output and 0 is * returned. */ - return png_muldiv_warn(png_ptr, microns, 500, 127); + png_fixed_point result; + + if (png_muldiv(&result, microns, 500, 127) != 0) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); + return 0; } png_fixed_point PNGAPI @@ -390,7 +396,7 @@ png_get_x_offset_inches_fixed(png_const_structrp png_ptr, return png_fixed_inches_from_microns(png_ptr, png_get_x_offset_microns(png_ptr, info_ptr)); } -#endif +#endif /* FIXED_POINT */ #ifdef PNG_FIXED_POINT_SUPPORTED png_fixed_point PNGAPI @@ -518,44 +524,31 @@ png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, # ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *white_x, double *white_y, double *red_x, double *red_y, - double *green_x, double *green_y, double *blue_x, double *blue_y) + double *whitex, double *whitey, double *redx, double *redy, + double *greenx, double *greeny, double *bluex, double *bluey) { png_debug1(1, "in %s retrieval function", "cHRM"); - /* Quiet API change: this code used to only return the end points if a cHRM - * chunk was present, but the end points can also come from iCCP or sRGB - * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and - * the png_set_ APIs merely check that set end points are mutually - * consistent. - */ + /* PNGv3: this just returns the values store from the cHRM, if any. */ if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + (info_ptr->valid & PNG_INFO_cHRM) != 0) { - if (white_x != NULL) - *white_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); - if (white_y != NULL) - *white_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); - if (red_x != NULL) - *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, - "cHRM red X"); - if (red_y != NULL) - *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, - "cHRM red Y"); - if (green_x != NULL) - *green_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); - if (green_y != NULL) - *green_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); - if (blue_x != NULL) - *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, - "cHRM blue X"); - if (blue_y != NULL) - *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, - "cHRM blue Y"); + if (whitex != NULL) + *whitex = png_float(png_ptr, info_ptr->cHRM.whitex, "cHRM wx"); + if (whitey != NULL) + *whitey = png_float(png_ptr, info_ptr->cHRM.whitey, "cHRM wy"); + if (redx != NULL) + *redx = png_float(png_ptr, info_ptr->cHRM.redx, "cHRM rx"); + if (redy != NULL) + *redy = png_float(png_ptr, info_ptr->cHRM.redy, "cHRM ry"); + if (greenx != NULL) + *greenx = png_float(png_ptr, info_ptr->cHRM.greenx, "cHRM gx"); + if (greeny != NULL) + *greeny = png_float(png_ptr, info_ptr->cHRM.greeny, "cHRM gy"); + if (bluex != NULL) + *bluex = png_float(png_ptr, info_ptr->cHRM.bluex, "cHRM bx"); + if (bluey != NULL) + *bluey = png_float(png_ptr, info_ptr->cHRM.bluey, "cHRM by"); return PNG_INFO_cHRM; } @@ -568,38 +561,31 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, double *green_Y, double *green_Z, double *blue_X, double *blue_Y, double *blue_Z) { + png_XYZ XYZ; png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + (info_ptr->valid & PNG_INFO_cHRM) != 0 && + png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0) { if (red_X != NULL) - *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, - "cHRM red X"); + *red_X = png_float(png_ptr, XYZ.red_X, "cHRM red X"); if (red_Y != NULL) - *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, - "cHRM red Y"); + *red_Y = png_float(png_ptr, XYZ.red_Y, "cHRM red Y"); if (red_Z != NULL) - *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, - "cHRM red Z"); + *red_Z = png_float(png_ptr, XYZ.red_Z, "cHRM red Z"); if (green_X != NULL) - *green_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); + *green_X = png_float(png_ptr, XYZ.green_X, "cHRM green X"); if (green_Y != NULL) - *green_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); + *green_Y = png_float(png_ptr, XYZ.green_Y, "cHRM green Y"); if (green_Z != NULL) - *green_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); + *green_Z = png_float(png_ptr, XYZ.green_Z, "cHRM green Z"); if (blue_X != NULL) - *blue_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); + *blue_X = png_float(png_ptr, XYZ.blue_X, "cHRM blue X"); if (blue_Y != NULL) - *blue_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); + *blue_Y = png_float(png_ptr, XYZ.blue_Y, "cHRM blue Y"); if (blue_Z != NULL) - *blue_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); + *blue_Z = png_float(png_ptr, XYZ.blue_Z, "cHRM blue Z"); return PNG_INFO_cHRM; } @@ -616,29 +602,22 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, png_fixed_point *int_blue_Z) { + png_XYZ XYZ; png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + (info_ptr->valid & PNG_INFO_cHRM) != 0U && + png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0) { - if (int_red_X != NULL) - *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; - if (int_red_Y != NULL) - *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; - if (int_red_Z != NULL) - *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; - if (int_green_X != NULL) - *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; - if (int_green_Y != NULL) - *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; - if (int_green_Z != NULL) - *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; - if (int_blue_X != NULL) - *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; - if (int_blue_Y != NULL) - *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; - if (int_blue_Z != NULL) - *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; + if (int_red_X != NULL) *int_red_X = XYZ.red_X; + if (int_red_Y != NULL) *int_red_Y = XYZ.red_Y; + if (int_red_Z != NULL) *int_red_Z = XYZ.red_Z; + if (int_green_X != NULL) *int_green_X = XYZ.green_X; + if (int_green_Y != NULL) *int_green_Y = XYZ.green_Y; + if (int_green_Z != NULL) *int_green_Z = XYZ.green_Z; + if (int_blue_X != NULL) *int_blue_X = XYZ.blue_X; + if (int_blue_Y != NULL) *int_blue_Y = XYZ.blue_Y; + if (int_blue_Z != NULL) *int_blue_Z = XYZ.blue_Z; return PNG_INFO_cHRM; } @@ -647,31 +626,24 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 PNGAPI png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) + png_fixed_point *whitex, png_fixed_point *whitey, png_fixed_point *redx, + png_fixed_point *redy, png_fixed_point *greenx, png_fixed_point *greeny, + png_fixed_point *bluex, png_fixed_point *bluey) { png_debug1(1, "in %s retrieval function", "cHRM"); + /* PNGv3: this just returns the values store from the cHRM, if any. */ if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + (info_ptr->valid & PNG_INFO_cHRM) != 0) { - if (white_x != NULL) - *white_x = info_ptr->colorspace.end_points_xy.whitex; - if (white_y != NULL) - *white_y = info_ptr->colorspace.end_points_xy.whitey; - if (red_x != NULL) - *red_x = info_ptr->colorspace.end_points_xy.redx; - if (red_y != NULL) - *red_y = info_ptr->colorspace.end_points_xy.redy; - if (green_x != NULL) - *green_x = info_ptr->colorspace.end_points_xy.greenx; - if (green_y != NULL) - *green_y = info_ptr->colorspace.end_points_xy.greeny; - if (blue_x != NULL) - *blue_x = info_ptr->colorspace.end_points_xy.bluex; - if (blue_y != NULL) - *blue_y = info_ptr->colorspace.end_points_xy.bluey; + if (whitex != NULL) *whitex = info_ptr->cHRM.whitex; + if (whitey != NULL) *whitey = info_ptr->cHRM.whitey; + if (redx != NULL) *redx = info_ptr->cHRM.redx; + if (redy != NULL) *redy = info_ptr->cHRM.redy; + if (greenx != NULL) *greenx = info_ptr->cHRM.greenx; + if (greeny != NULL) *greeny = info_ptr->cHRM.greeny; + if (bluex != NULL) *bluex = info_ptr->cHRM.bluex; + if (bluey != NULL) *bluey = info_ptr->cHRM.bluey; return PNG_INFO_cHRM; } @@ -688,11 +660,11 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, { png_debug1(1, "in %s retrieval function", "gAMA"); + /* PNGv3 compatibility: only report gAMA if it is really present. */ if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) + (info_ptr->valid & PNG_INFO_gAMA) != 0) { - *file_gamma = info_ptr->colorspace.gamma; + if (file_gamma != NULL) *file_gamma = info_ptr->gamma; return PNG_INFO_gAMA; } @@ -707,12 +679,13 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, { png_debug1(1, "in %s retrieval function", "gAMA(float)"); + /* PNGv3 compatibility: only report gAMA if it is really present. */ if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) + (info_ptr->valid & PNG_INFO_gAMA) != 0) { - *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, - "png_get_gAMA"); + if (file_gamma != NULL) + *file_gamma = png_float(png_ptr, info_ptr->gamma, "gAMA"); + return PNG_INFO_gAMA; } @@ -729,9 +702,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, png_debug1(1, "in %s retrieval function", "sRGB"); if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) + (info_ptr->valid & PNG_INFO_sRGB) != 0) { - *file_srgb_intent = info_ptr->colorspace.rendering_intent; + if (file_srgb_intent != NULL) + *file_srgb_intent = info_ptr->rendering_intent; return PNG_INFO_sRGB; } diff --git a/source/libs/libpng/libpng-src/pnginfo.h b/source/libs/libpng/libpng-src/pnginfo.h index 4e55da397..c2a907bc5 100644 --- a/source/libs/libpng/libpng-src/pnginfo.h +++ b/source/libs/libpng/libpng-src/pnginfo.h @@ -86,20 +86,6 @@ struct png_info_def * and initialize the appropriate fields below. */ -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are - * defined. When COLORSPACE is switched on all the colorspace-defining - * chunks should be enabled, when GAMMA is switched on all the gamma-defining - * chunks should be enabled. If this is not done it becomes possible to read - * inconsistent PNG files and assign a probably incorrect interpretation to - * the information. (In other words, by carefully choosing which chunks to - * recognize the system configuration can select an interpretation for PNG - * files containing ambiguous data and this will result in inconsistent - * behavior between different libpng builds!) - */ - png_colorspace colorspace; -#endif - #ifdef PNG_cICP_SUPPORTED /* cICP chunk data */ png_byte cicp_colour_primaries; @@ -211,11 +197,8 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) #endif #ifdef PNG_eXIf_SUPPORTED - int num_exif; /* Added at libpng-1.6.31 */ + png_uint_32 num_exif; /* Added at libpng-1.6.31 */ png_bytep exif; -# ifdef PNG_READ_eXIf_SUPPORTED - png_bytep eXIf_buf; /* Added at libpng-1.6.32 */ -# endif #endif #ifdef PNG_hIST_SUPPORTED @@ -288,5 +271,16 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytepp row_pointers; /* the image bits */ #endif +#ifdef PNG_cHRM_SUPPORTED + png_xy cHRM; +#endif + +#ifdef PNG_gAMA_SUPPORTED + png_fixed_point gamma; +#endif + +#ifdef PNG_sRGB_SUPPORTED + int rendering_intent; +#endif }; #endif /* PNGINFO_H */ diff --git a/source/libs/libpng/libpng-src/pnglibconf.h b/source/libs/libpng/libpng-src/pnglibconf.h index b7f6928a0..748220bfc 100644 --- a/source/libs/libpng/libpng-src/pnglibconf.h +++ b/source/libs/libpng/libpng-src/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.46 */ +/* libpng version 1.6.47 */ /* Copyright (c) 2018-2025 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/source/libs/libpng/libpng-src/pngmem.c b/source/libs/libpng/libpng-src/pngmem.c index d391c13ff..90c13b106 100644 --- a/source/libs/libpng/libpng-src/pngmem.c +++ b/source/libs/libpng/libpng-src/pngmem.c @@ -72,30 +72,29 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), * to implement a user memory handler. This checks to be sure it isn't * called with big numbers. */ -#ifndef PNG_USER_MEM_SUPPORTED - PNG_UNUSED(png_ptr) -#endif +# ifdef PNG_MAX_MALLOC_64K + /* This is support for legacy systems which had segmented addressing + * limiting the maximum allocation size to 65536. It takes precedence + * over PNG_SIZE_MAX which is set to 65535 on true 16-bit systems. + * + * TODO: libpng-1.8: finally remove both cases. + */ + if (size > 65536U) return NULL; +# endif - /* Some compilers complain that this is always true. However, it - * can be false when integer overflow happens. + /* This is checked too because the system malloc call below takes a (size_t). */ - if (size > 0 && size <= PNG_SIZE_MAX -# ifdef PNG_MAX_MALLOC_64K - && size <= 65536U -# endif - ) - { -#ifdef PNG_USER_MEM_SUPPORTED + if (size > PNG_SIZE_MAX) return NULL; + +# ifdef PNG_USER_MEM_SUPPORTED if (png_ptr != NULL && png_ptr->malloc_fn != NULL) return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); +# else + PNG_UNUSED(png_ptr) +# endif - else -#endif - return malloc((size_t)size); /* checked for truncation above */ - } - - else - return NULL; + /* Use the system malloc */ + return malloc((size_t)/*SAFE*/size); /* checked for truncation above */ } #if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ diff --git a/source/libs/libpng/libpng-src/pngpread.c b/source/libs/libpng/libpng-src/pngpread.c index d67a5676f..60d810693 100644 --- a/source/libs/libpng/libpng-src/pngpread.c +++ b/source/libs/libpng/libpng-src/pngpread.c @@ -193,17 +193,8 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) */ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - png_check_chunk_length(png_ptr, png_ptr->push_length); + png_ptr->push_length = png_read_chunk_header(png_ptr); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } @@ -244,13 +235,13 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) png_error(png_ptr, "Invalid IHDR length"); PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); + png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); } else if (chunk_name == png_IEND) { PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); + png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); png_ptr->process_mode = PNG_READ_DONE_MODE; png_push_have_end(png_ptr, info_ptr); @@ -267,12 +258,6 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) } #endif - else if (chunk_name == png_PLTE) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); - } - else if (chunk_name == png_IDAT) { png_ptr->idat_size = png_ptr->push_length; @@ -285,179 +270,10 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) return; } -#ifdef PNG_READ_gAMA_SUPPORTED - else if (png_ptr->chunk_name == png_gAMA) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - else if (png_ptr->chunk_name == png_sBIT) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - else if (png_ptr->chunk_name == png_cHRM) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_cICP_SUPPORTED - else if (png_ptr->chunk_name == png_cICP) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_cICP(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_cLLI_SUPPORTED - else if (png_ptr->chunk_name == png_cLLI) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_cLLI(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_mDCV_SUPPORTED - else if (png_ptr->chunk_name == png_mDCV) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_mDCV(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_eXIf_SUPPORTED - else if (png_ptr->chunk_name == png_eXIf) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - else if (png_ptr->chunk_name == png_iCCP) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - else { PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); } png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; diff --git a/source/libs/libpng/libpng-src/pngpriv.h b/source/libs/libpng/libpng-src/pngpriv.h index aeda39f0a..d514dff5c 100644 --- a/source/libs/libpng/libpng-src/pngpriv.h +++ b/source/libs/libpng/libpng-src/pngpriv.h @@ -671,7 +671,7 @@ #define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U #define PNG_FLAG_CRC_CRITICAL_USE 0x0400U #define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U -#define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */ +/* PNG_FLAG_ASSUME_sRGB unused 0x1000U * Added to libpng-1.5.4 */ #define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */ #define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */ /* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */ @@ -802,11 +802,31 @@ * * PNG_32b correctly produces a value shifted by up to 24 bits, even on * architectures where (int) is only 16 bits. + * + * 1.6.47: PNG_32b was made into a preprocessor evaluable macro by replacing the + * static_cast with a promoting binary operation using a guaranteed 32-bit + * (minimum) unsigned value. */ -#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) +#define PNG_32b(b,s) (((0xFFFFFFFFU)&(b)) << (s)) #define PNG_U32(b1,b2,b3,b4) \ (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) +/* Chunk name validation. When using these macros all the arguments should be + * constants, otherwise code bloat may well occur. The macros are provided + * primarily for use in #if checks. + * + * PNG_32to8 produces a byte value with the right shift; used to extract the + * byte value from a chunk name. + */ +#define PNG_32to8(cn,s) (((cn) >> (s)) & 0xffU) +#define PNG_CN_VALID_UPPER(b) ((b) >= 65 && (b) <= 90) /* upper-case ASCII */ +#define PNG_CN_VALID_ASCII(b) PNG_CN_VALID_UPPER((b) & ~32U) +#define PNG_CHUNK_NAME_VALID(cn) (\ + PNG_CN_VALID_ASCII(PNG_32to8(cn,24)) && /* critical, !ancillary */\ + PNG_CN_VALID_ASCII(PNG_32to8(cn,16)) && /* public, !privately defined */\ + PNG_CN_VALID_UPPER(PNG_32to8(cn, 8)) && /* VALID, !reserved */\ + PNG_CN_VALID_ASCII(PNG_32to8(cn, 0)) /* data-dependent, !copy ok */) + /* Constants for known chunk types. * * MAINTAINERS: If you need to add a chunk, define the name here. @@ -834,11 +854,14 @@ #define png_IEND PNG_U32( 73, 69, 78, 68) #define png_IHDR PNG_U32( 73, 72, 68, 82) #define png_PLTE PNG_U32( 80, 76, 84, 69) +#define png_acTL PNG_U32( 97, 99, 84, 76) /* PNGv3: APNG */ #define png_bKGD PNG_U32( 98, 75, 71, 68) #define png_cHRM PNG_U32( 99, 72, 82, 77) #define png_cICP PNG_U32( 99, 73, 67, 80) /* PNGv3 */ #define png_cLLI PNG_U32( 99, 76, 76, 73) /* PNGv3 */ #define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */ +#define png_fcTL PNG_U32(102, 99, 84, 76) /* PNGv3: APNG */ +#define png_fdAT PNG_U32(102, 100, 65, 84) /* PNGv3: APNG */ #define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ #define png_gAMA PNG_U32(103, 65, 77, 65) #define png_gIFg PNG_U32(103, 73, 70, 103) @@ -888,11 +911,74 @@ #define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) #define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) +/* Known chunks. All supported chunks must be listed here. The macro PNG_CHUNK + * contains the four character ASCII name by which the chunk is identified. The + * macro is implemented as required to build tables or switch statements which + * require entries for every known chunk. The macro also contains an index + * value which should be in order (this is checked in png.c). + * + * Notice that "known" does not require "SUPPORTED"; tables should be built in + * such a way that chunks unsupported in a build require no more than the table + * entry (which should be small.) In particular function pointers for + * unsupported chunks should be NULL. + * + * At present these index values are not exported (not part of the public API) + * so can be changed at will. For convenience the names are in lexical sort + * order but with the critical chunks at the start in the order of occurence in + * a PNG. + * + * PNG_INFO_ values do not exist for every one of these chunk handles; for + * example PNG_INFO_{IDAT,IEND,tEXt,iTXt,zTXt} and possibly other chunks in the + * future. + */ +#define PNG_KNOWN_CHUNKS\ + PNG_CHUNK(IHDR, 0)\ + PNG_CHUNK(PLTE, 1)\ + PNG_CHUNK(IDAT, 2)\ + PNG_CHUNK(IEND, 3)\ + PNG_CHUNK(acTL, 4)\ + PNG_CHUNK(bKGD, 5)\ + PNG_CHUNK(cHRM, 6)\ + PNG_CHUNK(cICP, 7)\ + PNG_CHUNK(cLLI, 8)\ + PNG_CHUNK(eXIf, 9)\ + PNG_CHUNK(fcTL, 10)\ + PNG_CHUNK(fdAT, 11)\ + PNG_CHUNK(gAMA, 12)\ + PNG_CHUNK(hIST, 13)\ + PNG_CHUNK(iCCP, 14)\ + PNG_CHUNK(iTXt, 15)\ + PNG_CHUNK(mDCV, 16)\ + PNG_CHUNK(oFFs, 17)\ + PNG_CHUNK(pCAL, 18)\ + PNG_CHUNK(pHYs, 19)\ + PNG_CHUNK(sBIT, 20)\ + PNG_CHUNK(sCAL, 21)\ + PNG_CHUNK(sPLT, 22)\ + PNG_CHUNK(sRGB, 23)\ + PNG_CHUNK(tEXt, 24)\ + PNG_CHUNK(tIME, 25)\ + PNG_CHUNK(tRNS, 26)\ + PNG_CHUNK(zTXt, 27) + /* Gamma values (new at libpng-1.5.4): */ #define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ #define PNG_GAMMA_MAC_INVERSE 65909 #define PNG_GAMMA_sRGB_INVERSE 45455 +/* gamma sanity check. libpng cannot implement gamma transforms outside a + * certain limit because of its use of 16-bit fixed point intermediate values. + * Gamma values that are too large or too small will zap the 16-bit values all + * to 0 or 65535 resulting in an obvious 'bad' image. + * + * In libpng 1.6.0 the limits were changed from 0.07..3 to 0.01..100 to + * accommodate the optimal 16-bit gamma of 36 and its reciprocal. + * + * These are png_fixed_point integral values: + */ +#define PNG_LIB_GAMMA_MIN 1000 +#define PNG_LIB_GAMMA_MAX 10000000 + /* Almost everything below is C specific; the #defines above can be used in * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. */ @@ -956,7 +1042,6 @@ extern "C" { * * All of these functions must be declared with PNG_INTERNAL_FUNCTION. */ - /* Zlib support */ #define PNG_UNEXPECTED_ZLIB_RETURN (-7) PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret), @@ -996,6 +1081,25 @@ PNG_INTERNAL_FUNCTION(png_uint_32,png_fixed_ITU,(png_const_structrp png_ptr, PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr, png_const_charp user_png_ver),PNG_EMPTY); +#ifdef PNG_READ_SUPPORTED /* should only be used on read */ +/* Security: read limits on the largest allocations while reading a PNG. This + * avoids very large allocations caused by PNG files with damaged or altered + * chunk 'length' fields. + */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED /* run-time limit */ +# define png_chunk_max(png_ptr) ((png_ptr)->user_chunk_malloc_max) + +#elif PNG_USER_CHUNK_MALLOC_MAX > 0 /* compile-time limit */ +# define png_chunk_max(png_ptr) ((void)png_ptr, PNG_USER_CHUNK_MALLOC_MAX) + +#elif (defined PNG_MAX_MALLOC_64K) /* legacy system limit */ +# define png_chunk_max(png_ptr) ((void)png_ptr, 65536U) + +#else /* modern system limit SIZE_MAX (C99) */ +# define png_chunk_max(png_ptr) ((void)png_ptr, PNG_SIZE_MAX) +#endif +#endif /* READ */ + /* Internal base allocator - no messages, NULL on failure to allocate. This * does, however, call the application provided allocator and that could call * png_error (although that would be a bug in the application implementation.) @@ -1095,9 +1199,6 @@ PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, png_uint_32 skip),PNG_EMPTY); -/* Read the CRC from the file and compare it to the libpng calculated CRC */ -PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); - /* Calculate the CRC over a section of data. Note that we are only * passing a maximum of 64K on systems that have this as a memory limit, * since this is the maximum buffer size we can specify. @@ -1175,10 +1276,10 @@ PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr, #ifdef PNG_WRITE_iCCP_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, - png_const_charp name, png_const_bytep profile), PNG_EMPTY); - /* The profile must have been previously validated for correctness, the - * length comes from the first four bytes. Only the base, deflate, - * compression is supported. + png_const_charp name, png_const_bytep profile, png_uint_32 proflen), + PNG_EMPTY); + /* Writes a previously 'set' profile. The profile argument is **not** + * compressed. */ #endif @@ -1487,134 +1588,36 @@ PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info, /* The following decodes the appropriate chunks, and does error correction, * then calls the appropriate callback for the chunk if it is valid. */ - -/* Decode the IHDR chunk */ -PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - -#ifdef PNG_READ_bKGD_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_cICP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_cICP,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_cLLI_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_cLLI,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif /* READ_iCCP */ - -#ifdef PNG_READ_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_mDCV_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_mDCV,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif /* READ_sPLT */ - -#ifdef PNG_READ_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, - png_uint_32 chunk_name),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, - png_uint_32 chunk_length),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); +typedef enum +{ + /* Result of a call to png_handle_chunk made to handle the current chunk + * png_struct::chunk_name on read. Always informational, either the stream + * is read for the next chunk or the routine will call png_error. + * + * NOTE: order is important internally. handled_saved and above are regarded + * as handling the chunk. + */ + handled_error = 0, /* bad crc or known and bad format or too long */ + handled_discarded, /* not saved in the unknown chunk list */ + handled_saved, /* saved in the unknown chunk list */ + handled_ok /* known, supported and handled without error */ +} png_handle_result_code; + +PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_unknown, + (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep), + PNG_EMPTY); /* This is the function that gets called for unknown chunks. The 'keep' * argument is either non-zero for a known chunk that has been set to be * handled as unknown or zero for an unknown chunk. By default the function * just skips the chunk or errors out if it is critical. */ +PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_chunk, + (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + /* This handles the current chunk png_ptr->chunk_name with unread + * data[length] and returns one of the above result codes. + */ + #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling, @@ -1654,8 +1657,6 @@ PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, png_bytep buffer, size_t buffer_length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, png_inforp info_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, @@ -1668,109 +1669,28 @@ PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, png_inforp info_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), PNG_EMPTY); -# ifdef PNG_READ_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif -# ifdef PNG_READ_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif -# ifdef PNG_READ_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif - #endif /* PROGRESSIVE_READ */ -/* Added at libpng version 1.6.0 */ -#ifdef PNG_GAMMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); - /* Set the colorspace gamma with a value provided by the application or by - * the gAMA chunk on read. The value will override anything set by an ICC - * profile. - */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Synchronize the info 'valid' flags with the colorspace */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Copy the png_struct colorspace to the info_struct and call the above to - * synchronize the flags. Checks for NULL info_ptr and does nothing. - */ -#endif - -/* Added at libpng version 1.4.0 */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* These internal functions are for maintaining the colorspace structure within - * a png_info or png_struct (or, indeed, both). - */ -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, - int preferred), PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, - int preferred), PNG_EMPTY); - -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, - png_colorspacerp colorspace, int intent), PNG_EMPTY); - /* This does set the colorspace gAMA and cHRM values too, but doesn't set the - * flags to write them, if it returns false there was a problem and an error - * message has already been output (but the colorspace may still need to be - * synced to record the invalid flag). - */ -#endif /* sRGB */ - #ifdef PNG_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, png_const_bytep profile, int color_type), - PNG_EMPTY); - /* The 'name' is used for information only */ - /* Routines for checking parts of an ICC profile. */ #ifdef PNG_READ_iCCP_SUPPORTED PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length), PNG_EMPTY); + png_const_charp name, png_uint_32 profile_length), PNG_EMPTY); #endif /* READ_iCCP */ PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, + png_const_charp name, png_uint_32 profile_length, png_const_bytep profile /* first 132 bytes only */, int color_type), PNG_EMPTY); PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, + png_const_charp name, png_uint_32 profile_length, png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( - png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_bytep profile, uLong adler), PNG_EMPTY); - /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may - * be zero to indicate that it is not available. It is used, if provided, - * as a fast check on the profile when checking to see if it is sRGB. - */ -#endif #endif /* iCCP */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients, - (png_structrp png_ptr), PNG_EMPTY); - /* Set the rgb_to_gray coefficients from the colorspace Y values */ +PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients, (png_structrp png_ptr), + PNG_EMPTY); + /* Set the rgb_to_gray coefficients from the cHRM Y values (if unset) */ #endif /* READ_RGB_TO_GRAY */ -#endif /* COLORSPACE */ /* Added at libpng version 1.4.0 */ PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr, @@ -2032,8 +1952,10 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, size_t size),PNG_EMPTY); #endif /* pCAL || sCAL */ -#if defined(PNG_GAMMA_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ + defined(PNG_COLORSPACE_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) ||\ + defined(PNG_READ_pHYs_SUPPORTED) /* Added at libpng version 1.5.0 */ /* This is a utility to provide a*times/div (rounded) and indicate * if there is an overflow. The result is a boolean - false (0) @@ -2042,22 +1964,14 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, */ PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); -#endif -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* Same deal, but issue a warning on overflow and return 0. */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn, - (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by, - png_int_32 divided_by),PNG_EMPTY); -#endif - -#ifdef PNG_GAMMA_SUPPORTED /* Calculate a reciprocal - used for gamma values. This returns * 0 if the argument is 0 in order to maintain an undefined value; * there are no warnings. */ PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), PNG_EMPTY); +#endif #ifdef PNG_READ_GAMMA_SUPPORTED /* The same but gives a reciprocal of the product of two fixed point @@ -2066,14 +1980,22 @@ PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), */ PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a, png_fixed_point b),PNG_EMPTY); -#endif /* Return true if the gamma value is significantly different from 1.0 */ PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value), PNG_EMPTY); -#endif -#ifdef PNG_READ_GAMMA_SUPPORTED +/* PNGv3: 'resolve' the file gamma according to the new PNGv3 rules for colour + * space information. + * + * NOTE: this uses precisely those chunks that libpng supports. For example it + * doesn't use iCCP and it can only use cICP for known and manageable + * transforms. For this reason a gamma specified by png_set_gamma always takes + * precedence. + */ +PNG_INTERNAL_FUNCTION(png_fixed_point,png_resolve_file_gamma, + (png_const_structrp png_ptr),PNG_EMPTY); + /* Internal fixed point gamma correction. These APIs are called as * required to convert single values - they don't need to be fast, * they are not used when processing image pixel values. @@ -2091,6 +2013,22 @@ PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr, int bit_depth),PNG_EMPTY); +#endif /* READ_GAMMA */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Set the RGB coefficients if not already set by png_set_rgb_to_gray */ +PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients,(png_structrp png_ptr), + PNG_EMPTY); +#endif + +#if defined(PNG_cHRM_SUPPORTED) || defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_INTERNAL_FUNCTION(int,png_XYZ_from_xy,(png_XYZ *XYZ, const png_xy *xy), + PNG_EMPTY); +#endif /* cHRM || READ_RGB_TO_GRAY */ + +#ifdef PNG_COLORSPACE_SUPPORTED +PNG_INTERNAL_FUNCTION(int,png_xy_from_XYZ,(png_xy *xy, const png_XYZ *XYZ), + PNG_EMPTY); #endif /* SIMPLIFIED READ/WRITE SUPPORT */ diff --git a/source/libs/libpng/libpng-src/pngread.c b/source/libs/libpng/libpng-src/pngread.c index 73192f75e..0fd364827 100644 --- a/source/libs/libpng/libpng-src/pngread.c +++ b/source/libs/libpng/libpng-src/pngread.c @@ -131,14 +131,11 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) png_ptr->mode |= PNG_AFTER_IDAT; } - /* This should be a binary subdivision search or a hash for - * matching the chunk name rather than a linear search. - */ if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); + png_handle_chunk(png_ptr, info_ptr, length); else if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); + png_handle_chunk(png_ptr, info_ptr, length); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) @@ -155,8 +152,6 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) } } #endif - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); else if (chunk_name == png_IDAT) { @@ -164,114 +159,8 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) break; } -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cICP_SUPPORTED - else if (chunk_name == png_cICP) - png_handle_cICP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cLLI_SUPPORTED - else if (chunk_name == png_cLLI) - png_handle_cLLI(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED - else if (chunk_name == png_eXIf) - png_handle_eXIf(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_mDCV_SUPPORTED - else if (chunk_name == png_mDCV) - png_handle_mDCV(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - else - png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + png_handle_chunk(png_ptr, info_ptr, length); } } #endif /* SEQUENTIAL_READ */ @@ -816,10 +705,10 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); + png_handle_chunk(png_ptr, info_ptr, length); else if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); + png_handle_chunk(png_ptr, info_ptr, length); else if (info_ptr == NULL) png_crc_finish(png_ptr, length); @@ -853,117 +742,9 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) png_crc_finish(png_ptr, length); } - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cICP_SUPPORTED - else if (chunk_name == png_cICP) - png_handle_cICP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cLLI_SUPPORTED - else if (chunk_name == png_cLLI) - png_handle_cLLI(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED - else if (chunk_name == png_eXIf) - png_handle_eXIf(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_mDCV_SUPPORTED - else if (chunk_name == png_mDCV) - png_handle_mDCV(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif else - png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + png_handle_chunk(png_ptr, info_ptr, length); } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); } #endif /* SEQUENTIAL_READ */ @@ -1414,6 +1195,31 @@ png_image_format(png_structrp png_ptr) return format; } +static int +chromaticities_match_sRGB(const png_xy *xy) +{ +# define sRGB_TOLERANCE 1000 + static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ + { + /* color x y */ + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000, + /* white */ 31270, 32900 + }; + + if (PNG_OUT_OF_RANGE(xy->whitex, sRGB_xy.whitex,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->whitey, sRGB_xy.whitey,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->redx, sRGB_xy.redx, sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->redy, sRGB_xy.redy, sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->greenx, sRGB_xy.greenx,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->greeny, sRGB_xy.greeny,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->bluex, sRGB_xy.bluex, sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->bluey, sRGB_xy.bluey, sRGB_TOLERANCE)) + return 0; + return 1; +} + /* Is the given gamma significantly different from sRGB? The test is the same * one used in pngrtran.c when deciding whether to do gamma correction. The * arithmetic optimizes the division by using the fact that the inverse of the @@ -1422,22 +1228,44 @@ png_image_format(png_structrp png_ptr) static int png_gamma_not_sRGB(png_fixed_point g) { - if (g < PNG_FP_1) - { - /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ - if (g == 0) - return 0; - - return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); - } + /* 1.6.47: use the same sanity checks as used in pngrtran.c */ + if (g < PNG_LIB_GAMMA_MIN || g > PNG_LIB_GAMMA_MAX) + return 0; /* Includes the uninitialized value 0 */ - return 1; + return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); } /* Do the main body of a 'png_image_begin_read' function; read the PNG file * header and fill in all the information. This is executed in a safe context, * unlike the init routine above. */ +static int +png_image_is_not_sRGB(png_const_structrp png_ptr) +{ + /* Does the colorspace **not** match sRGB? The flag is only set if the + * answer can be determined reliably. + * + * png_struct::chromaticities always exists since the simplified API + * requires rgb-to-gray. The mDCV, cICP and cHRM chunks may all set it to + * a non-sRGB value, so it needs to be checked but **only** if one of + * those chunks occured in the file. + */ + /* Highest priority: check to be safe. */ + if (png_has_chunk(png_ptr, cICP) || png_has_chunk(png_ptr, mDCV)) + return !chromaticities_match_sRGB(&png_ptr->chromaticities); + + /* If the image is marked as sRGB then it is... */ + if (png_has_chunk(png_ptr, sRGB)) + return 0; + + /* Last stop: cHRM, must check: */ + if (png_has_chunk(png_ptr, cHRM)) + return !chromaticities_match_sRGB(&png_ptr->chromaticities); + + /* Else default to sRGB */ + return 0; +} + static int png_image_read_header(png_voidp argument) { @@ -1459,17 +1287,13 @@ png_image_read_header(png_voidp argument) image->format = format; -#ifdef PNG_COLORSPACE_SUPPORTED - /* Does the colorspace match sRGB? If there is no color endpoint - * (colorant) information assume yes, otherwise require the - * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the - * colorspace has been determined to be invalid ignore it. + /* Greyscale images don't (typically) have colour space information and + * using it is pretty much impossible, so use sRGB for grayscale (it + * doesn't matter r==g==b so the transform is irrelevant.) */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags - & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| - PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) + if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && + png_image_is_not_sRGB(png_ptr)) image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; -#endif } /* We need the maximum number of entries regardless of the format the @@ -1657,21 +1481,18 @@ png_image_skip_unused_chunks(png_structrp png_ptr) * potential vulnerability to security problems in the unused chunks. * * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored - * too. This allows the simplified API to be compiled without iCCP support, - * however if the support is there the chunk is still checked to detect - * errors (which are unfortunately quite common.) + * too. This allows the simplified API to be compiled without iCCP support. */ { static const png_byte chunks_to_process[] = { 98, 75, 71, 68, '\0', /* bKGD */ 99, 72, 82, 77, '\0', /* cHRM */ + 99, 73, 67, 80, '\0', /* cICP */ 103, 65, 77, 65, '\0', /* gAMA */ -# ifdef PNG_READ_iCCP_SUPPORTED - 105, 67, 67, 80, '\0', /* iCCP */ -# endif + 109, 68, 67, 86, '\0', /* mDCV */ 115, 66, 73, 84, '\0', /* sBIT */ 115, 82, 71, 66, '\0', /* sRGB */ - }; + }; /* Ignore unknown chunks and all other chunks except for the * IHDR, PLTE, tRNS, IDAT, and IEND chunks. @@ -1700,7 +1521,15 @@ png_image_skip_unused_chunks(png_structrp png_ptr) static void set_file_encoding(png_image_read_control *display) { - png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; + png_structrp png_ptr = display->image->opaque->png_ptr; + png_fixed_point g = png_resolve_file_gamma(png_ptr); + + /* PNGv3: the result may be 0 however the 'default_gamma' should have been + * set before this is called so zero is an error: + */ + if (g == 0) + png_error(png_ptr, "internal: default gamma not set"); + if (png_gamma_significant(g) != 0) { if (png_gamma_not_sRGB(g) != 0) @@ -2188,24 +2017,18 @@ png_image_read_colormap(png_voidp argument) /* Default the input file gamma if required - this is necessary because * libpng assumes that if no gamma information is present the data is in the * output format, but the simplified API deduces the gamma from the input - * format. + * format. The 'default' gamma value is also set by png_set_alpha_mode, but + * this is happening before any such call, so: + * + * TODO: should be an internal API and all this code should be copied into a + * single common gamma+colorspace file. */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) - { - /* Do this directly, not using the png_colorspace functions, to ensure - * that it happens even if the colorspace is invalid (though probably if - * it is the setting will be ignored) Note that the same thing can be - * achieved at the application interface with png_set_gAMA. - */ - if (png_ptr->bit_depth == 16 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; + if (png_ptr->bit_depth == 16 && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) + png_ptr->default_gamma = PNG_GAMMA_LINEAR; - else - png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; - - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } + else + png_ptr->default_gamma = PNG_GAMMA_sRGB_INVERSE; /* Decide what to do based on the PNG color type of the input data. The * utility function png_create_colormap_entry deals with most aspects of the @@ -2583,6 +2406,8 @@ png_image_read_colormap(png_voidp argument) else { + const png_fixed_point gamma = png_resolve_file_gamma(png_ptr); + /* Either the input or the output has no alpha channel, so there * will be no non-opaque pixels in the color-map; it will just be * grayscale. @@ -2597,10 +2422,13 @@ png_image_read_colormap(png_voidp argument) * this case and doing it in the palette; this will result in * duplicate palette entries, but that's better than the * alternative of double gamma correction. + * + * NOTE: PNGv3: check the resolved result of all the potentially + * different colour space chunks. */ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || png_ptr->num_trans > 0) && - png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) + png_gamma_not_sRGB(gamma) != 0) { cmap_entries = (unsigned int)make_gray_file_colormap(display); data_encoding = P_FILE; @@ -2632,8 +2460,8 @@ png_image_read_colormap(png_voidp argument) if (output_encoding == P_sRGB) gray = png_sRGB_table[gray]; /* now P_LINEAR */ - gray = PNG_DIV257(png_gamma_16bit_correct(gray, - png_ptr->colorspace.gamma)); /* now P_FILE */ + gray = PNG_DIV257(png_gamma_16bit_correct(gray, gamma)); + /* now P_FILE */ /* And make sure the corresponding palette entry contains * exactly the required sRGB value. @@ -3764,6 +3592,12 @@ png_image_read_direct(png_voidp argument) /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. */ { + /* This is safe but should no longer be necessary as + * png_ptr->default_gamma should have been set after the + * info-before-IDAT was read in png_image_read_header. + * + * TODO: 1.8: remove this and see what happens. + */ png_fixed_point input_gamma_default; if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && @@ -3819,8 +3653,9 @@ png_image_read_direct(png_voidp argument) * yet; it's set below. png_struct::gamma, however, is set to the * final value. */ - if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, - PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) + if (png_muldiv(>est, output_gamma, + png_resolve_file_gamma(png_ptr), PNG_FP_1) != 0 && + png_gamma_significant(gtest) == 0) do_local_background = 0; else if (mode == PNG_ALPHA_STANDARD) diff --git a/source/libs/libpng/libpng-src/pngrtran.c b/source/libs/libpng/libpng-src/pngrtran.c index 124906635..a6ce30a52 100644 --- a/source/libs/libpng/libpng-src/pngrtran.c +++ b/source/libs/libpng/libpng-src/pngrtran.c @@ -218,9 +218,59 @@ png_set_strip_alpha(png_structrp png_ptr) #endif #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) +/* PNGv3 conformance: this private API exists to resolve the now mandatory error + * resolution when multiple conflicting sources of gamma or colour space + * information are available. + * + * Terminology (assuming power law, "gamma", encodings): + * "screen" gamma: a power law imposed by the output device when digital + * samples are converted to visible light output. The EOTF - volage to + * luminance on output. + * + * "file" gamma: a power law used to encode luminance levels from the input + * data (the scene or the mastering display system) into digital voltages. + * The OETF - luminance to voltage on input. + * + * gamma "correction": a power law matching the **inverse** of the overall + * transfer function from input luminance levels to output levels. The + * **inverse** of the OOTF; the correction "corrects" for the OOTF by aiming + * to make the overall OOTF (including the correction) linear. + * + * It is important to understand this terminology because the defined terms are + * scattered throughout the libpng code and it is very easy to end up with the + * inverse of the power law required. + * + * Variable and struct::member names: + * file_gamma OETF how the PNG data was encoded + * + * screen_gamma EOTF how the screen will decode digital levels + * + * -- not used -- OOTF the net effect OETF x EOTF + * gamma_correction the inverse of OOTF to make the result linear + * + * All versions of libpng require a call to "png_set_gamma" to establish the + * "screen" gamma, the power law representing the EOTF. png_set_gamma may also + * set or default the "file" gamma; the OETF. gamma_correction is calculated + * internally. + * + * The earliest libpng versions required file_gamma to be supplied to set_gamma. + * Later versions started allowing png_set_gamma and, later, png_set_alpha_mode, + * to cause defaulting from the file data. + * + * PNGv3 mandated a particular form for this defaulting, one that is compatible + * with what libpng did except that if libpng detected inconsistencies it marked + * all the chunks as "invalid". PNGv3 effectively invalidates this prior code. + * + * Behaviour implemented below: + * translate_gamma_flags(gamma, is_screen) + * The libpng-1.6 API for the gamma parameters to libpng APIs + * (png_set_gamma and png_set_alpha_mode at present). This allows the + * 'gamma' value to be passed as a png_fixed_point number or as one of a + * set of integral values for specific "well known" examples of transfer + * functions. This is compatible with PNGv3. + */ static png_fixed_point -translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, - int is_screen) +translate_gamma_flags(png_fixed_point output_gamma, int is_screen) { /* Check for flag values. The main reason for having the old Mac value as a * flag is that it is pretty near impossible to work out what the correct @@ -230,14 +280,6 @@ translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, if (output_gamma == PNG_DEFAULT_sRGB || output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) { - /* If there is no sRGB support this just sets the gamma to the standard - * sRGB value. (This is a side effect of using this function!) - */ -# ifdef PNG_READ_sRGB_SUPPORTED - png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; -# else - PNG_UNUSED(png_ptr) -# endif if (is_screen != 0) output_gamma = PNG_GAMMA_sRGB; else @@ -279,6 +321,33 @@ convert_gamma_value(png_structrp png_ptr, double output_gamma) return (png_fixed_point)output_gamma; } # endif + +static int +unsupported_gamma(png_structrp png_ptr, png_fixed_point gamma, int warn) +{ + /* Validate a gamma value to ensure it is in a reasonable range. The value + * is expected to be 1 or greater, but this range test allows for some + * viewing correction values. The intent is to weed out the API users + * who might use the inverse of the gamma value accidentally! + * + * 1.6.47: apply the test in png_set_gamma as well but only warn and return + * false if it fires. + * + * TODO: 1.8: make this an app_error in png_set_gamma as well. + */ + if (gamma < PNG_LIB_GAMMA_MIN || gamma > PNG_LIB_GAMMA_MAX) + { +# define msg "gamma out of supported range" + if (warn) + png_app_warning(png_ptr, msg); + else + png_app_error(png_ptr, msg); + return 1; +# undef msg + } + + return 0; +} #endif /* READ_ALPHA_MODE || READ_GAMMA */ #ifdef PNG_READ_ALPHA_MODE_SUPPORTED @@ -286,31 +355,29 @@ void PNGFAPI png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, png_fixed_point output_gamma) { - int compose = 0; png_fixed_point file_gamma; + int compose = 0; png_debug(1, "in png_set_alpha_mode_fixed"); if (png_rtran_ok(png_ptr, 0) == 0) return; - output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - - /* Validate the value to ensure it is in a reasonable range. The value - * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out the API users - * who might use the inverse of the gamma value accidentally! - * - * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate - * the optimal 16-bit gamma of 36 and its reciprocal. - */ - if (output_gamma < 1000 || output_gamma > 10000000) - png_error(png_ptr, "output gamma out of expected range"); + output_gamma = translate_gamma_flags(output_gamma, 1/*screen*/); + if (unsupported_gamma(png_ptr, output_gamma, 0/*error*/)) + return; /* The default file gamma is the inverse of the output gamma; the output - * gamma may be changed below so get the file value first: + * gamma may be changed below so get the file value first. The default_gamma + * is set here and from the simplified API (which uses a different algorithm) + * so don't overwrite a set value: */ - file_gamma = png_reciprocal(output_gamma); + file_gamma = png_ptr->default_gamma; + if (file_gamma == 0) + { + file_gamma = png_reciprocal(output_gamma); + png_ptr->default_gamma = file_gamma; + } /* There are really 8 possibilities here, composed of any combination * of: @@ -361,17 +428,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, png_error(png_ptr, "invalid alpha mode"); } - /* Only set the default gamma if the file gamma has not been set (this has - * the side effect that the gamma in a second call to png_set_alpha_mode will - * be ignored.) - */ - if (png_ptr->colorspace.gamma == 0) - { - png_ptr->colorspace.gamma = file_gamma; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* But always set the output gamma: */ + /* Set the screen gamma values: */ png_ptr->screen_gamma = output_gamma; /* Finally, if pre-multiplying, set the background fields to achieve the @@ -381,7 +438,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, { /* And obtain alpha pre-multiplication by composing on black: */ memset(&png_ptr->background, 0, (sizeof png_ptr->background)); - png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ + png_ptr->background_gamma = file_gamma; /* just in case */ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; @@ -819,8 +876,8 @@ png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, return; /* New in libpng-1.5.4 - reserve particular negative values as flags. */ - scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); - file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); + scrn_gamma = translate_gamma_flags(scrn_gamma, 1/*screen*/); + file_gamma = translate_gamma_flags(file_gamma, 0/*file*/); /* Checking the gamma values for being >0 was added in 1.5.4 along with the * premultiplied alpha support; this actually hides an undocumented feature @@ -834,17 +891,19 @@ png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, * libpng-1.6.0. */ if (file_gamma <= 0) - png_error(png_ptr, "invalid file gamma in png_set_gamma"); - + png_app_error(png_ptr, "invalid file gamma in png_set_gamma"); if (scrn_gamma <= 0) - png_error(png_ptr, "invalid screen gamma in png_set_gamma"); + png_app_error(png_ptr, "invalid screen gamma in png_set_gamma"); - /* Set the gamma values unconditionally - this overrides the value in the PNG - * file if a gAMA chunk was present. png_set_alpha_mode provides a - * different, easier, way to default the file gamma. + if (unsupported_gamma(png_ptr, file_gamma, 1/*warn*/) || + unsupported_gamma(png_ptr, scrn_gamma, 1/*warn*/)) + return; + + /* 1.6.47: png_struct::file_gamma and png_struct::screen_gamma are now only + * written by this API. This removes dependencies on the order of API calls + * and allows the complex gamma checks to be delayed until needed. */ - png_ptr->colorspace.gamma = file_gamma; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + png_ptr->file_gamma = file_gamma; png_ptr->screen_gamma = scrn_gamma; } @@ -1022,26 +1081,9 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, png_ptr->rgb_to_gray_coefficients_set = 1; } - else - { - if (red >= 0 && green >= 0) - png_app_warning(png_ptr, - "ignoring out of range rgb_to_gray coefficients"); - - /* Use the defaults, from the cHRM chunk if set, else the historical - * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See - * png_do_rgb_to_gray for more discussion of the values. In this case - * the coefficients are not marked as 'set' and are not overwritten if - * something has already provided a default. - */ - if (png_ptr->rgb_to_gray_red_coeff == 0 && - png_ptr->rgb_to_gray_green_coeff == 0) - { - png_ptr->rgb_to_gray_red_coeff = 6968; - png_ptr->rgb_to_gray_green_coeff = 23434; - /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ - } - } + else if (red >= 0 && green >= 0) + png_app_warning(png_ptr, + "ignoring out of range rgb_to_gray coefficients"); } } @@ -1282,6 +1324,80 @@ png_init_rgb_transformations(png_structrp png_ptr) #endif /* READ_EXPAND && READ_BACKGROUND */ } +#ifdef PNG_READ_GAMMA_SUPPORTED +png_fixed_point /* PRIVATE */ +png_resolve_file_gamma(png_const_structrp png_ptr) +{ + png_fixed_point file_gamma; + + /* The file gamma is determined by these precedence rules, in this order + * (i.e. use the first value found): + * + * png_set_gamma; png_struct::file_gammma if not zero, then: + * png_struct::chunk_gamma if not 0 (determined the PNGv3 rules), then: + * png_set_gamma; 1/png_struct::screen_gamma if not zero + * + * 0 (i.e. do no gamma handling) + */ + file_gamma = png_ptr->file_gamma; + if (file_gamma != 0) + return file_gamma; + + file_gamma = png_ptr->chunk_gamma; + if (file_gamma != 0) + return file_gamma; + + file_gamma = png_ptr->default_gamma; + if (file_gamma != 0) + return file_gamma; + + /* If png_reciprocal oveflows it returns 0 which indicates to the caller that + * there is no usable file gamma. (The checks added to png_set_gamma and + * png_set_alpha_mode should prevent a screen_gamma which would overflow.) + */ + if (png_ptr->screen_gamma != 0) + file_gamma = png_reciprocal(png_ptr->screen_gamma); + + return file_gamma; +} + +static int +png_init_gamma_values(png_structrp png_ptr) +{ + /* The following temporary indicates if overall gamma correction is + * required. + */ + int gamma_correction = 0; + png_fixed_point file_gamma, screen_gamma; + + /* Resolve the file_gamma. See above: if png_ptr::screen_gamma is set + * file_gamma will always be set here: + */ + file_gamma = png_resolve_file_gamma(png_ptr); + screen_gamma = png_ptr->screen_gamma; + + if (file_gamma > 0) /* file has been set */ + { + if (screen_gamma > 0) /* screen set too */ + gamma_correction = png_gamma_threshold(file_gamma, screen_gamma); + + else + /* Assume the output matches the input; a long time default behavior + * of libpng, although the standard has nothing to say about this. + */ + screen_gamma = png_reciprocal(file_gamma); + } + + else /* both unset, prevent corrections: */ + file_gamma = screen_gamma = PNG_FP_1; + + png_ptr->file_gamma = file_gamma; + png_ptr->screen_gamma = screen_gamma; + return gamma_correction; + +} +#endif /* READ_GAMMA */ + void /* PRIVATE */ png_init_read_transformations(png_structrp png_ptr) { @@ -1301,59 +1417,22 @@ png_init_read_transformations(png_structrp png_ptr) * the test needs to be performed later - here. In addition prior to 1.5.4 * the tests were repeated for the PALETTE color type here - this is no * longer necessary (and doesn't seem to have been necessary before.) + * + * PNGv3: the new mandatory precedence/priority rules for colour space chunks + * are handled here (by calling the above function). + * + * Turn the gamma transformation on or off as appropriate. Notice that + * PNG_GAMMA just refers to the file->screen correction. Alpha composition + * may independently cause gamma correction because it needs linear data + * (e.g. if the file has a gAMA chunk but the screen gamma hasn't been + * specified.) In any case this flag may get turned off in the code + * immediately below if the transform can be handled outside the row loop. */ - { - /* The following temporary indicates if overall gamma correction is - * required. - */ - int gamma_correction = 0; + if (png_init_gamma_values(png_ptr) != 0) + png_ptr->transformations |= PNG_GAMMA; - if (png_ptr->colorspace.gamma != 0) /* has been set */ - { - if (png_ptr->screen_gamma != 0) /* screen set too */ - gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - - else - /* Assume the output matches the input; a long time default behavior - * of libpng, although the standard has nothing to say about this. - */ - png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); - } - - else if (png_ptr->screen_gamma != 0) - /* The converse - assume the file matches the screen, note that this - * perhaps undesirable default can (from 1.5.4) be changed by calling - * png_set_alpha_mode (even if the alpha handling mode isn't required - * or isn't changed from the default.) - */ - png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); - - else /* neither are set */ - /* Just in case the following prevents any processing - file and screen - * are both assumed to be linear and there is no way to introduce a - * third gamma value other than png_set_background with 'UNIQUE', and, - * prior to 1.5.4 - */ - png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; - - /* We have a gamma value now. */ - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Now turn the gamma transformation on or off as appropriate. Notice - * that PNG_GAMMA just refers to the file->screen correction. Alpha - * composition may independently cause gamma correction because it needs - * linear data (e.g. if the file has a gAMA chunk but the screen gamma - * hasn't been specified.) In any case this flag may get turned off in - * the code immediately below if the transform can be handled outside the - * row loop. - */ - if (gamma_correction != 0) - png_ptr->transformations |= PNG_GAMMA; - - else - png_ptr->transformations &= ~PNG_GAMMA; - } + else + png_ptr->transformations &= ~PNG_GAMMA; #endif /* Certain transformations have the effect of preventing other @@ -1425,7 +1504,7 @@ png_init_read_transformations(png_structrp png_ptr) * appropriately. */ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - png_colorspace_set_rgb_coefficients(png_ptr); + png_set_rgb_coefficients(png_ptr); #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED @@ -1568,10 +1647,10 @@ png_init_read_transformations(png_structrp png_ptr) */ if ((png_ptr->transformations & PNG_GAMMA) != 0 || ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && - (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || + (png_gamma_significant(png_ptr->file_gamma) != 0 || png_gamma_significant(png_ptr->screen_gamma) != 0)) || ((png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || + (png_gamma_significant(png_ptr->file_gamma) != 0 || png_gamma_significant(png_ptr->screen_gamma) != 0 # ifdef PNG_READ_BACKGROUND_SUPPORTED || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && @@ -1627,8 +1706,8 @@ png_init_read_transformations(png_structrp png_ptr) break; case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, + g = png_reciprocal(png_ptr->file_gamma); + gs = png_reciprocal2(png_ptr->file_gamma, png_ptr->screen_gamma); break; @@ -1736,8 +1815,8 @@ png_init_read_transformations(png_structrp png_ptr) break; case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, + g = png_reciprocal(png_ptr->file_gamma); + gs = png_reciprocal2(png_ptr->file_gamma, png_ptr->screen_gamma); break; @@ -1987,11 +2066,11 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) * been called before this from png_read_update_info->png_read_start_row * sometimes does the gamma transform and cancels the flag. * - * TODO: this looks wrong; the info_ptr should end up with a gamma equal to - * the screen_gamma value. The following probably results in weirdness if - * the info_ptr is used by the app after the rows have been read. + * TODO: this is confusing. It only changes the result of png_get_gAMA and, + * yes, it does return the value that the transformed data effectively has + * but does any app really understand this? */ - info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; + info_ptr->gamma = png_ptr->file_gamma; #endif if (info_ptr->bit_depth == 16) diff --git a/source/libs/libpng/libpng-src/pngrutil.c b/source/libs/libpng/libpng-src/pngrutil.c index a8867cb29..d0f3ed35d 100644 --- a/source/libs/libpng/libpng-src/pngrutil.c +++ b/source/libs/libpng/libpng-src/pngrutil.c @@ -17,6 +17,11 @@ #ifdef PNG_READ_SUPPORTED +/* The minimum 'zlib' stream is assumed to be just the 2 byte header, 5 bytes + * minimum 'deflate' stream, and the 4 byte checksum. + */ +#define LZ77Min (2U+5U+4U) + #ifdef PNG_READ_INTERLACING_SUPPORTED /* Arrays to facilitate interlacing - use pass (0 - 6) as index. */ @@ -43,30 +48,6 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) return uval; } -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) -/* The following is a variation on the above for use with the fixed - * point values used for gAMA and cHRM. Instead of png_error it - * issues a warning and returns (-1) - an invalid value because both - * gAMA and cHRM use *unsigned* integers for fixed point values. - */ -#define PNG_FIXED_ERROR (-1) - -static png_fixed_point /* PRIVATE */ -png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval <= PNG_UINT_31_MAX) - return (png_fixed_point)uval; /* known to be in range */ - - /* The caller can turn off the warning by passing NULL. */ - if (png_ptr != NULL) - png_warning(png_ptr, "PNG fixed point integer out of range"); - - return PNG_FIXED_ERROR; -} -#endif - #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED /* NOTE: the read macros will obscure these definitions, so that if * PNG_USE_READ_MACROS is set the library will not use them internally, @@ -163,6 +144,38 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } +/* This function is called to verify that a chunk name is valid. + * Do this using the bit-whacking approach from contrib/tools/pngfix.c + * + * Copied from libpng 1.7. + */ +static int +check_chunk_name(png_uint_32 name) +{ + png_uint_32 t; + + /* Remove bit 5 from all but the reserved byte; this means + * every 8-bit unit must be in the range 65-90 to be valid. + * So bit 5 must be zero, bit 6 must be set and bit 7 zero. + */ + name &= ~PNG_U32(32,32,0,32); + t = (name & ~0x1f1f1f1fU) ^ 0x40404040U; + + /* Subtract 65 for each 8-bit quantity, this must not + * overflow and each byte must then be in the range 0-25. + */ + name -= PNG_U32(65,65,65,65); + t |= name; + + /* Subtract 26, handling the overflow which should set the + * top three bits of each byte. + */ + name -= PNG_U32(25,25,25,26); + t |= ~name; + + return (t & 0xe0e0e0e0U) == 0U; +} + /* Read the chunk header (length + type name). * Put the type name into png_ptr->chunk_name, and return the length. */ @@ -170,33 +183,36 @@ png_uint_32 /* PRIVATE */ png_read_chunk_header(png_structrp png_ptr) { png_byte buf[8]; - png_uint_32 length; + png_uint_32 chunk_name, length; #ifdef PNG_IO_STATE_SUPPORTED png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; #endif - /* Read the length and the chunk name. - * This must be performed in a single I/O call. + /* Read the length and the chunk name. png_struct::chunk_name is immediately + * updated even if they are detectably wrong. This aids error message + * handling by allowing png_chunk_error to be used. */ png_read_data(png_ptr, buf, 8); length = png_get_uint_31(png_ptr, buf); + png_ptr->chunk_name = chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - /* Put the chunk name into png_ptr->chunk_name. */ - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); + /* Reset the crc and run it over the chunk name. */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, buf + 4, 4); png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu", (unsigned long)png_ptr->chunk_name, (unsigned long)length); - /* Reset the crc and run it over the chunk name. */ - png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, buf + 4, 4); + /* Sanity check the length (first by <= 0x80) and the chunk name. An error + * here indicates a broken stream and libpng has no recovery from this. + */ + if (buf[0] >= 0x80U) + png_chunk_error(png_ptr, "bad header (invalid length)"); /* Check to see if chunk name is valid. */ - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - - /* Check for too-large chunk length */ - png_check_chunk_length(png_ptr, length); + if (!check_chunk_name(chunk_name)) + png_chunk_error(png_ptr, "bad header (invalid type)"); #ifdef PNG_IO_STATE_SUPPORTED png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; @@ -216,13 +232,85 @@ png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) png_calculate_crc(png_ptr, buf, length); } +/* Compare the CRC stored in the PNG file with that calculated by libpng from + * the data it has read thus far. + */ +static int +png_crc_error(png_structrp png_ptr, int handle_as_ancillary) +{ + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + + /* There are four flags two for ancillary and two for critical chunks. The + * default setting of these flags is all zero. + * + * PNG_FLAG_CRC_ANCILLARY_USE + * PNG_FLAG_CRC_ANCILLARY_NOWARN + * USE+NOWARN: no CRC calculation (implemented here), else; + * NOWARN: png_chunk_error on error (implemented in png_crc_finish) + * else: png_chunk_warning on error (implemented in png_crc_finish) + * This is the default. + * + * I.e. NOWARN without USE produces png_chunk_error. The default setting + * where neither are set does the same thing. + * + * PNG_FLAG_CRC_CRITICAL_USE + * PNG_FLAG_CRC_CRITICAL_IGNORE + * IGNORE: no CRC calculation (implemented here), else; + * USE: png_chunk_warning on error (implemented in png_crc_finish) + * else: png_chunk_error on error (implemented in png_crc_finish) + * This is the default. + * + * This arose because of original mis-implementation and has persisted for + * compatibility reasons. + * + * TODO: the flag names are internal so maybe this can be changed to + * something comprehensible. + */ + if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + + else /* critical */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) + need_crc = 0; + } + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; +#endif + + /* The chunk CRC must be serialized in a single I/O call. */ + png_read_data(png_ptr, crc_bytes, 4); + + if (need_crc != 0) + { + crc = png_get_uint_32(crc_bytes); + return crc != png_ptr->crc; + } + + else + return 0; +} + /* Optionally skip data and then check the CRC. Depending on whether we * are reading an ancillary or critical chunk, and how the program has set * things up, we may calculate the CRC on the data and print a message. * Returns '1' if there was a CRC error, '0' otherwise. + * + * There is one public version which is used in most places and another which + * takes the value for the 'critical' flag to check. This allows PLTE and IEND + * handling code to ignore the CRC error and removes some confusing code + * duplication. */ -int /* PRIVATE */ -png_crc_finish(png_structrp png_ptr, png_uint_32 skip) +static int +png_crc_finish_critical(png_structrp png_ptr, png_uint_32 skip, + int handle_as_ancillary) { /* The size of the local buffer for inflate is a good guess as to a * reasonable size to use for buffering reads from the application. @@ -240,14 +328,24 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip) png_crc_read(png_ptr, tmpbuf, len); } - if (png_crc_error(png_ptr) != 0) + /* If 'handle_as_ancillary' has been requested and this is a critical chunk + * but PNG_FLAG_CRC_CRITICAL_IGNORE was set then png_read_crc did not, in + * fact, calculate the CRC so the ANCILLARY settings should not be used + * instead. + */ + if (handle_as_ancillary && + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) + handle_as_ancillary = 0; + + /* TODO: this might be more comprehensible if png_crc_error was inlined here. + */ + if (png_crc_error(png_ptr, handle_as_ancillary) != 0) { - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? + /* See above for the explanation of how the flags work. */ + if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) - { png_chunk_warning(png_ptr, "CRC error"); - } else png_chunk_error(png_ptr, "CRC error"); @@ -258,61 +356,29 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip) return 0; } -/* Compare the CRC stored in the PNG file with that calculated by libpng from - * the data it has read thus far. - */ int /* PRIVATE */ -png_crc_error(png_structrp png_ptr) +png_crc_finish(png_structrp png_ptr, png_uint_32 skip) { - png_byte crc_bytes[4]; - png_uint_32 crc; - int need_crc = 1; - - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; -#endif - - /* The chunk CRC must be serialized in a single I/O call. */ - png_read_data(png_ptr, crc_bytes, 4); - - if (need_crc != 0) - { - crc = png_get_uint_32(crc_bytes); - return crc != png_ptr->crc; - } - - else - return 0; + return png_crc_finish_critical(png_ptr, skip, 0/*critical handling*/); } #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) + defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_eXIf_SUPPORTED) ||\ + defined(PNG_SEQUENTIAL_READ_SUPPORTED) /* Manage the read buffer; this simply reallocates the buffer if it is not small * enough (or if it is not allocated). The routine returns a pointer to the * buffer; if an error occurs and 'warn' is set the routine returns NULL, else - * it will call png_error (via png_malloc) on failure. (warn == 2 means - * 'silent'). + * it will call png_error on failure. */ static png_bytep -png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) +png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size) { png_bytep buffer = png_ptr->read_buffer; + if (new_size > png_chunk_max(png_ptr)) return NULL; + if (buffer != NULL && new_size > png_ptr->read_buffer_size) { png_ptr->read_buffer = NULL; @@ -327,24 +393,17 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) if (buffer != NULL) { - memset(buffer, 0, new_size); /* just in case */ +# ifndef PNG_NO_MEMZERO /* for detecting UIM bugs **only** */ + memset(buffer, 0, new_size); /* just in case */ +# endif png_ptr->read_buffer = buffer; png_ptr->read_buffer_size = new_size; } - - else if (warn < 2) /* else silent */ - { - if (warn != 0) - png_chunk_warning(png_ptr, "insufficient memory to read chunk"); - - else - png_chunk_error(png_ptr, "insufficient memory to read chunk"); - } } return buffer; } -#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ +#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|eXIf|SEQUENTIAL_READ */ /* png_inflate_claim: claim the zstream for some nefarious purpose that involves * decompression. Returns Z_OK on success, else a zlib error code. It checks @@ -631,16 +690,7 @@ png_decompress_chunk(png_structrp png_ptr, * maybe a '\0' terminator too. We have to assume that 'prefix_size' is * limited only by the maximum chunk size. */ - png_alloc_size_t limit = PNG_SIZE_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif + png_alloc_size_t limit = png_chunk_max(png_ptr); if (limit >= prefix_size + (terminate != 0)) { @@ -845,9 +895,9 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, } #endif /* READ_iCCP */ +/* CHUNK HANDLING */ /* Read and check the IDHR chunk */ - -void /* PRIVATE */ +static png_handle_result_code png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[13]; @@ -857,12 +907,7 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_IHDR"); - if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) - png_chunk_error(png_ptr, "out of place"); - - /* Check the length */ - if (length != 13) - png_chunk_error(png_ptr, "invalid"); + /* Length and position are checked by the caller. */ png_ptr->mode |= PNG_HAVE_IHDR; @@ -916,257 +961,196 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); png_debug1(3, "channels = %d", png_ptr->channels); png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); + + /* Rely on png_set_IHDR to completely validate the data and call png_error if + * it's wrong. + */ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_type); + + return handled_ok; + PNG_UNUSED(length) } /* Read and check the palette */ -void /* PRIVATE */ +/* TODO: there are several obvious errors in this code when handling + * out-of-place chunks and there is much over-complexity caused by trying to + * patch up the problems. + */ +static png_handle_result_code png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_color palette[PNG_MAX_PALETTE_LENGTH]; - int max_palette_length, num, i; -#ifdef PNG_POINTER_INDEXING_SUPPORTED - png_colorp pal_ptr; -#endif + png_const_charp errmsg = NULL; png_debug(1, "in png_handle_PLTE"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - /* Moved to before the 'after IDAT' check below because otherwise duplicate - * PLTE chunks are potentially ignored (the spec says there shall not be more - * than one PLTE, the error is not treated as benign, so this check trumps - * the requirement that PLTE appears before IDAT.) + /* 1.6.47: consistency. This used to be especially treated as a critical + * error even in an image which is not colour mapped, there isn't a good + * justification for treating some errors here one way and others another so + * everything uses the same logic. */ - else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) - png_chunk_error(png_ptr, "duplicate"); + if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) + errmsg = "duplicate"; else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - /* This is benign because the non-benign error happened before, when an - * IDAT was encountered in a color-mapped image with no PLTE. - */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } + errmsg = "out of place"; - png_ptr->mode |= PNG_HAVE_PLTE; + else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + errmsg = "ignored in grayscale PNG"; - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); - return; - } + else if (length > 3*PNG_MAX_PALETTE_LENGTH || (length % 3) != 0) + errmsg = "invalid"; -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - png_crc_finish(png_ptr, length); - return; - } -#endif + /* This drops PLTE in favour of tRNS or bKGD because both of those chunks + * can have an effect on the rendering of the image whereas PLTE only matters + * in the case of an 8-bit display with a decoder which controls the palette. + * + * The alternative here is to ignore the error and store the palette anyway; + * destroying the tRNS will definately cause problems. + * + * NOTE: the case of PNG_COLOR_TYPE_PALETTE need not be considered because + * the png_handle_ routines for the three 'after PLTE' chunks tRNS, bKGD and + * hIST all check for a preceding PLTE in these cases. + */ + else if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE && + (png_has_chunk(png_ptr, tRNS) || png_has_chunk(png_ptr, bKGD))) + errmsg = "out of place"; - if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) + else { - png_crc_finish(png_ptr, length); - - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - png_chunk_benign_error(png_ptr, "invalid"); - - else - png_chunk_error(png_ptr, "invalid"); - - return; - } + /* If the palette has 256 or fewer entries but is too large for the bit + * depth we don't issue an error to preserve the behavior of previous + * libpng versions. We silently truncate the unused extra palette entries + * here. + */ + const unsigned max_palette_length = + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + 1U << png_ptr->bit_depth : PNG_MAX_PALETTE_LENGTH; - /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ - num = (int)length / 3; + /* The cast is safe because 'length' is less than + * 3*PNG_MAX_PALETTE_LENGTH + */ + const unsigned num = (length > 3U*max_palette_length) ? + max_palette_length : (unsigned)length / 3U; - /* If the palette has 256 or fewer entries but is too large for the bit - * depth, we don't issue an error, to preserve the behavior of previous - * libpng versions. We silently truncate the unused extra palette entries - * here. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - max_palette_length = (1 << png_ptr->bit_depth); - else - max_palette_length = PNG_MAX_PALETTE_LENGTH; + unsigned i, j; + png_byte buf[3*PNG_MAX_PALETTE_LENGTH]; + png_color palette[PNG_MAX_PALETTE_LENGTH]; - if (num > max_palette_length) - num = max_palette_length; + /* Read the chunk into the buffer then read to the end of the chunk. */ + png_crc_read(png_ptr, buf, num*3U); + png_crc_finish_critical(png_ptr, length - 3U*num, + /* Handle as ancillary if PLTE is optional: */ + png_ptr->color_type != PNG_COLOR_TYPE_PALETTE); -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) - { - png_byte buf[3]; + for (i = 0U, j = 0U; i < num; i++) + { + palette[i].red = buf[j++]; + palette[i].green = buf[j++]; + palette[i].blue = buf[j++]; + } - png_crc_read(png_ptr, buf, 3); - pal_ptr->red = buf[0]; - pal_ptr->green = buf[1]; - pal_ptr->blue = buf[2]; - } -#else - for (i = 0; i < num; i++) - { - png_byte buf[3]; + /* A valid PLTE chunk has been read */ + png_ptr->mode |= PNG_HAVE_PLTE; - png_crc_read(png_ptr, buf, 3); - /* Don't depend upon png_color being any order */ - palette[i].red = buf[0]; - palette[i].green = buf[1]; - palette[i].blue = buf[2]; + /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to + * its own copy of the palette. This has the side effect that when + * png_start_row is called (this happens after any call to + * png_read_update_info) the info_ptr palette gets changed. This is + * extremely unexpected and confusing. + * + * REVIEW: there have been consistent bugs in the past about gamma and + * similar transforms to colour mapped images being useless because the + * modified palette cannot be accessed because of the above. + * + * CONSIDER: Fix this by not sharing the palette in this way. But does + * this completely fix the problem? + */ + png_set_PLTE(png_ptr, info_ptr, palette, num); + return handled_ok; } -#endif - /* If we actually need the PLTE chunk (ie for a paletted image), we do - * whatever the normal CRC configuration tells us. However, if we - * have an RGB image, the PLTE can be considered ancillary, so - * we will act as though it is. - */ -#ifndef PNG_READ_OPT_PLTE_SUPPORTED + /* Here on error: errmsg is non NULL. */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#endif { - png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3)); + png_crc_finish(png_ptr, length); + png_chunk_error(png_ptr, errmsg); } -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ + else /* not critical to this image */ { - /* If we don't want to use the data from an ancillary chunk, - * we have two options: an error abort, or a warning and we - * ignore the data in this chunk (which should be OK, since - * it's considered ancillary for a RGB or RGBA image). - * - * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the - * chunk type to determine whether to check the ancillary or the critical - * flags. - */ - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) - return; - - else - png_chunk_error(png_ptr, "CRC error"); - } - - /* Otherwise, we (optionally) emit a warning and use the chunk. */ - else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) - png_chunk_warning(png_ptr, "CRC error"); + png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/); + png_chunk_benign_error(png_ptr, errmsg); } -#endif - /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its - * own copy of the palette. This has the side effect that when png_start_row - * is called (this happens after any call to png_read_update_info) the - * info_ptr palette gets changed. This is extremely unexpected and - * confusing. - * - * Fix this by not sharing the palette in this way. - */ - png_set_PLTE(png_ptr, info_ptr, palette, num); - - /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before - * IDAT. Prior to 1.6.0 this was not checked; instead the code merely - * checked the apparent validity of a tRNS chunk inserted before PLTE on a - * palette PNG. 1.6.0 attempts to rigorously follow the standard and - * therefore does a benign error if the erroneous condition is detected *and* - * cancels the tRNS if the benign error returns. The alternative is to - * amend the standard since it would be rather hypocritical of the standards - * maintainers to ignore it. + /* Because PNG_UNUSED(errmsg) does not work if all the uses are compiled out + * (this does happen). */ -#ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->num_trans > 0 || - (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) - { - /* Cancel this because otherwise it would be used if the transforms - * require it. Don't cancel the 'valid' flag because this would prevent - * detection of duplicate chunks. - */ - png_ptr->num_trans = 0; - - if (info_ptr != NULL) - info_ptr->num_trans = 0; - - png_chunk_benign_error(png_ptr, "tRNS must be after"); - } -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - png_chunk_benign_error(png_ptr, "hIST must be after"); -#endif - -#ifdef PNG_READ_bKGD_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) - png_chunk_benign_error(png_ptr, "bKGD must be after"); -#endif + return errmsg != NULL ? handled_error : handled_error; } -void /* PRIVATE */ +/* On read the IDAT chunk is always handled specially, even if marked for + * unknown handling (this is allowed), so: + */ +#define png_handle_IDAT NULL + +static png_handle_result_code png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_debug(1, "in png_handle_IEND"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || - (png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_chunk_error(png_ptr, "out of place"); - png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); - png_crc_finish(png_ptr, length); - if (length != 0) png_chunk_benign_error(png_ptr, "invalid"); + png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/); + + return handled_ok; PNG_UNUSED(info_ptr) } #ifdef PNG_READ_gAMA_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_fixed_point igamma; + png_uint_32 ugamma; png_byte buf[4]; png_debug(1, "in png_handle_gAMA"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); + png_crc_read(png_ptr, buf, 4); - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; - if (length != 4) + ugamma = png_get_uint_32(buf); + + if (ugamma > PNG_UINT_31_MAX) { - png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } - png_crc_read(png_ptr, buf, 4); - - if (png_crc_finish(png_ptr, 0) != 0) - return; + png_set_gAMA_fixed(png_ptr, info_ptr, (png_fixed_point)/*SAFE*/ugamma); - igamma = png_get_fixed_point(NULL, buf); +#ifdef PNG_READ_GAMMA_SUPPORTED + /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. gAMA is + * at the end of the chain so simply check for an unset value. + */ + if (png_ptr->chunk_gamma == 0) + png_ptr->chunk_gamma = (png_fixed_point)/*SAFE*/ugamma; +#endif /*READ_GAMMA*/ - png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); - png_colorspace_sync(png_ptr, info_ptr); + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_gAMA NULL #endif #ifdef PNG_READ_sBIT_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { unsigned int truelen, i; @@ -1175,23 +1159,6 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_sBIT"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { truelen = 3; @@ -1204,25 +1171,25 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) sample_depth = png_ptr->bit_depth; } - if (length != truelen || length > 4) + if (length != truelen) { - png_chunk_benign_error(png_ptr, "invalid"); png_crc_finish(png_ptr, length); - return; + png_chunk_benign_error(png_ptr, "bad length"); + return handled_error; } buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; png_crc_read(png_ptr, buf, truelen); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; for (i=0; i<truelen; ++i) { if (buf[i] == 0 || buf[i] > sample_depth) { png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } } @@ -1234,7 +1201,7 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_ptr->sig_bit.alpha = buf[3]; } - else + else /* grayscale */ { png_ptr->sig_bit.gray = buf[0]; png_ptr->sig_bit.red = buf[0]; @@ -1244,133 +1211,132 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); + return handled_ok; } +#else +# define png_handle_sBIT NULL #endif #ifdef PNG_READ_cHRM_SUPPORTED -void /* PRIVATE */ -png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +static png_int_32 +png_get_int_32_checked(png_const_bytep buf, int *error) { - png_byte buf[32]; - png_xy xy; + png_uint_32 uval = png_get_uint_32(buf); + if ((uval & 0x80000000) == 0) /* non-negative */ + return (png_int_32)uval; - png_debug(1, "in png_handle_cHRM"); + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + if ((uval & 0x80000000) == 0) /* no overflow */ + return -(png_int_32)uval; - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); + /* This version of png_get_int_32 has a way of returning the error to the + * caller, so: + */ + *error = 1; + return 0; /* Safe */ +} - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } +static png_handle_result_code /* PRIVATE */ +png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + int error = 0; + png_xy xy; + png_byte buf[32]; - if (length != 32) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } + png_debug(1, "in png_handle_cHRM"); png_crc_read(png_ptr, buf, 32); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; + + xy.whitex = png_get_int_32_checked(buf + 0, &error); + xy.whitey = png_get_int_32_checked(buf + 4, &error); + xy.redx = png_get_int_32_checked(buf + 8, &error); + xy.redy = png_get_int_32_checked(buf + 12, &error); + xy.greenx = png_get_int_32_checked(buf + 16, &error); + xy.greeny = png_get_int_32_checked(buf + 20, &error); + xy.bluex = png_get_int_32_checked(buf + 24, &error); + xy.bluey = png_get_int_32_checked(buf + 28, &error); - xy.whitex = png_get_fixed_point(NULL, buf); - xy.whitey = png_get_fixed_point(NULL, buf + 4); - xy.redx = png_get_fixed_point(NULL, buf + 8); - xy.redy = png_get_fixed_point(NULL, buf + 12); - xy.greenx = png_get_fixed_point(NULL, buf + 16); - xy.greeny = png_get_fixed_point(NULL, buf + 20); - xy.bluex = png_get_fixed_point(NULL, buf + 24); - xy.bluey = png_get_fixed_point(NULL, buf + 28); - - if (xy.whitex == PNG_FIXED_ERROR || - xy.whitey == PNG_FIXED_ERROR || - xy.redx == PNG_FIXED_ERROR || - xy.redy == PNG_FIXED_ERROR || - xy.greenx == PNG_FIXED_ERROR || - xy.greeny == PNG_FIXED_ERROR || - xy.bluex == PNG_FIXED_ERROR || - xy.bluey == PNG_FIXED_ERROR) + if (error) { - png_chunk_benign_error(png_ptr, "invalid values"); - return; + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; } - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - return; + /* png_set_cHRM may complain about some of the values but this doesn't matter + * because it was a cHRM and it did have vaguely (if, perhaps, ridiculous) + * values. Ridiculousity will be checked if the values are used later. + */ + png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy, + xy.greenx, xy.greeny, xy.bluex, xy.bluey); - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } + /* We only use 'chromaticities' for RGB to gray */ +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* There is no need to check sRGB here, cICP is NYI and iCCP is not + * supported so just check mDCV. + */ + if (!png_has_chunk(png_ptr, mDCV)) + { + png_ptr->chromaticities = xy; + } +# endif /* READ_RGB_TO_GRAY */ - png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, - 1/*prefer cHRM values*/); - png_colorspace_sync(png_ptr, info_ptr); + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_cHRM NULL #endif #ifdef PNG_READ_sRGB_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte intent; png_debug(1, "in png_handle_sRGB"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, &intent, 1); if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - return; + return handled_error; - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. + /* This checks the range of the "rendering intent" because it is specified in + * the PNG spec itself; the "reserved" values will result in the chunk not + * being accepted, just as they do with the various "reserved" values in + * IHDR. */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) + if (intent > 3/*PNGv3 spec*/) { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "too many profiles"); - return; + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; } - (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); - png_colorspace_sync(png_ptr, info_ptr); + png_set_sRGB(png_ptr, info_ptr, intent); + /* NOTE: png_struct::chromaticities is not set here because the RGB to gray + * coefficients are known without a need for the chromaticities. + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. iCCP is + * not supported by libpng so the only requirement is to check for cICP + * setting the gamma (this is NYI, but this check is safe.) + */ + if (!png_has_chunk(png_ptr, cICP) || png_ptr->chunk_gamma == 0) + png_ptr->chunk_gamma = PNG_GAMMA_sRGB_INVERSE; +#endif /*READ_GAMMA*/ + + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_sRGB NULL #endif /* READ_sRGB */ #ifdef PNG_READ_iCCP_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* Note: this does not properly handle profiles that are > 64K under DOS */ { @@ -1379,44 +1345,10 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_iCCP"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - /* Consistent with all the above colorspace handling an obviously *invalid* - * chunk is just ignored, so does not invalidate the color space. An - * alternative is to set the 'invalid' flags at the start of this routine - * and only clear them in they were not set before and all the tests pass. - */ - - /* The keyword must be at least one character and there is a - * terminator (0) byte and the compression method byte, and the - * 'zlib' datastream is at least 11 bytes. - */ - if (length < 14) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - png_crc_finish(png_ptr, length); - return; - } - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. + /* PNGv3: allow PNG files with both sRGB and iCCP because the PNG spec only + * ever said that there "should" be only one, not "shall" and the PNGv3 + * colour chunk precedence rules give a handling for this case anyway. */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) { uInt read_length, keyword_length; char keyword[81]; @@ -1426,19 +1358,16 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) */ read_length = 81; /* maximum */ if (read_length > length) - read_length = (uInt)length; + read_length = (uInt)/*SAFE*/length; png_crc_read(png_ptr, (png_bytep)keyword, read_length); length -= read_length; - /* The minimum 'zlib' stream is assumed to be just the 2 byte header, - * 5 bytes minimum 'deflate' stream, and the 4 byte checksum. - */ - if (length < 11) + if (length < LZ77Min) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "too short"); - return; + return handled_error; } keyword_length = 0; @@ -1475,15 +1404,14 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) */ png_uint_32 profile_length = png_get_uint_32(profile_header); - if (png_icc_check_length(png_ptr, &png_ptr->colorspace, - keyword, profile_length) != 0) + if (png_icc_check_length(png_ptr, keyword, profile_length) != + 0) { /* The length is apparently ok, so we can check the 132 * byte header. */ - if (png_icc_check_header(png_ptr, &png_ptr->colorspace, - keyword, profile_length, profile_header, - png_ptr->color_type) != 0) + if (png_icc_check_header(png_ptr, keyword, profile_length, + profile_header, png_ptr->color_type) != 0) { /* Now read the tag table; a variable size buffer is * needed at this point, allocate one for the whole @@ -1493,7 +1421,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_uint_32 tag_count = png_get_uint_32(profile_header + 128); png_bytep profile = png_read_buffer(png_ptr, - profile_length, 2/*silent*/); + profile_length); if (profile != NULL) { @@ -1512,8 +1440,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (size == 0) { if (png_icc_check_tag_table(png_ptr, - &png_ptr->colorspace, keyword, profile_length, - profile) != 0) + keyword, profile_length, profile) != 0) { /* The profile has been validated for basic * security issues, so read the whole thing in. @@ -1545,13 +1472,6 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); finished = 1; -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* Check for a match against sRGB */ - png_icc_set_sRGB(png_ptr, - &png_ptr->colorspace, profile, - png_ptr->zstream.adler); -# endif - /* Steal the profile for info_ptr. */ if (info_ptr != NULL) { @@ -1574,11 +1494,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } else - { - png_ptr->colorspace.flags |= - PNG_COLORSPACE_INVALID; errmsg = "out of memory"; - } } /* else the profile remains in the read @@ -1586,13 +1502,10 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * chunks. */ - if (info_ptr != NULL) - png_colorspace_sync(png_ptr, info_ptr); - if (errmsg == NULL) { png_ptr->zowner = 0; - return; + return handled_ok; } } if (errmsg == NULL) @@ -1633,22 +1546,21 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) errmsg = "bad keyword"; } - else - errmsg = "too many profiles"; - /* Failure: the reason is in 'errmsg' */ if (finished == 0) png_crc_finish(png_ptr, length); - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); if (errmsg != NULL) /* else already output */ png_chunk_benign_error(png_ptr, errmsg); + + return handled_error; } +#else +# define png_handle_iCCP NULL #endif /* READ_iCCP */ #ifdef PNG_READ_sPLT_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { @@ -1669,43 +1581,24 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - return; + return handled_error; } if (--png_ptr->user_chunk_cache_max == 1) { png_warning(png_ptr, "No space in chunk cache for sPLT"); png_crc_finish(png_ptr, length); - return; + return handled_error; } } #endif - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535U) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too large to fit in memory"); - return; - } -#endif - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "out of memory"); - return; + return handled_error; } @@ -1716,7 +1609,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_crc_read(png_ptr, buffer, length); if (png_crc_finish(png_ptr, skip) != 0) - return; + return handled_error; buffer[length] = 0; @@ -1729,7 +1622,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (length < 2U || entry_start > buffer + (length - 2U)) { png_warning(png_ptr, "malformed sPLT chunk"); - return; + return handled_error; } new_palette.depth = *entry_start++; @@ -1743,7 +1636,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if ((data_length % (unsigned int)entry_size) != 0) { png_warning(png_ptr, "sPLT chunk has bad length"); - return; + return handled_error; } dl = (png_uint_32)(data_length / (unsigned int)entry_size); @@ -1752,7 +1645,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (dl > max_dl) { png_warning(png_ptr, "sPLT chunk too long"); - return; + return handled_error; } new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size); @@ -1763,10 +1656,9 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (new_palette.entries == NULL) { png_warning(png_ptr, "sPLT chunk requires too much memory"); - return; + return handled_error; } -#ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0; i < new_palette.nentries; i++) { pp = new_palette.entries + i; @@ -1789,31 +1681,6 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) pp->frequency = png_get_uint_16(entry_start); entry_start += 2; } -#else - pp = new_palette.entries; - - for (i = 0; i < new_palette.nentries; i++) - { - - if (new_palette.depth == 8) - { - pp[i].red = *entry_start++; - pp[i].green = *entry_start++; - pp[i].blue = *entry_start++; - pp[i].alpha = *entry_start++; - } - - else - { - pp[i].red = png_get_uint_16(entry_start); entry_start += 2; - pp[i].green = png_get_uint_16(entry_start); entry_start += 2; - pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; - pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#endif /* Discard all chunk data except the name and stash that */ new_palette.name = (png_charp)buffer; @@ -1821,34 +1688,20 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); png_free(png_ptr, new_palette.entries); + return handled_ok; } +#else +# define png_handle_sPLT NULL #endif /* READ_sPLT */ #ifdef PNG_READ_tRNS_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_tRNS"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { png_byte buf[2]; @@ -1857,7 +1710,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } png_crc_read(png_ptr, buf, 2); @@ -1873,7 +1726,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } png_crc_read(png_ptr, buf, length); @@ -1887,10 +1740,9 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) { - /* TODO: is this actually an error in the ISO spec? */ png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "out of place"); - return; + return handled_error; } if (length > (unsigned int) png_ptr->num_palette || @@ -1899,7 +1751,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } png_crc_read(png_ptr, readbuf, length); @@ -1910,13 +1762,13 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid with alpha channel"); - return; + return handled_error; } if (png_crc_finish(png_ptr, 0) != 0) { png_ptr->num_trans = 0; - return; + return handled_error; } /* TODO: this is a horrible side effect in the palette case because the @@ -1925,11 +1777,14 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) */ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, &(png_ptr->trans_color)); + return handled_ok; } +#else +# define png_handle_tRNS NULL #endif #ifdef PNG_READ_bKGD_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { unsigned int truelen; @@ -1938,27 +1793,17 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_bKGD"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0)) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } + if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return handled_error; + } - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 1; + } else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) truelen = 6; @@ -1970,13 +1815,13 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } png_crc_read(png_ptr, buf, truelen); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; /* We convert the index value into RGB components so that we can allow * arbitrary RGB values for background when we have transparency, and @@ -1992,7 +1837,7 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (buf[0] >= info_ptr->num_palette) { png_chunk_benign_error(png_ptr, "invalid index"); - return; + return handled_error; } background.red = (png_uint_16)png_ptr->palette[buf[0]].red; @@ -2013,7 +1858,7 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth)) { png_chunk_benign_error(png_ptr, "invalid gray level"); - return; + return handled_error; } } @@ -2031,7 +1876,7 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0) { png_chunk_benign_error(png_ptr, "invalid color"); - return; + return handled_error; } } @@ -2043,129 +1888,87 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } png_set_bKGD(png_ptr, info_ptr, &background); + return handled_ok; } +#else +# define png_handle_bKGD NULL #endif #ifdef PNG_READ_cICP_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[4]; png_debug(1, "in png_handle_cICP"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cICP) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - else if (length != 4) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, buf, 4); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; png_set_cICP(png_ptr, info_ptr, buf[0], buf[1], buf[2], buf[3]); + + /* We only use 'chromaticities' for RGB to gray */ +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if (!png_has_chunk(png_ptr, mDCV)) + { + /* TODO: png_ptr->chromaticities = chromaticities; */ + } +# endif /* READ_RGB_TO_GRAY */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. cICP is + * at the head so simply set the gamma if it can be determined. If not + * chunk_gamma remains unchanged; sRGB and gAMA handling check it for + * being zero. + */ + /* TODO: set png_struct::chunk_gamma when possible */ +#endif /*READ_GAMMA*/ + + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_cICP NULL #endif #ifdef PNG_READ_cLLI_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_cLLI(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[8]; png_debug(1, "in png_handle_cLLI"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cLLI) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - else if (length != 8) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, buf, 8); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; /* The error checking happens here, this puts it in just one place: */ png_set_cLLI_fixed(png_ptr, info_ptr, png_get_uint_32(buf), png_get_uint_32(buf+4)); + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_cLLI NULL #endif #ifdef PNG_READ_mDCV_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_mDCV(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { + png_xy chromaticities; png_byte buf[24]; png_debug(1, "in png_handle_mDCV"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_mDCV) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - else if (length != 24) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, buf, 24); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; /* The error checking happens here, this puts it in just one place. The * odd /50000 scaling factor makes it more difficult but the (x.y) values are @@ -2178,86 +1981,81 @@ png_handle_mDCV(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * stored in four bytes. This is very, very confusing. These APIs remove * the confusion by copying the existing, well established, API. */ + chromaticities.redx = png_get_uint_16(buf+ 0U) << 1; /* red x */ + chromaticities.redy = png_get_uint_16(buf+ 2U) << 1; /* red y */ + chromaticities.greenx = png_get_uint_16(buf+ 4U) << 1; /* green x */ + chromaticities.greeny = png_get_uint_16(buf+ 6U) << 1; /* green y */ + chromaticities.bluex = png_get_uint_16(buf+ 8U) << 1; /* blue x */ + chromaticities.bluey = png_get_uint_16(buf+10U) << 1; /* blue y */ + chromaticities.whitex = png_get_uint_16(buf+12U) << 1; /* white x */ + chromaticities.whitey = png_get_uint_16(buf+14U) << 1; /* white y */ + png_set_mDCV_fixed(png_ptr, info_ptr, - png_get_uint_16(buf+12U) << 1U, /* white x */ - png_get_uint_16(buf+14U) << 1U, /* white y */ - png_get_uint_16(buf+ 0U) << 1U, /* red x */ - png_get_uint_16(buf+ 2U) << 1U, /* red y */ - png_get_uint_16(buf+ 4U) << 1U, /* green x */ - png_get_uint_16(buf+ 6U) << 1U, /* green y */ - png_get_uint_16(buf+ 8U) << 1U, /* blue x */ - png_get_uint_16(buf+10U) << 1U, /* blue y */ + chromaticities.whitex, chromaticities.whitey, + chromaticities.redx, chromaticities.redy, + chromaticities.greenx, chromaticities.greeny, + chromaticities.bluex, chromaticities.bluey, png_get_uint_32(buf+16U), /* peak luminance */ png_get_uint_32(buf+20U));/* minimum perceivable luminance */ + + /* We only use 'chromaticities' for RGB to gray */ +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_ptr->chromaticities = chromaticities; +# endif /* READ_RGB_TO_GRAY */ + + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_mDCV NULL #endif #ifdef PNG_READ_eXIf_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - unsigned int i; + png_bytep buffer = NULL; png_debug(1, "in png_handle_eXIf"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if (length < 2) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } + buffer = png_read_buffer(png_ptr, length); - else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0) + if (buffer == NULL) { png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; } - info_ptr->free_me |= PNG_FREE_EXIF; + png_crc_read(png_ptr, buffer, length); - info_ptr->eXIf_buf = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, length)); + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; - if (info_ptr->eXIf_buf == NULL) + /* PNGv3: the code used to check the byte order mark at the start for MM or + * II, however PNGv3 states that the the first 4 bytes should be checked. + * The caller ensures that there are four bytes available. + */ { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } + png_uint_32 header = png_get_uint_32(buffer); - for (i = 0; i < length; i++) - { - png_byte buf[1]; - png_crc_read(png_ptr, buf, 1); - info_ptr->eXIf_buf[i] = buf[0]; - if (i == 1) + /* These numbers are copied from the PNGv3 spec: */ + if (header != 0x49492A00 && header != 0x4D4D002A) { - if ((buf[0] != 'M' && buf[0] != 'I') || - (info_ptr->eXIf_buf[0] != buf[0])) - { - png_crc_finish(png_ptr, length - 2); - png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - return; - } + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; } } - if (png_crc_finish(png_ptr, 0) == 0) - png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); - - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; + png_set_eXIf_1(png_ptr, info_ptr, length, buffer); + return handled_ok; } +#else +# define png_handle_eXIf NULL #endif #ifdef PNG_READ_hIST_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { unsigned int num, i; @@ -2265,25 +2063,13 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_hIST"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - num = length / 2 ; + /* This cast is safe because the chunk definition limits the length to a + * maximum of 1024 bytes. + * + * TODO: maybe use png_uint_32 anyway, not unsigned int, to reduce the + * casts. + */ + num = (unsigned int)length / 2 ; if (length != num * 2 || num != (unsigned int)png_ptr->num_palette || @@ -2291,7 +2077,7 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } for (i = 0; i < num; i++) @@ -2303,14 +2089,17 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; png_set_hIST(png_ptr, info_ptr, readbuf); + return handled_ok; } +#else +# define png_handle_hIST NULL #endif #ifdef PNG_READ_pHYs_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[9]; @@ -2319,44 +2108,24 @@ png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_pHYs"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, buf, 9); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; res_x = png_get_uint_32(buf); res_y = png_get_uint_32(buf + 4); unit_type = buf[8]; png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_pHYs NULL #endif #ifdef PNG_READ_oFFs_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[9]; @@ -2365,45 +2134,25 @@ png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_oFFs"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, buf, 9); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; offset_x = png_get_int_32(buf); offset_y = png_get_int_32(buf + 4); unit_type = buf[8]; png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_oFFs NULL #endif #ifdef PNG_READ_pCAL_SUPPORTED /* Read the pCAL chunk (described in the PNG Extensions document) */ -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_int_32 X0, X1; @@ -2413,40 +2162,22 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) int i; png_debug(1, "in png_handle_pCAL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", length + 1); - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "out of memory"); - return; + return handled_error; } png_crc_read(png_ptr, buffer, length); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; buffer[length] = 0; /* Null terminate the last string */ @@ -2462,7 +2193,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (endptr - buf <= 12) { png_chunk_benign_error(png_ptr, "invalid"); - return; + return handled_error; } png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); @@ -2482,7 +2213,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) { png_chunk_benign_error(png_ptr, "invalid parameter count"); - return; + return handled_error; } else if (type >= PNG_EQUATION_LAST) @@ -2501,7 +2232,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (params == NULL) { png_chunk_benign_error(png_ptr, "out of memory"); - return; + return handled_error; } /* Get pointers to the start of each parameter string. */ @@ -2519,20 +2250,29 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_free(png_ptr, params); png_chunk_benign_error(png_ptr, "invalid data"); - return; + return handled_error; } } png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, (png_charp)units, params); + /* TODO: BUG: png_set_pCAL calls png_chunk_report which, in this case, calls + * png_benign_error and that can error out. + * + * png_read_buffer needs to be allocated with space for both nparams and the + * parameter strings. Not hard to do. + */ png_free(png_ptr, params); + return handled_ok; } +#else +# define png_handle_pCAL NULL #endif #ifdef PNG_READ_sCAL_SUPPORTED /* Read the sCAL chunk */ -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_bytep buffer; @@ -2540,55 +2280,29 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) int state; png_debug(1, "in png_handle_sCAL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - /* Need unit type, width, \0, height: minimum 4 bytes */ - else if (length < 4) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", length + 1); - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { - png_chunk_benign_error(png_ptr, "out of memory"); png_crc_finish(png_ptr, length); - return; + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; } png_crc_read(png_ptr, buffer, length); buffer[length] = 0; /* Null terminate the last string */ if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; /* Validate the unit. */ if (buffer[0] != 1 && buffer[0] != 2) { png_chunk_benign_error(png_ptr, "invalid unit"); - return; + return handled_error; } /* Validate the ASCII numbers, need two ASCII numbers separated by @@ -2617,15 +2331,22 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_chunk_benign_error(png_ptr, "non-positive height"); else + { /* This is the (only) success case. */ png_set_sCAL_s(png_ptr, info_ptr, buffer[0], (png_charp)buffer+1, (png_charp)buffer+heighti); + return handled_ok; + } } + + return handled_error; } +#else +# define png_handle_sCAL NULL #endif #ifdef PNG_READ_tIME_SUPPORTED -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[7]; @@ -2633,30 +2354,17 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_tIME"); - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - + /* TODO: what is this doing here? It should be happened in pngread.c and + * pngpread.c, although it could be moved to png_handle_chunk below and + * thereby avoid some code duplication. + */ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; - if (length != 7) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - png_crc_read(png_ptr, buf, 7); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; mod_time.second = buf[6]; mod_time.minute = buf[5]; @@ -2666,12 +2374,16 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) mod_time.year = png_get_uint_16(buf); png_set_tIME(png_ptr, info_ptr, &mod_time); + return handled_ok; + PNG_UNUSED(length) } +#else +# define png_handle_tIME NULL #endif #ifdef PNG_READ_tEXt_SUPPORTED /* Note: this does not properly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_text text_info; @@ -2688,45 +2400,35 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - return; + return handled_error; } if (--png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; + return handled_error; } } #endif - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - + /* TODO: this doesn't work and shouldn't be necessary. */ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535U) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too large to fit in memory"); - return; - } -#endif - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); + buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { + png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "out of memory"); - return; + return handled_error; } png_crc_read(png_ptr, buffer, length); if (png_crc_finish(png_ptr, skip) != 0) - return; + return handled_error; key = (png_charp)buffer; key[length] = 0; @@ -2745,14 +2447,19 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) text_info.text = text; text_info.text_length = strlen(text); - if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) - png_warning(png_ptr, "Insufficient memory to process text chunk"); + if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) == 0) + return handled_ok; + + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; } +#else +# define png_handle_tEXt NULL #endif #ifdef PNG_READ_zTXt_SUPPORTED /* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_const_charp errmsg = NULL; @@ -2767,40 +2474,39 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - return; + return handled_error; } if (--png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; + return handled_error; } } #endif - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - + /* TODO: should not be necessary. */ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; /* Note, "length" is sufficient here; we won't be adding - * a null terminator later. + * a null terminator later. The limit check in png_handle_chunk should be + * sufficient. */ - buffer = png_read_buffer(png_ptr, length, 2/*silent*/); + buffer = png_read_buffer(png_ptr, length); if (buffer == NULL) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "out of memory"); - return; + return handled_error; } png_crc_read(png_ptr, buffer, length); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; /* TODO: also check that the keyword contents match the spec! */ for (keyword_length = 0; @@ -2853,8 +2559,10 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) text.lang = NULL; text.lang_key = NULL; - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; + if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0) + return handled_ok; + + errmsg = "out of memory"; } } @@ -2862,14 +2570,16 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) errmsg = png_ptr->zstream.msg; } - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); + png_chunk_benign_error(png_ptr, errmsg); + return handled_error; } +#else +# define png_handle_zTXt NULL #endif #ifdef PNG_READ_iTXt_SUPPORTED /* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ +static png_handle_result_code /* PRIVATE */ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_const_charp errmsg = NULL; @@ -2884,37 +2594,35 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - return; + return handled_error; } if (--png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; + return handled_error; } } #endif - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - + /* TODO: should not be necessary. */ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); + buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "out of memory"); - return; + return handled_error; } png_crc_read(png_ptr, buffer, length); if (png_crc_finish(png_ptr, 0) != 0) - return; + return handled_error; /* First the keyword. */ for (prefix_length=0; @@ -3004,8 +2712,10 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) text.text_length = 0; text.itxt_length = uncompressed_length; - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; + if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0) + return handled_ok; + + errmsg = "out of memory"; } } @@ -3014,7 +2724,10 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (errmsg != NULL) png_chunk_benign_error(png_ptr, errmsg); + return handled_error; } +#else +# define png_handle_iTXt NULL #endif #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED @@ -3022,7 +2735,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) static int png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) { - png_alloc_size_t limit = PNG_SIZE_MAX; + const png_alloc_size_t limit = png_chunk_max(png_ptr); if (png_ptr->unknown_chunk.data != NULL) { @@ -3030,16 +2743,6 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) png_ptr->unknown_chunk.data = NULL; } -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; - -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - if (length <= limit) { PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); @@ -3078,11 +2781,11 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) #endif /* READ_UNKNOWN_CHUNKS */ /* Handle an unknown, or known but disabled, chunk */ -void /* PRIVATE */ +png_handle_result_code /*PRIVATE*/ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep) { - int handled = 0; /* the chunk was handled */ + png_handle_result_code handled = handled_discarded; /* the default */ png_debug(1, "in png_handle_unknown"); @@ -3129,7 +2832,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, * error at this point unless it is to be saved. * positive: The chunk was handled, libpng will ignore/discard it. */ - if (ret < 0) + if (ret < 0) /* handled_error */ png_chunk_error(png_ptr, "error in user chunk"); else if (ret == 0) @@ -3163,7 +2866,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, else /* chunk was handled */ { - handled = 1; + handled = handled_ok; /* Critical chunks can be safely discarded at this point. */ keep = PNG_HANDLE_CHUNK_NEVER; } @@ -3248,7 +2951,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, */ png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); - handled = 1; + handled = handled_saved; # ifdef PNG_USER_LIMITS_SUPPORTED break; } @@ -3274,79 +2977,267 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, #endif /* !READ_UNKNOWN_CHUNKS */ /* Check for unhandled critical chunks */ - if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + if (handled < handled_saved && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) png_chunk_error(png_ptr, "unhandled critical chunk"); + + return handled; } -/* This function is called to verify that a chunk name is valid. - * This function can't have the "critical chunk check" incorporated - * into it, since in the future we will need to be able to call user - * functions to handle unknown critical chunks after we check that - * the chunk name itself is valid. +/* APNG handling: the minimal implementation of APNG handling in libpng 1.6 + * requires that those significant applications which already handle APNG not + * get hosed. To do this ensure the code here will have to ensure than APNG + * data by default (at least in 1.6) gets stored in the unknown chunk list. + * Maybe this can be relaxed in a few years but at present it's just the only + * safe way. + * + * ATM just cause unknown handling for all three chunks: */ +#define png_handle_acTL NULL +#define png_handle_fcTL NULL +#define png_handle_fdAT NULL -/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: +/* + * 1.6.47: This is the new table driven interface to all the chunk handling. + * + * The table describes the PNG standard rules for **reading** known chunks - + * every chunk which has an entry in PNG_KNOWN_CHUNKS. The table contains an + * entry for each PNG_INDEX_cHNK describing the rules. * - * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) + * In this initial version the only information in the entry is the + * png_handle_cHNK function for the chunk in question. When chunk support is + * compiled out the entry will be NULL. */ - -void /* PRIVATE */ -png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name) +static const struct { - int i; - png_uint_32 cn=chunk_name; - - png_debug(1, "in png_check_chunk_name"); + png_handle_result_code (*handler)( + png_structrp, png_inforp, png_uint_32 length); + /* A chunk-specific 'handler', NULL if the chunk is not supported in this + * build. + */ - for (i=1; i<=4; ++i) + /* Crushing these values helps on modern 32-bit architectures because the + * pointer and the following bit fields both end up requiring 32 bits. + * Typically this will halve the table size. On 64-bit architectures the + * table entries will typically be 8 bytes. + */ + png_uint_32 max_length :12; /* Length min, max in bytes */ + png_uint_32 min_length :8; + /* Length errors on critical chunks have special handling to preserve the + * existing behaviour in libpng 1.6. Anciallary chunks are checked below + * and produce a 'benign' error. + */ + png_uint_32 pos_before :4; /* PNG_HAVE_ values chunk must precede */ + png_uint_32 pos_after :4; /* PNG_HAVE_ values chunk must follow */ + /* NOTE: PLTE, tRNS and bKGD require special handling which depends on + * the colour type of the base image. + */ + png_uint_32 multiple :1; /* Multiple occurences permitted */ + /* This is enabled for PLTE because PLTE may, in practice, be optional */ +} +read_chunks[PNG_INDEX_unknown] = +{ + /* Definitions as above but done indirectly by #define so that + * PNG_KNOWN_CHUNKS can be used safely to build the table in order. + * + * Each CDcHNK definition lists the values for the parameters **after** + * the first, 'handler', function. 'handler' is NULL when the chunk has no + * compiled in support. + */ +# define NoCheck 0x801U /* Do not check the maximum length */ +# define Limit 0x802U /* Limit to png_chunk_max bytes */ +# define LKMin 3U+LZ77Min /* Minimum length of keyword+LZ77 */ + +#define hIHDR PNG_HAVE_IHDR +#define hPLTE PNG_HAVE_PLTE +#define hIDAT PNG_HAVE_IDAT + /* For the two chunks, tRNS and bKGD which can occur in PNGs without a PLTE + * but must occur after the PLTE use this and put the check in the handler + * routine for colour mapped images were PLTE is required. Also put a check + * in PLTE for other image types to drop the PLTE if tRNS or bKGD have been + * seen. + */ +#define hCOL (PNG_HAVE_PLTE|PNG_HAVE_IDAT) + /* Used for the decoding chunks which must be before PLTE. */ +#define aIDAT PNG_AFTER_IDAT + + /* Chunks from W3C PNG v3: */ + /* cHNK max_len, min, before, after, multiple */ +# define CDIHDR 13U, 13U, hIHDR, 0, 0 +# define CDPLTE NoCheck, 0U, 0, hIHDR, 1 + /* PLTE errors are only critical for colour-map images, consequently the + * hander does all the checks. + */ +# define CDIDAT NoCheck, 0U, aIDAT, hIHDR, 1 +# define CDIEND NoCheck, 0U, 0, aIDAT, 0 + /* Historically data was allowed in IEND */ +# define CDtRNS 256U, 0U, hIDAT, hIHDR, 0 +# define CDcHRM 32U, 32U, hCOL, hIHDR, 0 +# define CDgAMA 4U, 4U, hCOL, hIHDR, 0 +# define CDiCCP NoCheck, LKMin, hCOL, hIHDR, 0 +# define CDsBIT 4U, 1U, hCOL, hIHDR, 0 +# define CDsRGB 1U, 1U, hCOL, hIHDR, 0 +# define CDcICP 4U, 4U, hCOL, hIHDR, 0 +# define CDmDCV 24U, 24U, hCOL, hIHDR, 0 +# define CDeXIf Limit, 4U, 0, hIHDR, 0 +# define CDcLLI 8U, 8U, hCOL, hIHDR, 0 +# define CDtEXt NoCheck, 2U, 0, hIHDR, 1 + /* Allocates 'length+1'; checked in the handler */ +# define CDzTXt Limit, LKMin, 0, hIHDR, 1 +# define CDiTXt NoCheck, 6U, 0, hIHDR, 1 + /* Allocates 'length+1'; checked in the handler */ +# define CDbKGD 6U, 1U, hIDAT, hIHDR, 0 +# define CDhIST 1024U, 0U, hPLTE, hIHDR, 0 +# define CDpHYs 9U, 9U, hIDAT, hIHDR, 0 +# define CDsPLT NoCheck, 3U, hIDAT, hIHDR, 1 + /* Allocates 'length+1'; checked in the handler */ +# define CDtIME 7U, 7U, 0, hIHDR, 0 +# define CDacTL 8U, 8U, hIDAT, hIHDR, 0 +# define CDfcTL 25U, 26U, 0, hIHDR, 1 +# define CDfdAT Limit, 4U, hIDAT, hIHDR, 1 + /* Supported chunks from PNG extensions 1.5.0, NYI so limit */ +# define CDoFFs 9U, 9U, hIDAT, hIHDR, 0 +# define CDpCAL NoCheck, 14U, hIDAT, hIHDR, 0 + /* Allocates 'length+1'; checked in the handler */ +# define CDsCAL Limit, 4U, hIDAT, hIHDR, 0 + /* Allocates 'length+1'; checked in the handler */ + +# define PNG_CHUNK(cHNK, index) { png_handle_ ## cHNK, CD ## cHNK }, + PNG_KNOWN_CHUNKS +# undef PNG_CHUNK +}; + + +static png_index +png_chunk_index_from_name(png_uint_32 chunk_name) +{ + /* For chunk png_cHNK return PNG_INDEX_cHNK. Return PNG_INDEX_unknown if + * chunk_name is not known. Notice that in a particular build "known" does + * not necessarily mean "supported", although the inverse applies. + */ + switch (chunk_name) { - int c = cn & 0xff; +# define PNG_CHUNK(cHNK, index)\ + case png_ ## cHNK: return PNG_INDEX_ ## cHNK; /* == index */ - if (c < 65 || c > 122 || (c > 90 && c < 97)) - png_chunk_error(png_ptr, "invalid chunk type"); + PNG_KNOWN_CHUNKS - cn >>= 8; +# undef PNG_CHUNK + + default: return PNG_INDEX_unknown; } } -void /* PRIVATE */ -png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) +png_handle_result_code /*PRIVATE*/ +png_handle_chunk(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_alloc_size_t limit = PNG_UINT_31_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - if (png_ptr->chunk_name == png_IDAT) + /* CSE: these things don't change, these autos are just to save typing and + * make the code more clear. + */ + const png_uint_32 chunk_name = png_ptr->chunk_name; + const png_index chunk_index = png_chunk_index_from_name(chunk_name); + + png_handle_result_code handled = handled_error; + png_const_charp errmsg = NULL; + + /* Is this a known chunk? If not there are no checks performed here; + * png_handle_unknown does the correct checks. This means that the values + * for known but unsupported chunks in the above table are not used here + * however the chunks_seen fields in png_struct are still set. + */ + if (chunk_index == PNG_INDEX_unknown || + read_chunks[chunk_index].handler == NULL) { - png_alloc_size_t idat_limit = PNG_UINT_31_MAX; - size_t row_factor = - (size_t)png_ptr->width - * (size_t)png_ptr->channels - * (png_ptr->bit_depth > 8? 2: 1) - + 1 - + (png_ptr->interlaced? 6: 0); - if (png_ptr->height > PNG_UINT_32_MAX/row_factor) - idat_limit = PNG_UINT_31_MAX; - else - idat_limit = png_ptr->height * row_factor; - row_factor = row_factor > 32566? 32566 : row_factor; - idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ - idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; - limit = limit < idat_limit? idat_limit : limit; + handled = png_handle_unknown( + png_ptr, info_ptr, length, PNG_HANDLE_CHUNK_AS_DEFAULT); + } + + /* First check the position. The first check is historical; the stream must + * start with IHDR and anything else causes libpng to give up immediately. + */ + else if (chunk_index != PNG_INDEX_IHDR && + (png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); /* NORETURN */ + + /* Before all the pos_before chunks, after all the pos_after chunks. */ + else if (((png_ptr->mode & read_chunks[chunk_index].pos_before) != 0) || + ((png_ptr->mode & read_chunks[chunk_index].pos_after) != + read_chunks[chunk_index].pos_after)) + { + errmsg = "out of place"; + } + + /* Now check for duplicates: duplicated critical chunks also produce a + * full error. + */ + else if (read_chunks[chunk_index].multiple == 0 && + png_file_has_chunk(png_ptr, chunk_index)) + { + errmsg = "duplicate"; + } + + else if (length < read_chunks[chunk_index].min_length) + errmsg = "too short"; + else + { + /* NOTE: apart from IHDR the critical chunks (PLTE, IDAT and IEND) are set + * up above not to do any length checks. + * + * The png_chunk_max check ensures that the variable length chunks are + * always checked at this point for being within the system allocation + * limits. + */ + unsigned max_length = read_chunks[chunk_index].max_length; + + switch (max_length) + { + case Limit: + /* png_read_chunk_header has already png_error'ed chunks with a + * length exceeding the 31-bit PNG limit, so just check the memory + * limit: + */ + if (length <= png_chunk_max(png_ptr)) + goto MeetsLimit; + + errmsg = "length exceeds libpng limit"; + break; + + default: + if (length <= max_length) + goto MeetsLimit; + + errmsg = "too long"; + break; + + case NoCheck: + MeetsLimit: + handled = read_chunks[chunk_index].handler( + png_ptr, info_ptr, length); + break; + } + } + + /* If there was an error or the chunk was simply skipped it is not counted as + * 'seen'. + */ + if (errmsg != NULL) + { + if (PNG_CHUNK_CRITICAL(chunk_name)) /* stop immediately */ + png_chunk_error(png_ptr, errmsg); + else /* ancillary chunk */ + { + /* The chunk data is skipped: */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, errmsg); + } } - if (length > limit) + else if (handled >= handled_saved) { - png_debug2(0," length = %lu, limit = %lu", - (unsigned long)length,(unsigned long)limit); - png_benign_error(png_ptr, "chunk data is too large"); + if (chunk_index != PNG_INDEX_unknown) + png_file_add_chunk(png_ptr, chunk_index); } + + return handled; } /* Combines the row recently read in with the existing pixels in the row. This @@ -4336,6 +4227,9 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output, avail_in = png_ptr->IDAT_read_size; + if (avail_in > png_chunk_max(png_ptr)) + avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr); + if (avail_in > png_ptr->idat_size) avail_in = (uInt)png_ptr->idat_size; @@ -4343,8 +4237,13 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output, * to minimize memory usage by causing lots of re-allocs, but * realistically doing IDAT_read_size re-allocs is not likely to be a * big problem. + * + * An error here corresponds to the system being out of memory. */ - buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); + buffer = png_read_buffer(png_ptr, avail_in); + + if (buffer == NULL) + png_chunk_error(png_ptr, "out of memory"); png_crc_read(png_ptr, buffer, avail_in); png_ptr->idat_size -= avail_in; diff --git a/source/libs/libpng/libpng-src/pngset.c b/source/libs/libpng/libpng-src/pngset.c index 8e2b869d6..d7f3393c4 100644 --- a/source/libs/libpng/libpng-src/pngset.c +++ b/source/libs/libpng/libpng-src/pngset.c @@ -41,27 +41,21 @@ png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point blue_y) { - png_xy xy; - png_debug1(1, "in %s storage function", "cHRM fixed"); if (png_ptr == NULL || info_ptr == NULL) return; - xy.redx = red_x; - xy.redy = red_y; - xy.greenx = green_x; - xy.greeny = green_y; - xy.bluex = blue_x; - xy.bluey = blue_y; - xy.whitex = white_x; - xy.whitey = white_y; - - if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, - 2/* override with app values*/) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + info_ptr->cHRM.redx = red_x; + info_ptr->cHRM.redy = red_y; + info_ptr->cHRM.greenx = green_x; + info_ptr->cHRM.greeny = green_y; + info_ptr->cHRM.bluex = blue_x; + info_ptr->cHRM.bluey = blue_y; + info_ptr->cHRM.whitex = white_x; + info_ptr->cHRM.whitey = white_y; - png_colorspace_sync_info(png_ptr, info_ptr); + info_ptr->valid |= PNG_INFO_cHRM; } void PNGFAPI @@ -73,6 +67,7 @@ png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, png_fixed_point int_blue_Z) { png_XYZ XYZ; + png_xy xy; png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); @@ -89,11 +84,14 @@ png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, XYZ.blue_Y = int_blue_Y; XYZ.blue_Z = int_blue_Z; - if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, - &XYZ, 2) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + if (png_xy_from_XYZ(&xy, &XYZ) == 0) + { + info_ptr->cHRM = xy; + info_ptr->valid |= PNG_INFO_cHRM; + } - png_colorspace_sync_info(png_ptr, info_ptr); + else + png_app_error(png_ptr, "invalid cHRM XYZ"); } # ifdef PNG_FLOATING_POINT_SUPPORTED @@ -205,8 +203,7 @@ png_set_cLLI(png_const_structrp png_ptr, png_inforp info_ptr, #ifdef PNG_mDCV_SUPPORTED static png_uint_16 -png_ITU_fixed_16(png_const_structrp png_ptr, png_fixed_point v, - png_const_charp text) +png_ITU_fixed_16(int *error, png_fixed_point v) { /* Return a safe uint16_t value scaled according to the ITU H273 rules for * 16-bit display chromaticities. Functions like the corresponding @@ -216,11 +213,10 @@ png_ITU_fixed_16(png_const_structrp png_ptr, png_fixed_point v, */ v /= 2; /* rounds to 0 in C: avoids insignificant arithmetic errors */ if (v > 65535 || v < 0) - png_fixed_error(png_ptr, text); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(text) -# endif + { + *error = 1; + return 0; + } return (png_uint_16)/*SAFE*/v; } @@ -235,6 +231,7 @@ png_set_mDCV_fixed(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 minDL) { png_uint_16 rx, ry, gx, gy, bx, by, wx, wy; + int error; png_debug1(1, "in %s storage function", "mDCV"); @@ -242,14 +239,23 @@ png_set_mDCV_fixed(png_const_structrp png_ptr, png_inforp info_ptr, return; /* Check the input values to ensure they are in the expected range: */ - rx = png_ITU_fixed_16(png_ptr, red_x, "png_set_mDCV(red(x))"); - ry = png_ITU_fixed_16(png_ptr, red_y, "png_set_mDCV(red(y))"); - gx = png_ITU_fixed_16(png_ptr, green_x, "png_set_mDCV(green(x))"); - gy = png_ITU_fixed_16(png_ptr, green_y, "png_set_mDCV(green(y))"); - bx = png_ITU_fixed_16(png_ptr, blue_x, "png_set_mDCV(blue(x))"); - by = png_ITU_fixed_16(png_ptr, blue_y, "png_set_mDCV(blue(y))"); - wx = png_ITU_fixed_16(png_ptr, white_x, "png_set_mDCV(white(x))"); - wy = png_ITU_fixed_16(png_ptr, white_y, "png_set_mDCV(white(y))"); + error = 0; + rx = png_ITU_fixed_16(&error, red_x); + ry = png_ITU_fixed_16(&error, red_y); + gx = png_ITU_fixed_16(&error, green_x); + gy = png_ITU_fixed_16(&error, green_y); + bx = png_ITU_fixed_16(&error, blue_x); + by = png_ITU_fixed_16(&error, blue_y); + wx = png_ITU_fixed_16(&error, white_x); + wy = png_ITU_fixed_16(&error, white_y); + + if (error) + { + png_chunk_report(png_ptr, + "mDCV chromaticities outside representable range", + PNG_CHUNK_WRITE_ERROR); + return; + } /* Check the light level range: */ if (maxDL > 0x7FFFFFFFU || minDL > 0x7FFFFFFFU) @@ -362,8 +368,8 @@ png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; - png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); - png_colorspace_sync_info(png_ptr, info_ptr); + info_ptr->gamma = file_gamma; + info_ptr->valid |= PNG_INFO_gAMA; } # ifdef PNG_FLOATING_POINT_SUPPORTED @@ -822,8 +828,8 @@ png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) if (png_ptr == NULL || info_ptr == NULL) return; - (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); - png_colorspace_sync_info(png_ptr, info_ptr); + info_ptr->rendering_intent = srgb_intent; + info_ptr->valid |= PNG_INFO_sRGB; } void PNGAPI @@ -835,15 +841,20 @@ png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; - if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, - srgb_intent) != 0) - { - /* This causes the gAMA and cHRM to be written too */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } + png_set_sRGB(png_ptr, info_ptr, srgb_intent); - png_colorspace_sync_info(png_ptr, info_ptr); +# ifdef PNG_gAMA_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); +# endif /* gAMA */ + +# ifdef PNG_cHRM_SUPPORTED + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000); +# endif /* cHRM */ } #endif /* sRGB */ @@ -866,27 +877,6 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, if (compression_type != PNG_COMPRESSION_TYPE_BASE) png_app_error(png_ptr, "Invalid iCCP compression method"); - /* Set the colorspace first because this validates the profile; do not - * override previously set app cHRM or gAMA here (because likely as not the - * application knows better than libpng what the correct values are.) Pass - * the info_ptr color_type field to png_colorspace_set_ICC because in the - * write case it has not yet been stored in png_ptr. - */ - { - int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, - proflen, profile, info_ptr->color_type); - - png_colorspace_sync_info(png_ptr, info_ptr); - - /* Don't do any of the copying if the profile was bad, or inconsistent. */ - if (result == 0) - return; - - /* But do write the gAMA and cHRM chunks from the profile. */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - length = strlen(name)+1; new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); @@ -1841,8 +1831,24 @@ png_set_chunk_malloc_max(png_structrp png_ptr, { png_debug(1, "in png_set_chunk_malloc_max"); + /* pngstruct::user_chunk_malloc_max is initialized to a non-zero value in + * png.c. This API supports '0' for unlimited, make sure the correct + * (unlimited) value is set here to avoid a need to check for 0 everywhere + * the parameter is used. + */ if (png_ptr != NULL) - png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; + { + if (user_chunk_malloc_max == 0U) /* unlimited */ + { +# ifdef PNG_MAX_MALLOC_64K + png_ptr->user_chunk_malloc_max = 65536U; +# else + png_ptr->user_chunk_malloc_max = PNG_SIZE_MAX; +# endif + } + else + png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; + } } #endif /* ?SET_USER_LIMITS */ diff --git a/source/libs/libpng/libpng-src/pngstruct.h b/source/libs/libpng/libpng-src/pngstruct.h index 7e919d0a3..324424495 100644 --- a/source/libs/libpng/libpng-src/pngstruct.h +++ b/source/libs/libpng/libpng-src/pngstruct.h @@ -69,13 +69,7 @@ typedef struct png_compression_buffer /* Colorspace support; structures used in png_struct, png_info and in internal * functions to hold and communicate information about the color space. - * - * PNG_COLORSPACE_SUPPORTED is only required if the application will perform - * colorspace corrections, otherwise all the colorspace information can be - * skipped and the size of libpng can be reduced (significantly) by compiling - * out the colorspace support. */ -#ifdef PNG_COLORSPACE_SUPPORTED /* The chromaticities of the red, green and blue colorants and the chromaticity * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). */ @@ -96,48 +90,36 @@ typedef struct png_XYZ png_fixed_point green_X, green_Y, green_Z; png_fixed_point blue_X, blue_Y, blue_Z; } png_XYZ; -#endif /* COLORSPACE */ -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -/* A colorspace is all the above plus, potentially, profile information; - * however at present libpng does not use the profile internally so it is only - * stored in the png_info struct (if iCCP is supported.) The rendering intent - * is retained here and is checked. - * - * The file gamma encoding information is also stored here and gamma correction - * is done by libpng, whereas color correction must currently be done by the - * application. +/* Chunk index values as an enum, PNG_INDEX_unknown is also a count of the + * number of chunks. */ -typedef struct png_colorspace +#define PNG_CHUNK(cHNK, i) PNG_INDEX_ ## cHNK = (i), +typedef enum { -#ifdef PNG_GAMMA_SUPPORTED - png_fixed_point gamma; /* File gamma */ -#endif + PNG_KNOWN_CHUNKS + PNG_INDEX_unknown +} png_index; +#undef PNG_CHUNK -#ifdef PNG_COLORSPACE_SUPPORTED - png_xy end_points_xy; /* End points as chromaticities */ - png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ - png_uint_16 rendering_intent; /* Rendering intent of a profile */ -#endif - - /* Flags are always defined to simplify the code. */ - png_uint_16 flags; /* As defined below */ -} png_colorspace, * PNG_RESTRICT png_colorspacerp; +/* Chunk flag values. These are (png_uint_32 values) with exactly one bit set + * and can be combined into a flag set with bitwise 'or'. + * + * TODO: C23: convert these macros to C23 inlines (which are static). + */ +#define png_chunk_flag_from_index(i) (0x80000000U >> (31 - (i))) + /* The flag coresponding to the given png_index enum value. This is defined + * for png_unknown as well (until it reaches the value 32) but this should + * not be relied on. + */ -typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; +#define png_file_has_chunk(png_ptr, i)\ + (((png_ptr)->chunks & png_chunk_flag_from_index(i)) != 0) + /* The chunk has been recorded in png_struct */ -/* General flags for the 'flags' field */ -#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 -#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 -#define PNG_COLORSPACE_HAVE_INTENT 0x0004 -#define PNG_COLORSPACE_FROM_gAMA 0x0008 -#define PNG_COLORSPACE_FROM_cHRM 0x0010 -#define PNG_COLORSPACE_FROM_sRGB 0x0020 -#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 -#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ -#define PNG_COLORSPACE_INVALID 0x8000 -#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) -#endif /* COLORSPACE || GAMMA */ +#define png_file_add_chunk(pnt_ptr, i)\ + ((void)((png_ptr)->chunks |= png_chunk_flag_from_index(i))) + /* Record the chunk in the png_struct */ struct png_struct_def { @@ -209,6 +191,11 @@ struct png_struct_def int zlib_set_strategy; #endif + png_uint_32 chunks; /* PNG_CF_ for every chunk read or (NYI) written */ +# define png_has_chunk(png_ptr, cHNK)\ + png_file_has_chunk(png_ptr, PNG_INDEX_ ## cHNK) + /* Convenience accessor - use this to check for a known chunk by name */ + png_uint_32 width; /* width of image in pixels */ png_uint_32 height; /* height of image in pixels */ png_uint_32 num_rows; /* number of rows in current pass */ @@ -285,9 +272,16 @@ struct png_struct_def png_uint_32 flush_rows; /* number of rows written since last flush */ #endif +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_xy chromaticities; /* From mDVC, cICP, [iCCP], sRGB or cHRM */ +#endif + #ifdef PNG_READ_GAMMA_SUPPORTED int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ - png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ + png_fixed_point screen_gamma; /* screen gamma value (display exponent) */ + png_fixed_point file_gamma; /* file gamma value (encoding exponent) */ + png_fixed_point chunk_gamma; /* from cICP, iCCP, sRGB or gAMA */ + png_fixed_point default_gamma;/* from png_set_alpha_mode */ png_bytep gamma_table; /* gamma table for 8-bit depth files */ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ @@ -299,7 +293,7 @@ struct png_struct_def png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -#endif +#endif /* READ_GAMMA */ #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) png_color_8 sig_bit; /* significant bits in each available channel */ @@ -349,8 +343,8 @@ struct png_struct_def /* To do: remove this from libpng-1.7 */ #ifdef PNG_TIME_RFC1123_SUPPORTED char time_buffer[29]; /* String to hold RFC 1123 time text */ -#endif -#endif +#endif /* TIME_RFC1123 */ +#endif /* LIBPNG_VER < 10700 */ /* New members added in libpng-1.0.6 */ @@ -360,8 +354,8 @@ struct png_struct_def png_voidp user_chunk_ptr; #ifdef PNG_READ_USER_CHUNKS_SUPPORTED png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ -#endif -#endif +#endif /* READ_USER_CHUNKS */ +#endif /* USER_CHUNKS */ #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED int unknown_default; /* As PNG_HANDLE_* */ @@ -468,11 +462,5 @@ struct png_struct_def /* New member added in libpng-1.5.7 */ void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, png_bytep row, png_const_bytep prev_row); - -#ifdef PNG_READ_SUPPORTED -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - png_colorspace colorspace; -#endif -#endif }; #endif /* PNGSTRUCT_H */ diff --git a/source/libs/libpng/libpng-src/pngtest.c b/source/libs/libpng/libpng-src/pngtest.c index 2d54a51f3..1975b4b68 100644 --- a/source/libs/libpng/libpng-src/pngtest.c +++ b/source/libs/libpng/libpng-src/pngtest.c @@ -50,7 +50,7 @@ #define STDERR stdout /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_46 Your_png_h_is_not_version_1_6_46; +typedef png_libpng_version_1_6_47 Your_png_h_is_not_version_1_6_47; /* Ensure that all version numbers in png.h are consistent with one another. */ #if (PNG_LIBPNG_VER != PNG_LIBPNG_VER_MAJOR * 10000 + \ @@ -2137,6 +2137,7 @@ main(int argc, char *argv[]) fprintf(STDERR, " libpng FAILS test\n"); dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); +#ifdef PNG_USER_LIMITS_SUPPORTED fprintf(STDERR, " Default limits:\n"); fprintf(STDERR, " width_max = %lu\n", (unsigned long) png_get_user_width_max(dummy_ptr)); @@ -2152,6 +2153,7 @@ main(int argc, char *argv[]) else fprintf(STDERR, " malloc_max = %lu\n", (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); +#endif png_destroy_read_struct(&dummy_ptr, NULL, NULL); return (ierror != 0); diff --git a/source/libs/libpng/libpng-src/pngwrite.c b/source/libs/libpng/libpng-src/pngwrite.c index f6d9d816c..b7aeff4ce 100644 --- a/source/libs/libpng/libpng-src/pngwrite.c +++ b/source/libs/libpng/libpng-src/pngwrite.c @@ -181,7 +181,6 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) } #endif -#ifdef PNG_COLORSPACE_SUPPORTED # ifdef PNG_WRITE_cICP_SUPPORTED /* Priority 4 */ if ((info_ptr->valid & PNG_INFO_cICP) != 0) { @@ -193,50 +192,28 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) } # endif - /* PNG v3 change: it is now permitted to write both sRGB and ICC profiles, - * however because the libpng code auto-generates an sRGB for the - * corresponding ICC profiles and because PNG v2 disallowed this we need - * to only write one. - * - * Remove the PNG v2 warning about writing an sRGB ICC profile as well - * because it's invalid with PNG v3. - */ # ifdef PNG_WRITE_iCCP_SUPPORTED /* Priority 3 */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_iCCP) != 0) + if ((info_ptr->valid & PNG_INFO_iCCP) != 0) { png_write_iCCP(png_ptr, info_ptr->iccp_name, - info_ptr->iccp_profile); + info_ptr->iccp_profile, info_ptr->iccp_proflen); } -# ifdef PNG_WRITE_sRGB_SUPPORTED - else -# endif # endif # ifdef PNG_WRITE_sRGB_SUPPORTED /* Priority 2 */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_sRGB) != 0) - png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); + if ((info_ptr->valid & PNG_INFO_sRGB) != 0) + png_write_sRGB(png_ptr, info_ptr->rendering_intent); # endif /* WRITE_sRGB */ -#endif /* COLORSPACE */ -#ifdef PNG_GAMMA_SUPPORTED # ifdef PNG_WRITE_gAMA_SUPPORTED /* Priority 1 */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && - (info_ptr->valid & PNG_INFO_gAMA) != 0) - png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); + if ((info_ptr->valid & PNG_INFO_gAMA) != 0) + png_write_gAMA_fixed(png_ptr, info_ptr->gamma); # endif -#endif -#ifdef PNG_COLORSPACE_SUPPORTED # ifdef PNG_WRITE_cHRM_SUPPORTED /* Also priority 1 */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && - (info_ptr->valid & PNG_INFO_cHRM) != 0) - png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); + if ((info_ptr->valid & PNG_INFO_cHRM) != 0) + png_write_cHRM_fixed(png_ptr, &info_ptr->cHRM); # endif -#endif png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; } diff --git a/source/libs/libpng/libpng-src/pngwutil.c b/source/libs/libpng/libpng-src/pngwutil.c index c98475a08..be706afe6 100644 --- a/source/libs/libpng/libpng-src/pngwutil.c +++ b/source/libs/libpng/libpng-src/pngwutil.c @@ -1132,10 +1132,9 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent) /* Write an iCCP chunk */ void /* PRIVATE */ png_write_iCCP(png_structrp png_ptr, png_const_charp name, - png_const_bytep profile) + png_const_bytep profile, png_uint_32 profile_len) { png_uint_32 name_len; - png_uint_32 profile_len; png_byte new_name[81]; /* 1 byte for the compression byte */ compression_state comp; png_uint_32 temp; @@ -1148,11 +1147,12 @@ png_write_iCCP(png_structrp png_ptr, png_const_charp name, if (profile == NULL) png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ - profile_len = png_get_uint_32(profile); - if (profile_len < 132) png_error(png_ptr, "ICC profile too short"); + if (png_get_uint_32(profile) != profile_len) + png_error(png_ptr, "Incorrect data in iCCP"); + temp = (png_uint_32) (*(profile+8)); if (temp > 3 && (profile_len & 0x03)) png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); diff --git a/source/libs/libpng/libpng-src/scripts/libpng-config-head.in b/source/libs/libpng/libpng-src/scripts/libpng-config-head.in index 230eccde1..12574fcab 100644 --- a/source/libs/libpng/libpng-src/scripts/libpng-config-head.in +++ b/source/libs/libpng/libpng-src/scripts/libpng-config-head.in @@ -11,7 +11,7 @@ # Modeled after libxml-config. -version=1.6.46 +version=1.6.47 prefix="" libdir="" libs="" diff --git a/source/libs/libpng/libpng-src/scripts/libpng.pc.in b/source/libs/libpng/libpng-src/scripts/libpng.pc.in index d955d336a..10e29bfbd 100644 --- a/source/libs/libpng/libpng-src/scripts/libpng.pc.in +++ b/source/libs/libpng/libpng-src/scripts/libpng.pc.in @@ -5,6 +5,6 @@ includedir=@includedir@/libpng16 Name: libpng Description: Loads and saves PNG files -Version: 1.6.46 +Version: 1.6.47 Libs: -L${libdir} -lpng16 Cflags: -I${includedir} diff --git a/source/libs/libpng/libpng-src/scripts/pnglibconf.dfa b/source/libs/libpng/libpng-src/scripts/pnglibconf.dfa index 11b2e3a8e..f466da1a3 100644 --- a/source/libs/libpng/libpng-src/scripts/pnglibconf.dfa +++ b/source/libs/libpng/libpng-src/scripts/pnglibconf.dfa @@ -711,7 +711,7 @@ option WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT # processing, it just validates the data in the PNG file. option GAMMA disabled -option COLORSPACE enables GAMMA disabled +option COLORSPACE disabled # When an ICC profile is read, or png_set, it will be checked for a match # against known sRGB profiles if the sRGB handling is enabled. The @@ -851,16 +851,16 @@ chunk cLLI chunk eXIf chunk gAMA enables GAMMA chunk hIST -chunk iCCP enables COLORSPACE, GAMMA +chunk iCCP enables GAMMA chunk iTXt enables TEXT -chunk mDCV +chunk mDCV enables COLORSPACE chunk oFFs chunk pCAL chunk pHYs chunk sBIT chunk sCAL chunk sPLT -chunk sRGB enables COLORSPACE, GAMMA, SET_OPTION +chunk sRGB enables GAMMA, SET_OPTION chunk tEXt requires TEXT chunk tIME chunk tRNS @@ -995,7 +995,8 @@ option SIMPLIFIED_READ, READ_EXPAND, READ_16BIT, READ_EXPAND_16, READ_SCALE_16_TO_8, READ_RGB_TO_GRAY, READ_ALPHA_MODE, READ_BACKGROUND, READ_STRIP_ALPHA, READ_FILLER, READ_SWAP, READ_PACK, READ_GRAY_TO_RGB, READ_GAMMA, - READ_tRNS, READ_bKGD, READ_gAMA, READ_cHRM, READ_sRGB, READ_sBIT + READ_tRNS, READ_bKGD, READ_gAMA, READ_cHRM, READ_sRGB, READ_mDCV, + READ_cICP, READ_sBIT # AFIRST and BGR read options: # Prior to libpng 1.6.8 these were disabled but switched on if the low level diff --git a/source/libs/libpng/libpng-src/scripts/pnglibconf.h.prebuilt b/source/libs/libpng/libpng-src/scripts/pnglibconf.h.prebuilt index b7f6928a0..748220bfc 100644 --- a/source/libs/libpng/libpng-src/scripts/pnglibconf.h.prebuilt +++ b/source/libs/libpng/libpng-src/scripts/pnglibconf.h.prebuilt @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.46 */ +/* libpng version 1.6.47 */ /* Copyright (c) 2018-2025 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/source/libs/libpng/version.ac b/source/libs/libpng/version.ac index 669d1f309..0e7ce2e39 100644 --- a/source/libs/libpng/version.ac +++ b/source/libs/libpng/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current libpng version -m4_define([libpng_version], [1.6.46]) +m4_define([libpng_version], [1.6.47]) diff --git a/source/tardate.ac b/source/tardate.ac index 04046d255..c5255558a 100644 --- a/source/tardate.ac +++ b/source/tardate.ac @@ -1,5 +1,5 @@ -dnl $Id: tardate.ac 70573 2024-03-10 21:37:05Z karl $ -dnl Copyright 2016-2024 Karl Berry <tex-live@tug.org> +dnl $Id: tardate.ac 74485 2025-03-06 22:52:00Z karl $ +dnl Copyright 2016-2025 Karl Berry <tex-live@tug.org> dnl Copyright 2010-2015 Peter Breitenlohner <tex-live@tug.org> dnl dnl This file is free software; the copyright holder @@ -9,4 +9,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current TeX Live tarball version -m4_define([tex_live_tardate], [2024-03-10]) +m4_define([tex_live_tardate], [2025-03-07]) diff --git a/source/texk/README b/source/texk/README index 087899d4e..632d7b449 100644 --- a/source/texk/README +++ b/source/texk/README @@ -1,4 +1,4 @@ -$Id: README 74112 2025-02-18 21:53:39Z karl $ +$Id: README 74361 2025-02-28 23:31:39Z karl $ Copyright 2006-2025 TeX Users Group. You may freely use, modify and/or distribute this file. @@ -67,7 +67,7 @@ dvisvgm 3.4.3 - checked 11jan25 https://github.com/mgieseki/dvisvgm https://ctan.org/pkg/dvisvgm -gregorio 6.1.0beta2 - checked 18feb25 +gregorio 6.1.0 - checked 28feb25 https://mirror.ctan.org/support/gregoriotex/ gsftopk - from Paul Vojta's xdvi. diff --git a/source/texk/configure b/source/texk/configure index a2148cf9e..d27dbc134 100755 --- a/source/texk/configure +++ b/source/texk/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for TeX Live texk 2025. +# Generated by GNU Autoconf 2.72 for TeX Live texk 2026/dev. # # Report bugs to <tex-live@tug.org>. # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='TeX Live texk' PACKAGE_TARNAME='tex-live-texk' -PACKAGE_VERSION='2025' -PACKAGE_STRING='TeX Live texk 2025' +PACKAGE_VERSION='2026/dev' +PACKAGE_STRING='TeX Live texk 2026/dev' PACKAGE_BUGREPORT='tex-live@tug.org' PACKAGE_URL='' @@ -1382,7 +1382,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures TeX Live texk 2025 to adapt to many kinds of systems. +'configure' configures TeX Live texk 2026/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1453,7 +1453,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of TeX Live texk 2025:";; + short | recursive ) echo "Configuration of TeX Live texk 2026/dev:";; esac cat <<\_ACEOF @@ -1639,7 +1639,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -TeX Live texk configure 2025 +TeX Live texk configure 2026/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1799,7 +1799,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by TeX Live texk $as_me 2025, which was +It was created by TeX Live texk $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -5776,7 +5776,7 @@ fi # Define the identity of the package. PACKAGE='tex-live-texk' - VERSION='2025' + VERSION='2026/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -6701,7 +6701,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by TeX Live texk $as_me 2025, which was +This file was extended by TeX Live texk $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6760,7 +6760,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -TeX Live texk config.status 2025 +TeX Live texk config.status 2026/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/texk/kpathsea/ChangeLog b/source/texk/kpathsea/ChangeLog index 995d64077..9a80b60c6 100644 --- a/source/texk/kpathsea/ChangeLog +++ b/source/texk/kpathsea/ChangeLog @@ -1,3 +1,11 @@ +2025-03-08 Karl Berry <karl@tug.org> + + * version.ac: 6.4.2/dev. + +2025-03-07 Karl Berry <karl@tug.org> + + * TL'25 release. + 2025-02-12 Karl Berry <karl@freefriends.org> * texmf.cnf (shell_escape_commands): doc link to diff --git a/source/texk/kpathsea/NEWS b/source/texk/kpathsea/NEWS index 7f14c89ea..147b4aa64 100644 --- a/source/texk/kpathsea/NEWS +++ b/source/texk/kpathsea/NEWS @@ -1,7 +1,7 @@ -$Id: NEWS 73591 2025-01-25 18:41:15Z karl $ +$Id: NEWS 74485 2025-03-06 22:52:00Z karl $ This file records noteworthy changes. (Public domain.) -6.4.1 (for TeX Live 2025) +6.4.1 (for TeX Live 2025, 7 March 2025) * kpsewhich outputs a blank line when a given file cannot be found, if more than one file to search for is specified. diff --git a/source/texk/kpathsea/c-auto.in b/source/texk/kpathsea/c-auto.in index 8a22aa67c..8ffe4c8a6 100644 --- a/source/texk/kpathsea/c-auto.in +++ b/source/texk/kpathsea/c-auto.in @@ -23,7 +23,7 @@ #define KPATHSEA_C_AUTO_H /* kpathsea: the version string. */ -#define KPSEVERSION "kpathsea version 6.4.1" +#define KPSEVERSION "kpathsea version 6.4.2/dev" /* Define to 1 if the 'closedir' function returns void instead of int. */ #undef CLOSEDIR_VOID diff --git a/source/texk/kpathsea/configure b/source/texk/kpathsea/configure index 851b45c04..1ab8dc140 100755 --- a/source/texk/kpathsea/configure +++ b/source/texk/kpathsea/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for Kpathsea 6.4.1. +# Generated by GNU Autoconf 2.72 for Kpathsea 6.4.2/dev. # # Report bugs to <tex-k@tug.org>. # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Kpathsea' PACKAGE_TARNAME='kpathsea' -PACKAGE_VERSION='6.4.1' -PACKAGE_STRING='Kpathsea 6.4.1' +PACKAGE_VERSION='6.4.2/dev' +PACKAGE_STRING='Kpathsea 6.4.2/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1376,7 +1376,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures Kpathsea 6.4.1 to adapt to many kinds of systems. +'configure' configures Kpathsea 6.4.2/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1447,7 +1447,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Kpathsea 6.4.1:";; + short | recursive ) echo "Configuration of Kpathsea 6.4.2/dev:";; esac cat <<\_ACEOF @@ -1576,7 +1576,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Kpathsea configure 6.4.1 +Kpathsea configure 6.4.2/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2357,7 +2357,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Kpathsea $as_me 6.4.1, which was +It was created by Kpathsea $as_me 6.4.2/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3137,14 +3137,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -KPSEVERSION=6.4.1 +KPSEVERSION=6.4.2/dev -KPSE_LT_VERSINFO=10:1:4 +KPSE_LT_VERSINFO=10:2:4 - WEB2CVERSION=" (TeX Live 2025)" + WEB2CVERSION=" (TeX Live 2026/dev)" am__api_version='1.17' @@ -9259,7 +9259,7 @@ fi # Define the identity of the package. PACKAGE='kpathsea' - VERSION='6.4.1' + VERSION='6.4.2/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -16888,7 +16888,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Kpathsea $as_me 6.4.1, which was +This file was extended by Kpathsea $as_me 6.4.2/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16956,7 +16956,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -Kpathsea config.status 6.4.1 +Kpathsea config.status 6.4.2/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/texk/kpathsea/version.ac b/source/texk/kpathsea/version.ac index 52959db0a..8b7d26c1e 100644 --- a/source/texk/kpathsea/version.ac +++ b/source/texk/kpathsea/version.ac @@ -1,4 +1,4 @@ -dnl $Id: version.ac 73591 2025-01-25 18:41:15Z karl $ +dnl $Id: version.ac 74529 2025-03-08 18:17:45Z karl $ dnl Copyright 2016-2025 Karl Berry <tex-live@tug.org> dnl Copyright 2011-2015 Peter Breitenlohner <tex-live@tug.org> dnl @@ -23,4 +23,4 @@ dnl releases. dnl -------------------------------------------------------- dnl dnl This file is m4-included from configure.ac. -m4_define([kpse_version], [6.4.1]) +m4_define([kpse_version], [6.4.2/dev]) diff --git a/source/texk/texlive/configure b/source/texk/texlive/configure index e218d2480..6657a12ad 100755 --- a/source/texk/texlive/configure +++ b/source/texk/texlive/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for TeX Live Scripts 2025. +# Generated by GNU Autoconf 2.72 for TeX Live Scripts 2026/dev. # # Report bugs to <tex-k@tug.org>. # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='TeX Live Scripts' PACKAGE_TARNAME='tex-live-scripts' -PACKAGE_VERSION='2025' -PACKAGE_STRING='TeX Live Scripts 2025' +PACKAGE_VERSION='2026/dev' +PACKAGE_STRING='TeX Live Scripts 2026/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1276,7 +1276,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures TeX Live Scripts 2025 to adapt to many kinds of systems. +'configure' configures TeX Live Scripts 2026/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1344,7 +1344,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of TeX Live Scripts 2025:";; + short | recursive ) echo "Configuration of TeX Live Scripts 2026/dev:";; esac cat <<\_ACEOF @@ -1440,7 +1440,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -TeX Live Scripts configure 2025 +TeX Live Scripts configure 2026/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1517,7 +1517,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by TeX Live Scripts $as_me 2025, which was +It was created by TeX Live Scripts $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -2986,7 +2986,7 @@ fi # Define the identity of the package. PACKAGE='tex-live-scripts' - VERSION='2025' + VERSION='2026/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5129,7 +5129,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by TeX Live Scripts $as_me 2025, which was +This file was extended by TeX Live Scripts $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5188,7 +5188,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -TeX Live Scripts config.status 2025 +TeX Live Scripts config.status 2026/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/texk/web2c/ChangeLog b/source/texk/web2c/ChangeLog index fa66ecfca..992baa508 100644 --- a/source/texk/web2c/ChangeLog +++ b/source/texk/web2c/ChangeLog @@ -1,3 +1,17 @@ +2025-03-10 Andreas Scherer <https://ascherer.github.io> + + * texk/web2c/tangle.ch, + * texk/web2c/tangleboot.pin: Reject strings as macro names. + Report and initial patch from Benjamin Gray + (https://tug.org/pipermail/tex-k/2025-March/004163.html). + +2025-03-10 Andreas Scherer <https://ascherer.github.io> + + * texk/web2c/tangle.ch, + * texk/web2c/tangleboot.pin: Change case for letters only. + Report and initial patch from Benjamin Gray + (https://tug.org/pipermail/tex-k/2025-March/004161.html). + 2025-02-01 Karl Berry <karl@freefriends.org> * tex.ch (24.336): comment out this patch for interactive deletion diff --git a/source/texk/web2c/NEWS b/source/texk/web2c/NEWS index c2ebd02a4..34060576d 100644 --- a/source/texk/web2c/NEWS +++ b/source/texk/web2c/NEWS @@ -2,7 +2,7 @@ This file records noteworthy changes. (Public domain.) See also */NEWS, */ChangeLog, etc. -2025 (for TeX Live 2025) +2025 (for TeX Live 2025, 7 March 2025) * Most engines: new primitive parameter \ignoreprimitiveerror: if set to 1, the error "Infinite glue shrinkage found in box being split" becomes a warning (thus program exit status remains 0). Other values diff --git a/source/texk/web2c/configure b/source/texk/web2c/configure index 08a7cac77..548d8dc25 100755 --- a/source/texk/web2c/configure +++ b/source/texk/web2c/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for Web2C 2025. +# Generated by GNU Autoconf 2.72 for Web2C 2026/dev. # # Report bugs to <tex-k@tug.org>. # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Web2C' PACKAGE_TARNAME='web2c' -PACKAGE_VERSION='2025' -PACKAGE_STRING='Web2C 2025' +PACKAGE_VERSION='2026/dev' +PACKAGE_STRING='Web2C 2026/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1672,7 +1672,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures Web2C 2025 to adapt to many kinds of systems. +'configure' configures Web2C 2026/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1747,7 +1747,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Web2C 2025:";; + short | recursive ) echo "Configuration of Web2C 2026/dev:";; esac cat <<\_ACEOF @@ -1979,7 +1979,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Web2C configure 2025 +Web2C configure 2026/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -3001,7 +3001,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Web2C $as_me 2025, which was +It was created by Web2C $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3997,7 +3997,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -WEB2CVERSION=2025 +WEB2CVERSION=2026/dev # LuaTeX requires system extensions for socket support. @@ -9993,7 +9993,7 @@ fi # Define the identity of the package. PACKAGE='web2c' - VERSION='2025' + VERSION='2026/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -27427,7 +27427,7 @@ Usage: $0 [OPTIONS] Report bugs to <bug-libtool@gnu.org>." lt_cl_version="\ -Web2C config.lt 2025 +Web2C config.lt 2026/dev configured by $0, generated by GNU Autoconf 2.72. Copyright (C) 2024 Free Software Foundation, Inc. @@ -31345,7 +31345,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Web2C $as_me 2025, which was +This file was extended by Web2C $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -31417,7 +31417,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -Web2C config.status 2025 +Web2C config.status 2026/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/texk/web2c/cwebdir/ChangeLog b/source/texk/web2c/cwebdir/ChangeLog index bd7bbe0d7..1ed6c99a6 100644 --- a/source/texk/web2c/cwebdir/ChangeLog +++ b/source/texk/web2c/cwebdir/ChangeLog @@ -1,3 +1,11 @@ +2025-02-26 Andreas Scherer <https://ascherer.github.io> + + * tests/ham-sorted.tex, + * tests/ham.ch, + * tests/ham.ref, + * tests/ham.sref, + * tests/ham.tex: Command-line option 'm' is no SGB variable. + 2025-02-02 Andreas Scherer <https://ascherer.github.io> * ctwill-mini.ch: Avoid several 'Overfull \vbox'es. diff --git a/source/texk/web2c/lib/ChangeLog b/source/texk/web2c/lib/ChangeLog index b3e8f9902..2ea05b671 100644 --- a/source/texk/web2c/lib/ChangeLog +++ b/source/texk/web2c/lib/ChangeLog @@ -1,3 +1,12 @@ +2025-03-07 Karl Berry <karl@tug.org> + + * TL'25 release. + +2025-03-07 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + * texmfmp.c (gettexstring) [XETEX]: correct non-BMP characters in + filenames with synctex. + 2025-02-28 Akira Kakuto <kakuto@jcom.zaq.ne.jp> * texmfmp.c: Remove problematic lines for windows (windows only) diff --git a/source/texk/web2c/lib/texmfmp.c b/source/texk/web2c/lib/texmfmp.c index ad208e98c..d7d4d2547 100644 --- a/source/texk/web2c/lib/texmfmp.c +++ b/source/texk/web2c/lib/texmfmp.c @@ -3192,7 +3192,7 @@ gettexstring (strnumber s) if (c >= 0xD800 && c <= 0xDBFF) { unsigned lo = strpool[++i + strstart[s - 65536L]]; if (lo >= 0xDC00 && lo <= 0xDFFF) - c = (c - 0xD800) * 0x0400 + lo - 0xDC00; + c = 0x10000 + (c - 0xD800) * 0x0400 + lo - 0xDC00; else c = 0xFFFD; } diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h index e335dc7a2..935899d50 100644 --- a/source/texk/web2c/luatexdir/luatex_svnversion.h +++ b/source/texk/web2c/luatexdir/luatex_svnversion.h @@ -1,4 +1,4 @@ #ifndef luatex_svn_revision_h #define luatex_svn_revision_h -#define luatex_svn_revision 7669 +#define luatex_svn_revision 7670 #endif diff --git a/source/texk/web2c/man/ChangeLog b/source/texk/web2c/man/ChangeLog index 5c4208bb6..e999a9d4e 100644 --- a/source/texk/web2c/man/ChangeLog +++ b/source/texk/web2c/man/ChangeLog @@ -1,3 +1,7 @@ +2025-03-07 Karl Berry <karl@tug.org> + + * TL'25 release. + 2025-01-01 Andreas Scherer <https://ascherer.github.io> * ctwill.man: CWEB 4.12.1 release. diff --git a/source/texk/web2c/synctexdir/ChangeLog b/source/texk/web2c/synctexdir/ChangeLog index 64826d302..6e85d107f 100644 --- a/source/texk/web2c/synctexdir/ChangeLog +++ b/source/texk/web2c/synctexdir/ChangeLog @@ -1,3 +1,12 @@ +2025-03-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + * synctex.c: improve printing of a synctex file name + (windows only). + +2025-03-07 Karl Berry <karl@tug.org> + + * TL'25 release. + 2024-10-13 <user202729@protonmail.com> * synctex_record_node_kern: pass "kern" instead of "glue" diff --git a/source/texk/web2c/synctexdir/synctex.c b/source/texk/web2c/synctexdir/synctex.c index af211af61..a439b3960 100644 --- a/source/texk/web2c/synctexdir/synctex.c +++ b/source/texk/web2c/synctexdir/synctex.c @@ -968,10 +968,11 @@ void synctexterminate(boolean log_opened) if (SYNCTEX_interaction>0) { #ifdef W32UPTEXSYNCTEX { - char *stmp = chgto_oem(tmp); + int savecp = GetConsoleOutputCP(); + SetConsoleOutputCP(file_system_codepage); printf((synctex_ctxt.flags.quoted ? "\nSyncTeX written on \"%s\"\n" : "\nSyncTeX written on %s.\n"), - stmp); - free(stmp); + tmp); + SetConsoleOutputCP(savecp); } #else #ifndef SYNCTEX_PRE_NL diff --git a/source/texk/web2c/tangle.ch b/source/texk/web2c/tangle.ch index acf898630..8ce847bb3 100644 --- a/source/texk/web2c/tangle.ch +++ b/source/texk/web2c/tangle.ch @@ -295,7 +295,8 @@ the replacement text. begin if buffer[i]>="a" then chopped_id[s]:=buffer[i]-@'40 @y begin if (buffer[i]<>"_") or (allow_underlines and not strict_mode) then - begin if (strict_mode or force_uppercase) and (buffer[i]>="a") then + begin if (strict_mode or force_uppercase) + and (buffer[i]>="a") and (buffer[i]<="z") then chopped_id[s]:=buffer[i]-@'40 else if (not strict_mode and force_lowercase) and (buffer[i]>="A") and (buffer[i]<="Z") then @@ -313,7 +314,9 @@ else @<Define \(and output a new string of the pool@>; begin if c>="a" then c:=c-@'40; {merge lowercase with uppercase} @y if c<>"_" or (allow_underlines and not strict_mode) then - begin if (strict_mode or force_uppercase) and (c>="a") then c:=c-@'40 + begin if (strict_mode or force_uppercase) + and (c>="a") and (c<="z") then + c:=c-@'40 else if (not strict_mode and force_lowercase) and (c>="A") and (c<="Z") then c:=c+@'40; @@ -482,9 +485,11 @@ with underlines removed. Extremely long identifiers must be chopped. identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); - if force_uppercase and (out_contrib[k]>="a") then + if force_uppercase + and (out_contrib[k]>="a") and (out_contrib[k]<="z") then out_contrib[k]:=out_contrib[k]-@'40 - else if force_lowercase and (out_contrib[k]<="Z") then + else if force_lowercase + and (out_contrib[k]>="A") and (out_contrib[k]<="Z") then out_contrib[k]:=out_contrib[k]+@'40 else if not allow_underlines and (out_contrib[k]="_") then decr(k); end; @@ -568,6 +573,12 @@ equiv[p]:=accumulator+@'10000000000; {name |p| now is defined to equal |accumula end @z +@x [16.173] l.3095 - Reject strings as macro names. + if next_control<>identifier then +@y + if (next_control<>identifier) or (buffer[id_first]="""") then +@z + @x [16.173] l.3107 - Add parametric2 macros (macros that use [] to delimit arguments). else @<If the next text is `\.{(\#)==}', call |define_macro| and |goto continue|@>; diff --git a/source/texk/web2c/tangleboot.pin b/source/texk/web2c/tangleboot.pin index ed0acc4d9..a829f257d 100644 --- a/source/texk/web2c/tangleboot.pin +++ b/source/texk/web2c/tangleboot.pin @@ -197,11 +197,11 @@ if(p=nameptr)or(t<>0)then{57:}begin if((p<>nameptr)and(t<>0)and(ilk[p]=0 idfirst;s:=0;h:=0; while(i<idloc)and(s<unambiglength)do begin if(buffer[i]<>95)or( allowunderlines and not strictmode)then begin if(strictmode or -forceuppercase)and(buffer[i]>=97)then choppedid[s]:=buffer[i]-32 else if -(not strictmode and forcelowercase)and(buffer[i]>=65)and(buffer[i]<=90) -then choppedid[s]:=buffer[i]+32 else choppedid[s]:=buffer[i]; -h:=(h+h+choppedid[s])mod hashsize;s:=s+1;end;i:=i+1;end;choppedid[s]:=0; -end{:58}; +forceuppercase)and(buffer[i]>=97)and(buffer[i]<=122)then choppedid[s]:= +buffer[i]-32 else if(not strictmode and forcelowercase)and(buffer[i]>=65 +)and(buffer[i]<=90)then choppedid[s]:=buffer[i]+32 else choppedid[s]:= +buffer[i];h:=(h+h+choppedid[s])mod hashsize;s:=s+1;end;i:=i+1;end; +choppedid[s]:=0;end{:58}; if p<>nameptr then{59:}begin if ilk[p]=0 then begin if t=1 then begin writeln(stdout);write(stdout,'! This identifier has already appeared'); error;end;{60:}q:=chophash[h]; @@ -214,8 +214,8 @@ chophash[h];while q<>0 do begin{63:}begin k:=bytestart[q];s:=0; w:=q mod 3; while(k<bytestart[q+3])and(s<unambiglength)do begin c:=bytemem[w,k]; if c<>95 or(allowunderlines and not strictmode)then begin if(strictmode -or forceuppercase)and(c>=97)then c:=c-32 else if(not strictmode and -forcelowercase)and(c>=65)and(c<=90)then c:=c+32; +or forceuppercase)and(c>=97)and(c<=122)then c:=c-32 else if(not +strictmode and forcelowercase)and(c>=65)and(c<=90)then c:=c+32; if choppedid[s]<>c then goto 32;s:=s+1;end;k:=k+1;end; if(k=bytestart[q+3])and(choppedid[s]<>0)then goto 32; begin writeln(stdout);write(stdout,'! Identifier conflict with ');end; @@ -469,11 +469,11 @@ outcontrib[1]:=curchar;sendout(2,1);end; 130:begin k:=0;j:=bytestart[curval];w:=curval mod 3; while(k<maxidlength)and(j<bytestart[curval+3])do begin k:=k+1; outcontrib[k]:=bytemem[w,j];j:=j+1; -if forceuppercase and(outcontrib[k]>=97)then outcontrib[k]:=outcontrib[k -]-32 else if forcelowercase and(outcontrib[k]<=90)then outcontrib[k]:= -outcontrib[k]+32 else if not allowunderlines and(outcontrib[k]=95)then k -:=k-1;end;sendout(2,k);end; -{:116}{119:}48,49,50,51,52,53,54,55,56,57:begin n:=0; +if forceuppercase and(outcontrib[k]>=97)and(outcontrib[k]<=122)then +outcontrib[k]:=outcontrib[k]-32 else if forcelowercase and(outcontrib[k] +>=65)and(outcontrib[k]<=90)then outcontrib[k]:=outcontrib[k]+32 else if +not allowunderlines and(outcontrib[k]=95)then k:=k-1;end;sendout(2,k); +end;{:116}{119:}48,49,50,51,52,53,54,55,56,57:begin n:=0; repeat curchar:=curchar-48;if n>=214748364 then begin writeln(stdout); write(stdout,'! Constant too big');error;end else n:=10*n+curchar; curchar:=getoutput;until(curchar>57)or(curchar<48);sendval(n);k:=0; @@ -807,8 +807,8 @@ label 22,30,10;var p:namepointer;begin modulecount:=modulecount+1; while true do begin 22:while nextcontrol<=132 do begin nextcontrol:= skipahead;if nextcontrol=135 then begin loc:=loc-2;nextcontrol:=getnext; end;end;if nextcontrol<>133 then goto 30;nextcontrol:=getnext; -if nextcontrol<>130 then begin begin writeln(stdout); -write(stdout,'! Definition flushed, must start with ', +if(nextcontrol<>130)or(buffer[idfirst]=34)then begin begin writeln( +stdout);write(stdout,'! Definition flushed, must start with ', 'identifier of length > 1');error;end;goto 22;end;nextcontrol:=getnext; if nextcontrol=61 then begin scannumeric(idlookup(1));goto 22; end else if nextcontrol=30 then begin definemacro(2);goto 22; diff --git a/source/texk/web2c/web2c/ChangeLog b/source/texk/web2c/web2c/ChangeLog index 0990fd196..f6efef1eb 100644 --- a/source/texk/web2c/web2c/ChangeLog +++ b/source/texk/web2c/web2c/ChangeLog @@ -1,3 +1,7 @@ +2025-03-07 Karl Berry <karl@tug.org> + + * TL'25 release. + 2023-03-09 Karl Berry <karl@tug.org> * TL'23 release. diff --git a/source/texk/web2c/web2c/configure b/source/texk/web2c/web2c/configure index 9599d9a15..c24c87d5e 100755 --- a/source/texk/web2c/web2c/configure +++ b/source/texk/web2c/web2c/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for Web2C Tools 2025. +# Generated by GNU Autoconf 2.72 for Web2C Tools 2026/dev. # # Report bugs to <tex-k@tug.org>. # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Web2C Tools' PACKAGE_TARNAME='web2c-tools' -PACKAGE_VERSION='2025' -PACKAGE_STRING='Web2C Tools 2025' +PACKAGE_VERSION='2026/dev' +PACKAGE_STRING='Web2C Tools 2026/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1365,7 +1365,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures Web2C Tools 2025 to adapt to many kinds of systems. +'configure' configures Web2C Tools 2026/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1436,7 +1436,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Web2C Tools 2025:";; + short | recursive ) echo "Configuration of Web2C Tools 2026/dev:";; esac cat <<\_ACEOF @@ -1560,7 +1560,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Web2C Tools configure 2025 +Web2C Tools configure 2026/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2341,7 +2341,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Web2C Tools $as_me 2025, which was +It was created by Web2C Tools $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -9233,7 +9233,7 @@ fi # Define the identity of the package. PACKAGE='web2c-tools' - VERSION='2025' + VERSION='2026/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -16840,7 +16840,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Web2C Tools $as_me 2025, which was +This file was extended by Web2C Tools $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16908,7 +16908,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -Web2C Tools config.status 2025 +Web2C Tools config.status 2026/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/utils/README b/source/utils/README index ef098a8fd..a2748f2e6 100644 --- a/source/utils/README +++ b/source/utils/README @@ -1,4 +1,4 @@ -$Id: README 74242 2025-02-23 23:13:34Z karl $ +$Id: README 74435 2025-03-04 17:01:16Z karl $ Public domain. Originally written 2005 by Karl Berry. Extra utilities we (optionally) compile for TeX Live. @@ -9,6 +9,11 @@ asymptote 3.01 - checked 24feb25 See https://tug.org/texlive/build.html#asymptote and tlpkg/bin/tl-update-asy + Special builders for asy: + aarch64-linux - Johannes Hielscher + *solaris, as well as darwinlegacy - Mojca + windows - from asy dist, including dlls + autosp 2023-10-07 - checked 07jan24 https://ctan.org/pkg/autosp diff --git a/source/utils/configure b/source/utils/configure index c1a09ac48..6f70f9058 100755 --- a/source/utils/configure +++ b/source/utils/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for TeX Live utils 2025. +# Generated by GNU Autoconf 2.72 for TeX Live utils 2026/dev. # # Report bugs to <tex-k@tug.org>. # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='TeX Live utils' PACKAGE_TARNAME='tex-live-utils' -PACKAGE_VERSION='2025' -PACKAGE_STRING='TeX Live utils 2025' +PACKAGE_VERSION='2026/dev' +PACKAGE_STRING='TeX Live utils 2026/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1382,7 +1382,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures TeX Live utils 2025 to adapt to many kinds of systems. +'configure' configures TeX Live utils 2026/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1453,7 +1453,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of TeX Live utils 2025:";; + short | recursive ) echo "Configuration of TeX Live utils 2026/dev:";; esac cat <<\_ACEOF @@ -1639,7 +1639,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -TeX Live utils configure 2025 +TeX Live utils configure 2026/dev generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1799,7 +1799,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by TeX Live utils $as_me 2025, which was +It was created by TeX Live utils $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -5776,7 +5776,7 @@ fi # Define the identity of the package. PACKAGE='tex-live-utils' - VERSION='2025' + VERSION='2026/dev' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -6689,7 +6689,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by TeX Live utils $as_me 2025, which was +This file was extended by TeX Live utils $as_me 2026/dev, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6748,7 +6748,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -TeX Live utils config.status 2025 +TeX Live utils config.status 2026/dev configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/source/version.ac b/source/version.ac index df9f991a0..2ec2e79b3 100644 --- a/source/version.ac +++ b/source/version.ac @@ -1,4 +1,4 @@ -dnl $Id: version.ac 73591 2025-01-25 18:41:15Z karl $ +dnl $Id: version.ac 74529 2025-03-08 18:17:45Z karl $ dnl Copyright 2016-2025 Karl Berry <tex-live@tug.org> dnl Copyright 2010-2015 Peter Breitenlohner <tex-live@tug.org> dnl @@ -9,4 +9,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current TeX Live version -m4_define([tex_live_version], [2025]) +m4_define([tex_live_version], [2026/dev]) -- GitLab