Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions cupsfilters/ghostscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ typedef enum gs_doc_e

typedef cups_page_header_t gs_page_header;

typedef enum cups_halftone_type_e
{
HALFTONE_DEFAULT,
HALFTONE_STOCHASTIC,
HALFTONE_FOO2ZJS,
HALFTONE_BI_LEVEL
} cups_halftone_type_t;

static gs_doc_t
parse_doc_type(FILE *fp)
{
Expand Down Expand Up @@ -805,6 +813,7 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
struct sigaction sa;
cf_cm_calibration_t cm_calibrate;
int pxlcolor = 0; // 1 if printer is color printer otherwise 0.
cups_halftone_type_t halftonetype = HALFTONE_DEFAULT;
ipp_attribute_t *ipp_attr;
cf_logfunc_t log = data->logfunc;
void *ld = data->logdata;
Expand Down Expand Up @@ -1606,6 +1615,37 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
else if (!cm_disabled)
cupsArrayAdd(gs_args, strdup("-sOutputICCProfile=srgb.icc"));

if ((t = cupsGetOption("cupsHalftoneType", num_options, options)) != NULL ||
(t = cupsGetOption("halftone-type", num_options, options)) != NULL)
{
if (!strcasecmp(t, "true") || !strcasecmp(t, "on") ||
!strcasecmp(t, "yes") || !strcasecmp(t, "stochastic"))
halftonetype = HALFTONE_STOCHASTIC;
else if (!strcasecmp(t, "foo2zjs"))
halftonetype = HALFTONE_FOO2ZJS;
else if (!strcasecmp(t, "bi-level"))
halftonetype = HALFTONE_BI_LEVEL;
}

//
// For bi-level type, also check print-color-mode, the way it is
// handled by Poppler pwgtoraster/pdftoraster/pclmtoraster utilities.
//
if ((t = cupsGetOption("print-color-mode", num_options, options)) != NULL &&
!strcasecmp(t, "bi-level"))
halftonetype = HALFTONE_BI_LEVEL;

//
// Use Stochastic Halftone dithering found in GhostScript stocht.ps library file.
// It is activated automatically.
//
if (halftonetype == HALFTONE_STOCHASTIC)
{
if (log) log(ld, CF_LOGLEVEL_DEBUG,
"cfFilterGhostscript: Ghostscript using Stochastic Halftone dithering.");
cupsArrayAdd(gs_args, strdup("stocht.ps"));
}

// Switch to taking PostScript commands on the Ghostscript command line
cupsArrayAdd(gs_args, strdup("-c"));

Expand Down Expand Up @@ -1662,6 +1702,64 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
"cfFilterGhostscript: Ghostscript using Any-Part-of-Pixel method to "
"fill paths.");

//
// Use halftone dithering algorithm found in foo2zjs-pstops file
//
if (halftonetype == HALFTONE_FOO2ZJS)
{
if (log) log(ld, CF_LOGLEVEL_DEBUG,
"cfFilterGhostscript: Ghostscript using foo2zjs Halftone dithering.");
cupsArrayAdd(gs_args, strdup("/SpotDot { 180 mul cos exch 180 mul cos add 2 div } def\
<<\
/HalftoneType 5\
/Cyan <<\
/HalftoneType 1\
/AccurateScreens true\
/Frequency 150\
/Angle 105\
/SpotFunction /SpotDot load\
>>\
/Magenta <<\
/HalftoneType 1\
/AccurateScreens true\
/Frequency 150\
/Angle 165\
/SpotFunction /SpotDot load\
>>\
/Yellow <<\
/HalftoneType 1\
/AccurateScreens true\
/Frequency 150\
/Angle 30\
/SpotFunction /SpotDot load\
>>\
/Black <<\
/HalftoneType 1\
/AccurateScreens true\
/Frequency 150\
/Angle 45\
/SpotFunction /SpotDot load\
>>\
/Default <<\
/HalftoneType 1\
/AccurateScreens true\
/Frequency 150\
/Angle 37\
/SpotFunction /SpotDot load\
>>\
>> /Default exch /Halftone defineresource sethalftone"));
}

//
// Use simple threshold (bi-level) halftone algorithm
//
if (halftonetype == HALFTONE_BI_LEVEL)
{
if (log) log(ld, CF_LOGLEVEL_DEBUG,
"cfFilterGhostscript: Ghostscript using Bi-Level Halftone dithering.");
cupsArrayAdd(gs_args, strdup("{ .5 gt { 1 } { 0 } ifelse} settransfer"));
}

// Mark the end of PostScript commands supplied on the Ghostscript command
// line (with the "-c" option), so that we can supply the input file name
cupsArrayAdd(gs_args, strdup("-f"));
Expand Down