summaryrefslogtreecommitdiffstats
path: root/ui/gfx
diff options
context:
space:
mode:
authorasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-29 18:55:29 +0000
committerasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-29 18:55:29 +0000
commit56f06d5a7dbedf70b573c2efc18b18ab4d368720 (patch)
tree3aa2607bf32ccb3c72d2528d4c2d72326d375ed1 /ui/gfx
parent91ef14ef3bb920bb18ecf5ce5b73c2f4340efd3c (diff)
downloadchromium_src-56f06d5a7dbedf70b573c2efc18b18ab4d368720.zip
chromium_src-56f06d5a7dbedf70b573c2efc18b18ab4d368720.tar.gz
chromium_src-56f06d5a7dbedf70b573c2efc18b18ab4d368720.tar.bz2
Itemize and layout text lazily in RenderTextWin.
This matches what is done in render_text_linux.cc and avoids doing unnecessary work unless needed. BUG=none TEST=Run chrome.exe with command-line --use-pure-views. Edit text in the omnibox. It should work as before. Review URL: http://codereview.chromium.org/8633019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111983 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r--ui/gfx/render_text_win.cc40
-rw-r--r--ui/gfx/render_text_win.h3
2 files changed, 38 insertions, 5 deletions
diff --git a/ui/gfx/render_text_win.cc b/ui/gfx/render_text_win.cc
index b2b1b16..e5c64d0 100644
--- a/ui/gfx/render_text_win.cc
+++ b/ui/gfx/render_text_win.cc
@@ -145,7 +145,8 @@ RenderTextWin::RenderTextWin()
: 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 @@ RenderTextWin::~RenderTextWin() {
}
int RenderTextWin::GetStringWidth() {
+ EnsureLayout();
return string_width_;
}
void RenderTextWin::Draw(Canvas* canvas) {
+ EnsureLayout();
DrawSelection(canvas);
DrawVisualText(canvas);
DrawCursor(canvas);
@@ -181,6 +184,7 @@ SelectionModel RenderTextWin::FindCursorPosition(const Point& point) {
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 @@ SelectionModel RenderTextWin::FindCursorPosition(const Point& point) {
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 @@ Rect RenderTextWin::GetCursorBounds(const SelectionModel& selection,
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::GetLeftSelectionModel(
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::GetRightSelectionModel(
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::LeftEndSelectionModel() {
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 @@ SelectionModel RenderTextWin::RightEndSelectionModel() {
}
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 @@ bool RenderTextWin::IsCursorablePosition(size_t position) {
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 @@ bool RenderTextWin::IsCursorablePosition(size_t position) {
}
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 @@ size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) {
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 @@ void RenderTextWin::LayoutVisualText() {
}
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::GetRunContainingPosition(size_t position) const {
}
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::LastSelectionModelInsideRun(
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::LeftSelectionModel(
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);
diff --git a/ui/gfx/render_text_win.h b/ui/gfx/render_text_win.h
index 8fd1bf8..1711d7b 100644
--- a/ui/gfx/render_text_win.h
+++ b/ui/gfx/render_text_win.h
@@ -80,6 +80,7 @@ class RenderTextWin : public RenderText {
private:
virtual size_t IndexOfAdjacentGrapheme(size_t index, bool next) OVERRIDE;
+ void EnsureLayout();
void ItemizeLogicalText();
void LayoutVisualText();
@@ -116,6 +117,8 @@ class RenderTextWin : public RenderText {
scoped_array<int> visual_to_logical_;
scoped_array<int> logical_to_visual_;
+ bool needs_layout_;
+
DISALLOW_COPY_AND_ASSIGN(RenderTextWin);
};