Huw Davies : wineps: Send grayscale images to monochrome printers.

Alexandre Julliard julliard at winehq.org
Fri Apr 5 14:02:16 CDT 2013


Module: wine
Branch: master
Commit: 8c9ca2f7047287a429ee4f94e61bb613eb7f4b11
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8c9ca2f7047287a429ee4f94e61bb613eb7f4b11

Author: Huw Davies <huw at codeweavers.com>
Date:   Fri Apr  5 11:59:07 2013 +0100

wineps: Send grayscale images to monochrome printers.

---

 dlls/wineps.drv/bitmap.c |   38 ++++++++++++++++++++++++++++----------
 dlls/wineps.drv/ps.c     |   13 ++++++++-----
 dlls/wineps.drv/psdrv.h  |    2 +-
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/dlls/wineps.drv/bitmap.c b/dlls/wineps.drv/bitmap.c
index e7fcba3..f5a5547 100644
--- a/dlls/wineps.drv/bitmap.c
+++ b/dlls/wineps.drv/bitmap.c
@@ -44,7 +44,7 @@ static inline int get_dib_width_bytes( int width, int depth )
  *  Uses level 2 PostScript
  */
 
-static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst,
+static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, BOOL grayscale, INT xDst,
 				   INT yDst, INT widthDst, INT heightDst,
 				   INT widthSrc, INT heightSrc)
 {
@@ -63,14 +63,22 @@ static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst
     case 32:
       {
 	PSCOLOR pscol;
-	pscol.type = PSCOLOR_RGB;
-	pscol.value.rgb.r = pscol.value.rgb.g = pscol.value.rgb.b = 0.0;
+        if (grayscale)
+        {
+            pscol.type = PSCOLOR_GRAY;
+            pscol.value.gray.i = 0;
+        }
+        else
+        {
+            pscol.type = PSCOLOR_RGB;
+            pscol.value.rgb.r = pscol.value.rgb.g = pscol.value.rgb.b = 0.0;
+        }
         PSDRV_WriteSetColor(dev, &pscol);
         break;
       }
     }
 
-    PSDRV_WriteImage(dev, info->bmiHeader.biBitCount, xDst, yDst,
+    PSDRV_WriteImage(dev, info->bmiHeader.biBitCount, grayscale, xDst, yDst,
 		     widthDst, heightDst, widthSrc, heightSrc, FALSE, info->bmiHeader.biHeight < 0);
     return TRUE;
 }
@@ -115,7 +123,7 @@ static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT
     PSDRV_WriteGRestore(dev);
 
     PSDRV_WriteSetColor(dev, &foregnd);
-    PSDRV_WriteImage(dev, 1, xDst, yDst, widthDst, heightDst,
+    PSDRV_WriteImage(dev, 1, FALSE, xDst, yDst, widthDst, heightDst,
 		     widthSrc, heightSrc, TRUE, info->bmiHeader.biHeight < 0);
 
     return TRUE;
@@ -139,7 +147,7 @@ static void free_heap_bits( struct gdi_image_bits *bits )
 /***************************************************************************
  *                PSDRV_WriteImageBits
  */
-static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, INT xDst, INT yDst,
+static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, BOOL grayscale, INT xDst, INT yDst,
                                   INT widthDst, INT heightDst, INT widthSrc, INT heightSrc,
                                   void *bits, DWORD size )
 {
@@ -151,7 +159,7 @@ static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, INT xDst,
 	PSDRV_WriteImageMaskHeader(dev, info, xDst, yDst, widthDst, heightDst,
                                    widthSrc, heightSrc);
     else
-	PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
+	PSDRV_WriteImageHeader(dev, info, grayscale, xDst, yDst, widthDst, heightDst,
 			       widthSrc, heightSrc);
 
     rle = HeapAlloc(GetProcessHeap(), 0, max_rle_size(size));
@@ -175,6 +183,8 @@ DWORD PSDRV_PutImage( PHYSDEV dev, HRGN clip, BITMAPINFO *info,
     int dst_x, dst_y, dst_width, dst_height;
     unsigned char *src_ptr, *dst_ptr;
     struct gdi_image_bits dst_bits;
+    PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
+    BOOL grayscale = info->bmiHeader.biBitCount == 24 && physDev->pi->ppd->ColorDevice == CD_False;
 
     if (info->bmiHeader.biPlanes != 1) goto update_format;
     if (info->bmiHeader.biCompression != BI_RGB) goto update_format;
@@ -187,7 +197,8 @@ DWORD PSDRV_PutImage( PHYSDEV dev, HRGN clip, BITMAPINFO *info,
     width = src->visrect.right - src->visrect.left;
     height = src->visrect.bottom - src->visrect.top;
     src_stride = get_dib_width_bytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
-    dst_stride = (width * info->bmiHeader.biBitCount + 7) / 8;
+    if (grayscale) dst_stride = width;
+    else dst_stride = (width * info->bmiHeader.biBitCount + 7) / 8;
 
     src_ptr = bits->ptr;
     if (info->bmiHeader.biHeight > 0)
@@ -224,7 +235,14 @@ DWORD PSDRV_PutImage( PHYSDEV dev, HRGN clip, BITMAPINFO *info,
                 memcpy( dst_ptr, src_ptr, dst_stride );
         break;
     case 24:
-        if (dst_ptr != src_ptr)
+        if (grayscale)
+        {
+            PSRGB scale = rgb_to_grayscale_scale();
+            for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride)
+                for (x = 0; x < width; x++)
+                    dst_ptr[x] = src_ptr[x * 3 + 2] * scale.r + src_ptr[x * 3 + 1] * scale.g + src_ptr[x * 3] * scale.b;
+        }
+        else if (dst_ptr != src_ptr)
             for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride)
                 for (x = 0; x < width; x++)
                 {
@@ -261,7 +279,7 @@ DWORD PSDRV_PutImage( PHYSDEV dev, HRGN clip, BITMAPINFO *info,
     PSDRV_SetClip(dev);
     PSDRV_WriteGSave(dev);
     if (clip) PSDRV_AddClip( dev, clip );
-    PSDRV_WriteImageBits( dev, info, dst_x, dst_y, dst_width, dst_height,
+    PSDRV_WriteImageBits( dev, info, grayscale, dst_x, dst_y, dst_width, dst_height,
                           width, height, dst_bits.ptr, size );
     PSDRV_WriteGRestore(dev);
     PSDRV_ResetClip(dev);
diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c
index 2f482d4..6187223 100644
--- a/dlls/wineps.drv/ps.c
+++ b/dlls/wineps.drv/ps.c
@@ -772,7 +772,7 @@ BOOL PSDRV_WriteRGBQUAD(PHYSDEV dev, const RGBQUAD *rgb, int number)
     return TRUE;
 }
 
-static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth,
+static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth, BOOL grayscale,
 				 INT widthSrc, INT heightSrc, char *bits, BOOL top_down)
 {
     static const char start[] = "<<\n"
@@ -809,7 +809,10 @@ static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth,
 	break;
 
     default:
-        strcpy(buf, decode3);
+        if (grayscale)
+            sprintf(buf, decode1, 1);
+        else
+            strcpy(buf, decode3);
 	break;
     }
 
@@ -825,7 +828,7 @@ static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth,
     return TRUE;
 }
 
-BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst,
+BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, BOOL grayscale, INT xDst, INT yDst,
 		      INT widthDst, INT heightDst, INT widthSrc,
 		      INT heightSrc, BOOL mask, BOOL top_down)
 {
@@ -836,7 +839,7 @@ BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst,
 
     sprintf(buf, start, xDst, yDst, widthDst, heightDst);
     PSDRV_WriteSpool(dev, buf, strlen(buf));
-    PSDRV_WriteImageDict(dev, depth, widthSrc, heightSrc, NULL, top_down);
+    PSDRV_WriteImageDict(dev, depth, grayscale, widthSrc, heightSrc, NULL, top_down);
     if(mask)
         PSDRV_WriteSpool(dev, imagemask, sizeof(imagemask) - 1);
     else
@@ -945,7 +948,7 @@ BOOL PSDRV_WriteDIBPatternDict(PHYSDEV dev, const BITMAPINFO *bmi, BYTE *bits, U
 	}
     }
     PSDRV_WriteSpool(dev, mypat, sizeof(mypat) - 1);
-    PSDRV_WriteImageDict(dev, 1, 8, 8, buf, bmi->bmiHeader.biHeight < 0);
+    PSDRV_WriteImageDict(dev, 1, FALSE, 8, 8, buf, bmi->bmiHeader.biHeight < 0);
     PSDRV_WriteSpool(dev, "def\n", 4);
 
     PSDRV_WriteIndexColorSpaceBegin(dev, 1);
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index e7584fa..16fa977 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -521,7 +521,7 @@ extern BOOL PSDRV_WriteRotate(PHYSDEV dev, float ang) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_WriteIndexColorSpaceBegin(PHYSDEV dev, int size) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_WriteIndexColorSpaceEnd(PHYSDEV dev) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_WriteRGBQUAD(PHYSDEV dev, const RGBQUAD *rgb, int number) DECLSPEC_HIDDEN;
-extern BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst,
+extern BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, BOOL grayscale, INT xDst, INT yDst,
 			     INT widthDst, INT heightDst, INT widthSrc,
 			     INT heightSrc, BOOL mask, BOOL top_down) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_WriteBytes(PHYSDEV dev, const BYTE *bytes, DWORD number) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list