summary refs log tree commit diff stats
path: root/libs/FontLabel/FontLabel.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/FontLabel/FontLabel.m')
-rwxr-xr-xlibs/FontLabel/FontLabel.m195
1 files changed, 195 insertions, 0 deletions
diff --git a/libs/FontLabel/FontLabel.m b/libs/FontLabel/FontLabel.m new file mode 100755 index 0000000..58975b1 --- /dev/null +++ b/libs/FontLabel/FontLabel.m
@@ -0,0 +1,195 @@
1//
2// FontLabel.m
3// FontLabel
4//
5// Created by Kevin Ballard on 5/8/09.
6// Copyright © 2009 Zynga Game Networks
7//
8//
9// Licensed under the Apache License, Version 2.0 (the "License");
10// you may not use this file except in compliance with the License.
11// You may obtain a copy of the License at
12//
13// http://www.apache.org/licenses/LICENSE-2.0
14//
15// Unless required by applicable law or agreed to in writing, software
16// distributed under the License is distributed on an "AS IS" BASIS,
17// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18// See the License for the specific language governing permissions and
19// limitations under the License.
20//
21
22#import "FontLabel.h"
23#import "FontManager.h"
24#import "FontLabelStringDrawing.h"
25#import "ZFont.h"
26
27@interface ZFont (ZFontPrivate)
28@property (nonatomic, readonly) CGFloat ratio;
29@end
30
31@implementation FontLabel
32@synthesize zFont;
33@synthesize zAttributedText;
34
35- (id)initWithFrame:(CGRect)frame fontName:(NSString *)fontName pointSize:(CGFloat)pointSize {
36 return [self initWithFrame:frame zFont:[[FontManager sharedManager] zFontWithName:fontName pointSize:pointSize]];
37}
38
39- (id)initWithFrame:(CGRect)frame zFont:(ZFont *)font {
40 if ((self = [super initWithFrame:frame])) {
41 zFont = [font retain];
42 }
43 return self;
44}
45
46- (id)initWithFrame:(CGRect)frame font:(CGFontRef)font pointSize:(CGFloat)pointSize {
47 return [self initWithFrame:frame zFont:[ZFont fontWithCGFont:font size:pointSize]];
48}
49
50- (CGFontRef)cgFont {
51 return self.zFont.cgFont;
52}
53
54- (void)setCGFont:(CGFontRef)font {
55 if (self.zFont.cgFont != font) {
56 self.zFont = [ZFont fontWithCGFont:font size:self.zFont.pointSize];
57 }
58}
59
60- (CGFloat)pointSize {
61 return self.zFont.pointSize;
62}
63
64- (void)setPointSize:(CGFloat)pointSize {
65 if (self.zFont.pointSize != pointSize) {
66 self.zFont = [ZFont fontWithCGFont:self.zFont.cgFont size:pointSize];
67 }
68}
69
70- (void)setZAttributedText:(ZAttributedString *)attStr {
71 if (zAttributedText != attStr) {
72 [zAttributedText release];
73 zAttributedText = [attStr copy];
74 [self setNeedsDisplay];
75 }
76}
77
78- (void)drawTextInRect:(CGRect)rect {
79 if (self.zFont == NULL && self.zAttributedText == nil) {
80 [super drawTextInRect:rect];
81 return;
82 }
83
84 if (self.zAttributedText == nil) {
85 // this method is documented as setting the text color for us, but that doesn't appear to be the case
86 if (self.highlighted) {
87 [(self.highlightedTextColor ?: [UIColor whiteColor]) setFill];
88 } else {
89 [(self.textColor ?: [UIColor blackColor]) setFill];
90 }
91
92 ZFont *actualFont = self.zFont;
93 CGSize origSize = rect.size;
94 if (self.numberOfLines == 1) {
95 origSize.height = actualFont.leading;
96 CGPoint point = CGPointMake(rect.origin.x,
97 rect.origin.y + roundf(((rect.size.height - actualFont.leading) / 2.0f)));
98 CGSize size = [self.text sizeWithZFont:actualFont];
99 if (self.adjustsFontSizeToFitWidth && self.minimumFontSize < actualFont.pointSize) {
100 if (size.width > origSize.width) {
101 CGFloat desiredRatio = (origSize.width * actualFont.ratio) / size.width;
102 CGFloat desiredPointSize = desiredRatio * actualFont.pointSize / actualFont.ratio;
103 actualFont = [actualFont fontWithSize:MAX(MAX(desiredPointSize, self.minimumFontSize), 1.0f)];
104 size = [self.text sizeWithZFont:actualFont];
105 }
106 if (!CGSizeEqualToSize(origSize, size)) {
107 switch (self.baselineAdjustment) {
108 case UIBaselineAdjustmentAlignCenters:
109 point.y += roundf((origSize.height - size.height) / 2.0f);
110 break;
111 case UIBaselineAdjustmentAlignBaselines:
112 point.y += (self.zFont.ascender - actualFont.ascender);
113 break;
114 case UIBaselineAdjustmentNone:
115 break;
116 }
117 }
118 }
119 size.width = MIN(size.width, origSize.width);
120 // adjust the point for alignment
121 switch (self.textAlignment) {
122 case UITextAlignmentLeft:
123 break;
124 case UITextAlignmentCenter:
125 point.x += (origSize.width - size.width) / 2.0f;
126 break;
127 case UITextAlignmentRight:
128 point.x += origSize.width - size.width;
129 break;
130 }
131 [self.text drawAtPoint:point forWidth:size.width withZFont:actualFont lineBreakMode:self.lineBreakMode];
132 } else {
133 CGSize size = [self.text sizeWithZFont:actualFont constrainedToSize:origSize lineBreakMode:self.lineBreakMode numberOfLines:self.numberOfLines];
134 CGPoint point = rect.origin;
135 point.y += roundf((rect.size.height - size.height) / 2.0f);
136 rect = (CGRect){point, CGSizeMake(rect.size.width, size.height)};
137 [self.text drawInRect:rect withZFont:actualFont lineBreakMode:self.lineBreakMode alignment:self.textAlignment numberOfLines:self.numberOfLines];
138 }
139 } else {
140 ZAttributedString *attStr = self.zAttributedText;
141 if (self.highlighted) {
142 // modify the string to change the base color
143 ZMutableAttributedString *mutStr = [[attStr mutableCopy] autorelease];
144 NSRange activeRange = NSMakeRange(0, attStr.length);
145 while (activeRange.length > 0) {
146 NSRange effective;
147 UIColor *color = [attStr attribute:ZForegroundColorAttributeName atIndex:activeRange.location
148 longestEffectiveRange:&effective inRange:activeRange];
149 if (color == nil) {
150 [mutStr addAttribute:ZForegroundColorAttributeName value:[UIColor whiteColor] range:effective];
151 }
152 activeRange.location += effective.length, activeRange.length -= effective.length;
153 }
154 attStr = mutStr;
155 }
156 CGSize size = [attStr sizeConstrainedToSize:rect.size lineBreakMode:self.lineBreakMode numberOfLines:self.numberOfLines];
157 CGPoint point = rect.origin;
158 point.y += roundf((rect.size.height - size.height) / 2.0f);
159 rect = (CGRect){point, CGSizeMake(rect.size.width, size.height)};
160 [attStr drawInRect:rect withLineBreakMode:self.lineBreakMode alignment:self.textAlignment numberOfLines:self.numberOfLines];
161 }
162}
163
164- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
165 if (self.zFont == NULL && self.zAttributedText == nil) {
166 return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
167 }
168
169 if (numberOfLines == 1) {
170 // if numberOfLines == 1 we need to use the version that converts spaces
171 CGSize size;
172 if (self.zAttributedText == nil) {
173 size = [self.text sizeWithZFont:self.zFont];
174 } else {
175 size = [self.zAttributedText size];
176 }
177 bounds.size.width = MIN(bounds.size.width, size.width);
178 bounds.size.height = MIN(bounds.size.height, size.height);
179 } else {
180 if (numberOfLines > 0) bounds.size.height = MIN(bounds.size.height, self.zFont.leading * numberOfLines);
181 if (self.zAttributedText == nil) {
182 bounds.size = [self.text sizeWithZFont:self.zFont constrainedToSize:bounds.size lineBreakMode:self.lineBreakMode];
183 } else {
184 bounds.size = [self.zAttributedText sizeConstrainedToSize:bounds.size lineBreakMode:self.lineBreakMode];
185 }
186 }
187 return bounds;
188}
189
190- (void)dealloc {
191 [zFont release];
192 [zAttributedText release];
193 [super dealloc];
194}
195@end