# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1639310914 0 # Node ID f9df10c66353f91c4c63529dae8df48c49dd9207 # Parent 850da6b24830be9bce53cb1d7b04b24ee4f9b495 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. diff -r 850da6b24830 -r f9df10c66353 ios/dw.m --- 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 *)¶m1]; +#define DW_FUNCTION_ADD_PARAM1(param1) [_args addPointer:(void *)¶m1]; \ + [_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 *)¶m1]; \ - [_args addPointer:(void *)¶m2]; + [_args addPointer:(void *)¶m2]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ - [_args addPointer:(void *)¶m3]; + [_args addPointer:(void *)¶m3]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ [_args addPointer:(void *)¶m3]; \ - [_args addPointer:(void *)¶m4]; + [_args addPointer:(void *)¶m4]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ [_args addPointer:(void *)¶m3]; \ [_args addPointer:(void *)¶m4]; \ - [_args addPointer:(void *)¶m5]; + [_args addPointer:(void *)¶m5]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ [_args addPointer:(void *)¶m3]; \ [_args addPointer:(void *)¶m4]; \ [_args addPointer:(void *)¶m5]; \ - [_args addPointer:(void *)¶m6]; + [_args addPointer:(void *)¶m6]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ @@ -68,7 +80,9 @@ [_args addPointer:(void *)¶m4]; \ [_args addPointer:(void *)¶m5]; \ [_args addPointer:(void *)¶m6]; \ - [_args addPointer:(void *)¶m7]; + [_args addPointer:(void *)¶m7]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ @@ -77,7 +91,9 @@ [_args addPointer:(void *)¶m5]; \ [_args addPointer:(void *)¶m6]; \ [_args addPointer:(void *)¶m7]; \ - [_args addPointer:(void *)¶m8]; + [_args addPointer:(void *)¶m8]; \ + [_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 *)¶m1]; \ [_args addPointer:(void *)¶m2]; \ @@ -87,33 +103,48 @@ [_args addPointer:(void *)¶m6]; \ [_args addPointer:(void *)¶m7]; \ [_args addPointer:(void *)¶m8]; \ - [_args addPointer:(void *)¶m9]; -#define DW_FUNCTION_RESTORE_PARAM1(param1, vartype1) vartype1 param1 = *((vartype1 *)[_args pointerAtIndex:1]); + [_args addPointer:(void *)¶m9]; \ + [_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