You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by cx...@apache.org on 2017/04/13 11:21:03 UTC
[13/23] incubator-weex git commit: * [ios] fix text refactor mutli
line bug
* [ios] fix text refactor mutli line bug
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/ade22d61
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/ade22d61
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/ade22d61
Branch: refs/heads/0.12-dev
Commit: ade22d61b6db98e1690e0c0b31349bfbae55febf
Parents: 60460c6
Author: acton393 <zh...@gmail.com>
Authored: Thu Apr 13 02:45:51 2017 +0800
Committer: acton393 <zh...@gmail.com>
Committed: Thu Apr 13 02:45:51 2017 +0800
----------------------------------------------------------------------
.../WeexSDK/Sources/Component/WXTextComponent.m | 96 ++++++++++++--------
1 file changed, 60 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/ade22d61/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m
index 09e61e1..9df7fef 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m
@@ -29,10 +29,7 @@
#import <CoreText/CoreText.h>
@interface WXText : UIView
-
@property (nonatomic, strong) NSTextStorage *textStorage;
-@property (nonatomic, strong) NSMutableAttributedString * attributedString;
-
@end
@implementation WXText
@@ -63,13 +60,6 @@
}
}
-- (void)setAttributedString:(NSMutableAttributedString *)attributedString {
- if (_attributedString != attributedString) {
- _attributedString = attributedString;
- [self.wx_component setNeedsDisplay];
- }
-}
-
- (NSString *)description
{
NSString *superDescription = super.description;
@@ -114,6 +104,8 @@ static BOOL textRenderUsingCoreText;
WXTextDecoration _textDecoration;
NSString *_textOverflow;
CGFloat _lineHeight;
+
+ CTFrameRef coretextFrameRef;
}
+ (void)setRenderUsingCoreText:(BOOL)usingCoreText
@@ -154,9 +146,17 @@ static BOOL textRenderUsingCoreText;
return self;
}
+- (BOOL)useCoreText
+{
+ return (_coretext || [WXTextComponent textRenderUsingCoreText]);
+}
+
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ if (coretextFrameRef && CFGetRetainCount(coretextFrameRef)) {
+ CFRelease(coretextFrameRef);
+ }
}
#define WX_STYLE_FILL_TEXT(key, prop, type, needLayout)\
@@ -234,7 +234,6 @@ do {\
- (void)viewDidLoad
{
((WXText *)self.view).textStorage = _textStorage;
- ((WXText *)self.view).attributedString = [self buildCTAttributeString];
[self setNeedsDisplay];
}
@@ -272,9 +271,9 @@ do {\
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
} else {
- computedSize = [[weakSelf buildCTAttributeString] boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
+ computedSize = [weakSelf calculateTextHeightWithWidth:constrainedSize.width];
}
-
+
//TODO:more elegant way to use max and min constrained size
if (!isnan(weakSelf.cssNode->style.minDimensions[CSS_WIDTH])) {
computedSize.width = MAX(computedSize.width, weakSelf.cssNode->style.minDimensions[CSS_WIDTH]);
@@ -356,8 +355,6 @@ do {\
[attributedString addAttribute:(id)kCTFontAttributeName value:(__bridge id)(ctFont) range:NSMakeRange(0, string.length)];
}
- CFRelease(ctFont);
-
if(_textDecoration == WXTextDecorationUnderline){
[attributedString addAttribute:(id)kCTUnderlineStyleAttributeName value:@(kCTUnderlinePatternSolid | kCTUnderlineStyleSingle) range:NSMakeRange(0, string.length)];
} else if(_textDecoration == WXTextDecorationLineThrough){
@@ -371,9 +368,10 @@ do {\
}
// set default lineBreakMode
- paragraphStyle.lineBreakMode = NSLineBreakByClipping;
+ // TODO:default clip
+ paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
if (_textOverflow && [_textOverflow length] > 0) {
- if ([_textOverflow isEqualToString:@"ellipsis"])
+ if (_lines && [_textOverflow isEqualToString:@"ellipsis"])
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
}
@@ -395,6 +393,7 @@ do {\
}
}
+ CFRelease(ctFont);
return attributedString;
}
@@ -463,7 +462,7 @@ do {\
- (BOOL)adjustLineHeight
{
- return !(_coretext && [WXTextComponent textRenderUsingCoreText]);
+ return ![self useCoreText];
}
- (NSTextStorage *)textStorageWithWidth:(CGFloat)width
@@ -504,12 +503,9 @@ do {\
{
CGFloat width = self.calculatedFrame.size.width - (_padding.left + _padding.right);
NSTextStorage *textStorage = [self textStorageWithWidth:width];
- NSMutableAttributedString * attributedString = [self buildCTAttributeString];
-
[self.weexInstance.componentManager _addUITask:^{
if ([self isViewLoaded]) {
((WXText *)self.view).textStorage = textStorage;
- ((WXText *)self.view).attributedString = attributedString;
[self readyToRender]; // notify super component
[self setNeedsDisplay];
}
@@ -572,26 +568,21 @@ do {\
CGContextTranslateCTM(context, 0, textFrame.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
+ NSMutableAttributedString * attributedStringCopy = [self buildCTAttributeString];
//add path
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, textFrame);
- NSMutableAttributedString * attributedStringCopy = [self buildCTAttributeString];
-
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedStringCopy);
- CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
+ coretextFrameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
- CFArrayRef lines = CTFrameGetLines(frame);
+ CFArrayRef lines = CTFrameGetLines(coretextFrameRef);
CFIndex lineCount = CFArrayGetCount(lines);
CGPoint lineOrigins[lineCount];
- CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), lineOrigins);
- for (CFIndex index = 0; index < lineCount; index ++) {
- CTLineRef lineRef = CFArrayGetValueAtIndex(lines, index);
- CGFloat lineAscent;
- CGFloat lineDescent;
- CGFloat lineLeading;
+ CTFrameGetLineOrigins(coretextFrameRef, CFRangeMake(0, 0), lineOrigins);
+ for (CFIndex lineIndex = 0;(!_lines || _lines > lineIndex) && lineIndex < lineCount; lineIndex ++) {
- CTLineGetTypographicBounds(lineRef, &lineAscent, &lineDescent, &lineLeading);
- CGPoint lineOrigin = lineOrigins[index];
+ CTLineRef lineRef = CFArrayGetValueAtIndex(lines, lineIndex);
+ CGPoint lineOrigin = lineOrigins[lineIndex];
lineOrigin.x += padding.left;
lineOrigin.y -= padding.top;
CGContextSetTextPosition(context, lineOrigin.x, lineOrigin.y);
@@ -621,15 +612,48 @@ do {\
}
}
-
- CFRelease(frame);
CFRelease(framesetter);
CGPathRelease(path);
-
CGContextRestoreGState(context);
}
}
+- (CGSize)calculateTextHeightWithWidth:(CGFloat)aWidth
+{
+ if (isnan(aWidth)) {
+ aWidth = CGFLOAT_MAX;
+ }
+ NSAttributedString * attributedStringCpy = [self buildCTAttributeString];
+ CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedStringCpy);
+
+ CGSize suggestSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetterRef, CFRangeMake(0, attributedStringCpy.length), NULL, CGSizeMake(aWidth, MAXFLOAT), NULL);
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGPathAddRect(path, NULL, CGRectMake(0, 0, aWidth, suggestSize.height*10));
+
+ CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, attributedStringCpy.length), path, NULL);
+
+ CFArrayRef lines = CTFrameGetLines(frameRef);
+ CFIndex lineCount = CFArrayGetCount(lines);
+ CGFloat ascent = 0;
+ CGFloat descent = 0;
+ CGFloat leading = 0;
+ CGFloat totalHeight = 0;
+ // height = ascent + descent + lineCount*leading
+ // ignore linespaing
+ NSUInteger actualLineCount = 0;
+ for (CFIndex lineIndex = 0; (!_lines|| lineIndex < _lines) && lineIndex < lineCount; lineIndex ++)
+ {
+ CTLineRef lineRef = CFArrayGetValueAtIndex(lines, lineIndex);
+ CTLineGetTypographicBounds(lineRef, &ascent, &descent, &leading);
+ totalHeight += ascent + descent;
+ actualLineCount ++;
+ }
+
+ totalHeight = totalHeight + actualLineCount*leading;
+ return CGSizeMake(suggestSize.width, totalHeight);
+}
+
static void WXTextGetRunsMaxMetric(CFArrayRef runs, CGFloat *xHeight, CGFloat *underlinePosition, CGFloat *lineThickness) {
CGFloat maxXHeight = 0;
CGFloat maxUnderlinePos = 0;