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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/util/text_region_mapper.mm
diff --git a/ios/chrome/browser/ui/util/text_region_mapper.mm b/ios/chrome/browser/ui/util/text_region_mapper.mm
new file mode 100644
index 0000000000000000000000000000000000000000..f9c25f08b1e3cc47de6469f89c05f8ca1bbcd45f
--- /dev/null
+++ b/ios/chrome/browser/ui/util/text_region_mapper.mm
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/util/text_region_mapper.h"
+
+#import <CoreText/CoreText.h>
+#import <QuartzCore/QuartzCore.h>
+
+#include "base/i18n/rtl.h"
+#include "base/ios/ios_util.h"
+#include "base/logging.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_nsobject.h"
+#include "ios/chrome/browser/ui/ui_util.h"
+#import "ios/chrome/browser/ui/util/core_text_util.h"
+#import "ios/chrome/browser/ui/util/manual_text_framer.h"
+#import "ios/chrome/browser/ui/util/text_frame.h"
+
+@interface CoreTextRegionMapper () {
+ // Backing object for property of the same name.
+ base::scoped_nsprotocol<id<TextFrame>> _textFrame;
+}
+
+// The TextFrame used to calculate rects.
+@property(nonatomic, readonly) id<TextFrame> textFrame;
+
+@end
+
+@implementation CoreTextRegionMapper
+- (instancetype)initWithAttributedString:(NSAttributedString*)string
+ bounds:(CGRect)bounds {
+ if ((self = [super init])) {
+ base::ScopedCFTypeRef<CTFrameRef> ctFrame =
+ core_text_util::CreateTextFrameForStringInBounds(string, bounds);
+ base::scoped_nsobject<ManualTextFramer> framer(
+ [[ManualTextFramer alloc] initWithString:string inBounds:bounds]);
+ [framer frameText];
+ if (core_text_util::IsTextFrameValid(ctFrame, framer, string)) {
+ _textFrame.reset([[CoreTextTextFrame alloc] initWithString:string
+ bounds:bounds
+ frame:ctFrame]);
+ } else {
+ // Use ManualTextFramer if |ctFrame| is invalid.
+ _textFrame.reset([[framer textFrame] retain]);
+ }
+ DCHECK(self.textFrame);
+ }
+ return self;
+}
+
+- (instancetype)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (id<TextFrame>)textFrame {
+ return _textFrame.get();
+}
+
+- (NSArray*)rectsForRange:(NSRange)range {
+ NSRange framedRange = self.textFrame.framedRange;
+ if (!range.length || range.location + range.length > framedRange.length)
+ return @[];
+
+ NSMutableArray* rects = [NSMutableArray array];
+ // CoreText uses Quartz coordinates, so they will need to be flipped back to
+ // UIKit-space.
+ CGAffineTransform transformForCoreText = CGAffineTransformScale(
+ CGAffineTransformMakeTranslation(0, self.textFrame.bounds.size.height),
+ 1.f, -1.f);
+
+ CGFloat ascent = 0.0f; // height of text above the baseline.
+ CGFloat descent = 0.0f; // height of text below the baseline.
+
+ // Find any parts of the link on each line.
+ for (FramedLine* line in self.textFrame.lines) {
+ CGFloat lineWidth = static_cast<CGFloat>(
+ CTLineGetTypographicBounds(line.line, &ascent, &descent, nullptr));
+ if (!lineWidth)
+ break;
+
+ NSRange overlap = NSIntersectionRange(range, line.stringRange);
+ if (overlap.length > 0) {
+ // Some of the range is on this line; find where it starts and ends.
+ CFIndex stringOffset =
+ [line lineOffsetForStringLocation:overlap.location];
+ DCHECK_NE(stringOffset, kCFNotFound);
+ CGFloat start =
+ CTLineGetOffsetForStringIndex(line.line, stringOffset, nullptr);
+ CGFloat end = CTLineGetOffsetForStringIndex(
+ line.line, stringOffset + overlap.length, nullptr);
+ CGRect flippedRangeRect =
+ CGRectMake(line.origin.x + start,
+ line.origin.y - descent, // Lower extent of text.
+ end - start, // Length of link text.
+ ascent + descent); // Total height of text.
+ // Flip to UIKit coordinates.
+ CGRect rangeRect =
+ CGRectApplyAffineTransform(flippedRangeRect, transformForCoreText);
+ [rects addObject:[NSValue valueWithCGRect:rangeRect]];
+ }
+ }
+ return rects;
+}
+
+@end
« 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