Pārlūkot izejas kodu

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.
Rodrigo Tobar 2 gadi atpakaļ
vecāks
revīzija
f510b2b180

+ 9 - 3
Userland/Libraries/LibPDF/Document.cpp

@@ -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) {

+ 10 - 4
Userland/Libraries/LibPDF/Document.h

@@ -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);
     }