Author: fredkiefer
Date: Tue Oct 27 23:12:52 2015
New Revision: 39097

URL: http://svn.gna.org/viewcvs/gnustep?rev=39097&view=rev
Log:
        * Source/cairo/CairoGState.m (-GSReadRect:, -DPSimage:..:):
        Drawing speedup for slow machines.
        Patch by Josh Freeman <[email protected]>

Modified:
    libs/back/trunk/ChangeLog
    libs/back/trunk/Source/cairo/CairoGState.m

Modified: libs/back/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/back/trunk/ChangeLog?rev=39097&r1=39096&r2=39097&view=diff
==============================================================================
--- libs/back/trunk/ChangeLog   (original)
+++ libs/back/trunk/ChangeLog   Tue Oct 27 23:12:52 2015
@@ -1,3 +1,9 @@
+2015-10-28  Fred Kiefer <[email protected]>
+
+       * Source/cairo/CairoGState.m (-GSReadRect:, -DPSimage:..:):
+       Drawing speedup for slow machines.
+       Patch by Josh Freeman <[email protected]>
+
 2015-10-16  Fred Kiefer <[email protected]>
 
        * Source/x11/XGServerEvent.m (-processEvent:): Move repeate key

Modified: libs/back/trunk/Source/cairo/CairoGState.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/back/trunk/Source/cairo/CairoGState.m?rev=39097&r1=39096&r2=39097&view=diff
==============================================================================
--- libs/back/trunk/Source/cairo/CairoGState.m  (original)
+++ libs/back/trunk/Source/cairo/CairoGState.m  Tue Oct 27 23:12:52 2015
@@ -837,6 +837,7 @@
 
 - (NSDictionary *) GSReadRect: (NSRect)r
 {
+  static NSDictionary *baseDict = nil;
   NSMutableDictionary *dict;
   NSSize ssize;
   NSAffineTransform *matrix;
@@ -847,10 +848,11 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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;
-
-      for (i = 0; i < pixelsHigh; i++)
-        {
-          unsigned char *d = rowData;
-
-          for (j = 0; j < pixelsWide; j++)
+      dataRow = (unsigned char *)data[0];
+      reformattedDataPixel = (uint32_t *) reformattedData;
+
+      rowCounter = pixelsHigh;
+
+      while (rowCounter--)
+        {
+          uint32_t *dataPixel = (uint32_t *) dataRow;
+
+          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;
-
-      for (i = 0; i < pixelsHigh; i++)
-        {
-          unsigned char *d = rowData;
-
-          for (j = 0; j < pixelsWide; j++)
+      dataRow = (unsigned char *)data[0];
+      reformattedDataPixel = (uint32_t *) reformattedData;
+
+      rowCounter = pixelsHigh;
+
+      while (rowCounter--)
+        {
+          unsigned char *dataPixelComponent = dataRow;
+
+          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 @@
       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)
-        {
-          free(tmp);
+      if (reformattedData)
+        {
+          free(reformattedData);
         }
 
       return;
@@ -1191,9 +1202,9 @@
   cairo_surface_destroy(surface);
   cairo_restore(_ct);
 
-  if (tmp)
-    {
-      free(tmp);
+  if (reformattedData)
+    {
+      free(reformattedData);
     }
 }
 


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to