[gs-cvs] rev 8558 - in branches/mtrender: lib src

ray at ghostscript.com ray at ghostscript.com
Thu Feb 28 09:05:18 PST 2008


Author: ray
Date: 2008-02-28 09:05:14 -0800 (Thu, 28 Feb 2008)
New Revision: 8558

Modified:
   branches/mtrender/lib/gs_typ42.ps
   branches/mtrender/lib/pdf2dsc.ps
   branches/mtrender/lib/pdf_draw.ps
   branches/mtrender/lib/pdf_ops.ps
   branches/mtrender/lib/ps2pdfxx.bat
   branches/mtrender/src/configure.ac
   branches/mtrender/src/gdevbmpa.c
   branches/mtrender/src/gdevijs.c
   branches/mtrender/src/gdevm24.c
   branches/mtrender/src/gdevmem.c
   branches/mtrender/src/gdevp14.c
   branches/mtrender/src/gdevpdfg.c
   branches/mtrender/src/gdevpdft.c
   branches/mtrender/src/gdevpng.c
   branches/mtrender/src/gdevppla.c
   branches/mtrender/src/gdevppla.h
   branches/mtrender/src/gdevprn.c
   branches/mtrender/src/gdevprn.h
   branches/mtrender/src/gdevprna.c
   branches/mtrender/src/gdevpx.c
   branches/mtrender/src/gdevwts.c
   branches/mtrender/src/gsht.c
   branches/mtrender/src/gshtscr.c
   branches/mtrender/src/gsimage.c
   branches/mtrender/src/gsistate.c
   branches/mtrender/src/gsmatrix.c
   branches/mtrender/src/gsmatrix.h
   branches/mtrender/src/gstrans.c
   branches/mtrender/src/gstrans.h
   branches/mtrender/src/gxclist.c
   branches/mtrender/src/gxclread.c
   branches/mtrender/src/gxclthrd1.c
   branches/mtrender/src/gxdevbuf.h
   branches/mtrender/src/gxdevmem.h
   branches/mtrender/src/gxfixed.h
   branches/mtrender/src/gxht.c
   branches/mtrender/src/gxidata.c
   branches/mtrender/src/gximage.h
   branches/mtrender/src/gximono.c
   branches/mtrender/src/gxipixel.c
   branches/mtrender/src/gxiscale.c
   branches/mtrender/src/gxistate.h
   branches/mtrender/src/gzht.h
   branches/mtrender/src/lib.mak
   branches/mtrender/src/sfxstdio.c
   branches/mtrender/src/siscale.c
   branches/mtrender/src/sisparam.h
   branches/mtrender/src/spprint.c
   branches/mtrender/src/stdint_.h
   branches/mtrender/src/zdouble.c
   branches/mtrender/src/zfapi.c
   branches/mtrender/src/ztrans.c
Log:
Merge in changes to rev 8554.


Modified: branches/mtrender/lib/gs_typ42.ps
===================================================================
--- branches/mtrender/lib/gs_typ42.ps	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/lib/gs_typ42.ps	2008-02-28 17:05:14 UTC (rev 8558)
@@ -54,7 +54,7 @@
       } bind put
       //.buildfont3 exec
     } {
-      //.buildfont42 exec
+      systemdict /.buildfont42 get exec
     } ifelse
   } bind 
 put

Modified: branches/mtrender/lib/pdf2dsc.ps
===================================================================
--- branches/mtrender/lib/pdf2dsc.ps	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/lib/pdf2dsc.ps	2008-02-28 17:05:14 UTC (rev 8558)
@@ -200,7 +200,9 @@
 
          % output the page label
          (\() .pagePrefix
-         PageToString .pageCounterType known { % format the page number
+         .pageCounterType //null ne dup {
+           PageToString .pageCounterType known and
+         } if { % format the page number
            .pageCounter dup 0 gt { % don't try to format nonpositive numbers
              PageToString .pageCounterType get exec
            } {

Modified: branches/mtrender/lib/pdf_draw.ps
===================================================================
--- branches/mtrender/lib/pdf_draw.ps	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/lib/pdf_draw.ps	2008-02-28 17:05:14 UTC (rev 8558)
@@ -433,7 +433,6 @@
   gsave //nodict begin
   null SMask
   1 .setopacityalpha 1 .setshapealpha
-  0 .inittransparencymask 1 .inittransparencymask
   /Compatible .setblendmode
 	% Execute the body of the Form, similar to DoForm.
   pdfopdict .pdfruncontext
@@ -1038,16 +1037,15 @@
     } if
 	% Check elements of array are within 0::(2**BitsPerComponent)-1
 	% This is a PostScript error, but AR ignores Mask in that case
-    2 BitsPerComponent exp cvi 1 sub //false 2 index {
+    1 BitsPerComponent bitshift 1 sub //false 2 index {
       % stack: max_value result_bool value
       dup 0 lt exch 3 index gt or or
     } forall exch pop {
       (\n   **** Warning: Some elements of Mask array are out of range.\n)
       pdfformaterror
-      pop /ImageType 1 def		% revert to non-masked image
-    } {
-      /MaskColor exch def
-    } ifelse
+      [ exch { 0 .max 1 BitsPerComponent bitshift 1 sub .min } forall ]
+    } if
+    /MaskColor exch def
   } {
 		% Mask is a stream, another Image XObject.
 		% Stack: datasource imagemask(false) maskstreamdict
@@ -1081,7 +1079,6 @@
     gsave //nodict begin
     null /SoftMask gput
     1 .setopacityalpha 1 .setshapealpha
-    0 .inittransparencymask 1 .inittransparencymask
     /Compatible .setblendmode
     DoImage
     end grestore

Modified: branches/mtrender/lib/pdf_ops.ps
===================================================================
--- branches/mtrender/lib/pdf_ops.ps	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/lib/pdf_ops.ps	2008-02-28 17:05:14 UTC (rev 8558)
@@ -250,11 +250,11 @@
 % Establish a given color (and color space) as current.
 /.settransparencyparams {	% <alpha> <smask> .settransparencyparams -
   PDFusingtransparency {
-    /.inittransparencymask where {
+    /.begintransparencygroup where {
       pop AlphaIsShape {
-        1 .setopacityalpha 0 .inittransparencymask exch .setshapealpha 1
+        1 .setopacityalpha  exch .setshapealpha 1
       } {
-        1 .setshapealpha 1 .inittransparencymask exch .setopacityalpha 0
+        1 .setshapealpha  exch .setopacityalpha 0
       } ifelse
 	% Set the soft mask by rendering the XObject.  Doing this every time
 	% is obviously very inefficient; we'll improve it later.
@@ -269,7 +269,7 @@
 /.settransparencymask {		% <paramdict> <masknum> .settransparencymask -
   exch dup null eq {
     PDFusingtransparency {
-      pop .inittransparencymask
+      pop pop
     } {
       dup /Draw get exec
     } ifelse

Modified: branches/mtrender/lib/ps2pdfxx.bat
===================================================================
--- branches/mtrender/lib/ps2pdfxx.bat	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/lib/ps2pdfxx.bat	2008-02-28 17:05:14 UTC (rev 8558)
@@ -23,7 +23,7 @@
 :run
 echo -sOutputFile#%2 >>_.at2
 copy /b /y _.at2+_.at >NUL
-echo -c .setpdfwrite -f %1 >>_.at2
+echo -c .setpdfwrite -f%1 >>_.at2
 %GSC% @_.at @_.at2
 goto end
 

Modified: branches/mtrender/src/configure.ac
===================================================================
--- branches/mtrender/src/configure.ac	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/configure.ac	2008-02-28 17:05:14 UTC (rev 8558)
@@ -232,7 +232,7 @@
 	if test -z "$HAVE_FONTCONFIG"; then
 		AC_CHECK_LIB([fontconfig], [FcInitLoadConfigAndFonts], [
 		  AC_CHECK_HEADER([fontconfig/fontconfig.h], [
-		    FONTCONFIG_LIBS="-lfontconfg"
+		    FONTCONFIG_LIBS="-lfontconfig"
 		    HAVE_FONTCONFIG="-DHAVE_FONTCONFIG"
 		  ])
 		])

Modified: branches/mtrender/src/gdevbmpa.c
===================================================================
--- branches/mtrender/src/gdevbmpa.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevbmpa.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -452,7 +452,7 @@
 
 	    /* Set up the buffer device. */
 	    code = gdev_create_buf_device(crdev->buf_procs.create_buf_device,
-					  &bdev, crdev->target, &render_plane,
+					  &bdev, crdev->target, 0, &render_plane,
 					  dev->memory, NULL);
 	    if (code < 0)
 		goto done;

Modified: branches/mtrender/src/gdevijs.c
===================================================================
--- branches/mtrender/src/gdevijs.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevijs.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -482,12 +482,12 @@
    return 0;
 }
 
-static int gsijs_create_buf_device(gx_device **pbdev, gx_device *target,
+static int gsijs_create_buf_device(gx_device **pbdev, gx_device *target, int y,
             const gx_render_plane_t *render_plane, gs_memory_t *mem, gx_band_complexity_t *for_band)
 {
    gx_device_ijs *ijsdev = (gx_device_ijs *)target;
    int n_chan = ijsdev->color_info.num_components;
-   int code = gx_default_create_buf_device(pbdev, target, render_plane, mem, for_band);
+   int code = gx_default_create_buf_device(pbdev, target, y, render_plane, mem, for_band);
    if (code < 0 || n_chan != 3)
       return code;
 

Modified: branches/mtrender/src/gdevm24.c
===================================================================
--- branches/mtrender/src/gdevm24.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevm24.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -108,6 +108,7 @@
     declare_unpack_color(r, g, b, color);
     declare_scan_ptr(dest);
 
+    if_debug4('b', "[b]device y=%d h=%d x=%d w=%d\n", y + mdev->band_y, h, x, w);
     /*
      * In order to avoid testing w > 0 and h > 0 twice, we defer
      * executing setup_rect, and use fit_fill_xywh instead of
@@ -468,6 +469,7 @@
 {
     gx_device_memory * const mdev = (gx_device_memory *)dev;
 
+    if_debug1('w', "[w]device y=%d:\n", y + mdev->band_y); /* See siscale.c about 'w'. */
     fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
     mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
     return 0;

Modified: branches/mtrender/src/gdevmem.c
===================================================================
--- branches/mtrender/src/gdevmem.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevmem.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -174,6 +174,7 @@
     }
     check_device_separable((gx_device *)dev);
     gx_device_fill_in_procs((gx_device *)dev);
+    dev->band_y = 0;
 }
 /* Make a monobit memory device.  This is never a page device. */
 /* Note that white=0, black=1. */

Modified: branches/mtrender/src/gdevp14.c
===================================================================
--- branches/mtrender/src/gdevp14.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevp14.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -2063,9 +2063,6 @@
 	case PDF14_END_TRANS_GROUP:
 	    code = gx_end_transparency_group(pis, pdev);
 	    break;
-	case PDF14_INIT_TRANS_MASK:
-	    code = gx_init_transparency_mask(pis, &params);
-	    break;
 	case PDF14_BEGIN_TRANS_MASK:
 	    code = gx_begin_transparency_mask(pis, pdev, &params);
 	    break;
@@ -2889,9 +2886,6 @@
 	    put_value(pbuf, pparams->shape.alpha);
 	    put_value(pbuf, pparams->bbox);	    
 	    break;
-	case PDF14_INIT_TRANS_MASK:
-	    *pbuf++ = pparams->csel;
-	    break;
 	case PDF14_BEGIN_TRANS_MASK:
 	    put_value(pbuf, pparams->subtype);
 	    *pbuf++ = pparams->replacing;
@@ -3000,9 +2994,6 @@
 	    read_value(data, params.shape.alpha);
 	    read_value(data, params.bbox);
 	    break;
-	case PDF14_INIT_TRANS_MASK:
-	    params.csel = *data++;
-	    break;
 	case PDF14_BEGIN_TRANS_MASK:
 		/* This is the largest transparency parameter at this time (potentially
 		 * 1275 bytes in size if Background_components = 
@@ -3134,7 +3125,7 @@
 	    *ppcte = pcte;
 	    if (op == opening_op)
 		return return_code;
-	    if (op != PDF14_INIT_TRANS_MASK && op != PDF14_SET_BLEND_PARAMS) {
+	    if (op != PDF14_SET_BLEND_PARAMS) {
 		if (opening_op == PDF14_BEGIN_TRANS_MASK)
 		    return 0;
 		if (opening_op == PDF14_BEGIN_TRANS_GROUP) {
@@ -3210,10 +3201,6 @@
 	    if (*ppcte == NULL)
 		return 2;
 	    return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, 6);
-	case PDF14_INIT_TRANS_MASK: 
-	    if (*ppcte == NULL)
-		return 0;
-	    return find_same_op(this, PDF14_INIT_TRANS_MASK, ppcte);
 	case PDF14_BEGIN_TRANS_MASK: 
 	    return 0;
 	case PDF14_END_TRANS_MASK: 

Modified: branches/mtrender/src/gdevpdfg.c
===================================================================
--- branches/mtrender/src/gdevpdfg.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevpdfg.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -1417,8 +1417,8 @@
 	 * If the graphics state calls for any transparency functions,
 	 * we can't represent them, so return a rangecheck.
 	 */
-	if (pis->opacity.alpha != 1 || pis->opacity.mask != 0 ||
-	    pis->shape.alpha != 1 || pis->shape.mask != 0 ||
+	if (pis->opacity.alpha != 1 || 
+	    pis->shape.alpha != 1 || 
 	    pis->transparency_stack != 0
 	    )
 	    return_error(gs_error_rangecheck);

Modified: branches/mtrender/src/gdevpdft.c
===================================================================
--- branches/mtrender/src/gdevpdft.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevpdft.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -346,8 +346,6 @@
 		return pdf_begin_transparency_group(pis, pdev, params);
 	    case PDF14_END_TRANS_GROUP:
 		return pdf_end_transparency_group(pis, pdev);
-	    case PDF14_INIT_TRANS_MASK:
-		return gx_init_transparency_mask(pis, params);
 	    case PDF14_BEGIN_TRANS_MASK:
 		return pdf_begin_transparency_mask(pis, pdev, params);
 	    case PDF14_END_TRANS_MASK:

Modified: branches/mtrender/src/gdevpng.c
===================================================================
--- branches/mtrender/src/gdevpng.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevpng.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -447,12 +447,12 @@
 }
 
 static int 
-pngalpha_create_buf_device(gx_device **pbdev, gx_device *target,
+pngalpha_create_buf_device(gx_device **pbdev, gx_device *target, int y,
    const gx_render_plane_t *render_plane, gs_memory_t *mem,
    gx_band_complexity_t *band_complexity)
 {
     gx_device_printer *ptarget = (gx_device_printer *)target;
-    int code = gx_default_create_buf_device(pbdev, target, 
+    int code = gx_default_create_buf_device(pbdev, target, y, 
 	render_plane, mem, band_complexity);
     /* Now set copy_alpha to one that handles RGBA */
     set_dev_proc(*pbdev, copy_alpha, ptarget->orig_procs.copy_alpha);

Modified: branches/mtrender/src/gdevppla.c
===================================================================
--- branches/mtrender/src/gdevppla.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevppla.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -93,11 +93,11 @@
 
 /* Create a planar buffer device. */
 int
-gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target,
+gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target, int y,
 			   const gx_render_plane_t *render_plane,
 			   gs_memory_t *mem, gx_band_complexity_t *for_band)
 {
-    int code = gx_default_create_buf_device(pbdev, target, render_plane, mem,
+    int code = gx_default_create_buf_device(pbdev, target, y, render_plane, mem,
 					    for_band);
 
     if (code < 0)

Modified: branches/mtrender/src/gdevppla.h
===================================================================
--- branches/mtrender/src/gdevppla.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevppla.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -32,7 +32,7 @@
 
 /* Create a planar buffer device. */
 /* Use this instead of the default if UsePlanarBuffer is true. */
-int gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target,
+int gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target, int y,
 			       const gx_render_plane_t *render_plane,
 			       gs_memory_t *mem, gx_band_complexity_t *for_band);
 

Modified: branches/mtrender/src/gdevprn.c
===================================================================
--- branches/mtrender/src/gdevprn.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevprn.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -363,7 +363,7 @@
 	    ppdev->buffer_space = 0;
 	    if ((code = gdev_create_buf_device
 		 (ppdev->printer_procs.buf_procs.create_buf_device,
-		  &bdev, pdev, NULL, NULL, NULL)) < 0 ||
+		  &bdev, pdev, 0, NULL, NULL, NULL)) < 0 ||
 		(code = ppdev->printer_procs.buf_procs.setup_buf_device
 		 (bdev, base, buf_space.raster,
 		  (byte **)(base + buf_space.bits), 0, pdev->height,
@@ -986,11 +986,11 @@
  */
 int
 gdev_create_buf_device(create_buf_device_proc_t cbd_proc, gx_device **pbdev,
-		       gx_device *target,
+		       gx_device *target, int y,
 		       const gx_render_plane_t *render_plane,
 		       gs_memory_t *mem, gx_band_complexity_t *band_complexity)
 {
-    int code = cbd_proc(pbdev, target, render_plane, mem, band_complexity);
+    int code = cbd_proc(pbdev, target, y, render_plane, mem, band_complexity);
 
     if (code < 0)
 	return code;
@@ -1004,7 +1004,7 @@
  * possibly preceded by a plane extraction device.
  */
 int
-gx_default_create_buf_device(gx_device **pbdev, gx_device *target,
+gx_default_create_buf_device(gx_device **pbdev, gx_device *target, int y,
     const gx_render_plane_t *render_plane, gs_memory_t *mem, gx_band_complexity_t *band_complexity)
 {
     int plane_index = (render_plane ? render_plane->index : -1);
@@ -1037,6 +1037,7 @@
 	gs_make_mem_device(mdev, mdproto, mem, (band_complexity == NULL ? 1 : 0),
 			   (target == (gx_device *)mdev ? NULL : target));
     mdev->width = target->width;
+    mdev->band_y = y;
     /*
      * The matrix in the memory device is irrelevant,
      * because all we do with the device is call the device-level

Modified: branches/mtrender/src/gdevprn.h
===================================================================
--- branches/mtrender/src/gdevprn.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevprn.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -637,7 +637,7 @@
  */
 typedef dev_proc_create_buf_device((*create_buf_device_proc_t));
 int gdev_create_buf_device(create_buf_device_proc_t cbd_proc,
-			   gx_device **pbdev, gx_device *target,
+			   gx_device **pbdev, gx_device *target, int y,
 			   const gx_render_plane_t *render_plane,
 			   gs_memory_t *mem, gx_band_complexity_t *band_complexity);
 

Modified: branches/mtrender/src/gdevprna.c
===================================================================
--- branches/mtrender/src/gdevprna.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevprna.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -28,7 +28,7 @@
 #include "gxcldev.h"
 #include "gxclpath.h"
 #include "gxpageq.h"
-#include "gzht.h"		/* for gx_ht_cache_default_bits */
+#include "gzht.h"		/* for gx_ht_cache_default_bits_size */
 
 /* ----------------- Constants ----------------------- */
 /*
@@ -99,7 +99,7 @@
 	    pwdev->memory->non_gc_memory, RendererAllocationOverheadBytes + max_raster
 				    /* the first * 2 is not a hack */
 		   + (max_raster + sizeof(void *) * 2) * min_band_height
-		   + max_src_image_row + gx_ht_cache_default_bits() * 2)) < 0)
+		   + max_src_image_row + gx_ht_cache_default_bits_size() * 2)) < 0)
 	     goto open_err;
 
     /* Alloc & init bandlist allocators */

Modified: branches/mtrender/src/gdevpx.c
===================================================================
--- branches/mtrender/src/gdevpx.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevpx.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -1072,6 +1072,12 @@
     if (code < 0)
 	return code;
     if (type & (gx_path_type_fill | gx_path_type_stroke)) {
+	if (rule != xdev->fill_rule) {
+	    px_put_ub(s, (byte)(rule == gx_path_type_even_odd ? eEvenOdd :
+		       eNonZeroWinding));
+	    px_put_ac(s, pxaFillMode, pxtSetFillMode);
+	    xdev->fill_rule = rule;
+	}
 	pclxl_set_paints(xdev, type);
 	spputc(s, pxtPaintPath);
     }

Modified: branches/mtrender/src/gdevwts.c
===================================================================
--- branches/mtrender/src/gdevwts.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gdevwts.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -951,11 +951,11 @@
  * create_buf_device routine and then we set our custom device procedures.
  */
 static int 
-wtsimdi_create_buf_device(gx_device **pbdev, gx_device *target,
+wtsimdi_create_buf_device(gx_device **pbdev, gx_device *target, int y,
    const gx_render_plane_t *render_plane, gs_memory_t *mem,
    gx_band_complexity_t *band_complexity)
 {
-    int code = gx_default_create_buf_device(pbdev, target, 
+    int code = gx_default_create_buf_device(pbdev, target, y,
 	render_plane, mem, band_complexity);
     /* Now set our custom device procedures. */
     if (band_complexity && band_complexity->nontrivial_rops) {

Modified: branches/mtrender/src/gsht.c
===================================================================
--- branches/mtrender/src/gsht.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gsht.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -1109,7 +1109,7 @@
 
                 tile_bytes = porder->raster
                               * (porder->num_bits / porder->width);
-                num_tiles = 1 + max_tile_cache_bytes / tile_bytes;
+                num_tiles = 1 + gx_ht_cache_default_bits_size() / tile_bytes;
                 pcache = gx_ht_alloc_cache( pis->memory,
                                             num_tiles,
                                             tile_bytes * num_tiles );

Modified: branches/mtrender/src/gshtscr.c
===================================================================
--- branches/mtrender/src/gshtscr.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gshtscr.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -249,7 +249,7 @@
                             gs_memory_t * mem)
 {
     gs_matrix imat;
-    ulong max_size = max_tile_cache_bytes;
+    ulong max_size = gx_ht_cache_default_bits_size();
     int code;
 
     if (phsp->frequency < 0.1)

Modified: branches/mtrender/src/gsimage.c
===================================================================
--- branches/mtrender/src/gsimage.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gsimage.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -28,6 +28,7 @@
 #include "gximask.h"
 #include "gzstate.h"
 #include "gsutil.h"
+#include "vdtrace.h"
 
 /*
   The main internal invariant for the gs_image machinery is
@@ -477,6 +478,10 @@
     int code = 0;
 
 #ifdef DEBUG
+    vd_get_dc('i');
+    vd_set_shift(0, 0);
+    vd_set_scale(0.01);
+    vd_set_origin(0, 0);
     if (gs_debug_c('b')) {
 	int pi;
 
@@ -607,6 +612,7 @@
     /* Return the retained data pointers. */
     for (i = 0; i < num_planes; ++i)
 	plane_data[i] = penum->planes[i].source;
+    vd_release_dc;
     return code;
 }
 

Modified: branches/mtrender/src/gsistate.c
===================================================================
--- branches/mtrender/src/gsistate.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gsistate.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -62,10 +62,8 @@
 ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
     ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
     ENUM_PTR(0, gs_imager_state, client_data);
-    ENUM_PTR(1, gs_imager_state, opacity.mask);
-    ENUM_PTR(2, gs_imager_state, shape.mask);
-    ENUM_PTR(3, gs_imager_state, transparency_stack);
-#define E1(i,elt) ENUM_PTR(i+4,gs_imager_state,elt);
+    ENUM_PTR(1, gs_imager_state, transparency_stack);
+#define E1(i,elt) ENUM_PTR(i+2,gs_imager_state,elt);
     gs_cr_state_do_ptrs(E1)
 #undef E1
 ENUM_PTRS_END
@@ -73,8 +71,6 @@
 {
     RELOC_SUPER(gs_imager_state, st_line_params, line_params);
     RELOC_PTR(gs_imager_state, client_data);
-    RELOC_PTR(gs_imager_state, opacity.mask);
-    RELOC_PTR(gs_imager_state, shape.mask);
     RELOC_PTR(gs_imager_state, transparency_stack);
 #define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
     gs_cr_state_do_ptrs(R1)
@@ -96,8 +92,6 @@
     int i;
     pis->memory = mem;
     pis->client_data = 0;
-    pis->opacity.mask = 0;
-    pis->shape.mask = 0;
     pis->transparency_stack = 0;
     /* Color rendering state */
     pis->halftone = 0;
@@ -157,8 +151,6 @@
 void
 gs_imager_state_copied(gs_imager_state * pis)
 {
-    rc_increment(pis->opacity.mask);
-    rc_increment(pis->shape.mask);
     rc_increment(pis->halftone);
     rc_increment(pis->dev_ht);
     rc_increment(pis->cie_render);
@@ -192,8 +184,6 @@
     RCCOPY(cie_render);
     RCCOPY(dev_ht);
     RCCOPY(halftone);
-    RCCOPY(shape.mask);
-    RCCOPY(opacity.mask);
     RCCOPY(devicergb_cs);
     RCCOPY(devicecmyk_cs);
 #undef RCCOPY
@@ -226,8 +216,6 @@
     }
     RCDECR(dev_ht);
     RCDECR(halftone);
-    RCDECR(shape.mask);
-    RCDECR(opacity.mask);
     RCDECR(devicergb_cs);
     RCDECR(devicecmyk_cs);
 #undef RCDECR

Modified: branches/mtrender/src/gsmatrix.c
===================================================================
--- branches/mtrender/src/gsmatrix.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gsmatrix.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -110,7 +110,42 @@
     }
     return 0;
 }
+int
+gs_matrix_multiply_double(const gs_matrix_double * pm1, const gs_matrix * pm2, gs_matrix_double * pmr)
+{
+    double xx1 = pm1->xx, yy1 = pm1->yy;
+    double tx1 = pm1->tx, ty1 = pm1->ty;
+    double xx2 = pm2->xx, yy2 = pm2->yy;
+    double xy2 = pm2->xy, yx2 = pm2->yx;
 
+    if (is_xxyy(pm1)) {
+	pmr->tx = tx1 * xx2 + pm2->tx;
+	pmr->ty = ty1 * yy2 + pm2->ty;
+	if (is_fzero(xy2))
+	    pmr->xy = 0;
+	else
+	    pmr->xy = xx1 * xy2,
+		pmr->ty += tx1 * xy2;
+	pmr->xx = xx1 * xx2;
+	if (is_fzero(yx2))
+	    pmr->yx = 0;
+	else
+	    pmr->yx = yy1 * yx2,
+		pmr->tx += ty1 * yx2;
+	pmr->yy = yy1 * yy2;
+    } else {
+	double xy1 = pm1->xy, yx1 = pm1->yx;
+
+	pmr->xx = xx1 * xx2 + xy1 * yx2;
+	pmr->xy = xx1 * xy2 + xy1 * yy2;
+	pmr->yy = yx1 * xy2 + yy1 * yy2;
+	pmr->yx = yx1 * xx2 + yy1 * yx2;
+	pmr->tx = tx1 * xx2 + ty1 * yx2 + pm2->tx;
+	pmr->ty = tx1 * xy2 + ty1 * yy2 + pm2->ty;
+    }
+    return 0;
+}
+
 /* Invert a matrix.  Return gs_error_undefinedresult if not invertible. */
 int
 gs_matrix_invert(const gs_matrix * pm, gs_matrix * pmr)
@@ -143,7 +178,38 @@
     }
     return 0;
 }
+int
+gs_matrix_invert_to_double(const gs_matrix * pm, gs_matrix_double * pmr)
+{				/* We have to be careful about fetch/store order, */
+    /* because pm might be the same as pmr. */
+    if (is_xxyy(pm)) {
+	if (is_fzero(pm->xx) || is_fzero(pm->yy))
+	    return_error(gs_error_undefinedresult);
+	pmr->tx = -(pmr->xx = 1.0 / pm->xx) * pm->tx;
+	pmr->xy = 0.0;
+	pmr->yx = 0.0;
+	pmr->ty = -(pmr->yy = 1.0 / pm->yy) * pm->ty;
+    } else {
+	double mxx = pm->xx, myy = pm->yy, mxy = pm->xy, myx = pm->yx;
+        double mtx = pm->tx, mty = pm->ty;
+	double det = (mxx * myy) - (mxy * myx);
 
+        /*
+         * We are doing the math as floats instead of doubles to reproduce
+	 * the results in page 1 of CET 10-09.ps
+         */
+	if (det == 0)
+	    return_error(gs_error_undefinedresult);
+	pmr->xx = myy / det;
+	pmr->xy = -mxy / det;
+	pmr->yx = -myx / det;
+	pmr->yy = mxx / det;
+	pmr->tx = (((mty * myx) - (mtx * myy))) / det;
+	pmr->ty = (((mtx * mxy) - (mty * mxx))) / det;
+    }
+    return 0;
+}
+
 /* Translate a matrix, possibly in place. */
 int
 gs_matrix_translate(const gs_matrix * pm, floatp dx, floatp dy, gs_matrix * pmr)

Modified: branches/mtrender/src/gsmatrix.h
===================================================================
--- branches/mtrender/src/gsmatrix.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gsmatrix.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -26,11 +26,18 @@
 struct gs_matrix_s {
     _matrix_body;
 };
+struct gs_matrix_double_s {
+  double xx, xy, yx, yy, tx, ty;
+};
 
 #ifndef gs_matrix_DEFINED
 #  define gs_matrix_DEFINED
 typedef struct gs_matrix_s gs_matrix;
 #endif
+#ifndef gs_matrix_double_DEFINED
+#  define gs_matrix_double_DEFINED
+typedef struct gs_matrix_double_s gs_matrix_double;
+#endif
 
 /* Macro for initializing constant matrices */
 #define constant_matrix_body(xx, xy, yx, yy, tx, ty)\
@@ -54,7 +61,9 @@
 
 /* Matrix arithmetic */
 int gs_matrix_multiply(const gs_matrix *, const gs_matrix *, gs_matrix *),
+    gs_matrix_multiply_double(const gs_matrix_double *, const gs_matrix *, gs_matrix_double *),
     gs_matrix_invert(const gs_matrix *, gs_matrix *),
+    gs_matrix_invert_to_double(const gs_matrix *, gs_matrix_double *),
     gs_matrix_translate(const gs_matrix *, floatp, floatp, gs_matrix *),
     gs_matrix_scale(const gs_matrix *, floatp, floatp, gs_matrix *),
     gs_matrix_rotate(const gs_matrix *, floatp, gs_matrix *);

Modified: branches/mtrender/src/gstrans.c
===================================================================
--- branches/mtrender/src/gstrans.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gstrans.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -408,38 +408,6 @@
     return 0;
 }
 
-int
-gs_init_transparency_mask(gs_state *pgs,
-			  gs_transparency_channel_selector_t csel)
-{
-    gs_pdf14trans_params_t params = { 0 };
-
-    if_debug2('v', "[v](0x%lx)gs_init_transparency_mask(%d)\n", (ulong)pgs,
-	      (int)csel);
-
-    params.pdf14_op = PDF14_INIT_TRANS_MASK;
-    params.csel = csel;
-    return gs_state_update_pdf14trans(pgs, &params);
-}
-
-int
-gx_init_transparency_mask(gs_imager_state * pis,
-				const gs_pdf14trans_params_t * pparams)
-{
-    gs_transparency_source_t *ptm;
-
-    if_debug2('v', "[v](0x%lx)gx_init_transparency_mask(%d)\n", (ulong)pis,
-	      (int)pparams->csel);
-    switch (pparams->csel) {
-    case TRANSPARENCY_CHANNEL_Opacity: ptm = &pis->opacity; break;
-    case TRANSPARENCY_CHANNEL_Shape: ptm = &pis->shape; break;
-    default: return_error(gs_error_rangecheck);
-    }
-    rc_decrement_only(ptm->mask, "gs_init_transparency_mask");
-    ptm->mask = 0;
-    return 0;
-}
-
 /*
  * We really only care about the number of spot colors when we have
  * a device which supports spot colors.  With the other devices we use

Modified: branches/mtrender/src/gstrans.h
===================================================================
--- branches/mtrender/src/gstrans.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gstrans.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -29,7 +29,6 @@
     PDF14_POP_DEVICE,
     PDF14_BEGIN_TRANS_GROUP,
     PDF14_END_TRANS_GROUP,
-    PDF14_INIT_TRANS_MASK,
     PDF14_BEGIN_TRANS_MASK,
     PDF14_END_TRANS_MASK,
     PDF14_SET_BLEND_PARAMS
@@ -41,7 +40,6 @@
     "PDF14_POP_DEVICE       ",\
     "PDF14_BEGIN_TRANS_GROUP",\
     "PDF14_END_TRANS_GROUP  ",\
-    "PDF14_INIT_TRANS_MASK  ",\
     "PDF14_BEGIN_TRANS_MASK ",\
     "PDF14_END_TRANS_MASK   ",\
     "PDF14_SET_BLEND_PARAMS "\
@@ -60,7 +58,6 @@
 
 typedef struct gs_transparency_source_s {
     float alpha;		/* constant alpha */
-    gs_transparency_mask_t *mask;
 } gs_transparency_source_t;
 
 struct gs_pdf14trans_params_s {
@@ -155,9 +152,6 @@
 int gs_end_transparency_mask(gs_state *pgs,
 			     gs_transparency_channel_selector_t csel);
 
-int gs_init_transparency_mask(gs_state *pgs,
-			      gs_transparency_channel_selector_t csel);
-
 int gs_discard_transparency_layer(gs_state *pgs);
 
 /*
@@ -168,9 +162,6 @@
 
 int gx_end_transparency_group(gs_imager_state * pis, gx_device * pdev);
 
-int gx_init_transparency_mask(gs_imager_state * pis,
-				const gs_pdf14trans_params_t * pparams);
-
 int gx_begin_transparency_mask(gs_imager_state * pis, gx_device * pdev,
 				const gs_pdf14trans_params_t * pparams);
 

Modified: branches/mtrender/src/gxclist.c
===================================================================
--- branches/mtrender/src/gxclist.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxclist.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -355,7 +355,7 @@
     int code;
 
     /* Call create_buf_device to get the memory planarity set up. */
-    cdev->buf_procs.create_buf_device(&pbdev, target, NULL, NULL, clist_get_band_complexity(0, 0));
+    cdev->buf_procs.create_buf_device(&pbdev, target, 0, NULL, NULL, clist_get_band_complexity(0, 0));
     /* HACK - if the buffer device can't do copy_alpha, disallow */
     /* copy_alpha in the commmand list device as well. */
     if (dev_proc(pbdev, copy_alpha) == gx_no_copy_alpha)

Modified: branches/mtrender/src/gxclread.c
===================================================================
--- branches/mtrender/src/gxclread.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxclread.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -426,7 +426,7 @@
 
     clist_select_render_plane(dev, y, line_count, &render_plane, plane_index);
     code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
-				  &bdev, cdev->target, &render_plane,
+				  &bdev, cdev->target, y, &render_plane,
 				  dev->memory, clist_get_band_complexity(dev,y));
     if (code < 0)
 	return code;
@@ -464,7 +464,7 @@
 	uint raster = gx_device_raster(bdev, true);
 
 	code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
-				      &bdev, cdev->target, &render_plane,
+				      &bdev, cdev->target, y, &render_plane,
 				      dev->memory, clist_get_band_complexity(dev, y));
 	if (code < 0)
 	    return code;

Modified: branches/mtrender/src/gxclthrd1.c
===================================================================
--- branches/mtrender/src/gxclthrd1.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxclthrd1.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -142,8 +142,8 @@
 
 	/* create the buf device for this thread, and allocate the semaphores */
 	if ((code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
-				&(thread->bdev),
-				cdev->target, NULL,
+				&(thread->bdev), cdev->target,
+				band*crdev->page_band_height, NULL,
 				mem, clist_get_band_complexity(dev,y)) < 0)) 
 	    break;
 	if ((thread->sema_this = gx_semaphore_alloc(mem)) == NULL ||
@@ -425,7 +425,7 @@
 	goto free_thread_out;
     mdata = crdev->data + crdev->page_tile_cache_size;
     if ((code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
-				  &bdev, cdev->target, NULL,
+				  &bdev, cdev->target, y, NULL,
 				  mem, clist_get_band_complexity(dev,y))) < 0 ||
 	(code = crdev->buf_procs.setup_buf_device(bdev, mdata, raster, NULL,
 			    y - crdev->ymin, line_count, crdev->ymax - crdev->ymin)) < 0)
@@ -469,7 +469,7 @@
 	uint raster = gx_device_raster(bdev, true);
 
 	code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
-				      &bdev, cdev->target, NULL,
+				      &bdev, cdev->target, y, NULL,
 				      mem, clist_get_band_complexity(dev, y));
 	if (code < 0)
 	    return code;

Modified: branches/mtrender/src/gxdevbuf.h
===================================================================
--- branches/mtrender/src/gxdevbuf.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxdevbuf.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -71,7 +71,7 @@
      */
 
 #define dev_proc_create_buf_device(proc)\
-  int proc(gx_device **pbdev, gx_device *target,\
+  int proc(gx_device **pbdev, gx_device *target, int y,\
 	   const gx_render_plane_t *render_plane, gs_memory_t *mem,\
 	   gx_band_complexity_t *band_complexity)
 

Modified: branches/mtrender/src/gxdevmem.h
===================================================================
--- branches/mtrender/src/gxdevmem.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxdevmem.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -141,6 +141,7 @@
     gx_color_index save_color;	/* last (only) color displayed */
     /* Following are used only for planar devices. */
     int plane_depth;		/* if non-zero, depth of all planes */
+    int band_y; /* Debug purpose only. */
 };
 
 extern_st(st_device_memory);

Modified: branches/mtrender/src/gxfixed.h
===================================================================
--- branches/mtrender/src/gxfixed.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxfixed.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -76,6 +76,8 @@
 #define fixed2int_ceiling(x) ((int)_fixed_rshift((x)+_fixed_fraction_v))
 #define fixed_pre_pixround(x) ((x)+_fixed_pixround_v)
 #define fixed2int_pixround(x) fixed2int(fixed_pre_pixround(x))
+#define fixed2int_pixround_perfect(x) ((x) < 0 && ((x) & (fixed_1 - fixed_epsilon)) == fixed_half \
+	? (int)_fixed_rshift(x) + 1 : fixed2int_pixround(x))
 #define fixed_is_int(x) !((x)&_fixed_fraction_v)
 #if ARCH_INTS_ARE_SHORT & !ARCH_IS_BIG_ENDIAN
 /* Do some of the shifting and extraction ourselves. */

Modified: branches/mtrender/src/gxht.c
===================================================================
--- branches/mtrender/src/gxht.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxht.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -26,14 +26,6 @@
 #include "gzht.h"
 #include "gsserial.h"
 
-/* Define the sizes of the halftone cache. */
-#define max_cached_tiles_HUGE 5000	/* not used */
-#define max_ht_bits_HUGE 1000000	/* not used */
-#define max_cached_tiles_LARGE 577
-#define max_ht_bits_LARGE 100000
-#define max_cached_tiles_SMALL 25
-#define max_ht_bits_SMALL 1000
-
 /* Define the binary halftone device color type. */
 /* The type descriptor must be public for Pattern types. */
 gs_public_st_composite(st_dc_ht_binary, gx_device_color, "dc_ht_binary",
@@ -119,33 +111,25 @@
 uint
 gx_ht_cache_default_tiles(void)
 {
-#if arch_small_memory
-    return max_cached_tiles_SMALL;
-#else
-    return (gs_debug_c('.') ? max_cached_tiles_SMALL :
-	    max_cached_tiles_LARGE);
-#endif
+    return (gs_debug_c('.') ? max_ht_cached_tiles_SMALL :
+	    max_ht_cached_tiles);
 }
 uint
-gx_ht_cache_default_bits(void)
+gx_ht_cache_default_bits_size(void)
 {
-#if arch_small_memory
-    return max_ht_bits_SMALL;
-#else
-    return (gs_debug_c('.') ? max_ht_bits_SMALL :
-	    max_ht_bits_LARGE);
-#endif
+    return (gs_debug_c('.') ? max_ht_cache_bits_size_SMALL :
+	    max_ht_cache_bits_size);
 }
 
-/* Allocate a halftone cache. */
+/* Allocate a halftone cache. max_bits_size is number of bytes */
 gx_ht_cache *
-gx_ht_alloc_cache(gs_memory_t * mem, uint max_tiles, uint max_bits)
+gx_ht_alloc_cache(gs_memory_t * mem, uint max_tiles, uint max_bits_size)
 {
     gx_ht_cache *pcache =
     gs_alloc_struct(mem, gx_ht_cache, &st_ht_cache,
 		    "alloc_ht_cache(struct)");
     byte *tbits =
-	gs_alloc_bytes(mem, max_bits, "alloc_ht_cache(bits)");
+	gs_alloc_bytes(mem, max_bits_size, "alloc_ht_cache(bits)");
     gx_ht_tile *ht_tiles =
 	gs_alloc_struct_array(mem, max_tiles, gx_ht_tile, &st_ht_tiles,
 			      "alloc_ht_cache(ht_tiles)");
@@ -157,7 +141,7 @@
 	return 0;
     }
     pcache->bits = tbits;
-    pcache->bits_size = max_bits;
+    pcache->bits_size = max_bits_size;
     pcache->ht_tiles = ht_tiles;
     pcache->num_tiles = max_tiles;
     pcache->order.cache = pcache;
@@ -216,8 +200,13 @@
 {
     const gx_ht_order *porder = &pcache->order;
     int level = porder->levels[b_level];
-    gx_ht_tile *bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
+    gx_ht_tile *bt;
 
+    if (pcache->num_cached < porder->num_levels )
+	bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
+    else
+	bt =  &pcache->ht_tiles[b_level];	/* one tile per b_level */
+
     if (bt->level != level) {
 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
 
@@ -248,8 +237,13 @@
 {
     const gx_ht_order *porder = &pcache->order;
     int level = porder->levels[b_level];
-    gx_ht_tile *bt = &pcache->ht_tiles[level];
+    gx_ht_tile *bt;
 
+    if (pcache->num_cached < porder->num_levels )
+	bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
+    else
+	bt =  &pcache->ht_tiles[b_level];	/* one tile per b_level */
+
     if (bt->level != level) {
 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
 
@@ -317,8 +311,13 @@
     gx_ht_cache *pcache = porder->cache;
     int b_level = pdevc->colors.binary.b_level;
     int level = porder->levels[b_level];
-    gx_ht_tile *bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
+    gx_ht_tile *bt;
 
+    if (pcache->num_cached < porder->num_levels )
+	bt = &pcache->ht_tiles[level / pcache->levels_per_tile];
+    else
+	bt =  &pcache->ht_tiles[b_level];	/* one tile per b_level */
+
     if (bt->level != level) {
 	int code = render_ht(bt, level, porder, pcache->base_id + b_level);
 

Modified: branches/mtrender/src/gxidata.c
===================================================================
--- branches/mtrender/src/gxidata.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxidata.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -156,8 +156,8 @@
 			yn += adjust;
 			if (yn <= penum->clip_outer.p.y)
 			    goto mt;
-			penum->yci = fixed2int_pixround(yc);
-			penum->hci = fixed2int_pixround(yn) - penum->yci;
+			penum->yci = fixed2int_pixround_perfect(yc);
+			penum->hci = fixed2int_pixround_perfect(yn) - penum->yci;
 			if (penum->hci == 0)
 			    goto mt;
 			if_debug2('b', "[b]yci=%d, hci=%d\n",
@@ -181,8 +181,8 @@
 			xn += adjust;
 			if (xn <= penum->clip_outer.p.x)
 			    goto mt;
-			penum->xci = fixed2int_pixround(xc);
-			penum->wci = fixed2int_pixround(xn) - penum->xci;
+			penum->xci = fixed2int_pixround_perfect(xc);
+			penum->wci = fixed2int_pixround_perfect(xn) - penum->xci;
 			if (penum->wci == 0)
 			    goto mt;
 			if_debug2('b', "[b]xci=%d, wci=%d\n",

Modified: branches/mtrender/src/gximage.h
===================================================================
--- branches/mtrender/src/gximage.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gximage.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -254,6 +254,7 @@
 				/* (landscape only) */
     gs_int_point xyi;		/* integer origin of row */
 				/* (Interpolate only) */
+    int yi0;			/* integer y of entire image origin. */
     int yci, hci;		/* integer y & h of row (portrait) */
     int xci, wci;		/* integer x & w of row (landscape) */
     /* The maps are set at initialization.  We put them here */

Modified: branches/mtrender/src/gximono.c
===================================================================
--- branches/mtrender/src/gximono.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gximono.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -32,6 +32,7 @@
 #include "gxcpath.h"
 #include "gximage.h"
 #include "gzht.h"
+#include "vdtrace.h"
 
 /* ------ Strategy procedure ------ */
 
@@ -416,8 +417,10 @@
 	    dev_proc(dev, fill_rectangle);
 	int xmin = fixed2int_pixround(penum->clip_outer.p.x);
 	int xmax = fixed2int_pixround(penum->clip_outer.q.x);
+#define xl dda_current(next.x)
 
-#define xl dda_current(next.x)
+	if_debug2('b', "[b]image y=%d  dda.y.Q=%lg\n", penum->y + penum->rect.y, 
+		    penum->dda.row.y.state.Q / 256.);
 	/* Fold the adjustment into xrun and xl, */
 	/* including the +0.5-epsilon for rounding. */
 	xrun = xrun - xa + (fixed_half - fixed_epsilon);
@@ -495,7 +498,8 @@
 			    }
                             code = gx_fill_rectangle_device_rop(xi, yt, wi, iht,
                                                                  pdevc, dev, lop);
-
+			    vd_rect(int2fixed(xi), int2fixed(yt), int2fixed(xi + wi), int2fixed(yt + iht),
+				0, pdevc->colors.pure /* wrong with halftones */);
 		    }
 		    if (code < 0)
 			goto err;

Modified: branches/mtrender/src/gxipixel.c
===================================================================
--- branches/mtrender/src/gxipixel.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxipixel.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -191,7 +191,7 @@
     const int bps = pim->BitsPerComponent;
     bool masked = penum->masked;
     const float *decode = pim->Decode;
-    gs_matrix mat;
+    gs_matrix_double mat;
     int index_bps;
     const gs_color_space *pcs = pim->ColorSpace;
     gs_logical_operation_t lop = (pis ? pis->log_op : lop_default);
@@ -209,49 +209,23 @@
     penum->Height = height;
     if (pmat == 0)
 	pmat = &ctm_only(pis);
-    if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
-	(code = gs_matrix_multiply(&mat, pmat, &mat)) < 0
+    if ((code = gs_matrix_invert_to_double(&pim->ImageMatrix, &mat)) < 0 ||
+	(code = gs_matrix_multiply_double(&mat, pmat, &mat)) < 0
 	) {
 	gs_free_object(mem, penum, "gx_default_begin_image");
 	return code;
     }
-    penum->matrix = mat;
+    /*penum->matrix = mat;*/
+    penum->matrix.xx = mat.xx;
+    penum->matrix.xy = mat.xy;
+    penum->matrix.yx = mat.yx;
+    penum->matrix.yy = mat.yy;
+    penum->matrix.tx = mat.tx;
+    penum->matrix.ty = mat.ty;
     if_debug6('b', " [%g %g %g %g %g %g]\n",
 	      mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
     /* following works for 1, 2, 4, 8, 12, 16 */
     index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
-#if 0 /* replaced due to inaccurate precision, bug 687345 , text -r300 455690-1.pdf . */
-    mtx = float2fixed(mat.tx);
-    mty = float2fixed(mat.ty);
-    row_extent.x = float2fixed(width * mat.xx + mat.tx) - mtx;
-    row_extent.y =
-	(is_fzero(mat.xy) ? fixed_0 :
-	 float2fixed(width * mat.xy + mat.ty) - mty);
-    col_extent.x =
-	(is_fzero(mat.yx) ? fixed_0 :
-	 float2fixed(height * mat.yx + mat.tx) - mtx);
-    col_extent.y = float2fixed(height * mat.yy + mat.ty) - mty;
-    gx_image_enum_common_init((gx_image_enum_common_t *)penum,
-			      (const gs_data_image_t *)pim,
-			      &image1_enum_procs, dev,
-			      (masked ? 1 : (penum->alpha ? cs_num_components(pcs)+1 : cs_num_components(pcs))),
-			      format);
-    if (penum->rect.w == width && penum->rect.h == height) {
-	x_extent = row_extent;
-	y_extent = col_extent;
-    } else {
-	int rw = penum->rect.w, rh = penum->rect.h;
-
-	x_extent.x = float2fixed(rw * mat.xx + mat.tx) - mtx;
-	x_extent.y =
-	    (is_fzero(mat.xy) ? fixed_0 :
-	     float2fixed(rw * mat.xy + mat.ty) - mty);
-	y_extent.x =
-	    (is_fzero(mat.yx) ? fixed_0 :
-	     float2fixed(rh * mat.yx + mat.tx) - mtx);
-	y_extent.y = float2fixed(rh * mat.yy + mat.ty) - mty;
-    }
-#else
     /* 
      * Compute extents with distance transformation.
      */
@@ -298,7 +272,6 @@
 	     float2fixed_rounded(rh * mat.yx));
 	y_extent.y = float2fixed_rounded(rh * mat.yy);
     }
-#endif
     if (masked) {	/* This is imagemask. */
 	if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) {
 	    gs_free_object(mem, penum, "gx_default_begin_image");
@@ -551,9 +524,14 @@
 	dda_init(penum->dda.row.y, mty, col_extent.y, height);
 	penum->dst_width = row_extent.x;
 	penum->dst_height = col_extent.y;
+	penum->yi0 = fixed2int_pixround_perfect(dda_current(penum->dda.row.y)); /* For gs_image_class_0_interpolate. */
 	if (penum->rect.y) {
-	    dda_advance(penum->dda.row.x, penum->rect.y);
-	    dda_advance(penum->dda.row.y, penum->rect.y);
+	    int y = penum->rect.y;
+
+	    while (y--) {
+		dda_next(penum->dda.row.x);
+		dda_next(penum->dda.row.y);
+	    }
 	}
 	penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
 	penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);

Modified: branches/mtrender/src/gxiscale.c
===================================================================
--- branches/mtrender/src/gxiscale.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxiscale.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -16,6 +16,7 @@
 #include "gx.h"
 #include "math_.h"
 #include "memory_.h"
+#include "stdint_.h"
 #include "gpcheck.h"
 #include "gserrors.h"
 #include "gxfixed.h"
@@ -101,12 +102,17 @@
     iss.BitsPerComponentOut = sizeof(frac) * 8;
     iss.MaxValueOut = frac_1;
     iss.WidthOut = (int)ceil(fabs(dst_xy.x));
-    iss.HeightOut = (int)ceil(fabs(dst_xy.y));
+    iss.HeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rect.y + penum->rect.h) * 
+						penum->dst_height / penum->Height))
+	- fixed2int_pixround_perfect((fixed)((int64_t)penum->rect.y * penum->dst_height / penum->Height));
+    iss.HeightOut = any_abs(iss.HeightOut);
     iss.WidthIn = penum->rect.w;
     iss.HeightIn = penum->rect.h;
-    iss.xscale = any_abs((float)penum->dst_width / penum->Width / fixed_1);
-    iss.yscale = any_abs((float)penum->dst_height / penum->Height / fixed_1);
-    iss.dst_y_offset = penum->rect.y * iss.yscale;
+    iss.src_y_offset = penum->rect.y;
+    iss.EntireWidthIn = penum->Width;
+    iss.EntireHeightIn = penum->Height;
+    iss.EntireWidthOut = fixed2int_pixround(any_abs(penum->dst_width));
+    iss.EntireHeightOut = fixed2int_pixround(any_abs(penum->dst_height));
     pccs = cs_concrete_space(pcs, pis);
     iss.Colors = cs_num_components(pccs);
     if (penum->bps <= 8 && penum->device_color) {
@@ -182,7 +188,9 @@
 	    dda_advance(x0, penum->rect.w);
 	penum->xyi.x = fixed2int_pixround(dda_current(x0));
     }
-    penum->xyi.y = fixed2int_pixround(dda_current(penum->dda.pixel0.y));
+    penum->xyi.y = penum->yi0 + fixed2int_pixround_perfect((fixed)((int64_t)penum->rect.y 
+				    * penum->dst_height / penum->Height))
+		* (penum->matrix.yy > 0 ? 1 : -1);
     if_debug0('b', "[b]render=interpolate\n");
     return &image_render_interpolate;
 }
@@ -341,6 +349,7 @@
 			    case 3:
 				do {
 				    LINE_ACCUM(color, bpp);
+				    vd_pixel(int2fixed(x), int2fixed(ry), color);
 				    x++, psrc += 3;
 				} while (x < xe && psrc[-4] == psrc[0] &&
 				     psrc[-3] == psrc[1] && psrc[-2] == psrc[2] &&
@@ -372,6 +381,7 @@
 		    }
 		}
 		LINE_ACCUM_COPY(dev, out, bpp, xo, x, raster, ry);
+		/*if_debug1('w', "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */
 		penum->line_xy++;
 		if_debug0('B', "\n");
 	    }

Modified: branches/mtrender/src/gxistate.h
===================================================================
--- branches/mtrender/src/gxistate.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gxistate.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -246,7 +246,7 @@
 	  (*get_cmap_procs)(const gs_imager_state *, const gx_device *);\
 	gs_color_rendering_state_common
 #define st_imager_state_num_ptrs\
-  (st_line_params_num_ptrs + st_cr_state_num_ptrs + 4)
+  (st_line_params_num_ptrs + st_cr_state_num_ptrs + 2)
 /* Access macros */
 #define ctm_only(pis) (*(const gs_matrix *)&(pis)->ctm)
 #define ctm_only_writable(pis) (*(gs_matrix *)&(pis)->ctm)
@@ -272,7 +272,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, 0 }, { 1.0, 0 }, 0, 0/*false*/, 0, 0, 0/*false*/, 0, 0, 1.0,  \
+  { 1.0 }, { 1.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: branches/mtrender/src/gzht.h
===================================================================
--- branches/mtrender/src/gzht.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/gzht.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -125,21 +125,18 @@
 };
 
 /* Define the sizes of the halftone cache. */
-#define max_cached_tiles_HUGE 5000	/* not used */
-#define max_ht_bits_HUGE 1000000	/* not used */
-#define max_cached_tiles_LARGE 577
-#define max_ht_bits_LARGE 100000
-#define max_cached_tiles_SMALL 25
-#define max_ht_bits_SMALL 1000
+#define max_ht_cached_tiles_LARGE 8192
+#define max_ht_cache_bits_size_LARGE (1024*1024) /* enough for 256 levels 167x167 */
+					   /* see ht_stocht.ps */
+#define max_ht_cached_tiles_SMALL 256
+#define max_ht_cache_bits_size_SMALL 8192	/* enough for 256 levels 8x8 */
 
-/* Define the size of the halftone tile cache. */
-#define max_tile_bytes_LARGE 65536
-#define max_tile_bytes_SMALL 512
 #if arch_small_memory
-#  define max_tile_cache_bytes max_tile_bytes_SMALL
+#  define max_ht_cached_tiles max_ht_cached_tiles_SMALL
+#  define max_ht_cache_bits_size max_ht_cache_bits_size_SMALL
 #else
-#  define max_tile_cache_bytes\
-     (gs_debug_c('.') ? max_tile_bytes_SMALL : max_tile_bytes_LARGE)
+#  define max_ht_cached_tiles max_ht_cached_tiles_LARGE
+#  define max_ht_cache_bits_size max_ht_cache_bits_size_LARGE
 #endif
 
 /* We don't mark from the tiles pointer, and we relocate the tiles en masse. */
@@ -164,7 +161,7 @@
 
 /* Allocate/free a halftone cache. */
 uint gx_ht_cache_default_tiles(void);
-uint gx_ht_cache_default_bits(void);
+uint gx_ht_cache_default_bits_size(void); /* returns size in bytes of 'bits' area */
 gx_ht_cache *gx_ht_alloc_cache(gs_memory_t *, uint, uint);
 void gx_ht_free_cache(gs_memory_t *, gx_ht_cache *);
 

Modified: branches/mtrender/src/lib.mak
===================================================================
--- branches/mtrender/src/lib.mak	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/lib.mak	2008-02-28 17:05:14 UTC (rev 8558)
@@ -430,7 +430,7 @@
 gxcmap_h=$(GLSRC)gxcmap.h $(gscsel_h) $(gxcindex_h) $(gxcvalue_h) $(gxfmap_h)
 gxistate_h=$(GLSRC)gxistate.h\
  $(gscsel_h) $(gsrefct_h) $(gsropt_h) $(gstparam_h) $(gxcvalue_h) $(gxcmap_h)\
- $(gxfixed_h) $(gxline_h) $(gxmatrix_h) $(gxtmap_h) $(gscspace_h) $(gsnamecl_h)
+ $(gxfixed_h) $(gxline_h) $(gxmatrix_h) $(gxtmap_h) $(gscspace_h) $(gstrans_h) $(gsnamecl_h)
 gxclist_h=$(GLSRC)gxclist.h $(gscspace_h)\
  $(gxband_h) $(gxbcache_h) $(gxclio_h) $(gxdevbuf_h) $(gxistate_h)\
  $(gxrplane_h)
@@ -660,7 +660,7 @@
  $(gdevmem_h) $(gsccolor_h) $(gspaint_h) $(gsutil_h)\
  $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\
  $(gxdevmem_h) $(gxfixed_h) $(gximage_h) $(gxistate_h) $(gxmatrix_h)\
- $(gzht_h)
+ $(gzht_h) $(vdtrace_h)
 	$(GLCC) $(GLO_)gximono.$(OBJ) $(C_) $(GLSRC)gximono.c
 
 $(GLOBJ)gximask.$(OBJ) : $(GLSRC)gximask.c $(GXERR) $(memory__h) $(gserrors_h)\
@@ -843,7 +843,8 @@
 
 $(GLOBJ)gsimage.$(OBJ) : $(GLSRC)gsimage.c $(GXERR) $(memory__h) $(math__h)\
  $(gscspace_h) $(gsimage_h) $(gsmatrix_h) $(gsstruct_h) $(gsptype2_h)\
- $(gxarith_h) $(gxdevice_h) $(gxiparam_h) $(gxpath_h) $(gximask_h) $(gzstate_h)
+ $(gxarith_h) $(gxdevice_h) $(gxiparam_h) $(gxpath_h) $(gximask_h) $(gzstate_h)\
+ $(vdtrace_h)
 	$(GLCC) $(GLO_)gsimage.$(OBJ) $(C_) $(GLSRC)gsimage.c
 
 $(GLOBJ)gsimpath.$(OBJ) : $(GLSRC)gsimpath.c $(GXERR)\
@@ -1194,10 +1195,16 @@
 # Currently only the high-level drivers use these, but more drivers will
 # probably use them eventually.
 
-sfile_=$(GLOBJ)sfx$(FILE_IMPLEMENTATION).$(OBJ) $(GLOBJ)stream.$(OBJ)
+sfile_=$(GLOBJ)sfx$(FILE_IMPLEMENTATION).$(OBJ) $(GLOBJ)sfxcommon.$(OBJ)\
+ $(GLOBJ)stream.$(OBJ)
+
 $(GLD)sfile.dev : $(LIB_MAK) $(ECHOGS_XE) $(sfile_)
 	$(SETMOD) $(GLD)sfile $(sfile_)
 
+$(GLOBJ)sfxcommon.$(OBJ) : $(GLSRC)sfxcommon.c $(AK) $(stdio__h) $(memory__h)\
+ $(unistd__h) $(gsmemory_h) $(gp_h) $(stream_h) $(gserror_h) $(gserrors_h)
+	$(GLCC) $(GLO_)sfxcommon.$(OBJ) $(C_) $(GLSRC)sfxcommon.c
+
 $(GLOBJ)sfxstdio.$(OBJ) : $(GLSRC)sfxstdio.c $(AK) $(stdio__h) $(memory__h)\
  $(unistd__h) $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h)
 	$(GLCC) $(GLO_)sfxstdio.$(OBJ) $(C_) $(GLSRC)sfxstdio.c

Modified: branches/mtrender/src/sfxstdio.c
===================================================================
--- branches/mtrender/src/sfxstdio.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/sfxstdio.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -43,169 +43,6 @@
 
 /* ------ File reading ------ */
 
-#define DEFAULT_BUFFER_SIZE 2048
-const uint file_default_buffer_size = DEFAULT_BUFFER_SIZE;
-
-/* Prepare a stream with a file name. */
-/* Return 0 if successful, error code if not. */
-/* On a successful return, the C file name is in the stream buffer. */
-/* If fname==0, set up stream, and buffer. */
-int
-file_prepare_stream(const char *fname, uint len, const char *file_access, 
-		 uint buffer_size, stream ** ps, char fmode[4], gs_memory_t *mem)
-{
-    byte *buffer;
-    register stream *s;
-
-    /* Open the file, always in binary mode. */
-    strcpy(fmode, file_access);
-    strcat(fmode, gp_fmode_binary_suffix);
-    if (buffer_size == 0)
-	buffer_size = file_default_buffer_size;
-    if (len >= buffer_size)    /* we copy the file name into the buffer */
-	return_error(gs_error_limitcheck);
-    /* Allocate the stream first, since it persists */
-    /* even after the file has been closed. */
-    s = file_alloc_stream(mem, "file_prepare_stream");
-    if (s == 0)
-	return_error(gs_error_VMerror);
-    /* Allocate the buffer. */
-    buffer = gs_alloc_bytes(mem, buffer_size, "file_prepare_stream(buffer)");
-    if (buffer == 0)
-	return_error(gs_error_VMerror);
-    if (fname != 0) {
-	memcpy(buffer, fname, len);
-	buffer[len] = 0;	/* terminate string */
-    } else
-	buffer[0] = 0;	/* safety */
-    s->cbuf = buffer;
-    s->bsize = s->cbsize = buffer_size;
-    *ps = s;
-    return 0;
-}
-
-/*
- * Set up a file stream on an OS file.  The caller has allocated the
- * stream and buffer.
- */
-void
-file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer,
-		 uint buffer_size)
-{
-    switch (fmode[0]) {
-    case 'a':
-	sappend_file(s, file, buffer, buffer_size);
-	break;
-    case 'r':
-	/* Defeat buffering for terminals. */
-	{
-	    struct stat rstat;
-
-	    fstat(fileno(file), &rstat);
-	    sread_file(s, file, buffer,
-		       (S_ISCHR(rstat.st_mode) ? 1 : buffer_size));
-	}
-	break;
-    case 'w':
-	swrite_file(s, file, buffer, buffer_size);
-    }
-    if (fmode[1] == '+')
-	s->file_modes |= s_mode_read | s_mode_write;
-    s->save_close = s->procs.close;
-    s->procs.close = file_close_file;
-}
-
-/* Open a file stream, optionally on an OS file. */
-/* Return 0 if successful, error code if not. */
-/* On a successful return, the C file name is in the stream buffer. */
-/* If fname==0, set up the file entry, stream, and buffer, */
-/* but don't open an OS file or initialize the stream. */
-int
-file_open_stream(const char *fname, uint len, const char *file_access,
-		 uint buffer_size, stream ** ps, gx_io_device *iodev,
-		 iodev_proc_fopen_t fopen_proc, gs_memory_t *mem)
-{
-    int code;
-    FILE *file;
-    char fmode[4];  /* r/w/a, [+], [b], null */
-
-    if (!iodev)
-	iodev = iodev_default;
-    code = file_prepare_stream(fname, len, file_access, buffer_size, ps, fmode, mem);
-    if (code < 0)
-	return code;
-    if (fname == 0)
-	return 0;
-    if (fname[0] == 0)		/* fopen_proc gets NUL terminated string, not len */
-	return 0;		/* so this is the same as len == 0, so return NULL */
-    code = (*fopen_proc)(iodev, (char *)(*ps)->cbuf, fmode, &file,
-			 (char *)(*ps)->cbuf, (*ps)->bsize);
-    if (code < 0)
-	return code;
-    file_init_stream(*ps, file, fmode, (*ps)->cbuf, (*ps)->bsize);
-    return 0;
-}
-
-/* Allocate and return a file stream. */
-/* Return 0 if the allocation failed. */
-/* The stream is initialized to an invalid state, so the caller need not */
-/* worry about cleaning up if a later step in opening the stream fails. */
-stream *
-file_alloc_stream(gs_memory_t * mem, client_name_t cname)
-{
-    stream *s;
-    s = s_alloc(mem, cname);
-    if (s == 0)
-	return 0;
-    s_init_ids(s);
-    s->is_temp = 0;		/* not a temp stream */
-    s->foreign = 0;
-    /*
-     * Disable the stream now (in case we can't open the file,
-     * or a filter init procedure fails) so that `restore' won't
-     * crash when it tries to close open files.
-     */
-    s_disable(s);
-    s->prev = 0;
-    s->next = 0;
-    return s;
-}
-
-/* Close a file stream.  This replaces the close procedure in the stream */
-/* for normal (OS) files and for filters. */
-int
-file_close_file(stream * s)
-{
-    stream *stemp = s->strm;
-    gs_memory_t *mem;
-    int code = file_close_disable(s);
-
-    if (code)
-	return code;
-    /*
-     * Check for temporary streams created for filters.
-     * There may be more than one in the case of a procedure-based filter,
-     * or if we created an intermediate stream to ensure
-     * a large enough buffer.  Note that these streams may have been
-     * allocated by file_alloc_stream, so we mustn't free them.
-     */
-    while (stemp != 0 && stemp->is_temp != 0) {
-	stream *snext = stemp->strm;
-
-	mem = stemp->memory;
-	if (stemp->is_temp > 1)
-	    gs_free_object(mem, stemp->cbuf,
-			   "file_close(temp stream buffer)");
-	s_disable(stemp);
-	stemp = snext;
-    }
-    mem = s->memory;
-    gs_free_object(mem, s->cbuf, "file_close(buffer)");
-    if (s->close_strm && stemp != 0)
-	return sclose(stemp);
-    return 0;
-}
-
 /* Initialize a stream for reading an OS file. */
 void
 sread_file(register stream * s, FILE * file, byte * buf, uint len)

Modified: branches/mtrender/src/siscale.c
===================================================================
--- branches/mtrender/src/siscale.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/siscale.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -16,6 +16,7 @@
 #include "math_.h"
 #include "memory_.h"
 #include "stdio_.h"
+#include "stdint_.h"
 #include "gdebug.h"
 #include "strimpl.h"
 #include "siscale.h"
@@ -68,7 +69,6 @@
     /* The init procedure sets the following. */
     int sizeofPixelIn;		/* bytes per input value, 1 or 2 */
     int sizeofPixelOut;		/* bytes per output value, 1 or 2 */
-    double xscale, yscale;
     void /*PixelIn */ *src;
     void /*PixelOut */ *dst;
     PixelTmp *tmp;
@@ -78,7 +78,7 @@
     int src_y;
     uint src_offset, src_size;
     int dst_y;
-    float dst_y_offset;
+    int src_y_offset;
     uint dst_offset, dst_size;
     CLIST dst_next_list;	/* for next output value */
     int dst_last_index;		/* highest index used in list */
@@ -161,8 +161,12 @@
 		     double scale,
 	/* Start generating weights for input pixel 'starting_output_index'. */
 		     int starting_output_index,
-	/* Offset of output pixel from the output image start. */
-		     float dst_offset,
+	/* Offset of input subimage from the input image start. */
+		     int src_y_offset,
+	/* Entire output image size. */
+		     int dst_size,
+	/* Entire input image size. */
+		     int src_size,
 	/* Generate 'size' weight lists. */
 		     int size,
 	/* Limit pixel indices to 'limit', for clamping at the edges */
@@ -199,45 +203,34 @@
     npixels = (int)(WidthIn * 2 + 1);
 
     for (i = 0; i < size; ++i) {
-#if 0
-	double center = (starting_output_index + i) / scale;
-	int left = (int)ceil(center - WidthIn);
-	int right = (int)floor(center + WidthIn);
-
-	/*
-	 * In pathological cases, the limit may be much less
-	 * than the support.  We do need to deal with this.
+	/* Here we need :
+	   double scale = (double)dst_size / src_size;
+	   float dst_offset_fraction = floor(dst_offset) - dst_offset;
+	   double center = (starting_output_index  + i + dst_offset_fraction + 0.5) / scale - 0.5;
+	   int left = (int)ceil(center - WidthIn);
+	   int right = (int)floor(center + WidthIn);
+	   We can't compute 'right' in floats because float arithmetics is not associative.
+	   In older versions tt caused a 1 pixel bias of image bands due to 
+	   rounding direction appears to depend on src_y_offset. So compute in rationals.
+	   Since pixel center fall to half integers, we subtract 0.5 
+	   in the image space and add 0.5 in the device space.
 	 */
-#define clamp_pixel(j)\
-  (j < 0 ? (-j >= limit ? limit - 1 : -j) :\
-   j >= limit ? (j >> 1 >= limit ? 0 : (limit - j) + limit - 1) :\
-   j)
-	int lmin =
-	(left < 0 ? 0 : left);
-	int lmax =
-	(left < 0 ? (-left >= limit ? limit - 1 : -left) : left);
-	int rmin =
-	(right >= limit ?
-	 (right >> 1 >= limit ? 0 : (limit - right) + limit - 1) :
-	 right);
-	int rmax =
-	(right >= limit ? limit - 1 : right);
-	int first_pixel = min(lmin, rmin);
-	int last_pixel = max(lmax, rmax);
-#else
-	float dst_offset_fraction = ceil(dst_offset) - dst_offset; /* Compensate 
-				rounding for penum->xyi.y in gs_image_class_0_interpolate. */
-	double center = (starting_output_index  + i + dst_offset_fraction) / scale - 0.5;
-	int left = (int)ceil(center - WidthIn);
-	int right = (int)floor(center + WidthIn);
+	int dst_y_offset_fraction_num = (int)((int64_t)src_y_offset * dst_size % src_size) * 2 <= src_size
+			? -(int)((int64_t)src_y_offset * dst_size % src_size)
+			: src_size - (int)((int64_t)src_y_offset * dst_size % src_size);
+	int center_denom = dst_size * 2; 
+	int64_t center_num = /* center * center_denom * 2 = */ 
+	    (starting_output_index  + i) * src_size * 2 + src_size + dst_y_offset_fraction_num * 2 - dst_size;
+	int left = (int)ceil((center_num - WidthIn * center_denom) / center_denom);
+	int right = (int)floor((center_num + WidthIn * center_denom) / center_denom);
+	double center = (double)center_num / center_denom;
 #define clamp_pixel(j) (j < 0 ? 0 : j >= limit ? limit - 1 : j)
 	int first_pixel = clamp_pixel(left);
 	int last_pixel = clamp_pixel(right);
-#endif
 	CONTRIB *p;
 
-	if_debug4('W', "[W]i=%d, i+offset=%g scale=%lg center=%lg : ", starting_output_index + i, 
-		starting_output_index + i + dst_offset, scale, center);
+	if_debug4('w', "[w]i=%d, i+offset=%lg scale=%lg center=%lg : ", starting_output_index + i, 
+		starting_output_index + i + (double)src_y_offset / src_size * dst_size, scale, center);
 	if (last_pixel > last_index)
 	    last_index = last_pixel;
 	contrib[i].first_pixel = (first_pixel % modulus) * stride;
@@ -257,7 +250,7 @@
 
                 p[k].weight +=
 		    (PixelWeight) (weight * scaled_factor);
-		if_debug2('W', " %d %f", k, (float)p[k].weight);
+		if_debug2('w', " %d %f", k, (float)p[k].weight);
 	    }
 
 	} else {
@@ -271,10 +264,10 @@
 
 		p[k].weight +=
 		    (PixelWeight) (weight * scaled_factor);
-		if_debug2('W', " %d %f", k, (float)p[k].weight);
+		if_debug2('w', " %d %f", k, (float)p[k].weight);
 	    }
 	}
-	if_debug0('W', "\n");
+	if_debug0('w', "\n");
     }
     return last_index;
 }
@@ -383,7 +376,21 @@
     if (sizeofPixelOut == 1) {
 	zoom_y_loop(byte)
     } else {			/* sizeofPixelOut == 2 */
-	zoom_y_loop(bits16)
+	//zoom_y_loop(bits16)
+	for ( kc = 0; kc < kn; ++kc ) {
+		AccumTmp weight = 0;
+		{ const PixelTmp *pp = &tmp[kc + first_pixel];
+		  int j = cn;
+		  const CONTRIB *cp = cbp;
+		  for ( ; j > 0; pp += kn, ++cp, --j )
+		    weight += *pp * cp->weight;
+		}
+		{ PixelTmp2 pixel = unscale_AccumTmp(weight, fraction_bits);
+		  if_debug1('W', " %lx", (long)pixel);
+		  ((bits16 *)dst)[kc] =
+		    (bits16)CLAMP(pixel, 0, max_weight);
+		}
+	}
     }
     if_debug0('W', "\n");
 }
@@ -402,12 +409,14 @@
 {
     uint row_size = ss->params.WidthOut * ss->params.Colors;
     int last_index =
-    calculate_contrib(&ss->dst_next_list, ss->dst_items, ss->yscale,
-		      y, ss->dst_y_offset, 1, ss->params.HeightIn, MAX_ISCALE_SUPPORT, row_size,
+    calculate_contrib(&ss->dst_next_list, ss->dst_items, 
+		      (double)ss->params.EntireHeightOut / ss->params.EntireHeightIn,
+		      y, ss->src_y_offset, ss->params.EntireHeightOut, ss->params.EntireHeightIn, 
+		      1, ss->params.HeightIn, MAX_ISCALE_SUPPORT, row_size,
 		      (double)ss->params.MaxValueOut / (fixedScaleFactor * unitPixelTmp) );
     int first_index_mod = ss->dst_next_list.first_pixel / row_size;
 
-    if_debug2('w', "[w]calculate_dst_contrib for y = %d, y+offset=%d\n", y, y + ss->dst_y_offset);
+    if_debug2('w', "[W]calculate_dst_contrib for y = %d, y+offset=%d\n", y, y + ss->src_y_offset);
     ss->dst_last_index = last_index;
     last_index %= MAX_ISCALE_SUPPORT;
     if (last_index < first_index_mod) {		/* Shuffle the indices to account for wraparound. */
@@ -427,7 +436,7 @@
 	ss->dst_next_list.n = MAX_ISCALE_SUPPORT;
 	ss->dst_next_list.first_pixel = 0;
     }
-    if_debug0('w', "\n");
+    if_debug0('W', "\n");
 }
 
 /* Set default parameter values (actually, just clear pointers). */
@@ -452,14 +461,12 @@
 
     ss->sizeofPixelIn = ss->params.BitsPerComponentIn / 8;
     ss->sizeofPixelOut = ss->params.BitsPerComponentOut / 8;
-    ss->xscale = ss->params.xscale;
-    ss->yscale = ss->params.yscale;
 
     ss->src_y = 0;
     ss->src_size = ss->params.WidthIn * ss->sizeofPixelIn * ss->params.Colors;
     ss->src_offset = 0;
     ss->dst_y = 0;
-    ss->dst_y_offset = ss->params.dst_y_offset;
+    ss->src_y_offset = ss->params.src_y_offset;
     ss->dst_size = ss->params.WidthOut * ss->sizeofPixelOut * ss->params.Colors;
     ss->dst_offset = 0;
 
@@ -472,7 +479,8 @@
 					   max(ss->params.WidthOut, ss->params.HeightOut),
 				      sizeof(CLIST), "image_scale contrib");
     ss->items = (CONTRIB *) gs_alloc_byte_array(mem,
-				  contrib_pixels(ss->xscale) * ss->params.WidthOut,
+				  contrib_pixels((double)ss->params.EntireWidthOut / 
+					ss->params.EntireWidthIn) * ss->params.WidthOut,
 				 sizeof(CONTRIB), "image_scale contrib[*]");
     /* Allocate buffers for 1 row of source and destination. */
     ss->dst = gs_alloc_byte_array(mem, ss->params.WidthOut * ss->params.Colors,
@@ -487,8 +495,10 @@
 /****** WRONG ******/
     }
     /* Pre-calculate filter contributions for a row. */
-    calculate_contrib(ss->contrib, ss->items, ss->xscale,
-		      0, 0, ss->params.WidthOut, ss->params.WidthIn, ss->params.WidthIn,
+    calculate_contrib(ss->contrib, ss->items,
+		      (double)ss->params.EntireWidthOut / ss->params.EntireWidthIn,
+		      0, 0, ss->params.WidthOut, ss->params.WidthIn, 
+		      ss->params.WidthOut, ss->params.WidthIn, ss->params.WidthIn,
 		      ss->params.Colors, (double)unitPixelTmp * fixedScaleFactor / ss->params.MaxValueIn);
 
     /* Prepare the weights for the first output row. */
@@ -532,7 +542,8 @@
 	    /* inter-assigned freely, but not compared! */
 	    if ((void *)row != ss->dst)		/* no buffering */
 		goto adv;
-	} {			/* We're delivering a buffered output row. */
+	} 
+	{			/* We're delivering a buffered output row. */
 	    uint wcount = ss->dst_size - ss->dst_offset;
 	    uint ncopy = min(wleft, wcount);
 
@@ -544,7 +555,7 @@
 	    ss->dst_offset = 0;
 	}
 	/* Advance to the next output row. */
-      adv:++(ss->dst_y);
+      adv:++ss->dst_y;
 	if (ss->dst_y != ss->params.HeightOut)
 	    calculate_dst_contrib(ss, ss->dst_y);
     }

Modified: branches/mtrender/src/sisparam.h
===================================================================
--- branches/mtrender/src/sisparam.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/sisparam.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -56,9 +56,11 @@
 				/* 0 < MaxValueOut < 1 << BitsPerComponentOut*/
     int WidthOut, HeightOut;	/* > 0 */
     bool ColorPolarityAdditive;	/* needed by SpecialDownScale filter */
-    double xscale;		/* X scaling factor when the image covers fractional pixels. */
-    double yscale;		/* Y scaling factor when the image covers fractional pixels. */
-    float dst_y_offset;		/* Offset of the subimage due to grid fitting. */
+    int src_y_offset;		/* Offset of the subimage in the source image. */
+    int EntireWidthIn;		/* Height of entire input image. */
+    int EntireHeightIn;		/* Height of entire input image. */
+    int EntireWidthOut;		/* Height of entire output image. */
+    int EntireHeightOut;	/* Height of entire output image. */
 } stream_image_scale_params_t;
 
 /* Define a generic image scaling stream state. */

Modified: branches/mtrender/src/spprint.c
===================================================================
--- branches/mtrender/src/spprint.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/spprint.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -107,17 +107,25 @@
 pprintg1(stream * s, const char *format, floatp v)
 {
     const char *fp = pprintf_scan(s, format);
-    char str[150];
+    char dot, str[150];
 
 #ifdef DEBUG
     if (*fp == 0 || fp[1] != 'g')	/* shouldn't happen! */
 	lprintf1("Bad format in pprintg: %s\n", format);
 #endif
+    sprintf(str, "%f", 1.5);
+    dot = str[1]; /* locale-dependent */
     sprintf(str, "%g", v);
     if (strchr(str, 'e')) {
 	/* Bad news.  Try again using f-format. */
 	sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v);
     }
+    /* Juggling locales isn't thread-safe. Posix me harder. */
+    if (dot != '.') {
+        char *pdot = strchr(str, dot); 
+        if (pdot)
+            *pdot = '.';
+    }
     pputs_short(s, str);
     return pprintf_scan(s, fp + 2);
 }

Modified: branches/mtrender/src/stdint_.h
===================================================================
--- branches/mtrender/src/stdint_.h	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/stdint_.h	2008-02-28 17:05:14 UTC (rev 8558)
@@ -60,6 +60,13 @@
 # elif defined(__VMS) /* OpenVMS provides these types in inttypes.h */
 #  include <inttypes.h>
 #  define STDINT_TYPES_DEFINED
+# elif defined(__CYGWIN__)
+#  include <sys/types.h>  /* Old Cygwin has some of C99 types here. */
+   typedef unsigned char uint8_t;
+   typedef unsigned short uint16_t;
+   typedef unsigned int uint32_t;
+   typedef unsigned long long uint64_t;
+#  define STDINT_TYPES_DEFINED
 # endif
    /* other archs may want to add defines here, 
       or use the fallbacks in std.h */

Modified: branches/mtrender/src/zdouble.c
===================================================================
--- branches/mtrender/src/zdouble.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/zdouble.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -310,7 +310,7 @@
     os_ptr op = osp;
     int code = double_params_result(op, 0, NULL);
     double num;
-    char buf[MAX_CHARS + 2];
+    char dot, buf[MAX_CHARS + 2];
     char *str = buf;
     uint len;
     char end;
@@ -321,6 +321,8 @@
     len = r_size(op - 1);
     if (len > MAX_CHARS)
 	return_error(e_limitcheck);
+    sprintf(buf, "%f", 1.5);
+    dot = buf[1]; /* locale-dependent */
     memcpy(str, op[-1].value.bytes, len);
     /*
      * We check syntax in the following way: we remove whitespace,
@@ -336,6 +338,11 @@
     if (strspn(str, "0123456789+-.dDeE") != len)
 	return_error(e_syntaxerror);
     strcat(str, "$");
+    if (dot != '.') {
+        char *pdot = strchr(str, '.');
+        if (pdot)
+            *pdot = dot;
+    }
     if (sscanf(str, "%lf%c", &num, &end) != 2 || end != '$')
 	return_error(e_syntaxerror);
     return double_result(i_ctx_p, 1, num);
@@ -391,12 +398,14 @@
     os_ptr op = osp;
     double num;
     int code = double_params(op - 1, 1, &num);
-    char str[MAX_CHARS + 1];
+    char dot, str[MAX_CHARS + 1];
     int len;
 
     if (code < 0)
 	return code;
     check_write_type(*op, t_string);
+    sprintf(str, "%f", 1.5);
+    dot = buf[1]; /* locale-dependent */
     /*
      * To get fully accurate output results for IEEE double-
      * precision floats (53 bits of mantissa), the ANSI
@@ -417,6 +426,12 @@
     len = strlen(str);
     if (len > r_size(op))
 	return_error(e_rangecheck);
+    /* Juggling locales isn't thread-safe. Posix me harder. */
+    if (dot != '.') {
+        char *pdot = strchr(str, dot); 
+        if (pdot)
+            *pdot = '.';
+    }
     memcpy(op->value.bytes, str, len);
     op[-1] = *op;
     r_set_size(op - 1, len);

Modified: branches/mtrender/src/zfapi.c
===================================================================
--- branches/mtrender/src/zfapi.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/zfapi.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -562,16 +562,18 @@
 					ref *pdr, int char_code, const byte **ptr)
 {
     ref *GlyphDirectory, glyph0, *glyph = &glyph0, glyph_index;
-    if ((dict_find_string(pdr, "GlyphDirectory", &GlyphDirectory) > 0 &&
-         (r_type(GlyphDirectory) == t_dictionary &&
-          ( make_int(&glyph_index, char_code),
-            dict_find(GlyphDirectory, &glyph_index, &glyph) > 0))) ||
-        ((r_type(GlyphDirectory) == t_array &&
-          array_get(mem, GlyphDirectory, char_code, &glyph0) >= 0) &&
-         r_type(glyph) == t_string)) {
+    if (dict_find_string(pdr, "GlyphDirectory", &GlyphDirectory) > 0) {
+	if (((r_type(GlyphDirectory) == t_dictionary &&
+		(make_int(&glyph_index, char_code),
+		    dict_find(GlyphDirectory, &glyph_index, &glyph) > 0)) ||
+	     (r_type(GlyphDirectory) == t_array &&
+		array_get(mem, GlyphDirectory, char_code, &glyph0) >= 0)
+            )
+	    && r_type(glyph) == t_string) {
         *ptr = glyph->value.const_bytes;
 	return r_size(glyph);
     }
+    }
     return -1;
 }
 

Modified: branches/mtrender/src/ztrans.c
===================================================================
--- branches/mtrender/src/ztrans.c	2008-02-28 15:29:39 UTC (rev 8557)
+++ branches/mtrender/src/ztrans.c	2008-02-28 17:05:14 UTC (rev 8558)
@@ -337,13 +337,6 @@
     return mask_op(i_ctx_p, gs_end_transparency_mask);
 }
 
-/* <mask#> .inittransparencymask - */
-static int
-zinittransparencymask(i_ctx_t *i_ctx_p)
-{
-    return mask_op(i_ctx_p, gs_init_transparency_mask);
-}
-
 /* ------ Soft-mask images ------ */
 
 /* <dict> .image3x - */
@@ -478,7 +471,6 @@
     {"5.begintransparencymaskimage", zbegintransparencymaskimage},
     {"0.discardtransparencymask", zdiscardtransparencymask},
     {"1.endtransparencymask", zendtransparencymask},
-    {"1.inittransparencymask", zinittransparencymask},
     {"1.image3x", zimage3x},
     {"1.pushpdf14devicefilter", zpushpdf14devicefilter},
     {"0.poppdf14devicefilter", zpoppdf14devicefilter},



More information about the gs-cvs mailing list