mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-07-18 06:49:53 +02:00
Compare commits
14 Commits
f040cc41c2
...
v1.3.1
Author | SHA1 | Date | |
---|---|---|---|
986cc512cd | |||
c35ddbec00 | |||
e4e1c39578 | |||
1d4f77cab1 | |||
b035130cde | |||
d6d5813b04 | |||
6492f210cf | |||
207062a996 | |||
7d37abb0df | |||
0c1122b689 | |||
d4f8dd46b5 | |||
986c5f0438 | |||
a81907bdb9 | |||
63a7a2cdbd |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -60,3 +60,5 @@ jobs:
|
|||||||
run: nuget restore pdfio.sln
|
run: nuget restore pdfio.sln
|
||||||
- name: Build PDFio
|
- name: Build PDFio
|
||||||
run: msbuild pdfio.sln
|
run: msbuild pdfio.sln
|
||||||
|
- name: Test PDFio
|
||||||
|
run: .\runtests.bat x64\Debug
|
||||||
|
10
CHANGES.md
10
CHANGES.md
@ -2,9 +2,17 @@ Changes in PDFio
|
|||||||
================
|
================
|
||||||
|
|
||||||
|
|
||||||
v1.3.0 (Month DD, YYYY)
|
v1.3.1 (August 5, 2024)
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
- CVE 2024-42358: Updated TrueType font reader to avoid large memory
|
||||||
|
allocations.
|
||||||
|
- Fixed some documentation errors and added examples (Issue #68, Issue #69)
|
||||||
|
|
||||||
|
|
||||||
|
v1.3.0 (June 28, 2024)
|
||||||
|
----------------------
|
||||||
|
|
||||||
- Added `pdfioFileGetCatalog` API for accessing the root/catalog object of a
|
- Added `pdfioFileGetCatalog` API for accessing the root/catalog object of a
|
||||||
PDF file (Issue #67)
|
PDF file (Issue #67)
|
||||||
- Updated number support to avoid locale issues (Issue #61)
|
- Updated number support to avoid locale issues (Issue #61)
|
||||||
|
24
configure
vendored
24
configure
vendored
@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.71 for pdfio 1.3.0.
|
# Generated by GNU Autoconf 2.71 for pdfio 1.3.1.
|
||||||
#
|
#
|
||||||
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
|
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
|
||||||
#
|
#
|
||||||
@ -610,8 +610,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='pdfio'
|
PACKAGE_NAME='pdfio'
|
||||||
PACKAGE_TARNAME='pdfio'
|
PACKAGE_TARNAME='pdfio'
|
||||||
PACKAGE_VERSION='1.3.0'
|
PACKAGE_VERSION='1.3.1'
|
||||||
PACKAGE_STRING='pdfio 1.3.0'
|
PACKAGE_STRING='pdfio 1.3.1'
|
||||||
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
|
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
|
||||||
PACKAGE_URL='https://www.msweet.org/pdfio'
|
PACKAGE_URL='https://www.msweet.org/pdfio'
|
||||||
|
|
||||||
@ -1293,7 +1293,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.3.0 to adapt to many kinds of systems.
|
\`configure' configures pdfio 1.3.1 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@ -1359,7 +1359,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.3.0:";;
|
short | recursive ) echo "Configuration of pdfio 1.3.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@ -1456,7 +1456,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.3.0
|
pdfio configure 1.3.1
|
||||||
generated by GNU Autoconf 2.71
|
generated by GNU Autoconf 2.71
|
||||||
|
|
||||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
@ -1612,7 +1612,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.3.0, which was
|
It was created by pdfio $as_me 1.3.1, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
$ $0$ac_configure_args_raw
|
$ $0$ac_configure_args_raw
|
||||||
@ -2368,9 +2368,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
PDFIO_VERSION="1.3.0"
|
PDFIO_VERSION="1.3.1"
|
||||||
PDFIO_VERSION_MAJOR="`echo 1.3.0 | awk -F. '{print $1}'`"
|
PDFIO_VERSION_MAJOR="`echo 1.3.1 | awk -F. '{print $1}'`"
|
||||||
PDFIO_VERSION_MINOR="`echo 1.3.0 | awk -F. '{printf("%d\n",$2);}'`"
|
PDFIO_VERSION_MINOR="`echo 1.3.1 | awk -F. '{printf("%d\n",$2);}'`"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -4935,7 +4935,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.3.0, which was
|
This file was extended by pdfio $as_me 1.3.1, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@ -4991,7 +4991,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.3.0
|
pdfio config.status 1.3.1
|
||||||
configured by $0, generated by GNU Autoconf 2.71,
|
configured by $0, generated by GNU Autoconf 2.71,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ AC_PREREQ([2.70])
|
|||||||
|
|
||||||
|
|
||||||
dnl Package name and version...
|
dnl Package name and version...
|
||||||
AC_INIT([pdfio], [1.3.0], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
|
AC_INIT([pdfio], [1.3.1], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
|
||||||
|
|
||||||
PDFIO_VERSION="AC_PACKAGE_VERSION"
|
PDFIO_VERSION="AC_PACKAGE_VERSION"
|
||||||
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
|
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
|
||||||
|
159
doc/pdfio.3
159
doc/pdfio.3
@ -1,4 +1,4 @@
|
|||||||
.TH pdfio 3 "pdf read/write library" "2024-01-24" "pdf read/write library"
|
.TH pdfio 3 "pdf read/write library" "2024-08-05" "pdf read/write library"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
pdfio \- pdf read/write library
|
pdfio \- pdf read/write library
|
||||||
.SH Introduction
|
.SH Introduction
|
||||||
@ -361,7 +361,7 @@ pdfioStreamWrite writes a buffer of data to the stream
|
|||||||
.PP
|
.PP
|
||||||
The PDF content helper functions provide additional functions for writing specific PDF page stream commands.
|
The PDF content helper functions provide additional functions for writing specific PDF page stream commands.
|
||||||
.PP
|
.PP
|
||||||
When you are done writing the stream, call pdfioStreamCLose to close both the stream and the object.
|
When you are done writing the stream, call pdfioStreamClose to close both the stream and the object.
|
||||||
.SS PDF Content Helper Functions
|
.SS PDF Content Helper Functions
|
||||||
.PP
|
.PP
|
||||||
PDFio includes many helper functions for embedding or writing specific kinds of content to a PDF file. These functions can be roughly grouped into five categories:
|
PDFio includes many helper functions for embedding or writing specific kinds of content to a PDF file. These functions can be roughly grouped into five categories:
|
||||||
@ -787,6 +787,125 @@ 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
|
||||||
|
|
||||||
|
|
||||||
|
.SH Examples
|
||||||
|
.SS Read PDF Metadata
|
||||||
|
.PP
|
||||||
|
The following example function will open a PDF file and print the title, author, creation date, and number of pages:
|
||||||
|
.nf
|
||||||
|
|
||||||
|
#include <pdfio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
show_pdf_info(const char *filename)
|
||||||
|
{
|
||||||
|
pdfio_file_t *pdf;
|
||||||
|
time_t creation_date;
|
||||||
|
struct tm *creation_tm;
|
||||||
|
char creation_text[256];
|
||||||
|
|
||||||
|
|
||||||
|
// Open the PDF file with the default callbacks...
|
||||||
|
pdf = pdfioFileOpen(filename, /*password_cb*/NULL, /*password_cbdata*/NULL, /*error_cb*/NULL, /*error_cbdata*/NULL);
|
||||||
|
if (pdf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get the creation date and convert to a string...
|
||||||
|
creation_date = pdfioFileGetCreationDate(pdf);
|
||||||
|
creation_tm = localtime(&creation_date);
|
||||||
|
strftime(creation_text, sizeof(creation_text), "%c", &creation_tm);
|
||||||
|
|
||||||
|
// Print file information to stdout...
|
||||||
|
printf("%s:\\n", filename);
|
||||||
|
printf(" Title: %s\\n", pdfioFileGetTitle(pdf));
|
||||||
|
printf(" Author: %s\\n", pdfioFileGetAuthor(pdf));
|
||||||
|
printf(" Created On: %s\\n", creation_text);
|
||||||
|
printf(" Number Pages: %u\\n", (unsigned)pdfioFileGetNumPages(pdf));
|
||||||
|
|
||||||
|
// Close the PDF file...
|
||||||
|
pdfioFileClose(pdf);
|
||||||
|
}
|
||||||
|
.fi
|
||||||
|
.SS Create PDF File With Text and Image
|
||||||
|
.PP
|
||||||
|
The following example function will create a PDF file, embed a base font and the named JPEG or PNG image file, and then creates a page with the image centered on the page with the text centered below:
|
||||||
|
.nf
|
||||||
|
|
||||||
|
#include <pdfio.h>
|
||||||
|
#include <pdfio\-content.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
create_pdf_image_file(const char *pdfname, const char *imagename, const char *caption)
|
||||||
|
{
|
||||||
|
pdfio_file_t *pdf;
|
||||||
|
pdfio_obj_t *font;
|
||||||
|
pdfio_obj_t *image;
|
||||||
|
pdfio_dict_t *dict;
|
||||||
|
pdfio_stream_t *page;
|
||||||
|
double width, height;
|
||||||
|
double swidth, sheight;
|
||||||
|
double tx, ty;
|
||||||
|
|
||||||
|
|
||||||
|
// Create the PDF file...
|
||||||
|
pdf = pdfioFileCreate(pdfname, /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_cbdata*/NULL);
|
||||||
|
|
||||||
|
// Create a Courier base font for the caption
|
||||||
|
font = pdfioFileCreateFontObjFromBase(pdf, "Courier");
|
||||||
|
|
||||||
|
// Create an image object from the JPEG/PNG image file...
|
||||||
|
image = pdfioFileCreateImageObjFromFile(pdf, imagename, true);
|
||||||
|
|
||||||
|
// Create a page dictionary with the font and image...
|
||||||
|
dict = pdfioDictCreate(pdf);
|
||||||
|
pdfioPageDictAddFont(dict, "F1", font);
|
||||||
|
pdfioPageDictAddImage(dict, "IM1", image);
|
||||||
|
|
||||||
|
// Create the page and its content stream...
|
||||||
|
page = pdfioFileCreatePage(pdf, dict);
|
||||||
|
|
||||||
|
// Position and scale the image on the page...
|
||||||
|
width = pdfioImageGetWidth(image);
|
||||||
|
height = pdfioImageGetHeight(image);
|
||||||
|
|
||||||
|
// Default media_box is "universal" 595.28x792 points (8.27x11in or 210x279mm)
|
||||||
|
// Use margins of 36 points (0.5in or 12.7mm) with another 36 points for the
|
||||||
|
// caption underneath...
|
||||||
|
swidth = 595.28 \- 72.0;
|
||||||
|
sheight = swidth * height / width;
|
||||||
|
if (sheight > (792.0 \- 36.0 \- 72.0))
|
||||||
|
{
|
||||||
|
sheight = 792.0 \- 36.0 \- 72.0;
|
||||||
|
swidth = sheight * width / height;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx = 0.5 * (595.28 \- swidth);
|
||||||
|
ty = 0.5 * (792 \- 36 \- sheight);
|
||||||
|
|
||||||
|
pdfioContentDrawImage(page, "IM1", tx, ty + 36.0, swidth, sheight);
|
||||||
|
|
||||||
|
// Draw the caption in black...
|
||||||
|
pdfioContentSetFillColorDeviceGray(page, 0.0);
|
||||||
|
|
||||||
|
// Compute the starting point for the text \- Courier is monospaced with a
|
||||||
|
// nominal width of 0.6 times the text height...
|
||||||
|
tx = 0.5 * (595.28 \- 18.0 * 0.6 * strlen(caption));
|
||||||
|
|
||||||
|
// Position and draw the caption underneath...
|
||||||
|
pdfioContentTextBegin(page);
|
||||||
|
pdfioContentSetTextFont(page, "F1", 18.0);
|
||||||
|
pdfioContentTextMoveTo(page, tx, ty);
|
||||||
|
pdfioContentTextShow(page, /*unicode*/false, caption);
|
||||||
|
pdfioContentTextEnd(page);
|
||||||
|
|
||||||
|
// Close the page stream and the PDF file...
|
||||||
|
pdfioStreamClose(page);
|
||||||
|
pdfioFileClose(pdf);
|
||||||
|
}
|
||||||
|
.fi
|
||||||
|
|
||||||
.SH ENUMERATIONS
|
.SH ENUMERATIONS
|
||||||
.SS pdfio_cs_e
|
.SS pdfio_cs_e
|
||||||
@ -2148,7 +2267,7 @@ pdfio_file_t * pdfioFileCreate (
|
|||||||
pdfio_rect_t *media_box,
|
pdfio_rect_t *media_box,
|
||||||
pdfio_rect_t *crop_box,
|
pdfio_rect_t *crop_box,
|
||||||
pdfio_error_cb_t error_cb,
|
pdfio_error_cb_t error_cb,
|
||||||
void *error_data
|
void *error_cbdata
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
@ -2162,7 +2281,7 @@ The "media_box" and "crop_box" arguments specify the default MediaBox and
|
|||||||
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
|
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
|
||||||
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
|
||||||
.PP
|
.PP
|
||||||
The "error_cb" and "error_data" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if \fBNULL\fR the default error handler is used that
|
and its data pointer - if \fBNULL\fR the default error handler is used that
|
||||||
writes error messages to \fBstderr\fR.
|
writes error messages to \fBstderr\fR.
|
||||||
.SS pdfioFileCreateArrayObj
|
.SS pdfioFileCreateArrayObj
|
||||||
@ -2325,23 +2444,23 @@ Create a PDF file through an output callback.
|
|||||||
.nf
|
.nf
|
||||||
pdfio_file_t * pdfioFileCreateOutput (
|
pdfio_file_t * pdfioFileCreateOutput (
|
||||||
pdfio_output_cb_t output_cb,
|
pdfio_output_cb_t output_cb,
|
||||||
void *output_ctx,
|
void *output_cbdata,
|
||||||
const char *version,
|
const char *version,
|
||||||
pdfio_rect_t *media_box,
|
pdfio_rect_t *media_box,
|
||||||
pdfio_rect_t *crop_box,
|
pdfio_rect_t *crop_box,
|
||||||
pdfio_error_cb_t error_cb,
|
pdfio_error_cb_t error_cb,
|
||||||
void *error_data
|
void *error_cbdata
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
This function creates a new PDF file that is streamed though an output
|
This function creates a new PDF file that is streamed though an output
|
||||||
callback. The "output_cb" and "output_ctx" arguments specify the output
|
callback. The "output_cb" and "output_cbdata" arguments specify the output
|
||||||
callback and its context pointer which is called whenever data needs to be
|
callback and its data pointer which is called whenever data needs to be
|
||||||
written:
|
written:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
ssize_t
|
ssize_t
|
||||||
output_cb(void *output_ctx, const void *buffer, size_t bytes)
|
output_cb(void *output_cbdata, const void *buffer, size_t bytes)
|
||||||
{
|
{
|
||||||
// Write buffer to output and return the number of bytes written
|
// Write buffer to output and return the number of bytes written
|
||||||
}
|
}
|
||||||
@ -2355,7 +2474,7 @@ The "media_box" and "crop_box" arguments specify the default MediaBox and
|
|||||||
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
|
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
|
||||||
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
|
of 8.27x11in (the intersection of US Letter and ISO A4) is used.
|
||||||
.PP
|
.PP
|
||||||
The "error_cb" and "error_data" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if \fBNULL\fR the default error handler is used that
|
and its data pointer - if \fBNULL\fR the default error handler is used that
|
||||||
writes error messages to \fBstderr\fR.
|
writes error messages to \fBstderr\fR.
|
||||||
.PP
|
.PP
|
||||||
@ -2397,7 +2516,7 @@ pdfio_file_t * pdfioFileCreateTemporary (
|
|||||||
pdfio_rect_t *media_box,
|
pdfio_rect_t *media_box,
|
||||||
pdfio_rect_t *crop_box,
|
pdfio_rect_t *crop_box,
|
||||||
pdfio_error_cb_t error_cb,
|
pdfio_error_cb_t error_cb,
|
||||||
void *error_data
|
void *error_cbdata
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
.SS pdfioFileFindObj
|
.SS pdfioFileFindObj
|
||||||
@ -2420,6 +2539,16 @@ const char * pdfioFileGetAuthor (
|
|||||||
pdfio_file_t *pdf
|
pdfio_file_t *pdf
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
|
.SS pdfioFileGetCatalog
|
||||||
|
Get the document catalog dictionary.
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
pdfio_dict_t * pdfioFileGetCatalog (
|
||||||
|
pdfio_file_t *pdf
|
||||||
|
);
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
|
||||||
.SS pdfioFileGetCreationDate
|
.SS pdfioFileGetCreationDate
|
||||||
Get the creation date for a PDF file.
|
Get the creation date for a PDF file.
|
||||||
.PP
|
.PP
|
||||||
@ -2545,22 +2674,22 @@ Open a PDF file for reading.
|
|||||||
pdfio_file_t * pdfioFileOpen (
|
pdfio_file_t * pdfioFileOpen (
|
||||||
const char *filename,
|
const char *filename,
|
||||||
pdfio_password_cb_t password_cb,
|
pdfio_password_cb_t password_cb,
|
||||||
void *password_data,
|
void *password_cbdata,
|
||||||
pdfio_error_cb_t error_cb,
|
pdfio_error_cb_t error_cb,
|
||||||
void *error_data
|
void *error_cbdata
|
||||||
);
|
);
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
This function opens an existing PDF file. The "filename" argument specifies
|
This function opens an existing PDF file. The "filename" argument specifies
|
||||||
the name of the PDF file to create.
|
the name of the PDF file to create.
|
||||||
.PP
|
.PP
|
||||||
The "password_cb" and "password_data" arguments specify a password callback
|
The "password_cb" and "password_cbdata" arguments specify a password callback
|
||||||
and its data pointer for PDF files that use one of the standard Adobe
|
and its data pointer for PDF files that use one of the standard Adobe
|
||||||
"security" handlers. The callback returns a password string or \fBNULL\fR to
|
"security" handlers. The callback returns a password string or \fBNULL\fR to
|
||||||
cancel the open. If \fBNULL\fR is specified for the callback function and the
|
cancel the open. If \fBNULL\fR is specified for the callback function and the
|
||||||
PDF file requires a password, the open will always fail.
|
PDF file requires a password, the open will always fail.
|
||||||
.PP
|
.PP
|
||||||
The "error_cb" and "error_data" arguments specify an error handler callback
|
The "error_cb" and "error_cbdata" arguments specify an error handler callback
|
||||||
and its data pointer - if \fBNULL\fR the default error handler is used that
|
and its data pointer - if \fBNULL\fR the default error handler is used that
|
||||||
writes error messages to \fBstderr\fR.
|
writes error messages to \fBstderr\fR.
|
||||||
.SS pdfioFileSetAuthor
|
.SS pdfioFileSetAuthor
|
||||||
|
483
doc/pdfio.html
483
doc/pdfio.html
File diff suppressed because it is too large
Load Diff
132
doc/pdfio.md
132
doc/pdfio.md
@ -345,7 +345,7 @@ to the stream:
|
|||||||
The [PDF content helper functions](@) provide additional functions for writing
|
The [PDF content helper functions](@) provide additional functions for writing
|
||||||
specific PDF page stream commands.
|
specific PDF page stream commands.
|
||||||
|
|
||||||
When you are done writing the stream, call [`pdfioStreamCLose`](@@) to close
|
When you are done writing the stream, call [`pdfioStreamClose`](@@) to close
|
||||||
both the stream and the object.
|
both the stream and the object.
|
||||||
|
|
||||||
|
|
||||||
@ -586,3 +586,133 @@ escaping, as needed:
|
|||||||
- [`pdfioContentTextShowf`](@@) draws a formatted string in a text block
|
- [`pdfioContentTextShowf`](@@) draws a formatted string in a text block
|
||||||
- [`pdfioContentTextShowJustified`](@@) draws an array of literal strings with
|
- [`pdfioContentTextShowJustified`](@@) draws an array of literal strings with
|
||||||
offsets between them
|
offsets between them
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
========
|
||||||
|
|
||||||
|
Read PDF Metadata
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The following example function will open a PDF file and print the title, author,
|
||||||
|
creation date, and number of pages:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <pdfio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
show_pdf_info(const char *filename)
|
||||||
|
{
|
||||||
|
pdfio_file_t *pdf;
|
||||||
|
time_t creation_date;
|
||||||
|
struct tm *creation_tm;
|
||||||
|
char creation_text[256];
|
||||||
|
|
||||||
|
|
||||||
|
// Open the PDF file with the default callbacks...
|
||||||
|
pdf = pdfioFileOpen(filename, /*password_cb*/NULL, /*password_cbdata*/NULL, /*error_cb*/NULL, /*error_cbdata*/NULL);
|
||||||
|
if (pdf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get the creation date and convert to a string...
|
||||||
|
creation_date = pdfioFileGetCreationDate(pdf);
|
||||||
|
creation_tm = localtime(&creation_date);
|
||||||
|
strftime(creation_text, sizeof(creation_text), "%c", &creation_tm);
|
||||||
|
|
||||||
|
// Print file information to stdout...
|
||||||
|
printf("%s:\n", filename);
|
||||||
|
printf(" Title: %s\n", pdfioFileGetTitle(pdf));
|
||||||
|
printf(" Author: %s\n", pdfioFileGetAuthor(pdf));
|
||||||
|
printf(" Created On: %s\n", creation_text);
|
||||||
|
printf(" Number Pages: %u\n", (unsigned)pdfioFileGetNumPages(pdf));
|
||||||
|
|
||||||
|
// Close the PDF file...
|
||||||
|
pdfioFileClose(pdf);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Create PDF File With Text and Image
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
The following example function will create a PDF file, embed a base font and the
|
||||||
|
named JPEG or PNG image file, and then creates a page with the image centered on
|
||||||
|
the page with the text centered below:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <pdfio.h>
|
||||||
|
#include <pdfio-content.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
create_pdf_image_file(const char *pdfname, const char *imagename, const char *caption)
|
||||||
|
{
|
||||||
|
pdfio_file_t *pdf;
|
||||||
|
pdfio_obj_t *font;
|
||||||
|
pdfio_obj_t *image;
|
||||||
|
pdfio_dict_t *dict;
|
||||||
|
pdfio_stream_t *page;
|
||||||
|
double width, height;
|
||||||
|
double swidth, sheight;
|
||||||
|
double tx, ty;
|
||||||
|
|
||||||
|
|
||||||
|
// Create the PDF file...
|
||||||
|
pdf = pdfioFileCreate(pdfname, /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_cbdata*/NULL);
|
||||||
|
|
||||||
|
// Create a Courier base font for the caption
|
||||||
|
font = pdfioFileCreateFontObjFromBase(pdf, "Courier");
|
||||||
|
|
||||||
|
// Create an image object from the JPEG/PNG image file...
|
||||||
|
image = pdfioFileCreateImageObjFromFile(pdf, imagename, true);
|
||||||
|
|
||||||
|
// Create a page dictionary with the font and image...
|
||||||
|
dict = pdfioDictCreate(pdf);
|
||||||
|
pdfioPageDictAddFont(dict, "F1", font);
|
||||||
|
pdfioPageDictAddImage(dict, "IM1", image);
|
||||||
|
|
||||||
|
// Create the page and its content stream...
|
||||||
|
page = pdfioFileCreatePage(pdf, dict);
|
||||||
|
|
||||||
|
// Position and scale the image on the page...
|
||||||
|
width = pdfioImageGetWidth(image);
|
||||||
|
height = pdfioImageGetHeight(image);
|
||||||
|
|
||||||
|
// Default media_box is "universal" 595.28x792 points (8.27x11in or 210x279mm)
|
||||||
|
// Use margins of 36 points (0.5in or 12.7mm) with another 36 points for the
|
||||||
|
// caption underneath...
|
||||||
|
swidth = 595.28 - 72.0;
|
||||||
|
sheight = swidth * height / width;
|
||||||
|
if (sheight > (792.0 - 36.0 - 72.0))
|
||||||
|
{
|
||||||
|
sheight = 792.0 - 36.0 - 72.0;
|
||||||
|
swidth = sheight * width / height;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx = 0.5 * (595.28 - swidth);
|
||||||
|
ty = 0.5 * (792 - 36 - sheight);
|
||||||
|
|
||||||
|
pdfioContentDrawImage(page, "IM1", tx, ty + 36.0, swidth, sheight);
|
||||||
|
|
||||||
|
// Draw the caption in black...
|
||||||
|
pdfioContentSetFillColorDeviceGray(page, 0.0);
|
||||||
|
|
||||||
|
// Compute the starting point for the text - Courier is monospaced with a
|
||||||
|
// nominal width of 0.6 times the text height...
|
||||||
|
tx = 0.5 * (595.28 - 18.0 * 0.6 * strlen(caption));
|
||||||
|
|
||||||
|
// Position and draw the caption underneath...
|
||||||
|
pdfioContentTextBegin(page);
|
||||||
|
pdfioContentSetTextFont(page, "F1", 18.0);
|
||||||
|
pdfioContentTextMoveTo(page, tx, ty);
|
||||||
|
pdfioContentTextShow(page, /*unicode*/false, caption);
|
||||||
|
pdfioContentTextEnd(page);
|
||||||
|
|
||||||
|
// Close the page stream and the PDF file...
|
||||||
|
pdfioStreamClose(page);
|
||||||
|
pdfioFileClose(pdf);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -2349,7 +2349,7 @@ pdfioPageDictAddColorSpace(
|
|||||||
bool // O - `true` on success, `false` on failure
|
bool // O - `true` on success, `false` on failure
|
||||||
pdfioPageDictAddFont(
|
pdfioPageDictAddFont(
|
||||||
pdfio_dict_t *dict, // I - Page dictionary
|
pdfio_dict_t *dict, // I - Page dictionary
|
||||||
const char *name, // I - Font name
|
const char *name, // I - Font name; must not contain spaces
|
||||||
pdfio_obj_t *obj) // I - Font object
|
pdfio_obj_t *obj) // I - Font object
|
||||||
{
|
{
|
||||||
pdfio_dict_t *resources; // Resource dictionary
|
pdfio_dict_t *resources; // Resource dictionary
|
||||||
|
18
pdfio-dict.c
18
pdfio-dict.c
@ -426,10 +426,28 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
|
|||||||
|
|
||||||
|
|
||||||
if (value && value->type == PDFIO_VALTYPE_STRING)
|
if (value && value->type == PDFIO_VALTYPE_STRING)
|
||||||
|
{
|
||||||
return (value->value.string);
|
return (value->value.string);
|
||||||
|
}
|
||||||
|
else if (value && value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
|
||||||
|
{
|
||||||
|
// Convert binary string to regular string...
|
||||||
|
char temp[4096]; // Temporary string
|
||||||
|
|
||||||
|
memcpy(temp, value->value.binary.data, value->value.binary.datalen);
|
||||||
|
temp[value->value.binary.datalen] = '\0';
|
||||||
|
|
||||||
|
free(value->value.binary.data);
|
||||||
|
value->type = PDFIO_VALTYPE_STRING;
|
||||||
|
value->value.string = pdfioStringCreate(dict->pdf, temp);
|
||||||
|
|
||||||
|
return (value->value.string);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
29
pdfio-file.c
29
pdfio-file.c
@ -1412,36 +1412,13 @@ get_info_string(pdfio_file_t *pdf, // I - PDF file
|
|||||||
const char *key) // I - Dictionary key
|
const char *key) // I - Dictionary key
|
||||||
{
|
{
|
||||||
pdfio_dict_t *dict; // Info dictionary
|
pdfio_dict_t *dict; // Info dictionary
|
||||||
_pdfio_value_t *value; // Value
|
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!pdf || !pdf->info_obj || (dict = pdfioObjGetDict(pdf->info_obj)) == NULL || (value = _pdfioDictGetValue(dict, key)) == NULL)
|
if (!pdf || !pdf->info_obj || (dict = pdfioObjGetDict(pdf->info_obj)) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
// If we already have a value, return it...
|
|
||||||
if (value->type == PDFIO_VALTYPE_NAME || value->type == PDFIO_VALTYPE_STRING)
|
|
||||||
{
|
|
||||||
return (value->value.string);
|
|
||||||
}
|
|
||||||
else if (value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
|
|
||||||
{
|
|
||||||
// Convert binary string to regular string...
|
|
||||||
char temp[4096]; // Temporary string
|
|
||||||
|
|
||||||
memcpy(temp, value->value.binary.data, value->value.binary.datalen);
|
|
||||||
temp[value->value.binary.datalen] = '\0';
|
|
||||||
|
|
||||||
free(value->value.binary.data);
|
|
||||||
value->type = PDFIO_VALTYPE_STRING;
|
|
||||||
value->value.string = pdfioStringCreate(pdf, temp);
|
|
||||||
|
|
||||||
return (value->value.string);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return (pdfioDictGetString(dict, key));
|
||||||
// Something else that is not a string...
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
2
pdfio.h
2
pdfio.h
@ -23,7 +23,7 @@ extern "C" {
|
|||||||
// Version number...
|
// Version number...
|
||||||
//
|
//
|
||||||
|
|
||||||
# define PDFIO_VERSION "1.3.0"
|
# define PDFIO_VERSION "1.3.1"
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -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.3.0</version>
|
<version>1.3.1</version>
|
||||||
<authors>Michael R Sweet</authors>
|
<authors>Michael R Sweet</authors>
|
||||||
<owners>michaelrsweet</owners>
|
<owners>michaelrsweet</owners>
|
||||||
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<copyright>Copyright © 2019-2024 by Michael R Sweet</copyright>
|
<copyright>Copyright © 2019-2024 by Michael R Sweet</copyright>
|
||||||
<tags>pdf file native</tags>
|
<tags>pdf file native</tags>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="pdfio_native.redist" version="1.3.0" />
|
<dependency id="pdfio_native.redist" version="1.3.1" />
|
||||||
<dependency id="zlib_native.redist" version="1.2.11" />
|
<dependency id="zlib_native.redist" version="1.2.11" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -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.3.0</version>
|
<version>1.3.1</version>
|
||||||
<authors>Michael R Sweet</authors>
|
<authors>Michael R Sweet</authors>
|
||||||
<owners>michaelrsweet</owners>
|
<owners>michaelrsweet</owners>
|
||||||
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
<projectUrl>https://github.com/michaelrsweet/pappl</projectUrl>
|
||||||
|
16
runtests.bat
Normal file
16
runtests.bat
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
:: Script to run unit test program
|
||||||
|
::
|
||||||
|
:: Usage:
|
||||||
|
::
|
||||||
|
:: .\runtests.bat x64\{Debug|Release}
|
||||||
|
::
|
||||||
|
|
||||||
|
:: Copy dependent DLLs to the named build directory
|
||||||
|
echo Copying DLLs
|
||||||
|
copy packages\zlib_native.redist.1.2.11\build\native\bin\x64\Debug\*.dll %1
|
||||||
|
copy packages\zlib_native.redist.1.2.11\build\native\bin\x64\Release\*.dll %1
|
||||||
|
|
||||||
|
:: Run unit test program
|
||||||
|
echo Running %1\testpdfio.exe
|
||||||
|
cd %1
|
||||||
|
testpdfio.exe
|
96
testpdfio.c
96
testpdfio.c
@ -1308,6 +1308,7 @@ read_unit_file(const char *filename, // I - File to read
|
|||||||
bool is_output) // I - File written with output callback?
|
bool is_output) // I - File written with output callback?
|
||||||
{
|
{
|
||||||
pdfio_file_t *pdf; // PDF file
|
pdfio_file_t *pdf; // PDF file
|
||||||
|
pdfio_dict_t *catalog; // Catalog dictionary
|
||||||
size_t i; // Looping var
|
size_t i; // Looping var
|
||||||
const char *s; // String
|
const char *s; // String
|
||||||
bool error = false; // Error callback data
|
bool error = false; // Error callback data
|
||||||
@ -1320,6 +1321,83 @@ read_unit_file(const char *filename, // I - File to read
|
|||||||
else
|
else
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
|
// Get the root object/catalog dictionary
|
||||||
|
fputs("pdfioFileGetCatalog: ", stdout);
|
||||||
|
if ((catalog = pdfioFileGetCatalog(pdf)) != NULL)
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL (got NULL, expected dictionary)");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify some catalog values...
|
||||||
|
fputs("pdfioDictGetName(PageLayout): ", stdout);
|
||||||
|
if ((s = pdfioDictGetName(catalog, "PageLayout")) != NULL && !strcmp(s, "SinglePage"))
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
}
|
||||||
|
else if (s)
|
||||||
|
{
|
||||||
|
printf("FAIL (got '%s', expected 'SinglePage')\n", s);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL (got NULL, expected 'SinglePage')");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("pdfioDictGetName(PageLayout): ", stdout);
|
||||||
|
if ((s = pdfioDictGetName(catalog, "PageLayout")) != NULL && !strcmp(s, "SinglePage"))
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
}
|
||||||
|
else if (s)
|
||||||
|
{
|
||||||
|
printf("FAIL (got '%s', expected 'SinglePage')\n", s);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL (got NULL, expected 'SinglePage')");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("pdfioDictGetName(PageMode): ", stdout);
|
||||||
|
if ((s = pdfioDictGetName(catalog, "PageMode")) != NULL && !strcmp(s, "UseThumbs"))
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
}
|
||||||
|
else if (s)
|
||||||
|
{
|
||||||
|
printf("FAIL (got '%s', expected 'UseThumbs')\n", s);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL (got NULL, expected 'UseThumbs')");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("pdfioDictGetString(Lang): ", stdout);
|
||||||
|
if ((s = pdfioDictGetString(catalog, "Lang")) != NULL && !strcmp(s, "en"))
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
}
|
||||||
|
else if (s)
|
||||||
|
{
|
||||||
|
printf("FAIL (got '%s', expected 'en')\n", s);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL (got NULL, expected 'en')");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
// Verify metadata...
|
// Verify metadata...
|
||||||
fputs("pdfioFileGetAuthor: ", stdout);
|
fputs("pdfioFileGetAuthor: ", stdout);
|
||||||
if ((s = pdfioFileGetAuthor(pdf)) != NULL && !strcmp(s, "Michael R Sweet"))
|
if ((s = pdfioFileGetAuthor(pdf)) != NULL && !strcmp(s, "Michael R Sweet"))
|
||||||
@ -3256,8 +3334,26 @@ write_unit_file(
|
|||||||
*gray_jpg, // gray.jpg image
|
*gray_jpg, // gray.jpg image
|
||||||
*helvetica, // Helvetica font
|
*helvetica, // Helvetica font
|
||||||
*page; // Page from test PDF file
|
*page; // Page from test PDF file
|
||||||
|
pdfio_dict_t *catalog; // Catalog dictionary
|
||||||
|
|
||||||
|
|
||||||
|
// Get the root object/catalog dictionary
|
||||||
|
fputs("pdfioFileGetCatalog: ", stdout);
|
||||||
|
if ((catalog = pdfioFileGetCatalog(outpdf)) != NULL)
|
||||||
|
{
|
||||||
|
puts("PASS");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("FAIL (got NULL, expected dictionary)");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set some catalog values...
|
||||||
|
pdfioDictSetName(catalog, "PageLayout", "SinglePage");
|
||||||
|
pdfioDictSetName(catalog, "PageMode", "UseThumbs");
|
||||||
|
pdfioDictSetString(catalog, "Lang", "en");
|
||||||
|
|
||||||
// Set info values...
|
// Set info values...
|
||||||
fputs("pdfioFileGet/SetAuthor: ", stdout);
|
fputs("pdfioFileGet/SetAuthor: ", stdout);
|
||||||
pdfioFileSetAuthor(outpdf, "Michael R Sweet");
|
pdfioFileSetAuthor(outpdf, "Michael R Sweet");
|
||||||
|
37
ttf.c
37
ttf.c
@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// https://github.com/michaelrsweet/ttf
|
// https://github.com/michaelrsweet/ttf
|
||||||
//
|
//
|
||||||
// Copyright © 2018-2023 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.
|
||||||
@ -99,7 +99,7 @@ typedef __int64 ssize_t; // POSIX type not present on Windows...
|
|||||||
//
|
//
|
||||||
|
|
||||||
#define TTF_FONT_MAX_CHAR 262144 // Maximum number of character values
|
#define TTF_FONT_MAX_CHAR 262144 // Maximum number of character values
|
||||||
|
#define TTF_FONT_MAX_GROUPS 65536 // Maximum number of sub-groups
|
||||||
|
|
||||||
//
|
//
|
||||||
// TTF/OFF tag constants...
|
// TTF/OFF tag constants...
|
||||||
@ -1285,6 +1285,13 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
// segCount --; // Last segment is not used (sigh)
|
// segCount --; // Last segment is not used (sigh)
|
||||||
|
|
||||||
font->num_cmap = segments[segCount - 1].endCode + 1;
|
font->num_cmap = segments[segCount - 1].endCode + 1;
|
||||||
|
|
||||||
|
if (font->num_cmap > TTF_FONT_MAX_CHAR)
|
||||||
|
{
|
||||||
|
errorf(font, "Invalid cmap table with %u characters.", (unsigned)font->num_cmap);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
font->cmap = cmapptr = (int *)malloc(font->num_cmap * sizeof(int));
|
font->cmap = cmapptr = (int *)malloc(font->num_cmap * sizeof(int));
|
||||||
|
|
||||||
if (!font->cmap)
|
if (!font->cmap)
|
||||||
@ -1356,6 +1363,12 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
|
|
||||||
TTF_DEBUG("read_cmap: nGroups=%u\n", nGroups);
|
TTF_DEBUG("read_cmap: nGroups=%u\n", nGroups);
|
||||||
|
|
||||||
|
if (nGroups > TTF_FONT_MAX_GROUPS)
|
||||||
|
{
|
||||||
|
errorf(font, "Invalid cmap table with %u groups.", nGroups);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
if ((groups = (_ttf_off_cmap12_t *)calloc(nGroups, sizeof(_ttf_off_cmap12_t))) == NULL)
|
if ((groups = (_ttf_off_cmap12_t *)calloc(nGroups, sizeof(_ttf_off_cmap12_t))) == NULL)
|
||||||
{
|
{
|
||||||
errorf(font, "Unable to allocate memory for cmap.");
|
errorf(font, "Unable to allocate memory for cmap.");
|
||||||
@ -1376,6 +1389,13 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
// Based on the end code of the segent table, allocate space for the
|
// Based on the end code of the segent table, allocate space for the
|
||||||
// uncompressed cmap table...
|
// uncompressed cmap table...
|
||||||
TTF_DEBUG("read_cmap: num_cmap=%u\n", (unsigned)font->num_cmap);
|
TTF_DEBUG("read_cmap: num_cmap=%u\n", (unsigned)font->num_cmap);
|
||||||
|
|
||||||
|
if (font->num_cmap > TTF_FONT_MAX_CHAR)
|
||||||
|
{
|
||||||
|
errorf(font, "Invalid cmap table with %u characters.", (unsigned)font->num_cmap);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
font->cmap = cmapptr = (int *)malloc(font->num_cmap * sizeof(int));
|
font->cmap = cmapptr = (int *)malloc(font->num_cmap * sizeof(int));
|
||||||
|
|
||||||
if (!font->cmap)
|
if (!font->cmap)
|
||||||
@ -1426,6 +1446,12 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
|
|
||||||
TTF_DEBUG("read_cmap: nGroups=%u\n", nGroups);
|
TTF_DEBUG("read_cmap: nGroups=%u\n", nGroups);
|
||||||
|
|
||||||
|
if (nGroups > TTF_FONT_MAX_GROUPS)
|
||||||
|
{
|
||||||
|
errorf(font, "Invalid cmap table with %u groups.", nGroups);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
if ((groups = (_ttf_off_cmap13_t *)calloc(nGroups, sizeof(_ttf_off_cmap13_t))) == NULL)
|
if ((groups = (_ttf_off_cmap13_t *)calloc(nGroups, sizeof(_ttf_off_cmap13_t))) == NULL)
|
||||||
{
|
{
|
||||||
errorf(font, "Unable to allocate memory for cmap.");
|
errorf(font, "Unable to allocate memory for cmap.");
|
||||||
@ -1446,6 +1472,13 @@ read_cmap(ttf_t *font) // I - Font
|
|||||||
// Based on the end code of the segent table, allocate space for the
|
// Based on the end code of the segent table, allocate space for the
|
||||||
// uncompressed cmap table...
|
// uncompressed cmap table...
|
||||||
TTF_DEBUG("read_cmap: num_cmap=%u\n", (unsigned)font->num_cmap);
|
TTF_DEBUG("read_cmap: num_cmap=%u\n", (unsigned)font->num_cmap);
|
||||||
|
|
||||||
|
if (font->num_cmap > TTF_FONT_MAX_CHAR)
|
||||||
|
{
|
||||||
|
errorf(font, "Invalid cmap table with %u characters.", (unsigned)font->num_cmap);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
font->cmap = cmapptr = (int *)malloc(font->num_cmap * sizeof(int));
|
font->cmap = cmapptr = (int *)malloc(font->num_cmap * sizeof(int));
|
||||||
|
|
||||||
if (!font->cmap)
|
if (!font->cmap)
|
||||||
|
Reference in New Issue
Block a user