Chromium Code Reviews| Index: ui/gfx/pango_util.cc |
| diff --git a/ui/gfx/pango_util.cc b/ui/gfx/pango_util.cc |
| index 75043f4a23aadcb5b09c55602624fe9d7224d1f7..bd2a17696c2a8d2013bada50c596fb3b552f5ac2 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() { |
| @@ -193,4 +202,107 @@ void SetupPangoLayout(PangoLayout* layout, |
| } |
| } |
| + |
| +PangoDrawString::PangoDrawString(cairo_t* cr, |
| + const string16& text, |
| + const gfx::Font& font, |
| + const gfx::Rect& bounds, |
| + const gfx::Rect& clip, |
| + int flags) |
| + : bounds_(bounds), |
| + flags_(flags), |
| + font_(font), |
| + cr_(cr), |
| + layout_(pango_cairo_create_layout(cr_)), |
| + text_x_(bounds.x()), |
| + text_y_(bounds.y()), |
| + text_width_(0), |
| + text_height_(0), |
| + text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) { |
| + 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_); |
| + |
| + pango_layout_get_pixel_size(layout_, &text_width_, &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_y_ += (bounds.height() - text_height_); |
| + } else { |
| + // Vertically centered. |
| + text_y_ += ((bounds.height() - text_height_) / 2); |
| + } |
| +} |
| + |
| +PangoDrawString::~PangoDrawString() { |
| + cairo_restore(cr_); |
| + g_object_unref(layout_); |
| +} |
| + |
| +void PangoDrawString::Draw(const SkColor& text_color) { |
| + 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_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_height_) * kFadeWidthFactor; |
| + if (fade_width > (bounds_.width() / 2)) { |
|
Evan Stade
2011/10/25 23:33:30
remove excess parens
Elliot Glaysher
2011/10/26 21:06:57
I believe we should make order of operations expli
Evan Stade
2011/10/26 21:46:05
the C++ style guide doesn't touch on this, but the
|
| + // 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_x_, text_y_); |
| + pango_cairo_show_layout(cr_, layout_); |
| + |
| + if (font_.GetStyle() & gfx::Font::UNDERLINED) |
| + DrawUnderline(cr_, 0.0); |
| + |
| + if (pattern) |
| + cairo_pattern_destroy(pattern); |
| + |
| + cairo_restore(cr_); |
| +} |
| + |
| +void PangoDrawString::DrawUnderline(cairo_t* cr, double extra_edge_width) { |
| + gfx::PlatformFontPango* platform_font = |
| + static_cast<gfx::PlatformFontPango*>(font_.platform_font()); |
| + const double underline_y = |
| + static_cast<double>(text_y_) + text_height_ + |
| + platform_font->underline_position(); |
| + cairo_set_line_width( |
| + cr, platform_font->underline_thickness() + 2 * extra_edge_width); |
| + cairo_move_to(cr, text_x_ - extra_edge_width, underline_y); |
| + cairo_line_to(cr, text_x_ + text_width_ + extra_edge_width, underline_y); |
| + cairo_stroke(cr); |
| +} |
| + |
| } // namespace gfx |