[gs-cvs] rev 7152 - trunk/gs/src
ray at ghostscript.com
ray at ghostscript.com
Thu Nov 2 21:45:06 PST 2006
Author: ray
Date: 2006-11-02 21:45:05 -0800 (Thu, 02 Nov 2006)
New Revision: 7152
Modified:
trunk/gs/src/gsmisc.c
trunk/gs/src/gxdcconv.c
trunk/gs/src/zchar1.c
trunk/gs/src/zmisc.c
Log:
Implement dynamic configuration of previous compile options that are needed
for CPSI compatibility running the PS CET.
DETAILS:
While a 'state' variable to control this is preferred to a global, the
gs_device or gs_imager_state is not propagated through all of the color
functions. For example, the place where USE_ADOBE_CMYK_RGB was used with
#if to select the color, even though there was a 'pis', it was called
with NULL at times. Default will remain the same as the current gs.
The other option controlled with .setCPSImode is the Type 1 fill method.
While eofill is the Adobe spec method needed for CPSI compatibility,
the w.n. 'fill' method is needed for some Type1's created from TT fonts
that don't properly handle inadvertent crossings (and other bad fonts).
The "true .setCPSImode" will be added to the lib/gs_cet.ps to improve
CET CPSI compatibility.
PCL is not affected since it does not have CMYK colors and doesn't handle
Type1 fonts.
Modified: trunk/gs/src/gsmisc.c
===================================================================
--- trunk/gs/src/gsmisc.c 2006-11-02 19:42:47 UTC (rev 7151)
+++ trunk/gs/src/gsmisc.c 2006-11-03 05:45:05 UTC (rev 7152)
@@ -14,6 +14,16 @@
/* $Id$ */
/* Miscellaneous utilities for Ghostscript library */
+
+/****************************************************************************
+ * This should global should be put into either gs_imager_state or gs_device,
+ * but the "plumbing" retrofit is more than we need for things that were
+ * reviously compile time modifications. CPSI_mode will at least make these
+ * dynamic (but NOT thread safe)!!!
+ ****************************************************************************
+ */
+int CPSI_mode = 0; /* false */ /* default GS behavior is 'false' */
+
/*
* In order to capture the original definition of sqrt, which might be
* either a procedure or a macro and might not have an ANSI-compliant
Modified: trunk/gs/src/gxdcconv.c
===================================================================
--- trunk/gs/src/gxdcconv.c 2006-11-02 19:42:47 UTC (rev 7151)
+++ trunk/gs/src/gxdcconv.c 2006-11-03 05:45:05 UTC (rev 7152)
@@ -22,6 +22,8 @@
#include "gxlum.h"
#include "gxistate.h"
+extern bool CPSI_mode; /* not worth polluting a header file */
+
/*
* The CMYK to RGB algorithms specified by Adobe are, e.g.,
* R = 1.0 - min(1.0, C + K)
@@ -29,9 +31,10 @@
* We got better results on displays with
* R = (1.0 - C) * (1.0 - K)
* C = max(0.0, min(1.0, 1 - R / (1 - UCR)))
- * For utmost compatibility, we offer the Adobe algorithms as an option:
+ * For PLRM compatibility, we use the Adobe algorithms by default,
+ * but what Adobe says and what they do are two different things.
+ * Testing on CPSI shows that they use the 'better' algorithm.
*/
-#define USE_ADOBE_CMYK_RGB
/* ------ Color space conversion ------ */
@@ -74,28 +77,29 @@
else if (ucr == frac_0)
cmyk[0] = c, cmyk[1] = m, cmyk[2] = y;
else {
-#ifdef USE_ADOBE_CMYK_RGB
- /* C = max(0.0, min(1.0, 1 - R - UCR)), etc. */
- signed_frac not_ucr = (ucr < 0 ? frac_1 + ucr : frac_1);
+ if (! CPSI_mode) {
+ /* C = max(0.0, min(1.0, 1 - R - UCR)), etc. */
+ signed_frac not_ucr = (ucr < 0 ? frac_1 + ucr : frac_1);
- cmyk[0] = (c < ucr ? frac_0 : c > not_ucr ? frac_1 : c - ucr);
- cmyk[1] = (m < ucr ? frac_0 : m > not_ucr ? frac_1 : m - ucr);
- cmyk[2] = (y < ucr ? frac_0 : y > not_ucr ? frac_1 : y - ucr);
-#else
- /* C = max(0.0, min(1.0, 1 - R / (1 - UCR))), etc. */
- float denom = frac2float(frac_1 - ucr); /* unscaled */
- float v;
+ cmyk[0] = (c < ucr ? frac_0 : c > not_ucr ? frac_1 : c - ucr);
+ cmyk[1] = (m < ucr ? frac_0 : m > not_ucr ? frac_1 : m - ucr);
+ cmyk[2] = (y < ucr ? frac_0 : y > not_ucr ? frac_1 : y - ucr);
+ } else {
+ /* Adobe CPSI method */
+ /* C = max(0.0, min(1.0, 1 - R / (1 - UCR))), etc. */
+ float denom = frac2float(frac_1 - ucr); /* unscaled */
+ float v;
- v = (float)frac_1 - r / denom; /* unscaled */
- cmyk[0] =
- (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
- v = (float)frac_1 - g / denom; /* unscaled */
- cmyk[1] =
- (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
- v = (float)frac_1 - b / denom; /* unscaled */
- cmyk[2] =
- (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
-#endif
+ v = (float)frac_1 - r / denom; /* unscaled */
+ cmyk[0] =
+ (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
+ v = (float)frac_1 - g / denom; /* unscaled */
+ cmyk[1] =
+ (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
+ v = (float)frac_1 - b / denom; /* unscaled */
+ cmyk[2] =
+ (is_fneg(v) ? frac_0 : v >= (float)frac_1 ? frac_1 : (frac) v);
+ }
}
cmyk[3] = bg;
if_debug7('c', "[c]RGB 0x%x,0x%x,0x%x -> CMYK 0x%x,0x%x,0x%x,0x%x\n",
@@ -127,15 +131,14 @@
rgb[0] = rgb[1] = rgb[2] = frac_0;
break;
default:
- {
-#ifdef USE_ADOBE_CMYK_RGB
+ if (! CPSI_mode) {
/* R = 1.0 - min(1.0, C + K), etc. */
frac not_k = frac_1 - k;
rgb[0] = (c > not_k ? frac_0 : not_k - c);
rgb[1] = (m > not_k ? frac_0 : not_k - m);
rgb[2] = (y > not_k ? frac_0 : not_k - y);
-#else
+ } else {
/* R = (1.0 - C) * (1.0 - K), etc. */
ulong not_k = frac_1 - k;
@@ -148,7 +151,6 @@
rgb[1] = deduct_black(m);
rgb[2] = deduct_black(y);
#undef deduct_black
-#endif
}
}
if_debug7('c', "[c]CMYK 0x%x,0x%x,0x%x,0x%x -> RGB 0x%x,0x%x,0x%x\n",
Modified: trunk/gs/src/zchar1.c
===================================================================
--- trunk/gs/src/zchar1.c 2006-11-02 19:42:47 UTC (rev 7151)
+++ trunk/gs/src/zchar1.c 2006-11-03 05:45:05 UTC (rev 7152)
@@ -48,10 +48,10 @@
* directions, aren't affected by choice of filling rule; but some
* badly designed fonts in the Genoa test suite seem to require
* using the even-odd rule to match Adobe interpreters.
+ *
+ * Properly designed fonts will render correctly with: eofill
+ * (required for Adobe CPSI compliant behavior
*/
-#define GS_CHAR_FILL gs_eofill /* gs_fill or gs_eofill */
-
-/* ============== PATCH BEG=================== */
/*
* On April 4, 2002, we received bug report #539359
* which we interpret as some Genoa test are now obsolete,
@@ -63,10 +63,11 @@
* from user responses.
*/
-#undef GS_CHAR_FILL
-#define GS_CHAR_FILL gs_fill /* gs_fill or gs_eofill */
-
-/* ============== PATCH END=================== */
+/* *********************************************************************
+ * Make this dynamic via a global (somewhat better than a COMPILE option
+ ***********************************************************************/
+extern bool CPSI_mode;
+#define GS_CHAR_FILL (CPSI_mode ? gs_eofill : gs_fill)
/* ---------------- Utilities ---------------- */
Modified: trunk/gs/src/zmisc.c
===================================================================
--- trunk/gs/src/zmisc.c 2006-11-02 19:42:47 UTC (rev 7151)
+++ trunk/gs/src/zmisc.c 2006-11-03 05:45:05 UTC (rev 7152)
@@ -29,6 +29,14 @@
#include "ivmspace.h"
#include "store.h"
+/**********************************************************************/
+/*
+ * a global, which we don't really like, but at least it is better
+ * than a compile time #define, as in #USE_ADOBE_CMYK_RGB and allows
+ * us to easily test with/without and not recompile.
+ **********************************************************************
+ */
+
/* <proc> bind <proc> */
inline private bool
r_is_ex_oper(const ref *rp)
@@ -358,6 +366,24 @@
return 0;
}
+/* There are a few cases where a customer/user might want CPSI behavior
+ * instead of the GS default behavior. cmpy_to_rgb and Type 1 char fill
+ * method are two that have come up so far. This operator allows a PS
+ * program to control the behavior without needing to recompile
+ */
+/* <bool> .setCPSImode - */
+extern bool CPSI_mode; /* not worth polluting a header file */
+
+private int
+zsetCPSImode(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ check_type(*op, t_boolean);
+ CPSI_mode = op->value.boolval;
+ pop(1);
+ return 0;
+}
+
/* ------ gs persistent cache operators ------ */
/* these are for testing only. they're disabled in the normal build
* to prevent access to the cache by malicious postscript files
@@ -447,6 +473,7 @@
{"2.setdebug", zsetdebug},
{"1.setoserrno", zsetoserrno},
{"0usertime", zusertime},
+ {"1.setCPSImode", zsetCPSImode},
#ifdef DEBUG_CACHE
/* pcache test */
{"2.pcacheinsert", zpcacheinsert},
More information about the gs-cvs
mailing list