* back/Source/gsc/GSContext.m

* back/Source/cairo/CairoContext.m
        * back/Source/art/ARTContext.m
        * back/Source/xlib/XGContext.m
        * back/Source/winlib/WIN32Context.m: Move the bitmap conversion
        code from cairo to the gsc class. Add a new method to detect
        incompatible image formats and implement that for all backends.
        * back/Source/winlib/WIN32GState.m (GSCreateBitmap): Improve the
        handling of device black/white colour space.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@36025 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2013-01-27 14:38:16 +00:00
parent ad749a173a
commit 73dcf13efd
7 changed files with 290 additions and 91 deletions

View file

@ -1,3 +1,15 @@
2013-01-27 Fred Kiefer <FredKiefer@gmx.de>
* back/Source/gsc/GSContext.m
* back/Source/cairo/CairoContext.m
* back/Source/art/ARTContext.m
* back/Source/xlib/XGContext.m
* back/Source/winlib/WIN32Context.m: Move the bitmap conversion
code from cairo to the gsc class. Add a new method to detect
incompatible image formats and implement that for all backends.
* back/Source/winlib/WIN32GState.m (GSCreateBitmap): Improve the
handling of device black/white colour space.
2013-01-11 Fred Kiefer <FredKiefer@gmx.de>
* Source/win32/w32_general.m (-decodeWM_CLOSEParams:::): Post the

View file

@ -26,6 +26,8 @@
#include <Foundation/NSDebug.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSUserDefaults.h>
#include <AppKit/NSBitmapImageRep.h>
#include <AppKit/NSGraphics.h>
#include "ARTGState.h"
#include "blit.h"
@ -100,6 +102,49 @@
[(XWindowBuffer *)driver _exposeRect: rect];
}
- (BOOL) isCompatibleBitmap: (NSBitmapImageRep*)bitmap
{
NSString *colorSpaceName;
int numColors;
if ([bitmap bitmapFormat] != 0)
{
return NO;
}
if (([bitmap bitsPerSample] > 8) &&
([bitmap bitsPerSample] != 16))
{
return NO;
}
numColors = [bitmap samplesPerPixel] - ([bitmap hasAlpha] ? 1 : 0);
colorSpaceName = [bitmap colorSpaceName];
if ([colorSpaceName isEqualToString: NSDeviceRGBColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedRGBColorSpace])
{
return (numColors == 3);
}
else if ([colorSpaceName isEqualToString: NSDeviceCMYKColorSpace])
{
return (numColors == 4);
}
else if ([colorSpaceName isEqualToString: NSDeviceWhiteColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace])
{
return (numColors == 1);
}
else if ([colorSpaceName isEqualToString: NSDeviceBlackColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedBlackColorSpace])
{
return (numColors == 1);
}
else
{
return NO;
}
}
@end
@implementation ARTContext (ops)

View file

@ -72,17 +72,6 @@
# error Invalid server for Cairo backend : non implemented
#endif /* BUILD_SERVER */
@interface NSBitmapImageRep (GSPrivate)
- (NSBitmapImageRep *) _convertToFormatBitsPerSample: (int)bps
samplesPerPixel: (int)spp
hasAlpha: (BOOL)alpha
isPlanar: (BOOL)isPlanar
colorSpaceName: (NSString*)colorSpaceName
bitmapFormat: (NSBitmapFormat)bitmapFormat
bytesPerRow: (int)rowBytes
bitsPerPixel: (int)pixelBits;
@end
@implementation CairoContext
+ (void) initializeBackend
@ -164,48 +153,35 @@
@implementation CairoContext (Ops)
- (void) GSDrawImage: (NSRect)rect: (void *)imageref
- (BOOL) isCompatibleBitmap: (NSBitmapImageRep*)bitmap
{
NSBitmapImageRep *bitmap;
const unsigned char *data[5];
NSString *colorSpaceName;
bitmap = (NSBitmapImageRep*)imageref;
colorSpaceName = [bitmap colorSpaceName];
if ([bitmap isPlanar] || ([bitmap bitmapFormat] != 0)
|| ([bitmap bitsPerSample] != 8) ||
(![colorSpaceName isEqualToString: NSDeviceRGBColorSpace] &&
![colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]))
if ([bitmap bitmapFormat] != 0)
{
int bitsPerSample = 8;
BOOL isPlanar = NO;
int samplesPerPixel = [bitmap hasAlpha] ? 4 : 3;
NSString *colorSpaceName = NSCalibratedRGBColorSpace;
NSBitmapImageRep *new;
new = [bitmap _convertToFormatBitsPerSample: bitsPerSample
samplesPerPixel: samplesPerPixel
hasAlpha: [bitmap hasAlpha]
isPlanar: isPlanar
colorSpaceName: colorSpaceName
bitmapFormat: 0
bytesPerRow: 0
bitsPerPixel: 0];
if (new == nil)
{
NSLog(@"Could not convert bitmap data");
return;
}
bitmap = new;
return NO;
}
[bitmap getBitmapDataPlanes: (unsigned char **)&data];
[self NSDrawBitmap: rect : [bitmap pixelsWide] : [bitmap pixelsHigh]
: [bitmap bitsPerSample] : [bitmap samplesPerPixel]
: [bitmap bitsPerPixel] : [bitmap bytesPerRow] : [bitmap isPlanar]
: [bitmap hasAlpha] : [bitmap colorSpaceName]
: data];
if ([bitmap isPlanar])
{
return NO;
}
if ([bitmap bitsPerSample] != 8)
{
return NO;
}
colorSpaceName = [bitmap colorSpaceName];
if (![colorSpaceName isEqualToString: NSDeviceRGBColorSpace] &&
![colorSpaceName isEqualToString: NSCalibratedRGBColorSpace])
{
return NO;
}
else
{
return YES;
}
}
- (void) GSCurrentDevice: (void **)device : (int *)x : (int *)y

View file

@ -29,6 +29,7 @@
#include <AppKit/NSAffineTransform.h>
#include <AppKit/NSBitmapImageRep.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSView.h>
#include <AppKit/NSWindow.h>
#include <GNUstepGUI/GSDisplayServer.h>
@ -116,6 +117,17 @@ static NSMapTable *gtable;
- (void)DPSpop;
@end
@interface NSBitmapImageRep (GSPrivate)
- (NSBitmapImageRep *) _convertToFormatBitsPerSample: (int)bps
samplesPerPixel: (int)spp
hasAlpha: (BOOL)alpha
isPlanar: (BOOL)isPlanar
colorSpaceName: (NSString*)colorSpaceName
bitmapFormat: (NSBitmapFormat)bitmapFormat
bytesPerRow: (int)rowBytes
bitsPerPixel: (int)pixelBits;
@end
/**
<unit>
@ -850,12 +862,42 @@ static NSMapTable *gtable;
fraction: delta];
}
- (BOOL) isCompatibleBitmap: (NSBitmapImageRep*)bitmap
{
return ([bitmap bitmapFormat] == 0);
}
- (void) GSDrawImage: (NSRect) rect: (void *) imageref
{
NSBitmapImageRep *bitmap;
unsigned char *data[5];
bitmap = (NSBitmapImageRep*)imageref;
if (![self isCompatibleBitmap: bitmap])
{
int bitsPerSample = 8;
BOOL isPlanar = NO;
int samplesPerPixel = [bitmap hasAlpha] ? 4 : 3;
NSString *colorSpaceName = NSCalibratedRGBColorSpace;
NSBitmapImageRep *new;
new = [bitmap _convertToFormatBitsPerSample: bitsPerSample
samplesPerPixel: samplesPerPixel
hasAlpha: [bitmap hasAlpha]
isPlanar: isPlanar
colorSpaceName: colorSpaceName
bitmapFormat: 0
bytesPerRow: 0
bitsPerPixel: 0];
if (new == nil)
{
NSLog(@"Could not convert bitmap data");
return;
}
bitmap = new;
}
[bitmap getBitmapDataPlanes: data];
[self NSDrawBitmap: rect : [bitmap pixelsWide] : [bitmap pixelsHigh]
: [bitmap bitsPerSample] : [bitmap samplesPerPixel]

View file

@ -26,6 +26,8 @@
#include <Foundation/NSDebug.h>
#include <Foundation/NSString.h>
#include <AppKit/NSBitmapImageRep.h>
#include <AppKit/NSGraphics.h>
#include "winlib/WIN32GState.h"
#include "winlib/WIN32FontEnumerator.h"
@ -54,6 +56,49 @@
{
}
// Try to match restrictions in GSCreateBitmap()
- (BOOL) isCompatibleBitmap: (NSBitmapImageRep*)bitmap
{
NSString *colorSpaceName;
if ([bitmap bitmapFormat] != 0)
{
return NO;
}
if ([bitmap isPlanar])
{
return NO;
}
if ([bitmap bitsPerSample] != 8)
{
return NO;
}
numColors = [bitmap samplesPerPixel] - ([bitmap hasAlpha] ? 1 : 0);
colorSpaceName = [bitmap colorSpaceName];
if ([colorSpaceName isEqualToString: NSDeviceRGBColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedRGBColorSpace])
{
return (numColors == 3);
}
else if ([colorSpaceName isEqualToString: NSDeviceWhiteColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace])
{
return (numColors == 1);
}
else if ([colorSpaceName isEqualToString: NSDeviceBlackColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedBlackColorSpace])
{
return (numColors == 1);
}
else
{
return NO;
}
}
@end
@implementation WIN32Context (Ops)

View file

@ -584,10 +584,12 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
UINT fuColorUse;
if (isPlanar
|| !([colorSpaceName isEqualToString: NSDeviceRGBColorSpace]
|| ![colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace]
|| ![colorSpaceName isEqualToString: NSCalibratedBlackColorSpace]
|| [colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]))
|| (![colorSpaceName isEqualToString: NSDeviceRGBColorSpace]
&& ![colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]
&& ![colorSpaceName isEqualToString: NSDeviceWhiteColorSpace]
&& ![colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace]
&& ![colorSpaceName isEqualToString: NSDeviceBlackColorSpace]
&& ![colorSpaceName isEqualToString: NSCalibratedBlackColorSpace]))
{
NSLog(@"Bitmap type currently not supported %d %@",
isPlanar, colorSpaceName);
@ -680,7 +682,8 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
return NULL;
}
if ([colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace])
if ([colorSpaceName isEqualToString: NSDeviceWhiteColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace])
{
while (i < (pixels*4))
{
@ -694,7 +697,8 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
j++;
}
}
else if ([colorSpaceName isEqualToString: NSCalibratedBlackColorSpace])
else if ([colorSpaceName isEqualToString: NSDeviceBlackColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedBlackColorSpace])
{
while (i < (pixels*4))
{
@ -710,7 +714,74 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
}
else
{
NSLog(@"Unexpected condition, greyscale which is neither white nor black calibrated");
NSLog(@"Unexpected condition, greyscale which is neither white nor black");
free(tmp);
free(bitmap);
DeleteObject(hbitmap);
return NULL;
}
bits = tmp;
}
else if (bitsPerPixel == 16 && samplesPerPixel == 2) // 8 bit greyscale 8 bit alpha
{
BITMAPV4HEADER *bmih;
unsigned char *tmp;
unsigned int pixels = pixelsHigh * pixelsWide;
unsigned int i = 0;
unsigned int j = 0;
((BITMAPINFOHEADER*)bitmap)->biBitCount = 32;
bmih = (BITMAPV4HEADER*)bitmap;
bmih->bV4Size = sizeof(BITMAPV4HEADER);
bmih->bV4V4Compression = BI_BITFIELDS;
bmih->bV4BlueMask = 0x000000FF;
bmih->bV4GreenMask = 0x0000FF00;
bmih->bV4RedMask = 0x00FF0000;
bmih->bV4AlphaMask = 0xFF000000;
tmp = malloc(pixels * 4);
if (!tmp)
{
NSLog(@"Failed to allocate temporary memory for bitmap. Error %d",
GetLastError());
free(bitmap);
DeleteObject(hbitmap);
return NULL;
}
if ([colorSpaceName isEqualToString: NSDeviceWhiteColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace])
{
while (i < (pixels*4))
{
unsigned char pix;
pix = bits[j];
tmp[i+0] = pix;
tmp[i+1] = pix;
tmp[i+2] = pix;
tmp[i+3] = bits[j + 1];
i += 4;
j += 2;
}
}
else if ([colorSpaceName isEqualToString: NSDeviceBlackColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedBlackColorSpace])
{
while (i < (pixels*4))
{
unsigned char pix;
pix = UCHAR_MAX - bits[j];
tmp[i+0] = pix;
tmp[i+1] = pix;
tmp[i+2] = pix;
tmp[i+3] = bits[j + 1];
i += 4;
j += 2;
}
}
else
{
NSLog(@"Unexpected condition, greyscale which is neither white nor black");
free(tmp);
free(bitmap);
DeleteObject(hbitmap);
@ -752,43 +823,6 @@ HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
}
bits = tmp;
}
else if (bitsPerPixel == 16 && samplesPerPixel == 2) // 8 bit greyscale 8 bit alpha
{
BITMAPV4HEADER *bmih;
unsigned char *tmp;
unsigned int pixels = pixelsHigh * pixelsWide;
unsigned int i = 0, j = 0;
((BITMAPINFOHEADER*)bitmap)->biBitCount = 32;
bmih = (BITMAPV4HEADER*)bitmap;
bmih->bV4Size = sizeof(BITMAPV4HEADER);
bmih->bV4V4Compression = BI_BITFIELDS;
bmih->bV4BlueMask = 0x000000FF;
bmih->bV4GreenMask = 0x0000FF00;
bmih->bV4RedMask = 0x00FF0000;
bmih->bV4AlphaMask = 0xFF000000;
tmp = malloc(pixels * 4);
if (!tmp)
{
NSLog(@"Failed to allocate temporary memory for bitmap. Error %d",
GetLastError());
free(bitmap);
DeleteObject(hbitmap);
return NULL;
}
while (i < pixels*4)
{
tmp[i+0] = bits[j];
tmp[i+1] = bits[j];
tmp[i+2] = bits[j];
tmp[i+3] = bits[j + 1];
i += 4;
j += 2;
}
bits = tmp;
}
else if (bitsPerPixel == 24)
{
unsigned char* tmp;

View file

@ -28,6 +28,8 @@
#include "config.h"
#include <AppKit/AppKitExceptions.h>
#include <AppKit/NSAffineTransform.h>
#include <AppKit/NSBitmapImageRep.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSView.h>
#include <AppKit/NSWindow.h>
@ -141,6 +143,49 @@
XFlush([(XGServer *)server xDisplay]);
}
// Try to match the restrictions in XGBitmap
- (BOOL) isCompatibleBitmap: (NSBitmapImageRep*)bitmap
{
NSString *colorSpaceName;
int numColors;
if ([bitmap bitmapFormat] != 0)
{
return NO;
}
if ([bitmap bitsPerSample] > 8)
{
return NO;
}
numColors = [bitmap samplesPerPixel] - ([bitmap hasAlpha] ? 1 : 0);
colorSpaceName = [bitmap colorSpaceName];
if ([colorSpaceName isEqualToString: NSDeviceRGBColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedRGBColorSpace])
{
return (numColors == 3);
}
else if ([colorSpaceName isEqualToString: NSDeviceCMYKColorSpace])
{
return (numColors == 4);
}
else if ([colorSpaceName isEqualToString: NSDeviceWhiteColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedWhiteColorSpace])
{
return (numColors == 1);
}
else if ([colorSpaceName isEqualToString: NSDeviceBlackColorSpace] ||
[colorSpaceName isEqualToString: NSCalibratedBlackColorSpace])
{
return (numColors == 1);
}
else
{
return NO;
}
}
@end
@implementation XGContext (Ops)