| Index: ui/gfx/render_text_linux.cc
|
| ===================================================================
|
| --- ui/gfx/render_text_linux.cc (revision 111848)
|
| +++ ui/gfx/render_text_linux.cc (working copy)
|
| @@ -5,7 +5,6 @@
|
| #include "ui/gfx/render_text_linux.h"
|
|
|
| #include <pango/pangocairo.h>
|
| -
|
| #include <algorithm>
|
|
|
| #include "base/i18n/break_iterator.h"
|
| @@ -65,37 +64,8 @@
|
| }
|
|
|
| void RenderTextLinux::Draw(Canvas* canvas) {
|
| - PangoLayout* layout = EnsureLayout();
|
| - Rect bounds(display_rect());
|
| -
|
| - // Clip the canvas to the text display area.
|
| - SkCanvas* canvas_skia = canvas->GetSkCanvas();
|
| -
|
| - skia::ScopedPlatformPaint scoped_platform_paint(canvas_skia);
|
| - cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
|
| - cairo_save(cr);
|
| - cairo_rectangle(cr, bounds.x(), bounds.y(), bounds.width(), bounds.height());
|
| - cairo_clip(cr);
|
| -
|
| - int text_width, text_height;
|
| - pango_layout_get_pixel_size(layout, &text_width, &text_height);
|
| - Point offset(ToViewPoint(Point()));
|
| - // Vertically centered.
|
| - int text_y = offset.y() + ((bounds.height() - text_height) / 2);
|
| - // TODO(xji): need to use SkCanvas->drawPosText() for gpu acceleration.
|
| - cairo_move_to(cr, offset.x(), text_y);
|
| - pango_cairo_show_layout(cr, layout);
|
| -
|
| - cairo_restore(cr);
|
| -
|
| - // Paint cursor.
|
| - bounds = GetUpdatedCursorBounds();
|
| - if (cursor_visible() && focused())
|
| - canvas->DrawRectInt(kCursorColor,
|
| - bounds.x(),
|
| - bounds.y(),
|
| - bounds.width(),
|
| - bounds.height());
|
| + EnsureLayout();
|
| + RenderText::Draw(canvas);
|
| }
|
|
|
| SelectionModel RenderTextLinux::FindCursorPosition(const Point& point) {
|
| @@ -220,6 +190,32 @@
|
| return SelectionModel(0, 0, SelectionModel::LEADING);
|
| }
|
|
|
| +void RenderTextLinux::SetSelectionModel(const SelectionModel& selection_model) {
|
| + if (GetSelectionStart() != selection_model.selection_start() ||
|
| + GetCursorPosition() != selection_model.selection_end())
|
| + selection_visual_bounds_.clear();
|
| +
|
| + RenderText::SetSelectionModel(selection_model);
|
| +}
|
| +
|
| +void RenderTextLinux::GetSubstringBounds(size_t from,
|
| + size_t to,
|
| + std::vector<Rect>* bounds) {
|
| + DCHECK(from <= text().length());
|
| + DCHECK(to <= text().length());
|
| +
|
| + bounds->clear();
|
| + if (from == to)
|
| + return;
|
| +
|
| + EnsureLayout();
|
| +
|
| + if (from == GetSelectionStart() && to == GetCursorPosition())
|
| + GetSelectionBounds(bounds);
|
| + else
|
| + CalculateSubstringBounds(from, to, bounds);
|
| +}
|
| +
|
| bool RenderTextLinux::IsCursorablePosition(size_t position) {
|
| if (position == 0 && text().empty())
|
| return true;
|
| @@ -233,6 +229,30 @@
|
| ResetLayout();
|
| }
|
|
|
| +void RenderTextLinux::DrawVisualText(Canvas* canvas) {
|
| + Rect bounds(display_rect());
|
| +
|
| + // Clip the canvas to the text display area.
|
| + SkCanvas* canvas_skia = canvas->GetSkCanvas();
|
| +
|
| + skia::ScopedPlatformPaint scoped_platform_paint(canvas_skia);
|
| + cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
|
| + cairo_save(cr);
|
| + cairo_rectangle(cr, bounds.x(), bounds.y(), bounds.width(), bounds.height());
|
| + cairo_clip(cr);
|
| +
|
| + int text_width, text_height;
|
| + pango_layout_get_pixel_size(layout_, &text_width, &text_height);
|
| + Point offset(ToViewPoint(Point()));
|
| + // Vertically centered.
|
| + int text_y = offset.y() + ((bounds.height() - text_height) / 2);
|
| + // TODO(xji): need to use SkCanvas->drawPosText() for gpu acceleration.
|
| + cairo_move_to(cr, offset.x(), text_y);
|
| + pango_cairo_show_layout(cr, layout_);
|
| +
|
| + cairo_restore(cr);
|
| +}
|
| +
|
| size_t RenderTextLinux::IndexOfAdjacentGrapheme(size_t index, bool next) {
|
| EnsureLayout();
|
| return Utf16IndexOfAdjacentGrapheme(Utf16IndexToUtf8Index(index), next);
|
| @@ -525,44 +545,25 @@
|
| log_attrs_ = NULL;
|
| num_log_attrs_ = 0;
|
| }
|
| + if (!selection_visual_bounds_.empty())
|
| + selection_visual_bounds_.clear();
|
| layout_text_ = NULL;
|
| layout_text_len_ = 0;
|
| }
|
|
|
| void RenderTextLinux::SetupPangoAttributes(PangoLayout* layout) {
|
| PangoAttrList* attrs = pango_attr_list_new();
|
| - // Set selection background color.
|
| - // TODO(xji): There's a bug in pango that it can't use two colors in one
|
| - // glyph. Please refer to https://bugzilla.gnome.org/show_bug.cgi?id=648157
|
| - // for detail. So for example, if a font has "ffi" ligature, but you select
|
| - // half of that glyph, you either get the entire "ffi" ligature
|
| - // selection-colored, or none of it.
|
| - // We could use clipping to render selection.
|
| - // Use pango_glyph_item_get_logical_widths to find the exact boundaries of
|
| - // selection, then cairo_clip that, paint background, set color to white and
|
| - // redraw the layout.
|
| - SkColor selection_color =
|
| - focused() ? kFocusedSelectionColor : kUnfocusedSelectionColor;
|
| - size_t start = std::min(MinOfSelection(), text().length());
|
| - size_t end = std::min(MaxOfSelection(), text().length());
|
| - PangoAttribute* pango_attr;
|
| - if (end > start) {
|
| - pango_attr = pango_attr_background_new(
|
| - ConvertColorFrom8BitTo16Bit(SkColorGetR(selection_color)),
|
| - ConvertColorFrom8BitTo16Bit(SkColorGetG(selection_color)),
|
| - ConvertColorFrom8BitTo16Bit(SkColorGetB(selection_color)));
|
| - AppendPangoAttribute(start, end, pango_attr, attrs);
|
| - }
|
|
|
| StyleRanges ranges_of_style(style_ranges());
|
| ApplyCompositionAndSelectionStyles(&ranges_of_style);
|
|
|
| PlatformFont* default_platform_font = default_style().font.platform_font();
|
|
|
| + PangoAttribute* pango_attr;
|
| for (StyleRanges::const_iterator i = ranges_of_style.begin();
|
| i < ranges_of_style.end(); ++i) {
|
| - start = std::min(i->range.start(), text().length());
|
| - end = std::min(i->range.end(), text().length());
|
| + size_t start = std::min(i->range.start(), text().length());
|
| + size_t end = std::min(i->range.end(), text().length());
|
| if (start >= end)
|
| continue;
|
|
|
| @@ -657,4 +658,40 @@
|
| return utf16_index;
|
| }
|
|
|
| +void RenderTextLinux::CalculateSubstringBounds(size_t from,
|
| + size_t to,
|
| + std::vector<Rect>* bounds) {
|
| + int* ranges;
|
| + int n_ranges;
|
| + size_t from_in_utf8 = Utf16IndexToUtf8Index(from);
|
| + size_t to_in_utf8 = Utf16IndexToUtf8Index(to);
|
| + pango_layout_line_get_x_ranges(
|
| + current_line_,
|
| + std::min(from_in_utf8, to_in_utf8),
|
| + std::max(from_in_utf8, to_in_utf8),
|
| + &ranges,
|
| + &n_ranges);
|
| +
|
| + int height;
|
| + pango_layout_get_pixel_size(layout_, NULL, &height);
|
| +
|
| + int y = (display_rect().height() - height) / 2;
|
| +
|
| + for (int i = 0; i < n_ranges; ++i) {
|
| + int x = PANGO_PIXELS(ranges[2 * i]);
|
| + int width = PANGO_PIXELS(ranges[2 * i + 1]) - x;
|
| + Rect rect(x, y, width, height);
|
| + rect.set_origin(ToViewPoint(rect.origin()));
|
| + bounds->push_back(rect);
|
| + }
|
| + g_free(ranges);
|
| +}
|
| +
|
| +void RenderTextLinux::GetSelectionBounds(std::vector<Rect>* bounds) {
|
| + if (selection_visual_bounds_.empty())
|
| + CalculateSubstringBounds(GetSelectionStart(), GetCursorPosition(),
|
| + &selection_visual_bounds_);
|
| + *bounds = selection_visual_bounds_;
|
| +}
|
| +
|
| } // namespace gfx
|
|
|