From 57277d2c896d480402d657784586ca789dad2064 Mon Sep 17 00:00:00 2001
From: Alexander Golubev <fatzer2@gmail.com>
Date: Sun, 24 May 2026 00:27:40 +0300
Subject: kpdf/xpdf: use doc info for title and escape it

When exporting a PDF into a PostScript use the title from the PDF
metadata instead of explicitly passing it to PSOutputDev() and also
escape the title.

Closes: https://mirror.git.trinitydesktop.org/gitea/TDE/tdegraphics/issues/158
Signed-off-by: Alexander Golubev <fatzer2@gmail.com>
---
 kpdf/core/generator_pdf/generator_pdf.cpp | 19 ++++---------------
 kpdf/xpdf/xpdf/PSOutputDev.cpp            | 20 +++++++++++---------
 kpdf/xpdf/xpdf/PSOutputDev.h              |  6 +++---
 3 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/kpdf/core/generator_pdf/generator_pdf.cpp b/kpdf/core/generator_pdf/generator_pdf.cpp
index c5ec1b97..6d71ae98 100644
--- a/kpdf/core/generator_pdf/generator_pdf.cpp
+++ b/kpdf/core/generator_pdf/generator_pdf.cpp
@@ -457,25 +457,14 @@ bool PDFGenerator::print( KPrinter& printer )
     {
         pstitle = m_document->currentDocument().fileName( false );
     }
-    // this looks non-unicode-safe and it is. anything other than ASCII is not specified
-    // and some printers actually stop printing when they encounter non-ASCII characters in the
-    // Postscript %%Title tag
-    TQCString pstitle8Bit = pstitle.latin1();
-    const char* pstitlechar;
     if (!pstitle.isEmpty())
     {
-      pstitlechar = pstitle8Bit.data();
-      for (unsigned char* p = (unsigned char*) pstitle8Bit.data(); *p; ++p)
-          if (*p >= 0x80)
-              *p = '?';
-
       printer.setDocName(pstitle);
     }
-    else
-    {
-      pstitlechar = 0;
-    }
-    PSOutputDev *psOut = new PSOutputDev(const_cast<char*>(tf.name().latin1()), const_cast<char*>(pstitlechar), pdfdoc->getXRef(), pdfdoc->getCatalog(), 1, pdfdoc->getNumPages(), psModePS, marginLeft, marginBottom, paperWidth - marginRight, paperHeight - marginTop, forceRasterize);
+    PSOutputDev *psOut = new PSOutputDev( const_cast<char*>(tf.name().latin1()), pdfdoc->getXRef(),
+        pdfdoc->getCatalog(), 1, pdfdoc->getNumPages(), psModePS, marginLeft, marginBottom,
+        paperWidth - marginRight, paperHeight - marginTop, forceRasterize
+    );
 
     if (psOut->isOk())
     {
diff --git a/kpdf/xpdf/xpdf/PSOutputDev.cpp b/kpdf/xpdf/xpdf/PSOutputDev.cpp
index 9d1d7648..f05c86ea 100644
--- a/kpdf/xpdf/xpdf/PSOutputDev.cpp
+++ b/kpdf/xpdf/xpdf/PSOutputDev.cpp
@@ -943,7 +943,7 @@ static void outputToFile(void *stream, char *data, int len) {
   fwrite(data, 1, len, (FILE *)stream);
 }
 
-PSOutputDev::PSOutputDev(char *fileName, char *pstitle, XRef *xrefA, Catalog *catalog,
+PSOutputDev::PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog,
 			 int firstPage, int lastPage, PSOutMode modeA,
 			 int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
 			 GBool forceRasterizeA,
@@ -1000,13 +1000,13 @@ PSOutputDev::PSOutputDev(char *fileName, char *pstitle, XRef *xrefA, Catalog *ca
     }
   }
 
-  init(outputToFile, f, fileTypeA, pstitle,
+  init(outputToFile, f, fileTypeA,
        xrefA, catalog, firstPage, lastPage, modeA,
        imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA);
 }
 
 void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
-		       PSFileType fileTypeA, char *pstitle, XRef *xrefA, Catalog *catalog,
+		       PSFileType fileTypeA, XRef *xrefA, Catalog *catalog,
 		       int firstPage, int lastPage, PSOutMode modeA,
 		       int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
 		       GBool manualCtrlA) {
@@ -1100,10 +1100,10 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
       writeHeader(firstPage, lastPage,
 		  catalog->getPage(firstPage)->getMediaBox(),
 		  catalog->getPage(firstPage)->getCropBox(),
-		  catalog->getPage(firstPage)->getRotate(), pstitle);
+		  catalog->getPage(firstPage)->getRotate());
     } else {
       box = new PDFRectangle(0, 0, 1, 1);
-      writeHeader(firstPage, lastPage, box, box, 0, pstitle);
+      writeHeader(firstPage, lastPage, box, box, 0);
       delete box;
     }
     if (mode != psModeForm) {
@@ -1199,7 +1199,7 @@ PSOutputDev::~PSOutputDev() {
 
 void PSOutputDev::writeHeader(int firstPage, int lastPage,
 			      PDFRectangle *mediaBox, PDFRectangle *cropBox,
-			      int pageRotate, char *pstitle) {
+			      int pageRotate) {
   Object info, obj1;
   double x1, y1, x2, y2;
 
@@ -1221,10 +1221,12 @@ void PSOutputDev::writeHeader(int firstPage, int lastPage,
     writePSTextLine(obj1.getString());
   }
   obj1.free();
-  info.free();
-  if(pstitle) {
-    writePSFmt("%%Title: {0:s}\n", pstitle);
+  if (info.isDict() && info.dictLookup("Title", &obj1)->isString()) {
+    writePS("%%Title: ");
+    writePSTextLine(obj1.getString());
   }
+  obj1.free();
+  info.free();
   writePSFmt("%%LanguageLevel: {0:d}\n",
 	     (level == psLevel1 || level == psLevel1Sep) ? 1 :
 	     (level == psLevel2 || level == psLevel2Sep) ? 2 : 3);
diff --git a/kpdf/xpdf/xpdf/PSOutputDev.h b/kpdf/xpdf/xpdf/PSOutputDev.h
index 36c0e8b6..e069f2f7 100644
--- a/kpdf/xpdf/xpdf/PSOutputDev.h
+++ b/kpdf/xpdf/xpdf/PSOutputDev.h
@@ -54,7 +54,7 @@ class PSOutputDev: public OutputDev {
 public:
 
   // Open a PostScript output file, and write the prolog.
-  PSOutputDev(char *fileName, char *pstitle, XRef *xrefA, Catalog *catalog,
+  PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog,
 	      int firstPage, int lastPage, PSOutMode modeA,
 	      int imgLLXA = 0, int imgLLYA = 0,
 	      int imgURXA = 0, int imgURYA = 0,
@@ -100,7 +100,7 @@ public:
   // Write the document-level header.
   void writeHeader(int firstPage, int lastPage,
 		   PDFRectangle *mediaBox, PDFRectangle *cropBox,
-		   int pageRotate, char *pstitle);
+		   int pageRotate);
 
   // Write the Xpdf procset.
   void writeXpdfProcset();
@@ -237,7 +237,7 @@ public:
 private:
 
   void init(PSOutputFunc outputFuncA, void *outputStreamA,
-	    PSFileType fileTypeA, char *pstitle, XRef *xrefA, Catalog *catalog,
+	    PSFileType fileTypeA, XRef *xrefA, Catalog *catalog,
 	    int firstPage, int lastPage, PSOutMode modeA,
 	    int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
 	    GBool manualCtrlA);
-- 
cgit v1.2.3

