3 Commits

Author SHA1 Message Date
Michael R Sweet
29eea131b9 Remove old per-object crypto stuff we dont need. 2025-04-13 09:10:17 -04:00
Michael R Sweet
2dcef0936e Fix decryption of UTF-16 strings (Issue #42) 2025-04-13 09:05:02 -04:00
Michael R Sweet
20dd2a6d28 Fix decryption of RC4-40 files. 2025-04-13 08:37:24 -04:00
50 changed files with 4249 additions and 6308 deletions

View File

@@ -13,9 +13,7 @@ jobs:
steps:
- name: Checkout PDFio sources
uses: actions/checkout@v6
with:
submodules: recursive
uses: actions/checkout@v4
- name: Update Build Environment
run: sudo apt-get update --fix-missing -y
- name: Install Prerequisites
@@ -23,7 +21,7 @@ jobs:
- name: Configure PDFio
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
- name: Build PDFio
run: make
run: make "COMMONFLAGS=-g -fsanitize=address"
- name: Test PDFio
env:
ASAN_OPTIONS: leak_check_at_exit=false
@@ -39,9 +37,7 @@ jobs:
steps:
- name: Checkout PDFio sources
uses: actions/checkout@v6
with:
submodules: recursive
uses: actions/checkout@v4
- name: Configure PDFio
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
- name: Build PDFio
@@ -57,11 +53,9 @@ jobs:
steps:
- name: Checkout PDFio sources
uses: actions/checkout@v6
with:
submodules: recursive
uses: actions/checkout@v4
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
uses: microsoft/setup-msbuild@v1.0.2
- name: Nuget Restore
run: nuget restore pdfio.sln
- name: Build PDFio

View File

@@ -24,7 +24,7 @@ jobs:
steps:
- name: Checkout PDFio sources
uses: actions/checkout@v5
uses: actions/checkout@v4
with:
submodules: recursive

View File

@@ -8,7 +8,7 @@ jobs:
environment: Coverity
steps:
- name: Checkout PDFio sources
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Update Build Environment
run: sudo apt-get update --fix-missing -y
- name: Install Prerequisites

1
.gitignore vendored
View File

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

3
.gitmodules vendored
View File

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

View File

@@ -2,70 +2,11 @@ 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
-------------------
- Added missing input checking to `pdfioFileCreateFontObjFromBase` function.
- Updated support for UTF-16 strings (Issue #141)
- 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 some clang warnings.
- Fixed the generated pkg-config file.
v1.6.0 - 2025-10-06
-------------------
- Added generation of XMP metadata when writing PDFs (Issue #103)
- Added "standard" `PDFIO_CS_CGATS001` color space for non-device CMYK
(Issue #104)
- Added CMYK JPEG support with embedded ICC profiles or using the CGATS001
profile (Issue #104)
- Added `pdfioFileAddOutputIntent` function to adding output intent information
to a PDF file (Issue #104)
- Added explicit support for warning messages (Issue #118)
- Added `pdfioFileCreateFontObjFromData` function for embedding fonts in
memory (Issue #120)
- Added support for specifying PDF/A versions for created PDF files (Issue #122)
- Added `pdfioContentBeginMarked` and `pdfioContentEndMarked` functions for
creating tagged PDF content (Issue #123)
- Added `pdfioFileGetLanguage` and `pdfioFileSetLanguage` functions for getting
and setting the default/primary language of a PDF file (Issue #124)
- Now add default grayscale, RGB, and CMYK profile resources to pages as needed
(Issue #104)
- Fixed unsupported filter error (Issue #130)
- Fixed EOF comment written to the PDF (Issue #136)
- Fixed TTF cmap underflow error.
- Fixed some Clang warnings.
v1.5.4 - 2025-08-26
-------------------
- Updated indirect reference reading code to limit the range of generation
numbers.
- Updated error messages for too large tokens (Issue #131)
- Fixed a JPEG copy bug (Issue #132)
v1.5.3 - 2025-05-03
v1.5.3 - YYYY-MM-DD
-------------------
- Fixed decryption of PDF files "protected" by 40-bit RC4 (Issue #42)
- Fixed decryption of UTF-16 strings (Issue #42)
- Fixed decryption of PDF files with large permission values.
- Fixed support for EncryptMetadata key in the encryption dictionary.
- Fixed `pdfioObjCopy` and `pdfioPageCopy` to properly identify the source PDF
file being used (Issue #125)
v1.5.2 - 2025-04-12

View File

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

78
config.guess vendored
View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2025 Free Software Foundation, Inc.
# Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2025-07-10'
timestamp='2022-09-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system '$me' is run on.
Output the configuration name of the system \`$me' is run on.
Options:
-h, --help print this help, then exit
@@ -60,13 +60,13 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2025 Free Software Foundation, Inc.
Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try '$me --help' for more information."
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -102,8 +102,8 @@ GUESS=
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
# use 'HOST_CC' if defined, but it is deprecated.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
@@ -123,7 +123,7 @@ set_cc_for_build() {
dummy=$tmp/dummy
case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
,,) echo "int x;" > "$dummy.c"
for driver in cc gcc c17 c99 c89 ; do
for driver in cc gcc c89 c99 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
CC_FOR_BUILD=$driver
break
@@ -155,9 +155,6 @@ Linux|GNU|GNU/*)
set_cc_for_build
cat <<-EOF > "$dummy.c"
#if defined(__ANDROID__)
LIBC=android
#else
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -165,8 +162,6 @@ Linux|GNU|GNU/*)
LIBC=dietlibc
#elif defined(__GLIBC__)
LIBC=gnu
#elif defined(__LLVM_LIBC__)
LIBC=llvm
#else
#include <stdarg.h>
/* First heuristic to detect musl libc. */
@@ -174,7 +169,6 @@ Linux|GNU|GNU/*)
LIBC=musl
#endif
#endif
#endif
EOF
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
eval "$cc_set_libc"
@@ -465,7 +459,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like '4.1.3-JL'.
# Japanese Language versions have a version number like `4.1.3-JL'.
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
GUESS=sparc-sun-sunos$SUN_REL
;;
@@ -634,8 +628,7 @@ EOF
sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
int
main ()
main()
{
if (!__power_pc())
exit(1);
@@ -719,8 +712,7 @@ EOF
#include <stdlib.h>
#include <unistd.h>
int
main ()
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
@@ -912,7 +904,7 @@ EOF
fi
;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`uname -p`
UNAME_PROCESSOR=`/usr/bin/uname -p`
case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
@@ -984,27 +976,7 @@ EOF
GUESS=$UNAME_MACHINE-unknown-minix
;;
aarch64:Linux:*:*)
set_cc_for_build
CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
ABI=64
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __ARM_EABI__
#ifdef __ARM_PCS_VFP
ABI=eabihf
#else
ABI=eabi
#endif
#endif
EOF
cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
eval "$cc_set_abi"
case $ABI in
eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
esac
fi
GUESS=$CPU-unknown-linux-$LIBCABI
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
@@ -1070,15 +1042,6 @@ EOF
k1om:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
kvx:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
kvx:cos:*:*)
GUESS=$UNAME_MACHINE-unknown-cos
;;
kvx:mbr:*:*)
GUESS=$UNAME_MACHINE-unknown-mbr
;;
loongarch32:Linux:*:* | loongarch64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
@@ -1234,7 +1197,7 @@ EOF
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
;;
i*86:OS/2:*:*)
# If we were able to find 'uname', then EMX Unix compatibility
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
GUESS=$UNAME_MACHINE-pc-os2-emx
;;
@@ -1375,7 +1338,7 @@ EOF
GUESS=ns32k-sni-sysv
fi
;;
PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
GUESS=i586-unisys-sysv4
;;
@@ -1597,12 +1560,6 @@ EOF
*:Unleashed:*:*)
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
;;
x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
GUESS=$UNAME_MACHINE-pc-ironclad-mlibc
;;
*:[Ii]ronclad:*:*)
GUESS=$UNAME_MACHINE-unknown-ironclad-mlibc
;;
esac
# Do we have a guess based on uname results?
@@ -1626,7 +1583,6 @@ cat > "$dummy.c" <<EOF
#endif
#endif
#endif
int
main ()
{
#if defined (sony)
@@ -1811,8 +1767,8 @@ fi
exit 1
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%Y-%02m-%02d"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:

955
config.sub vendored

File diff suppressed because it is too large Load Diff

349
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for pdfio 1.7.0.
# Generated by GNU Autoconf 2.71 for pdfio 1.5.2.
#
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
#
@@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='pdfio'
PACKAGE_TARNAME='pdfio'
PACKAGE_VERSION='1.7.0'
PACKAGE_STRING='pdfio 1.7.0'
PACKAGE_VERSION='1.5.2'
PACKAGE_STRING='pdfio 1.5.2'
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
PACKAGE_URL='https://www.msweet.org/pdfio'
@@ -647,16 +647,13 @@ ac_includes_default="\
#endif"
ac_header_c_list=
enable_option_checking=no
ac_subst_vars='LTLIBOBJS
LIBOBJS
WARNINGS
CSFLAGS
LIBPDFIO_STATIC
LIBPDFIO
TTFDIR
subdirs
PKGCONFIG_REQUIRES_PRIVATE
PKGCONFIG_LIBPNG
PKGCONFIG_REQUIRES
PKGCONFIG_LIBS_PRIVATE
PKGCONFIG_LIBS
@@ -750,7 +747,7 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS'
ac_subdirs_all='ttf'
# Initialize some variables set by options.
ac_init_help=
@@ -1298,7 +1295,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 pdfio 1.7.0 to adapt to many kinds of systems.
\`configure' configures pdfio 1.5.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1364,7 +1361,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of pdfio 1.7.0:";;
short | recursive ) echo "Configuration of pdfio 1.5.2:";;
esac
cat <<\_ACEOF
@@ -1463,7 +1460,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
pdfio configure 1.7.0
pdfio configure 1.5.2
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1516,39 +1513,6 @@ fi
} # ac_fn_c_try_compile
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
# INCLUDES, setting the cache variable VAR accordingly.
ac_fn_c_check_header_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
printf %s "(cached) " >&6
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
eval "$3=yes"
else $as_nop
eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_compile
# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
@@ -1657,6 +1621,39 @@ printf "%s\n" "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_func
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
# INCLUDES, setting the cache variable VAR accordingly.
ac_fn_c_check_header_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
printf %s "checking for $2... " >&6; }
if eval test \${$3+y}
then :
printf %s "(cached) " >&6
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
eval "$3=yes"
else $as_nop
eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
eval ac_res=\$$3
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_compile
ac_configure_args_raw=
for ac_arg
do
@@ -1681,7 +1678,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 pdfio $as_me 1.7.0, which was
It was created by pdfio $as_me 1.5.2, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -2437,9 +2434,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
PDFIO_VERSION="1.7.0"
PDFIO_VERSION_MAJOR="`echo 1.7.0 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.7.0 | awk -F. '{printf("%d\n",$2);}'`"
PDFIO_VERSION="1.5.2"
PDFIO_VERSION_MAJOR="`echo 1.5.2 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.5.2 | awk -F. '{printf("%d\n",$2);}'`"
@@ -3943,43 +3940,6 @@ printf "%s\n" "using $INSTALL" >&6; }
ac_header= ac_cache=
for ac_item in $ac_header_c_list
do
if test $ac_cache; then
ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
printf "%s\n" "#define $ac_item 1" >> confdefs.h
fi
ac_header= ac_cache=
elif test $ac_header; then
ac_cache=$ac_item
else
ac_header=$ac_item
fi
done
if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
then :
printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default"
if test "x$ac_cv_header_math_h" = xyes
then :
fi
ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm"
if test "x$ac_cv_func_timegm" = xyes
then :
@@ -4141,46 +4101,44 @@ fi
PKGCONFIG_CFLAGS="-I\${includedir}"
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
PKGCONFIG_LIBS_PRIVATE="-lm"
PKGCONFIG_REQUIRES=""
PKGCONFIG_REQUIRES_PRIVATE="ttf"
PKGCONFIG_REQUIRES="zlib"
{ 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 "checking for zlib via pkg-config... " >&6; }
ac_header= ac_cache=
for ac_item in $ac_header_c_list
do
if test $ac_cache; then
ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
printf "%s\n" "#define $ac_item 1" >> confdefs.h
fi
ac_header= ac_cache=
elif test $ac_header; then
ac_cache=$ac_item
else
ac_header=$ac_item
fi
done
if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
then :
printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
fi
if $PKGCONFIG --exists zlib
then :
@@ -4188,7 +4146,6 @@ then :
printf "%s\n" "yes" >&6; }
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="$PKGCONFIG_REQUIRES_PRIVATE, zlib"
else $as_nop
@@ -4251,6 +4208,7 @@ then :
fi
PKGCONFIG_REQUIRES=""
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
fi
@@ -4263,6 +4221,9 @@ then :
fi
PKGCONFIG_LIBPNG=""
if test "x$PKGCONFIG" != x -a x$enable_libpng != xno
then :
@@ -4278,7 +4239,8 @@ printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
else $as_nop
@@ -4345,8 +4307,6 @@ else $as_nop
LIBPDFIO_STATIC=""
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_LIBS_PRIVATE=""
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES_PRIVATE=""
fi
@@ -5139,7 +5099,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 pdfio $as_me 1.7.0, which was
This file was extended by pdfio $as_me 1.5.2, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5195,7 +5155,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="\\
pdfio config.status 1.7.0
pdfio config.status 1.5.2
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
@@ -5751,149 +5711,6 @@ if test "$no_create" != yes; then
# would make configure fail if this is the last instruction.
$ac_cs_success || as_fn_exit 1
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
{ 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;}

View File

@@ -21,7 +21,7 @@ AC_PREREQ([2.70])
dnl Package name and version...
AC_INIT([pdfio], [1.7.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
AC_INIT([pdfio], [1.5.2], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
PDFIO_VERSION="AC_PACKAGE_VERSION"
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
@@ -88,10 +88,6 @@ AC_SUBST([INSTALL])
AC_MSG_RESULT([using $INSTALL])
dnl Standard C stuff...
AC_CHECK_HEADER([math.h])
dnl Check for date/time functionality...
AC_CHECK_FUNC([timegm], [
AC_DEFINE([HAVE_TIMEGM], [1], [Do we have the timegm function?])
@@ -119,32 +115,11 @@ AC_PATH_TOOL([PKGCONFIG], [pkg-config])
PKGCONFIG_CFLAGS="-I\${includedir}"
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
PKGCONFIG_LIBS_PRIVATE="-lm"
PKGCONFIG_REQUIRES=""
PKGCONFIG_REQUIRES_PRIVATE="ttf"
PKGCONFIG_REQUIRES="zlib"
AC_SUBST([PKGCONFIG_CFLAGS])
AC_SUBST([PKGCONFIG_LIBS])
AC_SUBST([PKGCONFIG_LIBS_PRIVATE])
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
@@ -153,7 +128,6 @@ AS_IF([$PKGCONFIG --exists zlib], [
AC_MSG_RESULT([yes])
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="$PKGCONFIG_REQUIRES_PRIVATE, zlib"
],[
AC_MSG_RESULT([no])
AC_CHECK_HEADER([zlib.h])
@@ -163,6 +137,7 @@ AS_IF([$PKGCONFIG --exists zlib], [
AC_MSG_ERROR([Sorry, this software requires zlib 1.1 or higher.])
])
PKGCONFIG_REQUIRES=""
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
])
@@ -170,6 +145,9 @@ AS_IF([$PKGCONFIG --exists zlib], [
dnl libpng...
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], [
AC_MSG_CHECKING([for libpng-1.6.x])
AS_IF([$PKGCONFIG --exists libpng16], [
@@ -177,7 +155,8 @@ AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?])
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
], [
AC_MSG_RESULT([no]);
AS_IF([test x$enable_libpng = xyes], [
@@ -210,8 +189,6 @@ AS_IF([test x$enable_shared = xyes], [
LIBPDFIO_STATIC=""
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
PKGCONFIG_LIBS_PRIVATE=""
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
PKGCONFIG_REQUIRES_PRIVATE=""
])
AC_SUBST([LIBPDFIO])

View File

@@ -1,4 +1,4 @@
.TH pdfio 3 "pdf read/write library" "2025-10-05" "pdf read/write library"
.TH pdfio 3 "pdf read/write library" "2025-04-12" "pdf read/write library"
.SH NAME
pdfio \- pdf read/write library
.SH Introduction
@@ -325,7 +325,7 @@ where the five arguments to the function are the filename ("myinputfile.pdf"), a
}
.fi
.PP
The error callback is called for both errors and warnings and accepts the pdfio_file_t pointer, a message string, and the callback pointer value. It returns true to continue processing the file or false to stop, for example:
The error callback is called for both errors and warnings and accepts the pdfio_file_t pointer, a message string, and the callback pointer value, for example:
.nf
bool
@@ -335,15 +335,12 @@ The error callback is called for both errors and warnings and accepts the pdfio_
fprintf(stderr, "%s: %s\\n", pdfioFileGetName(pdf), message);
// Return true for warning messages (continue) and false for errors (stop)
return (!strncmp(message, "WARNING:", 8));
// Return false to treat warnings as errors
return (false);
}
.fi
.PP
The default error callback (NULL) does the equivalent of the above.
.PP
Note: Many errors are unrecoverable, so PDFio ignores the return value from the error callback and always stops processing the PDF file. Warning messages start with the prefix "WARNING:" while errors have no prefix.
.PP
Each PDF file contains one or more pages. The pdfioFileGetNumPages function returns the number of pages in the file while the pdfioFileGetPage function gets the specified page in the PDF file:
.nf
@@ -1032,45 +1029,6 @@ pdfioContentTextShowf draws a formatted string in a text block
pdfioContentTextShowJustified draws an array of literal strings with offsets between them
.SS Tagged and Marked PDF Content
.PP
Content in a page stream can be tagged to help a PDF reader application know the kind and organization of that content. Content inserted using the PDFio Page Stream Functions can be tagged by surrounding it with the pdfioContentBeginMarked and pdfioContentEndMarked functions.
.PP
The pdfioContentBeginMarked function accepts a named tag and optional dictionary of attributes such as the marked content identifier ("MCID"). For example, the following code tags a paragraph of text:
.nf
pdfio_file_t *pdf; // PDF file
pdfio_stream_t *st; // Page stream
pdfioContentBeginMarked(st, "P", /*dict*/NULL);
pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\\n");
pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\\n");
pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\\n");
pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\\n");
pdfioContentEndMarked(st);
.fi
.PP
To mark the same paragraph with a content identifier you would first create a dictionary containing the "MCID" key/value pair and then mark the paragraph with that dictionary:
.nf
pdfio_file_t *pdf; // PDF file
pdfio_stream_t *st; // Page stream
pdfio_dict_t *dict; // Content dictionary
dict = pdfioDictCreate(pdf);
pdfioDictSetNumber(dict, "MCID", 42);
pdfioContentBeginMarked(st, "P", dict);
pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\\n");
pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\\n");
pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\\n");
pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\\n");
pdfioContentEndMarked(st);
.fi
.SH Examples
.PP
PDFio includes several example programs that are typically installed to the /usr/share/doc/pdfio/examples or /usr/local/share/doc/pdfio/examples directories. A makefile is included to build them.
@@ -1730,9 +1688,6 @@ The md2pdf program needs to maintain three sets of state \- one for the markdown
// State for the current page
pdfio_stream_t *st; // Current page stream
double y; // Current position on page
const char *tag; // Current block tag
bool in_table, // Are we in a table?
in_row; // Are we in a table row?
docfont_t font; // Current font
double fsize; // Current font size
doccolor_t color; // Current color
@@ -2209,9 +2164,6 @@ Code blocks consist of one or more lines of plain monospaced text. We draw a lig
pdfioContentFillAndStroke(dd\->st, false);
// Start a code text block...
dd\->tag = "P";
pdfioContentBeginMarked(dd\->st, dd\->tag, /*dict*/NULL);
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd\->st);
pdfioContentTextMoveTo(dd\->st, left, dd\->y);
@@ -2248,9 +2200,6 @@ Code blocks consist of one or more lines of plain monospaced text. We draw a lig
pdfioContentTextEnd(dd\->st);
dd\->y += lineheight;
pdfioContentEndMarked(dd\->st);
dd\->tag = NULL;
// Draw the bottom padding...
set_color(dd, DOCCOLOR_LTGRAY);
pdfioContentPathRect(dd\->st, left \- CODE_PADDING,
@@ -2380,17 +2329,8 @@ Finally, we render each row in the table:
.nf
// Render each table row...
dd\->in_table = true;
if (dd\->st)
pdfioContentBeginMarked(dd\->st, "Table", /*dict*/NULL);
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr);
pdfioContentEndMarked(dd\->st);
dd\->in_table = false;
.fi
.PP
Rendering the Markdown Document
@@ -2509,10 +2449,6 @@ PDFIO_CS_ADOBE
.br
AdobeRGB 1998
.TP 5
PDFIO_CS_CGATS001
.br
CGATS001 (CMYK)
.TP 5
PDFIO_CS_P3_D65
.br
Display P3
@@ -2541,7 +2477,7 @@ PDFIO_ENCRYPTION_RC4_128
.TP 5
PDFIO_ENCRYPTION_RC4_40
.br
40-bit RC4 encryption (PDF 1.3, reading only)
40-bit RC4 encryption (PDF 1.3)
.SS pdfio_filter_e
Compression/decompression filters for streams
.TP 5
@@ -2902,8 +2838,7 @@ pdfio_array_t * pdfioArrayCreateColorFromStandard (
.fi
.PP
This function creates a color array for a standard \fBPDFIO_CS_\fR enumerated color space.
The "num_colors" argument must be \fB1\fR for grayscale, \fB3\fR for RGB color, and
\fB4\fR for CMYK color.
The "num_colors" argument must be \fB1\fR for grayscale and \fB3\fR for RGB color.
.SS pdfioArrayGetArray
Get an array value from an array.
.PP
@@ -3012,32 +2947,6 @@ bool pdfioArrayRemove (
size_t n
);
.fi
.PP
.SS pdfioContentBeginMarked
Start marked content with an optional dictionary.
.PP
.nf
bool pdfioContentBeginMarked (
pdfio_stream_t *st,
const char *tag,
pdfio_dict_t *dict
);
.fi
.PP
This function starts an area of marked content with an optional dictionary.
It must be paired with a call to the \fIpdfioContentEndMarked\fR function.
.PP
The "tag" argument specifies the tag name string for the content such as "P"
for a paragraph, "H1" for a top-level heading, and so forth. The "dict"
argument specifies an optional dictionary of properties for the content such
as the marked content identifier ("MCID") number.
.PP
Calling this function sets the "Marked" key in the "MarkInfo" dictionary of
the document catalog. The caller is responsible for setting the
"StructTreeRoot" dictionary when creating marked content.
.SS pdfioContentClip
Clip output to the current path.
.PP
@@ -3063,19 +2972,6 @@ bool pdfioContentDrawImage (
.PP
The object name must be part of the page dictionary resources, typically
using the \fIpdfioPageDictAddImage\fR function.
.SS pdfioContentEndMarked
End marked content.
.PP
.nf
bool pdfioContentEndMarked (
pdfio_stream_t *st
);
.fi
.PP
This function ends an area of marked content that was started using the
\fIpdfioContentBeginMarked\fR function.
.SS pdfioContentFill
Fill the current path.
.PP
@@ -3187,8 +3083,6 @@ bool pdfioContentPathEnd (
pdfio_stream_t *st
);
.fi
.PP
.SS pdfioContentPathLineTo
Add a straight line to the current path.
.PP
@@ -3529,8 +3423,6 @@ double pdfioContentTextMeasure (
This function measures the given text string "s" and returns its width based
on "size". The text string must always use the UTF-8 (Unicode) encoding but
any control characters (such as newlines) are ignored.
.SS pdfioContentTextMoveLine
Move to the next line and offset.
.PP
@@ -3559,8 +3451,6 @@ bool pdfioContentTextNewLine (
pdfio_stream_t *st
);
.fi
.PP
.SS pdfioContentTextNewLineShow
Move to the next line and show text.
.PP
@@ -3578,8 +3468,6 @@ This function moves to the next line and then shows some text with optional
word and character spacing in a PDF content stream. The "unicode" argument
specifies that the current font maps to full Unicode. The "s" argument
specifies a UTF-8 encoded string.
.SS pdfioContentTextNewLineShowf
Show formatted text.
.PP
@@ -3598,8 +3486,6 @@ This function moves to the next line and shows some formatted text with
optional word and character spacing in a PDF content stream. The "unicode"
argument specifies that the current font maps to full Unicode. The "format"
argument specifies a UTF-8 encoded \fBprintf\fR-style format string.
.SS pdfioContentTextShow
Show text.
.PP
@@ -3650,8 +3536,6 @@ bool pdfioDictClear (
const char *key
);
.fi
.PP
.SS pdfioDictCopy
Copy a dictionary to a PDF file.
.PP
@@ -3724,8 +3608,6 @@ const char * pdfioDictGetKey (
size_t n
);
.fi
.PP
.SS pdfioDictGetName
Get a key name value from a dictionary.
.PP
@@ -3743,8 +3625,6 @@ size_t pdfioDictGetNumPairs (
pdfio_dict_t *dict
);
.fi
.PP
.SS pdfioDictGetNumber
Get a key number value from a dictionary.
.PP
@@ -3817,8 +3697,6 @@ function "cb":
The iteration continues as long as the callback returns \fBtrue\fR or all keys
have been iterated.
.SS pdfioDictSetArray
Set a key array in a dictionary.
.PP
@@ -3940,39 +3818,6 @@ bool pdfioDictSetStringf (
...
);
.fi
.SS pdfioFileAddOutputIntent
Add an OutputIntent to a file.
.PP
.nf
void pdfioFileAddOutputIntent (
pdfio_file_t *pdf,
const char *subtype,
const char *condition,
const char *cond_id,
const char *reg_name,
const char *info,
pdfio_obj_t *profile
);
.fi
.PP
This function adds an OutputIntent dictionary to the PDF file catalog.
The "subtype" argument specifies the intent subtype and is typically
"GTS_PDFX" for PDF/X, "GTS_PDFA1" for PDF/A, or "ISO_PDFE1" for PDF/E.
Passing \fBNULL\fR defaults the subtype to "GTS_PDFA1".
.PP
The "condition" argument specifies a short name for the output intent, while
the "info" argument specifies a longer description for the output intent.
Both can be \fBNULL\fR to omit this information.
.PP
The "cond_id" argument specifies a unique identifier such as a registration
("CGATS001") or color space name ("sRGB"). The "reg_name" argument provides
a URL for the identifier.
.PP
The "profile" argument specifies an ICC profile object for the output
condition. If \fBNULL\fR, the PDF consumer will attempt to look up the correct
profile using the "cond_id" value.
.SS pdfioFileClose
Close a PDF file and free all memory used for it.
.PP
@@ -3999,56 +3844,16 @@ This function creates a new PDF file. The "filename" argument specifies the
name of the PDF file to create.
.PP
The "version" argument specifies the PDF version number for the file or
\fBNULL\fR for the default ("2.0"). The following values are recognized:
.PP
.IP \(bu 5
"1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
specified versions.
.IP \(bu 5
"PCLm-1.0": The PCLm (raster) subset of PDF supported by some printers.
.IP \(bu 5
"PDF/A-1a": PDF/A-1a:2005
.IP \(bu 5
"PDF/A-1b": PDF/A-1b:2005
.IP \(bu 5
"PDF/A-2a": PDF/A-2a:2011
.IP \(bu 5
"PDF/A-2b": PDF/A-2b:2011
.IP \(bu 5
"PDF/A-2u": PDF/A-2u:2011
.IP \(bu 5
"PDF/A-3a": PDF/A-3a:2012
.IP \(bu 5
"PDF/A-3b": PDF/A-3b:2012
.IP \(bu 5
"PDF/A-3u": PDF/A-3u:2012
.IP \(bu 5
"PDF/A-4": PDF/A-4:2020
\fBNULL\fR for the default ("2.0"). The value "PCLm-1.0" can be specified to
produce the PCLm subset of PDF.
.PP
The "media_box" and "crop_box" arguments specify the default MediaBox and
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
.PP
The "error_cb" and "error_cbdata" arguments specify an error handler callback
and its data pointer - if \fBNULL\fR then the default error handler is used that
writes error and warning messages to \fBstderr\fR. The error handler callback
should return \fBtrue\fR to continue writing the PDF file or \fBfalse\fR to stop.
For example:
.PP
.nf
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, "%s: %sn", pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, "WARNING:", 8));
}
.fi
and its data pointer - if \fBNULL\fR the default error handler is used that
writes error messages to \fBstderr\fR.
.SS pdfioFileCreateArrayObj
Create a new object in a PDF file containing an array.
.PP
@@ -4106,30 +3911,8 @@ specifies the font nane:
Aside from "Symbol" and "Zapf-Dingbats", Base fonts use the Windows CP1252
(ISO-8859-1 with additional characters such as the Euro symbol) subset of
Unicode.
.PP
.IP 5
Note: This function cannot be used when producing PDF/A files.
.SS pdfioFileCreateFontObjFromData
Add a font in memory to a PDF file.
.PP
.nf
pdfio_obj_t * pdfioFileCreateFontObjFromData (
pdfio_file_t *pdf,
const void *data,
size_t datasize,
bool unicode
);
.fi
.PP
This function embeds TrueType/OpenType font data into a PDF file. The
"unicode" parameter controls whether the font is encoded for two-byte
characters (potentially full Unicode, but more typically a subset)
or to only support the Windows CP1252 (ISO-8859-1 with additional
characters such as the Euro symbol) subset of Unicode.
.SS pdfioFileCreateFontObjFromFile
Add a font file to a PDF file.
Add a font object to a PDF file.
.PP
.nf
pdfio_obj_t * pdfioFileCreateFontObjFromFile (
@@ -4139,7 +3922,7 @@ pdfio_obj_t * pdfioFileCreateFontObjFromFile (
);
.fi
.PP
This function embeds a TrueType/OpenType font file into a PDF file. The
This function embeds a TrueType/OpenType font into a PDF file. The
"unicode" parameter controls whether the font is encoded for two-byte
characters (potentially full Unicode, but more typically a subset)
or to only support the Windows CP1252 (ISO-8859-1 with additional
@@ -4192,12 +3975,8 @@ the image is encoded in the corresponding device color space. The
"interpolate" parameter specifies whether to interpolate when scaling the
image on the page.
.PP
.IP 5
Note: When creating an image object with alpha, a second image object is
.IP 5
created to hold the "soft mask" data for the primary image. PDF/A-1
.IP 5
files do not support alpha-based transparency.
created to hold the "soft mask" data for the primary image.
.SS pdfioFileCreateImageObjFromFile
Add an image object to a PDF file from a file.
.PP
@@ -4215,9 +3994,11 @@ the "interpolate" parameter specifies whether to interpolate when scaling the
image on the page.
.PP
.IP 5
Note: PNG files containing transparency cannot be used when producing
Note: Currently PNG support is limited to grayscale, RGB, or indexed files
.IP 5
PDF/A files.
without interlacing or alpha. Transparency (masking) based on color/index
.IP 5
is supported.
.SS pdfioFileCreateNameObj
Create a new object in a PDF file containing a name.
.PP
@@ -4230,8 +4011,6 @@ pdfio_obj_t * pdfioFileCreateNameObj (
.PP
This function creates a new object with a name value in a PDF file.
You must call \fIpdfioObjClose\fR to write the object to the file.
.SS pdfioFileCreateNumberObj
Create a new object in a PDF file containing a number.
.PP
@@ -4244,8 +4023,6 @@ pdfio_obj_t * pdfioFileCreateNumberObj (
.PP
This function creates a new object with a number value in a PDF file.
You must call \fIpdfioObjClose\fR to write the object to the file.
.SS pdfioFileCreateObj
Create a new object in a PDF file.
.PP
@@ -4285,57 +4062,18 @@ written:
.fi
The "version" argument specifies the PDF version number for the file or
\fBNULL\fR for the default ("2.0"). The following values are recognized:
.PP
.IP \(bu 5
"1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
specified versions.
.IP \(bu 5
"PDF/A-1a": PDF/A-1a:2005
.IP \(bu 5
"PDF/A-1b": PDF/A-1b:2005
.IP \(bu 5
"PDF/A-2a": PDF/A-2a:2011
.IP \(bu 5
"PDF/A-2b": PDF/A-2b:2011
.IP \(bu 5
"PDF/A-2u": PDF/A-2u:2011
.IP \(bu 5
"PDF/A-3a": PDF/A-3a:2012
.IP \(bu 5
"PDF/A-3b": PDF/A-3b:2012
.IP \(bu 5
"PDF/A-3u": PDF/A-3u:2012
.IP \(bu 5
"PDF/A-4": PDF/A-4:2020
.PP
Unlike \fIpdfioFileCreate\fR and \fIpdfioFileCreateTemporary\fR, it is
generally not safe to pass the "PCLm-1.0" version string.
\fBNULL\fR for the default ("2.0"). Unlike \fIpdfioFileCreate\fR and
\fIpdfioFileCreateTemporary\fR, it is generally not safe to pass the
"PCLm-1.0" version string.
.PP
The "media_box" and "crop_box" arguments specify the default MediaBox and
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
.PP
The "error_cb" and "error_cbdata" arguments specify an error handler callback
and its data pointer - if \fBNULL\fR then the default error handler is used that
writes error and warning messages to \fBstderr\fR. The error handler callback
should return \fBtrue\fR to continue writing the PDF file or \fBfalse\fR to stop.
For example:
and its data pointer - if \fBNULL\fR the default error handler is used that
writes error messages to \fBstderr\fR.
.PP
.nf
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, "%s: %sn", pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, "WARNING:", 8));
}
.fi
.IP 5
\fINote\fR: Files created using this API are slightly larger than those
.IP 5
@@ -4363,8 +4101,6 @@ pdfio_obj_t * pdfioFileCreateStringObj (
.PP
This function creates a new object with a string value in a PDF file.
You must call \fIpdfioObjClose\fR to write the object to the file.
.SS pdfioFileCreateTemporary
.PP
@@ -4441,21 +4177,6 @@ const char * pdfioFileGetKeywords (
pdfio_file_t *pdf
);
.fi
.SS pdfioFileGetLanguage
Get the language metadata for a PDF file.
.PP
.nf
const char * pdfioFileGetLanguage (
pdfio_file_t *pdf
);
.fi
.PP
This function gets the (primary/default) language metadata, if any, for a PDF
file. The returned string is an IETF BCP 47 language tag of the form
"lang-REGION". For example, the string "en-CA" specifies Canadian English
and the string "fr-CA" specifies Canadian French.
.SS pdfioFileGetModificationDate
Get the most recent modification date for a PDF file.
.PP
@@ -4573,33 +4294,8 @@ cancel the open. If \fBNULL\fR is specified for the callback function and the
PDF file requires a password, the open will always fail.
.PP
The "error_cb" and "error_cbdata" arguments specify an error handler callback
and its data pointer - if \fBNULL\fR then the default error handler is used that
writes error and warning messages to \fBstderr\fR. The error handler callback
should return \fBtrue\fR to continue reading the PDF file or \fBfalse\fR to stop.
For example:
.PP
.nf
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, "%s: %sn", pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, "WARNING:", 8));
}
.fi
.IP 5
Note: Error messages starting with "WARNING:" are actually warning
.IP 5
messages - the callback should normally return \fBtrue\fR to allow PDFio to
.IP 5
try to resolve the issue. In addition, some errors are unrecoverable and
.IP 5
ignore the return value of the error callback.
and its data pointer - if \fBNULL\fR the default error handler is used that
writes error messages to \fBstderr\fR.
.SS pdfioFileSetAuthor
Set the author for a PDF file.
.PP
@@ -4636,22 +4332,6 @@ void pdfioFileSetKeywords (
const char *value
);
.fi
.SS pdfioFileSetLanguage
Set the language metadata for a PDF file.
.PP
.nf
void pdfioFileSetLanguage (
pdfio_file_t *pdf,
const char *value
);
.fi
.PP
This function sets the (primary/default) language metadata for a PDF file.
The "value" argument is an IETF BCP 47 language tag string of the form
"lang-REGION". For example, the string "en-CA" specifies Canadian English
and the string "fr-CA" specifies Canadian French.
.SS pdfioFileSetModificationDate
Set the modification date for a PDF file.
.PP
@@ -4794,8 +4474,6 @@ const char * pdfioObjGetName (
pdfio_obj_t *obj
);
.fi
.PP
.SS pdfioObjGetNumber
Get the object's number.
.PP
@@ -4999,9 +4677,8 @@ bool pdfioStreamPrintf (
.fi
.PP
This function writes a formatted string to a stream. In addition to the
standard \fBprintf\fR format characters, you can use "%H" to format a HTML/XML
string value, "%N" to format a PDF name value ("/Name"), and "%S" to format
a PDF string ("(String)") value.
standard \fBprintf\fR format characters, you can use "%N" to format a PDF name
value ("/Name") and "%S" to format a PDF string ("(String)") value.
.SS pdfioStreamPutChar
Write a single character to a stream.
.PP

View File

@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>PDFio Programming Manual v1.6.0</title>
<title>PDFio Programming Manual v1.5.2</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta name="generator" content="codedoc v3.8">
<meta name="author" content="Michael R Sweet">
<meta name="language" content="en-US">
<meta name="copyright" content="Copyright © 2021-2025 by Michael R Sweet">
<meta name="version" content="1.6.0">
<meta name="version" content="1.5.2">
<style type="text/css"><!--
body {
background: white;
@@ -251,7 +251,7 @@ span.string {
<body>
<div class="header">
<p><img class="title" src="pdfio-512.png"></p>
<h1 class="title">PDFio Programming Manual v1.6.0</h1>
<h1 class="title">PDFio Programming Manual v1.5.2</h1>
<p>Michael R Sweet</p>
<p>Copyright © 2021-2025 by Michael R Sweet</p>
</div>
@@ -273,7 +273,6 @@ span.string {
<li><a href="#pdf-objects">PDF Objects</a></li>
<li><a href="#pdf-streams">PDF Streams</a></li>
<li><a href="#pdf-content-helper-functions">PDF Content Helper Functions</a></li>
<li><a href="#tagged-and-marked-pdf-content">Tagged and Marked PDF Content</a></li>
</ul></li>
<li><a href="#examples">Examples</a><ul class="subcontents">
<li><a href="#read-pdf-metadata">Read PDF Metadata</a></li>
@@ -311,10 +310,8 @@ span.string {
<li><a href="#pdfioArrayGetString">pdfioArrayGetString</a></li>
<li><a href="#pdfioArrayGetType">pdfioArrayGetType</a></li>
<li><a href="#pdfioArrayRemove">pdfioArrayRemove</a></li>
<li><a href="#pdfioContentBeginMarked">pdfioContentBeginMarked</a></li>
<li><a href="#pdfioContentClip">pdfioContentClip</a></li>
<li><a href="#pdfioContentDrawImage">pdfioContentDrawImage</a></li>
<li><a href="#pdfioContentEndMarked">pdfioContentEndMarked</a></li>
<li><a href="#pdfioContentFill">pdfioContentFill</a></li>
<li><a href="#pdfioContentFillAndStroke">pdfioContentFillAndStroke</a></li>
<li><a href="#pdfioContentMatrixConcat">pdfioContentMatrixConcat</a></li>
@@ -398,12 +395,10 @@ span.string {
<li><a href="#pdfioDictSetRect">pdfioDictSetRect</a></li>
<li><a href="#pdfioDictSetString">pdfioDictSetString</a></li>
<li><a href="#pdfioDictSetStringf">pdfioDictSetStringf</a></li>
<li><a href="#pdfioFileAddOutputIntent">pdfioFileAddOutputIntent</a></li>
<li><a href="#pdfioFileClose">pdfioFileClose</a></li>
<li><a href="#pdfioFileCreate">pdfioFileCreate</a></li>
<li><a href="#pdfioFileCreateArrayObj">pdfioFileCreateArrayObj</a></li>
<li><a href="#pdfioFileCreateFontObjFromBase">pdfioFileCreateFontObjFromBase</a></li>
<li><a href="#pdfioFileCreateFontObjFromData">pdfioFileCreateFontObjFromData</a></li>
<li><a href="#pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></li>
<li><a href="#pdfioFileCreateICCObjFromData">pdfioFileCreateICCObjFromData</a></li>
<li><a href="#pdfioFileCreateICCObjFromFile">pdfioFileCreateICCObjFromFile</a></li>
@@ -423,7 +418,6 @@ span.string {
<li><a href="#pdfioFileGetCreator">pdfioFileGetCreator</a></li>
<li><a href="#pdfioFileGetID">pdfioFileGetID</a></li>
<li><a href="#pdfioFileGetKeywords">pdfioFileGetKeywords</a></li>
<li><a href="#pdfioFileGetLanguage">pdfioFileGetLanguage</a></li>
<li><a href="#pdfioFileGetModificationDate">pdfioFileGetModificationDate</a></li>
<li><a href="#pdfioFileGetName">pdfioFileGetName</a></li>
<li><a href="#pdfioFileGetNumObjs">pdfioFileGetNumObjs</a></li>
@@ -440,7 +434,6 @@ span.string {
<li><a href="#pdfioFileSetCreationDate">pdfioFileSetCreationDate</a></li>
<li><a href="#pdfioFileSetCreator">pdfioFileSetCreator</a></li>
<li><a href="#pdfioFileSetKeywords">pdfioFileSetKeywords</a></li>
<li><a href="#pdfioFileSetLanguage">pdfioFileSetLanguage</a></li>
<li><a href="#pdfioFileSetModificationDate">pdfioFileSetModificationDate</a></li>
<li><a href="#pdfioFileSetPermissions">pdfioFileSetPermissions</a></li>
<li><a href="#pdfioFileSetSubject">pdfioFileSetSubject</a></li>
@@ -735,7 +728,7 @@ password_cb(<span class="reserved">void</span> *data, <span class="reserved">con
<span class="reserved">return</span> (<span class="string">&quot;Password42&quot;</span>);
}
</code></pre>
<p>The error callback is called for both errors and warnings and accepts the <code>pdfio_file_t</code> pointer, a message string, and the callback pointer value. It returns <code>true</code> to continue processing the file or <code>false</code> to stop, for example:</p>
<p>The error callback is called for both errors and warnings and accepts the <code>pdfio_file_t</code> pointer, a message string, and the callback pointer value, for example:</p>
<pre><code class="language-c"><span class="reserved">bool</span>
error_cb(pdfio_file_t *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *message, <span class="reserved">void</span> *data)
{
@@ -743,14 +736,11 @@ error_cb(pdfio_file_t *pdf, <span class="reserved">const</span> <span class="res
fprintf(stderr, <span class="string">&quot;%s: %s\n&quot;</span>, pdfioFileGetName(pdf), message);
<span class="comment">// Return true for warning messages (continue) and false for errors (stop)</span>
<span class="reserved">return</span> (!strncmp(message, <span class="string">&quot;WARNING:&quot;</span>, <span class="number">8</span>));
<span class="comment">// Return false to treat warnings as errors</span>
<span class="reserved">return</span> (<span class="reserved">false</span>);
}
</code></pre>
<p>The default error callback (<code>NULL</code>) does the equivalent of the above.</p>
<blockquote>
<p>Note: Many errors are unrecoverable, so PDFio ignores the return value from the error callback and always stops processing the PDF file. Warning messages start with the prefix &quot;WARNING:&quot; while errors have no prefix.</p>
</blockquote>
<p>Each PDF file contains one or more pages. The <a href="#pdfioFileGetNumPages"><code>pdfioFileGetNumPages</code></a> function returns the number of pages in the file while the <a href="#pdfioFileGetPage"><code>pdfioFileGetPage</code></a> function gets the specified page in the PDF file:</p>
<pre><code class="language-c">pdfio_file_t *pdf; <span class="comment">// PDF file</span>
size_t i; <span class="comment">// Looping var</span>
@@ -1161,38 +1151,6 @@ pdfio_obj_t *img =
<li><p><a href="#pdfioContentTextShowJustified"><code>pdfioContentTextShowJustified</code></a> draws an array of literal strings with offsets between them</p>
</li>
</ul>
<h3 class="title" id="tagged-and-marked-pdf-content">Tagged and Marked PDF Content</h3>
<p>Content in a page stream can be tagged to help a PDF reader application know the kind and organization of that content. Content inserted using the PDFio <a href="#page-stream-functions">Page Stream Functions</a> can be tagged by surrounding it with the <a href="#pdfioContentBeginMarked"><code>pdfioContentBeginMarked</code></a> and <a href="#pdfioContentEndMarked"><code>pdfioContentEndMarked</code></a> functions.</p>
<p>The <code>pdfioContentBeginMarked</code> function accepts a named tag and optional dictionary of attributes such as the marked content identifier (&quot;MCID&quot;). For example, the following code tags a paragraph of text:</p>
<pre><code class="language-c">pdfio_file_t *pdf; <span class="comment">// PDF file</span>
pdfio_stream_t *st; <span class="comment">// Page stream</span>
pdfioContentBeginMarked(st, <span class="string">&quot;P&quot;</span>, <span class="comment">/*dict*/</span>NULL);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;Mary had a little lamb\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;whose fleece was white as snow.\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;And everywhere that Mary went\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;the lamb was sure to go,\n&quot;</span>);
pdfioContentEndMarked(st);
</code></pre>
<p>To mark the same paragraph with a content identifier you would first create a dictionary containing the &quot;MCID&quot; key/value pair and then mark the paragraph with that dictionary:</p>
<pre><code class="language-c">pdfio_file_t *pdf; <span class="comment">// PDF file</span>
pdfio_stream_t *st; <span class="comment">// Page stream</span>
pdfio_dict_t *dict; <span class="comment">// Content dictionary</span>
dict = pdfioDictCreate(pdf);
pdfioDictSetNumber(dict, <span class="string">&quot;MCID&quot;</span>, <span class="number">42</span>);
pdfioContentBeginMarked(st, <span class="string">&quot;P&quot;</span>, dict);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;Mary had a little lamb\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;whose fleece was white as snow.\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;And everywhere that Mary went\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;the lamb was sure to go,\n&quot;</span>);
pdfioContentEndMarked(st);
</code></pre>
<h2 class="title" id="examples">Examples</h2>
<p>PDFio includes several example programs that are typically installed to the <code>/usr/share/doc/pdfio/examples</code> or <code>/usr/local/share/doc/pdfio/examples</code> directories. A makefile is included to build them.</p>
<h3 class="title" id="read-pdf-metadata">Read PDF Metadata</h3>
@@ -1788,9 +1746,6 @@ pdfioStreamClose(page_st);
<span class="comment">// State for the current page</span>
pdfio_stream_t *st; <span class="comment">// Current page stream</span>
<span class="reserved">double</span> y; <span class="comment">// Current position on page</span>
<span class="reserved">const</span> <span class="reserved">char</span> *tag; <span class="comment">// Current block tag</span>
<span class="reserved">bool</span> in_table, <span class="comment">// Are we in a table?</span>
in_row; <span class="comment">// Are we in a table row?</span>
docfont_t font; <span class="comment">// Current font</span>
<span class="reserved">double</span> fsize; <span class="comment">// Current font size</span>
doccolor_t color; <span class="comment">// Current color</span>
@@ -2168,9 +2123,6 @@ pdfioContentPathRect(dd-&gt;st, left - CODE_PADDING, dd-&gt;y + SIZE_CODEBLOCK,
pdfioContentFillAndStroke(dd-&gt;st, <span class="reserved">false</span>);
<span class="comment">// Start a code text block...</span>
dd-&gt;tag = <span class="string">&quot;P&quot;</span>;
pdfioContentBeginMarked(dd-&gt;st, dd-&gt;tag, <span class="comment">/*dict*/</span>NULL);
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd-&gt;st);
pdfioContentTextMoveTo(dd-&gt;st, left, dd-&gt;y);
@@ -2207,9 +2159,6 @@ pdfioContentTextMoveTo(dd-&gt;st, left, dd-&gt;y);
pdfioContentTextEnd(dd-&gt;st);
dd-&gt;y += lineheight;
pdfioContentEndMarked(dd-&gt;st);
dd-&gt;tag = NULL;
<span class="comment">// Draw the bottom padding...</span>
set_color(dd, DOCCOLOR_LTGRAY);
pdfioContentPathRect(dd-&gt;st, left - CODE_PADDING,
@@ -2320,17 +2269,8 @@ pdfioContentFillAndStroke(dd-&gt;st, <span class="reserved">false</span>);
</code></pre>
<p>Finally, we render each row in the table:</p>
<pre><code class="language-c"><span class="comment">// Render each table row...</span>
dd-&gt;in_table = <span class="reserved">true</span>;
<span class="reserved">if</span> (dd-&gt;st)
pdfioContentBeginMarked(dd-&gt;st, <span class="string">&quot;Table&quot;</span>, <span class="comment">/*dict*/</span>NULL);
<span class="reserved">for</span> (row = <span class="number">0</span>, rowptr = rows; row &lt; num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr);
pdfioContentEndMarked(dd-&gt;st);
dd-&gt;in_table = <span class="reserved">false</span>;
</code></pre>
<h4 id="rendering-the-markdown-document">Rendering the Markdown Document</h4>
<p>The formatted content in arrays of <code>linefrag_t</code> and <code>tablerow_t</code> structures are passed to the <code>render_line</code> and <code>render_row</code> functions respectively to produce content in the PDF document.</p>
@@ -2654,7 +2594,7 @@ dd-&gt;y = row_y - row-&gt;height;
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>num_colors</th>
<td class="description">Number of colors (1, 3, or 4)</td></tr>
<td class="description">Number of colors (1 or 3)</td></tr>
<tr><th>cs</th>
<td class="description">Color space enumeration</td></tr>
</tbody></table>
@@ -2662,8 +2602,7 @@ dd-&gt;y = row_y - row-&gt;height;
<p class="description">Color array</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function creates a color array for a standard <code>PDFIO_CS_</code> enumerated color space.
The &quot;num_colors&quot; argument must be <code>1</code> for grayscale, <code>3</code> for RGB color, and
<code>4</code> for CMYK color.</p>
The &quot;num_colors&quot; argument must be <code>1</code> for grayscale and <code>3</code> for RGB color.</p>
<h3 class="function"><a id="pdfioArrayGetArray">pdfioArrayGetArray</a></h3>
<p class="description">Get an array value from an array.</p>
<p class="code">
@@ -2807,7 +2746,7 @@ size_t pdfioArrayGetSize(<a href="#pdfio_array_t">pdfio_array_t</a> *a);</p>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Value type</p>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioArrayRemove">pdfioArrayRemove</a></h3>
<h3 class="function"><a id="pdfioArrayRemove">pdfioArrayRemove</a></h3>
<p class="description">Remove an array entry.</p>
<p class="code">
<span class="reserved">bool</span> pdfioArrayRemove(<a href="#pdfio_array_t">pdfio_array_t</a> *a, size_t n);</p>
@@ -2820,35 +2759,6 @@ size_t pdfioArrayGetSize(<a href="#pdfio_array_t">pdfio_array_t</a> *a);</p>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> otherwise</p>
<h3 class="function"><span class="info">&#160;PDFio 1.6&#160;</span><a id="pdfioContentBeginMarked">pdfioContentBeginMarked</a></h3>
<p class="description">Start marked content with an optional dictionary.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentBeginMarked(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, <span class="reserved">const</span> <span class="reserved">char</span> *tag, <a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>st</th>
<td class="description">Stream</td></tr>
<tr><th>tag</th>
<td class="description">Tag name of marked content</td></tr>
<tr><th>dict</th>
<td class="description">Dictionary of parameters or <code>NULL</code> if none</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function starts an area of marked content with an optional dictionary.
It must be paired with a call to the <a href="#pdfioContentEndMarked"><code>pdfioContentEndMarked</code></a> function.<br>
<br>
The &quot;tag&quot; argument specifies the tag name string for the content such as &quot;P&quot;
for a paragraph, &quot;H1&quot; for a top-level heading, and so forth. The &quot;dict&quot;
argument specifies an optional dictionary of properties for the content such
as the marked content identifier (&quot;MCID&quot;) number.<br>
<br>
Calling this function sets the &quot;Marked&quot; key in the &quot;MarkInfo&quot; dictionary of
the document catalog. The caller is responsible for setting the
&quot;StructTreeRoot&quot; dictionary when creating marked content.
</p>
<h3 class="function"><a id="pdfioContentClip">pdfioContentClip</a></h3>
<p class="description">Clip output to the current path.</p>
<p class="code">
@@ -2886,22 +2796,6 @@ the document catalog. The caller is responsible for setting the
<h4 class="discussion">Discussion</h4>
<p class="discussion">The object name must be part of the page dictionary resources, typically
using the <a href="#pdfioPageDictAddImage"><code>pdfioPageDictAddImage</code></a> function.</p>
<h3 class="function"><span class="info">&#160;PDFio 1.6&#160;</span><a id="pdfioContentEndMarked">pdfioContentEndMarked</a></h3>
<p class="description">End marked content.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentEndMarked(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>st</th>
<td class="description">Stream</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function ends an area of marked content that was started using the
<a href="#pdfioContentBeginMarked"><code>pdfioContentBeginMarked</code></a> function.
</p>
<h3 class="function"><a id="pdfioContentFill">pdfioContentFill</a></h3>
<p class="description">Fill the current path.</p>
<p class="code">
@@ -3057,7 +2951,7 @@ using the <a href="#pdfioPageDictAddImage"><code>pdfioPageDictAddImage</code></a
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h3 class="function"><span class="info">&#160;PDFio v1.1&#160;</span><a id="pdfioContentPathEnd">pdfioContentPathEnd</a></h3>
<h3 class="function"><a id="pdfioContentPathEnd">pdfioContentPathEnd</a></h3>
<p class="description">Clear the current path.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentPathEnd(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
@@ -3547,7 +3441,7 @@ are 0, a solid line is drawn.</p>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h3 class="function"><span class="info">&#160;PDFio v1.2&#160;</span><a id="pdfioContentTextMeasure">pdfioContentTextMeasure</a></h3>
<h3 class="function"><a id="pdfioContentTextMeasure">pdfioContentTextMeasure</a></h3>
<p class="description">Measure a text string and return its width.</p>
<p class="code">
<span class="reserved">double</span> pdfioContentTextMeasure(<a href="#pdfio_obj_t">pdfio_obj_t</a> *font, <span class="reserved">const</span> <span class="reserved">char</span> *s, <span class="reserved">double</span> size);</p>
@@ -3565,9 +3459,7 @@ are 0, a solid line is drawn.</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function measures the given text string &quot;s&quot; and returns its width based
on &quot;size&quot;. The text string must always use the UTF-8 (Unicode) encoding but
any control characters (such as newlines) are ignored.
</p>
any control characters (such as newlines) are ignored.</p>
<h3 class="function"><a id="pdfioContentTextMoveLine">pdfioContentTextMoveLine</a></h3>
<p class="description">Move to the next line and offset.</p>
<p class="code">
@@ -3598,7 +3490,7 @@ any control characters (such as newlines) are ignored.
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h3 class="function"><span class="info">&#160;PDFio v1.2&#160;</span><a id="pdfioContentTextNewLine">pdfioContentTextNewLine</a></h3>
<h3 class="function"><a id="pdfioContentTextNewLine">pdfioContentTextNewLine</a></h3>
<p class="description">Move to the next line.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentTextNewLine(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
@@ -3609,7 +3501,7 @@ any control characters (such as newlines) are ignored.
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h3 class="function"><span class="info">&#160;PDFio v1.2&#160;</span><a id="pdfioContentTextNewLineShow">pdfioContentTextNewLineShow</a></h3>
<h3 class="function"><a id="pdfioContentTextNewLineShow">pdfioContentTextNewLineShow</a></h3>
<p class="description">Move to the next line and show text.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentTextNewLineShow(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, <span class="reserved">double</span> ws, <span class="reserved">double</span> cs, <span class="reserved">bool</span> unicode, <span class="reserved">const</span> <span class="reserved">char</span> *s);</p>
@@ -3632,10 +3524,8 @@ any control characters (such as newlines) are ignored.
<p class="discussion">This function moves to the next line and then shows some text with optional
word and character spacing in a PDF content stream. The &quot;unicode&quot; argument
specifies that the current font maps to full Unicode. The &quot;s&quot; argument
specifies a UTF-8 encoded string.
</p>
<h3 class="function"><span class="info">&#160;PDFio v1.2&#160;</span><a id="pdfioContentTextNewLineShowf">pdfioContentTextNewLineShowf</a></h3>
specifies a UTF-8 encoded string.</p>
<h3 class="function"><a id="pdfioContentTextNewLineShowf">pdfioContentTextNewLineShowf</a></h3>
<p class="description">Show formatted text.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentTextNewLineShowf(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, <span class="reserved">double</span> ws, <span class="reserved">double</span> cs, <span class="reserved">bool</span> unicode, <span class="reserved">const</span> <span class="reserved">char</span> *format, ...);</p>
@@ -3660,9 +3550,7 @@ specifies a UTF-8 encoded string.
<p class="discussion">This function moves to the next line and shows some formatted text with
optional word and character spacing in a PDF content stream. The &quot;unicode&quot;
argument specifies that the current font maps to full Unicode. The &quot;format&quot;
argument specifies a UTF-8 encoded <code>printf</code>-style format string.
</p>
argument specifies a UTF-8 encoded <code>printf</code>-style format string.</p>
<h3 class="function"><a id="pdfioContentTextShow">pdfioContentTextShow</a></h3>
<p class="description">Show text.</p>
<p class="code">
@@ -3725,7 +3613,7 @@ argument specifies an array of UTF-8 encoded strings.</p>
<p class="discussion">This function shows some formatted text in a PDF content stream. The
&quot;unicode&quot; argument specifies that the current font maps to full Unicode.
The &quot;format&quot; argument specifies a UTF-8 encoded <code>printf</code>-style format string.</p>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioDictClear">pdfioDictClear</a></h3>
<h3 class="function"><a id="pdfioDictClear">pdfioDictClear</a></h3>
<p class="description">Remove a key/value pair from a dictionary.</p>
<p class="code">
<span class="reserved">bool</span> pdfioDictClear(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <span class="reserved">const</span> <span class="reserved">char</span> *key);</p>
@@ -3829,7 +3717,7 @@ time_t pdfioDictGetDate(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <span cl
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Value</p>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioDictGetKey">pdfioDictGetKey</a></h3>
<h3 class="function"><a id="pdfioDictGetKey">pdfioDictGetKey</a></h3>
<p class="description">Get the key for the specified pair.</p>
<p class="code">
<span class="reserved">const</span> <span class="reserved">char</span> *pdfioDictGetKey(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, size_t n);</p>
@@ -3855,7 +3743,7 @@ time_t pdfioDictGetDate(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <span cl
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Value</p>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioDictGetNumPairs">pdfioDictGetNumPairs</a></h3>
<h3 class="function"><a id="pdfioDictGetNumPairs">pdfioDictGetNumPairs</a></h3>
<p class="description">Get the number of key/value pairs in a dictionary.</p>
<p class="code">
size_t pdfioDictGetNumPairs(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
@@ -3933,7 +3821,7 @@ size_t pdfioDictGetNumPairs(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Value type</p>
<h3 class="function"><span class="info">&#160;PDFio v1.1&#160;</span><a id="pdfioDictIterateKeys">pdfioDictIterateKeys</a></h3>
<h3 class="function"><a id="pdfioDictIterateKeys">pdfioDictIterateKeys</a></h3>
<p class="description">Iterate the keys in a dictionary.</p>
<p class="code">
<span class="reserved">void</span> pdfioDictIterateKeys(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <a href="#pdfio_dict_cb_t">pdfio_dict_cb_t</a> cb, <span class="reserved">void</span> *cb_data);</p>
@@ -3960,9 +3848,7 @@ my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data)
</pre>
The iteration continues as long as the callback returns <code>true</code> or all keys
have been iterated.
</p>
have been iterated.</p>
<h3 class="function"><a id="pdfioDictSetArray">pdfioDictSetArray</a></h3>
<p class="description">Set a key array in a dictionary.</p>
<p class="code">
@@ -4145,46 +4031,6 @@ have been iterated.
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h3 class="function"><span class="info">&#160;PDFio 1.6&#160;</span><a id="pdfioFileAddOutputIntent">pdfioFileAddOutputIntent</a></h3>
<p class="description">Add an OutputIntent to a file.</p>
<p class="code">
<span class="reserved">void</span> pdfioFileAddOutputIntent(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *subtype, <span class="reserved">const</span> <span class="reserved">char</span> *condition, <span class="reserved">const</span> <span class="reserved">char</span> *cond_id, <span class="reserved">const</span> <span class="reserved">char</span> *reg_name, <span class="reserved">const</span> <span class="reserved">char</span> *info, <a href="#pdfio_obj_t">pdfio_obj_t</a> *profile);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>subtype</th>
<td class="description">Intent subtype (standard)</td></tr>
<tr><th>condition</th>
<td class="description">Condition name or <code>NULL</code> for none</td></tr>
<tr><th>cond_id</th>
<td class="description">Identifier such as registration name or <code>NULL</code> for none</td></tr>
<tr><th>reg_name</th>
<td class="description">Registry URL or <code>NULL</code> for none</td></tr>
<tr><th>info</th>
<td class="description">Description or <code>NULL</code> for none</td></tr>
<tr><th>profile</th>
<td class="description">ICC profile object or <code>NULL</code> for none</td></tr>
</tbody></table>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function adds an OutputIntent dictionary to the PDF file catalog.
The &quot;subtype&quot; argument specifies the intent subtype and is typically
&quot;GTS_PDFX&quot; for PDF/X, &quot;GTS_PDFA1&quot; for PDF/A, or &quot;ISO_PDFE1&quot; for PDF/E.
Passing <code>NULL</code> defaults the subtype to &quot;GTS_PDFA1&quot;.<br>
<br>
The &quot;condition&quot; argument specifies a short name for the output intent, while
the &quot;info&quot; argument specifies a longer description for the output intent.
Both can be <code>NULL</code> to omit this information.<br>
<br>
The &quot;cond_id&quot; argument specifies a unique identifier such as a registration
(&quot;CGATS001&quot;) or color space name (&quot;sRGB&quot;). The &quot;reg_name&quot; argument provides
a URL for the identifier.<br>
<br>
The &quot;profile&quot; argument specifies an ICC profile object for the output
condition. If <code>NULL</code>, the PDF consumer will attempt to look up the correct
profile using the &quot;cond_id&quot; value.
</p>
<h3 class="function"><a id="pdfioFileClose">pdfioFileClose</a></h3>
<p class="description">Close a PDF file and free all memory used for it.</p>
<p class="code">
@@ -4222,55 +4068,16 @@ profile using the &quot;cond_id&quot; value.
name of the PDF file to create.<br>
<br>
The &quot;version&quot; argument specifies the PDF version number for the file or
<code>NULL</code> for the default (&quot;2.0&quot;). The following values are recognized:
</p><ul>
<li>&quot;1.3&quot;, &quot;1.4&quot;, &quot;1.5&quot;, &quot;1.6&quot;, &quot;1.7&quot;, &quot;2.0&quot;: Generic PDF files of the
specified versions.
</li>
<li>&quot;PCLm-1.0&quot;: The PCLm (raster) subset of PDF supported by some printers.
</li>
<li>&quot;PDF/A-1a&quot;: PDF/A-1a:2005
</li>
<li>&quot;PDF/A-1b&quot;: PDF/A-1b:2005
</li>
<li>&quot;PDF/A-2a&quot;: PDF/A-2a:2011
</li>
<li>&quot;PDF/A-2b&quot;: PDF/A-2b:2011
</li>
<li>&quot;PDF/A-2u&quot;: PDF/A-2u:2011
</li>
<li>&quot;PDF/A-3a&quot;: PDF/A-3a:2012
</li>
<li>&quot;PDF/A-3b&quot;: PDF/A-3b:2012
</li>
<li>&quot;PDF/A-3u&quot;: PDF/A-3u:2012
</li>
<li>&quot;PDF/A-4&quot;: PDF/A-4:2020</li>
</ul>
<p class="discussion">The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
<code>NULL</code> for the default (&quot;2.0&quot;). The value &quot;PCLm-1.0&quot; can be specified to
produce the PCLm subset of PDF.<br>
<br>
The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
<br>
The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback
and its data pointer - if <code>NULL</code> then the default error handler is used that
writes error and warning messages to <code>stderr</code>. The error handler callback
should return <code>true</code> to continue writing the PDF file or <code>false</code> to stop.
For example:
<pre>
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, &quot;%s: %sn&quot;, pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, &quot;WARNING:&quot;, 8));
}
</pre>
</p>
and its data pointer - if <code>NULL</code> the default error handler is used that
writes error messages to <code>stderr</code>.</p>
<h3 class="function"><a id="pdfioFileCreateArrayObj">pdfioFileCreateArrayObj</a></h3>
<p class="description">Create a new object in a PDF file containing an array.</p>
<p class="code">
@@ -4335,37 +4142,9 @@ specifies the font nane:
</ul>
<p class="discussion">Aside from &quot;Symbol&quot; and &quot;Zapf-Dingbats&quot;, Base fonts use the Windows CP1252
(ISO-8859-1 with additional characters such as the Euro symbol) subset of
Unicode.<br>
<br>
</p><blockquote>
Note: This function cannot be used when producing PDF/A files.</blockquote>
<h3 class="function"><span class="info">&#160;PDFio v1.6&#160;</span><a id="pdfioFileCreateFontObjFromData">pdfioFileCreateFontObjFromData</a></h3>
<p class="description">Add a font in memory to a PDF file.</p>
<p class="code">
<a href="#pdfio_obj_t">pdfio_obj_t</a> *pdfioFileCreateFontObjFromData(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">void</span> *data, size_t datasize, <span class="reserved">bool</span> unicode);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>data</th>
<td class="description">Font data in memory</td></tr>
<tr><th>datasize</th>
<td class="description">Size of font in memory</td></tr>
<tr><th>unicode</th>
<td class="description">Force Unicode</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Font object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function embeds TrueType/OpenType font data into a PDF file. The
&quot;unicode&quot; parameter controls whether the font is encoded for two-byte
characters (potentially full Unicode, but more typically a subset)
or to only support the Windows CP1252 (ISO-8859-1 with additional
characters such as the Euro symbol) subset of Unicode.
</p>
Unicode.</p>
<h3 class="function"><a id="pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></h3>
<p class="description">Add a font file to a PDF file.</p>
<p class="description">Add a font object to a PDF file.</p>
<p class="code">
<a href="#pdfio_obj_t">pdfio_obj_t</a> *pdfioFileCreateFontObjFromFile(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *filename, <span class="reserved">bool</span> unicode);</p>
<h4 class="parameters">Parameters</h4>
@@ -4380,7 +4159,7 @@ characters such as the Euro symbol) subset of Unicode.
<h4 class="returnvalue">Return Value</h4>
<p class="description">Font object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function embeds a TrueType/OpenType font file into a PDF file. The
<p class="discussion">This function embeds a TrueType/OpenType font into a PDF file. The
&quot;unicode&quot; parameter controls whether the font is encoded for two-byte
characters (potentially full Unicode, but more typically a subset)
or to only support the Windows CP1252 (ISO-8859-1 with additional
@@ -4454,10 +4233,8 @@ the image is encoded in the corresponding device color space. The
&quot;interpolate&quot; parameter specifies whether to interpolate when scaling the
image on the page.<br>
<br>
</p><blockquote>
Note: When creating an image object with alpha, a second image object is
created to hold the &quot;soft mask&quot; data for the primary image. PDF/A-1
files do not support alpha-based transparency.</blockquote>
created to hold the &quot;soft mask&quot; data for the primary image.</p>
<h3 class="function"><a id="pdfioFileCreateImageObjFromFile">pdfioFileCreateImageObjFromFile</a></h3>
<p class="description">Add an image object to a PDF file from a file.</p>
<p class="code">
@@ -4480,9 +4257,10 @@ the &quot;interpolate&quot; parameter specifies whether to interpolate when scal
image on the page.<br>
<br>
</p><blockquote>
Note: PNG files containing transparency cannot be used when producing
PDF/A files.</blockquote>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioFileCreateNameObj">pdfioFileCreateNameObj</a></h3>
Note: Currently PNG support is limited to grayscale, RGB, or indexed files
without interlacing or alpha. Transparency (masking) based on color/index
is supported.</blockquote>
<h3 class="function"><a id="pdfioFileCreateNameObj">pdfioFileCreateNameObj</a></h3>
<p class="description">Create a new object in a PDF file containing a name.</p>
<p class="code">
<a href="#pdfio_obj_t">pdfio_obj_t</a> *pdfioFileCreateNameObj(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *name);</p>
@@ -4497,10 +4275,8 @@ PDF/A files.</blockquote>
<p class="description">New object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function creates a new object with a name value in a PDF file.
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.
</p>
<h3 class="function"><span class="info">&#160;PDFio v1.2&#160;</span><a id="pdfioFileCreateNumberObj">pdfioFileCreateNumberObj</a></h3>
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.</p>
<h3 class="function"><a id="pdfioFileCreateNumberObj">pdfioFileCreateNumberObj</a></h3>
<p class="description">Create a new object in a PDF file containing a number.</p>
<p class="code">
<a href="#pdfio_obj_t">pdfio_obj_t</a> *pdfioFileCreateNumberObj(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">double</span> number);</p>
@@ -4515,9 +4291,7 @@ You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write t
<p class="description">New object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function creates a new object with a number value in a PDF file.
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.
</p>
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.</p>
<h3 class="function"><a id="pdfioFileCreateObj">pdfioFileCreateObj</a></h3>
<p class="description">Create a new object in a PDF file.</p>
<p class="code">
@@ -4569,56 +4343,18 @@ output_cb(void *output_cbdata, const void *buffer, size_t bytes)
</pre>
The &quot;version&quot; argument specifies the PDF version number for the file or
<code>NULL</code> for the default (&quot;2.0&quot;). The following values are recognized:
</p><ul>
<li>&quot;1.3&quot;, &quot;1.4&quot;, &quot;1.5&quot;, &quot;1.6&quot;, &quot;1.7&quot;, &quot;2.0&quot;: Generic PDF files of the
specified versions.
</li>
<li>&quot;PDF/A-1a&quot;: PDF/A-1a:2005
</li>
<li>&quot;PDF/A-1b&quot;: PDF/A-1b:2005
</li>
<li>&quot;PDF/A-2a&quot;: PDF/A-2a:2011
</li>
<li>&quot;PDF/A-2b&quot;: PDF/A-2b:2011
</li>
<li>&quot;PDF/A-2u&quot;: PDF/A-2u:2011
</li>
<li>&quot;PDF/A-3a&quot;: PDF/A-3a:2012
</li>
<li>&quot;PDF/A-3b&quot;: PDF/A-3b:2012
</li>
<li>&quot;PDF/A-3u&quot;: PDF/A-3u:2012
</li>
<li>&quot;PDF/A-4&quot;: PDF/A-4:2020</li>
</ul>
<p class="discussion">Unlike <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> and <a href="#pdfioFileCreateTemporary"><code>pdfioFileCreateTemporary</code></a>, it is
generally not safe to pass the &quot;PCLm-1.0&quot; version string.<br>
<code>NULL</code> for the default (&quot;2.0&quot;). Unlike <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> and
<a href="#pdfioFileCreateTemporary"><code>pdfioFileCreateTemporary</code></a>, it is generally not safe to pass the
&quot;PCLm-1.0&quot; version string.<br>
<br>
The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
<br>
The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback
and its data pointer - if <code>NULL</code> then the default error handler is used that
writes error and warning messages to <code>stderr</code>. The error handler callback
should return <code>true</code> to continue writing the PDF file or <code>false</code> to stop.
For example:
<pre>
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, &quot;%s: %sn&quot;, pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, &quot;WARNING:&quot;, 8));
}
</pre>
and its data pointer - if <code>NULL</code> the default error handler is used that
writes error messages to <code>stderr</code>.<br>
<br>
</p><blockquote>
<em>Note</em>: Files created using this API are slightly larger than those
created using the <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> function since stream lengths are
@@ -4636,7 +4372,7 @@ stored as indirect object references.</blockquote>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Contents stream</p>
<h3 class="function"><span class="info">&#160;PDFio v1.2&#160;</span><a id="pdfioFileCreateStringObj">pdfioFileCreateStringObj</a></h3>
<h3 class="function"><a id="pdfioFileCreateStringObj">pdfioFileCreateStringObj</a></h3>
<p class="description">Create a new object in a PDF file containing a string.</p>
<p class="code">
<a href="#pdfio_obj_t">pdfio_obj_t</a> *pdfioFileCreateStringObj(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *string);</p>
@@ -4651,9 +4387,7 @@ stored as indirect object references.</blockquote>
<p class="description">New object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function creates a new object with a string value in a PDF file.
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.
</p>
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.</p>
<h3 class="function"><a id="pdfioFileCreateTemporary">pdfioFileCreateTemporary</a></h3>
<p class="description"></p>
<p class="code">
@@ -4682,33 +4416,10 @@ temporary directory. The temporary file is stored in the string &quot;buffer&qu
will have a &quot;.pdf&quot; extension.<br>
<br>
The &quot;version&quot; argument specifies the PDF version number for the file or
<code>NULL</code> for the default (&quot;2.0&quot;). The following values are recognized:
</p><ul>
<li>&quot;1.3&quot;, &quot;1.4&quot;, &quot;1.5&quot;, &quot;1.6&quot;, &quot;1.7&quot;, &quot;2.0&quot;: Generic PDF files of the
specified versions.
</li>
<li>&quot;PCLm-1.0&quot;: The PCLm (raster) subset of PDF supported by some printers.
</li>
<li>&quot;PDF/A-1a&quot;: PDF/A-1a:2005
</li>
<li>&quot;PDF/A-1b&quot;: PDF/A-1b:2005
</li>
<li>&quot;PDF/A-2a&quot;: PDF/A-2a:2011
</li>
<li>&quot;PDF/A-2b&quot;: PDF/A-2b:2011
</li>
<li>&quot;PDF/A-2u&quot;: PDF/A-2u:2011
</li>
<li>&quot;PDF/A-3a&quot;: PDF/A-3a:2012
</li>
<li>&quot;PDF/A-3b&quot;: PDF/A-3b:2012
</li>
<li>&quot;PDF/A-3u&quot;: PDF/A-3u:2012
</li>
<li>&quot;PDF/A-4&quot;: PDF/A-4:2020</li>
</ul>
<p class="discussion">The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
<code>NULL</code> for the default (&quot;2.0&quot;). The value &quot;PCLm-1.0&quot; can be specified to
produce the PCLm subset of PDF.<br>
<br>
The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
<br>
@@ -4799,24 +4510,6 @@ time_t pdfioFileGetCreationDate(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf);<
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Keywords string or <code>NULL</code> for none</p>
<h3 class="function"><span class="info">&#160;PDFio 1.6&#160;</span><a id="pdfioFileGetLanguage">pdfioFileGetLanguage</a></h3>
<p class="description">Get the language metadata for a PDF file.</p>
<p class="code">
<span class="reserved">const</span> <span class="reserved">char</span> *pdfioFileGetLanguage(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Language or <code>NULL</code> for none</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function gets the (primary/default) language metadata, if any, for a PDF
file. The returned string is an IETF BCP 47 language tag of the form
&quot;lang-REGION&quot;. For example, the string &quot;en-CA&quot; specifies Canadian English
and the string &quot;fr-CA&quot; specifies Canadian French.
</p>
<h3 class="function"><a id="pdfioFileGetModificationDate">pdfioFileGetModificationDate</a></h3>
<p class="description">Get the most recent modification date for a PDF file.</p>
<p class="code">
@@ -4977,29 +4670,8 @@ cancel the open. If <code>NULL</code> is specified for the callback function an
PDF file requires a password, the open will always fail.<br>
<br>
The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback
and its data pointer - if <code>NULL</code> then the default error handler is used that
writes error and warning messages to <code>stderr</code>. The error handler callback
should return <code>true</code> to continue reading the PDF file or <code>false</code> to stop.
For example:
<pre>
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, &quot;%s: %sn&quot;, pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, &quot;WARNING:&quot;, 8));
}
</pre>
</p><blockquote>
Note: Error messages starting with &quot;WARNING:&quot; are actually warning
messages - the callback should normally return <code>true</code> to allow PDFio to
try to resolve the issue. In addition, some errors are unrecoverable and
ignore the return value of the error callback.</blockquote>
and its data pointer - if <code>NULL</code> the default error handler is used that
writes error messages to <code>stderr</code>.</p>
<h3 class="function"><a id="pdfioFileSetAuthor">pdfioFileSetAuthor</a></h3>
<p class="description">Set the author for a PDF file.</p>
<p class="code">
@@ -5044,24 +4716,6 @@ ignore the return value of the error callback.</blockquote>
<tr><th>value</th>
<td class="description">Value</td></tr>
</tbody></table>
<h3 class="function"><span class="info">&#160;PDFio 1.6&#160;</span><a id="pdfioFileSetLanguage">pdfioFileSetLanguage</a></h3>
<p class="description">Set the language metadata for a PDF file.</p>
<p class="code">
<span class="reserved">void</span> pdfioFileSetLanguage(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *value);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>value</th>
<td class="description">Value</td></tr>
</tbody></table>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function sets the (primary/default) language metadata for a PDF file.
The &quot;value&quot; argument is an IETF BCP 47 language tag string of the form
&quot;lang-REGION&quot;. For example, the string &quot;en-CA&quot; specifies Canadian English
and the string &quot;fr-CA&quot; specifies Canadian French.
</p>
<h3 class="function"><a id="pdfioFileSetModificationDate">pdfioFileSetModificationDate</a></h3>
<p class="description">Set the modification date for a PDF file.</p>
<p class="code">
@@ -5238,7 +4892,7 @@ size_t pdfioObjGetLength(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Length in bytes or <code>0</code> for none</p>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioObjGetName">pdfioObjGetName</a></h3>
<h3 class="function"><a id="pdfioObjGetName">pdfioObjGetName</a></h3>
<p class="description">Get the name value associated with an object.</p>
<p class="code">
<span class="reserved">const</span> <span class="reserved">char</span> *pdfioObjGetName(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p>
@@ -5514,9 +5168,8 @@ ssize_t pdfioStreamPeek(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, <span
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function writes a formatted string to a stream. In addition to the
standard <code>printf</code> format characters, you can use &quot;%H&quot; to format a HTML/XML
string value, &quot;%N&quot; to format a PDF name value (&quot;/Name&quot;), and &quot;%S&quot; to format
a PDF string (&quot;(String)&quot;) value.</p>
standard <code>printf</code> format characters, you can use &quot;%N&quot; to format a PDF name
value (&quot;/Name&quot;) and &quot;%S&quot; to format a PDF string (&quot;(String)&quot;) value.</p>
<h3 class="function"><a id="pdfioStreamPutChar">pdfioStreamPutChar</a></h3>
<p class="description">Write a single character to a stream.</p>
<p class="code">
@@ -5740,7 +5393,6 @@ typedef enum <a href="#pdfio_valtype_e">pdfio_valtype_e</a> pdfio_valtype_t;
<h4 class="constants">Constants</h4>
<table class="list"><tbody>
<tr><th>PDFIO_CS_ADOBE </th><td class="description">AdobeRGB 1998</td></tr>
<tr><th>PDFIO_CS_CGATS001 </th><td class="description">CGATS001 (CMYK)</td></tr>
<tr><th>PDFIO_CS_P3_D65 </th><td class="description">Display P3</td></tr>
<tr><th>PDFIO_CS_SRGB </th><td class="description">sRGB</td></tr>
</tbody></table>
@@ -5751,7 +5403,7 @@ typedef enum <a href="#pdfio_valtype_e">pdfio_valtype_e</a> pdfio_valtype_t;
<tr><th>PDFIO_ENCRYPTION_AES_128 </th><td class="description">128-bit AES encryption (PDF 1.6)</td></tr>
<tr><th>PDFIO_ENCRYPTION_NONE </th><td class="description">No encryption</td></tr>
<tr><th>PDFIO_ENCRYPTION_RC4_128 </th><td class="description">128-bit RC4 encryption (PDF 1.4)</td></tr>
<tr><th>PDFIO_ENCRYPTION_RC4_40 </th><td class="description">40-bit RC4 encryption (PDF 1.3, reading only)</td></tr>
<tr><th>PDFIO_ENCRYPTION_RC4_40 </th><td class="description">40-bit RC4 encryption (PDF 1.3)</td></tr>
</tbody></table>
<h3 class="enumeration"><a id="pdfio_filter_e">pdfio_filter_e</a></h3>
<p class="description">Compression/decompression filters for streams</p>

View File

@@ -343,8 +343,8 @@ password_cb(void *data, const char *filename)
```
The error callback is called for both errors and warnings and accepts the
`pdfio_file_t` pointer, a message string, and the callback pointer value. It
returns `true` to continue processing the file or `false` to stop, for example:
`pdfio_file_t` pointer, a message string, and the callback pointer value, for
example:
```c
bool
@@ -354,17 +354,13 @@ error_cb(pdfio_file_t *pdf, const char *message, void *data)
fprintf(stderr, "%s: %s\n", pdfioFileGetName(pdf), message);
// Return true for warning messages (continue) and false for errors (stop)
return (!strncmp(message, "WARNING:", 8));
// Return false to treat warnings as errors
return (false);
}
```
The default error callback (`NULL`) does the equivalent of the above.
> Note: Many errors are unrecoverable, so PDFio ignores the return value from
> the error callback and always stops processing the PDF file. Warning messages
> start with the prefix "WARNING:" while errors have no prefix.
Each PDF file contains one or more pages. The [`pdfioFileGetNumPages`](@@)
function returns the number of pages in the file while the
[`pdfioFileGetPage`](@@) function gets the specified page in the PDF file:
@@ -868,55 +864,6 @@ escaping, as needed:
offsets between them
Tagged and Marked PDF Content
-----------------------------
Content in a page stream can be tagged to help a PDF reader application know the
kind and organization of that content. Content inserted using the PDFio
[Page Stream Functions](@) can be tagged by surrounding it with the
[`pdfioContentBeginMarked`](@@) and [`pdfioContentEndMarked`](@@) functions.
The `pdfioContentBeginMarked` function accepts a named tag and optional
dictionary of attributes such as the marked content identifier ("MCID"). For
example, the following code tags a paragraph of text:
```c
pdfio_file_t *pdf; // PDF file
pdfio_stream_t *st; // Page stream
pdfioContentBeginMarked(st, "P", /*dict*/NULL);
pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\n");
pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\n");
pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\n");
pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\n");
pdfioContentEndMarked(st);
```
To mark the same paragraph with a content identifier you would first create a
dictionary containing the "MCID" key/value pair and then mark the paragraph with
that dictionary:
```c
pdfio_file_t *pdf; // PDF file
pdfio_stream_t *st; // Page stream
pdfio_dict_t *dict; // Content dictionary
dict = pdfioDictCreate(pdf);
pdfioDictSetNumber(dict, "MCID", 42);
pdfioContentBeginMarked(st, "P", dict);
pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\n");
pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\n");
pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\n");
pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\n");
pdfioContentEndMarked(st);
```
Examples
========
@@ -1646,9 +1593,6 @@ typedef struct docdata_s // Document formatting data
// State for the current page
pdfio_stream_t *st; // Current page stream
double y; // Current position on page
const char *tag; // Current block tag
bool in_table, // Are we in a table?
in_row; // Are we in a table row?
docfont_t font; // Current font
double fsize; // Current font size
doccolor_t color; // Current color
@@ -2152,9 +2096,6 @@ pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y + SIZE_CODEBLOCK,
pdfioContentFillAndStroke(dd->st, false);
// Start a code text block...
dd->tag = "P";
pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd->st);
pdfioContentTextMoveTo(dd->st, left, dd->y);
@@ -2191,9 +2132,6 @@ for (code = mmdGetFirstChild(block); code; code = mmdGetNextSibling(code))
pdfioContentTextEnd(dd->st);
dd->y += lineheight;
pdfioContentEndMarked(dd->st);
dd->tag = NULL;
// Draw the bottom padding...
set_color(dd, DOCCOLOR_LTGRAY);
pdfioContentPathRect(dd->st, left - CODE_PADDING,
@@ -2334,17 +2272,8 @@ Finally, we render each row in the table:
```c
// Render each table row...
dd->in_table = true;
if (dd->st)
pdfioContentBeginMarked(dd->st, "Table", /*dict*/NULL);
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr);
pdfioContentEndMarked(dd->st);
dd->in_table = false;
```

View File

@@ -1,7 +1,7 @@
//
// Simple markdown to PDF converter example for PDFio.
//
// Copyright © 2024-2025 by Michael R Sweet.
// Copyright © 2024 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@@ -122,9 +122,6 @@ typedef struct docdata_s // Document formatting data
// State for the current page
pdfio_stream_t *st; // Current page stream
double y; // Current position on page
const char *tag; // Current block tag
bool in_table, // Are we in a table?
in_row; // Are we in a table row?
docfont_t font; // Current font
double fsize; // Current font size
doccolor_t color; // Current color
@@ -292,8 +289,8 @@ main(int argc, // I - Number of command-line arguments
// Get the markdown file from the command-line...
if (argc < 2 || argc > 3)
{
fputs("Usage: md2pdf FILENAME.md [FILENAME.pdf]\n", stderr);
fputs(" md2pdf FILENAME.md >FILENAME.pdf\n", stderr);
fputs("Usage: md2pdf FILENANE.md [FILENAME.pdf]\n", stderr);
fputs(" md2pdf FILENANE.md >FILENAME.pdf\n", stderr);
return (1);
}
@@ -475,7 +472,6 @@ add_links(docdata_t *dd) // I - Document data
// Create the annotation object pointing to the action...
dict = pdfioDictCreate(dd->pdf);
pdfioDictSetName(dict, "Subtype", "Link");
pdfioDictSetNumber(dict, "F", 4); // Print flag
pdfioDictSetRect(dict, "Rect", &l->box);
border = pdfioArrayCreate(dd->pdf);
pdfioArrayAppendNumber(border, 0.0);
@@ -622,50 +618,6 @@ format_block(docdata_t *dd, // I - Document data
frag = frags + num_frags;
switch (mmdGetType(block))
{
case MMD_TYPE_HEADING_1 :
dd->tag = "H1";
break;
case MMD_TYPE_HEADING_2 :
dd->tag = "H2";
break;
case MMD_TYPE_HEADING_3 :
dd->tag = "H3";
break;
case MMD_TYPE_HEADING_4 :
dd->tag = "H4";
break;
case MMD_TYPE_HEADING_5 :
dd->tag = "H5";
break;
case MMD_TYPE_HEADING_6 :
dd->tag = "H6";
break;
case MMD_TYPE_TABLE_HEADER_CELL :
dd->tag = "TH";
break;
case MMD_TYPE_TABLE_BODY_CELL_LEFT :
case MMD_TYPE_TABLE_BODY_CELL_CENTER :
case MMD_TYPE_TABLE_BODY_CELL_RIGHT :
dd->tag = "TD";
break;
default :
dd->tag = "P";
break;
}
if (dd->st)
pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
// Loop through the block and render lines...
for (current = mmdGetFirstChild(block), x = left; current; current = next)
{
@@ -844,9 +796,6 @@ format_block(docdata_t *dd, // I - Document data
pdfioContentRestore(dd->st);
}
}
pdfioContentEndMarked(dd->st);
dd->tag = NULL;
}
@@ -886,9 +835,6 @@ format_code(docdata_t *dd, // I - Document data
pdfioContentFillAndStroke(dd->st, false);
// Start a code text block...
dd->tag = "P";
pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd->st);
pdfioContentTextMoveTo(dd->st, left, dd->y);
@@ -923,9 +869,6 @@ format_code(docdata_t *dd, // I - Document data
pdfioContentTextEnd(dd->st);
dd->y += lineheight;
pdfioContentEndMarked(dd->st);
dd->tag = NULL;
// Draw the bottom padding...
set_color(dd, DOCCOLOR_LTGRAY);
pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y - CODE_PADDING - (LINE_HEIGHT - 1.0) * SIZE_CODEBLOCK, right - left + 2.0 * CODE_PADDING, CODE_PADDING);
@@ -1201,17 +1144,8 @@ format_table(docdata_t *dd, // I - Document data
}
// Render each table row...
dd->in_table = true;
if (dd->st)
pdfioContentBeginMarked(dd->st, "Table", /*dict*/NULL);
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr);
pdfioContentEndMarked(dd->st);
dd->in_table = false;
}
@@ -1425,16 +1359,6 @@ new_page(docdata_t *dd) // I - Document data
// Close the current page...
if (dd->st)
{
if (dd->tag)
{
// Close current tag and any row or table...
pdfioContentEndMarked(dd->st);
if (dd->in_row)
pdfioContentEndMarked(dd->st);
if (dd->in_table)
pdfioContentEndMarked(dd->st);
}
pdfioStreamClose(dd->st);
add_links(dd);
}
@@ -1463,7 +1387,6 @@ new_page(docdata_t *dd) // I - Document data
dd->y = dd->art_box.y2;
// Add header/footer text
pdfioContentBeginMarked(dd->st, "Artifact", /*dict*/NULL);
set_color(dd, DOCCOLOR_GRAY);
set_font(dd, DOCFONT_REGULAR, SIZE_HEADFOOT);
@@ -1522,17 +1445,6 @@ new_page(docdata_t *dd) // I - Document data
pdfioContentTextShow(dd->st, UNICODE_VALUE, dd->heading);
pdfioContentTextEnd(dd->st);
}
pdfioContentEndMarked(dd->st);
if (dd->in_table)
pdfioContentBeginMarked(dd->st, "Table", /*dict*/NULL);
if (dd->in_row)
pdfioContentBeginMarked(dd->st, "TR", /*dict*/NULL);
if (dd->tag)
pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
}
@@ -1705,11 +1617,9 @@ render_row(docdata_t *dd, // I - Document data
// Start a new page as needed...
if (!dd->st)
new_page(dd);
else if ((dd->y - row->height) < dd->art_box.y1)
new_page(dd);
dd->in_row = true;
pdfioContentBeginMarked(dd->st, "TR", /*dict*/NULL);
if ((dd->y - row->height) < dd->art_box.y1)
new_page(dd);
if (mmdGetType(row->cells[0]) == MMD_TYPE_TABLE_HEADER_CELL)
{
@@ -1741,9 +1651,6 @@ render_row(docdata_t *dd, // I - Document data
}
dd->y = row_y - row->height;
pdfioContentEndMarked(dd->st);
dd->in_row = false;
}

View File

@@ -3,7 +3,7 @@
//
// https://www.msweet.org/mmd
//
// Copyright © 2017-2025 by Michael R Sweet.
// Copyright © 2017-2024 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@@ -166,7 +166,7 @@ mmdCopyAllText(mmd_t *node) // I - Parent node
char *all = NULL, // String buffer
*allptr = NULL, // Pointer into string buffer
*temp; // Temporary pointer
size_t allsize = 0, // Size of "all" buffer
size_t allsize = 1, // Size of "all" buffer
textlen; // Length of "text" string
mmd_t *current, // Current node
*next; // Next node
@@ -179,8 +179,6 @@ mmdCopyAllText(mmd_t *node) // I - Parent node
if (current->text)
{
// Append this node's text to the string...
long alloff = allptr - all; // Offset within current buffer
textlen = strlen(current->text);
allsize += textlen + (size_t)current->whitespace;
temp = realloc(all, allsize);
@@ -191,8 +189,8 @@ mmdCopyAllText(mmd_t *node) // I - Parent node
return (NULL);
}
allptr = temp + (allptr - all);
all = temp;
allptr = all + alloff;
if (current->whitespace)
*allptr++ = ' ';
@@ -1061,8 +1059,6 @@ mmdLoadIO(mmd_t *root, // I - Root node for document or `NULL` for a new d
break;
else if (line[0] == '>' && *ptr == '>')
memmove(ptr, ptr + 1, strlen(ptr));
DEBUG2_printf(" line=\"%s\"\n", line);
}
mmd_parse_inline(&doc, block, lineptr);
@@ -1497,7 +1493,7 @@ mmd_parse_inline(_mmd_doc_t *doc, // I - Document
for (text = NULL, type = MMD_TYPE_NORMAL_TEXT; *lineptr; lineptr ++)
{
DEBUG2_printf("mmd_parse_inline: lineptr=%p(\"%s\"), type=%d, text=%p, whitespace=%d\n", lineptr, lineptr, type, text, whitespace);
DEBUG2_printf("mmd_parse_inline: lineptr=%p(\"%32.32s...\"), type=%d, text=%p, whitespace=%d\n", lineptr, lineptr, type, text, whitespace);
if (isspace(*lineptr & 255) && type != MMD_TYPE_CODE_TEXT)
{
@@ -2094,8 +2090,6 @@ mmd_read_buffer(_mmd_filebuf_t *file) // I - File buffer
if (file->bufptr && file->bufptr > file->buffer)
{
// Discard previous characters in the buffer.
DEBUG2_printf("mmd_read_buffer: before buffer=\"%s\"\n", file->bufptr);
memmove(file->buffer, file->bufptr, file->bufend - file->bufptr);
file->bufend -= (file->bufptr - file->buffer);
}
@@ -2105,13 +2099,11 @@ mmd_read_buffer(_mmd_filebuf_t *file) // I - File buffer
file->bufend = file->buffer;
}
if ((bytes = (file->cb)(file->cbdata, file->bufend, sizeof(file->buffer) - (size_t)(file->bufend - file->buffer) - 1)) > 0)
if ((bytes = (file->cb)(file->cbdata, file->bufend, sizeof(file->buffer) - (size_t)(file->bufend - file->buffer - 1))) > 0)
file->bufend += bytes;
*(file->bufend) = '\0';
file->bufptr = file->buffer;
DEBUG2_printf("mmd_read_buffer: after buffer=\"%s\"\n", file->buffer);
}
@@ -2169,8 +2161,6 @@ mmd_read_line(_mmd_filebuf_t *file, // I - File buffer
else if (!strchr(file->bufptr, '\n'))
mmd_read_buffer(file);
DEBUG2_printf("mmd_read_line: Returning \"%s\"\n", line);
return (line);
}

View File

@@ -1417,4 +1417,4 @@ puts_utf16(const char *s) // I - Hex string
put_utf8(ch);
}
}
}

View File

@@ -8,8 +8,8 @@
//
// Usage:
//
// ./pdfiomerge [-o OUTPUT.pdf] INPUT.pdf [... INPUT.pdf]
// ./pdfiomerge INPUT.pdf [... INPUT.pdf] >OUTPUT.pdf
// ./pdfmerge [-o OUTPUT.pdf] INPUT.pdf [... INPUT.pdf]
// ./pdfmerge INPUT.pdf [... INPUT.pdf] >OUTPUT.pdf
//
#include <pdfio.h>
@@ -47,7 +47,7 @@ main(int argc, // I - Number of command-line arguments
}
else if (!strncmp(argv[i], "--", 2))
{
fprintf(stderr, "pdfiomerge: Unknown option '%s'.\n", argv[i]);
fprintf(stderr, "pdfmerge: Unknown option '%s'.\n", argv[i]);
return (usage(stderr));
}
else if (argv[i][0] == '-')
@@ -59,14 +59,14 @@ main(int argc, // I - Number of command-line arguments
case 'o' : // -o OUTPUT.pdf
if (outpdf)
{
fputs("pdfiomerge: Only one output file can be specified.\n", stderr);
fputs("pdfmerge: Only one output file can be specified.\n", stderr);
return (usage(stderr));
}
i ++;
if (i >= argc)
{
fputs("pdfiomerge: Missing output filename after '-o'.\n", stderr);
fputs("pdfmerge: Missing output filename after '-o'.\n", stderr);
return (usage(stderr));
}
@@ -75,7 +75,7 @@ main(int argc, // I - Number of command-line arguments
break;
default :
fprintf(stderr, "pdfiomerge: Unknown option '-%c'.\n", *opt);
fprintf(stderr, "pdfmerge: Unknown option '-%c'.\n", *opt);
return (usage(stderr));
}
}

View File

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

View File

@@ -262,7 +262,7 @@ pdfioArrayCopy(pdfio_file_t *pdf, // I - PDF file
vdst; // Current destination value
PDFIO_DEBUG("pdfioArrayCopy(pdf=%p, a=%p(%p))\n", (void *)pdf, (void *)a, a ? (void *)a->pdf : NULL);
PDFIO_DEBUG("pdfioArrayCopy(pdf=%p, a=%p(%p))\n", pdf, a, a ? a->pdf : NULL);
// Create the new array...
if ((na = pdfioArrayCreate(pdf)) == NULL)
@@ -606,7 +606,7 @@ _pdfioArrayRead(pdfio_file_t *pdf, // I - PDF file
_pdfio_value_t value; // Value
PDFIO_DEBUG("_pdfioArrayRead(pdf=%p, tb=%p)\n", (void *)pdf, (void *)tb);
PDFIO_DEBUG("_pdfioArrayRead(pdf=%p, tb=%p)\n", pdf, tb);
// Create an array...
if ((array = pdfioArrayCreate(pdf)) == NULL)
@@ -640,8 +640,6 @@ _pdfioArrayRead(pdfio_file_t *pdf, // I - PDF file
//
// 'pdfioArrayRemove()' - Remove an array entry.
//
// @since PDFio v1.4@
//
bool // O - `true` on success, `false` otherwise
pdfioArrayRemove(pdfio_array_t *a, // I - Array

View File

@@ -1,532 +0,0 @@
/* CGATS001Compat-v2-micro.icc */
static unsigned char CGATS001Compat_v2_micro_icc[] = {
0,0,33,16,65,68,66,69,2,16,0,0,115,99,110,114,
67,77,89,75,76,97,98,32,7,230,0,12,0,7,0,22,
0,16,0,42,97,99,115,112,77,83,70,84,0,0,0,0,
115,97,119,115,99,116,114,108,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,246,214,0,1,0,0,0,0,211,45,
104,97,110,100,195,103,209,209,26,217,105,182,62,57,156,48,
22,179,165,88,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,4,100,101,115,99,0,0,0,180,0,0,0,95,
99,112,114,116,0,0,0,208,0,0,0,12,119,116,112,116,
0,0,0,220,0,0,0,20,65,50,66,48,0,0,0,240,
0,0,32,32,100,101,115,99,0,0,0,0,0,0,0,5,
117,67,77,89,0,0,0,0,0,0,0,0,0,0,0,0,
116,101,120,116,0,0,0,0,67,67,48,0,88,89,90,32,
0,0,0,0,0,0,246,214,0,1,0,0,0,0,211,45,
109,102,116,50,0,0,0,0,4,3,6,0,0,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
0,48,0,2,0,0,10,35,16,0,22,155,28,150,35,8,
41,37,47,68,53,83,59,90,65,90,71,78,77,74,83,48,
89,25,94,245,100,188,106,133,112,43,117,193,123,79,128,187,
134,23,139,107,144,166,149,206,154,244,160,21,165,30,170,40,
175,51,180,64,185,71,190,81,195,91,200,103,205,100,210,85,
215,65,220,33,224,252,229,190,234,87,238,218,243,138,248,23,
252,104,255,255,0,0,8,214,13,206,19,98,24,129,30,6,
35,77,40,160,46,0,51,86,56,193,62,41,67,165,73,37,
78,162,84,51,89,175,95,46,100,173,106,10,111,107,116,191,
121,244,127,36,132,82,137,98,142,111,147,127,152,147,157,151,
162,172,167,211,173,14,178,88,183,186,189,52,194,199,200,90,
205,244,211,154,217,72,223,1,228,146,234,19,239,215,245,132,
251,7,255,255,0,0,9,30,14,44,19,200,24,222,30,99,
35,150,40,200,45,246,51,35,56,84,61,138,66,209,72,33,
77,126,82,234,88,89,93,211,99,74,104,190,110,47,115,148,
120,237,126,59,131,126,136,180,141,231,147,29,152,90,157,169,
163,18,168,158,174,79,180,41,186,39,192,69,198,114,204,164,
210,199,216,201,222,161,228,73,233,160,238,170,243,244,248,186,
252,225,255,255,0,0,8,135,13,57,18,115,23,60,28,123,
33,106,38,94,43,92,48,99,53,110,58,133,63,163,68,202,
73,244,79,35,84,77,89,109,94,139,99,158,104,170,109,176,
114,172,119,156,124,135,129,112,134,74,139,35,143,254,148,223,
153,201,158,194,163,209,168,251,174,67,179,163,185,36,190,202,
196,145,202,125,208,133,214,166,220,240,227,93,234,118,241,193,
249,40,255,255,255,0,128,0,128,0,214,110,127,181,126,251,
173,86,127,150,126,88,131,53,127,186,126,83,86,78,128,50,
126,192,31,100,129,254,128,28,251,120,125,171,146,104,211,247,
125,155,142,161,171,46,125,194,139,106,129,32,126,37,136,221,
84,57,126,196,134,230,28,170,128,62,134,99,248,103,123,237,
165,11,209,76,123,249,158,148,168,209,124,68,152,192,127,22,
124,213,147,218,82,110,125,139,143,116,26,73,126,145,140,106,
245,211,122,201,183,251,206,211,122,205,174,205,166,160,123,35,
166,133,125,42,123,200,159,52,80,217,124,141,151,243,24,82,
125,10,144,4,243,199,122,9,203,97,204,207,121,247,191,95,
164,205,122,74,180,169,123,179,123,1,171,70,79,144,123,201,
163,159,22,200,123,191,143,103,242,42,121,140,223,132,203,50,
121,98,208,125,163,73,121,169,195,108,122,115,122,107,184,86,
78,150,123,56,174,96,21,158,122,200,142,157,227,233,142,168,
125,57,191,208,140,54,124,173,154,204,138,30,124,141,116,50,
136,124,124,247,74,84,135,121,125,199,20,34,137,177,127,236,
224,239,140,172,141,230,189,193,138,73,138,227,152,241,136,91,
136,116,114,87,134,238,134,171,72,129,134,18,133,143,18,45,
135,202,133,165,222,108,139,13,159,8,187,88,136,200,153,179,
150,192,134,245,148,251,112,129,133,173,145,24,70,249,132,229,
142,34,16,97,134,27,137,235,220,58,137,245,176,93,185,57,
135,184,168,203,148,204,133,239,161,238,110,212,132,170,155,243,
69,169,131,235,151,169,15,9,132,165,138,43,218,113,137,45,
194,46,183,137,134,242,184,87,147,63,133,43,175,95,109,144,
131,243,167,166,68,161,131,41,161,166,14,7,131,135,137,124,
217,12,136,152,212,229,182,53,134,99,200,164,145,250,132,152,
189,153,108,133,131,103,180,155,67,209,130,165,170,33,13,68,
130,183,136,248,201,213,157,235,123,46,169,121,153,123,122,234,
136,53,149,117,123,19,101,12,146,14,123,193,62,13,143,191,
124,214,9,84,144,204,127,187,199,84,156,73,138,107,167,205,
151,198,136,7,134,185,147,217,134,42,99,150,144,153,132,246,
60,167,142,98,132,135,8,113,142,126,132,36,197,113,154,202,
153,237,165,235,150,98,149,123,132,247,146,119,145,165,98,4,
143,82,142,167,59,93,141,42,140,19,7,182,140,158,133,55,
195,166,153,193,169,229,164,50,149,94,163,134,131,66,145,135,
157,217,96,149,142,92,153,26,58,81,140,51,150,79,7,25,
139,41,132,204,194,42,153,10,186,48,162,214,148,166,177,236,
129,253,144,210,170,123,95,138,141,175,164,116,57,139,139,110,
159,13,6,174,138,21,132,132,192,255,152,123,203,106,161,198,
148,25,193,44,128,245,144,72,184,9,94,179,141,45,177,103,
56,235,138,244,165,100,6,89,137,77,132,75,177,37,173,245,
122,2,147,243,167,169,121,209,117,242,161,206,122,23,85,235,
156,180,122,225,49,88,150,201,124,2,0,239,149,92,127,195,
175,57,172,141,135,237,146,202,166,25,133,179,116,224,160,67,
132,66,84,210,155,60,131,120,48,93,152,11,131,193,0,226,
147,96,128,133,173,202,171,58,150,19,145,79,164,217,146,68,
115,118,159,2,143,29,83,154,154,5,140,217,47,124,150,201,
140,54,0,206,145,182,128,139,172,145,170,52,164,133,144,19,
163,219,159,13,114,58,158,5,154,89,82,143,152,241,150,198,
46,202,149,168,148,235,0,217,144,85,128,147,171,106,169,130,
179,137,143,32,163,20,172,85,113,80,157,63,162,160,81,202,
152,62,161,248,46,73,148,212,155,139,0,219,143,72,128,148,
170,119,169,1,195,84,142,87,162,131,186,91,112,151,156,179,
178,242,81,58,151,186,174,21,45,236,148,82,159,13,0,222,
142,134,128,150,154,49,190,221,121,79,127,198,182,195,121,6,
100,136,175,54,121,74,71,42,168,146,122,23,36,45,165,99,
123,14,0,0,143,153,128,0,152,249,189,121,134,22,127,13,
181,72,132,75,99,211,173,165,130,235,70,115,166,244,130,111,
35,202,163,124,130,239,0,0,142,213,128,0,152,46,188,21,
146,252,126,42,179,238,143,148,98,240,172,64,140,239,69,182,
165,143,139,90,35,118,161,226,138,239,0,0,142,33,128,0,
151,95,187,20,156,183,125,105,178,222,152,248,98,53,171,44,
148,44,69,34,164,102,145,119,35,60,160,141,143,228,0,0,
141,150,128,0,150,186,186,65,173,194,124,235,177,250,167,108,
97,205,170,70,162,133,68,210,163,131,159,209,35,33,159,106,
150,67,0,0,141,57,128,0,150,10,185,176,188,68,124,138,
177,69,180,40,97,126,169,128,174,82,68,159,162,198,170,52,
35,38,158,179,151,196,0,0,140,230,128,0,132,180,208,159,
120,243,108,190,198,205,120,107,83,203,189,201,120,144,56,144,
181,241,121,63,22,242,178,158,122,81,0,0,137,249,128,0,
132,84,206,246,132,213,108,102,197,80,130,218,83,105,188,24,
129,168,56,75,180,0,129,93,23,73,176,8,130,10,0,0,
138,37,128,0,132,67,205,78,144,147,108,56,195,164,141,107,
83,48,186,79,139,41,56,52,178,35,138,58,23,180,173,196,
137,41,0,0,138,73,128,0,132,35,203,251,156,155,108,55,
194,41,152,56,83,60,184,196,149,21,56,85,176,133,148,4,
24,42,171,234,144,154,0,0,138,101,128,0,131,240,202,242,
168,242,108,66,193,0,163,54,83,110,183,140,159,100,56,150,
175,80,157,234,24,158,170,120,144,165,0,0,138,121,128,0,
131,190,202,18,181,197,108,88,192,13,174,136,83,181,182,138,
170,24,56,250,174,76,165,33,25,38,169,99,145,1,0,0,
138,136,128,0,235,21,120,95,117,172,198,143,121,103,118,146,
160,155,122,106,119,154,120,244,123,117,120,218,78,61,124,157,
122,46,24,103,126,52,123,43,231,220,117,150,135,222,195,241,
118,230,133,232,158,88,120,46,132,101,118,244,121,124,131,68,
76,100,122,195,129,102,22,11,123,166,130,96,228,245,115,130,
154,56,193,46,116,236,149,151,155,232,118,93,145,116,116,232,
119,221,141,248,74,174,121,54,138,229,19,252,121,133,135,196,
226,139,114,5,172,159,190,208,115,112,165,140,153,177,116,238,
158,247,114,251,118,134,153,19,73,38,119,231,148,52,18,94,
119,220,139,241,224,194,113,11,191,52,189,12,114,105,181,200,
151,244,115,224,172,209,113,127,117,135,164,211,71,234,118,225,
158,108,17,36,118,168,139,151,223,129,112,120,210,33,187,195,
113,192,198,94,150,146,115,32,187,38,112,68,116,200,177,102,
70,235,118,28,168,223,16,59,117,202,138,249,209,115,134,135,
115,123,177,87,133,101,116,211,143,52,132,136,118,40,106,212,
131,237,119,166,66,203,131,210,121,44,13,68,133,161,122,166,
207,74,132,21,132,44,175,136,131,38,130,252,141,102,130,108,
130,15,105,23,129,246,129,111,65,44,129,242,129,3,11,242,
131,47,128,187,204,230,130,32,148,250,173,11,129,68,145,118,
139,42,128,171,142,60,103,60,128,104,139,143,63,171,128,112,
137,123,10,160,129,38,133,169,202,204,128,181,165,229,170,253,
127,222,160,68,137,59,127,80,154,224,101,154,127,25,150,30,
62,106,127,39,146,206,9,181,127,147,134,144,201,66,127,194,
183,38,169,111,126,232,175,109,135,176,126,82,167,231,100,77,
126,40,161,100,61,104,126,40,156,138,9,4,126,105,134,24,
200,52,127,42,201,23,168,66,126,72,191,65,134,106,125,151,
181,160,99,54,125,111,173,200,60,152,125,113,164,221,8,120,
125,143,133,186,184,173,149,106,113,228,156,34,146,61,115,98,
125,114,143,136,116,221,92,54,141,74,118,127,54,161,140,45,
120,8,3,238,139,88,123,49,182,255,147,72,129,49,154,137,
144,64,128,123,123,227,141,162,127,240,90,199,139,126,127,190,
53,89,138,93,127,196,3,128,136,228,128,74,181,64,145,117,
144,98,152,169,142,132,141,169,122,46,139,240,139,55,89,77,
137,236,137,71,52,47,136,204,136,38,3,22,134,234,130,22,
179,141,144,32,160,3,151,4,141,51,155,112,120,129,138,173,
151,29,87,228,136,172,147,114,51,37,135,135,145,82,2,193,
133,95,129,221,178,73,143,62,175,217,149,185,140,83,169,123,
119,61,137,196,163,94,86,209,135,201,158,101,50,96,134,132,
153,234,2,137,132,59,129,182,177,102,142,167,192,110,148,187,
139,188,184,74,118,48,137,28,176,117,85,236,135,30,170,208,
49,180,133,217,160,46,2,88,131,104,129,150,161,39,165,31,
112,232,135,104,160,39,114,94,107,178,155,186,115,225,77,78,
151,243,117,130,41,135,150,141,118,177,0,66,137,171,126,52,
160,0,163,78,126,58,134,90,158,94,125,202,106,159,153,235,
126,68,76,76,150,41,126,114,40,187,148,150,126,116,0,60,
135,218,127,249,158,179,161,163,140,195,132,230,156,194,138,139,
105,69,152,84,136,161,75,40,148,163,135,100,39,242,146,245,
134,224,0,50,134,74,128,34,157,132,160,84,154,226,131,173,
155,126,151,25,104,13,151,13,147,166,74,49,147,72,145,0,
39,88,145,123,143,118,0,46,133,35,128,31,156,138,159,124,
169,118,130,195,154,160,164,33,103,23,150,32,159,51,73,88,
146,97,155,208,38,210,144,100,150,43,0,40,132,62,128,27,
155,211,158,242,184,169,130,0,154,13,177,217,102,77,149,124,
171,165,72,175,145,184,167,171,38,95,143,176,153,237,0,36,
131,152,128,24,139,20,181,218,112,19,115,151,175,83,113,97,
90,95,169,85,114,209,62,89,164,67,116,78,27,220,162,240,
117,20,0,0,132,76,128,0,138,120,180,61,125,106,115,25,
173,150,124,255,89,217,167,107,124,81,61,228,162,62,124,151,
27,203,160,109,125,6,0,0,131,187,128,0,137,192,178,136,
137,145,114,53,171,233,135,226,88,255,165,185,134,144,61,56,
160,141,133,174,27,150,158,104,133,23,0,0,131,37,128,0,
136,247,177,65,150,121,113,106,170,160,145,137,88,50,164,101,
144,140,60,162,159,30,142,229,27,110,156,173,140,81,0,0,
130,194,128,0,136,101,176,88,163,151,112,222,169,174,159,42,
87,167,163,100,155,105,60,52,158,16,153,106,27,92,155,60,
144,208,0,0,130,140,128,0,135,225,175,208,177,149,112,130,
169,4,171,225,87,60,162,144,167,47,59,221,157,49,163,199,
27,68,154,81,146,112,0,0,130,90,128,0,118,47,199,165,
111,81,96,137,191,214,112,85,73,93,184,132,113,146,47,37,
178,156,114,188,14,114,176,12,115,215,0,0,129,66,128,0,
118,37,198,9,123,103,96,145,189,252,122,224,73,95,182,83,
122,140,47,79,176,27,122,242,15,16,173,6,123,149,0,0,
129,65,128,0,118,26,196,25,134,225,96,81,188,12,133,19,
73,32,180,78,131,219,47,67,173,249,131,127,15,152,170,90,
131,15,0,0,129,64,128,0,117,232,194,153,146,128,96,44,
186,112,143,187,72,249,178,157,141,124,47,72,172,34,141,8,
16,17,168,31,136,88,0,0,129,63,128,0,117,180,193,153,
158,127,96,36,185,65,154,198,72,250,177,80,152,1,47,90,
170,197,151,16,16,120,166,98,139,34,0,0,129,63,128,0,
117,138,192,236,171,6,96,44,184,93,166,88,73,12,176,73,
163,22,47,127,169,175,158,184,16,201,165,41,139,89,0,0,
129,62,128,0,215,58,112,125,107,98,182,48,114,183,110,9,
147,81,116,191,112,146,110,79,118,168,115,18,69,242,120,110,
117,99,17,41,122,4,118,21,212,37,109,25,125,61,179,174,
111,175,125,19,145,41,114,6,125,27,108,110,116,58,125,82,
68,67,118,17,125,118,15,115,119,100,124,211,209,76,106,99,
143,18,176,232,109,33,140,81,142,189,111,175,137,216,106,111,
114,31,135,215,66,173,115,252,133,236,14,12,117,65,131,106,
206,240,104,112,160,225,174,148,107,62,155,216,140,130,109,225,
150,255,104,143,112,110,146,160,65,64,114,73,142,92,12,238,
115,154,136,44,205,74,103,27,178,184,172,233,105,229,171,138,
138,211,108,132,164,100,103,24,111,33,157,249,64,30,112,232,
153,0,12,32,114,96,136,51,204,67,102,85,196,179,171,201,
105,11,187,103,137,134,107,139,178,19,101,232,110,39,169,242,
63,37,113,29,163,2,11,134,113,150,135,202,191,51,125,253,
105,204,162,88,126,40,108,203,130,244,126,117,111,124,96,224,
126,227,114,20,58,181,127,161,116,87,6,250,129,135,117,232,
189,59,122,243,122,101,160,121,123,114,122,237,129,38,123,241,
123,66,95,70,124,136,123,210,57,87,125,61,124,104,6,56,
126,240,124,161,186,231,120,104,138,147,158,7,121,10,136,216,
126,247,121,180,135,50,93,119,122,128,133,202,55,236,123,44,
132,147,5,122,125,75,129,223,184,229,118,148,155,6,156,7,
119,69,151,69,125,15,119,255,147,122,91,227,120,220,144,16,
54,189,121,122,141,190,4,240,123,230,131,75,183,122,117,78,
171,160,154,140,117,255,165,231,123,150,118,180,160,18,90,158,
119,159,154,248,53,206,120,29,151,54,4,139,123,11,131,18,
182,151,116,140,188,154,153,124,117,45,180,249,122,105,117,198,
173,42,89,148,118,175,166,195,52,247,119,27,159,91,4,58,
122,75,130,219,168,10,140,102,104,152,142,157,138,129,107,167,
114,84,137,23,110,98,83,5,136,13,112,248,46,178,136,50,
114,232,0,0,134,1,119,195,166,152,137,165,119,142,140,252,
136,21,120,113,112,187,134,199,121,68,81,165,133,209,122,43,
45,147,133,199,122,111,0,0,131,203,125,115,164,228,135,58,
134,91,139,30,133,208,133,102,111,24,132,156,132,87,80,93,
131,190,131,134,44,163,131,149,130,248,0,0,129,242,128,0,
163,51,133,129,149,157,137,135,132,33,146,220,109,118,130,247,
143,243,78,252,130,37,141,109,43,168,129,222,139,252,0,0,
128,80,128,0,162,3,132,83,164,223,136,69,130,249,160,109,
108,52,129,194,155,194,77,229,128,243,151,242,42,242,128,117,
148,112,0,0,128,0,128,0,161,66,131,152,180,173,135,81,
130,59,174,155,107,41,128,225,168,60,77,1,128,10,163,180,
42,74,127,120,154,175,0,0,128,0,128,0,145,188,155,172,
103,193,122,194,152,25,106,174,97,34,149,28,109,90,68,88,
146,185,111,205,33,58,147,6,113,3,0,0,128,158,125,23,
144,178,153,85,117,117,121,161,149,241,118,113,96,7,146,235,
119,201,67,104,144,128,120,192,32,163,144,90,120,208,0,0,
128,83,127,160,143,100,151,24,131,16,120,32,147,209,130,146,
94,175,144,218,130,3,66,85,142,130,129,188,32,1,142,10,
128,235,0,0,128,0,128,0,142,45,149,108,144,194,118,226,
146,54,142,170,93,120,143,61,140,135,65,117,140,210,138,222,
31,136,140,18,137,181,0,0,128,0,128,0,141,62,148,80,
158,204,117,254,145,26,155,76,92,129,142,10,151,180,64,146,
139,158,149,70,31,15,138,141,145,227,0,0,128,0,128,0,
140,159,147,161,173,59,117,64,144,98,168,119,91,182,141,51,
163,160,63,227,138,184,160,184,30,155,137,127,148,146,0,0,
128,0,128,0,124,171,172,10,102,190,103,126,167,39,105,111,
80,11,162,201,107,245,53,57,159,120,110,24,19,165,158,208,
111,20,0,0,128,0,128,0,123,249,170,24,116,224,102,230,
165,24,117,140,79,132,160,128,117,94,52,226,156,255,118,88,
19,187,155,193,119,9,0,0,128,0,128,0,123,42,167,228,
127,253,101,234,162,244,127,85,78,167,158,94,127,12,52,67,
154,215,126,238,19,159,153,39,127,38,0,0,128,0,128,0,
122,87,166,68,140,182,101,22,161,89,139,59,77,209,156,183,
137,52,51,180,153,17,136,91,19,135,150,246,134,122,0,0,
128,0,128,0,121,194,165,30,152,238,100,130,160,44,150,73,
77,54,155,119,147,192,51,58,151,189,146,136,19,131,149,48,
139,58,0,0,128,0,128,0,121,80,164,119,166,54,100,51,
159,99,162,165,76,201,154,118,159,46,50,220,150,162,156,195,
19,98,147,245,141,27,0,0,128,0,128,0,104,127,189,181,
101,120,84,142,183,253,103,201,62,206,178,149,106,4,37,57,
175,32,107,133,7,201,168,185,110,103,0,0,128,0,128,0,
104,19,188,17,113,56,84,117,181,220,113,249,62,221,175,253,
114,239,37,150,172,20,115,158,8,71,165,174,118,13,0,0,
128,0,128,0,103,206,185,191,124,128,84,14,179,133,124,35,
62,146,173,145,124,7,37,152,169,115,124,23,8,149,163,10,
125,3,0,0,128,0,128,0,103,132,183,243,135,237,83,215,
177,160,134,186,62,83,171,151,133,157,37,151,167,69,133,155,
8,210,160,225,134,24,0,0,128,0,128,0,103,71,182,193,
147,197,83,203,176,53,145,186,62,65,170,12,143,228,37,150,
165,157,143,124,9,4,159,47,134,25,0,0,128,0,128,0,
103,34,182,5,159,118,83,218,175,42,156,247,62,66,168,216,
154,228,37,162,164,81,151,207,9,28,157,237,134,41,0,0,
128,0,128,0,195,134,104,39,97,50,165,143,107,98,101,100,
133,177,110,87,105,86,99,107,113,26,109,23,61,117,115,78,
112,105,10,197,118,146,113,155,192,120,99,196,114,159,163,37,
103,127,116,32,131,159,106,221,117,164,97,161,109,247,119,42,
59,237,112,35,120,108,9,208,115,227,120,197,189,150,96,56,
131,182,160,101,100,60,130,212,129,66,103,227,130,4,95,178,
107,69,129,80,58,117,109,94,128,220,8,252,114,54,127,181,
187,44,93,116,149,0,158,28,97,167,145,220,127,29,101,119,
142,191,93,247,105,0,139,222,57,48,106,248,136,228,8,98,
114,207,133,15,185,130,91,150,166,49,156,129,95,216,160,239,
125,137,99,178,155,159,92,152,103,80,150,226,56,49,105,27,
147,108,7,231,114,249,133,88,184,132,90,105,183,86,155,115,
94,161,175,238,124,98,98,101,168,131,91,140,105,1,162,44,
55,84,103,155,156,250,7,143,115,57,133,29,173,93,116,242,
96,48,147,55,118,74,100,152,118,92,119,176,104,140,86,142,
121,30,108,57,50,50,122,128,111,45,2,87,126,109,114,86,
171,85,112,240,112,28,145,91,114,194,114,35,116,164,116,109,
115,251,85,28,118,12,117,186,49,17,119,53,119,0,2,43,
125,195,121,110,168,240,109,150,128,2,142,230,111,169,127,232,
114,129,113,144,127,187,83,92,115,109,127,135,47,194,116,98,
127,74,1,226,125,94,127,32,166,228,106,254,143,238,140,233,
109,54,141,221,112,164,111,63,139,156,81,229,113,51,137,125,
46,184,113,233,136,69,1,188,125,70,129,22,165,119,105,58,
159,231,139,118,107,126,155,238,111,59,109,141,151,183,80,175,
111,144,148,16,45,231,112,10,145,123,1,153,125,77,129,20,
164,153,104,24,176,2,138,114,106,82,170,42,110,35,111,42,
164,16,79,186,110,75,159,42,45,29,110,151,153,133,1,123,
125,127,129,0,151,185,130,155,95,107,128,155,130,26,99,200,
102,131,129,250,103,171,73,25,130,36,107,48,37,224,131,72,
109,106,0,0,128,15,119,32,150,37,126,232,109,252,126,233,
126,222,112,71,100,238,126,239,114,85,71,211,127,49,116,50,
36,254,127,224,117,40,0,0,128,0,125,1,148,89,123,191,
124,214,124,252,123,247,125,43,99,88,124,49,125,116,70,157,
124,147,125,171,36,61,124,241,125,162,0,0,128,0,128,0,
146,160,121,84,139,48,123,96,121,170,138,25,97,182,121,248,
136,132,69,80,122,100,134,203,35,88,122,135,134,48,0,0,
128,0,128,0,145,107,119,175,153,210,122,36,120,16,150,250,
96,132,120,91,147,207,68,71,120,200,145,64,34,188,120,174,
142,195,0,0,128,0,128,0,144,162,120,93,168,186,121,57,
120,129,164,90,95,144,120,148,159,155,67,117,120,204,156,88,
34,21,119,83,148,183,0,0,128,0,128,0,130,198,145,99,
94,162,109,209,143,77,98,193,86,12,141,196,102,123,58,184,
140,221,105,176,24,115,141,200,107,28,0,0,128,0,124,73,
129,132,142,31,107,235,108,146,140,92,110,64,84,240,138,218,
113,211,57,230,137,229,115,138,24,36,138,59,114,239,0,0,
128,0,127,132,128,22,139,40,121,37,107,6,137,153,122,194,
83,165,136,48,123,82,56,243,135,70,123,12,23,189,135,58,
123,75,0,0,128,0,128,0,126,190,136,215,135,50,105,197,
135,98,134,150,82,127,133,248,133,151,56,76,132,242,133,17,
23,130,132,161,132,185,0,0,128,0,128,0,125,190,135,83,
147,232,104,226,133,228,145,251,81,131,132,98,143,208,55,90,
131,82,142,43,23,27,130,174,140,195,0,0,128,0,128,0,
125,14,134,79,161,162,104,29,132,220,158,145,80,187,131,56,
154,254,54,173,130,12,153,42,22,191,129,62,143,48,0,0,
128,0,128,0,110,138,161,103,93,113,91,64,158,36,97,61,
69,98,155,115,100,180,43,134,154,24,103,87,11,238,152,5,
105,90,0,0,128,0,127,174,109,133,158,164,105,164,90,112,
155,103,107,227,68,195,152,129,109,252,43,62,150,221,111,137,
12,25,148,105,113,67,0,0,128,0,128,0,108,132,155,200,
117,179,89,77,152,172,118,164,67,211,149,207,119,119,42,162,
148,24,120,5,12,19,145,67,121,90,0,0,128,0,128,0,
107,134,153,143,129,221,88,92,150,130,129,173,66,235,147,154,
129,73,42,24,145,180,129,15,12,0,142,157,128,215,0,0,
128,0,128,0,106,209,152,11,143,26,87,176,149,0,141,197,
66,62,146,3,140,0,41,140,143,253,139,52,12,1,140,140,
133,216,0,0,128,0,128,0,106,74,151,18,154,199,87,83,
147,243,152,208,65,214,144,186,150,118,41,61,142,132,149,10,
11,233,139,8,136,14,0,0,128,0,128,0,90,217,179,10,
91,159,72,146,175,35,94,239,52,17,171,191,97,242,26,122,
171,135,99,103,2,147,158,4,105,195,0,0,128,0,128,0,
89,242,176,188,102,234,72,22,172,122,104,233,51,223,168,163,
106,202,26,208,167,186,107,134,3,13,154,120,113,121,0,0,
128,0,128,0,89,104,173,222,113,237,71,119,169,158,114,221,
51,113,165,180,115,185,26,205,164,114,115,225,3,91,151,84,
119,101,0,0,128,0,128,0,88,225,171,136,125,19,71,16,
167,63,125,46,51,16,163,58,125,29,26,204,161,154,125,2,
3,150,148,166,126,188,0,0,128,0,128,0,88,127,169,250,
136,100,70,230,165,137,135,210,50,233,161,96,135,19,26,190,
159,136,135,59,3,199,146,155,130,61,0,0,128,0,128,0,
88,66,168,239,147,235,70,221,164,67,146,236,50,224,159,237,
145,204,26,206,157,221,143,133,3,222,145,7,130,157,0,0,
128,0,128,0,176,156,94,195,87,72,149,115,98,233,92,217,
120,99,102,205,98,34,88,182,106,104,103,28,53,1,108,159,
107,102,5,152,118,139,109,251,173,120,88,199,104,44,147,0,
93,173,107,60,118,78,98,35,110,48,86,244,102,42,113,1,
51,155,104,36,115,88,5,62,119,36,117,123,170,129,83,218,
120,230,144,69,89,66,121,155,116,3,94,37,122,79,85,27,
98,129,123,12,50,72,100,77,123,164,4,235,119,176,124,186,
167,244,79,239,137,125,142,8,85,186,136,49,114,1,90,231,
134,220,83,144,95,120,133,94,49,50,97,23,132,122,4,171,
120,27,130,105,166,29,76,244,153,245,140,119,83,4,150,99,
112,161,88,98,146,223,82,98,93,18,143,209,48,103,94,148,
141,222,4,128,120,101,131,11,165,1,75,27,170,73,139,111,
81,61,164,132,111,168,86,158,159,0,81,141,91,86,154,125,
47,181,92,180,151,6,4,90,120,165,130,241,156,106,106,192,
86,220,132,107,109,76,92,113,105,223,111,205,97,148,76,63,
114,46,102,77,41,113,115,222,105,208,0,133,127,32,112,194,
154,6,101,52,102,67,130,120,104,112,105,168,104,51,107,92,
108,201,74,235,109,253,111,166,40,136,111,123,113,155,0,121,
127,52,119,248,151,123,96,136,117,195,127,250,100,52,119,22,
102,27,103,124,120,55,73,62,106,97,121,62,39,94,107,182,
121,207,0,101,127,85,125,231,149,85,92,216,133,116,125,254,
96,208,133,45,100,78,100,86,131,234,71,229,103,88,131,7,
38,123,104,160,130,168,0,90,127,104,128,21,147,206,90,13,
148,102,124,145,94,51,145,245,98,253,97,219,143,75,70,199,
100,234,141,18,37,213,102,40,139,156,0,82,127,118,128,55,
146,221,88,74,163,183,123,146,92,123,159,112,97,255,96,28,
154,247,69,241,99,40,151,144,37,38,100,94,147,151,0,74,
127,132,128,50,136,83,119,164,86,119,114,249,120,152,91,224,
90,200,121,197,96,207,63,24,123,14,101,47,28,228,124,239,
103,177,0,0,128,0,118,153,134,86,114,117,100,134,113,39,
116,9,104,12,89,55,117,132,107,62,61,232,118,232,110,10,
28,63,120,131,111,111,0,0,128,0,124,173,132,83,110,13,
114,153,111,34,112,8,116,89,87,166,113,196,117,216,60,195,
115,69,119,23,27,177,116,190,119,163,0,0,128,0,128,0,
130,119,106,149,129,11,109,119,108,205,130,35,86,4,110,179,
128,158,59,134,112,55,128,143,26,244,113,202,129,140,0,0,
128,0,128,0,129,36,103,242,142,177,108,51,106,79,140,179,
84,214,108,70,139,126,58,135,109,187,138,52,26,128,111,130,
137,83,0,0,128,0,128,0,128,71,102,62,157,11,107,73,
104,167,154,28,83,238,106,146,150,196,57,196,107,241,148,173,
25,237,109,244,142,180,0,0,128,0,128,0,116,102,133,188,
85,206,97,9,133,77,90,232,74,225,133,71,95,143,48,197,
133,211,99,100,15,223,135,31,101,112,0,0,128,0,123,165,
114,183,129,2,98,152,95,147,129,17,102,24,73,174,129,44,
105,65,47,247,129,153,107,201,15,177,130,194,109,55,0,0,
128,0,127,79,113,14,124,224,111,119,93,220,125,64,113,115,
72,73,125,135,115,40,46,243,125,235,116,107,15,86,127,106,
117,126,0,0,128,0,128,0,111,138,121,149,124,88,92,114,
122,42,124,241,71,9,122,128,125,56,46,66,122,185,125,99,
15,42,124,159,125,207,0,0,128,0,128,0,110,95,119,23,
138,202,91,117,119,207,138,10,70,19,120,28,137,0,45,94,
120,38,135,245,14,222,122,140,135,102,0,0,128,0,128,0,
109,149,121,89,150,108,90,170,121,119,148,158,69,84,118,115,
146,87,44,190,118,78,145,129,14,137,120,225,137,87,0,0,
128,0,128,0,96,221,149,113,84,82,79,24,147,218,89,8,
58,133,146,240,93,68,32,234,148,5,96,5,5,223,142,72,
100,242,0,0,128,0,127,76,95,109,145,55,96,1,77,234,
143,234,99,97,57,154,142,232,102,93,32,131,143,118,104,29,
6,7,138,144,108,199,0,0,128,0,128,0,94,36,141,70,
107,194,76,143,140,50,109,216,56,136,139,63,111,156,31,218,
139,127,112,111,5,254,135,60,116,52,0,0,128,0,128,0,
92,237,138,30,122,85,75,113,137,51,120,146,55,133,136,57,
121,39,31,91,136,14,123,110,5,246,132,117,123,118,0,0,
128,0,128,0,91,246,135,172,131,111,74,141,134,231,131,84,
54,186,133,222,130,234,30,202,133,72,130,209,6,11,130,149,
129,136,0,0,128,0,128,0,91,71,134,25,143,189,74,30,
133,105,142,218,54,108,132,29,141,96,30,192,131,24,140,170,
6,8,129,66,132,20,0,0,128,0,128,0,77,84,167,52,
81,238,60,225,164,229,86,29,41,102,163,178,89,171,15,187,
165,245,91,30,0,0,143,192,102,232,0,0,128,0,128,0,
76,0,163,132,92,179,59,195,161,83,95,199,40,139,159,206,
98,84,15,179,160,234,99,35,0,0,141,58,110,94,0,0,
128,0,128,0,75,38,159,158,103,107,58,198,157,140,105,113,
39,202,155,249,107,4,15,139,156,80,107,83,0,0,138,237,
113,76,0,0,128,0,128,0,74,77,156,103,114,86,58,10,
154,119,115,117,39,52,152,188,116,26,15,133,152,85,116,52,
0,33,136,220,120,138,0,0,128,0,128,0,73,149,153,242,
125,109,57,132,152,31,125,200,38,211,150,60,125,178,15,95,
149,64,125,240,0,63,135,71,127,146,0,0,128,0,128,0,
73,42,152,77,136,216,57,58,150,125,136,168,38,173,148,107,
136,30,15,114,147,1,134,175,0,80,134,33,128,54,0,0,
128,0,128,0,158,251,83,213,77,213,134,82,88,228,84,162,
107,209,93,194,91,44,78,135,98,47,97,81,44,208,100,17,
102,124,1,123,125,128,107,25,155,163,75,156,94,40,131,186,
81,193,98,171,105,163,87,113,102,252,76,186,92,94,107,9,
43,127,94,109,110,93,1,148,125,85,114,218,152,136,68,110,
110,104,128,251,75,123,112,169,103,104,81,210,114,214,74,252,
87,33,116,232,42,89,89,132,118,188,1,168,125,50,122,87,
149,187,62,95,127,39,126,199,70,68,127,37,101,151,77,45,
126,223,73,179,82,194,126,247,41,128,85,129,127,2,1,184,
125,23,128,57,147,155,57,144,141,195,125,55,66,42,139,246,
100,109,73,147,138,142,72,188,79,81,137,33,40,239,82,91,
136,147,1,196,125,4,129,50,146,51,54,15,157,180,124,41,
63,34,153,134,99,178,70,225,149,233,72,51,76,186,147,48,
40,130,79,242,145,93,1,205,124,245,129,56,140,172,95,13,
78,0,118,82,98,194,84,136,93,217,102,97,90,197,66,68,
105,148,96,126,32,220,108,22,100,131,0,0,128,0,112,38,
137,166,87,69,92,206,116,43,92,3,97,107,92,39,96,73,
101,193,64,246,99,194,105,173,32,26,102,123,108,69,0,0,
128,0,119,103,134,217,80,99,107,214,113,151,85,234,110,117,
90,18,90,193,112,228,63,85,94,121,115,18,31,23,97,180,
116,108,0,0,128,0,125,112,132,131,74,171,122,184,111,150,
80,207,123,118,88,87,86,26,124,13,62,35,89,237,124,145,
30,107,94,103,125,47,0,0,128,0,127,202,130,209,70,47,
137,129,110,40,76,204,136,111,87,33,82,108,135,54,61,36,
86,56,134,85,29,248,92,10,133,252,0,0,128,0,128,0,
129,180,66,231,151,227,109,43,73,215,149,17,86,72,79,164,
146,42,60,121,83,93,144,56,29,122,90,173,141,217,0,0,
128,0,128,0,122,59,107,13,78,9,101,239,109,128,84,51,
79,94,111,248,90,17,53,66,114,34,95,58,20,89,117,114,
98,63,0,0,128,0,118,48,119,113,99,183,91,125,99,224,
103,9,96,10,77,191,105,251,100,71,52,13,108,44,103,232,
19,212,112,104,105,245,0,0,128,0,124,88,117,9,93,44,
105,29,97,175,97,41,107,247,76,39,100,134,110,150,50,241,
102,174,112,192,19,113,108,243,114,23,0,0,128,0,128,0,
114,243,87,180,118,223,95,234,92,47,120,23,74,129,95,218,
121,16,49,195,97,217,121,223,18,225,106,136,122,228,0,0,
128,0,128,0,113,120,83,101,132,147,94,155,88,59,132,58,
73,87,92,22,131,141,48,207,93,197,131,35,18,148,104,170,
130,227,0,0,128,0,128,0,112,124,80,47,145,214,93,175,
85,72,144,47,72,123,89,48,142,34,48,28,90,139,141,35,
18,32,103,124,136,248,0,0,128,0,128,0,103,70,120,84,
77,117,84,232,121,161,83,63,64,11,123,28,88,172,38,210,
124,209,92,243,8,233,127,70,96,200,0,0,128,0,123,34,
100,213,113,135,89,167,83,25,115,126,94,24,62,167,117,48,
98,36,37,231,118,126,101,44,8,193,123,161,104,123,0,0,
128,0,127,24,98,194,107,80,102,30,81,34,109,203,105,23,
61,29,111,188,107,190,36,205,112,158,109,148,8,119,120,180,
112,173,0,0,128,0,128,0,96,242,102,12,114,156,79,130,
104,236,116,47,59,191,107,0,117,116,36,18,107,82,118,75,
8,91,118,101,120,166,0,0,128,0,128,0,95,146,97,206,
130,67,78,97,101,12,129,141,58,188,103,46,129,182,35,42,
103,31,127,144,8,40,116,175,127,220,0,0,128,0,128,0,
94,161,94,147,139,177,77,129,98,16,138,232,57,241,100,48,
137,174,34,137,99,241,137,147,7,229,115,133,132,115,0,0,
128,0,128,0,84,37,135,119,75,195,67,155,135,178,81,48,
48,13,136,148,86,4,22,132,139,57,88,202,1,153,133,28,
97,193,0,0,128,0,126,220,82,13,129,47,86,229,65,224,
129,244,91,44,46,166,130,201,94,217,21,210,132,77,96,184,
1,163,129,218,105,124,0,0,128,0,128,0,80,85,123,60,
98,71,64,40,124,97,101,75,45,71,125,64,103,204,20,248,
126,25,104,210,1,154,127,79,110,152,0,0,128,0,128,0,
78,197,118,17,114,119,62,180,119,146,116,238,44,4,120,106,
118,37,20,83,121,5,113,106,1,147,125,213,117,185,0,0,
128,0,128,0,77,131,113,206,121,100,61,140,115,179,122,30,
43,13,116,126,122,121,19,183,117,62,122,187,1,164,125,57,
126,172,0,0,128,0,128,0,76,158,110,125,133,67,60,216,
112,196,133,20,42,153,113,118,132,123,19,130,114,86,132,73,
1,142,125,96,129,13,0,0,128,0,128,0,64,153,153,69,
72,171,49,169,152,158,77,168,30,160,153,228,81,115,6,90,
154,60,83,247,0,0,130,209,102,37,0,0,128,0,128,0,
62,163,147,140,82,227,47,151,147,139,86,215,28,182,148,160,
89,168,5,183,147,71,91,203,0,0,128,103,109,199,0,0,
128,0,128,0,61,68,141,206,93,80,46,3,142,29,96,44,
27,97,143,2,98,7,5,78,141,29,99,223,0,0,128,0,
117,60,0,0,128,0,128,0,59,244,136,146,104,3,44,191,
137,80,105,212,26,96,137,238,106,205,5,45,136,30,108,152,
0,0,128,0,123,80,0,0,128,0,128,0,58,216,132,48,
114,233,43,191,133,110,115,203,25,174,133,218,116,14,4,250,
132,101,118,30,0,0,128,0,127,34,0,0,128,0,128,0,
58,13,128,170,126,39,42,253,130,99,126,61,25,57,130,182,
126,10,4,241,129,178,126,213,0,0,128,0,128,0,0,0,
128,0,128,0,0,0,255,255,0,0,255,255,0,0,255,255
};

View File

@@ -27,7 +27,7 @@ bool // O - `true` on sucess, `false` on EOF
_pdfioFileConsume(pdfio_file_t *pdf, // I - PDF file
size_t bytes) // I - Bytes to consume
{
PDFIO_DEBUG("_pdfioFileConsume(pdf=%p, bytes=%u)\n", (void *)pdf, (unsigned)bytes);
PDFIO_DEBUG("_pdfioFileConsume(pdf=%p, bytes=%u)\n", pdf, (unsigned)bytes);
if ((size_t)(pdf->bufend - pdf->bufptr) > bytes)
pdf->bufptr += bytes;
@@ -47,7 +47,7 @@ _pdfioFileConsume(pdfio_file_t *pdf, // I - PDF file
// `false` to halt.
//
bool // O - `false` to stop, `true` to continue
bool // O - `false` to stop
_pdfioFileDefaultError(
pdfio_file_t *pdf, // I - PDF file
const char *message, // I - Error message
@@ -57,7 +57,7 @@ _pdfioFileDefaultError(
fprintf(stderr, "%s: %s\n", pdf->filename, message);
return (!strncmp(message, "WARNING:", 8));
return (false);
}
@@ -91,7 +91,7 @@ _pdfioFileError(pdfio_file_t *pdf, // I - PDF file
bool // O - `true` on success, `false` on failure
_pdfioFileFlush(pdfio_file_t *pdf) // I - PDF file
{
PDFIO_DEBUG("_pdfioFileFlush(pdf=%p)\n", (void *)pdf);
PDFIO_DEBUG("_pdfioFileFlush(pdf=%p)\n", pdf);
if (pdf->bufptr > pdf->buffer)
{
@@ -134,20 +134,19 @@ _pdfioFileGetChar(pdfio_file_t *pdf) // I - PDF file
bool // O - `true` on success, `false` on error
_pdfioFileGets(pdfio_file_t *pdf, // I - PDF file
char *buffer, // I - Line buffer
size_t bufsize, // I - Size of line buffer
bool discard) // I - OK to discard excess line chars?
size_t bufsize) // I - Size of line buffer
{
bool eol = false; // End of line?
char *bufptr = buffer, // Pointer into buffer
*bufend = buffer + bufsize - 1; // Pointer to end of buffer
PDFIO_DEBUG("_pdfioFileGets(pdf=%p, buffer=%p, bufsize=%lu, discard=%s) bufpos=%ld, buffer=%p, bufptr=%p, bufend=%p, offset=%lu\n", (void *)pdf, (void *)buffer, (unsigned long)bufsize, discard ? "true" : "false", (long)pdf->bufpos, (void *)pdf->buffer, (void *)pdf->bufptr, (void *)pdf->bufend, (unsigned long)(pdf->bufpos + (pdf->bufptr - pdf->buffer)));
PDFIO_DEBUG("_pdfioFileGets(pdf=%p, buffer=%p, bufsize=%lu) bufpos=%ld, buffer=%p, bufptr=%p, bufend=%p, offset=%lu\n", pdf, buffer, (unsigned long)bufsize, (long)pdf->bufpos, pdf->buffer, pdf->bufptr, pdf->bufend, (unsigned long)(pdf->bufpos + (pdf->bufptr - pdf->buffer)));
while (!eol)
{
// If there are characters ready in the buffer, use them...
while (!eol && pdf->bufptr < pdf->bufend)
while (!eol && pdf->bufptr < pdf->bufend && bufptr < bufend)
{
char ch = *(pdf->bufptr++); // Next character in buffer
@@ -169,10 +168,8 @@ _pdfioFileGets(pdfio_file_t *pdf, // I - PDF file
pdf->bufptr ++;
}
}
else if (bufptr < bufend)
else
*bufptr++ = ch;
else if (!discard)
break;
}
// Fill the read buffer as needed...
@@ -359,7 +356,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
off_t offset, // I - Offset
int whence) // I - Offset base
{
PDFIO_DEBUG("_pdfioFileSeek(pdf=%p, offset=%ld, whence=%d) pdf->bufpos=%lu\n", (void *)pdf, (long)offset, whence, (unsigned long)(pdf ? pdf->bufpos : 0));
PDFIO_DEBUG("_pdfioFileSeek(pdf=%p, offset=%ld, whence=%d) pdf->bufpos=%lu\n", pdf, (long)offset, whence, (unsigned long)(pdf ? pdf->bufpos : 0));
// Adjust offset for relative seeks...
if (whence == SEEK_CUR)
@@ -376,7 +373,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
// Yes, seek within existing buffer...
pdf->bufptr = pdf->buffer + (offset - pdf->bufpos);
PDFIO_DEBUG("_pdfioFileSeek: Seek within buffer, bufpos=%ld.\n", (long)pdf->bufpos);
PDFIO_DEBUG("_pdfioFileSeek: buffer=%p, bufptr=%p(<%02X%02X...>), bufend=%p\n", (void *)pdf->buffer, (void *)pdf->bufptr, pdf->bufptr[0] & 255, pdf->bufptr[1] & 255, (void *)pdf->bufend);
PDFIO_DEBUG("_pdfioFileSeek: buffer=%p, bufptr=%p(<%02X%02X...>), bufend=%p\n", pdf->buffer, pdf->bufptr, pdf->bufptr[0] & 255, pdf->bufptr[1] & 255, pdf->bufend);
return (offset);
}
@@ -411,7 +408,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
}
PDFIO_DEBUG("_pdfioFileSeek: Reset bufpos=%ld, offset=%lu.\n", (long)pdf->bufpos, (unsigned long)offset);
PDFIO_DEBUG("_pdfioFileSeek: buffer=%p, bufptr=%p, bufend=%p\n", (void *)pdf->buffer, (void *)pdf->bufptr, (void *)pdf->bufend);
PDFIO_DEBUG("_pdfioFileSeek: buffer=%p, bufptr=%p, bufend=%p\n", pdf->buffer, pdf->bufptr, pdf->bufend);
pdf->bufpos = offset;
@@ -427,7 +424,7 @@ off_t // O - Offset from beginning of file
_pdfioFileTell(pdfio_file_t *pdf) // I - PDF file
{
if (pdf->bufptr)
return (pdf->bufpos + (off_t)(pdf->bufptr - pdf->buffer));
return (pdf->bufpos + (pdf->bufptr - pdf->buffer));
else
return (pdf->bufpos);
}
@@ -455,7 +452,7 @@ _pdfioFileWrite(pdfio_file_t *pdf, // I - PDF file
if (!write_buffer(pdf, buffer, bytes))
return (false);
pdf->bufpos += (off_t)bytes;
pdf->bufpos += bytes;
return (true);
}
@@ -481,7 +478,7 @@ fill_buffer(pdfio_file_t *pdf) // I - PDF file
// Advance current position in file as needed...
if (pdf->bufend)
pdf->bufpos += (off_t)(pdf->bufend - pdf->buffer);
pdf->bufpos += pdf->bufend - pdf->buffer;
// Try reading from the file...
if ((bytes = read_buffer(pdf, pdf->buffer, sizeof(pdf->buffer))) <= 0)

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
//
// Public content header file for PDFio.
//
// Copyright © 2021-2025 by Michael R Sweet.
// Copyright © 2021-2023 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
@@ -23,8 +23,7 @@ typedef enum pdfio_cs_e // Standard color spaces
{
PDFIO_CS_ADOBE, // AdobeRGB 1998
PDFIO_CS_P3_D65, // Display P3
PDFIO_CS_SRGB, // sRGB
PDFIO_CS_CGATS001 // CGATS001 (CMYK)
PDFIO_CS_SRGB // sRGB
} pdfio_cs_t;
typedef enum pdfio_linecap_e // Line capping modes
@@ -69,10 +68,8 @@ extern pdfio_array_t *pdfioArrayCreateColorFromPrimaries(pdfio_file_t *pdf, size
extern pdfio_array_t *pdfioArrayCreateColorFromStandard(pdfio_file_t *pdf, size_t num_colors, pdfio_cs_t cs);
// PDF content drawing functions...
extern bool pdfioContentBeginMarked(pdfio_stream_t *st, const char *tag, pdfio_dict_t *dict) _PDFIO_PUBLIC;
extern bool pdfioContentClip(pdfio_stream_t *st, bool even_odd) _PDFIO_PUBLIC;
extern bool pdfioContentDrawImage(pdfio_stream_t *st, const char *name, double x, double y, double w, double h) _PDFIO_PUBLIC;
extern bool pdfioContentEndMarked(pdfio_stream_t *st) _PDFIO_PUBLIC;
extern bool pdfioContentFill(pdfio_stream_t *st, bool even_odd) _PDFIO_PUBLIC;
extern bool pdfioContentFillAndStroke(pdfio_stream_t *st, bool even_odd) _PDFIO_PUBLIC;
extern bool pdfioContentMatrixConcat(pdfio_stream_t *st, pdfio_matrix_t m) _PDFIO_PUBLIC;
@@ -130,9 +127,7 @@ extern bool pdfioContentTextShowf(pdfio_stream_t *st, bool unicode, const char
extern bool pdfioContentTextShowJustified(pdfio_stream_t *st, bool unicode, size_t num_fragments, const double *offsets, const char * const *fragments) _PDFIO_PUBLIC;
// Resource helpers...
extern void pdfioFileAddOutputIntent(pdfio_file_t *pdf, const char *subtype, const char *condition, const char *cond_id, const char *reg_name, const char *info, pdfio_obj_t *profile) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateFontObjFromBase(pdfio_file_t *pdf, const char *name) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateFontObjFromData(pdfio_file_t *pdf, const void *data, size_t datasize, bool unicode) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateFontObjFromFile(pdfio_file_t *pdf, const char *filename, bool unicode) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateICCObjFromData(pdfio_file_t *pdf, const unsigned char *data, size_t datalen, size_t num_colors) _PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateICCObjFromFile(pdfio_file_t *pdf, const char *filename, size_t num_colors) _PDFIO_PUBLIC;

View File

@@ -98,7 +98,7 @@ static uint8_t pdf_passpad[32] = // Padding for passwords
static void decrypt_user_key(pdfio_encryption_t encryption, const uint8_t *file_key, uint8_t user_key[32]);
static void encrypt_user_key(pdfio_encryption_t encryption, const uint8_t *file_key, uint8_t user_key[32]);
static void make_file_key(pdfio_encryption_t encryption, pdfio_permission_t permissions, const unsigned char *file_id, size_t file_idlen, const uint8_t *user_pad, const uint8_t *owner_key, bool encrypt_metadata, uint8_t file_key[16]);
static void make_file_key(pdfio_encryption_t encryption, pdfio_permission_t permissions, const unsigned char *file_id, size_t file_idlen, const uint8_t *user_pad, const uint8_t *owner_key, uint8_t file_key[16]);
static void make_owner_key(pdfio_encryption_t encryption, const uint8_t *owner_pad, const uint8_t *user_pad, uint8_t owner_key[32]);
static void make_user_key(const unsigned char *file_id, size_t file_idlen, uint8_t user_key[32]);
static void pad_password(const char *password, uint8_t pad[32]);
@@ -158,7 +158,7 @@ _pdfioCryptoLock(
// Generate the encryption key
file_id = pdfioArrayGetBinary(pdf->id_array, 0, &file_idlen);
make_file_key(encryption, permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->encrypt_metadata, pdf->file_key);
make_file_key(encryption, permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->file_key);
pdf->file_keylen = 16;
// Generate the user key...
@@ -214,9 +214,8 @@ _pdfioCryptoLock(
pdfioObjClose(pdf->encrypt_obj);
pdf->encrypt_dict = dict;
pdf->encryption = encryption;
pdf->permissions = permissions;
pdf->encryption = encryption;
pdf->permissions = permissions;
return (true);
}
@@ -412,7 +411,7 @@ _pdfioCryptoMakeReader(
uint8_t digest[16]; // MD5 digest value
PDFIO_DEBUG("_pdfioCryptoMakeReader(pdf=%p, obj=%p(%d), ctx=%p, iv=%p, ivlen=%p(%d))\n", (void *)pdf, (void *)obj, (int)obj->number, (void *)ctx, (void *)iv, (void *)ivlen, (int)*ivlen);
PDFIO_DEBUG("_pdfioCryptoMakeReader(pdf=%p, obj=%p(%d), ctx=%p, iv=%p, ivlen=%p(%d))\n", pdf, obj, (int)obj->number, ctx, iv, ivlen, (int)*ivlen);
// Range check input...
if (!pdf)
@@ -455,10 +454,6 @@ _pdfioCryptoMakeReader(
return (NULL);
}
#ifdef __APPLE__
__attribute__((fallthrough));
#endif // __APPLE__
case PDFIO_ENCRYPTION_RC4_128 :
// Copy the key data for the MD5 hash.
memcpy(data, pdf->file_key, 16);
@@ -509,7 +504,7 @@ _pdfioCryptoMakeWriter(
uint8_t digest[16]; /* MD5 digest value */
PDFIO_DEBUG("_pdfioCryptoMakeWriter(pdf=%p, obj=%p(%d), ctx=%p, iv=%p, ivlen=%p(%d))\n", (void *)pdf, (void *)obj, (int)obj->number, (void *)ctx, (void *)iv, (void *)ivlen, (int)*ivlen);
PDFIO_DEBUG("_pdfioCryptoMakeWriter(pdf=%p, obj=%p(%d), ctx=%p, iv=%p, ivlen=%p(%d))\n", pdf, obj, (int)obj->number, ctx, iv, ivlen, (int)*ivlen);
// Range check input...
if (!pdf)
@@ -571,6 +566,7 @@ _pdfioCryptoUnlock(
{
int tries; // Number of tries
const char *password = NULL; // Password to try
pdfio_dict_t *encrypt_dict; // Encrypt objection dictionary
int version, // Version value
revision, // Revision value
length; // Key length value
@@ -586,23 +582,22 @@ _pdfioCryptoUnlock(
file_idlen; // Length of file ID
_pdfio_md5_t md5; // MD5 context
uint8_t file_digest[16]; // MD5 digest of file ID and pad
double p; // Permissions value as a double
_pdfio_value_t *value; // Encrypt dictionary value, if any
// See if we support the type of encryption specified by the Encrypt
// See if we support the type of encryption specified by the Encrypt object
// dictionary...
handler = pdfioDictGetName(pdf->encrypt_dict, "Filter");
version = (int)pdfioDictGetNumber(pdf->encrypt_dict, "V");
revision = (int)pdfioDictGetNumber(pdf->encrypt_dict, "R");
length = (int)pdfioDictGetNumber(pdf->encrypt_dict, "Length");
if ((encrypt_dict = pdfioObjGetDict(pdf->encrypt_obj)) == NULL)
{
_pdfioFileError(pdf, "Unable to get encryption dictionary.");
return (false);
}
if ((value = _pdfioDictGetValue(pdf->encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
pdf->encrypt_metadata = value->value.boolean;
else
pdf->encrypt_metadata = true;
handler = pdfioDictGetName(encrypt_dict, "Filter");
version = (int)pdfioDictGetNumber(encrypt_dict, "V");
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
PDFIO_DEBUG("_pdfioCryptoUnlock: handler=%p(%s), version=%d, revision=%d, length=%d, encrypt_metadata=%s\n", (void *)handler, handler ? handler : "(null)", version, revision, length, pdf->encrypt_metadata ? "true" : "false");
PDFIO_DEBUG("_pdfioCryptoUnlock: handler=%p(%s), version=%d, revision=%d, length=%d\n", (void *)handler, handler ? handler : "(null)", version, revision, length);
if (!handler || strcmp(handler, "Standard"))
{
@@ -616,9 +611,9 @@ _pdfioCryptoUnlock(
pdfio_dict_t *filter; // Crypt Filter
const char *cfm; // Crypt filter method
stream_filter = pdfioDictGetName(pdf->encrypt_dict, "StmF");
string_filter = pdfioDictGetName(pdf->encrypt_dict, "StrF");
cf_dict = pdfioDictGetDict(pdf->encrypt_dict, "CF");
stream_filter = pdfioDictGetName(encrypt_dict, "StmF");
string_filter = pdfioDictGetName(encrypt_dict, "StrF");
cf_dict = pdfioDictGetDict(encrypt_dict, "CF");
if (!cf_dict)
{
@@ -694,17 +689,12 @@ _pdfioCryptoUnlock(
// Grab the remaining values we need to unlock the PDF...
pdf->file_keylen = (size_t)(length / 8);
pdf->permissions = (pdfio_permission_t)pdfioDictGetNumber(encrypt_dict, "P");
p = pdfioDictGetNumber(pdf->encrypt_dict, "P");
PDFIO_DEBUG("_pdfioCryptoUnlock: P=%.0f\n", p);
if (p < 0x7fffffff) // Handle integers > 2^31-1
pdf->permissions = (pdfio_permission_t)p;
else
pdf->permissions = (pdfio_permission_t)(p - 4294967296.0);
PDFIO_DEBUG("_pdfioCryptoUnlock: permissions=%d\n", pdf->permissions);
owner_key = pdfioDictGetBinary(pdf->encrypt_dict, "O", &owner_keylen);
user_key = pdfioDictGetBinary(pdf->encrypt_dict, "U", &user_keylen);
owner_key = pdfioDictGetBinary(encrypt_dict, "O", &owner_keylen);
user_key = pdfioDictGetBinary(encrypt_dict, "U", &user_keylen);
if (!owner_key)
{
@@ -772,7 +762,7 @@ _pdfioCryptoUnlock(
make_owner_key(pdf->encryption, pad, pdf->owner_key, user_pad);
PDFIO_DEBUG("_pdfioCryptoUnlock: Upad=%02X%02X%02X%02X...%02X%02X%02X%02X\n", user_pad[0], user_pad[1], user_pad[2], user_pad[3], user_pad[28], user_pad[29], user_pad[30], user_pad[31]);
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->encrypt_metadata, file_key);
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, user_pad, pdf->owner_key, file_key);
PDFIO_DEBUG("_pdfioCryptoUnlock: Fown=%02X%02X%02X%02X...%02X%02X%02X%02X\n", file_key[0], file_key[1], file_key[2], file_key[3], file_key[12], file_key[13], file_key[14], file_key[15]);
make_user_key(file_id, file_idlen, own_user_key);
@@ -790,7 +780,7 @@ _pdfioCryptoUnlock(
}
// Not the owner password, try the user password...
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, pad, pdf->owner_key, pdf->encrypt_metadata, file_key);
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, pad, pdf->owner_key, file_key);
PDFIO_DEBUG("_pdfioCryptoUnlock: Fuse=%02X%02X%02X%02X...%02X%02X%02X%02X\n", file_key[0], file_key[1], file_key[2], file_key[3], file_key[12], file_key[13], file_key[14], file_key[15]);
make_user_key(file_id, file_idlen, own_user_key);
@@ -922,8 +912,6 @@ make_file_key(
size_t file_idlen, // I - Length of file ID
const uint8_t *user_pad, // I - Padded user password
const uint8_t *owner_key, // I - Owner key
bool encrypt_metadata,
// I - Encrypt metadata?
uint8_t file_key[16]) // O - Encryption key
{
size_t i; // Looping var
@@ -937,25 +925,13 @@ make_file_key(
perm_bytes[2] = (uint8_t)(permissions >> 16);
perm_bytes[3] = (uint8_t)(permissions >> 24);
PDFIO_DEBUG("make_file_key: user_pad[32]=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", user_pad[0], user_pad[1], user_pad[2], user_pad[3], user_pad[28], user_pad[29], user_pad[30], user_pad[31]);
PDFIO_DEBUG("make_file_key: owner_key[32]=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", owner_key[0], owner_key[1], owner_key[2], owner_key[3], owner_key[28], owner_key[29], owner_key[30], owner_key[31]);
PDFIO_DEBUG("make_file_key: permissions(%d)=<%02X%02X%02X%02X>\n", permissions, perm_bytes[0], perm_bytes[1], perm_bytes[2], perm_bytes[3]);
_pdfioCryptoMD5Init(&md5);
_pdfioCryptoMD5Append(&md5, user_pad, 32);
_pdfioCryptoMD5Append(&md5, owner_key, 32);
_pdfioCryptoMD5Append(&md5, perm_bytes, 4);
_pdfioCryptoMD5Append(&md5, file_id, file_idlen);
if (!encrypt_metadata)
{
uint8_t meta_bytes[4] = { 0xff, 0xff, 0xff, 0xff };
// Metadata bytes
_pdfioCryptoMD5Append(&md5, meta_bytes, 4);
}
_pdfioCryptoMD5Finish(&md5, digest);
PDFIO_DEBUG("make_file_key: first md5=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", digest[0], digest[1], digest[2], digest[3], digest[12], digest[13], digest[14], digest[15]);
if (encryption != PDFIO_ENCRYPTION_RC4_40)
{
// MD5 the result 50 times..
@@ -967,8 +943,6 @@ make_file_key(
}
}
PDFIO_DEBUG("make_file_key: file_key[16]=<%02X%02X%02X%02X...%02X%02X%02X%02X>\n", digest[0], digest[1], digest[2], digest[3], digest[12], digest[13], digest[14], digest[15]);
memcpy(file_key, digest, 16);
}
@@ -1019,11 +993,9 @@ make_owner_key(
// Encrypt 20 times...
uint8_t encrypt_key[16]; // RC4 encryption key
for (i = 20; i > 0;)
for (i = 0; i < 20; i ++)
{
// XOR each byte in the digest with the loop counter to make a key...
i --;
for (j = 0; j < sizeof(encrypt_key); j ++)
encrypt_key[j] = (uint8_t)(digest[j] ^ i);

View File

@@ -20,8 +20,6 @@ static int compare_pairs(_pdfio_pair_t *a, _pdfio_pair_t *b);
//
// 'pdfioDictClear()' - Remove a key/value pair from a dictionary.
//
// @since PDFio v1.4@
//
bool // O - `true` if cleared, `false` otherwise
pdfioDictClear(pdfio_dict_t *dict, // I - Dictionary
@@ -32,7 +30,7 @@ pdfioDictClear(pdfio_dict_t *dict, // I - Dictionary
pkey; // Search key
PDFIO_DEBUG("pdfioDictClear(dict=%p, key=\"%s\")\n", (void *)dict, key);
PDFIO_DEBUG("pdfioDictClear(dict=%p, key=\"%s\")\n", dict, key);
if (!dict || !key)
return (false);
@@ -77,7 +75,7 @@ pdfioDictCopy(pdfio_file_t *pdf, // I - PDF file
_pdfio_value_t v; // Current destination value
PDFIO_DEBUG("pdfioDictCopy(pdf=%p, dict=%p(%p))\n", (void *)pdf, (void *)dict, dict ? (void *)dict->pdf : NULL);
PDFIO_DEBUG("pdfioDictCopy(pdf=%p, dict=%p(%p))\n", pdf, dict, dict ? dict->pdf : NULL);
// Create the new dictionary...
if ((ndict = pdfioDictCreate(pdf)) == NULL)
@@ -347,8 +345,6 @@ pdfioDictGetDict(pdfio_dict_t *dict, // I - Dictionary
//
// 'pdfioDictGetKey()' - Get the key for the specified pair.
//
// @since PDFio v1.4@
//
const char * // O - Key for specified pair
pdfioDictGetKey(pdfio_dict_t *dict, // I - Dictionary
@@ -379,8 +375,6 @@ pdfioDictGetName(pdfio_dict_t *dict, // I - Dictionary
//
// 'pdfioDictGetNumPairs()' - Get the number of key/value pairs in a dictionary.
//
// @since PDFio v1.4@
//
size_t // O - Number of pairs
pdfioDictGetNumPairs(pdfio_dict_t *dict)// I - Dictionary
@@ -464,12 +458,8 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
PDFIO_DEBUG("pdfioDictGetString(dict=%p, key=\"%s\")\n", (void *)dict, key);
PDFIO_DEBUG("pdfioDictGetString: value=%p(type=%d)\n", (void *)value, value ? value->type : 0);
if (value && value->type == PDFIO_VALTYPE_STRING)
{
PDFIO_DEBUG("pdfioDictGetString: Returning \"%s\".\n", value->value.string);
return (value->value.string);
}
else if (value && value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
@@ -480,8 +470,6 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
if (!(value->value.binary.datalen & 1) && (!memcmp(value->value.binary.data, "\376\377", 2) || !memcmp(value->value.binary.data, "\377\376", 2)))
{
// Copy UTF-16...
PDFIO_DEBUG("pdfioDictGetString: Converting UTF-16 to UTF-8 string.\n");
_pdfio_utf16cpy(temp, value->value.binary.data, value->value.binary.datalen, sizeof(temp));
}
else
@@ -495,13 +483,10 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
value->type = PDFIO_VALTYPE_STRING;
value->value.string = pdfioStringCreate(dict->pdf, temp);
PDFIO_DEBUG("pdfioDictGetString: Returning \"%s\".\n", value->value.string);
return (value->value.string);
}
else
{
PDFIO_DEBUG("pdfioDictGetString: Returning NULL.\n");
return (NULL);
}
}
@@ -534,7 +519,7 @@ _pdfioDictGetValue(pdfio_dict_t *dict, // I - Dictionary
*match; // Matching key pair
PDFIO_DEBUG("_pdfioDictGetValue(dict=%p, key=\"%s\")\n", (void *)dict, key);
PDFIO_DEBUG("_pdfioDictGetValue(dict=%p, key=\"%s\")\n", dict, key);
if (!dict || !dict->num_pairs || !key)
{
@@ -577,8 +562,6 @@ _pdfioDictGetValue(pdfio_dict_t *dict, // I - Dictionary
// The iteration continues as long as the callback returns `true` or all keys
// have been iterated.
//
// @since PDFio v1.1@
//
void
pdfioDictIterateKeys(
@@ -619,7 +602,7 @@ _pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
_pdfio_value_t value; // Dictionary value
PDFIO_DEBUG("_pdfioDictRead(pdf=%p, obj=%p, tb=%p, depth=%lu)\n", (void *)pdf, (void *)obj, (void *)tb, (unsigned long)depth);
PDFIO_DEBUG("_pdfioDictRead(pdf=%p, obj=%p, tb=%p, depth=%lu)\n", pdf, obj, tb, (unsigned long)depth);
// Create a dictionary and start reading...
if ((dict = pdfioDictCreate(pdf)) == NULL)
@@ -652,11 +635,9 @@ _pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
{
// Issue 118: Discard duplicate key/value pairs, in the future this will
// be a warning message...
_pdfioFileError(pdf, "WARNING: Discarding value for duplicate dictionary key '%s'.", key + 1);
_pdfioValueDelete(&value);
if (_pdfioFileError(pdf, "WARNING: Discarding value for duplicate dictionary key '%s'.", key + 1))
continue;
else
break;
continue;
}
else if (!_pdfioDictSetValue(dict, pdfioStringCreate(pdf, key + 1), &value))
break;
@@ -993,7 +974,7 @@ _pdfioDictSetValue(
_pdfio_pair_t *pair; // Current pair
PDFIO_DEBUG("_pdfioDictSetValue(dict=%p, key=\"%s\", value=%p)\n", (void *)dict, key, (void *)value);
PDFIO_DEBUG("_pdfioDictSetValue(dict=%p, key=\"%s\", value=%p)\n", dict, key, (void *)value);
// See if the key is already set...
if (dict->num_pairs > 0)

File diff suppressed because it is too large Load Diff

View File

@@ -69,7 +69,7 @@ pdfioObjCopy(pdfio_file_t *pdf, // I - PDF file
ssize_t bytes; // Bytes read
PDFIO_DEBUG("pdfioObjCopy(pdf=%p, srcobj=%p(%p))\n", (void *)pdf, (void *)srcobj, srcobj ? (void *)srcobj->pdf : NULL);
PDFIO_DEBUG("pdfioObjCopy(pdf=%p, srcobj=%p(%p))\n", pdf, srcobj, srcobj ? srcobj->pdf : NULL);
// Range check input
if (!pdf || !srcobj)
@@ -79,10 +79,6 @@ pdfioObjCopy(pdfio_file_t *pdf, // I - PDF file
if (srcobj->value.type == PDFIO_VALTYPE_NONE)
_pdfioObjLoad(srcobj);
// See if we have already mapped this object...
if ((dstobj = _pdfioFileFindMappedObj(pdf, srcobj->pdf, srcobj->number)) != NULL)
return (dstobj); // Yes, return that one...
// Create the new object...
if ((dstobj = _pdfioFileCreateObj(pdf, srcobj->pdf, NULL)) == NULL)
return (NULL);
@@ -145,7 +141,6 @@ pdfioObjCreateStream(
pdfio_obj_t *obj, // I - Object
pdfio_filter_t filter) // I - Type of compression to apply
{
pdfio_stream_t *st; // Stream
pdfio_obj_t *length_obj = NULL; // Length object, if any
@@ -199,13 +194,11 @@ pdfioObjCreateStream(
if (!_pdfioFilePuts(obj->pdf, "stream\n"))
return (NULL);
obj->stream_offset = _pdfioFileTell(obj->pdf);
obj->stream_offset = _pdfioFileTell(obj->pdf);
obj->pdf->current_obj = obj;
// Return the new stream...
if ((st = _pdfioStreamCreate(obj, length_obj, 0, filter)) != NULL)
obj->pdf->current_obj = obj;
return (st);
return (_pdfioStreamCreate(obj, length_obj, 0, filter));
}
@@ -308,7 +301,7 @@ pdfioObjGetLength(pdfio_obj_t *obj) // I - Object
// Try getting the length, directly or indirectly
if ((length = (size_t)pdfioDictGetNumber(obj->value.value.dict, "Length")) > 0)
{
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", (void *)obj, (unsigned long)length);
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", obj, (unsigned long)length);
return (length);
}
@@ -328,7 +321,7 @@ pdfioObjGetLength(pdfio_obj_t *obj) // I - Object
return (0);
}
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", (void *)obj, (unsigned long)lenobj->value.value.number);
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", obj, (unsigned long)lenobj->value.value.number);
return ((size_t)lenobj->value.value.number);
}
@@ -337,8 +330,6 @@ pdfioObjGetLength(pdfio_obj_t *obj) // I - Object
//
// 'pdfioObjGetName()' - Get the name value associated with an object.
//
// @since PDFio v1.4@
//
const char * // O - Dictionary or `NULL` on error
pdfioObjGetName(pdfio_obj_t *obj) // I - Object
@@ -440,7 +431,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
_pdfio_token_t tb; // Token buffer/stack
PDFIO_DEBUG("_pdfioObjLoad(obj=%p(%lu)), offset=%lu\n", (void *)obj, (unsigned long)obj->number, (unsigned long)obj->offset);
PDFIO_DEBUG("_pdfioObjLoad(obj=%p(%lu)), offset=%lu\n", obj, (unsigned long)obj->number, (unsigned long)obj->offset);
// Seek to the start of the object and read its header...
if (_pdfioFileSeek(obj->pdf, obj->offset, SEEK_SET) != obj->offset)
@@ -502,7 +493,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
return (false);
}
PDFIO_DEBUG("_pdfioObjLoad: tb.bufptr=%p, tb.bufend=%p, tb.bufptr[0]=0x%02x, tb.bufptr[1]=0x%02x\n", (void *)tb.bufptr, (void *)tb.bufend, tb.bufptr[0], tb.bufptr[1]);
PDFIO_DEBUG("_pdfioObjLoad: tb.bufptr=%p, tb.bufend=%p, tb.bufptr[0]=0x%02x, tb.bufptr[1]=0x%02x\n", tb.bufptr, tb.bufend, tb.bufptr[0], tb.bufptr[1]);
_pdfioTokenFlush(&tb);
@@ -514,7 +505,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
}
// Decrypt as needed...
if (obj->pdf->encryption && obj->pdf->encrypt_metadata)
if (obj->pdf->encryption)
{
PDFIO_DEBUG("_pdfioObjLoad: Decrypting value...\n");
@@ -541,9 +532,6 @@ pdfio_stream_t * // O - Stream or `NULL` on error
pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
bool decode) // I - Decode/decompress data?
{
pdfio_stream_t *st; // Stream
// Range check input...
if (!obj)
return (NULL);
@@ -566,10 +554,9 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
return (NULL);
// Open the stream...
if ((st = _pdfioStreamOpen(obj, decode)) != NULL)
obj->pdf->current_obj = obj;
obj->pdf->current_obj = obj;
return (st);
return (_pdfioStreamOpen(obj, decode));
}

View File

@@ -28,7 +28,7 @@ pdfioPageCopy(pdfio_file_t *pdf, // I - PDF file
pdfio_obj_t *dstpage; // Destination page object
PDFIO_DEBUG("pdfioPageCopy(pdf=%p, srcpage=%p(%p))\n", (void *)pdf, (void *)srcpage, srcpage ? (void *)srcpage->pdf : NULL);
PDFIO_DEBUG("pdfioPageCopy(pdf=%p, srcpage=%p(%p))\n", pdf, srcpage, srcpage ? srcpage->pdf : NULL);
// Range check input
if (!pdf || !srcpage || srcpage->value.type != PDFIO_VALTYPE_DICT)

View File

@@ -10,7 +10,7 @@
#ifndef PDFIO_PRIVATE_H
# define PDFIO_PRIVATE_H
# ifdef _WIN32
# define _CRT_SECURE_NO_WARNINGS 1 // Disable bogus VS warnings/errors...
# define _CRT_SECURE_NO_WARNINGS // Disable bogus VS warnings/errors...
# endif // _WIN32
# include "pdfio.h"
# include <stdarg.h>
@@ -28,16 +28,16 @@
# define access _access // Map standard POSIX/C99 names
# define close _close
# define fileno _fileno
# define lseek(f,o,w) (off_t)_lseek((f),(long)(o),(w))
# define lseek _lseek
# define mkdir(d,p) _mkdir(d)
# define open _open
# define read(f,b,s) _read((f),(b),(unsigned)(s))
# define read _read
# define rmdir _rmdir
# define snprintf _snprintf
# define strdup _strdup
# define unlink _unlink
# define vsnprintf _vsnprintf
# define write(f,b,s) _write((f),(b),(unsigned)(s))
# define write _write
# ifndef F_OK
# define F_OK 00 // POSIX parameters/flags
# define W_OK 02
@@ -117,21 +117,6 @@ typedef enum _pdfio_predictor_e // PNG predictor constants
_PDFIO_PREDICTOR_PNG_AUTO = 15 // PNG "auto" predictor (currently mapped to Paeth)
} _pdfio_predictor_t;
typedef enum _pdfio_profile_e // PDF profile constants
{
_PDFIO_PROFILE_NONE = 0, // Base PDF file
_PDFIO_PROFILE_PCLM, // PCLm (PDF raster) file
_PDFIO_PROFILE_PDFA_1A, // PDF/A-1a:2005
_PDFIO_PROFILE_PDFA_1B, // PDF/A-1b:2005
_PDFIO_PROFILE_PDFA_2A, // PDF/A-2a:2011
_PDFIO_PROFILE_PDFA_2B, // PDF/A-2b:2011
_PDFIO_PROFILE_PDFA_2U, // PDF/A-2u:2011
_PDFIO_PROFILE_PDFA_3A, // PDF/A-3a:2012
_PDFIO_PROFILE_PDFA_3B, // PDF/A-3b:2012
_PDFIO_PROFILE_PDFA_3U, // PDF/A-3u:2012
_PDFIO_PROFILE_PDFA_4 // PDF/A-4:2020
} _pdfio_profile_t;
typedef ssize_t (*_pdfio_tconsume_cb_t)(void *data, size_t bytes);
typedef ssize_t (*_pdfio_tpeek_cb_t)(void *data, void *buffer, size_t bytes);
@@ -236,7 +221,7 @@ struct _pdfio_dict_s // Dictionary
typedef struct _pdfio_objmap_s // PDF object map
{
pdfio_obj_t *obj; // Object for this file
unsigned char src_id[32]; // Source PDF file file identifier
pdfio_file_t *src_pdf; // Source PDF file
size_t src_number; // Source object number
} _pdfio_objmap_t;
@@ -251,10 +236,8 @@ typedef struct _pdfio_strbuf_s // PDF string buffer
struct _pdfio_file_s // PDF file structure
{
char *filename; // Filename
unsigned char file_id[32]; // File identifier bytes
struct lconv *loc; // Locale data
char *version; // Version number
_pdfio_profile_t profile; // PDF profile, if any
pdfio_rect_t media_box, // Default MediaBox value
crop_box; // Default CropBox value
_pdfio_mode_t mode; // Read/write mode
@@ -283,14 +266,10 @@ struct _pdfio_file_s // PDF file structure
pdfio_obj_t *root_obj; // Root object/dictionary
pdfio_obj_t *info_obj; // Information object
pdfio_obj_t *pages_obj; // Root pages object
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
*cp1252_obj, // CP1252 font encoding object
pdfio_obj_t *encrypt_obj; // De/Encryption object/dictionary
pdfio_obj_t *cp1252_obj, // CP1252 font encoding object
*unicode_obj; // Unicode font encoding object
pdfio_array_t *id_array; // ID array
bool encrypt_metadata; // Encrypt metadata?
pdfio_dict_t *markinfo; // MarkInfo dictionary, if any
// Allocated data elements
size_t num_arrays, // Number of arrays
@@ -404,7 +383,7 @@ extern bool _pdfioFileError(pdfio_file_t *pdf, const char *format, ...) _PDFIO_
extern pdfio_obj_t *_pdfioFileFindMappedObj(pdfio_file_t *pdf, pdfio_file_t *src_pdf, size_t src_number) _PDFIO_INTERNAL;
extern bool _pdfioFileFlush(pdfio_file_t *pdf) _PDFIO_INTERNAL;
extern int _pdfioFileGetChar(pdfio_file_t *pdf) _PDFIO_INTERNAL;
extern bool _pdfioFileGets(pdfio_file_t *pdf, char *buffer, size_t bufsize, bool discard) _PDFIO_INTERNAL;
extern bool _pdfioFileGets(pdfio_file_t *pdf, char *buffer, size_t bufsize) _PDFIO_INTERNAL;
extern ssize_t _pdfioFilePeek(pdfio_file_t *pdf, void *buffer, size_t bytes) _PDFIO_INTERNAL;
extern bool _pdfioFilePrintf(pdfio_file_t *pdf, const char *format, ...) _PDFIO_INTERNAL;
extern bool _pdfioFilePuts(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;

View File

@@ -259,7 +259,7 @@ _pdfioStreamCreate(
{
colors = 1;
}
else if (colors < 0 || colors > 32)
else if (colors < 0 || colors > 4)
{
_pdfioFileError(st->pdf, "Unsupported Colors value %d.", colors);
free(st);
@@ -270,7 +270,7 @@ _pdfioStreamCreate(
{
columns = 1;
}
else if (columns < 0 || columns > 65536)
else if (columns < 0)
{
_pdfioFileError(st->pdf, "Unsupported Columns value %d.", columns);
free(st);
@@ -427,7 +427,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
const char *type; // Object type
PDFIO_DEBUG("_pdfioStreamOpen(obj=%p(%u), decode=%s)\n", (void *)obj, (unsigned)obj->number, decode ? "true" : "false");
PDFIO_DEBUG("_pdfioStreamOpen(obj=%p(%u), decode=%s)\n", obj, (unsigned)obj->number, decode ? "true" : "false");
// Allocate a new stream object...
if ((st = (pdfio_stream_t *)calloc(1, sizeof(pdfio_stream_t))) == NULL)
@@ -532,7 +532,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
{
colors = 1;
}
else if (colors < 0 || colors > 32)
else if (colors < 0 || colors > 4)
{
_pdfioFileError(st->pdf, "Unsupported Colors value %d.", colors);
goto error;
@@ -542,7 +542,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
{
columns = 1;
}
else if (columns < 0 || columns > 65536)
else if (columns < 0)
{
_pdfioFileError(st->pdf, "Unsupported Columns value %d.", columns);
goto error;
@@ -562,13 +562,6 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
if (predictor >= 10)
st->pbsize ++; // Add PNG predictor byte
if (st->pbsize < 2)
{
_pdfioFileError(st->pdf, "Bad Predictor buffer size %lu.", (unsigned long)st->pbsize);
goto error;
}
PDFIO_DEBUG("_pdfioStreamOpen: st->predictor=%d, st->pbpixel=%u, st->pbsize=%lu\n", st->predictor, (unsigned)st->pbpixel, (unsigned long)st->pbsize);
if ((st->prbuffer = calloc(1, st->pbsize - 1)) == NULL || (st->psbuffer = calloc(1, st->pbsize)) == NULL)
{
_pdfioFileError(st->pdf, "Unable to allocate %lu bytes for Predictor buffers.", (unsigned long)st->pbsize);
@@ -623,7 +616,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
else
{
// Something else we don't support
_pdfioFileError(st->pdf, "Unsupported stream filter '/%s'.", filter);
_pdfioFileError(st->pdf, "Unsupported stream filter '%N'.", filter);
goto error;
}
}
@@ -697,9 +690,8 @@ pdfioStreamPeek(pdfio_stream_t *st, // I - Stream
// 'pdfioStreamPrintf()' - Write a formatted string to a stream.
//
// This function writes a formatted string to a stream. In addition to the
// standard `printf` format characters, you can use "%H" to format a HTML/XML
// string value, "%N" to format a PDF name value ("/Name"), and "%S" to format
// a PDF string ("(String)") value.
// standard `printf` format characters, you can use "%N" to format a PDF name
// value ("/Name") and "%S" to format a PDF string ("(String)") value.
//
bool // O - `true` on success, `false` on failure
@@ -848,7 +840,7 @@ pdfioStreamWrite(
*pptr; // Previous raw buffer
PDFIO_DEBUG("pdfioStreamWrite(st=%p, buffer=%p, bytes=%lu)\n", (void *)st, buffer, (unsigned long)bytes);
PDFIO_DEBUG("pdfioStreamWrite(st=%p, buffer=%p, bytes=%lu)\n", st, buffer, (unsigned long)bytes);
// Range check input...
if (!st || st->pdf->mode != _PDFIO_MODE_WRITE || !buffer || !bytes)
@@ -1235,18 +1227,7 @@ stream_read(pdfio_stream_t *st, // I - Stream
}
// Apply predictor for this line
#ifdef DEBUG
if (remaining > 4)
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X ...\n", sptr[-1], sptr[0], sptr[1], sptr[2], sptr[3]);
else if (remaining > 3)
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[1], sptr[2], sptr[3]);
else if (remaining > 2)
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[1], sptr[2]);
else if (remaining > 1)
PDFIO_DEBUG("stream_read: Line %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[1]);
else
PDFIO_DEBUG("stream_read: Line %02X %02X.\n", sptr[-1], sptr[0]);
#endif // DEBUG
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[0], sptr[2], sptr[3]);
switch (sptr[-1])
{

View File

@@ -486,59 +486,6 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
}
break;
case 'H' : // XML/HTML string
if ((s = va_arg(ap, char *)) == NULL)
s = "(null)";
// Loop through the literal string...
while (*s)
{
// Escape special characters
if (*s == '&')
{
// &amp;
if (bufptr < bufend)
{
_pdfio_strlcpy(bufptr, "&amp;", (size_t)(bufend - bufptr + 1));
bufptr += strlen(bufptr);
}
bytes += 5;
}
else if (*s == '<')
{
// &lt;
if (bufptr < bufend)
{
_pdfio_strlcpy(bufptr, "&lt;", (size_t)(bufend - bufptr + 1));
bufptr += strlen(bufptr);
}
bytes += 4;
}
else if (*s == '>')
{
// &gt;
if (bufptr < bufend)
{
_pdfio_strlcpy(bufptr, "&gt;", (size_t)(bufend - bufptr + 1));
bufptr += strlen(bufptr);
}
bytes += 4;
}
else
{
// Literal character...
if (bufptr < bufend)
*bufptr++ = *s;
bytes ++;
}
s ++;
}
break;
case 'S' : // PDF string
if ((s = va_arg(ap, char *)) == NULL)
s = "(null)";
@@ -723,7 +670,7 @@ pdfioStringCreate(
int diff; // Different
PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", (void *)pdf, s);
PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", pdf, s);
// Range check input...
if (!pdf || !s)

View File

@@ -54,7 +54,7 @@ static int get_char(_pdfio_token_t *tb);
void
_pdfioTokenClear(_pdfio_token_t *tb) // I - Token buffer/stack
{
PDFIO_DEBUG("_pdfioTokenClear(tb=%p)\n", (void *)tb);
PDFIO_DEBUG("_pdfioTokenClear(tb=%p)\n", tb);
while (tb->num_tokens > 0)
{
@@ -132,7 +132,7 @@ _pdfioTokenGet(_pdfio_token_t *tb, // I - Token buffer/stack
if ((len = strlen(tb->tokens[tb->num_tokens])) > (bufsize - 1))
{
// Value too large...
PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Token '%s' from stack too large.\n", (void *)tb, (void *)buffer, (unsigned)bufsize, tb->tokens[tb->num_tokens]);
PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Token '%s' from stack too large.\n", tb, buffer, (unsigned)bufsize, tb->tokens[tb->num_tokens]);
*buffer = '\0';
return (false);
}
@@ -140,7 +140,7 @@ _pdfioTokenGet(_pdfio_token_t *tb, // I - Token buffer/stack
memcpy(buffer, tb->tokens[tb->num_tokens], len);
buffer[len] = '\0';
PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Popping '%s' from stack.\n", (void *)tb, (void *)buffer, (unsigned)bufsize, buffer);
PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Popping '%s' from stack.\n", tb, buffer, (unsigned)bufsize, buffer);
free(tb->tokens[tb->num_tokens]);
tb->tokens[tb->num_tokens] = NULL;
@@ -380,7 +380,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space
_pdfioFileError(tb->pdf, "String token too large.");
_pdfioFileError(tb->pdf, "Token too large.");
*bufptr = '\0';
return (false);
}
@@ -393,18 +393,9 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
return (false);
}
if ((bufptr - buffer) > 3 && ((bufptr - buffer) & 1) != 0 && (!memcmp(buffer, "(\377\376", 3) || !memcmp(buffer, "(\376\377", 3)))
{
// UTF-16 string, convert to UTF-8...
PDFIO_DEBUG("_pdfioTokenRead: Converting string to UTF-8.\n", stderr);
_pdfio_utf16cpy(buffer + 1, (unsigned char *)buffer + 1, bufptr - buffer - 1, bufsize - 1);
PDFIO_DEBUG("_pdfioTokenRead: Read '%s'.\n", buffer);
return (true);
}
else if (saw_nul)
if (saw_nul)
{
// Contains nul characters, convert to a hex (binary) string...
// Convert to a hex (binary) string...
char *litptr, // Pointer to literal character
*hexptr; // Pointer to hex character
size_t bytes = (size_t)(bufptr - buffer - 1);
@@ -417,7 +408,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
if ((2 * (bytes + 1)) > bufsize)
{
// Out of space...
_pdfioFileError(tb->pdf, "Binary string token too large.");
_pdfioFileError(tb->pdf, "Token too large.");
*bufptr = '\0';
return (false);
}
@@ -451,7 +442,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space...
_pdfioFileError(tb->pdf, "Keyword token too large.");
_pdfioFileError(tb->pdf, "Token too large.");
*bufptr = '\0';
return (false);
}
@@ -483,7 +474,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space...
_pdfioFileError(tb->pdf, "Number token too large.");
_pdfioFileError(tb->pdf, "Token too large.");
*bufptr = '\0';
return (false);
}
@@ -532,7 +523,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Out of space
_pdfioFileError(tb->pdf, "Name token too large.");
_pdfioFileError(tb->pdf, "Token too large.");
*bufptr = '\0';
return (false);
}
@@ -575,7 +566,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
else
{
// Too large
_pdfioFileError(tb->pdf, "Hex string token too large.");
_pdfioFileError(tb->pdf, "Token too large.");
*bufptr = '\0';
return (false);
}

View File

@@ -46,7 +46,7 @@ _pdfioValueCopy(pdfio_file_t *pdfdst, // I - Destination PDF file
#endif // DEBUG
PDFIO_DEBUG("_pdfioValueCopy(pdfdst=%p, vdst=%p, pdfsrc=%p, vsrc=%p(%s))\n", (void *)pdfdst, (void *)vdst, (void *)pdfsrc, (void *)vsrc, types[vsrc->type]);
PDFIO_DEBUG("_pdfioValueCopy(pdfdst=%p, vdst=%p, pdfsrc=%p, vsrc=%p(%s))\n", pdfdst, vdst, pdfsrc, vsrc, types[vsrc->type]);
if (pdfdst == pdfsrc && vsrc->type != PDFIO_VALTYPE_BINARY)
{
@@ -359,7 +359,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
#endif // DEBUG
PDFIO_DEBUG("_pdfioValueRead(pdf=%p, obj=%p, v=%p)\n", (void *)pdf, (void *)obj, (void *)v);
PDFIO_DEBUG("_pdfioValueRead(pdf=%p, obj=%p, v=%p)\n", pdf, obj, v);
if (!token)
goto done;
@@ -397,22 +397,18 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
ret = v;
}
else if ((timeval = get_date_time(token + 1)) != 0)
{
v->type = PDFIO_VALTYPE_DATE;
v->value.date = timeval;
ret = v;
}
else if (token[0] == '(')
{
if ((timeval = get_date_time(token + 1)) != 0)
{
// Date
v->type = PDFIO_VALTYPE_DATE;
v->value.date = timeval;
ret = v;
}
else
{
// String
v->type = PDFIO_VALTYPE_STRING;
v->value.string = pdfioStringCreate(pdf, token + 1);
ret = v;
}
// String
v->type = PDFIO_VALTYPE_STRING;
v->value.string = pdfioStringCreate(pdf, token + 1);
ret = v;
}
else if (token[0] == '/')
{
@@ -515,7 +511,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
// Integer...
long generation = 0; // Generation number
while (tempptr < tb->bufend && generation < 65536 && isdigit(*tempptr & 255))
while (tempptr < tb->bufend && isdigit(*tempptr & 255))
{
generation = generation * 10 + *tempptr - '0';
tempptr ++;

10
pdfio.h
View File

@@ -23,9 +23,9 @@ extern "C" {
// Version numbers...
//
# define PDFIO_VERSION "1.7.0"
# define PDFIO_VERSION "1.5.2"
# define PDFIO_VERSION_MAJOR 1
# define PDFIO_VERSION_MINOR 7
# define PDFIO_VERSION_MINOR 5
//
@@ -46,7 +46,7 @@ extern "C" {
//
# if _WIN32
typedef __int64 ssize_t; // POSIX type not present on Windows @private@
typedef __int64 ssize_t; // POSIX type not present on Windows... @private@
# endif // _WIN32
typedef struct _pdfio_array_s pdfio_array_t;
@@ -62,7 +62,7 @@ typedef bool (*pdfio_error_cb_t)(pdfio_file_t *pdf, const char *message, void *d
typedef enum pdfio_encryption_e // PDF encryption modes
{
PDFIO_ENCRYPTION_NONE = 0, // No encryption
PDFIO_ENCRYPTION_RC4_40, // 40-bit RC4 encryption (PDF 1.3, reading only)
PDFIO_ENCRYPTION_RC4_40, // 40-bit RC4 encryption (PDF 1.3)
PDFIO_ENCRYPTION_RC4_128, // 128-bit RC4 encryption (PDF 1.4)
PDFIO_ENCRYPTION_AES_128, // 128-bit AES encryption (PDF 1.6)
PDFIO_ENCRYPTION_AES_256 // 256-bit AES encryption (PDF 2.0) @exclude all@
@@ -201,7 +201,6 @@ extern time_t pdfioFileGetCreationDate(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern const char *pdfioFileGetCreator(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern pdfio_array_t *pdfioFileGetID(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern const char *pdfioFileGetKeywords(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern const char *pdfioFileGetLanguage(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern time_t pdfioFileGetModificationDate(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern const char *pdfioFileGetName(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern size_t pdfioFileGetNumObjs(pdfio_file_t *pdf) _PDFIO_PUBLIC;
@@ -218,7 +217,6 @@ extern void pdfioFileSetAuthor(pdfio_file_t *pdf, const char *value) _PDFIO_PUB
extern void pdfioFileSetCreationDate(pdfio_file_t *pdf, time_t value) _PDFIO_PUBLIC;
extern void pdfioFileSetCreator(pdfio_file_t *pdf, const char *value) _PDFIO_PUBLIC;
extern void pdfioFileSetKeywords(pdfio_file_t *pdf, const char *value) _PDFIO_PUBLIC;
extern void pdfioFileSetLanguage(pdfio_file_t *pdf, const char *value) _PDFIO_PUBLIC;
extern void pdfioFileSetModificationDate(pdfio_file_t *pdf, time_t value) _PDFIO_PUBLIC;
extern bool pdfioFileSetPermissions(pdfio_file_t *pdf, pdfio_permission_t permissions, pdfio_encryption_t encryption, const char *owner_password, const char *user_password) _PDFIO_PUBLIC;
extern void pdfioFileSetSubject(pdfio_file_t *pdf, const char *value) _PDFIO_PUBLIC;

View File

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

View File

@@ -261,7 +261,7 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 2600;
LastUpgradeCheck = 1600;
TargetAttributes = {
273440AF263D6FE200FBFD63 = {
CreatedOnToolsVersion = 12.5;
@@ -353,14 +353,12 @@
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
@@ -379,7 +377,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Apple Development";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.6.1;
CURRENT_PROJECT_VERSION = 1.1.2;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -390,16 +388,10 @@
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"DEBUG=1",
"HAVE_LIBPNG=1",
"HAVE_TM_GMTOFF=1",
"HAVE_TIMEGM=1",
);
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
@@ -407,29 +399,16 @@
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
/usr/local/include,
/opt/local/include,
/opt/homebrew/include,
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = (
"-L/usr/local/lib",
"-L/opt/local/lib",
"-L/opt/homebrew/lib",
"-lpng16",
);
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@@ -453,14 +432,12 @@
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
@@ -479,7 +456,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Apple Development";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.6.1;
CURRENT_PROJECT_VERSION = 1.1.2;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_HARDENED_RUNTIME = YES;
@@ -488,17 +465,10 @@
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"HAVE_LIBPNG=1",
"HAVE_TM_GMTOFF=1",
"HAVE_TIMEGM=1",
);
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
@@ -506,28 +476,15 @@
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
/usr/local/include,
/opt/local/include,
/opt/homebrew/include,
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
OTHER_LDFLAGS = (
"-L/usr/local/lib",
"-L/opt/local/lib",
"-L/opt/homebrew/lib",
"-lpng16",
);
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;

View File

@@ -1,23 +1,9 @@
LIBRARY pdfio1
VERSION 1.7
VERSION 1.5
EXPORTS
_pdfio_strlcpy
_pdfio_strtod
_pdfio_utf16cpy
_pdfio_vsnprintf
_pdfioArrayDebug
_pdfioArrayDecrypt
_pdfioArrayDelete
_pdfioArrayGetValue
_pdfioArrayRead
_pdfioArrayWrite
_pdfioCryptoAESDecrypt
_pdfioCryptoAESEncrypt
_pdfioCryptoAESInit
_pdfioCryptoLock
_pdfioCryptoMakeRandom
_pdfioCryptoMakeReader
_pdfioCryptoMakeWriter
_pdfioCryptoMD5Append
_pdfioCryptoMD5Finish
_pdfioCryptoMD5Init
@@ -26,53 +12,9 @@ _pdfioCryptoRC4Init
_pdfioCryptoSHA256Append
_pdfioCryptoSHA256Finish
_pdfioCryptoSHA256Init
_pdfioCryptoUnlock
_pdfioDictDebug
_pdfioDictDecrypt
_pdfioDictDelete
_pdfioDictGetValue
_pdfioDictRead
_pdfioDictSetValue
_pdfioDictWrite
_pdfioFileAddMappedObj
_pdfioFileAddPage
_pdfioFileConsume
_pdfioFileCreateObj
_pdfioFileDefaultError
_pdfioFileError
_pdfioFileFindMappedObj
_pdfioFileFlush
_pdfioFileGetChar
_pdfioFileGets
_pdfioFilePeek
_pdfioFilePrintf
_pdfioFilePuts
_pdfioFileRead
_pdfioFileSeek
_pdfioFileTell
_pdfioFileWrite
_pdfioObjDelete
_pdfioObjGetExtension
_pdfioObjLoad
_pdfioObjSetExtension
_pdfioObjWriteHeader
_pdfioStreamCreate
_pdfioStreamOpen
_pdfioStringAllocBuffer
_pdfioStringFreeBuffer
_pdfioStringIsAllocated
_pdfioTokenClear
_pdfioTokenFlush
_pdfioTokenGet
_pdfioTokenInit
_pdfioTokenPush
_pdfioTokenRead
_pdfioValueCopy
_pdfioValueDebug
_pdfioValueDecrypt
_pdfioValueDelete
_pdfioValueRead
_pdfioValueWrite
pdfioArrayAppendArray
pdfioArrayAppendBinary
pdfioArrayAppendBoolean
@@ -101,10 +43,8 @@ pdfioArrayGetSize
pdfioArrayGetString
pdfioArrayGetType
pdfioArrayRemove
pdfioContentBeginMarked
pdfioContentClip
pdfioContentDrawImage
pdfioContentEndMarked
pdfioContentFill
pdfioContentFillAndStroke
pdfioContentMatrixConcat
@@ -158,8 +98,8 @@ pdfioContentTextNewLineShow
pdfioContentTextNewLineShowf
pdfioContentTextNextLine
pdfioContentTextShow
pdfioContentTextShowf
pdfioContentTextShowJustified
pdfioContentTextShowf
pdfioDictClear
pdfioDictCopy
pdfioDictCreate
@@ -170,8 +110,8 @@ pdfioDictGetDate
pdfioDictGetDict
pdfioDictGetKey
pdfioDictGetName
pdfioDictGetNumber
pdfioDictGetNumPairs
pdfioDictGetNumber
pdfioDictGetObj
pdfioDictGetRect
pdfioDictGetString
@@ -189,12 +129,10 @@ pdfioDictSetObj
pdfioDictSetRect
pdfioDictSetString
pdfioDictSetStringf
pdfioFileAddOutputIntent
pdfioFileClose
pdfioFileCreate
pdfioFileCreateArrayObj
pdfioFileCreateFontObjFromBase
pdfioFileCreateFontObjFromData
pdfioFileCreateFontObjFromFile
pdfioFileCreateICCObjFromData
pdfioFileCreateICCObjFromFile
@@ -214,7 +152,6 @@ pdfioFileGetCreationDate
pdfioFileGetCreator
pdfioFileGetID
pdfioFileGetKeywords
pdfioFileGetLanguage
pdfioFileGetModificationDate
pdfioFileGetName
pdfioFileGetNumObjs
@@ -231,7 +168,6 @@ pdfioFileSetAuthor
pdfioFileSetCreationDate
pdfioFileSetCreator
pdfioFileSetKeywords
pdfioFileSetLanguage
pdfioFileSetModificationDate
pdfioFileSetPermissions
pdfioFileSetSubject

View File

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

View File

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

View File

@@ -1,30 +0,0 @@
#!/bin/sh
#
# Script to test PDFio against a directory of PDF files.
#
# Copyright © 2025 by Michael R Sweet.
#
# Licensed under Apache License v2.0. See the file "LICENSE" for more
# information.
#
# Usage:
#
# ./test-corpus.sh DIRECTORY
#
if test $# = 0; then
echo "Usage: ./test-corpus.sh DIRECTORY"
exit 1
fi
for file in $(find "$@" -name \*.pdf -print); do
# Run testpdfio to test loading the file...
./testpdfio $file >$file.log 2>&1
if test $? = 0; then
# Passed
rm -f $file.log
else
# Failed, preserve log and write filename to stdout...
echo $file
fi
done

282
test.h
View File

@@ -1,282 +0,0 @@
//
// Unit test header for C/C++ programs.
//
// Copyright © 2021-2025 by Michael R Sweet.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#ifndef TEST_H
# define TEST_H
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <stdbool.h>
# include <string.h>
# if _WIN32
# include <io.h>
# define isatty(f) _isatty(f)
# else
# include <unistd.h>
# endif // !_WIN32
# ifdef __cplusplus
extern "C" {
# endif // __cplusplus
//
// This header implements a simple unit test framework for C/C++ programs.
// Inline functions are provided to write a test summary to stdout and the
// details to stderr. This allows unit test programs to output a summary to
// stdout with details sent to stderr, e.g.:
//
// mytestprogram 2>test.log
//
// Documentation:
//
// void testBegin(const char *title, ...)
//
// Start a test with a printf-style title message. "Title:" (the formatted
// title followed by a colon) is output.
//
// void testEnd(bool pass)
//
// End a test without an additional message. "pass" should be `true` if the
// test passed and `false` otherwise. "PASS" or "FAIL" is output.
//
// void testEndMessage(bool pass, const char *message, ...)
//
// End a test with an additional printf-style message. "pass" should be
// `true` if the test passed and `false` otherwise. "PASS (message)" or
// "FAIL (message)" is output.
//
// testError(const char *error, ...)
//
// Sends a formatted error string to stderr.
//
// testHexDump(const unsigned char *buffer, size_t bytes)
//
// Sends a hex dump of the specified buffer to stderr.
//
// testMessage(const char *error, ...)
//
// Outputs a formatted message string.
//
// testProgress(void)
//
// Shows a progress spinner for long-running tests.
//
// bool testsPassed
//
// This global variable specifies whether all tests have passed (`true`)
// or one or more have failed (`false`).
//
static bool testsPassed = true; // All tests passed?
static int test_progress; // Current progress
static char test_title[1024] = ""; // Current test title
// Start a test
static inline void
testBegin(const char *title, ...) // I - printf-style title string
{
va_list ap; // Pointer to additional arguments
// Format the title string
va_start(ap, title);
vsnprintf(test_title, sizeof(test_title), title, ap);
va_end(ap);
// Send the title to stdout and stderr...
test_progress = 0;
printf("%s: ", test_title);
fflush(stdout);
if (!isatty(2))
fprintf(stderr, "%s: ", test_title);
}
// End a test with no additional information
static inline void
testEnd(bool pass) // I - `true` if the test passed, `false` otherwise
{
// Send the test result to stdout and stderr
if (test_progress)
putchar('\b');
if (!pass)
testsPassed = false;
puts(pass ? "PASS" : "FAIL");
if (!isatty(2))
fputs(pass ? "PASS\n" : "FAIL\n", stderr);
test_title[0] = '\0';
}
// End a test with no additional information
static inline void
testEndMessage(bool pass, // I - `true` if the test passed, `false` otherwise
const char *message, ...)// I - printf-style message
{
char buffer[1024]; // Formatted title string
va_list ap; // Pointer to additional arguments
// Format the title string
va_start(ap, message);
vsnprintf(buffer, sizeof(buffer), message, ap);
va_end(ap);
// Send the test result to stdout and stderr
if (test_progress)
putchar('\b');
printf(pass ? "PASS (%s)\n" : "FAIL (%s)\n", buffer);
if (!isatty(2))
fprintf(stderr, pass ? "PASS (%s)\n" : "FAIL (%s)\n", buffer);
test_title[0] = '\0';
}
// Show/update a progress spinner
static inline void
testProgress(void)
{
if (test_progress)
putchar('\b');
putchar("-\\|/"[test_progress & 3]);
fflush(stdout);
test_progress ++;
}
// Show an error to stderr...
static inline void
testError(const char *error, ...) // I - printf-style error string
{
char buffer[1024]; // Formatted title string
va_list ap; // Pointer to additional arguments
// Format the error string
va_start(ap, error);
vsnprintf(buffer, sizeof(buffer), error, ap);
va_end(ap);
// Send the error to stderr...
fprintf(stderr, "%s\n", buffer);
if (test_title[0])
fprintf(stderr, "%s: ", test_title);
}
// Show a message to stdout and stderr...
static inline void
testMessage(const char *error, ...) // I - printf-style error string
{
char buffer[1024]; // Formatted title string
va_list ap; // Pointer to additional arguments
// Format the error string
va_start(ap, error);
vsnprintf(buffer, sizeof(buffer), error, ap);
va_end(ap);
// Send the message to stdout and stderr too if needed...
printf("%s\n", buffer);
if (test_title[0])
{
printf("%s: ", test_title);
fflush(stdout);
}
if (!isatty(2))
{
fprintf(stderr, "%s\n", buffer);
if (test_title[0])
fprintf(stderr, "%s: ", test_title);
}
}
// Show a hex dump of a buffer to stderr...
static inline void
testHexDump(const unsigned char *buffer,// I - Buffer
size_t bytes) // I - Number of bytes
{
size_t i, j; // Looping vars
int ch; // Current ASCII char
if (test_title[0])
fputs("\n", stderr);
// Show lines of 16 bytes at a time...
for (i = 0; i < bytes; i += 16)
{
// Show the offset...
fprintf(stderr, "%04x ", (unsigned)i);
// Then up to 16 bytes in hex...
for (j = 0; j < 16; j ++)
{
if ((i + j) < bytes)
fprintf(stderr, " %02x", buffer[i + j]);
else
fputs(" ", stderr);
}
// Then the ASCII representation of the bytes...
fputs(" ", stderr);
for (j = 0; j < 16 && (i + j) < bytes; j ++)
{
ch = buffer[i + j] & 127;
if (ch < ' ' || ch == 127)
fputc('.', stderr);
else
fputc(ch, stderr);
}
fputc('\n', stderr);
}
if (test_title[0])
fprintf(stderr, "%s: ", test_title);
}
# ifdef __cplusplus
}
# endif // __cplusplus
#endif // !TEST_H

View File

@@ -1,5 +0,0 @@
https://github.com/saucecontrol/Compact-ICC-Profiles
All profiles in this collection are released to the public domain under the
Creative Commons CC0 license. They are free from restrictions on distribution
and use to the extent allowed by law.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because it is too large Load Diff

305
testttf.c Normal file
View File

@@ -0,0 +1,305 @@
//
// Unit test program for TTF library
//
// https://github.com/michaelrsweet/ttf
//
// Copyright © 2018-2024 by Michael R Sweet.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
//
// Usage:
//
// ./testttf [FILENAME]
//
#include <stdio.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
const char *value; // Font (string) value
int intvalue; // Font (integer) value
float realvalue; // Font (real) value
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);
}
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);
return (errors);
}

1
ttf

Submodule ttf deleted from efbdbf3074

2100
ttf.c Normal file

File diff suppressed because it is too large Load Diff

110
ttf.h Normal file
View File

@@ -0,0 +1,110 @@
//
// Header file for TTF library
//
// https://github.com/michaelrsweet/ttf
//
// Copyright © 2018-2024 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 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