mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 07:21:02 +00:00
* Source/cairo/CairoGState.m (-GSReadRect:, -DPSimage:..:):
Drawing speedup for slow machines. Patch by Josh Freeman <gnustep_lists@twilightedge.com> git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@39097 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5e0d451269
commit
6a727f5837
2 changed files with 95 additions and 78 deletions
|
@ -1,3 +1,9 @@
|
|||
2015-10-28 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/cairo/CairoGState.m (-GSReadRect:, -DPSimage:..:):
|
||||
Drawing speedup for slow machines.
|
||||
Patch by Josh Freeman <gnustep_lists@twilightedge.com>
|
||||
|
||||
2015-10-16 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/x11/XGServerEvent.m (-processEvent:): Move repeate key
|
||||
|
|
|
@ -837,6 +837,7 @@ static inline cairo_filter_t cairoFilterFromNSImageInterpolation(NSImageInterpol
|
|||
|
||||
- (NSDictionary *) GSReadRect: (NSRect)r
|
||||
{
|
||||
static NSDictionary *baseDict = nil;
|
||||
NSMutableDictionary *dict;
|
||||
NSSize ssize;
|
||||
NSAffineTransform *matrix;
|
||||
|
@ -847,10 +848,11 @@ static inline cairo_filter_t cairoFilterFromNSImageInterpolation(NSImageInterpol
|
|||
cairo_surface_t *isurface;
|
||||
cairo_t *ct;
|
||||
cairo_status_t status;
|
||||
int size;
|
||||
int i;
|
||||
int dataSize;
|
||||
NSMutableData *data;
|
||||
unsigned char *cdata;
|
||||
unsigned char *dataBytes;
|
||||
uint32_t *dataPixel;
|
||||
int pixelCounter;
|
||||
|
||||
if (!_ct)
|
||||
{
|
||||
|
@ -864,31 +866,35 @@ static inline cairo_filter_t cairoFilterFromNSImageInterpolation(NSImageInterpol
|
|||
iy = fabs(floor(y));
|
||||
ssize = NSMakeSize(ix, iy);
|
||||
|
||||
dict = [NSMutableDictionary dictionary];
|
||||
if (!baseDict)
|
||||
{
|
||||
baseDict = [[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSDeviceRGBColorSpace, @"ColorSpace",
|
||||
[NSNumber numberWithUnsignedInt: 8], @"BitsPerSample",
|
||||
[NSNumber numberWithUnsignedInt: 32], @"Depth",
|
||||
[NSNumber numberWithUnsignedInt: 4], @"SamplesPerPixel",
|
||||
[NSNumber numberWithUnsignedInt: 1], @"HasAlpha",
|
||||
nil]
|
||||
retain];
|
||||
}
|
||||
|
||||
dict = [NSMutableDictionary dictionaryWithDictionary: baseDict];
|
||||
|
||||
[dict setObject: [NSValue valueWithSize: ssize] forKey: @"Size"];
|
||||
[dict setObject: NSDeviceRGBColorSpace forKey: @"ColorSpace"];
|
||||
|
||||
[dict setObject: [NSNumber numberWithUnsignedInt: 8] forKey: @"BitsPerSample"];
|
||||
[dict setObject: [NSNumber numberWithUnsignedInt: 32]
|
||||
forKey: @"Depth"];
|
||||
[dict setObject: [NSNumber numberWithUnsignedInt: 4]
|
||||
forKey: @"SamplesPerPixel"];
|
||||
[dict setObject: [NSNumber numberWithUnsignedInt: 1]
|
||||
forKey: @"HasAlpha"];
|
||||
|
||||
matrix = [self GSCurrentCTM];
|
||||
[matrix translateXBy: -r.origin.x - offset.x
|
||||
yBy: r.origin.y + NSHeight(r) - offset.y];
|
||||
[dict setObject: matrix forKey: @"Matrix"];
|
||||
|
||||
size = ix*iy*4;
|
||||
data = [NSMutableData dataWithLength: size];
|
||||
dataSize = ix*iy*4;
|
||||
data = [NSMutableData dataWithLength: dataSize];
|
||||
if (data == nil)
|
||||
return nil;
|
||||
cdata = [data mutableBytes];
|
||||
dataBytes = [data mutableBytes];
|
||||
|
||||
surface = cairo_get_target(_ct);
|
||||
isurface = cairo_image_surface_create_for_data(cdata, format, ix, iy, 4*ix);
|
||||
isurface = cairo_image_surface_create_for_data(dataBytes, format, ix, iy, 4*ix);
|
||||
status = cairo_surface_status(isurface);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
|
@ -920,21 +926,24 @@ static inline cairo_filter_t cairoFilterFromNSImageInterpolation(NSImageInterpol
|
|||
cairo_destroy(ct);
|
||||
cairo_surface_destroy(isurface);
|
||||
|
||||
for (i = 0; i < 4 * ix * iy; i += 4)
|
||||
{
|
||||
unsigned char d = cdata[i];
|
||||
dataPixel = (uint32_t *) dataBytes;
|
||||
|
||||
pixelCounter = ix * iy;
|
||||
|
||||
while (pixelCounter--)
|
||||
{
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
cdata[i] = cdata[i + 1];
|
||||
cdata[i + 1] = cdata[i + 2];
|
||||
cdata[i + 2] = cdata[i + 3];
|
||||
cdata[i + 3] = d;
|
||||
// ARGB -> RGBA
|
||||
*dataPixel = (*dataPixel << 8) // ARGB -> RGB_
|
||||
| (*dataPixel >> 24); // ARGB -> ___A
|
||||
#else
|
||||
cdata[i] = cdata[i + 2];
|
||||
//cdata[i + 1] = cdata[i + 1];
|
||||
cdata[i + 2] = d;
|
||||
//cdata[i + 3] = cdata[i + 3];
|
||||
#endif
|
||||
// ARGB -> ABGR
|
||||
*dataPixel = ((*dataPixel & 0x000000FF) << 16) // ___B -> _B__
|
||||
| ((*dataPixel & 0x00FF0000) >> 16) // _R__ -> ___R
|
||||
| (*dataPixel & 0xFF00FF00); // A_G_ -> A_G_
|
||||
#endif
|
||||
|
||||
dataPixel++;
|
||||
}
|
||||
|
||||
[dict setObject: data forKey: @"Data"];
|
||||
|
@ -1017,12 +1026,9 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
cairo_format_t format;
|
||||
NSAffineTransformStruct tstruct;
|
||||
cairo_surface_t *surface;
|
||||
unsigned char *tmp = NULL;
|
||||
int i = 0;
|
||||
int j;
|
||||
int index;
|
||||
unsigned int pixels = pixelsHigh * pixelsWide;
|
||||
unsigned char *rowData;
|
||||
unsigned char *dataRow, *reformattedData;
|
||||
int reformattedDataSize, rowCounter, columnCounter;
|
||||
uint32_t *reformattedDataPixel;
|
||||
cairo_matrix_t local_matrix;
|
||||
cairo_status_t status;
|
||||
|
||||
|
@ -1055,73 +1061,78 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
while ((bytesPerRow * 8) < (bitsPerPixel * pixelsWide))
|
||||
bytesPerRow++;
|
||||
|
||||
reformattedDataSize = pixelsWide * pixelsHigh * sizeof(*reformattedDataPixel);
|
||||
|
||||
switch (bitsPerPixel)
|
||||
{
|
||||
case 32:
|
||||
tmp = malloc(pixels * 4);
|
||||
if (!tmp)
|
||||
reformattedData = malloc(reformattedDataSize);
|
||||
if (!reformattedData)
|
||||
{
|
||||
NSLog(@"Could not allocate drawing space for image");
|
||||
return;
|
||||
}
|
||||
|
||||
rowData = (unsigned char *)data[0];
|
||||
index = 0;
|
||||
dataRow = (unsigned char *)data[0];
|
||||
reformattedDataPixel = (uint32_t *) reformattedData;
|
||||
|
||||
for (i = 0; i < pixelsHigh; i++)
|
||||
rowCounter = pixelsHigh;
|
||||
|
||||
while (rowCounter--)
|
||||
{
|
||||
unsigned char *d = rowData;
|
||||
uint32_t *dataPixel = (uint32_t *) dataRow;
|
||||
|
||||
for (j = 0; j < pixelsWide; j++)
|
||||
columnCounter = pixelsWide;
|
||||
|
||||
while (columnCounter--)
|
||||
{
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
tmp[index++] = d[3];
|
||||
tmp[index++] = d[0];
|
||||
tmp[index++] = d[1];
|
||||
tmp[index++] = d[2];
|
||||
// RGBA (uint32) -> ARGB (uint32)
|
||||
*reformattedDataPixel++ = (*dataPixel >> 8) // RGBA -> _RGB
|
||||
| (*dataPixel << 24); // RGBA -> A___
|
||||
#else
|
||||
tmp[index++] = d[2];
|
||||
tmp[index++] = d[1];
|
||||
tmp[index++] = d[0];
|
||||
tmp[index++] = d[3];
|
||||
// ABGR (uint32) -> ARGB (uint32)
|
||||
*reformattedDataPixel++ = ((*dataPixel & 0x000000FF) << 16) // ___R -> _R__
|
||||
| ((*dataPixel & 0x00FF0000) >> 16) // _B__ -> ___B
|
||||
| (*dataPixel & 0xFF00FF00); // A_G_ -> A_G_
|
||||
#endif
|
||||
d += 4;
|
||||
dataPixel++;
|
||||
}
|
||||
rowData += bytesPerRow;
|
||||
|
||||
dataRow += bytesPerRow;
|
||||
}
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
break;
|
||||
case 24:
|
||||
tmp = malloc(pixels * 4);
|
||||
if (!tmp)
|
||||
reformattedData = malloc(reformattedDataSize);
|
||||
if (!reformattedData)
|
||||
{
|
||||
NSLog(@"Could not allocate drawing space for image");
|
||||
return;
|
||||
}
|
||||
|
||||
rowData = (unsigned char *)data[0];
|
||||
index = 0;
|
||||
dataRow = (unsigned char *)data[0];
|
||||
reformattedDataPixel = (uint32_t *) reformattedData;
|
||||
|
||||
for (i = 0; i < pixelsHigh; i++)
|
||||
rowCounter = pixelsHigh;
|
||||
|
||||
while (rowCounter--)
|
||||
{
|
||||
unsigned char *d = rowData;
|
||||
unsigned char *dataPixelComponent = dataRow;
|
||||
|
||||
for (j = 0; j < pixelsWide; j++)
|
||||
columnCounter = pixelsWide;
|
||||
|
||||
while (columnCounter--)
|
||||
{
|
||||
#if GS_WORDS_BIGENDIAN
|
||||
tmp[index++] = 0;
|
||||
tmp[index++] = d[0];
|
||||
tmp[index++] = d[1];
|
||||
tmp[index++] = d[2];
|
||||
#else
|
||||
tmp[index++] = d[2];
|
||||
tmp[index++] = d[1];
|
||||
tmp[index++] = d[0];
|
||||
tmp[index++] = 0;
|
||||
#endif
|
||||
d += 3;
|
||||
// R,G,B (uchar[0-2]) -> _RGB (uint32)
|
||||
*reformattedDataPixel++ = (((uint32_t) dataPixelComponent[0]) << 16) // R -> _R__
|
||||
| (((uint32_t) dataPixelComponent[1]) << 8) // G -> __G_
|
||||
| ((uint32_t) dataPixelComponent[2]); // B -> ___B
|
||||
|
||||
dataPixelComponent += 3;
|
||||
}
|
||||
rowData += bytesPerRow;
|
||||
|
||||
dataRow += bytesPerRow;
|
||||
}
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
break;
|
||||
|
@ -1130,18 +1141,18 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
return;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create_for_data((void*)tmp,
|
||||
surface = cairo_image_surface_create_for_data((void*)reformattedData,
|
||||
format,
|
||||
pixelsWide,
|
||||
pixelsHigh,
|
||||
pixelsWide * 4);
|
||||
pixelsWide * sizeof(*reformattedDataPixel));
|
||||
status = cairo_surface_status(surface);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
NSLog(@"Cairo status '%s' in DPSimage", cairo_status_to_string(status));
|
||||
if (tmp)
|
||||
if (reformattedData)
|
||||
{
|
||||
free(tmp);
|
||||
free(reformattedData);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1191,9 +1202,9 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
cairo_surface_destroy(surface);
|
||||
cairo_restore(_ct);
|
||||
|
||||
if (tmp)
|
||||
if (reformattedData)
|
||||
{
|
||||
free(tmp);
|
||||
free(reformattedData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue