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_region_mapper.h" | 5 #import "ios/chrome/browser/ui/util/text_region_mapper.h" |
6 | 6 |
7 #import <CoreText/CoreText.h> | 7 #import <CoreText/CoreText.h> |
8 #import <QuartzCore/QuartzCore.h> | 8 #import <QuartzCore/QuartzCore.h> |
9 | 9 |
10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
11 #include "base/ios/ios_util.h" | 11 #include "base/ios/ios_util.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/mac/foundation_util.h" | 13 #include "base/mac/foundation_util.h" |
14 #include "base/mac/scoped_nsobject.h" | |
15 #include "ios/chrome/browser/ui/ui_util.h" | 14 #include "ios/chrome/browser/ui/ui_util.h" |
16 #import "ios/chrome/browser/ui/util/core_text_util.h" | 15 #import "ios/chrome/browser/ui/util/core_text_util.h" |
17 #import "ios/chrome/browser/ui/util/manual_text_framer.h" | 16 #import "ios/chrome/browser/ui/util/manual_text_framer.h" |
18 #import "ios/chrome/browser/ui/util/text_frame.h" | 17 #import "ios/chrome/browser/ui/util/text_frame.h" |
19 | 18 |
20 @interface CoreTextRegionMapper () { | 19 #if !defined(__has_feature) || !__has_feature(objc_arc) |
21 // Backing object for property of the same name. | 20 #error "This file requires ARC support." |
22 base::scoped_nsprotocol<id<TextFrame>> _textFrame; | 21 #endif |
23 } | 22 |
| 23 @interface CoreTextRegionMapper () |
24 | 24 |
25 // The TextFrame used to calculate rects. | 25 // The TextFrame used to calculate rects. |
26 @property(nonatomic, readonly) id<TextFrame> textFrame; | 26 @property(strong, nonatomic, readonly) id<TextFrame> textFrame; |
27 | 27 |
28 @end | 28 @end |
29 | 29 |
30 @implementation CoreTextRegionMapper | 30 @implementation CoreTextRegionMapper |
| 31 |
| 32 @synthesize textFrame = _textFrame; |
| 33 |
31 - (instancetype)initWithAttributedString:(NSAttributedString*)string | 34 - (instancetype)initWithAttributedString:(NSAttributedString*)string |
32 bounds:(CGRect)bounds { | 35 bounds:(CGRect)bounds { |
33 if ((self = [super init])) { | 36 if ((self = [super init])) { |
34 base::ScopedCFTypeRef<CTFrameRef> ctFrame = | 37 base::ScopedCFTypeRef<CTFrameRef> ctFrame = |
35 core_text_util::CreateTextFrameForStringInBounds(string, bounds); | 38 core_text_util::CreateTextFrameForStringInBounds(string, bounds); |
36 base::scoped_nsobject<ManualTextFramer> framer( | 39 ManualTextFramer* framer = |
37 [[ManualTextFramer alloc] initWithString:string inBounds:bounds]); | 40 [[ManualTextFramer alloc] initWithString:string inBounds:bounds]; |
38 [framer frameText]; | 41 [framer frameText]; |
39 if (core_text_util::IsTextFrameValid(ctFrame, framer, string)) { | 42 if (core_text_util::IsTextFrameValid(ctFrame, framer, string)) { |
40 _textFrame.reset([[CoreTextTextFrame alloc] initWithString:string | 43 _textFrame = [[CoreTextTextFrame alloc] initWithString:string |
41 bounds:bounds | 44 bounds:bounds |
42 frame:ctFrame]); | 45 frame:ctFrame]; |
43 } else { | 46 } else { |
44 // Use ManualTextFramer if |ctFrame| is invalid. | 47 // Use ManualTextFramer if |ctFrame| is invalid. |
45 _textFrame.reset([[framer textFrame] retain]); | 48 _textFrame = [framer textFrame]; |
46 } | 49 } |
47 DCHECK(self.textFrame); | 50 DCHECK(self.textFrame); |
48 } | 51 } |
49 return self; | 52 return self; |
50 } | 53 } |
51 | 54 |
52 - (instancetype)init { | 55 - (instancetype)init { |
53 NOTREACHED(); | 56 NOTREACHED(); |
54 return nil; | 57 return nil; |
55 } | 58 } |
56 | 59 |
57 - (id<TextFrame>)textFrame { | |
58 return _textFrame.get(); | |
59 } | |
60 | |
61 - (NSArray*)rectsForRange:(NSRange)range { | 60 - (NSArray*)rectsForRange:(NSRange)range { |
62 NSRange framedRange = self.textFrame.framedRange; | 61 NSRange framedRange = self.textFrame.framedRange; |
63 if (!range.length || range.location + range.length > framedRange.length) | 62 if (!range.length || range.location + range.length > framedRange.length) |
64 return @[]; | 63 return @[]; |
65 | 64 |
66 NSMutableArray* rects = [NSMutableArray array]; | 65 NSMutableArray* rects = [NSMutableArray array]; |
67 // CoreText uses Quartz coordinates, so they will need to be flipped back to | 66 // CoreText uses Quartz coordinates, so they will need to be flipped back to |
68 // UIKit-space. | 67 // UIKit-space. |
69 CGAffineTransform transformForCoreText = CGAffineTransformScale( | 68 CGAffineTransform transformForCoreText = CGAffineTransformScale( |
70 CGAffineTransformMakeTranslation(0, self.textFrame.bounds.size.height), | 69 CGAffineTransformMakeTranslation(0, self.textFrame.bounds.size.height), |
(...skipping 27 matching lines...) Expand all Loading... |
98 // Flip to UIKit coordinates. | 97 // Flip to UIKit coordinates. |
99 CGRect rangeRect = | 98 CGRect rangeRect = |
100 CGRectApplyAffineTransform(flippedRangeRect, transformForCoreText); | 99 CGRectApplyAffineTransform(flippedRangeRect, transformForCoreText); |
101 [rects addObject:[NSValue valueWithCGRect:rangeRect]]; | 100 [rects addObject:[NSValue valueWithCGRect:rangeRect]]; |
102 } | 101 } |
103 } | 102 } |
104 return rects; | 103 return rects; |
105 } | 104 } |
106 | 105 |
107 @end | 106 @end |
OLD | NEW |