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

Side by Side Diff: ios/chrome/common/string_util.mm

Issue 1073863005: Upstream string_util function. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: test deps Created 5 years, 8 months 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
« no previous file with comments | « ios/chrome/common/string_util.h ('k') | ios/chrome/common/string_util_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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 #include "ios/chrome/common/string_util.h"
6
7 #import <UIKit/UIKit.h>
8
9 #include "base/logging.h"
10 #include "base/mac/scoped_block.h"
11 #include "base/mac/scoped_nsobject.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/sys_string_conversions.h"
14
15 namespace {
16 typedef BOOL (^ArrayFilterProcedure)(id object, NSUInteger index, BOOL* stop);
17 typedef NSString* (^SubstringExtractionProcedure)(NSUInteger);
18 }
19
20 NSString* ParseStringWithLink(NSString* text, NSRange* out_link_range) {
21 // Find the range within |text| and create a substring without the link tags.
22 NSRange begin_range = [text rangeOfString:@"BEGIN_LINK[ \t]*"
23 options:NSRegularExpressionSearch];
24 NSRange link_text_range = NSMakeRange(NSNotFound, 0);
25 if (begin_range.length == 0) {
26 if (out_link_range)
27 *out_link_range = link_text_range;
28 return text;
29 }
30
31 NSUInteger after_begin_link = NSMaxRange(begin_range);
32 NSRange range_to_search_for_end_link =
33 NSMakeRange(after_begin_link, text.length - after_begin_link);
34 NSRange end_range = [text rangeOfString:@"[ \t]*END_LINK"
35 options:NSRegularExpressionSearch
36 range:range_to_search_for_end_link];
37 if (end_range.length == 0) {
38 if (out_link_range)
39 *out_link_range = link_text_range;
40 return text;
41 }
42
43 link_text_range.location = after_begin_link;
44 link_text_range.length = end_range.location - link_text_range.location;
45 base::scoped_nsobject<NSMutableString> out_text(
46 [[NSMutableString alloc] init]);
47 // First part - before the link.
48 if (begin_range.location > 0)
49 [out_text appendString:[text substringToIndex:begin_range.location]];
50
51 // Link part.
52 [out_text appendString:[text substringWithRange:link_text_range]];
53
54 // Last part - after the link.
55 NSUInteger after_end_link = NSMaxRange(end_range);
56 if (after_end_link < [text length]) {
57 [out_text appendString:[text substringFromIndex:after_end_link]];
58 }
59
60 link_text_range.location = begin_range.location;
61 if (out_link_range)
62 *out_link_range = link_text_range;
63 return [NSString stringWithString:out_text];
64 }
65
66 // Ranges of unicode codepage containing drawing characters.
67 // 2190—21FF Arrows
68 // 2200—22FF Mathematical Operators
69 // 2300—23FF Miscellaneous Technical
70 // 2400—243F Control Pictures
71 // 2440—245F Optical Character Recognition
72 // 2460—24FF Enclosed Alphanumerics
73 // 2500—257F Box Drawing
74 // 2580—259F Block Elements
75 // 25A0—25FF Geometric Shapes
76 // 2600—26FF Miscellaneous Symbols
77 // 2700—27BF Dingbats
78 // 27C0—27EF Miscellaneous Mathematical Symbols-A
79 // 27F0—27FF Supplemental Arrows-A
80 // 2900—297F Supplemental Arrows-B
81 // 2980—29FF Miscellaneous Mathematical Symbols-B
82 // 2A00—2AFF Supplemental Mathematical Operators
83 // 2B00—2BFF Miscellaneous Symbols and Arrows
84 // The section 2800—28FF Braille Patterns must be preserved.
85 // The list of characters that must be deleted from the selection.
86 NSCharacterSet* GraphicCharactersSet() {
87 static NSMutableCharacterSet* graphicalCharsSet;
88 static dispatch_once_t dispatch_once_token;
89 dispatch_once(&dispatch_once_token, ^{
90 graphicalCharsSet = [[NSMutableCharacterSet alloc] init];
91 NSRange graphicalCharsFirstRange = NSMakeRange(0x2190, 0x2800 - 0x2190);
92 NSRange graphicalCharsSecondRange = NSMakeRange(0x2900, 0x2c00 - 0x2900);
93 [graphicalCharsSet addCharactersInRange:graphicalCharsFirstRange];
94 [graphicalCharsSet addCharactersInRange:graphicalCharsSecondRange];
95 });
96 return graphicalCharsSet;
97 }
98
99 // TODO(marq): Add unit tests for this function.
100 NSString* CleanNSStringForDisplay(NSString* dirty,
101 BOOL removeGraphicChars,
102 BOOL trim) {
103 NSCharacterSet* wspace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
104 NSString* cleanString = dirty;
105 if (removeGraphicChars) {
106 cleanString = [[cleanString
107 componentsSeparatedByCharactersInSet:GraphicCharactersSet()]
108 componentsJoinedByString:@" "];
109 }
110 base::scoped_nsobject<NSMutableArray> spaceSeparatedCompoments(
111 [[cleanString componentsSeparatedByCharactersInSet:wspace] mutableCopy]);
112 ArrayFilterProcedure filter = ^(id object, NSUInteger index, BOOL* stop) {
113 return [object isEqualToString:@""];
114 };
115 [spaceSeparatedCompoments
116 removeObjectsAtIndexes:[spaceSeparatedCompoments
117 indexesOfObjectsPassingTest:filter]];
118 cleanString = [spaceSeparatedCompoments componentsJoinedByString:@" "];
119 return trim ? [cleanString stringByTrimmingCharactersInSet:wspace]
120 : cleanString;
121 }
122
123 std::string CleanStringForDisplay(std::string dirty,
124 BOOL removeGraphicChars,
125 BOOL trim) {
126 return base::SysNSStringToUTF8(CleanNSStringForDisplay(
127 base::SysUTF8ToNSString(dirty), removeGraphicChars, trim));
128 }
129
130 // TODO(marq): Add unit tests for this function.
131 NSString* SubstringOfWidth(NSString* string,
132 NSDictionary* attributes,
133 CGFloat targetWidth,
134 BOOL trailing) {
135 if (![string length])
136 return nil;
137
138 UIFont* font = [attributes objectForKey:NSFontAttributeName];
139 DCHECK(font);
140
141 // Function to get the correct substring while insulating against
142 // length overrun/underrun.
143 base::mac::ScopedBlock<SubstringExtractionProcedure> getSubstring;
144 if (trailing) {
145 getSubstring.reset([^NSString*(NSUInteger chars) {
146 NSUInteger length = [string length];
147 return [string substringFromIndex:length - MIN(length, chars)];
148 } copy]);
149 } else {
150 getSubstring.reset([^NSString*(NSUInteger chars) {
151 return [string substringToIndex:MIN(chars, [string length])];
152 } copy]);
153 }
154
155 // Guess at the number of characters that will fit, assuming
156 // the font's x-height is about 25% wider than an average character (25%
157 // value was determined experimentally).
158 NSUInteger characters =
159 MIN(targetWidth / (font.xHeight * 0.8), [string length]);
160 NSInteger increment = 1;
161 NSString* substring = getSubstring.get()(characters);
162 CGFloat prevWidth = [substring sizeWithAttributes:attributes].width;
163 do {
164 characters += increment;
165 substring = getSubstring.get()(characters);
166 CGFloat thisWidth = [substring sizeWithAttributes:attributes].width;
167 if (prevWidth > targetWidth) {
168 if (thisWidth < targetWidth)
169 break; // Shrinking the string, found the right size.
170 else
171 increment = -1; // Shrink the string
172 } else if (prevWidth < targetWidth) {
173 if (thisWidth < targetWidth)
174 increment = 1; // Grow the string
175 else {
176 substring = getSubstring.get()(characters - increment);
177 break; // Growing the string, found the right size.
178 }
179 }
180 prevWidth = thisWidth;
181 } while (characters > 0 && characters < [string length]);
182
183 return substring;
184 }
OLDNEW
« no previous file with comments | « ios/chrome/common/string_util.h ('k') | ios/chrome/common/string_util_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698