OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 } | 157 } |
158 } | 158 } |
159 style_ranges_.back().range.set_end(text_.length()); | 159 style_ranges_.back().range.set_end(text_.length()); |
160 } | 160 } |
161 #ifndef NDEBUG | 161 #ifndef NDEBUG |
162 CheckStyleRanges(style_ranges_, text_.length()); | 162 CheckStyleRanges(style_ranges_, text_.length()); |
163 #endif | 163 #endif |
164 cached_bounds_and_offset_valid_ = false; | 164 cached_bounds_and_offset_valid_ = false; |
165 } | 165 } |
166 | 166 |
167 void RenderText::SetSelectionModel(const SelectionModel& sel) { | 167 void RenderText::ToggleInsertMode() { |
168 size_t start = sel.selection_start(); | 168 insert_mode_ = !insert_mode_; |
169 size_t end = sel.selection_end(); | |
170 selection_model_.set_selection_start(std::min(start, text().length())); | |
171 selection_model_.set_selection_end(std::min(end, text().length())); | |
172 selection_model_.set_caret_pos(std::min(sel.caret_pos(), text().length())); | |
173 selection_model_.set_caret_placement(sel.caret_placement()); | |
174 | |
175 cached_bounds_and_offset_valid_ = false; | 169 cached_bounds_and_offset_valid_ = false; |
176 } | 170 } |
177 | 171 |
178 void RenderText::SetDisplayRect(const Rect& r) { | 172 void RenderText::SetDisplayRect(const Rect& r) { |
179 display_rect_ = r; | 173 display_rect_ = r; |
180 cached_bounds_and_offset_valid_ = false; | 174 cached_bounds_and_offset_valid_ = false; |
181 } | 175 } |
182 | 176 |
183 size_t RenderText::GetCursorPosition() const { | 177 size_t RenderText::GetCursorPosition() const { |
184 return selection_model_.selection_end(); | 178 return selection_model_.selection_end(); |
185 } | 179 } |
186 | 180 |
187 void RenderText::SetCursorPosition(const size_t position) { | 181 void RenderText::SetCursorPosition(size_t position) { |
188 SelectionModel sel(selection_model()); | 182 MoveCursorTo(position, false); |
189 sel.set_selection_start(position); | |
190 sel.set_selection_end(position); | |
191 sel.set_caret_pos(GetIndexOfPreviousGrapheme(position)); | |
192 sel.set_caret_placement(SelectionModel::TRAILING); | |
193 SetSelectionModel(sel); | |
194 } | 183 } |
195 | 184 |
196 void RenderText::MoveCursorLeft(BreakType break_type, bool select) { | 185 void RenderText::MoveCursorLeft(BreakType break_type, bool select) { |
197 SelectionModel position(selection_model()); | 186 SelectionModel position(selection_model()); |
198 position.set_selection_start(GetCursorPosition()); | 187 position.set_selection_start(GetCursorPosition()); |
199 // Cancelling a selection moves to the edge of the selection. | 188 // Cancelling a selection moves to the edge of the selection. |
200 if (break_type != LINE_BREAK && !EmptySelection() && !select) { | 189 if (break_type != LINE_BREAK && !EmptySelection() && !select) { |
201 // Use the selection start if it is left of the selection end. | 190 // Use the selection start if it is left of the selection end. |
202 SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), | 191 SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), |
203 SelectionModel::LEADING); | 192 SelectionModel::LEADING); |
(...skipping 26 matching lines...) Expand all Loading... | |
230 if (break_type == WORD_BREAK) | 219 if (break_type == WORD_BREAK) |
231 position = GetRightSelectionModel(position, break_type); | 220 position = GetRightSelectionModel(position, break_type); |
232 } else { | 221 } else { |
233 position = GetRightSelectionModel(position, break_type); | 222 position = GetRightSelectionModel(position, break_type); |
234 } | 223 } |
235 if (select) | 224 if (select) |
236 position.set_selection_start(GetSelectionStart()); | 225 position.set_selection_start(GetSelectionStart()); |
237 MoveCursorTo(position); | 226 MoveCursorTo(position); |
238 } | 227 } |
239 | 228 |
240 bool RenderText::MoveCursorTo(const SelectionModel& selection) { | 229 bool RenderText::MoveCursorTo(const SelectionModel& selection_model) { |
241 bool changed = !selection.Equals(selection_model_); | 230 SelectionModel sel(selection_model); |
242 SetSelectionModel(selection); | 231 size_t text_length = text().length(); |
232 // Enforce valid selection model components. | |
233 if (sel.selection_start() > text_length) | |
234 sel.set_selection_start(text_length); | |
235 if (sel.selection_end() > text_length) | |
236 sel.set_selection_end(text_length); | |
237 // The current model only supports caret positions at valid character indices. | |
238 if (text_length == 0) { | |
239 sel.set_caret_pos(0); | |
240 sel.set_caret_placement(SelectionModel::LEADING); | |
241 } else if (sel.caret_pos() >= text_length) { | |
242 SelectionModel end = base::i18n::IsRTL() ? LeftEndSelectionModel() : | |
xji
2011/08/25 05:58:38
change
base::i18n::IsRTL()
to
GetTextDirection(
msw
2011/08/26 16:26:25
Done.
| |
243 RightEndSelectionModel(); | |
244 sel.set_caret_pos(end.caret_pos()); | |
245 sel.set_caret_placement(end.caret_placement()); | |
246 } | |
247 bool changed = !sel.Equals(selection_model_); | |
248 SetSelectionModel(sel); | |
243 return changed; | 249 return changed; |
244 } | 250 } |
245 | 251 |
246 bool RenderText::MoveCursorTo(const Point& point, bool select) { | 252 bool RenderText::MoveCursorTo(const Point& point, bool select) { |
247 SelectionModel selection = FindCursorPosition(point); | 253 SelectionModel selection = FindCursorPosition(point); |
248 if (select) | 254 if (select) |
249 selection.set_selection_start(GetSelectionStart()); | 255 selection.set_selection_start(GetSelectionStart()); |
250 return MoveCursorTo(selection); | 256 return MoveCursorTo(selection); |
251 } | 257 } |
252 | 258 |
253 bool RenderText::IsPointInSelection(const Point& point) { | 259 bool RenderText::IsPointInSelection(const Point& point) { |
260 if (EmptySelection()) | |
261 return false; | |
254 // TODO(xji): should this check whether the point is inside the visual | 262 // TODO(xji): should this check whether the point is inside the visual |
255 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points | 263 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points |
256 // to the right half of 'c', is the point in selection? | 264 // to the right half of 'c', is the point in selection? |
257 size_t pos = FindCursorPosition(point).selection_end(); | 265 size_t pos = FindCursorPosition(point).selection_end(); |
258 return (pos >= MinOfSelection() && pos < MaxOfSelection()); | 266 return (pos >= MinOfSelection() && pos < MaxOfSelection()); |
259 } | 267 } |
260 | 268 |
261 void RenderText::ClearSelection() { | 269 void RenderText::ClearSelection() { |
262 SelectionModel sel(selection_model()); | 270 SelectionModel sel(selection_model()); |
263 sel.set_selection_start(GetCursorPosition()); | 271 sel.set_selection_start(GetCursorPosition()); |
264 SetSelectionModel(sel); | 272 SetSelectionModel(sel); |
265 } | 273 } |
266 | 274 |
267 void RenderText::SelectAll() { | 275 void RenderText::SelectAll() { |
268 SelectionModel sel(0, text().length(), | 276 SelectionModel sel(RightEndSelectionModel()); |
269 text().length(), SelectionModel::LEADING); | 277 sel.set_selection_start(LeftEndSelectionModel().selection_start()); |
270 SetSelectionModel(sel); | 278 SetSelectionModel(sel); |
271 } | 279 } |
272 | 280 |
273 // TODO(xji): it does not work for languages do not use space as word breaker, | 281 // TODO(xji): it does not work for languages do not use space as word breaker, |
274 // such as Chinese. Should use BreakIterator. | 282 // such as Chinese. Should use BreakIterator. |
275 void RenderText::SelectWord() { | 283 void RenderText::SelectWord() { |
276 size_t selection_start = GetSelectionStart(); | 284 size_t selection_start = GetSelectionStart(); |
277 size_t cursor_position = GetCursorPosition(); | 285 size_t cursor_position = GetCursorPosition(); |
278 // First we setup selection_start_ and selection_end_. There are so many cases | 286 // First we setup selection_start_ and selection_end_. There are so many cases |
279 // because we try to emulate what select-word looks like in a gtk textfield. | 287 // because we try to emulate what select-word looks like in a gtk textfield. |
(...skipping 21 matching lines...) Expand all Loading... | |
301 } | 309 } |
302 | 310 |
303 // Now we move selection_end_ to end of selection. Selection boundary | 311 // Now we move selection_end_ to end of selection. Selection boundary |
304 // is defined as the position where we have alpha-num character on one side | 312 // is defined as the position where we have alpha-num character on one side |
305 // and non-alpha-num char on the other side. | 313 // and non-alpha-num char on the other side. |
306 for (; cursor_position < text().length(); cursor_position++) { | 314 for (; cursor_position < text().length(); cursor_position++) { |
307 if (IsPositionAtWordSelectionBoundary(cursor_position)) | 315 if (IsPositionAtWordSelectionBoundary(cursor_position)) |
308 break; | 316 break; |
309 } | 317 } |
310 | 318 |
311 SelectionModel sel(selection_model()); | 319 MoveCursorTo(selection_start, false); |
312 sel.set_selection_start(selection_start); | 320 MoveCursorTo(cursor_position, true); |
313 sel.set_selection_end(cursor_position); | |
314 sel.set_caret_pos(GetIndexOfPreviousGrapheme(cursor_position)); | |
315 sel.set_caret_placement(SelectionModel::TRAILING); | |
316 SetSelectionModel(sel); | |
317 } | 321 } |
318 | 322 |
319 const ui::Range& RenderText::GetCompositionRange() const { | 323 const ui::Range& RenderText::GetCompositionRange() const { |
320 return composition_range_; | 324 return composition_range_; |
321 } | 325 } |
322 | 326 |
323 void RenderText::SetCompositionRange(const ui::Range& composition_range) { | 327 void RenderText::SetCompositionRange(const ui::Range& composition_range) { |
324 CHECK(!composition_range.IsValid() || | 328 CHECK(!composition_range.IsValid() || |
325 ui::Range(0, text_.length()).Contains(composition_range)); | 329 ui::Range(0, text_.length()).Contains(composition_range)); |
326 composition_range_.set_end(composition_range.end()); | 330 composition_range_.set_end(composition_range.end()); |
(...skipping 16 matching lines...) Expand all Loading... | |
343 | 347 |
344 void RenderText::ApplyDefaultStyle() { | 348 void RenderText::ApplyDefaultStyle() { |
345 style_ranges_.clear(); | 349 style_ranges_.clear(); |
346 StyleRange style = StyleRange(default_style_); | 350 StyleRange style = StyleRange(default_style_); |
347 style.range.set_end(text_.length()); | 351 style.range.set_end(text_.length()); |
348 style_ranges_.push_back(style); | 352 style_ranges_.push_back(style); |
349 cached_bounds_and_offset_valid_ = false; | 353 cached_bounds_and_offset_valid_ = false; |
350 } | 354 } |
351 | 355 |
352 base::i18n::TextDirection RenderText::GetTextDirection() const { | 356 base::i18n::TextDirection RenderText::GetTextDirection() const { |
353 // TODO(msw): Bidi implementation, intended to replace the functionality added | 357 if (base::i18n::IsRTL()) |
354 // in crrev.com/91881 (discussed in codereview.chromium.org/7324011). | 358 return base::i18n::RIGHT_TO_LEFT; |
355 return base::i18n::LEFT_TO_RIGHT; | 359 return base::i18n::LEFT_TO_RIGHT; |
356 } | 360 } |
357 | 361 |
358 int RenderText::GetStringWidth() { | 362 int RenderText::GetStringWidth() { |
359 return default_style_.font.GetStringWidth(text()); | 363 return default_style_.font.GetStringWidth(text()); |
360 } | 364 } |
361 | 365 |
362 void RenderText::Draw(Canvas* canvas) { | 366 void RenderText::Draw(Canvas* canvas) { |
363 // Clip the canvas to the text display area. | 367 // Clip the canvas to the text display area. |
364 canvas->ClipRectInt(display_rect_.x(), display_rect_.y(), | 368 canvas->ClipRectInt(display_rect_.x(), display_rect_.y(), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
436 } else if (pivot == x) { | 440 } else if (pivot == x) { |
437 return SelectionModel(pivot_pos); | 441 return SelectionModel(pivot_pos); |
438 } else { | 442 } else { |
439 right = pivot; | 443 right = pivot; |
440 right_pos = pivot_pos; | 444 right_pos = pivot_pos; |
441 } | 445 } |
442 } | 446 } |
443 return SelectionModel(left_pos); | 447 return SelectionModel(left_pos); |
444 } | 448 } |
445 | 449 |
446 std::vector<Rect> RenderText::GetSubstringBounds(size_t from, size_t to) { | |
447 size_t start = std::min(from, to); | |
448 size_t end = std::max(from, to); | |
449 const Font& font = default_style_.font; | |
450 int start_x = font.GetStringWidth(text().substr(0, start)); | |
451 int end_x = font.GetStringWidth(text().substr(0, end)); | |
452 Rect rect(start_x, 0, end_x - start_x, font.GetHeight()); | |
453 rect.Offset(display_rect_.origin()); | |
454 rect.Offset(GetUpdatedDisplayOffset()); | |
455 // Center the rect vertically in |display_rect_|. | |
456 rect.Offset(Point(0, (display_rect_.height() - rect.height()) / 2)); | |
457 return std::vector<Rect>(1, rect); | |
458 } | |
459 | |
460 Rect RenderText::GetCursorBounds(const SelectionModel& selection, | 450 Rect RenderText::GetCursorBounds(const SelectionModel& selection, |
461 bool insert_mode) { | 451 bool insert_mode) { |
462 size_t from = selection.selection_end(); | 452 size_t from = selection.selection_end(); |
463 size_t to = insert_mode ? from : std::min(text_.length(), from + 1); | 453 size_t to = insert_mode ? from : std::min(text_.length(), from + 1); |
464 return GetSubstringBounds(from, to)[0]; | 454 return GetSubstringBounds(from, to)[0]; |
465 } | 455 } |
466 | 456 |
467 const Rect& RenderText::GetUpdatedCursorBounds() { | 457 const Rect& RenderText::GetUpdatedCursorBounds() { |
468 UpdateCachedBoundsAndOffset(); | 458 UpdateCachedBoundsAndOffset(); |
469 return cursor_bounds_; | 459 return cursor_bounds_; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 if (!success) | 532 if (!success) |
543 return current; | 533 return current; |
544 while (iter.Advance()) { | 534 while (iter.Advance()) { |
545 pos = iter.pos(); | 535 pos = iter.pos(); |
546 if (iter.IsWord() && pos > current.selection_end()) | 536 if (iter.IsWord() && pos > current.selection_end()) |
547 break; | 537 break; |
548 } | 538 } |
549 return SelectionModel(pos, pos, SelectionModel::LEADING); | 539 return SelectionModel(pos, pos, SelectionModel::LEADING); |
550 } | 540 } |
551 | 541 |
542 SelectionModel RenderText::LeftEndSelectionModel() { | |
543 return SelectionModel(0, 0, SelectionModel::LEADING); | |
544 } | |
545 | |
546 SelectionModel RenderText::RightEndSelectionModel() { | |
547 size_t cursor = text().length(); | |
548 size_t caret_pos = GetIndexOfPreviousGrapheme(cursor); | |
549 SelectionModel::CaretPlacement placement = (caret_pos == cursor) ? | |
550 SelectionModel::LEADING : SelectionModel::TRAILING; | |
551 return SelectionModel(cursor, caret_pos, placement); | |
552 } | |
553 | |
552 size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) { | 554 size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) { |
553 // TODO(msw): Handle complex script. | 555 // TODO(msw): Handle complex script. |
554 return std::max(static_cast<int>(position - 1), static_cast<int>(0)); | 556 return std::max(static_cast<long>(position - 1), static_cast<long>(0)); |
557 } | |
558 | |
559 std::vector<Rect> RenderText::GetSubstringBounds(size_t from, size_t to) { | |
560 size_t start = std::min(from, to); | |
561 size_t end = std::max(from, to); | |
562 const Font& font = default_style_.font; | |
563 int start_x = font.GetStringWidth(text().substr(0, start)); | |
564 int end_x = font.GetStringWidth(text().substr(0, end)); | |
565 Rect rect(start_x, 0, end_x - start_x, font.GetHeight()); | |
566 rect.Offset(display_rect_.origin()); | |
567 rect.Offset(GetUpdatedDisplayOffset()); | |
568 // Center the rect vertically in |display_rect_|. | |
569 rect.Offset(Point(0, (display_rect_.height() - rect.height()) / 2)); | |
570 return std::vector<Rect>(1, rect); | |
555 } | 571 } |
556 | 572 |
557 void RenderText::ApplyCompositionAndSelectionStyles( | 573 void RenderText::ApplyCompositionAndSelectionStyles( |
558 StyleRanges* style_ranges) const { | 574 StyleRanges* style_ranges) const { |
559 // TODO(msw): This pattern ought to be reconsidered; what about composition | 575 // TODO(msw): This pattern ought to be reconsidered; what about composition |
560 // and selection overlaps, retain existing local style features? | 576 // and selection overlaps, retain existing local style features? |
561 // Apply a composition style override to a copy of the style ranges. | 577 // Apply a composition style override to a copy of the style ranges. |
562 if (composition_range_.IsValid() && !composition_range_.is_empty()) { | 578 if (composition_range_.IsValid() && !composition_range_.is_empty()) { |
563 StyleRange composition_style(default_style_); | 579 StyleRange composition_style(default_style_); |
564 composition_style.underline = true; | 580 composition_style.underline = true; |
565 composition_style.range.set_start(composition_range_.start()); | 581 composition_style.range.set_start(composition_range_.start()); |
566 composition_style.range.set_end(composition_range_.end()); | 582 composition_style.range.set_end(composition_range_.end()); |
567 ApplyStyleRangeImpl(style_ranges, composition_style); | 583 ApplyStyleRangeImpl(style_ranges, composition_style); |
568 } | 584 } |
569 // Apply a selection style override to a copy of the style ranges. | 585 // Apply a selection style override to a copy of the style ranges. |
570 if (!EmptySelection()) { | 586 if (!EmptySelection()) { |
571 StyleRange selection_style(default_style_); | 587 StyleRange selection_style(default_style_); |
572 selection_style.foreground = kSelectedTextColor; | 588 selection_style.foreground = kSelectedTextColor; |
573 selection_style.range.set_start(MinOfSelection()); | 589 selection_style.range.set_start(MinOfSelection()); |
574 selection_style.range.set_end(MaxOfSelection()); | 590 selection_style.range.set_end(MaxOfSelection()); |
575 ApplyStyleRangeImpl(style_ranges, selection_style); | 591 ApplyStyleRangeImpl(style_ranges, selection_style); |
576 } | 592 } |
577 } | 593 } |
578 | 594 |
595 Point RenderText::ToTextPoint(const Point& point) { | |
596 Point p(point.Subtract(display_rect().origin())); | |
597 p = p.Subtract(GetUpdatedDisplayOffset()); | |
598 if (base::i18n::IsRTL()) | |
599 p.Offset(GetStringWidth() - display_rect().width() + 1, 0); | |
600 return p; | |
601 } | |
602 | |
603 Point RenderText::ToViewPoint(const Point& point) { | |
604 Point p(point.Add(display_rect().origin())); | |
605 p = p.Add(GetUpdatedDisplayOffset()); | |
606 if (base::i18n::IsRTL()) | |
607 p.Offset(display_rect().width() - GetStringWidth() - 1, 0); | |
608 return p; | |
609 } | |
610 | |
611 void RenderText::SetSelectionModel(const SelectionModel& selection_model) { | |
612 DCHECK_LE(selection_model.selection_start(), text().length()); | |
613 selection_model_.set_selection_start(selection_model.selection_start()); | |
614 DCHECK_LE(selection_model.selection_end(), text().length()); | |
615 selection_model_.set_selection_end(selection_model.selection_end()); | |
616 DCHECK_LT(selection_model.caret_pos(), | |
617 std::max(text().length(), static_cast<size_t>(1))); | |
618 selection_model_.set_caret_pos(selection_model.caret_pos()); | |
619 selection_model_.set_caret_placement(selection_model.caret_placement()); | |
620 | |
621 cached_bounds_and_offset_valid_ = false; | |
622 } | |
623 | |
624 void RenderText::MoveCursorTo(size_t position, bool select) { | |
625 size_t cursor = std::min(position, text().length()); | |
626 size_t caret_pos = GetIndexOfPreviousGrapheme(cursor); | |
627 SelectionModel::CaretPlacement placement = (caret_pos == cursor) ? | |
628 SelectionModel::LEADING : SelectionModel::TRAILING; | |
629 size_t selection_start = select ? GetSelectionStart() : cursor; | |
630 SelectionModel sel(selection_start, cursor, caret_pos, placement); | |
631 SetSelectionModel(sel); | |
632 } | |
633 | |
579 bool RenderText::IsPositionAtWordSelectionBoundary(size_t pos) { | 634 bool RenderText::IsPositionAtWordSelectionBoundary(size_t pos) { |
580 return pos == 0 || (u_isalnum(text()[pos - 1]) && !u_isalnum(text()[pos])) || | 635 return pos == 0 || (u_isalnum(text()[pos - 1]) && !u_isalnum(text()[pos])) || |
581 (!u_isalnum(text()[pos - 1]) && u_isalnum(text()[pos])); | 636 (!u_isalnum(text()[pos - 1]) && u_isalnum(text()[pos])); |
582 } | 637 } |
583 | 638 |
584 void RenderText::UpdateCachedBoundsAndOffset() { | 639 void RenderText::UpdateCachedBoundsAndOffset() { |
585 if (cached_bounds_and_offset_valid_) | 640 if (cached_bounds_and_offset_valid_) |
586 return; | 641 return; |
587 // First, set the valid flag true to calculate the current cursor bounds using | 642 // First, set the valid flag true to calculate the current cursor bounds using |
588 // the stale |display_offset_|. Applying |delta_offset| at the end of this | 643 // the stale |display_offset_|. Applying |delta_offset| at the end of this |
589 // function will set |cursor_bounds_| and |display_offset_| to correct values. | 644 // function will set |cursor_bounds_| and |display_offset_| to correct values. |
590 cached_bounds_and_offset_valid_ = true; | 645 cached_bounds_and_offset_valid_ = true; |
591 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); | 646 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); |
592 cursor_bounds_.set_width(std::max(cursor_bounds_.width(), 1)); | |
593 // Update |display_offset_| to ensure the current cursor is visible. | 647 // Update |display_offset_| to ensure the current cursor is visible. |
594 int display_width = display_rect_.width(); | 648 int display_width = display_rect_.width(); |
595 int string_width = GetStringWidth(); | 649 int string_width = GetStringWidth(); |
596 int delta_offset = 0; | 650 int delta_offset = 0; |
597 if (string_width < display_width) { | 651 if (string_width < display_width) { |
598 // Show all text whenever the text fits to the size. | 652 // Show all text whenever the text fits to the size. |
599 delta_offset = -display_offset_.x(); | 653 delta_offset = -display_offset_.x(); |
600 } else if (cursor_bounds_.right() > display_rect_.right()) { | 654 } else if (cursor_bounds_.right() > display_rect_.right()) { |
601 // Pan to show the cursor when it overflows to the right, | 655 // Pan to show the cursor when it overflows to the right, |
602 delta_offset = display_rect_.right() - cursor_bounds_.right(); | 656 delta_offset = display_rect_.right() - cursor_bounds_.right(); |
603 } else if (cursor_bounds_.x() < display_rect_.x()) { | 657 } else if (cursor_bounds_.x() < display_rect_.x()) { |
604 // Pan to show the cursor when it overflows to the left. | 658 // Pan to show the cursor when it overflows to the left. |
605 delta_offset = display_rect_.x() - cursor_bounds_.x(); | 659 delta_offset = display_rect_.x() - cursor_bounds_.x(); |
606 } | 660 } |
607 display_offset_.Offset(delta_offset, 0); | 661 display_offset_.Offset(delta_offset, 0); |
608 cursor_bounds_.Offset(delta_offset, 0); | 662 cursor_bounds_.Offset(delta_offset, 0); |
609 } | 663 } |
610 | 664 |
611 } // namespace gfx | 665 } // namespace gfx |
OLD | NEW |