summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-24 17:45:59 +0000
committerasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-24 17:45:59 +0000
commitf0ed8a2f0e95ab61f755f3f4c10b0cdd6007fe26 (patch)
tree2ef39f64782098f912dcb6221943aa1f9ec52d9a /ui
parentb39c9b201b7a950c647cd9d79494b74692dfeb56 (diff)
downloadchromium_src-f0ed8a2f0e95ab61f755f3f4c10b0cdd6007fe26.zip
chromium_src-f0ed8a2f0e95ab61f755f3f4c10b0cdd6007fe26.tar.gz
chromium_src-f0ed8a2f0e95ab61f755f3f4c10b0cdd6007fe26.tar.bz2
Add support for horizontal text alignment to RenderText.
Also adds a |cursor_enabled| setting to RenderText to control whether the cursor bounds should be added to the string width for the purposes of layout and gating the |display_offset_| behavior. BUG=110595 TEST=Moving cursor outside of omnibox bounds under Aura in both LTR and RTL mode - view should pan and follow the cursor. Resizing the window when there is a pan offset, which should consume any new empty space. Also programmatically setting the new alignment modes via some unreleased code and inspecting the results. Review URL: http://codereview.chromium.org/9252021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/render_text.cc98
-rw-r--r--ui/gfx/render_text.h41
-rw-r--r--ui/gfx/render_text_linux.cc3
-rw-r--r--ui/gfx/render_text_win.cc3
4 files changed, 98 insertions, 47 deletions
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index bb35294..f61ddc9 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -319,6 +319,14 @@ void RenderText::SetText(const string16& text) {
UpdateLayout();
}
+void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) {
+ if (horizontal_alignment_ != alignment) {
+ horizontal_alignment_ = alignment;
+ display_offset_ = Point();
+ cached_bounds_and_offset_valid_ = false;
+ }
+}
+
void RenderText::SetFontList(const FontList& font_list) {
font_list_ = font_list;
cached_bounds_and_offset_valid_ = false;
@@ -331,6 +339,11 @@ void RenderText::SetFontSize(int size) {
UpdateLayout();
}
+void RenderText::SetCursorEnabled(bool cursor_enabled) {
+ cursor_enabled_ = cursor_enabled;
+ cached_bounds_and_offset_valid_ = false;
+}
+
const Font& RenderText::GetFont() const {
return font_list_.GetFonts()[0];
}
@@ -575,7 +588,9 @@ SelectionModel RenderText::GetSelectionModelForSelectionStart() {
}
RenderText::RenderText()
- : cursor_visible_(false),
+ : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT),
+ cursor_enabled_(true),
+ cursor_visible_(false),
insert_mode_(true),
focused_(false),
composition_range_(ui::Range::InvalidRange()),
@@ -656,24 +671,37 @@ void RenderText::ApplyCompositionAndSelectionStyles(
}
}
+Point RenderText::GetTextOrigin() {
+ Point origin = display_rect().origin();
+ origin = origin.Add(GetUpdatedDisplayOffset());
+ origin = origin.Add(GetAlignmentOffset());
+ return origin;
+}
+
Point RenderText::ToTextPoint(const Point& point) {
- Point p(point.Subtract(display_rect().origin()));
- p = p.Subtract(GetUpdatedDisplayOffset());
- if (base::i18n::IsRTL())
- p.Offset(GetStringWidth() - display_rect().width() + 1, 0);
- return p;
+ return point.Subtract(GetTextOrigin());
}
Point RenderText::ToViewPoint(const Point& point) {
- Point p(point.Add(display_rect().origin()));
- p = p.Add(GetUpdatedDisplayOffset());
- if (base::i18n::IsRTL())
- p.Offset(display_rect().width() - GetStringWidth() - 1, 0);
- return p;
+ return point.Add(GetTextOrigin());
+}
+
+int RenderText::GetContentWidth() {
+ return GetStringWidth() + (cursor_enabled_ ? 1 : 0);
+}
+
+Point RenderText::GetAlignmentOffset() {
+ if (horizontal_alignment() != ALIGN_LEFT) {
+ int x_offset = display_rect().width() - GetContentWidth();
+ if (horizontal_alignment() == ALIGN_CENTER)
+ x_offset /= 2;
+ return Point(x_offset, 0);
+ }
+ return Point();
}
Point RenderText::GetOriginForSkiaDrawing() {
- Point origin(ToViewPoint(Point()));
+ Point origin(GetTextOrigin());
// TODO(msw): Establish a vertical baseline for strings of mixed font heights.
const Font& font = GetFont();
int height = font.GetHeight();
@@ -685,20 +713,20 @@ Point RenderText::GetOriginForSkiaDrawing() {
return origin;
}
-int RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) {
+void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) {
if (!fade_head() && !fade_tail())
- return 0;
+ return;
const int text_width = GetStringWidth();
const int display_width = display_rect().width();
// If the text fits as-is, no need to fade.
if (text_width <= display_width)
- return 0;
+ return;
int gradient_width = CalculateFadeGradientWidth(GetFont(), display_width);
if (gradient_width == 0)
- return 0;
+ return;
bool fade_left = fade_head();
bool fade_right = fade_tail();
@@ -720,14 +748,8 @@ int RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) {
solid_part.Inset(0, 0, gradient_width, 0);
}
- // Right-align the text when fading left.
- int x_offset = 0;
gfx::Rect text_rect = display_rect();
- if (fade_left && !fade_right) {
- x_offset = display_width - text_width;
- text_rect.Offset(x_offset, 0);
- text_rect.set_width(text_width);
- }
+ text_rect.Inset(GetAlignmentOffset().x(), 0, 0, 0);
const SkColor color = default_style().foreground;
SkAutoTUnref<SkShader> shader(
@@ -736,8 +758,6 @@ int RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) {
// |renderer| adds its own ref. So don't |release()| it from the ref ptr.
renderer->SetShader(shader.get());
}
-
- return x_offset;
}
void RenderText::MoveCursorTo(size_t position, bool select) {
@@ -755,17 +775,21 @@ void RenderText::MoveCursorTo(size_t position, bool select) {
void RenderText::UpdateCachedBoundsAndOffset() {
if (cached_bounds_and_offset_valid_)
return;
+
// First, set the valid flag true to calculate the current cursor bounds using
// the stale |display_offset_|. Applying |delta_offset| at the end of this
// function will set |cursor_bounds_| and |display_offset_| to correct values.
cached_bounds_and_offset_valid_ = true;
cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_);
+
// Update |display_offset_| to ensure the current cursor is visible.
- int display_width = display_rect_.width();
- int string_width = GetStringWidth();
+ const int display_width = display_rect_.width();
+ const int content_width = GetContentWidth();
+
int delta_offset = 0;
- if (string_width < display_width) {
- // Show all text whenever it fits in the display width.
+ if (content_width <= display_width || !cursor_enabled()) {
+ // Don't pan if the text fits in the display width or when the cursor is
+ // disabled.
delta_offset = -display_offset_.x();
} else if (cursor_bounds_.right() >= display_rect_.right()) {
// TODO(xji): when the character overflow is a RTL character, currently, if
@@ -780,13 +804,15 @@ void RenderText::UpdateCachedBoundsAndOffset() {
//
// Pan to show the cursor when it overflows to the left.
delta_offset = display_rect_.x() - cursor_bounds_.x();
- } else {
- // Pan to show additional overflow text when the display width increases.
- int negate_rtl = base::i18n::IsRTL() ? -1 : 1;
- int offset = negate_rtl * display_offset_.x();
- if (display_width > (string_width + offset))
- delta_offset = negate_rtl * (display_width - (string_width + offset) - 1);
+ } else if (display_offset_.x() != 0) {
+ // Reduce the pan offset to show additional overflow text when the display
+ // width increases.
+ const int negate_rtl = horizontal_alignment_ == ALIGN_RIGHT ? -1 : 1;
+ const int offset = negate_rtl * display_offset_.x();
+ if (display_width > (content_width + offset))
+ delta_offset = negate_rtl * (display_width - (content_width + offset));
}
+
display_offset_.Offset(delta_offset, 0);
cursor_bounds_.Offset(delta_offset, 0);
}
@@ -805,7 +831,7 @@ void RenderText::DrawSelection(Canvas* canvas) {
void RenderText::DrawCursor(Canvas* canvas) {
// Paint cursor. Replace cursor is drawn as rectangle for now.
// TODO(msw): Draw a better cursor with a better indication of association.
- if (cursor_visible() && focused()) {
+ if (cursor_enabled() && cursor_visible() && focused()) {
const Rect& bounds = GetUpdatedCursorBounds();
if (bounds.width() != 0)
canvas->FillRect(kCursorColor, bounds);
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h
index 47471d3..21fe484 100644
--- a/ui/gfx/render_text.h
+++ b/ui/gfx/render_text.h
@@ -81,6 +81,13 @@ enum BreakType {
LINE_BREAK,
};
+// Horizontal text alignment styles.
+enum HorizontalAlignment {
+ ALIGN_LEFT,
+ ALIGN_CENTER,
+ ALIGN_RIGHT,
+};
+
// VisualCursorDirection and LogicalCursorDirection represent directions of
// motion of the cursor in BiDi text. The combinations that make sense are:
//
@@ -112,6 +119,11 @@ class UI_EXPORT RenderText {
const string16& text() const { return text_; }
void SetText(const string16& text);
+ HorizontalAlignment horizontal_alignment() const {
+ return horizontal_alignment_;
+ }
+ void SetHorizontalAlignment(HorizontalAlignment alignment);
+
const FontList& font_list() const { return font_list_; }
void SetFontList(const FontList& font_list);
@@ -123,6 +135,9 @@ class UI_EXPORT RenderText {
const SelectionModel& selection_model() const { return selection_model_; }
+ bool cursor_enabled() const { return cursor_enabled_; }
+ void SetCursorEnabled(bool cursor_enabled);
+
bool cursor_visible() const { return cursor_visible_; }
void set_cursor_visible(bool visible) { cursor_visible_ = visible; }
@@ -312,21 +327,26 @@ class UI_EXPORT RenderText {
// style (foreground) to selection range.
void ApplyCompositionAndSelectionStyles(StyleRanges* style_ranges);
+ // Returns the text origin after applying text alignment and display offset.
+ Point GetTextOrigin();
+
// Convert points from the text space to the view space and back.
// Handles the display area, display offset, and the application LTR/RTL mode.
Point ToTextPoint(const Point& point);
Point ToViewPoint(const Point& point);
+ // Returns the width of content, which reserves room for the cursor if
+ // |cursor_enabled_| is true.
+ int GetContentWidth();
+
+ // Returns display offset based on current text alignment.
+ Point GetAlignmentOffset();
+
// Returns the origin point for drawing text via Skia.
Point GetOriginForSkiaDrawing();
- // Applies fade effects to |renderer| and returns a text drawing offset when
- // fading the head would cause the text to change alignment.
- // TODO(asvitkine): Applying right-alignment in this way doesn't work well
- // with drawing the text selection and cursor. Instead, we
- // should make RenderText support horizontal alignment
- // explicitly.
- int ApplyFadeEffects(internal::SkiaTextRenderer* renderer);
+ // Applies fade effects to |renderer|.
+ void ApplyFadeEffects(internal::SkiaTextRenderer* renderer);
private:
friend class RenderTextTest;
@@ -357,6 +377,9 @@ class UI_EXPORT RenderText {
// Logical UTF-16 string data to be drawn.
string16 text_;
+ // Horizontal alignment of the text with respect to |display_rect_|.
+ HorizontalAlignment horizontal_alignment_;
+
// A list of fonts used to render |text_|.
FontList font_list_;
@@ -366,6 +389,10 @@ class UI_EXPORT RenderText {
// The cached cursor bounds; get these bounds with GetUpdatedCursorBounds.
Rect cursor_bounds_;
+ // Specifies whether the cursor is enabled. If disabled, no space is reserved
+ // for the cursor when positioning text.
+ bool cursor_enabled_;
+
// The cursor visibility and insert mode.
bool cursor_visible_;
bool insert_mode_;
diff --git a/ui/gfx/render_text_linux.cc b/ui/gfx/render_text_linux.cc
index 1043d88..14bf1f6 100644
--- a/ui/gfx/render_text_linux.cc
+++ b/ui/gfx/render_text_linux.cc
@@ -381,8 +381,7 @@ void RenderTextLinux::DrawVisualText(Canvas* canvas) {
}
internal::SkiaTextRenderer renderer(canvas);
- // Fade effects may force right alignment, requiring an offset to |x|.
- x += ApplyFadeEffects(&renderer);
+ ApplyFadeEffects(&renderer);
for (GSList* it = current_line_->runs; it; it = it->next) {
PangoLayoutRun* run = reinterpret_cast<PangoLayoutRun*>(it->data);
diff --git a/ui/gfx/render_text_win.cc b/ui/gfx/render_text_win.cc
index 9896fb2..692d8e3 100644
--- a/ui/gfx/render_text_win.cc
+++ b/ui/gfx/render_text_win.cc
@@ -452,8 +452,7 @@ void RenderTextWin::DrawVisualText(Canvas* canvas) {
std::vector<SkPoint> pos;
internal::SkiaTextRenderer renderer(canvas);
- // Fade effects may force right alignment, requiring an offset to |x|.
- x += ApplyFadeEffects(&renderer);
+ ApplyFadeEffects(&renderer);
for (size_t i = 0; i < runs_.size(); ++i) {
// Get the run specified by the visual-to-logical map.