Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -180,10 +180,11 @@ OFBitSetCharacterSet.m \ OFBytesValue.m \ OFCRC16.m \ OFCRC32.m \ OFConcreteArray.m \ + OFConcreteColor.m \ OFConcreteData.m \ OFConcreteMutableArray.m \ OFConcreteMutableData.m \ OFConcreteSubarray.m \ OFCountedMapTableSet.m \ @@ -206,10 +207,11 @@ OFSandbox.m \ OFSizeValue.m \ OFStrPTime.m \ OFSubarray.m \ OFSubdata.m \ + OFTaggedPointerColor.m \ OFUTF8String.m \ ${LIBBASES_M} \ ${RUNTIME_AUTORELEASE_M} \ ${RUNTIME_INSTANCE_M} \ ${UNICODE_M} Index: src/OFColor.m ================================================================== --- src/OFColor.m +++ src/OFColor.m @@ -16,41 +16,27 @@ #include "config.h" #include #import "OFColor.h" +#import "OFConcreteColor.h" #import "OFOnce.h" #import "OFString.h" - -#import "OFInvalidArgumentException.h" - -@interface OFConcreteColor: OFColor -{ - float _red, _green, _blue, _alpha; - OF_RESERVE_IVARS(OFColor, 4) -} -@end +#import "OFTaggedPointerColor.h" @interface OFColorSingleton: OFConcreteColor @end @interface OFColorPlaceholder: OFColorSingleton @end -#ifdef OF_OBJFW_RUNTIME -@interface OFTaggedPointerColor: OFColorSingleton -@end - -static const float allowedImprecision = 0.0000001; -#endif - static struct { Class isa; } placeholder; #ifdef OF_OBJFW_RUNTIME -static int colorTag; +static const float allowedImprecision = 0.0000001; #endif @implementation OFColorPlaceholder - (instancetype)initWithRed: (float)red green: (float)green @@ -63,13 +49,13 @@ uint8_t blueInt = nearbyintf(blue * 255); if (fabsf(red * 255 - redInt) < allowedImprecision && fabsf(green * 255 - greenInt) < allowedImprecision && fabsf(blue * 255 - blueInt) < allowedImprecision && alpha == 1) { - id ret = objc_createTaggedPointer(colorTag, - (uintptr_t)redInt << 16 | (uintptr_t)greenInt << 8 | - (uintptr_t)blueInt); + id ret = [OFTaggedPointerColor colorWithRed: redInt + green: greenInt + blue: blueInt]; if (ret != nil) return ret; } #endif @@ -100,81 +86,15 @@ { return OFMaxRetainCount; } @end -@implementation OFConcreteColor -- (instancetype)initWithRed: (float)red - green: (float)green - blue: (float)blue - alpha: (float)alpha -{ - self = [super init]; - - @try { - if (red < 0.0 || red > 1.0 || - green < 0.0 || green > 1.0 || - blue < 0.0 || blue > 1.0 || - alpha < 0.0 || alpha > 1.0) - @throw [OFInvalidArgumentException exception]; - - _red = red; - _green = green; - _blue = blue; - _alpha = alpha; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)getRed: (float *)red - green: (float *)green - blue: (float *)blue - alpha: (float *)alpha -{ - *red = _red; - *green = _green; - *blue = _blue; - - if (alpha != NULL) - *alpha = _alpha; -} -@end - -#ifdef OF_OBJFW_RUNTIME -@implementation OFTaggedPointerColor -- (void)getRed: (float *)red - green: (float *)green - blue: (float *)blue - alpha: (float *)alpha -{ - uintptr_t value = object_getTaggedPointerValue(self); - - *red = (float)(value >> 16) / 255; - *green = (float)((value >> 8) & 0xFF) / 255; - *blue = (float)(value & 0xFF) / 255; - - if (alpha != NULL) - *alpha = 1; -} -@end -#endif - @implementation OFColor + (void)initialize { - if (self != [OFColor class]) - return; - - object_setClass((id)&placeholder, [OFColorPlaceholder class]); -#ifdef OF_OBJFW_RUNTIME - colorTag = - objc_registerTaggedPointerClass([OFTaggedPointerColor class]); -#endif + if (self == [OFColor class]) + object_setClass((id)&placeholder, [OFColorPlaceholder class]); } + (instancetype)alloc { if (self == [OFColor class]) ADDED src/OFConcreteColor.h Index: src/OFConcreteColor.h ================================================================== --- src/OFConcreteColor.h +++ src/OFConcreteColor.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008-2023 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFColor.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OFConcreteColor: OFColor +{ + float _red, _green, _blue, _alpha; +} +@end + +OF_ASSUME_NONNULL_END ADDED src/OFConcreteColor.m Index: src/OFConcreteColor.m ================================================================== --- src/OFConcreteColor.m +++ src/OFConcreteColor.m @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008-2023 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFConcreteColor.h" + +#import "OFInvalidArgumentException.h" + +@implementation OFConcreteColor +- (instancetype)initWithRed: (float)red + green: (float)green + blue: (float)blue + alpha: (float)alpha +{ + self = [super init]; + + @try { + if (red < 0.0 || red > 1.0 || + green < 0.0 || green > 1.0 || + blue < 0.0 || blue > 1.0 || + alpha < 0.0 || alpha > 1.0) + @throw [OFInvalidArgumentException exception]; + + _red = red; + _green = green; + _blue = blue; + _alpha = alpha; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)getRed: (float *)red + green: (float *)green + blue: (float *)blue + alpha: (float *)alpha +{ + *red = _red; + *green = _green; + *blue = _blue; + + if (alpha != NULL) + *alpha = _alpha; +} +@end + ADDED src/OFTaggedPointerColor.h Index: src/OFTaggedPointerColor.h ================================================================== --- src/OFTaggedPointerColor.h +++ src/OFTaggedPointerColor.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2008-2023 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFColor.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifdef OF_OBJFW_RUNTIME +@interface OFTaggedPointerColor: OFColor ++ (instancetype)colorWithRed: (uint8_t)red + green: (uint8_t)green + blue: (uint8_t)blue; +@end +#endif + +OF_ASSUME_NONNULL_END ADDED src/OFTaggedPointerColor.m Index: src/OFTaggedPointerColor.m ================================================================== --- src/OFTaggedPointerColor.m +++ src/OFTaggedPointerColor.m @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2008-2023 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFTaggedPointerColor.h" + +#ifdef OF_OBJFW_RUNTIME +static int colorTag; + +@implementation OFTaggedPointerColor ++ (void)initialize +{ + if (self == [OFTaggedPointerColor class]) + colorTag = objc_registerTaggedPointerClass(self); +} + ++ (instancetype)colorWithRed: (uint8_t)red + green: (uint8_t)green + blue: (uint8_t)blue +{ + return objc_createTaggedPointer(colorTag, + (uintptr_t)red << 16 | (uintptr_t)green << 8 | (uintptr_t)blue); +} + +- (void)getRed: (float *)red + green: (float *)green + blue: (float *)blue + alpha: (float *)alpha +{ + uintptr_t value = object_getTaggedPointerValue(self); + + *red = (float)(value >> 16) / 255; + *green = (float)((value >> 8) & 0xFF) / 255; + *blue = (float)(value & 0xFF) / 255; + + if (alpha != NULL) + *alpha = 1; +} + +- (instancetype)retain +{ + return self; +} + +- (instancetype)autorelease +{ + return self; +} + +- (void)release +{ +} + +- (void)dealloc +{ + OF_DEALLOC_UNSUPPORTED +} +@end +#endif