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

Unified 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: Rebase to ToT again. Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
« chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc ('K') | « ui/gfx/pango_util.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/pango_util.cc
diff --git a/ui/gfx/pango_util.cc b/ui/gfx/pango_util.cc
index 75043f4a23aadcb5b09c55602624fe9d7224d1f7..8a05469f3209c376da9e8037593a877a1b90710d 100644
--- a/ui/gfx/pango_util.cc
+++ b/ui/gfx/pango_util.cc
@@ -12,6 +12,8 @@
#include "base/utf_string_conversions.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
+#include "ui/gfx/platform_font_pango.h"
+#include "ui/gfx/rect.h"
#if !defined(USE_WAYLAND) && defined(TOOLKIT_USES_GTK)
#include <gtk/gtk.h>
@@ -27,6 +29,13 @@ namespace {
// Marker for accelerators in the text.
const gunichar kAcceleratorChar = '&';
+// Multiply by the text height to determine how much text should be faded
+// when elliding.
+const double kFadeWidthFactor = 1.5;
+
+// End state of the elliding fade.
+const double kFadeFinalAlpha = 0.15;
+
// Return |cairo_font_options|. If needed, allocate and update it based on
// GtkSettings.
cairo_font_options_t* GetCairoFontOptions() {
@@ -107,6 +116,37 @@ cairo_font_options_t* GetCairoFontOptions() {
namespace gfx {
+void DrawTextOntoCairoSurface(cairo_t* cr,
+ const string16& text,
+ const gfx::Font& font,
+ const gfx::Rect& bounds,
+ const gfx::Rect& clip,
+ const SkColor& text_color,
+ int flags) {
+ PangoLayout* layout = pango_cairo_create_layout(cr);
+ base::i18n::TextDirection text_direction =
+ base::i18n::GetFirstStrongCharacterDirection(text);
+ Rect text_rect(bounds.x(), bounds.y(), 0, 0);
+ DCHECK(!bounds.IsEmpty());
+
+ gfx::SetupPangoLayout(
+ layout, text, font, bounds.width(), text_direction, flags);
+
+ pango_layout_set_height(layout, bounds.height() * PANGO_SCALE);
+
+ cairo_save(cr);
+ cairo_rectangle(cr, clip.x(), clip.y(), clip.width(), clip.height());
+ cairo_clip(cr);
+
+ AdjustTextRectBasedOnLayout(layout, bounds, flags, &text_rect);
+
+ DrawPangoLayout(cr, layout, font, bounds, text_rect,
+ text_color, text_direction, flags);
+
+ cairo_restore(cr);
+ g_object_unref(layout);
+}
+
// Pass a width greater than 0 to force wrapping and eliding.
void SetupPangoLayout(PangoLayout* layout,
const string16& text,
@@ -193,4 +233,96 @@ void SetupPangoLayout(PangoLayout* layout,
}
}
+void AdjustTextRectBasedOnLayout(PangoLayout* layout,
+ const gfx::Rect& bounds,
+ int flags,
+ gfx::Rect* text_rect) {
+ int text_width, text_height;
+ pango_layout_get_pixel_size(layout, &text_width, &text_height);
+ text_rect->set_width(text_width);
+ text_rect->set_height(text_height);
+
+ if (flags & gfx::Canvas::TEXT_VALIGN_TOP) {
+ // Cairo should draw from the top left corner already.
+ } else if (flags & gfx::Canvas::TEXT_VALIGN_BOTTOM) {
+ text_rect->set_y(text_rect->y() + bounds.height() - text_rect->height());
+ } else {
+ // Vertically centered.
+ text_rect->set_y(text_rect->y() +
+ ((bounds.height() - text_rect->height()) / 2));
+ }
+}
+
+void DrawPangoLayout(cairo_t* cr,
+ PangoLayout* layout,
+ const Font& font,
+ const gfx::Rect& bounds,
+ const gfx::Rect& text_rect,
+ const SkColor& text_color,
+ base::i18n::TextDirection text_direction,
+ int flags) {
+ double r = SkColorGetR(text_color) / 255.0,
+ g = SkColorGetG(text_color) / 255.0,
+ b = SkColorGetB(text_color) / 255.0,
+ a = SkColorGetA(text_color) / 255.0;
+
+ cairo_pattern_t* pattern = NULL;
+
+ cairo_save(cr);
+
+ // If we're not eliding, use a fixed color.
+ // Otherwise, create a gradient pattern to use as the source.
+ if (text_direction == base::i18n::RIGHT_TO_LEFT ||
+ (flags & gfx::Canvas::NO_ELLIPSIS) ||
+ text_rect.width() <= bounds.width()) {
+ cairo_set_source_rgba(cr, r, g, b, a);
+ } else {
+ // Fade to semi-transparent to elide.
+ int fade_width = static_cast<double>(text_rect.height()) * kFadeWidthFactor;
+ if (fade_width > bounds.width() / 2) {
+ // Don't fade more than half the text.
+ fade_width = bounds.width() / 2;
+ }
+ int fade_x = bounds.x() + bounds.width() - fade_width;
+
+ pattern = cairo_pattern_create_linear(
+ fade_x, bounds.y(), bounds.x() + bounds.width(), bounds.y());
+ cairo_pattern_add_color_stop_rgba(pattern, 0, r, g, b, a);
+ cairo_pattern_add_color_stop_rgba(pattern, 1, r, g, b, kFadeFinalAlpha);
+ cairo_set_source(cr, pattern);
+ }
+
+ cairo_move_to(cr, text_rect.x(), text_rect.y());
+ pango_cairo_show_layout(cr, layout);
+
+ if (font.GetStyle() & gfx::Font::UNDERLINED) {
+ gfx::PlatformFontPango* platform_font =
+ static_cast<gfx::PlatformFontPango*>(font.platform_font());
+ DrawPangoTextUnderline(cr, platform_font, 0.0, text_rect);
+ }
+
+ if (pattern)
+ cairo_pattern_destroy(pattern);
+
+ cairo_restore(cr);
+}
+
+void DrawPangoTextUnderline(cairo_t* cr,
+ gfx::PlatformFontPango* platform_font,
+ double extra_edge_width,
+ const Rect& text_rect) {
+ const double underline_y =
+ static_cast<double>(text_rect.y()) + text_rect.height() +
+ platform_font->underline_position();
+ cairo_set_line_width(
+ cr, platform_font->underline_thickness() + 2 * extra_edge_width);
+ cairo_move_to(cr,
+ text_rect.x() - extra_edge_width,
+ underline_y);
+ cairo_line_to(cr,
+ text_rect.x() + text_rect.width() + extra_edge_width,
+ underline_y);
+ cairo_stroke(cr);
+}
+
} // namespace gfx
« chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc ('K') | « ui/gfx/pango_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698