discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Q] Trasparent Tiff drawing on Windows.


From: MA Garcias
Subject: Re: [Q] Trasparent Tiff drawing on Windows.
Date: Mon, 05 Jul 2004 11:40:16 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

After some try, I didn't get transparent tiff drawing work right in the
win32 backend. Actually, making alpha blending work (for the
NSCompositeSourceOver operation, which is 90% of the image drawing) was
quite simply, just using AlphaBlend instead of BitBlt. Found two
problems though:
1 - the standard tiff images in the gnustep distribution work fine with
alpha blending, with their alpha channel correctly interpreted, but
somehow the red and blue channels are swapped. When trying to set proper
masks in the GSCreateBitmap function, the results are much worse.
2 - other tiff images (like the ones generated with Paint or other win32
image tools) are drawn with oversaturated values, so that the image
appears almost (or completely) white. Again, the color masks in the
BITMAPV4HEADER struct seem to be completely useless to fix it. Anyway,
it seems that the tiff library doesn't load correctly all tiff formats
(or maybe the win32 tools don't stick to standard?).
Anyway, you can find a patch in the attached file so that you people can
play around (I'm not releasing it officially because of the poor
results). Please report if you get any results.
maGarcias | tragnarionStudios

S.J.Chun wrote:

>Hi,
>
>I've managed to create a Windows program which can read 
>common_3DArrowRight.tiff and correctly display
>it. I cannot make this work with gnustep-back(yes, I'm not good at win32 
>programming and gnustep-back :).
>
>Can anyone let me know the difference/problem between my attached sample and 
>gnustep-back? Or if anyone
>can adopt my sample so that gnustep-back can also draw tiff correctly.
>
>Thanks in advance.
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Discuss-gnustep mailing list
>Discuss-gnustep@gnu.org
>http://lists.gnu.org/mailman/listinfo/discuss-gnustep
>  
>

diff -u -w -b -r old/back/Source/winlib/WIN32GState.m 
new/back/Source/winlib/WIN32GState.m
--- old/back/Source/winlib/WIN32GState.m        Wed May 26 12:24:40 2004
+++ new/back/Source/winlib/WIN32GState.m        Mon Jul  5 11:27:33 2004
@@ -22,6 +22,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
    */
 
+#define WINVER 0x0500
+#include <windows.h>
+
 #include <AppKit/NSAffineTransform.h>
 #include <AppKit/NSBezierPath.h>
 #include <AppKit/NSColor.h>
@@ -41,6 +44,9 @@
 // before and after the PolyBezierTo().
 #define GDI_WIDELINE_BEZIERPATH_BUG 1
 
+// Missing definitions from wingdi.h
+#define AC_SRC_ALPHA    0x01
+
 static inline
 int WindowHeight(HWND window)
 {
@@ -167,6 +173,11 @@
     wscolor = RGB(color.field[0]*255, color.field[1]*255, color.field[2]*255);
 }
 
+/** HDC composition using the right function for the job:
+    BitBlt          for NSCompositeCopy
+    TransparentBlt  for NSCompositeSourceOver
+    AlphaBlend      for ...
+*/
 - (void) copyBits: (WIN32GState*)source 
         fromRect: (NSRect)aRect 
          toPoint: (NSPoint)aPoint
@@ -227,13 +238,107 @@
   [source releaseHDC: otherDC]; 
 }
 
+- (void) _compositeGState: (WIN32GState *) source
+                 fromRect: (NSRect) sourceRect
+                  toPoint: (NSPoint) destPoint
+                       op: (NSCompositingOperation) op
+                 fraction: (float)delta
+{
+    HDC sourceDC;
+    HDC hDC;
+    RECT rectFrom;
+    RECT rectTo;
+    int h;
+    int x;
+    int y;
+    NSRect destRect;
+
+    NSDebugLLog( @"WIN32GState", @"compositeGState: fromRect: %@ toPoint: %@ 
op: %d",
+                 NSStringFromRect(sourceRect), NSStringFromPoint(destPoint), 
op );
+
+    rectFrom = GSViewRectToWin( source, sourceRect );
+    h = rectFrom.bottom - rectFrom.top;
+
+    destRect.size = sourceRect.size;
+    destRect.origin = destPoint;
+    rectTo = GSViewRectToWin( self, destRect );
+    x = rectTo.left;
+    y = rectTo.top;
+
+    if (source->ctm->matrix.m22 < 0 && ctm->matrix.m22 > 0) y += h;
+    if (source->ctm->matrix.m22 > 0 && ctm->matrix.m22 < 0) y -= h;
+
+    sourceDC = [source getHDC];
+
+    if( !sourceDC )
+    {
+        return;
+    }
+
+    if( self == source )
+    {
+        hDC = sourceDC;
+    }
+    else
+    {
+        hDC = [self getHDC];
+        if( !hDC )
+        {
+            [source releaseHDC: sourceDC];
+            return;
+        }
+    }
+
+    BOOL success;
+    switch (op)
+    {
+    case NSCompositeSourceOver:
+    {
+        // @FIXME use (0..1) fraction to set a (0..255) alpha constant value
+        //success = TransparentBlt( hDC, ..., RGB( 0, 0, 0 ) ) );
+        BLENDFUNCTION blendFunc = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
+        success = AlphaBlend( hDC,
+                              x, y, (rectFrom.right - rectFrom.left), h,
+                              sourceDC,
+                              rectFrom.left, rectFrom.top,
+                              (rectFrom.right - rectFrom.left), h, blendFunc );
+        break;
+    }
+
+    default:
+        success = BitBlt( hDC, x, y, (rectFrom.right - rectFrom.left), h,
+                         sourceDC, rectFrom.left, rectFrom.top, SRCCOPY );
+        break;
+    }
+
+    if (!success)
+    {
+        NSLog( @"Blit operation failed %d", GetLastError() );
+        NSLog( @"Orig Copy Bits to %@ from %@", NSStringFromPoint(destPoint),
+               NSStringFromRect(destRect) );
+        NSLog( @"Copy bits to {%d, %d} from {%d, %d} size {%d, %d}", x, y,
+               rectFrom.left, rectFrom.top, (rectFrom.right - rectFrom.left), 
h );
+    }
+
+    if( self != source )
+    {
+        [self releaseHDC: hDC];
+    }
+    [source releaseHDC: sourceDC];
+}
+
+/** GSGState composition
+*/
 - (void) compositeGState: (GSGState *)source 
                 fromRect: (NSRect)aRect
                  toPoint: (NSPoint)aPoint
                       op: (NSCompositingOperation)op
 {
-  // FIXME
-  [self copyBits: (WIN32GState *)source fromRect: aRect toPoint: aPoint];
+    [self _compositeGState: (WIN32GState *) source
+                  fromRect: aRect
+                   toPoint: aPoint
+                        op: op
+                  fraction: 1];
 }
 
 - (void) dissolveGState: (GSGState *)source
@@ -243,6 +348,12 @@
 {
   // FIXME
   [self copyBits: (WIN32GState *)source fromRect: aRect toPoint: aPoint];
+
+//    [self _compositeGState: source
+//                  fromRect: aRect
+//                   toPoint: aPoint
+//                        op: NSCompositeSourceOver
+//                  fraction: delta];
 }
 
 - (void) compositerect: (NSRect)aRect
@@ -376,7 +487,7 @@
       //bitmap->bmiColors;
       fuColorUse = DIB_RGB_COLORS;
     }
-  else if (bitsPerPixel == 32)
+/*  else if (bitsPerPixel == 32 && hasAlpha)
     {
       BITMAPV4HEADER *bmih;
 
@@ -387,23 +498,23 @@
       bmih->bV4GreenMask = 0x0000FF00;
       bmih->bV4BlueMask = 0x00FF0000;
       bmih->bV4AlphaMask = 0xFF000000;
+      fuColorUse = DIB_RGB_COLORS;
     }
+*/
   else if (bitsPerPixel == 16)
     {
-/*
-      BITMAPV4HEADER *bmih;
+//        BITMAPV4HEADER *bmih;
+//
+//        bmih = (BITMAPV4HEADER*)bitmap;
+//        bmih->bV4Size = sizeof(BITMAPV4HEADER);
+//        bmih->bV4V4Compression = BI_BITFIELDS;
+//        bmih->bV4RedMask = 0xF000;
+//        bmih->bV4GreenMask = 0x0F00;
+//        bmih->bV4BlueMask = 0x00F0;
+//        bmih->bV4AlphaMask = 0x000F;
 
-      bmih = (BITMAPV4HEADER*)bitmap;
-      bmih->bV4Size = sizeof(BITMAPV4HEADER);
-      bmih->bV4V4Compression = BI_BITFIELDS;
-      bmih->bV4RedMask = 0xF000;
-      bmih->bV4GreenMask = 0x0F00;
-      bmih->bV4BlueMask = 0x00F0;
-      bmih->bV4AlphaMask = 0x000F;
-*/
       NSLog(@"Unsure how to handle images with %d bits", bitsPerPixel);
     }
-
   if (!SetDIBits(hDC, hbitmap, 0, pixelsHigh, data[0], 
                 bitmap, fuColorUse))
     {
@@ -432,6 +543,16 @@
   int h;
   int y1;
 
+    NSDebugLLog( @"WIN32GState", @"DPSImage : pixelsWide = %d : pixelsHigh = 
%d"
+                                  ": bitsPerSample = %d : samplesPerPixel = %d"
+                                  ": bitsPerPixel = %d : bytesPerRow = %d "
+                                  ": isPlanar = %d"
+                                  ": hasAlpha = %d : colorSpaceName = %@",
+                                  pixelsWide, pixelsHigh,
+                                  bitsPerSample, samplesPerPixel,
+                                  bitsPerPixel, bytesPerRow,
+                                  isPlanar, hasAlpha, colorSpaceName );
+
   if (window == NULL)
     {
       NSLog(@"No window in DPSImage");

reply via email to

[Prev in Thread] Current Thread [Next in Thread]