Sophie

Sophie

distrib > Mageia > 9 > armv7hl > media > core-release-src > by-pkgid > d3fc76fe325ca661cb5adbf012153e1c > files > 15

ghostscript-10.00.0-6.mga9.src.rpm

From 45a27a3b7d45fc75c2f9bf96cb877036f6c7e6c2 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Sat, 15 Oct 2022 13:07:03 +0100
Subject: [PATCH 155/155] GhostPDF - Fix /Outline processing

Bug #705971 " New PDF interpreter nests flat bookmarks"

Due to the strange difference in the meaning of /Count in an /Outline
entry and in a /OUT pdfmark, the wrong value was being passed to the
pdfwrite device in the pdfmark.
---
 pdf/pdf_doc.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/pdf/pdf_doc.c b/pdf/pdf_doc.c
index 991455cf0..8f7a7222a 100644
--- a/pdf/pdf_doc.c
+++ b/pdf/pdf_doc.c
@@ -1071,6 +1071,7 @@ static int pdfi_doc_mark_the_outline(pdf_context *ctx, pdf_dict *outline)
     uint64_t dictsize;
     uint64_t index;
     pdf_name *Key = NULL;
+    double num;
 
     /* Basically we only do /Count, /Title, /A, /C, /F
      * The /First, /Last, /Next, /Parent get written magically by pdfwrite
@@ -1084,6 +1085,42 @@ static int pdfi_doc_mark_the_outline(pdf_context *ctx, pdf_dict *outline)
     code = pdfi_dict_copy(ctx, tempdict, outline);
     if (code < 0) goto exit;
 
+    /* Due to some craziness on the part of Adobe, the /Count in an Outline entry
+     * in a PDF file, and the /Count value in an /OUT pdfmark mean different things(!)
+     * In a PDF file it is the number of outline entries beneath the current entry
+     * (all child descsndants) whereas in a pdfmark it is the number of entries
+     * in just the next level. So we cannot use the /Count from the PDF file, we
+     * need to go to the /First entry of the next level, and then count all
+     * the entries at that level by following each /Next.
+     */
+    code = pdfi_dict_knownget_number(ctx, outline, "Count", &num);
+    if (code < 0)
+        goto exit;
+
+    if (code > 0) {
+        pdf_dict *current = NULL, *next = NULL;
+        int count = 0;
+
+        code = pdfi_dict_knownget_type(ctx, outline, "First", PDF_DICT, (pdf_obj **)&current);
+        if (code > 0) {
+            count++;
+            do {
+                code = pdfi_dict_knownget_type(ctx, current, "Next", PDF_DICT, (pdf_obj **)&next);
+                if (code > 0) {
+                    pdfi_countdown(current);
+                    current = next;
+                    next = NULL;
+                    count++;
+                } else
+                    break;
+            } while (1);
+            pdfi_countdown(current);
+        }
+        if (num < 0)
+            count *= -1;
+        pdfi_dict_put_int(ctx, tempdict, "Count", count);
+    }
+
     /* Go through the dict, removing some keys and doing special handling for others.
      */
     code = pdfi_dict_key_first(ctx, outline, (pdf_obj **)&Key, &index);
-- 
2.30.4