28 Commits

Author SHA1 Message Date
Michael R Sweet
4f28159e6a Fix the unsupported filter error message (Issue #130) 2025-09-30 19:49:09 -04:00
Michael R Sweet
ef8dee325a Fallthrough attribute is Apple-specific at the moment... 2025-09-25 17:47:31 -04:00
Michael R Sweet
dc09418660 More clang warning fixes. 2025-09-25 17:20:20 -04:00
Michael R Sweet
06d680d6cd Clean up compiler warnings, update Xcode project. 2025-09-25 16:54:55 -04:00
Michael R Sweet
0dd2e6fd37 Mirror EOF fix (Issue #136) 2025-09-13 11:34:41 -04:00
Michael R Sweet
2b6f04a5a1 Fix some Clang warnings. 2025-09-04 14:40:18 -04:00
Michael R Sweet
cc695fef2c Current autoconf triggers the obsolete AC_HEADER_STDC checks, so force things before zlib. 2025-08-30 13:37:28 -04:00
Michael R Sweet
410e3b92ea Add underflow detection to TTF cmap code. 2025-08-27 11:21:16 -04:00
Michael R Sweet
dc584c0868 PDFio 1.5.4. 2025-08-26 12:33:30 -04:00
Michael R Sweet
4b7e9691b3 PDFio 1.5.4. 2025-08-26 12:32:50 -04:00
Michael R Sweet
795daba88e Fix typos. 2025-08-06 11:26:10 -04:00
Michael R Sweet
ca4f20e84c Clarify token too large errors (Issue #131) 2025-07-28 19:11:17 +01:00
Michael R Sweet
a54e2886a6 Fix copy_jpeg with invalid/corrupt JPEG data (Issue #132) 2025-07-28 19:04:17 +01:00
Michael R Sweet
d3a5fa9e0b Limit generation numbers to 0 to 65535. 2025-07-28 12:51:17 +01:00
Michael R Sweet
4bbb8b0b38 Update docos. 2025-05-03 10:09:45 -04:00
Michael R Sweet
1657e89ddb Bump version. 2025-05-03 10:08:54 -04:00
Michael R Sweet
afa6d4c4de Don't set extension pointer if object is NULL. 2025-04-25 12:41:11 -04:00
Michael R Sweet
31a086e165 Fix object map to use unique file hash instead of pointer values (Issue #125) 2025-04-24 14:00:30 -04:00
Michael R Sweet
01cc243bcf Add more range checking for streams. 2025-04-24 13:17:53 -04:00
Michael R Sweet
25f5e28e56 Update docos. 2025-04-24 12:30:01 -04:00
Michael R Sweet
e6588d3960 Backport more changes from master. 2025-04-24 12:29:53 -04:00
Michael R Sweet
8f706b9fe7 Backport reading improvements/bug fixes from master. 2025-04-24 12:19:11 -04:00
Michael R Sweet
f9c07a0346 Add support for EncryptMetadata key in encryption dictionary. 2025-04-23 10:12:33 -04:00
Michael R Sweet
a22957baa1 Protect against invalid predictor buffer size. 2025-04-23 10:12:18 -04:00
Michael R Sweet
d7f3c64f63 Fix encrypted PDF files with P values >2^31-1. 2025-04-20 17:34:38 -04:00
Michael R Sweet
29eea131b9 Remove old per-object crypto stuff we dont need. 2025-04-13 09:10:17 -04:00
Michael R Sweet
2dcef0936e Fix decryption of UTF-16 strings (Issue #42) 2025-04-13 09:05:02 -04:00
Michael R Sweet
20dd2a6d28 Fix decryption of RC4-40 files. 2025-04-13 08:37:24 -04:00
29 changed files with 1196 additions and 4752 deletions

View File

@@ -2,26 +2,9 @@ Changes in PDFio
================ ================
v1.6.0 - 2025-10-06 v1.5.5 - YYYY-MM-DD
------------------- -------------------
- 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 unsupported filter error (Issue #130)
- Fixed EOF comment written to the PDF (Issue #136) - Fixed EOF comment written to the PDF (Issue #136)
- Fixed TTF cmap underflow error. - Fixed TTF cmap underflow error.

View File

@@ -241,7 +241,6 @@ 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

24
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for pdfio 1.6.0. # Generated by GNU Autoconf 2.71 for pdfio 1.5.4.
# #
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>. # Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
# #
@@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='pdfio' PACKAGE_NAME='pdfio'
PACKAGE_TARNAME='pdfio' PACKAGE_TARNAME='pdfio'
PACKAGE_VERSION='1.6.0' PACKAGE_VERSION='1.5.4'
PACKAGE_STRING='pdfio 1.6.0' PACKAGE_STRING='pdfio 1.5.4'
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'
@@ -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.6.0 to adapt to many kinds of systems. \`configure' configures pdfio 1.5.4 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.6.0:";; short | recursive ) echo "Configuration of pdfio 1.5.4:";;
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.6.0 pdfio configure 1.5.4
generated by GNU Autoconf 2.71 generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc. Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1678,7 +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.6.0, which was It was created by pdfio $as_me 1.5.4, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@@ -2434,9 +2434,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
PDFIO_VERSION="1.6.0" PDFIO_VERSION="1.5.4"
PDFIO_VERSION_MAJOR="`echo 1.6.0 | awk -F. '{print $1}'`" PDFIO_VERSION_MAJOR="`echo 1.5.4 | awk -F. '{print $1}'`"
PDFIO_VERSION_MINOR="`echo 1.6.0 | awk -F. '{printf("%d\n",$2);}'`" PDFIO_VERSION_MINOR="`echo 1.5.4 | awk -F. '{printf("%d\n",$2);}'`"
@@ -5106,7 +5106,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by pdfio $as_me 1.6.0, which was This file was extended by pdfio $as_me 1.5.4, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -5162,7 +5162,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
pdfio config.status 1.6.0 pdfio config.status 1.5.4
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\\"

View File

@@ -21,7 +21,7 @@ AC_PREREQ([2.70])
dnl Package name and version... dnl Package name and version...
AC_INIT([pdfio], [1.6.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio]) AC_INIT([pdfio], [1.5.4], [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}'`"

View File

@@ -1,4 +1,4 @@
.TH pdfio 3 "pdf read/write library" "2025-10-05" "pdf read/write library" .TH pdfio 3 "pdf read/write library" "2025-05-03" "pdf read/write library"
.SH NAME .SH NAME
pdfio \- pdf read/write library pdfio \- pdf read/write library
.SH Introduction .SH Introduction
@@ -1032,45 +1032,6 @@ 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.
@@ -1730,9 +1691,6 @@ 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
@@ -2209,9 +2167,6 @@ 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);
@@ -2248,9 +2203,6 @@ 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,
@@ -2380,17 +2332,8 @@ 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
@@ -2509,10 +2452,6 @@ 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
@@ -2902,8 +2841,7 @@ 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, \fB3\fR for RGB color, and The "num_colors" argument must be \fB1\fR for grayscale and \fB3\fR for RGB color.
\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
@@ -3014,30 +2952,6 @@ bool pdfioArrayRemove (
.fi .fi
.PP .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
@@ -3063,19 +2977,6 @@ 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
@@ -3940,39 +3841,6 @@ 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
@@ -3999,31 +3867,8 @@ 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 following values are recognized: \fBNULL\fR for the default ("2.0"). The value "PCLm-1.0" can be specified to
.PP produce the PCLm subset of PDF.
.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
@@ -4031,24 +3876,8 @@ 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 then the default error handler is used that and its data pointer - if \fBNULL\fR then the default error handler is used that
writes error and warning messages to \fBstderr\fR. The error handler callback writes error messages to \fBstderr\fR. The error handler callback should return
should return \fBtrue\fR to continue writing the PDF file or \fBfalse\fR to stop. \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
@@ -4106,30 +3935,8 @@ 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 file to a PDF file. Add a font object to a PDF file.
.PP .PP
.nf .nf
pdfio_obj_t * pdfioFileCreateFontObjFromFile ( pdfio_obj_t * pdfioFileCreateFontObjFromFile (
@@ -4139,7 +3946,7 @@ pdfio_obj_t * pdfioFileCreateFontObjFromFile (
); );
.fi .fi
.PP .PP
This function embeds a TrueType/OpenType font file into a PDF file. The This function embeds a TrueType/OpenType font into a PDF file. The
"unicode" parameter controls whether the font is encoded for two-byte "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
@@ -4192,12 +3999,8 @@ 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
.IP 5 created to hold the "soft mask" data for the primary image.
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
@@ -4215,9 +4018,11 @@ 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: PNG files containing transparency cannot be used when producing Note: Currently PNG support is limited to grayscale, RGB, or indexed files
.IP 5 .IP 5
PDF/A files. without interlacing or alpha. Transparency (masking) based on color/index
.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
@@ -4285,32 +4090,9 @@ 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"). The following values are recognized: \fBNULL\fR for the default ("2.0"). Unlike \fIpdfioFileCreate\fR and
.PP \fIpdfioFileCreateTemporary\fR, it is generally not safe to pass the
.IP \(bu 5 "PCLm-1.0" version string.
"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
@@ -4318,24 +4100,9 @@ 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 then the default error handler is used that and its data pointer - if \fBNULL\fR then the default error handler is used that
writes error and warning messages to \fBstderr\fR. The error handler callback writes error messages to \fBstderr\fR. The error handler callback should return
should return \fBtrue\fR to continue writing the PDF file or \fBfalse\fR to stop. \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
@@ -4441,21 +4208,6 @@ 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
@@ -4574,24 +4326,9 @@ 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 then the default error handler is used that and its data pointer - if \fBNULL\fR then the default error handler is used that
writes error and warning messages to \fBstderr\fR. The error handler callback writes error messages to \fBstderr\fR. The error handler callback should return
should return \fBtrue\fR to continue reading the PDF file or \fBfalse\fR to stop. \fBtrue\fR to continue reading 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
Note: Error messages starting with "WARNING:" are actually warning Note: Error messages starting with "WARNING:" are actually warning
.IP 5 .IP 5
@@ -4636,22 +4373,6 @@ 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

View File

@@ -1,13 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en-US"> <html lang="en-US">
<head> <head>
<title>PDFio Programming Manual v1.6.0</title> <title>PDFio Programming Manual v1.5.3</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.6.0"> <meta name="version" content="1.5.3">
<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.6.0</h1> <h1 class="title">PDFio Programming Manual v1.5.3</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,7 +273,6 @@ 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>
@@ -311,10 +310,8 @@ 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>
@@ -398,12 +395,10 @@ 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>
@@ -423,7 +418,6 @@ 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>
@@ -440,7 +434,6 @@ 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>
@@ -1161,38 +1154,6 @@ pdfio_obj_t *img =
<li><p><a href="#pdfioContentTextShowJustified"><code>pdfioContentTextShowJustified</code></a> draws an array of literal strings with offsets between them</p> <li><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 (&quot;MCID&quot;). For example, the following code tags a paragraph of text:</p>
<pre><code class="language-c">pdfio_file_t *pdf; <span class="comment">// PDF file</span>
pdfio_stream_t *st; <span class="comment">// Page stream</span>
pdfioContentBeginMarked(st, <span class="string">&quot;P&quot;</span>, <span class="comment">/*dict*/</span>NULL);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;Mary had a little lamb\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;whose fleece was white as snow.\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;And everywhere that Mary went\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;the lamb was sure to go,\n&quot;</span>);
pdfioContentEndMarked(st);
</code></pre>
<p>To mark the same paragraph with a content identifier you would first create a dictionary containing the &quot;MCID&quot; key/value pair and then mark the paragraph with that dictionary:</p>
<pre><code class="language-c">pdfio_file_t *pdf; <span class="comment">// PDF file</span>
pdfio_stream_t *st; <span class="comment">// Page stream</span>
pdfio_dict_t *dict; <span class="comment">// Content dictionary</span>
dict = pdfioDictCreate(pdf);
pdfioDictSetNumber(dict, <span class="string">&quot;MCID&quot;</span>, <span class="number">42</span>);
pdfioContentBeginMarked(st, <span class="string">&quot;P&quot;</span>, dict);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;Mary had a little lamb\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;whose fleece was white as snow.\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;And everywhere that Mary went\n&quot;</span>);
pdfioContentTextShow(st, <span class="comment">/*unicode*/</span><span class="reserved">false</span>, <span class="string">&quot;the lamb was sure to go,\n&quot;</span>);
pdfioContentEndMarked(st);
</code></pre>
<h2 class="title" id="examples">Examples</h2> <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>
@@ -1788,9 +1749,6 @@ 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>
@@ -2168,9 +2126,6 @@ pdfioContentPathRect(dd-&gt;st, left - CODE_PADDING, dd-&gt;y + SIZE_CODEBLOCK,
pdfioContentFillAndStroke(dd-&gt;st, <span class="reserved">false</span>); pdfioContentFillAndStroke(dd-&gt;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-&gt;tag = <span class="string">&quot;P&quot;</span>;
pdfioContentBeginMarked(dd-&gt;st, dd-&gt;tag, <span class="comment">/*dict*/</span>NULL);
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK); set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd-&gt;st); pdfioContentTextBegin(dd-&gt;st);
pdfioContentTextMoveTo(dd-&gt;st, left, dd-&gt;y); pdfioContentTextMoveTo(dd-&gt;st, left, dd-&gt;y);
@@ -2207,9 +2162,6 @@ pdfioContentTextMoveTo(dd-&gt;st, left, dd-&gt;y);
pdfioContentTextEnd(dd-&gt;st); pdfioContentTextEnd(dd-&gt;st);
dd-&gt;y += lineheight; dd-&gt;y += lineheight;
pdfioContentEndMarked(dd-&gt;st);
dd-&gt;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-&gt;st, left - CODE_PADDING, pdfioContentPathRect(dd-&gt;st, left - CODE_PADDING,
@@ -2320,17 +2272,8 @@ pdfioContentFillAndStroke(dd-&gt;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-&gt;in_table = <span class="reserved">true</span>;
<span class="reserved">if</span> (dd-&gt;st)
pdfioContentBeginMarked(dd-&gt;st, <span class="string">&quot;Table&quot;</span>, <span class="comment">/*dict*/</span>NULL);
<span class="reserved">for</span> (row = <span class="number">0</span>, rowptr = rows; row &lt; num_rows; row ++, rowptr ++) <span class="reserved">for</span> (row = <span class="number">0</span>, rowptr = rows; row &lt; num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr); render_row(dd, num_cols, cols, rowptr);
pdfioContentEndMarked(dd-&gt;st);
dd-&gt;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>
@@ -2654,7 +2597,7 @@ dd-&gt;y = row_y - row-&gt;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, 3, or 4)</td></tr> <td class="description">Number of colors (1 or 3)</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>
@@ -2662,8 +2605,7 @@ dd-&gt;y = row_y - row-&gt;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 &quot;num_colors&quot; argument must be <code>1</code> for grayscale, <code>3</code> for RGB color, and The &quot;num_colors&quot; argument must be <code>1</code> for grayscale and <code>3</code> for RGB color.</p>
<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">
@@ -2820,35 +2762,6 @@ 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">&#160;PDFio 1.6&#160;</span><a id="pdfioContentBeginMarked">pdfioContentBeginMarked</a></h3>
<p class="description">Start marked content with an optional dictionary.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentBeginMarked(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, <span class="reserved">const</span> <span class="reserved">char</span> *tag, <a href="#pdfio_dict_t">pdfio_dict_t</a> *dict);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>st</th>
<td class="description">Stream</td></tr>
<tr><th>tag</th>
<td class="description">Tag name of marked content</td></tr>
<tr><th>dict</th>
<td class="description">Dictionary of parameters or <code>NULL</code> if none</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function starts an area of marked content with an optional dictionary.
It must be paired with a call to the <a href="#pdfioContentEndMarked"><code>pdfioContentEndMarked</code></a> function.<br>
<br>
The &quot;tag&quot; argument specifies the tag name string for the content such as &quot;P&quot;
for a paragraph, &quot;H1&quot; for a top-level heading, and so forth. The &quot;dict&quot;
argument specifies an optional dictionary of properties for the content such
as the marked content identifier (&quot;MCID&quot;) number.<br>
<br>
Calling this function sets the &quot;Marked&quot; key in the &quot;MarkInfo&quot; dictionary of
the document catalog. The caller is responsible for setting the
&quot;StructTreeRoot&quot; dictionary when creating marked content.
</p>
<h3 class="function"><a id="pdfioContentClip">pdfioContentClip</a></h3> <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">
@@ -2886,22 +2799,6 @@ the document catalog. The caller is responsible for setting the
<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">&#160;PDFio 1.6&#160;</span><a id="pdfioContentEndMarked">pdfioContentEndMarked</a></h3>
<p class="description">End marked content.</p>
<p class="code">
<span class="reserved">bool</span> pdfioContentEndMarked(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>st</th>
<td class="description">Stream</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function ends an area of marked content that was started using the
<a href="#pdfioContentBeginMarked"><code>pdfioContentBeginMarked</code></a> function.
</p>
<h3 class="function"><a id="pdfioContentFill">pdfioContentFill</a></h3> <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">
@@ -4145,46 +4042,6 @@ have been iterated.
</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">&#160;PDFio 1.6&#160;</span><a id="pdfioFileAddOutputIntent">pdfioFileAddOutputIntent</a></h3>
<p class="description">Add an OutputIntent to a file.</p>
<p class="code">
<span class="reserved">void</span> pdfioFileAddOutputIntent(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *subtype, <span class="reserved">const</span> <span class="reserved">char</span> *condition, <span class="reserved">const</span> <span class="reserved">char</span> *cond_id, <span class="reserved">const</span> <span class="reserved">char</span> *reg_name, <span class="reserved">const</span> <span class="reserved">char</span> *info, <a href="#pdfio_obj_t">pdfio_obj_t</a> *profile);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>subtype</th>
<td class="description">Intent subtype (standard)</td></tr>
<tr><th>condition</th>
<td class="description">Condition name or <code>NULL</code> for none</td></tr>
<tr><th>cond_id</th>
<td class="description">Identifier such as registration name or <code>NULL</code> for none</td></tr>
<tr><th>reg_name</th>
<td class="description">Registry URL or <code>NULL</code> for none</td></tr>
<tr><th>info</th>
<td class="description">Description or <code>NULL</code> for none</td></tr>
<tr><th>profile</th>
<td class="description">ICC profile object or <code>NULL</code> for none</td></tr>
</tbody></table>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function adds an OutputIntent dictionary to the PDF file catalog.
The &quot;subtype&quot; argument specifies the intent subtype and is typically
&quot;GTS_PDFX&quot; for PDF/X, &quot;GTS_PDFA1&quot; for PDF/A, or &quot;ISO_PDFE1&quot; for PDF/E.
Passing <code>NULL</code> defaults the subtype to &quot;GTS_PDFA1&quot;.<br>
<br>
The &quot;condition&quot; argument specifies a short name for the output intent, while
the &quot;info&quot; argument specifies a longer description for the output intent.
Both can be <code>NULL</code> to omit this information.<br>
<br>
The &quot;cond_id&quot; argument specifies a unique identifier such as a registration
(&quot;CGATS001&quot;) or color space name (&quot;sRGB&quot;). The &quot;reg_name&quot; argument provides
a URL for the identifier.<br>
<br>
The &quot;profile&quot; argument specifies an ICC profile object for the output
condition. If <code>NULL</code>, the PDF consumer will attempt to look up the correct
profile using the &quot;cond_id&quot; value.
</p>
<h3 class="function"><a id="pdfioFileClose">pdfioFileClose</a></h3> <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">
@@ -4222,55 +4079,17 @@ profile using the &quot;cond_id&quot; value.
name of the PDF file to create.<br> name of the PDF file to create.<br>
<br> <br>
The &quot;version&quot; argument specifies the PDF version number for the file or The &quot;version&quot; argument specifies the PDF version number for the file or
<code>NULL</code> for the default (&quot;2.0&quot;). The following values are recognized: <code>NULL</code> for the default (&quot;2.0&quot;). The value &quot;PCLm-1.0&quot; can be specified to
produce the PCLm subset of PDF.<br>
</p><ul> <br>
<li>&quot;1.3&quot;, &quot;1.4&quot;, &quot;1.5&quot;, &quot;1.6&quot;, &quot;1.7&quot;, &quot;2.0&quot;: Generic PDF files of the The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
specified versions.
</li>
<li>&quot;PCLm-1.0&quot;: The PCLm (raster) subset of PDF supported by some printers.
</li>
<li>&quot;PDF/A-1a&quot;: PDF/A-1a:2005
</li>
<li>&quot;PDF/A-1b&quot;: PDF/A-1b:2005
</li>
<li>&quot;PDF/A-2a&quot;: PDF/A-2a:2011
</li>
<li>&quot;PDF/A-2b&quot;: PDF/A-2b:2011
</li>
<li>&quot;PDF/A-2u&quot;: PDF/A-2u:2011
</li>
<li>&quot;PDF/A-3a&quot;: PDF/A-3a:2012
</li>
<li>&quot;PDF/A-3b&quot;: PDF/A-3b:2012
</li>
<li>&quot;PDF/A-3u&quot;: PDF/A-3u:2012
</li>
<li>&quot;PDF/A-4&quot;: PDF/A-4:2020</li>
</ul>
<p class="discussion">The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br> of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
<br> <br>
The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback
and its data pointer - if <code>NULL</code> then the default error handler is used that and its data pointer - if <code>NULL</code> then the default error handler is used that
writes error and warning messages to <code>stderr</code>. The error handler callback writes error messages to <code>stderr</code>. The error handler callback should return
should return <code>true</code> to continue writing the PDF file or <code>false</code> to stop. <code>true</code> to continue writing the PDF file or <code>false</code> to stop.</p>
For example:
<pre>
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, &quot;%s: %sn&quot;, pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, &quot;WARNING:&quot;, 8));
}
</pre>
</p>
<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">
@@ -4335,37 +4154,9 @@ specifies the font nane:
</ul> </ul>
<p class="discussion">Aside from &quot;Symbol&quot; and &quot;Zapf-Dingbats&quot;, Base fonts use the Windows CP1252 <p class="discussion">Aside from &quot;Symbol&quot; and &quot;Zapf-Dingbats&quot;, Base fonts use the Windows CP1252
(ISO-8859-1 with additional characters such as the Euro symbol) subset of (ISO-8859-1 with additional characters such as the Euro symbol) subset of
Unicode.<br> Unicode.</p>
<br>
</p><blockquote>
Note: This function cannot be used when producing PDF/A files.</blockquote>
<h3 class="function"><span class="info">&#160;PDFio v1.6&#160;</span><a id="pdfioFileCreateFontObjFromData">pdfioFileCreateFontObjFromData</a></h3>
<p class="description">Add a font in memory to a PDF file.</p>
<p class="code">
<a href="#pdfio_obj_t">pdfio_obj_t</a> *pdfioFileCreateFontObjFromData(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">void</span> *data, size_t datasize, <span class="reserved">bool</span> unicode);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>data</th>
<td class="description">Font data in memory</td></tr>
<tr><th>datasize</th>
<td class="description">Size of font in memory</td></tr>
<tr><th>unicode</th>
<td class="description">Force Unicode</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Font object</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function embeds TrueType/OpenType font data into a PDF file. The
&quot;unicode&quot; parameter controls whether the font is encoded for two-byte
characters (potentially full Unicode, but more typically a subset)
or to only support the Windows CP1252 (ISO-8859-1 with additional
characters such as the Euro symbol) subset of Unicode.
</p>
<h3 class="function"><a id="pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></h3> <h3 class="function"><a id="pdfioFileCreateFontObjFromFile">pdfioFileCreateFontObjFromFile</a></h3>
<p class="description">Add a font file to a PDF file.</p> <p class="description">Add a font object to a PDF file.</p>
<p class="code"> <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>
@@ -4380,7 +4171,7 @@ characters such as the Euro symbol) subset of Unicode.
<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 file into a PDF file. The <p class="discussion">This function embeds a TrueType/OpenType font into a PDF file. The
&quot;unicode&quot; parameter controls whether the font is encoded for two-byte &quot;unicode&quot; 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
@@ -4454,10 +4245,8 @@ the image is encoded in the corresponding device color space. The
&quot;interpolate&quot; parameter specifies whether to interpolate when scaling the &quot;interpolate&quot; 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 &quot;soft mask&quot; data for the primary image. PDF/A-1 created to hold the &quot;soft mask&quot; data for the primary image.</p>
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">
@@ -4480,8 +4269,9 @@ the &quot;interpolate&quot; parameter specifies whether to interpolate when scal
image on the page.<br> image on the page.<br>
<br> <br>
</p><blockquote> </p><blockquote>
Note: PNG files containing transparency cannot be used when producing Note: Currently PNG support is limited to grayscale, RGB, or indexed files
PDF/A files.</blockquote> without interlacing or alpha. Transparency (masking) based on color/index
is supported.</blockquote>
<h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><a id="pdfioFileCreateNameObj">pdfioFileCreateNameObj</a></h3> <h3 class="function"><span class="info">&#160;PDFio v1.4&#160;</span><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">
@@ -4569,32 +4359,9 @@ output_cb(void *output_cbdata, const void *buffer, size_t bytes)
</pre> </pre>
The &quot;version&quot; argument specifies the PDF version number for the file or The &quot;version&quot; argument specifies the PDF version number for the file or
<code>NULL</code> for the default (&quot;2.0&quot;). The following values are recognized: <code>NULL</code> for the default (&quot;2.0&quot;). Unlike <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> and
<a href="#pdfioFileCreateTemporary"><code>pdfioFileCreateTemporary</code></a>, it is generally not safe to pass the
</p><ul> &quot;PCLm-1.0&quot; version string.<br>
<li>&quot;1.3&quot;, &quot;1.4&quot;, &quot;1.5&quot;, &quot;1.6&quot;, &quot;1.7&quot;, &quot;2.0&quot;: Generic PDF files of the
specified versions.
</li>
<li>&quot;PDF/A-1a&quot;: PDF/A-1a:2005
</li>
<li>&quot;PDF/A-1b&quot;: PDF/A-1b:2005
</li>
<li>&quot;PDF/A-2a&quot;: PDF/A-2a:2011
</li>
<li>&quot;PDF/A-2b&quot;: PDF/A-2b:2011
</li>
<li>&quot;PDF/A-2u&quot;: PDF/A-2u:2011
</li>
<li>&quot;PDF/A-3a&quot;: PDF/A-3a:2012
</li>
<li>&quot;PDF/A-3b&quot;: PDF/A-3b:2012
</li>
<li>&quot;PDF/A-3u&quot;: PDF/A-3u:2012
</li>
<li>&quot;PDF/A-4&quot;: PDF/A-4:2020</li>
</ul>
<p class="discussion">Unlike <a href="#pdfioFileCreate"><code>pdfioFileCreate</code></a> and <a href="#pdfioFileCreateTemporary"><code>pdfioFileCreateTemporary</code></a>, it is
generally not safe to pass the &quot;PCLm-1.0&quot; version string.<br>
<br> <br>
The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size
@@ -4602,23 +4369,9 @@ of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
<br> <br>
The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback
and its data pointer - if <code>NULL</code> then the default error handler is used that and its data pointer - if <code>NULL</code> then the default error handler is used that
writes error and warning messages to <code>stderr</code>. The error handler callback writes error messages to <code>stderr</code>. The error handler callback should return
should return <code>true</code> to continue writing the PDF file or <code>false</code> to stop. <code>true</code> to continue writing the PDF file or <code>false</code> to stop.<br>
For example: <br>
<pre>
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, &quot;%s: %sn&quot;, pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, &quot;WARNING:&quot;, 8));
}
</pre>
</p><blockquote> </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
@@ -4682,33 +4435,10 @@ temporary directory. The temporary file is stored in the string &quot;buffer&qu
will have a &quot;.pdf&quot; extension.<br> will have a &quot;.pdf&quot; extension.<br>
<br> <br>
The &quot;version&quot; argument specifies the PDF version number for the file or The &quot;version&quot; argument specifies the PDF version number for the file or
<code>NULL</code> for the default (&quot;2.0&quot;). The following values are recognized: <code>NULL</code> for the default (&quot;2.0&quot;). The value &quot;PCLm-1.0&quot; can be specified to
produce the PCLm subset of PDF.<br>
</p><ul> <br>
<li>&quot;1.3&quot;, &quot;1.4&quot;, &quot;1.5&quot;, &quot;1.6&quot;, &quot;1.7&quot;, &quot;2.0&quot;: Generic PDF files of the The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
specified versions.
</li>
<li>&quot;PCLm-1.0&quot;: The PCLm (raster) subset of PDF supported by some printers.
</li>
<li>&quot;PDF/A-1a&quot;: PDF/A-1a:2005
</li>
<li>&quot;PDF/A-1b&quot;: PDF/A-1b:2005
</li>
<li>&quot;PDF/A-2a&quot;: PDF/A-2a:2011
</li>
<li>&quot;PDF/A-2b&quot;: PDF/A-2b:2011
</li>
<li>&quot;PDF/A-2u&quot;: PDF/A-2u:2011
</li>
<li>&quot;PDF/A-3a&quot;: PDF/A-3a:2012
</li>
<li>&quot;PDF/A-3b&quot;: PDF/A-3b:2012
</li>
<li>&quot;PDF/A-3u&quot;: PDF/A-3u:2012
</li>
<li>&quot;PDF/A-4&quot;: PDF/A-4:2020</li>
</ul>
<p class="discussion">The &quot;media_box&quot; and &quot;crop_box&quot; arguments specify the default MediaBox and
CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size CropBox for pages in the PDF file - if <code>NULL</code> then a default &quot;Universal&quot; size
of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br> of 8.27x11in (the intersection of US Letter and ISO A4) is used.<br>
<br> <br>
@@ -4799,24 +4529,6 @@ 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">&#160;PDFio 1.6&#160;</span><a id="pdfioFileGetLanguage">pdfioFileGetLanguage</a></h3>
<p class="description">Get the language metadata for a PDF file.</p>
<p class="code">
<span class="reserved">const</span> <span class="reserved">char</span> *pdfioFileGetLanguage(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
</tbody></table>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Language or <code>NULL</code> for none</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function gets the (primary/default) language metadata, if any, for a PDF
file. The returned string is an IETF BCP 47 language tag of the form
&quot;lang-REGION&quot;. For example, the string &quot;en-CA&quot; specifies Canadian English
and the string &quot;fr-CA&quot; specifies Canadian French.
</p>
<h3 class="function"><a id="pdfioFileGetModificationDate">pdfioFileGetModificationDate</a></h3> <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">
@@ -4978,23 +4690,9 @@ PDF file requires a password, the open will always fail.<br>
<br> <br>
The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback The &quot;error_cb&quot; and &quot;error_cbdata&quot; arguments specify an error handler callback
and its data pointer - if <code>NULL</code> then the default error handler is used that and its data pointer - if <code>NULL</code> then the default error handler is used that
writes error and warning messages to <code>stderr</code>. The error handler callback writes error messages to <code>stderr</code>. The error handler callback should return
should return <code>true</code> to continue reading the PDF file or <code>false</code> to stop. <code>true</code> to continue reading the PDF file or <code>false</code> to stop.<br>
For example: <br>
<pre>
bool
my_error_cb(pdfio_file_t *pdf, const char *message, void *data)
{
(void)data; /* Not using data pointer in this callback */
fprintf(stderr, &quot;%s: %sn&quot;, pdfioFileGetName(pdf), message);
/* Return true to continue on warning messages, false otherwise... */
return (!strncmp(message, &quot;WARNING:&quot;, 8));
}
</pre>
</p><blockquote> </p><blockquote>
Note: Error messages starting with &quot;WARNING:&quot; are actually warning Note: Error messages starting with &quot;WARNING:&quot; are actually warning
messages - the callback should normally return <code>true</code> to allow PDFio to messages - the callback should normally return <code>true</code> to allow PDFio to
@@ -5044,24 +4742,6 @@ ignore the return value of the error callback.</blockquote>
<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">&#160;PDFio 1.6&#160;</span><a id="pdfioFileSetLanguage">pdfioFileSetLanguage</a></h3>
<p class="description">Set the language metadata for a PDF file.</p>
<p class="code">
<span class="reserved">void</span> pdfioFileSetLanguage(<a href="#pdfio_file_t">pdfio_file_t</a> *pdf, <span class="reserved">const</span> <span class="reserved">char</span> *value);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>pdf</th>
<td class="description">PDF file</td></tr>
<tr><th>value</th>
<td class="description">Value</td></tr>
</tbody></table>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function sets the (primary/default) language metadata for a PDF file.
The &quot;value&quot; argument is an IETF BCP 47 language tag string of the form
&quot;lang-REGION&quot;. For example, the string &quot;en-CA&quot; specifies Canadian English
and the string &quot;fr-CA&quot; specifies Canadian French.
</p>
<h3 class="function"><a id="pdfioFileSetModificationDate">pdfioFileSetModificationDate</a></h3> <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">
@@ -5740,7 +5420,6 @@ 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>

View File

@@ -868,55 +868,6 @@ 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
======== ========
@@ -1646,9 +1597,6 @@ 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
@@ -2152,9 +2100,6 @@ 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);
@@ -2191,9 +2136,6 @@ 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,
@@ -2334,17 +2276,8 @@ 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;
``` ```

View File

@@ -122,9 +122,6 @@ 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
@@ -475,7 +472,6 @@ 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);
@@ -622,50 +618,6 @@ 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)
{ {
@@ -844,9 +796,6 @@ format_block(docdata_t *dd, // I - Document data
pdfioContentRestore(dd->st); pdfioContentRestore(dd->st);
} }
} }
pdfioContentEndMarked(dd->st);
dd->tag = NULL;
} }
@@ -886,9 +835,6 @@ format_code(docdata_t *dd, // I - Document data
pdfioContentFillAndStroke(dd->st, false); 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);
@@ -923,9 +869,6 @@ 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);
@@ -1201,17 +1144,8 @@ 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;
} }
@@ -1425,16 +1359,6 @@ 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);
} }
@@ -1463,7 +1387,6 @@ 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);
@@ -1522,17 +1445,6 @@ 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);
} }
@@ -1705,11 +1617,9 @@ 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)
new_page(dd);
dd->in_row = true; if ((dd->y - row->height) < dd->art_box.y1)
pdfioContentBeginMarked(dd->st, "TR", /*dict*/NULL); new_page(dd);
if (mmdGetType(row->cells[0]) == MMD_TYPE_TABLE_HEADER_CELL) if (mmdGetType(row->cells[0]) == MMD_TYPE_TABLE_HEADER_CELL)
{ {
@@ -1741,9 +1651,6 @@ render_row(docdata_t *dd, // I - Document data
} }
dd->y = row_y - row->height; dd->y = row_y - row->height;
pdfioContentEndMarked(dd->st);
dd->in_row = false;
} }

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
// //
// Public content header file for PDFio. // Public content header file for PDFio.
// //
// Copyright © 2021-2025 by Michael R Sweet. // Copyright © 2021-2023 by Michael R Sweet.
// //
// Licensed under Apache License v2.0. See the file "LICENSE" for more // Licensed under Apache License v2.0. See the file "LICENSE" for more
// information. // information.
@@ -23,8 +23,7 @@ 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
@@ -69,10 +68,8 @@ extern pdfio_array_t *pdfioArrayCreateColorFromPrimaries(pdfio_file_t *pdf, size
extern pdfio_array_t *pdfioArrayCreateColorFromStandard(pdfio_file_t *pdf, size_t num_colors, pdfio_cs_t cs); 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;
@@ -130,9 +127,7 @@ extern bool pdfioContentTextShowf(pdfio_stream_t *st, bool unicode, const char
extern bool pdfioContentTextShowJustified(pdfio_stream_t *st, bool unicode, size_t num_fragments, const double *offsets, const char * const *fragments) _PDFIO_PUBLIC; 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;

View File

@@ -8,7 +8,6 @@
// //
#include "pdfio-private.h" #include "pdfio-private.h"
#include "pdfio-content.h"
#ifndef O_BINARY #ifndef O_BINARY
# define O_BINARY 0 # define O_BINARY 0
#endif // !O_BINARY #endif // !O_BINARY
@@ -22,13 +21,11 @@ static pdfio_obj_t *add_obj(pdfio_file_t *pdf, size_t number, unsigned short gen
static int compare_objmaps(_pdfio_objmap_t *a, _pdfio_objmap_t *b); static int compare_objmaps(_pdfio_objmap_t *a, _pdfio_objmap_t *b);
static pdfio_file_t *create_common(const char *filename, int fd, pdfio_output_cb_t output_cb, void *output_cbdata, const char *version, pdfio_rect_t *media_box, pdfio_rect_t *crop_box, pdfio_error_cb_t error_cb, void *error_cbdata); static pdfio_file_t *create_common(const char *filename, int fd, pdfio_output_cb_t output_cb, void *output_cbdata, const char *version, pdfio_rect_t *media_box, pdfio_rect_t *crop_box, pdfio_error_cb_t error_cb, void *error_cbdata);
static const char *get_info_string(pdfio_file_t *pdf, const char *key); static const char *get_info_string(pdfio_file_t *pdf, const char *key);
static char *get_iso_date(time_t t, char *buffer, size_t bufsize);
static struct lconv *get_lconv(void); static struct lconv *get_lconv(void);
static bool load_obj_stream(pdfio_obj_t *obj); static bool load_obj_stream(pdfio_obj_t *obj);
static bool load_pages(pdfio_file_t *pdf, pdfio_obj_t *obj, size_t depth); static bool load_pages(pdfio_file_t *pdf, pdfio_obj_t *obj, size_t depth);
static bool load_xref(pdfio_file_t *pdf, off_t xref_offset, pdfio_password_cb_t password_cb, void *password_data); static bool load_xref(pdfio_file_t *pdf, off_t xref_offset, pdfio_password_cb_t password_cb, void *password_data);
static bool repair_xref(pdfio_file_t *pdf, pdfio_password_cb_t password_cb, void *password_data); static bool repair_xref(pdfio_file_t *pdf, pdfio_password_cb_t password_cb, void *password_data);
static bool write_metadata(pdfio_file_t *pdf);
static bool write_pages(pdfio_file_t *pdf); static bool write_pages(pdfio_file_t *pdf);
static bool write_trailer(pdfio_file_t *pdf); static bool write_trailer(pdfio_file_t *pdf);
@@ -127,11 +124,7 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
{ {
ret = false; ret = false;
// Add default OutputIntent for PDF/A CMYK printing... if (pdfioObjClose(pdf->info_obj) && write_pages(pdf) && pdfioObjClose(pdf->root_obj) && write_trailer(pdf))
pdfioFileAddOutputIntent(pdf, /*subtype*/"GTS_PDFA1", /*condition*/"CMYK", /*cond_id*/"CGATS001", /*reg_name*/NULL, /*info*/"CMYK Printing", /*profile*/NULL);
// Close and write out the last bits...
if (write_metadata(pdf) && pdfioObjClose(pdf->info_obj) && write_pages(pdf) && pdfioObjClose(pdf->root_obj) && write_trailer(pdf))
ret = _pdfioFileFlush(pdf); ret = _pdfioFileFlush(pdf);
} }
@@ -181,20 +174,8 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
// name of the PDF file to create. // name of the PDF file to create.
// //
// The "version" argument specifies the PDF version number for the file or // The "version" argument specifies the PDF version number for the file or
// `NULL` for the default ("2.0"). The following values are recognized: // `NULL` for the default ("2.0"). The value "PCLm-1.0" can be specified to
// // produce the PCLm subset of PDF.
// - "1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
// specified versions.
// - "PCLm-1.0": The PCLm (raster) subset of PDF supported by some printers.
// - "PDF/A-1a": PDF/A-1a:2005
// - "PDF/A-1b": PDF/A-1b:2005
// - "PDF/A-2a": PDF/A-2a:2011
// - "PDF/A-2b": PDF/A-2b:2011
// - "PDF/A-2u": PDF/A-2u:2011
// - "PDF/A-3a": PDF/A-3a:2012
// - "PDF/A-3b": PDF/A-3b:2012
// - "PDF/A-3u": PDF/A-3u:2012
// - "PDF/A-4": PDF/A-4:2020
// //
// 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 `NULL` then a default "Universal" size // CropBox for pages in the PDF file - if `NULL` then a default "Universal" size
@@ -202,22 +183,8 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
// //
// 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 `NULL` then the default error handler is used that // and its data pointer - if `NULL` then the default error handler is used that
// writes error and warning messages to `stderr`. The error handler callback // writes error messages to `stderr`. The error handler callback should return
// should return `true` to continue writing the PDF file or `false` to stop. // `true` to continue writing the PDF file or `false` to stop.
// For example:
//
// ```
// 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: %s\n", pdfioFileGetName(pdf), message);
//
// /* Return true to continue on warning messages, false otherwise... */
// return (!strncmp(message, "WARNING:", 8));
// }
// ```
// //
pdfio_file_t * // O - PDF file or `NULL` on error pdfio_file_t * // O - PDF file or `NULL` on error
@@ -445,22 +412,9 @@ _pdfioFileCreateObj(
// ``` // ```
// //
// The "version" argument specifies the PDF version number for the file or // The "version" argument specifies the PDF version number for the file or
// `NULL` for the default ("2.0"). The following values are recognized: // `NULL` for the default ("2.0"). Unlike @link pdfioFileCreate@ and
// // @link pdfioFileCreateTemporary@, it is generally not safe to pass the
// - "1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the // "PCLm-1.0" version string.
// specified versions.
// - "PDF/A-1a": PDF/A-1a:2005
// - "PDF/A-1b": PDF/A-1b:2005
// - "PDF/A-2a": PDF/A-2a:2011
// - "PDF/A-2b": PDF/A-2b:2011
// - "PDF/A-2u": PDF/A-2u:2011
// - "PDF/A-3a": PDF/A-3a:2012
// - "PDF/A-3b": PDF/A-3b:2012
// - "PDF/A-3u": PDF/A-3u:2012
// - "PDF/A-4": PDF/A-4:2020
//
// Unlike @link pdfioFileCreate@ and @link pdfioFileCreateTemporary@, it is
// generally not safe to pass the "PCLm-1.0" version string.
// //
// 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 `NULL` then a default "Universal" size // CropBox for pages in the PDF file - if `NULL` then a default "Universal" size
@@ -468,22 +422,8 @@ _pdfioFileCreateObj(
// //
// 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 `NULL` then the default error handler is used that // and its data pointer - if `NULL` then the default error handler is used that
// writes error and warning messages to `stderr`. The error handler callback // writes error messages to `stderr`. The error handler callback should return
// should return `true` to continue writing the PDF file or `false` to stop. // `true` to continue writing the PDF file or `false` to stop.
// For example:
//
// ```
// 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: %s\n", pdfioFileGetName(pdf), message);
//
// /* Return true to continue on warning messages, false otherwise... */
// return (!strncmp(message, "WARNING:", 8));
// }
// ```
// //
// > *Note*: Files created using this API are slightly larger than those // > *Note*: Files created using this API are slightly larger than those
// > created using the @link pdfioFileCreate@ function since stream lengths are // > created using the @link pdfioFileCreate@ function since stream lengths are
@@ -541,9 +481,8 @@ pdfioFileCreatePage(pdfio_file_t *pdf, // I - PDF file
pdfioDictSetObj(dict, "Parent", pdf->pages_obj); pdfioDictSetObj(dict, "Parent", pdf->pages_obj);
pdfioPageDictAddColorSpace(dict, "DefaultGray", pdfioArrayCreateColorFromStandard(pdf, 1, PDFIO_CS_SRGB)); if (!_pdfioDictGetValue(dict, "Resources"))
pdfioPageDictAddColorSpace(dict, "DefaultRGB", pdfioArrayCreateColorFromStandard(pdf, 3, PDFIO_CS_SRGB)); pdfioDictSetDict(dict, "Resources", pdfioDictCreate(pdf));
pdfioPageDictAddColorSpace(dict, "DefaultCMYK", pdfioArrayCreateColorFromStandard(pdf, 4, PDFIO_CS_CGATS001));
if (!_pdfioDictGetValue(dict, "Type")) if (!_pdfioDictGetValue(dict, "Type"))
pdfioDictSetName(dict, "Type", "Page"); pdfioDictSetName(dict, "Type", "Page");
@@ -616,20 +555,8 @@ pdfioFileCreateStringObj(
// will have a ".pdf" extension. // will have a ".pdf" extension.
// //
// The "version" argument specifies the PDF version number for the file or // The "version" argument specifies the PDF version number for the file or
// `NULL` for the default ("2.0"). The following values are recognized: // `NULL` for the default ("2.0"). The value "PCLm-1.0" can be specified to
// // produce the PCLm subset of PDF.
// - "1.3", "1.4", "1.5", "1.6", "1.7", "2.0": Generic PDF files of the
// specified versions.
// - "PCLm-1.0": The PCLm (raster) subset of PDF supported by some printers.
// - "PDF/A-1a": PDF/A-1a:2005
// - "PDF/A-1b": PDF/A-1b:2005
// - "PDF/A-2a": PDF/A-2a:2011
// - "PDF/A-2b": PDF/A-2b:2011
// - "PDF/A-2u": PDF/A-2u:2011
// - "PDF/A-3a": PDF/A-3a:2012
// - "PDF/A-3b": PDF/A-3b:2012
// - "PDF/A-3u": PDF/A-3u:2012
// - "PDF/A-4": PDF/A-4:2020
// //
// 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 `NULL` then a default "Universal" size // CropBox for pages in the PDF file - if `NULL` then a default "Universal" size
@@ -906,24 +833,6 @@ pdfioFileGetKeywords(pdfio_file_t *pdf) // I - PDF file
} }
//
// 'pdfioFileGetLanguage()' - Get the language metadata for a PDF file.
//
// 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.
//
// @since PDFio 1.6@
//
const char * // O - Language or `NULL` for none
pdfioFileGetLanguage(pdfio_file_t *pdf) // I - PDF file
{
return (pdfioDictGetString(pdfioFileGetCatalog(pdf), "Lang"));
}
// //
// 'pdfioFileGetModificationDate()' - Get the most recent modification date for a PDF file. // 'pdfioFileGetModificationDate()' - Get the most recent modification date for a PDF file.
// //
@@ -1088,22 +997,8 @@ pdfioFileGetVersion(
// //
// 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 `NULL` then the default error handler is used that // and its data pointer - if `NULL` then the default error handler is used that
// writes error and warning messages to `stderr`. The error handler callback // writes error messages to `stderr`. The error handler callback should return
// should return `true` to continue reading the PDF file or `false` to stop. // `true` to continue reading the PDF file or `false` to stop.
// For example:
//
// ```
// 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: %s\n", pdfioFileGetName(pdf), message);
//
// /* Return true to continue on warning messages, false otherwise... */
// return (!strncmp(message, "WARNING:", 8));
// }
// ```
// //
// > Note: Error messages starting with "WARNING:" are actually warning // > Note: Error messages starting with "WARNING:" are actually warning
// > messages - the callback should normally return `true` to allow PDFio to // > messages - the callback should normally return `true` to allow PDFio to
@@ -1151,9 +1046,8 @@ pdfioFileOpen(
char message[8192]; // Message string char message[8192]; // Message string
temp.filename = (char *)filename; temp.filename = (char *)filename;
snprintf(message, sizeof(message), "Unable to allocate memory for PDF file: %s", strerror(errno)); snprintf(message, sizeof(message), "Unable to allocate memory for PDF file - %s", strerror(errno));
(error_cb)(&temp, message, error_cbdata); (error_cb)(&temp, message, error_cbdata);
return (NULL); return (NULL);
} }
@@ -1309,26 +1203,6 @@ pdfioFileSetKeywords(
} }
//
// 'pdfioFileSetLanguage()' - Set the language metadata for a PDF file.
//
// 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.
//
// @since PDFio 1.6@
//
void
pdfioFileSetLanguage(
pdfio_file_t *pdf, // I - PDF file
const char *value) // I - Value
{
pdfioDictSetString(pdfioFileGetCatalog(pdf), "Lang", value);
}
// //
// 'pdfioFileSetModificationDate()' - Set the modification date for a PDF file. // 'pdfioFileSetModificationDate()' - Set the modification date for a PDF file.
// //
@@ -1366,26 +1240,21 @@ pdfioFileSetPermissions(
if (!pdf) if (!pdf)
return (false); return (false);
if (pdf->profile >= _PDFIO_PROFILE_PDFA_1A && pdf->profile <= _PDFIO_PROFILE_PDFA_4 && encryption != PDFIO_ENCRYPTION_NONE)
{
_pdfioFileError(pdf, "Encryption is not allowed for PDF/A files.");
return (false);
}
if (encryption == PDFIO_ENCRYPTION_NONE)
return (true);
if (pdf->num_objs > 3) // First three objects are pages, info, and root if (pdf->num_objs > 3) // First three objects are pages, info, and root
{ {
_pdfioFileError(pdf, "You must call pdfioFileSetPermissions before adding any objects."); _pdfioFileError(pdf, "You must call pdfioFileSetPermissions before adding any objects.");
return (false); return (false);
} }
if (encryption == PDFIO_ENCRYPTION_NONE)
return (true);
pdf->encrypt_metadata = true; pdf->encrypt_metadata = true;
return (_pdfioCryptoLock(pdf, permissions, encryption, owner_password, user_password)); return (_pdfioCryptoLock(pdf, permissions, encryption, owner_password, user_password));
} }
// //
// 'pdfioFileSetSubject()' - Set the subject for a PDF file. // 'pdfioFileSetSubject()' - Set the subject for a PDF file.
// //
@@ -1557,7 +1426,6 @@ create_common(
unsigned char id_value[16]; // File ID value unsigned char id_value[16]; // File ID value
time_t curtime; // Creation date/time time_t curtime; // Creation date/time
_pdfio_sha256_t ctx; // Hashing context _pdfio_sha256_t ctx; // Hashing context
const char *file_version; // PDF file version string
PDFIO_DEBUG("create_common(filename=\"%s\", fd=%d, output_cb=%p, output_cbdata=%p, version=\"%s\", media_box=%p, crop_box=%p, error_cb=%p, error_cbdata=%p)\n", filename, fd, (void *)output_cb, (void *)output_cbdata, version, (void *)media_box, (void *)crop_box, (void *)error_cb, (void *)error_cbdata); PDFIO_DEBUG("create_common(filename=\"%s\", fd=%d, output_cb=%p, output_cbdata=%p, version=\"%s\", media_box=%p, crop_box=%p, error_cb=%p, error_cbdata=%p)\n", filename, fd, (void *)output_cb, (void *)output_cbdata, version, (void *)media_box, (void *)crop_box, (void *)error_cb, (void *)error_cbdata);
@@ -1566,6 +1434,9 @@ create_common(
if (!filename || (fd < 0 && !output_cb)) if (!filename || (fd < 0 && !output_cb))
return (NULL); return (NULL);
if (!version)
version = "2.0";
if (!error_cb) if (!error_cb)
{ {
error_cb = _pdfioFileDefaultError; error_cb = _pdfioFileDefaultError;
@@ -1591,58 +1462,7 @@ create_common(
pdf->output_cb = output_cb; pdf->output_cb = output_cb;
pdf->output_ctx = output_cbdata; pdf->output_ctx = output_cbdata;
pdf->filename = strdup(filename); pdf->filename = strdup(filename);
pdf->version = strdup(!strncmp(version, "PCLm-", 5) ? "1.4" : version);
if (!version)
version = "2.0";
if (!strncmp(version, "PDF/A-1", 7))
{
file_version = "1.4";
if (version[7] == 'a')
pdf->profile = _PDFIO_PROFILE_PDFA_1A;
else
pdf->profile = _PDFIO_PROFILE_PDFA_1B; // Default to 'b'
}
else if (!strncmp(version, "PDF/A-2", 7))
{
file_version = "1.7";
if (version[7] == 'a')
pdf->profile = _PDFIO_PROFILE_PDFA_2A;
else if (version[7] == 'u')
pdf->profile = _PDFIO_PROFILE_PDFA_2U;
else
pdf->profile = _PDFIO_PROFILE_PDFA_2B; // Default to 'b'
}
else if (!strncmp(version, "PDF/A-3", 7))
{
file_version = "1.7";
if (version[7] == 'a')
pdf->profile = _PDFIO_PROFILE_PDFA_3A;
else if (version[7] == 'u')
pdf->profile = _PDFIO_PROFILE_PDFA_3U;
else
pdf->profile = _PDFIO_PROFILE_PDFA_3B; // Default to 'b'
}
else if (!strncmp(version, "PDF/A-4", 7))
{
file_version = "2.0";
pdf->profile = _PDFIO_PROFILE_PDFA_4;
}
else if (!strncmp(version, "PCLm-", 5))
{
file_version = "1.4";
pdf->profile = _PDFIO_PROFILE_PCLM;
}
else
{
file_version = version;
pdf->profile = _PDFIO_PROFILE_NONE;
}
pdf->version = strdup(file_version);
pdf->mode = _PDFIO_MODE_WRITE; pdf->mode = _PDFIO_MODE_WRITE;
pdf->error_cb = error_cb; pdf->error_cb = error_cb;
pdf->error_data = error_cbdata; pdf->error_data = error_cbdata;
@@ -1672,13 +1492,13 @@ create_common(
pdf->crop_box.y2 = 11.0f * 72.0f; pdf->crop_box.y2 = 11.0f * 72.0f;
} }
// Write the PDF header (special case for PCLm, otherwise standard header) // Write a standard PDF header...
if (pdf->profile == _PDFIO_PROFILE_PCLM) if (!strncmp(version, "PCLm-", 5))
{ {
if (!_pdfioFilePrintf(pdf, "%%PDF-1.4\n%%%s\n", version)) if (!_pdfioFilePrintf(pdf, "%%PDF-1.4\n%%%s\n", version))
goto error; goto error;
} }
else if (!_pdfioFilePrintf(pdf, "%%PDF-%s\n%%\342\343\317\323\n", pdf->version)) else if (!_pdfioFilePrintf(pdf, "%%PDF-%s\n%%\342\343\317\323\n", version))
{ {
goto error; goto error;
} }
@@ -1764,32 +1584,6 @@ get_info_string(pdfio_file_t *pdf, // I - PDF file
} }
//
// 'get_iso_date()' - Convert a time_t value to an ISO 8601 date/time value.
//
static char * // O - Date string
get_iso_date(time_t t, // I - Time value in seconds
char *buffer, // I - Date buffer
size_t bufsize) // I - Size of date buffer
{
struct tm d; // Date values
// Convert time to UTC date
#if _WIN32
gmtime_s(&d, &t);
#else
gmtime_r(&t, &d);
#endif // _WIN32
// Format the string and return...
snprintf(buffer, bufsize, "%04d-%02d-%02dT%02d:%02d:%02dZ", d.tm_year + 1900, d.tm_mon + 1, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec);
return (buffer);
}
// //
// 'get_lconv()' - Get any locale-specific numeric information. // 'get_lconv()' - Get any locale-specific numeric information.
// //
@@ -2715,119 +2509,6 @@ repair_xref(
} }
//
// 'write_metadata()' - Write an XMP metadata stream.
//
static bool // O - `true` on success, `false` on failure
write_metadata(pdfio_file_t *pdf) // I - PDF file
{
pdfio_dict_t *dict; // Info/XMP object dictionary
pdfio_obj_t *obj; // XMP object
pdfio_stream_t *st; // XMP stream
bool status = true; // Write status
const char *value; // Value from info dictionary
time_t t; // Date/time value in seconds
char d[64]; // Date/time string (ISO 8601)
// Create the Metadata object...
if ((dict = pdfioDictCreate(pdf)) == NULL)
return (false);
pdfioDictSetName(dict, "Type", "Metadata");
pdfioDictSetName(dict, "Subtype", "XML");
if ((obj = pdfioFileCreateObj(pdf, dict)) == NULL)
return (false);
// Write the XMP stream...
if ((st = pdfioObjCreateStream(obj, PDFIO_FILTER_NONE)) == NULL)
return (false);
status &= pdfioStreamPuts(st, "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n");
status &= pdfioStreamPuts(st, "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\">\n");
status &= pdfioStreamPuts(st, " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n");
status &= pdfioStreamPuts(st, " <rdf:Description rdf:about=\"\" xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\">\n");
t = pdfioFileGetCreationDate(pdf);
status &= pdfioStreamPrintf(st, " <xmp:CreateDate>%H</xmp:CreateDate>\n", get_iso_date(t, d, sizeof(d)));
if ((value = pdfioFileGetCreator(pdf)) != NULL)
status &= pdfioStreamPrintf(st, " <xmp:CreatorTool>%H</xmp:CreatorTool>\n", value);
status &= pdfioStreamPrintf(st, " <xmp:MetadataDate>%H</xmp:MetadataDate>\n", d);
if ((t = pdfioFileGetModificationDate(pdf)) > 0)
status &= pdfioStreamPrintf(st, " <xmp:ModifyDate>%H</xmp:ModifyDate>\n", get_iso_date(t, d, sizeof(d)));
status &= pdfioStreamPuts(st, " </rdf:Description>\n");
status &= pdfioStreamPuts(st, " <rdf:Description rdf:about=\"\" xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n");
status &= pdfioStreamPrintf(st, " <pdf:Producer>%H</pdf:Producer>\n", pdfioFileGetProducer(pdf));
if ((value = pdfioFileGetKeywords(pdf)) != NULL)
status &= pdfioStreamPrintf(st, " <pdf:Keywords>%H</pdf:Keywords>\n", value);
status &= pdfioStreamPuts(st, " </rdf:Description>\n");
status &= pdfioStreamPuts(st, " <rdf:Description rdf:about=\"\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n");
status &= pdfioStreamPrintf(st, " <dc:format>application/pdf</dc:format>\n");
if ((value = pdfioFileGetTitle(pdf)) != NULL)
status &= pdfioStreamPrintf(st, " <dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">%H</rdf:li></rdf:Alt></dc:title>\n", value);
if ((value = pdfioFileGetAuthor(pdf)) != NULL)
status &= pdfioStreamPrintf(st, " <dc:creator><rdf:Seq><rdf:li>%H</rdf:li></rdf:Seq></dc:creator>\n", value);
if ((value = pdfioFileGetSubject(pdf)) != NULL)
status &= pdfioStreamPrintf(st, " <dc:description><rdf:Alt><rdf:li xml:lang=\"x-default\">%H</rdf:li></rdf:Alt></dc:description>\n", value);
status &= pdfioStreamPuts(st, " </rdf:Description>\n");
if (pdf->profile >= _PDFIO_PROFILE_PDFA_1A && pdf->profile <= _PDFIO_PROFILE_PDFA_4)
{
static const char * const pdfa_versions[] =
{
"1A", // _PDFIO_PROFILE_PDFA_1A
"1B", // _PDFIO_PROFILE_PDFA_1B
"2A", // _PDFIO_PROFILE_PDFA_2A
"2B", // _PDFIO_PROFILE_PDFA_2B
"2U", // _PDFIO_PROFILE_PDFA_2U
"3A", // _PDFIO_PROFILE_PDFA_3A
"3B", // _PDFIO_PROFILE_PDFA_3B
"3U", // _PDFIO_PROFILE_PDFA_3U
"4", // _PDFIO_PROFILE_PDFA_4
};
const char *info = pdfa_versions[pdf->profile - _PDFIO_PROFILE_PDFA_1A];
status &= pdfioStreamPuts(st, " <rdf:Description rdf:about=\"\" xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n");
status &= pdfioStreamPrintf(st, " <pdfaid:part>%c</pdfaid:part>\n", *info);
if (info[1])
status &= pdfioStreamPrintf(st, " <pdfaid:conformance>%s</pdfaid:conformance>\n", info + 1);
status &= pdfioStreamPuts(st, " </rdf:Description>\n");
}
status &= pdfioStreamPuts(st, " </rdf:RDF>\n");
status &= pdfioStreamPuts(st, "</x:xmpmeta>\n");
status &= pdfioStreamPuts(st, "<?xpacket end=\"r\"?>\n");
status &= pdfioStreamClose(st);
if (!status)
return (false);
// If we get this far, add the Metadata key/value to the catalog/root object.
if (!pdfioDictSetObj(pdfioFileGetCatalog(pdf), "Metadata", obj))
return (false);
// Finally, remove deprecated info key/value pairs for PDF/2.0...
if (!strcmp(pdf->version, "2.0") && (dict = pdfioObjGetDict(pdf->info_obj)) != NULL)
{
pdfioDictClear(dict, "Author");
pdfioDictClear(dict, "Creator");
pdfioDictClear(dict, "Keywords");
pdfioDictClear(dict, "Producer");
pdfioDictClear(dict, "Subject");
pdfioDictClear(dict, "Title");
pdfioDictClear(dict, "Trapped");
}
return (true);
}
// //
// 'write_pages()' - Write the PDF pages objects. // 'write_pages()' - Write the PDF pages objects.
// //

View File

@@ -117,21 +117,6 @@ typedef enum _pdfio_predictor_e // PNG predictor constants
_PDFIO_PREDICTOR_PNG_AUTO = 15 // PNG "auto" predictor (currently mapped to Paeth) _PDFIO_PREDICTOR_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);
@@ -254,7 +239,6 @@ struct _pdfio_file_s // PDF file structure
unsigned char file_id[32]; // File identifier bytes 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
@@ -284,12 +268,10 @@ struct _pdfio_file_s // PDF file structure
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; // De/Encryption object/dictionary
pdfio_obj_t *cgats001_obj, // CGATS001 ICC profile object pdfio_obj_t *cp1252_obj, // CP1252 font encoding 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? 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

View File

@@ -848,7 +848,7 @@ pdfioStreamWrite(
*pptr; // Previous raw buffer *pptr; // Previous raw buffer
PDFIO_DEBUG("pdfioStreamWrite(st=%p, buffer=%p, bytes=%lu)\n", (void *)st, buffer, (unsigned long)bytes); PDFIO_DEBUG("pdfioStreamWrite(st=%p, buffer=%p, bytes=%lu)\n", (void *)st, (void *)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)

View File

@@ -23,9 +23,9 @@ extern "C" {
// Version numbers... // Version numbers...
// //
# define PDFIO_VERSION "1.6.0" # define PDFIO_VERSION "1.5.4"
# define PDFIO_VERSION_MAJOR 1 # define PDFIO_VERSION_MAJOR 1
# define PDFIO_VERSION_MINOR 6 # define PDFIO_VERSION_MINOR 5
// //
@@ -201,7 +201,6 @@ extern time_t pdfioFileGetCreationDate(pdfio_file_t *pdf) _PDFIO_PUBLIC;
extern const char *pdfioFileGetCreator(pdfio_file_t *pdf) _PDFIO_PUBLIC; extern 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;
@@ -218,7 +217,6 @@ extern void pdfioFileSetAuthor(pdfio_file_t *pdf, const char *value) _PDFIO_PUB
extern void pdfioFileSetCreationDate(pdfio_file_t *pdf, time_t value) _PDFIO_PUBLIC; extern void 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;

View File

@@ -353,14 +353,12 @@
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;
@@ -392,11 +390,8 @@
"DEBUG=1", "DEBUG=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;
@@ -404,7 +399,6 @@
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;
@@ -439,14 +433,12 @@
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;
@@ -476,10 +468,8 @@
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
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;
@@ -487,7 +477,6 @@
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;
@@ -505,10 +494,15 @@
273440B5263D6FE200FBFD63 /* Debug */ = { 273440B5263D6FE200FBFD63 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = RU58A2256H; DEVELOPMENT_TEAM = RU58A2256H;
EXECUTABLE_PREFIX = lib; EXECUTABLE_PREFIX = lib;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };
@@ -517,10 +511,14 @@
273440B6263D6FE200FBFD63 /* Release */ = { 273440B6263D6FE200FBFD63 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = RU58A2256H; DEVELOPMENT_TEAM = RU58A2256H;
EXECUTABLE_PREFIX = lib; EXECUTABLE_PREFIX = lib;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };
@@ -529,6 +527,8 @@
273440D5263D72AE00FBFD63 /* Debug */ = { 273440D5263D72AE00FBFD63 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
@@ -536,6 +536,9 @@
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = org.msweet.testpdfio; PRODUCT_BUNDLE_IDENTIFIER = org.msweet.testpdfio;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -546,11 +549,15 @@
273440D6263D72AE00FBFD63 /* Release */ = { 273440D6263D72AE00FBFD63 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES;
CLANG_WARN_IMPLICIT_FALLTHROUGH = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = org.msweet.testpdfio; PRODUCT_BUNDLE_IDENTIFIER = org.msweet.testpdfio;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -1,23 +1,9 @@
LIBRARY pdfio1 LIBRARY pdfio1
VERSION 1.6 VERSION 1.5
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
@@ -26,53 +12,9 @@ _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
@@ -101,10 +43,8 @@ pdfioArrayGetSize
pdfioArrayGetString pdfioArrayGetString
pdfioArrayGetType pdfioArrayGetType
pdfioArrayRemove pdfioArrayRemove
pdfioContentBeginMarked
pdfioContentClip pdfioContentClip
pdfioContentDrawImage pdfioContentDrawImage
pdfioContentEndMarked
pdfioContentFill pdfioContentFill
pdfioContentFillAndStroke pdfioContentFillAndStroke
pdfioContentMatrixConcat pdfioContentMatrixConcat
@@ -158,8 +98,8 @@ pdfioContentTextNewLineShow
pdfioContentTextNewLineShowf pdfioContentTextNewLineShowf
pdfioContentTextNextLine pdfioContentTextNextLine
pdfioContentTextShow pdfioContentTextShow
pdfioContentTextShowf
pdfioContentTextShowJustified pdfioContentTextShowJustified
pdfioContentTextShowf
pdfioDictClear pdfioDictClear
pdfioDictCopy pdfioDictCopy
pdfioDictCreate pdfioDictCreate
@@ -170,8 +110,8 @@ pdfioDictGetDate
pdfioDictGetDict pdfioDictGetDict
pdfioDictGetKey pdfioDictGetKey
pdfioDictGetName pdfioDictGetName
pdfioDictGetNumber
pdfioDictGetNumPairs pdfioDictGetNumPairs
pdfioDictGetNumber
pdfioDictGetObj pdfioDictGetObj
pdfioDictGetRect pdfioDictGetRect
pdfioDictGetString pdfioDictGetString
@@ -189,12 +129,10 @@ pdfioDictSetObj
pdfioDictSetRect pdfioDictSetRect
pdfioDictSetString pdfioDictSetString
pdfioDictSetStringf pdfioDictSetStringf
pdfioFileAddOutputIntent
pdfioFileClose pdfioFileClose
pdfioFileCreate pdfioFileCreate
pdfioFileCreateArrayObj pdfioFileCreateArrayObj
pdfioFileCreateFontObjFromBase pdfioFileCreateFontObjFromBase
pdfioFileCreateFontObjFromData
pdfioFileCreateFontObjFromFile pdfioFileCreateFontObjFromFile
pdfioFileCreateICCObjFromData pdfioFileCreateICCObjFromData
pdfioFileCreateICCObjFromFile pdfioFileCreateICCObjFromFile
@@ -214,7 +152,6 @@ pdfioFileGetCreationDate
pdfioFileGetCreator pdfioFileGetCreator
pdfioFileGetID pdfioFileGetID
pdfioFileGetKeywords pdfioFileGetKeywords
pdfioFileGetLanguage
pdfioFileGetModificationDate pdfioFileGetModificationDate
pdfioFileGetName pdfioFileGetName
pdfioFileGetNumObjs pdfioFileGetNumObjs
@@ -231,7 +168,6 @@ pdfioFileSetAuthor
pdfioFileSetCreationDate pdfioFileSetCreationDate
pdfioFileSetCreator pdfioFileSetCreator
pdfioFileSetKeywords pdfioFileSetKeywords
pdfioFileSetLanguage
pdfioFileSetModificationDate pdfioFileSetModificationDate
pdfioFileSetPermissions pdfioFileSetPermissions
pdfioFileSetSubject pdfioFileSetSubject

View File

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

View File

@@ -3,7 +3,7 @@
<metadata> <metadata>
<id>pdfio_native.redist</id> <id>pdfio_native.redist</id>
<title>PDFio Library for VS2019+</title> <title>PDFio Library for VS2019+</title>
<version>1.6.0</version> <version>1.5.4</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>

View File

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

282
test.h
View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
// //
// https://github.com/michaelrsweet/ttf // https://github.com/michaelrsweet/ttf
// //
// Copyright © 2018-2025 by Michael R Sweet. // Copyright © 2018-2024 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,10 +14,6 @@
// //
#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"
@@ -85,13 +81,9 @@ 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
@@ -228,9 +220,6 @@ 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
{ {
@@ -311,86 +300,6 @@ 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);
} }

584
ttf.c
View File

@@ -10,7 +10,7 @@
// //
#ifdef _WIN32 #ifdef _WIN32
# define _CRT_SECURE_NO_WARNINGS 1 # define _CRT_SECURE_NO_WARNINGS
#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(f,o,w) (off_t)_lseek((f),(long)(o),(w)) # define lseek _lseek
# define mkdir(d,p) _mkdir(d) # define mkdir(d,p) _mkdir(d)
# define open _open # define open _open
# define read(f,b,s) _read((f),(b),(unsigned)(s)) # define read _read
# 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(f,b,s) _write((f),(b),(unsigned)(s)) # define write _write
// //
// Map various parameters for POSIX... // Map various parameters for POSIX...
@@ -177,19 +177,9 @@ 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
{ {
_ttf_read_cb_t read_cb; // Read callback int fd; // File descriptor
_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
@@ -255,10 +245,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
@@ -292,12 +282,7 @@ 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);
@@ -344,6 +329,15 @@ 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
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, (void *)err_cb, err_data); TTF_DEBUG("ttfCreate(filename=\"%s\", idx=%u, err_cb=%p, err_data=%p)\n", filename, (unsigned)idx, (void *)err_cb, err_data);
// Range check input.. // Range check input..
@@ -353,57 +347,178 @@ ttfCreate(const char *filename, // I - Filename
return (NULL); return (NULL);
} }
// Open and return the font... // Allocate memory...
return (create_font(filename, /*data*/NULL, /*datasize*/0, idx, err_cb, err_data)); if ((font = (ttf_t *)calloc(1, sizeof(ttf_t))) == NULL)
}
//
// '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;
} }
// Open and return the font... TTF_DEBUG("ttfCreate: fd=%d\n", font->fd);
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);
} }
@@ -422,8 +537,8 @@ ttfDelete(ttf_t *font) // I - Font
return; return;
// Close the font file... // Close the font file...
if (font->file_fd >= 0) if (font->fd >= 0)
close(font->file_fd); close(font->fd);
// Free all memory used... // Free all memory used...
free(font->copyright); free(font->copyright);
@@ -928,219 +1043,6 @@ 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.
// //
@@ -1168,85 +1070,9 @@ errorf(ttf_t *font, // I - Font
} }
// /*
// 'fd_read_cb()' - Read from a file. * 'read_cmap()' - Read the cmap table, getting the Unicode mapping table.
// */
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
@@ -1393,7 +1219,7 @@ read_cmap(ttf_t *font) // I - Font
return (false); return (false);
} }
if ((font->read_cb)(font, bmap, font->num_cmap) != font->num_cmap) if (read(font->fd, bmap, font->num_cmap) != (ssize_t)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);
@@ -1792,9 +1618,6 @@ 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)
@@ -1817,18 +1640,15 @@ 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);
if ((temp = read_ushort(font)) < 0) hhea->numberOfHMetrics = (unsigned short)read_ushort(font);
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
@@ -1954,7 +1774,7 @@ read_names(ttf_t *font) // I - Font
length -= (unsigned)offset; length -= (unsigned)offset;
if ((font->read_cb)(font, font->names.storage, length) == 0) if (read(font->fd, 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);
@@ -2003,7 +1823,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 ((font->read_cb)(font, panose, sizeof(panose)) != sizeof(panose)) if (read(font->fd, panose, sizeof(panose)) != (ssize_t)sizeof(panose))
return (false); return (false);
/* ulUnicodeRange1 */ read_ulong(font); /* ulUnicodeRange1 */ read_ulong(font);
/* ulUnicodeRange2 */ read_ulong(font); /* ulUnicodeRange2 */ read_ulong(font);
@@ -2065,7 +1885,7 @@ read_short(ttf_t *font) // I - Font
unsigned char buffer[2]; // Read buffer unsigned char buffer[2]; // Read buffer
if ((font->read_cb)(font, buffer, sizeof(buffer)) != sizeof(buffer)) if (read(font->fd, 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);
@@ -2138,7 +1958,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 (!(font->seek_cb)(font, temp + 4)) if (lseek(font->fd, temp + 4, SEEK_SET) < 0)
{ {
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);
@@ -2214,7 +2034,7 @@ read_ulong(ttf_t *font) // I - Font
unsigned char buffer[4]; // Read buffer unsigned char buffer[4]; // Read buffer
if ((font->read_cb)(font, buffer, sizeof(buffer)) != sizeof(buffer)) if (read(font->fd, 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]));
@@ -2231,7 +2051,7 @@ read_ushort(ttf_t *font) // I - Font
unsigned char buffer[2]; // Read buffer unsigned char buffer[2]; // Read buffer
if ((font->read_cb)(font, buffer, sizeof(buffer)) != sizeof(buffer)) if (read(font->fd, buffer, sizeof(buffer)) != sizeof(buffer))
return (EOF); return (EOF);
else else
return ((buffer[0] << 8) | buffer[1]); return ((buffer[0] << 8) | buffer[1]);
@@ -2258,7 +2078,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 ((font->seek_cb)(font, current->offset + offset)) if (lseek(font->fd, current->offset + offset, SEEK_SET) == (current->offset + offset))
{ {
// Successful seek... // Successful seek...
return (current->length - offset); return (current->length - offset);

3
ttf.h
View File

@@ -3,7 +3,7 @@
// //
// https://github.com/michaelrsweet/ttf // https://github.com/michaelrsweet/ttf
// //
// Copyright © 2018-2025 by Michael R Sweet. // Copyright © 2018-2024 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,7 +81,6 @@ 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);