OLD | NEW |
---|---|
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 "ui/gfx/canvas_skia.h" | 5 #include "ui/gfx/canvas_skia.h" |
6 | 6 |
7 #include <cairo/cairo.h> | 7 #include <cairo/cairo.h> |
8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
9 #include <pango/pango.h> | 9 #include <pango/pango.h> |
10 #include <pango/pangocairo.h> | 10 #include <pango/pangocairo.h> |
11 | 11 |
12 #include "base/i18n/rtl.h" | |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/stringprintf.h" | |
oshima
2011/05/31 23:56:10
you dont need this anymore? (guessing you added fo
| |
13 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
14 #include "ui/gfx/font.h" | 16 #include "ui/gfx/font.h" |
15 #include "ui/gfx/gtk_util.h" | 17 #include "ui/gfx/gtk_util.h" |
16 #include "ui/gfx/platform_font_gtk.h" | 18 #include "ui/gfx/platform_font_gtk.h" |
17 #include "ui/gfx/rect.h" | 19 #include "ui/gfx/rect.h" |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 const gunichar kAcceleratorChar = '&'; | 23 const gunichar kAcceleratorChar = '&'; |
22 | 24 |
25 // Multiply by the text height to determine how much text should be faded | |
26 // when elliding. | |
27 const double kFadeWidthFactor = 1.5; | |
28 | |
29 // End state of the elliding fade. | |
30 const double kKFadeFinalAlpha = 0.15; | |
31 | |
23 // Font settings that we initialize once and then use when drawing text in | 32 // Font settings that we initialize once and then use when drawing text in |
24 // DrawStringInt(). | 33 // DrawStringInt(). |
25 static cairo_font_options_t* cairo_font_options = NULL; | 34 static cairo_font_options_t* cairo_font_options = NULL; |
26 | 35 |
27 // Update |cairo_font_options| based on GtkSettings, allocating it if needed. | 36 // Update |cairo_font_options| based on GtkSettings, allocating it if needed. |
28 static void UpdateCairoFontOptions() { | 37 static void UpdateCairoFontOptions() { |
29 if (!cairo_font_options) | 38 if (!cairo_font_options) |
30 cairo_font_options = cairo_font_options_create(); | 39 cairo_font_options = cairo_font_options_create(); |
31 | 40 |
32 GtkSettings* gtk_settings = gtk_settings_get_default(); | 41 GtkSettings* gtk_settings = gtk_settings_get_default(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 pango_cairo_context_set_font_options( | 110 pango_cairo_context_set_font_options( |
102 pango_layout_get_context(layout), cairo_font_options); | 111 pango_layout_get_context(layout), cairo_font_options); |
103 | 112 |
104 // Callers of DrawStringInt handle RTL layout themselves, so tell pango to not | 113 // Callers of DrawStringInt handle RTL layout themselves, so tell pango to not |
105 // scope out RTL characters. | 114 // scope out RTL characters. |
106 pango_layout_set_auto_dir(layout, FALSE); | 115 pango_layout_set_auto_dir(layout, FALSE); |
107 | 116 |
108 if (width > 0) | 117 if (width > 0) |
109 pango_layout_set_width(layout, width * PANGO_SCALE); | 118 pango_layout_set_width(layout, width * PANGO_SCALE); |
110 | 119 |
111 if (flags & gfx::Canvas::NO_ELLIPSIS) { | |
112 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); | |
113 } else { | |
114 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); | |
115 } | |
116 | |
117 if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) { | 120 if (flags & gfx::Canvas::TEXT_ALIGN_CENTER) { |
118 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); | 121 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); |
119 } else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) { | 122 } else if (flags & gfx::Canvas::TEXT_ALIGN_RIGHT) { |
120 pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); | 123 pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); |
121 } | 124 } |
122 | 125 |
123 if (flags & gfx::Canvas::MULTI_LINE) { | 126 if (flags & gfx::Canvas::NO_ELLIPSIS) { |
124 pango_layout_set_wrap(layout, | 127 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); |
125 (flags & gfx::Canvas::CHARACTER_BREAK) ? | 128 if (flags & gfx::Canvas::MULTI_LINE) { |
126 PANGO_WRAP_WORD_CHAR : PANGO_WRAP_WORD); | 129 pango_layout_set_wrap(layout, |
130 (flags & gfx::Canvas::CHARACTER_BREAK) ? | |
131 PANGO_WRAP_WORD_CHAR : PANGO_WRAP_WORD); | |
132 } | |
133 } else if (base::i18n::IsRTL()){ | |
134 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); | |
135 } else { | |
136 // Fading the text will be handled in the draw operation. | |
137 // that the text is only on one line. | |
138 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); | |
139 pango_layout_set_width(layout, -1); | |
Dmitry Polukhin
2011/06/08 12:50:35
Setting width to -1 breaks TEXT_ALIGN_CENTER. See
Dmitry Polukhin
2011/06/08 13:09:48
It looks like we can't disable wrap without settin
| |
127 } | 140 } |
128 | 141 |
129 // Set the resolution to match that used by Gtk. If we don't set the | 142 // Set the resolution to match that used by Gtk. If we don't set the |
130 // resolution and the resolution differs from the default, Gtk and Chrome end | 143 // resolution and the resolution differs from the default, Gtk and Chrome end |
131 // up drawing at different sizes. | 144 // up drawing at different sizes. |
132 double resolution = gfx::GetPangoResolution(); | 145 double resolution = gfx::GetPangoResolution(); |
133 if (resolution > 0) { | 146 if (resolution > 0) { |
134 pango_cairo_context_set_resolution(pango_layout_get_context(layout), | 147 pango_cairo_context_set_resolution(pango_layout_get_context(layout), |
135 resolution); | 148 resolution); |
136 } | 149 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 } | 259 } |
247 cairo_restore(cr_); | 260 cairo_restore(cr_); |
248 | 261 |
249 skia::EndPlatformPaint(canvas_); | 262 skia::EndPlatformPaint(canvas_); |
250 | 263 |
251 g_object_unref(layout_); | 264 g_object_unref(layout_); |
252 // NOTE: BeginPlatformPaint returned its surface, we shouldn't destroy it. | 265 // NOTE: BeginPlatformPaint returned its surface, we shouldn't destroy it. |
253 } | 266 } |
254 | 267 |
255 void DrawStringContext::Draw(const SkColor& text_color) { | 268 void DrawStringContext::Draw(const SkColor& text_color) { |
256 cairo_set_source_rgba(cr_, | 269 double r = SkColorGetR(text_color) / 255.0, |
257 SkColorGetR(text_color) / 255.0, | 270 g = SkColorGetG(text_color) / 255.0, |
258 SkColorGetG(text_color) / 255.0, | 271 b = SkColorGetB(text_color) / 255.0, |
259 SkColorGetB(text_color) / 255.0, | 272 a = SkColorGetA(text_color) / 255.0; |
260 SkColorGetA(text_color) / 255.0); | 273 |
261 cairo_move_to(cr_, text_x_, text_y_); | 274 if (base::i18n::IsRTL() || |
262 pango_cairo_show_layout(cr_, layout_); | 275 (flags_ & gfx::Canvas::NO_ELLIPSIS) || |
276 text_width_ <= bounds_.width()) { | |
277 cairo_set_source_rgba(cr_, r, g, b, a); | |
278 cairo_move_to(cr_, text_x_, text_y_); | |
279 pango_cairo_show_layout(cr_, layout_); | |
280 } else { | |
281 // Fade to gray to ellide. | |
282 int fade_width = static_cast<double>(text_height_) * kFadeWidthFactor; | |
283 if (fade_width > (bounds_.width() / 2)) { | |
284 // Don't fade more than half the text. | |
285 fade_width = bounds_.width() / 2; | |
286 } | |
287 int fade_x = bounds_.x() + bounds_.width() - fade_width; | |
288 | |
289 // Draw left part of text, clipped at fade_width. | |
290 cairo_save(cr_); | |
291 cairo_rectangle( | |
oshima
2011/05/31 23:56:10
indent at "(" ?
| |
292 cr_, | |
293 bounds_.x(), | |
294 bounds_.y(), | |
295 bounds_.width() - fade_width, | |
296 bounds_.height()); | |
297 cairo_clip(cr_); | |
298 cairo_set_source_rgba(cr_, r, g, b, a); | |
299 cairo_move_to(cr_, text_x_, text_y_); | |
300 pango_cairo_show_layout(cr_, layout_); | |
301 cairo_restore(cr_); | |
302 | |
303 // Clip to the left of fade_width. | |
304 cairo_save(cr_); | |
305 cairo_rectangle(cr_, fade_x, bounds_.y(), fade_width, bounds_.height()); | |
306 cairo_clip(cr_); | |
307 | |
308 // Create clip for text. | |
309 cairo_move_to(cr_, text_x_, text_y_); | |
310 pango_cairo_layout_path(cr_, layout_); | |
311 cairo_clip(cr_); | |
312 | |
313 // Create alpha fade pattern. | |
314 cairo_pattern_t* pattern = cairo_pattern_create_linear( | |
315 fade_x, bounds_.y(), bounds_.x() + bounds_.width(), bounds_.y()); | |
316 cairo_pattern_add_color_stop_rgba(pattern, 0, r, g, b, a); | |
317 cairo_pattern_add_color_stop_rgba(pattern, 1, r, g, b, kKFadeFinalAlpha); | |
318 | |
319 // Draw pattern, clipped by text. | |
320 cairo_set_source(cr_, pattern); | |
321 cairo_fill(cr_); | |
322 cairo_paint(cr_); | |
323 cairo_pattern_destroy(pattern); | |
324 | |
325 cairo_restore(cr_); | |
326 } | |
263 } | 327 } |
264 | 328 |
265 void DrawStringContext::DrawWithHalo(const SkColor& text_color, | 329 void DrawStringContext::DrawWithHalo(const SkColor& text_color, |
266 const SkColor& halo_color) { | 330 const SkColor& halo_color) { |
267 gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false); | 331 gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false); |
268 text_canvas.FillRectInt(static_cast<SkColor>(0), | 332 text_canvas.FillRectInt(static_cast<SkColor>(0), |
269 0, 0, bounds_.width() + 2, bounds_.height() + 2); | 333 0, 0, bounds_.width() + 2, bounds_.height() + 2); |
270 | 334 |
271 { | 335 { |
272 skia::ScopedPlatformPaint scoped_platform_paint(&text_canvas); | 336 skia::ScopedPlatformPaint scoped_platform_paint(&text_canvas); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); | 451 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); |
388 cairo_paint(cr); | 452 cairo_paint(cr); |
389 } | 453 } |
390 | 454 |
391 ui::TextureID CanvasSkia::GetTextureID() { | 455 ui::TextureID CanvasSkia::GetTextureID() { |
392 // TODO(wjmaclean) | 456 // TODO(wjmaclean) |
393 return 0; | 457 return 0; |
394 } | 458 } |
395 | 459 |
396 } // namespace gfx | 460 } // namespace gfx |
OLD | NEW |