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

Side by Side Diff: ui/gfx/canvas_skia.cc

Issue 10391187: Merge 137535 - Fix incorrect forcing of text directionality in canvas_skia.cc. (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1132/src/
Patch Set: Created 8 years, 7 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
« no previous file with comments | « no previous file | 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) 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"
11 #include "ui/base/text/text_elider.h" 11 #include "ui/base/text/text_elider.h"
12 #include "ui/gfx/font.h" 12 #include "ui/gfx/font.h"
13 #include "ui/gfx/font_list.h" 13 #include "ui/gfx/font_list.h"
14 #include "ui/gfx/insets.h" 14 #include "ui/gfx/insets.h"
15 #include "ui/gfx/rect.h" 15 #include "ui/gfx/rect.h"
16 #include "ui/gfx/render_text.h" 16 #include "ui/gfx/render_text.h"
17 #include "ui/gfx/shadow_value.h" 17 #include "ui/gfx/shadow_value.h"
18 #include "ui/gfx/skia_util.h" 18 #include "ui/gfx/skia_util.h"
19 19
20 namespace { 20 namespace {
21 21
22 // Based on |flags| and |text| content, returns whether text should be 22 // If necessary, wraps |text| with RTL/LTR directionality characters based on
23 // rendered right-to-left. 23 // |flags| and |text| content.
24 bool IsTextRTL(int flags, const string16& text) { 24 // Returns true if the text will be rendered right-to-left.
25 if (flags & gfx::Canvas::FORCE_RTL_DIRECTIONALITY) 25 // TODO(asvitkine): Support setting directionality directly on RenderText, so
26 // that wrapping the text is not needed.
27 bool AdjustStringDirection(int flags, string16* text) {
28 // If the string is empty or LTR was forced, simply return false since the
29 // default RenderText directionality is already LTR.
30 if (text->empty() || (flags & gfx::Canvas::FORCE_LTR_DIRECTIONALITY))
31 return false;
32
33 // If RTL is forced, apply it to the string.
34 if (flags & gfx::Canvas::FORCE_RTL_DIRECTIONALITY) {
35 base::i18n::WrapStringWithRTLFormatting(text);
26 return true; 36 return true;
27 if (flags & gfx::Canvas::FORCE_LTR_DIRECTIONALITY) 37 }
28 return false; 38
29 return base::i18n::IsRTL() && base::i18n::StringContainsStrongRTLChars(text); 39 // If a direction wasn't forced but the UI language is RTL and there were
40 // strong RTL characters, ensure RTL is applied.
41 if (base::i18n::IsRTL() && base::i18n::StringContainsStrongRTLChars(*text)) {
42 base::i18n::WrapStringWithRTLFormatting(text);
43 return true;
44 }
45
46 // In the default case, the string should be rendered as LTR. RenderText's
47 // default directionality is LTR, so the text doesn't need to be wrapped.
48 // Note that individual runs within the string may still be rendered RTL
49 // (which will be the case for RTL text under non-RTL locales, since under RTL
50 // locales it will be handled by the if statement above).
51 return false;
30 } 52 }
31 53
32 // Checks each pixel immediately adjacent to the given pixel in the bitmap. If 54 // Checks each pixel immediately adjacent to the given pixel in the bitmap. If
33 // any of them are not the halo color, returns true. This defines the halo of 55 // any of them are not the halo color, returns true. This defines the halo of
34 // pixels that will appear around the text. Note that we have to check each 56 // pixels that will appear around the text. Note that we have to check each
35 // pixel against both the halo color and transparent since |DrawStringWithHalo| 57 // pixel against both the halo color and transparent since |DrawStringWithHalo|
36 // will modify the bitmap as it goes, and cleared pixels shouldn't count as 58 // will modify the bitmap as it goes, and cleared pixels shouldn't count as
37 // changed. 59 // changed.
38 bool PixelShouldGetHalo(const SkBitmap& bitmap, 60 bool PixelShouldGetHalo(const SkBitmap& bitmap,
39 int x, int y, 61 int x, int y,
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 190
169 // static 191 // static
170 void Canvas::SizeStringInt(const string16& text, 192 void Canvas::SizeStringInt(const string16& text,
171 const gfx::Font& font, 193 const gfx::Font& font,
172 int* width, int* height, 194 int* width, int* height,
173 int flags) { 195 int flags) {
174 DCHECK_GE(*width, 0); 196 DCHECK_GE(*width, 0);
175 DCHECK_GE(*height, 0); 197 DCHECK_GE(*height, 0);
176 198
177 flags = AdjustPlatformSpecificFlags(text, flags); 199 flags = AdjustPlatformSpecificFlags(text, flags);
200
201 string16 adjusted_text = text;
202 #if defined(OS_WIN)
203 AdjustStringDirection(flags, &adjusted_text);
204 #endif
205
178 if ((flags & MULTI_LINE) && *width != 0) { 206 if ((flags & MULTI_LINE) && *width != 0) {
179 ui::WordWrapBehavior wrap_behavior = ui::TRUNCATE_LONG_WORDS; 207 ui::WordWrapBehavior wrap_behavior = ui::TRUNCATE_LONG_WORDS;
180 if (flags & CHARACTER_BREAK) 208 if (flags & CHARACTER_BREAK)
181 wrap_behavior = ui::WRAP_LONG_WORDS; 209 wrap_behavior = ui::WRAP_LONG_WORDS;
182 else if (!(flags & NO_ELLIPSIS)) 210 else if (!(flags & NO_ELLIPSIS))
183 wrap_behavior = ui::ELIDE_LONG_WORDS; 211 wrap_behavior = ui::ELIDE_LONG_WORDS;
184 212
185 gfx::Rect rect(*width, INT_MAX); 213 gfx::Rect rect(*width, INT_MAX);
186 std::vector<string16> strings; 214 std::vector<string16> strings;
187 ui::ElideRectangleText(text, font, rect.width(), rect.height(), 215 ui::ElideRectangleText(adjusted_text, font, rect.width(), rect.height(),
188 wrap_behavior, &strings); 216 wrap_behavior, &strings);
189 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); 217 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText());
190 UpdateRenderText(rect, string16(), font, flags, 0, render_text.get()); 218 UpdateRenderText(rect, string16(), font, flags, 0, render_text.get());
191 219
192 int h = 0; 220 int h = 0;
193 int w = 0; 221 int w = 0;
194 for (size_t i = 0; i < strings.size(); ++i) { 222 for (size_t i = 0; i < strings.size(); ++i) {
195 StripAcceleratorChars(flags, &strings[i]); 223 StripAcceleratorChars(flags, &strings[i]);
196 render_text->SetText(strings[i]); 224 render_text->SetText(strings[i]);
197 const Size string_size = render_text->GetStringSize(); 225 const Size string_size = render_text->GetStringSize();
198 w = std::max(w, string_size.width()); 226 w = std::max(w, string_size.width());
199 h += string_size.height(); 227 h += string_size.height();
200 } 228 }
201 *width = w; 229 *width = w;
202 *height = h; 230 *height = h;
203 } else { 231 } else {
204 // If the string is too long, the call by |RenderTextWin| to |ScriptShape()| 232 // If the string is too long, the call by |RenderTextWin| to |ScriptShape()|
205 // will inexplicably fail with result E_INVALIDARG. Guard against this. 233 // will inexplicably fail with result E_INVALIDARG. Guard against this.
206 const size_t kMaxRenderTextLength = 5000; 234 const size_t kMaxRenderTextLength = 5000;
207 if (text.length() >= kMaxRenderTextLength) { 235 if (adjusted_text.length() >= kMaxRenderTextLength) {
208 *width = text.length() * font.GetAverageCharacterWidth(); 236 *width = adjusted_text.length() * font.GetAverageCharacterWidth();
209 *height = font.GetHeight(); 237 *height = font.GetHeight();
210 } else { 238 } else {
211 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); 239 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText());
212 gfx::Rect rect(*width, *height); 240 gfx::Rect rect(*width, *height);
213 string16 adjusted_text = text;
214 StripAcceleratorChars(flags, &adjusted_text); 241 StripAcceleratorChars(flags, &adjusted_text);
215 UpdateRenderText(rect, adjusted_text, font, flags, 0, render_text.get()); 242 UpdateRenderText(rect, adjusted_text, font, flags, 0, render_text.get());
216 const Size string_size = render_text->GetStringSize(); 243 const Size string_size = render_text->GetStringSize();
217 *width = string_size.width(); 244 *width = string_size.width();
218 *height = string_size.height(); 245 *height = string_size.height();
219 } 246 }
220 } 247 }
221 } 248 }
222 249
223 void Canvas::DrawStringWithShadows(const string16& text, 250 void Canvas::DrawStringWithShadows(const string16& text,
(...skipping 19 matching lines...) Expand all
243 gfx::Rect clip_rect(text_bounds); 270 gfx::Rect clip_rect(text_bounds);
244 clip_rect.Inset(ShadowValue::GetMargin(shadows)); 271 clip_rect.Inset(ShadowValue::GetMargin(shadows));
245 272
246 canvas_->save(SkCanvas::kClip_SaveFlag); 273 canvas_->save(SkCanvas::kClip_SaveFlag);
247 ClipRect(clip_rect); 274 ClipRect(clip_rect);
248 275
249 gfx::Rect rect(text_bounds); 276 gfx::Rect rect(text_bounds);
250 string16 adjusted_text = text; 277 string16 adjusted_text = text;
251 278
252 #if defined(OS_WIN) 279 #if defined(OS_WIN)
253 if (IsTextRTL(flags, adjusted_text)) 280 AdjustStringDirection(flags, &adjusted_text);
254 base::i18n::AdjustStringForLocaleDirection(&adjusted_text);
255 #endif 281 #endif
256 282
257 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); 283 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText());
258 render_text->SetTextShadows(shadows); 284 render_text->SetTextShadows(shadows);
259 285
260 if (flags & MULTI_LINE) { 286 if (flags & MULTI_LINE) {
261 ui::WordWrapBehavior wrap_behavior = ui::IGNORE_LONG_WORDS; 287 ui::WordWrapBehavior wrap_behavior = ui::IGNORE_LONG_WORDS;
262 if (flags & CHARACTER_BREAK) 288 if (flags & CHARACTER_BREAK)
263 wrap_behavior = ui::WRAP_LONG_WORDS; 289 wrap_behavior = ui::WRAP_LONG_WORDS;
264 else if (!(flags & NO_ELLIPSIS)) 290 else if (!(flags & NO_ELLIPSIS))
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 411
386 // If the whole string fits in the destination then just draw it directly. 412 // If the whole string fits in the destination then just draw it directly.
387 if (GetStringWidth(text, font) <= display_rect.width()) { 413 if (GetStringWidth(text, font) <= display_rect.width()) {
388 DrawStringInt(text, font, color, display_rect.x(), display_rect.y(), 414 DrawStringInt(text, font, color, display_rect.x(), display_rect.y(),
389 display_rect.width(), display_rect.height(), flags); 415 display_rect.width(), display_rect.height(), flags);
390 return; 416 return;
391 } 417 }
392 418
393 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText()); 419 scoped_ptr<RenderText> render_text(RenderText::CreateRenderText());
394 string16 clipped_text = text; 420 string16 clipped_text = text;
395 const bool is_rtl = IsTextRTL(flags, text); 421 const bool is_rtl = AdjustStringDirection(flags, &clipped_text);
396 if (is_rtl)
397 base::i18n::AdjustStringForLocaleDirection(&clipped_text);
398 422
399 switch (truncate_mode) { 423 switch (truncate_mode) {
400 case TruncateFadeTail: 424 case TruncateFadeTail:
401 render_text->set_fade_tail(true); 425 render_text->set_fade_tail(true);
402 if (is_rtl) 426 if (is_rtl)
403 flags |= TEXT_ALIGN_RIGHT; 427 flags |= TEXT_ALIGN_RIGHT;
404 break; 428 break;
405 case TruncateFadeHead: 429 case TruncateFadeHead:
406 render_text->set_fade_head(true); 430 render_text->set_fade_head(true);
407 if (!is_rtl) 431 if (!is_rtl)
(...skipping 30 matching lines...) Expand all
438 render_text->SetDisplayRect(rect); 462 render_text->SetDisplayRect(rect);
439 463
440 canvas_->save(SkCanvas::kClip_SaveFlag); 464 canvas_->save(SkCanvas::kClip_SaveFlag);
441 ClipRect(display_rect); 465 ClipRect(display_rect);
442 render_text->Draw(this); 466 render_text->Draw(this);
443 canvas_->restore(); 467 canvas_->restore();
444 } 468 }
445 #endif 469 #endif
446 470
447 } // namespace gfx 471 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698