Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.