mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-12-24 05:56:25 +01:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09198056a5 | ||
|
|
1c9e675cf6 | ||
|
|
f16f0c10ed | ||
|
|
019f0e8003 | ||
|
|
d5d089c560 | ||
|
|
23eb44e80b | ||
|
|
7d412cf855 | ||
|
|
597c9f8cda | ||
|
|
789b74af39 | ||
|
|
5032ce926e | ||
|
|
2977b82f35 | ||
|
|
b6008bae76 | ||
|
|
8459d97ff3 | ||
|
|
ed8be1f378 | ||
|
|
5edb5ad006 | ||
|
|
1b82f141e7 | ||
|
|
5699a52127 | ||
|
|
3c9a52a824 | ||
|
|
c272ddde3b | ||
|
|
26a92febc6 | ||
|
|
d82da750d9 | ||
|
|
e6fea00d74 | ||
|
|
815a45aec1 | ||
|
|
fe3ab5d67f | ||
|
|
abf2d6e7d8 | ||
|
|
2b68a0e0db | ||
|
|
c319f5a047 | ||
|
|
6e98635d91 | ||
|
|
04c52a74f6 | ||
|
|
c603a4e2b0 | ||
|
|
66f0c84621 | ||
|
|
98f6b90b53 | ||
|
|
c1ecf3a1ed | ||
|
|
f417a25121 | ||
|
|
1325c9cd61 | ||
|
|
71790bb6c4 | ||
|
|
a08614911a | ||
|
|
7bc3e84aed | ||
|
|
0194feca6f | ||
|
|
219a288488 | ||
|
|
2b4b20efe4 | ||
|
|
4032eef826 | ||
|
|
da58eec96d | ||
|
|
203a974682 | ||
|
|
7c69f13ba9 | ||
|
|
6dcb2cdced | ||
|
|
b1550fdc10 | ||
|
|
ef3a6cb1c0 | ||
|
|
0d1d5413ee | ||
|
|
f7db310942 | ||
|
|
99d03ddf9c | ||
|
|
fe122d557b | ||
|
|
2582052377 | ||
|
|
af5c412c96 | ||
|
|
e13526226a | ||
|
|
868794ab24 | ||
|
|
604396c0e7 | ||
|
|
156a184a45 | ||
|
|
eb0c785d6d | ||
|
|
359b65298e | ||
|
|
ccf3a90c97 | ||
|
|
c8017f50f6 | ||
|
|
4a1c53e31b | ||
|
|
5e8c3eb0b2 | ||
|
|
07ea310cd1 | ||
|
|
7ce8ec07ab | ||
|
|
f9ff913bb9 | ||
|
|
0c41a14919 | ||
|
|
57a01a7317 | ||
|
|
5b08046ece | ||
|
|
d1bf9a92dc | ||
|
|
749c0f845d | ||
|
|
cad8f450ab | ||
|
|
278ddb7fa7 | ||
|
|
1e6bb710e3 | ||
|
|
4ca93bd34f | ||
|
|
404ca72882 | ||
|
|
67704ce493 | ||
|
|
e983ba98d8 | ||
|
|
c23c6dec9a | ||
|
|
5e9617a742 | ||
|
|
09ee7d16c1 | ||
|
|
078985fc20 | ||
|
|
13fedfc424 | ||
|
|
c07927dc2d | ||
|
|
1393cd6c04 | ||
|
|
b278e33aac | ||
|
|
1116e929f7 | ||
|
|
c75611e274 | ||
|
|
c507cabbda | ||
|
|
81aeef46d2 | ||
|
|
ba7371b2e1 | ||
|
|
ec64af8b20 | ||
|
|
acd68df592 | ||
|
|
3d9c22aa49 | ||
|
|
3ae95f1545 | ||
|
|
cfdd6f55d9 | ||
|
|
06f38edcc7 | ||
|
|
76c1cc694f | ||
|
|
4219b8fd77 | ||
|
|
064e7fa473 | ||
|
|
ea9b7843fc | ||
|
|
755efe08da | ||
|
|
0391df5bbd | ||
|
|
49efd97cab | ||
|
|
d7eb1fc540 | ||
|
|
7afefda326 | ||
|
|
cbea3ecc2a | ||
|
|
130cef8702 | ||
|
|
0bd9edc845 | ||
|
|
fe755eac3d | ||
|
|
8cca645835 | ||
|
|
b8ea9ea064 | ||
|
|
2874022aa4 | ||
|
|
3befcf2fd5 | ||
|
|
3b2f7e21d9 | ||
|
|
7e01069c5a | ||
|
|
88839ccb56 | ||
|
|
ebd5aab39b | ||
|
|
71d33c03ff | ||
|
|
cfe91b4ea2 |
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout PDFio sources
|
- name: Checkout PDFio sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Update Build Environment
|
- name: Update Build Environment
|
||||||
run: sudo apt-get update --fix-missing -y
|
run: sudo apt-get update --fix-missing -y
|
||||||
- name: Install Prerequisites
|
- name: Install Prerequisites
|
||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- name: Configure PDFio
|
- name: Configure PDFio
|
||||||
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
|
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
|
||||||
- name: Build PDFio
|
- name: Build PDFio
|
||||||
run: make "COMMONFLAGS=-g -fsanitize=address"
|
run: make
|
||||||
- name: Test PDFio
|
- name: Test PDFio
|
||||||
env:
|
env:
|
||||||
ASAN_OPTIONS: leak_check_at_exit=false
|
ASAN_OPTIONS: leak_check_at_exit=false
|
||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout PDFio sources
|
- name: Checkout PDFio sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Configure PDFio
|
- name: Configure PDFio
|
||||||
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
|
run: ./configure --enable-debug --enable-sanitizer --enable-maintainer
|
||||||
- name: Build PDFio
|
- name: Build PDFio
|
||||||
@@ -53,9 +53,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout PDFio sources
|
- name: Checkout PDFio sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Setup MSBuild
|
- name: Setup MSBuild
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v2
|
||||||
- name: Nuget Restore
|
- name: Nuget Restore
|
||||||
run: nuget restore pdfio.sln
|
run: nuget restore pdfio.sln
|
||||||
- name: Build PDFio
|
- name: Build PDFio
|
||||||
|
|||||||
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout PDFio sources
|
- name: Checkout PDFio sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/coverity.yml
vendored
2
.github/workflows/coverity.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
environment: Coverity
|
environment: Coverity
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout PDFio sources
|
- name: Checkout PDFio sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Update Build Environment
|
- name: Update Build Environment
|
||||||
run: sudo apt-get update --fix-missing -y
|
run: sudo apt-get update --fix-missing -y
|
||||||
- name: Install Prerequisites
|
- name: Install Prerequisites
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,6 +16,7 @@
|
|||||||
/examples/md2pdf
|
/examples/md2pdf
|
||||||
/examples/pdf2text
|
/examples/pdf2text
|
||||||
/examples/pdfioinfo
|
/examples/pdfioinfo
|
||||||
|
/examples/pdfiomerge
|
||||||
/Makefile
|
/Makefile
|
||||||
/packages
|
/packages
|
||||||
/pdfio.pc
|
/pdfio.pc
|
||||||
|
|||||||
82
CHANGES.md
82
CHANGES.md
@@ -1,6 +1,88 @@
|
|||||||
Changes in PDFio
|
Changes in PDFio
|
||||||
================
|
================
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- 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
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Updated maximum allowed PDF string size to 64k (Issue #117)
|
||||||
|
- Updated dictionary reading code to discard duplicate key/value pairs with a
|
||||||
|
warning message (Issue #118)
|
||||||
|
- Fixed form detection in `pdfioinfo` example code (Issue #114)
|
||||||
|
- Fixed parsing of certain date/time values (Issue #115)
|
||||||
|
- Fixed support for empty name values (Issue #116)
|
||||||
|
- Fixed range checking in `pdfioImageGetBytesPerLine` (Issue #121)
|
||||||
|
|
||||||
|
|
||||||
|
v1.5.1 - 2025-03-28
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Fixed output of special characters in name values (Issue #106)
|
||||||
|
- Fixed output of special characters in string values (Issue #107)
|
||||||
|
- Fixed output of large integers in dictionaries (Issue #108)
|
||||||
|
- Fixed handling of 0-length streams (Issue #111)
|
||||||
|
- Fixed detection of UTF-16 Big-Endian strings (Issue #112)
|
||||||
|
|
||||||
|
|
||||||
v1.5.0 - 2025-03-06
|
v1.5.0 - 2025-03-06
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ testttf: ttf.o testttf.o
|
|||||||
# Dependencies
|
# Dependencies
|
||||||
$(OBJS): pdfio.h pdfio-private.h Makefile
|
$(OBJS): pdfio.h pdfio-private.h Makefile
|
||||||
pdfio-content.o: pdfio-content.h ttf.h
|
pdfio-content.o: pdfio-content.h ttf.h
|
||||||
|
testpdfio.o: test.h
|
||||||
testttf.o: ttf.h
|
testttf.o: ttf.h
|
||||||
ttf.o: ttf.h
|
ttf.o: ttf.h
|
||||||
|
|
||||||
|
|||||||
78
config.guess
vendored
78
config.guess
vendored
@@ -1,10 +1,10 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Attempt to guess a canonical system name.
|
# Attempt to guess a canonical system name.
|
||||||
# Copyright 1992-2022 Free Software Foundation, Inc.
|
# Copyright 1992-2025 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||||
|
|
||||||
timestamp='2022-09-17'
|
timestamp='2025-07-10'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# 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
|
# under the terms of the GNU General Public License as published by
|
||||||
@@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'`
|
|||||||
usage="\
|
usage="\
|
||||||
Usage: $0 [OPTION]
|
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:
|
Options:
|
||||||
-h, --help print this help, then exit
|
-h, --help print this help, then exit
|
||||||
@@ -60,13 +60,13 @@ version="\
|
|||||||
GNU config.guess ($timestamp)
|
GNU config.guess ($timestamp)
|
||||||
|
|
||||||
Originally written by Per Bothner.
|
Originally written by Per Bothner.
|
||||||
Copyright 1992-2022 Free Software Foundation, Inc.
|
Copyright 1992-2025 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
|
||||||
help="
|
help="
|
||||||
Try \`$me --help' for more information."
|
Try '$me --help' for more information."
|
||||||
|
|
||||||
# Parse command line
|
# Parse command line
|
||||||
while test $# -gt 0 ; do
|
while test $# -gt 0 ; do
|
||||||
@@ -102,8 +102,8 @@ GUESS=
|
|||||||
# temporary files to be created and, as you can see below, it is a
|
# temporary files to be created and, as you can see below, it is a
|
||||||
# headache to deal with in a portable fashion.
|
# headache to deal with in a portable fashion.
|
||||||
|
|
||||||
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
|
# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
|
||||||
# use `HOST_CC' if defined, but it is deprecated.
|
# use 'HOST_CC' if defined, but it is deprecated.
|
||||||
|
|
||||||
# Portable tmp directory creation inspired by the Autoconf team.
|
# Portable tmp directory creation inspired by the Autoconf team.
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ set_cc_for_build() {
|
|||||||
dummy=$tmp/dummy
|
dummy=$tmp/dummy
|
||||||
case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
|
case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
|
||||||
,,) echo "int x;" > "$dummy.c"
|
,,) echo "int x;" > "$dummy.c"
|
||||||
for driver in cc gcc c89 c99 ; do
|
for driver in cc gcc c17 c99 c89 ; do
|
||||||
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
|
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
|
||||||
CC_FOR_BUILD=$driver
|
CC_FOR_BUILD=$driver
|
||||||
break
|
break
|
||||||
@@ -155,6 +155,9 @@ Linux|GNU|GNU/*)
|
|||||||
|
|
||||||
set_cc_for_build
|
set_cc_for_build
|
||||||
cat <<-EOF > "$dummy.c"
|
cat <<-EOF > "$dummy.c"
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
LIBC=android
|
||||||
|
#else
|
||||||
#include <features.h>
|
#include <features.h>
|
||||||
#if defined(__UCLIBC__)
|
#if defined(__UCLIBC__)
|
||||||
LIBC=uclibc
|
LIBC=uclibc
|
||||||
@@ -162,6 +165,8 @@ Linux|GNU|GNU/*)
|
|||||||
LIBC=dietlibc
|
LIBC=dietlibc
|
||||||
#elif defined(__GLIBC__)
|
#elif defined(__GLIBC__)
|
||||||
LIBC=gnu
|
LIBC=gnu
|
||||||
|
#elif defined(__LLVM_LIBC__)
|
||||||
|
LIBC=llvm
|
||||||
#else
|
#else
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
/* First heuristic to detect musl libc. */
|
/* First heuristic to detect musl libc. */
|
||||||
@@ -169,6 +174,7 @@ Linux|GNU|GNU/*)
|
|||||||
LIBC=musl
|
LIBC=musl
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
EOF
|
EOF
|
||||||
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
|
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
|
||||||
eval "$cc_set_libc"
|
eval "$cc_set_libc"
|
||||||
@@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
|
|||||||
UNAME_RELEASE=`uname -v`
|
UNAME_RELEASE=`uname -v`
|
||||||
;;
|
;;
|
||||||
esac
|
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/-/_/'`
|
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
|
||||||
GUESS=sparc-sun-sunos$SUN_REL
|
GUESS=sparc-sun-sunos$SUN_REL
|
||||||
;;
|
;;
|
||||||
@@ -628,7 +634,8 @@ EOF
|
|||||||
sed 's/^ //' << EOF > "$dummy.c"
|
sed 's/^ //' << EOF > "$dummy.c"
|
||||||
#include <sys/systemcfg.h>
|
#include <sys/systemcfg.h>
|
||||||
|
|
||||||
main()
|
int
|
||||||
|
main ()
|
||||||
{
|
{
|
||||||
if (!__power_pc())
|
if (!__power_pc())
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -712,7 +719,8 @@ EOF
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main ()
|
int
|
||||||
|
main ()
|
||||||
{
|
{
|
||||||
#if defined(_SC_KERNEL_BITS)
|
#if defined(_SC_KERNEL_BITS)
|
||||||
long bits = sysconf(_SC_KERNEL_BITS);
|
long bits = sysconf(_SC_KERNEL_BITS);
|
||||||
@@ -904,7 +912,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*:FreeBSD:*:*)
|
*:FreeBSD:*:*)
|
||||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
UNAME_PROCESSOR=`uname -p`
|
||||||
case $UNAME_PROCESSOR in
|
case $UNAME_PROCESSOR in
|
||||||
amd64)
|
amd64)
|
||||||
UNAME_PROCESSOR=x86_64 ;;
|
UNAME_PROCESSOR=x86_64 ;;
|
||||||
@@ -976,7 +984,27 @@ EOF
|
|||||||
GUESS=$UNAME_MACHINE-unknown-minix
|
GUESS=$UNAME_MACHINE-unknown-minix
|
||||||
;;
|
;;
|
||||||
aarch64:Linux:*:*)
|
aarch64:Linux:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
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
|
||||||
;;
|
;;
|
||||||
aarch64_be:Linux:*:*)
|
aarch64_be:Linux:*:*)
|
||||||
UNAME_MACHINE=aarch64_be
|
UNAME_MACHINE=aarch64_be
|
||||||
@@ -1042,6 +1070,15 @@ EOF
|
|||||||
k1om:Linux:*:*)
|
k1om:Linux:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
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:*:*)
|
loongarch32:Linux:*:* | loongarch64:Linux:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||||
;;
|
;;
|
||||||
@@ -1197,7 +1234,7 @@ EOF
|
|||||||
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
|
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
|
||||||
;;
|
;;
|
||||||
i*86:OS/2:*:*)
|
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.
|
# is probably installed.
|
||||||
GUESS=$UNAME_MACHINE-pc-os2-emx
|
GUESS=$UNAME_MACHINE-pc-os2-emx
|
||||||
;;
|
;;
|
||||||
@@ -1338,7 +1375,7 @@ EOF
|
|||||||
GUESS=ns32k-sni-sysv
|
GUESS=ns32k-sni-sysv
|
||||||
fi
|
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>
|
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||||
GUESS=i586-unisys-sysv4
|
GUESS=i586-unisys-sysv4
|
||||||
;;
|
;;
|
||||||
@@ -1560,6 +1597,12 @@ EOF
|
|||||||
*:Unleashed:*:*)
|
*:Unleashed:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
|
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
|
esac
|
||||||
|
|
||||||
# Do we have a guess based on uname results?
|
# Do we have a guess based on uname results?
|
||||||
@@ -1583,6 +1626,7 @@ cat > "$dummy.c" <<EOF
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
#if defined (sony)
|
#if defined (sony)
|
||||||
@@ -1767,8 +1811,8 @@ fi
|
|||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
|
||||||
# time-stamp-start: "timestamp='"
|
# time-stamp-start: "timestamp='"
|
||||||
# time-stamp-format: "%:y-%02m-%02d"
|
# time-stamp-format: "%Y-%02m-%02d"
|
||||||
# time-stamp-end: "'"
|
# time-stamp-end: "'"
|
||||||
# End:
|
# End:
|
||||||
|
|||||||
953
config.sub
vendored
953
config.sub
vendored
File diff suppressed because it is too large
Load Diff
229
configure
vendored
229
configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.71 for pdfio 1.5.0.
|
# Generated by GNU Autoconf 2.71 for pdfio 1.6.1.
|
||||||
#
|
#
|
||||||
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
|
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
|
||||||
#
|
#
|
||||||
@@ -610,8 +610,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='pdfio'
|
PACKAGE_NAME='pdfio'
|
||||||
PACKAGE_TARNAME='pdfio'
|
PACKAGE_TARNAME='pdfio'
|
||||||
PACKAGE_VERSION='1.5.0'
|
PACKAGE_VERSION='1.6.1'
|
||||||
PACKAGE_STRING='pdfio 1.5.0'
|
PACKAGE_STRING='pdfio 1.6.1'
|
||||||
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
|
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
|
||||||
PACKAGE_URL='https://www.msweet.org/pdfio'
|
PACKAGE_URL='https://www.msweet.org/pdfio'
|
||||||
|
|
||||||
@@ -653,7 +653,7 @@ WARNINGS
|
|||||||
CSFLAGS
|
CSFLAGS
|
||||||
LIBPDFIO_STATIC
|
LIBPDFIO_STATIC
|
||||||
LIBPDFIO
|
LIBPDFIO
|
||||||
PKGCONFIG_LIBPNG
|
PKGCONFIG_REQUIRES_PRIVATE
|
||||||
PKGCONFIG_REQUIRES
|
PKGCONFIG_REQUIRES
|
||||||
PKGCONFIG_LIBS_PRIVATE
|
PKGCONFIG_LIBS_PRIVATE
|
||||||
PKGCONFIG_LIBS
|
PKGCONFIG_LIBS
|
||||||
@@ -1295,7 +1295,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures pdfio 1.5.0 to adapt to many kinds of systems.
|
\`configure' configures pdfio 1.6.1 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1361,7 +1361,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of pdfio 1.5.0:";;
|
short | recursive ) echo "Configuration of pdfio 1.6.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1460,7 +1460,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
pdfio configure 1.5.0
|
pdfio configure 1.6.1
|
||||||
generated by GNU Autoconf 2.71
|
generated by GNU Autoconf 2.71
|
||||||
|
|
||||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
@@ -1592,6 +1592,68 @@ fi
|
|||||||
as_fn_set_status $ac_retval
|
as_fn_set_status $ac_retval
|
||||||
|
|
||||||
} # ac_fn_c_try_link
|
} # ac_fn_c_try_link
|
||||||
|
|
||||||
|
# ac_fn_c_check_func LINENO FUNC VAR
|
||||||
|
# ----------------------------------
|
||||||
|
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
||||||
|
ac_fn_c_check_func ()
|
||||||
|
{
|
||||||
|
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. */
|
||||||
|
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
|
||||||
|
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||||
|
#define $2 innocuous_$2
|
||||||
|
|
||||||
|
/* System header to define __stub macros and hopefully few prototypes,
|
||||||
|
which can conflict with char $2 (); below. */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#undef $2
|
||||||
|
|
||||||
|
/* Override any GCC internal prototype to avoid an error.
|
||||||
|
Use char because int might match the return type of a GCC
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
char $2 ();
|
||||||
|
/* The GNU C library defines this for functions which it implements
|
||||||
|
to always fail with ENOSYS. Some functions are actually named
|
||||||
|
something starting with __ and the normal name is an alias. */
|
||||||
|
#if defined __stub_$2 || defined __stub___$2
|
||||||
|
choke me
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
return $2 ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"
|
||||||
|
then :
|
||||||
|
eval "$3=yes"
|
||||||
|
else $as_nop
|
||||||
|
eval "$3=no"
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||||
|
conftest$ac_exeext 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_func
|
||||||
ac_configure_args_raw=
|
ac_configure_args_raw=
|
||||||
for ac_arg
|
for ac_arg
|
||||||
do
|
do
|
||||||
@@ -1616,7 +1678,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by pdfio $as_me 1.5.0, which was
|
It was created by pdfio $as_me 1.6.1, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
$ $0$ac_configure_args_raw
|
$ $0$ac_configure_args_raw
|
||||||
@@ -2372,9 +2434,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
PDFIO_VERSION="1.5.0"
|
PDFIO_VERSION="1.6.1"
|
||||||
PDFIO_VERSION_MAJOR="`echo 1.5.0 | awk -F. '{print $1}'`"
|
PDFIO_VERSION_MAJOR="`echo 1.6.1 | awk -F. '{print $1}'`"
|
||||||
PDFIO_VERSION_MINOR="`echo 1.5.0 | awk -F. '{printf("%d\n",$2);}'`"
|
PDFIO_VERSION_MINOR="`echo 1.6.1 | awk -F. '{printf("%d\n",$2);}'`"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3877,6 +3939,93 @@ INSTALL="$(pwd)/install-sh"
|
|||||||
printf "%s\n" "using $INSTALL" >&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 :
|
||||||
|
|
||||||
|
|
||||||
|
printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h
|
||||||
|
|
||||||
|
CPPFLAGS="-DHAVE_TIMEGM=1 $CPPFLAGS"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff member in tm structure" >&5
|
||||||
|
printf %s "checking for tm_gmtoff member in tm structure... " >&6; }
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct tm t;
|
||||||
|
int o = t.tm_gmtoff;
|
||||||
|
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"
|
||||||
|
then :
|
||||||
|
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
printf "%s\n" "yes" >&6; }
|
||||||
|
|
||||||
|
printf "%s\n" "#define HAVE_TM_GMTOFF 1" >>confdefs.h
|
||||||
|
|
||||||
|
CPPFLAGS="-DHAVE_TM_GMTOFF=1 $CPPFLAGS"
|
||||||
|
|
||||||
|
else $as_nop
|
||||||
|
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
printf "%s\n" "no" >&6; }
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||||
|
|
||||||
|
|
||||||
if test -n "$ac_tool_prefix"; then
|
if test -n "$ac_tool_prefix"; then
|
||||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||||
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
||||||
@@ -3989,7 +4138,9 @@ fi
|
|||||||
PKGCONFIG_CFLAGS="-I\${includedir}"
|
PKGCONFIG_CFLAGS="-I\${includedir}"
|
||||||
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
|
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
|
||||||
PKGCONFIG_LIBS_PRIVATE="-lm"
|
PKGCONFIG_LIBS_PRIVATE="-lm"
|
||||||
PKGCONFIG_REQUIRES="zlib"
|
PKBCONFIG_REQUIRES=""
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE=""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3998,36 +4149,6 @@ PKGCONFIG_REQUIRES="zlib"
|
|||||||
|
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib via pkg-config" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib via pkg-config" >&5
|
||||||
printf %s "checking for zlib via pkg-config... " >&6; }
|
printf %s "checking for zlib via pkg-config... " >&6; }
|
||||||
|
|
||||||
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
|
if $PKGCONFIG --exists zlib
|
||||||
then :
|
then :
|
||||||
|
|
||||||
@@ -4035,6 +4156,7 @@ then :
|
|||||||
printf "%s\n" "yes" >&6; }
|
printf "%s\n" "yes" >&6; }
|
||||||
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
|
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
|
||||||
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
|
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE="zlib"
|
||||||
|
|
||||||
else $as_nop
|
else $as_nop
|
||||||
|
|
||||||
@@ -4097,12 +4219,10 @@ then :
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PKGCONFIG_REQUIRES=""
|
|
||||||
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
|
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Check whether --enable-libpng was given.
|
# Check whether --enable-libpng was given.
|
||||||
if test ${enable_libpng+y}
|
if test ${enable_libpng+y}
|
||||||
then :
|
then :
|
||||||
@@ -4110,9 +4230,6 @@ then :
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
PKGCONFIG_LIBPNG=""
|
|
||||||
|
|
||||||
|
|
||||||
if test "x$PKGCONFIG" != x -a x$enable_libpng != xno
|
if test "x$PKGCONFIG" != x -a x$enable_libpng != xno
|
||||||
then :
|
then :
|
||||||
|
|
||||||
@@ -4128,8 +4245,16 @@ printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h
|
|||||||
|
|
||||||
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
|
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
|
||||||
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
|
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
|
||||||
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
|
if test "x$PKGCONFIG_REQUIRES_PRIVATE" = x
|
||||||
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
|
then :
|
||||||
|
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6"
|
||||||
|
|
||||||
|
else $as_nop
|
||||||
|
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
else $as_nop
|
else $as_nop
|
||||||
|
|
||||||
@@ -4196,6 +4321,8 @@ else $as_nop
|
|||||||
LIBPDFIO_STATIC=""
|
LIBPDFIO_STATIC=""
|
||||||
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
|
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
|
||||||
PKGCONFIG_LIBS_PRIVATE=""
|
PKGCONFIG_LIBS_PRIVATE=""
|
||||||
|
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE=""
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4988,7 +5115,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by pdfio $as_me 1.5.0, which was
|
This file was extended by pdfio $as_me 1.6.1, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -5044,7 +5171,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config='$ac_cs_config_escaped'
|
ac_cs_config='$ac_cs_config_escaped'
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
pdfio config.status 1.5.0
|
pdfio config.status 1.6.1
|
||||||
configured by $0, generated by GNU Autoconf 2.71,
|
configured by $0, generated by GNU Autoconf 2.71,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|||||||
46
configure.ac
46
configure.ac
@@ -21,7 +21,7 @@ AC_PREREQ([2.70])
|
|||||||
|
|
||||||
|
|
||||||
dnl Package name and version...
|
dnl Package name and version...
|
||||||
AC_INIT([pdfio], [1.5.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
|
AC_INIT([pdfio], [1.6.1], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
|
||||||
|
|
||||||
PDFIO_VERSION="AC_PACKAGE_VERSION"
|
PDFIO_VERSION="AC_PACKAGE_VERSION"
|
||||||
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
|
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
|
||||||
@@ -88,17 +88,44 @@ AC_SUBST([INSTALL])
|
|||||||
AC_MSG_RESULT([using $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?])
|
||||||
|
CPPFLAGS="-DHAVE_TIMEGM=1 $CPPFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for tm_gmtoff member in tm structure])
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([[#include <time.h>]], [[
|
||||||
|
struct tm t;
|
||||||
|
int o = t.tm_gmtoff;
|
||||||
|
]])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE([HAVE_TM_GMTOFF], [1], [Have tm_gmtoff member in struct tm?])
|
||||||
|
CPPFLAGS="-DHAVE_TM_GMTOFF=1 $CPPFLAGS"
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl Check for pkg-config, which is used for some other tests later on...
|
dnl Check for pkg-config, which is used for some other tests later on...
|
||||||
AC_PATH_TOOL([PKGCONFIG], [pkg-config])
|
AC_PATH_TOOL([PKGCONFIG], [pkg-config])
|
||||||
|
|
||||||
PKGCONFIG_CFLAGS="-I\${includedir}"
|
PKGCONFIG_CFLAGS="-I\${includedir}"
|
||||||
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
|
PKGCONFIG_LIBS="-L\${libdir} -lpdfio"
|
||||||
PKGCONFIG_LIBS_PRIVATE="-lm"
|
PKGCONFIG_LIBS_PRIVATE="-lm"
|
||||||
PKGCONFIG_REQUIRES="zlib"
|
PKBCONFIG_REQUIRES=""
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE=""
|
||||||
AC_SUBST([PKGCONFIG_CFLAGS])
|
AC_SUBST([PKGCONFIG_CFLAGS])
|
||||||
AC_SUBST([PKGCONFIG_LIBS])
|
AC_SUBST([PKGCONFIG_LIBS])
|
||||||
AC_SUBST([PKGCONFIG_LIBS_PRIVATE])
|
AC_SUBST([PKGCONFIG_LIBS_PRIVATE])
|
||||||
AC_SUBST([PKGCONFIG_REQUIRES])
|
AC_SUBST([PKGCONFIG_REQUIRES])
|
||||||
|
AC_SUBST([PKGCONFIG_REQUIRES_PRIVATE])
|
||||||
|
|
||||||
|
|
||||||
dnl ZLIB
|
dnl ZLIB
|
||||||
@@ -107,6 +134,7 @@ AS_IF([$PKGCONFIG --exists zlib], [
|
|||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
|
CPPFLAGS="$($PKGCONFIG --cflags zlib) $CPPFLAGS"
|
||||||
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
|
LIBS="$($PKGCONFIG --libs zlib) $LIBS"
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE="zlib"
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
AC_CHECK_HEADER([zlib.h])
|
AC_CHECK_HEADER([zlib.h])
|
||||||
@@ -116,17 +144,12 @@ AS_IF([$PKGCONFIG --exists zlib], [
|
|||||||
AC_MSG_ERROR([Sorry, this software requires zlib 1.1 or higher.])
|
AC_MSG_ERROR([Sorry, this software requires zlib 1.1 or higher.])
|
||||||
])
|
])
|
||||||
|
|
||||||
PKGCONFIG_REQUIRES=""
|
|
||||||
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
|
PKGCONFIG_LIBS_PRIVATE="-lz $PKGCONFIG_LIBS_PRIVATE"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl libpng...
|
dnl libpng...
|
||||||
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
|
AC_ARG_ENABLE([libpng], AS_HELP_STRING([--enable-libpng], [use libpng for pdfioFileCreateImageObjFromFile, default=auto]))
|
||||||
|
|
||||||
PKGCONFIG_LIBPNG=""
|
|
||||||
AC_SUBST([PKGCONFIG_LIBPNG])
|
|
||||||
|
|
||||||
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
|
AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
|
||||||
AC_MSG_CHECKING([for libpng-1.6.x])
|
AC_MSG_CHECKING([for libpng-1.6.x])
|
||||||
AS_IF([$PKGCONFIG --exists libpng16], [
|
AS_IF([$PKGCONFIG --exists libpng16], [
|
||||||
@@ -134,8 +157,11 @@ AS_IF([test "x$PKGCONFIG" != x -a x$enable_libpng != xno], [
|
|||||||
AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?])
|
AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?])
|
||||||
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
|
CPPFLAGS="$($PKGCONFIG --cflags libpng16) -DHAVE_LIBPNG=1 $CPPFLAGS"
|
||||||
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
|
LIBS="$($PKGCONFIG --libs libpng16) -lz $LIBS"
|
||||||
PKGCONFIG_LIBS_PRIVATE="$($PKGCONFIG --libs libpng16) $PKGCONFIG_LIBS_PRIVATE"
|
AS_IF([test "x$PKGCONFIG_REQUIRES_PRIVATE" = x], [
|
||||||
PKGCONFIG_REQUIRES="libpng >= 1.6,$PKGCONFIG_REQUIRES"
|
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6"
|
||||||
|
], [
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE="libpng >= 1.6, $PKGCONFIG_REQUIRES_PRIVATE"
|
||||||
|
])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT([no]);
|
AC_MSG_RESULT([no]);
|
||||||
AS_IF([test x$enable_libpng = xyes], [
|
AS_IF([test x$enable_libpng = xyes], [
|
||||||
@@ -168,6 +194,8 @@ AS_IF([test x$enable_shared = xyes], [
|
|||||||
LIBPDFIO_STATIC=""
|
LIBPDFIO_STATIC=""
|
||||||
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
|
PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
|
||||||
PKGCONFIG_LIBS_PRIVATE=""
|
PKGCONFIG_LIBS_PRIVATE=""
|
||||||
|
PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES_PRIVATE"
|
||||||
|
PKGCONFIG_REQUIRES_PRIVATE=""
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_SUBST([LIBPDFIO])
|
AC_SUBST([LIBPDFIO])
|
||||||
|
|||||||
488
doc/pdfio.3
488
doc/pdfio.3
@@ -1,4 +1,4 @@
|
|||||||
.TH pdfio 3 "pdf read/write library" "2025-03-06" "pdf read/write library"
|
.TH pdfio 3 "pdf read/write library" "2025-10-05" "pdf read/write library"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
pdfio \- pdf read/write library
|
pdfio \- pdf read/write library
|
||||||
.SH Introduction
|
.SH Introduction
|
||||||
@@ -325,7 +325,7 @@ where the five arguments to the function are the filename ("myinputfile.pdf"), a
|
|||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.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, 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. It returns true to continue processing the file or false to stop, for example:
|
||||||
.nf
|
.nf
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -335,12 +335,15 @@ The error callback is called for both errors and warnings and accepts the pdfio_
|
|||||||
|
|
||||||
fprintf(stderr, "%s: %s\\n", pdfioFileGetName(pdf), message);
|
fprintf(stderr, "%s: %s\\n", pdfioFileGetName(pdf), message);
|
||||||
|
|
||||||
// Return false to treat warnings as errors
|
// Return true for warning messages (continue) and false for errors (stop)
|
||||||
return (false);
|
return (!strncmp(message, "WARNING:", 8));
|
||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
The default error callback (NULL) does the equivalent of the above.
|
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
|
.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:
|
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
|
.nf
|
||||||
@@ -1029,6 +1032,45 @@ pdfioContentTextShowf draws a formatted string in a text block
|
|||||||
pdfioContentTextShowJustified draws an array of literal strings with offsets between them
|
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
|
.SH Examples
|
||||||
.PP
|
.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.
|
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.
|
||||||
@@ -1047,11 +1089,26 @@ The pdfioinfo.c example program opens a PDF file and prints the title, author, c
|
|||||||
{
|
{
|
||||||
const char *filename; // PDF filename
|
const char *filename; // PDF filename
|
||||||
pdfio_file_t *pdf; // PDF file
|
pdfio_file_t *pdf; // PDF file
|
||||||
const char *author; // Author name
|
pdfio_dict_t *catalog; // Catalog dictionary
|
||||||
time_t creation_date; // Creation date
|
const char *author, // Author name
|
||||||
struct tm *creation_tm; // Creation date/time information
|
*creator, // Creator name
|
||||||
char creation_text[256]; // Creation date/time as a string
|
*producer, // Producer name
|
||||||
const char *title; // Title
|
*title; // Title
|
||||||
|
time_t creation_date, // Creation date
|
||||||
|
modification_date; // Modification date
|
||||||
|
struct tm *creation_tm, // Creation date/time information
|
||||||
|
*modification_tm; // Modification date/time information
|
||||||
|
char creation_text[256], // Creation date/time as a string
|
||||||
|
modification_text[256], // Modification date/time human fmt string
|
||||||
|
range_text[255]; // Page range text
|
||||||
|
size_t num_pages; // PDF number of pages
|
||||||
|
bool has_acroform; // Does the file have an AcroForm?
|
||||||
|
pdfio_obj_t *page; // Object
|
||||||
|
pdfio_dict_t *page_dict; // Object dictionary
|
||||||
|
size_t cur, // Current page index
|
||||||
|
prev; // Previous page index
|
||||||
|
pdfio_rect_t cur_box, // Current MediaBox
|
||||||
|
prev_box; // Previous MediaBox
|
||||||
|
|
||||||
|
|
||||||
// Get the filename from the command\-line...
|
// Get the filename from the command\-line...
|
||||||
@@ -1064,14 +1121,20 @@ The pdfioinfo.c example program opens a PDF file and prints the title, author, c
|
|||||||
filename = argv[1];
|
filename = argv[1];
|
||||||
|
|
||||||
// Open the PDF file with the default callbacks...
|
// Open the PDF file with the default callbacks...
|
||||||
pdf = pdfioFileOpen(filename, /*password_cb*/NULL, /*password_cbdata*/NULL,
|
pdf = pdfioFileOpen(filename, /*password_cb*/NULL,
|
||||||
/*error_cb*/NULL, /*error_cbdata*/NULL);
|
/*password_cbdata*/NULL, /*error_cb*/NULL,
|
||||||
|
/*error_cbdata*/NULL);
|
||||||
if (pdf == NULL)
|
if (pdf == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
// Get the title and author...
|
// Get the title, author, etc...
|
||||||
author = pdfioFileGetAuthor(pdf);
|
catalog = pdfioFileGetCatalog(pdf);
|
||||||
title = pdfioFileGetTitle(pdf);
|
author = pdfioFileGetAuthor(pdf);
|
||||||
|
creator = pdfioFileGetCreator(pdf);
|
||||||
|
has_acroform = pdfioDictGetType(catalog, "AcroForm") != PDFIO_VALTYPE_NONE;
|
||||||
|
num_pages = pdfioFileGetNumPages(pdf);
|
||||||
|
producer = pdfioFileGetProducer(pdf);
|
||||||
|
title = pdfioFileGetTitle(pdf);
|
||||||
|
|
||||||
// Get the creation date and convert to a string...
|
// Get the creation date and convert to a string...
|
||||||
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
|
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
|
||||||
@@ -1084,12 +1147,76 @@ The pdfioinfo.c example program opens a PDF file and prints the title, author, c
|
|||||||
snprintf(creation_text, sizeof(creation_text), "\-\- not set \-\-");
|
snprintf(creation_text, sizeof(creation_text), "\-\- not set \-\-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the modification date and convert to a string...
|
||||||
|
if ((modification_date = pdfioFileGetModificationDate(pdf)) > 0)
|
||||||
|
{
|
||||||
|
modification_tm = localtime(&modification_date);
|
||||||
|
strftime(modification_text, sizeof(modification_text), "%c", modification_tm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(modification_text, sizeof(modification_text), "\-\- not set \-\-");
|
||||||
|
}
|
||||||
|
|
||||||
// Print file information to stdout...
|
// Print file information to stdout...
|
||||||
printf("%s:\\n", filename);
|
printf("%s:\\n", filename);
|
||||||
printf(" Title: %s\\n", title ? title : "\-\- not set \-\-");
|
printf(" Title: %s\\n", title ? title : "\-\- not set \-\-");
|
||||||
printf(" Author: %s\\n", author ? author : "\-\- not set \-\-");
|
printf(" Author: %s\\n", author ? author : "\-\- not set \-\-");
|
||||||
printf(" Created On: %s\\n", creation_text);
|
printf(" Creator: %s\\n", creator ? creator : "\-\- not set \-\-");
|
||||||
printf(" Number Pages: %u\\n", (unsigned)pdfioFileGetNumPages(pdf));
|
printf(" Producer: %s\\n", producer ? producer : "\-\- not set \-\-");
|
||||||
|
printf(" Created On: %s\\n", creation_text);
|
||||||
|
printf(" Modified On: %s\\n", modification_text);
|
||||||
|
printf(" Version: %s\\n", pdfioFileGetVersion(pdf));
|
||||||
|
printf(" AcroForm: %s\\n", has_acroform ? "Yes" : "No");
|
||||||
|
printf(" Number of Pages: %u\\n", (unsigned)num_pages);
|
||||||
|
|
||||||
|
// Report the MediaBox for all of the pages
|
||||||
|
prev_box.x1 = prev_box.x2 = prev_box.y1 = prev_box.y2 = 0.0;
|
||||||
|
|
||||||
|
for (cur = 0, prev = 0; cur < num_pages; cur ++)
|
||||||
|
{
|
||||||
|
// Find the MediaBox for this page in the page tree...
|
||||||
|
for (page = pdfioFileGetPage(pdf, cur);
|
||||||
|
page != NULL;
|
||||||
|
page = pdfioDictGetObj(page_dict, "Parent"))
|
||||||
|
{
|
||||||
|
cur_box.x1 = cur_box.x2 = cur_box.y1 = cur_box.y2 = 0.0;
|
||||||
|
page_dict = pdfioObjGetDict(page);
|
||||||
|
|
||||||
|
if (pdfioDictGetRect(page_dict, "MediaBox", &cur_box))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this MediaBox is different from the previous one, show the range of
|
||||||
|
// pages that have that size...
|
||||||
|
if (cur == 0 ||
|
||||||
|
fabs(cur_box.x1 \- prev_box.x1) > 0.01 ||
|
||||||
|
fabs(cur_box.y1 \- prev_box.y1) > 0.01 ||
|
||||||
|
fabs(cur_box.x2 \- prev_box.x2) > 0.01 ||
|
||||||
|
fabs(cur_box.y2 \- prev_box.y2) > 0.01)
|
||||||
|
{
|
||||||
|
if (cur > prev)
|
||||||
|
{
|
||||||
|
snprintf(range_text, sizeof(range_text), "Pages %u\-%u",
|
||||||
|
(unsigned)(prev + 1), (unsigned)cur);
|
||||||
|
printf("%16s: [%g %g %g %g]\\n", range_text,
|
||||||
|
prev_box.x1, prev_box.y1, prev_box.x2, prev_box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a new series of pages with the new size...
|
||||||
|
prev = cur;
|
||||||
|
prev_box = cur_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the last range as needed...
|
||||||
|
if (cur > prev)
|
||||||
|
{
|
||||||
|
snprintf(range_text, sizeof(range_text), "Pages %u\-%u",
|
||||||
|
(unsigned)(prev + 1), (unsigned)cur);
|
||||||
|
printf("%16s: [%g %g %g %g]\\n", range_text,
|
||||||
|
prev_box.x1, prev_box.y1, prev_box.x2, prev_box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
// Close the PDF file...
|
// Close the PDF file...
|
||||||
pdfioFileClose(pdf);
|
pdfioFileClose(pdf);
|
||||||
@@ -1603,6 +1730,9 @@ The md2pdf program needs to maintain three sets of state \- one for the markdown
|
|||||||
// State for the current page
|
// State for the current page
|
||||||
pdfio_stream_t *st; // Current page stream
|
pdfio_stream_t *st; // Current page stream
|
||||||
double y; // Current position on page
|
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
|
docfont_t font; // Current font
|
||||||
double fsize; // Current font size
|
double fsize; // Current font size
|
||||||
doccolor_t color; // Current color
|
doccolor_t color; // Current color
|
||||||
@@ -2079,6 +2209,9 @@ Code blocks consist of one or more lines of plain monospaced text. We draw a lig
|
|||||||
pdfioContentFillAndStroke(dd\->st, false);
|
pdfioContentFillAndStroke(dd\->st, false);
|
||||||
|
|
||||||
// Start a code text block...
|
// Start a code text block...
|
||||||
|
dd\->tag = "P";
|
||||||
|
pdfioContentBeginMarked(dd\->st, dd\->tag, /*dict*/NULL);
|
||||||
|
|
||||||
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
||||||
pdfioContentTextBegin(dd\->st);
|
pdfioContentTextBegin(dd\->st);
|
||||||
pdfioContentTextMoveTo(dd\->st, left, dd\->y);
|
pdfioContentTextMoveTo(dd\->st, left, dd\->y);
|
||||||
@@ -2115,6 +2248,9 @@ Code blocks consist of one or more lines of plain monospaced text. We draw a lig
|
|||||||
pdfioContentTextEnd(dd\->st);
|
pdfioContentTextEnd(dd\->st);
|
||||||
dd\->y += lineheight;
|
dd\->y += lineheight;
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd\->st);
|
||||||
|
dd\->tag = NULL;
|
||||||
|
|
||||||
// Draw the bottom padding...
|
// Draw the bottom padding...
|
||||||
set_color(dd, DOCCOLOR_LTGRAY);
|
set_color(dd, DOCCOLOR_LTGRAY);
|
||||||
pdfioContentPathRect(dd\->st, left \- CODE_PADDING,
|
pdfioContentPathRect(dd\->st, left \- CODE_PADDING,
|
||||||
@@ -2244,8 +2380,17 @@ Finally, we render each row in the table:
|
|||||||
.nf
|
.nf
|
||||||
|
|
||||||
// Render each table row...
|
// 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 ++)
|
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
|
||||||
render_row(dd, num_cols, cols, rowptr);
|
render_row(dd, num_cols, cols, rowptr);
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd\->st);
|
||||||
|
|
||||||
|
dd\->in_table = false;
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Rendering the Markdown Document
|
Rendering the Markdown Document
|
||||||
@@ -2364,6 +2509,10 @@ PDFIO_CS_ADOBE
|
|||||||
.br
|
.br
|
||||||
AdobeRGB 1998
|
AdobeRGB 1998
|
||||||
.TP 5
|
.TP 5
|
||||||
|
PDFIO_CS_CGATS001
|
||||||
|
.br
|
||||||
|
CGATS001 (CMYK)
|
||||||
|
.TP 5
|
||||||
PDFIO_CS_P3_D65
|
PDFIO_CS_P3_D65
|
||||||
.br
|
.br
|
||||||
Display P3
|
Display P3
|
||||||
@@ -2392,7 +2541,7 @@ PDFIO_ENCRYPTION_RC4_128
|
|||||||
.TP 5
|
.TP 5
|
||||||
PDFIO_ENCRYPTION_RC4_40
|
PDFIO_ENCRYPTION_RC4_40
|
||||||
.br
|
.br
|
||||||
40-bit RC4 encryption (PDF 1.3)
|
40-bit RC4 encryption (PDF 1.3, reading only)
|
||||||
.SS pdfio_filter_e
|
.SS pdfio_filter_e
|
||||||
Compression/decompression filters for streams
|
Compression/decompression filters for streams
|
||||||
.TP 5
|
.TP 5
|
||||||
@@ -2753,7 +2902,8 @@ pdfio_array_t * pdfioArrayCreateColorFromStandard (
|
|||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
This function creates a color array for a standard \fBPDFIO_CS_\fR enumerated color space.
|
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 and \fB3\fR for RGB color.
|
The "num_colors" argument must be \fB1\fR for grayscale, \fB3\fR for RGB color, and
|
||||||
|
\fB4\fR for CMYK color.
|
||||||
.SS pdfioArrayGetArray
|
.SS pdfioArrayGetArray
|
||||||
Get an array value from an array.
|
Get an array value from an array.
|
||||||
.PP
|
.PP
|
||||||
@@ -2862,6 +3012,32 @@ bool pdfioArrayRemove (
|
|||||||
size_t n
|
size_t n
|
||||||
);
|
);
|
||||||
.fi
|
.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
|
.SS pdfioContentClip
|
||||||
Clip output to the current path.
|
Clip output to the current path.
|
||||||
.PP
|
.PP
|
||||||
@@ -2887,6 +3063,19 @@ bool pdfioContentDrawImage (
|
|||||||
.PP
|
.PP
|
||||||
The object name must be part of the page dictionary resources, typically
|
The object name must be part of the page dictionary resources, typically
|
||||||
using the \fIpdfioPageDictAddImage\fR function.
|
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
|
.SS pdfioContentFill
|
||||||
Fill the current path.
|
Fill the current path.
|
||||||
.PP
|
.PP
|
||||||
@@ -2998,6 +3187,8 @@ bool pdfioContentPathEnd (
|
|||||||
pdfio_stream_t *st
|
pdfio_stream_t *st
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioContentPathLineTo
|
.SS pdfioContentPathLineTo
|
||||||
Add a straight line to the current path.
|
Add a straight line to the current path.
|
||||||
.PP
|
.PP
|
||||||
@@ -3338,6 +3529,8 @@ double pdfioContentTextMeasure (
|
|||||||
This function measures the given text string "s" and returns its width based
|
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
|
on "size". The text string must always use the UTF-8 (Unicode) encoding but
|
||||||
any control characters (such as newlines) are ignored.
|
any control characters (such as newlines) are ignored.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioContentTextMoveLine
|
.SS pdfioContentTextMoveLine
|
||||||
Move to the next line and offset.
|
Move to the next line and offset.
|
||||||
.PP
|
.PP
|
||||||
@@ -3366,6 +3559,8 @@ bool pdfioContentTextNewLine (
|
|||||||
pdfio_stream_t *st
|
pdfio_stream_t *st
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioContentTextNewLineShow
|
.SS pdfioContentTextNewLineShow
|
||||||
Move to the next line and show text.
|
Move to the next line and show text.
|
||||||
.PP
|
.PP
|
||||||
@@ -3383,6 +3578,8 @@ 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
|
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 that the current font maps to full Unicode. The "s" argument
|
||||||
specifies a UTF-8 encoded string.
|
specifies a UTF-8 encoded string.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioContentTextNewLineShowf
|
.SS pdfioContentTextNewLineShowf
|
||||||
Show formatted text.
|
Show formatted text.
|
||||||
.PP
|
.PP
|
||||||
@@ -3401,6 +3598,8 @@ 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"
|
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 that the current font maps to full Unicode. The "format"
|
||||||
argument specifies a UTF-8 encoded \fBprintf\fR-style format string.
|
argument specifies a UTF-8 encoded \fBprintf\fR-style format string.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioContentTextShow
|
.SS pdfioContentTextShow
|
||||||
Show text.
|
Show text.
|
||||||
.PP
|
.PP
|
||||||
@@ -3451,6 +3650,8 @@ bool pdfioDictClear (
|
|||||||
const char *key
|
const char *key
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioDictCopy
|
.SS pdfioDictCopy
|
||||||
Copy a dictionary to a PDF file.
|
Copy a dictionary to a PDF file.
|
||||||
.PP
|
.PP
|
||||||
@@ -3523,6 +3724,8 @@ const char * pdfioDictGetKey (
|
|||||||
size_t n
|
size_t n
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioDictGetName
|
.SS pdfioDictGetName
|
||||||
Get a key name value from a dictionary.
|
Get a key name value from a dictionary.
|
||||||
.PP
|
.PP
|
||||||
@@ -3540,6 +3743,8 @@ size_t pdfioDictGetNumPairs (
|
|||||||
pdfio_dict_t *dict
|
pdfio_dict_t *dict
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioDictGetNumber
|
.SS pdfioDictGetNumber
|
||||||
Get a key number value from a dictionary.
|
Get a key number value from a dictionary.
|
||||||
.PP
|
.PP
|
||||||
@@ -3612,6 +3817,8 @@ function "cb":
|
|||||||
|
|
||||||
The iteration continues as long as the callback returns \fBtrue\fR or all keys
|
The iteration continues as long as the callback returns \fBtrue\fR or all keys
|
||||||
have been iterated.
|
have been iterated.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioDictSetArray
|
.SS pdfioDictSetArray
|
||||||
Set a key array in a dictionary.
|
Set a key array in a dictionary.
|
||||||
.PP
|
.PP
|
||||||
@@ -3733,6 +3940,39 @@ bool pdfioDictSetStringf (
|
|||||||
...
|
...
|
||||||
);
|
);
|
||||||
.fi
|
.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
|
.SS pdfioFileClose
|
||||||
Close a PDF file and free all memory used for it.
|
Close a PDF file and free all memory used for it.
|
||||||
.PP
|
.PP
|
||||||
@@ -3759,16 +3999,56 @@ This function creates a new PDF file. The "filename" argument specifies the
|
|||||||
name of the PDF file to create.
|
name of the PDF file to create.
|
||||||
.PP
|
.PP
|
||||||
The "version" argument specifies the PDF version number for the file or
|
The "version" argument specifies the PDF version number for the file or
|
||||||
\fBNULL\fR for the default ("2.0"). The value "PCLm-1.0" can be specified to
|
\fBNULL\fR for the default ("2.0"). The following values are recognized:
|
||||||
produce the PCLm subset of PDF.
|
.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
|
||||||
.PP
|
.PP
|
||||||
The "media_box" and "crop_box" arguments specify the default MediaBox and
|
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
|
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.
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
|
||||||
.PP
|
.PP
|
||||||
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if \fBNULL\fR the default error handler is used that
|
and its data pointer - if \fBNULL\fR then the default error handler is used that
|
||||||
writes error messages to \fBstderr\fR.
|
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
|
||||||
|
|
||||||
.SS pdfioFileCreateArrayObj
|
.SS pdfioFileCreateArrayObj
|
||||||
Create a new object in a PDF file containing an array.
|
Create a new object in a PDF file containing an array.
|
||||||
.PP
|
.PP
|
||||||
@@ -3826,8 +4106,30 @@ specifies the font nane:
|
|||||||
Aside from "Symbol" and "Zapf-Dingbats", Base fonts use the Windows CP1252
|
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
|
(ISO-8859-1 with additional characters such as the Euro symbol) subset of
|
||||||
Unicode.
|
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
|
.SS pdfioFileCreateFontObjFromFile
|
||||||
Add a font object to a PDF file.
|
Add a font file to a PDF file.
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
pdfio_obj_t * pdfioFileCreateFontObjFromFile (
|
pdfio_obj_t * pdfioFileCreateFontObjFromFile (
|
||||||
@@ -3837,7 +4139,7 @@ pdfio_obj_t * pdfioFileCreateFontObjFromFile (
|
|||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
This function embeds a TrueType/OpenType font into a PDF file. The
|
This function embeds a TrueType/OpenType font file into a PDF file. The
|
||||||
"unicode" parameter controls whether the font is encoded for two-byte
|
"unicode" parameter controls whether the font is encoded for two-byte
|
||||||
characters (potentially full Unicode, but more typically a subset)
|
characters (potentially full Unicode, but more typically a subset)
|
||||||
or to only support the Windows CP1252 (ISO-8859-1 with additional
|
or to only support the Windows CP1252 (ISO-8859-1 with additional
|
||||||
@@ -3890,8 +4192,12 @@ the image is encoded in the corresponding device color space. The
|
|||||||
"interpolate" parameter specifies whether to interpolate when scaling the
|
"interpolate" parameter specifies whether to interpolate when scaling the
|
||||||
image on the page.
|
image on the page.
|
||||||
.PP
|
.PP
|
||||||
|
.IP 5
|
||||||
Note: When creating an image object with alpha, a second image object is
|
Note: When creating an image object with alpha, a second image object is
|
||||||
created to hold the "soft mask" data for the primary image.
|
.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.
|
||||||
.SS pdfioFileCreateImageObjFromFile
|
.SS pdfioFileCreateImageObjFromFile
|
||||||
Add an image object to a PDF file from a file.
|
Add an image object to a PDF file from a file.
|
||||||
.PP
|
.PP
|
||||||
@@ -3909,11 +4215,9 @@ the "interpolate" parameter specifies whether to interpolate when scaling the
|
|||||||
image on the page.
|
image on the page.
|
||||||
.PP
|
.PP
|
||||||
.IP 5
|
.IP 5
|
||||||
Note: Currently PNG support is limited to grayscale, RGB, or indexed files
|
Note: PNG files containing transparency cannot be used when producing
|
||||||
.IP 5
|
.IP 5
|
||||||
without interlacing or alpha. Transparency (masking) based on color/index
|
PDF/A files.
|
||||||
.IP 5
|
|
||||||
is supported.
|
|
||||||
.SS pdfioFileCreateNameObj
|
.SS pdfioFileCreateNameObj
|
||||||
Create a new object in a PDF file containing a name.
|
Create a new object in a PDF file containing a name.
|
||||||
.PP
|
.PP
|
||||||
@@ -3926,6 +4230,8 @@ pdfio_obj_t * pdfioFileCreateNameObj (
|
|||||||
.PP
|
.PP
|
||||||
This function creates a new object with a name value in a PDF file.
|
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.
|
You must call \fIpdfioObjClose\fR to write the object to the file.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioFileCreateNumberObj
|
.SS pdfioFileCreateNumberObj
|
||||||
Create a new object in a PDF file containing a number.
|
Create a new object in a PDF file containing a number.
|
||||||
.PP
|
.PP
|
||||||
@@ -3938,6 +4244,8 @@ pdfio_obj_t * pdfioFileCreateNumberObj (
|
|||||||
.PP
|
.PP
|
||||||
This function creates a new object with a number value in a PDF file.
|
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.
|
You must call \fIpdfioObjClose\fR to write the object to the file.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioFileCreateObj
|
.SS pdfioFileCreateObj
|
||||||
Create a new object in a PDF file.
|
Create a new object in a PDF file.
|
||||||
.PP
|
.PP
|
||||||
@@ -3977,18 +4285,57 @@ written:
|
|||||||
.fi
|
.fi
|
||||||
|
|
||||||
The "version" argument specifies the PDF version number for the file or
|
The "version" argument specifies the PDF version number for the file or
|
||||||
\fBNULL\fR for the default ("2.0"). Unlike \fIpdfioFileCreate\fR and
|
\fBNULL\fR for the default ("2.0"). The following values are recognized:
|
||||||
\fIpdfioFileCreateTemporary\fR, it is generally not safe to pass the
|
.PP
|
||||||
"PCLm-1.0" version string.
|
.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.
|
||||||
.PP
|
.PP
|
||||||
The "media_box" and "crop_box" arguments specify the default MediaBox and
|
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
|
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.
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
|
||||||
.PP
|
.PP
|
||||||
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if \fBNULL\fR the default error handler is used that
|
and its data pointer - if \fBNULL\fR then the default error handler is used that
|
||||||
writes error messages to \fBstderr\fR.
|
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
|
.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
|
.IP 5
|
||||||
\fINote\fR: Files created using this API are slightly larger than those
|
\fINote\fR: Files created using this API are slightly larger than those
|
||||||
.IP 5
|
.IP 5
|
||||||
@@ -4016,6 +4363,8 @@ pdfio_obj_t * pdfioFileCreateStringObj (
|
|||||||
.PP
|
.PP
|
||||||
This function creates a new object with a string value in a PDF file.
|
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.
|
You must call \fIpdfioObjClose\fR to write the object to the file.
|
||||||
|
|
||||||
|
|
||||||
.SS pdfioFileCreateTemporary
|
.SS pdfioFileCreateTemporary
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
@@ -4092,6 +4441,21 @@ const char * pdfioFileGetKeywords (
|
|||||||
pdfio_file_t *pdf
|
pdfio_file_t *pdf
|
||||||
);
|
);
|
||||||
.fi
|
.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
|
.SS pdfioFileGetModificationDate
|
||||||
Get the most recent modification date for a PDF file.
|
Get the most recent modification date for a PDF file.
|
||||||
.PP
|
.PP
|
||||||
@@ -4209,8 +4573,33 @@ cancel the open. If \fBNULL\fR is specified for the callback function and the
|
|||||||
PDF file requires a password, the open will always fail.
|
PDF file requires a password, the open will always fail.
|
||||||
.PP
|
.PP
|
||||||
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if \fBNULL\fR the default error handler is used that
|
and its data pointer - if \fBNULL\fR then the default error handler is used that
|
||||||
writes error messages to \fBstderr\fR.
|
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.
|
||||||
.SS pdfioFileSetAuthor
|
.SS pdfioFileSetAuthor
|
||||||
Set the author for a PDF file.
|
Set the author for a PDF file.
|
||||||
.PP
|
.PP
|
||||||
@@ -4247,6 +4636,22 @@ void pdfioFileSetKeywords (
|
|||||||
const char *value
|
const char *value
|
||||||
);
|
);
|
||||||
.fi
|
.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
|
.SS pdfioFileSetModificationDate
|
||||||
Set the modification date for a PDF file.
|
Set the modification date for a PDF file.
|
||||||
.PP
|
.PP
|
||||||
@@ -4389,6 +4794,8 @@ const char * pdfioObjGetName (
|
|||||||
pdfio_obj_t *obj
|
pdfio_obj_t *obj
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioObjGetNumber
|
.SS pdfioObjGetNumber
|
||||||
Get the object's number.
|
Get the object's number.
|
||||||
.PP
|
.PP
|
||||||
@@ -4590,6 +4997,11 @@ bool pdfioStreamPrintf (
|
|||||||
...
|
...
|
||||||
);
|
);
|
||||||
.fi
|
.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.
|
||||||
.SS pdfioStreamPutChar
|
.SS pdfioStreamPutChar
|
||||||
Write a single character to a stream.
|
Write a single character to a stream.
|
||||||
.PP
|
.PP
|
||||||
|
|||||||
577
doc/pdfio.html
577
doc/pdfio.html
@@ -1,13 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en-US">
|
<html lang="en-US">
|
||||||
<head>
|
<head>
|
||||||
<title>PDFio Programming Manual v1.5.0</title>
|
<title>PDFio Programming Manual v1.6.0</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||||
<meta name="generator" content="codedoc v3.8">
|
<meta name="generator" content="codedoc v3.8">
|
||||||
<meta name="author" content="Michael R Sweet">
|
<meta name="author" content="Michael R Sweet">
|
||||||
<meta name="language" content="en-US">
|
<meta name="language" content="en-US">
|
||||||
<meta name="copyright" content="Copyright © 2021-2025 by Michael R Sweet">
|
<meta name="copyright" content="Copyright © 2021-2025 by Michael R Sweet">
|
||||||
<meta name="version" content="1.5.0">
|
<meta name="version" content="1.6.0">
|
||||||
<style type="text/css"><!--
|
<style type="text/css"><!--
|
||||||
body {
|
body {
|
||||||
background: white;
|
background: white;
|
||||||
@@ -251,7 +251,7 @@ span.string {
|
|||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<p><img class="title" src="pdfio-512.png"></p>
|
<p><img class="title" src="pdfio-512.png"></p>
|
||||||
<h1 class="title">PDFio Programming Manual v1.5.0</h1>
|
<h1 class="title">PDFio Programming Manual v1.6.0</h1>
|
||||||
<p>Michael R Sweet</p>
|
<p>Michael R Sweet</p>
|
||||||
<p>Copyright © 2021-2025 by Michael R Sweet</p>
|
<p>Copyright © 2021-2025 by Michael R Sweet</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -273,6 +273,7 @@ span.string {
|
|||||||
<li><a href="#pdf-objects">PDF Objects</a></li>
|
<li><a href="#pdf-objects">PDF Objects</a></li>
|
||||||
<li><a href="#pdf-streams">PDF Streams</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="#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>
|
</ul></li>
|
||||||
<li><a href="#examples">Examples</a><ul class="subcontents">
|
<li><a href="#examples">Examples</a><ul class="subcontents">
|
||||||
<li><a href="#read-pdf-metadata">Read PDF Metadata</a></li>
|
<li><a href="#read-pdf-metadata">Read PDF Metadata</a></li>
|
||||||
@@ -310,8 +311,10 @@ span.string {
|
|||||||
<li><a href="#pdfioArrayGetString">pdfioArrayGetString</a></li>
|
<li><a href="#pdfioArrayGetString">pdfioArrayGetString</a></li>
|
||||||
<li><a href="#pdfioArrayGetType">pdfioArrayGetType</a></li>
|
<li><a href="#pdfioArrayGetType">pdfioArrayGetType</a></li>
|
||||||
<li><a href="#pdfioArrayRemove">pdfioArrayRemove</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="#pdfioContentClip">pdfioContentClip</a></li>
|
||||||
<li><a href="#pdfioContentDrawImage">pdfioContentDrawImage</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="#pdfioContentFill">pdfioContentFill</a></li>
|
||||||
<li><a href="#pdfioContentFillAndStroke">pdfioContentFillAndStroke</a></li>
|
<li><a href="#pdfioContentFillAndStroke">pdfioContentFillAndStroke</a></li>
|
||||||
<li><a href="#pdfioContentMatrixConcat">pdfioContentMatrixConcat</a></li>
|
<li><a href="#pdfioContentMatrixConcat">pdfioContentMatrixConcat</a></li>
|
||||||
@@ -395,10 +398,12 @@ span.string {
|
|||||||
<li><a href="#pdfioDictSetRect">pdfioDictSetRect</a></li>
|
<li><a href="#pdfioDictSetRect">pdfioDictSetRect</a></li>
|
||||||
<li><a href="#pdfioDictSetString">pdfioDictSetString</a></li>
|
<li><a href="#pdfioDictSetString">pdfioDictSetString</a></li>
|
||||||
<li><a href="#pdfioDictSetStringf">pdfioDictSetStringf</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="#pdfioFileClose">pdfioFileClose</a></li>
|
||||||
<li><a href="#pdfioFileCreate">pdfioFileCreate</a></li>
|
<li><a href="#pdfioFileCreate">pdfioFileCreate</a></li>
|
||||||
<li><a href="#pdfioFileCreateArrayObj">pdfioFileCreateArrayObj</a></li>
|
<li><a href="#pdfioFileCreateArrayObj">pdfioFileCreateArrayObj</a></li>
|
||||||
<li><a href="#pdfioFileCreateFontObjFromBase">pdfioFileCreateFontObjFromBase</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="#pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></li>
|
||||||
<li><a href="#pdfioFileCreateICCObjFromData">pdfioFileCreateICCObjFromData</a></li>
|
<li><a href="#pdfioFileCreateICCObjFromData">pdfioFileCreateICCObjFromData</a></li>
|
||||||
<li><a href="#pdfioFileCreateICCObjFromFile">pdfioFileCreateICCObjFromFile</a></li>
|
<li><a href="#pdfioFileCreateICCObjFromFile">pdfioFileCreateICCObjFromFile</a></li>
|
||||||
@@ -418,6 +423,7 @@ span.string {
|
|||||||
<li><a href="#pdfioFileGetCreator">pdfioFileGetCreator</a></li>
|
<li><a href="#pdfioFileGetCreator">pdfioFileGetCreator</a></li>
|
||||||
<li><a href="#pdfioFileGetID">pdfioFileGetID</a></li>
|
<li><a href="#pdfioFileGetID">pdfioFileGetID</a></li>
|
||||||
<li><a href="#pdfioFileGetKeywords">pdfioFileGetKeywords</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="#pdfioFileGetModificationDate">pdfioFileGetModificationDate</a></li>
|
||||||
<li><a href="#pdfioFileGetName">pdfioFileGetName</a></li>
|
<li><a href="#pdfioFileGetName">pdfioFileGetName</a></li>
|
||||||
<li><a href="#pdfioFileGetNumObjs">pdfioFileGetNumObjs</a></li>
|
<li><a href="#pdfioFileGetNumObjs">pdfioFileGetNumObjs</a></li>
|
||||||
@@ -434,6 +440,7 @@ span.string {
|
|||||||
<li><a href="#pdfioFileSetCreationDate">pdfioFileSetCreationDate</a></li>
|
<li><a href="#pdfioFileSetCreationDate">pdfioFileSetCreationDate</a></li>
|
||||||
<li><a href="#pdfioFileSetCreator">pdfioFileSetCreator</a></li>
|
<li><a href="#pdfioFileSetCreator">pdfioFileSetCreator</a></li>
|
||||||
<li><a href="#pdfioFileSetKeywords">pdfioFileSetKeywords</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="#pdfioFileSetModificationDate">pdfioFileSetModificationDate</a></li>
|
||||||
<li><a href="#pdfioFileSetPermissions">pdfioFileSetPermissions</a></li>
|
<li><a href="#pdfioFileSetPermissions">pdfioFileSetPermissions</a></li>
|
||||||
<li><a href="#pdfioFileSetSubject">pdfioFileSetSubject</a></li>
|
<li><a href="#pdfioFileSetSubject">pdfioFileSetSubject</a></li>
|
||||||
@@ -728,7 +735,7 @@ password_cb(<span class="reserved">void</span> *data, <span class="reserved">con
|
|||||||
<span class="reserved">return</span> (<span class="string">"Password42"</span>);
|
<span class="reserved">return</span> (<span class="string">"Password42"</span>);
|
||||||
}
|
}
|
||||||
</code></pre>
|
</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, 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. It returns <code>true</code> to continue processing the file or <code>false</code> to stop, for example:</p>
|
||||||
<pre><code class="language-c"><span class="reserved">bool</span>
|
<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)
|
error_cb(pdfio_file_t *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *message, <span class="reserved">void</span> *data)
|
||||||
{
|
{
|
||||||
@@ -736,11 +743,14 @@ error_cb(pdfio_file_t *pdf, <span class="reserved">const</span> <span class="res
|
|||||||
|
|
||||||
fprintf(stderr, <span class="string">"%s: %s\n"</span>, pdfioFileGetName(pdf), message);
|
fprintf(stderr, <span class="string">"%s: %s\n"</span>, pdfioFileGetName(pdf), message);
|
||||||
|
|
||||||
<span class="comment">// Return false to treat warnings as errors</span>
|
<span class="comment">// Return true for warning messages (continue) and false for errors (stop)</span>
|
||||||
<span class="reserved">return</span> (<span class="reserved">false</span>);
|
<span class="reserved">return</span> (!strncmp(message, <span class="string">"WARNING:"</span>, <span class="number">8</span>));
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<p>The default error callback (<code>NULL</code>) does the equivalent of the above.</p>
|
<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 "WARNING:" 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>
|
<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>
|
<pre><code class="language-c">pdfio_file_t *pdf; <span class="comment">// PDF file</span>
|
||||||
size_t i; <span class="comment">// Looping var</span>
|
size_t i; <span class="comment">// Looping var</span>
|
||||||
@@ -1151,6 +1161,38 @@ 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><p><a href="#pdfioContentTextShowJustified"><code>pdfioContentTextShowJustified</code></a> draws an array of literal strings with offsets between them</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</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 ("MCID"). 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">"P"</span>, <span class="comment">/*dict*/</span>NULL);
|
||||||
|
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"Mary had a little lamb\n"</span>);
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"whose fleece was white as snow.\n"</span>);
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"And everywhere that Mary went\n"</span>);
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"the lamb was sure to go,\n"</span>);
|
||||||
|
|
||||||
|
pdfioContentEndMarked(st);
|
||||||
|
</code></pre>
|
||||||
|
<p>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:</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">"MCID"</span>, <span class="number">42</span>);
|
||||||
|
|
||||||
|
pdfioContentBeginMarked(st, <span class="string">"P"</span>, dict);
|
||||||
|
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"Mary had a little lamb\n"</span>);
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"whose fleece was white as snow.\n"</span>);
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"And everywhere that Mary went\n"</span>);
|
||||||
|
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">"the lamb was sure to go,\n"</span>);
|
||||||
|
|
||||||
|
pdfioContentEndMarked(st);
|
||||||
|
</code></pre>
|
||||||
<h2 class="title" id="examples">Examples</h2>
|
<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>
|
<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>
|
<h3 class="title" id="read-pdf-metadata">Read PDF Metadata</h3>
|
||||||
@@ -1165,11 +1207,26 @@ main(<span class="reserved">int</span> argc, <span clas
|
|||||||
{
|
{
|
||||||
<span class="reserved">const</span> <span class="reserved">char</span> *filename; <span class="comment">// PDF filename</span>
|
<span class="reserved">const</span> <span class="reserved">char</span> *filename; <span class="comment">// PDF filename</span>
|
||||||
pdfio_file_t *pdf; <span class="comment">// PDF file</span>
|
pdfio_file_t *pdf; <span class="comment">// PDF file</span>
|
||||||
<span class="reserved">const</span> <span class="reserved">char</span> *author; <span class="comment">// Author name</span>
|
pdfio_dict_t *catalog; <span class="comment">// Catalog dictionary</span>
|
||||||
time_t creation_date; <span class="comment">// Creation date</span>
|
<span class="reserved">const</span> <span class="reserved">char</span> *author, <span class="comment">// Author name</span>
|
||||||
<span class="reserved">struct</span> tm *creation_tm; <span class="comment">// Creation date/time information</span>
|
*creator, <span class="comment">// Creator name</span>
|
||||||
<span class="reserved">char</span> creation_text[<span class="number">256</span>]; <span class="comment">// Creation date/time as a string</span>
|
*producer, <span class="comment">// Producer name</span>
|
||||||
<span class="reserved">const</span> <span class="reserved">char</span> *title; <span class="comment">// Title</span>
|
*title; <span class="comment">// Title</span>
|
||||||
|
time_t creation_date, <span class="comment">// Creation date</span>
|
||||||
|
modification_date; <span class="comment">// Modification date</span>
|
||||||
|
<span class="reserved">struct</span> tm *creation_tm, <span class="comment">// Creation date/time information</span>
|
||||||
|
*modification_tm; <span class="comment">// Modification date/time information</span>
|
||||||
|
<span class="reserved">char</span> creation_text[<span class="number">256</span>], <span class="comment">// Creation date/time as a string</span>
|
||||||
|
modification_text[<span class="number">256</span>], <span class="comment">// Modification date/time human fmt string</span>
|
||||||
|
range_text[<span class="number">255</span>]; <span class="comment">// Page range text</span>
|
||||||
|
size_t num_pages; <span class="comment">// PDF number of pages</span>
|
||||||
|
<span class="reserved">bool</span> has_acroform; <span class="comment">// Does the file have an AcroForm?</span>
|
||||||
|
pdfio_obj_t *page; <span class="comment">// Object</span>
|
||||||
|
pdfio_dict_t *page_dict; <span class="comment">// Object dictionary</span>
|
||||||
|
size_t cur, <span class="comment">// Current page index</span>
|
||||||
|
prev; <span class="comment">// Previous page index</span>
|
||||||
|
pdfio_rect_t cur_box, <span class="comment">// Current MediaBox</span>
|
||||||
|
prev_box; <span class="comment">// Previous MediaBox</span>
|
||||||
|
|
||||||
|
|
||||||
<span class="comment">// Get the filename from the command-line...</span>
|
<span class="comment">// Get the filename from the command-line...</span>
|
||||||
@@ -1182,14 +1239,20 @@ main(<span class="reserved">int</span> argc, <span clas
|
|||||||
filename = argv[<span class="number">1</span>];
|
filename = argv[<span class="number">1</span>];
|
||||||
|
|
||||||
<span class="comment">// Open the PDF file with the default callbacks...</span>
|
<span class="comment">// Open the PDF file with the default callbacks...</span>
|
||||||
pdf = pdfioFileOpen(filename, <span class="comment">/*password_cb*/</span>NULL, <span class="comment">/*password_cbdata*/</span>NULL,
|
pdf = pdfioFileOpen(filename, <span class="comment">/*password_cb*/</span>NULL,
|
||||||
<span class="comment">/*error_cb*/</span>NULL, <span class="comment">/*error_cbdata*/</span>NULL);
|
<span class="comment">/*password_cbdata*/</span>NULL, <span class="comment">/*error_cb*/</span>NULL,
|
||||||
|
<span class="comment">/*error_cbdata*/</span>NULL);
|
||||||
<span class="reserved">if</span> (pdf == NULL)
|
<span class="reserved">if</span> (pdf == NULL)
|
||||||
<span class="reserved">return</span> (<span class="number">1</span>);
|
<span class="reserved">return</span> (<span class="number">1</span>);
|
||||||
|
|
||||||
<span class="comment">// Get the title and author...</span>
|
<span class="comment">// Get the title, author, etc...</span>
|
||||||
author = pdfioFileGetAuthor(pdf);
|
catalog = pdfioFileGetCatalog(pdf);
|
||||||
title = pdfioFileGetTitle(pdf);
|
author = pdfioFileGetAuthor(pdf);
|
||||||
|
creator = pdfioFileGetCreator(pdf);
|
||||||
|
has_acroform = pdfioDictGetType(catalog, <span class="string">"AcroForm"</span>) != PDFIO_VALTYPE_NONE;
|
||||||
|
num_pages = pdfioFileGetNumPages(pdf);
|
||||||
|
producer = pdfioFileGetProducer(pdf);
|
||||||
|
title = pdfioFileGetTitle(pdf);
|
||||||
|
|
||||||
<span class="comment">// Get the creation date and convert to a string...</span>
|
<span class="comment">// Get the creation date and convert to a string...</span>
|
||||||
<span class="reserved">if</span> ((creation_date = pdfioFileGetCreationDate(pdf)) > <span class="number">0</span>)
|
<span class="reserved">if</span> ((creation_date = pdfioFileGetCreationDate(pdf)) > <span class="number">0</span>)
|
||||||
@@ -1202,12 +1265,76 @@ main(<span class="reserved">int</span> argc, <span clas
|
|||||||
snprintf(creation_text, <span class="reserved">sizeof</span>(creation_text), <span class="string">"-- not set --"</span>);
|
snprintf(creation_text, <span class="reserved">sizeof</span>(creation_text), <span class="string">"-- not set --"</span>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<span class="comment">// Get the modification date and convert to a string...</span>
|
||||||
|
<span class="reserved">if</span> ((modification_date = pdfioFileGetModificationDate(pdf)) > <span class="number">0</span>)
|
||||||
|
{
|
||||||
|
modification_tm = localtime(&modification_date);
|
||||||
|
strftime(modification_text, <span class="reserved">sizeof</span>(modification_text), <span class="string">"%c"</span>, modification_tm);
|
||||||
|
}
|
||||||
|
<span class="reserved">else</span>
|
||||||
|
{
|
||||||
|
snprintf(modification_text, <span class="reserved">sizeof</span>(modification_text), <span class="string">"-- not set --"</span>);
|
||||||
|
}
|
||||||
|
|
||||||
<span class="comment">// Print file information to stdout...</span>
|
<span class="comment">// Print file information to stdout...</span>
|
||||||
printf(<span class="string">"%s:\n"</span>, filename);
|
printf(<span class="string">"%s:\n"</span>, filename);
|
||||||
printf(<span class="string">" Title: %s\n"</span>, title ? title : <span class="string">"-- not set --"</span>);
|
printf(<span class="string">" Title: %s\n"</span>, title ? title : <span class="string">"-- not set --"</span>);
|
||||||
printf(<span class="string">" Author: %s\n"</span>, author ? author : <span class="string">"-- not set --"</span>);
|
printf(<span class="string">" Author: %s\n"</span>, author ? author : <span class="string">"-- not set --"</span>);
|
||||||
printf(<span class="string">" Created On: %s\n"</span>, creation_text);
|
printf(<span class="string">" Creator: %s\n"</span>, creator ? creator : <span class="string">"-- not set --"</span>);
|
||||||
printf(<span class="string">" Number Pages: %u\n"</span>, (<span class="reserved">unsigned</span>)pdfioFileGetNumPages(pdf));
|
printf(<span class="string">" Producer: %s\n"</span>, producer ? producer : <span class="string">"-- not set --"</span>);
|
||||||
|
printf(<span class="string">" Created On: %s\n"</span>, creation_text);
|
||||||
|
printf(<span class="string">" Modified On: %s\n"</span>, modification_text);
|
||||||
|
printf(<span class="string">" Version: %s\n"</span>, pdfioFileGetVersion(pdf));
|
||||||
|
printf(<span class="string">" AcroForm: %s\n"</span>, has_acroform ? <span class="string">"Yes"</span> : <span class="string">"No"</span>);
|
||||||
|
printf(<span class="string">" Number of Pages: %u\n"</span>, (<span class="reserved">unsigned</span>)num_pages);
|
||||||
|
|
||||||
|
<span class="comment">// Report the MediaBox for all of the pages</span>
|
||||||
|
prev_box.x1 = prev_box.x2 = prev_box.y1 = prev_box.y2 = <span class="number">0.0</span>;
|
||||||
|
|
||||||
|
<span class="reserved">for</span> (cur = <span class="number">0</span>, prev = <span class="number">0</span>; cur < num_pages; cur ++)
|
||||||
|
{
|
||||||
|
<span class="comment">// Find the MediaBox for this page in the page tree...</span>
|
||||||
|
<span class="reserved">for</span> (page = pdfioFileGetPage(pdf, cur);
|
||||||
|
page != NULL;
|
||||||
|
page = pdfioDictGetObj(page_dict, <span class="string">"Parent"</span>))
|
||||||
|
{
|
||||||
|
cur_box.x1 = cur_box.x2 = cur_box.y1 = cur_box.y2 = <span class="number">0.0</span>;
|
||||||
|
page_dict = pdfioObjGetDict(page);
|
||||||
|
|
||||||
|
<span class="reserved">if</span> (pdfioDictGetRect(page_dict, <span class="string">"MediaBox"</span>, &cur_box))
|
||||||
|
<span class="reserved">break</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
<span class="comment">// If this MediaBox is different from the previous one, show the range of</span>
|
||||||
|
<span class="comment">// pages that have that size...</span>
|
||||||
|
<span class="reserved">if</span> (cur == <span class="number">0</span> ||
|
||||||
|
fabs(cur_box.x1 - prev_box.x1) > <span class="number">0.01</span> ||
|
||||||
|
fabs(cur_box.y1 - prev_box.y1) > <span class="number">0.01</span> ||
|
||||||
|
fabs(cur_box.x2 - prev_box.x2) > <span class="number">0.01</span> ||
|
||||||
|
fabs(cur_box.y2 - prev_box.y2) > <span class="number">0.01</span>)
|
||||||
|
{
|
||||||
|
<span class="reserved">if</span> (cur > prev)
|
||||||
|
{
|
||||||
|
snprintf(range_text, <span class="reserved">sizeof</span>(range_text), <span class="string">"Pages %u-%u"</span>,
|
||||||
|
(<span class="reserved">unsigned</span>)(prev + <span class="number">1</span>), (<span class="reserved">unsigned</span>)cur);
|
||||||
|
printf(<span class="string">"%16s: [%g %g %g %g]\n"</span>, range_text,
|
||||||
|
prev_box.x1, prev_box.y1, prev_box.x2, prev_box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
<span class="comment">// Start a new series of pages with the new size...</span>
|
||||||
|
prev = cur;
|
||||||
|
prev_box = cur_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<span class="comment">// Show the last range as needed...</span>
|
||||||
|
<span class="reserved">if</span> (cur > prev)
|
||||||
|
{
|
||||||
|
snprintf(range_text, <span class="reserved">sizeof</span>(range_text), <span class="string">"Pages %u-%u"</span>,
|
||||||
|
(<span class="reserved">unsigned</span>)(prev + <span class="number">1</span>), (<span class="reserved">unsigned</span>)cur);
|
||||||
|
printf(<span class="string">"%16s: [%g %g %g %g]\n"</span>, range_text,
|
||||||
|
prev_box.x1, prev_box.y1, prev_box.x2, prev_box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
<span class="comment">// Close the PDF file...</span>
|
<span class="comment">// Close the PDF file...</span>
|
||||||
pdfioFileClose(pdf);
|
pdfioFileClose(pdf);
|
||||||
@@ -1661,6 +1788,9 @@ pdfioStreamClose(page_st);
|
|||||||
<span class="comment">// State for the current page</span>
|
<span class="comment">// State for the current page</span>
|
||||||
pdfio_stream_t *st; <span class="comment">// Current page stream</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">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>
|
docfont_t font; <span class="comment">// Current font</span>
|
||||||
<span class="reserved">double</span> fsize; <span class="comment">// Current font size</span>
|
<span class="reserved">double</span> fsize; <span class="comment">// Current font size</span>
|
||||||
doccolor_t color; <span class="comment">// Current color</span>
|
doccolor_t color; <span class="comment">// Current color</span>
|
||||||
@@ -2038,6 +2168,9 @@ pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y + SIZE_CODEBLOCK,
|
|||||||
pdfioContentFillAndStroke(dd->st, <span class="reserved">false</span>);
|
pdfioContentFillAndStroke(dd->st, <span class="reserved">false</span>);
|
||||||
|
|
||||||
<span class="comment">// Start a code text block...</span>
|
<span class="comment">// Start a code text block...</span>
|
||||||
|
dd->tag = <span class="string">"P"</span>;
|
||||||
|
pdfioContentBeginMarked(dd->st, dd->tag, <span class="comment">/*dict*/</span>NULL);
|
||||||
|
|
||||||
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
||||||
pdfioContentTextBegin(dd->st);
|
pdfioContentTextBegin(dd->st);
|
||||||
pdfioContentTextMoveTo(dd->st, left, dd->y);
|
pdfioContentTextMoveTo(dd->st, left, dd->y);
|
||||||
@@ -2074,6 +2207,9 @@ pdfioContentTextMoveTo(dd->st, left, dd->y);
|
|||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
dd->y += lineheight;
|
dd->y += lineheight;
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
dd->tag = NULL;
|
||||||
|
|
||||||
<span class="comment">// Draw the bottom padding...</span>
|
<span class="comment">// Draw the bottom padding...</span>
|
||||||
set_color(dd, DOCCOLOR_LTGRAY);
|
set_color(dd, DOCCOLOR_LTGRAY);
|
||||||
pdfioContentPathRect(dd->st, left - CODE_PADDING,
|
pdfioContentPathRect(dd->st, left - CODE_PADDING,
|
||||||
@@ -2184,8 +2320,17 @@ pdfioContentFillAndStroke(dd->st, <span class="reserved">false</span>);
|
|||||||
</code></pre>
|
</code></pre>
|
||||||
<p>Finally, we render each row in the table:</p>
|
<p>Finally, we render each row in the table:</p>
|
||||||
<pre><code class="language-c"><span class="comment">// Render each table row...</span>
|
<pre><code class="language-c"><span class="comment">// Render each table row...</span>
|
||||||
|
dd->in_table = <span class="reserved">true</span>;
|
||||||
|
|
||||||
|
<span class="reserved">if</span> (dd->st)
|
||||||
|
pdfioContentBeginMarked(dd->st, <span class="string">"Table"</span>, <span class="comment">/*dict*/</span>NULL);
|
||||||
|
|
||||||
<span class="reserved">for</span> (row = <span class="number">0</span>, rowptr = rows; row < num_rows; row ++, rowptr ++)
|
<span class="reserved">for</span> (row = <span class="number">0</span>, rowptr = rows; row < num_rows; row ++, rowptr ++)
|
||||||
render_row(dd, num_cols, cols, rowptr);
|
render_row(dd, num_cols, cols, rowptr);
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
|
||||||
|
dd->in_table = <span class="reserved">false</span>;
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 id="rendering-the-markdown-document">Rendering the Markdown Document</h4>
|
<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>
|
<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>
|
||||||
@@ -2509,7 +2654,7 @@ dd->y = row_y - row->height;
|
|||||||
<tr><th>pdf</th>
|
<tr><th>pdf</th>
|
||||||
<td class="description">PDF file</td></tr>
|
<td class="description">PDF file</td></tr>
|
||||||
<tr><th>num_colors</th>
|
<tr><th>num_colors</th>
|
||||||
<td class="description">Number of colors (1 or 3)</td></tr>
|
<td class="description">Number of colors (1, 3, or 4)</td></tr>
|
||||||
<tr><th>cs</th>
|
<tr><th>cs</th>
|
||||||
<td class="description">Color space enumeration</td></tr>
|
<td class="description">Color space enumeration</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
@@ -2517,7 +2662,8 @@ dd->y = row_y - row->height;
|
|||||||
<p class="description">Color array</p>
|
<p class="description">Color array</p>
|
||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">This function creates a color array for a standard <code>PDFIO_CS_</code> enumerated color space.
|
<p class="discussion">This function creates a color array for a standard <code>PDFIO_CS_</code> enumerated color space.
|
||||||
The "num_colors" argument must be <code>1</code> for grayscale and <code>3</code> for RGB color.</p>
|
The "num_colors" argument must be <code>1</code> for grayscale, <code>3</code> for RGB color, and
|
||||||
|
<code>4</code> for CMYK color.</p>
|
||||||
<h3 class="function"><a id="pdfioArrayGetArray">pdfioArrayGetArray</a></h3>
|
<h3 class="function"><a id="pdfioArrayGetArray">pdfioArrayGetArray</a></h3>
|
||||||
<p class="description">Get an array value from an array.</p>
|
<p class="description">Get an array value from an array.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -2661,7 +2807,7 @@ size_t pdfioArrayGetSize(<a href="#pdfio_array_t">pdfio_array_t</a> *a);</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Value type</p>
|
<p class="description">Value type</p>
|
||||||
<h3 class="function"><a id="pdfioArrayRemove">pdfioArrayRemove</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.4 </span><a id="pdfioArrayRemove">pdfioArrayRemove</a></h3>
|
||||||
<p class="description">Remove an array entry.</p>
|
<p class="description">Remove an array entry.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
<span class="reserved">bool</span> pdfioArrayRemove(<a href="#pdfio_array_t">pdfio_array_t</a> *a, size_t n);</p>
|
<span class="reserved">bool</span> pdfioArrayRemove(<a href="#pdfio_array_t">pdfio_array_t</a> *a, size_t n);</p>
|
||||||
@@ -2674,6 +2820,35 @@ size_t pdfioArrayGetSize(<a href="#pdfio_array_t">pdfio_array_t</a> *a);</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> otherwise</p>
|
<p class="description"><code>true</code> on success, <code>false</code> otherwise</p>
|
||||||
|
<h3 class="function"><span class="info"> PDFio 1.6 </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 "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.<br>
|
||||||
|
<br>
|
||||||
|
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.
|
||||||
|
|
||||||
|
</p>
|
||||||
<h3 class="function"><a id="pdfioContentClip">pdfioContentClip</a></h3>
|
<h3 class="function"><a id="pdfioContentClip">pdfioContentClip</a></h3>
|
||||||
<p class="description">Clip output to the current path.</p>
|
<p class="description">Clip output to the current path.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -2711,6 +2886,22 @@ size_t pdfioArrayGetSize(<a href="#pdfio_array_t">pdfio_array_t</a> *a);</p>
|
|||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">The object name must be part of the page dictionary resources, typically
|
<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>
|
using the <a href="#pdfioPageDictAddImage"><code>pdfioPageDictAddImage</code></a> function.</p>
|
||||||
|
<h3 class="function"><span class="info"> PDFio 1.6 </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>
|
<h3 class="function"><a id="pdfioContentFill">pdfioContentFill</a></h3>
|
||||||
<p class="description">Fill the current path.</p>
|
<p class="description">Fill the current path.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -2866,7 +3057,7 @@ using the <a href="#pdfioPageDictAddImage"><code>pdfioPageDictAddImage</code></a
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
||||||
<h3 class="function"><a id="pdfioContentPathEnd">pdfioContentPathEnd</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.1 </span><a id="pdfioContentPathEnd">pdfioContentPathEnd</a></h3>
|
||||||
<p class="description">Clear the current path.</p>
|
<p class="description">Clear the current path.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
<span class="reserved">bool</span> pdfioContentPathEnd(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
|
<span class="reserved">bool</span> pdfioContentPathEnd(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
|
||||||
@@ -3356,7 +3547,7 @@ are 0, a solid line is drawn.</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
||||||
<h3 class="function"><a id="pdfioContentTextMeasure">pdfioContentTextMeasure</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.2 </span><a id="pdfioContentTextMeasure">pdfioContentTextMeasure</a></h3>
|
||||||
<p class="description">Measure a text string and return its width.</p>
|
<p class="description">Measure a text string and return its width.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -3374,7 +3565,9 @@ are 0, a solid line is drawn.</p>
|
|||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">This function measures the given text string "s" and returns its width based
|
<p class="discussion">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
|
on "size". 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>
|
<h3 class="function"><a id="pdfioContentTextMoveLine">pdfioContentTextMoveLine</a></h3>
|
||||||
<p class="description">Move to the next line and offset.</p>
|
<p class="description">Move to the next line and offset.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -3405,7 +3598,7 @@ any control characters (such as newlines) are ignored.</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
||||||
<h3 class="function"><a id="pdfioContentTextNewLine">pdfioContentTextNewLine</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.2 </span><a id="pdfioContentTextNewLine">pdfioContentTextNewLine</a></h3>
|
||||||
<p class="description">Move to the next line.</p>
|
<p class="description">Move to the next line.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
<span class="reserved">bool</span> pdfioContentTextNewLine(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
|
<span class="reserved">bool</span> pdfioContentTextNewLine(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
|
||||||
@@ -3416,7 +3609,7 @@ any control characters (such as newlines) are ignored.</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
||||||
<h3 class="function"><a id="pdfioContentTextNewLineShow">pdfioContentTextNewLineShow</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.2 </span><a id="pdfioContentTextNewLineShow">pdfioContentTextNewLineShow</a></h3>
|
||||||
<p class="description">Move to the next line and show text.</p>
|
<p class="description">Move to the next line and show text.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -3439,8 +3632,10 @@ any control characters (such as newlines) are ignored.</p>
|
|||||||
<p class="discussion">This function moves to the next line and then shows some text with optional
|
<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 "unicode" argument
|
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 that the current font maps to full Unicode. The "s" argument
|
||||||
specifies a UTF-8 encoded string.</p>
|
specifies a UTF-8 encoded string.
|
||||||
<h3 class="function"><a id="pdfioContentTextNewLineShowf">pdfioContentTextNewLineShowf</a></h3>
|
|
||||||
|
</p>
|
||||||
|
<h3 class="function"><span class="info"> PDFio v1.2 </span><a id="pdfioContentTextNewLineShowf">pdfioContentTextNewLineShowf</a></h3>
|
||||||
<p class="description">Show formatted text.</p>
|
<p class="description">Show formatted text.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -3465,7 +3660,9 @@ specifies a UTF-8 encoded string.</p>
|
|||||||
<p class="discussion">This function moves to the next line and shows some formatted text with
|
<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 "unicode"
|
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 that the current font maps to full Unicode. The "format"
|
||||||
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>
|
<h3 class="function"><a id="pdfioContentTextShow">pdfioContentTextShow</a></h3>
|
||||||
<p class="description">Show text.</p>
|
<p class="description">Show text.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -3528,7 +3725,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
|
<p class="discussion">This function shows some formatted text in a PDF content stream. The
|
||||||
"unicode" argument specifies that the current font maps to full Unicode.
|
"unicode" argument specifies that the current font maps to full Unicode.
|
||||||
The "format" argument specifies a UTF-8 encoded <code>printf</code>-style format string.</p>
|
The "format" argument specifies a UTF-8 encoded <code>printf</code>-style format string.</p>
|
||||||
<h3 class="function"><a id="pdfioDictClear">pdfioDictClear</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.4 </span><a id="pdfioDictClear">pdfioDictClear</a></h3>
|
||||||
<p class="description">Remove a key/value pair from a dictionary.</p>
|
<p class="description">Remove a key/value pair from a dictionary.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -3632,7 +3829,7 @@ time_t pdfioDictGetDate(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <span cl
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Value</p>
|
<p class="description">Value</p>
|
||||||
<h3 class="function"><a id="pdfioDictGetKey">pdfioDictGetKey</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.4 </span><a id="pdfioDictGetKey">pdfioDictGetKey</a></h3>
|
||||||
<p class="description">Get the key for the specified pair.</p>
|
<p class="description">Get the key for the specified pair.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -3658,7 +3855,7 @@ time_t pdfioDictGetDate(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <span cl
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Value</p>
|
<p class="description">Value</p>
|
||||||
<h3 class="function"><a id="pdfioDictGetNumPairs">pdfioDictGetNumPairs</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.4 </span><a id="pdfioDictGetNumPairs">pdfioDictGetNumPairs</a></h3>
|
||||||
<p class="description">Get the number of key/value pairs in a dictionary.</p>
|
<p class="description">Get the number of key/value pairs in a dictionary.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
size_t pdfioDictGetNumPairs(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
|
size_t pdfioDictGetNumPairs(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
|
||||||
@@ -3736,7 +3933,7 @@ size_t pdfioDictGetNumPairs(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Value type</p>
|
<p class="description">Value type</p>
|
||||||
<h3 class="function"><a id="pdfioDictIterateKeys">pdfioDictIterateKeys</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.1 </span><a id="pdfioDictIterateKeys">pdfioDictIterateKeys</a></h3>
|
||||||
<p class="description">Iterate the keys in a dictionary.</p>
|
<p class="description">Iterate the keys in a dictionary.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -3763,7 +3960,9 @@ my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data)
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
The iteration continues as long as the callback returns <code>true</code> or all keys
|
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>
|
<h3 class="function"><a id="pdfioDictSetArray">pdfioDictSetArray</a></h3>
|
||||||
<p class="description">Set a key array in a dictionary.</p>
|
<p class="description">Set a key array in a dictionary.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -3946,6 +4145,46 @@ have been iterated.</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
||||||
|
<h3 class="function"><span class="info"> PDFio 1.6 </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 "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 <code>NULL</code> defaults the subtype to "GTS_PDFA1".<br>
|
||||||
|
<br>
|
||||||
|
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 <code>NULL</code> to omit this information.<br>
|
||||||
|
<br>
|
||||||
|
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.<br>
|
||||||
|
<br>
|
||||||
|
The "profile" 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 "cond_id" value.
|
||||||
|
|
||||||
|
</p>
|
||||||
<h3 class="function"><a id="pdfioFileClose">pdfioFileClose</a></h3>
|
<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="description">Close a PDF file and free all memory used for it.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -3983,16 +4222,55 @@ have been iterated.</p>
|
|||||||
name of the PDF file to create.<br>
|
name of the PDF file to create.<br>
|
||||||
<br>
|
<br>
|
||||||
The "version" argument specifies the PDF version number for the file or
|
The "version" argument specifies the PDF version number for the file or
|
||||||
<code>NULL</code> for the default ("2.0"). The value "PCLm-1.0" can be specified to
|
<code>NULL</code> for the default ("2.0"). The following values are recognized:
|
||||||
produce the PCLm subset of PDF.<br>
|
|
||||||
<br>
|
</p><ul>
|
||||||
The "media_box" and "crop_box" arguments specify the default MediaBox and
|
<li>"1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
|
||||||
|
specified versions.
|
||||||
|
</li>
|
||||||
|
<li>"PCLm-1.0": The PCLm (raster) subset of PDF supported by some printers.
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-1a": PDF/A-1a:2005
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-1b": PDF/A-1b:2005
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2a": PDF/A-2a:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2b": PDF/A-2b:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2u": PDF/A-2u:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3a": PDF/A-3a:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3b": PDF/A-3b:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3u": PDF/A-3u:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-4": PDF/A-4:2020</li>
|
||||||
|
</ul>
|
||||||
|
<p class="discussion">The "media_box" and "crop_box" arguments specify the default MediaBox and
|
||||||
CropBox for pages in the PDF file - if <code>NULL</code> then a default "Universal" size
|
CropBox for pages in the PDF file - if <code>NULL</code> then a default "Universal" size
|
||||||
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
|
||||||
<br>
|
<br>
|
||||||
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if <code>NULL</code> the default error handler is used that
|
and its data pointer - if <code>NULL</code> then the default error handler is used that
|
||||||
writes error messages to <code>stderr</code>.</p>
|
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, "%s: %sn", pdfioFileGetName(pdf), message);
|
||||||
|
|
||||||
|
/* Return true to continue on warning messages, false otherwise... */
|
||||||
|
return (!strncmp(message, "WARNING:", 8));
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
<h3 class="function"><a id="pdfioFileCreateArrayObj">pdfioFileCreateArrayObj</a></h3>
|
<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="description">Create a new object in a PDF file containing an array.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4057,9 +4335,37 @@ specifies the font nane:
|
|||||||
</ul>
|
</ul>
|
||||||
<p class="discussion">Aside from "Symbol" and "Zapf-Dingbats", Base fonts use the Windows CP1252
|
<p class="discussion">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
|
(ISO-8859-1 with additional characters such as the Euro symbol) subset of
|
||||||
Unicode.</p>
|
Unicode.<br>
|
||||||
|
<br>
|
||||||
|
</p><blockquote>
|
||||||
|
Note: This function cannot be used when producing PDF/A files.</blockquote>
|
||||||
|
<h3 class="function"><span class="info"> PDFio v1.6 </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
|
||||||
|
"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.
|
||||||
|
|
||||||
|
</p>
|
||||||
<h3 class="function"><a id="pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></h3>
|
<h3 class="function"><a id="pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></h3>
|
||||||
<p class="description">Add a font object to a PDF file.</p>
|
<p class="description">Add a font file to a PDF file.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
<h4 class="parameters">Parameters</h4>
|
||||||
@@ -4074,7 +4380,7 @@ Unicode.</p>
|
|||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Font object</p>
|
<p class="description">Font object</p>
|
||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">This function embeds a TrueType/OpenType font into a PDF file. The
|
<p class="discussion">This function embeds a TrueType/OpenType font file into a PDF file. The
|
||||||
"unicode" parameter controls whether the font is encoded for two-byte
|
"unicode" parameter controls whether the font is encoded for two-byte
|
||||||
characters (potentially full Unicode, but more typically a subset)
|
characters (potentially full Unicode, but more typically a subset)
|
||||||
or to only support the Windows CP1252 (ISO-8859-1 with additional
|
or to only support the Windows CP1252 (ISO-8859-1 with additional
|
||||||
@@ -4148,8 +4454,10 @@ the image is encoded in the corresponding device color space. The
|
|||||||
"interpolate" parameter specifies whether to interpolate when scaling the
|
"interpolate" parameter specifies whether to interpolate when scaling the
|
||||||
image on the page.<br>
|
image on the page.<br>
|
||||||
<br>
|
<br>
|
||||||
|
</p><blockquote>
|
||||||
Note: When creating an image object with alpha, a second image object is
|
Note: When creating an image object with alpha, a second image object is
|
||||||
created to hold the "soft mask" data for the primary image.</p>
|
created to hold the "soft mask" data for the primary image. PDF/A-1
|
||||||
|
files do not support alpha-based transparency.</blockquote>
|
||||||
<h3 class="function"><a id="pdfioFileCreateImageObjFromFile">pdfioFileCreateImageObjFromFile</a></h3>
|
<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="description">Add an image object to a PDF file from a file.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4172,10 +4480,9 @@ the "interpolate" parameter specifies whether to interpolate when scal
|
|||||||
image on the page.<br>
|
image on the page.<br>
|
||||||
<br>
|
<br>
|
||||||
</p><blockquote>
|
</p><blockquote>
|
||||||
Note: Currently PNG support is limited to grayscale, RGB, or indexed files
|
Note: PNG files containing transparency cannot be used when producing
|
||||||
without interlacing or alpha. Transparency (masking) based on color/index
|
PDF/A files.</blockquote>
|
||||||
is supported.</blockquote>
|
<h3 class="function"><span class="info"> PDFio v1.4 </span><a id="pdfioFileCreateNameObj">pdfioFileCreateNameObj</a></h3>
|
||||||
<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="description">Create a new object in a PDF file containing a name.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -4190,8 +4497,10 @@ is supported.</blockquote>
|
|||||||
<p class="description">New object</p>
|
<p class="description">New object</p>
|
||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">This function creates a new object with a name value in a PDF file.
|
<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>
|
You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write the object to the file.
|
||||||
<h3 class="function"><a id="pdfioFileCreateNumberObj">pdfioFileCreateNumberObj</a></h3>
|
|
||||||
|
</p>
|
||||||
|
<h3 class="function"><span class="info"> PDFio v1.2 </span><a id="pdfioFileCreateNumberObj">pdfioFileCreateNumberObj</a></h3>
|
||||||
<p class="description">Create a new object in a PDF file containing a number.</p>
|
<p class="description">Create a new object in a PDF file containing a number.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -4206,7 +4515,9 @@ You must call <a href="#pdfioObjClose"><code>pdfioObjClose</code></a> to write t
|
|||||||
<p class="description">New object</p>
|
<p class="description">New object</p>
|
||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">This function creates a new object with a number value in a PDF file.
|
<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>
|
<h3 class="function"><a id="pdfioFileCreateObj">pdfioFileCreateObj</a></h3>
|
||||||
<p class="description">Create a new object in a PDF file.</p>
|
<p class="description">Create a new object in a PDF file.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4258,18 +4569,56 @@ output_cb(void *output_cbdata, const void *buffer, size_t bytes)
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
The "version" argument specifies the PDF version number for the file or
|
The "version" argument specifies the PDF version number for the file or
|
||||||
<code>NULL</code> for the default ("2.0"). Unlike <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> and
|
<code>NULL</code> for the default ("2.0"). The following values are recognized:
|
||||||
<a href="#pdfioFileCreateTemporary"><code>pdfioFileCreateTemporary</code></a>, it is generally not safe to pass the
|
|
||||||
"PCLm-1.0" version string.<br>
|
</p><ul>
|
||||||
|
<li>"1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
|
||||||
|
specified versions.
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-1a": PDF/A-1a:2005
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-1b": PDF/A-1b:2005
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2a": PDF/A-2a:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2b": PDF/A-2b:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2u": PDF/A-2u:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3a": PDF/A-3a:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3b": PDF/A-3b:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3u": PDF/A-3u:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-4": 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 "PCLm-1.0" version string.<br>
|
||||||
<br>
|
<br>
|
||||||
The "media_box" and "crop_box" arguments specify the default MediaBox and
|
The "media_box" and "crop_box" arguments specify the default MediaBox and
|
||||||
CropBox for pages in the PDF file - if <code>NULL</code> then a default "Universal" size
|
CropBox for pages in the PDF file - if <code>NULL</code> then a default "Universal" size
|
||||||
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
|
||||||
<br>
|
<br>
|
||||||
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if <code>NULL</code> the default error handler is used that
|
and its data pointer - if <code>NULL</code> then the default error handler is used that
|
||||||
writes error messages to <code>stderr</code>.<br>
|
writes error and warning messages to <code>stderr</code>. The error handler callback
|
||||||
<br>
|
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, "%s: %sn", pdfioFileGetName(pdf), message);
|
||||||
|
|
||||||
|
/* Return true to continue on warning messages, false otherwise... */
|
||||||
|
return (!strncmp(message, "WARNING:", 8));
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
</p><blockquote>
|
</p><blockquote>
|
||||||
<em>Note</em>: Files created using this API are slightly larger than those
|
<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
|
created using the <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> function since stream lengths are
|
||||||
@@ -4287,7 +4636,7 @@ stored as indirect object references.</blockquote>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Contents stream</p>
|
<p class="description">Contents stream</p>
|
||||||
<h3 class="function"><a id="pdfioFileCreateStringObj">pdfioFileCreateStringObj</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.2 </span><a id="pdfioFileCreateStringObj">pdfioFileCreateStringObj</a></h3>
|
||||||
<p class="description">Create a new object in a PDF file containing a string.</p>
|
<p class="description">Create a new object in a PDF file containing a string.</p>
|
||||||
<p class="code">
|
<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>
|
<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>
|
||||||
@@ -4302,7 +4651,9 @@ stored as indirect object references.</blockquote>
|
|||||||
<p class="description">New object</p>
|
<p class="description">New object</p>
|
||||||
<h4 class="discussion">Discussion</h4>
|
<h4 class="discussion">Discussion</h4>
|
||||||
<p class="discussion">This function creates a new object with a string value in a PDF file.
|
<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>
|
<h3 class="function"><a id="pdfioFileCreateTemporary">pdfioFileCreateTemporary</a></h3>
|
||||||
<p class="description"></p>
|
<p class="description"></p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4331,10 +4682,33 @@ temporary directory. The temporary file is stored in the string "buffer&qu
|
|||||||
will have a ".pdf" extension.<br>
|
will have a ".pdf" extension.<br>
|
||||||
<br>
|
<br>
|
||||||
The "version" argument specifies the PDF version number for the file or
|
The "version" argument specifies the PDF version number for the file or
|
||||||
<code>NULL</code> for the default ("2.0"). The value "PCLm-1.0" can be specified to
|
<code>NULL</code> for the default ("2.0"). The following values are recognized:
|
||||||
produce the PCLm subset of PDF.<br>
|
|
||||||
<br>
|
</p><ul>
|
||||||
The "media_box" and "crop_box" arguments specify the default MediaBox and
|
<li>"1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
|
||||||
|
specified versions.
|
||||||
|
</li>
|
||||||
|
<li>"PCLm-1.0": The PCLm (raster) subset of PDF supported by some printers.
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-1a": PDF/A-1a:2005
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-1b": PDF/A-1b:2005
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2a": PDF/A-2a:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2b": PDF/A-2b:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-2u": PDF/A-2u:2011
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3a": PDF/A-3a:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3b": PDF/A-3b:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-3u": PDF/A-3u:2012
|
||||||
|
</li>
|
||||||
|
<li>"PDF/A-4": PDF/A-4:2020</li>
|
||||||
|
</ul>
|
||||||
|
<p class="discussion">The "media_box" and "crop_box" arguments specify the default MediaBox and
|
||||||
CropBox for pages in the PDF file - if <code>NULL</code> then a default "Universal" size
|
CropBox for pages in the PDF file - if <code>NULL</code> then a default "Universal" size
|
||||||
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
|
||||||
<br>
|
<br>
|
||||||
@@ -4425,6 +4799,24 @@ time_t pdfioFileGetCreationDate(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf);<
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Keywords string or <code>NULL</code> for none</p>
|
<p class="description">Keywords string or <code>NULL</code> for none</p>
|
||||||
|
<h3 class="function"><span class="info"> PDFio 1.6 </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
|
||||||
|
"lang-REGION". For example, the string "en-CA" specifies Canadian English
|
||||||
|
and the string "fr-CA" specifies Canadian French.
|
||||||
|
|
||||||
|
</p>
|
||||||
<h3 class="function"><a id="pdfioFileGetModificationDate">pdfioFileGetModificationDate</a></h3>
|
<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="description">Get the most recent modification date for a PDF file.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4585,8 +4977,29 @@ 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>
|
PDF file requires a password, the open will always fail.<br>
|
||||||
<br>
|
<br>
|
||||||
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if <code>NULL</code> the default error handler is used that
|
and its data pointer - if <code>NULL</code> then the default error handler is used that
|
||||||
writes error messages to <code>stderr</code>.</p>
|
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, "%s: %sn", pdfioFileGetName(pdf), message);
|
||||||
|
|
||||||
|
/* Return true to continue on warning messages, false otherwise... */
|
||||||
|
return (!strncmp(message, "WARNING:", 8));
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</p><blockquote>
|
||||||
|
Note: Error messages starting with "WARNING:" 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>
|
||||||
<h3 class="function"><a id="pdfioFileSetAuthor">pdfioFileSetAuthor</a></h3>
|
<h3 class="function"><a id="pdfioFileSetAuthor">pdfioFileSetAuthor</a></h3>
|
||||||
<p class="description">Set the author for a PDF file.</p>
|
<p class="description">Set the author for a PDF file.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4631,6 +5044,24 @@ writes error messages to <code>stderr</code>.</p>
|
|||||||
<tr><th>value</th>
|
<tr><th>value</th>
|
||||||
<td class="description">Value</td></tr>
|
<td class="description">Value</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
|
<h3 class="function"><span class="info"> PDFio 1.6 </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 "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.
|
||||||
|
|
||||||
|
</p>
|
||||||
<h3 class="function"><a id="pdfioFileSetModificationDate">pdfioFileSetModificationDate</a></h3>
|
<h3 class="function"><a id="pdfioFileSetModificationDate">pdfioFileSetModificationDate</a></h3>
|
||||||
<p class="description">Set the modification date for a PDF file.</p>
|
<p class="description">Set the modification date for a PDF file.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4702,7 +5133,7 @@ size_t pdfioImageGetBytesPerLine(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</
|
|||||||
<td class="description">Image object</td></tr>
|
<td class="description">Image object</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Number of bytes per line</p>
|
<p class="description">Number of bytes per line or <code>0</code> on error</p>
|
||||||
<h3 class="function"><a id="pdfioImageGetHeight">pdfioImageGetHeight</a></h3>
|
<h3 class="function"><a id="pdfioImageGetHeight">pdfioImageGetHeight</a></h3>
|
||||||
<p class="description">Get the height of an image object.</p>
|
<p class="description">Get the height of an image object.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -4807,7 +5238,7 @@ size_t pdfioObjGetLength(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p>
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description">Length in bytes or <code>0</code> for none</p>
|
<p class="description">Length in bytes or <code>0</code> for none</p>
|
||||||
<h3 class="function"><a id="pdfioObjGetName">pdfioObjGetName</a></h3>
|
<h3 class="function"><span class="info"> PDFio v1.4 </span><a id="pdfioObjGetName">pdfioObjGetName</a></h3>
|
||||||
<p class="description">Get the name value associated with an object.</p>
|
<p class="description">Get the name value associated with an object.</p>
|
||||||
<p class="code">
|
<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>
|
<span class="reserved">const</span> <span class="reserved">char</span> *pdfioObjGetName(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p>
|
||||||
@@ -5081,6 +5512,11 @@ ssize_t pdfioStreamPeek(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, <span
|
|||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h4 class="returnvalue">Return Value</h4>
|
<h4 class="returnvalue">Return Value</h4>
|
||||||
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
<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 "%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.</p>
|
||||||
<h3 class="function"><a id="pdfioStreamPutChar">pdfioStreamPutChar</a></h3>
|
<h3 class="function"><a id="pdfioStreamPutChar">pdfioStreamPutChar</a></h3>
|
||||||
<p class="description">Write a single character to a stream.</p>
|
<p class="description">Write a single character to a stream.</p>
|
||||||
<p class="code">
|
<p class="code">
|
||||||
@@ -5304,6 +5740,7 @@ typedef enum <a href="#pdfio_valtype_e">pdfio_valtype_e</a> pdfio_valtype_t;
|
|||||||
<h4 class="constants">Constants</h4>
|
<h4 class="constants">Constants</h4>
|
||||||
<table class="list"><tbody>
|
<table class="list"><tbody>
|
||||||
<tr><th>PDFIO_CS_ADOBE </th><td class="description">AdobeRGB 1998</td></tr>
|
<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_P3_D65 </th><td class="description">Display P3</td></tr>
|
||||||
<tr><th>PDFIO_CS_SRGB </th><td class="description">sRGB</td></tr>
|
<tr><th>PDFIO_CS_SRGB </th><td class="description">sRGB</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
@@ -5314,7 +5751,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_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_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_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)</td></tr>
|
<tr><th>PDFIO_ENCRYPTION_RC4_40 </th><td class="description">40-bit RC4 encryption (PDF 1.3, reading only)</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
<h3 class="enumeration"><a id="pdfio_filter_e">pdfio_filter_e</a></h3>
|
<h3 class="enumeration"><a id="pdfio_filter_e">pdfio_filter_e</a></h3>
|
||||||
<p class="description">Compression/decompression filters for streams</p>
|
<p class="description">Compression/decompression filters for streams</p>
|
||||||
|
|||||||
192
doc/pdfio.md
192
doc/pdfio.md
@@ -343,8 +343,8 @@ password_cb(void *data, const char *filename)
|
|||||||
```
|
```
|
||||||
|
|
||||||
The error callback is called for both errors and warnings and accepts the
|
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
|
`pdfio_file_t` pointer, a message string, and the callback pointer value. It
|
||||||
example:
|
returns `true` to continue processing the file or `false` to stop, for example:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
bool
|
bool
|
||||||
@@ -354,13 +354,17 @@ error_cb(pdfio_file_t *pdf, const char *message, void *data)
|
|||||||
|
|
||||||
fprintf(stderr, "%s: %s\n", pdfioFileGetName(pdf), message);
|
fprintf(stderr, "%s: %s\n", pdfioFileGetName(pdf), message);
|
||||||
|
|
||||||
// Return false to treat warnings as errors
|
// Return true for warning messages (continue) and false for errors (stop)
|
||||||
return (false);
|
return (!strncmp(message, "WARNING:", 8));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The default error callback (`NULL`) does the equivalent of the above.
|
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`](@@)
|
Each PDF file contains one or more pages. The [`pdfioFileGetNumPages`](@@)
|
||||||
function returns the number of pages in the file while the
|
function returns the number of pages in the file while the
|
||||||
[`pdfioFileGetPage`](@@) function gets the specified page in the PDF file:
|
[`pdfioFileGetPage`](@@) function gets the specified page in the PDF file:
|
||||||
@@ -864,6 +868,55 @@ escaping, as needed:
|
|||||||
offsets between them
|
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
|
Examples
|
||||||
========
|
========
|
||||||
|
|
||||||
@@ -889,11 +942,26 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
{
|
{
|
||||||
const char *filename; // PDF filename
|
const char *filename; // PDF filename
|
||||||
pdfio_file_t *pdf; // PDF file
|
pdfio_file_t *pdf; // PDF file
|
||||||
const char *author; // Author name
|
pdfio_dict_t *catalog; // Catalog dictionary
|
||||||
time_t creation_date; // Creation date
|
const char *author, // Author name
|
||||||
struct tm *creation_tm; // Creation date/time information
|
*creator, // Creator name
|
||||||
char creation_text[256]; // Creation date/time as a string
|
*producer, // Producer name
|
||||||
const char *title; // Title
|
*title; // Title
|
||||||
|
time_t creation_date, // Creation date
|
||||||
|
modification_date; // Modification date
|
||||||
|
struct tm *creation_tm, // Creation date/time information
|
||||||
|
*modification_tm; // Modification date/time information
|
||||||
|
char creation_text[256], // Creation date/time as a string
|
||||||
|
modification_text[256], // Modification date/time human fmt string
|
||||||
|
range_text[255]; // Page range text
|
||||||
|
size_t num_pages; // PDF number of pages
|
||||||
|
bool has_acroform; // Does the file have an AcroForm?
|
||||||
|
pdfio_obj_t *page; // Object
|
||||||
|
pdfio_dict_t *page_dict; // Object dictionary
|
||||||
|
size_t cur, // Current page index
|
||||||
|
prev; // Previous page index
|
||||||
|
pdfio_rect_t cur_box, // Current MediaBox
|
||||||
|
prev_box; // Previous MediaBox
|
||||||
|
|
||||||
|
|
||||||
// Get the filename from the command-line...
|
// Get the filename from the command-line...
|
||||||
@@ -906,14 +974,20 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
filename = argv[1];
|
filename = argv[1];
|
||||||
|
|
||||||
// Open the PDF file with the default callbacks...
|
// Open the PDF file with the default callbacks...
|
||||||
pdf = pdfioFileOpen(filename, /*password_cb*/NULL, /*password_cbdata*/NULL,
|
pdf = pdfioFileOpen(filename, /*password_cb*/NULL,
|
||||||
/*error_cb*/NULL, /*error_cbdata*/NULL);
|
/*password_cbdata*/NULL, /*error_cb*/NULL,
|
||||||
|
/*error_cbdata*/NULL);
|
||||||
if (pdf == NULL)
|
if (pdf == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
// Get the title and author...
|
// Get the title, author, etc...
|
||||||
author = pdfioFileGetAuthor(pdf);
|
catalog = pdfioFileGetCatalog(pdf);
|
||||||
title = pdfioFileGetTitle(pdf);
|
author = pdfioFileGetAuthor(pdf);
|
||||||
|
creator = pdfioFileGetCreator(pdf);
|
||||||
|
has_acroform = pdfioDictGetType(catalog, "AcroForm") != PDFIO_VALTYPE_NONE;
|
||||||
|
num_pages = pdfioFileGetNumPages(pdf);
|
||||||
|
producer = pdfioFileGetProducer(pdf);
|
||||||
|
title = pdfioFileGetTitle(pdf);
|
||||||
|
|
||||||
// Get the creation date and convert to a string...
|
// Get the creation date and convert to a string...
|
||||||
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
|
if ((creation_date = pdfioFileGetCreationDate(pdf)) > 0)
|
||||||
@@ -926,12 +1000,76 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
snprintf(creation_text, sizeof(creation_text), "-- not set --");
|
snprintf(creation_text, sizeof(creation_text), "-- not set --");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the modification date and convert to a string...
|
||||||
|
if ((modification_date = pdfioFileGetModificationDate(pdf)) > 0)
|
||||||
|
{
|
||||||
|
modification_tm = localtime(&modification_date);
|
||||||
|
strftime(modification_text, sizeof(modification_text), "%c", modification_tm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(modification_text, sizeof(modification_text), "-- not set --");
|
||||||
|
}
|
||||||
|
|
||||||
// Print file information to stdout...
|
// Print file information to stdout...
|
||||||
printf("%s:\n", filename);
|
printf("%s:\n", filename);
|
||||||
printf(" Title: %s\n", title ? title : "-- not set --");
|
printf(" Title: %s\n", title ? title : "-- not set --");
|
||||||
printf(" Author: %s\n", author ? author : "-- not set --");
|
printf(" Author: %s\n", author ? author : "-- not set --");
|
||||||
printf(" Created On: %s\n", creation_text);
|
printf(" Creator: %s\n", creator ? creator : "-- not set --");
|
||||||
printf(" Number Pages: %u\n", (unsigned)pdfioFileGetNumPages(pdf));
|
printf(" Producer: %s\n", producer ? producer : "-- not set --");
|
||||||
|
printf(" Created On: %s\n", creation_text);
|
||||||
|
printf(" Modified On: %s\n", modification_text);
|
||||||
|
printf(" Version: %s\n", pdfioFileGetVersion(pdf));
|
||||||
|
printf(" AcroForm: %s\n", has_acroform ? "Yes" : "No");
|
||||||
|
printf(" Number of Pages: %u\n", (unsigned)num_pages);
|
||||||
|
|
||||||
|
// Report the MediaBox for all of the pages
|
||||||
|
prev_box.x1 = prev_box.x2 = prev_box.y1 = prev_box.y2 = 0.0;
|
||||||
|
|
||||||
|
for (cur = 0, prev = 0; cur < num_pages; cur ++)
|
||||||
|
{
|
||||||
|
// Find the MediaBox for this page in the page tree...
|
||||||
|
for (page = pdfioFileGetPage(pdf, cur);
|
||||||
|
page != NULL;
|
||||||
|
page = pdfioDictGetObj(page_dict, "Parent"))
|
||||||
|
{
|
||||||
|
cur_box.x1 = cur_box.x2 = cur_box.y1 = cur_box.y2 = 0.0;
|
||||||
|
page_dict = pdfioObjGetDict(page);
|
||||||
|
|
||||||
|
if (pdfioDictGetRect(page_dict, "MediaBox", &cur_box))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this MediaBox is different from the previous one, show the range of
|
||||||
|
// pages that have that size...
|
||||||
|
if (cur == 0 ||
|
||||||
|
fabs(cur_box.x1 - prev_box.x1) > 0.01 ||
|
||||||
|
fabs(cur_box.y1 - prev_box.y1) > 0.01 ||
|
||||||
|
fabs(cur_box.x2 - prev_box.x2) > 0.01 ||
|
||||||
|
fabs(cur_box.y2 - prev_box.y2) > 0.01)
|
||||||
|
{
|
||||||
|
if (cur > prev)
|
||||||
|
{
|
||||||
|
snprintf(range_text, sizeof(range_text), "Pages %u-%u",
|
||||||
|
(unsigned)(prev + 1), (unsigned)cur);
|
||||||
|
printf("%16s: [%g %g %g %g]\n", range_text,
|
||||||
|
prev_box.x1, prev_box.y1, prev_box.x2, prev_box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a new series of pages with the new size...
|
||||||
|
prev = cur;
|
||||||
|
prev_box = cur_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the last range as needed...
|
||||||
|
if (cur > prev)
|
||||||
|
{
|
||||||
|
snprintf(range_text, sizeof(range_text), "Pages %u-%u",
|
||||||
|
(unsigned)(prev + 1), (unsigned)cur);
|
||||||
|
printf("%16s: [%g %g %g %g]\n", range_text,
|
||||||
|
prev_box.x1, prev_box.y1, prev_box.x2, prev_box.y2);
|
||||||
|
}
|
||||||
|
|
||||||
// Close the PDF file...
|
// Close the PDF file...
|
||||||
pdfioFileClose(pdf);
|
pdfioFileClose(pdf);
|
||||||
@@ -1508,6 +1646,9 @@ typedef struct docdata_s // Document formatting data
|
|||||||
// State for the current page
|
// State for the current page
|
||||||
pdfio_stream_t *st; // Current page stream
|
pdfio_stream_t *st; // Current page stream
|
||||||
double y; // Current position on page
|
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
|
docfont_t font; // Current font
|
||||||
double fsize; // Current font size
|
double fsize; // Current font size
|
||||||
doccolor_t color; // Current color
|
doccolor_t color; // Current color
|
||||||
@@ -2011,6 +2152,9 @@ pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y + SIZE_CODEBLOCK,
|
|||||||
pdfioContentFillAndStroke(dd->st, false);
|
pdfioContentFillAndStroke(dd->st, false);
|
||||||
|
|
||||||
// Start a code text block...
|
// Start a code text block...
|
||||||
|
dd->tag = "P";
|
||||||
|
pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
|
||||||
|
|
||||||
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
||||||
pdfioContentTextBegin(dd->st);
|
pdfioContentTextBegin(dd->st);
|
||||||
pdfioContentTextMoveTo(dd->st, left, dd->y);
|
pdfioContentTextMoveTo(dd->st, left, dd->y);
|
||||||
@@ -2047,6 +2191,9 @@ for (code = mmdGetFirstChild(block); code; code = mmdGetNextSibling(code))
|
|||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
dd->y += lineheight;
|
dd->y += lineheight;
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
dd->tag = NULL;
|
||||||
|
|
||||||
// Draw the bottom padding...
|
// Draw the bottom padding...
|
||||||
set_color(dd, DOCCOLOR_LTGRAY);
|
set_color(dd, DOCCOLOR_LTGRAY);
|
||||||
pdfioContentPathRect(dd->st, left - CODE_PADDING,
|
pdfioContentPathRect(dd->st, left - CODE_PADDING,
|
||||||
@@ -2187,8 +2334,17 @@ Finally, we render each row in the table:
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
// Render each table row...
|
// 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 ++)
|
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
|
||||||
render_row(dd, num_cols, cols, rowptr);
|
render_row(dd, num_cols, cols, rowptr);
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
|
||||||
|
dd->in_table = false;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ TARGETS = \
|
|||||||
image2pdf \
|
image2pdf \
|
||||||
md2pdf \
|
md2pdf \
|
||||||
pdf2text \
|
pdf2text \
|
||||||
pdfioinfo
|
pdfioinfo \
|
||||||
|
pdfiomerge
|
||||||
|
|
||||||
|
|
||||||
# Make everything
|
# Make everything
|
||||||
@@ -61,5 +62,10 @@ pdfioinfo: pdfioinfo.c
|
|||||||
$(CC) $(CFLAGS) -o $@ pdfioinfo.c $(LIBS)
|
$(CC) $(CFLAGS) -o $@ pdfioinfo.c $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
# pdfiomerge
|
||||||
|
pdfiomerge: pdfiomerge.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ pdfiomerge.c $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
# Common dependencies...
|
# Common dependencies...
|
||||||
$(TARGETS): Makefile ../pdfio.h ../pdfio-content.h
|
$(TARGETS): Makefile ../pdfio.h ../pdfio-content.h
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Simple markdown to PDF converter example for PDFio.
|
// Simple markdown to PDF converter example for PDFio.
|
||||||
//
|
//
|
||||||
// Copyright © 2024 by Michael R Sweet.
|
// Copyright © 2024-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -122,6 +122,9 @@ typedef struct docdata_s // Document formatting data
|
|||||||
// State for the current page
|
// State for the current page
|
||||||
pdfio_stream_t *st; // Current page stream
|
pdfio_stream_t *st; // Current page stream
|
||||||
double y; // Current position on page
|
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
|
docfont_t font; // Current font
|
||||||
double fsize; // Current font size
|
double fsize; // Current font size
|
||||||
doccolor_t color; // Current color
|
doccolor_t color; // Current color
|
||||||
@@ -289,8 +292,8 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
// Get the markdown file from the command-line...
|
// Get the markdown file from the command-line...
|
||||||
if (argc < 2 || argc > 3)
|
if (argc < 2 || argc > 3)
|
||||||
{
|
{
|
||||||
fputs("Usage: md2pdf FILENANE.md [FILENAME.pdf]\n", stderr);
|
fputs("Usage: md2pdf FILENAME.md [FILENAME.pdf]\n", stderr);
|
||||||
fputs(" md2pdf FILENANE.md >FILENAME.pdf\n", stderr);
|
fputs(" md2pdf FILENAME.md >FILENAME.pdf\n", stderr);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,6 +475,7 @@ add_links(docdata_t *dd) // I - Document data
|
|||||||
// Create the annotation object pointing to the action...
|
// Create the annotation object pointing to the action...
|
||||||
dict = pdfioDictCreate(dd->pdf);
|
dict = pdfioDictCreate(dd->pdf);
|
||||||
pdfioDictSetName(dict, "Subtype", "Link");
|
pdfioDictSetName(dict, "Subtype", "Link");
|
||||||
|
pdfioDictSetNumber(dict, "F", 4); // Print flag
|
||||||
pdfioDictSetRect(dict, "Rect", &l->box);
|
pdfioDictSetRect(dict, "Rect", &l->box);
|
||||||
border = pdfioArrayCreate(dd->pdf);
|
border = pdfioArrayCreate(dd->pdf);
|
||||||
pdfioArrayAppendNumber(border, 0.0);
|
pdfioArrayAppendNumber(border, 0.0);
|
||||||
@@ -618,6 +622,50 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
|
|
||||||
frag = frags + num_frags;
|
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...
|
// Loop through the block and render lines...
|
||||||
for (current = mmdGetFirstChild(block), x = left; current; current = next)
|
for (current = mmdGetFirstChild(block), x = left; current; current = next)
|
||||||
{
|
{
|
||||||
@@ -796,6 +844,9 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
pdfioContentRestore(dd->st);
|
pdfioContentRestore(dd->st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
dd->tag = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -835,6 +886,9 @@ format_code(docdata_t *dd, // I - Document data
|
|||||||
pdfioContentFillAndStroke(dd->st, false);
|
pdfioContentFillAndStroke(dd->st, false);
|
||||||
|
|
||||||
// Start a code text block...
|
// Start a code text block...
|
||||||
|
dd->tag = "P";
|
||||||
|
pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
|
||||||
|
|
||||||
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
|
||||||
pdfioContentTextBegin(dd->st);
|
pdfioContentTextBegin(dd->st);
|
||||||
pdfioContentTextMoveTo(dd->st, left, dd->y);
|
pdfioContentTextMoveTo(dd->st, left, dd->y);
|
||||||
@@ -869,6 +923,9 @@ format_code(docdata_t *dd, // I - Document data
|
|||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
dd->y += lineheight;
|
dd->y += lineheight;
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
dd->tag = NULL;
|
||||||
|
|
||||||
// Draw the bottom padding...
|
// Draw the bottom padding...
|
||||||
set_color(dd, DOCCOLOR_LTGRAY);
|
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);
|
pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y - CODE_PADDING - (LINE_HEIGHT - 1.0) * SIZE_CODEBLOCK, right - left + 2.0 * CODE_PADDING, CODE_PADDING);
|
||||||
@@ -1144,8 +1201,17 @@ format_table(docdata_t *dd, // I - Document data
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render each table row...
|
// 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 ++)
|
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
|
||||||
render_row(dd, num_cols, cols, rowptr);
|
render_row(dd, num_cols, cols, rowptr);
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
|
||||||
|
dd->in_table = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1359,6 +1425,16 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
// Close the current page...
|
// Close the current page...
|
||||||
if (dd->st)
|
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);
|
pdfioStreamClose(dd->st);
|
||||||
add_links(dd);
|
add_links(dd);
|
||||||
}
|
}
|
||||||
@@ -1387,6 +1463,7 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
dd->y = dd->art_box.y2;
|
dd->y = dd->art_box.y2;
|
||||||
|
|
||||||
// Add header/footer text
|
// Add header/footer text
|
||||||
|
pdfioContentBeginMarked(dd->st, "Artifact", /*dict*/NULL);
|
||||||
set_color(dd, DOCCOLOR_GRAY);
|
set_color(dd, DOCCOLOR_GRAY);
|
||||||
set_font(dd, DOCFONT_REGULAR, SIZE_HEADFOOT);
|
set_font(dd, DOCFONT_REGULAR, SIZE_HEADFOOT);
|
||||||
|
|
||||||
@@ -1445,6 +1522,17 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
pdfioContentTextShow(dd->st, UNICODE_VALUE, dd->heading);
|
pdfioContentTextShow(dd->st, UNICODE_VALUE, dd->heading);
|
||||||
pdfioContentTextEnd(dd->st);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1617,10 +1705,12 @@ render_row(docdata_t *dd, // I - Document data
|
|||||||
// Start a new page as needed...
|
// Start a new page as needed...
|
||||||
if (!dd->st)
|
if (!dd->st)
|
||||||
new_page(dd);
|
new_page(dd);
|
||||||
|
else if ((dd->y - row->height) < dd->art_box.y1)
|
||||||
if ((dd->y - row->height) < dd->art_box.y1)
|
|
||||||
new_page(dd);
|
new_page(dd);
|
||||||
|
|
||||||
|
dd->in_row = true;
|
||||||
|
pdfioContentBeginMarked(dd->st, "TR", /*dict*/NULL);
|
||||||
|
|
||||||
if (mmdGetType(row->cells[0]) == MMD_TYPE_TABLE_HEADER_CELL)
|
if (mmdGetType(row->cells[0]) == MMD_TYPE_TABLE_HEADER_CELL)
|
||||||
{
|
{
|
||||||
// Header row, no border...
|
// Header row, no border...
|
||||||
@@ -1651,6 +1741,9 @@ render_row(docdata_t *dd, // I - Document data
|
|||||||
}
|
}
|
||||||
|
|
||||||
dd->y = row_y - row->height;
|
dd->y = row_y - row->height;
|
||||||
|
|
||||||
|
pdfioContentEndMarked(dd->st);
|
||||||
|
dd->in_row = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// https://www.msweet.org/mmd
|
// https://www.msweet.org/mmd
|
||||||
//
|
//
|
||||||
// Copyright © 2017-2024 by Michael R Sweet.
|
// Copyright © 2017-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -166,7 +166,7 @@ mmdCopyAllText(mmd_t *node) // I - Parent node
|
|||||||
char *all = NULL, // String buffer
|
char *all = NULL, // String buffer
|
||||||
*allptr = NULL, // Pointer into string buffer
|
*allptr = NULL, // Pointer into string buffer
|
||||||
*temp; // Temporary pointer
|
*temp; // Temporary pointer
|
||||||
size_t allsize = 1, // Size of "all" buffer
|
size_t allsize = 0, // Size of "all" buffer
|
||||||
textlen; // Length of "text" string
|
textlen; // Length of "text" string
|
||||||
mmd_t *current, // Current node
|
mmd_t *current, // Current node
|
||||||
*next; // Next node
|
*next; // Next node
|
||||||
@@ -179,6 +179,8 @@ mmdCopyAllText(mmd_t *node) // I - Parent node
|
|||||||
if (current->text)
|
if (current->text)
|
||||||
{
|
{
|
||||||
// Append this node's text to the string...
|
// Append this node's text to the string...
|
||||||
|
long alloff = allptr - all; // Offset within current buffer
|
||||||
|
|
||||||
textlen = strlen(current->text);
|
textlen = strlen(current->text);
|
||||||
allsize += textlen + (size_t)current->whitespace;
|
allsize += textlen + (size_t)current->whitespace;
|
||||||
temp = realloc(all, allsize);
|
temp = realloc(all, allsize);
|
||||||
@@ -189,8 +191,8 @@ mmdCopyAllText(mmd_t *node) // I - Parent node
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
allptr = temp + (allptr - all);
|
|
||||||
all = temp;
|
all = temp;
|
||||||
|
allptr = all + alloff;
|
||||||
|
|
||||||
if (current->whitespace)
|
if (current->whitespace)
|
||||||
*allptr++ = ' ';
|
*allptr++ = ' ';
|
||||||
@@ -1059,6 +1061,8 @@ mmdLoadIO(mmd_t *root, // I - Root node for document or `NULL` for a new d
|
|||||||
break;
|
break;
|
||||||
else if (line[0] == '>' && *ptr == '>')
|
else if (line[0] == '>' && *ptr == '>')
|
||||||
memmove(ptr, ptr + 1, strlen(ptr));
|
memmove(ptr, ptr + 1, strlen(ptr));
|
||||||
|
|
||||||
|
DEBUG2_printf(" line=\"%s\"\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
mmd_parse_inline(&doc, block, lineptr);
|
mmd_parse_inline(&doc, block, lineptr);
|
||||||
@@ -1493,7 +1497,7 @@ mmd_parse_inline(_mmd_doc_t *doc, // I - Document
|
|||||||
|
|
||||||
for (text = NULL, type = MMD_TYPE_NORMAL_TEXT; *lineptr; lineptr ++)
|
for (text = NULL, type = MMD_TYPE_NORMAL_TEXT; *lineptr; lineptr ++)
|
||||||
{
|
{
|
||||||
DEBUG2_printf("mmd_parse_inline: lineptr=%p(\"%32.32s...\"), type=%d, text=%p, whitespace=%d\n", lineptr, lineptr, type, text, whitespace);
|
DEBUG2_printf("mmd_parse_inline: lineptr=%p(\"%s\"), type=%d, text=%p, whitespace=%d\n", lineptr, lineptr, type, text, whitespace);
|
||||||
|
|
||||||
if (isspace(*lineptr & 255) && type != MMD_TYPE_CODE_TEXT)
|
if (isspace(*lineptr & 255) && type != MMD_TYPE_CODE_TEXT)
|
||||||
{
|
{
|
||||||
@@ -2090,6 +2094,8 @@ mmd_read_buffer(_mmd_filebuf_t *file) // I - File buffer
|
|||||||
if (file->bufptr && file->bufptr > file->buffer)
|
if (file->bufptr && file->bufptr > file->buffer)
|
||||||
{
|
{
|
||||||
// Discard previous characters in the 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);
|
memmove(file->buffer, file->bufptr, file->bufend - file->bufptr);
|
||||||
file->bufend -= (file->bufptr - file->buffer);
|
file->bufend -= (file->bufptr - file->buffer);
|
||||||
}
|
}
|
||||||
@@ -2099,11 +2105,13 @@ mmd_read_buffer(_mmd_filebuf_t *file) // I - File buffer
|
|||||||
file->bufend = 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 += bytes;
|
||||||
|
|
||||||
*(file->bufend) = '\0';
|
*(file->bufend) = '\0';
|
||||||
file->bufptr = file->buffer;
|
file->bufptr = file->buffer;
|
||||||
|
|
||||||
|
DEBUG2_printf("mmd_read_buffer: after buffer=\"%s\"\n", file->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2161,6 +2169,8 @@ mmd_read_line(_mmd_filebuf_t *file, // I - File buffer
|
|||||||
else if (!strchr(file->bufptr, '\n'))
|
else if (!strchr(file->bufptr, '\n'))
|
||||||
mmd_read_buffer(file);
|
mmd_read_buffer(file);
|
||||||
|
|
||||||
|
DEBUG2_printf("mmd_read_line: Returning \"%s\"\n", line);
|
||||||
|
|
||||||
return (line);
|
return (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1417,4 +1417,4 @@ puts_utf16(const char *s) // I - Hex string
|
|||||||
|
|
||||||
put_utf8(ch);
|
put_utf8(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
catalog = pdfioFileGetCatalog(pdf);
|
catalog = pdfioFileGetCatalog(pdf);
|
||||||
author = pdfioFileGetAuthor(pdf);
|
author = pdfioFileGetAuthor(pdf);
|
||||||
creator = pdfioFileGetCreator(pdf);
|
creator = pdfioFileGetCreator(pdf);
|
||||||
has_acroform = pdfioDictGetObj(catalog, "AcroForm") != NULL ? true : false;
|
has_acroform = pdfioDictGetType(catalog, "AcroForm") != PDFIO_VALTYPE_NONE;
|
||||||
num_pages = pdfioFileGetNumPages(pdf);
|
num_pages = pdfioFileGetNumPages(pdf);
|
||||||
producer = pdfioFileGetProducer(pdf);
|
producer = pdfioFileGetProducer(pdf);
|
||||||
title = pdfioFileGetTitle(pdf);
|
title = pdfioFileGetTitle(pdf);
|
||||||
|
|||||||
146
examples/pdfiomerge.c
Normal file
146
examples/pdfiomerge.c
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
//
|
||||||
|
// PDF merge program for PDFio.
|
||||||
|
//
|
||||||
|
// Copyright © 2025 by Michael R Sweet.
|
||||||
|
//
|
||||||
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
|
// information.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// ./pdfiomerge [-o OUTPUT.pdf] INPUT.pdf [... INPUT.pdf]
|
||||||
|
// ./pdfiomerge INPUT.pdf [... INPUT.pdf] >OUTPUT.pdf
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <pdfio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Local functions...
|
||||||
|
//
|
||||||
|
|
||||||
|
static ssize_t output_cb(void *output_cbdata, const void *buffer, size_t bytes);
|
||||||
|
static int usage(FILE *out);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'main()' - Main entry.
|
||||||
|
//
|
||||||
|
|
||||||
|
int // O - Exit status
|
||||||
|
main(int argc, // I - Number of command-line arguments
|
||||||
|
char *argv[]) // I - Command-line arguments
|
||||||
|
{
|
||||||
|
int i; // Looping var
|
||||||
|
const char *opt; // Current option
|
||||||
|
pdfio_file_t *inpdf, // Input PDF file
|
||||||
|
*outpdf = NULL; // Output PDF file
|
||||||
|
|
||||||
|
|
||||||
|
// Parse command-line...
|
||||||
|
for (i = 1; i < argc; i ++)
|
||||||
|
{
|
||||||
|
if (!strcmp(argv[i], "--help"))
|
||||||
|
{
|
||||||
|
return (usage(stdout));
|
||||||
|
}
|
||||||
|
else if (!strncmp(argv[i], "--", 2))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "pdfiomerge: Unknown option '%s'.\n", argv[i]);
|
||||||
|
return (usage(stderr));
|
||||||
|
}
|
||||||
|
else if (argv[i][0] == '-')
|
||||||
|
{
|
||||||
|
for (opt = argv[i] + 1; *opt; opt ++)
|
||||||
|
{
|
||||||
|
switch (*opt)
|
||||||
|
{
|
||||||
|
case 'o' : // -o OUTPUT.pdf
|
||||||
|
if (outpdf)
|
||||||
|
{
|
||||||
|
fputs("pdfiomerge: 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);
|
||||||
|
return (usage(stderr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((outpdf = pdfioFileCreate(argv[i], /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL)
|
||||||
|
return (1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
fprintf(stderr, "pdfiomerge: Unknown option '-%c'.\n", *opt);
|
||||||
|
return (usage(stderr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((inpdf = pdfioFileOpen(argv[i], /*password_cb*/NULL, /*password_data*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL)
|
||||||
|
{
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy PDF file...
|
||||||
|
size_t p, // Current page
|
||||||
|
nump; // Number of pages
|
||||||
|
|
||||||
|
if (!outpdf)
|
||||||
|
{
|
||||||
|
if ((outpdf = pdfioFileCreateOutput(output_cb, /*output_cbdata*/NULL, /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL)
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = 0, nump = pdfioFileGetNumPages(inpdf); p < nump; p ++)
|
||||||
|
{
|
||||||
|
if (!pdfioPageCopy(outpdf, pdfioFileGetPage(inpdf, p)))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdfioFileClose(inpdf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outpdf)
|
||||||
|
return (usage(stderr));
|
||||||
|
|
||||||
|
pdfioFileClose(outpdf);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'output_cb()' - Write PDF data to the standard output...
|
||||||
|
//
|
||||||
|
|
||||||
|
static ssize_t // O - Number of bytes written
|
||||||
|
output_cb(void *output_cbdata, // I - Callback data (not used)
|
||||||
|
const void *buffer, // I - Buffer to write
|
||||||
|
size_t bytes) // I - Number of bytes to write
|
||||||
|
{
|
||||||
|
(void)output_cbdata;
|
||||||
|
|
||||||
|
return ((ssize_t)fwrite(buffer, 1, bytes, stdout));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'usage()' - Show program usage.
|
||||||
|
//
|
||||||
|
|
||||||
|
static int // O - Exit status
|
||||||
|
usage(FILE *out) // I - stdout or stderr
|
||||||
|
{
|
||||||
|
fputs("Usage: pdfmerge [OPTIONS] INPUT.pdf [... INPUT.pdf] >OUTPUT.pdf\n", out);
|
||||||
|
fputs("Options:\n", out);
|
||||||
|
fputs(" --help Show help.\n", out);
|
||||||
|
fputs(" -o OUTPUT.pdf Send output to filename instead of stdout.\n", out);
|
||||||
|
|
||||||
|
return (out == stdout ? 0 : 1);
|
||||||
|
}
|
||||||
@@ -32,11 +32,11 @@ if test $(grep AC_INIT configure.ac | awk '{print $2}') != "[$version],"; then
|
|||||||
status=1
|
status=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $(head -4 CHANGES.md | tail -1 | awk '{print $1}') != "v$version"; then
|
if test $(head -5 CHANGES.md | tail -1 | awk '{print $1}') != "v$version"; then
|
||||||
echo "Still need to update CHANGES.md version number."
|
echo "Still need to update CHANGES.md version number."
|
||||||
status=1
|
status=1
|
||||||
fi
|
fi
|
||||||
if test $(head -4 CHANGES.md | tail -1 | awk '{print $3}') = "YYYY-MM-DD"; then
|
if test $(head -5 CHANGES.md | tail -1 | awk '{print $3}') = "YYYY-MM-DD"; then
|
||||||
echo "Still need to update CHANGES.md release date."
|
echo "Still need to update CHANGES.md release date."
|
||||||
status=1
|
status=1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ pdfioArrayCopy(pdfio_file_t *pdf, // I - PDF file
|
|||||||
vdst; // Current destination value
|
vdst; // Current destination value
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioArrayCopy(pdf=%p, a=%p(%p))\n", pdf, a, a ? a->pdf : NULL);
|
PDFIO_DEBUG("pdfioArrayCopy(pdf=%p, a=%p(%p))\n", (void *)pdf, (void *)a, a ? (void *)a->pdf : NULL);
|
||||||
|
|
||||||
// Create the new array...
|
// Create the new array...
|
||||||
if ((na = pdfioArrayCreate(pdf)) == NULL)
|
if ((na = pdfioArrayCreate(pdf)) == NULL)
|
||||||
@@ -606,7 +606,7 @@ _pdfioArrayRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfio_value_t value; // Value
|
_pdfio_value_t value; // Value
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioArrayRead(pdf=%p, tb=%p)\n", pdf, tb);
|
PDFIO_DEBUG("_pdfioArrayRead(pdf=%p, tb=%p)\n", (void *)pdf, (void *)tb);
|
||||||
|
|
||||||
// Create an array...
|
// Create an array...
|
||||||
if ((array = pdfioArrayCreate(pdf)) == NULL)
|
if ((array = pdfioArrayCreate(pdf)) == NULL)
|
||||||
@@ -640,6 +640,8 @@ _pdfioArrayRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
//
|
//
|
||||||
// 'pdfioArrayRemove()' - Remove an array entry.
|
// 'pdfioArrayRemove()' - Remove an array entry.
|
||||||
//
|
//
|
||||||
|
// @since PDFio v1.4@
|
||||||
|
//
|
||||||
|
|
||||||
bool // O - `true` on success, `false` otherwise
|
bool // O - `true` on success, `false` otherwise
|
||||||
pdfioArrayRemove(pdfio_array_t *a, // I - Array
|
pdfioArrayRemove(pdfio_array_t *a, // I - Array
|
||||||
|
|||||||
532
pdfio-cgats001-compat.h
Normal file
532
pdfio-cgats001-compat.h
Normal file
@@ -0,0 +1,532 @@
|
|||||||
|
/* 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
|
||||||
|
};
|
||||||
@@ -27,7 +27,7 @@ bool // O - `true` on sucess, `false` on EOF
|
|||||||
_pdfioFileConsume(pdfio_file_t *pdf, // I - PDF file
|
_pdfioFileConsume(pdfio_file_t *pdf, // I - PDF file
|
||||||
size_t bytes) // I - Bytes to consume
|
size_t bytes) // I - Bytes to consume
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("_pdfioFileConsume(pdf=%p, bytes=%u)\n", pdf, (unsigned)bytes);
|
PDFIO_DEBUG("_pdfioFileConsume(pdf=%p, bytes=%u)\n", (void *)pdf, (unsigned)bytes);
|
||||||
|
|
||||||
if ((size_t)(pdf->bufend - pdf->bufptr) > bytes)
|
if ((size_t)(pdf->bufend - pdf->bufptr) > bytes)
|
||||||
pdf->bufptr += bytes;
|
pdf->bufptr += bytes;
|
||||||
@@ -47,7 +47,7 @@ _pdfioFileConsume(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// `false` to halt.
|
// `false` to halt.
|
||||||
//
|
//
|
||||||
|
|
||||||
bool // O - `false` to stop
|
bool // O - `false` to stop, `true` to continue
|
||||||
_pdfioFileDefaultError(
|
_pdfioFileDefaultError(
|
||||||
pdfio_file_t *pdf, // I - PDF file
|
pdfio_file_t *pdf, // I - PDF file
|
||||||
const char *message, // I - Error message
|
const char *message, // I - Error message
|
||||||
@@ -57,7 +57,7 @@ _pdfioFileDefaultError(
|
|||||||
|
|
||||||
fprintf(stderr, "%s: %s\n", pdf->filename, message);
|
fprintf(stderr, "%s: %s\n", pdf->filename, message);
|
||||||
|
|
||||||
return (false);
|
return (!strncmp(message, "WARNING:", 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ _pdfioFileError(pdfio_file_t *pdf, // I - PDF file
|
|||||||
bool // O - `true` on success, `false` on failure
|
bool // O - `true` on success, `false` on failure
|
||||||
_pdfioFileFlush(pdfio_file_t *pdf) // I - PDF file
|
_pdfioFileFlush(pdfio_file_t *pdf) // I - PDF file
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("_pdfioFileFlush(pdf=%p)\n", pdf);
|
PDFIO_DEBUG("_pdfioFileFlush(pdf=%p)\n", (void *)pdf);
|
||||||
|
|
||||||
if (pdf->bufptr > pdf->buffer)
|
if (pdf->bufptr > pdf->buffer)
|
||||||
{
|
{
|
||||||
@@ -134,19 +134,20 @@ _pdfioFileGetChar(pdfio_file_t *pdf) // I - PDF file
|
|||||||
bool // O - `true` on success, `false` on error
|
bool // O - `true` on success, `false` on error
|
||||||
_pdfioFileGets(pdfio_file_t *pdf, // I - PDF file
|
_pdfioFileGets(pdfio_file_t *pdf, // I - PDF file
|
||||||
char *buffer, // I - Line buffer
|
char *buffer, // I - Line buffer
|
||||||
size_t bufsize) // I - Size of line buffer
|
size_t bufsize, // I - Size of line buffer
|
||||||
|
bool discard) // I - OK to discard excess line chars?
|
||||||
{
|
{
|
||||||
bool eol = false; // End of line?
|
bool eol = false; // End of line?
|
||||||
char *bufptr = buffer, // Pointer into buffer
|
char *bufptr = buffer, // Pointer into buffer
|
||||||
*bufend = buffer + bufsize - 1; // Pointer to end of buffer
|
*bufend = buffer + bufsize - 1; // Pointer to end of 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)));
|
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)));
|
||||||
|
|
||||||
while (!eol)
|
while (!eol)
|
||||||
{
|
{
|
||||||
// If there are characters ready in the buffer, use them...
|
// If there are characters ready in the buffer, use them...
|
||||||
while (!eol && pdf->bufptr < pdf->bufend && bufptr < bufend)
|
while (!eol && pdf->bufptr < pdf->bufend)
|
||||||
{
|
{
|
||||||
char ch = *(pdf->bufptr++); // Next character in buffer
|
char ch = *(pdf->bufptr++); // Next character in buffer
|
||||||
|
|
||||||
@@ -168,8 +169,10 @@ _pdfioFileGets(pdfio_file_t *pdf, // I - PDF file
|
|||||||
pdf->bufptr ++;
|
pdf->bufptr ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (bufptr < bufend)
|
||||||
*bufptr++ = ch;
|
*bufptr++ = ch;
|
||||||
|
else if (!discard)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the read buffer as needed...
|
// Fill the read buffer as needed...
|
||||||
@@ -356,7 +359,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
|
|||||||
off_t offset, // I - Offset
|
off_t offset, // I - Offset
|
||||||
int whence) // I - Offset base
|
int whence) // I - Offset base
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("_pdfioFileSeek(pdf=%p, offset=%ld, whence=%d) pdf->bufpos=%lu\n", pdf, (long)offset, whence, (unsigned long)(pdf ? pdf->bufpos : 0));
|
PDFIO_DEBUG("_pdfioFileSeek(pdf=%p, offset=%ld, whence=%d) pdf->bufpos=%lu\n", (void *)pdf, (long)offset, whence, (unsigned long)(pdf ? pdf->bufpos : 0));
|
||||||
|
|
||||||
// Adjust offset for relative seeks...
|
// Adjust offset for relative seeks...
|
||||||
if (whence == SEEK_CUR)
|
if (whence == SEEK_CUR)
|
||||||
@@ -373,7 +376,7 @@ _pdfioFileSeek(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Yes, seek within existing buffer...
|
// Yes, seek within existing buffer...
|
||||||
pdf->bufptr = pdf->buffer + (offset - pdf->bufpos);
|
pdf->bufptr = pdf->buffer + (offset - pdf->bufpos);
|
||||||
PDFIO_DEBUG("_pdfioFileSeek: Seek within buffer, bufpos=%ld.\n", (long)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", pdf->buffer, pdf->bufptr, pdf->bufptr[0] & 255, pdf->bufptr[1] & 255, pdf->bufend);
|
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);
|
||||||
return (offset);
|
return (offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +411,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: Reset bufpos=%ld, offset=%lu.\n", (long)pdf->bufpos, (unsigned long)offset);
|
||||||
PDFIO_DEBUG("_pdfioFileSeek: buffer=%p, bufptr=%p, bufend=%p\n", pdf->buffer, pdf->bufptr, pdf->bufend);
|
PDFIO_DEBUG("_pdfioFileSeek: buffer=%p, bufptr=%p, bufend=%p\n", (void *)pdf->buffer, (void *)pdf->bufptr, (void *)pdf->bufend);
|
||||||
|
|
||||||
pdf->bufpos = offset;
|
pdf->bufpos = offset;
|
||||||
|
|
||||||
@@ -424,7 +427,7 @@ off_t // O - Offset from beginning of file
|
|||||||
_pdfioFileTell(pdfio_file_t *pdf) // I - PDF file
|
_pdfioFileTell(pdfio_file_t *pdf) // I - PDF file
|
||||||
{
|
{
|
||||||
if (pdf->bufptr)
|
if (pdf->bufptr)
|
||||||
return (pdf->bufpos + (pdf->bufptr - pdf->buffer));
|
return (pdf->bufpos + (off_t)(pdf->bufptr - pdf->buffer));
|
||||||
else
|
else
|
||||||
return (pdf->bufpos);
|
return (pdf->bufpos);
|
||||||
}
|
}
|
||||||
@@ -452,7 +455,7 @@ _pdfioFileWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
if (!write_buffer(pdf, buffer, bytes))
|
if (!write_buffer(pdf, buffer, bytes))
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
pdf->bufpos += bytes;
|
pdf->bufpos += (off_t)bytes;
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@@ -478,7 +481,7 @@ fill_buffer(pdfio_file_t *pdf) // I - PDF file
|
|||||||
|
|
||||||
// Advance current position in file as needed...
|
// Advance current position in file as needed...
|
||||||
if (pdf->bufend)
|
if (pdf->bufend)
|
||||||
pdf->bufpos += pdf->bufend - pdf->buffer;
|
pdf->bufpos += (off_t)(pdf->bufend - pdf->buffer);
|
||||||
|
|
||||||
// Try reading from the file...
|
// Try reading from the file...
|
||||||
if ((bytes = read_buffer(pdf, pdf->buffer, sizeof(pdf->buffer))) <= 0)
|
if ((bytes = read_buffer(pdf, pdf->buffer, sizeof(pdf->buffer))) <= 0)
|
||||||
|
|||||||
1434
pdfio-content.c
1434
pdfio-content.c
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Public content header file for PDFio.
|
// Public content header file for PDFio.
|
||||||
//
|
//
|
||||||
// Copyright © 2021-2023 by Michael R Sweet.
|
// Copyright © 2021-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -23,7 +23,8 @@ typedef enum pdfio_cs_e // Standard color spaces
|
|||||||
{
|
{
|
||||||
PDFIO_CS_ADOBE, // AdobeRGB 1998
|
PDFIO_CS_ADOBE, // AdobeRGB 1998
|
||||||
PDFIO_CS_P3_D65, // Display P3
|
PDFIO_CS_P3_D65, // Display P3
|
||||||
PDFIO_CS_SRGB // sRGB
|
PDFIO_CS_SRGB, // sRGB
|
||||||
|
PDFIO_CS_CGATS001 // CGATS001 (CMYK)
|
||||||
} pdfio_cs_t;
|
} pdfio_cs_t;
|
||||||
|
|
||||||
typedef enum pdfio_linecap_e // Line capping modes
|
typedef enum pdfio_linecap_e // Line capping modes
|
||||||
@@ -68,8 +69,10 @@ 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);
|
extern pdfio_array_t *pdfioArrayCreateColorFromStandard(pdfio_file_t *pdf, size_t num_colors, pdfio_cs_t cs);
|
||||||
|
|
||||||
// PDF content drawing functions...
|
// 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 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 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 pdfioContentFill(pdfio_stream_t *st, bool even_odd) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentFillAndStroke(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;
|
extern bool pdfioContentMatrixConcat(pdfio_stream_t *st, pdfio_matrix_t m) _PDFIO_PUBLIC;
|
||||||
@@ -120,14 +123,16 @@ extern bool pdfioContentTextMoveLine(pdfio_stream_t *st, double tx, double ty)
|
|||||||
extern bool pdfioContentTextMoveTo(pdfio_stream_t *st, double tx, double ty) _PDFIO_PUBLIC;
|
extern bool pdfioContentTextMoveTo(pdfio_stream_t *st, double tx, double ty) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextNewLine(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
extern bool pdfioContentTextNewLine(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextNewLineShow(pdfio_stream_t *st, double ws, double cs, bool unicode, const char *s) _PDFIO_PUBLIC;
|
extern bool pdfioContentTextNewLineShow(pdfio_stream_t *st, double ws, double cs, bool unicode, const char *s) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextNewLineShowf(pdfio_stream_t *st, double ws, double cs, bool unicode, const char *format, ...) _PDFIO_PUBLIC _PDFIO_FORMAT(5,6);
|
extern bool pdfioContentTextNewLineShowf(pdfio_stream_t *st, double ws, double cs, bool unicode, const char *format, ...) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextNextLine(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
extern bool pdfioContentTextNextLine(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextShow(pdfio_stream_t *st, bool unicode, const char *s) _PDFIO_PUBLIC;
|
extern bool pdfioContentTextShow(pdfio_stream_t *st, bool unicode, const char *s) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextShowf(pdfio_stream_t *st, bool unicode, const char *format, ...) _PDFIO_PUBLIC _PDFIO_FORMAT(3,4);
|
extern bool pdfioContentTextShowf(pdfio_stream_t *st, bool unicode, const char *format, ...) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioContentTextShowJustified(pdfio_stream_t *st, bool unicode, size_t num_fragments, const double *offsets, const char * const *fragments) _PDFIO_PUBLIC;
|
extern bool pdfioContentTextShowJustified(pdfio_stream_t *st, bool unicode, size_t num_fragments, const double *offsets, const char * const *fragments) _PDFIO_PUBLIC;
|
||||||
|
|
||||||
// Resource helpers...
|
// 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 *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 *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 *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;
|
extern pdfio_obj_t *pdfioFileCreateICCObjFromFile(pdfio_file_t *pdf, const char *filename, size_t num_colors) _PDFIO_PUBLIC;
|
||||||
|
|||||||
163
pdfio-crypto.c
163
pdfio-crypto.c
@@ -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 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 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, 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, bool encrypt_metadata, 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_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 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]);
|
static void pad_password(const char *password, uint8_t pad[32]);
|
||||||
@@ -158,7 +158,7 @@ _pdfioCryptoLock(
|
|||||||
// Generate the encryption key
|
// Generate the encryption key
|
||||||
file_id = pdfioArrayGetBinary(pdf->id_array, 0, &file_idlen);
|
file_id = pdfioArrayGetBinary(pdf->id_array, 0, &file_idlen);
|
||||||
|
|
||||||
make_file_key(encryption, permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->file_key);
|
make_file_key(encryption, permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->encrypt_metadata, pdf->file_key);
|
||||||
pdf->file_keylen = 16;
|
pdf->file_keylen = 16;
|
||||||
|
|
||||||
// Generate the user key...
|
// Generate the user key...
|
||||||
@@ -214,8 +214,9 @@ _pdfioCryptoLock(
|
|||||||
|
|
||||||
pdfioObjClose(pdf->encrypt_obj);
|
pdfioObjClose(pdf->encrypt_obj);
|
||||||
|
|
||||||
pdf->encryption = encryption;
|
pdf->encrypt_dict = dict;
|
||||||
pdf->permissions = permissions;
|
pdf->encryption = encryption;
|
||||||
|
pdf->permissions = permissions;
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@@ -409,16 +410,9 @@ _pdfioCryptoMakeReader(
|
|||||||
uint8_t data[21]; // Key data
|
uint8_t data[21]; // Key data
|
||||||
_pdfio_md5_t md5; // MD5 state
|
_pdfio_md5_t md5; // MD5 state
|
||||||
uint8_t digest[16]; // MD5 digest value
|
uint8_t digest[16]; // MD5 digest value
|
||||||
#if PDFIO_OBJ_CRYPT
|
|
||||||
pdfio_array_t *id_array; // Object ID array
|
|
||||||
unsigned char *id_value; // Object ID value
|
|
||||||
size_t id_len; // Length of object ID
|
|
||||||
uint8_t temp_key[16]; // File key for object
|
|
||||||
#endif // PDFIO_OBJ_CRYPT
|
|
||||||
uint8_t *file_key; // Computed file key to use
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
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);
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!pdf)
|
if (!pdf)
|
||||||
@@ -427,60 +421,6 @@ _pdfioCryptoMakeReader(
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PDFIO_OBJ_CRYPT
|
|
||||||
if ((id_array = pdfioDictGetArray(pdfioObjGetDict(obj), "ID")) != NULL)
|
|
||||||
{
|
|
||||||
// Object has its own ID that will get used for encryption...
|
|
||||||
_pdfio_md5_t md5; // MD5 context
|
|
||||||
uint8_t file_digest[16]; // MD5 digest of file ID and pad
|
|
||||||
uint8_t user_pad[32], // Padded user password
|
|
||||||
own_user_key[32], // Calculated user key
|
|
||||||
pdf_user_key[32]; // Decrypted user key
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioCryptoMakeReader: Per-object file ID.\n");
|
|
||||||
|
|
||||||
if ((id_value = pdfioArrayGetBinary(id_array, 0, &id_len)) == NULL)
|
|
||||||
{
|
|
||||||
*ivlen = 0;
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_pdfioCryptoMD5Init(&md5);
|
|
||||||
_pdfioCryptoMD5Append(&md5, pdf_passpad, 32);
|
|
||||||
_pdfioCryptoMD5Append(&md5, id_value, id_len);
|
|
||||||
_pdfioCryptoMD5Finish(&md5, file_digest);
|
|
||||||
|
|
||||||
make_owner_key(pdf->encryption, pdf->password, pdf->owner_key, user_pad);
|
|
||||||
make_file_key(pdf->encryption, pdf->permissions, id_value, id_len, user_pad, pdf->owner_key, temp_key);
|
|
||||||
make_user_key(id_value, id_len, own_user_key);
|
|
||||||
|
|
||||||
if (memcmp(own_user_key, pdf->user_key, sizeof(own_user_key)))
|
|
||||||
{
|
|
||||||
PDFIO_DEBUG("_pdfioCryptoMakeReader: Not user password, trying owner password.\n");
|
|
||||||
|
|
||||||
make_file_key(pdf->encryption, pdf->permissions, id_value, id_len, pdf->password, pdf->owner_key, temp_key);
|
|
||||||
make_user_key(id_value, id_len, own_user_key);
|
|
||||||
|
|
||||||
memcpy(pdf_user_key, pdf->user_key, sizeof(pdf_user_key));
|
|
||||||
decrypt_user_key(pdf->encryption, temp_key, pdf_user_key);
|
|
||||||
|
|
||||||
if (memcmp(pdf->password, pdf_user_key, 32) && memcmp(own_user_key, pdf_user_key, 16))
|
|
||||||
{
|
|
||||||
_pdfioFileError(pdf, "Unable to unlock file.");
|
|
||||||
*ivlen = 0;
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file_key = temp_key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif // PDFIO_OBJ_CRYPT
|
|
||||||
{
|
|
||||||
// Use the default file key...
|
|
||||||
file_key = pdf->file_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (pdf->encryption)
|
switch (pdf->encryption)
|
||||||
{
|
{
|
||||||
default :
|
default :
|
||||||
@@ -490,20 +430,20 @@ _pdfioCryptoMakeReader(
|
|||||||
|
|
||||||
case PDFIO_ENCRYPTION_RC4_40 :
|
case PDFIO_ENCRYPTION_RC4_40 :
|
||||||
// Copy the key data for the MD5 hash.
|
// Copy the key data for the MD5 hash.
|
||||||
memcpy(data, file_key, 16);
|
memcpy(data, pdf->file_key, 5);
|
||||||
data[16] = (uint8_t)obj->number;
|
data[5] = (uint8_t)obj->number;
|
||||||
data[17] = (uint8_t)(obj->number >> 8);
|
data[6] = (uint8_t)(obj->number >> 8);
|
||||||
data[18] = (uint8_t)(obj->number >> 16);
|
data[7] = (uint8_t)(obj->number >> 16);
|
||||||
data[19] = (uint8_t)obj->generation;
|
data[8] = (uint8_t)obj->generation;
|
||||||
data[20] = (uint8_t)(obj->generation >> 8);
|
data[9] = (uint8_t)(obj->generation >> 8);
|
||||||
|
|
||||||
// Hash it...
|
// Hash it...
|
||||||
_pdfioCryptoMD5Init(&md5);
|
_pdfioCryptoMD5Init(&md5);
|
||||||
_pdfioCryptoMD5Append(&md5, data, sizeof(data));
|
_pdfioCryptoMD5Append(&md5, data, 10);
|
||||||
_pdfioCryptoMD5Finish(&md5, digest);
|
_pdfioCryptoMD5Finish(&md5, digest);
|
||||||
|
|
||||||
// Initialize the RC4 context using 40 bits of the digest...
|
// Initialize the RC4 context using 80 bits of the digest...
|
||||||
_pdfioCryptoRC4Init(&ctx->rc4, digest, 5);
|
_pdfioCryptoRC4Init(&ctx->rc4, digest, 10);
|
||||||
*ivlen = 0;
|
*ivlen = 0;
|
||||||
return ((_pdfio_crypto_cb_t)_pdfioCryptoRC4Crypt);
|
return ((_pdfio_crypto_cb_t)_pdfioCryptoRC4Crypt);
|
||||||
|
|
||||||
@@ -515,9 +455,13 @@ _pdfioCryptoMakeReader(
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
__attribute__((fallthrough));
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
case PDFIO_ENCRYPTION_RC4_128 :
|
case PDFIO_ENCRYPTION_RC4_128 :
|
||||||
// Copy the key data for the MD5 hash.
|
// Copy the key data for the MD5 hash.
|
||||||
memcpy(data, file_key, 16);
|
memcpy(data, pdf->file_key, 16);
|
||||||
data[16] = (uint8_t)obj->number;
|
data[16] = (uint8_t)obj->number;
|
||||||
data[17] = (uint8_t)(obj->number >> 8);
|
data[17] = (uint8_t)(obj->number >> 8);
|
||||||
data[18] = (uint8_t)(obj->number >> 16);
|
data[18] = (uint8_t)(obj->number >> 16);
|
||||||
@@ -565,7 +509,7 @@ _pdfioCryptoMakeWriter(
|
|||||||
uint8_t digest[16]; /* MD5 digest value */
|
uint8_t digest[16]; /* MD5 digest value */
|
||||||
|
|
||||||
|
|
||||||
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);
|
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);
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!pdf)
|
if (!pdf)
|
||||||
@@ -627,7 +571,6 @@ _pdfioCryptoUnlock(
|
|||||||
{
|
{
|
||||||
int tries; // Number of tries
|
int tries; // Number of tries
|
||||||
const char *password = NULL; // Password to try
|
const char *password = NULL; // Password to try
|
||||||
pdfio_dict_t *encrypt_dict; // Encrypt objection dictionary
|
|
||||||
int version, // Version value
|
int version, // Version value
|
||||||
revision, // Revision value
|
revision, // Revision value
|
||||||
length; // Key length value
|
length; // Key length value
|
||||||
@@ -643,22 +586,23 @@ _pdfioCryptoUnlock(
|
|||||||
file_idlen; // Length of file ID
|
file_idlen; // Length of file ID
|
||||||
_pdfio_md5_t md5; // MD5 context
|
_pdfio_md5_t md5; // MD5 context
|
||||||
uint8_t file_digest[16]; // MD5 digest of file ID and pad
|
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 object
|
// See if we support the type of encryption specified by the Encrypt
|
||||||
// dictionary...
|
// dictionary...
|
||||||
if ((encrypt_dict = pdfioObjGetDict(pdf->encrypt_obj)) == NULL)
|
handler = pdfioDictGetName(pdf->encrypt_dict, "Filter");
|
||||||
{
|
version = (int)pdfioDictGetNumber(pdf->encrypt_dict, "V");
|
||||||
_pdfioFileError(pdf, "Unable to get encryption dictionary.");
|
revision = (int)pdfioDictGetNumber(pdf->encrypt_dict, "R");
|
||||||
return (false);
|
length = (int)pdfioDictGetNumber(pdf->encrypt_dict, "Length");
|
||||||
}
|
|
||||||
|
|
||||||
handler = pdfioDictGetName(encrypt_dict, "Filter");
|
if ((value = _pdfioDictGetValue(pdf->encrypt_dict, "EncryptMetadata")) != NULL && value->type == PDFIO_VALTYPE_BOOLEAN)
|
||||||
version = (int)pdfioDictGetNumber(encrypt_dict, "V");
|
pdf->encrypt_metadata = value->value.boolean;
|
||||||
revision = (int)pdfioDictGetNumber(encrypt_dict, "R");
|
else
|
||||||
length = (int)pdfioDictGetNumber(encrypt_dict, "Length");
|
pdf->encrypt_metadata = true;
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioCryptoUnlock: handler=%p(%s), version=%d, revision=%d, length=%d\n", (void *)handler, handler ? handler : "(null)", version, revision, 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");
|
||||||
|
|
||||||
if (!handler || strcmp(handler, "Standard"))
|
if (!handler || strcmp(handler, "Standard"))
|
||||||
{
|
{
|
||||||
@@ -672,9 +616,9 @@ _pdfioCryptoUnlock(
|
|||||||
pdfio_dict_t *filter; // Crypt Filter
|
pdfio_dict_t *filter; // Crypt Filter
|
||||||
const char *cfm; // Crypt filter method
|
const char *cfm; // Crypt filter method
|
||||||
|
|
||||||
stream_filter = pdfioDictGetName(encrypt_dict, "StmF");
|
stream_filter = pdfioDictGetName(pdf->encrypt_dict, "StmF");
|
||||||
string_filter = pdfioDictGetName(encrypt_dict, "StrF");
|
string_filter = pdfioDictGetName(pdf->encrypt_dict, "StrF");
|
||||||
cf_dict = pdfioDictGetDict(encrypt_dict, "CF");
|
cf_dict = pdfioDictGetDict(pdf->encrypt_dict, "CF");
|
||||||
|
|
||||||
if (!cf_dict)
|
if (!cf_dict)
|
||||||
{
|
{
|
||||||
@@ -750,12 +694,17 @@ _pdfioCryptoUnlock(
|
|||||||
|
|
||||||
// Grab the remaining values we need to unlock the PDF...
|
// Grab the remaining values we need to unlock the PDF...
|
||||||
pdf->file_keylen = (size_t)(length / 8);
|
pdf->file_keylen = (size_t)(length / 8);
|
||||||
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);
|
PDFIO_DEBUG("_pdfioCryptoUnlock: permissions=%d\n", pdf->permissions);
|
||||||
|
|
||||||
owner_key = pdfioDictGetBinary(encrypt_dict, "O", &owner_keylen);
|
owner_key = pdfioDictGetBinary(pdf->encrypt_dict, "O", &owner_keylen);
|
||||||
user_key = pdfioDictGetBinary(encrypt_dict, "U", &user_keylen);
|
user_key = pdfioDictGetBinary(pdf->encrypt_dict, "U", &user_keylen);
|
||||||
|
|
||||||
if (!owner_key)
|
if (!owner_key)
|
||||||
{
|
{
|
||||||
@@ -823,7 +772,7 @@ _pdfioCryptoUnlock(
|
|||||||
make_owner_key(pdf->encryption, pad, pdf->owner_key, user_pad);
|
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]);
|
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, file_key);
|
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, user_pad, pdf->owner_key, pdf->encrypt_metadata, 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]);
|
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);
|
make_user_key(file_id, file_idlen, own_user_key);
|
||||||
@@ -841,7 +790,7 @@ _pdfioCryptoUnlock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not the owner password, try the user password...
|
// Not the owner password, try the user password...
|
||||||
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, pad, pdf->owner_key, file_key);
|
make_file_key(pdf->encryption, pdf->permissions, file_id, file_idlen, pad, pdf->owner_key, pdf->encrypt_metadata, 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]);
|
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);
|
make_user_key(file_id, file_idlen, own_user_key);
|
||||||
@@ -973,6 +922,8 @@ make_file_key(
|
|||||||
size_t file_idlen, // I - Length of file ID
|
size_t file_idlen, // I - Length of file ID
|
||||||
const uint8_t *user_pad, // I - Padded user password
|
const uint8_t *user_pad, // I - Padded user password
|
||||||
const uint8_t *owner_key, // I - Owner key
|
const uint8_t *owner_key, // I - Owner key
|
||||||
|
bool encrypt_metadata,
|
||||||
|
// I - Encrypt metadata?
|
||||||
uint8_t file_key[16]) // O - Encryption key
|
uint8_t file_key[16]) // O - Encryption key
|
||||||
{
|
{
|
||||||
size_t i; // Looping var
|
size_t i; // Looping var
|
||||||
@@ -986,13 +937,25 @@ make_file_key(
|
|||||||
perm_bytes[2] = (uint8_t)(permissions >> 16);
|
perm_bytes[2] = (uint8_t)(permissions >> 16);
|
||||||
perm_bytes[3] = (uint8_t)(permissions >> 24);
|
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);
|
_pdfioCryptoMD5Init(&md5);
|
||||||
_pdfioCryptoMD5Append(&md5, user_pad, 32);
|
_pdfioCryptoMD5Append(&md5, user_pad, 32);
|
||||||
_pdfioCryptoMD5Append(&md5, owner_key, 32);
|
_pdfioCryptoMD5Append(&md5, owner_key, 32);
|
||||||
_pdfioCryptoMD5Append(&md5, perm_bytes, 4);
|
_pdfioCryptoMD5Append(&md5, perm_bytes, 4);
|
||||||
_pdfioCryptoMD5Append(&md5, file_id, file_idlen);
|
_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);
|
_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)
|
if (encryption != PDFIO_ENCRYPTION_RC4_40)
|
||||||
{
|
{
|
||||||
// MD5 the result 50 times..
|
// MD5 the result 50 times..
|
||||||
@@ -1004,6 +967,8 @@ 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);
|
memcpy(file_key, digest, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1054,9 +1019,11 @@ make_owner_key(
|
|||||||
// Encrypt 20 times...
|
// Encrypt 20 times...
|
||||||
uint8_t encrypt_key[16]; // RC4 encryption key
|
uint8_t encrypt_key[16]; // RC4 encryption key
|
||||||
|
|
||||||
for (i = 0; i < 20; i ++)
|
for (i = 20; i > 0;)
|
||||||
{
|
{
|
||||||
// XOR each byte in the digest with the loop counter to make a key...
|
// XOR each byte in the digest with the loop counter to make a key...
|
||||||
|
i --;
|
||||||
|
|
||||||
for (j = 0; j < sizeof(encrypt_key); j ++)
|
for (j = 0; j < sizeof(encrypt_key); j ++)
|
||||||
encrypt_key[j] = (uint8_t)(digest[j] ^ i);
|
encrypt_key[j] = (uint8_t)(digest[j] ^ i);
|
||||||
|
|
||||||
|
|||||||
170
pdfio-dict.c
170
pdfio-dict.c
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// PDF dictionary functions for PDFio.
|
// PDF dictionary functions for PDFio.
|
||||||
//
|
//
|
||||||
// Copyright © 2021-2024 by Michael R Sweet.
|
// Copyright © 2021-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -20,6 +20,8 @@ static int compare_pairs(_pdfio_pair_t *a, _pdfio_pair_t *b);
|
|||||||
//
|
//
|
||||||
// 'pdfioDictClear()' - Remove a key/value pair from a dictionary.
|
// 'pdfioDictClear()' - Remove a key/value pair from a dictionary.
|
||||||
//
|
//
|
||||||
|
// @since PDFio v1.4@
|
||||||
|
//
|
||||||
|
|
||||||
bool // O - `true` if cleared, `false` otherwise
|
bool // O - `true` if cleared, `false` otherwise
|
||||||
pdfioDictClear(pdfio_dict_t *dict, // I - Dictionary
|
pdfioDictClear(pdfio_dict_t *dict, // I - Dictionary
|
||||||
@@ -30,7 +32,7 @@ pdfioDictClear(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
pkey; // Search key
|
pkey; // Search key
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioDictClear(dict=%p, key=\"%s\")\n", dict, key);
|
PDFIO_DEBUG("pdfioDictClear(dict=%p, key=\"%s\")\n", (void *)dict, key);
|
||||||
|
|
||||||
if (!dict || !key)
|
if (!dict || !key)
|
||||||
return (false);
|
return (false);
|
||||||
@@ -75,7 +77,7 @@ pdfioDictCopy(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfio_value_t v; // Current destination value
|
_pdfio_value_t v; // Current destination value
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioDictCopy(pdf=%p, dict=%p(%p))\n", pdf, dict, dict ? dict->pdf : NULL);
|
PDFIO_DEBUG("pdfioDictCopy(pdf=%p, dict=%p(%p))\n", (void *)pdf, (void *)dict, dict ? (void *)dict->pdf : NULL);
|
||||||
|
|
||||||
// Create the new dictionary...
|
// Create the new dictionary...
|
||||||
if ((ndict = pdfioDictCreate(pdf)) == NULL)
|
if ((ndict = pdfioDictCreate(pdf)) == NULL)
|
||||||
@@ -345,6 +347,8 @@ pdfioDictGetDict(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
//
|
//
|
||||||
// 'pdfioDictGetKey()' - Get the key for the specified pair.
|
// 'pdfioDictGetKey()' - Get the key for the specified pair.
|
||||||
//
|
//
|
||||||
|
// @since PDFio v1.4@
|
||||||
|
//
|
||||||
|
|
||||||
const char * // O - Key for specified pair
|
const char * // O - Key for specified pair
|
||||||
pdfioDictGetKey(pdfio_dict_t *dict, // I - Dictionary
|
pdfioDictGetKey(pdfio_dict_t *dict, // I - Dictionary
|
||||||
@@ -375,6 +379,8 @@ pdfioDictGetName(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
//
|
//
|
||||||
// 'pdfioDictGetNumPairs()' - Get the number of key/value pairs in a dictionary.
|
// 'pdfioDictGetNumPairs()' - Get the number of key/value pairs in a dictionary.
|
||||||
//
|
//
|
||||||
|
// @since PDFio v1.4@
|
||||||
|
//
|
||||||
|
|
||||||
size_t // O - Number of pairs
|
size_t // O - Number of pairs
|
||||||
pdfioDictGetNumPairs(pdfio_dict_t *dict)// I - Dictionary
|
pdfioDictGetNumPairs(pdfio_dict_t *dict)// I - Dictionary
|
||||||
@@ -458,134 +464,25 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
_pdfio_value_t *value = _pdfioDictGetValue(dict, key);
|
_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)
|
if (value && value->type == PDFIO_VALTYPE_STRING)
|
||||||
{
|
{
|
||||||
|
PDFIO_DEBUG("pdfioDictGetString: Returning \"%s\".\n", value->value.string);
|
||||||
return (value->value.string);
|
return (value->value.string);
|
||||||
}
|
}
|
||||||
else if (value && value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
|
else if (value && value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
|
||||||
{
|
{
|
||||||
// Convert binary string to regular string...
|
// Convert binary string to regular string...
|
||||||
char temp[4096], // Temporary string
|
char temp[4096]; // Temporary UTF-8 string
|
||||||
*tempptr; // Pointer into temporary string
|
|
||||||
unsigned char *dataptr; // Pointer into the data string
|
|
||||||
|
|
||||||
if (!(value->value.binary.datalen & 1) && !memcmp(value->value.binary.data, "\377\376", 2))
|
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 BE
|
// Copy UTF-16...
|
||||||
int ch; // Unicode character
|
PDFIO_DEBUG("pdfioDictGetString: Converting UTF-16 to UTF-8 string.\n");
|
||||||
size_t remaining; // Remaining bytes
|
|
||||||
|
|
||||||
for (dataptr = value->value.binary.data + 2, remaining = value->value.binary.datalen - 2, tempptr = temp; remaining > 1 && tempptr < (temp + sizeof(temp) - 5); dataptr += 2, remaining -= 2)
|
_pdfio_utf16cpy(temp, value->value.binary.data, value->value.binary.datalen, sizeof(temp));
|
||||||
{
|
|
||||||
ch = (dataptr[0] << 8) | dataptr[1];
|
|
||||||
|
|
||||||
if (ch >= 0xd800 && ch <= 0xdbff && remaining > 3)
|
|
||||||
{
|
|
||||||
// Multi-word UTF-16 char...
|
|
||||||
int lch; // Lower bits
|
|
||||||
|
|
||||||
lch = (dataptr[2] << 8) | dataptr[3];
|
|
||||||
|
|
||||||
if (lch < 0xdc00 || lch >= 0xdfff)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
|
|
||||||
dataptr += 2;
|
|
||||||
remaining -= 2;
|
|
||||||
}
|
|
||||||
else if (ch >= 0xfffe)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch < 128)
|
|
||||||
{
|
|
||||||
// ASCII
|
|
||||||
*tempptr++ = (char)ch;
|
|
||||||
}
|
|
||||||
else if (ch < 4096)
|
|
||||||
{
|
|
||||||
// 2-byte UTF-8
|
|
||||||
*tempptr++ = (char)(0xc0 | (ch >> 6));
|
|
||||||
*tempptr++ = (char)(0x80 | (ch & 0x3f));
|
|
||||||
}
|
|
||||||
else if (ch < 65536)
|
|
||||||
{
|
|
||||||
// 3-byte UTF-8
|
|
||||||
*tempptr++ = (char)(0xe0 | (ch >> 12));
|
|
||||||
*tempptr++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
|
||||||
*tempptr++ = (char)(0x80 | (ch & 0x3f));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 4-byte UTF-8
|
|
||||||
*tempptr++ = (char)(0xe0 | (ch >> 18));
|
|
||||||
*tempptr++ = (char)(0x80 | ((ch >> 12) & 0x3f));
|
|
||||||
*tempptr++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
|
||||||
*tempptr++ = (char)(0x80 | (ch & 0x3f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*tempptr = '\0';
|
|
||||||
}
|
|
||||||
else if (!(value->value.binary.datalen & 1) && !memcmp(value->value.binary.data, "\376\377", 2))
|
|
||||||
{
|
|
||||||
// Copy UTF-16 LE
|
|
||||||
int ch; // Unicode character
|
|
||||||
size_t remaining; // Remaining bytes
|
|
||||||
|
|
||||||
for (dataptr = value->value.binary.data + 2, remaining = value->value.binary.datalen - 2, tempptr = temp; remaining > 1 && tempptr < (temp + sizeof(temp) - 5); dataptr += 2, remaining -= 2)
|
|
||||||
{
|
|
||||||
ch = (dataptr[1] << 8) | dataptr[0];
|
|
||||||
|
|
||||||
if (ch >= 0xd800 && ch <= 0xdbff && remaining > 3)
|
|
||||||
{
|
|
||||||
// Multi-word UTF-16 char...
|
|
||||||
int lch; // Lower bits
|
|
||||||
|
|
||||||
lch = (dataptr[3] << 8) | dataptr[2];
|
|
||||||
|
|
||||||
if (lch < 0xdc00 || lch >= 0xdfff)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
|
|
||||||
dataptr += 2;
|
|
||||||
remaining -= 2;
|
|
||||||
}
|
|
||||||
else if (ch >= 0xfffe)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch < 128)
|
|
||||||
{
|
|
||||||
// ASCII
|
|
||||||
*tempptr++ = (char)ch;
|
|
||||||
}
|
|
||||||
else if (ch < 4096)
|
|
||||||
{
|
|
||||||
// 2-byte UTF-8
|
|
||||||
*tempptr++ = (char)(0xc0 | (ch >> 6));
|
|
||||||
*tempptr++ = (char)(0x80 | (ch & 0x3f));
|
|
||||||
}
|
|
||||||
else if (ch < 65536)
|
|
||||||
{
|
|
||||||
// 3-byte UTF-8
|
|
||||||
*tempptr++ = (char)(0xe0 | (ch >> 12));
|
|
||||||
*tempptr++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
|
||||||
*tempptr++ = (char)(0x80 | (ch & 0x3f));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 4-byte UTF-8
|
|
||||||
*tempptr++ = (char)(0xe0 | (ch >> 18));
|
|
||||||
*tempptr++ = (char)(0x80 | ((ch >> 12) & 0x3f));
|
|
||||||
*tempptr++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
|
||||||
*tempptr++ = (char)(0x80 | (ch & 0x3f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*tempptr = '\0';
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -598,10 +495,13 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
value->type = PDFIO_VALTYPE_STRING;
|
value->type = PDFIO_VALTYPE_STRING;
|
||||||
value->value.string = pdfioStringCreate(dict->pdf, temp);
|
value->value.string = pdfioStringCreate(dict->pdf, temp);
|
||||||
|
|
||||||
|
PDFIO_DEBUG("pdfioDictGetString: Returning \"%s\".\n", value->value.string);
|
||||||
|
|
||||||
return (value->value.string);
|
return (value->value.string);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
PDFIO_DEBUG("pdfioDictGetString: Returning NULL.\n");
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -634,7 +534,7 @@ _pdfioDictGetValue(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
*match; // Matching key pair
|
*match; // Matching key pair
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioDictGetValue(dict=%p, key=\"%s\")\n", dict, key);
|
PDFIO_DEBUG("_pdfioDictGetValue(dict=%p, key=\"%s\")\n", (void *)dict, key);
|
||||||
|
|
||||||
if (!dict || !dict->num_pairs || !key)
|
if (!dict || !dict->num_pairs || !key)
|
||||||
{
|
{
|
||||||
@@ -677,6 +577,8 @@ _pdfioDictGetValue(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
// The iteration continues as long as the callback returns `true` or all keys
|
// The iteration continues as long as the callback returns `true` or all keys
|
||||||
// have been iterated.
|
// have been iterated.
|
||||||
//
|
//
|
||||||
|
// @since PDFio v1.1@
|
||||||
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
pdfioDictIterateKeys(
|
pdfioDictIterateKeys(
|
||||||
@@ -717,7 +619,7 @@ _pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfio_value_t value; // Dictionary value
|
_pdfio_value_t value; // Dictionary value
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioDictRead(pdf=%p, obj=%p, tb=%p, depth=%lu)\n", pdf, obj, tb, (unsigned long)depth);
|
PDFIO_DEBUG("_pdfioDictRead(pdf=%p, obj=%p, tb=%p, depth=%lu)\n", (void *)pdf, (void *)obj, (void *)tb, (unsigned long)depth);
|
||||||
|
|
||||||
// Create a dictionary and start reading...
|
// Create a dictionary and start reading...
|
||||||
if ((dict = pdfioDictCreate(pdf)) == NULL)
|
if ((dict = pdfioDictCreate(pdf)) == NULL)
|
||||||
@@ -737,11 +639,6 @@ _pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfioFileError(pdf, "Invalid dictionary contents.");
|
_pdfioFileError(pdf, "Invalid dictionary contents.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (_pdfioDictGetValue(dict, key + 1))
|
|
||||||
{
|
|
||||||
_pdfioFileError(pdf, "Duplicate dictionary key '%s'.", key + 1);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then get the next value...
|
// Then get the next value...
|
||||||
PDFIO_DEBUG("_pdfioDictRead: Reading value for '%s'.\n", key + 1);
|
PDFIO_DEBUG("_pdfioDictRead: Reading value for '%s'.\n", key + 1);
|
||||||
@@ -751,8 +648,17 @@ _pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfioFileError(pdf, "Missing value for dictionary key '%s'.", key + 1);
|
_pdfioFileError(pdf, "Missing value for dictionary key '%s'.", key + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (_pdfioDictGetValue(dict, key + 1))
|
||||||
if (!_pdfioDictSetValue(dict, pdfioStringCreate(pdf, key + 1), &value))
|
{
|
||||||
|
// Issue 118: Discard duplicate key/value pairs, in the future this will
|
||||||
|
// be a warning message...
|
||||||
|
_pdfioValueDelete(&value);
|
||||||
|
if (_pdfioFileError(pdf, "WARNING: Discarding value for duplicate dictionary key '%s'.", key + 1))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!_pdfioDictSetValue(dict, pdfioStringCreate(pdf, key + 1), &value))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioDictRead: Set %s.\n", key);
|
PDFIO_DEBUG("_pdfioDictRead: Set %s.\n", key);
|
||||||
@@ -1087,7 +993,7 @@ _pdfioDictSetValue(
|
|||||||
_pdfio_pair_t *pair; // Current pair
|
_pdfio_pair_t *pair; // Current pair
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioDictSetValue(dict=%p, key=\"%s\", value=%p)\n", dict, key, (void *)value);
|
PDFIO_DEBUG("_pdfioDictSetValue(dict=%p, key=\"%s\", value=%p)\n", (void *)dict, key, (void *)value);
|
||||||
|
|
||||||
// See if the key is already set...
|
// See if the key is already set...
|
||||||
if (dict->num_pairs > 0)
|
if (dict->num_pairs > 0)
|
||||||
@@ -1168,7 +1074,7 @@ _pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
// Write all of the key/value pairs...
|
// Write all of the key/value pairs...
|
||||||
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
||||||
{
|
{
|
||||||
if (!_pdfioFilePrintf(pdf, "/%s", pair->key))
|
if (!_pdfioFilePrintf(pdf, "%N", pair->key))
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
if (length && !strcmp(pair->key, "Length") && pair->value.type == PDFIO_VALTYPE_NUMBER && pair->value.value.number <= 0.0)
|
if (length && !strcmp(pair->key, "Length") && pair->value.type == PDFIO_VALTYPE_NUMBER && pair->value.value.number <= 0.0)
|
||||||
|
|||||||
799
pdfio-file.c
799
pdfio-file.c
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,7 @@ pdfioObjCopy(pdfio_file_t *pdf, // I - PDF file
|
|||||||
ssize_t bytes; // Bytes read
|
ssize_t bytes; // Bytes read
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioObjCopy(pdf=%p, srcobj=%p(%p))\n", pdf, srcobj, srcobj ? srcobj->pdf : NULL);
|
PDFIO_DEBUG("pdfioObjCopy(pdf=%p, srcobj=%p(%p))\n", (void *)pdf, (void *)srcobj, srcobj ? (void *)srcobj->pdf : NULL);
|
||||||
|
|
||||||
// Range check input
|
// Range check input
|
||||||
if (!pdf || !srcobj)
|
if (!pdf || !srcobj)
|
||||||
@@ -79,6 +79,10 @@ pdfioObjCopy(pdfio_file_t *pdf, // I - PDF file
|
|||||||
if (srcobj->value.type == PDFIO_VALTYPE_NONE)
|
if (srcobj->value.type == PDFIO_VALTYPE_NONE)
|
||||||
_pdfioObjLoad(srcobj);
|
_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...
|
// Create the new object...
|
||||||
if ((dstobj = _pdfioFileCreateObj(pdf, srcobj->pdf, NULL)) == NULL)
|
if ((dstobj = _pdfioFileCreateObj(pdf, srcobj->pdf, NULL)) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -141,6 +145,7 @@ pdfioObjCreateStream(
|
|||||||
pdfio_obj_t *obj, // I - Object
|
pdfio_obj_t *obj, // I - Object
|
||||||
pdfio_filter_t filter) // I - Type of compression to apply
|
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
|
pdfio_obj_t *length_obj = NULL; // Length object, if any
|
||||||
|
|
||||||
|
|
||||||
@@ -194,11 +199,13 @@ pdfioObjCreateStream(
|
|||||||
if (!_pdfioFilePuts(obj->pdf, "stream\n"))
|
if (!_pdfioFilePuts(obj->pdf, "stream\n"))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
obj->stream_offset = _pdfioFileTell(obj->pdf);
|
obj->stream_offset = _pdfioFileTell(obj->pdf);
|
||||||
obj->pdf->current_obj = obj;
|
|
||||||
|
|
||||||
// Return the new stream...
|
// Return the new stream...
|
||||||
return (_pdfioStreamCreate(obj, length_obj, 0, filter));
|
if ((st = _pdfioStreamCreate(obj, length_obj, 0, filter)) != NULL)
|
||||||
|
obj->pdf->current_obj = obj;
|
||||||
|
|
||||||
|
return (st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -301,13 +308,14 @@ pdfioObjGetLength(pdfio_obj_t *obj) // I - Object
|
|||||||
// Try getting the length, directly or indirectly
|
// Try getting the length, directly or indirectly
|
||||||
if ((length = (size_t)pdfioDictGetNumber(obj->value.value.dict, "Length")) > 0)
|
if ((length = (size_t)pdfioDictGetNumber(obj->value.value.dict, "Length")) > 0)
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", obj, (unsigned long)length);
|
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", (void *)obj, (unsigned long)length);
|
||||||
return (length);
|
return (length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lenobj = pdfioDictGetObj(obj->value.value.dict, "Length")) == NULL)
|
if ((lenobj = pdfioDictGetObj(obj->value.value.dict, "Length")) == NULL)
|
||||||
{
|
{
|
||||||
_pdfioFileError(obj->pdf, "Unable to get length of stream.");
|
if (!_pdfioDictGetValue(obj->value.value.dict, "Length"))
|
||||||
|
_pdfioFileError(obj->pdf, "Unable to get length of stream.");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +328,7 @@ pdfioObjGetLength(pdfio_obj_t *obj) // I - Object
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", obj, (unsigned long)lenobj->value.value.number);
|
PDFIO_DEBUG("pdfioObjGetLength(obj=%p) returning %lu.\n", (void *)obj, (unsigned long)lenobj->value.value.number);
|
||||||
|
|
||||||
return ((size_t)lenobj->value.value.number);
|
return ((size_t)lenobj->value.value.number);
|
||||||
}
|
}
|
||||||
@@ -329,6 +337,8 @@ pdfioObjGetLength(pdfio_obj_t *obj) // I - Object
|
|||||||
//
|
//
|
||||||
// 'pdfioObjGetName()' - Get the name value associated with an object.
|
// 'pdfioObjGetName()' - Get the name value associated with an object.
|
||||||
//
|
//
|
||||||
|
// @since PDFio v1.4@
|
||||||
|
//
|
||||||
|
|
||||||
const char * // O - Dictionary or `NULL` on error
|
const char * // O - Dictionary or `NULL` on error
|
||||||
pdfioObjGetName(pdfio_obj_t *obj) // I - Object
|
pdfioObjGetName(pdfio_obj_t *obj) // I - Object
|
||||||
@@ -430,7 +440,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
|
|||||||
_pdfio_token_t tb; // Token buffer/stack
|
_pdfio_token_t tb; // Token buffer/stack
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioObjLoad(obj=%p(%lu)), offset=%lu\n", obj, (unsigned long)obj->number, (unsigned long)obj->offset);
|
PDFIO_DEBUG("_pdfioObjLoad(obj=%p(%lu)), offset=%lu\n", (void *)obj, (unsigned long)obj->number, (unsigned long)obj->offset);
|
||||||
|
|
||||||
// Seek to the start of the object and read its header...
|
// Seek to the start of the object and read its header...
|
||||||
if (_pdfioFileSeek(obj->pdf, obj->offset, SEEK_SET) != obj->offset)
|
if (_pdfioFileSeek(obj->pdf, obj->offset, SEEK_SET) != obj->offset)
|
||||||
@@ -492,7 +502,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
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]);
|
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]);
|
||||||
|
|
||||||
_pdfioTokenFlush(&tb);
|
_pdfioTokenFlush(&tb);
|
||||||
|
|
||||||
@@ -504,7 +514,7 @@ _pdfioObjLoad(pdfio_obj_t *obj) // I - Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt as needed...
|
// Decrypt as needed...
|
||||||
if (obj->pdf->encryption)
|
if (obj->pdf->encryption && obj->pdf->encrypt_metadata)
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("_pdfioObjLoad: Decrypting value...\n");
|
PDFIO_DEBUG("_pdfioObjLoad: Decrypting value...\n");
|
||||||
|
|
||||||
@@ -531,6 +541,9 @@ pdfio_stream_t * // O - Stream or `NULL` on error
|
|||||||
pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
|
pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
|
||||||
bool decode) // I - Decode/decompress data?
|
bool decode) // I - Decode/decompress data?
|
||||||
{
|
{
|
||||||
|
pdfio_stream_t *st; // Stream
|
||||||
|
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -553,9 +566,10 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
// Open the stream...
|
// Open the stream...
|
||||||
obj->pdf->current_obj = obj;
|
if ((st = _pdfioStreamOpen(obj, decode)) != NULL)
|
||||||
|
obj->pdf->current_obj = obj;
|
||||||
|
|
||||||
return (_pdfioStreamOpen(obj, decode));
|
return (st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pdfioPageCopy(pdfio_file_t *pdf, // I - PDF file
|
|||||||
pdfio_obj_t *dstpage; // Destination page object
|
pdfio_obj_t *dstpage; // Destination page object
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioPageCopy(pdf=%p, srcpage=%p(%p))\n", pdf, srcpage, srcpage ? srcpage->pdf : NULL);
|
PDFIO_DEBUG("pdfioPageCopy(pdf=%p, srcpage=%p(%p))\n", (void *)pdf, (void *)srcpage, srcpage ? (void *)srcpage->pdf : NULL);
|
||||||
|
|
||||||
// Range check input
|
// Range check input
|
||||||
if (!pdf || !srcpage || srcpage->value.type != PDFIO_VALTYPE_DICT)
|
if (!pdf || !srcpage || srcpage->value.type != PDFIO_VALTYPE_DICT)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#ifndef PDFIO_PRIVATE_H
|
#ifndef PDFIO_PRIVATE_H
|
||||||
# define PDFIO_PRIVATE_H
|
# define PDFIO_PRIVATE_H
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
# define _CRT_SECURE_NO_WARNINGS // Disable bogus VS warnings/errors...
|
# define _CRT_SECURE_NO_WARNINGS 1 // Disable bogus VS warnings/errors...
|
||||||
# endif // _WIN32
|
# endif // _WIN32
|
||||||
# include "pdfio.h"
|
# include "pdfio.h"
|
||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
@@ -28,16 +28,16 @@
|
|||||||
# define access _access // Map standard POSIX/C99 names
|
# define access _access // Map standard POSIX/C99 names
|
||||||
# define close _close
|
# define close _close
|
||||||
# define fileno _fileno
|
# define fileno _fileno
|
||||||
# define lseek _lseek
|
# define lseek(f,o,w) (off_t)_lseek((f),(long)(o),(w))
|
||||||
# define mkdir(d,p) _mkdir(d)
|
# define mkdir(d,p) _mkdir(d)
|
||||||
# define open _open
|
# define open _open
|
||||||
# define read _read
|
# define read(f,b,s) _read((f),(b),(unsigned)(s))
|
||||||
# define rmdir _rmdir
|
# define rmdir _rmdir
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
# define strdup _strdup
|
# define strdup _strdup
|
||||||
# define unlink _unlink
|
# define unlink _unlink
|
||||||
# define vsnprintf _vsnprintf
|
# define vsnprintf _vsnprintf
|
||||||
# define write _write
|
# define write(f,b,s) _write((f),(b),(unsigned)(s))
|
||||||
# ifndef F_OK
|
# ifndef F_OK
|
||||||
# define F_OK 00 // POSIX parameters/flags
|
# define F_OK 00 // POSIX parameters/flags
|
||||||
# define W_OK 02
|
# define W_OK 02
|
||||||
@@ -94,6 +94,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
# define PDFIO_MAX_DEPTH 32 // Maximum nesting depth for values
|
# define PDFIO_MAX_DEPTH 32 // Maximum nesting depth for values
|
||||||
|
# define PDFIO_MAX_STRING 65536 // Maximum length of string
|
||||||
|
|
||||||
typedef void (*_pdfio_extfree_t)(void *);
|
typedef void (*_pdfio_extfree_t)(void *);
|
||||||
// Extension data free function
|
// Extension data free function
|
||||||
@@ -116,6 +117,21 @@ typedef enum _pdfio_predictor_e // PNG predictor constants
|
|||||||
_PDFIO_PREDICTOR_PNG_AUTO = 15 // PNG "auto" predictor (currently mapped to Paeth)
|
_PDFIO_PREDICTOR_PNG_AUTO = 15 // PNG "auto" predictor (currently mapped to Paeth)
|
||||||
} _pdfio_predictor_t;
|
} _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_tconsume_cb_t)(void *data, size_t bytes);
|
||||||
typedef ssize_t (*_pdfio_tpeek_cb_t)(void *data, void *buffer, size_t bytes);
|
typedef ssize_t (*_pdfio_tpeek_cb_t)(void *data, void *buffer, size_t bytes);
|
||||||
|
|
||||||
@@ -220,15 +236,25 @@ struct _pdfio_dict_s // Dictionary
|
|||||||
typedef struct _pdfio_objmap_s // PDF object map
|
typedef struct _pdfio_objmap_s // PDF object map
|
||||||
{
|
{
|
||||||
pdfio_obj_t *obj; // Object for this file
|
pdfio_obj_t *obj; // Object for this file
|
||||||
pdfio_file_t *src_pdf; // Source PDF file
|
unsigned char src_id[32]; // Source PDF file file identifier
|
||||||
size_t src_number; // Source object number
|
size_t src_number; // Source object number
|
||||||
} _pdfio_objmap_t;
|
} _pdfio_objmap_t;
|
||||||
|
|
||||||
|
typedef struct _pdfio_strbuf_s // PDF string buffer
|
||||||
|
{
|
||||||
|
struct _pdfio_strbuf_s *next; // Next string buffer
|
||||||
|
bool bufused; // Is this string buffer being used?
|
||||||
|
char buffer[PDFIO_MAX_STRING + 32];
|
||||||
|
// String buffer
|
||||||
|
} _pdfio_strbuf_t;
|
||||||
|
|
||||||
struct _pdfio_file_s // PDF file structure
|
struct _pdfio_file_s // PDF file structure
|
||||||
{
|
{
|
||||||
char *filename; // Filename
|
char *filename; // Filename
|
||||||
|
unsigned char file_id[32]; // File identifier bytes
|
||||||
struct lconv *loc; // Locale data
|
struct lconv *loc; // Locale data
|
||||||
char *version; // Version number
|
char *version; // Version number
|
||||||
|
_pdfio_profile_t profile; // PDF profile, if any
|
||||||
pdfio_rect_t media_box, // Default MediaBox value
|
pdfio_rect_t media_box, // Default MediaBox value
|
||||||
crop_box; // Default CropBox value
|
crop_box; // Default CropBox value
|
||||||
_pdfio_mode_t mode; // Read/write mode
|
_pdfio_mode_t mode; // Read/write mode
|
||||||
@@ -257,10 +283,14 @@ struct _pdfio_file_s // PDF file structure
|
|||||||
pdfio_obj_t *root_obj; // Root object/dictionary
|
pdfio_obj_t *root_obj; // Root object/dictionary
|
||||||
pdfio_obj_t *info_obj; // Information object
|
pdfio_obj_t *info_obj; // Information object
|
||||||
pdfio_obj_t *pages_obj; // Root pages object
|
pdfio_obj_t *pages_obj; // Root pages object
|
||||||
pdfio_obj_t *encrypt_obj; // De/Encryption object/dictionary
|
pdfio_obj_t *encrypt_obj; // Encryption object (not used for reading)
|
||||||
pdfio_obj_t *cp1252_obj, // CP1252 font encoding object
|
pdfio_dict_t *encrypt_dict; // De/Encryption dictionary
|
||||||
|
pdfio_obj_t *cgats001_obj, // CGATS001 ICC profile object
|
||||||
|
*cp1252_obj, // CP1252 font encoding object
|
||||||
*unicode_obj; // Unicode font encoding object
|
*unicode_obj; // Unicode font encoding object
|
||||||
pdfio_array_t *id_array; // ID array
|
pdfio_array_t *id_array; // ID array
|
||||||
|
bool encrypt_metadata; // Encrypt metadata?
|
||||||
|
pdfio_dict_t *markinfo; // MarkInfo dictionary, if any
|
||||||
|
|
||||||
// Allocated data elements
|
// Allocated data elements
|
||||||
size_t num_arrays, // Number of arrays
|
size_t num_arrays, // Number of arrays
|
||||||
@@ -283,6 +313,7 @@ struct _pdfio_file_s // PDF file structure
|
|||||||
size_t num_strings, // Number of strings
|
size_t num_strings, // Number of strings
|
||||||
alloc_strings; // Allocated strings
|
alloc_strings; // Allocated strings
|
||||||
char **strings; // Nul-terminated strings
|
char **strings; // Nul-terminated strings
|
||||||
|
_pdfio_strbuf_t *strbuffers; // String buffers
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _pdfio_obj_s // Object
|
struct _pdfio_obj_s // Object
|
||||||
@@ -327,7 +358,9 @@ struct _pdfio_stream_s // Stream
|
|||||||
// Functions...
|
// Functions...
|
||||||
//
|
//
|
||||||
|
|
||||||
|
extern size_t _pdfio_strlcpy(char *dst, const char *src, size_t dstsize) _PDFIO_INTERNAL;
|
||||||
extern double _pdfio_strtod(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
|
extern double _pdfio_strtod(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
|
||||||
|
extern void _pdfio_utf16cpy(char *dst, const unsigned char *src, size_t srclen, size_t dstsize) _PDFIO_INTERNAL;
|
||||||
extern ssize_t _pdfio_vsnprintf(pdfio_file_t *pdf, char *buffer, size_t bufsize, const char *format, va_list ap) _PDFIO_INTERNAL;
|
extern ssize_t _pdfio_vsnprintf(pdfio_file_t *pdf, char *buffer, size_t bufsize, const char *format, va_list ap) _PDFIO_INTERNAL;
|
||||||
|
|
||||||
extern bool _pdfioArrayDecrypt(pdfio_file_t *pdf, pdfio_obj_t *obj, pdfio_array_t *a, size_t depth) _PDFIO_INTERNAL;
|
extern bool _pdfioArrayDecrypt(pdfio_file_t *pdf, pdfio_obj_t *obj, pdfio_array_t *a, size_t depth) _PDFIO_INTERNAL;
|
||||||
@@ -367,13 +400,13 @@ extern bool _pdfioFileAddPage(pdfio_file_t *pdf, pdfio_obj_t *obj) _PDFIO_INTER
|
|||||||
extern bool _pdfioFileConsume(pdfio_file_t *pdf, size_t bytes) _PDFIO_INTERNAL;
|
extern bool _pdfioFileConsume(pdfio_file_t *pdf, size_t bytes) _PDFIO_INTERNAL;
|
||||||
extern pdfio_obj_t *_pdfioFileCreateObj(pdfio_file_t *pdf, pdfio_file_t *srcpdf, _pdfio_value_t *value) _PDFIO_INTERNAL;
|
extern pdfio_obj_t *_pdfioFileCreateObj(pdfio_file_t *pdf, pdfio_file_t *srcpdf, _pdfio_value_t *value) _PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileDefaultError(pdfio_file_t *pdf, const char *message, void *data) _PDFIO_INTERNAL;
|
extern bool _pdfioFileDefaultError(pdfio_file_t *pdf, const char *message, void *data) _PDFIO_INTERNAL;
|
||||||
extern bool _pdfioFileError(pdfio_file_t *pdf, const char *format, ...) _PDFIO_FORMAT(2,3) _PDFIO_INTERNAL;
|
extern bool _pdfioFileError(pdfio_file_t *pdf, const char *format, ...) _PDFIO_INTERNAL;
|
||||||
extern pdfio_obj_t *_pdfioFileFindMappedObj(pdfio_file_t *pdf, pdfio_file_t *src_pdf, size_t src_number) _PDFIO_INTERNAL;
|
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 bool _pdfioFileFlush(pdfio_file_t *pdf) _PDFIO_INTERNAL;
|
||||||
extern int _pdfioFileGetChar(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) _PDFIO_INTERNAL;
|
extern bool _pdfioFileGets(pdfio_file_t *pdf, char *buffer, size_t bufsize, bool discard) _PDFIO_INTERNAL;
|
||||||
extern ssize_t _pdfioFilePeek(pdfio_file_t *pdf, void *buffer, size_t bytes) _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_FORMAT(2,3) _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;
|
extern bool _pdfioFilePuts(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
|
||||||
extern ssize_t _pdfioFileRead(pdfio_file_t *pdf, void *buffer, size_t bytes) _PDFIO_INTERNAL;
|
extern ssize_t _pdfioFileRead(pdfio_file_t *pdf, void *buffer, size_t bytes) _PDFIO_INTERNAL;
|
||||||
extern off_t _pdfioFileSeek(pdfio_file_t *pdf, off_t offset, int whence) _PDFIO_INTERNAL;
|
extern off_t _pdfioFileSeek(pdfio_file_t *pdf, off_t offset, int whence) _PDFIO_INTERNAL;
|
||||||
@@ -389,6 +422,8 @@ extern bool _pdfioObjWriteHeader(pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
|||||||
extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, size_t cbsize, pdfio_filter_t compression) _PDFIO_INTERNAL;
|
extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, size_t cbsize, pdfio_filter_t compression) _PDFIO_INTERNAL;
|
||||||
extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL;
|
extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL;
|
||||||
|
|
||||||
|
extern char *_pdfioStringAllocBuffer(pdfio_file_t *pdf);
|
||||||
|
extern void _pdfioStringFreeBuffer(pdfio_file_t *pdf, char *buffer);
|
||||||
extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
|
extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
|
||||||
|
|
||||||
extern void _pdfioTokenClear(_pdfio_token_t *tb) _PDFIO_INTERNAL;
|
extern void _pdfioTokenClear(_pdfio_token_t *tb) _PDFIO_INTERNAL;
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ _pdfioStreamCreate(
|
|||||||
{
|
{
|
||||||
colors = 1;
|
colors = 1;
|
||||||
}
|
}
|
||||||
else if (colors < 0 || colors > 4)
|
else if (colors < 0 || colors > 32)
|
||||||
{
|
{
|
||||||
_pdfioFileError(st->pdf, "Unsupported Colors value %d.", colors);
|
_pdfioFileError(st->pdf, "Unsupported Colors value %d.", colors);
|
||||||
free(st);
|
free(st);
|
||||||
@@ -270,7 +270,7 @@ _pdfioStreamCreate(
|
|||||||
{
|
{
|
||||||
columns = 1;
|
columns = 1;
|
||||||
}
|
}
|
||||||
else if (columns < 0)
|
else if (columns < 0 || columns > 65536)
|
||||||
{
|
{
|
||||||
_pdfioFileError(st->pdf, "Unsupported Columns value %d.", columns);
|
_pdfioFileError(st->pdf, "Unsupported Columns value %d.", columns);
|
||||||
free(st);
|
free(st);
|
||||||
@@ -427,7 +427,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
|
|||||||
const char *type; // Object type
|
const char *type; // Object type
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioStreamOpen(obj=%p(%u), decode=%s)\n", obj, (unsigned)obj->number, decode ? "true" : "false");
|
PDFIO_DEBUG("_pdfioStreamOpen(obj=%p(%u), decode=%s)\n", (void *)obj, (unsigned)obj->number, decode ? "true" : "false");
|
||||||
|
|
||||||
// Allocate a new stream object...
|
// Allocate a new stream object...
|
||||||
if ((st = (pdfio_stream_t *)calloc(1, sizeof(pdfio_stream_t))) == NULL)
|
if ((st = (pdfio_stream_t *)calloc(1, sizeof(pdfio_stream_t))) == NULL)
|
||||||
@@ -439,7 +439,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
|
|||||||
st->pdf = obj->pdf;
|
st->pdf = obj->pdf;
|
||||||
st->obj = obj;
|
st->obj = obj;
|
||||||
|
|
||||||
if ((st->remaining = pdfioObjGetLength(obj)) == 0)
|
if ((st->remaining = pdfioObjGetLength(obj)) == 0 && !_pdfioDictGetValue(pdfioObjGetDict(obj), "Length"))
|
||||||
{
|
{
|
||||||
_pdfioFileError(obj->pdf, "No stream data.");
|
_pdfioFileError(obj->pdf, "No stream data.");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -532,7 +532,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
|
|||||||
{
|
{
|
||||||
colors = 1;
|
colors = 1;
|
||||||
}
|
}
|
||||||
else if (colors < 0 || colors > 4)
|
else if (colors < 0 || colors > 32)
|
||||||
{
|
{
|
||||||
_pdfioFileError(st->pdf, "Unsupported Colors value %d.", colors);
|
_pdfioFileError(st->pdf, "Unsupported Colors value %d.", colors);
|
||||||
goto error;
|
goto error;
|
||||||
@@ -542,7 +542,7 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
|
|||||||
{
|
{
|
||||||
columns = 1;
|
columns = 1;
|
||||||
}
|
}
|
||||||
else if (columns < 0)
|
else if (columns < 0 || columns > 65536)
|
||||||
{
|
{
|
||||||
_pdfioFileError(st->pdf, "Unsupported Columns value %d.", columns);
|
_pdfioFileError(st->pdf, "Unsupported Columns value %d.", columns);
|
||||||
goto error;
|
goto error;
|
||||||
@@ -562,6 +562,13 @@ _pdfioStreamOpen(pdfio_obj_t *obj, // I - Object
|
|||||||
if (predictor >= 10)
|
if (predictor >= 10)
|
||||||
st->pbsize ++; // Add PNG predictor byte
|
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)
|
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);
|
_pdfioFileError(st->pdf, "Unable to allocate %lu bytes for Predictor buffers.", (unsigned long)st->pbsize);
|
||||||
@@ -689,6 +696,11 @@ pdfioStreamPeek(pdfio_stream_t *st, // I - Stream
|
|||||||
//
|
//
|
||||||
// 'pdfioStreamPrintf()' - Write a formatted string to a 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.
|
||||||
|
//
|
||||||
|
|
||||||
bool // O - `true` on success, `false` on failure
|
bool // O - `true` on success, `false` on failure
|
||||||
pdfioStreamPrintf(
|
pdfioStreamPrintf(
|
||||||
@@ -836,7 +848,7 @@ pdfioStreamWrite(
|
|||||||
*pptr; // Previous raw buffer
|
*pptr; // Previous raw buffer
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioStreamWrite(st=%p, buffer=%p, bytes=%lu)\n", st, buffer, (unsigned long)bytes);
|
PDFIO_DEBUG("pdfioStreamWrite(st=%p, buffer=%p, bytes=%lu)\n", (void *)st, buffer, (unsigned long)bytes);
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!st || st->pdf->mode != _PDFIO_MODE_WRITE || !buffer || !bytes)
|
if (!st || st->pdf->mode != _PDFIO_MODE_WRITE || !buffer || !bytes)
|
||||||
@@ -1223,7 +1235,18 @@ stream_read(pdfio_stream_t *st, // I - Stream
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply predictor for this line
|
// Apply predictor for this line
|
||||||
PDFIO_DEBUG("stream_read: Line %02X %02X %02X %02X %02X.\n", sptr[-1], sptr[0], sptr[0], sptr[2], sptr[3]);
|
#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
|
||||||
|
|
||||||
switch (sptr[-1])
|
switch (sptr[-1])
|
||||||
{
|
{
|
||||||
|
|||||||
394
pdfio-string.c
394
pdfio-string.c
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// PDF string functions for PDFio.
|
// PDF string functions for PDFio.
|
||||||
//
|
//
|
||||||
// Copyright © 2021-2024 by Michael R Sweet.
|
// Copyright © 2021-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -17,6 +17,83 @@
|
|||||||
static size_t find_string(pdfio_file_t *pdf, const char *s, int *rdiff);
|
static size_t find_string(pdfio_file_t *pdf, const char *s, int *rdiff);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// '_pdfio_strlcpy()' - Safe string copy.
|
||||||
|
//
|
||||||
|
|
||||||
|
size_t // O - Length of source string
|
||||||
|
_pdfio_strlcpy(char *dst, // I - Destination string buffer
|
||||||
|
const char *src, // I - Source string
|
||||||
|
size_t dstsize) // I - Size of destination
|
||||||
|
{
|
||||||
|
size_t srclen; // Length of source string
|
||||||
|
|
||||||
|
|
||||||
|
// Range check input...
|
||||||
|
if (!dst || !src || dstsize == 0)
|
||||||
|
{
|
||||||
|
if (dst)
|
||||||
|
*dst = '\0';
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out how much room is needed...
|
||||||
|
dstsize --;
|
||||||
|
|
||||||
|
srclen = strlen(src);
|
||||||
|
|
||||||
|
// Copy the appropriate amount...
|
||||||
|
if (srclen <= dstsize)
|
||||||
|
{
|
||||||
|
// Source string will fit...
|
||||||
|
memmove(dst, src, srclen);
|
||||||
|
dst[srclen] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Source string too big, copy what we can and clean up the end...
|
||||||
|
char *ptr = dst + dstsize - 1, // Pointer into string
|
||||||
|
*end = ptr + 1; // Pointer to end of string
|
||||||
|
|
||||||
|
memmove(dst, src, dstsize);
|
||||||
|
dst[dstsize] = '\0';
|
||||||
|
|
||||||
|
// Validate last character in destination buffer...
|
||||||
|
if (ptr > dst && *ptr & 0x80)
|
||||||
|
{
|
||||||
|
while ((*ptr & 0xc0) == 0x80 && ptr > dst)
|
||||||
|
ptr --;
|
||||||
|
|
||||||
|
if ((*ptr & 0xe0) == 0xc0)
|
||||||
|
{
|
||||||
|
// Verify 2-byte UTF-8 sequence...
|
||||||
|
if ((end - ptr) != 2)
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
else if ((*ptr & 0xf0) == 0xe0)
|
||||||
|
{
|
||||||
|
// Verify 3-byte UTF-8 sequence...
|
||||||
|
if ((end - ptr) != 3)
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
else if ((*ptr & 0xf8) == 0xf0)
|
||||||
|
{
|
||||||
|
// Verify 4-byte UTF-8 sequence...
|
||||||
|
if ((end - ptr) != 4)
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
else if (*ptr & 0x80)
|
||||||
|
{
|
||||||
|
// Invalid sequence at end...
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (srclen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// '_pdfio_strtod()' - Convert a string to a double value.
|
// '_pdfio_strtod()' - Convert a string to a double value.
|
||||||
//
|
//
|
||||||
@@ -81,6 +158,89 @@ _pdfio_strtod(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// '_pdfio_utf16cpy()' - Convert UTF-16 to UTF-8.
|
||||||
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
_pdfio_utf16cpy(
|
||||||
|
char *dst, // I - Destination buffer for UTF-8
|
||||||
|
const unsigned char *src, // I - Source UTF-16
|
||||||
|
size_t srclen, // I - Length of UTF-16
|
||||||
|
size_t dstsize) // I - Destination buffer size
|
||||||
|
{
|
||||||
|
char *dstptr = dst, // Pointer into buffer
|
||||||
|
*dstend = dst + dstsize - 5; // End of buffer
|
||||||
|
int ch; // Unicode character
|
||||||
|
bool is_be = !memcmp(src, "\376\377", 2);
|
||||||
|
// Big-endian strings?
|
||||||
|
|
||||||
|
|
||||||
|
// Loop through the UTF-16 string, converting to Unicode then UTF-8...
|
||||||
|
for (src += 2, srclen -= 2; srclen > 1 && dstptr < dstend; src += 2, srclen -= 2)
|
||||||
|
{
|
||||||
|
// Initial character...
|
||||||
|
if (is_be)
|
||||||
|
ch = (src[0] << 8) | src[1];
|
||||||
|
else
|
||||||
|
ch = (src[1] << 8) | src[0];
|
||||||
|
|
||||||
|
if (ch >= 0xd800 && ch <= 0xdbff && srclen > 3)
|
||||||
|
{
|
||||||
|
// Multi-word UTF-16 char...
|
||||||
|
int lch; // Lower bits
|
||||||
|
|
||||||
|
if (is_be)
|
||||||
|
lch = (src[2] << 8) | src[3];
|
||||||
|
else
|
||||||
|
lch = (src[3] << 8) | src[2];
|
||||||
|
|
||||||
|
if (lch < 0xdc00 || lch >= 0xdfff)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
|
||||||
|
src += 2;
|
||||||
|
srclen -= 2;
|
||||||
|
}
|
||||||
|
else if (ch >= 0xfffe)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert Unicode to UTF-8...
|
||||||
|
if (ch < 128)
|
||||||
|
{
|
||||||
|
// ASCII
|
||||||
|
*dstptr++ = (char)ch;
|
||||||
|
}
|
||||||
|
else if (ch < 4096)
|
||||||
|
{
|
||||||
|
// 2-byte UTF-8
|
||||||
|
*dstptr++ = (char)(0xc0 | (ch >> 6));
|
||||||
|
*dstptr++ = (char)(0x80 | (ch & 0x3f));
|
||||||
|
}
|
||||||
|
else if (ch < 65536)
|
||||||
|
{
|
||||||
|
// 3-byte UTF-8
|
||||||
|
*dstptr++ = (char)(0xe0 | (ch >> 12));
|
||||||
|
*dstptr++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
||||||
|
*dstptr++ = (char)(0x80 | (ch & 0x3f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 4-byte UTF-8
|
||||||
|
*dstptr++ = (char)(0xe0 | (ch >> 18));
|
||||||
|
*dstptr++ = (char)(0x80 | ((ch >> 12) & 0x3f));
|
||||||
|
*dstptr++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
||||||
|
*dstptr++ = (char)(0x80 | (ch & 0x3f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nul-terminate the UTF-8 string...
|
||||||
|
*dstptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// '_pdfio_vsnprintf()' - Format a string.
|
// '_pdfio_vsnprintf()' - Format a string.
|
||||||
//
|
//
|
||||||
@@ -112,10 +272,9 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
|
|
||||||
// Loop through the format string, formatting as needed...
|
// Loop through the format string, formatting as needed...
|
||||||
bufptr = buffer;
|
bufptr = buffer;
|
||||||
bufend = buffer + bufsize - 1;
|
bufend = buffer + bufsize - 1;
|
||||||
*bufend = '\0';
|
bytes = 0;
|
||||||
bytes = 0;
|
|
||||||
|
|
||||||
while (*format)
|
while (*format)
|
||||||
{
|
{
|
||||||
@@ -178,14 +337,12 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prec = 0;
|
|
||||||
|
|
||||||
while (isdigit(*format & 255))
|
while (isdigit(*format & 255))
|
||||||
{
|
{
|
||||||
if (tptr < (tformat + sizeof(tformat) - 1))
|
if (tptr < (tformat + sizeof(tformat) - 1))
|
||||||
*tptr++ = *format;
|
*tptr++ = *format;
|
||||||
|
|
||||||
prec = prec * 10 + *format++ - '0';
|
format ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,7 +416,7 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
if (bufptr < bufend)
|
if (bufptr < bufend)
|
||||||
{
|
{
|
||||||
strncpy(bufptr, temp, (size_t)(bufend - bufptr - 1));
|
_pdfio_strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));
|
||||||
bufptr += strlen(bufptr);
|
bufptr += strlen(bufptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -289,7 +446,7 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
if (bufptr < bufend)
|
if (bufptr < bufend)
|
||||||
{
|
{
|
||||||
strncpy(bufptr, temp, (size_t)(bufend - bufptr - 1));
|
_pdfio_strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));
|
||||||
bufptr += strlen(bufptr);
|
bufptr += strlen(bufptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -304,7 +461,7 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
if (bufptr < bufend)
|
if (bufptr < bufend)
|
||||||
{
|
{
|
||||||
strncpy(bufptr, temp, (size_t)(bufend - bufptr - 1));
|
_pdfio_strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1));
|
||||||
bufptr += strlen(bufptr);
|
bufptr += strlen(bufptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -329,19 +486,164 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's' : // String
|
case 'H' : // XML/HTML string
|
||||||
if ((s = va_arg(ap, char *)) == NULL)
|
if ((s = va_arg(ap, char *)) == NULL)
|
||||||
s = "(null)";
|
s = "(null)";
|
||||||
|
|
||||||
|
// Loop through the literal string...
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
// Escape special characters
|
||||||
|
if (*s == '&')
|
||||||
|
{
|
||||||
|
// &
|
||||||
|
if (bufptr < bufend)
|
||||||
|
{
|
||||||
|
_pdfio_strlcpy(bufptr, "&", (size_t)(bufend - bufptr + 1));
|
||||||
|
bufptr += strlen(bufptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes += 5;
|
||||||
|
}
|
||||||
|
else if (*s == '<')
|
||||||
|
{
|
||||||
|
// <
|
||||||
|
if (bufptr < bufend)
|
||||||
|
{
|
||||||
|
_pdfio_strlcpy(bufptr, "<", (size_t)(bufend - bufptr + 1));
|
||||||
|
bufptr += strlen(bufptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes += 4;
|
||||||
|
}
|
||||||
|
else if (*s == '>')
|
||||||
|
{
|
||||||
|
// >
|
||||||
|
if (bufptr < bufend)
|
||||||
|
{
|
||||||
|
_pdfio_strlcpy(bufptr, ">", (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)";
|
||||||
|
|
||||||
|
// PDF strings start with "("...
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = '(';
|
||||||
|
|
||||||
|
bytes ++;
|
||||||
|
|
||||||
|
// Loop through the literal string...
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
// Escape special characters
|
||||||
|
if (*s == '\\' || *s == '(' || *s == ')')
|
||||||
|
{
|
||||||
|
// Simple escape...
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = '\\';
|
||||||
|
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = *s;
|
||||||
|
|
||||||
|
bytes += 2;
|
||||||
|
}
|
||||||
|
else if (*s < ' ')
|
||||||
|
{
|
||||||
|
// Octal escape...
|
||||||
|
snprintf(bufptr, (size_t)(bufend - bufptr + 1), "\\%03o", *s & 255);
|
||||||
|
bufptr += strlen(bufptr);
|
||||||
|
bytes += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Literal character...
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = *s;
|
||||||
|
bytes ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDF strings end with ")"...
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = ')';
|
||||||
|
|
||||||
|
bytes ++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's' : // Literal string
|
||||||
|
if ((s = va_arg(ap, char *)) == NULL)
|
||||||
|
s = "(null)";
|
||||||
|
|
||||||
|
if (width != 0)
|
||||||
|
{
|
||||||
|
// Format string to fit inside the specified width...
|
||||||
|
if ((size_t)(width + 1) > sizeof(temp))
|
||||||
|
break;
|
||||||
|
|
||||||
|
snprintf(temp, sizeof(temp), tformat, s);
|
||||||
|
s = temp;
|
||||||
|
}
|
||||||
|
|
||||||
bytes += strlen(s);
|
bytes += strlen(s);
|
||||||
|
|
||||||
if (bufptr < bufend)
|
if (bufptr < bufend)
|
||||||
{
|
{
|
||||||
strncpy(bufptr, s, (size_t)(bufend - bufptr - 1));
|
_pdfio_strlcpy(bufptr, s, (size_t)(bufend - bufptr + 1));
|
||||||
bufptr += strlen(bufptr);
|
bufptr += strlen(bufptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'N' : // Output name string with proper escaping
|
||||||
|
if ((s = va_arg(ap, char *)) == NULL)
|
||||||
|
s = "(null)";
|
||||||
|
|
||||||
|
// PDF names start with "/"...
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = '/';
|
||||||
|
|
||||||
|
bytes ++;
|
||||||
|
|
||||||
|
// Loop through the name string...
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s < 0x21 || *s > 0x7e || *s == '#')
|
||||||
|
{
|
||||||
|
// Output #XX for character...
|
||||||
|
snprintf(bufptr, (size_t)(bufend - bufptr + 1), "#%02X", *s & 255);
|
||||||
|
bufptr += strlen(bufptr);
|
||||||
|
bytes += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Output literal character...
|
||||||
|
if (bufptr < bufend)
|
||||||
|
*bufptr++ = *s;
|
||||||
|
bytes ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s ++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'n' : // Output number of chars so far
|
case 'n' : // Output number of chars so far
|
||||||
*(va_arg(ap, int *)) = (int)bytes;
|
*(va_arg(ap, int *)) = (int)bytes;
|
||||||
break;
|
break;
|
||||||
@@ -358,11 +660,7 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nul-terminate the string and return the number of characters needed.
|
// Nul-terminate the string and return the number of characters needed.
|
||||||
if (bufptr < bufend)
|
*bufptr = '\0';
|
||||||
{
|
|
||||||
// Everything fit in the buffer...
|
|
||||||
*bufptr = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfio_vsnprintf: Returning %ld \"%s\"\n", (long)bytes, buffer);
|
PDFIO_DEBUG("_pdfio_vsnprintf: Returning %ld \"%s\"\n", (long)bytes, buffer);
|
||||||
|
|
||||||
@@ -370,6 +668,41 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// '_pdfioStringAllocBuffer()' - Allocate a string buffer.
|
||||||
|
//
|
||||||
|
|
||||||
|
char * // O - Buffer or `NULL` on error
|
||||||
|
_pdfioStringAllocBuffer(
|
||||||
|
pdfio_file_t *pdf) // I - PDF file
|
||||||
|
{
|
||||||
|
_pdfio_strbuf_t *current; // Current string buffer
|
||||||
|
|
||||||
|
|
||||||
|
// See if we have an available string buffer...
|
||||||
|
for (current = pdf->strbuffers; current; current = current->next)
|
||||||
|
{
|
||||||
|
if (!current->bufused)
|
||||||
|
{
|
||||||
|
current->bufused = true;
|
||||||
|
return (current->buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't find one, allocate a new one...
|
||||||
|
if ((current = calloc(1, sizeof(_pdfio_strbuf_t))) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
// Add to the linked list of string buffers...
|
||||||
|
current->next = pdf->strbuffers;
|
||||||
|
current->bufused = true;
|
||||||
|
|
||||||
|
pdf->strbuffers = current;
|
||||||
|
|
||||||
|
return (current->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'pdfioStringCreate()' - Create a durable literal string.
|
// 'pdfioStringCreate()' - Create a durable literal string.
|
||||||
//
|
//
|
||||||
@@ -390,7 +723,7 @@ pdfioStringCreate(
|
|||||||
int diff; // Different
|
int diff; // Different
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", pdf, s);
|
PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", (void *)pdf, s);
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!pdf || !s)
|
if (!pdf || !s)
|
||||||
@@ -480,6 +813,29 @@ pdfioStringCreatef(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// '_pdfioStringFreeBuffer()' - Free a string buffer.
|
||||||
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
_pdfioStringFreeBuffer(
|
||||||
|
pdfio_file_t *pdf, // I - PDF file
|
||||||
|
char *buffer) // I - String buffer
|
||||||
|
{
|
||||||
|
_pdfio_strbuf_t *current; // Current string buffer
|
||||||
|
|
||||||
|
|
||||||
|
for (current = pdf->strbuffers; current; current = current->next)
|
||||||
|
{
|
||||||
|
if (current->buffer == buffer)
|
||||||
|
{
|
||||||
|
current->bufused = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// '_pdfioStringIsAllocated()' - Check whether a string has been allocated.
|
// '_pdfioStringIsAllocated()' - Check whether a string has been allocated.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// PDF token parsing functions for PDFio.
|
// PDF token parsing functions for PDFio.
|
||||||
//
|
//
|
||||||
// Copyright © 2021-2023 by Michael R Sweet.
|
// Copyright © 2021-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -54,7 +54,7 @@ static int get_char(_pdfio_token_t *tb);
|
|||||||
void
|
void
|
||||||
_pdfioTokenClear(_pdfio_token_t *tb) // I - Token buffer/stack
|
_pdfioTokenClear(_pdfio_token_t *tb) // I - Token buffer/stack
|
||||||
{
|
{
|
||||||
PDFIO_DEBUG("_pdfioTokenClear(tb=%p)\n", tb);
|
PDFIO_DEBUG("_pdfioTokenClear(tb=%p)\n", (void *)tb);
|
||||||
|
|
||||||
while (tb->num_tokens > 0)
|
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))
|
if ((len = strlen(tb->tokens[tb->num_tokens])) > (bufsize - 1))
|
||||||
{
|
{
|
||||||
// Value too large...
|
// Value too large...
|
||||||
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]);
|
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]);
|
||||||
*buffer = '\0';
|
*buffer = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ _pdfioTokenGet(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
memcpy(buffer, tb->tokens[tb->num_tokens], len);
|
memcpy(buffer, tb->tokens[tb->num_tokens], len);
|
||||||
buffer[len] = '\0';
|
buffer[len] = '\0';
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Popping '%s' from stack.\n", tb, buffer, (unsigned)bufsize, buffer);
|
PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Popping '%s' from stack.\n", (void *)tb, (void *)buffer, (unsigned)bufsize, buffer);
|
||||||
|
|
||||||
free(tb->tokens[tb->num_tokens]);
|
free(tb->tokens[tb->num_tokens]);
|
||||||
tb->tokens[tb->num_tokens] = NULL;
|
tb->tokens[tb->num_tokens] = NULL;
|
||||||
@@ -380,7 +380,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Out of space
|
// Out of space
|
||||||
_pdfioFileError(tb->pdf, "Token too large.");
|
_pdfioFileError(tb->pdf, "String token too large.");
|
||||||
*bufptr = '\0';
|
*bufptr = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -393,9 +393,18 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saw_nul)
|
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)
|
||||||
{
|
{
|
||||||
// Convert to a hex (binary) string...
|
// Contains nul characters, convert to a hex (binary) string...
|
||||||
char *litptr, // Pointer to literal character
|
char *litptr, // Pointer to literal character
|
||||||
*hexptr; // Pointer to hex character
|
*hexptr; // Pointer to hex character
|
||||||
size_t bytes = (size_t)(bufptr - buffer - 1);
|
size_t bytes = (size_t)(bufptr - buffer - 1);
|
||||||
@@ -408,7 +417,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
if ((2 * (bytes + 1)) > bufsize)
|
if ((2 * (bytes + 1)) > bufsize)
|
||||||
{
|
{
|
||||||
// Out of space...
|
// Out of space...
|
||||||
_pdfioFileError(tb->pdf, "Token too large.");
|
_pdfioFileError(tb->pdf, "Binary string token too large.");
|
||||||
*bufptr = '\0';
|
*bufptr = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -442,7 +451,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Out of space...
|
// Out of space...
|
||||||
_pdfioFileError(tb->pdf, "Token too large.");
|
_pdfioFileError(tb->pdf, "Keyword token too large.");
|
||||||
*bufptr = '\0';
|
*bufptr = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -474,7 +483,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Out of space...
|
// Out of space...
|
||||||
_pdfioFileError(tb->pdf, "Token too large.");
|
_pdfioFileError(tb->pdf, "Number token too large.");
|
||||||
*bufptr = '\0';
|
*bufptr = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -523,18 +532,11 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Out of space
|
// Out of space
|
||||||
_pdfioFileError(tb->pdf, "Token too large.");
|
_pdfioFileError(tb->pdf, "Name token too large.");
|
||||||
*bufptr = '\0';
|
*bufptr = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufptr == (buffer + 1))
|
|
||||||
{
|
|
||||||
_pdfioFileError(tb->pdf, "Empty name.");
|
|
||||||
*bufptr = '\0';
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<' : // Potential hex string
|
case '<' : // Potential hex string
|
||||||
@@ -573,7 +575,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Too large
|
// Too large
|
||||||
_pdfioFileError(tb->pdf, "Token too large.");
|
_pdfioFileError(tb->pdf, "Hex string token too large.");
|
||||||
*bufptr = '\0';
|
*bufptr = '\0';
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|||||||
329
pdfio-value.c
329
pdfio-value.c
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// PDF value functions for PDFio.
|
// PDF value functions for PDFio.
|
||||||
//
|
//
|
||||||
// Copyright © 2021-2024 by Michael R Sweet.
|
// Copyright © 2021-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -46,7 +46,7 @@ _pdfioValueCopy(pdfio_file_t *pdfdst, // I - Destination PDF file
|
|||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioValueCopy(pdfdst=%p, vdst=%p, pdfsrc=%p, vsrc=%p(%s))\n", pdfdst, vdst, pdfsrc, vsrc, types[vsrc->type]);
|
PDFIO_DEBUG("_pdfioValueCopy(pdfdst=%p, vdst=%p, pdfsrc=%p, vsrc=%p(%s))\n", (void *)pdfdst, (void *)vdst, (void *)pdfsrc, (void *)vsrc, types[vsrc->type]);
|
||||||
|
|
||||||
if (pdfdst == pdfsrc && vsrc->type != PDFIO_VALTYPE_BINARY)
|
if (pdfdst == pdfsrc && vsrc->type != PDFIO_VALTYPE_BINARY)
|
||||||
{
|
{
|
||||||
@@ -125,7 +125,7 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfio_crypto_ctx_t ctx; // Decryption context
|
_pdfio_crypto_ctx_t ctx; // Decryption context
|
||||||
_pdfio_crypto_cb_t cb; // Decryption callback
|
_pdfio_crypto_cb_t cb; // Decryption callback
|
||||||
size_t ivlen; // Number of initialization vector bytes
|
size_t ivlen; // Number of initialization vector bytes
|
||||||
uint8_t temp[32768]; // Temporary buffer for decryption
|
uint8_t *temp = NULL; // Temporary buffer for decryption
|
||||||
size_t templen; // Number of actual data bytes
|
size_t templen; // Number of actual data bytes
|
||||||
time_t timeval; // Date/time value
|
time_t timeval; // Date/time value
|
||||||
|
|
||||||
@@ -152,11 +152,16 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
case PDFIO_VALTYPE_BINARY :
|
case PDFIO_VALTYPE_BINARY :
|
||||||
// Decrypt the binary string...
|
// Decrypt the binary string...
|
||||||
if (v->value.binary.datalen > (sizeof(temp) - 32))
|
if (v->value.binary.datalen > PDFIO_MAX_STRING)
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Unable to read encrypted binary string - too long.");
|
_pdfioFileError(pdf, "Unable to read encrypted binary string - too long.");
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||||
|
{
|
||||||
|
_pdfioFileError(pdf, "Unable to read encrypted binary string - out of memory.");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
ivlen = v->value.binary.datalen;
|
ivlen = v->value.binary.datalen;
|
||||||
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, v->value.binary.data, &ivlen)) == NULL)
|
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, v->value.binary.data, &ivlen)) == NULL)
|
||||||
@@ -167,29 +172,59 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Copy the decrypted string back to the value and adjust the length...
|
// Copy the decrypted string back to the value and adjust the length...
|
||||||
memcpy(v->value.binary.data, temp, templen);
|
memcpy(v->value.binary.data, temp, templen);
|
||||||
|
|
||||||
if (pdf->encryption >= PDFIO_ENCRYPTION_AES_128)
|
if (pdf->encryption >= PDFIO_ENCRYPTION_AES_128 && temp[templen - 1] <= templen)
|
||||||
v->value.binary.datalen = templen - temp[templen - 1];
|
v->value.binary.datalen = templen - temp[templen - 1];
|
||||||
else
|
else
|
||||||
v->value.binary.datalen = templen;
|
v->value.binary.datalen = templen;
|
||||||
|
|
||||||
|
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PDFIO_VALTYPE_STRING :
|
case PDFIO_VALTYPE_STRING :
|
||||||
// Decrypt regular string...
|
// Decrypt regular string...
|
||||||
templen = strlen(v->value.string);
|
templen = strlen(v->value.string);
|
||||||
if (templen > (sizeof(temp) - 33))
|
if (templen > (PDFIO_MAX_STRING - 1))
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Unable to read encrypted string - too long.");
|
_pdfioFileError(pdf, "Unable to read encrypted string - too long.");
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||||
|
{
|
||||||
|
_pdfioFileError(pdf, "Unable to read encrypted binary string - out of memory.");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
ivlen = templen;
|
ivlen = templen;
|
||||||
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, (uint8_t *)v->value.string, &ivlen)) == NULL)
|
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, (uint8_t *)v->value.string, &ivlen)) == NULL)
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
templen = (cb)(&ctx, temp, (uint8_t *)v->value.string + ivlen, templen - ivlen);
|
templen = (cb)(&ctx, temp, (uint8_t *)v->value.string + ivlen, templen - ivlen);
|
||||||
|
|
||||||
|
if (pdf->encryption >= PDFIO_ENCRYPTION_AES_128 && temp[templen - 1] <= templen)
|
||||||
|
templen -= temp[templen - 1];
|
||||||
|
|
||||||
temp[templen] = '\0';
|
temp[templen] = '\0';
|
||||||
|
|
||||||
if ((timeval = get_date_time((char *)temp)) != 0)
|
if ((templen & 1) == 0 && (!memcmp(temp, "\376\377", 2) || !memcmp(temp, "\377\376", 2)))
|
||||||
|
{
|
||||||
|
// Convert UTF-16 to UTF-8...
|
||||||
|
char utf8[4096]; // Temporary string
|
||||||
|
|
||||||
|
_pdfio_utf16cpy(utf8, temp, templen, sizeof(utf8));
|
||||||
|
|
||||||
|
if ((timeval = get_date_time((char *)utf8)) != 0)
|
||||||
|
{
|
||||||
|
// Change the type to date...
|
||||||
|
v->type = PDFIO_VALTYPE_DATE;
|
||||||
|
v->value.date = timeval;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy the decrypted string back to the value...
|
||||||
|
v->value.string = pdfioStringCreate(pdf, utf8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((timeval = get_date_time((char *)temp)) != 0)
|
||||||
{
|
{
|
||||||
// Change the type to date...
|
// Change the type to date...
|
||||||
v->type = PDFIO_VALTYPE_DATE;
|
v->type = PDFIO_VALTYPE_DATE;
|
||||||
@@ -200,6 +235,8 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Copy the decrypted string back to the value...
|
// Copy the decrypted string back to the value...
|
||||||
v->value.string = pdfioStringCreate(pdf, (char *)temp);
|
v->value.string = pdfioStringCreate(pdf, (char *)temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +337,9 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfio_value_t *v, // I - Value
|
_pdfio_value_t *v, // I - Value
|
||||||
size_t depth) // I - Depth of value
|
size_t depth) // I - Depth of value
|
||||||
{
|
{
|
||||||
char token[32768]; // Token buffer
|
_pdfio_value_t *ret = NULL; // Return value
|
||||||
|
char *token = _pdfioStringAllocBuffer(pdf);
|
||||||
|
// Token buffer
|
||||||
time_t timeval; // Date/time value
|
time_t timeval; // Date/time value
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static const char * const valtypes[] =
|
static const char * const valtypes[] =
|
||||||
@@ -320,10 +359,13 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioValueRead(pdf=%p, obj=%p, v=%p)\n", pdf, obj, v);
|
PDFIO_DEBUG("_pdfioValueRead(pdf=%p, obj=%p, v=%p)\n", (void *)pdf, (void *)obj, (void *)v);
|
||||||
|
|
||||||
if (!_pdfioTokenGet(tb, token, sizeof(token)))
|
if (!token)
|
||||||
return (NULL);
|
goto done;
|
||||||
|
|
||||||
|
if (!_pdfioTokenGet(tb, token, PDFIO_MAX_STRING))
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (!strcmp(token, "["))
|
if (!strcmp(token, "["))
|
||||||
{
|
{
|
||||||
@@ -331,12 +373,14 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
if (depth >= PDFIO_MAX_DEPTH)
|
if (depth >= PDFIO_MAX_DEPTH)
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Too many nested arrays.");
|
_pdfioFileError(pdf, "Too many nested arrays.");
|
||||||
return (NULL);
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->type = PDFIO_VALTYPE_ARRAY;
|
v->type = PDFIO_VALTYPE_ARRAY;
|
||||||
if ((v->value.array = _pdfioArrayRead(pdf, obj, tb, depth + 1)) == NULL)
|
if ((v->value.array = _pdfioArrayRead(pdf, obj, tb, depth + 1)) == NULL)
|
||||||
return (NULL);
|
goto done;
|
||||||
|
|
||||||
|
ret = v;
|
||||||
}
|
}
|
||||||
else if (!strcmp(token, "<<"))
|
else if (!strcmp(token, "<<"))
|
||||||
{
|
{
|
||||||
@@ -344,29 +388,38 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
if (depth >= PDFIO_MAX_DEPTH)
|
if (depth >= PDFIO_MAX_DEPTH)
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Too many nested dictionaries.");
|
_pdfioFileError(pdf, "Too many nested dictionaries.");
|
||||||
return (NULL);
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->type = PDFIO_VALTYPE_DICT;
|
v->type = PDFIO_VALTYPE_DICT;
|
||||||
if ((v->value.dict = _pdfioDictRead(pdf, obj, tb, depth + 1)) == NULL)
|
if ((v->value.dict = _pdfioDictRead(pdf, obj, tb, depth + 1)) == NULL)
|
||||||
return (NULL);
|
goto done;
|
||||||
}
|
|
||||||
else if (!strncmp(token, "(D:", 3) && (timeval = get_date_time(token + 1)) != 0)
|
ret = v;
|
||||||
{
|
|
||||||
v->type = PDFIO_VALTYPE_DATE;
|
|
||||||
v->value.date = timeval;
|
|
||||||
}
|
}
|
||||||
else if (token[0] == '(')
|
else if (token[0] == '(')
|
||||||
{
|
{
|
||||||
// String
|
if ((timeval = get_date_time(token + 1)) != 0)
|
||||||
v->type = PDFIO_VALTYPE_STRING;
|
{
|
||||||
v->value.string = pdfioStringCreate(pdf, token + 1);
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (token[0] == '/')
|
else if (token[0] == '/')
|
||||||
{
|
{
|
||||||
// Name
|
// Name
|
||||||
v->type = PDFIO_VALTYPE_NAME;
|
v->type = PDFIO_VALTYPE_NAME;
|
||||||
v->value.name = pdfioStringCreate(pdf, token + 1);
|
v->value.name = pdfioStringCreate(pdf, token + 1);
|
||||||
|
ret = v;
|
||||||
}
|
}
|
||||||
else if (token[0] == '<')
|
else if (token[0] == '<')
|
||||||
{
|
{
|
||||||
@@ -379,7 +432,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
if ((v->value.binary.data = (unsigned char *)malloc(v->value.binary.datalen)) == NULL)
|
if ((v->value.binary.data = (unsigned char *)malloc(v->value.binary.datalen)) == NULL)
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Out of memory for hex string.");
|
_pdfioFileError(pdf, "Out of memory for hex string.");
|
||||||
return (NULL);
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert hex to binary...
|
// Convert hex to binary...
|
||||||
@@ -406,6 +459,8 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
*dataptr++ = (unsigned char)d;
|
*dataptr++ = (unsigned char)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = v;
|
||||||
}
|
}
|
||||||
else if (strchr("0123456789-+.", token[0]) != NULL)
|
else if (strchr("0123456789-+.", token[0]) != NULL)
|
||||||
{
|
{
|
||||||
@@ -460,7 +515,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Integer...
|
// Integer...
|
||||||
long generation = 0; // Generation number
|
long generation = 0; // Generation number
|
||||||
|
|
||||||
while (tempptr < tb->bufend && isdigit(*tempptr & 255))
|
while (tempptr < tb->bufend && generation < 65536 && isdigit(*tempptr & 255))
|
||||||
{
|
{
|
||||||
generation = generation * 10 + *tempptr - '0';
|
generation = generation * 10 + *tempptr - '0';
|
||||||
tempptr ++;
|
tempptr ++;
|
||||||
@@ -493,7 +548,8 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
|
|
||||||
PDFIO_DEBUG("_pdfioValueRead: Returning indirect value %lu %u R.\n", (unsigned long)v->value.indirect.number, v->value.indirect.generation);
|
PDFIO_DEBUG("_pdfioValueRead: Returning indirect value %lu %u R.\n", (unsigned long)v->value.indirect.number, v->value.indirect.generation);
|
||||||
|
|
||||||
return (v);
|
ret = v;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -501,27 +557,41 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// If we get here, we have a number...
|
// If we get here, we have a number...
|
||||||
v->type = PDFIO_VALTYPE_NUMBER;
|
v->type = PDFIO_VALTYPE_NUMBER;
|
||||||
v->value.number = _pdfio_strtod(pdf, token);
|
v->value.number = _pdfio_strtod(pdf, token);
|
||||||
|
ret = v;
|
||||||
}
|
}
|
||||||
else if (!strcmp(token, "true") || !strcmp(token, "false"))
|
else if (!strcmp(token, "true") || !strcmp(token, "false"))
|
||||||
{
|
{
|
||||||
// Boolean value
|
// Boolean value
|
||||||
v->type = PDFIO_VALTYPE_BOOLEAN;
|
v->type = PDFIO_VALTYPE_BOOLEAN;
|
||||||
v->value.boolean = !strcmp(token, "true");
|
v->value.boolean = !strcmp(token, "true");
|
||||||
|
ret = v;
|
||||||
}
|
}
|
||||||
else if (!strcmp(token, "null"))
|
else if (!strcmp(token, "null"))
|
||||||
{
|
{
|
||||||
// null value
|
// null value
|
||||||
v->type = PDFIO_VALTYPE_NULL;
|
v->type = PDFIO_VALTYPE_NULL;
|
||||||
|
ret = v;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Unexpected '%s' token seen.", token);
|
_pdfioFileError(pdf, "Unexpected '%s' token seen.", token);
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFIO_DEBUG("_pdfioValueRead: Returning %s value.\n", valtypes[v->type]);
|
done:
|
||||||
|
|
||||||
return (v);
|
if (token)
|
||||||
|
_pdfioStringFreeBuffer(pdf, token);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
PDFIO_DEBUG("_pdfioValueRead: Returning %s value.\n", valtypes[ret->type]);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PDFIO_DEBUG("_pdfioValueRead: Returning NULL.\n");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -546,8 +616,10 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
case PDFIO_VALTYPE_BINARY :
|
case PDFIO_VALTYPE_BINARY :
|
||||||
{
|
{
|
||||||
size_t databytes; // Bytes to write
|
size_t databytes; // Bytes to write
|
||||||
uint8_t temp[32768], // Temporary buffer for encryption
|
uint8_t *temp = NULL, // Temporary buffer for encryption
|
||||||
*dataptr; // Pointer into data
|
*dataptr; // Pointer into data
|
||||||
|
bool ret = false; // Return value
|
||||||
|
|
||||||
|
|
||||||
if (obj && pdf->encryption)
|
if (obj && pdf->encryption)
|
||||||
{
|
{
|
||||||
@@ -556,11 +628,16 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||||
size_t ivlen; // Number of initialization vector bytes
|
size_t ivlen; // Number of initialization vector bytes
|
||||||
|
|
||||||
if (v->value.binary.datalen > (sizeof(temp) - 32))
|
if (v->value.binary.datalen > PDFIO_MAX_STRING)
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Unable to write encrypted binary string - too long.");
|
_pdfioFileError(pdf, "Unable to write encrypted binary string - too long.");
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||||
|
{
|
||||||
|
_pdfioFileError(pdf, "Unable to write encrypted binary string - out of memory.");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||||
databytes = (cb)(&ctx, temp + ivlen, v->value.binary.data, v->value.binary.datalen) + ivlen;
|
databytes = (cb)(&ctx, temp + ivlen, v->value.binary.data, v->value.binary.datalen) + ivlen;
|
||||||
@@ -573,18 +650,25 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!_pdfioFilePuts(pdf, "<"))
|
if (!_pdfioFilePuts(pdf, "<"))
|
||||||
return (false);
|
goto bindone;
|
||||||
|
|
||||||
for (; databytes > 1; databytes -= 2, dataptr += 2)
|
for (; databytes > 1; databytes -= 2, dataptr += 2)
|
||||||
{
|
{
|
||||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", dataptr[0], dataptr[1]))
|
if (!_pdfioFilePrintf(pdf, "%02X%02X", dataptr[0], dataptr[1]))
|
||||||
return (false);
|
goto bindone;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (databytes > 0)
|
if (databytes > 0 && !_pdfioFilePrintf(pdf, "%02X", dataptr[0]))
|
||||||
return (_pdfioFilePrintf(pdf, "%02X>", dataptr[0]));
|
goto bindone;
|
||||||
else
|
|
||||||
return (_pdfioFilePuts(pdf, ">"));
|
ret = _pdfioFilePuts(pdf, ">");
|
||||||
|
|
||||||
|
bindone:
|
||||||
|
|
||||||
|
if (temp)
|
||||||
|
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
case PDFIO_VALTYPE_BOOLEAN :
|
case PDFIO_VALTYPE_BOOLEAN :
|
||||||
@@ -609,7 +693,7 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
if (obj && pdf->encryption)
|
if (obj && pdf->encryption)
|
||||||
{
|
{
|
||||||
// Write encrypted string...
|
// Write encrypted string...
|
||||||
uint8_t temp[32768], // Encrypted bytes
|
uint8_t temp[64], // Encrypted bytes
|
||||||
*tempptr; // Pointer into encrypted bytes
|
*tempptr; // Pointer into encrypted bytes
|
||||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||||
@@ -637,7 +721,7 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (_pdfioFilePrintf(pdf, "(%s)", datestr));
|
return (_pdfioFilePrintf(pdf, "%S", datestr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,19 +732,19 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
return (_pdfioFilePrintf(pdf, " %lu %u R", (unsigned long)v->value.indirect.number, v->value.indirect.generation));
|
return (_pdfioFilePrintf(pdf, " %lu %u R", (unsigned long)v->value.indirect.number, v->value.indirect.generation));
|
||||||
|
|
||||||
case PDFIO_VALTYPE_NAME :
|
case PDFIO_VALTYPE_NAME :
|
||||||
return (_pdfioFilePrintf(pdf, "/%s", v->value.name));
|
return (_pdfioFilePrintf(pdf, "%N", v->value.name));
|
||||||
|
|
||||||
case PDFIO_VALTYPE_NULL :
|
case PDFIO_VALTYPE_NULL :
|
||||||
return (_pdfioFilePuts(pdf, " null"));
|
return (_pdfioFilePuts(pdf, " null"));
|
||||||
|
|
||||||
case PDFIO_VALTYPE_NUMBER :
|
case PDFIO_VALTYPE_NUMBER :
|
||||||
return (_pdfioFilePrintf(pdf, " %g", v->value.number));
|
return (_pdfioFilePrintf(pdf, " %.6f", v->value.number));
|
||||||
|
|
||||||
case PDFIO_VALTYPE_STRING :
|
case PDFIO_VALTYPE_STRING :
|
||||||
if (obj && pdf->encryption)
|
if (obj && pdf->encryption)
|
||||||
{
|
{
|
||||||
// Write encrypted string...
|
// Write encrypted string...
|
||||||
uint8_t temp[32768], // Encrypted bytes
|
uint8_t *temp = NULL, // Encrypted bytes
|
||||||
*tempptr; // Pointer into encrypted bytes
|
*tempptr; // Pointer into encrypted bytes
|
||||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||||
@@ -668,74 +752,46 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// Length of value
|
// Length of value
|
||||||
ivlen, // Number of initialization vector bytes
|
ivlen, // Number of initialization vector bytes
|
||||||
tempbytes; // Number of output bytes
|
tempbytes; // Number of output bytes
|
||||||
|
bool ret = false; // Return value
|
||||||
|
|
||||||
if (len > (sizeof(temp) - 32))
|
if (len > PDFIO_MAX_STRING)
|
||||||
{
|
{
|
||||||
_pdfioFileError(pdf, "Unable to write encrypted string - too long.");
|
_pdfioFileError(pdf, "Unable to write encrypted string - too long.");
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||||
|
{
|
||||||
|
_pdfioFileError(pdf, "Unable to write encrypted string - out of memory.");
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||||
tempbytes = (cb)(&ctx, temp + ivlen, (const uint8_t *)v->value.string, len) + ivlen;
|
tempbytes = (cb)(&ctx, temp + ivlen, (const uint8_t *)v->value.string, len) + ivlen;
|
||||||
|
|
||||||
if (!_pdfioFilePuts(pdf, "<"))
|
if (!_pdfioFilePuts(pdf, "<"))
|
||||||
return (false);
|
goto strdone;
|
||||||
|
|
||||||
for (tempptr = temp; tempbytes > 1; tempbytes -= 2, tempptr += 2)
|
for (tempptr = temp; tempbytes > 1; tempbytes -= 2, tempptr += 2)
|
||||||
{
|
{
|
||||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", tempptr[0], tempptr[1]))
|
if (!_pdfioFilePrintf(pdf, "%02X%02X", tempptr[0], tempptr[1]))
|
||||||
return (false);
|
goto strdone;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempbytes > 0)
|
if (tempbytes > 0 && !_pdfioFilePrintf(pdf, "%02X", *tempptr))
|
||||||
return (_pdfioFilePrintf(pdf, "%02X>", *tempptr));
|
goto strdone;
|
||||||
else
|
|
||||||
return (_pdfioFilePuts(pdf, ">"));
|
ret = _pdfioFilePuts(pdf, ">");
|
||||||
|
|
||||||
|
strdone :
|
||||||
|
|
||||||
|
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Write unencrypted string...
|
// Write unencrypted string...
|
||||||
const char *start, // Start of fragment
|
return (_pdfioFilePrintf(pdf, "%S", v->value.string));
|
||||||
*end; // End of fragment
|
|
||||||
|
|
||||||
if (!_pdfioFilePuts(pdf, "("))
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
// Write a quoted string value...
|
|
||||||
for (start = v->value.string; *start; start = end)
|
|
||||||
{
|
|
||||||
// Find the next character that needs to be quoted...
|
|
||||||
for (end = start; *end; end ++)
|
|
||||||
{
|
|
||||||
if (*end == '\\' || *end == ')' || (*end & 255) < ' ')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end > start)
|
|
||||||
{
|
|
||||||
// Write unquoted (safe) characters...
|
|
||||||
if (!_pdfioFileWrite(pdf, start, (size_t)(end - start)))
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*end)
|
|
||||||
{
|
|
||||||
// Quote this character...
|
|
||||||
bool success; // Did the write work?
|
|
||||||
|
|
||||||
if (*end == '\\' || *end == ')')
|
|
||||||
success = _pdfioFilePrintf(pdf, "\\%c", *end);
|
|
||||||
else
|
|
||||||
success = _pdfioFilePrintf(pdf, "\\%03o", *end);
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
end ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (_pdfioFilePuts(pdf, ")"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,31 +803,59 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
|||||||
// 'get_date_time()' - Convert PDF date/time value to time_t.
|
// 'get_date_time()' - Convert PDF date/time value to time_t.
|
||||||
//
|
//
|
||||||
|
|
||||||
static time_t // O - Time in seconds
|
static time_t // O - Time in seconds or `0` for none
|
||||||
get_date_time(const char *s) // I - PDF date/time value
|
get_date_time(const char *s) // I - PDF date/time value
|
||||||
{
|
{
|
||||||
int i; // Looping var
|
int i; // Looping var
|
||||||
struct tm dateval; // Date value
|
struct tm dateval; // Date value
|
||||||
int offset; // Date offset
|
int offset = 0; // Date offset in seconds
|
||||||
|
time_t t; // Time value
|
||||||
|
|
||||||
|
|
||||||
PDFIO_DEBUG("get_date_time(s=\"%s\")\n", s);
|
PDFIO_DEBUG("get_date_time(s=\"%s\")\n", s);
|
||||||
|
|
||||||
// Possible date value of the form:
|
// Possible date value of the form:
|
||||||
//
|
//
|
||||||
// (D:YYYYMMDDhhmmssZ)
|
// D:YYYYMMDDhhmmssZ
|
||||||
// (D:YYYYMMDDhhmmss+HH'mm)
|
// D:YYYYMMDDhhmmss+HH'mm
|
||||||
// (D:YYYYMMDDhhmmss-HH'mm)
|
// D:YYYYMMDDhhmmss-HH'mm
|
||||||
//
|
//
|
||||||
|
|
||||||
|
if (strncmp(s, "D:", 2))
|
||||||
|
return (0);
|
||||||
|
|
||||||
for (i = 2; i < 16; i ++)
|
for (i = 2; i < 16; i ++)
|
||||||
{
|
{
|
||||||
|
// Look for date/time digits...
|
||||||
if (!isdigit(s[i] & 255) || !s[i])
|
if (!isdigit(s[i] & 255) || !s[i])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= 16)
|
if (i < 6 || (i & 1))
|
||||||
{
|
{
|
||||||
|
// Short year or missing digit...
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&dateval, 0, sizeof(dateval));
|
||||||
|
|
||||||
|
dateval.tm_year = (s[2] - '0') * 1000 + (s[3] - '0') * 100 + (s[4] - '0') * 10 + s[5] - '0' - 1900;
|
||||||
|
if (i > 6)
|
||||||
|
dateval.tm_mon = (s[6] - '0') * 10 + s[7] - '0' - 1;
|
||||||
|
if (i > 8)
|
||||||
|
dateval.tm_mday = (s[8] - '0') * 10 + s[9] - '0';
|
||||||
|
else
|
||||||
|
dateval.tm_mday = 1;
|
||||||
|
if (i > 10)
|
||||||
|
dateval.tm_hour = (s[10] - '0') * 10 + s[11] - '0';
|
||||||
|
if (i > 12)
|
||||||
|
dateval.tm_min = (s[12] - '0') * 10 + s[13] - '0';
|
||||||
|
if (i > 14)
|
||||||
|
dateval.tm_sec = (s[14] - '0') * 10 + s[15] - '0';
|
||||||
|
|
||||||
|
if (i >= 16 && s[i])
|
||||||
|
{
|
||||||
|
// Get zone info...
|
||||||
if (s[i] == 'Z')
|
if (s[i] == 'Z')
|
||||||
{
|
{
|
||||||
// UTC...
|
// UTC...
|
||||||
@@ -782,14 +866,20 @@ get_date_time(const char *s) // I - PDF date/time value
|
|||||||
// Timezone offset from UTC...
|
// Timezone offset from UTC...
|
||||||
if (isdigit(s[i + 1] & 255) && isdigit(s[i + 2] & 255) && s[i + 3] == '\'' && isdigit(s[i + 4] & 255) && isdigit(s[i + 5] & 255))
|
if (isdigit(s[i + 1] & 255) && isdigit(s[i + 2] & 255) && s[i + 3] == '\'' && isdigit(s[i + 4] & 255) && isdigit(s[i + 5] & 255))
|
||||||
{
|
{
|
||||||
|
offset = (s[i + 1] - '0') * 36000 + (s[i + 2] - '0') * 3600 + (s[i + 4] - '0') * 600 + (s[i + 5] - '0') * 60;
|
||||||
|
if (s[i] == '-')
|
||||||
|
offset = -offset;
|
||||||
|
|
||||||
i += 6;
|
i += 6;
|
||||||
|
|
||||||
|
// Accept trailing quote, per PDF spec...
|
||||||
if (s[i] == '\'')
|
if (s[i] == '\'')
|
||||||
i ++;
|
i ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!s[i])
|
else
|
||||||
{
|
{
|
||||||
// Missing zone info, invalid date string...
|
// Random zone info, invalid date string...
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -800,26 +890,31 @@ get_date_time(const char *s) // I - PDF date/time value
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Date value...
|
// Convert date value to time_t...
|
||||||
memset(&dateval, 0, sizeof(dateval));
|
#if _WIN32
|
||||||
|
if ((t = _mkgmtime(&dateval)) <= 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
dateval.tm_year = (s[2] - '0') * 1000 + (s[3] - '0') * 100 + (s[4] - '0') * 10 + s[5] - '0' - 1900;
|
#elif defined(HAVE_TIMEGM)
|
||||||
dateval.tm_mon = (s[6] - '0') * 10 + s[7] - '0' - 1;
|
if ((t = timegm(&dateval)) <= 0)
|
||||||
dateval.tm_mday = (s[8] - '0') * 10 + s[9] - '0';
|
return (0);
|
||||||
dateval.tm_hour = (s[10] - '0') * 10 + s[11] - '0';
|
|
||||||
dateval.tm_min = (s[12] - '0') * 10 + s[13] - '0';
|
|
||||||
dateval.tm_sec = (s[14] - '0') * 10 + s[15] - '0';
|
|
||||||
|
|
||||||
if (s[16] == 'Z')
|
#else
|
||||||
{
|
if ((t = mktime(&dateval)) <= 0)
|
||||||
offset = 0;
|
return (0);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
offset = (s[17] - '0') * 600 + (s[18] - '0') * 60 + (s[19] - '0') * 10 + s[20] - '0';
|
|
||||||
if (s[16] == '-')
|
|
||||||
offset = -offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (mktime(&dateval) + offset);
|
# if defined(HAVE_TM_GMTOFF)
|
||||||
|
// Adjust the time value using the "tm_gmtoff" and "tm_isdst" members. As
|
||||||
|
// noted by M-HT on Github, this DST hack will fail in timezones where the
|
||||||
|
// DST offset is not one hour, such as Australia/Lord_Howe. Fortunately,
|
||||||
|
// this is unusual and most systems support the "timegm" function...
|
||||||
|
t += dateval.tm_gmtoff - 3600 * dateval.tm_isdst;
|
||||||
|
# else
|
||||||
|
// Adjust the time value using the even more legacy "timezone" variable,
|
||||||
|
// which also reflects any DST offset...
|
||||||
|
t += timezone;
|
||||||
|
# endif // HAVE_TM_GMTOFF
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
return (t - offset);
|
||||||
}
|
}
|
||||||
|
|||||||
18
pdfio.h
18
pdfio.h
@@ -23,9 +23,9 @@ extern "C" {
|
|||||||
// Version numbers...
|
// Version numbers...
|
||||||
//
|
//
|
||||||
|
|
||||||
# define PDFIO_VERSION "1.5.0"
|
# define PDFIO_VERSION "1.6.1"
|
||||||
# define PDFIO_VERSION_MAJOR 1
|
# define PDFIO_VERSION_MAJOR 1
|
||||||
# define PDFIO_VERSION_MINOR 5
|
# define PDFIO_VERSION_MINOR 6
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -34,11 +34,9 @@ extern "C" {
|
|||||||
|
|
||||||
# if defined(__has_extension) || defined(__GNUC__)
|
# if defined(__has_extension) || defined(__GNUC__)
|
||||||
# define _PDFIO_PUBLIC __attribute__ ((visibility("default")))
|
# define _PDFIO_PUBLIC __attribute__ ((visibility("default")))
|
||||||
# define _PDFIO_FORMAT(a,b) __attribute__ ((__format__(__printf__, a,b)))
|
|
||||||
# define _PDFIO_DEPRECATED __attribute__ ((deprecated)) _PDFIO_PUBLIC
|
# define _PDFIO_DEPRECATED __attribute__ ((deprecated)) _PDFIO_PUBLIC
|
||||||
# else
|
# else
|
||||||
# define _PDFIO_PUBLIC
|
# define _PDFIO_PUBLIC
|
||||||
# define _PDFIO_FORMAT(a,b)
|
|
||||||
# define _PDFIO_DEPRECATED
|
# define _PDFIO_DEPRECATED
|
||||||
# endif // __has_extension || __GNUC__
|
# endif // __has_extension || __GNUC__
|
||||||
|
|
||||||
@@ -48,7 +46,7 @@ extern "C" {
|
|||||||
//
|
//
|
||||||
|
|
||||||
# if _WIN32
|
# 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
|
# endif // _WIN32
|
||||||
|
|
||||||
typedef struct _pdfio_array_s pdfio_array_t;
|
typedef struct _pdfio_array_s pdfio_array_t;
|
||||||
@@ -64,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
|
typedef enum pdfio_encryption_e // PDF encryption modes
|
||||||
{
|
{
|
||||||
PDFIO_ENCRYPTION_NONE = 0, // No encryption
|
PDFIO_ENCRYPTION_NONE = 0, // No encryption
|
||||||
PDFIO_ENCRYPTION_RC4_40, // 40-bit RC4 encryption (PDF 1.3)
|
PDFIO_ENCRYPTION_RC4_40, // 40-bit RC4 encryption (PDF 1.3, reading only)
|
||||||
PDFIO_ENCRYPTION_RC4_128, // 128-bit RC4 encryption (PDF 1.4)
|
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_128, // 128-bit AES encryption (PDF 1.6)
|
||||||
PDFIO_ENCRYPTION_AES_256 // 256-bit AES encryption (PDF 2.0) @exclude all@
|
PDFIO_ENCRYPTION_AES_256 // 256-bit AES encryption (PDF 2.0) @exclude all@
|
||||||
@@ -183,7 +181,7 @@ extern bool pdfioDictSetNumber(pdfio_dict_t *dict, const char *key, double valu
|
|||||||
extern bool pdfioDictSetObj(pdfio_dict_t *dict, const char *key, pdfio_obj_t *value) _PDFIO_PUBLIC;
|
extern bool pdfioDictSetObj(pdfio_dict_t *dict, const char *key, pdfio_obj_t *value) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioDictSetRect(pdfio_dict_t *dict, const char *key, pdfio_rect_t *value) _PDFIO_PUBLIC;
|
extern bool pdfioDictSetRect(pdfio_dict_t *dict, const char *key, pdfio_rect_t *value) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioDictSetString(pdfio_dict_t *dict, const char *key, const char *value) _PDFIO_PUBLIC;
|
extern bool pdfioDictSetString(pdfio_dict_t *dict, const char *key, const char *value) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioDictSetStringf(pdfio_dict_t *dict, const char *key, const char *format, ...) _PDFIO_PUBLIC _PDFIO_FORMAT(3,4);
|
extern bool pdfioDictSetStringf(pdfio_dict_t *dict, const char *key, const char *format, ...) _PDFIO_PUBLIC;
|
||||||
|
|
||||||
extern bool pdfioFileClose(pdfio_file_t *pdf) _PDFIO_PUBLIC;
|
extern bool pdfioFileClose(pdfio_file_t *pdf) _PDFIO_PUBLIC;
|
||||||
extern pdfio_file_t *pdfioFileCreate(const char *filename, const char *version, pdfio_rect_t *media_box, pdfio_rect_t *crop_box, pdfio_error_cb_t error_cb, void *error_data) _PDFIO_PUBLIC;
|
extern pdfio_file_t *pdfioFileCreate(const char *filename, const char *version, pdfio_rect_t *media_box, pdfio_rect_t *crop_box, pdfio_error_cb_t error_cb, void *error_data) _PDFIO_PUBLIC;
|
||||||
@@ -203,6 +201,7 @@ extern time_t pdfioFileGetCreationDate(pdfio_file_t *pdf) _PDFIO_PUBLIC;
|
|||||||
extern const char *pdfioFileGetCreator(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 pdfio_array_t *pdfioFileGetID(pdfio_file_t *pdf) _PDFIO_PUBLIC;
|
||||||
extern const char *pdfioFileGetKeywords(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 time_t pdfioFileGetModificationDate(pdfio_file_t *pdf) _PDFIO_PUBLIC;
|
||||||
extern const char *pdfioFileGetName(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;
|
extern size_t pdfioFileGetNumObjs(pdfio_file_t *pdf) _PDFIO_PUBLIC;
|
||||||
@@ -219,6 +218,7 @@ 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 pdfioFileSetCreationDate(pdfio_file_t *pdf, time_t value) _PDFIO_PUBLIC;
|
||||||
extern void pdfioFileSetCreator(pdfio_file_t *pdf, const char *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 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 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 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;
|
extern void pdfioFileSetSubject(pdfio_file_t *pdf, const char *value) _PDFIO_PUBLIC;
|
||||||
@@ -245,14 +245,14 @@ extern bool pdfioStreamClose(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
|||||||
extern bool pdfioStreamConsume(pdfio_stream_t *st, size_t bytes) _PDFIO_PUBLIC;
|
extern bool pdfioStreamConsume(pdfio_stream_t *st, size_t bytes) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioStreamGetToken(pdfio_stream_t *st, char *buffer, size_t bufsize) _PDFIO_PUBLIC;
|
extern bool pdfioStreamGetToken(pdfio_stream_t *st, char *buffer, size_t bufsize) _PDFIO_PUBLIC;
|
||||||
extern ssize_t pdfioStreamPeek(pdfio_stream_t *st, void *buffer, size_t bytes) _PDFIO_PUBLIC;
|
extern ssize_t pdfioStreamPeek(pdfio_stream_t *st, void *buffer, size_t bytes) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioStreamPrintf(pdfio_stream_t *st, const char *format, ...) _PDFIO_PUBLIC _PDFIO_FORMAT(2,3);
|
extern bool pdfioStreamPrintf(pdfio_stream_t *st, const char *format, ...) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioStreamPutChar(pdfio_stream_t *st, int ch) _PDFIO_PUBLIC;
|
extern bool pdfioStreamPutChar(pdfio_stream_t *st, int ch) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioStreamPuts(pdfio_stream_t *st, const char *s) _PDFIO_PUBLIC;
|
extern bool pdfioStreamPuts(pdfio_stream_t *st, const char *s) _PDFIO_PUBLIC;
|
||||||
extern ssize_t pdfioStreamRead(pdfio_stream_t *st, void *buffer, size_t bytes) _PDFIO_PUBLIC;
|
extern ssize_t pdfioStreamRead(pdfio_stream_t *st, void *buffer, size_t bytes) _PDFIO_PUBLIC;
|
||||||
extern bool pdfioStreamWrite(pdfio_stream_t *st, const void *buffer, size_t bytes) _PDFIO_PUBLIC;
|
extern bool pdfioStreamWrite(pdfio_stream_t *st, const void *buffer, size_t bytes) _PDFIO_PUBLIC;
|
||||||
|
|
||||||
extern char *pdfioStringCreate(pdfio_file_t *pdf, const char *s) _PDFIO_PUBLIC;
|
extern char *pdfioStringCreate(pdfio_file_t *pdf, const char *s) _PDFIO_PUBLIC;
|
||||||
extern char *pdfioStringCreatef(pdfio_file_t *pdf, const char *format, ...) _PDFIO_FORMAT(2,3) _PDFIO_PUBLIC;
|
extern char *pdfioStringCreatef(pdfio_file_t *pdf, const char *format, ...) _PDFIO_PUBLIC;
|
||||||
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ Cflags: @PKGCONFIG_CFLAGS@
|
|||||||
Libs: @PKGCONFIG_LIBS@
|
Libs: @PKGCONFIG_LIBS@
|
||||||
Libs.private: @PKGCONFIG_LIBS_PRIVATE@
|
Libs.private: @PKGCONFIG_LIBS_PRIVATE@
|
||||||
Requires: @PKGCONFIG_REQUIRES@
|
Requires: @PKGCONFIG_REQUIRES@
|
||||||
|
Requires.private: @PKGCONFIG_REQUIRES_PRIVATE@
|
||||||
|
|||||||
@@ -261,7 +261,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
LastUpgradeCheck = 1600;
|
LastUpgradeCheck = 2600;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
273440AF263D6FE200FBFD63 = {
|
273440AF263D6FE200FBFD63 = {
|
||||||
CreatedOnToolsVersion = 12.5;
|
CreatedOnToolsVersion = 12.5;
|
||||||
@@ -353,12 +353,14 @@
|
|||||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
CLANG_WARN_COMMA = YES;
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
|
||||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
@@ -377,7 +379,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1.1.2;
|
CURRENT_PROJECT_VERSION = 1.6.1;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
@@ -388,10 +390,16 @@
|
|||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
|
"HAVE_LIBPNG=1",
|
||||||
|
"HAVE_TM_GMTOFF=1",
|
||||||
|
"HAVE_TIMEGM=1",
|
||||||
);
|
);
|
||||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
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_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||||
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||||
@@ -399,16 +407,29 @@
|
|||||||
GCC_WARN_SIGN_COMPARE = YES;
|
GCC_WARN_SIGN_COMPARE = YES;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_LABEL = YES;
|
GCC_WARN_UNUSED_LABEL = YES;
|
||||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
/usr/local/include,
|
||||||
|
/opt/local/include,
|
||||||
|
/opt/homebrew/include,
|
||||||
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
ONLY_ACTIVE_ARCH = 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;
|
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -432,12 +453,14 @@
|
|||||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
CLANG_WARN_COMMA = YES;
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
|
||||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
@@ -456,7 +479,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1.1.2;
|
CURRENT_PROJECT_VERSION = 1.6.1;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -465,10 +488,17 @@
|
|||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"HAVE_LIBPNG=1",
|
||||||
|
"HAVE_TM_GMTOFF=1",
|
||||||
|
"HAVE_TIMEGM=1",
|
||||||
|
);
|
||||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
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_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
|
||||||
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||||
@@ -476,15 +506,28 @@
|
|||||||
GCC_WARN_SIGN_COMPARE = YES;
|
GCC_WARN_SIGN_COMPARE = YES;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_LABEL = YES;
|
GCC_WARN_UNUSED_LABEL = YES;
|
||||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
/usr/local/include,
|
||||||
|
/opt/local/include,
|
||||||
|
/opt/homebrew/include,
|
||||||
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
|
OTHER_LDFLAGS = (
|
||||||
|
"-L/usr/local/lib",
|
||||||
|
"-L/opt/local/lib",
|
||||||
|
"-L/opt/homebrew/lib",
|
||||||
|
"-lpng16",
|
||||||
|
);
|
||||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
70
pdfio1.def
70
pdfio1.def
@@ -1,9 +1,23 @@
|
|||||||
LIBRARY pdfio1
|
LIBRARY pdfio1
|
||||||
VERSION 1.5
|
VERSION 1.6
|
||||||
EXPORTS
|
EXPORTS
|
||||||
|
_pdfio_strlcpy
|
||||||
|
_pdfio_strtod
|
||||||
|
_pdfio_utf16cpy
|
||||||
|
_pdfio_vsnprintf
|
||||||
|
_pdfioArrayDebug
|
||||||
|
_pdfioArrayDecrypt
|
||||||
|
_pdfioArrayDelete
|
||||||
|
_pdfioArrayGetValue
|
||||||
|
_pdfioArrayRead
|
||||||
|
_pdfioArrayWrite
|
||||||
_pdfioCryptoAESDecrypt
|
_pdfioCryptoAESDecrypt
|
||||||
_pdfioCryptoAESEncrypt
|
_pdfioCryptoAESEncrypt
|
||||||
_pdfioCryptoAESInit
|
_pdfioCryptoAESInit
|
||||||
|
_pdfioCryptoLock
|
||||||
|
_pdfioCryptoMakeRandom
|
||||||
|
_pdfioCryptoMakeReader
|
||||||
|
_pdfioCryptoMakeWriter
|
||||||
_pdfioCryptoMD5Append
|
_pdfioCryptoMD5Append
|
||||||
_pdfioCryptoMD5Finish
|
_pdfioCryptoMD5Finish
|
||||||
_pdfioCryptoMD5Init
|
_pdfioCryptoMD5Init
|
||||||
@@ -12,9 +26,53 @@ _pdfioCryptoRC4Init
|
|||||||
_pdfioCryptoSHA256Append
|
_pdfioCryptoSHA256Append
|
||||||
_pdfioCryptoSHA256Finish
|
_pdfioCryptoSHA256Finish
|
||||||
_pdfioCryptoSHA256Init
|
_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
|
_pdfioTokenInit
|
||||||
|
_pdfioTokenPush
|
||||||
|
_pdfioTokenRead
|
||||||
|
_pdfioValueCopy
|
||||||
_pdfioValueDebug
|
_pdfioValueDebug
|
||||||
|
_pdfioValueDecrypt
|
||||||
|
_pdfioValueDelete
|
||||||
_pdfioValueRead
|
_pdfioValueRead
|
||||||
|
_pdfioValueWrite
|
||||||
pdfioArrayAppendArray
|
pdfioArrayAppendArray
|
||||||
pdfioArrayAppendBinary
|
pdfioArrayAppendBinary
|
||||||
pdfioArrayAppendBoolean
|
pdfioArrayAppendBoolean
|
||||||
@@ -43,8 +101,10 @@ pdfioArrayGetSize
|
|||||||
pdfioArrayGetString
|
pdfioArrayGetString
|
||||||
pdfioArrayGetType
|
pdfioArrayGetType
|
||||||
pdfioArrayRemove
|
pdfioArrayRemove
|
||||||
|
pdfioContentBeginMarked
|
||||||
pdfioContentClip
|
pdfioContentClip
|
||||||
pdfioContentDrawImage
|
pdfioContentDrawImage
|
||||||
|
pdfioContentEndMarked
|
||||||
pdfioContentFill
|
pdfioContentFill
|
||||||
pdfioContentFillAndStroke
|
pdfioContentFillAndStroke
|
||||||
pdfioContentMatrixConcat
|
pdfioContentMatrixConcat
|
||||||
@@ -98,8 +158,8 @@ pdfioContentTextNewLineShow
|
|||||||
pdfioContentTextNewLineShowf
|
pdfioContentTextNewLineShowf
|
||||||
pdfioContentTextNextLine
|
pdfioContentTextNextLine
|
||||||
pdfioContentTextShow
|
pdfioContentTextShow
|
||||||
pdfioContentTextShowJustified
|
|
||||||
pdfioContentTextShowf
|
pdfioContentTextShowf
|
||||||
|
pdfioContentTextShowJustified
|
||||||
pdfioDictClear
|
pdfioDictClear
|
||||||
pdfioDictCopy
|
pdfioDictCopy
|
||||||
pdfioDictCreate
|
pdfioDictCreate
|
||||||
@@ -110,8 +170,8 @@ pdfioDictGetDate
|
|||||||
pdfioDictGetDict
|
pdfioDictGetDict
|
||||||
pdfioDictGetKey
|
pdfioDictGetKey
|
||||||
pdfioDictGetName
|
pdfioDictGetName
|
||||||
pdfioDictGetNumPairs
|
|
||||||
pdfioDictGetNumber
|
pdfioDictGetNumber
|
||||||
|
pdfioDictGetNumPairs
|
||||||
pdfioDictGetObj
|
pdfioDictGetObj
|
||||||
pdfioDictGetRect
|
pdfioDictGetRect
|
||||||
pdfioDictGetString
|
pdfioDictGetString
|
||||||
@@ -129,10 +189,12 @@ pdfioDictSetObj
|
|||||||
pdfioDictSetRect
|
pdfioDictSetRect
|
||||||
pdfioDictSetString
|
pdfioDictSetString
|
||||||
pdfioDictSetStringf
|
pdfioDictSetStringf
|
||||||
|
pdfioFileAddOutputIntent
|
||||||
pdfioFileClose
|
pdfioFileClose
|
||||||
pdfioFileCreate
|
pdfioFileCreate
|
||||||
pdfioFileCreateArrayObj
|
pdfioFileCreateArrayObj
|
||||||
pdfioFileCreateFontObjFromBase
|
pdfioFileCreateFontObjFromBase
|
||||||
|
pdfioFileCreateFontObjFromData
|
||||||
pdfioFileCreateFontObjFromFile
|
pdfioFileCreateFontObjFromFile
|
||||||
pdfioFileCreateICCObjFromData
|
pdfioFileCreateICCObjFromData
|
||||||
pdfioFileCreateICCObjFromFile
|
pdfioFileCreateICCObjFromFile
|
||||||
@@ -152,6 +214,7 @@ pdfioFileGetCreationDate
|
|||||||
pdfioFileGetCreator
|
pdfioFileGetCreator
|
||||||
pdfioFileGetID
|
pdfioFileGetID
|
||||||
pdfioFileGetKeywords
|
pdfioFileGetKeywords
|
||||||
|
pdfioFileGetLanguage
|
||||||
pdfioFileGetModificationDate
|
pdfioFileGetModificationDate
|
||||||
pdfioFileGetName
|
pdfioFileGetName
|
||||||
pdfioFileGetNumObjs
|
pdfioFileGetNumObjs
|
||||||
@@ -168,6 +231,7 @@ pdfioFileSetAuthor
|
|||||||
pdfioFileSetCreationDate
|
pdfioFileSetCreationDate
|
||||||
pdfioFileSetCreator
|
pdfioFileSetCreator
|
||||||
pdfioFileSetKeywords
|
pdfioFileSetKeywords
|
||||||
|
pdfioFileSetLanguage
|
||||||
pdfioFileSetModificationDate
|
pdfioFileSetModificationDate
|
||||||
pdfioFileSetPermissions
|
pdfioFileSetPermissions
|
||||||
pdfioFileSetSubject
|
pdfioFileSetSubject
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<metadata>
|
<metadata>
|
||||||
<id>pdfio_native</id>
|
<id>pdfio_native</id>
|
||||||
<title>PDFio Library for VS2019+</title>
|
<title>PDFio Library for VS2019+</title>
|
||||||
<version>1.5.0</version>
|
<version>1.6.1</version>
|
||||||
<authors>Michael R Sweet</authors>
|
<authors>Michael R Sweet</authors>
|
||||||
<owners>michaelrsweet</owners>
|
<owners>michaelrsweet</owners>
|
||||||
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
|
<copyright>Copyright © 2019-2025 by Michael R Sweet</copyright>
|
||||||
<tags>pdf file native</tags>
|
<tags>pdf file native</tags>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="pdfio_native.redist" version="1.5.0" />
|
<dependency id="pdfio_native.redist" version="1.6.1" />
|
||||||
<dependency id="libpng_native.redist" version="1.6.30" />
|
<dependency id="libpng_native.redist" version="1.6.30" />
|
||||||
<dependency id="zlib_native.redist" version="1.2.11" />
|
<dependency id="zlib_native.redist" version="1.2.11" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<metadata>
|
<metadata>
|
||||||
<id>pdfio_native.redist</id>
|
<id>pdfio_native.redist</id>
|
||||||
<title>PDFio Library for VS2019+</title>
|
<title>PDFio Library for VS2019+</title>
|
||||||
<version>1.5.0</version>
|
<version>1.6.1</version>
|
||||||
<authors>Michael R Sweet</authors>
|
<authors>Michael R Sweet</authors>
|
||||||
<owners>michaelrsweet</owners>
|
<owners>michaelrsweet</owners>
|
||||||
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
||||||
|
|||||||
30
test-corpus.sh
Executable file
30
test-corpus.sh
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/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
Normal file
282
test.h
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
BIN
testfiles/CGATS001Compat-v2-micro.icc
Normal file
BIN
testfiles/CGATS001Compat-v2-micro.icc
Normal file
Binary file not shown.
5
testfiles/CGATS001Compat-v2-micro.txt
Normal file
5
testfiles/CGATS001Compat-v2-micro.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
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.
|
||||||
BIN
testfiles/pdfio-rgba.png
Normal file
BIN
testfiles/pdfio-rgba.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
1840
testpdfio.c
1840
testpdfio.c
File diff suppressed because it is too large
Load Diff
93
testttf.c
93
testttf.c
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// https://github.com/michaelrsweet/ttf
|
// https://github.com/michaelrsweet/ttf
|
||||||
//
|
//
|
||||||
// Copyright © 2018-2024 by Michael R Sweet.
|
// Copyright © 2018-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -14,6 +14,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "ttf.h"
|
#include "ttf.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -81,9 +85,13 @@ test_font(const char *filename) // I - Font filename
|
|||||||
int i, // Looping var
|
int i, // Looping var
|
||||||
errors = 0; // Number of errors
|
errors = 0; // Number of errors
|
||||||
ttf_t *font; // Font
|
ttf_t *font; // Font
|
||||||
|
struct stat fileinfo; // Font file information
|
||||||
|
FILE *fp = NULL; // File pointer
|
||||||
|
void *data = NULL; // Memory buffer for font file
|
||||||
const char *value; // Font (string) value
|
const char *value; // Font (string) value
|
||||||
int intvalue; // Font (integer) value
|
int intvalue; // Font (integer) value
|
||||||
float realvalue; // Font (real) value
|
float realvalue; // Font (real) value
|
||||||
|
char psname[1024]; // Postscript font name
|
||||||
ttf_rect_t bounds; // Bounds
|
ttf_rect_t bounds; // Bounds
|
||||||
ttf_rect_t extents; // Extents
|
ttf_rect_t extents; // Extents
|
||||||
size_t num_fonts; // Number of fonts
|
size_t num_fonts; // Number of fonts
|
||||||
@@ -220,6 +228,9 @@ test_font(const char *filename) // I - Font filename
|
|||||||
if ((value = ttfGetPostScriptName(font)) != NULL)
|
if ((value = ttfGetPostScriptName(font)) != NULL)
|
||||||
{
|
{
|
||||||
printf("PASS (%s)\n", value);
|
printf("PASS (%s)\n", value);
|
||||||
|
|
||||||
|
strncpy(psname, value, sizeof(psname) - 1);
|
||||||
|
psname[sizeof(psname) - 1] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -300,6 +311,86 @@ test_font(const char *filename) // I - Font filename
|
|||||||
puts("PASS (false)");
|
puts("PASS (false)");
|
||||||
|
|
||||||
ttfDelete(font);
|
ttfDelete(font);
|
||||||
|
font = NULL;
|
||||||
|
|
||||||
|
// Now copy the font to memory and open it that way...
|
||||||
|
printf("fopen(\"%s\", \"rb\"): ", filename);
|
||||||
|
if ((fp = fopen(filename, "rb")) == NULL)
|
||||||
|
{
|
||||||
|
printf("FAIL (%s)\n", strerror(errno));
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("PASS (%d)\n", fileno(fp));
|
||||||
|
printf("fstat(%d): ", fileno(fp));
|
||||||
|
if (fstat(fileno(fp), &fileinfo))
|
||||||
|
{
|
||||||
|
printf("FAIL (%s)\n", strerror(errno));
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("PASS (%lu bytes)\n", (unsigned long)fileinfo.st_size);
|
||||||
|
|
||||||
|
fputs("malloc(): ", stdout);
|
||||||
|
if ((data = malloc((size_t)fileinfo.st_size)) == NULL)
|
||||||
|
{
|
||||||
|
printf("FAIL (%s)\n", strerror(errno));
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
fputs("fread(): ", stdout);
|
||||||
|
if (fread(data, (size_t)fileinfo.st_size, 1, fp) != 1)
|
||||||
|
{
|
||||||
|
printf("FAIL (%s)\n", strerror(errno));
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
fputs("ttfCreateData(): ", stdout);
|
||||||
|
if ((font = ttfCreateData(data, (size_t)fileinfo.st_size, /*idx*/0, error_cb, /*err_data*/NULL)) == NULL)
|
||||||
|
{
|
||||||
|
puts("FAIL");
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
|
||||||
|
fputs("ttfGetPostScriptName: ", stdout);
|
||||||
|
if ((value = ttfGetPostScriptName(font)) != NULL)
|
||||||
|
{
|
||||||
|
if (!strcmp(value, psname))
|
||||||
|
{
|
||||||
|
printf("PASS (%s)\n", value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("FAIL (got \"%s\", expected \"%s\")\n", value, psname);
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL");
|
||||||
|
errors ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
ttfDelete(font);
|
||||||
|
}
|
||||||
|
|
||||||
return (errors);
|
return (errors);
|
||||||
}
|
}
|
||||||
|
|||||||
590
ttf.c
590
ttf.c
@@ -10,7 +10,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define _CRT_SECURE_NO_WARNINGS
|
# define _CRT_SECURE_NO_WARNINGS 1
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
#include "ttf.h"
|
#include "ttf.h"
|
||||||
@@ -38,16 +38,16 @@
|
|||||||
# define access _access
|
# define access _access
|
||||||
# define close _close
|
# define close _close
|
||||||
# define fileno _fileno
|
# define fileno _fileno
|
||||||
# define lseek _lseek
|
# define lseek(f,o,w) (off_t)_lseek((f),(long)(o),(w))
|
||||||
# define mkdir(d,p) _mkdir(d)
|
# define mkdir(d,p) _mkdir(d)
|
||||||
# define open _open
|
# define open _open
|
||||||
# define read _read
|
# define read(f,b,s) _read((f),(b),(unsigned)(s))
|
||||||
# define rmdir _rmdir
|
# define rmdir _rmdir
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
# define strdup _strdup
|
# define strdup _strdup
|
||||||
# define unlink _unlink
|
# define unlink _unlink
|
||||||
# define vsnprintf _vsnprintf
|
# define vsnprintf _vsnprintf
|
||||||
# define write _write
|
# define write(f,b,s) _write((f),(b),(unsigned)(s))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Map various parameters for POSIX...
|
// Map various parameters for POSIX...
|
||||||
@@ -177,9 +177,19 @@ typedef struct _ttf_off_names_s // OFF/TTF naming table
|
|||||||
unsigned storage_size; // Size of storage area
|
unsigned storage_size; // Size of storage area
|
||||||
} _ttf_off_names_t;
|
} _ttf_off_names_t;
|
||||||
|
|
||||||
|
typedef size_t (*_ttf_read_cb_t)(ttf_t *font, void *buffer, size_t bytes);
|
||||||
|
// Font read callback, returns number of bytes read
|
||||||
|
typedef bool (*_ttf_seek_cb_t)(ttf_t *font, size_t offset);
|
||||||
|
// Font seek callback, returns `true` on success
|
||||||
|
|
||||||
struct _ttf_s
|
struct _ttf_s
|
||||||
{
|
{
|
||||||
int fd; // File descriptor
|
_ttf_read_cb_t read_cb; // Read callback
|
||||||
|
_ttf_seek_cb_t seek_cb; // Seek callback
|
||||||
|
int file_fd; // File descriptor for ttfCreate
|
||||||
|
const char *data; // Font data for ttfCreateData
|
||||||
|
size_t data_size; // Size of font data for ttfCreateData
|
||||||
|
size_t data_offset; // Offset within input
|
||||||
size_t idx; // Font number in file
|
size_t idx; // Font number in file
|
||||||
ttf_err_cb_t err_cb; // Error callback, if any
|
ttf_err_cb_t err_cb; // Error callback, if any
|
||||||
void *err_data; // Error callback data
|
void *err_data; // Error callback data
|
||||||
@@ -245,10 +255,10 @@ typedef struct _ttf_off_head_s // Font header
|
|||||||
} _ttf_off_head_t;
|
} _ttf_off_head_t;
|
||||||
|
|
||||||
#define TTF_OFF_macStyle_Bold 0x01
|
#define TTF_OFF_macStyle_Bold 0x01
|
||||||
#define TTF_OFF_macStyle_Italic 0x02
|
#define TTF_OFF_macStyle_Italic 0x02
|
||||||
#define TTF_OFF_macStyle_Underline 0x04
|
#define TTF_OFF_macStyle_Underline 0x04
|
||||||
#define TTF_OFF_macStyle_Outline 0x08
|
#define TTF_OFF_macStyle_Outline 0x08
|
||||||
#define TTF_OFF_macStyle_Shadow 0x10
|
#define TTF_OFF_macStyle_Shadow 0x10
|
||||||
#define TTF_OFF_macStyle_Condensed 0x20
|
#define TTF_OFF_macStyle_Condensed 0x20
|
||||||
#define TTF_OFF_macStyle_Extended 0x40
|
#define TTF_OFF_macStyle_Extended 0x40
|
||||||
|
|
||||||
@@ -282,7 +292,12 @@ typedef struct _ttf_off_post_s // PostScript information
|
|||||||
//
|
//
|
||||||
|
|
||||||
static char *copy_name(ttf_t *font, unsigned name_id);
|
static char *copy_name(ttf_t *font, unsigned name_id);
|
||||||
|
static ttf_t *create_font(const char *filename, const void *data, size_t datasize, size_t idx, ttf_err_cb_t err_cb, void *err_data);
|
||||||
static void errorf(ttf_t *font, const char *message, ...) TTF_FORMAT_ARGS(2,3);
|
static void errorf(ttf_t *font, const char *message, ...) TTF_FORMAT_ARGS(2,3);
|
||||||
|
static size_t fd_read_cb(ttf_t *font, void *buffer, size_t bytes);
|
||||||
|
static bool fd_seek_cb(ttf_t *font, size_t offset);
|
||||||
|
static size_t mem_read_cb(ttf_t *font, void *buffer, size_t bytes);
|
||||||
|
static bool mem_seek_cb(ttf_t *font, size_t offset);
|
||||||
static bool read_cmap(ttf_t *font);
|
static bool read_cmap(ttf_t *font);
|
||||||
static bool read_head(ttf_t *font, _ttf_off_head_t *head);
|
static bool read_head(ttf_t *font, _ttf_off_head_t *head);
|
||||||
static bool read_hhea(ttf_t *font, _ttf_off_hhea_t *hhea);
|
static bool read_hhea(ttf_t *font, _ttf_off_hhea_t *hhea);
|
||||||
@@ -329,16 +344,7 @@ ttfCreate(const char *filename, // I - Filename
|
|||||||
ttf_err_cb_t err_cb, // I - Error callback or `NULL` to log to stderr
|
ttf_err_cb_t err_cb, // I - Error callback or `NULL` to log to stderr
|
||||||
void *err_data) // I - Error callback data
|
void *err_data) // I - Error callback data
|
||||||
{
|
{
|
||||||
ttf_t *font = NULL; // New font object
|
TTF_DEBUG("ttfCreate(filename=\"%s\", idx=%u, err_cb=%p, err_data=%p)\n", filename, (unsigned)idx, (void *)err_cb, err_data);
|
||||||
size_t i; // Looping var
|
|
||||||
_ttf_metric_t *widths = NULL; // Glyph metrics
|
|
||||||
_ttf_off_head_t head; // head table
|
|
||||||
_ttf_off_hhea_t hhea; // hhea table
|
|
||||||
_ttf_off_os_2_t os_2; // OS/2 table
|
|
||||||
_ttf_off_post_t post; // PostScript table
|
|
||||||
|
|
||||||
|
|
||||||
TTF_DEBUG("ttfCreate(filename=\"%s\", idx=%u, err_cb=%p, err_data=%p)\n", filename, (unsigned)idx, err_cb, err_data);
|
|
||||||
|
|
||||||
// Range check input..
|
// Range check input..
|
||||||
if (!filename)
|
if (!filename)
|
||||||
@@ -347,178 +353,57 @@ ttfCreate(const char *filename, // I - Filename
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory...
|
// Open and return the font...
|
||||||
if ((font = (ttf_t *)calloc(1, sizeof(ttf_t))) == NULL)
|
return (create_font(filename, /*data*/NULL, /*datasize*/0, idx, err_cb, err_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'ttfCreateData()' - Create a new font object from a memory buffer.
|
||||||
|
//
|
||||||
|
// This function creates a new font object from a memory buffer. The "data"
|
||||||
|
// argument specifies a pointer to the first byte of data and the "datasize"
|
||||||
|
// argument specifies the length of the memory buffer in bytes.
|
||||||
|
//
|
||||||
|
// > Note: The caller is responsible for ensuring that the memory buffer is
|
||||||
|
// > available until the font object is deleted with @link ttfDelete@.
|
||||||
|
//
|
||||||
|
// The "idx" argument specifies the font to load from a collection - the first
|
||||||
|
// font is number `0`. Once created, you can call the @link ttfGetNumFonts@
|
||||||
|
// function to determine whether the loaded font file is a collection with more
|
||||||
|
// than one font.
|
||||||
|
//
|
||||||
|
// The "err_cb" and "err_data" arguments specify a callback function and data
|
||||||
|
// pointer for receiving error messages. If `NULL`, errors are sent to the
|
||||||
|
// `stderr` file. The callback function receives the data pointer and a text
|
||||||
|
// message string, for example:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// void my_err_cb(void *err_data, const char *message)
|
||||||
|
// {
|
||||||
|
// fprintf(stderr, "ERROR: %s\n", message);
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
|
||||||
|
ttf_t * // O - New font object
|
||||||
|
ttfCreateData(const void *data, // I - Buffer
|
||||||
|
size_t datasize, // I - Size of buffer in bytes
|
||||||
|
size_t idx, // I - Font number to create in collection (0-based)
|
||||||
|
ttf_err_cb_t err_cb, // I - Error callback or `NULL` to log to stderr
|
||||||
|
void *err_data) // I - Error callback data
|
||||||
|
{
|
||||||
|
TTF_DEBUG("ttfCreateData(data=%p, datasize=%lu, idx=%u, err_cb=%p, err_data=%p)\n", data, (unsigned long)datasize, (unsigned)idx, (void *)err_cb, err_data);
|
||||||
|
|
||||||
|
// Range check input..
|
||||||
|
if (!data || datasize == 0)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
font->idx = idx;
|
|
||||||
font->err_cb = err_cb;
|
|
||||||
font->err_data = err_data;
|
|
||||||
|
|
||||||
// Open the font file...
|
|
||||||
if ((font->fd = open(filename, O_RDONLY | O_BINARY)) < 0)
|
|
||||||
{
|
|
||||||
errorf(font, "Unable to open '%s': %s", filename, strerror(errno));
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TTF_DEBUG("ttfCreate: fd=%d\n", font->fd);
|
// Open and return the font...
|
||||||
|
return (create_font(/*filename*/NULL, data, datasize, idx, err_cb, err_data));
|
||||||
// Read the table of contents and the identifying names...
|
|
||||||
if (!read_table(font))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
TTF_DEBUG("ttfCreate: num_entries=%d\n", font->table.num_entries);
|
|
||||||
|
|
||||||
if (!read_names(font))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
TTF_DEBUG("ttfCreate: num_names=%d\n", font->names.num_names);
|
|
||||||
|
|
||||||
// Copy key font meta data strings...
|
|
||||||
font->copyright = copy_name(font, TTF_OFF_Copyright);
|
|
||||||
font->family = copy_name(font, TTF_OFF_FontFamily);
|
|
||||||
font->postscript_name = copy_name(font, TTF_OFF_PostScriptName);
|
|
||||||
font->version = copy_name(font, TTF_OFF_FontVersion);
|
|
||||||
|
|
||||||
if (read_post(font, &post))
|
|
||||||
{
|
|
||||||
font->italic_angle = post.italicAngle;
|
|
||||||
font->is_fixed = post.isFixedPitch != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TTF_DEBUG("ttfCreate: copyright=\"%s\"\n", font->copyright);
|
|
||||||
TTF_DEBUG("ttfCreate: family=\"%s\"\n", font->family);
|
|
||||||
TTF_DEBUG("ttfCreate: postscript_name=\"%s\"\n", font->postscript_name);
|
|
||||||
TTF_DEBUG("ttfCreate: version=\"%s\"\n", font->version);
|
|
||||||
TTF_DEBUG("ttfCreate: italic_angle=%g\n", font->italic_angle);
|
|
||||||
TTF_DEBUG("ttfCreate: is_fixed=%s\n", font->is_fixed ? "true" : "false");
|
|
||||||
|
|
||||||
if (!read_cmap(font))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!read_head(font, &head))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
font->units = (float)head.unitsPerEm;
|
|
||||||
font->x_max = head.xMax;
|
|
||||||
font->x_min = head.xMin;
|
|
||||||
font->y_max = head.yMax;
|
|
||||||
font->y_min = head.yMin;
|
|
||||||
|
|
||||||
if (head.macStyle & TTF_OFF_macStyle_Italic)
|
|
||||||
{
|
|
||||||
if (font->postscript_name && strstr(font->postscript_name, "Oblique"))
|
|
||||||
font->style = TTF_STYLE_OBLIQUE;
|
|
||||||
else
|
|
||||||
font->style = TTF_STYLE_ITALIC;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
font->style = TTF_STYLE_NORMAL;
|
|
||||||
|
|
||||||
if (!read_hhea(font, &hhea))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
font->ascent = hhea.ascender;
|
|
||||||
font->descent = hhea.descender;
|
|
||||||
|
|
||||||
if (read_maxp(font) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (hhea.numberOfHMetrics > 0)
|
|
||||||
{
|
|
||||||
if ((widths = read_hmtx(font, &hhea)) == NULL)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errorf(font, "Number of horizontal metrics is 0.");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read_os_2(font, &os_2))
|
|
||||||
{
|
|
||||||
// Copy key values from OS/2 table...
|
|
||||||
static const ttf_stretch_t stretches[] =
|
|
||||||
{
|
|
||||||
TTF_STRETCH_ULTRA_CONDENSED, // ultra-condensed
|
|
||||||
TTF_STRETCH_EXTRA_CONDENSED, // extra-condensed
|
|
||||||
TTF_STRETCH_CONDENSED, // condensed
|
|
||||||
TTF_STRETCH_SEMI_CONDENSED, // semi-condensed
|
|
||||||
TTF_STRETCH_NORMAL, // normal
|
|
||||||
TTF_STRETCH_SEMI_EXPANDED, // semi-expanded
|
|
||||||
TTF_STRETCH_EXPANDED, // expanded
|
|
||||||
TTF_STRETCH_EXTRA_EXPANDED, // extra-expanded
|
|
||||||
TTF_STRETCH_ULTRA_EXPANDED // ultra-expanded
|
|
||||||
};
|
|
||||||
|
|
||||||
if (os_2.usWidthClass >= 1 && os_2.usWidthClass <= (int)(sizeof(stretches) / sizeof(stretches[0])))
|
|
||||||
font->stretch = stretches[os_2.usWidthClass - 1];
|
|
||||||
|
|
||||||
font->weight = (short)os_2.usWeightClass;
|
|
||||||
font->cap_height = os_2.sCapHeight;
|
|
||||||
font->x_height = os_2.sxHeight;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Default key values since there isn't an OS/2 table...
|
|
||||||
TTF_DEBUG("ttfCreate: Unable to read OS/2 table.\n");
|
|
||||||
|
|
||||||
font->weight = 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (font->cap_height == 0)
|
|
||||||
font->cap_height = font->ascent;
|
|
||||||
|
|
||||||
if (font->x_height == 0)
|
|
||||||
font->x_height = 3 * font->ascent / 5;
|
|
||||||
|
|
||||||
// Build a sparse glyph widths table...
|
|
||||||
font->min_char = -1;
|
|
||||||
|
|
||||||
for (i = 0; i < font->num_cmap; i ++)
|
|
||||||
{
|
|
||||||
if (font->cmap[i] >= 0)
|
|
||||||
{
|
|
||||||
int bin = (int)i / 256, // Sub-array bin
|
|
||||||
glyph = font->cmap[i]; // Glyph index
|
|
||||||
|
|
||||||
// Update min/max...
|
|
||||||
if (font->min_char < 0)
|
|
||||||
font->min_char = (int)i;
|
|
||||||
|
|
||||||
font->max_char = (int)i;
|
|
||||||
|
|
||||||
// Allocate a sub-array as needed...
|
|
||||||
if (!font->widths[bin])
|
|
||||||
font->widths[bin] = (_ttf_metric_t *)calloc(256, sizeof(_ttf_metric_t));
|
|
||||||
|
|
||||||
// Copy the width of the specified glyph or the last one if we are past
|
|
||||||
// the end of the table...
|
|
||||||
if (glyph >= hhea.numberOfHMetrics)
|
|
||||||
font->widths[bin][i & 255] = widths[hhea.numberOfHMetrics - 1];
|
|
||||||
else
|
|
||||||
font->widths[bin][i & 255] = widths[glyph];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (i >= ' ' && i < 127 && font->widths[0])
|
|
||||||
TTF_DEBUG("ttfCreate: width['%c']=%d(%d)\n", (char)i, font->widths[0][i].width, font->widths[0][i].left_bearing);
|
|
||||||
#endif // DEBUG
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup and return the font...
|
|
||||||
free(widths);
|
|
||||||
|
|
||||||
return (font);
|
|
||||||
|
|
||||||
// If we get here something bad happened...
|
|
||||||
error:
|
|
||||||
|
|
||||||
free(widths);
|
|
||||||
ttfDelete(font);
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -537,8 +422,8 @@ ttfDelete(ttf_t *font) // I - Font
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Close the font file...
|
// Close the font file...
|
||||||
if (font->fd >= 0)
|
if (font->file_fd >= 0)
|
||||||
close(font->fd);
|
close(font->file_fd);
|
||||||
|
|
||||||
// Free all memory used...
|
// Free all memory used...
|
||||||
free(font->copyright);
|
free(font->copyright);
|
||||||
@@ -723,7 +608,7 @@ ttfGetExtents(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find its width...
|
// Find its width...
|
||||||
if ((widths = font->widths[ch / 256]) != NULL)
|
if (ch < TTF_FONT_MAX_CHAR && (widths = font->widths[ch / 256]) != NULL)
|
||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
@@ -1043,6 +928,219 @@ copy_name(ttf_t *font, // I - Font
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'create_font()' - Create a font object from the file or data.
|
||||||
|
//
|
||||||
|
|
||||||
|
static ttf_t *
|
||||||
|
create_font(const char *filename, // I - Filename of `NULL`
|
||||||
|
const void *data, // I - Data pointer or `NULL`
|
||||||
|
size_t datasize, // I - Size of data or 0
|
||||||
|
size_t idx, // I - Font index
|
||||||
|
ttf_err_cb_t err_cb, // I - Error callback function
|
||||||
|
void *err_data) // I - Error callback data
|
||||||
|
{
|
||||||
|
ttf_t *font = NULL; // New font object
|
||||||
|
size_t i; // Looping var
|
||||||
|
_ttf_metric_t *widths = NULL; // Glyph metrics
|
||||||
|
_ttf_off_head_t head; // head table
|
||||||
|
_ttf_off_hhea_t hhea; // hhea table
|
||||||
|
_ttf_off_os_2_t os_2; // OS/2 table
|
||||||
|
_ttf_off_post_t post; // PostScript table
|
||||||
|
|
||||||
|
|
||||||
|
TTF_DEBUG("create_font(filename=\"%s\", data=%p, datasize=%lu, idx=%u, err_cb=%p, err_data=%p)\n", filename, data, (unsigned long)datasize, (unsigned)idx, (void *)err_cb, err_data);
|
||||||
|
|
||||||
|
// Allocate memory...
|
||||||
|
if ((font = (ttf_t *)calloc(1, sizeof(ttf_t))) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
font->idx = idx;
|
||||||
|
font->err_cb = err_cb;
|
||||||
|
font->err_data = err_data;
|
||||||
|
|
||||||
|
if (filename)
|
||||||
|
{
|
||||||
|
// Open the font file...
|
||||||
|
if ((font->file_fd = open(filename, O_RDONLY | O_BINARY)) < 0)
|
||||||
|
{
|
||||||
|
errorf(font, "Unable to open '%s': %s", filename, strerror(errno));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
TTF_DEBUG("create_font: file_fd=%d\n", font->file_fd);
|
||||||
|
|
||||||
|
font->read_cb = fd_read_cb;
|
||||||
|
font->seek_cb = fd_seek_cb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Read from memory...
|
||||||
|
font->file_fd = -1;
|
||||||
|
font->data = (const char *)data;
|
||||||
|
font->data_size = datasize;
|
||||||
|
font->read_cb = mem_read_cb;
|
||||||
|
font->seek_cb = mem_seek_cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the table of contents and the identifying names...
|
||||||
|
if (!read_table(font))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
TTF_DEBUG("create_font: num_entries=%d\n", font->table.num_entries);
|
||||||
|
|
||||||
|
if (!read_names(font))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
TTF_DEBUG("create_font: num_names=%d\n", font->names.num_names);
|
||||||
|
|
||||||
|
// Copy key font meta data strings...
|
||||||
|
font->copyright = copy_name(font, TTF_OFF_Copyright);
|
||||||
|
font->family = copy_name(font, TTF_OFF_FontFamily);
|
||||||
|
font->postscript_name = copy_name(font, TTF_OFF_PostScriptName);
|
||||||
|
font->version = copy_name(font, TTF_OFF_FontVersion);
|
||||||
|
|
||||||
|
if (read_post(font, &post))
|
||||||
|
{
|
||||||
|
font->italic_angle = post.italicAngle;
|
||||||
|
font->is_fixed = post.isFixedPitch != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TTF_DEBUG("create_font: copyright=\"%s\"\n", font->copyright);
|
||||||
|
TTF_DEBUG("create_font: family=\"%s\"\n", font->family);
|
||||||
|
TTF_DEBUG("create_font: postscript_name=\"%s\"\n", font->postscript_name);
|
||||||
|
TTF_DEBUG("create_font: version=\"%s\"\n", font->version);
|
||||||
|
TTF_DEBUG("create_font: italic_angle=%g\n", font->italic_angle);
|
||||||
|
TTF_DEBUG("create_font: is_fixed=%s\n", font->is_fixed ? "true" : "false");
|
||||||
|
|
||||||
|
if (!read_cmap(font))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!read_head(font, &head))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
font->units = (float)head.unitsPerEm;
|
||||||
|
font->x_max = head.xMax;
|
||||||
|
font->x_min = head.xMin;
|
||||||
|
font->y_max = head.yMax;
|
||||||
|
font->y_min = head.yMin;
|
||||||
|
|
||||||
|
if (head.macStyle & TTF_OFF_macStyle_Italic)
|
||||||
|
{
|
||||||
|
if (font->postscript_name && strstr(font->postscript_name, "Oblique"))
|
||||||
|
font->style = TTF_STYLE_OBLIQUE;
|
||||||
|
else
|
||||||
|
font->style = TTF_STYLE_ITALIC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
font->style = TTF_STYLE_NORMAL;
|
||||||
|
|
||||||
|
if (!read_hhea(font, &hhea))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
font->ascent = hhea.ascender;
|
||||||
|
font->descent = hhea.descender;
|
||||||
|
|
||||||
|
if (read_maxp(font) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (hhea.numberOfHMetrics > 0)
|
||||||
|
{
|
||||||
|
if ((widths = read_hmtx(font, &hhea)) == NULL)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorf(font, "Number of horizontal metrics is 0.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_os_2(font, &os_2))
|
||||||
|
{
|
||||||
|
// Copy key values from OS/2 table...
|
||||||
|
static const ttf_stretch_t stretches[] =
|
||||||
|
{
|
||||||
|
TTF_STRETCH_ULTRA_CONDENSED, // ultra-condensed
|
||||||
|
TTF_STRETCH_EXTRA_CONDENSED, // extra-condensed
|
||||||
|
TTF_STRETCH_CONDENSED, // condensed
|
||||||
|
TTF_STRETCH_SEMI_CONDENSED, // semi-condensed
|
||||||
|
TTF_STRETCH_NORMAL, // normal
|
||||||
|
TTF_STRETCH_SEMI_EXPANDED, // semi-expanded
|
||||||
|
TTF_STRETCH_EXPANDED, // expanded
|
||||||
|
TTF_STRETCH_EXTRA_EXPANDED, // extra-expanded
|
||||||
|
TTF_STRETCH_ULTRA_EXPANDED // ultra-expanded
|
||||||
|
};
|
||||||
|
|
||||||
|
if (os_2.usWidthClass >= 1 && os_2.usWidthClass <= (int)(sizeof(stretches) / sizeof(stretches[0])))
|
||||||
|
font->stretch = stretches[os_2.usWidthClass - 1];
|
||||||
|
|
||||||
|
font->weight = (short)os_2.usWeightClass;
|
||||||
|
font->cap_height = os_2.sCapHeight;
|
||||||
|
font->x_height = os_2.sxHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default key values since there isn't an OS/2 table...
|
||||||
|
TTF_DEBUG("create_font: Unable to read OS/2 table.\n");
|
||||||
|
|
||||||
|
font->weight = 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font->cap_height == 0)
|
||||||
|
font->cap_height = font->ascent;
|
||||||
|
|
||||||
|
if (font->x_height == 0)
|
||||||
|
font->x_height = 3 * font->ascent / 5;
|
||||||
|
|
||||||
|
// Build a sparse glyph widths table...
|
||||||
|
font->min_char = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < font->num_cmap; i ++)
|
||||||
|
{
|
||||||
|
if (font->cmap[i] >= 0)
|
||||||
|
{
|
||||||
|
int bin = (int)i / 256, // Sub-array bin
|
||||||
|
glyph = font->cmap[i]; // Glyph index
|
||||||
|
|
||||||
|
// Update min/max...
|
||||||
|
if (font->min_char < 0)
|
||||||
|
font->min_char = (int)i;
|
||||||
|
|
||||||
|
font->max_char = (int)i;
|
||||||
|
|
||||||
|
// Allocate a sub-array as needed...
|
||||||
|
if (!font->widths[bin])
|
||||||
|
font->widths[bin] = (_ttf_metric_t *)calloc(256, sizeof(_ttf_metric_t));
|
||||||
|
|
||||||
|
// Copy the width of the specified glyph or the last one if we are past
|
||||||
|
// the end of the table...
|
||||||
|
if (glyph >= hhea.numberOfHMetrics)
|
||||||
|
font->widths[bin][i & 255] = widths[hhea.numberOfHMetrics - 1];
|
||||||
|
else
|
||||||
|
font->widths[bin][i & 255] = widths[glyph];
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (i >= ' ' && i < 127 && font->widths[0])
|
||||||
|
TTF_DEBUG("create_font: width['%c']=%d(%d)\n", (char)i, font->widths[0][i].width, font->widths[0][i].left_bearing);
|
||||||
|
#endif // DEBUG
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup and return the font...
|
||||||
|
free(widths);
|
||||||
|
|
||||||
|
return (font);
|
||||||
|
|
||||||
|
// If we get here something bad happened...
|
||||||
|
error:
|
||||||
|
|
||||||
|
free(widths);
|
||||||
|
ttfDelete(font);
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'errorf()' - Show an error message.
|
// 'errorf()' - Show an error message.
|
||||||
//
|
//
|
||||||
@@ -1070,9 +1168,85 @@ errorf(ttf_t *font, // I - Font
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'read_cmap()' - Read the cmap table, getting the Unicode mapping table.
|
// 'fd_read_cb()' - Read from a file.
|
||||||
*/
|
//
|
||||||
|
|
||||||
|
static size_t // O - Number of bytes read
|
||||||
|
fd_read_cb(ttf_t *font, // I - Font
|
||||||
|
void *buffer, // I - Read buffer
|
||||||
|
size_t bytes) // I - Number of bytes to read
|
||||||
|
{
|
||||||
|
ssize_t rbytes; // Bytes read
|
||||||
|
|
||||||
|
|
||||||
|
if ((rbytes = read(font->file_fd, buffer, bytes)) < 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return ((size_t)rbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'fd_seek_cb()' - Seek in a file.
|
||||||
|
//
|
||||||
|
|
||||||
|
static bool // O - `true` on success, `false` on failure
|
||||||
|
fd_seek_cb(ttf_t *font, // I - Font
|
||||||
|
size_t offset) // I - Offset in data
|
||||||
|
{
|
||||||
|
return (lseek(font->file_fd, (off_t)offset, SEEK_SET) == (off_t)offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'mem_read_cb()' - Read from a memory buffer.
|
||||||
|
//
|
||||||
|
|
||||||
|
static size_t // O - Number of bytes read
|
||||||
|
mem_read_cb(ttf_t *font, // I - Font
|
||||||
|
void *buffer, // I - Read buffer
|
||||||
|
size_t bytes) // I - Number of bytes to read
|
||||||
|
{
|
||||||
|
size_t rbytes; // Bytes to copy
|
||||||
|
|
||||||
|
|
||||||
|
if (font->data_offset >= font->data_size)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if ((rbytes = font->data_size - font->data_offset) > bytes)
|
||||||
|
rbytes = bytes;
|
||||||
|
|
||||||
|
memcpy(buffer, font->data + font->data_offset, rbytes);
|
||||||
|
font->data_offset += rbytes;
|
||||||
|
|
||||||
|
return (rbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'mem_seek_cb()' - Seek in a memory buffer.
|
||||||
|
//
|
||||||
|
|
||||||
|
static bool // O - `true` on success, `false` on error
|
||||||
|
mem_seek_cb(ttf_t *font, // I - Font
|
||||||
|
size_t offset) // I - Offset in data
|
||||||
|
{
|
||||||
|
if (offset >= font->data_size)
|
||||||
|
{
|
||||||
|
errno = ENXIO;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
font->data_offset = offset;
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'read_cmap()' - Read the cmap table, getting the Unicode mapping table.
|
||||||
|
//
|
||||||
|
|
||||||
static bool // O - `true` on success, `false` on error
|
static bool // O - `true` on success, `false` on error
|
||||||
read_cmap(ttf_t *font) // I - Font
|
read_cmap(ttf_t *font) // I - Font
|
||||||
@@ -1205,7 +1379,7 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
|
|
||||||
/* language = */ read_ushort(font);
|
/* language = */ read_ushort(font);
|
||||||
|
|
||||||
if (length > (256 + 6))
|
if (length > (256 + 6) || length < 7)
|
||||||
{
|
{
|
||||||
errorf(font, "Bad cmap table length at offset %u.", coffset);
|
errorf(font, "Bad cmap table length at offset %u.", coffset);
|
||||||
return (false);
|
return (false);
|
||||||
@@ -1219,7 +1393,7 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(font->fd, bmap, font->num_cmap) != (ssize_t)font->num_cmap)
|
if ((font->read_cb)(font, bmap, font->num_cmap) != font->num_cmap)
|
||||||
{
|
{
|
||||||
errorf(font, "Unable to read cmap table length at offset %u.", coffset);
|
errorf(font, "Unable to read cmap table length at offset %u.", coffset);
|
||||||
return (false);
|
return (false);
|
||||||
@@ -1618,6 +1792,9 @@ static bool // O - `true` on success, `false` on error
|
|||||||
read_hhea(ttf_t *font, // I - Font
|
read_hhea(ttf_t *font, // I - Font
|
||||||
_ttf_off_hhea_t *hhea) // O - hhea table data
|
_ttf_off_hhea_t *hhea) // O - hhea table data
|
||||||
{
|
{
|
||||||
|
int temp; // Temporary read value
|
||||||
|
|
||||||
|
|
||||||
memset(hhea, 0, sizeof(_ttf_off_hhea_t));
|
memset(hhea, 0, sizeof(_ttf_off_hhea_t));
|
||||||
|
|
||||||
if (seek_table(font, TTF_OFF_hhea, 0, true) == 0)
|
if (seek_table(font, TTF_OFF_hhea, 0, true) == 0)
|
||||||
@@ -1640,15 +1817,18 @@ read_hhea(ttf_t *font, // I - Font
|
|||||||
/* (reserved) */ read_short(font);
|
/* (reserved) */ read_short(font);
|
||||||
/* (reserved) */ read_short(font);
|
/* (reserved) */ read_short(font);
|
||||||
/* metricDataFormat */ read_short(font);
|
/* metricDataFormat */ read_short(font);
|
||||||
hhea->numberOfHMetrics = (unsigned short)read_ushort(font);
|
if ((temp = read_ushort(font)) < 0)
|
||||||
|
return (false);
|
||||||
|
else
|
||||||
|
hhea->numberOfHMetrics = (unsigned short)temp;
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'read_hmtx()' - Read the horizontal metrics from the font.
|
// 'read_hmtx()' - Read the horizontal metrics from the font.
|
||||||
*/
|
//
|
||||||
|
|
||||||
static _ttf_metric_t * // O - Array of glyph metrics
|
static _ttf_metric_t * // O - Array of glyph metrics
|
||||||
read_hmtx(ttf_t *font, // I - Font
|
read_hmtx(ttf_t *font, // I - Font
|
||||||
@@ -1774,7 +1954,7 @@ read_names(ttf_t *font) // I - Font
|
|||||||
|
|
||||||
length -= (unsigned)offset;
|
length -= (unsigned)offset;
|
||||||
|
|
||||||
if (read(font->fd, font->names.storage, length) < 0)
|
if ((font->read_cb)(font, font->names.storage, length) == 0)
|
||||||
{
|
{
|
||||||
errorf(font, "Unable to read name table: %s", strerror(errno));
|
errorf(font, "Unable to read name table: %s", strerror(errno));
|
||||||
return (false);
|
return (false);
|
||||||
@@ -1823,7 +2003,7 @@ read_os_2(ttf_t *font, // I - Font
|
|||||||
/* yStrikeoutOffset */ read_short(font);
|
/* yStrikeoutOffset */ read_short(font);
|
||||||
/* sFamilyClass */ read_short(font);
|
/* sFamilyClass */ read_short(font);
|
||||||
/* panose[10] */
|
/* panose[10] */
|
||||||
if (read(font->fd, panose, sizeof(panose)) != (ssize_t)sizeof(panose))
|
if ((font->read_cb)(font, panose, sizeof(panose)) != sizeof(panose))
|
||||||
return (false);
|
return (false);
|
||||||
/* ulUnicodeRange1 */ read_ulong(font);
|
/* ulUnicodeRange1 */ read_ulong(font);
|
||||||
/* ulUnicodeRange2 */ read_ulong(font);
|
/* ulUnicodeRange2 */ read_ulong(font);
|
||||||
@@ -1885,7 +2065,7 @@ read_short(ttf_t *font) // I - Font
|
|||||||
unsigned char buffer[2]; // Read buffer
|
unsigned char buffer[2]; // Read buffer
|
||||||
|
|
||||||
|
|
||||||
if (read(font->fd, buffer, sizeof(buffer)) != sizeof(buffer))
|
if ((font->read_cb)(font, buffer, sizeof(buffer)) != sizeof(buffer))
|
||||||
return (EOF);
|
return (EOF);
|
||||||
else if (buffer[0] & 0x80)
|
else if (buffer[0] & 0x80)
|
||||||
return (((buffer[0] << 8) | buffer[1]) - 65536);
|
return (((buffer[0] << 8) | buffer[1]) - 65536);
|
||||||
@@ -1958,7 +2138,7 @@ read_table(ttf_t *font) // I - Font
|
|||||||
|
|
||||||
TTF_DEBUG("read_table: Offset for font %u is %u.\n", (unsigned)font->idx, temp);
|
TTF_DEBUG("read_table: Offset for font %u is %u.\n", (unsigned)font->idx, temp);
|
||||||
|
|
||||||
if (lseek(font->fd, temp + 4, SEEK_SET) < 0)
|
if (!(font->seek_cb)(font, temp + 4))
|
||||||
{
|
{
|
||||||
errorf(font, "Unable to seek to font %u: %s", (unsigned)font->idx, strerror(errno));
|
errorf(font, "Unable to seek to font %u: %s", (unsigned)font->idx, strerror(errno));
|
||||||
return (false);
|
return (false);
|
||||||
@@ -2034,7 +2214,7 @@ read_ulong(ttf_t *font) // I - Font
|
|||||||
unsigned char buffer[4]; // Read buffer
|
unsigned char buffer[4]; // Read buffer
|
||||||
|
|
||||||
|
|
||||||
if (read(font->fd, buffer, sizeof(buffer)) != sizeof(buffer))
|
if ((font->read_cb)(font, buffer, sizeof(buffer)) != sizeof(buffer))
|
||||||
return ((unsigned)EOF);
|
return ((unsigned)EOF);
|
||||||
else
|
else
|
||||||
return ((unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]));
|
return ((unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]));
|
||||||
@@ -2051,7 +2231,7 @@ read_ushort(ttf_t *font) // I - Font
|
|||||||
unsigned char buffer[2]; // Read buffer
|
unsigned char buffer[2]; // Read buffer
|
||||||
|
|
||||||
|
|
||||||
if (read(font->fd, buffer, sizeof(buffer)) != sizeof(buffer))
|
if ((font->read_cb)(font, buffer, sizeof(buffer)) != sizeof(buffer))
|
||||||
return (EOF);
|
return (EOF);
|
||||||
else
|
else
|
||||||
return ((buffer[0] << 8) | buffer[1]);
|
return ((buffer[0] << 8) | buffer[1]);
|
||||||
@@ -2078,7 +2258,7 @@ seek_table(ttf_t *font, // I - Font
|
|||||||
if (current->tag == tag)
|
if (current->tag == tag)
|
||||||
{
|
{
|
||||||
// Found it, seek and return...
|
// Found it, seek and return...
|
||||||
if (lseek(font->fd, current->offset + offset, SEEK_SET) == (current->offset + offset))
|
if ((font->seek_cb)(font, current->offset + offset))
|
||||||
{
|
{
|
||||||
// Successful seek...
|
// Successful seek...
|
||||||
return (current->length - offset);
|
return (current->length - offset);
|
||||||
|
|||||||
3
ttf.h
3
ttf.h
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// https://github.com/michaelrsweet/ttf
|
// https://github.com/michaelrsweet/ttf
|
||||||
//
|
//
|
||||||
// Copyright © 2018-2024 by Michael R Sweet.
|
// Copyright © 2018-2025 by Michael R Sweet.
|
||||||
//
|
//
|
||||||
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
// information.
|
// information.
|
||||||
@@ -81,6 +81,7 @@ typedef struct ttf_rect_s // Bounding rectangle
|
|||||||
//
|
//
|
||||||
|
|
||||||
extern ttf_t *ttfCreate(const char *filename, size_t idx, ttf_err_cb_t err_cb, void *err_data);
|
extern ttf_t *ttfCreate(const char *filename, size_t idx, ttf_err_cb_t err_cb, void *err_data);
|
||||||
|
extern ttf_t *ttfCreateData(const void *data, size_t data_size, size_t idx, ttf_err_cb_t err_cb, void *err_data);
|
||||||
extern void ttfDelete(ttf_t *font);
|
extern void ttfDelete(ttf_t *font);
|
||||||
extern int ttfGetAscent(ttf_t *font);
|
extern int ttfGetAscent(ttf_t *font);
|
||||||
extern ttf_rect_t *ttfGetBounds(ttf_t *font, ttf_rect_t *bounds);
|
extern ttf_rect_t *ttfGetBounds(ttf_t *font, ttf_rect_t *bounds);
|
||||||
|
|||||||
Reference in New Issue
Block a user