Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/chrome/browser/ui/util/text_frame.h" | 5 #import "ios/chrome/browser/ui/util/text_frame.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/mac/foundation_util.h" | 8 #include "base/mac/foundation_util.h" |
| 9 #import "base/mac/scoped_nsobject.h" | 9 |
| 10 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
| 11 #error "This file requires ARC support." | |
| 12 #endif | |
| 10 | 13 |
| 11 #pragma mark - FramedLine | 14 #pragma mark - FramedLine |
| 12 | 15 |
| 13 @implementation FramedLine { | 16 @implementation FramedLine { |
| 14 // Backing object for property of the same name. | 17 // Backing object for property of the same name. |
| 15 base::scoped_nsprotocol<id> _line; | 18 id _line; |
| 16 } | 19 } |
| 17 | 20 |
| 18 @synthesize stringRange = _stringRange; | 21 @synthesize stringRange = _stringRange; |
| 19 @synthesize origin = _origin; | 22 @synthesize origin = _origin; |
| 20 | 23 |
| 21 - (instancetype)initWithLine:(CTLineRef)line | 24 - (instancetype)initWithLine:(CTLineRef)line |
| 22 stringRange:(NSRange)stringRange | 25 stringRange:(NSRange)stringRange |
| 23 origin:(CGPoint)origin { | 26 origin:(CGPoint)origin { |
| 24 if ((self = [super init])) { | 27 if ((self = [super init])) { |
| 25 DCHECK(line); | 28 DCHECK(line); |
| 26 // CTLines created by ManualTextFramers all have zero for their string range | 29 // CTLines created by ManualTextFramers all have zero for their string range |
| 27 // locations, but its length should be equal to |stringRange|. | 30 // locations, but its length should be equal to |stringRange|. |
| 28 NSRange lineRange; | 31 NSRange lineRange; |
| 29 if (!base::mac::CFRangeToNSRange(CTLineGetStringRange(line), &lineRange)) { | 32 if (!base::mac::CFRangeToNSRange(CTLineGetStringRange(line), &lineRange)) { |
| 30 [self release]; | |
| 31 return nil; | 33 return nil; |
| 32 } | 34 } |
| 33 DCHECK_EQ(lineRange.length, stringRange.length); | 35 DCHECK_EQ(lineRange.length, stringRange.length); |
| 34 _line.reset([static_cast<id>(line) retain]); | 36 _line = (__bridge id)(line); |
|
marq (ping after 24h)
2017/04/21 16:25:04
static cast
| |
| 35 _stringRange = stringRange; | 37 _stringRange = stringRange; |
| 36 _origin = origin; | 38 _origin = origin; |
| 37 } | 39 } |
| 38 return self; | 40 return self; |
| 39 } | 41 } |
| 40 | 42 |
| 41 - (NSString*)description { | 43 - (NSString*)description { |
| 42 return [NSString stringWithFormat:@"%@ line:%@, stringRange:%@, origin:%@", | 44 return [NSString stringWithFormat:@"%@ line:%@, stringRange:%@, origin:%@", |
| 43 [super description], _line.get(), | 45 [super description], _line, |
| 44 NSStringFromRange(_stringRange), | 46 NSStringFromRange(_stringRange), |
| 45 NSStringFromCGPoint(_origin)]; | 47 NSStringFromCGPoint(_origin)]; |
| 46 } | 48 } |
| 47 | 49 |
| 48 - (CFIndex)lineOffsetForStringLocation:(NSUInteger)stringLocation { | 50 - (CFIndex)lineOffsetForStringLocation:(NSUInteger)stringLocation { |
| 49 if (stringLocation < self.stringRange.location || | 51 if (stringLocation < self.stringRange.location || |
| 50 stringLocation >= self.stringRange.location + self.stringRange.length) { | 52 stringLocation >= self.stringRange.location + self.stringRange.length) { |
| 51 return kCFNotFound; | 53 return kCFNotFound; |
| 52 } | 54 } |
| 53 NSRange lineRange; | 55 NSRange lineRange; |
| 54 if (!base::mac::CFRangeToNSRange(CTLineGetStringRange(self.line), &lineRange)) | 56 if (!base::mac::CFRangeToNSRange(CTLineGetStringRange(self.line), &lineRange)) |
| 55 return kCFNotFound; | 57 return kCFNotFound; |
| 56 return lineRange.location + (stringLocation - self.stringRange.location); | 58 return lineRange.location + (stringLocation - self.stringRange.location); |
| 57 } | 59 } |
| 58 | 60 |
| 59 #pragma mark Accessors | 61 #pragma mark Accessors |
| 60 | 62 |
| 61 - (CTLineRef)line { | 63 - (CTLineRef)line { |
| 62 return static_cast<CTLineRef>(_line.get()); | 64 return (__bridge CTLineRef)(_line); |
| 63 } | 65 } |
| 64 | 66 |
| 65 @end | 67 @end |
| 66 | 68 |
| 67 #pragma mark - CoreTextTextFrame | 69 #pragma mark - CoreTextTextFrame |
| 68 | 70 |
| 69 @interface CoreTextTextFrame () { | 71 @interface CoreTextTextFrame () { |
| 70 // Backing object for property of the same name. | 72 // Backing object for property of the same name. |
| 71 base::scoped_nsobject<NSAttributedString> _string; | 73 NSAttributedString* _string; |
| 72 base::scoped_nsprotocol<id> _frame; | 74 id _frame; |
| 73 base::scoped_nsobject<NSMutableArray> _lines; | 75 NSMutableArray* _lines; |
| 74 } | 76 } |
| 75 | 77 |
| 76 // The CTFrameRef passed on initializaton. | 78 // The CTFrameRef passed on initializaton. |
| 77 @property(nonatomic, readonly) CTFrameRef frame; | 79 @property(nonatomic, readonly) CTFrameRef frame; |
| 78 | 80 |
| 79 // Populates |lines| using |frame|. | 81 // Populates |lines| using |frame|. |
| 80 - (void)createFramedLines; | 82 - (void)createFramedLines; |
| 81 | 83 |
| 82 @end | 84 @end |
| 83 | 85 |
| 84 @implementation CoreTextTextFrame | 86 @implementation CoreTextTextFrame |
| 85 | 87 |
| 86 @synthesize bounds = _bounds; | 88 @synthesize bounds = _bounds; |
| 87 | 89 |
| 88 - (instancetype)initWithString:(NSAttributedString*)string | 90 - (instancetype)initWithString:(NSAttributedString*)string |
| 89 bounds:(CGRect)bounds | 91 bounds:(CGRect)bounds |
| 90 frame:(CTFrameRef)frame { | 92 frame:(CTFrameRef)frame { |
| 91 if ((self = [super self])) { | 93 if ((self = [super self])) { |
| 92 DCHECK(string.string.length); | 94 DCHECK(string.string.length); |
| 93 _string.reset([string retain]); | 95 _string = string; |
| 94 _bounds = bounds; | 96 _bounds = bounds; |
| 95 DCHECK(frame); | 97 DCHECK(frame); |
| 96 _frame.reset([static_cast<id>(frame) retain]); | 98 _frame = (__bridge id)(frame); |
| 97 } | 99 } |
| 98 return self; | 100 return self; |
| 99 } | 101 } |
| 100 | 102 |
| 101 #pragma mark Accessors | 103 #pragma mark Accessors |
| 102 | 104 |
| 103 - (NSAttributedString*)string { | 105 - (NSAttributedString*)string { |
| 104 return _string.get(); | 106 return _string; |
| 105 } | 107 } |
| 106 | 108 |
| 107 - (NSRange)framedRange { | 109 - (NSRange)framedRange { |
| 108 NSRange range; | 110 NSRange range; |
| 109 CFRange cfRange = CTFrameGetVisibleStringRange(self.frame); | 111 CFRange cfRange = CTFrameGetVisibleStringRange(self.frame); |
| 110 if (base::mac::CFRangeToNSRange(cfRange, &range)) | 112 if (base::mac::CFRangeToNSRange(cfRange, &range)) |
| 111 return range; | 113 return range; |
| 112 return NSMakeRange(NSNotFound, 0); | 114 return NSMakeRange(NSNotFound, 0); |
| 113 } | 115 } |
| 114 | 116 |
| 115 - (NSArray*)lines { | 117 - (NSArray*)lines { |
| 116 if (!_lines) | 118 if (!_lines) |
| 117 [self createFramedLines]; | 119 [self createFramedLines]; |
| 118 return _lines.get(); | 120 return _lines; |
| 119 } | 121 } |
| 120 | 122 |
| 121 - (CTFrameRef)frame { | 123 - (CTFrameRef)frame { |
| 122 return static_cast<CTFrameRef>(_frame.get()); | 124 return (__bridge CTFrameRef)(_frame); |
| 123 } | 125 } |
| 124 | 126 |
| 125 #pragma mark Private | 127 #pragma mark Private |
| 126 | 128 |
| 127 - (void)createFramedLines { | 129 - (void)createFramedLines { |
| 128 NSArray* lines = base::mac::CFToNSCast(CTFrameGetLines(self.frame)); | 130 NSArray* lines = base::mac::CFToNSCast(CTFrameGetLines(self.frame)); |
| 129 CGPoint origins[lines.count]; | 131 CGPoint origins[lines.count]; |
| 130 CTFrameGetLineOrigins(self.frame, CFRangeMake(0, 0), origins); | 132 CTFrameGetLineOrigins(self.frame, CFRangeMake(0, 0), origins); |
| 131 _lines.reset([[NSMutableArray alloc] initWithCapacity:lines.count]); | 133 _lines = [[NSMutableArray alloc] initWithCapacity:lines.count]; |
| 132 for (NSUInteger line_idx = 0; line_idx < lines.count; ++line_idx) { | 134 for (NSUInteger line_idx = 0; line_idx < lines.count; ++line_idx) { |
| 133 CTLineRef line = static_cast<CTLineRef>(lines[line_idx]); | 135 CTLineRef line = (__bridge CTLineRef)(lines[line_idx]); |
| 134 NSRange stringRange; | 136 NSRange stringRange; |
| 135 CFRange cfStringRange = CTLineGetStringRange(line); | 137 CFRange cfStringRange = CTLineGetStringRange(line); |
| 136 if (!base::mac::CFRangeToNSRange(cfStringRange, &stringRange)) | 138 if (!base::mac::CFRangeToNSRange(cfStringRange, &stringRange)) |
| 137 break; | 139 break; |
| 138 base::scoped_nsobject<FramedLine> framedLine([[FramedLine alloc] | 140 FramedLine* framedLine = |
| 139 initWithLine:line | 141 [[FramedLine alloc] initWithLine:line |
| 140 stringRange:stringRange | 142 stringRange:stringRange |
| 141 origin:origins[line_idx]]); | 143 origin:origins[line_idx]]; |
| 142 [_lines addObject:framedLine]; | 144 [_lines addObject:framedLine]; |
| 143 } | 145 } |
| 144 } | 146 } |
| 145 | 147 |
| 146 @end | 148 @end |
| OLD | NEW |