Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: ios/chrome/browser/ui/util/text_region_mapper.mm

Issue 2580333003: Upstream Chrome on iOS source code [10/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/ui/util/text_region_mapper.h"
6
7 #import <CoreText/CoreText.h>
8 #import <QuartzCore/QuartzCore.h>
9
10 #include "base/i18n/rtl.h"
11 #include "base/ios/ios_util.h"
12 #include "base/logging.h"
13 #include "base/mac/foundation_util.h"
14 #include "base/mac/scoped_nsobject.h"
15 #include "ios/chrome/browser/ui/ui_util.h"
16 #import "ios/chrome/browser/ui/util/core_text_util.h"
17 #import "ios/chrome/browser/ui/util/manual_text_framer.h"
18 #import "ios/chrome/browser/ui/util/text_frame.h"
19
20 @interface CoreTextRegionMapper () {
21 // Backing object for property of the same name.
22 base::scoped_nsprotocol<id<TextFrame>> _textFrame;
23 }
24
25 // The TextFrame used to calculate rects.
26 @property(nonatomic, readonly) id<TextFrame> textFrame;
27
28 @end
29
30 @implementation CoreTextRegionMapper
31 - (instancetype)initWithAttributedString:(NSAttributedString*)string
32 bounds:(CGRect)bounds {
33 if ((self = [super init])) {
34 base::ScopedCFTypeRef<CTFrameRef> ctFrame =
35 core_text_util::CreateTextFrameForStringInBounds(string, bounds);
36 base::scoped_nsobject<ManualTextFramer> framer(
37 [[ManualTextFramer alloc] initWithString:string inBounds:bounds]);
38 [framer frameText];
39 if (core_text_util::IsTextFrameValid(ctFrame, framer, string)) {
40 _textFrame.reset([[CoreTextTextFrame alloc] initWithString:string
41 bounds:bounds
42 frame:ctFrame]);
43 } else {
44 // Use ManualTextFramer if |ctFrame| is invalid.
45 _textFrame.reset([[framer textFrame] retain]);
46 }
47 DCHECK(self.textFrame);
48 }
49 return self;
50 }
51
52 - (instancetype)init {
53 NOTREACHED();
54 return nil;
55 }
56
57 - (id<TextFrame>)textFrame {
58 return _textFrame.get();
59 }
60
61 - (NSArray*)rectsForRange:(NSRange)range {
62 NSRange framedRange = self.textFrame.framedRange;
63 if (!range.length || range.location + range.length > framedRange.length)
64 return @[];
65
66 NSMutableArray* rects = [NSMutableArray array];
67 // CoreText uses Quartz coordinates, so they will need to be flipped back to
68 // UIKit-space.
69 CGAffineTransform transformForCoreText = CGAffineTransformScale(
70 CGAffineTransformMakeTranslation(0, self.textFrame.bounds.size.height),
71 1.f, -1.f);
72
73 CGFloat ascent = 0.0f; // height of text above the baseline.
74 CGFloat descent = 0.0f; // height of text below the baseline.
75
76 // Find any parts of the link on each line.
77 for (FramedLine* line in self.textFrame.lines) {
78 CGFloat lineWidth = static_cast<CGFloat>(
79 CTLineGetTypographicBounds(line.line, &ascent, &descent, nullptr));
80 if (!lineWidth)
81 break;
82
83 NSRange overlap = NSIntersectionRange(range, line.stringRange);
84 if (overlap.length > 0) {
85 // Some of the range is on this line; find where it starts and ends.
86 CFIndex stringOffset =
87 [line lineOffsetForStringLocation:overlap.location];
88 DCHECK_NE(stringOffset, kCFNotFound);
89 CGFloat start =
90 CTLineGetOffsetForStringIndex(line.line, stringOffset, nullptr);
91 CGFloat end = CTLineGetOffsetForStringIndex(
92 line.line, stringOffset + overlap.length, nullptr);
93 CGRect flippedRangeRect =
94 CGRectMake(line.origin.x + start,
95 line.origin.y - descent, // Lower extent of text.
96 end - start, // Length of link text.
97 ascent + descent); // Total height of text.
98 // Flip to UIKit coordinates.
99 CGRect rangeRect =
100 CGRectApplyAffineTransform(flippedRangeRect, transformForCoreText);
101 [rects addObject:[NSValue valueWithCGRect:rangeRect]];
102 }
103 }
104 return rects;
105 }
106
107 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/util/text_region_mapper.h ('k') | ios/chrome/browser/ui/util/text_region_mapper_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698