Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Revert rendering back to CoreText

UIKit cannot render dynamically loaded CT fonts on iOS. CATextLayer cannot position algorithmically. Nominal support for CALayer#contentsGravity.
  • Loading branch information...
commit 1ae91a6d29eef84767b50022c2aa822e2ceb816b 1 parent f5354bc
@dnalot dnalot authored
View
4 FontasticIcons.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'FontasticIcons'
- s.version = '0.1.2'
+ s.version = '0.2.0'
s.summary = 'Objective-C wrapper for iconic fonts.'
s.description = <<-DESC
- [Entypo](http://entypo.com) pictograms by Daniel Bruce
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.license = 'MIT'
s.author = { 'Alex Denisov' => '1101.debian@gmail.com' }
s.source = { :git => 'https://github.com/AlexDenisov/FontasticIcons.git', :tag => "#{s.version}" }
- s.platform = :ios
+ s.platform = :ios, '3.2'
s.source_files = 'FontasticIcons/Sources/Classes'
s.resources = 'FontasticIcons/Sources/Resources/Fonts/*'
s.frameworks = 'CoreText', 'QuartzCore'
View
6 FontasticIcons.xcodeproj/project.pbxproj
@@ -35,6 +35,7 @@
CA7C5609163E433400AC32A3 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA7C5608163E433400AC32A3 /* CoreText.framework */; };
CA7C561A163EFBCC00AC32A3 /* FIEntypoSocialIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = CA7C5619163EFBCC00AC32A3 /* FIEntypoSocialIcon.m */; };
CA7C561E163F060500AC32A3 /* FIMetaInfoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CA7C561D163F060500AC32A3 /* FIMetaInfoManager.m */; };
+ E1B6DBF51693A4A600B6704C /* FIIconLayer+FIRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = B0E07B56EB080A788441AB2E /* FIIconLayer+FIRenderer.m */; };
E1EC0266168FE25D004A8EDD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1EC0263168FE23B004A8EDD /* QuartzCore.framework */; };
/* End PBXBuildFile section */
@@ -43,9 +44,11 @@
B0E071BA8380551D25FD2D4E /* FIIcon+Impl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FIIcon+Impl.m"; sourceTree = "<group>"; };
B0E0777366E59C96383968B1 /* FIIconRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIIconRendering.h; sourceTree = "<group>"; };
B0E07850BEB4C2B283D2B5ED /* FIIconLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIIconLayer.m; sourceTree = "<group>"; };
+ B0E07B56EB080A788441AB2E /* FIIconLayer+FIRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FIIconLayer+FIRenderer.m"; sourceTree = "<group>"; };
B0E07BBBF4C52B8C81F77A17 /* FIIcon+Impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FIIcon+Impl.h"; sourceTree = "<group>"; };
B0E07CBF20E7F6200491F0BF /* FIRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIRenderer.h; sourceTree = "<group>"; };
B0E07DAC8153129F1E3083B1 /* FIIcon+FIIconRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FIIcon+FIIconRenderer.m"; sourceTree = "<group>"; };
+ B0E07DB134AFAE78AD220A42 /* FIIconLayer+FIRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FIIconLayer+FIRenderer.h"; sourceTree = "<group>"; };
B0E07F9CA8E68482CC5775F0 /* FIIcon+FIIconRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FIIcon+FIIconRenderer.h"; sourceTree = "<group>"; };
CA31B9A51657E194002A9EDD /* FIFontListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIFontListViewController.h; sourceTree = "<group>"; };
CA31B9A61657E194002A9EDD /* FIFontListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIFontListViewController.m; sourceTree = "<group>"; };
@@ -271,6 +274,8 @@
B0E07DAC8153129F1E3083B1 /* FIIcon+FIIconRenderer.m */,
B0E07F9CA8E68482CC5775F0 /* FIIcon+FIIconRenderer.h */,
B0E07CBF20E7F6200491F0BF /* FIRenderer.h */,
+ B0E07B56EB080A788441AB2E /* FIIconLayer+FIRenderer.m */,
+ B0E07DB134AFAE78AD220A42 /* FIIconLayer+FIRenderer.h */,
);
name = FIIconRendering;
sourceTree = "<group>";
@@ -394,6 +399,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ E1B6DBF51693A4A600B6704C /* FIIconLayer+FIRenderer.m in Sources */,
CA7C55D1163DC00700AC32A3 /* main.m in Sources */,
CA7C55D5163DC00700AC32A3 /* FIAppDelegate.m in Sources */,
CA7C55DE163DC00700AC32A3 /* FIViewController.m in Sources */,
View
7 FontasticIcons/Sample/FontasticIcons-Info.plist
@@ -24,13 +24,6 @@
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
- <key>UIAppFonts</key>
- <array>
- <string>Entypo.otf</string>
- <string>Entypo-Social.otf</string>
- <string>fontawesome.ttf</string>
- <string>iconic.otf</string>
- </array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
View
4 FontasticIcons/Sources/Classes/FIFont.m
@@ -51,10 +51,6 @@ - (NSString *)fontName {
return (NSString *)CTFontCopyFullName(self.fontRef);
}
-- (NSString *)UIFontName {
- return (NSString *)CTFontCopyPostScriptName(self.fontRef);
-}
-
#pragma mark - Fonts
+ (FIFont *)entypoFont {
View
1  FontasticIcons/Sources/Classes/FIFont_Private.h
@@ -13,7 +13,6 @@
+ (FIFont *)fontWithName:(NSString *)aName ofType:(NSString *)aType;
- (FIFont *)initWithFontName:(NSString *)aName ofType:(NSString *)aType;
-- (NSString *)UIFontName;
- (CTFontRef)fontRef;
@end
View
2  FontasticIcons/Sources/Classes/FIIcon+FIIconRenderer.h
@@ -7,7 +7,7 @@
//
#import "FIIcon.h"
-#import "FIIconLayer.h"
+#import "FIIconLayer+FIRenderer.h"
@interface FIIcon (FIIconRenderer)
View
16 FontasticIcons/Sources/Classes/FIIconLayer+FIRenderer.h
@@ -0,0 +1,16 @@
+//
+// FIIconLayer(FIRenderer)
+// FontasticIcons
+//
+// Created by Jonathan Toland on 1.1.13.
+// Copyright (c) 2012 Alex Denisov. All rights reserved.
+//
+
+#import "FIIconLayer.h"
+#import "FIRenderer.h"
+
+typedef id <FIRenderer, FIIconRendering> FIIconRenderer;
+
+@interface FIIconLayer (FIRenderer) <FIRenderer>
+
+@end
View
60 FontasticIcons/Sources/Classes/FIIconLayer+FIRenderer.m
@@ -0,0 +1,60 @@
+//
+// FIIconLayer(FIRenderer)
+// FontasticIcons
+//
+// Created by Jonathan Toland on 1.1.13.
+// Copyright (c) 2012 Alex Denisov. All rights reserved.
+//
+
+#import <CoreText/CoreText.h>
+#import "FIIconLayer+FIRenderer.h"
+#import "FIUtils.h"
+
+@implementation FIIconLayer (FIRenderer)
+
+#pragma mark self <FIRenderer>
+@dynamic bounds;
+
+- (UIImage *)image {
+ UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
+ [self renderInContext:UIGraphicsGetCurrentContext()];
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ return image;
+}
+
+#pragma mark super
+- (void)drawInContext:(CGContextRef)ctx {
+ CTLineRef line = CTLineCreateWithAttributedString(arcsafe_toll_free_bridge(CFAttributedStringRef, self.iconString));
+ [self setTransformForContext:ctx
+ bounds:CGRectInset(CGContextGetClipBoundingBox(ctx), self.inset.x, self.inset.y)
+ iconBounds:CTLineGetImageBounds(line, ctx)];
+ CTLineDraw(line, ctx);
+ CFRelease((CFTypeRef) line);
+ [super drawInContext:ctx];
+}
+
+#pragma mark private
+- (void)setTransformForContext:(CGContextRef)ctx bounds:(CGRect)bounds iconBounds:(CGRect)iconBounds {
+ CGPoint scale = [self scaleForBounds:bounds iconBounds:iconBounds];
+ CGAffineTransform t = CGAffineTransformScale(CGAffineTransformMakeTranslation(
+ bounds.origin.x, bounds.size.height + bounds.origin.y), scale.x, -scale.y);
+ CGContextConcatCTM(ctx, t);
+ CGRect scaleBounds = CGRectApplyAffineTransform(bounds, CGAffineTransformInvert(t));
+ CGContextSetTextPosition(ctx,
+ -iconBounds.origin.x + (scaleBounds.size.width - iconBounds.size.width) / 2,
+ -iconBounds.origin.y + (scaleBounds.size.height - iconBounds.size.height) / 2);
+}
+
+- (CGPoint)scaleForBounds:(CGRect)bounds iconBounds:(CGRect)iconBounds {
+ CGFloat sx = bounds.size.width / iconBounds.size.width;
+ CGFloat sy = bounds.size.height / iconBounds.size.height;
+ if ([self.contentsGravity isEqualToString:kCAGravityResizeAspectFill]) {
+ sx = sy = fmaxf(sx, sy);
+ } else if (![self.contentsGravity isEqualToString:kCAGravityResize]) {
+ sx = sy = fminf(sx, sy);
+ }
+ return CGPointMake(sx, sy);
+}
+
+@end
View
6 FontasticIcons/Sources/Classes/FIIconLayer.h
@@ -7,11 +7,11 @@
//
#import <QuartzCore/QuartzCore.h>
-#import "FIRenderer.h"
#import "FIIconRendering.h"
-typedef id <FIRenderer, FIIconRendering> FIIconRenderer;
+@interface FIIconLayer : CALayer <FIIconRendering>
-@interface FIIconLayer : CALayer <FIRenderer, FIIconRendering>
+@property(nonatomic, copy, readonly) NSAttributedString *iconString;
+-(void)setIconAttribute:(CFStringRef)name value:(CFTypeRef)value;
@end
View
74 FontasticIcons/Sources/Classes/FIIconLayer.m
@@ -12,75 +12,67 @@
#import "FIIcon_Private.h"
#import "FIFont_Private.h"
-@implementation FIIconLayer
+@implementation FIIconLayer {
+ NSMutableDictionary *iconAttributes;
+}
-#pragma mark self <FIRenderer>
-- (UIImage *)image {
- UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
- [self renderInContext:UIGraphicsGetCurrentContext()];
- UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return image;
+#pragma mark self
+- (NSAttributedString *)iconString {
+ return arcsafe_autorelease([[NSAttributedString alloc] initWithString:self.icon.iconString ? : @""
+ attributes:iconAttributes]);
+}
+
+- (void)setIconAttribute:(CFStringRef)name value:(CFTypeRef)value {
+ if (value) {
+ iconAttributes[arcsafe_toll_free_bridge(NSString *, name)] = arcsafe_toll_free_bridge(id, value);
+ } else {
+ [iconAttributes removeObjectForKey:arcsafe_toll_free_bridge(NSString *, name)];
+ }
+ [self setNeedsDisplay];
}
#pragma mark self <FIIconRendering>
-@synthesize inset = _inset, iconColor=_iconColor, icon= _icon;
+@synthesize inset = _inset, iconColor = _iconColor, icon = _icon;
-- (void)setInset:(CGPoint)inset {
- if (!(CGPointEqualToPoint(inset, _inset))) {
- _inset = inset;
- [self setNeedsDisplay];
+- (void)setIcon:(FIIcon *)icon {
+ CFTypeRef font = (CFTypeRef) [[icon.class metaFont] fontRef];
+ if (font != [[_icon.class metaFont] fontRef] || ![icon.iconString isEqualToString:_icon.iconString]) {
+ _icon = icon.copy;
+ [self setIconAttribute:kCTFontAttributeName value:font];
}
}
- (void)setIconColor:(UIColor *)iconColor {
if (![iconColor isEqual:_iconColor]) {
_iconColor = iconColor.copy;
- [self setNeedsDisplay];
+ [self setIconAttribute:kCTForegroundColorAttributeName value:_iconColor.CGColor];
}
}
-- (void)setIcon:(FIIcon *)icon {
- if (![icon.iconString isEqualToString:_icon.iconString] || ![icon.fontSetName isEqualToString:_icon.fontSetName]) {
- _icon = icon.copy;
+- (void)setInset:(CGPoint)inset {
+ if (!(CGPointEqualToPoint(inset, _inset))) {
+ _inset = inset;
[self setNeedsDisplay];
}
}
-#pragma mark super
-- (void)drawInContext:(CGContextRef)ctx {
- UIGraphicsPushContext(ctx);
- const CGFloat kFontOversize = 1000;
- CGRect bounds = CGContextGetClipBoundingBox(ctx);
- bounds = CGRectMake(bounds.origin.x + self.inset.x, bounds.origin.y + self.inset.y,
- bounds.size.width - self.inset.x * 2, bounds.size.height - self.inset.y * 2);
- //region calculate scale of oversize glyph to aspect fit bounds
- UIFont *font = [UIFont fontWithName:[[self.icon.class metaFont] UIFontName] size:kFontOversize];
- CGSize oversize = [self.icon.iconString sizeWithFont:font];
- float scale = fminf(bounds.size.width / oversize.width, bounds.size.height / oversize.height);
- //endregion
- //region scale font size and center drawing rectangle
- font = [font fontWithSize:kFontOversize * scale];
- CGRect rect = CGRectMake(bounds.origin.x, bounds.origin.y, oversize.width * scale, oversize.height * scale);
- rect = CGRectOffset(rect, (bounds.size.width - rect.size.width) / 2, (bounds.size.height - rect.size.height) / 2);
- //endregion
- [self.iconColor set];
- [self.icon.iconString drawInRect:rect withFont:font];
- UIGraphicsPopContext();
-}
-
#pragma mark super : NSObject
- (id)init {
self = [super init];
if (self) {
+ iconAttributes = [[NSMutableDictionary alloc] initWithCapacity:2];
self.needsDisplayOnBoundsChange = YES;
+ self.contentsGravity = kCAGravityResizeAspect;
+ // http://markpospesel.wordpress.com/2012/07/10/on-the-importance-of-setting-contentsscale-in-catextlayer/
+ self.contentsScale = [UIScreen mainScreen].scale;
}
return self;
}
- (void)dealloc {
- self.icon = nil;
- self.iconColor = nil;
+ arcsafe_release(_icon);
+ arcsafe_release(_iconColor);
+ arcsafe_release(iconAttributes);
arcsafe_super_dealloc();
}
View
4 FontasticIcons/Sources/Classes/FIIconRendering.h
@@ -10,8 +10,8 @@
@protocol FIIconRendering
-@property (nonatomic, assign) CGPoint inset;
-@property (nonatomic, copy) UIColor *iconColor;
@property (nonatomic, copy) FIIcon *icon;
+@property (nonatomic, copy) UIColor *iconColor;
+@property (nonatomic, assign) CGPoint inset;
@end
View
2  FontasticIcons/Sources/Classes/FIIconView.h
@@ -13,7 +13,7 @@
@interface FIIconView : UIView <FIIconRendering>
-@property(nonatomic, strong, readonly) FIIconLayer *iconLayer;
+@property(nonatomic, retain, readonly) FIIconLayer *iconLayer;
@property (nonatomic, assign) CGFloat padding;
@end
View
2  FontasticIcons/Sources/Classes/FIIconView.m
@@ -26,7 +26,7 @@ - (void)setPadding:(CGFloat)padding {
}
#pragma mark self <FIIconRendering>
-@dynamic inset, iconColor, icon;
+@dynamic icon, iconColor, inset;
#pragma mark super
+ (Class)layerClass {
Please sign in to comment.
Something went wrong with that request. Please try again.