changeset 2729:f9df10c66353

iOS: Pass thread specific colors through thread safety macros. This allows colors to be correct when rendering on different threads. This was apparent in the new print code, which ran on a different thread.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 12 Dec 2021 12:08:34 +0000
parents 850da6b24830
children cff8f6b6e302
files ios/dw.m
diffstat 1 files changed, 67 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/ios/dw.m	Sat Dec 11 14:44:37 2021 +0000
+++ b/ios/dw.m	Sun Dec 12 12:08:34 2021 +0000
@@ -39,28 +39,40 @@
     DW_LOCAL_POOL_IN; \
     NSPointerArray *_args = [[NSPointerArray alloc] initWithOptions:NSPointerFunctionsOpaqueMemory]; \
     [_args addPointer:(void *)_##func];
-#define DW_FUNCTION_ADD_PARAM1(param1) [_args addPointer:(void *)&param1];
+#define DW_FUNCTION_ADD_PARAM1(param1) [_args addPointer:(void *)&param1]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM2(param1, param2) [_args addPointer:(void *)&param1]; \
-    [_args addPointer:(void *)&param2];
+    [_args addPointer:(void *)&param2]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM3(param1, param2, param3) [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
-    [_args addPointer:(void *)&param3];
+    [_args addPointer:(void *)&param3]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM4(param1, param2, param3, param4) [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
     [_args addPointer:(void *)&param3]; \
-    [_args addPointer:(void *)&param4];
+    [_args addPointer:(void *)&param4]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM5(param1, param2, param3, param4, param5) [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
     [_args addPointer:(void *)&param3]; \
     [_args addPointer:(void *)&param4]; \
-    [_args addPointer:(void *)&param5];
+    [_args addPointer:(void *)&param5]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM6(param1, param2, param3, param4, param5, param6) \
     [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
     [_args addPointer:(void *)&param3]; \
     [_args addPointer:(void *)&param4]; \
     [_args addPointer:(void *)&param5]; \
-    [_args addPointer:(void *)&param6];
+    [_args addPointer:(void *)&param6]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM7(param1, param2, param3, param4, param5, param6, param7) \
     [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
@@ -68,7 +80,9 @@
     [_args addPointer:(void *)&param4]; \
     [_args addPointer:(void *)&param5]; \
     [_args addPointer:(void *)&param6]; \
-    [_args addPointer:(void *)&param7];
+    [_args addPointer:(void *)&param7]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM8(param1, param2, param3, param4, param5, param6, param7, param8) \
     [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
@@ -77,7 +91,9 @@
     [_args addPointer:(void *)&param5]; \
     [_args addPointer:(void *)&param6]; \
     [_args addPointer:(void *)&param7]; \
-    [_args addPointer:(void *)&param8];
+    [_args addPointer:(void *)&param8]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
 #define DW_FUNCTION_ADD_PARAM9(param1, param2, param3, param4, param5, param6, param7, param8, param9) \
     [_args addPointer:(void *)&param1]; \
     [_args addPointer:(void *)&param2]; \
@@ -87,33 +103,48 @@
     [_args addPointer:(void *)&param6]; \
     [_args addPointer:(void *)&param7]; \
     [_args addPointer:(void *)&param8]; \
-    [_args addPointer:(void *)&param9];
-#define DW_FUNCTION_RESTORE_PARAM1(param1, vartype1) vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]);
+    [_args addPointer:(void *)&param9]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_fg_color_key)]; \
+    [_args addPointer:(void *)pthread_getspecific(_dw_bg_color_key)];
+#define DW_FUNCTION_RESTORE_PARAM1(param1, vartype1) \
+    vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:2]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:3];
 #define DW_FUNCTION_RESTORE_PARAM2(param1, vartype1, param2, vartype2) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
-    vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]);
+    vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:3]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:4];
 #define DW_FUNCTION_RESTORE_PARAM3(param1, vartype1, param2, vartype2, param3, vartype3) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
-    vartype3 param3 = *((vartype3 *)[_args pointerAtIndex:3]);
+    vartype3 param3 = *((vartype3 *)[_args pointerAtIndex:3]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:4]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:5];
 #define DW_FUNCTION_RESTORE_PARAM4(param1, vartype1, param2, vartype2, param3, vartype3, param4, vartype4) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
     vartype3 param3 = *((vartype3 *)[_args pointerAtIndex:3]); \
-    vartype4 param4 = *((vartype4 *)[_args pointerAtIndex:4]);
+    vartype4 param4 = *((vartype4 *)[_args pointerAtIndex:4]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:5]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:6];
 #define DW_FUNCTION_RESTORE_PARAM5(param1, vartype1, param2, vartype2, param3, vartype3, param4, vartype4, param5, vartype5) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
     vartype3 param3 = *((vartype3 *)[_args pointerAtIndex:3]); \
     vartype4 param4 = *((vartype4 *)[_args pointerAtIndex:4]); \
-    vartype5 param5 = *((vartype5 *)[_args pointerAtIndex:5]);
+    vartype5 param5 = *((vartype5 *)[_args pointerAtIndex:5]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:6]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:7];
 #define DW_FUNCTION_RESTORE_PARAM6(param1, vartype1, param2, vartype2, param3, vartype3, param4, vartype4, param5, vartype5, param6, vartype6) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
     vartype3 param3 = *((vartype3 *)[_args pointerAtIndex:3]); \
     vartype4 param4 = *((vartype4 *)[_args pointerAtIndex:4]); \
     vartype5 param5 = *((vartype5 *)[_args pointerAtIndex:5]); \
-    vartype6 param6 = *((vartype6 *)[_args pointerAtIndex:6]);
+    vartype6 param6 = *((vartype6 *)[_args pointerAtIndex:6]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:7]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:8];
 #define DW_FUNCTION_RESTORE_PARAM7(param1, vartype1, param2, vartype2, param3, vartype3, param4, vartype4, param5, vartype5, param6, vartype6, param7, vartype7) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
@@ -121,7 +152,9 @@
     vartype4 param4 = *((vartype4 *)[_args pointerAtIndex:4]); \
     vartype5 param5 = *((vartype5 *)[_args pointerAtIndex:5]); \
     vartype6 param6 = *((vartype6 *)[_args pointerAtIndex:6]); \
-    vartype7 param7 = *((vartype7 *)[_args pointerAtIndex:7]);
+    vartype7 param7 = *((vartype7 *)[_args pointerAtIndex:7]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:8]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:9];
 #define DW_FUNCTION_RESTORE_PARAM8(param1, vartype1, param2, vartype2, param3, vartype3, param4, vartype4, param5, vartype5, param6, vartype6, param7, vartype7, param8, vartype8) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
@@ -130,7 +163,9 @@
     vartype5 param5 = *((vartype5 *)[_args pointerAtIndex:5]); \
     vartype6 param6 = *((vartype6 *)[_args pointerAtIndex:6]); \
     vartype7 param7 = *((vartype7 *)[_args pointerAtIndex:7]); \
-    vartype8 param8 = *((vartype8 *)[_args pointerAtIndex:8]);
+    vartype8 param8 = *((vartype8 *)[_args pointerAtIndex:8]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:9]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:10];
 #define DW_FUNCTION_RESTORE_PARAM9(param1, vartype1, param2, vartype2, param3, vartype3, param4, vartype4, param5, vartype5, param6, vartype6, param7, vartype7, param8, vartype8, param9, vartype9) \
     vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); \
     vartype2 param2 = *((vartype2 *)[_args pointerAtIndex:2]); \
@@ -140,7 +175,9 @@
     vartype6 param6 = *((vartype6 *)[_args pointerAtIndex:6]); \
     vartype7 param7 = *((vartype7 *)[_args pointerAtIndex:7]); \
     vartype8 param8 = *((vartype8 *)[_args pointerAtIndex:8]); \
-    vartype9 param9 = *((vartype9 *)[_args pointerAtIndex:9]);
+    vartype9 param9 = *((vartype9 *)[_args pointerAtIndex:9]); \
+    UIColor *__attribute__((__unused__))_dw_fg_color = (UIColor *)[_args pointerAtIndex:10]; \
+    UIColor *__attribute__((__unused__))_dw_bg_color = (UIColor *)[_args pointerAtIndex:11];
 #define DW_FUNCTION_END }
 #define DW_FUNCTION_NO_RETURN(func) [DWObj safeCall:@selector(callBack:) withObject:_args]; \
     [_args release]; \
@@ -966,8 +1003,10 @@
 {
     HPIXMAP pm = dw_pixmap_new(nil, contentRect.size.width, contentRect.size.height, 32);
     DWImage *image = pm->image;
+    CGBlendMode op = kCGBlendModeNormal;
+
     drawfunc(print, pm, (int)pageIndex, drawdata);
-    [[image image] drawInRect:contentRect];
+    [[image image] drawInRect:contentRect blendMode:op alpha:1.0];
     dw_pixmap_destroy(pm);
 }
 -(NSInteger)numberOfPages { return (NSInteger)pages; }
@@ -5727,8 +5766,7 @@
     {
         UIBezierPath* aPath = [UIBezierPath bezierPath];
         [aPath setLineWidth: 0.5];
-        UIColor *color = pthread_getspecific(_dw_fg_color_key);
-        [color set];
+        [_dw_fg_color set];
 
         [aPath moveToPoint:CGPointMake(x, y)];
         [aPath stroke];
@@ -5762,8 +5800,7 @@
     if(bi)
     {
         UIBezierPath* aPath = [UIBezierPath bezierPath];
-        UIColor *color = pthread_getspecific(_dw_fg_color_key);
-        [color set];
+        [_dw_fg_color set];
 
         [aPath moveToPoint:CGPointMake(x1 + 0.5, y1 + 0.5)];
         [aPath addLineToPoint:CGPointMake(x2 + 0.5, y2 + 0.5)];
@@ -5817,11 +5854,9 @@
         if(context)
             UIGraphicsPushContext(context);
 
-        UIColor *fgcolor = pthread_getspecific(_dw_fg_color_key);
-        UIColor *bgcolor = pthread_getspecific(_dw_bg_color_key);
-        NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:fgcolor, NSForegroundColorAttributeName, nil];
-        if(bgcolor)
-            [dict setValue:bgcolor forKey:NSBackgroundColorAttributeName];
+        NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:_dw_fg_color, NSForegroundColorAttributeName, nil];
+        if(_dw_bg_color)
+            [dict setValue:_dw_bg_color forKey:NSBackgroundColorAttributeName];
         if(font)
             [dict setValue:font forKey:NSFontAttributeName];
         [nstr drawAtPoint:CGPointMake(x, y) withAttributes:dict];
@@ -5907,10 +5942,9 @@
     if(bi)
     {
         UIBezierPath* aPath = [UIBezierPath bezierPath];
-        UIColor *color = pthread_getspecific(_dw_fg_color_key);
         int z;
 
-        [color set];
+        [_dw_fg_color set];
 
         [aPath moveToPoint:CGPointMake(*x + 0.5, *y + 0.5)];
         for(z=1;z<npoints;z++)
@@ -5952,10 +5986,9 @@
 
     if(bi)
     {
-        UIColor *color = pthread_getspecific(_dw_fg_color_key);
         UIBezierPath *bp = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, width, height)];;
         
-        [color set];
+        [_dw_fg_color set];
 
         if(flags & DW_DRAW_FILL)
             [bp fill];
@@ -5995,8 +6028,8 @@
     if(bi)
     {
         UIBezierPath* aPath;
-        UIColor *color = pthread_getspecific(_dw_fg_color_key);
-        [color set];
+
+        [_dw_fg_color set];
 
         /* Special case of a full circle/oval */
         if(flags & DW_DRAW_FULL)
@@ -10952,7 +10985,6 @@
         if(!jobname)
             jobname = "Dynamic Windows Print Job";
 
-
         [pi setOutputType:UIPrintInfoOutputGeneral];
         [pi setJobName:[NSString stringWithUTF8String:jobname]];
         [pi setOrientation:UIPrintInfoOrientationPortrait];