0

If I create a PDF from LibreOffice Writer using the cups-pdf printer on Ubuntu 16.04, the resulting document displays fine, but I cannot copy/paste from it because I obtain garbled text.

The problem is restricted to cups-pdf because if I print the same document with LO Writer's "Export to PDF" button, copy/paste works well.

Is there any special setting (e.g. encoding) that must be configured on the cups-pdf printer to fix this?

1

I confirm exactly same behaviour, and this is long lasting "bug" [1] [2], while author of 'cups-pdf' does not consider it is a bug, so existing patches are not going to be used upstream.

For Ubuntu, using mentioned PPAs should work, but i can't test it currently.

More skills need if someone use raw Slackware. For Slackware 14.2 and CUPS-PDF 3.0.1 [4], the patch [5][6] from [7] will not work, it is too old. During blind trial-and-errors, i try to prepare working one [8].

Note, you should install it manually, then very carefully install your new 'cups-pdf' file-by-file; i can't get to work provided SlackBuild and install.sh in any way, too few skills i have. But the fact that finally problem was gone.

You should remove your existing PDF printers, and add one using manually provided CUPS-PDF_opt.ppd, optionally (to ensure) remove CUPS-PDF.ppd.

[1] https://www.linuxquestions.org/questions/linux-software-2/cannot-copy-text-from-pdfs-created-with-cups-pdf-4175440557/

[2] https://github.com/alexivkin/CUPS-PDF-to-PDF

[3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=658004

[4] https://slackbuilds.org/repository/14.2/office/cups-pdf/

[5] https://bugs.launchpad.net/ubuntu/+source/cups-pdf/+bug/820820/+attachment/3878188/+files/04_add_pdf_passthrough_support.patch

[6] https://launchpadlibrarian.net/153781216/04_add_pdf_passthrough_support.patch

[7] https://bugs.launchpad.net/ubuntu/+source/cups-pdf/+bug/820820

[8]

--- a/extra/CUPS-PDF_noopt.ppd
+++ b/extra/CUPS-PDF_noopt.ppd
@@ -31,7 +31,8 @@
*ModelName:     "Generic CUPS-PDF Printer"
*ShortNickName: "Generic CUPS-PDF Printer"
*NickName:      "Generic CUPS-PDF Printer (no options)"
-*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;"
+*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;"
+*cupsFilter:    "application/pdf 0 -"
*% cupsFilter:    "application/vnd.cups-postscript 0 pstitleiconv"
*PSVersion: "(2017.000) 0"
*LanguageLevel: "2"
--- a/extra/CUPS-PDF_opt.ppd
+++ b/extra/CUPS-PDF_opt.ppd
@@ -31,7 +31,8 @@
*ModelName:     "Generic CUPS-PDF Printer"
*ShortNickName: "Generic CUPS-PDF Printer"
*NickName:      "Generic CUPS-PDF Printer (w/ options)"
-*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;"
+*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;"
+*cupsFilter:    "application/pdf 0 -"
*% cupsFilter:    "application/vnd.cups-postscript 0 pstitleiconv"
*PSVersion: "(2017.000) 0"
*LanguageLevel: "2"
--- a/src/cups-pdf.c
+++ b/src/cups-pdf.c
@@ -60,6 +60,7 @@
extern int errno;

static FILE *logfp=NULL;
+int input_is_pdf=0;

static void log_event(short type, char message[], char *detail) {
    time_t secs;
@@ -427,7 +427,7 @@
    int len;
    cp_string setup;

-  printf("file cups-pdf:/ \"Virtual PDF Printer\" \"CUPS-PDF\" \"MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;\"\n");
+  printf("file cups-pdf:/ \"Virtual PDF Printer\" \"CUPS-PDF\" \"MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;\"\n");

    if ((dir = opendir(CP_CONFIG_PATH)) != NULL) {
        while ((config_ent = readdir(dir)) != NULL) {
@@ -460,6 +461,7 @@
    cp_string buffer;
    int rec_depth,is_title=0;
    FILE *fpdest;
+  size_t bytes = 0; 

    if (fpsrc == NULL) {
        log_event(CPERROR, "failed to open source stream", NULL);
@@ -483,14 +485,39 @@
        log_event(CPSTATUS, "***Experimental Option: FixNewlines");
    else
        log_event(CPDEBUG, "using traditional fgets");
-  while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) {
+  while ((bytes = fread(buffer, sizeof(char), 4, fpsrc)) > 0) {
+    if (!strncmp(buffer, "%PDF", 4)) {
+      log_event(CPDEBUG, "found beginning of PDF code", buffer);
+      input_is_pdf=1;
+      break;
+    }
        if (!strncmp(buffer, "%!", 2) && strncmp(buffer, "%!PS-AdobeFont", 14)) {
            log_event(CPDEBUG, "found beginning of postscript code: %s", buffer);
            break;
        }
    }
-  log_event(CPDEBUG, "now extracting postscript code");
-  (void) fputs(buffer, fpdest);
+  log_event(CPDEBUG, "now extracting code");
+  fwrite(buffer, sizeof(char), bytes, fpdest);
+  if (input_is_pdf) {
+    while((bytes = fread(buffer, sizeof(char), BUFSIZE, fpsrc)) > 0)
+      fwrite(buffer, sizeof(char), bytes, fpdest);
+/* Commented out because decoding of utf16 PDF strings isn't implemented.
+    rewind(fpsrc);
+    while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) {
+      if (!is_title) {
+        char *begin = strstr(buffer, "/Title");
+        if (begin) {
+          char *end = strstr(begin, ">");
+          if (end) {
+            strncpy(title, begin+6, BUFSIZE);
+            log_event(CPDEBUG, "found title in PDF code", title);
+            is_title=1;
+          }
+        }
+      }
+    }*/
+  }
+  else {
    while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) {
        (void) fputs(buffer, fpdest);
        if (!is_title && !rec_depth)
@@ -513,6 +540,7 @@
            }
        }
    }
+  }
    (void) fclose(fpdest);
    (void) fclose(fpsrc);
    log_event(CPDEBUG, "all data written to spoolfile: %s", spoolfile);
@@ -761,7 +789,12 @@
            (void) fclose(logfp);
        return 5;
    }
-  snprintf(gscall, size, Conf_GSCall, Conf_GhostScript, Conf_PDFVer, outfile, spoolfile);
+  if (input_is_pdf) {
+    snprintf(gscall, size, "cp %s %s", spoolfile, outfile);
+  }
+  else {
+    snprintf(gscall, size, Conf_GSCall, Conf_GhostScript, Conf_PDFVer, outfile, spoolfile);
+  }
    log_event(CPDEBUG, "ghostscript commandline built: %s", gscall);

    (void) unlink(outfile);
  • I'm glad you were able to fix it, but the solution seems too complex for many users (including me). If the author does not consider this a bug, maybe we should look elsewhere for pdf printing solutions. – ARX Dec 4 '17 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.