Compare commits

...

2 Commits

Author SHA1 Message Date
Michael R Sweet
59959bf0e5
Merge TTF changes to fix off-by-one error. 2023-10-06 16:44:20 -04:00
Michael R Sweet
19c45871fa
Update pdfioContentSetDashPattern to support setting solid line styles (Issue #41) 2023-10-06 15:47:27 -04:00
7 changed files with 59 additions and 33 deletions

View File

@ -5,6 +5,8 @@ Changes in PDFio
v1.1.2 (TBD) v1.1.2 (TBD)
------------ ------------
- Updated `pdfioContentSetDashPattern` to support setting a solid (0 length)
dash pattern (Issue #41)
- Fixed an issue with broken PDF files containing extra CR and/or LF separators - Fixed an issue with broken PDF files containing extra CR and/or LF separators
after the object stream token (Issue #40) after the object stream token (Issue #40)
- Fixed an issue with PDF files produced by Microsoft Reporting Services - Fixed an issue with PDF files produced by Microsoft Reporting Services

View File

@ -1,4 +1,4 @@
.TH pdfio 3 "pdf read/write library" "2022-07-03" "pdf read/write library" .TH pdfio 3 "pdf read/write library" "2023-10-06" "pdf read/write library"
.SH NAME .SH NAME
pdfio \- pdf read/write library pdfio \- pdf read/write library
.SH Introduction .SH Introduction
@ -34,7 +34,7 @@ PDFio is
.I not .I not
concerned with rendering or viewing a PDF file, although a PDF RIP or viewer could be written using it. concerned with rendering or viewing a PDF file, although a PDF RIP or viewer could be written using it.
.PP .PP
PDFio is Copyright \[co] 2021\-2022 by Michael R Sweet and is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2 software. See the files "LICENSE" and "NOTICE" for more information. PDFio is Copyright \[co] 2021\-2023 by Michael R Sweet and is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2 software. See the files "LICENSE" and "NOTICE" for more information.
.SS Requirements .SS Requirements
.PP .PP
PDFio requires the following to build the software: PDFio requires the following to build the software:
@ -1357,7 +1357,7 @@ bool pdfioContentFillAndStroke (
.fi .fi
.SS pdfioContentMatrixConcat .SS pdfioContentMatrixConcat
Concatenate a matrix to the current graphics Concatenate a matrix to the current graphics
state. state.
.PP .PP
.nf .nf
bool pdfioContentMatrixConcat ( bool pdfioContentMatrixConcat (
@ -1507,6 +1507,9 @@ bool pdfioContentSetDashPattern (
double off double off
); );
.fi .fi
.PP
This function sets the stroke pattern when drawing lines. If "on" and "off"
are 0, a solid line is drawn.
.SS pdfioContentSetFillColorDeviceCMYK .SS pdfioContentSetFillColorDeviceCMYK
Set device CMYK fill color. Set device CMYK fill color.
.PP .PP
@ -1981,6 +1984,7 @@ function "cb":
} }
.fi .fi
The iteration continues as long as the callback returns \fBtrue\fR or all keys The iteration continues as long as the callback returns \fBtrue\fR or all keys
have been iterated. have been iterated.
.SS pdfioDictSetArray .SS pdfioDictSetArray
@ -2305,10 +2309,11 @@ written:
ssize_t ssize_t
output_cb(void *output_ctx, const void *buffer, size_t bytes) output_cb(void *output_ctx, 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
} }
.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"). \fBNULL\fR for the default ("2.0").
.PP .PP
@ -2616,7 +2621,7 @@ double pdfioImageGetWidth (
.fi .fi
.SS pdfioObjClose .SS pdfioObjClose
Close an object, writing any data as needed to the PDF Close an object, writing any data as needed to the PDF
file. file.
.PP .PP
.nf .nf
bool pdfioObjClose ( bool pdfioObjClose (
@ -2802,6 +2807,13 @@ bool pdfioStreamGetToken (
size_t bufsize size_t bufsize
); );
.fi .fi
.PP
This function reads a single PDF token from a stream. Operator tokens,
boolean values, and numbers are returned as-is in the provided string buffer.
String values start with the opening parenthesis ('(') but have all escaping
resolved and the terminating parenthesis removed. Hexadecimal string values
start with the opening angle bracket ('<') and have all whitespace and the
terminating angle bracket removed.
.SS pdfioStreamPeek .SS pdfioStreamPeek
Peek at data in a stream. Peek at data in a stream.
.PP .PP
@ -3035,4 +3047,4 @@ typedef uint8_t state_t[4][4];
Michael R Sweet Michael R Sweet
.SH COPYRIGHT .SH COPYRIGHT
.PP .PP
Copyright (c) 2021-2022 by Michael R Sweet Copyright (c) 2021-2023 by Michael R Sweet

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.1</title> <title>PDFio Programming Manual v1.1.2</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.7"> <meta name="generator" content="codedoc v3.7">
<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-2022 by Michael R Sweet"> <meta name="copyright" content="Copyright © 2021-2023 by Michael R Sweet">
<meta name="version" content="1.1"> <meta name="version" content="1.1.2">
<style type="text/css"><!-- <style type="text/css"><!--
body { body {
background: white; background: white;
@ -245,9 +245,9 @@ 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.1</h1> <h1 class="title">PDFio Programming Manual v1.1.2</h1>
<p>Michael R Sweet</p> <p>Michael R Sweet</p>
<p>Copyright © 2021-2022 by Michael R Sweet</p> <p>Copyright © 2021-2023 by Michael R Sweet</p>
</div> </div>
<div class="contents"> <div class="contents">
<h2 class="title">Contents</h2> <h2 class="title">Contents</h2>
@ -497,7 +497,7 @@ span.string {
</li> </li>
</ul> </ul>
<p>PDFio is <em>not</em> concerned with rendering or viewing a PDF file, although a PDF RIP or viewer could be written using it.</p> <p>PDFio is <em>not</em> concerned with rendering or viewing a PDF file, although a PDF RIP or viewer could be written using it.</p>
<p>PDFio is Copyright © 2021-2022 by Michael R Sweet and is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2 software. See the files &quot;LICENSE&quot; and &quot;NOTICE&quot; for more information.</p> <p>PDFio is Copyright © 2021-2023 by Michael R Sweet and is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2 software. See the files &quot;LICENSE&quot; and &quot;NOTICE&quot; for more information.</p>
<h3 class="title" id="requirements">Requirements</h3> <h3 class="title" id="requirements">Requirements</h3>
<p>PDFio requires the following to build the software:</p> <p>PDFio requires the following to build the software:</p>
<ul> <ul>
@ -1388,7 +1388,7 @@ bool pdfioContentFillAndStroke(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st,
<p class="description"><code>true</code> on success, <code>false</code> on failure</p> <p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h3 class="function"><a id="pdfioContentMatrixConcat">pdfioContentMatrixConcat</a></h3> <h3 class="function"><a id="pdfioContentMatrixConcat">pdfioContentMatrixConcat</a></h3>
<p class="description">Concatenate a matrix to the current graphics <p class="description">Concatenate a matrix to the current graphics
state.</p> state.</p>
<p class="code"> <p class="code">
bool pdfioContentMatrixConcat(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, pdfio_matrix_t m);</p> bool pdfioContentMatrixConcat(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, pdfio_matrix_t m);</p>
<h4 class="parameters">Parameters</h4> <h4 class="parameters">Parameters</h4>
@ -1614,6 +1614,9 @@ bool pdfioContentSetDashPattern(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st
</tbody></table> </tbody></table>
<h4 class="returnvalue">Return Value</h4> <h4 class="returnvalue">Return Value</h4>
<p class="description"><code>true</code> on success, <code>false</code> on failure</p> <p class="description"><code>true</code> on success, <code>false</code> on failure</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function sets the stroke pattern when drawing lines. If &quot;on&quot; and &quot;off&quot;
are 0, a solid line is drawn.</p>
<h3 class="function"><a id="pdfioContentSetFillColorDeviceCMYK">pdfioContentSetFillColorDeviceCMYK</a></h3> <h3 class="function"><a id="pdfioContentSetFillColorDeviceCMYK">pdfioContentSetFillColorDeviceCMYK</a></h3>
<p class="description">Set device CMYK fill color.</p> <p class="description">Set device CMYK fill color.</p>
<p class="code"> <p class="code">
@ -2301,6 +2304,7 @@ my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data)
... return true to continue or false to stop ... ... return true to continue or false to stop ...
} }
</pre> </pre>
The iteration continues as long as the callback returns <code>true</code> or all keys The iteration continues as long as the callback returns <code>true</code> or all keys
have been iterated.</p> have been iterated.</p>
<h3 class="function"><a id="pdfioDictSetArray">pdfioDictSetArray</a></h3> <h3 class="function"><a id="pdfioDictSetArray">pdfioDictSetArray</a></h3>
@ -2741,9 +2745,10 @@ written:
ssize_t ssize_t
output_cb(void *output_ctx, const void *buffer, size_t bytes) output_cb(void *output_ctx, 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
} }
</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;).<br> <code>NULL</code> for the default (&quot;2.0&quot;).<br>
<br> <br>
@ -3152,7 +3157,7 @@ double pdfioImageGetWidth(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p>
<p class="description">Width in columns</p> <p class="description">Width in columns</p>
<h3 class="function"><a id="pdfioObjClose">pdfioObjClose</a></h3> <h3 class="function"><a id="pdfioObjClose">pdfioObjClose</a></h3>
<p class="description">Close an object, writing any data as needed to the PDF <p class="description">Close an object, writing any data as needed to the PDF
file.</p> file.</p>
<p class="code"> <p class="code">
bool pdfioObjClose(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p> bool pdfioObjClose(<a href="#pdfio_obj_t">pdfio_obj_t</a> *obj);</p>
<h4 class="parameters">Parameters</h4> <h4 class="parameters">Parameters</h4>
@ -3413,6 +3418,13 @@ bool pdfioStreamGetToken(<a href="#pdfio_stream_t">pdfio_stream_t</a> *st, char
</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 EOF</p> <p class="description"><code>true</code> on success, <code>false</code> on EOF</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">This function reads a single PDF token from a stream. Operator tokens,
boolean values, and numbers are returned as-is in the provided string buffer.
String values start with the opening parenthesis ('(') but have all escaping
resolved and the terminating parenthesis removed. Hexadecimal string values
start with the opening angle bracket ('&lt;') and have all whitespace and the
terminating angle bracket removed.</p>
<h3 class="function"><a id="pdfioStreamPeek">pdfioStreamPeek</a></h3> <h3 class="function"><a id="pdfioStreamPeek">pdfioStreamPeek</a></h3>
<p class="description">Peek at data in a stream.</p> <p class="description">Peek at data in a stream.</p>
<p class="code"> <p class="code">

View File

@ -15,7 +15,7 @@ goals of pdfio are:
PDFio is *not* concerned with rendering or viewing a PDF file, although a PDF PDFio is *not* concerned with rendering or viewing a PDF file, although a PDF
RIP or viewer could be written using it. RIP or viewer could be written using it.
PDFio is Copyright © 2021-2022 by Michael R Sweet and is licensed under the PDFio is Copyright © 2021-2023 by Michael R Sweet and is licensed under the
Apache License Version 2.0 with an (optional) exception to allow linking against Apache License Version 2.0 with an (optional) exception to allow linking against
GPL2/LGPL2 software. See the files "LICENSE" and "NOTICE" for more information. GPL2/LGPL2 software. See the files "LICENSE" and "NOTICE" for more information.

View File

@ -1,7 +1,7 @@
// //
// Content helper functions for PDFio. // Content helper functions for PDFio.
// //
// Copyright © 2021 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.
@ -670,6 +670,9 @@ pdfioContentSave(pdfio_stream_t *st) // I - Stream
// //
// 'pdfioContentSetDashPattern()' - Set the stroke pattern. // 'pdfioContentSetDashPattern()' - Set the stroke pattern.
// //
// This function sets the stroke pattern when drawing lines. If "on" and "off"
// are 0, a solid line is drawn.
//
bool // O - `true` on success, `false` on failure bool // O - `true` on success, `false` on failure
pdfioContentSetDashPattern( pdfioContentSetDashPattern(
@ -678,7 +681,12 @@ pdfioContentSetDashPattern(
double on, // I - On length double on, // I - On length
double off) // I - Off length double off) // I - Off length
{ {
return (pdfioStreamPrintf(st, "[%g %g] %g d\n", on, off, phase)); if (on <= 0.0 && off <= 0.0)
return (pdfioStreamPrintf(st, "[] %g d\n", phase));
else if (fabs(on - off) < 0.001)
return (pdfioStreamPrintf(st, "[%g] %g d\n", on, phase));
else
return (pdfioStreamPrintf(st, "[%g %g] %g d\n", on, off, phase));
} }

9
ttf.c
View File

@ -3,16 +3,12 @@
// //
// https://github.com/michaelrsweet/ttf // https://github.com/michaelrsweet/ttf
// //
// Copyright © 2018-2021 by Michael R Sweet. // Copyright © 2018-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.
// //
//
// Include necessary headers...
//
#ifdef _WIN32 #ifdef _WIN32
# define _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS
#endif // _WIN32 #endif // _WIN32
@ -691,6 +687,9 @@ ttfGetExtents(
ch = *s++; ch = *s++;
} }
// Issue #1: Offset past ".notdef"...
ch ++;
// Find its width... // Find its width...
if ((widths = font->widths[ch / 256]) != NULL) if ((widths = font->widths[ch / 256]) != NULL)
{ {

13
ttf.h
View File

@ -3,7 +3,7 @@
// //
// https://github.com/michaelrsweet/ttf // https://github.com/michaelrsweet/ttf
// //
// Copyright © 2018-2021 by Michael R Sweet. // Copyright © 2018-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.
@ -11,17 +11,11 @@
#ifndef TTF_H #ifndef TTF_H
# define TTF_H # define TTF_H
//
// Include necessary headers...
//
# include <stdbool.h> # include <stdbool.h>
# include <sys/types.h> # include <sys/types.h>
# ifdef __cplusplus # ifdef __cplusplus
extern "C" { extern "C" {
# endif // # endif // __cplusplus
// //
@ -89,8 +83,8 @@ extern ttf_t *ttfCreate(const char *filename, size_t idx, ttf_err_cb_t err_cb,
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);
extern int ttfGetCapHeight(ttf_t *font);
extern const int *ttfGetCMap(ttf_t *font, size_t *num_cmap); extern const int *ttfGetCMap(ttf_t *font, size_t *num_cmap);
extern int ttfGetCapHeight(ttf_t *font);
extern const char *ttfGetCopyright(ttf_t *font); extern const char *ttfGetCopyright(ttf_t *font);
extern int ttfGetDescent(ttf_t *font); extern int ttfGetDescent(ttf_t *font);
extern ttf_rect_t *ttfGetExtents(ttf_t *font, float size, const char *s, ttf_rect_t *extents); extern ttf_rect_t *ttfGetExtents(ttf_t *font, float size, const char *s, ttf_rect_t *extents);
@ -112,5 +106,4 @@ extern bool ttfIsFixedPitch(ttf_t *font);
# ifdef __cplusplus # ifdef __cplusplus
} }
# endif // __cplusplus # endif // __cplusplus
#endif // !TTF_H #endif // !TTF_H