[gs-commits] rev 10940 - in trunk/gs: . Resource/Init base psi

robin at ghostscript.com robin at ghostscript.com
Thu Mar 18 00:57:14 UTC 2010


Author: robin
Date: 2010-03-18 00:57:10 +0000 (Thu, 18 Mar 2010)
New Revision: 10940

Modified:
   trunk/gs/
   trunk/gs/Resource/Init/pdf_draw.ps
   trunk/gs/Resource/Init/pdf_font.ps
   trunk/gs/Resource/Init/pdf_ops.ps
   trunk/gs/base/gdevpdft.c
   trunk/gs/base/gscdevn.c
   trunk/gs/base/gscie.c
   trunk/gs/base/gscolor.c
   trunk/gs/base/gscolor1.c
   trunk/gs/base/gscolor2.c
   trunk/gs/base/gscsepr.c
   trunk/gs/base/gscspace.c
   trunk/gs/base/gsdps1.c
   trunk/gs/base/gsequivc.c
   trunk/gs/base/gsimage.c
   trunk/gs/base/gspaint.c
   trunk/gs/base/gspcolor.c
   trunk/gs/base/gsptype1.c
   trunk/gs/base/gsstate.c
   trunk/gs/base/gstext.c
   trunk/gs/base/gstrans.c
   trunk/gs/base/gxccache.c
   trunk/gs/base/gxchar.c
   trunk/gs/base/gxcmap.c
   trunk/gs/base/gxcspace.h
   trunk/gs/base/gxdcolor.h
   trunk/gs/base/gxhldevc.c
   trunk/gs/base/gxistate.h
   trunk/gs/base/gxpaint.c
   trunk/gs/base/gzstate.h
   trunk/gs/psi/dmmain.c
   trunk/gs/psi/dmmain.r
   trunk/gs/psi/dxmain.c
   trunk/gs/psi/dxmainc.c
   trunk/gs/psi/igstate.h
   trunk/gs/psi/interp.c
   trunk/gs/psi/psromfs.mak
   trunk/gs/psi/zchar1.c
   trunk/gs/psi/zcie.c
   trunk/gs/psi/zcolor.c
   trunk/gs/psi/zht.c
   trunk/gs/psi/zht1.c
   trunk/gs/psi/zicc.c
Log:
Merge gs_2_colors branch down to trunk.

This adds a new set of color state information to the graphics/imager
state, along with a new non-standard postscript operator .swapcolors to
toggle between them.

The Postscript interpreter is updated to use one set of color information
for stroking, and the other for all non-stroking colors.

This produces differences in just 2 pdfwrite tests, due to rounding errors
due to changes in the way pdf with non-zero rendering modes is emitted now.




Property changes on: trunk/gs
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/gs_extendgraphic:10114-10199
/branches/smask_work:9134-9665
/trunk/gs:9855-10113
   + /branches/gs_2_colors:10650-10937
/branches/gs_extendgraphic:10114-10199
/branches/smask_work:9134-9665

Modified: trunk/gs/Resource/Init/pdf_draw.ps
===================================================================
--- trunk/gs/Resource/Init/pdf_draw.ps	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/Resource/Init/pdf_draw.ps	2010-03-18 00:57:10 UTC (rev 10940)
@@ -325,13 +325,22 @@
   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
-  /HT {
+
+  % Some functions used to implement phases of HT and HTP
+  /sethalftones {
     dup /Default eq {
       pop .setdefaulthalftone
     } {
 	%****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
       resolvehalftone sethalftone
     } ifelse
+  } bdef
+  /sethalftonephases {
+    /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
+  } bdef
+
+  /HT {
+    dup sethalftones .swapcolors sethalftones .swapcolors
     % the transfer function may dependent on the halftone, so make sure
     % it is set if included in the graphic state (otherwise this is
     % subject to order of a dictionary forall, which is unpredictable)
@@ -344,8 +353,8 @@
     } ifelse
   }
   /HTP {
-	% HTP may be present even if this isn't a DPS interpreter.
-    /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
+    % HTP may be present even if this isn't a DPS interpreter.
+    dup sethalftonephases .swapcolors sethalftonephases .swapcolors
   }
 	% PDF 1.3
   /Font { aload pop Tf }

Modified: trunk/gs/Resource/Init/pdf_font.ps
===================================================================
--- trunk/gs/Resource/Init/pdf_font.ps	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/Resource/Init/pdf_font.ps	2010-03-18 00:57:10 UTC (rev 10940)
@@ -1832,6 +1832,7 @@
 
 drawopdict begin
   /d0 {
+    currentcolor currentcolorspace .swapcolors setcolorspace setcolor .swapcolors
     .adjustcharwidth setcharwidth
   } bdef
   /d1 {

Modified: trunk/gs/Resource/Init/pdf_ops.ps
===================================================================
--- trunk/gs/Resource/Init/pdf_ops.ps	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/Resource/Init/pdf_ops.ps	2010-03-18 00:57:10 UTC (rev 10940)
@@ -263,7 +263,7 @@
 /op { /FillOverprint gput } bdef
 /OP { /StrokeOverprint gput } bdef
 /OPM {
-  /.setoverprintmode where { pop .setoverprintmode } { pop } ifelse
+  /.setoverprintmode where { pop dup .setoverprintmode .swapcolors .setoverprintmode .swapcolors } { pop } ifelse
 } bdef
 /ca { /FillConstantAlpha gput } bdef
 /CA { /StrokeConstantAlpha gput } bdef
@@ -323,8 +323,10 @@
   FillColor FillColorSpace setgcolor setfillblend
 } def
 /setstrokestate {
+  .swapcolors
   StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint
   StrokeConstantAlpha SoftMask .settransparencyparams
+  .swapcolors
 } def
 /Cdict 15 dict dup begin	% <color...> <colorspace> -proc- -
   /DeviceGray { pop setgray } bdef
@@ -423,7 +425,7 @@
 
 /S {
   OFFlevels length 0 eq {
-    setstrokestate /stroke fsexec
+    setstrokestate .swapcolors /stroke fsexec .swapcolors
   } {
     newpath
   } ifelse
@@ -452,7 +454,7 @@
 /B {
   OFFlevels length 0 eq {
     gsave setfillstate fill grestore
-    setstrokestate /stroke fsexec
+    setstrokestate .swapcolors /stroke fsexec .swapcolors
   } {
     newpath
   } ifelse
@@ -463,7 +465,7 @@
 /B* {
   OFFlevels length 0 eq {
     gsave setfillstate eofill grestore
-    setstrokestate /stroke fsexec
+    setstrokestate .swapcolors /stroke fsexec .swapcolors
   } {
     newpath
   } ifelse
@@ -474,7 +476,7 @@
 % Clipping:
 
 /Wdict 4 dict dup begin
-/S { OFFlevels length 0 eq { gsave setstrokestate stroke grestore } if n } bdef
+/S { OFFlevels length 0 eq { gsave setstrokestate .swapcolors stroke .swapcolors grestore } if n } bdef
 /f { OFFlevels length 0 eq { gsave setfillstate fill grestore } if n } bdef
 /f* { OFFlevels length 0 eq { gsave setfillstate eofill grestore } if n } bdef
 /n { end { currentpoint } stopped not { pop pop clip } if newpath } bdef
@@ -744,8 +746,10 @@
 ] readonly def
 
 /pdfwrite_textrenderingprocs [
+	% Tr 0 - Fill
 	{ setfillstate show } bind
-	{ setstrokestate 
+	% Tr 1 - Stroke
+	{ setstrokestate
         % Need to set the stroke width to a value which gives the correct
         % width under pdfwrite. Pdfwrite uses (in text mode) an identity
         % CTM, so we need to calculate the stroke width which would result
@@ -759,24 +763,31 @@
           % we can ignore it. (wrong answer, but consistent)
           pop pop currentlinewidth
         }ifelse setlinewidth
-        show } bind
+        .swapcolors show .swapcolors } bind
+	% Tr 2 - Fill then Stroke
 	{ gsave 0 .settextrenderingmode 
 	  setfillstate dup show currentpoint 3 -1 roll 
-	  grestore gsave setstrokestate 
+	  grestore gsave setstrokestate
         false charpath 
         % We need to make sure the matrix used for the stroke
         % and therefore stroke width does not include the 
         % Text Matrix Tm.
         TextSaveMatrix setmatrix
+        .swapcolors
         stroke 
+        .swapcolors
 	  grestore moveto
 	} bind
+	% Tr 3 - Neither fill nor stroke
 	{ setfillstate show } bind
+	% Tr 4 - Fill, add to clip
 	{ gsave 0 .settextrenderingmode 
 	  setfillstate dup show grestore true charpath } bind
+	% Tr 5 - Stroke, add to clip
 	{ gsave 1 .settextrenderingmode 
-	  setstrokestate dup show grestore
+	  setstrokestate dup .swapcolors show .swapcolors grestore
 	  true charpath } bind
+	% Tr 6 - Fill, stroke, add to clip
 	{ gsave 0 .settextrenderingmode 
 	  setfillstate dup show grestore gsave dup 
 	  setstrokestate false charpath 
@@ -784,8 +795,10 @@
         % and therefore stroke width does not include the 
         % Text Matrix Tm.
         TextSaveMatrix setmatrix
-        stroke grestore 
+        .swapcolors
+        stroke .swapcolors grestore 
 	  true charpath } bind
+	% Tr 7 - Add to clip
 	{ true charpath } bind
 ] readonly def
 
@@ -931,7 +944,7 @@
 /Tmatrix matrix def
 /tS
  { setstrokestate
-   currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix stroke
+   currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix .swapcolors stroke .swapcolors
    setmatrix moveto
  } bdef
 /tB { gsave tf grestore tS } bdef

Modified: trunk/gs/base/gdevpdft.c
===================================================================
--- trunk/gs/base/gdevpdft.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gdevpdft.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -101,7 +101,7 @@
 	    return code;
     }
     if (gstate != NULL) {
-	const gs_color_space *cs = gstate->color_space;
+	const gs_color_space *cs = gs_currentcolorspace_inline(gstate);
 
 	code = pdf_color_space_named(pdev, &cs_value, NULL, cs,
 		&pdf_color_space_names, false, NULL, 0);

Modified: trunk/gs/base/gscdevn.c
===================================================================
--- trunk/gs/base/gscdevn.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscdevn.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -171,7 +171,7 @@
     /* Verify that we have a DeviceN color space */
     if (!pgs->saved)
 	return_error(gs_error_rangecheck);
-    pdevncs = pgs->saved->color_space;
+    pdevncs = gs_currentcolorspace_inline(pgs->saved);
     if (pdevncs->type != &gs_color_space_type_DeviceN)
 	return_error(gs_error_rangecheck);
 
@@ -182,8 +182,8 @@
 
     /* Point our attribute list entry to the attribute color space */
     patt->colorant_name = sep_name;
-    patt->cspace = pgs->color_space;
-    rc_increment(pgs->color_space);
+    patt->cspace = gs_currentcolorspace_inline(pgs);
+    rc_increment(patt->cspace);
 
     /* Link our new attribute color space to the DeviceN color space */
     patt->next = pdevncs->params.device_n.colorants;

Modified: trunk/gs/base/gscie.c
===================================================================
--- trunk/gs/base/gscie.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscie.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -1176,7 +1176,7 @@
 {
     const gs_cie_abc *ignore_pabc;
 
-    return cie_cs_common_abc(pgs->color_space, &ignore_pabc);
+    return cie_cs_common_abc(gs_currentcolorspace_inline(pgs), &ignore_pabc);
 }
 
 /*

Modified: trunk/gs/base/gscolor.c
===================================================================
--- trunk/gs/base/gscolor.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscolor.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -110,7 +110,7 @@
     if (pcs == NULL)
 	return_error(gs_error_VMerror);
     if ((code = gs_setcolorspace(pgs, pcs)) >= 0) {
-        gs_client_color *   pcc = pgs->ccolor;
+        gs_client_color *pcc = gs_currentcolor_inline(pgs);
 
         cs_adjust_color_count(pgs, -1); /* not strictly necessary */
         pcc->paint.values[0] = FORCE_UNIT(gray);
@@ -132,7 +132,7 @@
     if (pcs == NULL)
 	return_error(gs_error_VMerror);
     if ((code = gs_setcolorspace(pgs, pcs)) >= 0) {
-       gs_client_color *    pcc = pgs->ccolor;
+       gs_client_color *pcc = gs_currentcolor_inline(pgs);
 
         cs_adjust_color_count(pgs, -1); /* not strictly necessary */
         pcc->paint.values[0] = FORCE_UNIT(r);
@@ -153,7 +153,7 @@
     if (pgs->in_cachedevice)
 	return_error(gs_error_undefined);
     gs_setgray(pgs, 0.0);	/* set color space to something harmless */
-    color_set_null(pgs->dev_color);
+    color_set_null(gs_currentdevicecolor_inline(pgs));
     return 0;
 }
 
@@ -223,7 +223,7 @@
     } else {
 	/* {csrc} really need to signal an error here */
     }
-    set_nonclient_dev_color(pgs->dev_color, 1);
+    set_nonclient_dev_color(gs_currentdevicecolor_inline(pgs), 1);
     pgs->log_op = lop_default;
     /*
      * In the unlikely event that  overprint mode is in effect,

Modified: trunk/gs/base/gscolor1.c
===================================================================
--- trunk/gs/base/gscolor1.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscolor1.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -48,7 +48,7 @@
     if (pcs == NULL)
 	return_error(gs_error_VMerror);
     if ((code = gs_setcolorspace(pgs, pcs)) >= 0) {
-       gs_client_color *    pcc = pgs->ccolor;
+       gs_client_color *pcc = gs_currentcolor_inline(pgs);
 
         cs_adjust_color_count(pgs, -1); /* not strictly necessary */
         pcc->paint.values[0] = FORCE_UNIT(c);

Modified: trunk/gs/base/gscolor2.c
===================================================================
--- trunk/gs/base/gscolor2.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscolor2.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -34,18 +34,18 @@
 gs_setcolorspace(gs_state * pgs, gs_color_space * pcs)
 {
     int             code = 0;
-    gs_color_space  *cs_old = pgs->color_space;
-    gs_client_color cc_old = *pgs->ccolor;
+    gs_color_space  *cs_old = pgs->color[0].color_space;
+    gs_client_color cc_old = *pgs->color[0].ccolor;
 
     if (pgs->in_cachedevice)
 	return_error(gs_error_undefined);
 
-    if (pcs->id != pgs->color_space->id) {
+    if (pcs->id != cs_old->id) {
         rc_increment(pcs);
-        pgs->color_space = pcs;
+        pgs->color[0].color_space = pcs;
         if ( (code = pcs->type->install_cspace(pcs, pgs)) < 0          ||
               (pgs->overprint && (code = gs_do_set_overprint(pgs)) < 0)  ) {
-            pgs->color_space = cs_old;
+            pgs->color[0].color_space = cs_old;
             rc_decrement_only(pcs, "gs_setcolorspace");
         } else {
 	    cs_old->type->adjust_color_count(&cc_old, cs_old, -1);
@@ -54,9 +54,9 @@
     }
 
     if (code >= 0) {
-	pgs->color_space->pclient_color_space_data =
+	pgs->color[0].color_space->pclient_color_space_data =
 	    pcs->pclient_color_space_data;
-        cs_full_init_color(pgs->ccolor, pcs);
+        cs_full_init_color(pgs->color[0].ccolor, pcs);
         gx_unset_dev_color(pgs);
     }
 
@@ -67,22 +67,22 @@
 gs_color_space *
 gs_currentcolorspace(const gs_state * pgs)
 {
-    return pgs->color_space;
+    return pgs->color[0].color_space;
 }
 
 /* setcolor */
 int
 gs_setcolor(gs_state * pgs, const gs_client_color * pcc)
 {
-    gs_color_space *    pcs = pgs->color_space;
-    gs_client_color     cc_old = *pgs->ccolor;
+    gs_color_space *    pcs = pgs->color[0].color_space;
+    gs_client_color     cc_old = *pgs->color[0].ccolor;
 
    if (pgs->in_cachedevice)
 	return_error(gs_error_undefined); /* PLRM3 page 215. */
     gx_unset_dev_color(pgs);
     (*pcs->type->adjust_color_count)(pcc, pcs, 1);
-    *pgs->ccolor = *pcc;
-    (*pcs->type->restrict_color)(pgs->ccolor, pcs);
+    *pgs->color[0].ccolor = *pcc;
+    (*pcs->type->restrict_color)(pgs->color[0].ccolor, pcs);
     (*pcs->type->adjust_color_count)(&cc_old, pcs, -1);
 
     return 0;
@@ -92,14 +92,14 @@
 const gs_client_color *
 gs_currentcolor(const gs_state * pgs)
 {
-    return pgs->ccolor;
+    return pgs->color[0].ccolor;
 }
 
 /* currentdevicecolor */
 const gx_device_color *
 gs_currentdevicecolor(const gs_state * pgs)
 {
-    return pgs->dev_color;
+    return pgs->color[0].dev_color;
 }
 
 /* ------ Internal procedures ------ */
@@ -711,5 +711,5 @@
 int
 gs_includecolorspace(gs_state * pgs, const byte *res_name, int name_length)
 {
-    return (*dev_proc(pgs->device, include_color_space))(pgs->device, pgs->color_space, res_name, name_length);
+    return (*dev_proc(pgs->device, include_color_space))(pgs->device, gs_currentcolorspace_inline(pgs), res_name, name_length);
 }

Modified: trunk/gs/base/gscsepr.c
===================================================================
--- trunk/gs/base/gscsepr.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscsepr.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -129,9 +129,9 @@
     code = check_Separation_component_name(pcs, pgs);
     if (code < 0)
        return code;
-    pgs->color_space->params.separation.use_alt_cspace =
+    gs_currentcolorspace_inline(pgs)->params.separation.use_alt_cspace =
 	using_alt_color_space(pgs);
-    if (pgs->color_space->params.separation.use_alt_cspace)
+    if (gs_currentcolorspace_inline(pgs)->params.separation.use_alt_cspace)
         code = (pcs->base_space->type->install_cspace)
 	    (pcs->base_space, pgs);
     /*

Modified: trunk/gs/base/gscspace.c
===================================================================
--- trunk/gs/base/gscspace.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gscspace.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -436,6 +436,7 @@
     gx_device_color_info *  pcinfo = (dev == 0 ? 0 : &dev->color_info);
     gx_color_index          drawn_comps = 0;
     gs_overprint_params_t   params;
+    gx_device_color        *pdc;
 
     /* check if we require special handling */
     if ( !pgs->overprint                      ||
@@ -454,13 +455,14 @@
 
     /* correct for any zero'ed color components */
     pgs->effective_overprint_mode = 1;
-    if (color_is_set(pgs->dev_color)) {
+    pdc = gs_currentdevicecolor_inline(pgs);
+    if (color_is_set(pdc)) {
         gx_color_index  nz_comps;
         int             code;
         dev_color_proc_get_nonzero_comps((*procp));
 
-        procp = pgs->dev_color->type->get_nonzero_comps;
-        if ((code = procp(pgs->dev_color, dev, &nz_comps)) < 0)
+        procp = pdc->type->get_nonzero_comps;
+        if ((code = procp(pdc, dev, &nz_comps)) < 0)
             return code;
         drawn_comps &= nz_comps;
     }

Modified: trunk/gs/base/gsdps1.c
===================================================================
--- trunk/gs/base/gsdps1.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gsdps1.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -189,7 +189,7 @@
     uint rcount = count;
     int code;
     gx_device * pdev = pgs->device;
-    gx_device_color *pdc = pgs->dev_color;
+    gx_device_color *pdc = gs_currentdevicecolor_inline(pgs);
     const gs_imager_state *pis = (const gs_imager_state *)pgs;
     bool hl_color_available = gx_hld_is_hl_color_available(pis, pdc);
     gs_fixed_rect empty = {{0, 0}, {0, 0}};

Modified: trunk/gs/base/gsequivc.c
===================================================================
--- trunk/gs/base/gsequivc.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gsequivc.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -238,7 +238,7 @@
      * space.  If so then when check if the color space contains a separation
      * color for which we need a CMYK equivalent.
      */
-    pcs = pgs->color_space;
+    pcs = gs_currentcolorspace_inline(pgs);
     if (pcs != NULL) {
 	if (pcs->type->index == gs_color_space_index_Separation) {
 	    update_Separation_spot_equivalent_cmyk_colors(pdev, pgs, pcs,

Modified: trunk/gs/base/gsimage.c
===================================================================
--- trunk/gs/base/gsimage.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gsimage.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -205,7 +205,7 @@
     gx_clip_path *pcpath;
     int code = gx_effective_clip_path(pgs, &pcpath);
     gx_device *dev2 = dev;
-    gx_device_color dc_temp, *pdevc = pgs->dev_color;
+    gx_device_color dc_temp, *pdevc = gs_currentdevicecolor_inline(pgs);
 
     if (code < 0)
 	return code;
@@ -227,7 +227,7 @@
 	gs_image_t *image = (gs_image_t *)pic;
 
 	if(image->ImageMask) {
-	    code = gx_image_fill_masked_start(dev, pgs->dev_color, pcpath, pgs->memory, &dev2);
+	    code = gx_image_fill_masked_start(dev, gs_currentdevicecolor_inline(pgs), pcpath, pgs->memory, &dev2);
 	    if (code < 0)
 		return code;
 	}
@@ -648,7 +648,7 @@
 	    gx_device *cdev = penum->info->dev;
 
 	    code = gx_image_end(penum->info, !penum->error); /* Releases penum->info . */
-	    code1 = gx_image_fill_masked_end(cdev, penum->dev, pgs->dev_color);
+	    code1 = gx_image_fill_masked_end(cdev, penum->dev, gs_currentdevicecolor_inline(pgs));
 	    if (code == 0)
 		code = code1;
 	} else

Modified: trunk/gs/base/gspaint.c
===================================================================
--- trunk/gs/base/gspaint.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gspaint.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -81,7 +81,8 @@
 
     gx_set_dev_color(pgs);
 
-    code = (*dev_proc(dev, fillpage))(dev, (gs_imager_state *)pgs, pgs->dev_color);
+    code = (*dev_proc(dev, fillpage))(dev, (gs_imager_state *)pgs,
+				      gs_currentdevicecolor_inline(pgs));
     if (code < 0)
 	return code;
     return (*dev_proc(dev, sync_output)) (dev);
@@ -96,7 +97,7 @@
 {
     gx_device *dev;
 
-    if (!color_is_pure(pgs->dev_color))
+    if (!color_is_pure(gs_currentdevicecolor_inline(pgs)))
 	return 0;
     dev = gs_currentdevice_inline(pgs);
     if (gs_device_is_abuf(dev)) {
@@ -243,6 +244,66 @@
     return code;
 }
 
+static int do_fill(gs_state *pgs, int rule)
+{
+    int code, abits, acode, rcode = 0;
+
+    /* Here we need to distinguish text from vectors to compute the object tag.
+       Actually we need to know whether this function is called to rasterize a character,
+       or to rasterize a vector graphics to the output device.
+       Currently we assume it works for the bitrgbtags device only,
+       which is a low level device with a 4-component color model.
+       We use the fact that with printers a character is usually being rendered 
+       to a 1bpp cache device rather than to the output device.
+       Therefore we hackly look whether the target device
+       "has a color" : either it's a multicomponent color model,
+       or it is not gray (such as a yellow separation).
+
+       This check has several limitations :
+       1. It doesn't work with -dNOCACHE.
+       2. It doesn't work with large characters,
+	  which cannot fit into a cache cell and thus they
+	  render directly to the output device.
+       3. It doesn't work for TextAlphaBits=2 or 4.
+	  We don't care of this case because
+	  text antialiasing usually usn't applied to printers.
+       4. It doesn't work for things like with "(xyz) true charpath stroke".
+	  That's unfortunate, we'd like to improve someday.
+       5. It doesn't work for high level devices when a Type 3 character is being constructed.
+	  This case is not important for low level devices
+	  (which a printer is), because low level device doesn't accept
+	  Type 3 charproc streams immediately.
+       6. It doesn't work properly while an insiding testing,
+	  which sets gs_hit_device, which is uncolored.
+     */
+    if (gx_device_has_color(gs_currentdevice(pgs))) {
+	gs_set_object_tag(pgs, GS_PATH_TAG);
+    }
+    else {
+	gs_set_object_tag(pgs, GS_TEXT_TAG);
+    }
+    gx_set_dev_color(pgs);
+    code = gs_state_color_load(pgs);
+    if (code < 0)
+	return code;
+    abits = alpha_buffer_bits(pgs);
+    if (abits > 1) {
+	acode = alpha_buffer_init(pgs, pgs->fill_adjust.x,
+				  pgs->fill_adjust.y, abits);
+	if (acode < 0)
+	    return acode;
+    } else
+	acode = 0;
+    code = gx_fill_path(pgs->path, gs_currentdevicecolor_inline(pgs), pgs, rule,
+			pgs->fill_adjust.x, pgs->fill_adjust.y);
+    if (acode > 0)
+	rcode = alpha_buffer_release(pgs, code >= 0);
+    if (code >= 0 && rcode < 0)
+        code = rcode;
+
+    return code;
+}
+
 /* Fill the current path using a specified rule. */
 static int
 fill_with_rule(gs_state * pgs, int rule)
@@ -259,63 +320,9 @@
 	gs_newpath(pgs);
 	code = 0;
     } else {
-	int abits, acode, rcode = 0;
-
-	/* Here we need to distinguish text from vectors to compute the object tag.
-	   Actually we need to know whether this function is called to rasterize a character,
-	   or to rasterize a vector graphics to the output device.
-	   Currently we assume it works for the bitrgbtags device only,
-	   which is a low level device with a 4-component color model.
-	   We use the fact that with printers a character is usually being rendered 
-	   to a 1bpp cache device rather than to the output device.
-	   Therefore we hackly look whether the target device
-	   "has a color" : either it's a multicomponent color model,
-	   or it is not gray (such as a yellow separation).
-
-	   This check has several limitations :
-	   1. It doesn't work with -dNOCACHE.
-	   2. It doesn't work with large characters,
-	      which cannot fit into a cache cell and thus they
-	      render directly to the output device.
-	   3. It doesn't work for TextAlphaBits=2 or 4.
-	      We don't care of this case because
-	      text antialiasing usually usn't applied to printers.
-	   4. It doesn't work for things like with "(xyz) true charpath stroke".
-	      That's unfortunate, we'd like to improve someday.
-	   5. It doesn't work for high level devices when a Type 3 character is being constructed.
-	      This case is not important for low level devices
-	      (which a printer is), because low level device doesn't accept
-	      Type 3 charproc streams immediately.
-	   6. It doesn't work properly while an insiding testing,
-	      which sets gs_hit_device, which is uncolored.
-	 */
-        if (gx_device_has_color(gs_currentdevice(pgs))) {
-            gs_set_object_tag(pgs, GS_PATH_TAG);
-	}
-	else {
-            gs_set_object_tag(pgs, GS_TEXT_TAG);
-	}
-	gx_set_dev_color(pgs);
-	code = gs_state_color_load(pgs);
-	if (code < 0)
-	    return code;
-	abits = alpha_buffer_bits(pgs);
-	if (abits > 1) {
-	    acode = alpha_buffer_init(pgs, pgs->fill_adjust.x,
-				      pgs->fill_adjust.y, abits);
-	    if (acode < 0)
-		return acode;
-	} else
-	    acode = 0;
-	code = gx_fill_path(pgs->path, pgs->dev_color, pgs, rule,
-			    pgs->fill_adjust.x, pgs->fill_adjust.y);
-	if (acode > 0)
-	    rcode = alpha_buffer_release(pgs, code >= 0);
+        code = do_fill(pgs, rule);
 	if (code >= 0)
 	    gs_newpath(pgs);
-	if (code >= 0 && rcode < 0)
-	    code = rcode;
-
     }
     return code;
 }
@@ -334,6 +341,109 @@
     return fill_with_rule(pgs, gx_rule_even_odd);
 }
 
+static int
+do_stroke(gs_state * pgs)
+{
+    int code, abits, acode, rcode = 0;
+
+    /* to distinguish text from vectors we hackly look at the
+       target device 1 bit per component is a cache and this is
+       text else it is a path */
+    if (gx_device_has_color(gs_currentdevice(pgs)))
+        gs_set_object_tag(pgs, GS_PATH_TAG);
+    else
+        gs_set_object_tag(pgs, GS_TEXT_TAG);
+
+    /* Here we need to distinguish text from vectors to compute the object tag.
+       Actually we need to know whether this function is called to rasterize a character,
+       or to rasterize a vector graphics to the output device.
+       Currently we assume it works for the bitrgbtags device only,
+       which is a low level device with a 4-component color model.
+       We use the fact that with printers a character is usually being rendered 
+       to a 1bpp cache device rather than to the output device.
+       Therefore we hackly look whether the target device
+       "has a color" : either it's a multicomponent color model,
+       or it is not gray (such as a yellow separation).
+
+       This check has several limitations :
+       1. It doesn't work with -dNOCACHE.
+       2. It doesn't work with large characters,
+          which cannot fit into a cache cell and thus they
+          render directly to the output device.
+       3. It doesn't work for TextAlphaBits=2 or 4.
+          We don't care of this case because
+          text antialiasing usually usn't applied to printers.
+       4. It doesn't work for things like with "(xyz) true charpath stroke".
+          That's unfortunate, we'd like to improve someday.
+       5. It doesn't work for high level devices when a Type 3 character is being constructed.
+          This case is not important for low level devices
+          (which a printer is), because low level device doesn't accept
+          Type 3 charproc streams immediately.
+     */
+    if (gx_device_has_color(gs_currentdevice(pgs))) {
+	gs_set_object_tag(pgs, GS_PATH_TAG);
+    }
+    else {
+	gs_set_object_tag(pgs, GS_TEXT_TAG);
+    }
+    /* Evil: The following call is a macro that might return! */
+    gx_set_dev_color(pgs);
+    code = gs_state_color_load(pgs);
+    if (code < 0)
+	return code;
+    abits = alpha_buffer_bits(pgs);
+    if (abits > 1) {
+	/*
+	 * Expand the bounding box by the line width.
+	 * This is expensive to compute, so we only do it
+	 * if we know we're going to buffer.
+	 */
+	float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
+	float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
+	float scale = (float)(1 << (abits / 2));
+	float orig_width = gs_currentlinewidth(pgs);
+	float new_width = orig_width * scale;
+	fixed extra_adjust =
+		float2fixed(max(xxyy, xyyx) * new_width / 2);
+	float orig_flatness = gs_currentflat(pgs);
+	gx_path spath;
+
+	/* Scale up the line width, dash pattern, and flatness. */
+	if (extra_adjust < fixed_1)
+	    extra_adjust = fixed_1;
+	acode = alpha_buffer_init(pgs,
+				  pgs->fill_adjust.x + extra_adjust,
+				  pgs->fill_adjust.y + extra_adjust,
+				  abits);
+	if (acode < 0)
+	    return acode;
+	gs_setlinewidth(pgs, new_width);
+	scale_dash_pattern(pgs, scale);
+	gs_setflat(pgs, orig_flatness * scale);
+	/*
+	 * The alpha-buffer device requires that we fill the
+	 * entire path as a single unit.
+	 */
+	gx_path_init_local(&spath, pgs->memory);
+	code = gx_stroke_add(pgs->path, &spath, pgs, false);
+	gs_setlinewidth(pgs, orig_width);
+	scale_dash_pattern(pgs, 1.0 / scale);
+	if (code >= 0)
+	    code = gx_fill_path(&spath, gs_currentdevicecolor_inline(pgs), pgs,
+				gx_rule_winding_number,
+				pgs->fill_adjust.x,
+				pgs->fill_adjust.y);
+	gs_setflat(pgs, orig_flatness);
+	gx_path_free(&spath, "gs_stroke");
+	if (acode > 0)
+	    rcode = alpha_buffer_release(pgs, code >= 0);
+    } else
+	code = gx_stroke_fill(pgs->path, pgs);
+    if (code >= 0 && rcode < 0)
+	code = rcode;
+    return code;
+}
+
 /* Stroke the current path */
 int
 gs_stroke(gs_state * pgs)
@@ -362,104 +472,9 @@
 	gs_newpath(pgs);
 	code = 0;
     } else {
-	int abits, acode, rcode = 0;
-
-        /* to distinguish text from vectors we hackly look at the
-           target device 1 bit per component is a cache and this is
-           text else it is a path */
-        if (gx_device_has_color(gs_currentdevice(pgs)))
-            gs_set_object_tag(pgs, GS_PATH_TAG);
-        else
-            gs_set_object_tag(pgs, GS_TEXT_TAG);
-
-	/* Here we need to distinguish text from vectors to compute the object tag.
-	   Actually we need to know whether this function is called to rasterize a character,
-	   or to rasterize a vector graphics to the output device.
-	   Currently we assume it works for the bitrgbtags device only,
-	   which is a low level device with a 4-component color model.
-	   We use the fact that with printers a character is usually being rendered 
-	   to a 1bpp cache device rather than to the output device.
-	   Therefore we hackly look whether the target device
-	   "has a color" : either it's a multicomponent color model,
-	   or it is not gray (such as a yellow separation).
-
-	   This check has several limitations :
-	   1. It doesn't work with -dNOCACHE.
-	   2. It doesn't work with large characters,
-	      which cannot fit into a cache cell and thus they
-	      render directly to the output device.
-	   3. It doesn't work for TextAlphaBits=2 or 4.
-	      We don't care of this case because
-	      text antialiasing usually usn't applied to printers.
-	   4. It doesn't work for things like with "(xyz) true charpath stroke".
-	      That's unfortunate, we'd like to improve someday.
-	   5. It doesn't work for high level devices when a Type 3 character is being constructed.
-	      This case is not important for low level devices
-	      (which a printer is), because low level device doesn't accept
-	      Type 3 charproc streams immediately.
-	 */
-        if (gx_device_has_color(gs_currentdevice(pgs))) {
-            gs_set_object_tag(pgs, GS_PATH_TAG);
-	}
-	else {
-            gs_set_object_tag(pgs, GS_TEXT_TAG);
-	}
-	gx_set_dev_color(pgs);
-	code = gs_state_color_load(pgs);
-	if (code < 0)
-	    return code;
-	abits = alpha_buffer_bits(pgs);
-	if (abits > 1) {
-	    /*
-	     * Expand the bounding box by the line width.
-	     * This is expensive to compute, so we only do it
-	     * if we know we're going to buffer.
-	     */
-	    float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
-	    float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
-	    float scale = (float)(1 << (abits / 2));
-	    float orig_width = gs_currentlinewidth(pgs);
-	    float new_width = orig_width * scale;
-	    fixed extra_adjust =
-		float2fixed(max(xxyy, xyyx) * new_width / 2);
-	    float orig_flatness = gs_currentflat(pgs);
-	    gx_path spath;
-
-	    /* Scale up the line width, dash pattern, and flatness. */
-	    if (extra_adjust < fixed_1)
-		extra_adjust = fixed_1;
-	    acode = alpha_buffer_init(pgs,
-				      pgs->fill_adjust.x + extra_adjust,
-				      pgs->fill_adjust.y + extra_adjust,
-				      abits);
-	    if (acode < 0)
-		return acode;
-	    gs_setlinewidth(pgs, new_width);
-	    scale_dash_pattern(pgs, scale);
-	    gs_setflat(pgs, orig_flatness * scale);
-	    /*
-	     * The alpha-buffer device requires that we fill the
-	     * entire path as a single unit.
-	     */
-	    gx_path_init_local(&spath, pgs->memory);
-	    code = gx_stroke_add(pgs->path, &spath, pgs, false);
-	    gs_setlinewidth(pgs, orig_width);
-	    scale_dash_pattern(pgs, 1.0 / scale);
-	    if (code >= 0)
-		code = gx_fill_path(&spath, pgs->dev_color, pgs,
-				    gx_rule_winding_number,
-				    pgs->fill_adjust.x,
-				    pgs->fill_adjust.y);
-	    gs_setflat(pgs, orig_flatness);
-	    gx_path_free(&spath, "gs_stroke");
-	    if (acode > 0)
-		rcode = alpha_buffer_release(pgs, code >= 0);
-	} else
-	    code = gx_stroke_fill(pgs->path, pgs);
+        code = do_stroke(pgs);
 	if (code >= 0)
 	    gs_newpath(pgs);
-	if (code >= 0 && rcode < 0)
-	    code = rcode;
     }
     return code;
 }

Modified: trunk/gs/base/gspcolor.c
===================================================================
--- trunk/gs/base/gspcolor.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gspcolor.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -146,20 +146,22 @@
 gs_setpatternspace(gs_state * pgs)
 {
     int code = 0;
+    gs_color_space *ccs_old;
 
     if (pgs->in_cachedevice)
 	return_error(gs_error_undefined);
-    if (pgs->color_space->type->index != gs_color_space_index_Pattern) {
+    ccs_old = gs_currentcolorspace_inline(pgs);
+    if (ccs_old->type->index != gs_color_space_index_Pattern) {
 	gs_color_space *pcs;
 
 	pcs = gs_cspace_alloc(pgs->memory, &gs_color_space_type_Pattern);
 	if (pcs == NULL)
 	    return_error(gs_error_VMerror);
 	/* reference to base space shifts from pgs to pcs with no net change */
-	pcs->base_space = pgs->color_space;
+	pcs->base_space = ccs_old;
 	pcs->params.pattern.has_base_space = true;
-	pgs->color_space = pcs;
-	cs_full_init_color(pgs->ccolor, pcs);
+	pgs->color[0].color_space = pcs;
+	cs_full_init_color(pgs->color[0].ccolor, pcs);
 	gx_unset_dev_color(pgs);
     }
     return code;

Modified: trunk/gs/base/gsptype1.c
===================================================================
--- trunk/gs/base/gsptype1.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gsptype1.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -590,7 +590,7 @@
     gs_pattern1_template_t * ptmplt = &pinst->template;
 
     if (ptmplt->PaintType == 2) {
-        const gs_color_space *  pcs = pgs->color_space;
+        const gs_color_space *pcs = gs_currentcolorspace_inline(pgs);
 
         pcs = pcs->base_space;
         return pcs->type->set_overprint(pcs, pgs);

Modified: trunk/gs/base/gsstate.c
===================================================================
--- trunk/gs/base/gsstate.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gsstate.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -140,14 +140,19 @@
     gx_path *path;
     gx_clip_path *clip_path;
     gx_clip_path *effective_clip_path;
-    gs_client_color *ccolor;
-    gx_device_color *dev_color;
+    struct {
+        gs_client_color *ccolor;
+        gx_device_color *dev_color;
+    } color[2];
 } gs_state_parts;
 
 #define GSTATE_ASSIGN_PARTS(pto, pfrom)\
   ((pto)->path = (pfrom)->path, (pto)->clip_path = (pfrom)->clip_path,\
    (pto)->effective_clip_path = (pfrom)->effective_clip_path,\
-   (pto)->ccolor = (pfrom)->ccolor, (pto)->dev_color = (pfrom)->dev_color)
+   (pto)->color[0].ccolor = (pfrom)->color[0].ccolor,\
+   (pto)->color[0].dev_color = (pfrom)->color[0].dev_color,\
+   (pto)->color[1].ccolor = (pfrom)->color[1].ccolor,\
+   (pto)->color[1].dev_color = (pfrom)->color[1].dev_color)
 
 /* GC descriptors */
 extern_st(st_imager_state);
@@ -247,10 +252,17 @@
     pgs->effective_clip_path = pgs->clip_path;
     pgs->effective_clip_shared = true;
     /* Initialize things so that gx_remap_color won't crash. */
-    pgs->color_space = gs_cspace_new_DeviceGray(pgs->memory);
+    pgs->color[0].color_space = gs_cspace_new_DeviceGray(pgs->memory);
+    pgs->color[1].color_space = gs_cspace_new_DeviceGray(pgs->memory);
     pgs->in_cachedevice = 0;
+    gs_swapcolors_quick(pgs); /* To color 1 */
     gx_set_device_color_1(pgs); /* sets colorspace and client color */
+    gs_swapcolors_quick(pgs); /* To color 0 */
+    gx_set_device_color_1(pgs); /* sets colorspace and client color */
     pgs->device = 0;		/* setting device adjusts refcts */
+    pgs->dev_ht_alt = 0;
+    pgs->cie_joint_caches_alt = 0;
+    pgs->pattern_cache_alt = 0;
     gs_nulldevice(pgs);
     gs_setalpha(pgs, 1.0);
     gs_settransfer(pgs, gs_identity_transfer);
@@ -390,6 +402,7 @@
     void *sdata;
     gs_transparency_state_t *tstack = pgs->transparency_stack;
     bool prior_overprint = pgs->overprint;
+    int code;
 
     if_debug2('g', "[g]grestore 0x%lx, level was %d\n",
 	      (ulong) saved, pgs->level);
@@ -412,9 +425,10 @@
 
     /* update the overprint compositor, if necessary */
     if (prior_overprint || pgs->overprint)
+    {
         return gs_do_set_overprint(pgs);
-    else
-        return 0;
+    }
+    return 0;
 }
 
 /* Restore the graphics state per PostScript semantics */
@@ -649,8 +663,8 @@
 int
 gs_do_set_overprint(gs_state * pgs)
 {
-    const gs_color_space *  pcs = pgs->color_space;
-    const gs_client_color * pcc = pgs->ccolor;
+    const gs_color_space *  pcs = gs_currentcolorspace_inline(pgs);
+    const gs_client_color * pcc = gs_currentcolor_inline(pgs);
     int                     code = 0;
 
     if (cs_num_components(pcs) < 0 && pcc->pattern != 0)
@@ -813,8 +827,10 @@
 static void
 gstate_free_parts(const gs_state * parts, gs_memory_t * mem, client_name_t cname)
 {
-    gs_free_object(mem, parts->dev_color, cname);
-    gs_free_object(mem, parts->ccolor, cname);
+    gs_free_object(mem, parts->color[1].dev_color, cname);
+    gs_free_object(mem, parts->color[1].ccolor, cname);
+    gs_free_object(mem, parts->color[0].dev_color, cname);
+    gs_free_object(mem, parts->color[0].ccolor, cname);
     if (!parts->effective_clip_shared)
 	gx_cpath_free(parts->effective_clip_path, cname);
     gx_cpath_free(parts->clip_path, cname);
@@ -847,14 +863,20 @@
 				  "gstate_alloc_parts(effective_clip_path)");
 	parts->effective_clip_shared = false;
     }
-    parts->color_space = NULL;
-    parts->ccolor =
+    parts->color[0].color_space = NULL;
+    parts->color[1].color_space = NULL;
+    parts->color[0].ccolor =
 	gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
-    parts->dev_color =
+    parts->color[1].ccolor =
+	gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
+    parts->color[0].dev_color =
 	gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
+    parts->color[1].dev_color =
+	gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
     if (parts->path == 0 || parts->clip_path == 0 ||
 	parts->effective_clip_path == 0 ||
-	parts->ccolor == 0 || parts->dev_color == 0
+	parts->color[0].ccolor == 0 || parts->color[0].dev_color == 0 ||
+	parts->color[1].ccolor == 0 || parts->color[1].dev_color == 0
 	) {
 	gstate_free_parts(parts, mem, cname);
 	return_error(gs_error_VMerror);
@@ -927,10 +949,14 @@
 	    goto fail;
     }
     gs_imager_state_copied((gs_imager_state *)pgs);
+    rc_increment(pgs->dev_ht_alt);
+    rc_increment(pgs->cie_joint_caches_alt);
     /* Don't do anything to clip_stack. */
     rc_increment(pgs->device);
-    *parts.ccolor = *pfrom->ccolor;
-    *parts.dev_color = *pfrom->dev_color;
+    *parts.color[0].ccolor    = *pfrom->color[0].ccolor;
+    *parts.color[0].dev_color = *pfrom->color[0].dev_color;
+    *parts.color[1].ccolor    = *pfrom->color[1].ccolor;
+    *parts.color[1].dev_color = *pfrom->color[1].dev_color;
     if (reason == copy_for_gsave) {
 	float *dfrom = pfrom->line_params.dash.pattern;
 	float *dto = pgs->line_params.dash.pattern;
@@ -941,7 +967,10 @@
     } else {
 	GSTATE_ASSIGN_PARTS(pgs, &parts);
     }
+    gs_swapcolors_quick(pgs);
     cs_adjust_counts(pgs, 1);
+    gs_swapcolors_quick(pgs);
+    cs_adjust_counts(pgs, 1);
     return pgs;
   fail:
     gs_free_object(mem, pgs->line_params.dash.pattern, cname);
@@ -973,16 +1002,30 @@
 {
     gs_memory_t *mem = pgs->memory;
     const char *const cname = "gstate_free_contents";
+    int current_col;
+    gx_device_halftone *pdhta = pgs->dev_ht_alt;
 
     rc_decrement(pgs->device, cname);
     clip_stack_rc_adjust(pgs->clip_stack, -1, cname);
     rc_decrement(pgs->dfilter_stack, cname);
+    gs_swapcolors_quick(pgs);
     cs_adjust_counts(pgs, -1);
+    gs_swapcolors_quick(pgs);
+    cs_adjust_counts(pgs, -1);
     if (pgs->client_data != 0)
 	(*pgs->client_procs.free) (pgs->client_data, mem);
     gs_free_object(mem, pgs->line_params.dash.pattern, cname);
     gstate_free_parts(pgs, mem, cname);
     gs_imager_state_release((gs_imager_state *)pgs);
+    /*
+     * If we're going to free the device halftone, make sure we free the
+     * dependent structures as well.
+     */
+    if (pdhta != 0 && pdhta->rc.ref_count == 1) {
+	gx_device_halftone_release(pdhta, pdhta->rc.memory);
+    }
+    rc_decrement(pgs->dev_ht_alt, "gstate_free_contents");
+    rc_decrement(pgs->cie_joint_caches_alt, "gstate_free_contents");
 }
 
 /* Copy one gstate to another. */
@@ -1007,6 +1050,9 @@
      * Handle references from contents.
      */
     cs_adjust_counts(pto, -1);
+    gs_swapcolors_quick(pto);
+    cs_adjust_counts(pto, -1);
+    gs_swapcolors_quick(pto);
     gx_path_assign_preserve(pto->path, pfrom->path);
     gx_cpath_assign_preserve(pto->clip_path, pfrom->clip_path);
     /*
@@ -1024,8 +1070,10 @@
     } else
 	gx_cpath_assign_preserve(pto->effective_clip_path,
 				 pfrom->effective_clip_path);
-    *parts.ccolor = *pfrom->ccolor;
-    *parts.dev_color = *pfrom->dev_color;
+    *parts.color[0].ccolor    = *pfrom->color[0].ccolor;
+    *parts.color[0].dev_color = *pfrom->color[0].dev_color;
+    *parts.color[1].ccolor    = *pfrom->color[1].ccolor;
+    *parts.color[1].dev_color = *pfrom->color[1].dev_color;
     /* Handle references from gstate object. */
     rc_pre_assign(pto->device, pfrom->device, cname);
     rc_pre_assign(pto->dfilter_stack, pfrom->dfilter_stack, cname);
@@ -1042,6 +1090,8 @@
 
 	gs_imager_state_pre_assign((gs_imager_state *)pto,
 				   (const gs_imager_state *)pfrom);
+	rc_pre_assign(pto->dev_ht_alt, pfrom->dev_ht_alt, "gstate_copy");
+	rc_pre_assign(pto->cie_joint_caches_alt, pfrom->cie_joint_caches_alt, "gstate_copy");
 	*pto = *pfrom;
 	pto->client_data = pdata;
 	pto->memory = mem;
@@ -1057,6 +1107,9 @@
     }
     GSTATE_ASSIGN_PARTS(pto, &parts);
     cs_adjust_counts(pto, 1);
+    gs_swapcolors_quick(pto);
+    cs_adjust_counts(pto, 1);
+    gs_swapcolors_quick(pto);
     pto->show_gstate =
 	(pfrom->show_gstate == pfrom ? pto : 0);
     return 0;
@@ -1067,3 +1120,83 @@
 {
     return pgs->clip_path->id;
 }
+
+void gs_swapcolors_quick(gs_state *pgs)
+{
+    struct gx_cie_joint_caches_s *tmp_cie;
+    gx_device_halftone           *tmp_ht;
+    gs_devicen_color_map          tmp_ccm;
+    struct gx_pattern_cache_s    *tmp_pc;
+    gs_client_color              *tmp_cc;
+    int                           tmp;
+    gx_device_color              *tmp_dc;
+    gs_color_space               *tmp_cs;
+    
+    tmp_cc               = pgs->color[0].ccolor;
+    pgs->color[0].ccolor = pgs->color[1].ccolor;
+    pgs->color[1].ccolor = tmp_cc;
+
+    tmp_dc                  = pgs->color[0].dev_color;
+    pgs->color[0].dev_color = pgs->color[1].dev_color;
+    pgs->color[1].dev_color = tmp_dc;
+
+    tmp_cs                    = pgs->color[0].color_space;
+    pgs->color[0].color_space = pgs->color[1].color_space;
+    pgs->color[1].color_space = tmp_cs;
+
+    /* Swap the bits of the imager state that depend on the current color */
+    tmp_ht          = pgs->dev_ht;
+    pgs->dev_ht     = pgs->dev_ht_alt;
+    pgs->dev_ht_alt = tmp_ht;
+    
+    tmp_cie                   = pgs->cie_joint_caches;
+    pgs->cie_joint_caches     = pgs->cie_joint_caches_alt;
+    pgs->cie_joint_caches_alt = tmp_cie;
+    
+    tmp_ccm                      = pgs->color_component_map;
+    pgs->color_component_map     = pgs->color_component_map_alt;
+    pgs->color_component_map_alt = tmp_ccm;
+
+    tmp_pc                 = pgs->pattern_cache;
+    pgs->pattern_cache     = pgs->pattern_cache_alt;
+    pgs->pattern_cache_alt = tmp_pc;
+    
+    tmp                = pgs->overprint;
+    pgs->overprint     = pgs->overprint_alt;
+    pgs->overprint_alt = tmp;
+
+    tmp                     = pgs->overprint_mode;
+    pgs->overprint_mode     = pgs->overprint_mode_alt;
+    pgs->overprint_mode_alt = tmp;
+
+    tmp                               = pgs->effective_overprint_mode;
+    pgs->effective_overprint_mode     = pgs->effective_overprint_mode_alt;
+    pgs->effective_overprint_mode_alt = tmp;
+    
+}
+
+int gs_swapcolors(gs_state *pgs)
+{
+    int prior_overprint = pgs->overprint;
+    int prior_mode      = pgs->effective_overprint_mode;
+
+    gs_swapcolors_quick(pgs);
+
+    /* The following code will only call gs_do_set_overprint when we
+     * have a change:
+     * if ((prior_overprint != pgs->overprint) ||
+     *    ((prior_mode != pgs->effective_overprint_mode) &&
+     *     (pgs->overprint)))
+     *    return gs_do_set_overprint(pgs);
+     * Sadly, that's no good, as we need to call when we have swapped
+     * image space types too (separation <-> non separation for example).
+     *
+     * So instead, we call whenever at least one of them had overprint
+     * turned on.
+     */
+    if (prior_overprint || pgs->overprint)
+    {
+        return gs_do_set_overprint(pgs);
+    }
+    return 0;
+}

Modified: trunk/gs/base/gstext.c
===================================================================
--- trunk/gs/base/gstext.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gstext.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -265,7 +265,8 @@
 	return code;
     pgs->device->sgr.stroke_stored = false;
     return gx_device_text_begin(pgs->device, (gs_imager_state *) pgs,
-				text, pgs->font, pgs->path, pgs->dev_color,
+				text, pgs->font, pgs->path,
+				gs_currentdevicecolor_inline(pgs),
 				pcpath, mem, ppte);
 }
 

Modified: trunk/gs/base/gstrans.c
===================================================================
--- trunk/gs/base/gstrans.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gstrans.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -210,12 +210,9 @@
         device space.  However, if the device is a sep device it will blend
         in DeviceN color space as required.  */
 
-    if (gs_color_space_get_index(pgs->color_space) <= gs_color_space_index_DeviceCMYK) {
+    blend_color_space = gs_currentcolorspace_inline(pgs);
+    if (gs_color_space_get_index(blend_color_space) > gs_color_space_index_DeviceCMYK) {
 
-        blend_color_space = pgs->color_space;
-
-    } else {
-
        /* ICC and CIE based color space.  Problem right now is that the 
        current code does a concretization to the color space
        defined by the CRD.  This is not the space that we want
@@ -227,7 +224,7 @@
        concrete space for the ICC space, which is defined by
        the output (or default) CRD. */
 
-        blend_color_space = cs_concrete_space(pgs->color_space, pis);
+        blend_color_space = cs_concrete_space(blend_color_space, pis);
 
     }
 
@@ -516,7 +513,7 @@
     params.replacing = ptmp->replacing;
     /* Note that the SMask buffer may have a different 
        numcomps than the device buffer */
-    params.group_color_numcomps = cs_num_components(pgs->color_space);
+    params.group_color_numcomps = cs_num_components(gs_currentcolorspace_inline(pgs));
 
     if_debug9('v', "[v](0x%lx)gs_begin_transparency_mask [%g %g %g %g]\n\
       subtype = %d  Background_components = %d Num_grp_clr_comp = %d  %s\n",
@@ -571,13 +568,9 @@
         to the fact that things are done
         in device space always. */
 
+        blend_color_space = gs_currentcolorspace_inline(pgs);
+        if(gs_color_space_is_CIE(blend_color_space)){
 
-        if(!gs_color_space_is_CIE(pgs->color_space)){
-
-            blend_color_space = pgs->color_space;
-
-        } else {
-
            /* ICC or CIE based color space.  Problem right now is that the 
            current code does a concretization to the color space
            defined by the CRD.  This is not the space that we want
@@ -589,7 +582,7 @@
            concrete space for the ICC space, which is defined by
            the output (or default) CRD. */
 
-            blend_color_space = cs_concrete_space(pgs->color_space, pis);
+            blend_color_space = cs_concrete_space(blend_color_space, pis);
 
         }
 

Modified: trunk/gs/base/gxccache.c
===================================================================
--- trunk/gs/base/gxccache.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxccache.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -259,7 +259,7 @@
 gx_image_cached_char(register gs_show_enum * penum, register cached_char * cc)
 {
     register gs_state *pgs = penum->pgs;
-    gx_device_color *pdevc = pgs->dev_color;
+    gx_device_color *pdevc = gs_currentdevicecolor_inline(pgs);
     int x, y, w, h, depth;
     int code;
     gs_fixed_point pt;

Modified: trunk/gs/base/gxchar.c
===================================================================
--- trunk/gs/base/gxchar.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxchar.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -680,6 +680,9 @@
 	if ((code = gx_clip_to_rectangle(pgs, &clip_box)) < 0)
 	    return code;
 	gx_set_device_color_1(pgs);	/* write 1's */
+        gs_swapcolors_quick(pgs);
+	gx_set_device_color_1(pgs);	/* write 1's */
+        gs_swapcolors_quick(pgs);
 	pgs->in_cachedevice = CACHE_DEVICE_CACHING;
     }
     penum->width_status = sws_cache;

Modified: trunk/gs/base/gxcmap.c
===================================================================
--- trunk/gs/base/gxcmap.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxcmap.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -540,12 +540,13 @@
 int
 gx_remap_color(gs_state * pgs)
 {
-    const gs_color_space *pcs = pgs->color_space;
+    const gs_color_space *pcs = gs_currentcolorspace_inline(pgs);
     int                   code;
 
     /* The current color in the graphics state is always used for */
     /* the texture, never for the source. */
-    code = (*pcs->type->remap_color) (pgs->ccolor, pcs, pgs->dev_color,
+    code = (*pcs->type->remap_color) (gs_currentcolor_inline(pgs),
+				      pcs, gs_currentdevicecolor_inline(pgs),
 				      (gs_imager_state *) pgs, pgs->device,
 				      gs_color_select_texture);
     /* if overprint mode is in effect, update the overprint information */

Modified: trunk/gs/base/gxcspace.h
===================================================================
--- trunk/gs/base/gxcspace.h	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxcspace.h	2010-03-18 00:57:10 UTC (rev 10940)
@@ -177,14 +177,14 @@
 #define cs_proc_adjust_color_count(proc)\
   void proc(const gs_client_color *, const gs_color_space *, int)
 #define cs_adjust_color_count(pgs, delta)\
-  (*(pgs)->color_space->type->adjust_color_count)\
-    ((pgs)->ccolor, (pgs)->color_space, delta)
+  (*gs_currentcolorspace_inline(pgs)->type->adjust_color_count)\
+    (gs_currentcolor_inline(pgs), gs_currentcolorspace_inline(pgs), delta)
 	cs_proc_adjust_color_count((*adjust_color_count));
 
 /* Adjust both reference counts. */
 #define cs_adjust_counts(pgs, delta)\
     cs_adjust_color_count(pgs, delta);					\
-	rc_adjust_const(pgs->color_space, delta, "cs_adjust_counts")
+	rc_adjust_const(gs_currentcolorspace_inline(pgs), delta, "cs_adjust_counts")
 
     /* Serialization. */
     /*

Modified: trunk/gs/base/gxdcolor.h
===================================================================
--- trunk/gs/base/gxdcolor.h	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxdcolor.h	2010-03-18 00:57:10 UTC (rev 10940)
@@ -291,7 +291,7 @@
 
 
 #define gs_color_writes_pure(pgs)\
-  color_writes_pure((pgs)->dev_color, (pgs)->log_op)
+  color_writes_pure(gs_currentdevicecolor_inline(pgs), (pgs)->log_op)
 
 /* Set up device color 1 for writing into a mask cache */
 /* (e.g., the character cache). */
@@ -301,14 +301,14 @@
 int gx_remap_color(gs_state *);
 
 #define gx_set_dev_color(pgs)\
-  if ( !color_is_set((pgs)->dev_color) )\
+  if ( !color_is_set(gs_currentdevicecolor_inline(pgs)) )\
    { int code_dc = gx_remap_color(pgs);\
      if ( code_dc != 0 ) return code_dc;\
    }
 
 /* Indicate that the device color needs remapping. */
 #define gx_unset_dev_color(pgs)\
-  color_unset((pgs)->dev_color)
+  color_unset(gs_currentdevicecolor_inline(pgs))
 
 /* Load the halftone cache in preparation for drawing. */
 #define gx_color_load_select(pdevc, pis, dev, select)\
@@ -316,7 +316,7 @@
 #define gx_color_load(pdevc, pis, dev)\
   gx_color_load_select(pdevc, pis, dev, gs_color_select_texture)
 #define gs_state_color_load(pgs)\
-  gx_color_load((pgs)->dev_color, (const gs_imager_state *)(pgs),\
+  gx_color_load(gs_currentdevicecolor_inline(pgs), (const gs_imager_state *)(pgs),\
 		(pgs)->device)
 
 /* Fill a rectangle with a color. */

Modified: trunk/gs/base/gxhldevc.c
===================================================================
--- trunk/gs/base/gxhldevc.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxhldevc.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -81,7 +81,7 @@
 	 * may be the same but for differing high level colors (due to the
 	 * usual lower resolution of the gx_color_index values.
 	 */
-        const gs_color_space * pcs = pgs->color_space;
+        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
         int i = gs_color_space_num_components(pcs);
 
         psc->color_space_id = pcs->id;
@@ -158,7 +158,7 @@
     /* Check if the current color space was used to build the device color */
     if (gx_hld_is_hl_color_available(pis, pdevc)) {
 	const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
-        const gs_color_space * pcs = pgs->color_space;
+        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
 
 	*ppcs = pcs;
 	*ppcc = &(pdevc->ccolor);
@@ -187,7 +187,7 @@
     const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
 
     if (pgs != NULL) {
-        const gs_color_space * pcs = pgs->color_space;
+        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
 	int n = gs_color_space_num_components(pcs);
 
 	return (n >= 0 ? n : -n - 1);

Modified: trunk/gs/base/gxistate.h
===================================================================
--- trunk/gs/base/gxistate.h	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxistate.h	2010-03-18 00:57:10 UTC (rev 10940)
@@ -162,7 +162,14 @@
 	/* Simple color spaces, stored here for easy access from */ 	\
 	/* gx_concrete_space_CIE */ \
 	gs_color_space *devicergb_cs;\
-	gs_color_space *devicecmyk_cs
+	gs_color_space *devicecmyk_cs;\
+\
+	/* Stores for cached values which correspond to whichever */\
+	/* color isn't in force at the moment */\
+	struct gx_cie_joint_caches_s *cie_joint_caches_alt;\
+	gs_devicen_color_map          color_component_map_alt;\
+	struct gx_pattern_cache_s    *pattern_cache_alt;\
+	gx_device_halftone           *dev_ht_alt
 
 /*
  * Enumerate the reference-counted pointers in a c.r. state.  Note that
@@ -176,7 +183,8 @@
   m(set_transfer.red) m(set_transfer.green)\
   m(set_transfer.blue) m(set_transfer.gray)\
   m(cie_joint_caches)\
-  m(devicergb_cs) m(devicecmyk_cs)
+  m(devicergb_cs) m(devicecmyk_cs)\
+  m(dev_ht_alt) m(cie_joint_caches)
 
 /* Enumerate the pointers in a c.r. state. */
 #define gs_cr_state_do_ptrs(m)\
@@ -185,7 +193,9 @@
   m(5,set_transfer.red) m(6,set_transfer.green)\
   m(7,set_transfer.blue) m(8,set_transfer.gray)\
   m(9,cie_joint_caches) m(10,pattern_cache)\
-  m(11,devicergb_cs) m(12,devicecmyk_cs)
+  m(11,devicergb_cs) m(12,devicecmyk_cs)\
+  m(13,cie_joint_caches_alt) m(14,pattern_cache_alt)\
+  m(15,dev_ht_alt)
   /*
    * We handle effective_transfer specially in gsistate.c since its pointers
    * are not enumerated for garbage collection but they are are relocated.
@@ -194,7 +204,7 @@
  * This count does not include the effective_transfer pointers since they
  * are not enumerated for GC.
  */
-#define st_cr_state_num_ptrs 13
+#define st_cr_state_num_ptrs 16
 
 
 typedef struct gs_devicen_color_map_s {
@@ -250,6 +260,9 @@
 	bool overprint;\
 	int overprint_mode;\
 	int effective_overprint_mode;\
+	bool overprint_alt;\
+	int overprint_mode_alt;\
+	int effective_overprint_mode_alt;\
 	float flatness;\
 	gs_fixed_point fill_adjust; /* A path expansion for fill; -1 = dropout prevention*/\
 	bool stroke_adjust;\
@@ -288,7 +301,7 @@
    { (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\
   false, {0, 0}, {0, 0}, false, \
   lop_default, gx_max_color_value, BLEND_MODE_Compatible,\
-{ 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0, 0, 0, 0/*false*/, 0, 0, 1.0,  \
+{ 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0, 0, 0, 0/*false*/, 0, 0, 0/*false*/, 0, 0, 1.0,  \
    { fixed_half, fixed_half }, 0/*false*/, 0/*false*/, 0/*false*/, 1.0,\
   1, INIT_CUSTOM_COLOR_PTR	/* 'Custom color' callback pointer */  \
   gx_default_get_cmap_procs

Modified: trunk/gs/base/gxpaint.c
===================================================================
--- trunk/gs/base/gxpaint.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gxpaint.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -64,7 +64,7 @@
     params.traditional = false;
     return (*dev_proc(dev, stroke_path))
 	(dev, (const gs_imager_state *)pgs, ppath, &params,
-	 pgs->dev_color, pcpath);
+	 gs_currentdevicecolor_inline(pgs), pcpath);
 }
 
 int

Modified: trunk/gs/base/gzstate.h
===================================================================
--- trunk/gs/base/gzstate.h	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/base/gzstate.h	2010-03-18 00:57:10 UTC (rev 10940)
@@ -104,17 +104,20 @@
 				/* possibly = clip_path or view_clip */
     bool effective_clip_shared;	/* true iff e.c.p. = c.p. or v.c. */
 
-    /* Color (device-independent): */
+#define gs_currentdevicecolor_inline(pgs) \
+    ((pgs)->color[0].dev_color)
+#define gs_currentcolor_inline(pgs) \
+    ((pgs)->color[0].ccolor)
+#define gs_currentcolorspace_inline(pgs) \
+    ((pgs)->color[0].color_space)
 
-    gs_color_space *color_space; /* after substitution */
-    gs_client_color *ccolor;
-
-    /* Color caches: */
-
-#define gs_currentdevicecolor_inline(pgs) ((pgs)->dev_color)
-
-    gx_device_color *dev_color;
-
+    /* Current colors (non-stroking, and stroking) */
+    struct {
+        gs_color_space *color_space; /* after substitution */
+        gs_client_color *ccolor;
+        gx_device_color *dev_color;
+    } color[2];
+    
     /* Font: */
 
     gs_font *font;
@@ -155,10 +158,11 @@
 #define gs_state_do_ptrs(m)\
   m(0,saved) m(1,path) m(2,clip_path) m(3,clip_stack)\
   m(4,view_clip) m(5,effective_clip_path)\
-  m(6,color_space) m(7,ccolor) m(8,dev_color)\
-  m(9,font) m(10,root_font) m(11,show_gstate) /*m(---,device)*/\
-  m(12,transparency_group_stack)
-#define gs_state_num_ptrs 13
+  m(6,color[0].color_space) m(7,color[0].ccolor) m(8,color[0].dev_color)\
+  m(9,color[1].color_space) m(10,color[1].ccolor) m(11,color[1].dev_color)\
+  m(12,font) m(13,root_font) m(14,show_gstate) /*m(---,device)*/\
+  m(15,transparency_group_stack)
+#define gs_state_num_ptrs 16
 
 /* The following macro is used for development purpose for designating places 
    where current point is changed. Clients must not use it. */
@@ -166,4 +170,7 @@
     (pgs)->current_point.x = xx;\
     (pgs)->current_point.y = yy;
 
+int gs_swapcolors(gs_state *);
+void gs_swapcolors_quick(gs_state *);
+
 #endif /* gzstate_INCLUDED */


Property changes on: trunk/gs/psi/dmmain.c
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/smask_work/base/dmmain.c:9134-9665
   + /branches/gs_2_colors/psi/dmmain.c:10650-10937
/branches/smask_work/base/dmmain.c:9134-9665


Property changes on: trunk/gs/psi/dmmain.r
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/smask_work/base/dmmain.r:9134-9665
   + /branches/gs_2_colors/psi/dmmain.r:10650-10937
/branches/smask_work/base/dmmain.r:9134-9665


Property changes on: trunk/gs/psi/dxmain.c
___________________________________________________________________
Modified: svn:mergeinfo
   - 
   + /branches/gs_2_colors/psi/dxmain.c:10650-10937


Property changes on: trunk/gs/psi/dxmainc.c
___________________________________________________________________
Modified: svn:mergeinfo
   - 
   + /branches/gs_2_colors/psi/dxmainc.c:10650-10937

Modified: trunk/gs/psi/igstate.h
===================================================================
--- trunk/gs/psi/igstate.h	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/igstate.h	2010-03-18 00:57:10 UTC (rev 10940)
@@ -122,12 +122,12 @@
           transfer_procs;	/* transfer procedures */
     ref black_generation;	/* (procedure) */
     ref undercolor_removal;	/* (procedure) */
-    ref_colorspace colorspace;
+    ref_colorspace colorspace[2];
     /*
      * Pattern is relevant only if the current color space
      * is a pattern space.
      */
-    ref pattern;		/* pattern (dictionary) */
+    ref pattern[2];		/* pattern (dictionary) */
     struct {
 	ref dict;		/* CIE color rendering dictionary */
 	ref_cie_render_procs procs;	/* (see above) */

Modified: trunk/gs/psi/interp.c
===================================================================
--- trunk/gs/psi/interp.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/interp.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -105,10 +105,22 @@
 {
     int code;
 
-#   ifdef DEBUG_TRACE_PS_OPERATORS
+# ifdef DEBUG_TRACE_PS_OPERATORS
+#   ifndef SHOW_STACK_DEPTHS
     if_debug1('!', "[!]operator %s\n", op_get_name_string(op_proc));
+#   else
+    if_debug3('!', "[!][es=%d os=%d]operator %s\n",
+	    esp-i_ctx_p->exec_stack.stack.bot,
+	    osp-i_ctx_p->op_stack.stack.bot,
+	    op_get_name_string(op_proc));
 #   endif
+# endif
     code = op_proc(i_ctx_p);
+# if defined(DEBUG_TRACE_PS_OPERATORS) && !defined(SHOW_STACK_DEPTHS)
+    if_debug2('!', "[!][es=%d os=%d]\n",
+	    esp-i_ctx_p->exec_stack.stack.bot,
+	    osp-i_ctx_p->op_stack.stack.bot);
+# endif
     return code; /* A good place for a conditional breakpoint. */
 }
 #else

Modified: trunk/gs/psi/psromfs.mak
===================================================================
--- trunk/gs/psi/psromfs.mak	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/psromfs.mak	2010-03-18 00:57:10 UTC (rev 10940)
@@ -27,7 +27,71 @@
 #	Note: gs_cet.ps is only needed to match Adobe CPSI defaults
 PS_ROMFS_ARGS=-c -P $(PSRESDIR)$(D) -d Resource/ $(RESOURCE_LIST) -d lib/ -P $(PSLIBDIR)$(D) $(EXTRA_INIT_FILES)
 
-# We'd really like to have all of the files in Resourc/Init/ be dependencies
-# for COMPILE_INITS=1, but we settle for just the main one. "touch" it if
-# you change any Resource/Init files to force re-build of the %rom% data.
-PS_ROMFS_DEPS=$(PSRESDIR)$(D)Init$(D)$(GS_INIT)
+# A list of all the files in Resource/Init/ as dependencies for COMPILE_INITS=1.
+# If you add a file remember to add it here. If you forget then builds from
+# clean will work (as all files in the directory are included), but rebuilds
+# after changes to unlisted files will not cause the romfs to be regenerated.
+PS_ROMFS_DEPS=\
+	$(PSRESDIR)$(D)Init$(D)cidfmap \
+	$(PSRESDIR)$(D)Init$(D)FCOfontmap-PCLPS2 \
+	$(PSRESDIR)$(D)Init$(D)Fontmap \
+	$(PSRESDIR)$(D)Init$(D)Fontmap.GS \
+	$(PSRESDIR)$(D)Init$(D)gs_agl.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_btokn.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cet.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cff.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cidcm.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_ciddc.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cidfm.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cidfn.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cidtt.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cmap.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_cspace.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_css_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_dbt_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_diskf.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_diskn.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_dpnxt.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_dps.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_dps1.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_dps2.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_dscp.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_epsf.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_fapi.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_fntem.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_fonts.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_frsd.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_icc.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_il1_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_img.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_init.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_l2img.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_lev2.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_ll3.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_mex_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_mgl_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_mro_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_pdfwr.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_pdf_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_res.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_resmp.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_setpd.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_statd.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_std_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_sym_e.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_trap.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_ttf.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_typ32.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_typ42.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_type1.ps \
+	$(PSRESDIR)$(D)Init$(D)gs_wan_e.ps \
+	$(PSRESDIR)$(D)Init$(D)opdfread.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_base.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_cslayer.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_draw.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_font.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_main.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_ops.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_rbld.ps \
+	$(PSRESDIR)$(D)Init$(D)pdf_sec.ps \
+	$(PSRESDIR)$(D)Init$(D)xlatmap


Property changes on: trunk/gs/psi/psromfs.mak
___________________________________________________________________
Modified: svn:mergeinfo
   - 
   + /branches/gs_2_colors/psi/psromfs.mak:10650-10937

Modified: trunk/gs/psi/zchar1.c
===================================================================
--- trunk/gs/psi/zchar1.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/zchar1.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -94,7 +94,7 @@
     int alpha_bits = 1; 
     gs_log2_scale_point log2_subpixels;
     
-    if (color_is_pure(pgs->dev_color)) /* Keep consistency with alpha_buffer_bits() */
+    if (color_is_pure(gs_currentdevicecolor_inline(pgs))) /* Keep consistency with alpha_buffer_bits() */
 	alpha_bits = (*dev_proc(pgs->device, get_alpha_bits)) (pgs->device, go_text);
     if (alpha_bits <= 1) {
 	/* We render to cache device or the target device has no alpha bits. */

Modified: trunk/gs/psi/zcie.c
===================================================================
--- trunk/gs/psi/zcie.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/zcie.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -285,7 +285,7 @@
 	ref_stack_pop_to(&e_stack, edepth);
 	return code;
     }
-    istate->colorspace.procs.cie = *pcprocs;
+    istate->colorspace[0].procs.cie = *pcprocs;
     pop(1);
     return (ref_stack_count(&e_stack) == edepth ? 0 : o_push_estack);
 }
@@ -316,7 +316,7 @@
     check_read_type(*ptref, t_array);
     if (r_size(ptref) != 5)
 	return_error(e_rangecheck);
-    procs = istate->colorspace.procs.cie;
+    procs = istate->colorspace[0].procs.cie;
     code = gs_cspace_build_CIEDEFG(&pcs, NULL, mem);
     if (code < 0)
 	return code;
@@ -373,7 +373,7 @@
     check_read_type(*ptref, t_array);
     if (r_size(ptref) != 4)
 	return_error(e_rangecheck);
-    procs = istate->colorspace.procs.cie;
+    procs = istate->colorspace[0].procs.cie;
     code = gs_cspace_build_CIEDEF(&pcs, NULL, mem);
     if (code < 0)
 	return code;
@@ -425,7 +425,7 @@
     int code;
 
     push(1); /* Sacrificial */
-    procs = istate->colorspace.procs.cie;
+    procs = istate->colorspace[0].procs.cie;
     code = gs_cspace_build_CIEABC(&pcs, NULL, mem);
     if (code < 0)
 	return code;
@@ -467,7 +467,7 @@
     int code;
 
     push(1); /* Sacrificial. cie_a_finish does a pop... */
-    procs = istate->colorspace.procs.cie;
+    procs = istate->colorspace[0].procs.cie;
     if ((code = dict_proc_param(CIEdict, "DecodeA", &procs.Decode.A, true)) < 0)
 	return code;
     code = gs_cspace_build_CIEA(&pcs, NULL, mem);

Modified: trunk/gs/psi/zcolor.c
===================================================================
--- trunk/gs/psi/zcolor.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/zcolor.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -129,7 +129,7 @@
 
     /* push the pattern dictionary or null object, if appropriate */
     if (push_pattern)
-        *op = istate->pattern;
+        *op = istate->pattern[0];
 
     return 0;
 }
@@ -155,8 +155,8 @@
      * this we define the arrays at startup (see gs_cspace.ps), and 
      * recover them here by executing PostScript.
      */
-    if (r_has_type(&istate->colorspace.array, t_name)) {
-	name_string_ref(imemory, &istate->colorspace.array, &namestr);
+    if (r_has_type(&istate->colorspace[0].array, t_name)) {
+	name_string_ref(imemory, &istate->colorspace[0].array, &namestr);
 	if (r_size(&namestr) == 10 && !memcmp(namestr.value.bytes, "DeviceGray", 10)) {
 	    body = ialloc_string(32, "string");
 	    if (body == 0)
@@ -186,7 +186,9 @@
 		    if (code < 0)
 			return code;
 		    refset_null(op->value.refs, 1);
-		    ref_assign_old(op, op->value.refs, &istate->colorspace.array, "currentcolorspace");
+		    ref_assign_old(op, op->value.refs,
+				   &istate->colorspace[0].array,
+				   "currentcolorspace");
 		    return 0;
 		}
 	    }
@@ -200,7 +202,7 @@
 	 * action and can simply use it.
 	 */
 	push(1);
-	*op = istate->colorspace.array;
+	*op = istate->colorspace[0].array;
     }
     return 0;
 }
@@ -256,7 +258,7 @@
     int                     n_comps, n_numeric_comps, num_offset = 0, code, depth;
     bool                    is_ptype2 = 0;
     PS_colour_space_t *space;
-
+    
     /* initialize the client color pattern pointer for GC */
     cc.pattern = 0; 
 
@@ -290,11 +292,13 @@
     if (code < 0)
 	return code;
 
-    code = get_space_object(i_ctx_p, &istate->colorspace.array, &space);
+    code = get_space_object(i_ctx_p, &istate->colorspace[0].array, &space);
     if (code < 0)
 	return code;
     if (space->validatecomponents) {
-	code = space->validatecomponents(i_ctx_p, &istate->colorspace.array, cc.paint.values, n_numeric_comps);
+	code = space->validatecomponents(i_ctx_p,
+					 &istate->colorspace[0].array,
+					 cc.paint.values, n_numeric_comps);
 	if (code < 0)
 	    return code;
     }
@@ -303,17 +307,17 @@
     if ((code = gs_setcolor(igs, &cc)) >= 0) {
 
         if (n_comps > n_numeric_comps) {
-            istate->pattern = *op;      /* save pattern dict or null */
+            istate->pattern[0] = *op;      /* save pattern dict or null */
             n_comps = n_numeric_comps + 1;
         }
     }
-
+    
     /* Check the color spaces, to see if we need to run any tint transform
      * procedures. Some Adobe applications *eg Photoshop) expect that the 
      * tint transform will be run and use this to set up duotone DeviceN
      * spaces.
      */
-    code = validate_spaces(i_ctx_p, &istate->colorspace.array, &depth);
+    code = validate_spaces(i_ctx_p, &istate->colorspace[0].array, &depth);
     if (code < 0)
 	return code;
     /* Set up for the continuation procedure which will do the work */
@@ -333,7 +337,7 @@
      * to the space difficult
      */
     ep = esp += 1;
-    *ep = istate->colorspace.array;
+    *ep = istate->colorspace[0].array;
     /* Finally, the actual continuation routine */
     push_op_estack(setcolor_cont);
     return o_push_estack;
@@ -409,7 +413,7 @@
             */
 
         if ( name_is_device_color(newcspace->name) ){
-            if ( gs_color_space_is_CIE(i_ctx_p->pgs->color_space) ){
+            if ( gs_color_space_is_CIE(gs_currentcolorspace_inline(i_ctx_p->pgs)) ){
                 if ( !isCIE ) return 0; /*  The color spaces will be different */
             } else {
                 if ( isCIE ) return 0; /*  The color spaces will be different */
@@ -470,17 +474,17 @@
     is_CIE = istate->use_cie_color.value.boolval;
 
     /* See if its the same as the current space */
-    if (is_same_colorspace(i_ctx_p, op, &istate->colorspace.array, is_CIE)) {
+    if (is_same_colorspace(i_ctx_p, op, &istate->colorspace[0].array, is_CIE)) {
 	PS_colour_space_t *cspace;
 
 	/* Even if its the same space, we still need to set the correct
 	 * initial color value.
 	 */
-	code = get_space_object(i_ctx_p, &istate->colorspace.array, &cspace);
+	code = get_space_object(i_ctx_p, &istate->colorspace[0].array, &cspace);
 	if (code < 0)
 	    return 0;
 	if (cspace->initialcolorproc) {
-	    cspace->initialcolorproc(i_ctx_p, &istate->colorspace.array);
+	    cspace->initialcolorproc(i_ctx_p, &istate->colorspace[0].array);
 	}
 	/* Pop the space off the stack */
 	pop(1);
@@ -510,7 +514,7 @@
 }
 
 /*
- * A sepcial version of the setcolorspace operation above. This sets the 
+ * A special version of the setcolorspace operation above. This sets the 
  * CIE substitution flag to true before starting, which prevents any further
  * CIE substitution taking place.
  */
@@ -721,7 +725,11 @@
 int
 zcolor_remap_color(i_ctx_t *i_ctx_p)
 {
+    /* Remap both colors. This should never hurt. */
+    gs_swapcolors(igs);
     gx_unset_dev_color(igs);
+    gs_swapcolors(igs);
+    gx_unset_dev_color(igs);
     return 0;
 }
 
@@ -1085,7 +1093,7 @@
     return 0;
 }
 
-/* The routiens for handling colors and color spaces, moved from 
+/* The routines for handling colors and color spaces, moved from 
  * PostScript to C, start here.
  */
 
@@ -1143,7 +1151,7 @@
 		    return_error(e_VMerror);
 		code = gs_setcolorspace(igs, pcs);
 		if (code >= 0) {
-		    gs_client_color *   pcc = igs->ccolor;
+		    gs_client_color *pcc = gs_currentcolor_inline(igs);
 
 		    cs_adjust_color_count(igs, -1); /* not strictly necessary */
 		    pcc->paint.values[0] = (0);
@@ -1366,7 +1374,7 @@
 		    return_error(e_VMerror);
 		code = gs_setcolorspace(igs, pcs);
 		if (code >= 0) {
-		    gs_client_color *   pcc = igs->ccolor;
+		    gs_client_color *pcc = gs_currentcolor_inline(igs);
 
 		    cs_adjust_color_count(igs, -1); /* not strictly necessary */
 		    pcc->paint.values[0] = 0;
@@ -1700,7 +1708,7 @@
 		    return_error(e_VMerror);
 		code = gs_setcolorspace(igs, pcs);
 		if (code >= 0) {
-		    gs_client_color *   pcc = igs->ccolor;
+		    gs_client_color *pcc = gs_currentcolor_inline(igs);
 
 		    cs_adjust_color_count(igs, -1); /* not strictly necessary */
 		    pcc->paint.values[0] = 0;
@@ -3395,7 +3403,7 @@
     /* The alternate color space has been selected as the current color space */
     pacs = gs_currentcolorspace(igs);
 
-    cspace_old = istate->colorspace;
+    cspace_old = istate->colorspace[0];
     /* Now set the current color space as Separation */
     code = gs_cspace_new_Separation(&pcs, pacs, imemory);
     if (code < 0)
@@ -3406,11 +3414,11 @@
     code = array_get(imemory, sepspace, 1, &proc);
     if (code < 0)
 	return code;
-    istate->colorspace.procs.special.separation.layer_name = proc;
+    istate->colorspace[0].procs.special.separation.layer_name = proc;
     code = array_get(imemory, sepspace, 3, &proc);
     if (code < 0)
 	return code;
-    istate->colorspace.procs.special.separation.tint_transform = proc;
+    istate->colorspace[0].procs.special.separation.tint_transform = proc;
     if (code >= 0)
         code = gs_cspace_set_sepr_function(pcs, pfn);
     if (code >= 0)
@@ -3418,7 +3426,7 @@
     /* release reference from construction */
     rc_decrement_only(pcs, "setseparationspace");
     if (code < 0) {
-	istate->colorspace = cspace_old;
+	istate->colorspace[0] = cspace_old;
 	return code;
     }
     cc.pattern = 0x00;
@@ -3941,7 +3949,7 @@
 	    /* The alternate color space has been selected as the current color space */
 	    pacs = gs_currentcolorspace(igs);
 
-	    cspace_old = istate->colorspace;
+	    cspace_old = istate->colorspace[0];
 	    /* Now set the current color space as Separation */
 	    code = gs_cspace_new_Separation(&pcs, pacs, imemory);
 	    if (code < 0)
@@ -3952,11 +3960,11 @@
 	    code = array_get(imemory, &namesarray, (long)0, &sname);
 	    if (code < 0)
 		return code;
-	    istate->colorspace.procs.special.separation.layer_name = sname;
+	    istate->colorspace[0].procs.special.separation.layer_name = sname;
 	    code = array_get(imemory, devicenspace, 3, &proc);
 	    if (code < 0)
 		return code;
-	    istate->colorspace.procs.special.separation.tint_transform = proc;
+	    istate->colorspace[0].procs.special.separation.tint_transform = proc;
 	    if (code >= 0)
 		code = gs_cspace_set_sepr_function(pcs, pfn);
 	    if (code >= 0)
@@ -3964,7 +3972,7 @@
 	    /* release reference from construction */
 	    rc_decrement_only(pcs, "setseparationspace");
 	    if (code < 0) {
-		istate->colorspace = cspace_old;
+		istate->colorspace[0] = cspace_old;
 		return code;
 	    }
 	    cc.pattern = 0x00;
@@ -4007,18 +4015,18 @@
 
     /* Now set the current color space as DeviceN */
 
-    cspace_old = istate->colorspace;
-    istate->colorspace.procs.special.device_n.layer_names = namesarray;
+    cspace_old = istate->colorspace[0];
+    istate->colorspace[0].procs.special.device_n.layer_names = namesarray;
     code = array_get(imemory, devicenspace, 3, &proc);
     if (code < 0)
 	return code;
-    istate->colorspace.procs.special.device_n.tint_transform = proc;    
+    istate->colorspace[0].procs.special.device_n.tint_transform = proc;    
     gs_cspace_set_devn_function(pcs, pfn);
     code = gs_setcolorspace(igs, pcs);
     /* release reference from construction */
     rc_decrement_only(pcs, "setdevicenspace");
     if (code < 0) {
-	istate->colorspace = cspace_old;
+	istate->colorspace[0] = cspace_old;
 	return code;
     }
 
@@ -4437,7 +4445,7 @@
 }
 static int setindexedspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int CIESubst)
 {
-    ref *pproc = &istate->colorspace.procs.special.index_proc;
+    ref *pproc = &istate->colorspace[0].procs.special.index_proc;
     int code = 0;
     uint edepth = ref_stack_count(&e_stack);
     ref_colorspace cspace_old;
@@ -4454,7 +4462,7 @@
 	return 0;
     }
 
-    cspace_old = istate->colorspace;
+    cspace_old = istate->colorspace[0];
 
     pcs_base = gs_currentcolorspace(igs);
 
@@ -4510,7 +4518,7 @@
     /* release reference from construction */
     rc_decrement_only(pcs, "setindexedspace");
     if (code < 0) {
-	istate->colorspace = cspace_old;
+	istate->colorspace[0] = cspace_old;
 	ref_stack_pop_to(&e_stack, edepth);
 	return code;
     }
@@ -4754,7 +4762,7 @@
 	ref_stack_pop_to(&e_stack, edepth);
 	return code;
     }
-    make_null(&istate->pattern); /* PLRM: initial color value is a null object */
+    make_null(&istate->pattern[0]); /* PLRM: initial color value is a null object */
     *stage = 0;
     return (ref_stack_count(&e_stack) == edepth ? 0 : o_push_estack);	/* installation will load the caches */
 }
@@ -5527,7 +5535,7 @@
 	    }
 	}
 	if (obj->runtransformproc) {
-	    code = obj->runtransformproc(i_ctx_p, &istate->colorspace.array, &usealternate, &stage, &stack_depth);
+	    code = obj->runtransformproc(i_ctx_p, &istate->colorspace[0].array, &usealternate, &stage, &stack_depth);
 	    make_int(&ep[-3], stack_depth);
 	    make_int(&ep[-1], stage);
 	    if (code != 0) {
@@ -5590,7 +5598,7 @@
 	for (i = 0;i < depth;i++) {
 	    code = get_space_object(i_ctx_p, parr, &obj);
  	    if (code < 0) 
-	        return code;
+		return code;
 
 	    if (i < (depth - 1)) {
 		if (!obj->alternateproc) {
@@ -5616,7 +5624,7 @@
         /* Remove our next continuation and our data */
 	esp -= 5;
 	op = osp;
-	istate->colorspace.array = *op;
+	istate->colorspace[0].array = *op;
 	/* Remove the colorspace array form the operand stack */
 	pop(1);
 	code = o_pop_estack;
@@ -5807,6 +5815,7 @@
     push_op_estack(setdevicecolor_cont);
     return o_push_estack;
 }
+
 static int
 zsetcmykcolor(i_ctx_t * i_ctx_p)
 {
@@ -5844,6 +5853,7 @@
     push_op_estack(setdevicecolor_cont);
     return o_push_estack;
 }
+
 /*
  * The routine which does all the dispatching for the device-space specific
  * 'current color' routines currentgray, currentrgbcolo and currentcmykcolor.
@@ -5927,7 +5937,7 @@
 {
     int code, depth;
 
-    code = validate_spaces(i_ctx_p, &istate->colorspace.array, &depth);
+    code = validate_spaces(i_ctx_p, &istate->colorspace[0].array, &depth);
     if (code < 0)
 	return code;
 
@@ -5951,7 +5961,7 @@
      * as the stack may grow unpredictably making further access
      * to the space difficult
      */
-    esp[3] = istate->colorspace.array;
+    esp[3] = istate->colorspace[0].array;
     esp += 3; /* The push_op_estack macro increments esp before using it */
     /* Finally, the actual continuation routine */
     push_op_estack(currentbasecolor_cont);
@@ -5962,7 +5972,7 @@
 {
     int code, depth;
 
-    code = validate_spaces(i_ctx_p, &istate->colorspace.array, &depth);
+    code = validate_spaces(i_ctx_p, &istate->colorspace[0].array, &depth);
     if (code < 0)
 	return code;
 
@@ -5986,7 +5996,7 @@
      * as the stack may grow unpredictably making further access
      * to the space difficult
      */
-    esp[3] = istate->colorspace.array;
+    esp[3] = istate->colorspace[0].array;
     esp += 3; /* The push_op_estack macro increments esp before using it */
     /* Finally, the actual continuation routine */
     push_op_estack(currentbasecolor_cont);
@@ -6017,7 +6027,7 @@
      * as the stack may grow unpredictably making further access
      * to the space difficult
      */
-    esp[3] = istate->colorspace.array;
+    esp[3] = istate->colorspace[0].array;
     esp += 3; /* The push_op_estack macro increments esp before using it */
     /* Finally, the actual continuation routine */
     push_op_estack(currentbasecolor_cont);
@@ -6048,13 +6058,31 @@
      * as the stack may grow unpredictably making further access
      * to the space difficult
      */
-    esp[3] = istate->colorspace.array;
+    esp[3] = istate->colorspace[0].array;
     esp += 3; /* The push_op_estack macro increments esp before using it */
     /* Finally, the actual continuation routine */
     push_op_estack(currentbasecolor_cont);
     return o_push_estack;
 }
 
+/* Can't be static, as setcolorscreen needs to call it */
+int
+zswapcolors(i_ctx_t * i_ctx_p)
+{
+    ref_colorspace tmp_cs;
+    ref            tmp_pat;
+
+    tmp_cs                = istate->colorspace[0];
+    istate->colorspace[0] = istate->colorspace[1];
+    istate->colorspace[1] = tmp_cs;
+
+    tmp_pat            = istate->pattern[0];
+    istate->pattern[0] = istate->pattern[1];
+    istate->pattern[1] = tmp_pat;
+
+    return gs_swapcolors(igs);
+}
+
 /* ------ Initialization procedure ------ */
 
 /* We need to split the table because of the 16-element limit. */
@@ -6086,14 +6114,17 @@
 
 const op_def    zcolor_ext_op_defs[] = 
 {
-    {"0currentgray", zcurrentgray },
-    {"1setgray", zsetgray },
-    {"0currenthsbcolor", zcurrenthsbcolor },
-    {"3sethsbcolor", zsethsbcolor },
-    {"0currentrgbcolor", zcurrentrgbcolor },
-    {"3setrgbcolor", zsetrgbcolor },
-    {"0currentcmykcolor", zcurrentcmykcolor },
-    {"4setcmykcolor", zsetcmykcolor },
+    { "0currentgray", zcurrentgray },
+    { "1setgray", zsetgray },
+    { "0currenthsbcolor", zcurrenthsbcolor },
+    { "3sethsbcolor", zsethsbcolor },
+    { "0currentrgbcolor", zcurrentrgbcolor },
+    { "3setrgbcolor", zsetrgbcolor },
+    { "0currentcmykcolor", zcurrentcmykcolor },
+    { "4setcmykcolor", zsetcmykcolor },
+    
+    /* Operators to deal with setting stroking/non-stroking colors
+     * individually */
+    { "1.swapcolors", zswapcolors },
     op_def_end(0)
 };
-

Modified: trunk/gs/psi/zht.c
===================================================================
--- trunk/gs/psi/zht.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/zht.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -121,7 +121,7 @@
 
 /* <frequency> <angle> <proc> setscreen - */
 static int
-zsetscreen(i_ctx_t *i_ctx_p)
+zsetscreen_aux(i_ctx_t *i_ctx_p)
 {
     os_ptr op = osp;
     gs_screen_halftone screen;
@@ -144,6 +144,24 @@
     return zscreen_enum_init(i_ctx_p, &order, &screen, op, 3,
 			     setscreen_finish, space_index);
 }
+
+extern int zswapcolors(i_ctx_t *i_ctx_p);
+
+static int
+zsetscreen(i_ctx_t *i_ctx_p)
+{
+    check_ostack(3);
+    osp++; *osp = osp[-3];
+    osp++; *osp = osp[-3];
+    osp++; *osp = osp[-3];
+    check_estack(4);
+    esp += 4;
+    make_op_estack(esp-3, zsetscreen_aux);
+    make_op_estack(esp-2, zswapcolors);
+    make_op_estack(esp-1, zsetscreen_aux);
+    make_op_estack(esp,   zswapcolors);
+    return o_push_estack;
+}
 /* We break out the body of this operator so it can be shared with */
 /* the code for Type 1 halftones in sethalftone. */
 int

Modified: trunk/gs/psi/zht1.c
===================================================================
--- trunk/gs/psi/zht1.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/zht1.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -39,7 +39,7 @@
 static int setcolorscreen_finish(i_ctx_t *);
 static int setcolorscreen_cleanup(i_ctx_t *);
 static int
-zsetcolorscreen(i_ctx_t *i_ctx_p)
+zsetcolorscreen_aux(i_ctx_t *i_ctx_p)
 {
     os_ptr op = osp;
     gs_colorscreen_halftone cscreen;
@@ -138,6 +138,33 @@
     return 0;
 }
 
+extern int zswapcolors(i_ctx_t *i_ctx_p);
+
+static int
+zsetcolorscreen(i_ctx_t *i_ctx_p)
+{
+    check_ostack(12);
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    osp++; *osp = osp[-12];
+    check_estack(4);
+    esp += 4;
+    make_op_estack(esp-3, zsetcolorscreen_aux);
+    make_op_estack(esp-2, zswapcolors);
+    make_op_estack(esp-1, zsetcolorscreen_aux);
+    make_op_estack(esp,   zswapcolors);
+    return o_push_estack;
+}
+
 /* ------ Initialization procedure ------ */
 
 const op_def zht1_op_defs[] =

Modified: trunk/gs/psi/zicc.c
===================================================================
--- trunk/gs/psi/zicc.c	2010-03-17 21:41:13 UTC (rev 10939)
+++ trunk/gs/psi/zicc.c	2010-03-18 00:57:10 UTC (rev 10940)
@@ -107,7 +107,7 @@
 
     return cie_set_finish( i_ctx_p,
                            pcs,
-                           &istate->colorspace.procs.cie,
+                           &istate->colorspace[0].procs.cie,
                            edepth,
                            code );
 }



More information about the gs-commits mailing list