]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
libcupsfilters: Add input-page-ranges attribute to pdftopdf()
authorMohit Verma <b20215@students.iitmandi.ac.in>
Tue, 25 Jan 2022 20:38:04 +0000 (02:08 +0530)
committerGitHub <noreply@github.com>
Tue, 25 Jan 2022 20:38:04 +0000 (21:38 +0100)
Pull request #444

The page-ranges option/attribute applies to the putput page stream going to the printer. If an 8-page input document is printed with number-up=2 one gets 4 sheets, with input pages 1+2, 3+4, 5+6, and 7+8, applying page-ranges=1,4 in addition will give a sheet with input pages 1+2 and 7+8. This way you can easily repeat sheets if they failed to print correctly on the first attempt to print the job.

There was no way to select for example page 1-3 and page 6 from the input and arrange it on 2 sheets with 1+2 and 3+6, for example if only these pages contain exercises which you have to solve. or content relevant for your exam. This is now solved by adding the new input-page-ranges attribute. If you now print with "input-page-ranges=1-3,6 number-up=2" you get exactly what you want (Issue #365).

cupsfilters/pdftopdf/pdftopdf.cc
cupsfilters/pdftopdf/pdftopdf_processor.cc
cupsfilters/pdftopdf/pdftopdf_processor.h

index 9024b6a4f1c24ec3a1ffa888ae3990138a24e5e4..be31039dd0a931f47011a7060fe26d3b160ac3ce 100644 (file)
@@ -589,6 +589,10 @@ void getParameters(filter_data_t *data,int num_options,cups_option_t *options,Pr
     parseRanges(val,param.pageRange);
   }
 
+  if ((val=cupsGetOption("input-page-ranges",num_options,options)) !=NULL){
+    parseRanges(val,param.inputPageRange);
+  }
+
   ppd_choice_t *choice;
   if ((choice=ppdFindMarkedChoice(ppd,"MirrorPrint")) != NULL) {
     val=choice->choice;
index cc006bf453eb760677307302bfba6bbba127b08b..83f84777d536976deb3dd32e4d0be4e7364b658d 100644 (file)
@@ -30,6 +30,10 @@ bool ProcessingParameters::withPage(int outno) const // {{{
   return pageRange.contains(outno);
 }
 // }}}
+bool ProcessingParameters::havePage(int pageno) const
+{
+  return inputPageRange.contains(pageno);
+}
 
 void ProcessingParameters::dump(pdftopdf_doc_t *doc) const // {{{
 {
@@ -67,6 +71,10 @@ void ProcessingParameters::dump(pdftopdf_doc_t *doc) const // {{{
                                 "pdftopdf: evenPages: %s, oddPages: %s",
                                 (evenPages)?"true":"false",
                                 (oddPages)?"true":"false");
+  
+   if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_DEBUG,
+                                "pdftopdf: input page range:");
+  inputPageRange.dump(doc);
 
   if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_DEBUG,
                                 "pdftopdf: page range:");
@@ -174,7 +182,14 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param,pdftop
   }
 
   std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> pages=proc.get_pages(doc);
-  const int numOrigPages=pages.size();
+  
+  std::vector<std::shared_ptr<PDFTOPDF_PageHandle>> input_page_range_list;
+   
+   for(int i=1;i<=(int)pages.size();i++)
+      if(param.havePage(i))
+      input_page_range_list.push_back(pages[i-1]);
+
+  const int numOrigPages=input_page_range_list.size(); 
 
   // TODO FIXME? elsewhere
   std::vector<int> shuffle;
@@ -190,7 +205,7 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param,pdftop
     shuffle.resize(numOrigPages);
     std::iota(shuffle.begin(),shuffle.end(),0);
   }
-  const int numPages=std::max(shuffle.size(),pages.size());
+  const int numPages=std::max(shuffle.size(),input_page_range_list.size());
 
   if (doc->logfunc) doc->logfunc(doc->logdata, FILTER_LOGLEVEL_DEBUG,
                                 "pdftopdf: \"print-scaling\" IPP attribute: %s",
@@ -210,9 +225,9 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param,pdftop
     if ((param.page.width == pw) && (param.page.height == ph))
       margin_defined = false;
 
-    for (int i = 0; i < (int)pages.size(); i ++)
+    for (int i = 0; i < (int)input_page_range_list.size(); i ++)
     {
-      PageRect r = pages[i]->getRect();
+      PageRect r = input_page_range_list[i]->getRect();
       int w = r.width;
       int h = r.height;
       if ((w > param.page.width || h > param.page.height) &&
@@ -275,9 +290,9 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param,pdftop
 
   if (param.fillprint || param.cropfit)
   {
-    for (int i = 0; i < (int)pages.size(); i ++)
+    for (int i = 0; i < (int)input_page_range_list.size(); i ++)
     {
-      std::shared_ptr<PDFTOPDF_PageHandle> page = pages[i];
+      std::shared_ptr<PDFTOPDF_PageHandle> page = input_page_range_list[i];
       Rotation orientation = param.orientation;
       if (param.noOrientation &&
          page->is_landscape(param.orientation))
@@ -343,7 +358,7 @@ bool processPDFTOPDF(PDFTOPDF_Processor &proc,ProcessingParameters &param,pdftop
       // add empty page as filler
       page = proc.new_page(param.page.width, param.page.height, doc);
     else
-      page = pages[shuffle[iA]];
+      page = input_page_range_list[shuffle[iA]];
 
     PageRect rect;
     rect = page->getRect();
index 052d61ea718c202dd81c53ff15a6b0c24bf645ab..92cd105c09349c0ecfb3149ceee724179a319421 100644 (file)
@@ -54,6 +54,8 @@ ProcessingParameters()
     page.right=page.width-18.0;
 
     // everything
+    inputPageRange.add(1);
+    inputPageRange.finish();
     pageRange.add(1);
     pageRange.finish();
   }
@@ -78,6 +80,7 @@ ProcessingParameters()
   std::string pageLabel;
   bool evenPages,oddPages;
   IntervalSet pageRange;
+  IntervalSet inputPageRange;
 
   bool mirror;
 
@@ -104,6 +107,7 @@ ProcessingParameters()
 
   // helper functions
   bool withPage(int outno) const; // 1 based
+  bool havePage(int pageno) const; //1 based
   void dump(pdftopdf_doc_t *doc) const;
 };