Created
January 11, 2012 12:44
-
-
Save pita5/1594494 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // These classese should be treated as immutable | |
| @interface MWAttributedString : NSObject <NSCoding> | |
| - (id)initWithAttributedString:(NSAttributedString *)string; | |
| - (NSAttributedString *)attributedString; | |
| @end | |
| @interface MWFont : NSObject <NSCoding> | |
| - (id)initWithFont:(CTFontRef)font; | |
| - (CTFontRef)fontRef; | |
| @end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #import "MWAttributedString.h" | |
| @interface MWAttributedString () | |
| @property (nonatomic, retain) NSAttributedString *attributedString; | |
| @property (nonatomic, copy) NSString *string; | |
| @property (nonatomic, retain) NSArray *attributes; | |
| @end | |
| @implementation MWAttributedString | |
| @synthesize | |
| string=_string, | |
| attributes=_attributes, | |
| attributedString=_attributedString; | |
| - (id)initWithAttributedString:(NSAttributedString *)string | |
| { | |
| if ((self = [super init])) | |
| { | |
| __block BOOL error = NO; | |
| NSMutableArray *attributes = [NSMutableArray array]; | |
| [string enumerateAttributesInRange:NSMakeRange(0, [string length]) | |
| options:0 | |
| usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stopAttrsInRange) | |
| { | |
| __block NSMutableDictionary *attributeDict = [NSMutableDictionary dictionary]; | |
| [attributeDict setObject:NSStringFromRange(range) | |
| forKey:@"range"]; | |
| [attrs enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stopAttrs) { | |
| if ([obj conformsToProtocol:@protocol(NSCoding)]) | |
| { | |
| [attributeDict setObject:obj | |
| forKey:key]; | |
| } | |
| else | |
| { | |
| if ([key isEqualToString:@"CTForegroundColor"] || | |
| [key isEqualToString:@"CTStrokeColor"]) | |
| { | |
| UIColor *color = [UIColor colorWithCGColor:(CGColorRef)obj]; | |
| [attributeDict setObject:color | |
| forKey:key]; | |
| } | |
| else if ([key isEqualToString:@"NSFont"]) | |
| { | |
| CTFontRef font = (CTFontRef)obj; | |
| if(!font) | |
| { | |
| error = YES; *stopAttrs = YES; *stopAttrsInRange = YES; | |
| return; | |
| } | |
| [attributeDict setObject:[[[MWFont alloc] initWithFont:font] autorelease] | |
| forKey:key]; | |
| } | |
| else | |
| { | |
| // Something in here | |
| NSLog(@"something %@", key); | |
| } | |
| } | |
| [attributes addObject:attributeDict]; | |
| }]; | |
| }]; | |
| if (error) | |
| { | |
| [self release]; | |
| return nil; | |
| } | |
| [self setAttributes:attributes]; | |
| [self setString:[string string]]; | |
| [self setAttributedString:string]; | |
| } | |
| return self; | |
| } | |
| - (void)dealloc | |
| { | |
| self.attributedString = nil; | |
| self.attributes = nil; | |
| self.string = nil; | |
| [super dealloc]; | |
| } | |
| - (NSAttributedString *)attributedString | |
| { | |
| if (!_string || !_attributes) | |
| return nil; | |
| if (_attributedString) | |
| return _attributedString; | |
| NSMutableAttributedString *str = [[[NSMutableAttributedString alloc] initWithString:_string] autorelease]; | |
| for (NSDictionary *dict in _attributes) | |
| { | |
| NSRange range = NSRangeFromString([dict objectForKey:@"range"]); | |
| [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { | |
| if (![key isEqualToString:@"range"]) | |
| [str addAttribute:key value:obj range:range]; | |
| }]; | |
| } | |
| [self setAttributedString:str]; | |
| return str; | |
| } | |
| - (void)encodeWithCoder:(NSCoder *)coder | |
| { | |
| [coder encodeObject:_attributes | |
| forKey:@"attributes"]; | |
| [coder encodeObject:_string | |
| forKey:@"string"]; | |
| } | |
| - (id)initWithCoder:(NSCoder *)coder | |
| { | |
| if ((self = [super init])) | |
| { | |
| [self setString:[coder decodeObjectForKey:@"string"]]; | |
| [self setAttributes:[coder decodeObjectForKey:@"attributes"]]; | |
| if (!_attributedString) | |
| { | |
| NSMutableArray *decodedAttributes = [NSMutableArray array]; | |
| for (NSDictionary *attr in _attributes) | |
| { | |
| NSMutableDictionary *copy = [attr mutableCopy]; | |
| if ([attr objectForKey:@"NSFont"]) | |
| { | |
| MWFont *font = [attr objectForKey:@"NSFont"]; | |
| if (![font isKindOfClass:[MWFont class]]) | |
| continue; | |
| [copy setObject:(id)[font fontRef] | |
| forKey:@"NSFont"]; | |
| } | |
| [decodedAttributes addObject:copy]; | |
| } | |
| [self setAttributes:decodedAttributes]; | |
| } | |
| } | |
| return self; | |
| } | |
| @end | |
| @interface MWFont () | |
| @property (nonatomic, retain) NSDictionary *attributes; | |
| @property (nonatomic, assign) CTFontRef font; | |
| @end | |
| @implementation MWFont | |
| @synthesize | |
| attributes=_attributes, | |
| font=_font; | |
| - (void)dealloc | |
| { | |
| if (_font) | |
| CFRelease(_font); _font = NULL; | |
| self.attributes = nil; | |
| [super dealloc]; | |
| } | |
| - (id)initWithFont:(CTFontRef)font | |
| { | |
| if ((self = [super init])) | |
| { | |
| CTFontDescriptorRef descriptor = CTFontCopyFontDescriptor(font); | |
| if (!descriptor) | |
| { | |
| [self release]; | |
| return nil; | |
| } | |
| CFDictionaryRef attrs = CTFontDescriptorCopyAttributes(descriptor); | |
| [self setAttributes:[NSDictionary dictionaryWithDictionary:(NSDictionary *)attrs]]; | |
| CFRelease(attrs), attrs = NULL; | |
| CFRelease(descriptor), descriptor = NULL; | |
| _font = NULL; | |
| } | |
| return self; | |
| } | |
| - (void)encodeWithCoder:(NSCoder *)coder | |
| { | |
| if (_font) { | |
| CFRelease(_font); _font = NULL; | |
| } | |
| [coder encodeObject:_attributes | |
| forKey:@"attributes"]; | |
| } | |
| - (id)initWithCoder:(NSCoder *)coder | |
| { | |
| if ((self = [super init])) | |
| { | |
| [self setAttributes:[coder decodeObjectForKey:@"attributes"]]; | |
| _font = NULL; | |
| } | |
| return self; | |
| } | |
| - (CTFontRef)fontRef | |
| { | |
| if (_font) | |
| return _font; | |
| CTFontDescriptorRef fontDescriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)_attributes); | |
| CTFontRef font = CTFontCreateWithFontDescriptor(fontDescriptor, [[_attributes objectForKey:@"NSFontSizeAttribute"] floatValue], NULL); | |
| _font = font; | |
| CFRelease(fontDescriptor), fontDescriptor = NULL; | |
| return _font; | |
| } | |
| @end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment