From 899362980fe53317fa5931f01b67f45d9b240137 Mon Sep 17 00:00:00 2001
From: Zdenek Dohnal
Date: Tue, 10 Jun 2025 14:57:49 +0200
Subject: [PATCH] Introduce print-as-raster as printer/job attribute
Some printers do not take kindly newer PDF versions which results in
omitting font characters in the printout. Such jobs print fine as a
raster, however retrying as raster depends on benevolence of the printer
firmware what it counts as an unrecoverable printing error.
In the past, we preferred raster over PDF in cups-filters, causing other
issues like with finishings, or solutions like generating PCLm PPD were
mentioned, however it would require a way how to define for which models
it should be used, and take of such database.
Thus introducing `print-as-raster` job attribute, which makes the job
to be printed as raster, and `print-as-raster-default` printer attributes,
which makes any job coming into the printer object to be printed as raster.
Internally it uses similar mechanism as raster retry, which was adjusted
to match both use cases now.
---
cups/encode.c | 2 ++
doc/help/man-lp.html | 3 +++
man/lp.1 | 3 +++
scheduler/ipp.c | 3 +++
scheduler/job.c | 8 ++++----
scheduler/job.h | 3 ++-
scheduler/printers.c | 3 +++
7 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/cups/encode.c b/cups/encode.c
index 0e907d734e..8b6bb51a96 100644
--- a/cups/encode.c
+++ b/cups/encode.c
@@ -298,6 +298,8 @@ static const _ipp_option_t ipp_options[] =
{ 0, "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
{ 0, "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "print-as-raster", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 0, "print-as-raster-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
{ 0, "print-color-mode", IPP_TAG_KEYWORD, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "print-color-mode-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
diff --git a/doc/help/man-lp.html b/doc/help/man-lp.html
index f3aa5e745c..7b3e448390 100644
--- a/doc/help/man-lp.html
+++ b/doc/help/man-lp.html
@@ -184,6 +184,9 @@ Prints the job in landscape (rotated 90 degrees clockwise).
-o orientation-requested=6
Prints the job in reverse portrait (rotated 180 degrees).
+
+ -o print-as-raster
+Prints the job as raster.
-o print-quality=3
diff --git a/man/lp.1 b/man/lp.1
index f11c27c230..26d7421ffa 100644
--- a/man/lp.1
+++ b/man/lp.1
@@ -180,6 +180,9 @@ Prints the job in landscape (rotated 90 degrees clockwise).
\fB\-o orientation\-requested=6\fR
Prints the job in reverse portrait (rotated 180 degrees).
.TP 5
+\fB\-o print-as-raster\fR
+Prints the job as raster.
+.TP 5
\fB\-o print\-quality=3\fR
.TP 5
\fB\-o print\-quality=4\fR
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 1748d1036b..8691e2662a 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1517,6 +1517,9 @@ add_job(cupsd_client_t *con, /* I - Client connection */
return (NULL);
}
+ if (ippGetBoolean(ippFindAttribute(con->request, "print-as-raster", IPP_TAG_BOOLEAN), 0))
+ job->print_as_raster = 1;
+
job->dtype = printer->type & (CUPS_PTYPE_CLASS | CUPS_PTYPE_REMOTE);
job->attrs = con->request;
job->dirty = 1;
diff --git a/scheduler/job.c b/scheduler/job.c
index 7b1ab093c8..4383c7743f 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -579,7 +579,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
cupsRWLockWrite(&MimeDatabase->lock);
- if (job->retry_as_raster)
+ if (job->print_as_raster)
{
/*
* Need to figure out whether the printer supports image/pwg-raster or
@@ -596,9 +596,9 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
}
if (dst)
- cupsdLogJob(job, CUPSD_LOG_DEBUG, "Retrying job as \"%s\".", strchr(dst->type, '/') + 1);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s job as \"%s\".", job->print_as_raster > 0 ? "Printing" : "Retrying", strchr(dst->type, '/') + 1);
else
- cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to retry job using a supported raster format.");
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to print job using a supported raster format.");
}
filters = mimeFilter2(MimeDatabase, job->filetypes[job->current_file], (size_t)fileinfo.st_size, dst, &(job->cost));
@@ -5247,7 +5247,7 @@ update_job(cupsd_job_t *job) /* I - Job to check */
cupsdLogJob(job, CUPSD_LOG_DEBUG, "JOBSTATE: %s", message);
if (!strcmp(message, "cups-retry-as-raster"))
- job->retry_as_raster = 1;
+ job->print_as_raster = -1;
else
ippSetString(job->attrs, &job->reasons, 0, message);
}
diff --git a/scheduler/job.h b/scheduler/job.h
index 8562cac416..a035fc659d 100644
--- a/scheduler/job.h
+++ b/scheduler/job.h
@@ -76,7 +76,8 @@ struct cupsd_job_s /**** Job request ****/
int status; /* Status code from filters */
int tries; /* Number of tries for this job */
int completed; /* cups-waiting-for-job-completed seen */
- int retry_as_raster;/* Need to retry the job as raster */
+ int print_as_raster;
+ /* Need to print the job as raster */
char *auth_env[3], /* AUTH_xxx environment variables,
* if any */
*auth_uid; /* AUTH_UID environment variable */
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 6b78e0d325..0469734c26 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -578,6 +578,9 @@ cupsdCreateCommonData(void)
/* pdl-override-supported */
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "pdl-override-supported", NULL, "attempted");
+ /* print-as-raster-supported */
+ ippAddBoolean(CommonData, IPP_TAG_PRINTER, "print-as-raster-supported", 1);
+
/* print-scaling-supported */
ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-scaling-supported", sizeof(print_scaling) / sizeof(print_scaling[0]), NULL, print_scaling);
--
2.47.2