mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Back out fluent QPDFObjectHandle methods. Keep the andGet methods.
I decided these were confusing and inconsistent with how JSON works. They muddle the API rather than improving it.
This commit is contained in:
parent
7e7a9c4379
commit
56f1b411fe
15
ChangeLog
15
ChangeLog
@ -86,15 +86,12 @@
|
||||
2022-04-29 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* QPDFObjectHandle: for the methods insertItem, appendItem,
|
||||
eraseItem, replaceKey, and removeKey, have the methods return a
|
||||
reference to the original object, making a fluent interface to
|
||||
initializing or modifying QPDFObjectHandle possible. Also, for
|
||||
each one, add a corresponding "AndGet" method (insertItemAndGet,
|
||||
appendItemAndGet, eraseItemAndGet, replaceKeyAndGet, and
|
||||
removeKeyAndGet) that returns the newly inserted, replaced, or
|
||||
removed item. This makes it possible to create a new object, add
|
||||
it to an array or dictionary, and get a handle to it all in one
|
||||
line.
|
||||
eraseItem, replaceKey, and removeKey, add a corresponding "AndGet"
|
||||
method (insertItemAndGet, appendItemAndGet, eraseItemAndGet,
|
||||
replaceKeyAndGet, and removeKeyAndGet) that returns the newly
|
||||
inserted, replaced, or removed item. This makes it possible to
|
||||
create a new object, add it to an array or dictionary, and get a
|
||||
handle to it all in one line.
|
||||
|
||||
2022-04-24 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
|
@ -106,10 +106,10 @@ process(
|
||||
// apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
||||
// apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"));
|
||||
// apdict.replaceKey("/BBox", QPDFObjectHandle::parse("[ 0 0 20 20 ]"));
|
||||
apdict.replaceKey("/Resources", "<< >>"_qpdf)
|
||||
.replaceKey("/Type", "/XObject"_qpdf)
|
||||
.replaceKey("/Subtype", "/Form"_qpdf)
|
||||
.replaceKey("/BBox", "[ 0 0 20 20 ]"_qpdf);
|
||||
apdict.replaceKey("/Resources", "<< >>"_qpdf);
|
||||
apdict.replaceKey("/Type", "/XObject"_qpdf);
|
||||
apdict.replaceKey("/Subtype", "/Form"_qpdf);
|
||||
apdict.replaceKey("/BBox", "[ 0 0 20 20 ]"_qpdf);
|
||||
auto annot = q.makeIndirectObject(QPDFObjectHandle::parse(
|
||||
&q,
|
||||
("<<"
|
||||
|
@ -181,9 +181,9 @@ add_page(
|
||||
" /Subtype /Image"
|
||||
" /BitsPerComponent 8"
|
||||
">>"_qpdf;
|
||||
image_dict.replaceKey("/ColorSpace", newName(color_space))
|
||||
.replaceKey("/Width", newInteger(width))
|
||||
.replaceKey("/Height", newInteger(height));
|
||||
image_dict.replaceKey("/ColorSpace", newName(color_space));
|
||||
image_dict.replaceKey("/Width", newInteger(width));
|
||||
image_dict.replaceKey("/Height", newInteger(height));
|
||||
image.replaceDict(image_dict);
|
||||
|
||||
// Provide the stream data.
|
||||
@ -200,9 +200,9 @@ add_page(
|
||||
xobject.replaceKey("/Im1", image);
|
||||
|
||||
QPDFObjectHandle resources = QPDFObjectHandle::newDictionary();
|
||||
resources.replaceKey("/ProcSet", procset)
|
||||
.replaceKey("/Font", rfont)
|
||||
.replaceKey("/XObject", xobject);
|
||||
resources.replaceKey("/ProcSet", procset);
|
||||
resources.replaceKey("/Font", rfont);
|
||||
resources.replaceKey("/XObject", xobject);
|
||||
|
||||
// Create the page content stream
|
||||
QPDFObjectHandle contents =
|
||||
@ -213,7 +213,8 @@ add_page(
|
||||
" /Type /Page"
|
||||
" /MediaBox [0 0 612 392]"
|
||||
">>"_qpdf);
|
||||
page.replaceKey("/Contents", contents).replaceKey("/Resources", resources);
|
||||
page.replaceKey("/Contents", contents);
|
||||
page.replaceKey("/Resources", resources);
|
||||
|
||||
// Add the page to the PDF file
|
||||
dh.addPage(page, false);
|
||||
|
@ -1024,25 +1024,22 @@ class QPDFObjectHandle
|
||||
void setArrayFromVector(std::vector<QPDFObjectHandle> const& items);
|
||||
// Insert an item before the item at the given position ("at") so
|
||||
// that it has that position after insertion. If "at" is equal to
|
||||
// the size of the array, insert the item at the end. Return a
|
||||
// reference to the array (not the new item).
|
||||
// the size of the array, insert the item at the end.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle& insertItem(int at, QPDFObjectHandle const& item);
|
||||
void insertItem(int at, QPDFObjectHandle const& item);
|
||||
// Like insertItem but return the item that was inserted.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle insertItemAndGet(int at, QPDFObjectHandle const& item);
|
||||
// Append an item, and return a reference to the original array
|
||||
// (not the new item).
|
||||
// Append an item to an array.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle& appendItem(QPDFObjectHandle const& item);
|
||||
void appendItem(QPDFObjectHandle const& item);
|
||||
// Append an item, and return the newly added item.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle appendItemAndGet(QPDFObjectHandle const& item);
|
||||
// Remove the item at that position, reducing the size of the
|
||||
// array by one. Return a reference the original array (not the
|
||||
// item that was removed).
|
||||
// array by one.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle& eraseItem(int at);
|
||||
void eraseItem(int at);
|
||||
// Erase and item and return the item that was removed.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle eraseItemAndGet(int at);
|
||||
@ -1050,19 +1047,16 @@ class QPDFObjectHandle
|
||||
// Mutator methods for dictionary objects
|
||||
|
||||
// Replace value of key, adding it if it does not exist. If value
|
||||
// is null, remove the key. Return a reference to the original
|
||||
// dictionary (not the new item).
|
||||
// is null, remove the key.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle&
|
||||
replaceKey(std::string const& key, QPDFObjectHandle const& value);
|
||||
void replaceKey(std::string const& key, QPDFObjectHandle const& value);
|
||||
// Replace value of key and return the value.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle
|
||||
replaceKeyAndGet(std::string const& key, QPDFObjectHandle const& value);
|
||||
// Remove key, doing nothing if key does not exist. Return the
|
||||
// original dictionary (not the removed item).
|
||||
// Remove key, doing nothing if key does not exist.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle& removeKey(std::string const& key);
|
||||
void removeKey(std::string const& key);
|
||||
// Remove key and return the old value. If the old value didn't
|
||||
// exist, return a null object.
|
||||
QPDF_DLL
|
||||
|
@ -208,8 +208,9 @@ NNTreeIterator::resetLimits(
|
||||
}
|
||||
}
|
||||
if (first.isInitialized() && last.isInitialized()) {
|
||||
auto limits =
|
||||
QPDFObjectHandle::newArray().appendItem(first).appendItem(last);
|
||||
auto limits = QPDFObjectHandle::newArray();
|
||||
limits.appendItem(first);
|
||||
limits.appendItem(last);
|
||||
auto olimits = node.getKey("/Limits");
|
||||
if (olimits.isArray() && (olimits.getArrayNItems() == 2)) {
|
||||
auto ofirst = olimits.getArrayItem(0);
|
||||
@ -340,10 +341,9 @@ NNTreeIterator::split(
|
||||
first_node.replaceKey(key, first_half);
|
||||
QPDFObjectHandle new_kids = QPDFObjectHandle::newArray();
|
||||
new_kids.appendItem(first_node);
|
||||
to_split
|
||||
.removeKey("/Limits") // already shouldn't be there for root
|
||||
.removeKey(impl.details.itemsKey())
|
||||
.replaceKey("/Kids", new_kids);
|
||||
to_split.removeKey("/Limits"); // already shouldn't be there for root
|
||||
to_split.removeKey(impl.details.itemsKey());
|
||||
to_split.replaceKey("/Kids", new_kids);
|
||||
if (is_leaf) {
|
||||
QTC::TC("qpdf", "NNTree split root + leaf");
|
||||
this->node = first_node;
|
||||
@ -884,8 +884,9 @@ NNTreeImpl::repair()
|
||||
for (auto const& i: *this) {
|
||||
repl.insert(i.first, i.second);
|
||||
}
|
||||
this->oh.replaceKey("/Kids", new_node.getKey("/Kids"))
|
||||
.replaceKey(details.itemsKey(), new_node.getKey(details.itemsKey()));
|
||||
this->oh.replaceKey("/Kids", new_node.getKey("/Kids"));
|
||||
this->oh.replaceKey(
|
||||
details.itemsKey(), new_node.getKey(details.itemsKey()));
|
||||
}
|
||||
|
||||
NNTreeImpl::iterator
|
||||
|
@ -733,7 +733,8 @@ QPDFAcroFormDocumentHelper::adjustAppearanceStream(
|
||||
auto existing_old = subdict.getKey(old_key);
|
||||
if (!existing_old.isNull()) {
|
||||
QTC::TC("qpdf", "QPDFAcroFormDocumentHelper ap rename");
|
||||
subdict.replaceKey(new_key, existing_old).removeKey(old_key);
|
||||
subdict.replaceKey(new_key, existing_old);
|
||||
subdict.removeKey(old_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ QPDFFileSpecObjectHelper::createFileSpec(
|
||||
QPDFFileSpecObjectHelper result(oh);
|
||||
result.setFilename(filename);
|
||||
auto ef = QPDFObjectHandle::newDictionary();
|
||||
ef.replaceKey("/F", efsoh.getObjectHandle())
|
||||
.replaceKey("/UF", efsoh.getObjectHandle());
|
||||
ef.replaceKey("/F", efsoh.getObjectHandle());
|
||||
ef.replaceKey("/UF", efsoh.getObjectHandle());
|
||||
oh.replaceKey("/EF", ef);
|
||||
return result;
|
||||
}
|
||||
|
@ -959,7 +959,7 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
|
||||
}
|
||||
}
|
||||
|
||||
QPDFObjectHandle&
|
||||
void
|
||||
QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item)
|
||||
{
|
||||
if (isArray()) {
|
||||
@ -968,7 +968,6 @@ QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item)
|
||||
typeWarning("array", "ignoring attempt to insert item");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
@ -978,7 +977,7 @@ QPDFObjectHandle::insertItemAndGet(int at, QPDFObjectHandle const& item)
|
||||
return item;
|
||||
}
|
||||
|
||||
QPDFObjectHandle&
|
||||
void
|
||||
QPDFObjectHandle::appendItem(QPDFObjectHandle const& item)
|
||||
{
|
||||
if (isArray()) {
|
||||
@ -988,7 +987,6 @@ QPDFObjectHandle::appendItem(QPDFObjectHandle const& item)
|
||||
typeWarning("array", "ignoring attempt to append item");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring append item");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
@ -998,7 +996,7 @@ QPDFObjectHandle::appendItemAndGet(QPDFObjectHandle const& item)
|
||||
return item;
|
||||
}
|
||||
|
||||
QPDFObjectHandle&
|
||||
void
|
||||
QPDFObjectHandle::eraseItem(int at)
|
||||
{
|
||||
if (isArray() && (at < getArrayNItems()) && (at >= 0)) {
|
||||
@ -1012,7 +1010,6 @@ QPDFObjectHandle::eraseItem(int at)
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item");
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
@ -1289,7 +1286,7 @@ QPDFObjectHandle::getOwningQPDF()
|
||||
|
||||
// Dictionary mutators
|
||||
|
||||
QPDFObjectHandle&
|
||||
void
|
||||
QPDFObjectHandle::replaceKey(
|
||||
std::string const& key, QPDFObjectHandle const& value)
|
||||
{
|
||||
@ -1300,7 +1297,6 @@ QPDFObjectHandle::replaceKey(
|
||||
typeWarning("dictionary", "ignoring key replacement request");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring replaceKey");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
@ -1311,7 +1307,7 @@ QPDFObjectHandle::replaceKeyAndGet(
|
||||
return value;
|
||||
}
|
||||
|
||||
QPDFObjectHandle&
|
||||
void
|
||||
QPDFObjectHandle::removeKey(std::string const& key)
|
||||
{
|
||||
if (isDictionary()) {
|
||||
@ -1320,7 +1316,6 @@ QPDFObjectHandle::removeKey(std::string const& key)
|
||||
typeWarning("dictionary", "ignoring key removal request");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring removeKey");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
|
@ -44,8 +44,9 @@ QPDFPageLabelDocumentHelper::getLabelForPage(long long page_idx)
|
||||
QIntC::range_check(start, offset);
|
||||
start += offset;
|
||||
result = QPDFObjectHandle::newDictionary();
|
||||
result.replaceKey("/S", S).replaceKey("/P", P).replaceKey(
|
||||
"/St", QPDFObjectHandle::newInteger(start));
|
||||
result.replaceKey("/S", S);
|
||||
result.replaceKey("/P", P);
|
||||
result.replaceKey("/St", QPDFObjectHandle::newInteger(start));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,8 @@ QPDFObjectHandle
|
||||
InlineImageTracker::convertIIDict(QPDFObjectHandle odict)
|
||||
{
|
||||
QPDFObjectHandle dict = QPDFObjectHandle::newDictionary();
|
||||
dict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"))
|
||||
.replaceKey("/Subtype", QPDFObjectHandle::newName("/Image"));
|
||||
dict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
||||
dict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Image"));
|
||||
std::set<std::string> keys = odict.getKeys();
|
||||
for (auto key: keys) {
|
||||
QPDFObjectHandle value = odict.getKey(key);
|
||||
@ -752,11 +752,11 @@ QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
|
||||
}
|
||||
QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf);
|
||||
QPDFObjectHandle newdict = result.getDict();
|
||||
newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"))
|
||||
.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"))
|
||||
.replaceKey(
|
||||
"/Resources", getAttribute("/Resources", false).shallowCopy())
|
||||
.replaceKey("/Group", getAttribute("/Group", false).shallowCopy());
|
||||
newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
||||
newdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"));
|
||||
newdict.replaceKey(
|
||||
"/Resources", getAttribute("/Resources", false).shallowCopy());
|
||||
newdict.replaceKey("/Group", getAttribute("/Group", false).shallowCopy());
|
||||
QPDFObjectHandle bbox = getTrimBox(false).shallowCopy();
|
||||
if (!bbox.isRectangle()) {
|
||||
this->oh.warnIfPossible("bounding box is invalid; form"
|
||||
|
@ -725,8 +725,8 @@ QPDF_Stream::replaceFilterData(
|
||||
QPDFObjectHandle const& decode_parms,
|
||||
size_t length)
|
||||
{
|
||||
this->stream_dict.replaceKey("/Filter", filter)
|
||||
.replaceKey("/DecodeParms", decode_parms);
|
||||
this->stream_dict.replaceKey("/Filter", filter);
|
||||
this->stream_dict.replaceKey("/DecodeParms", decode_parms);
|
||||
if (length == 0) {
|
||||
QTC::TC("qpdf", "QPDF_Stream unknown stream length");
|
||||
this->stream_dict.removeKey("/Length");
|
||||
|
@ -62,15 +62,16 @@ test_bsearch()
|
||||
auto mk = [&q](std::vector<int> const& v) {
|
||||
auto nums = QPDFObjectHandle::newArray();
|
||||
for (auto i: v) {
|
||||
nums.appendItem(QPDFObjectHandle::newInteger(i))
|
||||
.appendItem(QPDFObjectHandle::newString(
|
||||
"-" + QUtil::int_to_string(i) + "-"));
|
||||
nums.appendItem(QPDFObjectHandle::newInteger(i));
|
||||
nums.appendItem(QPDFObjectHandle::newString(
|
||||
"-" + QUtil::int_to_string(i) + "-"));
|
||||
}
|
||||
auto limits = QPDFObjectHandle::newArray();
|
||||
limits.appendItem(QPDFObjectHandle::newInteger(v.at(0)))
|
||||
.appendItem(QPDFObjectHandle::newInteger(v.at(v.size() - 1)));
|
||||
limits.appendItem(QPDFObjectHandle::newInteger(v.at(0)));
|
||||
limits.appendItem(QPDFObjectHandle::newInteger(v.at(v.size() - 1)));
|
||||
auto node = q.makeIndirectObject(QPDFObjectHandle::newDictionary());
|
||||
node.replaceKey("/Nums", nums).replaceKey("/Limits", limits);
|
||||
node.replaceKey("/Nums", nums);
|
||||
node.replaceKey("/Limits", limits);
|
||||
return node;
|
||||
};
|
||||
|
||||
@ -168,8 +169,8 @@ test_depth()
|
||||
int val =
|
||||
(((((i1 * NITEMS) + i2) * NITEMS) + i3) * NITEMS) + i4;
|
||||
std::string str = QUtil::int_to_string(10 * val, 6);
|
||||
items.appendItem(QPDFObjectHandle::newString(str))
|
||||
.appendItem(QPDFObjectHandle::newString("val " + str));
|
||||
items.appendItem(QPDFObjectHandle::newString(str));
|
||||
items.appendItem(QPDFObjectHandle::newString("val " + str));
|
||||
if (i4 == 0) {
|
||||
first = str;
|
||||
} else if (i4 == NITEMS - 1) {
|
||||
@ -178,23 +179,21 @@ test_depth()
|
||||
}
|
||||
auto limits = QPDFObjectHandle::newArray();
|
||||
n3.replaceKey("/Limits", limits);
|
||||
limits.appendItem(QPDFObjectHandle::newString(first))
|
||||
.appendItem(QPDFObjectHandle::newString(last));
|
||||
limits.appendItem(QPDFObjectHandle::newString(first));
|
||||
limits.appendItem(QPDFObjectHandle::newString(last));
|
||||
}
|
||||
auto limits = QPDFObjectHandle::newArray();
|
||||
n2.replaceKey("/Limits", limits);
|
||||
limits
|
||||
.appendItem(
|
||||
k2.getArrayItem(0).getKey("/Limits").getArrayItem(0))
|
||||
.appendItem(k2.getArrayItem(NITEMS - 1)
|
||||
.getKey("/Limits")
|
||||
.getArrayItem(1));
|
||||
limits.appendItem(
|
||||
k2.getArrayItem(0).getKey("/Limits").getArrayItem(0));
|
||||
limits.appendItem(
|
||||
k2.getArrayItem(NITEMS - 1).getKey("/Limits").getArrayItem(1));
|
||||
}
|
||||
auto limits = QPDFObjectHandle::newArray();
|
||||
n1.replaceKey("/Limits", limits);
|
||||
limits.appendItem(k1.getArrayItem(0).getKey("/Limits").getArrayItem(0))
|
||||
.appendItem(
|
||||
k1.getArrayItem(NITEMS - 1).getKey("/Limits").getArrayItem(1));
|
||||
limits.appendItem(k1.getArrayItem(0).getKey("/Limits").getArrayItem(0));
|
||||
limits.appendItem(
|
||||
k1.getArrayItem(NITEMS - 1).getKey("/Limits").getArrayItem(1));
|
||||
}
|
||||
|
||||
QPDFNameTreeObjectHelper nh(n0, q);
|
||||
|
@ -98,12 +98,9 @@ For a detailed list of changes, please see the file
|
||||
|
||||
- Library Enhancements
|
||||
|
||||
- Support for more fluent programming with ``QPDFObjectHandle``.
|
||||
The methods ``insertItem``, ``appendItem``, ``eraseItem``,
|
||||
``replaceKey``, and ``removeKey`` all return a reference to the
|
||||
object being modified. New methods ``insertItemAndGet``,
|
||||
``appendItemAndGet``, ``eraseItemAndGet``, ``replaceKeyAndGet``,
|
||||
and ``removeKeyAndGet`` return the newly added or removed object.
|
||||
- New methods ``insertItemAndGet``, ``appendItemAndGet``,
|
||||
``eraseItemAndGet``, ``replaceKeyAndGet``, and
|
||||
``removeKeyAndGet`` return the newly added or removed object.
|
||||
|
||||
- Add new ``Pipeline`` methods to reduce the amount of casting that is
|
||||
needed:
|
||||
|
@ -60,14 +60,15 @@ runtest(int n)
|
||||
rfont.replaceKey("/F1", font);
|
||||
|
||||
QPDFObjectHandle resources = QPDFObjectHandle::newDictionary();
|
||||
resources.replaceKey("/ProcSet", procset).replaceKey("/Font", rfont);
|
||||
resources.replaceKey("/ProcSet", procset);
|
||||
resources.replaceKey("/Font", rfont);
|
||||
|
||||
QPDFObjectHandle page =
|
||||
pdf.makeIndirectObject(QPDFObjectHandle::newDictionary());
|
||||
page.replaceKey("/Type", newName("/Page"))
|
||||
.replaceKey("/MediaBox", mediabox)
|
||||
.replaceKey("/Contents", contents)
|
||||
.replaceKey("/Resources", resources);
|
||||
page.replaceKey("/Type", newName("/Page"));
|
||||
page.replaceKey("/MediaBox", mediabox);
|
||||
page.replaceKey("/Contents", contents);
|
||||
page.replaceKey("/Resources", resources);
|
||||
|
||||
QPDFPageDocumentHelper(pdf).addPage(page, true);
|
||||
|
||||
|
@ -525,7 +525,8 @@ test_9(QPDF& pdf, char const* arg2)
|
||||
"data for other stream\n",
|
||||
QPDFObjectHandle::newNull(),
|
||||
QPDFObjectHandle::newNull());
|
||||
root.replaceKey("/QStream", qstream).replaceKey("/RStream", rstream);
|
||||
root.replaceKey("/QStream", qstream);
|
||||
root.replaceKey("/RStream", rstream);
|
||||
QPDFWriter w(pdf, "a.pdf");
|
||||
w.setStaticID(true);
|
||||
w.setStreamDataMode(qpdf_s_preserve);
|
||||
@ -895,12 +896,15 @@ test_24(QPDF& pdf, char const* arg2)
|
||||
QPDFObjectHandle res1 = QPDFObjectHandle::newReserved(&pdf);
|
||||
QPDFObjectHandle res2 = QPDFObjectHandle::newReserved(&pdf);
|
||||
QPDFObjectHandle trailer = pdf.getTrailer();
|
||||
trailer.replaceKey("Array1", res1).replaceKey("Array2", res2);
|
||||
trailer.replaceKey("Array1", res1);
|
||||
trailer.replaceKey("Array2", res2);
|
||||
|
||||
QPDFObjectHandle array1 = QPDFObjectHandle::newArray();
|
||||
QPDFObjectHandle array2 = QPDFObjectHandle::newArray();
|
||||
array1.appendItem(res2).appendItem(QPDFObjectHandle::newInteger(1));
|
||||
array2.appendItem(res1).appendItem(QPDFObjectHandle::newInteger(2));
|
||||
array1.appendItem(res2);
|
||||
array1.appendItem(QPDFObjectHandle::newInteger(1));
|
||||
array2.appendItem(res1);
|
||||
array2.appendItem(QPDFObjectHandle::newInteger(2));
|
||||
// Make sure trying to ask questions about a reserved object
|
||||
// doesn't break it.
|
||||
if (res1.isArray()) {
|
||||
@ -1065,14 +1069,13 @@ test_27(QPDF& pdf, char const* arg2)
|
||||
dh.addPage(O3.getKey("/OtherPage"), false);
|
||||
dh.addPage(O3, false);
|
||||
QPDFObjectHandle s2 = QPDFObjectHandle::newStream(&oldpdf, "potato\n");
|
||||
pdf.getTrailer()
|
||||
.replaceKey("/QTest", pdf.copyForeignObject(qtest))
|
||||
.replaceKey("/QTest2", QPDFObjectHandle::newArray());
|
||||
pdf.getTrailer()
|
||||
.getKey("/QTest2")
|
||||
.appendItem(pdf.copyForeignObject(s1))
|
||||
.appendItem(pdf.copyForeignObject(s2))
|
||||
.appendItem(pdf.copyForeignObject(s3));
|
||||
auto trailer = pdf.getTrailer();
|
||||
trailer.replaceKey("/QTest", pdf.copyForeignObject(qtest));
|
||||
auto qtest2 =
|
||||
trailer.replaceKeyAndGet("/QTest2", QPDFObjectHandle::newArray());
|
||||
qtest2.appendItem(pdf.copyForeignObject(s1));
|
||||
qtest2.appendItem(pdf.copyForeignObject(s2));
|
||||
qtest2.appendItem(pdf.copyForeignObject(s3));
|
||||
}
|
||||
|
||||
QPDFWriter w(pdf, "a.pdf");
|
||||
@ -2035,12 +2038,6 @@ test_55(QPDF& pdf, char const* arg2)
|
||||
QPDFPageDocumentHelper(pdf).getAllPages();
|
||||
QPDFObjectHandle qtest = QPDFObjectHandle::newArray();
|
||||
for (auto& ph: pages) {
|
||||
// Note: using fluent appendItem causes a test failure with
|
||||
// MSVC 19.31.31107, which appears to evaluate the argument to
|
||||
// the second appendItem before the first. Since these
|
||||
// arguments have the side effect of creating objects, the
|
||||
// object numbers end up being different even though the
|
||||
// resulting file is semantically correct.
|
||||
qtest.appendItem(ph.getFormXObjectForPage());
|
||||
qtest.appendItem(ph.getFormXObjectForPage(false));
|
||||
}
|
||||
@ -2196,10 +2193,10 @@ test_60(QPDF& pdf, char const* arg2)
|
||||
|
||||
// The only differences between /QTest and /QTest3 should be
|
||||
// the direct objects merged from r2.
|
||||
pdf.getTrailer()
|
||||
.replaceKey("/QTest1", r1)
|
||||
.replaceKey("/QTest2", r2)
|
||||
.replaceKey("/QTest3", r3);
|
||||
auto trailer = pdf.getTrailer();
|
||||
trailer.replaceKey("/QTest1", r1);
|
||||
trailer.replaceKey("/QTest2", r2);
|
||||
trailer.replaceKey("/QTest3", r3);
|
||||
QPDFWriter w(pdf, "a.pdf");
|
||||
w.setQDFMode(true);
|
||||
w.setStaticID(true);
|
||||
@ -2259,9 +2256,9 @@ test_62(QPDF& pdf, char const* arg2)
|
||||
long long q2 = QIntC::to_longlong(q2_l);
|
||||
unsigned int q3_i = UINT_MAX;
|
||||
long long q3 = QIntC::to_longlong(q3_i);
|
||||
t.replaceKey("/Q1", QPDFObjectHandle::newInteger(q1))
|
||||
.replaceKey("/Q2", QPDFObjectHandle::newInteger(q2))
|
||||
.replaceKey("/Q3", QPDFObjectHandle::newInteger(q3));
|
||||
t.replaceKey("/Q1", QPDFObjectHandle::newInteger(q1));
|
||||
t.replaceKey("/Q2", QPDFObjectHandle::newInteger(q2));
|
||||
t.replaceKey("/Q3", QPDFObjectHandle::newInteger(q3));
|
||||
assert_compare_numbers(q1, t.getKey("/Q1").getIntValue());
|
||||
assert_compare_numbers(q1_l, t.getKey("/Q1").getUIntValue());
|
||||
assert_compare_numbers(INT_MAX, t.getKey("/Q1").getIntValueAsInt());
|
||||
@ -3120,17 +3117,16 @@ test_87(QPDF& pdf, char const* arg2)
|
||||
static void
|
||||
test_88(QPDF& pdf, char const* arg2)
|
||||
{
|
||||
// Exercise fluent QPDFObjectHandle mutators and similar methods
|
||||
// added for qpdf 11.
|
||||
auto dict = QPDFObjectHandle::newDictionary()
|
||||
.replaceKey("/One", QPDFObjectHandle::newInteger(1))
|
||||
.replaceKey("/Two", QPDFObjectHandle::newInteger(2));
|
||||
dict.replaceKeyAndGet("/Three", QPDFObjectHandle::newArray())
|
||||
.appendItem("(a)"_qpdf)
|
||||
.appendItem("(b)"_qpdf)
|
||||
.appendItemAndGet(QPDFObjectHandle::newDictionary())
|
||||
.replaceKey("/Z", "/Y"_qpdf)
|
||||
.replaceKey("/X", "/W"_qpdf);
|
||||
// Exercise mutate and get methods added for qpdf 11.
|
||||
auto dict = QPDFObjectHandle::newDictionary();
|
||||
dict.replaceKey("/One", QPDFObjectHandle::newInteger(1));
|
||||
dict.replaceKey("/Two", QPDFObjectHandle::newInteger(2));
|
||||
auto three = dict.replaceKeyAndGet("/Three", QPDFObjectHandle::newArray());
|
||||
three.appendItem("(a)"_qpdf);
|
||||
three.appendItem("(b)"_qpdf);
|
||||
auto newdict = three.appendItemAndGet(QPDFObjectHandle::newDictionary());
|
||||
newdict.replaceKey("/Z", "/Y"_qpdf);
|
||||
newdict.replaceKey("/X", "/W"_qpdf);
|
||||
assert(dict.unparse() == R"(
|
||||
<<
|
||||
/One 1
|
||||
@ -3138,14 +3134,15 @@ test_88(QPDF& pdf, char const* arg2)
|
||||
/Three [ (a) (b) << /Z /Y /X /W >> ]
|
||||
>>
|
||||
)"_qpdf.unparse());
|
||||
auto arr = dict.getKey("/Three")
|
||||
.insertItem(0, QPDFObjectHandle::newString("0"))
|
||||
.insertItem(0, QPDFObjectHandle::newString("00"));
|
||||
auto arr = dict.getKey("/Three");
|
||||
arr.insertItem(0, QPDFObjectHandle::newString("0"));
|
||||
arr.insertItem(0, QPDFObjectHandle::newString("00"));
|
||||
assert(
|
||||
arr.unparse() ==
|
||||
"[ (00) (0) (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse());
|
||||
auto new_dict = arr.insertItemAndGet(1, "<< /P /Q /R /S >>"_qpdf);
|
||||
arr.eraseItem(2).eraseItem(0);
|
||||
arr.eraseItem(2);
|
||||
arr.eraseItem(0);
|
||||
assert(
|
||||
arr.unparse() ==
|
||||
"[ << /P /Q /R /S >> (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse());
|
||||
@ -3154,7 +3151,8 @@ test_88(QPDF& pdf, char const* arg2)
|
||||
// always been this way, and there is code that relies on this
|
||||
// behavior. Maybe it would be different if I could start over
|
||||
// again...
|
||||
new_dict.removeKey("/R").replaceKey("/T", "/U"_qpdf);
|
||||
new_dict.removeKey("/R");
|
||||
new_dict.replaceKey("/T", "/U"_qpdf);
|
||||
assert(
|
||||
arr.unparse() ==
|
||||
"[ << /P /Q /T /U >> (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse());
|
||||
|
@ -187,37 +187,37 @@ create_pdf(char const* filename)
|
||||
|
||||
QPDFObjectHandle font =
|
||||
pdf.makeIndirectObject(QPDFObjectHandle::newDictionary());
|
||||
font.replaceKey("/Type", newName("/Font"))
|
||||
.replaceKey("/Subtype", newName("/Type1"))
|
||||
.replaceKey("/Name", newName("/F1"))
|
||||
.replaceKey("/BaseFont", newName("/Helvetica"))
|
||||
.replaceKey("/Encoding", newName("/WinAnsiEncoding"));
|
||||
font.replaceKey("/Type", newName("/Font"));
|
||||
font.replaceKey("/Subtype", newName("/Type1"));
|
||||
font.replaceKey("/Name", newName("/F1"));
|
||||
font.replaceKey("/BaseFont", newName("/Helvetica"));
|
||||
font.replaceKey("/Encoding", newName("/WinAnsiEncoding"));
|
||||
|
||||
QPDFObjectHandle procset =
|
||||
pdf.makeIndirectObject(QPDFObjectHandle::newArray());
|
||||
procset.appendItem(newName("/PDF"))
|
||||
.appendItem(newName("/Text"))
|
||||
.appendItem(newName("/ImageC"));
|
||||
procset.appendItem(newName("/PDF"));
|
||||
procset.appendItem(newName("/Text"));
|
||||
procset.appendItem(newName("/ImageC"));
|
||||
|
||||
QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary();
|
||||
rfont.replaceKey("/F1", font);
|
||||
|
||||
QPDFObjectHandle mediabox = QPDFObjectHandle::newArray();
|
||||
mediabox.appendItem(newInteger(0))
|
||||
.appendItem(newInteger(0))
|
||||
.appendItem(newInteger(612))
|
||||
.appendItem(newInteger(792));
|
||||
mediabox.appendItem(newInteger(0));
|
||||
mediabox.appendItem(newInteger(0));
|
||||
mediabox.appendItem(newInteger(612));
|
||||
mediabox.appendItem(newInteger(792));
|
||||
|
||||
QPDFPageDocumentHelper dh(pdf);
|
||||
for (size_t pageno = 1; pageno <= npages; ++pageno) {
|
||||
QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf);
|
||||
QPDFObjectHandle image_dict = image.getDict();
|
||||
image_dict.replaceKey("/Type", newName("/XObject"))
|
||||
.replaceKey("/Subtype", newName("/Image"))
|
||||
.replaceKey("/ColorSpace", newName("/DeviceGray"))
|
||||
.replaceKey("/BitsPerComponent", newInteger(8))
|
||||
.replaceKey("/Width", newInteger(width))
|
||||
.replaceKey("/Height", newInteger(height));
|
||||
image_dict.replaceKey("/Type", newName("/XObject"));
|
||||
image_dict.replaceKey("/Subtype", newName("/Image"));
|
||||
image_dict.replaceKey("/ColorSpace", newName("/DeviceGray"));
|
||||
image_dict.replaceKey("/BitsPerComponent", newInteger(8));
|
||||
image_dict.replaceKey("/Width", newInteger(width));
|
||||
image_dict.replaceKey("/Height", newInteger(height));
|
||||
ImageProvider* p = new ImageProvider(pageno);
|
||||
std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p);
|
||||
image.replaceStreamData(
|
||||
@ -227,18 +227,18 @@ create_pdf(char const* filename)
|
||||
xobject.replaceKey("/Im1", image);
|
||||
|
||||
QPDFObjectHandle resources = QPDFObjectHandle::newDictionary();
|
||||
resources.replaceKey("/ProcSet", procset)
|
||||
.replaceKey("/Font", rfont)
|
||||
.replaceKey("/XObject", xobject);
|
||||
resources.replaceKey("/ProcSet", procset);
|
||||
resources.replaceKey("/Font", rfont);
|
||||
resources.replaceKey("/XObject", xobject);
|
||||
|
||||
QPDFObjectHandle contents = create_page_contents(pdf, pageno);
|
||||
|
||||
QPDFObjectHandle page =
|
||||
pdf.makeIndirectObject(QPDFObjectHandle::newDictionary());
|
||||
page.replaceKey("/Type", newName("/Page"))
|
||||
.replaceKey("/MediaBox", mediabox)
|
||||
.replaceKey("/Contents", contents)
|
||||
.replaceKey("/Resources", resources);
|
||||
page.replaceKey("/Type", newName("/Page"));
|
||||
page.replaceKey("/MediaBox", mediabox);
|
||||
page.replaceKey("/Contents", contents);
|
||||
page.replaceKey("/Resources", resources);
|
||||
|
||||
dh.addPage(page, false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user