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

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

Issue 8392011: GTK: Step 1 of tab strip refresh. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Redo as functions. Created 9 years, 1 month 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
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 "ui/gfx/pango_util.h" 5 #include "ui/gfx/pango_util.h"
6 6
7 #include <cairo/cairo.h> 7 #include <cairo/cairo.h>
8 #include <pango/pango.h> 8 #include <pango/pango.h>
9 #include <pango/pangocairo.h> 9 #include <pango/pangocairo.h>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "ui/gfx/canvas.h" 13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/font.h" 14 #include "ui/gfx/font.h"
15 #include "ui/gfx/platform_font_pango.h"
16 #include "ui/gfx/rect.h"
15 17
16 #if !defined(USE_WAYLAND) && defined(TOOLKIT_USES_GTK) 18 #if !defined(USE_WAYLAND) && defined(TOOLKIT_USES_GTK)
17 #include <gtk/gtk.h> 19 #include <gtk/gtk.h>
18 #include "ui/gfx/gtk_util.h" 20 #include "ui/gfx/gtk_util.h"
19 #else 21 #else
20 #include "ui/gfx/linux_util.h" 22 #include "ui/gfx/linux_util.h"
21 #endif 23 #endif
22 24
23 #include "ui/gfx/skia_util.h" 25 #include "ui/gfx/skia_util.h"
24 26
25 namespace { 27 namespace {
26 28
27 // Marker for accelerators in the text. 29 // Marker for accelerators in the text.
28 const gunichar kAcceleratorChar = '&'; 30 const gunichar kAcceleratorChar = '&';
29 31
32 // Multiply by the text height to determine how much text should be faded
33 // when elliding.
34 const double kFadeWidthFactor = 1.5;
35
36 // End state of the elliding fade.
37 const double kFadeFinalAlpha = 0.15;
38
30 // Return |cairo_font_options|. If needed, allocate and update it based on 39 // Return |cairo_font_options|. If needed, allocate and update it based on
31 // GtkSettings. 40 // GtkSettings.
32 cairo_font_options_t* GetCairoFontOptions() { 41 cairo_font_options_t* GetCairoFontOptions() {
33 // Font settings that we initialize once and then use when drawing text. 42 // Font settings that we initialize once and then use when drawing text.
34 static cairo_font_options_t* cairo_font_options = NULL; 43 static cairo_font_options_t* cairo_font_options = NULL;
35 44
36 if (cairo_font_options) 45 if (cairo_font_options)
37 return cairo_font_options; 46 return cairo_font_options;
38 47
39 cairo_font_options = cairo_font_options_create(); 48 cairo_font_options = cairo_font_options_create();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 if (rgba_style) 109 if (rgba_style)
101 g_free(rgba_style); 110 g_free(rgba_style);
102 111
103 return cairo_font_options; 112 return cairo_font_options;
104 } 113 }
105 114
106 } // namespace 115 } // namespace
107 116
108 namespace gfx { 117 namespace gfx {
109 118
119 void DrawTextOntoCairoSurface(cairo_t* cr,
120 const string16& text,
121 const gfx::Font& font,
122 const gfx::Rect& bounds,
123 const gfx::Rect& clip,
124 const SkColor& text_color,
125 int flags) {
126 PangoLayout* layout = pango_cairo_create_layout(cr);
127 base::i18n::TextDirection text_direction =
128 base::i18n::GetFirstStrongCharacterDirection(text);
129 Rect text_rect(bounds.x(), bounds.y(), 0, 0);
130 DCHECK(!bounds.IsEmpty());
131
132 gfx::SetupPangoLayout(
133 layout, text, font, bounds.width(), text_direction, flags);
134
135 pango_layout_set_height(layout, bounds.height() * PANGO_SCALE);
136
137 cairo_save(cr);
138 cairo_rectangle(cr, clip.x(), clip.y(), clip.width(), clip.height());
139 cairo_clip(cr);
140
141 AdjustTextRectBasedOnLayout(layout, bounds, flags, &text_rect);
142
143 DrawPangoLayout(cr, layout, font, bounds, text_rect,
144 text_color, text_direction, flags);
145
146 cairo_restore(cr);
147 g_object_unref(layout);
148 }
149
Evan Stade 2011/10/26 21:46:05 ^H
150
110 // Pass a width greater than 0 to force wrapping and eliding. 151 // Pass a width greater than 0 to force wrapping and eliding.
111 void SetupPangoLayout(PangoLayout* layout, 152 void SetupPangoLayout(PangoLayout* layout,
112 const string16& text, 153 const string16& text,
113 const Font& font, 154 const Font& font,
114 int width, 155 int width,
115 base::i18n::TextDirection text_direction, 156 base::i18n::TextDirection text_direction,
116 int flags) { 157 int flags) {
117 cairo_font_options_t* cairo_font_options = GetCairoFontOptions(); 158 cairo_font_options_t* cairo_font_options = GetCairoFontOptions();
118 // This needs to be done early on; it has no effect when called just before 159 // This needs to be done early on; it has no effect when called just before
119 // pango_cairo_show_layout(). 160 // pango_cairo_show_layout().
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 NULL, NULL); 227 NULL, NULL);
187 utf8 = UTF16ToUTF8(accelerator_removed); 228 utf8 = UTF16ToUTF8(accelerator_removed);
188 } else { 229 } else {
189 utf8 = UTF16ToUTF8(text); 230 utf8 = UTF16ToUTF8(text);
190 } 231 }
191 232
192 pango_layout_set_text(layout, utf8.data(), utf8.size()); 233 pango_layout_set_text(layout, utf8.data(), utf8.size());
193 } 234 }
194 } 235 }
195 236
237 void AdjustTextRectBasedOnLayout(PangoLayout* layout,
238 const gfx::Rect& bounds,
239 int flags,
240 gfx::Rect* text_rect) {
241 int text_width, text_height;
242 pango_layout_get_pixel_size(layout, &text_width, &text_height);
243 text_rect->set_width(text_width);
244 text_rect->set_height(text_height);
245
246 if (flags & gfx::Canvas::TEXT_VALIGN_TOP) {
247 // Cairo should draw from the top left corner already.
248 } else if (flags & gfx::Canvas::TEXT_VALIGN_BOTTOM) {
249 text_rect->set_y(text_rect->y() + bounds.height() - text_rect->height());
250 } else {
251 // Vertically centered.
252 text_rect->set_y(text_rect->y() +
253 ((bounds.height() - text_rect->height()) / 2));
254 }
255 }
256
257 void DrawPangoLayout(cairo_t* cr,
258 PangoLayout* layout,
259 const Font& font,
260 const gfx::Rect& bounds,
261 const gfx::Rect& text_rect,
262 const SkColor& text_color,
263 base::i18n::TextDirection text_direction,
264 int flags) {
265 double r = SkColorGetR(text_color) / 255.0,
266 g = SkColorGetG(text_color) / 255.0,
267 b = SkColorGetB(text_color) / 255.0,
268 a = SkColorGetA(text_color) / 255.0;
269
270 cairo_pattern_t* pattern = NULL;
271
272 cairo_save(cr);
273
274 // If we're not eliding, use a fixed color.
275 // Otherwise, create a gradient pattern to use as the source.
276 if (text_direction == base::i18n::RIGHT_TO_LEFT ||
277 (flags & gfx::Canvas::NO_ELLIPSIS) ||
278 text_rect.width() <= bounds.width()) {
279 cairo_set_source_rgba(cr, r, g, b, a);
280 } else {
281 // Fade to semi-transparent to elide.
282 int fade_width = static_cast<double>(text_rect.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 pattern = cairo_pattern_create_linear(
290 fade_x, bounds.y(), bounds.x() + bounds.width(), bounds.y());
291 cairo_pattern_add_color_stop_rgba(pattern, 0, r, g, b, a);
292 cairo_pattern_add_color_stop_rgba(pattern, 1, r, g, b, kFadeFinalAlpha);
293 cairo_set_source(cr, pattern);
294 }
295
296 cairo_move_to(cr, text_rect.x(), text_rect.y());
297 pango_cairo_show_layout(cr, layout);
298
299 if (font.GetStyle() & gfx::Font::UNDERLINED) {
300 gfx::PlatformFontPango* platform_font =
301 static_cast<gfx::PlatformFontPango*>(font.platform_font());
302 DrawPangoTextUnderline(cr, platform_font, 0.0, text_rect);
303 }
304
305 if (pattern)
306 cairo_pattern_destroy(pattern);
307
308 cairo_restore(cr);
309 }
310
311 void DrawPangoTextUnderline(cairo_t* cr,
312 gfx::PlatformFontPango* platform_font,
313 double extra_edge_width,
314 const Rect& text_rect) {
315 const double underline_y =
316 static_cast<double>(text_rect.y()) + text_rect.height() +
317 platform_font->underline_position();
318 cairo_set_line_width(
319 cr, platform_font->underline_thickness() + 2 * extra_edge_width);
320 cairo_move_to(cr,
321 text_rect.x() - extra_edge_width,
322 underline_y);
323 cairo_line_to(cr,
324 text_rect.x() + text_rect.width() + extra_edge_width,
325 underline_y);
326 cairo_stroke(cr);
327 }
328
196 } // namespace gfx 329 } // namespace gfx
OLDNEW
« chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h ('K') | « ui/gfx/pango_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698