Add IPC argument to handle composition character bounds into ViewHostMsg_ImeCompositionRangeChanged.

What for:
Using this argument, browser can acquire the composition character boundary rectangles.
This information is used by Japanese input method editor to show its window at the correct position.
This is used not only for fixing http://crbug.com/120597 but also for supporting IMR_QUERYCHARPOSITION message in Windows Chrome.
To support IMR_QUERYCHARPOSITION(Ref 1) message, input method editor can also show its window at the correct position(Ref 2).

Performance:
There is no performance concern for latin language users because this IPC is only emitted if the user uses an input method editor.
Even if the user uses an input method editor, the cost of this IPC is small because this IPC will be emitted at the same frequency as key typing.

Data size:
The data size to be transferred is small: it is the composition string length (typically less than a few dozen characters) times sizeof(gfx::Rect).

Ref 1. http://msdn.microsoft.com/en-us/library/windows/desktop/dd318634(v=vs.85).aspx
Ref 2. https://bug-87911-attachments.webkit.org/attachment.cgi?id=144954
(In Ref2, Safari works well for all IMEs. Firefox works well except ATOK. Chrome doesn't work for all IMEs.)

BUG=120597
TEST=try bots.

Review URL: https://chromiumcodereview.appspot.com/10543024

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141866 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 8514eed..f17b665 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1323,6 +1323,17 @@
   input_method_is_active_ = is_active;
 }
 
+void RenderWidget::UpdateCompositionInfo(
+    const ui::Range& range,
+    const std::vector<gfx::Rect>& character_bounds) {
+  if (!ShouldUpdateCompositionInfo(range, character_bounds))
+    return;
+  composition_character_bounds_ = character_bounds;
+  composition_range_ = range;
+  Send(new ViewHostMsg_ImeCompositionRangeChanged(
+      routing_id(), composition_range_, composition_character_bounds_));
+}
+
 void RenderWidget::OnImeSetComposition(
     const string16& text,
     const std::vector<WebCompositionUnderline>& underlines,
@@ -1345,7 +1356,9 @@
       range.set_start(location);
       range.set_end(location + length);
     }
-    Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range));
+    std::vector<gfx::Rect> character_bounds;
+    GetCompositionCharacterBounds(&character_bounds);
+    UpdateCompositionInfo(range, character_bounds);
   } else {
     // If we failed to set the composition text, then we need to let the browser
     // process to cancel the input method's ongoing composition session, to make
@@ -1359,7 +1372,7 @@
       range.set_start(location);
       range.set_end(location + length);
     }
-    Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range));
+    UpdateCompositionInfo(range, std::vector<gfx::Rect>());
   }
 }
 
@@ -1379,7 +1392,7 @@
     range.set_start(location);
     range.set_end(location + length);
   }
-  Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range));
+  UpdateCompositionInfo(range, std::vector<gfx::Rect>());
 }
 
 // This message causes the renderer to render an image of the
@@ -1586,13 +1599,30 @@
   gfx::Rect start_rect;
   gfx::Rect end_rect;
   GetSelectionBounds(&start_rect, &end_rect);
-  if (selection_start_rect_ == start_rect && selection_end_rect_ == end_rect)
-    return;
+  if (selection_start_rect_ != start_rect || selection_end_rect_ != end_rect) {
+    selection_start_rect_ = start_rect;
+    selection_end_rect_ = end_rect;
+    Send(new ViewHostMsg_SelectionBoundsChanged(
+        routing_id_, selection_start_rect_, selection_end_rect_));
+  }
 
-  selection_start_rect_ = start_rect;
-  selection_end_rect_ = end_rect;
-  Send(new ViewHostMsg_SelectionBoundsChanged(
-      routing_id_, selection_start_rect_, selection_end_rect_));
+  std::vector<gfx::Rect> character_bounds;
+  GetCompositionCharacterBounds(&character_bounds);
+  UpdateCompositionInfo(composition_range_, character_bounds);
+}
+
+bool RenderWidget::ShouldUpdateCompositionInfo(
+    const ui::Range& range,
+    const std::vector<gfx::Rect>& bounds) {
+  if (composition_range_ != range)
+    return true;
+  if (bounds.size() != composition_character_bounds_.size())
+    return true;
+  for (size_t i = 0; i < bounds.size(); ++i) {
+    if (bounds[i] != composition_character_bounds_[i])
+      return true;
+  }
+  return false;
 }
 
 // Check WebKit::WebTextInputType and ui::TextInputType is kept in sync.
@@ -1636,6 +1666,12 @@
   return ui::TEXT_INPUT_TYPE_NONE;
 }
 
+void RenderWidget::GetCompositionCharacterBounds(
+    std::vector<gfx::Rect>* bounds) {
+  DCHECK(bounds);
+  bounds->clear();
+}
+
 bool RenderWidget::CanComposeInline() {
   return true;
 }
@@ -1668,7 +1704,8 @@
     range.set_start(location);
     range.set_end(location + length);
   }
-  Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range));
+
+  UpdateCompositionInfo(range, std::vector<gfx::Rect>());
 }
 
 void RenderWidget::SchedulePluginMove(