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

Unified Diff: ui/gfx/render_text.cc

Issue 16867016: Windows implementation of multiline RenderText (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fix ComputeLines and rects Created 7 years, 5 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
Index: ui/gfx/render_text.cc
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index cdc706ed28193eee11213fa5154fbc1e4447a265..1c8ca71b55ed84245fe1b3262c09302a11e46f85 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -306,8 +306,19 @@ RenderText::~RenderText() {
void RenderText::SetText(const base::string16& text) {
DCHECK(!composition_range_.IsValid());
+ if (text_ == text)
+ return;
text_ = text;
+ // TODO: we might be displaying obscured_text... also move somewhere better.
Alexei Svitkine (slow) 2013/07/09 15:35:13 I think this should be done at the end of UpdateLa
ckocagil 2013/07/13 16:05:10 Done.
+ line_breaks_.clear();
+ base::i18n::BreakIterator iter(text_, base::i18n::BreakIterator::BREAK_LINE);
+ bool success = iter.Init();
+ CHECK(success);
+ do {
+ line_breaks_.push_back(iter.pos());
+ } while (iter.Advance());
+
// Adjust ranged styles and colors to accommodate a new text length.
const size_t text_length = text_.length();
colors_.SetMax(text_length);
@@ -397,6 +408,7 @@ void RenderText::SetObscuredRevealIndex(int index) {
void RenderText::SetDisplayRect(const Rect& r) {
display_rect_ = r;
cached_bounds_and_offset_valid_ = false;
+ lines_valid_ = false;
}
void RenderText::SetCursorPosition(size_t position) {
@@ -689,18 +701,50 @@ Rect RenderText::GetCursorBounds(const SelectionModel& caret,
// since there is nothing to overtype.
if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0))
x = size.width();
- } else {
- size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ?
- caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD);
- ui::Range xspan(GetGlyphBounds(grapheme_start));
- if (insert_mode) {
- x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start();
- } else { // overtype mode
- x = xspan.GetMin();
- width = xspan.length();
+ } else {
+ size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ?
+ caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD);
+ ui::Range xspan(GetGlyphBounds(grapheme_start));
+ if (insert_mode) {
+ x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start();
+ } else { // overtype mode
+ x = xspan.GetMin();
+ width = xspan.length();
+ }
+ }
+ return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height()));
+}
+
+std::vector<Rect> RenderText::RangeToViewRects(const ui::Range& x, int y) {
+ std::vector<Rect> rects;
+
+ int height = GetStringSize().height();
msw 2013/07/10 04:01:56 This is fine for the single line case, but each li
ckocagil 2013/07/13 16:05:10 Done.
+
+ if (!multiline()) {
+ Point start(x.GetMin(), y);
+ rects.push_back(Rect(ToViewPoint(start), Size(x.length(), height)));
+ return rects;
+ }
+
+ EnsureLayout();
+ ComputeLines();
msw 2013/07/10 04:01:56 EnsureLayout should ComputeLines as needed, don't
ckocagil 2013/07/13 16:05:10 Done.
+
+ for (size_t line = 0; line < lines().size(); ++line) {
msw 2013/07/10 04:01:56 Add a comment to explain what's happening here, it
ckocagil 2013/07/13 16:05:10 Done.
+ int line_x = 0;
+ for (size_t i = 0; i < lines()[line].size(); ++i) {
+ const internal::LineSegment* segment = lines()[line][i];
+ ui::Range intersection = segment->x_pos.Intersect(x);
+ if (!intersection.is_empty()) {
+ Rect rect(line_x + intersection.start() - segment->x_pos.start(),
+ y + line * height, intersection.length(), height);
msw 2013/07/10 04:01:56 You need to use the proper per-line heights; at le
ckocagil 2013/07/13 16:05:10 Done, it uses per-line heights now.
+ rect += GetTextOffset(LineWidth(line));
msw 2013/07/10 04:01:56 Cache the line's offset in the outer loop.
ckocagil 2013/07/13 16:05:10 Done.
+ rects.push_back(rect);
+ }
+ line_x += segment->x_pos.length();
}
}
- return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height()));
+
+ return rects;
}
const Rect& RenderText::GetUpdatedCursorBounds() {
@@ -763,11 +807,13 @@ RenderText::RenderText()
composition_and_selection_styles_applied_(false),
obscured_(false),
obscured_reveal_index_(-1),
+ multiline_(false),
fade_head_(false),
fade_tail_(false),
background_is_transparent_(false),
clip_to_display_rect_(true),
- cached_bounds_and_offset_valid_(false) {
+ cached_bounds_and_offset_valid_(false),
+ lines_valid_(false) {
}
const Vector2d& RenderText::GetUpdatedDisplayOffset() {
@@ -832,30 +878,45 @@ void RenderText::UndoCompositionAndSelectionStyles() {
composition_and_selection_styles_applied_ = false;
}
-Vector2d RenderText::GetTextOffset() {
+Vector2d RenderText::GetTextOffset(int line_width) {
Vector2d offset = display_rect().OffsetFromOrigin();
- offset.Add(GetUpdatedDisplayOffset());
- offset.Add(GetAlignmentOffset());
+ if (!multiline())
msw 2013/07/10 04:01:56 Why ignore the display offset for multi-line? Even
ckocagil 2013/07/13 16:05:10 I ignored it for now because multi-line vertical s
+ offset.Add(GetUpdatedDisplayOffset());
+ offset.Add(GetAlignmentOffset(line_width));
return offset;
}
Point RenderText::ToTextPoint(const Point& point) {
- return point - GetTextOffset();
+ return point - GetTextOffset(GetContentWidth());
+ // TODO: implement multiline
Alexei Svitkine (slow) 2013/07/09 15:35:13 TODO(ckocagil)
ckocagil 2013/07/13 16:05:10 Done.
}
Point RenderText::ToViewPoint(const Point& point) {
- return point + GetTextOffset();
+ if (!multiline())
+ return point + GetTextOffset(GetContentWidth());
+
+ ComputeLines();
msw 2013/07/10 04:01:56 Don't explicitly call this here, EnsureLayout or [
ckocagil 2013/07/13 16:05:10 Done.
+ int x = point.x();
+ unsigned int line = 0;
+ while (line < lines_.size() && x > LineWidth(line)) {
+ x -= LineWidth(line);
Alexei Svitkine (slow) 2013/07/09 15:35:13 Can you refactor this code to not call LineWidth()
ckocagil 2013/07/13 16:05:10 I will rewrite this method to support RTL soon (be
+ ++line;
+ }
+ return Point(x, point.y() + line * GetStringSize().height()) +
msw 2013/07/10 04:01:56 Again, this needs per-line heights.
ckocagil 2013/07/13 16:05:10 Done.
+ GetTextOffset(LineWidth(line));
}
-Vector2d RenderText::GetAlignmentOffset() {
+Vector2d RenderText::GetAlignmentOffset(int line_width) {
+
msw 2013/07/10 04:01:56 nit: remove blank line.
ckocagil 2013/07/13 16:05:10 Done.
Vector2d offset;
if (horizontal_alignment_ != ALIGN_LEFT) {
- offset.set_x(display_rect().width() - GetContentWidth());
+ offset.set_x(display_rect().width() - (multiline() ? line_width
msw 2013/07/10 04:01:56 Always use |line_width|, you pass in GetContentWid
ckocagil 2013/07/13 16:05:10 I now pass 0 for single-line mode. Single-line mod
+ : GetContentWidth()));
if (horizontal_alignment_ == ALIGN_CENTER)
offset.set_x(offset.x() / 2);
}
if (vertical_alignment_ != ALIGN_TOP) {
- offset.set_y(display_rect().height() - GetStringSize().height());
+ offset.set_y(display_rect().height() - GetMultilineTextSize().height());
if (vertical_alignment_ == ALIGN_VCENTER)
offset.set_y(offset.y() / 2);
}
@@ -901,7 +962,7 @@ void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) {
}
Rect text_rect = display_rect();
- text_rect.Inset(GetAlignmentOffset().x(), 0, 0, 0);
+ text_rect.Inset(GetAlignmentOffset(GetContentWidth()).x(), 0, 0, 0);
// TODO(msw): Use the actual text colors corresponding to each faded part.
skia::RefPtr<SkShader> shader = CreateFadeShader(

Powered by Google App Engine
This is Rietveld 408576698