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

Unified Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 10656019: Use cached composition bounds for firstRectForCharacterRange (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: leave todo comment Created 8 years, 6 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: content/browser/renderer_host/render_widget_host_view_mac.mm
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index e6bfb673c4ff0c1c50a7a35d4435727b3d4ced9f..68f0d97dd56823082b477e5d36685c0c43fb6d30 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -647,6 +647,8 @@ void RenderWidgetHostViewMac::ImeCompositionRangeChanged(
// The RangeChanged message is only sent with valid values. The current
// caret position (start == end) will be sent if there is no IME range.
[cocoa_view_ setMarkedRange:range.ToNSRange()];
+ composition_range_ = range;
+ composition_bounds_ = character_bounds;
}
void RenderWidgetHostViewMac::DidUpdateBackingStore(
@@ -1039,6 +1041,81 @@ void RenderWidgetHostViewMac::AckPendingSwapBuffers() {
}
}
+bool RenderWidgetHostViewMac::GetLineBreakIdx(
+ const std::vector<gfx::Rect>& bounds,
+ const ui::Range& range,
+ size_t* line_break_point) {
+ DCHECK(line_break_point);
+ if (range.start() >= bounds.size() || range.is_reversed() || range.is_empty())
+ return false;
+
+ // Detect line break by comparing x value because we can't assume the
+ // each character's height is fixed.
+ // TODO(nona): Bidi support.
James Su 2012/07/05 01:44:26 Yes, Bidi supporting is a big problem, besides it,
Seigo Nonaka 2012/07/05 06:59:45 Done.
+ const size_t loop_end_idx = std::min(bounds.size(), range.end());
+ for (size_t idx = range.start(); idx < loop_end_idx - 1; ++idx) {
+ if (bounds[idx].x() > bounds[idx + 1].x()) {
+ *line_break_point = idx + 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+gfx::Rect RenderWidgetHostViewMac::GetFirstRectForCompositionRange(
+ const ui::Range& range) {
+ DCHECK(range.start() < composition_bounds_.size());
James Su 2012/07/05 01:44:26 I'm still wondering if it's possible that an IME w
Seigo Nonaka 2012/07/05 06:59:45 Done.
+ DCHECK(range.end() <= composition_bounds_.size());
+
+ if (range.is_empty()) {
+ return gfx::Rect(composition_bounds_[range.start()].x(),
+ composition_bounds_[range.start()].y(),
+ 0,
+ composition_bounds_[range.start()].height());
+ }
+
+ size_t end_idx;
+ if (!GetLineBreakIdx(composition_bounds_, range, &end_idx)) {
+ end_idx = range.end();
+ }
+ gfx::Rect rect = composition_bounds_[range.start()];
+ for (size_t i = range.start() + 1; i < end_idx; ++i) {
+ rect = rect.Union(composition_bounds_[i]);
+ }
+ return rect;
+}
+
+ui::Range RenderWidgetHostViewMac::ConvertCharacterRangeToCompositionRange(
+ const ui::Range& request_range) {
+ if (composition_range_.is_empty())
James Su 2012/07/05 01:44:26 I think it's better to return correct rect for an
Seigo Nonaka 2012/07/05 06:59:45 composition_range_.is_empty() == true means there
+ return ui::Range::InvalidRange();
+
+ if (request_range.is_reversed())
+ return ui::Range::InvalidRange();
+
+ if (request_range.start() < composition_range_.start() ||
+ request_range.start() >= composition_range_.end())
James Su 2012/07/05 01:44:26 request_range.start() may equal to composition_ran
Seigo Nonaka 2012/07/05 06:59:45 Done.
+ return ui::Range::InvalidRange();
+
+ return ui::Range(
+ request_range.start() - composition_range_.start(),
+ request_range.end() - composition_range_.start());
+}
+
+bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange(
+ NSRange range,
+ NSRect* rect) {
+ TRACE_EVENT0("browser",
+ "RenderWidgetHostViewMac::GetFirstRectForCharacterRange");
+ const ui::Range request_range_in_composition =
+ ConvertCharacterRangeToCompositionRange(ui::Range(range));
+ if (request_range_in_composition == ui::Range::InvalidRange())
+ return false;
+ *rect = NSRectFromCGRect(
+ GetFirstRectForCompositionRange(request_range_in_composition).ToCGRect());
+ return true;
+}
+
void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
@@ -2684,8 +2761,12 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
// TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery.
if (actualRange)
*actualRange = theRange;
James Su 2012/07/05 01:44:26 Can you please help fix the logic of actualRange?
Seigo Nonaka 2012/07/05 06:59:45 Done for chached rectangle. On 2012/07/05 01:44:2
- NSRect rect = TextInputClientMac::GetInstance()->GetFirstRectForRange(
- renderWidgetHostView_->render_widget_host_, theRange);
+ NSRect rect;
+ if (!renderWidgetHostView_->GetCachedFirstRectForCharacterRange(theRange,
+ &rect)) {
+ rect = TextInputClientMac::GetInstance()->GetFirstRectForRange(
+ renderWidgetHostView_->render_widget_host_, theRange);
+ }
// The returned rectangle is in WebKit coordinates (upper left origin), so
// flip the coordinate system and then convert it into screen coordinates for

Powered by Google App Engine
This is Rietveld 408576698