mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +00:00
Add operator ""_qpdf for creating QPDFObjectHandle literals
This commit is contained in:
parent
b48a0ff0e8
commit
7fb22740e1
@ -1,5 +1,11 @@
|
||||
2022-02-05 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add a global user-defined string literal "_qpdf" as a shorthand
|
||||
for QPDFObjectHandle::parse, allowing you to create
|
||||
QPDFObjectHandle objects with
|
||||
|
||||
QPDFObjectHandle oh = "<</Some (PDF)>>"_qpdf;
|
||||
|
||||
* Expose QPDF::emptyPDF to the C API as qpdf_empty_pdf()
|
||||
|
||||
* Add comments letting people know that the version string
|
||||
|
3
TODO
3
TODO
@ -11,9 +11,6 @@
|
||||
|
||||
* QPDFObjectHandle: getValueAsX methods, getKeyIfDict. Plus C API.
|
||||
|
||||
* Add user-defined initializer `QPDFObjectHandle operator ""_qpdf` to
|
||||
be like QPDFObjectHandle::parse: `auto oh = "<< /a (b) >>"_qpdf;`
|
||||
|
||||
* See if this has been done or is trivial with C++11 local static
|
||||
initializers: Secure random number generation could be made more
|
||||
efficient by using a local static to ensure a single random device
|
||||
|
@ -36,16 +36,16 @@ static void process(char const* infilename, char const* password,
|
||||
QPDF q;
|
||||
q.processFile(infilename, password);
|
||||
|
||||
// Create an indirect object for the built-in Helvetica font.
|
||||
// Create an indirect object for the built-in Helvetica font. This
|
||||
// uses the qpdf literal syntax introduced in qpdf 10.6.
|
||||
auto f1 = q.makeIndirectObject(
|
||||
QPDFObjectHandle::parse(
|
||||
"<<"
|
||||
" /Type /Font"
|
||||
" /Subtype /Type1"
|
||||
" /Name /F1"
|
||||
" /BaseFont /Helvetica"
|
||||
" /Encoding /WinAnsiEncoding"
|
||||
">>"));
|
||||
"<<"
|
||||
" /Type /Font"
|
||||
" /Subtype /Type1"
|
||||
" /Name /F1"
|
||||
" /BaseFont /Helvetica"
|
||||
" /Encoding /WinAnsiEncoding"
|
||||
">>"_qpdf);
|
||||
|
||||
// Create a resources dictionary with fonts. This uses the new
|
||||
// parse introduced in qpdf 10.2 that takes a QPDF* and allows
|
||||
@ -93,7 +93,7 @@ static void process(char const* infilename, char const* password,
|
||||
apdict.replaceKey("/Resources", QPDFObjectHandle::newDictionary());
|
||||
apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
||||
apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"));
|
||||
apdict.replaceKey("/BBox", QPDFObjectHandle::parse("[ 0 0 20 20 ]"));
|
||||
apdict.replaceKey("/BBox", "[ 0 0 20 20 ]"_qpdf);
|
||||
auto annot = q.makeIndirectObject(
|
||||
QPDFObjectHandle::parse(
|
||||
&q,
|
||||
|
@ -182,12 +182,11 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
|
||||
size_t width = p->getWidth();
|
||||
size_t height = p->getHeight();
|
||||
QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf);
|
||||
image.replaceDict(QPDFObjectHandle::parse(
|
||||
"<<"
|
||||
" /Type /XObject"
|
||||
" /Subtype /Image"
|
||||
" /BitsPerComponent 8"
|
||||
">>"));
|
||||
image.replaceDict("<<"
|
||||
" /Type /XObject"
|
||||
" /Subtype /Image"
|
||||
" /BitsPerComponent 8"
|
||||
">>"_qpdf);
|
||||
QPDFObjectHandle image_dict = image.getDict();
|
||||
image_dict.replaceKey("/ColorSpace", newName(color_space));
|
||||
image_dict.replaceKey("/Width", newInteger(width));
|
||||
@ -199,8 +198,7 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
|
||||
QPDFObjectHandle::newNull());
|
||||
|
||||
// Create direct objects as needed by the page dictionary.
|
||||
QPDFObjectHandle procset = QPDFObjectHandle::parse(
|
||||
"[/PDF /Text /ImageC]");
|
||||
QPDFObjectHandle procset = "[/PDF /Text /ImageC]"_qpdf;
|
||||
|
||||
QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary();
|
||||
rfont.replaceKey("/F1", font);
|
||||
@ -384,14 +382,13 @@ static void create_pdf(char const* filename)
|
||||
// Add an indirect object to contain a font descriptor for the
|
||||
// built-in Helvetica font.
|
||||
QPDFObjectHandle font = pdf.makeIndirectObject(
|
||||
QPDFObjectHandle::parse(
|
||||
"<<"
|
||||
" /Type /Font"
|
||||
" /Subtype /Type1"
|
||||
" /Name /F1"
|
||||
" /BaseFont /Helvetica"
|
||||
" /Encoding /WinAnsiEncoding"
|
||||
">>"));
|
||||
"<<"
|
||||
" /Type /Font"
|
||||
" /Subtype /Type1"
|
||||
" /Name /F1"
|
||||
" /BaseFont /Helvetica"
|
||||
" /Encoding /WinAnsiEncoding"
|
||||
">>"_qpdf);
|
||||
|
||||
std::vector<std::string> color_spaces;
|
||||
color_spaces.push_back("/DeviceCMYK");
|
||||
|
@ -65,8 +65,7 @@ static void stamp_page(char const* infile,
|
||||
// Append the content to the page's content. Surround the
|
||||
// original content with q...Q to the new content from the
|
||||
// page's original content.
|
||||
resources.mergeResources(
|
||||
QPDFObjectHandle::parse("<< /XObject << >> >>"));
|
||||
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
||||
resources.getKey("/XObject").replaceKey(name, stamp_fo);
|
||||
ph.addPageContents(
|
||||
QPDFObjectHandle::newStream(&inpdf, "q\n"), true);
|
||||
|
@ -395,7 +395,7 @@ class QPDFObjectHandle
|
||||
// object syntax (obj gen R) will cause a logic_error exception to
|
||||
// be thrown. If object_description is provided, it will appear
|
||||
// in the message of any QPDFExc exception thrown for invalid
|
||||
// syntax.
|
||||
// syntax. See also the global `operator ""_qpdf` defined below.
|
||||
QPDF_DLL
|
||||
static QPDFObjectHandle parse(std::string const& object_str,
|
||||
std::string const& object_description = "");
|
||||
@ -1450,6 +1450,17 @@ class QPDFObjectHandle
|
||||
bool reserved;
|
||||
};
|
||||
|
||||
#ifndef QPDF_NO_QPDF_STRING
|
||||
// This is short for QPDFObjectHandle::parse, so you can do
|
||||
|
||||
// auto oh = "<< /Key (value) >>"_qpdf;
|
||||
|
||||
// If this is causing problems in your code, define
|
||||
// QPDF_NO_QPDF_STRING to prevent the declaration from being here.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle operator ""_qpdf(char const* v, size_t len);
|
||||
#endif // QPDF_NO_QPDF_STRING
|
||||
|
||||
class QPDFObjectHandle::QPDFDictItems
|
||||
{
|
||||
// This class allows C++-style iteration, including range-for
|
||||
|
@ -981,8 +981,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance(
|
||||
AS.getDict().replaceKey("/Resources", resources);
|
||||
}
|
||||
// Use mergeResources to force /Font to be local
|
||||
resources.mergeResources(
|
||||
QPDFObjectHandle::parse("<< /Font << >> >>"));
|
||||
resources.mergeResources("<< /Font << >> >>"_qpdf);
|
||||
resources.getKey("/Font").replaceKey(font_name, font);
|
||||
}
|
||||
|
||||
|
@ -2281,8 +2281,7 @@ QPDFJob::doUnderOverlayForPage(
|
||||
from_page, cm, dest_afdh, make_afdh(from_page));
|
||||
if (! new_content.empty())
|
||||
{
|
||||
resources.mergeResources(
|
||||
QPDFObjectHandle::parse("<< /XObject << >> >>"));
|
||||
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
||||
auto xobject = resources.getKey("/XObject");
|
||||
if (xobject.isDictionary())
|
||||
{
|
||||
|
@ -61,8 +61,7 @@ QPDFNameTreeObjectHelper
|
||||
QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
|
||||
{
|
||||
return QPDFNameTreeObjectHelper(
|
||||
qpdf.makeIndirectObject(
|
||||
QPDFObjectHandle::parse("<< /Names [] >>")), qpdf, auto_repair);
|
||||
qpdf.makeIndirectObject("<< /Names [] >>"_qpdf), qpdf, auto_repair);
|
||||
}
|
||||
|
||||
QPDFNameTreeObjectHelper::iterator::iterator(
|
||||
|
@ -58,8 +58,7 @@ QPDFNumberTreeObjectHelper
|
||||
QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
|
||||
{
|
||||
return QPDFNumberTreeObjectHelper(
|
||||
qpdf.makeIndirectObject(
|
||||
QPDFObjectHandle::parse("<< /Nums [] >>")), qpdf, auto_repair);
|
||||
qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair);
|
||||
}
|
||||
|
||||
QPDFNumberTreeObjectHelper::iterator::iterator(
|
||||
|
@ -3666,3 +3666,10 @@ QPDFObjectHandle::QPDFArrayItems::end()
|
||||
{
|
||||
return iterator(oh, false);
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
operator ""_qpdf(char const* v, size_t len)
|
||||
{
|
||||
return QPDFObjectHandle::parse(
|
||||
std::string(v, len), "QPDFObjectHandle literal");
|
||||
}
|
||||
|
@ -161,8 +161,7 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage(
|
||||
name, rotate, required_flags, forbidden_flags);
|
||||
if (! content.empty())
|
||||
{
|
||||
resources.mergeResources(
|
||||
QPDFObjectHandle::parse("<< /XObject << >> >>"));
|
||||
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
||||
resources.getKey("/XObject").replaceKey(name, as);
|
||||
++next_fx;
|
||||
}
|
||||
|
@ -500,8 +500,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
|
||||
QPDFObjectHandle resources = getAttribute("/Resources", true);
|
||||
// Calling mergeResources also ensures that /XObject becomes
|
||||
// direct and is not shared with other pages.
|
||||
resources.mergeResources(
|
||||
QPDFObjectHandle::parse("<< /XObject << >> >>"));
|
||||
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
||||
InlineImageTracker iit(this->oh.getOwningQPDF(), min_size, resources);
|
||||
Pl_Buffer b("new page content");
|
||||
bool filtered = false;
|
||||
|
@ -1255,10 +1255,8 @@ static void test_31(QPDF& pdf, char const* arg2)
|
||||
{
|
||||
// Test object parsing from a string. The input file is not used.
|
||||
|
||||
QPDFObjectHandle o1 =
|
||||
QPDFObjectHandle::parse(
|
||||
"[/name 16059 3.14159 false\n"
|
||||
" << /key true /other [ (string1) (string2) ] >> null]");
|
||||
auto o1 = "[/name 16059 3.14159 false\n"
|
||||
" << /key true /other [ (string1) (string2) ] >> null]"_qpdf;
|
||||
std::cout << o1.unparse() << std::endl;
|
||||
QPDFObjectHandle o2 = QPDFObjectHandle::parse(" 12345 \f ");
|
||||
assert(o2.isInteger() && (o2.getIntValue() == 12345));
|
||||
|
Loading…
Reference in New Issue
Block a user