-
Notifications
You must be signed in to change notification settings - Fork 41
Fix gradient crash on non-RGB NSColor and add regression test #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1584,10 +1584,26 @@ - (void) drawGradient: (NSGradient*)gradient | |||||||||||||||
| [gradient getColor: &color | ||||||||||||||||
| location: &location | ||||||||||||||||
| atIndex: i]; | ||||||||||||||||
| red = [color redComponent]; | ||||||||||||||||
| green = [color greenComponent]; | ||||||||||||||||
| blue = [color blueComponent]; | ||||||||||||||||
| alpha = [color alphaComponent]; | ||||||||||||||||
| /* Ensure color is in an RGB-compatible colorspace to avoid | ||||||||||||||||
| -redComponent/-greenComponent/-blueComponent raising | ||||||||||||||||
| for non-RGB colors (patterns, color lists, etc.). Try | ||||||||||||||||
| device RGB first, then calibrated RGB, and finally | ||||||||||||||||
| fall back to a safe opaque black if conversion fails. */ | ||||||||||||||||
| NSColor *rgbColor = [color colorUsingColorSpaceName: NSDeviceRGBColorSpace]; | ||||||||||||||||
| if (!rgbColor) rgbColor = [color colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; | ||||||||||||||||
| if (!rgbColor) rgbColor = [NSColor colorWithCalibratedWhite:0.0 alpha:1.0]; | ||||||||||||||||
|
|
||||||||||||||||
| @try { | ||||||||||||||||
| red = [rgbColor redComponent]; | ||||||||||||||||
| green = [rgbColor greenComponent]; | ||||||||||||||||
| blue = [rgbColor blueComponent]; | ||||||||||||||||
| alpha = [rgbColor alphaComponent]; | ||||||||||||||||
| } @catch (NSException *ex) { | ||||||||||||||||
| /* Last-resort safe defaults */ | ||||||||||||||||
| red = green = blue = 0.0; | ||||||||||||||||
| alpha = 1.0; | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+1587
to
+1605
|
||||||||||||||||
|
|
||||||||||||||||
| cairo_pattern_add_color_stop_rgba(cpattern, location, | ||||||||||||||||
| red, green, blue, alpha); | ||||||||||||||||
| } | ||||||||||||||||
|
|
@@ -1629,39 +1645,28 @@ - (void) drawGradient: (NSGradient*)gradient | |||||||||||||||
| double green; | ||||||||||||||||
| double blue; | ||||||||||||||||
| double alpha; | ||||||||||||||||
| NSString *colorSpaceName; | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| [gradient getColor: &color | ||||||||||||||||
| location: &location | ||||||||||||||||
| atIndex: i]; | ||||||||||||||||
|
|
||||||||||||||||
| colorSpaceName = [color colorSpaceName]; | ||||||||||||||||
| if([NSCalibratedRGBColorSpace isEqualToString: colorSpaceName] || | ||||||||||||||||
| [NSDeviceRGBColorSpace isEqualToString: colorSpaceName]) | ||||||||||||||||
| { | ||||||||||||||||
| red = [color redComponent]; | ||||||||||||||||
| green = [color greenComponent]; | ||||||||||||||||
| blue = [color blueComponent]; | ||||||||||||||||
| alpha = [color alphaComponent]; | ||||||||||||||||
| cairo_pattern_add_color_stop_rgba(cpattern, location, | ||||||||||||||||
| red, green, blue, alpha); | ||||||||||||||||
| } | ||||||||||||||||
| else if([NSCalibratedWhiteColorSpace isEqualToString: colorSpaceName] || | ||||||||||||||||
| [NSDeviceWhiteColorSpace isEqualToString: colorSpaceName] || | ||||||||||||||||
| [NSCalibratedBlackColorSpace isEqualToString: colorSpaceName] || | ||||||||||||||||
| [NSDeviceBlackColorSpace isEqualToString: colorSpaceName]) | ||||||||||||||||
| { | ||||||||||||||||
| red = [color whiteComponent]; | ||||||||||||||||
| green = [color whiteComponent]; | ||||||||||||||||
| blue = [color whiteComponent]; | ||||||||||||||||
| alpha = [color alphaComponent]; | ||||||||||||||||
| cairo_pattern_add_color_stop_rgba(cpattern, location, | ||||||||||||||||
| red, green, blue, alpha); | ||||||||||||||||
| } | ||||||||||||||||
| else | ||||||||||||||||
| { | ||||||||||||||||
| NSLog(@"Cannot draw gradient for %@",colorSpaceName); | ||||||||||||||||
| } | ||||||||||||||||
| /* Normalize to RGB-compatible color before extracting components */ | ||||||||||||||||
| NSColor *rgbColor = [color colorUsingColorSpaceName: NSDeviceRGBColorSpace]; | ||||||||||||||||
| if (!rgbColor) rgbColor = [color colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; | ||||||||||||||||
| if (!rgbColor) rgbColor = [NSColor colorWithCalibratedWhite:0.0 alpha:1.0]; | ||||||||||||||||
|
|
||||||||||||||||
| @try { | ||||||||||||||||
| red = [rgbColor redComponent]; | ||||||||||||||||
| green = [rgbColor greenComponent]; | ||||||||||||||||
| blue = [rgbColor blueComponent]; | ||||||||||||||||
| alpha = [rgbColor alphaComponent]; | ||||||||||||||||
| } @catch (NSException *ex) { | ||||||||||||||||
|
||||||||||||||||
| } @catch (NSException *ex) { | |
| } @catch (NSException *ex) { | |
| NSLog(@"CairoGState: Failed to convert color %@ to RGB components for gradient stop at location %f: %@ - %@", | |
| rgbColor, | |
| location, | |
| [ex name], | |
| [ex reason]); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| include $(GNUSTEP_MAKEFILES)/common.make | ||
|
||
|
|
||
| TOOL_NAME = testgradient | ||
|
|
||
| testgradient_OBJC_FILES = gradient_test.m | ||
|
|
||
| testgradient_TOOL_LIBS = -lgnustep-gui -lgnustep-base | ||
|
|
||
| include $(GNUSTEP_MAKEFILES)/tool.make | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #import <Foundation/Foundation.h> | ||
|
||
| #import <AppKit/AppKit.h> | ||
|
|
||
| int main (int argc, const char * argv[]) { | ||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||
|
|
||
| // Create a small pattern image and make a pattern color (non-RGB) | ||
| NSImage *pat = [[NSImage alloc] initWithSize:NSMakeSize(4,4)]; | ||
| [pat lockFocus]; | ||
| [[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:1.0] setFill]; | ||
| NSRectFill(NSMakeRect(0,0,4,4)); | ||
| [pat unlockFocus]; | ||
|
|
||
| NSColor *pattern = [NSColor colorWithPatternImage:pat]; | ||
|
|
||
| NSGradient *g = [[NSGradient alloc] initWithStartingColor:pattern endingColor:[NSColor colorWithCalibratedWhite:1.0 alpha:1.0]]; | ||
|
|
||
| NSImage *img = [[NSImage alloc] initWithSize:NSMakeSize(100,100)]; | ||
|
Comment on lines
+8
to
+18
|
||
| @try { | ||
| [img lockFocus]; | ||
| [g drawInRect:NSMakeRect(0,0,100,100) angle:90.0]; | ||
|
||
| [img unlockFocus]; | ||
|
Comment on lines
+18
to
+22
|
||
| NSLog(@"OK: gradient drawn without exception"); | ||
| } @catch (NSException *ex) { | ||
| NSLog(@"FAIL: exception: %@", ex); | ||
| return 1; | ||
| } | ||
|
|
||
| [pool drain]; | ||
| return 0; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent error handling may hide issues: When color conversion fails and the catch block assigns default black color values (red = green = blue = 0.0, alpha = 1.0), no warning or log message is generated. This makes debugging difficult if unexpected color conversions occur. Consider adding an NSLog statement in the catch block to help diagnose color conversion failures, similar to other error logging patterns in this file (e.g., line 160, 518, 567).