I get my first color by creating it with: set colorA to (current application's NSColor's colorWithCalibratedRed:0.299992 green:0.30457 blue:0.30457 alpha:1)
and the second color from an attributed string: set colorB to theFont's valueForKey:"NSColor"
They both have the same value in log panel: (*NSCalibratedRGBColorSpace 0.299992 0.30457 0.30457 1*)
But when I compare them using colorA's isEqual:colorB the result is false.
Is this an issue with Applescript’s inherent approximation on large numbers?
Or something else?
This code and my Mac mini M1 (macOS 13.6) returns true.
My MacBook Air M2 (macOS 14.6) returns true, too.
Which is your os and machine?
use AppleScript
use framework “Foundation”
use framework “AppKit”
use scripting additions
set colA to current application’s NSColor’s colorWithCalibratedRed:0.299992 green:0.30457 blue:0.30457 alpha:1
set colB to current application’s NSColor’s colorWithCalibratedRed:0.299992 green:0.30457 blue:0.30457 alpha:1
Post again. It reads RTF format information, converts it to a dictionary in list, and processes color matching with AppleScript. It is a function that is actually used in various AppleScripts, such as extracting color values from each RGB channel, extracting general color trends as color domains.
Using such AppleScript routines, we believe that we can make comparisons with numbers and characters.
Your script is more or less what I’m doing: I’m using color values to compare them.
Here is the handler I’m using to retrieve color values:
on getColorValues:colRange inText:colText
set theFont to colText's fontAttributesInRange:colRange
set theColor to theFont's valueForKey:"NSColor"
if theColor = missing value then return {}
set theRed to round ((theColor's redComponent()) * 1000000) rounding down
set theGreen to round ((theColor's greenComponent()) * 1000000) rounding down
set theBlue to round ((theColor's blueComponent()) * 1000000) rounding down
set theAlpha to theColor's alphaComponent()
set theSpace to theColor's colorSpace()
return {theRed, theGreen, theBlue, theAlpha, theSpace}
end getColorValues:inText:
And the following is to get the attribute runs, given an attributed string:
-- get attribute runs
set textStorage to (current application's NSTextStorage's alloc()'s initWithAttributedString:attString)
set attRuns to textStorage's attributeRuns()
@ionah what if you just compare the colors’ descriptions as strings:
set colorA to (current application's NSColor's colorWithCalibratedRed:0.299992 green:0.30457 blue:0.30457 alpha:1)
set colorB to theFont's valueForKey:"NSColor"
colorA's |description|()'s isEqualToString:(colorB's |description|())
@ionah
I played with your code, and both examples return boolean true with method:isEqual
use framework "Foundation"
use framework "AppKit"
use scripting additions
set theColor1 to current application's NSColor's redColor()
log theColor1's |description|() as string
set attrDict1 to current application's NSDictionary's dictionaryWithObject:theColor1 forKey:"NSForegroundColorAttributeName"
set attrString to current application's NSAttributedString's alloc()'s initWithString:"hello" attributes:attrDict1
set theColor2_2 to (attrString's attributesAtIndex:0 effectiveRange:(current application's NSMakeRange(0, 1)))'s valueForKey:"NSForegroundColorAttributeName"
set theColor2 to current application's NSColor's colorWithSRGBRed:1 green:0 blue:0 alpha:1
log (theColor1's isEqual:theColor2)
log (theColor1's isEqual:theColor2_2)
set theColor3 to (current application's NSColor's colorWithCalibratedRed:1 green:0 blue:0 alpha:1)
log theColor3's |description|() as string
set attrDict2 to current application's NSDictionary's dictionaryWithObject:theColor3 forKey:"NSForegroundColorAttributeName"
set attrString to current application's NSAttributedString's alloc()'s initWithString:"hello" attributes:attrDict2
set theColor4 to (attrString's attributesAtIndex:0 effectiveRange:(current application's NSMakeRange(0, 1)))'s valueForKey:"NSForegroundColorAttributeName"
log (theColor3's isEqual:theColor4)
The colors I use come from several client documents, generated on PC by a database manager.
RGB values in those documents are up to 12 digits when I load them using AppleScriptObjC.
The problem here is that if we look for the color value in the result or log pane, it will return values rounded to 6 digits.
The only way to get the complete value is to ask for individual components like in this example:
use framework "Foundation"
set theRed to (current application's NSColor's colorWithCalibratedRed:0.654987321987 green:0 blue:0 alpha:1)
log theRed's redComponent()
log theRed
return theRed
If I’m correct CGFloat could be float or double. So I took @leo_r info and convert it to NSNumber
use framework "Foundation"
use framework "AppKit"
use scripting additions
set theColor1 to (current application's NSColor's colorWithCalibratedRed:0.123456789123 green:0 blue:0 alpha:1)
log theColor1's |description|() as string
log theColor1's |debugDescription|() as string
set theNumber1 to current application's NSNumber's numberWithDouble:(theColor1's redComponent())
log theNumber1's |debugDescription|() as string
set attrDict2 to current application's NSDictionary's dictionaryWithObject:theColor1 forKey:"NSForegroundColorAttributeName"
set attrString to current application's NSAttributedString's alloc()'s initWithString:"hello" attributes:attrDict2
set theColor2 to (attrString's attributesAtIndex:0 effectiveRange:(current application's NSMakeRange(0, 1)))'s valueForKey:"NSForegroundColorAttributeName"
set theNumber2 to current application's NSNumber's numberWithDouble:(theColor2's redComponent())
log theNumber2's |debugDescription|() as string
log theColor2's |description|() as string
log theColor2's |debugDescription|() as string
-- 6 digits
log (theColor1's isEqual:theColor2)
-- 12 digits
log (theNumber1's isEqual:theNumber2)