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

Unified Diff: ui/gfx/render_text_win.cc

Issue 8633019: Itemize and layout text lazily in RenderTextWin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/render_text_win.cc
===================================================================
--- ui/gfx/render_text_win.cc (revision 111778)
+++ ui/gfx/render_text_win.cc (working copy)
@@ -145,7 +145,8 @@
: RenderText(),
script_control_(),
script_state_(),
- string_width_(0) {
+ string_width_(0),
+ needs_layout_(false) {
// Omitting default constructors for script_* would leave POD uninitialized.
HRESULT hr = 0;
@@ -168,10 +169,12 @@
}
int RenderTextWin::GetStringWidth() {
+ EnsureLayout();
return string_width_;
}
void RenderTextWin::Draw(Canvas* canvas) {
+ EnsureLayout();
DrawSelection(canvas);
DrawVisualText(canvas);
DrawCursor(canvas);
@@ -181,6 +184,7 @@
if (text().empty())
return SelectionModel();
+ EnsureLayout();
// Find the run that contains the point and adjust the argument location.
Point p(ToTextPoint(point));
size_t run_index = GetRunContainingPoint(p);
@@ -210,6 +214,8 @@
Rect RenderTextWin::GetCursorBounds(const SelectionModel& selection,
bool insert_mode) {
+ EnsureLayout();
+
// Highlight the logical cursor (selection end) when not in insert mode.
size_t pos = insert_mode ? selection.caret_pos() : selection.selection_end();
size_t run_index = GetRunContainingPosition(pos);
@@ -262,6 +268,8 @@
SelectionModel RenderTextWin::GetLeftSelectionModel(
const SelectionModel& selection,
BreakType break_type) {
+ EnsureLayout();
+
if (break_type == LINE_BREAK || text().empty())
return LeftEndSelectionModel();
if (break_type == CHARACTER_BREAK)
@@ -273,6 +281,8 @@
SelectionModel RenderTextWin::GetRightSelectionModel(
const SelectionModel& selection,
BreakType break_type) {
+ EnsureLayout();
+
if (break_type == LINE_BREAK || text().empty())
return RightEndSelectionModel();
if (break_type == CHARACTER_BREAK)
@@ -284,6 +294,8 @@
SelectionModel RenderTextWin::LeftEndSelectionModel() {
if (text().empty())
return SelectionModel(0, 0, SelectionModel::LEADING);
+
+ EnsureLayout();
size_t cursor = base::i18n::IsRTL() ? text().length() : 0;
internal::TextRun* run = runs_[visual_to_logical_[0]];
bool rtl = run->script_analysis.fRTL;
@@ -296,6 +308,8 @@
SelectionModel RenderTextWin::RightEndSelectionModel() {
if (text().empty())
return SelectionModel(0, 0, SelectionModel::LEADING);
+
+ EnsureLayout();
size_t cursor = base::i18n::IsRTL() ? 0 : text().length();
internal::TextRun* run = runs_[visual_to_logical_[runs_.size() - 1]];
bool rtl = run->script_analysis.fRTL;
@@ -306,6 +320,7 @@
}
std::vector<Rect> RenderTextWin::GetSubstringBounds(size_t from, size_t to) {
+ DCHECK(!needs_layout_);
ui::Range range(from, to);
DCHECK(ui::Range(0, text().length()).Contains(range));
Point display_offset(GetUpdatedDisplayOffset());
@@ -363,6 +378,7 @@
if (position == 0 || position == text().length())
return true;
+ EnsureLayout();
size_t run_index = GetRunContainingPosition(position);
if (run_index >= runs_.size())
return false;
@@ -376,13 +392,12 @@
}
void RenderTextWin::UpdateLayout() {
- // TODO(msw): Skip complex processing if ScriptIsComplex returns false.
- ItemizeLogicalText();
- if (!runs_.empty())
- LayoutVisualText();
+ // Layout is performed lazily as needed for drawing/metrics.
+ needs_layout_ = true;
}
size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) {
+ EnsureLayout();
size_t run_index = GetRunContainingPosition(index);
internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL;
int start = run ? run->range.start() : 0;
@@ -401,9 +416,20 @@
return std::max(std::min(ch, length) + start, 0);
}
+void RenderTextWin::EnsureLayout() {
+ if (!needs_layout_)
+ return;
+ // TODO(msw): Skip complex processing if ScriptIsComplex returns false.
+ ItemizeLogicalText();
+ if (!runs_.empty())
+ LayoutVisualText();
+ needs_layout_ = false;
+}
+
void RenderTextWin::ItemizeLogicalText() {
STLDeleteContainerPointers(runs_.begin(), runs_.end());
runs_.clear();
+ string_width_ = 0;
if (text().empty())
return;
@@ -556,6 +582,7 @@
}
size_t RenderTextWin::GetRunContainingPosition(size_t position) const {
+ DCHECK(!needs_layout_);
// Find the text run containing the argument position.
size_t run = 0;
for (; run < runs_.size(); ++run)
@@ -566,6 +593,7 @@
}
size_t RenderTextWin::GetRunContainingPoint(const Point& point) const {
+ DCHECK(!needs_layout_);
// Find the text run containing the argument point (assumed already offset).
size_t run = 0;
for (; run < runs_.size(); ++run)
@@ -590,6 +618,7 @@
SelectionModel RenderTextWin::LeftSelectionModel(
const SelectionModel& selection) {
+ DCHECK(!needs_layout_);
size_t caret = selection.caret_pos();
SelectionModel::CaretPlacement caret_placement = selection.caret_placement();
size_t run_index = GetRunContainingPosition(caret);
@@ -626,6 +655,7 @@
SelectionModel RenderTextWin::RightSelectionModel(
const SelectionModel& selection) {
+ DCHECK(!needs_layout_);
size_t caret = selection.caret_pos();
SelectionModel::CaretPlacement caret_placement = selection.caret_placement();
size_t run_index = GetRunContainingPosition(caret);
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698