LibPDF: Support null destination parameters

Destination arrays contain a page number, a mode name, and parameters
specific to that mode. In many cases these parameters can be set to
"null", which our code wasn't taking into consideration.

This commit parses these parameters taking into account whether they are
null or actual numbers, and stores them as Optional<float> instead of
plain floats. The parameters are not yet used anywhere else other than
when formatting a Destination object, so the change is fairly small.
This commit is contained in:
Rodrigo Tobar 2023-01-05 23:49:40 +08:00 committed by Andreas Kling
parent 2485c500a3
commit f510b2b180
2 changed files with 19 additions and 7 deletions

View file

@ -232,9 +232,15 @@ PDFErrorOr<Destination> Document::create_destination_from_parameters(NonnullRefP
auto page_ref = array->at(0);
auto type_name = TRY(array->get_name_at(this, 1))->name();
Vector<float> parameters;
for (size_t i = 2; i < array->size(); i++)
parameters.append(array->at(i).to_float());
Vector<Optional<float>> parameters;
TRY(parameters.try_ensure_capacity(array->size() - 2));
for (size_t i = 2; i < array->size(); i++) {
auto& param = array->at(i);
if (param.has<nullptr_t>())
parameters.unchecked_append({});
else
parameters.append(param.to_float());
}
Destination::Type type;
if (type_name == CommonNames::XYZ) {

View file

@ -51,7 +51,7 @@ struct Destination {
Type type;
Optional<u32> page;
Vector<float> parameters;
Vector<Optional<float>> parameters;
};
struct OutlineItem final : public RefCounted<OutlineItem> {
@ -232,9 +232,15 @@ struct Formatter<PDF::Destination> : Formatter<FormatString> {
TRY(builder.put_literal("{{}}"sv));
else
TRY(builder.put_u64(destination.page.value()));
for (auto& param : destination.parameters) {
TRY(builder.put_f64(double(param)));
TRY(builder.put_literal(" "sv));
if (!destination.parameters.is_empty()) {
TRY(builder.put_literal(" parameters="sv));
for (auto const& param : destination.parameters) {
if (param.has_value())
TRY(builder.put_f64(double(param.value())));
else
TRY(builder.put_literal("{{}}"sv));
TRY(builder.put_literal(" "sv));
}
}
return builder.put_literal(" }}"sv);
}