Blame SOURCES/cups-filters-page-label.patch

b95efc
diff -up cups-filters-1.0.35/filter/pdftopdf/pdftopdf.cc.page-label cups-filters-1.0.35/filter/pdftopdf/pdftopdf.cc
b95efc
--- cups-filters-1.0.35/filter/pdftopdf/pdftopdf.cc.page-label	2013-04-09 19:14:42.000000000 +0100
b95efc
+++ cups-filters-1.0.35/filter/pdftopdf/pdftopdf.cc	2013-07-24 08:49:23.919081384 +0100
b95efc
@@ -9,6 +9,8 @@
b95efc
 #include <assert.h>
b95efc
 #include <cups/cups.h>
b95efc
 #include <cups/ppd.h>
b95efc
+#include <iomanip>
b95efc
+#include <sstream>
b95efc
 #include <memory>
b95efc
 
b95efc
 #include "pdftopdf_processor.h"
b95efc
@@ -402,8 +404,27 @@ void getParameters(ppd_file_t *ppd,int n
b95efc
     param.reverse=ppdDefaultOrder(ppd);
b95efc
   }
b95efc
 
b95efc
-  // TODO: pageLabel  (not used)
b95efc
-  // param.pageLabel=cupsGetOption("page-label",num_options,options);  // strdup?
b95efc
+  std::string rawlabel;
b95efc
+  char *classification = getenv("CLASSIFICATION");
b95efc
+  if (classification)
b95efc
+    rawlabel.append (classification);
b95efc
+
b95efc
+  if ( (val=cupsGetOption("page-label", num_options, options)) != NULL) {
b95efc
+    if (!rawlabel.empty())
b95efc
+      rawlabel.append (" - ");
b95efc
+    rawlabel.append(cupsGetOption("page-label",num_options,options));
b95efc
+  }
b95efc
+
b95efc
+  std::ostringstream cookedlabel;
b95efc
+  for (std::string::iterator it = rawlabel.begin();
b95efc
+       it != rawlabel.end ();
b95efc
+       ++it) {
b95efc
+    if (*it < 32 || *it > 126)
b95efc
+      cookedlabel << "\\" << std::oct << std::setfill('0') << std::setw(3) << (unsigned int) *it;
b95efc
+    else
b95efc
+      cookedlabel.put (*it);
b95efc
+  }
b95efc
+  param.pageLabel = cookedlabel.str ();
b95efc
 
b95efc
   if ( (val=cupsGetOption("page-set",num_options,options)) != NULL) {
b95efc
     if (strcasecmp(val,"even")==0) {
b95efc
diff -up cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.cc.page-label cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.cc
b95efc
--- cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.cc.page-label	2013-02-15 17:37:59.000000000 +0000
b95efc
+++ cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.cc	2013-07-24 09:50:04.437720618 +0100
b95efc
@@ -80,12 +80,8 @@ void ProcessingParameters::dump() const
b95efc
   fprintf(stderr,"evenDuplex: %s\n",
b95efc
                  (evenDuplex)?"true":"false");
b95efc
 
b95efc
-/*
b95efc
-  // std::string pageLabel; // or NULL?  must stay/dup!
b95efc
-  ...
b95efc
-  ...
b95efc
-
b95efc
-*/
b95efc
+  fprintf(stderr,"pageLabel: %s\n",
b95efc
+	  pageLabel.empty () ? "(none)" : pageLabel.c_str());
b95efc
 
b95efc
   fprintf(stderr,"bookletMode: ");
b95efc
   BookletMode_dump(booklet);
b95efc
@@ -206,6 +202,10 @@ bool processPDFTOPDF(PDFTOPDF_Processor
b95efc
         page->mirror();
b95efc
       }
b95efc
 
b95efc
+      if (!param.pageLabel.empty()) {
b95efc
+	page->add_label(param.page, param.pageLabel);
b95efc
+      }
b95efc
+
b95efc
       // place border
b95efc
       if ( (param.border!=BorderType::NONE)&&(iA
b95efc
 #if 0 // would be nice, but is not possible
b95efc
@@ -310,6 +310,10 @@ const bool origls=param.nup.landscape;
b95efc
         page->add_border_rect(rect,param.border,1.0/pgedit.scale);
b95efc
       }
b95efc
 
b95efc
+      if (!param.pageLabel.empty()) {
b95efc
+	page->add_label(param.page, param.pageLabel);
b95efc
+      }
b95efc
+
b95efc
       if (!param.fitplot) {
b95efc
         curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale,&rect);
b95efc
       } else {
b95efc
diff -up cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.h.page-label cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.h
b95efc
--- cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.h.page-label	2012-11-15 15:58:39.000000000 +0000
b95efc
+++ cups-filters-1.0.35/filter/pdftopdf/pdftopdf_processor.h	2013-07-24 08:49:23.920081389 +0100
b95efc
@@ -20,7 +20,7 @@ struct ProcessingParameters {
b95efc
       border(NONE),
b95efc
       reverse(false),
b95efc
 
b95efc
-//      pageLabel(NULL),
b95efc
+      pageLabel(),
b95efc
       evenPages(true),oddPages(true),
b95efc
 
b95efc
       mirror(false),
b95efc
@@ -60,7 +60,7 @@ struct ProcessingParameters {
b95efc
   NupParameters nup;
b95efc
   bool reverse;
b95efc
 
b95efc
-  // std::string pageLabel; // or NULL?  must stay/dup!
b95efc
+  std::string pageLabel;
b95efc
   bool evenPages,oddPages;
b95efc
   IntervalSet pageRange;
b95efc
 
b95efc
@@ -105,6 +105,7 @@ public:
b95efc
   virtual void add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop=NULL) =0;
b95efc
   virtual void mirror() =0;
b95efc
   virtual void rotate(Rotation rot) =0;
b95efc
+  virtual void add_label(const PageRect &rect, const std::string label) =0;
b95efc
 };
b95efc
 
b95efc
 // TODO: ... error output?
b95efc
diff -up cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.cc.page-label cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.cc
b95efc
--- cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.cc.page-label	2013-03-14 20:32:42.000000000 +0000
b95efc
+++ cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.cc	2013-07-24 08:49:23.920081389 +0100
b95efc
@@ -257,6 +257,94 @@ void QPDF_PDFTOPDF_PageHandle::rotate(Ro
b95efc
 }
b95efc
 // }}}
b95efc
 
b95efc
+void QPDF_PDFTOPDF_PageHandle::add_label(const PageRect &_rect, const std::string label) // {{{
b95efc
+{
b95efc
+  assert(isExisting());
b95efc
+
b95efc
+  PageRect rect = ungetRect (_rect, *this, rotation, page);
b95efc
+
b95efc
+  assert (rect.left <= rect.right);
b95efc
+  assert (rect.bottom <= rect.top);
b95efc
+
b95efc
+  // TODO: Only add in the font once, not once per page.
b95efc
+  QPDFObjectHandle font = page.getOwningQPDF()->makeIndirectObject (
b95efc
+    QPDFObjectHandle::parse(
b95efc
+      "<<"
b95efc
+      " /Type /Font"
b95efc
+      " /Subtype /Type1"
b95efc
+      " /Name /pagelabel-font"
b95efc
+      " /BaseFont /Helvetica" // TODO: support UTF-8 labels?
b95efc
+      ">>"));
b95efc
+  QPDFObjectHandle resources = page.getKey ("/Resources");
b95efc
+  QPDFObjectHandle rfont = resources.getKey ("/Font");
b95efc
+  rfont.replaceKey ("/pagelabel-font", font);
b95efc
+
b95efc
+  double margin = 2.25;
b95efc
+  double height = 12;
b95efc
+
b95efc
+  std::string boxcmd = "q\n";
b95efc
+
b95efc
+  // White filled rectangle (top)
b95efc
+  boxcmd += "  1 1 1 rg\n";
b95efc
+  boxcmd += "  " + QUtil::double_to_string(rect.left + margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.top - height - 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(height + 2 * margin) + " re f\n";
b95efc
+
b95efc
+  // White filled rectangle (bottom)
b95efc
+  boxcmd += "  " + QUtil::double_to_string(rect.left + margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.bottom + height + margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(height + 2 * margin) + " re f\n";
b95efc
+
b95efc
+  // Black outline (top)
b95efc
+  boxcmd += "  0 0 0 RG\n";
b95efc
+  boxcmd += "  " + QUtil::double_to_string(rect.left + margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.top - height - 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(height + 2 * margin) + " re S\n";
b95efc
+
b95efc
+  // Black outline (bottom)
b95efc
+  boxcmd += "  " + QUtil::double_to_string(rect.left + margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.bottom + height + margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.right - rect.left - 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(height + 2 * margin) + " re S\n";
b95efc
+
b95efc
+  // Black text (top)
b95efc
+  boxcmd += "  0 0 0 rg\n";
b95efc
+  boxcmd += "  BT\n";
b95efc
+  boxcmd += "  /pagelabel-font 12 Tf\n";
b95efc
+  boxcmd += "  " + QUtil::double_to_string(rect.left + 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.top - height - margin) + " Td\n";
b95efc
+  boxcmd += "  (" + label + ") Tj\n";
b95efc
+  boxcmd += "  ET\n";
b95efc
+
b95efc
+  // Black text (bottom)
b95efc
+  boxcmd += "  BT\n";
b95efc
+  boxcmd += "  /pagelabel-font 12 Tf\n";
b95efc
+  boxcmd += "  " + QUtil::double_to_string(rect.left + 2 * margin) + " " +
b95efc
+		   QUtil::double_to_string(rect.bottom + height + 2 * margin) + " Td\n";
b95efc
+  boxcmd += "  (" + label + ") Tj\n";
b95efc
+  boxcmd += "  ET\n";
b95efc
+
b95efc
+  boxcmd += "Q\n";
b95efc
+
b95efc
+  assert(page.getOwningQPDF()); // existing pages are always indirect
b95efc
+  static const char *pre="%pdftopdf q\n"
b95efc
+                         "q\n",
b95efc
+                    *post="%pdftopdf Q\n"
b95efc
+                          "Q\n";
b95efc
+
b95efc
+  QPDFObjectHandle stm1=QPDFObjectHandle::newStream(page.getOwningQPDF(),
b95efc
+						    pre),
b95efc
+                   stm2=QPDFObjectHandle::newStream(page.getOwningQPDF(),
b95efc
+						    std::string(post) + boxcmd);
b95efc
+
b95efc
+  page.addPageContents(stm1,true); // before
b95efc
+  page.addPageContents(stm2,false); // after
b95efc
+}
b95efc
+// }}}
b95efc
+
b95efc
 void QPDF_PDFTOPDF_PageHandle::debug(const PageRect &rect,float xpos,float ypos) // {{{
b95efc
 {
b95efc
   assert(!isExisting());
b95efc
@@ -264,7 +352,7 @@ void QPDF_PDFTOPDF_PageHandle::debug(con
b95efc
 }
b95efc
 // }}}
b95efc
 
b95efc
-
b95efc
+// }}}
b95efc
 void QPDF_PDFTOPDF_Processor::closeFile() // {{{
b95efc
 {
b95efc
   pdf.reset();
b95efc
diff -up cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.h.page-label cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.h
b95efc
--- cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.h.page-label	2012-11-15 15:58:39.000000000 +0000
b95efc
+++ cups-filters-1.0.35/filter/pdftopdf/qpdf_pdftopdf_processor.h	2013-07-24 08:49:23.920081389 +0100
b95efc
@@ -11,6 +11,7 @@ public:
b95efc
   virtual void add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop=NULL);
b95efc
   virtual void mirror();
b95efc
   virtual void rotate(Rotation rot);
b95efc
+  virtual void add_label(const PageRect &rect, const std::string label);
b95efc
 
b95efc
   void debug(const PageRect &rect,float xpos,float ypos);
b95efc
 private: