2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-31 17:30:54 +00:00

Add QPDFWriter::setExtraHeaderText

This commit is contained in:
Jay Berkenbilt 2012-09-06 15:30:13 -04:00
parent fc4c82a950
commit c1627d0438
11 changed files with 102 additions and 2 deletions

View File

@ -1,5 +1,11 @@
2012-09-06 Jay Berkenbilt <ejb@ql.org> 2012-09-06 Jay Berkenbilt <ejb@ql.org>
* Add new method QPDFWriter::setExtraHeaderText to add extra text,
such as application-specific comments, to near the beginning of a
PDF file. For linearized files, this appears after the
linearization parameter dictionary. For non-linearized files, it
appears right after the PDF header and non-ASCII comment.
* Make it possible to write the same QPDF object with two * Make it possible to write the same QPDF object with two
different QPDFWriter objects that have both called different QPDFWriter objects that have both called
setLinearization(true) by making private method setLinearization(true) by making private method

View File

@ -163,6 +163,18 @@ class QPDFWriter
QPDF_DLL QPDF_DLL
void forcePDFVersion(std::string const&); void forcePDFVersion(std::string const&);
// Provide additional text to insert in the PDF file somewhere
// near the beginning of the file. This can be used to add
// comments to the beginning of a PDF file, for example, if those
// comments are to be consumed by some other application. No
// checks are performed to ensure that the text inserted here is
// valid PDF. If you want to insert multiline comments, you will
// need to include \n in the string yourself and start each line
// with %. An extra newline will be appended if one is not
// already present at the end of your text.
QPDF_DLL
void setExtraHeaderText(std::string const&);
// Cause a static /ID value to be generated. Use only in test // Cause a static /ID value to be generated. Use only in test
// suites. // suites.
QPDF_DLL QPDF_DLL
@ -354,6 +366,7 @@ class QPDFWriter
std::string id2; // trailer dictionary std::string id2; // trailer dictionary
std::string min_pdf_version; std::string min_pdf_version;
std::string forced_pdf_version; std::string forced_pdf_version;
std::string extra_header_text;
int encryption_dict_objid; int encryption_dict_objid;
std::string cur_data_key; std::string cur_data_key;
std::list<PointerHolder<Pipeline> > to_delete; std::list<PointerHolder<Pipeline> > to_delete;

View File

@ -195,6 +195,22 @@ QPDFWriter::forcePDFVersion(std::string const& version)
this->forced_pdf_version = version; this->forced_pdf_version = version;
} }
void
QPDFWriter::setExtraHeaderText(std::string const& text)
{
this->extra_header_text = text;
if ((this->extra_header_text.length() > 0) &&
(*(this->extra_header_text.rbegin()) != '\n'))
{
QTC::TC("qpdf", "QPDFWriter extra header text add newline");
this->extra_header_text += "\n";
}
else
{
QTC::TC("qpdf", "QPDFWriter extra header text no newline");
}
}
void void
QPDFWriter::setStaticID(bool val) QPDFWriter::setStaticID(bool val)
{ {
@ -1832,6 +1848,12 @@ QPDFWriter::writeHeader()
// it really should be treated as binary. // it really should be treated as binary.
writeString("\n%\xbf\xf7\xa2\xfe\n"); writeString("\n%\xbf\xf7\xa2\xfe\n");
writeStringQDF("%QDF-1.0\n\n"); writeStringQDF("%QDF-1.0\n\n");
// Note: do not write extra header text here. Linearized PDFs
// must include the entire linearization parameter dictionary
// within the first 1024 characters of the PDF file, so for
// linearized files, we have to write extra header text after the
// linearization parameter dictionary.
} }
void void
@ -2189,7 +2211,9 @@ QPDFWriter::writeLinearized()
// space to write real dictionary. 200 characters is enough // space to write real dictionary. 200 characters is enough
// space if all numerical values in the parameter dictionary // space if all numerical values in the parameter dictionary
// that contain offsets are 20 digits long plus a few extra // that contain offsets are 20 digits long plus a few extra
// characters for safety. // characters for safety. The entire linearization parameter
// dictionary must appear within the first 1024 characters of
// the file.
qpdf_offset_t pos = this->pipeline->getCount(); qpdf_offset_t pos = this->pipeline->getCount();
openObject(lindict_id); openObject(lindict_id);
@ -2225,6 +2249,10 @@ QPDFWriter::writeLinearized()
writePad(spaces); writePad(spaces);
writeString("\n"); writeString("\n");
// If the user supplied any additional header text, write it
// here after the linearization parameter dictionary.
writeString(this->extra_header_text);
// Part 3: first page cross reference table and trailer. // Part 3: first page cross reference table and trailer.
qpdf_offset_t first_xref_offset = this->pipeline->getCount(); qpdf_offset_t first_xref_offset = this->pipeline->getCount();
@ -2396,6 +2424,7 @@ QPDFWriter::writeStandard()
// Start writing // Start writing
writeHeader(); writeHeader();
writeString(this->extra_header_text);
// Put root first on queue. // Put root first on queue.
QPDFObjectHandle trailer = pdf.getTrailer(); QPDFObjectHandle trailer = pdf.getTrailer();

View File

@ -240,3 +240,5 @@ QPDFObjectHandle trailing data in parse 0
qpdf pages encryption password 0 qpdf pages encryption password 0
QPDF_Tokenizer EOF reading token 0 QPDF_Tokenizer EOF reading token 0
QPDF_Tokenizer EOF reading appendable token 0 QPDF_Tokenizer EOF reading appendable token 0
QPDFWriter extra header text no newline 0
QPDFWriter extra header text add newline 0

View File

@ -149,7 +149,7 @@ $td->runtest("remove page we don't have",
$td->NORMALIZE_NEWLINES); $td->NORMALIZE_NEWLINES);
# ---------- # ----------
$td->notify("--- Miscellaneous Tests ---"); $td->notify("--- Miscellaneous Tests ---");
$n_tests += 48; $n_tests += 53;
$td->runtest("qpdf version", $td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"}, {$td->COMMAND => "qpdf --version"},
@ -387,6 +387,22 @@ $td->runtest("EOF reading token",
{$td->COMMAND => "qpdf --check eof-reading-token.pdf"}, {$td->COMMAND => "qpdf --check eof-reading-token.pdf"},
{$td->FILE => "eof-reading-token.out", $td->EXIT_STATUS => 0}, {$td->FILE => "eof-reading-token.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES); $td->NORMALIZE_NEWLINES);
$td->runtest("extra header text",
{$td->COMMAND => "test_driver 32 minimal.pdf"},
{$td->FILE => "test-32.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "extra-header-no-newline.pdf"});
$td->runtest("check output",
{$td->FILE => "b.pdf"},
{$td->FILE => "extra-header-lin-no-newline.pdf"});
$td->runtest("check output",
{$td->FILE => "c.pdf"},
{$td->FILE => "extra-header-newline.pdf"});
$td->runtest("check output",
{$td->FILE => "d.pdf"},
{$td->FILE => "extra-header-lin-newline.pdf"});
show_ntests(); show_ntests();
# ---------- # ----------

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,13 @@
file: a.pdf
linearized: no
newline: no
file: b.pdf
linearized: yes
newline: no
file: c.pdf
linearized: no
newline: yes
file: d.pdf
linearized: yes
newline: yes
test 32 done

View File

@ -1091,6 +1091,27 @@ void runtest(int n, char const* filename1, char const* filename2)
<< std::endl; << std::endl;
} }
} }
else if (n == 32)
{
// Extra header text
char const* filenames[] = {"a.pdf", "b.pdf", "c.pdf", "d.pdf"};
for (int i = 0; i < 4; ++i)
{
bool linearized = ((i & 1) != 0);
bool newline = ((i & 2) != 0);
QPDFWriter w(pdf, filenames[i]);
w.setStaticID(true);
std::cout
<< "file: " << filenames[i] << std::endl
<< "linearized: " << (linearized ? "yes" : "no") << std::endl
<< "newline: " << (newline ? "yes" : "no") << std::endl;
w.setLinearization(linearized);
w.setExtraHeaderText(newline
? "%% Comment with newline\n"
: "%% Comment\n% No newline");
w.write();
}
}
else else
{ {
throw std::runtime_error(std::string("invalid test ") + throw std::runtime_error(std::string("invalid test ") +