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