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

Side by Side Diff: ui/base/text/text_elider.cc

Issue 7348010: Added Header and Footer support using Skia (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Added Headers and Footers support - New Snapshot Uploaded Created 9 years, 5 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 | Annotate | Revision Log
« ui/base/text/text_elider.h ('K') | « ui/base/text/text_elider.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include <vector> 5 #include <vector>
6 6
7 #include "ui/base/text/text_elider.h" 7 #include "ui/base/text/text_elider.h"
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/i18n/break_iterator.h" 10 #include "base/i18n/break_iterator.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 path += path_elements[j] + kForwardSlash; 66 path += path_elements[j] + kForwardSlash;
67 67
68 // Add |filename|, ellipsis if necessary. 68 // Add |filename|, ellipsis if necessary.
69 if (num_components != (path_elements.size() - 1)) 69 if (num_components != (path_elements.size() - 1))
70 path += kEllipsisAndSlash; 70 path += kEllipsisAndSlash;
71 path += filename; 71 path += filename;
72 72
73 return path; 73 return path;
74 } 74 }
75 75
76 // Measures the width of the |text| string passed depending on the |object_type|
77 // passed.
78 // If the object is a Skia_Paint object, then the width of the text is returned
79 // in points.
80 // If the object is a gfx::Font object, then the width of the text is returned
81 // in pixels.
82 SkScalar measureStringWidth(const string16& text,
83 void* font_or_paint,
84 ObjectType object_type) {
85 // TODO(aayushkumar): Make sure that |font_or_paint| is actually of type
86 // |object_type| otherwise we will segfault!
87 if (object_type == Skia_Paint)
88 return ((SkPaint *)font_or_paint)->measureText(text.c_str(),
89 text.length()*sizeof(char16));
90 else
91 return ((gfx::Font *)font_or_paint)->GetStringWidth(text);
92 }
93
76 // Takes a prefix (Domain, or Domain+subdomain) and a collection of path 94 // Takes a prefix (Domain, or Domain+subdomain) and a collection of path
77 // components and elides if possible. Returns a string containing the longest 95 // components and elides if possible. Returns a string containing the longest
78 // possible elided path, or an empty string if elision is not possible. 96 // possible elided path, or an empty string if elision is not possible.
79 string16 ElideComponentizedPath(const string16& url_path_prefix, 97 string16 ElideComponentizedPath(const string16& url_path_prefix,
80 const std::vector<string16>& url_path_elements, 98 const std::vector<string16>& url_path_elements,
81 const string16& url_filename, 99 const string16& url_filename,
82 const string16& url_query, 100 const string16& url_query,
83 const gfx::Font& font, 101 void* font_or_paint,//const gfx::Font& font,
kmadhusu 2011/07/13 18:47:53 Is this comment intentional?
Aayush Kumar 2011/07/13 21:52:16 No, it wasn't, sorry! On 2011/07/13 18:47:53, kmad
Aayush Kumar 2011/07/13 21:52:16 Done.
84 int available_pixel_width) { 102 int available_width,
103 ObjectType object_type) {
85 size_t url_path_number_of_elements = url_path_elements.size(); 104 size_t url_path_number_of_elements = url_path_elements.size();
86 105
87 static const string16 kEllipsisAndSlash = UTF8ToUTF16(kEllipsis) + 106 static const string16 kEllipsisAndSlash = UTF8ToUTF16(kEllipsis) +
88 kForwardSlash; 107 kForwardSlash;
89 108
90 for (size_t i = url_path_number_of_elements - 1; i > 0; --i) { 109 for (size_t i = url_path_number_of_elements - 1; i > 0; --i) {
91 string16 elided_path = BuildPathFromComponents(url_path_prefix, 110 string16 elided_path = BuildPathFromComponents(url_path_prefix,
92 url_path_elements, url_filename, i); 111 url_path_elements, url_filename, i);
93 if (available_pixel_width >= font.GetStringWidth(elided_path)) 112 if (available_width >= measureStringWidth(elided_path,
kmadhusu 2011/07/13 18:47:53 nit: remove extra spaces.
Aayush Kumar 2011/07/13 21:52:16 Done.
113 font_or_paint, object_type)) {
94 return ElideText(elided_path + url_query, 114 return ElideText(elided_path + url_query,
95 font, available_pixel_width, false); 115 font_or_paint, available_width, false, object_type);
116 }
96 } 117 }
97 118
98 return string16(); 119 return string16();
99 } 120 }
100 121
101 } // namespace 122 } // namespace
102 123
Lei Zhang 2011/07/12 22:04:50 nit: Why the blank spaces? Try reviewing your own
Aayush Kumar 2011/07/13 21:52:16 Done.
124
125
103 // This function takes a GURL object and elides it. It returns a string 126 // This function takes a GURL object and elides it. It returns a string
104 // which composed of parts from subdomain, domain, path, filename and query. 127 // which composed of parts from subdomain, domain, path, filename and query.
105 // A "..." is added automatically at the end if the elided string is bigger 128 // A "..." is added automatically at the end if the elided string is bigger
106 // than the available pixel width. For available pixel width = 0, a formatted, 129 // than the available pixel width. For available pixel width = 0, a formatted,
107 // but un-elided, string is returned. 130 // but un-elided, string is returned.
108 // 131 //
109 // TODO(pkasting): http://crbug.com/77883 This whole function gets 132 // TODO(pkasting): http://crbug.com/77883 This whole function gets
110 // kerning/ligatures/etc. issues potentially wrong by assuming that the width of 133 // kerning/ligatures/etc. issues potentially wrong by assuming that the width of
111 // a rendered string is always the sum of the widths of its substrings. Also I 134 // a rendered string is always the sum of the widths of its substrings. Also I
112 // suspect it could be made simpler. 135 // suspect it could be made simpler.
113 string16 ElideUrl(const GURL& url, 136 string16 ElideUrl(const GURL& url,
114 const gfx::Font& font, 137 const gfx::Font& font,
115 int available_pixel_width, 138 int available_pixel_width,
116 const std::string& languages) { 139 const std::string& languages) {
140 return ElideUrl(url, (void* )&font, available_pixel_width, languages,
141 GFX_Font);
kmadhusu 2011/07/13 18:47:53 Fix indentation
Aayush Kumar 2011/07/13 21:52:16 Done.
142 }
143
144 // Overloaded Function.
145 // Takes a SkPaint object to measure the string width.
146 string16 ElideUrl(const GURL& url,
147 const SkPaint paint,
148 SkScalar available_point_width,
149 const std::string& languages) {
150 return ElideUrl(url, (void* )&paint, available_point_width, languages,
151 Skia_Paint);
152 }
153
154 // Overloaded Function.
155 // Takes a pointer to font or paint object and the |object_type| is specified.
156 string16 ElideUrl(const GURL& url,
157 void* font_or_paint,
158 int available_width,
159 const std::string& languages,
160 ObjectType object_type) {
117 // Get a formatted string and corresponding parsing of the url. 161 // Get a formatted string and corresponding parsing of the url.
118 url_parse::Parsed parsed; 162 url_parse::Parsed parsed;
119 string16 url_string = net::FormatUrl(url, languages, net::kFormatUrlOmitAll, 163 string16 url_string = net::FormatUrl(url, languages, net::kFormatUrlOmitAll,
120 UnescapeRule::SPACES, &parsed, NULL, NULL); 164 UnescapeRule::SPACES, &parsed, NULL, NULL);
121 if (available_pixel_width <= 0) 165 if (available_width <= 0)
122 return url_string; 166 return url_string;
123 167
124 // If non-standard or not file type, return plain eliding. 168 // If non-standard or not file type, return plain eliding.
125 if (!(url.SchemeIsFile() || url.IsStandard())) 169 if (!(url.SchemeIsFile() || url.IsStandard()))
126 return ElideText(url_string, font, available_pixel_width, false); 170 return ElideText(url_string, font_or_paint, available_width, false,
171 object_type);
127 172
128 // Now start eliding url_string to fit within available pixel width. 173 // Now start eliding url_string to fit within available pixel width.
129 // Fist pass - check to see whether entire url_string fits. 174 // Fist pass - check to see whether entire url_string fits.
130 int pixel_width_url_string = font.GetStringWidth(url_string); 175 int pixel_width_url_string = measureStringWidth(url_string, font_or_paint,
131 if (available_pixel_width >= pixel_width_url_string) 176 object_type);
177 if (available_width >= pixel_width_url_string)
132 return url_string; 178 return url_string;
133 179
134 // Get the path substring, including query and reference. 180 // Get the path substring, including query and reference.
135 size_t path_start_index = parsed.path.begin; 181 size_t path_start_index = parsed.path.begin;
136 size_t path_len = parsed.path.len; 182 size_t path_len = parsed.path.len;
137 string16 url_path_query_etc = url_string.substr(path_start_index); 183 string16 url_path_query_etc = url_string.substr(path_start_index);
138 string16 url_path = url_string.substr(path_start_index, path_len); 184 string16 url_path = url_string.substr(path_start_index, path_len);
139 185
140 // Return general elided text if url minus the query fits. 186 // Return general elided text if url minus the query fits.
141 string16 url_minus_query = url_string.substr(0, path_start_index + path_len); 187 string16 url_minus_query = url_string.substr(0, path_start_index + path_len);
142 if (available_pixel_width >= font.GetStringWidth(url_minus_query)) 188 if (available_width >= measureStringWidth(url_minus_query, font_or_paint,
143 return ElideText(url_string, font, available_pixel_width, false); 189 object_type)) {
190 return ElideText(url_string, font_or_paint, available_width, false,
191 object_type);
192 }
144 193
145 // Get Host. 194 // Get Host.
146 string16 url_host = UTF8ToUTF16(url.host()); 195 string16 url_host = UTF8ToUTF16(url.host());
147 196
148 // Get domain and registry information from the URL. 197 // Get domain and registry information from the URL.
149 string16 url_domain = UTF8ToUTF16( 198 string16 url_domain = UTF8ToUTF16(
150 net::RegistryControlledDomainService::GetDomainAndRegistry(url)); 199 net::RegistryControlledDomainService::GetDomainAndRegistry(url));
151 if (url_domain.empty()) 200 if (url_domain.empty())
152 url_domain = url_host; 201 url_domain = url_host;
153 202
(...skipping 26 matching lines...) Expand all
180 url_domain.clear(); 229 url_domain.clear();
181 url_subdomain.clear(); 230 url_subdomain.clear();
182 231
183 static const string16 kColon = UTF8ToUTF16(":"); 232 static const string16 kColon = UTF8ToUTF16(":");
184 url_host = url_domain = file_path_split.at(0).substr(1) + kColon; 233 url_host = url_domain = file_path_split.at(0).substr(1) + kColon;
185 url_path_query_etc = url_path = file_path_split.at(1); 234 url_path_query_etc = url_path = file_path_split.at(1);
186 } 235 }
187 } 236 }
188 237
189 // Second Pass - remove scheme - the rest fits. 238 // Second Pass - remove scheme - the rest fits.
190 int pixel_width_url_host = font.GetStringWidth(url_host); 239 int pixel_width_url_host = measureStringWidth(url_host, font_or_paint,
191 int pixel_width_url_path = font.GetStringWidth(url_path_query_etc); 240 object_type);
192 if (available_pixel_width >= 241 int pixel_width_url_path = measureStringWidth(url_path_query_etc,
242 font_or_paint, object_type);
243 if (available_width >=
193 pixel_width_url_host + pixel_width_url_path) 244 pixel_width_url_host + pixel_width_url_path)
194 return url_host + url_path_query_etc; 245 return url_host + url_path_query_etc;
195 246
196 // Third Pass: Subdomain, domain and entire path fits. 247 // Third Pass: Subdomain, domain and entire path fits.
197 int pixel_width_url_domain = font.GetStringWidth(url_domain); 248 int pixel_width_url_domain = measureStringWidth(url_domain, font_or_paint,
198 int pixel_width_url_subdomain = font.GetStringWidth(url_subdomain); 249 object_type);
199 if (available_pixel_width >= 250 int pixel_width_url_subdomain = measureStringWidth(url_subdomain,
251 font_or_paint,
252 object_type);
253 if (available_width >=
200 pixel_width_url_subdomain + pixel_width_url_domain + 254 pixel_width_url_subdomain + pixel_width_url_domain +
201 pixel_width_url_path) 255 pixel_width_url_path)
202 return url_subdomain + url_domain + url_path_query_etc; 256 return url_subdomain + url_domain + url_path_query_etc;
203 257
204 // Query element. 258 // Query element.
205 string16 url_query; 259 string16 url_query;
206 const int kPixelWidthDotsTrailer = 260 const int kPixelWidthDotsTrailer =
207 font.GetStringWidth(UTF8ToUTF16(kEllipsis)); 261 measureStringWidth(UTF8ToUTF16(kEllipsis), font_or_paint, object_type);
208 if (parsed.query.is_nonempty()) { 262 if (parsed.query.is_nonempty()) {
209 url_query = UTF8ToUTF16("?") + url_string.substr(parsed.query.begin); 263 url_query = UTF8ToUTF16("?") + url_string.substr(parsed.query.begin);
210 if (available_pixel_width >= (pixel_width_url_subdomain + 264 if (available_width >= (pixel_width_url_subdomain +
211 pixel_width_url_domain + pixel_width_url_path - 265 pixel_width_url_domain + pixel_width_url_path -
212 font.GetStringWidth(url_query))) { 266 measureStringWidth(url_query, font_or_paint, object_type))) {
213 return ElideText(url_subdomain + url_domain + url_path_query_etc, 267 return ElideText(url_subdomain + url_domain + url_path_query_etc,
214 font, available_pixel_width, false); 268 font_or_paint, available_width, false, object_type);
215 } 269 }
216 } 270 }
217 271
218 // Parse url_path using '/'. 272 // Parse url_path using '/'.
219 std::vector<string16> url_path_elements; 273 std::vector<string16> url_path_elements;
220 base::SplitString(url_path, kForwardSlash, &url_path_elements); 274 base::SplitString(url_path, kForwardSlash, &url_path_elements);
221 275
222 // Get filename - note that for a path ending with / 276 // Get filename - note that for a path ending with /
223 // such as www.google.com/intl/ads/, the file name is ads/. 277 // such as www.google.com/intl/ads/, the file name is ads/.
224 size_t url_path_number_of_elements = url_path_elements.size(); 278 size_t url_path_number_of_elements = url_path_elements.size();
225 DCHECK(url_path_number_of_elements != 0); 279 DCHECK(url_path_number_of_elements != 0);
226 string16 url_filename; 280 string16 url_filename;
227 if ((url_path_elements.at(url_path_number_of_elements - 1)).length() > 0) { 281 if ((url_path_elements.at(url_path_number_of_elements - 1)).length() > 0) {
228 url_filename = *(url_path_elements.end() - 1); 282 url_filename = *(url_path_elements.end() - 1);
229 } else if (url_path_number_of_elements > 1) { // Path ends with a '/'. 283 } else if (url_path_number_of_elements > 1) { // Path ends with a '/'.
230 url_filename = url_path_elements.at(url_path_number_of_elements - 2) + 284 url_filename = url_path_elements.at(url_path_number_of_elements - 2) +
231 kForwardSlash; 285 kForwardSlash;
232 url_path_number_of_elements--; 286 url_path_number_of_elements--;
233 } 287 }
234 DCHECK(url_path_number_of_elements != 0); 288 DCHECK(url_path_number_of_elements != 0);
235 289
236 const size_t kMaxNumberOfUrlPathElementsAllowed = 1024; 290 const size_t kMaxNumberOfUrlPathElementsAllowed = 1024;
237 if (url_path_number_of_elements <= 1 || 291 if (url_path_number_of_elements <= 1 ||
238 url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { 292 url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) {
239 // No path to elide, or too long of a path (could overflow in loop below) 293 // No path to elide, or too long of a path (could overflow in loop below)
240 // Just elide this as a text string. 294 // Just elide this as a text string.
241 return ElideText(url_subdomain + url_domain + url_path_query_etc, font, 295 return ElideText(url_subdomain + url_domain + url_path_query_etc,
242 available_pixel_width, false); 296 font_or_paint, available_width, false, object_type);
243 } 297 }
244 298
245 // Start eliding the path and replacing elements by ".../". 299 // Start eliding the path and replacing elements by ".../".
246 const string16 kEllipsisAndSlash = UTF8ToUTF16(kEllipsis) + kForwardSlash; 300 const string16 kEllipsisAndSlash = UTF8ToUTF16(kEllipsis) + kForwardSlash;
247 int pixel_width_ellipsis_slash = font.GetStringWidth(kEllipsisAndSlash); 301 int pixel_width_ellipsis_slash = measureStringWidth(kEllipsisAndSlash,
302 font_or_paint,
303 object_type);
248 304
249 // Check with both subdomain and domain. 305 // Check with both subdomain and domain.
250 string16 elided_path = ElideComponentizedPath(url_subdomain + url_domain, 306 string16 elided_path = ElideComponentizedPath(url_subdomain + url_domain,
251 url_path_elements, url_filename, url_query, font, available_pixel_width); 307 url_path_elements, url_filename, url_query, font_or_paint,
308 available_width, object_type);
252 if (!elided_path.empty()) 309 if (!elided_path.empty())
253 return elided_path; 310 return elided_path;
254 311
255 // Check with only domain. 312 // Check with only domain.
256 // If a subdomain is present, add an ellipsis before domain. 313 // If a subdomain is present, add an ellipsis before domain.
257 // This is added only if the subdomain pixel width is larger than 314 // This is added only if the subdomain pixel width is larger than
258 // the pixel width of kEllipsis. Otherwise, subdomain remains, 315 // the pixel width of kEllipsis. Otherwise, subdomain remains,
259 // which means that this case has been resolved earlier. 316 // which means that this case has been resolved earlier.
260 string16 url_elided_domain = url_subdomain + url_domain; 317 string16 url_elided_domain = url_subdomain + url_domain;
261 int pixel_width_url_elided_domain = pixel_width_url_domain; 318 int pixel_width_url_elided_domain = pixel_width_url_domain;
262 if (pixel_width_url_subdomain > kPixelWidthDotsTrailer) { 319 if (pixel_width_url_subdomain > kPixelWidthDotsTrailer) {
263 if (!url_subdomain.empty()) { 320 if (!url_subdomain.empty()) {
264 url_elided_domain = kEllipsisAndSlash[0] + url_domain; 321 url_elided_domain = kEllipsisAndSlash[0] + url_domain;
265 pixel_width_url_elided_domain += kPixelWidthDotsTrailer; 322 pixel_width_url_elided_domain += kPixelWidthDotsTrailer;
266 } else { 323 } else {
267 url_elided_domain = url_domain; 324 url_elided_domain = url_domain;
268 } 325 }
269 326
270 elided_path = ElideComponentizedPath(url_elided_domain, url_path_elements, 327 elided_path = ElideComponentizedPath(url_elided_domain, url_path_elements,
271 url_filename, url_query, font, available_pixel_width); 328 url_filename, url_query, font_or_paint, available_width, object_type);
272 329
273 if (!elided_path.empty()) 330 if (!elided_path.empty())
274 return elided_path; 331 return elided_path;
275 } 332 }
276 333
277 // Return elided domain/.../filename anyway. 334 // Return elided domain/.../filename anyway.
278 string16 final_elided_url_string(url_elided_domain); 335 string16 final_elided_url_string(url_elided_domain);
279 int url_elided_domain_width = font.GetStringWidth(url_elided_domain); 336 int url_elided_domain_width = measureStringWidth(url_elided_domain,
337 font_or_paint, object_type);
280 338
281 // A hack to prevent trailing ".../...". 339 // A hack to prevent trailing ".../...".
282 if ((available_pixel_width - url_elided_domain_width) > 340 if ((available_width - url_elided_domain_width) >
283 pixel_width_ellipsis_slash + kPixelWidthDotsTrailer + 341 pixel_width_ellipsis_slash + kPixelWidthDotsTrailer +
284 font.GetStringWidth(ASCIIToUTF16("UV"))) { 342 measureStringWidth(ASCIIToUTF16("UV"), font_or_paint, object_type)) {
285 final_elided_url_string += BuildPathFromComponents(string16(), 343 final_elided_url_string += BuildPathFromComponents(string16(),
286 url_path_elements, url_filename, 1); 344 url_path_elements, url_filename, 1);
287 } else { 345 } else {
288 final_elided_url_string += url_path; 346 final_elided_url_string += url_path;
289 } 347 }
290 348
291 return ElideText(final_elided_url_string, font, available_pixel_width, false); 349 return ElideText(final_elided_url_string, font_or_paint, available_width,
350 false, object_type);
292 } 351 }
293 352
294 string16 ElideFilename(const FilePath& filename, 353 string16 ElideFilename(const FilePath& filename,
295 const gfx::Font& font, 354 const gfx::Font& font,
296 int available_pixel_width) { 355 int available_width) {
297 #if defined(OS_WIN) 356 #if defined(OS_WIN)
298 string16 filename_utf16 = filename.value(); 357 string16 filename_utf16 = filename.value();
299 string16 extension = filename.Extension(); 358 string16 extension = filename.Extension();
300 string16 rootname = filename.BaseName().RemoveExtension().value(); 359 string16 rootname = filename.BaseName().RemoveExtension().value();
301 #elif defined(OS_POSIX) 360 #elif defined(OS_POSIX)
302 string16 filename_utf16 = WideToUTF16(base::SysNativeMBToWide( 361 string16 filename_utf16 = WideToUTF16(base::SysNativeMBToWide(
303 filename.value())); 362 filename.value()));
304 string16 extension = WideToUTF16(base::SysNativeMBToWide( 363 string16 extension = WideToUTF16(base::SysNativeMBToWide(
305 filename.Extension())); 364 filename.Extension()));
306 string16 rootname = WideToUTF16(base::SysNativeMBToWide( 365 string16 rootname = WideToUTF16(base::SysNativeMBToWide(
307 filename.BaseName().RemoveExtension().value())); 366 filename.BaseName().RemoveExtension().value()));
308 #endif 367 #endif
309 368
310 int full_width = font.GetStringWidth(filename_utf16); 369 int full_width = font.GetStringWidth(filename_utf16);
311 if (full_width <= available_pixel_width) 370 if (full_width <= available_width)
312 return base::i18n::GetDisplayStringInLTRDirectionality(filename_utf16); 371 return base::i18n::GetDisplayStringInLTRDirectionality(filename_utf16);
313 372
314 if (rootname.empty() || extension.empty()) { 373 if (rootname.empty() || extension.empty()) {
315 string16 elided_name = ElideText(filename_utf16, font, 374 string16 elided_name = ElideText(filename_utf16, font,
316 available_pixel_width, false); 375 available_width, false);
317 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); 376 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
318 } 377 }
319 378
320 int ext_width = font.GetStringWidth(extension); 379 int ext_width = font.GetStringWidth(extension);
321 int root_width = font.GetStringWidth(rootname); 380 int root_width = font.GetStringWidth(rootname);
322 381
323 // We may have trimmed the path. 382 // We may have trimmed the path.
324 if (root_width + ext_width <= available_pixel_width) { 383 if (root_width + ext_width <= available_width) {
325 string16 elided_name = rootname + extension; 384 string16 elided_name = rootname + extension;
326 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); 385 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
327 } 386 }
328 387
329 if (ext_width >= available_pixel_width) { 388 if (ext_width >= available_width) {
330 string16 elided_name = ElideText(rootname + extension, font, 389 string16 elided_name = ElideText(rootname + extension, font,
331 available_pixel_width, true); 390 available_width, true);
332 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); 391 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
333 } 392 }
334 393
335 int available_root_width = available_pixel_width - ext_width; 394 int available_root_width = available_width - ext_width;
336 string16 elided_name = 395 string16 elided_name =
337 ElideText(rootname, font, available_root_width, false); 396 ElideText(rootname, font, available_root_width, false);
338 elided_name += extension; 397 elided_name += extension;
339 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name); 398 return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
340 } 399 }
341 400
342 // This function adds an ellipsis at the end of the text if the text 401 // This function adds an ellipsis at the end of the text if the text
343 // does not fit the given pixel width. 402 // does not fit the given pixel width.
344 string16 ElideText(const string16& text, 403 string16 ElideText(const string16& text,
345 const gfx::Font& font, 404 const gfx::Font& font,
346 int available_pixel_width, 405 int available_pixel_width,
347 bool elide_in_middle) { 406 bool elide_in_middle) {
407 return ElideText(text, (void* )&font, (SkScalar)available_pixel_width,
408 elide_in_middle, GFX_Font);
409 }
410
411 // Overloaded function.
412 // Uses SkPaint object to determine text width
413 string16 ElideText(const string16& text,
414 const SkPaint paint,
415 SkScalar available_point_width,
416 bool elide_in_middle) {
417 return ElideText(text, (void* )&paint, available_point_width, elide_in_middle,
418 Skia_Paint);
419 }
420
421 // Overloaded function.
422 // Takes a pointer to font or paint object and the |object_type| is specified.
423 string16 ElideText(const string16& text,
424 void* font_or_paint,
425 SkScalar available_width,
426 bool elide_in_middle,
427 ObjectType object_type) {
428
348 if (text.empty()) 429 if (text.empty())
349 return text; 430 return text;
350 431
351 int current_text_pixel_width = font.GetStringWidth(text); 432 int current_text_pixel_width = measureStringWidth(text, font_or_paint,
433 object_type);
352 434
353 // Pango will return 0 width for absurdly long strings. Cut the string in 435 // Pango will return 0 width for absurdly long strings. Cut the string in
354 // half and try again. 436 // half and try again.
355 // This is caused by an int overflow in Pango (specifically, in 437 // This is caused by an int overflow in Pango (specifically, in
356 // pango_glyph_string_extents_range). It's actually more subtle than just 438 // pango_glyph_string_extents_range). It's actually more subtle than just
357 // returning 0, since on super absurdly long strings, the int can wrap and 439 // returning 0, since on super absurdly long strings, the int can wrap and
358 // return positive numbers again. Detecting that is probably not worth it 440 // return positive numbers again. Detecting that is probably not worth it
359 // (eliding way too much from a ridiculous string is probably still 441 // (eliding way too much from a ridiculous string is probably still
360 // ridiculous), but we should check other widths for bogus values as well. 442 // ridiculous), but we should check other widths for bogus values as well.
361 if (current_text_pixel_width <= 0 && !text.empty()) { 443 if (current_text_pixel_width <= 0 && !text.empty()) {
362 return ElideText(CutString(text, text.length() / 2, elide_in_middle, false), 444 return ElideText(CutString(text, text.length() / 2, elide_in_middle, false),
363 font, available_pixel_width, false); 445 font_or_paint, available_width, false, object_type);
364 } 446 }
365 447
366 if (current_text_pixel_width <= available_pixel_width) 448 if (current_text_pixel_width <= available_width)
367 return text; 449 return text;
368 450
369 if (font.GetStringWidth(UTF8ToUTF16(kEllipsis)) > available_pixel_width) 451 if (measureStringWidth(UTF8ToUTF16(kEllipsis), font_or_paint, object_type) >
452 available_width)
370 return string16(); 453 return string16();
371 454
372 // Use binary search to compute the elided text. 455 // Use binary search to compute the elided text.
373 size_t lo = 0; 456 size_t lo = 0;
374 size_t hi = text.length() - 1; 457 size_t hi = text.length() - 1;
375 for (size_t guess = (lo + hi) / 2; guess != lo; guess = (lo + hi) / 2) { 458 for (size_t guess = (lo + hi) / 2; guess != lo; guess = (lo + hi) / 2) {
376 // We check the length of the whole desired string at once to ensure we 459 // We check the length of the whole desired string at once to ensure we
377 // handle kerning/ligatures/etc. correctly. 460 // handle kerning/ligatures/etc. correctly.
378 int guess_length = font.GetStringWidth( 461 int guess_length = measureStringWidth(//font.GetStringWidth(
379 CutString(text, guess, elide_in_middle, true)); 462 CutString(text, guess, elide_in_middle, true), font_or_paint,
463 object_type);
380 // Check again that we didn't hit a Pango width overflow. If so, cut the 464 // Check again that we didn't hit a Pango width overflow. If so, cut the
381 // current string in half and start over. 465 // current string in half and start over.
382 if (guess_length <= 0) { 466 if (guess_length <= 0) {
383 return ElideText(CutString(text, guess / 2, elide_in_middle, false), 467 return ElideText(CutString(text, guess / 2, elide_in_middle, false),
384 font, available_pixel_width, elide_in_middle); 468 font_or_paint, available_width, elide_in_middle,
469 object_type);
385 } 470 }
386 if (guess_length > available_pixel_width) 471 if (guess_length > available_width)
387 hi = guess; 472 hi = guess;
388 else 473 else
389 lo = guess; 474 lo = guess;
390 } 475 }
391 476
392 return CutString(text, lo, elide_in_middle, true); 477 return CutString(text, lo, elide_in_middle, true);
393 } 478 }
394 479
395 SortedDisplayURL::SortedDisplayURL(const GURL& url, 480 SortedDisplayURL::SortedDisplayURL(const GURL& url,
396 const std::string& languages) { 481 const std::string& languages) {
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 752
668 bool ElideRectangleString(const string16& input, size_t max_rows, 753 bool ElideRectangleString(const string16& input, size_t max_rows,
669 size_t max_cols, bool strict, string16* output) { 754 size_t max_cols, bool strict, string16* output) {
670 RectangleString rect(max_rows, max_cols, strict, output); 755 RectangleString rect(max_rows, max_cols, strict, output);
671 rect.Init(); 756 rect.Init();
672 rect.AddString(input); 757 rect.AddString(input);
673 return rect.Finalize(); 758 return rect.Finalize();
674 } 759 }
675 760
676 } // namespace ui 761 } // namespace ui
OLDNEW
« ui/base/text/text_elider.h ('K') | « ui/base/text/text_elider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698