| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/common/gfx/chrome_canvas.h" | 5 #include "chrome/common/gfx/chrome_canvas.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/gfx/rect.h" | 9 #include "base/gfx/rect.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "skia/include/SkShader.h" | 11 #include "skia/include/SkShader.h" |
| 12 #include "chrome/common/gfx/chrome_font.h" | 12 #include "chrome/common/gfx/chrome_font.h" |
| 13 #include "chrome/common/l10n_util.h" | 13 #include "chrome/common/l10n_util.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // We make sure that LTR text we draw in an RTL context is modified | 17 // We make sure that LTR text we draw in an RTL context is modified |
| 18 // appropriately to make sure it maintains it LTR orientation. | 18 // appropriately to make sure it maintains it LTR orientation. |
| 19 void DoDrawText(HDC hdc, const std::wstring& text, | 19 void DoDrawText(HDC hdc, const std::wstring& text, |
| 20 RECT* text_bounds, int flags) { | 20 RECT* text_bounds, int flags) { |
| 21 std::wstring localized_text; | 21 std::wstring localized_text; |
| 22 const wchar_t* string_ptr = text.c_str(); | 22 const wchar_t* string_ptr = text.c_str(); |
| 23 int string_size = static_cast<int>(text.length()); | 23 int string_size = static_cast<int>(text.length()); |
| 24 if (l10n_util::AdjustStringForLocaleDirection(text, &localized_text)) { | 24 // Only adjust string directionality if both of the following are true: |
| 25 string_ptr = localized_text.c_str(); | 25 // 1. The current locale is RTL. |
| 26 string_size = static_cast<int>(localized_text.length()); | 26 // 2. The string itself has RTL directionality. |
| 27 if (flags & DT_RTLREADING) { |
| 28 if (l10n_util::AdjustStringForLocaleDirection(text, &localized_text)) { |
| 29 string_ptr = localized_text.c_str(); |
| 30 string_size = static_cast<int>(localized_text.length()); |
| 31 } |
| 27 } | 32 } |
| 28 | 33 |
| 29 DrawText(hdc, string_ptr, string_size, text_bounds, flags); | 34 DrawText(hdc, string_ptr, string_size, text_bounds, flags); |
| 30 } | 35 } |
| 31 | 36 |
| 32 // Compute the windows flags necessary to implement the provided text | 37 // Compute the windows flags necessary to implement the provided text |
| 33 // ChromeCanvas flags. | 38 // ChromeCanvas flags. |
| 34 int ComputeFormatFlags(int flags) { | 39 int ComputeFormatFlags(int flags, const std::wstring& text) { |
| 35 int f = 0; | 40 int f = 0; |
| 36 | 41 |
| 37 // Setting the text alignment explicitly in case it hasn't already been set. | 42 // Setting the text alignment explicitly in case it hasn't already been set. |
| 38 // This will make sure that we don't align text to the left on RTL locales | 43 // This will make sure that we don't align text to the left on RTL locales |
| 39 // just because no alignment flag was passed to DrawStringInt(). | 44 // just because no alignment flag was passed to DrawStringInt(). |
| 40 if (!(flags & (ChromeCanvas::TEXT_ALIGN_CENTER | | 45 if (!(flags & (ChromeCanvas::TEXT_ALIGN_CENTER | |
| 41 ChromeCanvas::TEXT_ALIGN_RIGHT | | 46 ChromeCanvas::TEXT_ALIGN_RIGHT | |
| 42 ChromeCanvas::TEXT_ALIGN_LEFT))) { | 47 ChromeCanvas::TEXT_ALIGN_LEFT))) { |
| 43 flags |= l10n_util::DefaultCanvasTextAlignment(); | 48 flags |= l10n_util::DefaultCanvasTextAlignment(); |
| 44 } | 49 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 75 // In order to make sure RTL/BiDi strings are rendered correctly, we must | 80 // In order to make sure RTL/BiDi strings are rendered correctly, we must |
| 76 // pass the flag DT_RTLREADING to DrawText (when the locale's language is | 81 // pass the flag DT_RTLREADING to DrawText (when the locale's language is |
| 77 // a right-to-left language) so that Windows does the right thing. | 82 // a right-to-left language) so that Windows does the right thing. |
| 78 // | 83 // |
| 79 // In addition to correctly displaying text containing both RTL and LTR | 84 // In addition to correctly displaying text containing both RTL and LTR |
| 80 // elements (for example, a string containing a telephone number within a | 85 // elements (for example, a string containing a telephone number within a |
| 81 // sentence in Hebrew, or a sentence in Hebrew that contains a word in | 86 // sentence in Hebrew, or a sentence in Hebrew that contains a word in |
| 82 // English) this flag also makes sure that if there is not enough space to | 87 // English) this flag also makes sure that if there is not enough space to |
| 83 // display the entire string, the ellipsis is displayed on the left hand side | 88 // display the entire string, the ellipsis is displayed on the left hand side |
| 84 // of the truncated string and not on the right hand side. | 89 // of the truncated string and not on the right hand side. |
| 85 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) | 90 // |
| 86 f |= DT_RTLREADING; | 91 // We make a distinction between Chrome UI strings and text coming from a web |
| 87 | 92 // page. |
| 93 // |
| 94 // For text coming from a web page we determine the alignment based on the |
| 95 // first character with strong directionality. If the directionality of the |
| 96 // first character with strong directionality in the text is LTR, the |
| 97 // alignment is set to DT_LEFT, and the directionality should not be set as |
| 98 // DT_RTLREADING. |
| 99 // |
| 100 // This heuristic doesn't work for Chrome UI strings since even in RTL |
| 101 // locales, some of those might start with English text but we know they're |
| 102 // localized so we always want them to be right aligned, and their |
| 103 // directionality should be set as DT_RTLREADING. |
| 104 // |
| 105 // Caveat: If the string is purely LTR, don't set DTL_RTLREADING since when |
| 106 // the flag is set, LRE-PDF don't have the desired effect of rendering |
| 107 // multiline English-only text as LTR. |
| 108 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT && |
| 109 (f & DT_RIGHT)) { |
| 110 if (l10n_util::StringContainsStrongRTLChars(text)) { |
| 111 f |= DT_RTLREADING; |
| 112 } |
| 113 } |
| 88 return f; | 114 return f; |
| 89 } | 115 } |
| 90 | 116 |
| 91 } // anonymous namespace | 117 } // anonymous namespace |
| 92 | 118 |
| 93 ChromeCanvas::ChromeCanvas(int width, int height, bool is_opaque) | 119 ChromeCanvas::ChromeCanvas(int width, int height, bool is_opaque) |
| 94 : skia::PlatformCanvasWin(width, height, is_opaque) { | 120 : skia::PlatformCanvasWin(width, height, is_opaque) { |
| 95 } | 121 } |
| 96 | 122 |
| 97 ChromeCanvas::ChromeCanvas() : skia::PlatformCanvasWin() { | 123 ChromeCanvas::ChromeCanvas() : skia::PlatformCanvasWin() { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 108 HFONT old_font = static_cast<HFONT>(SelectObject(dc, font.hfont())); | 134 HFONT old_font = static_cast<HFONT>(SelectObject(dc, font.hfont())); |
| 109 RECT b; | 135 RECT b; |
| 110 b.left = 0; | 136 b.left = 0; |
| 111 b.top = 0; | 137 b.top = 0; |
| 112 b.right = *width; | 138 b.right = *width; |
| 113 if (b.right == 0 && !text.empty()) { | 139 if (b.right == 0 && !text.empty()) { |
| 114 // Width needs to be at least 1 or else DoDrawText will not resize it. | 140 // Width needs to be at least 1 or else DoDrawText will not resize it. |
| 115 b.right = 1; | 141 b.right = 1; |
| 116 } | 142 } |
| 117 b.bottom = *height; | 143 b.bottom = *height; |
| 118 DoDrawText(dc, text, &b, ComputeFormatFlags(flags) | DT_CALCRECT); | 144 DoDrawText(dc, text, &b, ComputeFormatFlags(flags, text) | DT_CALCRECT); |
| 119 | 145 |
| 120 // Restore the old font. This way we don't have to worry if the caller | 146 // Restore the old font. This way we don't have to worry if the caller |
| 121 // deletes the font and the DC lives longer. | 147 // deletes the font and the DC lives longer. |
| 122 SelectObject(dc, old_font); | 148 SelectObject(dc, old_font); |
| 123 *width = b.right; | 149 *width = b.right; |
| 124 *height = b.bottom; | 150 *height = b.bottom; |
| 125 | 151 |
| 126 ReleaseDC(NULL, dc); | 152 ReleaseDC(NULL, dc); |
| 127 } | 153 } |
| 128 | 154 |
| 129 void ChromeCanvas::DrawStringInt(const std::wstring& text, HFONT font, | 155 void ChromeCanvas::DrawStringInt(const std::wstring& text, HFONT font, |
| 130 const SkColor& color, int x, int y, int w, | 156 const SkColor& color, int x, int y, int w, |
| 131 int h, int flags) { | 157 int h, int flags) { |
| 132 if (!IntersectsClipRectInt(x, y, w, h)) | 158 if (!IntersectsClipRectInt(x, y, w, h)) |
| 133 return; | 159 return; |
| 134 | 160 |
| 135 getTopPlatformDevice().prepareForGDI(x, y, w, h); | 161 getTopPlatformDevice().prepareForGDI(x, y, w, h); |
| 136 RECT text_bounds = { x, y, x + w, y + h }; | 162 RECT text_bounds = { x, y, x + w, y + h }; |
| 137 HDC dc = beginPlatformPaint(); | 163 HDC dc = beginPlatformPaint(); |
| 138 SetBkMode(dc, TRANSPARENT); | 164 SetBkMode(dc, TRANSPARENT); |
| 139 HFONT old_font = (HFONT)SelectObject(dc, font); | 165 HFONT old_font = (HFONT)SelectObject(dc, font); |
| 140 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color), | 166 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color), |
| 141 SkColorGetB(color)); | 167 SkColorGetB(color)); |
| 142 SetTextColor(dc, brush_color); | 168 SetTextColor(dc, brush_color); |
| 143 | 169 |
| 144 int f = ComputeFormatFlags(flags); | 170 int f = ComputeFormatFlags(flags, text); |
| 145 DoDrawText(dc, text, &text_bounds, f); | 171 DoDrawText(dc, text, &text_bounds, f); |
| 146 endPlatformPaint(); | 172 endPlatformPaint(); |
| 147 | 173 |
| 148 // Restore the old font. This way we don't have to worry if the caller | 174 // Restore the old font. This way we don't have to worry if the caller |
| 149 // deletes the font and the DC lives longer. | 175 // deletes the font and the DC lives longer. |
| 150 SelectObject(dc, old_font); | 176 SelectObject(dc, old_font); |
| 151 getTopPlatformDevice().postProcessGDI(x, y, w, h); | 177 getTopPlatformDevice().postProcessGDI(x, y, w, h); |
| 152 } | 178 } |
| 153 | 179 |
| 154 void ChromeCanvas::DrawStringInt(const std::wstring& text, | 180 void ChromeCanvas::DrawStringInt(const std::wstring& text, |
| 155 const ChromeFont& font, | 181 const ChromeFont& font, |
| 156 const SkColor& color, | 182 const SkColor& color, |
| 157 int x, int y, | 183 int x, int y, |
| 158 int w, int h) { | 184 int w, int h) { |
| 159 DrawStringInt(text, font, color, x, y, w, h, | 185 DrawStringInt(text, font, color, x, y, w, h, |
| 160 l10n_util::DefaultCanvasTextAlignment()); | 186 l10n_util::DefaultCanvasTextAlignment()); |
| 161 } | 187 } |
| 162 | 188 |
| 163 void ChromeCanvas::DrawStringInt(const std::wstring& text, | 189 void ChromeCanvas::DrawStringInt(const std::wstring& text, |
| 164 const ChromeFont& font, | 190 const ChromeFont& font, |
| 165 const SkColor& color, | 191 const SkColor& color, |
| 166 int x, int y, int w, int h, int flags) { | 192 int x, int y, int w, int h, int flags) { |
| 167 DrawStringInt(text, font.hfont(), color, x, y, w, h, flags); | 193 DrawStringInt(text, font.hfont(), color, x, y, w, h, flags); |
| 168 } | 194 } |
| OLD | NEW |