5 Commits

Author SHA1 Message Date
Michael R Sweet
06d3e85627 Update GitHub CI rules. 2025-12-21 22:14:20 -05:00
Michael R Sweet
850b0fa0a0 Update makesrcdist to correctly embed a copy of the TTF library. 2025-12-21 20:37:50 -05:00
Michael R Sweet
7ac8669057 Change to using external TTF library, when available, otherwise local copy.
Fix pkgconfig file.
2025-12-21 20:28:26 -05:00
Michael R Sweet
f6f3191a8d Bump version. 2025-12-21 19:18:33 -05:00
Michael R Sweet
c2b25a1fa0 Support Encrypt dictionaries as well as indirect references (Issue #139) 2025-12-21 19:04:36 -05:00
20 changed files with 356 additions and 2882 deletions

View File

@@ -13,7 +13,9 @@ jobs:
steps: steps:
- name: Checkout PDFio sources - name: Checkout PDFio sources
uses: actions/checkout@v5 uses: actions/checkout@v6
with:
submodules: recursive
- name: Update Build Environment - name: Update Build Environment
run: sudo apt-get update --fix-missing -y run: sudo apt-get update --fix-missing -y
- name: Install Prerequisites - name: Install Prerequisites
@@ -37,7 +39,9 @@ jobs:
steps: steps:
- name: Checkout PDFio sources - name: Checkout PDFio sources
uses: actions/checkout@v5 uses: actions/checkout@v6
with:
submodules: recursive
- name: Configure PDFio - name: Configure PDFio
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
- name: Build PDFio - name: Build PDFio
@@ -53,7 +57,9 @@ jobs:
steps: steps:
- name: Checkout PDFio sources - name: Checkout PDFio sources
uses: actions/checkout@v5 uses: actions/checkout@v6
with:
submodules: recursive
- name: Setup MSBuild - name: Setup MSBuild
uses: microsoft/setup-msbuild@v2 uses: microsoft/setup-msbuild@v2
- name: Nuget Restore - name: Nuget Restore

1
.gitignore vendored
View File

@@ -25,5 +25,4 @@
/pdfio-*.zip* /pdfio-*.zip*
/testpdfio /testpdfio
/testpdfio-*.pdf /testpdfio-*.pdf
/testttf
/x64 /x64

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "ttf"]
path = ttf
url = https://github.com/michaelrsweet/ttf.git

View File

@@ -2,14 +2,23 @@ Changes in PDFio
================ ================
v1.7.0 - YYYY-MM-DD
-------------------
- Now use TTF 1.1 or later for font support.
v1.6.1 - YYYY-MM-DD v1.6.1 - YYYY-MM-DD
------------------- -------------------
- Added missing input checking to `pdfioFileCreateFontObjFromBase` function. - Added missing input checking to `pdfioFileCreateFontObjFromBase` function.
- Updated support for UTF-16 strings (Issue #141) - Updated support for UTF-16 strings (Issue #141)
- Updated Xcode project to use installed PNG library. - Updated Xcode project to use installed PNG library.
- Fixed decryption of PDF files using an Encrypt dictionary instead of an
indirect reference (Issue #139)
- Fixed character range checking in a TTF support function. - Fixed character range checking in a TTF support function.
- Fixed some clang warnings. - Fixed some clang warnings.
- Fixed the generated pkg-config file.

View File

@@ -69,6 +69,8 @@ top_srcdir = @top_srcdir@
BUILDROOT = $(DSTROOT)$(RPM_BUILD_ROOT)$(DESTDIR) BUILDROOT = $(DSTROOT)$(RPM_BUILD_ROOT)$(DESTDIR)
TTFDIR = @TTFDIR@
# Build commands... # Build commands...
.SUFFIXES: .c .h .o .SUFFIXES: .c .h .o
@@ -99,17 +101,14 @@ PUBOBJS = \
pdfio-token.o \ pdfio-token.o \
pdfio-value.o pdfio-value.o
LIBOBJS = \ LIBOBJS = \
$(PUBOBJS) \ $(PUBOBJS)
ttf.o
OBJS = \ OBJS = \
$(LIBOBJS) \ $(LIBOBJS) \
testpdfio.o \ testpdfio.o
testttf.o
TARGETS = \ TARGETS = \
$(LIBPDFIO) \ $(LIBPDFIO) \
$(LIBPDFIO_STATIC) \ $(LIBPDFIO_STATIC) \
testpdfio \ testpdfio
testttf
DOCFILES = \ DOCFILES = \
doc/pdfio.html \ doc/pdfio.html \
doc/pdfio-512.png \ doc/pdfio-512.png \
@@ -135,16 +134,30 @@ EXAMPLES = \
# Make everything # Make everything
all: $(TARGETS) all:
if test "x$(TTFDIR)" != x; then \
echo Making all in $(TTFDIR)...; \
(cd $(TTFDIR); $(MAKE) $(MFLAGS) all) || exit 1; \
fi
$(MAKE) $(MFLAGS) $(TARGETS)
# Clean everything # Clean everything
clean: clean:
if test "x$(TTFDIR)" != x; then \
echo Cleaning in $(TTFDIR)...; \
(cd $(TTFDIR); $(MAKE) $(MFLAGS) clean) || exit 1; \
fi
echo Cleaning build files...
rm -f $(TARGETS) $(OBJS) rm -f $(TARGETS) $(OBJS)
# Install everything # Install everything
install: $(TARGETS) install: $(TARGETS)
if test "x$(TTFDIR)" != x; then \
echo Installing in $(TTFDIR)...; \
(cd $(TTFDIR); $(MAKE) $(MFLAGS) install) || exit 1; \
fi
echo Installing header files to $(BUILDROOT)$(includedir)... echo Installing header files to $(BUILDROOT)$(includedir)...
$(INSTALL) -d -m 755 $(BUILDROOT)$(includedir) $(INSTALL) -d -m 755 $(BUILDROOT)$(includedir)
for file in $(PUBHEADERS); do \ for file in $(PUBHEADERS); do \
@@ -232,18 +245,10 @@ testpdfio: testpdfio.o libpdfio.a
$(CC) $(LDFLAGS) -o $@ testpdfio.o libpdfio.a $(LIBS) $(CC) $(LDFLAGS) -o $@ testpdfio.o libpdfio.a $(LIBS)
# TTF test program
testttf: ttf.o testttf.o
echo Linking $@...
$(CC) $(LDFLAGS) -o testttf ttf.o testttf.o $(LIBS)
# Dependencies # Dependencies
$(OBJS): pdfio.h pdfio-private.h Makefile $(OBJS): pdfio.h pdfio-private.h Makefile
pdfio-content.o: pdfio-content.h ttf.h pdfio-content.o: pdfio-content.h
testpdfio.o: test.h testpdfio.o: test.h
testttf.o: ttf.h
ttf.o: ttf.h
# Make documentation using Codedoc <https://www.msweet.org/codedoc> # Make documentation using Codedoc <https://www.msweet.org/codedoc>

218
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for pdfio 1.6.0. # Generated by GNU Autoconf 2.71 for pdfio 1.7.0.
# #
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>. # Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
# #
@@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='pdfio' PACKAGE_NAME='pdfio'
PACKAGE_TARNAME='pdfio' PACKAGE_TARNAME='pdfio'
PACKAGE_VERSION='1.6.0' PACKAGE_VERSION='1.7.0'
PACKAGE_STRING='pdfio 1.6.0' PACKAGE_STRING='pdfio 1.7.0'
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues' PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
PACKAGE_URL='https://www.msweet.org/pdfio' PACKAGE_URL='https://www.msweet.org/pdfio'
@@ -647,13 +647,16 @@ ac_includes_default="\
#endif" #endif"
ac_header_c_list= ac_header_c_list=
enable_option_checking=no
ac_subst_vars='LTLIBOBJS ac_subst_vars='LTLIBOBJS
LIBOBJS LIBOBJS
WARNINGS WARNINGS
CSFLAGS CSFLAGS
LIBPDFIO_STATIC LIBPDFIO_STATIC
LIBPDFIO LIBPDFIO
PKGCONFIG_LIBPNG TTFDIR
subdirs
PKGCONFIG_REQUIRES_PRIVATE
PKGCONFIG_REQUIRES PKGCONFIG_REQUIRES
PKGCONFIG_LIBS_PRIVATE PKGCONFIG_LIBS_PRIVATE
PKGCONFIG_LIBS PKGCONFIG_LIBS
@@ -747,7 +750,7 @@ CFLAGS
LDFLAGS LDFLAGS
LIBS LIBS
CPPFLAGS' CPPFLAGS'
ac_subdirs_all='ttf'
# Initialize some variables set by options. # Initialize some variables set by options.
ac_init_help= ac_init_help=
@@ -1295,7 +1298,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures pdfio 1.6.0 to adapt to many kinds of systems. \`configure' configures pdfio 1.7.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1361,7 +1364,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of pdfio 1.6.0:";; short | recursive ) echo "Configuration of pdfio 1.7.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1460,7 +1463,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
pdfio configure 1.6.0 pdfio configure 1.7.0
generated by GNU Autoconf 2.71 generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc. Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1678,7 +1681,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by pdfio $as_me 1.6.0, which was It was created by pdfio $as_me 1.7.0, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@@ -2434,9 +2437,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
PDFIO_VERSION="1.6.0" PDFIO_VERSION="1.7.0"
PDFIO_VERSION_MAJOR="`echo 1.6.0 | awk -F. '{print $1}'`" PDFIO_VERSION_MAJOR="`echo 1.7.0 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.6.0 | awk -F. '{printf("%d\n",$2);}'`" PDFIO_VERSION_MINOR="`echo 1.7.0 | awk -F. '{printf("%d\n",$2);}'`"
@@ -4138,13 +4141,44 @@ fi
PKGCONFIG_CFLAGS="-I\${includedir}" PKGCONFIG_CFLAGS="-I\${includedir}"
PKGCONFIG_LIBS="-L\${libdir} -lpdfio" PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
PKGCONFIG_LIBS_PRIVATE="-lm" PKGCONFIG_LIBS_PRIVATE="-lm"
PKGCONFIG_REQUIRES="zlib" PKGCONFIG_REQUIRES=""
PKGCONFIG_REQUIRES_PRIVATE="ttf"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ttf library" >&5
printf %s "checking for ttf library... " >&6; }
if $PKGCONFIG --exists ttf
then :
# Use installed TTF library...
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags ttf)"
TTFDIR=""
LIBS="$($PKGCONFIG --libs ttf) $LIBS"
else $as_nop
# Use embedded TTF library...
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using embedded version" >&5
printf "%s\n" "no, using embedded version" >&6; }
CPPFLAGS="$CPPFLAGS -Ittf"
TTFDIR="ttf"
LIBS="-Lttf \`PKG_CONFIG_PATH=ttf $PKGCONFIG --libs ttf\` $LIBS"
subdirs="$subdirs ttf"
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib via pkg-config" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib via pkg-config" >&5
printf %s "checking for zlib via pkg-config... " >&6; } printf %s "checking for zlib via pkg-config... " >&6; }
if $PKGCONFIG --exists zlib if $PKGCONFIG --exists zlib
@@ -4154,6 +4188,7 @@ then :
printf "%s\n" "yes" >&6; } printf "%s\n" "yes" >&6; }
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS" CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
LIBS="$($PKGCONFIG --libs zlib) $LIBS" LIBS="$($PKGCONFIG --libs zlib) $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="$PKGCONFIG_REQUIRES_PRIVATE, zlib"
else $as_nop else $as_nop
@@ -4216,11 +4251,11 @@ then :
fi fi
PKGCONFIG_REQUIRES=""
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
fi fi
# Check whether --enable-libpng was given. # Check whether --enable-libpng was given.
if test ${enable_libpng+y} if test ${enable_libpng+y}
then : then :
@@ -4228,9 +4263,6 @@ then :
fi fi
PKGCONFIG_LIBPNG=""
if test "x$PKGCONFIG" != x -a x$enable_libpng != xno if test "x$PKGCONFIG" != x -a x$enable_libpng != xno
then : then :
@@ -4246,8 +4278,7 @@ printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS" CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS" LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
else $as_nop else $as_nop
@@ -4314,6 +4345,8 @@ else $as_nop
LIBPDFIO_STATIC="" LIBPDFIO_STATIC=""
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_LIBS_PRIVATE="" PKGCONFIG_LIBS_PRIVATE=""
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES_PRIVATE=""
fi fi
@@ -5106,7 +5139,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by pdfio $as_me 1.6.0, which was This file was extended by pdfio $as_me 1.7.0, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -5162,7 +5195,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
pdfio config.status 1.6.0 pdfio config.status 1.7.0
configured by $0, generated by GNU Autoconf 2.71, configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
@@ -5718,6 +5751,149 @@ if test "$no_create" != yes; then
# would make configure fail if this is the last instruction. # would make configure fail if this is the last instruction.
$ac_cs_success || as_fn_exit 1 $ac_cs_success || as_fn_exit 1
fi fi
#
# CONFIG_SUBDIRS section.
#
if test "$no_recursion" != yes; then
# Remove --cache-file, --srcdir, and --disable-option-checking arguments
# so they do not pile up.
ac_sub_configure_args=
ac_prev=
eval "set x $ac_configure_args"
shift
for ac_arg
do
if test -n "$ac_prev"; then
ac_prev=
continue
fi
case $ac_arg in
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
| --c=*)
;;
--config-cache | -C)
;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
;;
--disable-option-checking)
;;
*)
case $ac_arg in
*\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
esac
done
# Always prepend --prefix to ensure using the same prefix
# in subdir configurations.
ac_arg="--prefix=$prefix"
case $ac_arg in
*\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
# Pass --silent
if test "$silent" = yes; then
ac_sub_configure_args="--silent $ac_sub_configure_args"
fi
# Always prepend --disable-option-checking to silence warnings, since
# different subdirs can have different --enable and --with options.
ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
ac_popdir=`pwd`
for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
# Do not complain, so a configure script can configure whichever
# parts of a large source tree are present.
test -d "$srcdir/$ac_dir" || continue
ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
printf "%s\n" "$ac_msg" >&6
as_dir="$ac_dir"; as_fn_mkdir_p
ac_builddir=.
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
case $srcdir in
.) # We are building in place.
ac_srcdir=.
ac_top_srcdir=$ac_top_builddir_sub
ac_abs_top_srcdir=$ac_pwd ;;
[\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir
ac_abs_top_srcdir=$srcdir ;;
*) # Relative name.
ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_build_prefix$srcdir
ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
cd "$ac_dir"
# Check for configure.gnu first; this name is used for a wrapper for
# Metaconfig's "Configure" on case-insensitive file systems.
if test -f "$ac_srcdir/configure.gnu"; then
ac_sub_configure=$ac_srcdir/configure.gnu
elif test -f "$ac_srcdir/configure"; then
ac_sub_configure=$ac_srcdir/configure
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
ac_sub_configure=
fi
# The recursion is here.
if test -n "$ac_sub_configure"; then
# Make the cache file name correct relative to the subdirectory.
case $cache_file in
[\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
*) # Relative name.
ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
esac
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
printf "%s\n" "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
# The eval makes quoting arguments work.
eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
--cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
fi
cd "$ac_popdir"
done
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}

View File

@@ -21,7 +21,7 @@ AC_PREREQ([2.70])
dnl Package name and version... dnl Package name and version...
AC_INIT([pdfio], [1.6.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio]) AC_INIT([pdfio], [1.7.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
PDFIO_VERSION="AC_PACKAGE_VERSION" PDFIO_VERSION="AC_PACKAGE_VERSION"
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`" PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
@@ -119,11 +119,32 @@ AC_PATH_TOOL([PKGCONFIG], [pkg-config])
PKGCONFIG_CFLAGS="-I\${includedir}" PKGCONFIG_CFLAGS="-I\${includedir}"
PKGCONFIG_LIBS="-L\${libdir} -lpdfio" PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
PKGCONFIG_LIBS_PRIVATE="-lm" PKGCONFIG_LIBS_PRIVATE="-lm"
PKGCONFIG_REQUIRES="zlib" PKGCONFIG_REQUIRES=""
PKGCONFIG_REQUIRES_PRIVATE="ttf"
AC_SUBST([PKGCONFIG_CFLAGS]) AC_SUBST([PKGCONFIG_CFLAGS])
AC_SUBST([PKGCONFIG_LIBS]) AC_SUBST([PKGCONFIG_LIBS])
AC_SUBST([PKGCONFIG_LIBS_PRIVATE]) AC_SUBST([PKGCONFIG_LIBS_PRIVATE])
AC_SUBST([PKGCONFIG_REQUIRES]) AC_SUBST([PKGCONFIG_REQUIRES])
AC_SUBST([PKGCONFIG_REQUIRES_PRIVATE])
dnl TTF library for font support...
AC_MSG_CHECKING([for ttf library])
AS_IF([$PKGCONFIG --exists ttf], [
# Use installed TTF library...
AC_MSG_RESULT([yes])
CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags ttf)"
TTFDIR=""
LIBS="$($PKGCONFIG --libs ttf) $LIBS"
], [
# Use embedded TTF library...
AC_MSG_RESULT([no, using embedded version])
CPPFLAGS="$CPPFLAGS -Ittf"
TTFDIR="ttf"
LIBS="-Lttf \`PKG_CONFIG_PATH=ttf $PKGCONFIG --libs ttf\` $LIBS"
AC_CONFIG_SUBDIRS([ttf])
])
AC_SUBST([TTFDIR])
dnl ZLIB dnl ZLIB
@@ -132,6 +153,7 @@ AS_IF([$PKGCONFIG --exists zlib], [
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS" CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
LIBS="$($PKGCONFIG --libs zlib) $LIBS" LIBS="$($PKGCONFIG --libs zlib) $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="$PKGCONFIG_REQUIRES_PRIVATE, zlib"
],[ ],[
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
AC_CHECK_HEADER([zlib.h]) AC_CHECK_HEADER([zlib.h])
@@ -141,16 +163,13 @@ AS_IF([$PKGCONFIG --exists zlib], [
AC_MSG_ERROR([Sorry, this software requires zlib 1.1 or higher.]) AC_MSG_ERROR([Sorry, this software requires zlib 1.1 or higher.])
]) ])
PKGCONFIG_REQUIRES=""
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
]) ])
dnl libpng... dnl libpng...
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto])) AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
PKGCONFIG_LIBPNG=""
AC_SUBST([PKGCONFIG_LIBPNG])
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [ AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_MSG_CHECKING([for libpng-1.6.x]) AC_MSG_CHECKING([for libpng-1.6.x])
AS_IF([$PKGCONFIG --exists libpng16], [ AS_IF([$PKGCONFIG --exists libpng16], [
@@ -158,8 +177,7 @@ AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?]) AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?])
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS" CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS" LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
], [ ], [
AC_MSG_RESULT([no]); AC_MSG_RESULT([no]);
AS_IF([test x$enable_libpng = xyes], [ AS_IF([test x$enable_libpng = xyes], [
@@ -192,6 +210,8 @@ AS_IF([test x$enable_shared = xyes], [
LIBPDFIO_STATIC="" LIBPDFIO_STATIC=""
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_LIBS_PRIVATE="" PKGCONFIG_LIBS_PRIVATE=""
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES_PRIVATE=""
]) ])
AC_SUBST([LIBPDFIO]) AC_SUBST([LIBPDFIO])

View File

@@ -7,6 +7,10 @@
# ./makesrcdist [--snapshot] VERSION # ./makesrcdist [--snapshot] VERSION
# #
# Save the current directory...
basedir="$(pwd)"
# Support "--snapshot" option... # Support "--snapshot" option...
if test "$1" == "--snapshot"; then if test "$1" == "--snapshot"; then
shift shift
@@ -15,18 +19,21 @@ else
snapshot=0 snapshot=0
fi fi
# Get version...
# Get the release version...
if test $# != 1; then if test $# != 1; then
echo "Usage: ./makesrcdist [--snapshot] VERSION" echo "Usage: ./makesrcdist [--snapshot] VERSION"
exit 1 exit 1
fi fi
status=0
version=$1 version=$1
version_major=$(echo $1 | awk -F. '{print $1}') version_major=$(echo $1 | awk -F. '{print $1}')
version_minor=$(echo $1 | awk -F. '{print $2}') version_minor=$(echo $1 | awk -F. '{print $2}')
# Check that version number has been updated everywhere... # Check that version number has been updated everywhere...
status=0
if test $(grep AC_INIT configure.ac | awk '{print $2}') != "[$version],"; then if test $(grep AC_INIT configure.ac | awk '{print $2}') != "[$version],"; then
echo "Still need to update AC_INIT version in 'configure.ac'." echo "Still need to update AC_INIT version in 'configure.ac'."
status=1 status=1
@@ -78,18 +85,32 @@ if test $status = 1; then
exit 1 exit 1
fi fi
# Tag release... # Tag release...
if test $snapshot = 0; then if test $snapshot = 0; then
echo Creating tag for release... echo "Creating tag v$version for release..."
git tag -m "Tag $version" v$version git tag -m "Tag $version" v$version
git push origin v$version git push origin v$version
fi fi
# Make source archives...
echo Creating pdfio-$version.tar.gz...
git archive --format tar --prefix=pdfio-$version/ HEAD | gzip -v9 >pdfio-$version.tar.gz
gpg --detach-sign pdfio-$version.tar.gz
echo Creating pdfio-$version.zip... # Make and sign source archives...
git archive --format zip --prefix=pdfio-$version/ HEAD >pdfio-$version.zip echo "Exporting $version..."
gpg --detach-sign pdfio-$version.zip rm -rf $TMPDIR/pdfio-$version
mkdir $TMPDIR/pdfio-$version
git archive --format tar HEAD | (cd $TMPDIR/pdfio-$version; tar xf -)
(cd ttf; git archive --prefix=ttf/ HEAD) | (cd $TMPDIR/pdfio-$version; tar xf -)
cd $TMPDIR
echo "Creating pdfio-$version.tar.gz..."
tar cf - pdfio-$version | gzip -v9 >"$basedir/pdfio-$version.tar.gz"
gpg --detach-sign "$basedir/pdfio-$version.tar.gz"
echo "Creating pdfio-$version.zip..."
zip -r "$basedir/pdfio-$version.zip" pdfio-$version
gpg --detach-sign "$basedir/pdfio-$version.zip"
# Clean up...
echo "Removing temporary files..."
rm -rf pdfio-$version

View File

@@ -214,8 +214,9 @@ _pdfioCryptoLock(
pdfioObjClose(pdf->encrypt_obj); pdfioObjClose(pdf->encrypt_obj);
pdf->encryption = encryption; pdf->encrypt_dict = dict;
pdf->permissions = permissions; pdf->encryption = encryption;
pdf->permissions = permissions;
return (true); return (true);
} }
@@ -570,7 +571,6 @@ _pdfioCryptoUnlock(
{ {
int tries; // Number of tries int tries; // Number of tries
const char *password = NULL; // Password to try const char *password = NULL; // Password to try
pdfio_dict_t *encrypt_dict; // Encrypt objection dictionary
int version, // Version value int version, // Version value
revision, // Revision value revision, // Revision value
length; // Key length value length; // Key length value
@@ -590,20 +590,14 @@ _pdfioCryptoUnlock(
_pdfio_value_t *value; // Encrypt dictionary value, if any _pdfio_value_t *value; // Encrypt dictionary value, if any
// See if we support the type of encryption specified by the Encrypt object // See if we support the type of encryption specified by the Encrypt
// dictionary... // dictionary...
if ((encrypt_dict = pdfioObjGetDict(pdf->encrypt_obj)) == NULL) handler = pdfioDictGetName(pdf->encrypt_dict, "Filter");
{ version = (int)pdfioDictGetNumber(pdf->encrypt_dict, "V");
_pdfioFileError(pdf, "Unable to get encryption dictionary."); revision = (int)pdfioDictGetNumber(pdf->encrypt_dict, "R");
return (false); length = (int)pdfioDictGetNumber(pdf->encrypt_dict, "Length");
}
handler = pdfioDictGetName(encrypt_dict, "Filter"); if ((value = _pdfioDictGetValue(pdf->encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
version = (int)pdfioDictGetNumber(encrypt_dict, "V");
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
if ((value = _pdfioDictGetValue(encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
pdf->encrypt_metadata = value->value.boolean; pdf->encrypt_metadata = value->value.boolean;
else else
pdf->encrypt_metadata = true; pdf->encrypt_metadata = true;
@@ -622,9 +616,9 @@ _pdfioCryptoUnlock(
pdfio_dict_t *filter; // Crypt Filter pdfio_dict_t *filter; // Crypt Filter
const char *cfm; // Crypt filter method const char *cfm; // Crypt filter method
stream_filter = pdfioDictGetName(encrypt_dict, "StmF"); stream_filter = pdfioDictGetName(pdf->encrypt_dict, "StmF");
string_filter = pdfioDictGetName(encrypt_dict, "StrF"); string_filter = pdfioDictGetName(pdf->encrypt_dict, "StrF");
cf_dict = pdfioDictGetDict(encrypt_dict, "CF"); cf_dict = pdfioDictGetDict(pdf->encrypt_dict, "CF");
if (!cf_dict) if (!cf_dict)
{ {
@@ -701,7 +695,7 @@ _pdfioCryptoUnlock(
// Grab the remaining values we need to unlock the PDF... // Grab the remaining values we need to unlock the PDF...
pdf->file_keylen = (size_t)(length / 8); pdf->file_keylen = (size_t)(length / 8);
p = pdfioDictGetNumber(encrypt_dict, "P"); p = pdfioDictGetNumber(pdf->encrypt_dict, "P");
PDFIO_DEBUG("_pdfioCryptoUnlock: P=%.0f\n", p); PDFIO_DEBUG("_pdfioCryptoUnlock: P=%.0f\n", p);
if (p < 0x7fffffff) // Handle integers > 2^31-1 if (p < 0x7fffffff) // Handle integers > 2^31-1
pdf->permissions = (pdfio_permission_t)p; pdf->permissions = (pdfio_permission_t)p;
@@ -709,8 +703,8 @@ _pdfioCryptoUnlock(
pdf->permissions = (pdfio_permission_t)(p - 4294967296.0); pdf->permissions = (pdfio_permission_t)(p - 4294967296.0);
PDFIO_DEBUG("_pdfioCryptoUnlock: permissions=%d\n", pdf->permissions); PDFIO_DEBUG("_pdfioCryptoUnlock: permissions=%d\n", pdf->permissions);
owner_key = pdfioDictGetBinary(encrypt_dict, "O", &owner_keylen); owner_key = pdfioDictGetBinary(pdf->encrypt_dict, "O", &owner_keylen);
user_key = pdfioDictGetBinary(encrypt_dict, "U", &user_keylen); user_key = pdfioDictGetBinary(pdf->encrypt_dict, "U", &user_keylen);
if (!owner_key) if (!owner_key)
{ {

View File

@@ -2283,12 +2283,18 @@ load_xref(
{ {
// Save the trailer dictionary and grab the root (catalog) and info // Save the trailer dictionary and grab the root (catalog) and info
// objects... // objects...
pdfio_obj_t *encrypt_obj; // Encryption object
pdf->trailer_dict = trailer.value.dict; pdf->trailer_dict = trailer.value.dict;
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID"); pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
// If the trailer contains an Encrypt key, try unlocking the file... // If the trailer contains an Encrypt key, try unlocking the file...
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data)) if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
return (false); return (false);
} }
@@ -2434,12 +2440,18 @@ load_xref(
{ {
// Save the trailer dictionary and grab the root (catalog) and info // Save the trailer dictionary and grab the root (catalog) and info
// objects... // objects...
pdfio_obj_t *encrypt_obj; // Encryption object
pdf->trailer_dict = trailer.value.dict; pdf->trailer_dict = trailer.value.dict;
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID"); pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
// If the trailer contains an Encrypt key, try unlocking the file... // If the trailer contains an Encrypt key, try unlocking the file...
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data)) if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
return (false); return (false);
} }
} }
@@ -2529,7 +2541,7 @@ repair_xref(
pdf->root_obj = NULL; pdf->root_obj = NULL;
pdf->info_obj = NULL; pdf->info_obj = NULL;
pdf->pages_obj = NULL; pdf->pages_obj = NULL;
pdf->encrypt_obj = NULL; pdf->encrypt_dict = NULL;
// Read from the beginning of the file, looking for objects... // Read from the beginning of the file, looking for objects...
if ((line_offset = _pdfioFileSeek(pdf, 0, SEEK_SET)) < 0) if ((line_offset = _pdfioFileSeek(pdf, 0, SEEK_SET)) < 0)
@@ -2603,10 +2615,17 @@ repair_xref(
if (!strcmp(type, "XRef") && !pdf->trailer_dict) if (!strcmp(type, "XRef") && !pdf->trailer_dict)
{ {
// Save the trailer dictionary... // Save the trailer dictionary...
pdfio_obj_t *encrypt_obj;
// Encryption object
PDFIO_DEBUG("repair_xref: XRef stream...\n"); PDFIO_DEBUG("repair_xref: XRef stream...\n");
pdf->trailer_dict = pdfioObjGetDict(obj); pdf->trailer_dict = pdfioObjGetDict(obj);
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID"); pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
} }
} }
else if (type && !strcmp(line, "endobj")) else if (type && !strcmp(line, "endobj"))
@@ -2660,11 +2679,17 @@ repair_xref(
{ {
// Save the trailer dictionary and grab the root (catalog) and info // Save the trailer dictionary and grab the root (catalog) and info
// objects... // objects...
pdfio_obj_t *encrypt_obj; // Encryption object
PDFIO_DEBUG("repair_xref: Using this trailer dictionary.\n"); PDFIO_DEBUG("repair_xref: Using this trailer dictionary.\n");
pdf->trailer_dict = trailer.value.dict; pdf->trailer_dict = trailer.value.dict;
pdf->encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt");
pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID"); pdf->id_array = pdfioDictGetArray(pdf->trailer_dict, "ID");
if ((encrypt_obj = pdfioDictGetObj(pdf->trailer_dict, "Encrypt")) != NULL)
pdf->encrypt_dict = pdfioObjGetDict(encrypt_obj);
else
pdf->encrypt_dict = pdfioDictGetDict(pdf->trailer_dict, "Encrypt");
} }
} }
@@ -2678,7 +2703,7 @@ repair_xref(
pdf->trailer_dict = backup_trailer; pdf->trailer_dict = backup_trailer;
// If the trailer contains an Encrypt key, try unlocking the file... // If the trailer contains an Encrypt key, try unlocking the file...
if (pdf->encrypt_obj && !_pdfioCryptoUnlock(pdf, password_cb, password_data)) if (pdf->encrypt_dict && !_pdfioCryptoUnlock(pdf, password_cb, password_data))
return (false); return (false);
// Load any stream objects... // Load any stream objects...

View File

@@ -283,7 +283,8 @@ struct _pdfio_file_s // PDF file structure
pdfio_obj_t *root_obj; // Root object/dictionary pdfio_obj_t *root_obj; // Root object/dictionary
pdfio_obj_t *info_obj; // Information object pdfio_obj_t *info_obj; // Information object
pdfio_obj_t *pages_obj; // Root pages object pdfio_obj_t *pages_obj; // Root pages object
pdfio_obj_t *encrypt_obj; // De/Encryption object/dictionary pdfio_obj_t *encrypt_obj; // Encryption object (not used for reading)
pdfio_dict_t *encrypt_dict; // De/Encryption dictionary
pdfio_obj_t *cgats001_obj, // CGATS001 ICC profile object pdfio_obj_t *cgats001_obj, // CGATS001 ICC profile object
*cp1252_obj, // CP1252 font encoding object *cp1252_obj, // CP1252 font encoding object
*unicode_obj; // Unicode font encoding object *unicode_obj; // Unicode font encoding object

View File

@@ -23,9 +23,9 @@ extern "C" {
// Version numbers... // Version numbers...
// //
# define PDFIO_VERSION "1.6.0" # define PDFIO_VERSION "1.7.0"
# define PDFIO_VERSION_MAJOR 1 # define PDFIO_VERSION_MAJOR 1
# define PDFIO_VERSION_MINOR 6 # define PDFIO_VERSION_MINOR 7
// //

View File

@@ -11,3 +11,4 @@ Cflags: @PKGCONFIG_CFLAGS@
Libs: @PKGCONFIG_LIBS@ Libs: @PKGCONFIG_LIBS@
Libs.private: @PKGCONFIG_LIBS_PRIVATE@ Libs.private: @PKGCONFIG_LIBS_PRIVATE@
Requires: @PKGCONFIG_REQUIRES@ Requires: @PKGCONFIG_REQUIRES@
Requires.private: @PKGCONFIG_REQUIRES_PRIVATE@

View File

@@ -1,5 +1,5 @@
LIBRARY pdfio1 LIBRARY pdfio1
VERSION 1.6 VERSION 1.7
EXPORTS EXPORTS
_pdfio_strlcpy _pdfio_strlcpy
_pdfio_strtod _pdfio_strtod

View File

@@ -3,7 +3,7 @@
<metadata> <metadata>
<id>pdfio_native</id> <id>pdfio_native</id>
<title>PDFio Library for VS2019+</title> <title>PDFio Library for VS2019+</title>
<version>1.6.0</version> <version>1.7.0</version>
<authors>Michael R Sweet</authors> <authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners> <owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl> <projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
@@ -16,7 +16,7 @@
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright> <copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
<tags>pdf file native</tags> <tags>pdf file native</tags>
<dependencies> <dependencies>
<dependency id="pdfio_native.redist" version="1.6.0" /> <dependency id="pdfio_native.redist" version="1.7.0" />
<dependency id="libpng_native.redist" version="1.6.30" /> <dependency id="libpng_native.redist" version="1.6.30" />
<dependency id="zlib_native.redist" version="1.2.11" /> <dependency id="zlib_native.redist" version="1.2.11" />
</dependencies> </dependencies>

View File

@@ -3,7 +3,7 @@
<metadata> <metadata>
<id>pdfio_native.redist</id> <id>pdfio_native.redist</id>
<title>PDFio Library for VS2019+</title> <title>PDFio Library for VS2019+</title>
<version>1.6.0</version> <version>1.7.0</version>
<authors>Michael R Sweet</authors> <authors>Michael R Sweet</authors>
<owners>michaelrsweet</owners> <owners>michaelrsweet</owners>
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl> <projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>

396
testttf.c
View File

@@ -1,396 +0,0 @@
//
// Unit test program for TTF library
//
// https://github.com/michaelrsweet/ttf
//
// Copyright © 2018-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
//
// Usage:
//
// ./testttf [FILENAME]
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include "ttf.h"
//
// Local functions...
//
static void error_cb(void *data, const char *message);
static int test_font(const char *filename);
//
// 'main()' - Main entry for unit tests.
//
int // O - Exit status
main(int argc, // I - Number of command-line arguments
char *argv[]) // I - Command-line arguments
{
int i; // Looping var
int errors = 0; // Number of errors
if (argc > 1)
{
for (i = 1; i < argc; i ++)
errors += test_font(argv[i]);
}
else
{
// Test with the bundled TrueType files...
errors += test_font("testfiles/OpenSans-Bold.ttf");
errors += test_font("testfiles/OpenSans-Regular.ttf");
errors += test_font("testfiles/NotoSansJP-Regular.otf");
}
if (!errors)
puts("\nALL TESTS PASSED");
else
printf("\n%d TEST(S) FAILED\n", errors);
return (errors);
}
//
// 'error_cb()' - Error callback.
//
static void
error_cb(void *data, // I - User data (not used)
const char *message) // I - Message string
{
fprintf(stderr, "FAIL (%s)\n", message);
}
//
// 'test_font()' - Test a font file.
//
static int // O - Number of errors
test_font(const char *filename) // I - Font filename
{
int i, // Looping var
errors = 0; // Number of errors
ttf_t *font; // Font
struct stat fileinfo; // Font file information
FILE *fp = NULL; // File pointer
void *data = NULL; // Memory buffer for font file
const char *value; // Font (string) value
int intvalue; // Font (integer) value
float realvalue; // Font (real) value
char psname[1024]; // Postscript font name
ttf_rect_t bounds; // Bounds
ttf_rect_t extents; // Extents
size_t num_fonts; // Number of fonts
ttf_style_t style; // Font style
ttf_weight_t weight; // Font weight
static const char * const stretches[] =
{ // Font stretch strings
"TTF_STRETCH_NORMAL", // normal
"TTF_STRETCH_ULTRA_CONDENSED", // ultra-condensed
"TTF_STRETCH_EXTRA_CONDENSED", // extra-condensed
"TTF_STRETCH_CONDENSED", // condensed
"TTF_STRETCH_SEMI_CONDENSED", // semi-condensed
"TTF_STRETCH_SEMI_EXPANDED", // semi-expanded
"TTF_STRETCH_EXPANDED", // expanded
"TTF_STRETCH_EXTRA_EXPANDED", // extra-expanded
"TTF_STRETCH_ULTRA_EXPANDED" // ultra-expanded
};
static const char * const strings[] = // Test strings
{
"Hello, World!", // English
"مرحبا بالعالم!", // Arabic
"Bonjour le monde!", // French
"Γειά σου Κόσμε!", // Greek
"שלום עולם!", // Hebrew
"Привет мир!", // Russian
"こんにちは世界!" // Japanese
};
static const char * const styles[] = // Font style names
{
"TTF_STYLE_NORMAL",
"TTF_STYLE_ITALIC",
"TTF_STYLE_OBLIQUE"
};
printf("ttfCreate(\"%s\"): ", filename);
fflush(stdout);
if ((font = ttfCreate(filename, 0, error_cb, NULL)) != NULL)
puts("PASS");
else
errors ++;
fputs("ttfGetAscent: ", stdout);
if ((intvalue = ttfGetAscent(font)) > 0)
{
printf("PASS (%d)\n", intvalue);
}
else
{
printf("FAIL (%d)\n", intvalue);
errors ++;
}
fputs("ttfGetBounds: ", stdout);
if (ttfGetBounds(font, &bounds))
{
printf("PASS (%g %g %g %g)\n", bounds.left, bounds.bottom, bounds.right, bounds.top);
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetCapHeight: ", stdout);
if ((intvalue = ttfGetCapHeight(font)) > 0)
{
printf("PASS (%d)\n", intvalue);
}
else
{
printf("FAIL (%d)\n", intvalue);
errors ++;
}
fputs("ttfGetCopyright: ", stdout);
if ((value = ttfGetCopyright(font)) != NULL)
{
printf("PASS (%s)\n", value);
}
else
{
puts("WARNING (no copyright found)");
}
for (i = 0; i < (int)(sizeof(strings) / sizeof(strings[0])); i ++)
{
printf("ttfGetExtents(\"%s\"): ", strings[i]);
if (ttfGetExtents(font, 12.0f, strings[i], &extents))
{
printf("PASS (%.1f %.1f %.1f %.1f)\n", extents.left, extents.bottom, extents.right, extents.top);
}
else
{
puts("FAIL");
errors ++;
}
}
fputs("ttfGetFamily: ", stdout);
if ((value = ttfGetFamily(font)) != NULL)
{
printf("PASS (%s)\n", value);
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetItalicAngle: ", stdout);
if ((realvalue = ttfGetItalicAngle(font)) >= -180.0 && realvalue <= 180.0)
{
printf("PASS (%g)\n", realvalue);
}
else
{
printf("FAIL (%g)\n", realvalue);
errors ++;
}
fputs("ttfGetNumFonts: ", stdout);
if ((num_fonts = ttfGetNumFonts(font)) > 0)
{
printf("PASS (%u)\n", (unsigned)num_fonts);
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetPostScriptName: ", stdout);
if ((value = ttfGetPostScriptName(font)) != NULL)
{
printf("PASS (%s)\n", value);
strncpy(psname, value, sizeof(psname) - 1);
psname[sizeof(psname) - 1] = '\0';
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetStretch: ", stdout);
if ((intvalue = (int)ttfGetStretch(font)) >= TTF_STRETCH_NORMAL && intvalue <= TTF_STRETCH_ULTRA_EXPANDED)
{
printf("PASS (%s)\n", stretches[intvalue]);
}
else
{
printf("FAIL (%d)\n", intvalue);
errors ++;
}
fputs("ttfGetStyle: ", stdout);
if ((style = ttfGetStyle(font)) >= TTF_STYLE_NORMAL && style <= TTF_STYLE_ITALIC)
{
printf("PASS (%s)\n", styles[style]);
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetVersion: ", stdout);
if ((value = ttfGetVersion(font)) != NULL)
{
printf("PASS (%s)\n", value);
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetWeight: ", stdout);
if ((weight = ttfGetWeight(font)) >= 0)
{
printf("PASS (%u)\n", (unsigned)weight);
}
else
{
puts("FAIL");
errors ++;
}
fputs("ttfGetWidth(' '): ", stdout);
if ((intvalue = ttfGetWidth(font, ' ')) > 0)
{
printf("PASS (%d)\n", intvalue);
}
else
{
printf("FAIL (%d)\n", intvalue);
errors ++;
}
fputs("ttfGetXHeight: ", stdout);
if ((intvalue = ttfGetXHeight(font)) > 0)
{
printf("PASS (%d)\n", intvalue);
}
else
{
printf("FAIL (%d)\n", intvalue);
errors ++;
}
fputs("ttfIsFixedPitch: ", stdout);
if (ttfIsFixedPitch(font))
puts("PASS (true)");
else
puts("PASS (false)");
ttfDelete(font);
font = NULL;
// Now copy the font to memory and open it that way...
printf("fopen(\"%s\", \"rb\"): ", filename);
if ((fp = fopen(filename, "rb")) == NULL)
{
printf("FAIL (%s)\n", strerror(errno));
errors ++;
}
else
{
printf("PASS (%d)\n", fileno(fp));
printf("fstat(%d): ", fileno(fp));
if (fstat(fileno(fp), &fileinfo))
{
printf("FAIL (%s)\n", strerror(errno));
errors ++;
}
else
{
printf("PASS (%lu bytes)\n", (unsigned long)fileinfo.st_size);
fputs("malloc(): ", stdout);
if ((data = malloc((size_t)fileinfo.st_size)) == NULL)
{
printf("FAIL (%s)\n", strerror(errno));
errors ++;
}
else
{
puts("PASS");
fputs("fread(): ", stdout);
if (fread(data, (size_t)fileinfo.st_size, 1, fp) != 1)
{
printf("FAIL (%s)\n", strerror(errno));
errors ++;
}
else
{
puts("PASS");
fputs("ttfCreateData(): ", stdout);
if ((font = ttfCreateData(data, (size_t)fileinfo.st_size, /*idx*/0, error_cb, /*err_data*/NULL)) == NULL)
{
puts("FAIL");
errors ++;
}
else
{
puts("PASS");
fputs("ttfGetPostScriptName: ", stdout);
if ((value = ttfGetPostScriptName(font)) != NULL)
{
if (!strcmp(value, psname))
{
printf("PASS (%s)\n", value);
}
else
{
printf("FAIL (got \"%s\", expected \"%s\")\n", value, psname);
errors ++;
}
}
else
{
puts("FAIL");
errors ++;
}
}
}
}
}
if (fp)
fclose(fp);
free(data);
ttfDelete(font);
}
return (errors);
}

1
ttf Submodule

Submodule ttf added at efbdbf3074

2280
ttf.c

File diff suppressed because it is too large Load Diff

111
ttf.h
View File

@@ -1,111 +0,0 @@
//
// Header file for TTF library
//
// https://github.com/michaelrsweet/ttf
//
// Copyright © 2018-2025 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
//
#ifndef TTF_H
# define TTF_H
# include <stddef.h>
# include <stdbool.h>
# include <sys/types.h>
# ifdef __cplusplus
extern "C" {
# endif // __cplusplus
//
// Types...
//
typedef struct _ttf_s ttf_t; // Font object
typedef void (*ttf_err_cb_t)(void *data, const char *message);
// Font error callback
typedef enum ttf_stretch_e // Font stretch
{
TTF_STRETCH_NORMAL, // normal
TTF_STRETCH_ULTRA_CONDENSED, // ultra-condensed
TTF_STRETCH_EXTRA_CONDENSED, // extra-condensed
TTF_STRETCH_CONDENSED, // condensed
TTF_STRETCH_SEMI_CONDENSED, // semi-condensed
TTF_STRETCH_SEMI_EXPANDED, // semi-expanded
TTF_STRETCH_EXPANDED, // expanded
TTF_STRETCH_EXTRA_EXPANDED, // extra-expanded
TTF_STRETCH_ULTRA_EXPANDED // ultra-expanded
} ttf_stretch_t;
typedef enum ttf_style_e // Font style
{
TTF_STYLE_NORMAL, // Normal font
TTF_STYLE_ITALIC, // Italic font
TTF_STYLE_OBLIQUE // Oblique (angled) font
} ttf_style_t;
typedef enum ttf_variant_e // Font variant
{
TTF_VARIANT_NORMAL, // Normal font
TTF_VARIANT_SMALL_CAPS // Font whose lowercase letters are small capitals
} ttf_variant_t;
typedef enum ttf_weight_e // Font weight
{
TTF_WEIGHT_100 = 100, // Weight 100 (Thin)
TTF_WEIGHT_200 = 200, // Weight 200 (Extra/Ultra-Light)
TTF_WEIGHT_300 = 300, // Weight 300 (Light)
TTF_WEIGHT_400 = 400, // Weight 400 (Normal/Regular)
TTF_WEIGHT_500 = 500, // Weight 500 (Medium)
TTF_WEIGHT_600 = 600, // Weight 600 (Semi/Demi-Bold)
TTF_WEIGHT_700 = 700, // Weight 700 (Bold)
TTF_WEIGHT_800 = 800, // Weight 800 (Extra/Ultra-Bold)
TTF_WEIGHT_900 = 900 // Weight 900 (Black/Heavy)
} ttf_weight_t;
typedef struct ttf_rect_s // Bounding rectangle
{
float left; // Left offset
float top; // Top offset
float right; // Right offset
float bottom; // Bottom offset
} ttf_rect_t;
//
// Functions...
//
extern ttf_t *ttfCreate(const char *filename, size_t idx, ttf_err_cb_t err_cb, void *err_data);
extern ttf_t *ttfCreateData(const void *data, size_t data_size, size_t idx, ttf_err_cb_t err_cb, void *err_data);
extern void ttfDelete(ttf_t *font);
extern int ttfGetAscent(ttf_t *font);
extern ttf_rect_t *ttfGetBounds(ttf_t *font, ttf_rect_t *bounds);
extern const int *ttfGetCMap(ttf_t *font, size_t *num_cmap);
extern int ttfGetCapHeight(ttf_t *font);
extern const char *ttfGetCopyright(ttf_t *font);
extern int ttfGetDescent(ttf_t *font);
extern ttf_rect_t *ttfGetExtents(ttf_t *font, float size, const char *s, ttf_rect_t *extents);
extern const char *ttfGetFamily(ttf_t *font);
extern float ttfGetItalicAngle(ttf_t *font);
extern int ttfGetMaxChar(ttf_t *font);
extern int ttfGetMinChar(ttf_t *font);
extern size_t ttfGetNumFonts(ttf_t *font);
extern const char *ttfGetPostScriptName(ttf_t *font);
extern ttf_stretch_t ttfGetStretch(ttf_t *font);
extern ttf_style_t ttfGetStyle(ttf_t *font);
extern const char *ttfGetVersion(ttf_t *font);
extern int ttfGetWidth(ttf_t *font, int ch);
extern ttf_weight_t ttfGetWeight(ttf_t *font);
extern int ttfGetXHeight(ttf_t *font);
extern bool ttfIsFixedPitch(ttf_t *font);
# ifdef __cplusplus
}
# endif // __cplusplus
#endif // !TTF_H