OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/gfx/canvas.h" | 5 #include "ui/gfx/canvas.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "ui/base/range/range.h" | 10 #include "ui/base/range/range.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 *bitmap.getAddr32(x, y - 1) != halo_color && | 73 *bitmap.getAddr32(x, y - 1) != halo_color && |
74 *bitmap.getAddr32(x, y - 1) != 0) | 74 *bitmap.getAddr32(x, y - 1) != 0) |
75 return true; // Touched pixel above. | 75 return true; // Touched pixel above. |
76 if (y < bitmap.height() - 1 && | 76 if (y < bitmap.height() - 1 && |
77 *bitmap.getAddr32(x, y + 1) != halo_color && | 77 *bitmap.getAddr32(x, y + 1) != halo_color && |
78 *bitmap.getAddr32(x, y + 1) != 0) | 78 *bitmap.getAddr32(x, y + 1) != 0) |
79 return true; // Touched pixel below. | 79 return true; // Touched pixel below. |
80 return false; | 80 return false; |
81 } | 81 } |
82 | 82 |
83 // Apply vertical alignment per |flags|. Returns y-coordinate delta. | |
84 int VAlignText(int text_height, | |
85 int flags, | |
86 int available_height) { | |
87 if (flags & gfx::Canvas::TEXT_VALIGN_TOP) | |
88 return 0; | |
89 | |
90 if (flags & gfx::Canvas::TEXT_VALIGN_BOTTOM) | |
91 return available_height - text_height; | |
92 | |
93 // Default case: TEXT_VALIGN_MIDDLE. | |
94 return (available_height - text_height) / 2; | |
95 } | |
96 | |
97 // Strips accelerator character prefixes in |text| if needed, based on |flags|. | 83 // Strips accelerator character prefixes in |text| if needed, based on |flags|. |
98 // Returns a range in |text| to underline or ui::Range::InvalidRange() if | 84 // Returns a range in |text| to underline or ui::Range::InvalidRange() if |
99 // underlining is not needed. | 85 // underlining is not needed. |
100 ui::Range StripAcceleratorChars(int flags, string16* text) { | 86 ui::Range StripAcceleratorChars(int flags, string16* text) { |
101 if (flags & (gfx::Canvas::SHOW_PREFIX | gfx::Canvas::HIDE_PREFIX)) { | 87 if (flags & (gfx::Canvas::SHOW_PREFIX | gfx::Canvas::HIDE_PREFIX)) { |
102 int char_pos = -1; | 88 int char_pos = -1; |
103 int char_span = 0; | 89 int char_span = 0; |
104 *text = gfx::RemoveAcceleratorChar(*text, '&', &char_pos, &char_span); | 90 *text = gfx::RemoveAcceleratorChar(*text, '&', &char_pos, &char_span); |
105 if ((flags & gfx::Canvas::SHOW_PREFIX) && char_pos != -1) | 91 if ((flags & gfx::Canvas::SHOW_PREFIX) && char_pos != -1) |
106 return ui::Range(char_pos, char_pos + char_span); | 92 return ui::Range(char_pos, char_pos + char_span); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 const gfx::Font& font, | 241 const gfx::Font& font, |
256 SkColor color, | 242 SkColor color, |
257 const gfx::Rect& text_bounds, | 243 const gfx::Rect& text_bounds, |
258 int flags, | 244 int flags, |
259 const ShadowValues& shadows) { | 245 const ShadowValues& shadows) { |
260 if (!IntersectsClipRect(text_bounds)) | 246 if (!IntersectsClipRect(text_bounds)) |
261 return; | 247 return; |
262 | 248 |
263 flags = AdjustPlatformSpecificFlags(text, flags); | 249 flags = AdjustPlatformSpecificFlags(text, flags); |
264 | 250 |
265 #if defined(OS_WIN) | |
266 // TODO(asvitkine): On Windows, MULTI_LINE implies top alignment. | |
267 // http://crbug.com/107357 | |
268 if (flags & MULTI_LINE) { | |
269 flags &= ~(TEXT_VALIGN_MIDDLE | TEXT_VALIGN_BOTTOM); | |
270 flags |= TEXT_VALIGN_TOP; | |
271 } | |
272 #endif | |
273 | |
274 gfx::Rect clip_rect(text_bounds); | 251 gfx::Rect clip_rect(text_bounds); |
275 clip_rect.Inset(ShadowValue::GetMargin(shadows)); | 252 clip_rect.Inset(ShadowValue::GetMargin(shadows)); |
276 | 253 |
277 canvas_->save(SkCanvas::kClip_SaveFlag); | 254 canvas_->save(SkCanvas::kClip_SaveFlag); |
278 ClipRect(clip_rect); | 255 ClipRect(clip_rect); |
279 | 256 |
280 gfx::Rect rect(text_bounds); | 257 gfx::Rect rect(text_bounds); |
281 string16 adjusted_text = text; | 258 string16 adjusted_text = text; |
282 | 259 |
283 #if defined(OS_WIN) | 260 #if defined(OS_WIN) |
(...skipping 13 matching lines...) Expand all Loading... |
297 std::vector<string16> strings; | 274 std::vector<string16> strings; |
298 ui::ElideRectangleText(adjusted_text, | 275 ui::ElideRectangleText(adjusted_text, |
299 font, | 276 font, |
300 text_bounds.width(), text_bounds.height(), | 277 text_bounds.width(), text_bounds.height(), |
301 wrap_behavior, | 278 wrap_behavior, |
302 &strings); | 279 &strings); |
303 | 280 |
304 for (size_t i = 0; i < strings.size(); i++) { | 281 for (size_t i = 0; i < strings.size(); i++) { |
305 ui::Range range = StripAcceleratorChars(flags, &strings[i]); | 282 ui::Range range = StripAcceleratorChars(flags, &strings[i]); |
306 UpdateRenderText(rect, strings[i], font, flags, color, render_text.get()); | 283 UpdateRenderText(rect, strings[i], font, flags, color, render_text.get()); |
| 284 const int line_height = render_text->GetStringSize().height(); |
307 | 285 |
308 // Apply vertical alignment over the block of text using the height of the | 286 // TODO(msw|asvitkine): Center Windows multi-line text: crbug.com/107357 |
309 // first line. This may not be correct if different lines in the text have | 287 #if !defined(OS_WIN) |
310 // different heights, but avoids needing to do two passes. | |
311 const int line_height = render_text->GetStringSize().height(); | |
312 if (i == 0) { | 288 if (i == 0) { |
313 rect.Offset(0, VAlignText(strings.size() * line_height, | 289 // TODO(msw|asvitkine): Support multi-line text with varied heights. |
314 flags, | 290 const int aggregate_height = strings.size() * line_height; |
315 text_bounds.height())); | 291 rect.Offset(0, (text_bounds.height() - aggregate_height) / 2); |
316 } | 292 } |
| 293 #endif |
| 294 |
317 rect.set_height(line_height); | 295 rect.set_height(line_height); |
318 | 296 |
319 ApplyUnderlineStyle(range, render_text.get()); | 297 ApplyUnderlineStyle(range, render_text.get()); |
320 render_text->SetDisplayRect(rect); | 298 render_text->SetDisplayRect(rect); |
321 render_text->Draw(this); | 299 render_text->Draw(this); |
322 rect.Offset(0, line_height); | 300 rect.Offset(0, line_height); |
323 } | 301 } |
324 } else { | 302 } else { |
325 ui::Range range = StripAcceleratorChars(flags, &adjusted_text); | 303 ui::Range range = StripAcceleratorChars(flags, &adjusted_text); |
326 bool elide_text = ((flags & NO_ELLIPSIS) == 0); | 304 bool elide_text = ((flags & NO_ELLIPSIS) == 0); |
(...skipping 14 matching lines...) Expand all Loading... |
341 ElideTextAndAdjustRange(font, | 319 ElideTextAndAdjustRange(font, |
342 text_bounds.width(), | 320 text_bounds.width(), |
343 &adjusted_text, | 321 &adjusted_text, |
344 &range); | 322 &range); |
345 } | 323 } |
346 | 324 |
347 UpdateRenderText(rect, adjusted_text, font, flags, color, | 325 UpdateRenderText(rect, adjusted_text, font, flags, color, |
348 render_text.get()); | 326 render_text.get()); |
349 | 327 |
350 const int line_height = render_text->GetStringSize().height(); | 328 const int line_height = render_text->GetStringSize().height(); |
351 rect.Offset(0, VAlignText(line_height, flags, text_bounds.height())); | 329 // Center the text vertically. |
| 330 rect.Offset(0, (text_bounds.height() - line_height) / 2); |
352 rect.set_height(line_height); | 331 rect.set_height(line_height); |
353 render_text->SetDisplayRect(rect); | 332 render_text->SetDisplayRect(rect); |
354 | 333 |
355 ApplyUnderlineStyle(range, render_text.get()); | 334 ApplyUnderlineStyle(range, render_text.get()); |
356 render_text->Draw(this); | 335 render_text->Draw(this); |
357 } | 336 } |
358 | 337 |
359 canvas_->restore(); | 338 canvas_->restore(); |
360 } | 339 } |
361 | 340 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 } | 438 } |
460 | 439 |
461 // Default to left alignment unless right alignment was chosen above. | 440 // Default to left alignment unless right alignment was chosen above. |
462 if (!(flags & TEXT_ALIGN_RIGHT)) | 441 if (!(flags & TEXT_ALIGN_RIGHT)) |
463 flags |= TEXT_ALIGN_LEFT; | 442 flags |= TEXT_ALIGN_LEFT; |
464 | 443 |
465 gfx::Rect rect = display_rect; | 444 gfx::Rect rect = display_rect; |
466 UpdateRenderText(rect, clipped_text, font, flags, color, render_text.get()); | 445 UpdateRenderText(rect, clipped_text, font, flags, color, render_text.get()); |
467 | 446 |
468 const int line_height = render_text->GetStringSize().height(); | 447 const int line_height = render_text->GetStringSize().height(); |
469 rect.Offset(0, VAlignText(line_height, flags, display_rect.height())); | 448 // Center the text vertically. |
| 449 rect.Offset(0, (display_rect.height() - line_height) / 2); |
470 rect.set_height(line_height); | 450 rect.set_height(line_height); |
471 render_text->SetDisplayRect(rect); | 451 render_text->SetDisplayRect(rect); |
472 | 452 |
473 canvas_->save(SkCanvas::kClip_SaveFlag); | 453 canvas_->save(SkCanvas::kClip_SaveFlag); |
474 ClipRect(display_rect); | 454 ClipRect(display_rect); |
475 render_text->Draw(this); | 455 render_text->Draw(this); |
476 canvas_->restore(); | 456 canvas_->restore(); |
477 } | 457 } |
478 | 458 |
479 } // namespace gfx | 459 } // namespace gfx |
OLD | NEW |