@@ -44,6 +44,14 @@ typedef enum gs_doc_e
4444
4545typedef cups_page_header_t gs_page_header ;
4646
47+ typedef enum cups_halftone_type_e
48+ {
49+ HALFTONE_DEFAULT ,
50+ HALFTONE_STOCHASTIC ,
51+ HALFTONE_FOO2ZJS ,
52+ HALFTONE_BI_LEVEL
53+ } cups_halftone_type_t ;
54+
4755static gs_doc_t
4856parse_doc_type (FILE * fp )
4957{
@@ -816,6 +824,7 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
816824 struct sigaction sa ;
817825 cf_cm_calibration_t cm_calibrate ;
818826 int pxlcolor = 0 ; // 1 if printer is color printer otherwise 0.
827+ cups_halftone_type_t halftonetype = HALFTONE_DEFAULT ;
819828 ipp_attribute_t * ipp_attr ;
820829 cf_logfunc_t log = data -> logfunc ;
821830 void * ld = data -> logdata ;
@@ -1617,6 +1626,37 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
16171626 else if (!cm_disabled )
16181627 cupsArrayAdd (gs_args , strdup ("-sOutputICCProfile=srgb.icc" ));
16191628
1629+ if ((t = cupsGetOption ("cupsHalftoneType" , num_options , options )) != NULL ||
1630+ (t = cupsGetOption ("halftone-type" , num_options , options )) != NULL )
1631+ {
1632+ if (!strcasecmp (t , "true" ) || !strcasecmp (t , "on" ) ||
1633+ !strcasecmp (t , "yes" ) || !strcasecmp (t , "stochastic" ))
1634+ halftonetype = HALFTONE_STOCHASTIC ;
1635+ else if (!strcasecmp (t , "foo2zjs" ))
1636+ halftonetype = HALFTONE_FOO2ZJS ;
1637+ else if (!strcasecmp (t , "bi-level" ))
1638+ halftonetype = HALFTONE_BI_LEVEL ;
1639+ }
1640+
1641+ //
1642+ // For bi-level type, also check print-color-mode, the way it is
1643+ // handled by Poppler pwgtoraster/pdftoraster/pclmtoraster utilities.
1644+ //
1645+ if ((t = cupsGetOption ("print-color-mode" , num_options , options )) != NULL &&
1646+ !strcasecmp (t , "bi-level" ))
1647+ halftonetype = HALFTONE_BI_LEVEL ;
1648+
1649+ //
1650+ // Use Stochastic Halftone dithering found in GhostScript stocht.ps library file.
1651+ // It is activated automatically.
1652+ //
1653+ if (halftonetype == HALFTONE_STOCHASTIC )
1654+ {
1655+ if (log ) log (ld , CF_LOGLEVEL_DEBUG ,
1656+ "cfFilterGhostscript: Ghostscript using Stochastic Halftone dithering." );
1657+ cupsArrayAdd (gs_args , strdup ("stocht.ps" ));
1658+ }
1659+
16201660 // Switch to taking PostScript commands on the Ghostscript command line
16211661 cupsArrayAdd (gs_args , strdup ("-c" ));
16221662
@@ -1673,6 +1713,64 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
16731713 "cfFilterGhostscript: Ghostscript using Any-Part-of-Pixel method to "
16741714 "fill paths." );
16751715
1716+ //
1717+ // Use halftone dithering algorithm found in foo2zjs-pstops file
1718+ //
1719+ if (halftonetype == HALFTONE_FOO2ZJS )
1720+ {
1721+ if (log ) log (ld , CF_LOGLEVEL_DEBUG ,
1722+ "cfFilterGhostscript: Ghostscript using foo2zjs Halftone dithering." );
1723+ cupsArrayAdd (gs_args , strdup ("/SpotDot { 180 mul cos exch 180 mul cos add 2 div } def\
1724+ <<\
1725+ /HalftoneType 5\
1726+ /Cyan <<\
1727+ /HalftoneType 1\
1728+ /AccurateScreens true\
1729+ /Frequency 150\
1730+ /Angle 105\
1731+ /SpotFunction /SpotDot load\
1732+ >>\
1733+ /Magenta <<\
1734+ /HalftoneType 1\
1735+ /AccurateScreens true\
1736+ /Frequency 150\
1737+ /Angle 165\
1738+ /SpotFunction /SpotDot load\
1739+ >>\
1740+ /Yellow <<\
1741+ /HalftoneType 1\
1742+ /AccurateScreens true\
1743+ /Frequency 150\
1744+ /Angle 30\
1745+ /SpotFunction /SpotDot load\
1746+ >>\
1747+ /Black <<\
1748+ /HalftoneType 1\
1749+ /AccurateScreens true\
1750+ /Frequency 150\
1751+ /Angle 45\
1752+ /SpotFunction /SpotDot load\
1753+ >>\
1754+ /Default <<\
1755+ /HalftoneType 1\
1756+ /AccurateScreens true\
1757+ /Frequency 150\
1758+ /Angle 37\
1759+ /SpotFunction /SpotDot load\
1760+ >>\
1761+ >> /Default exch /Halftone defineresource sethalftone" ));
1762+ }
1763+
1764+ //
1765+ // Use simple threshold (bi-level) halftone algorithm
1766+ //
1767+ if (halftonetype == HALFTONE_BI_LEVEL )
1768+ {
1769+ if (log ) log (ld , CF_LOGLEVEL_DEBUG ,
1770+ "cfFilterGhostscript: Ghostscript using Bi-Level Halftone dithering." );
1771+ cupsArrayAdd (gs_args , strdup ("{ .5 gt { 1 } { 0 } ifelse} settransfer" ));
1772+ }
1773+
16761774 // Mark the end of PostScript commands supplied on the Ghostscript command
16771775 // line (with the "-c" option), so that we can supply the input file name
16781776 cupsArrayAdd (gs_args , strdup ("-f" ));
0 commit comments