Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / gfx / render_text_win.cc
index 73fa73b..19b2caa 100644 (file)
@@ -504,19 +504,14 @@ HDC RenderTextWin::cached_hdc_ = NULL;
 // static
 std::map<std::string, Font> RenderTextWin::successful_substitute_fonts_;
 
-RenderTextWin::RenderTextWin()
-    : RenderText(),
-      needs_layout_(false) {
+RenderTextWin::RenderTextWin() : RenderText(), needs_layout_(false) {
   set_truncate_length(kMaxUniscribeTextLength);
-
   memset(&script_control_, 0, sizeof(script_control_));
   memset(&script_state_, 0, sizeof(script_state_));
-
   MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT));
 }
 
-RenderTextWin::~RenderTextWin() {
-}
+RenderTextWin::~RenderTextWin() {}
 
 Size RenderTextWin::GetStringSize() {
   EnsureLayout();
@@ -716,7 +711,7 @@ std::vector<Rect> RenderTextWin::GetSubstringBounds(const Range& range) {
 
 size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const {
   DCHECK_LE(index, text().length());
-  ptrdiff_t i = obscured() ? gfx::UTF16IndexToOffset(text(), 0, index) : index;
+  ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index;
   CHECK_GE(i, 0);
   // Clamp layout indices to the length of the text actually used for layout.
   return std::min<size_t>(GetLayoutText().length(), i);
@@ -727,24 +722,22 @@ size_t RenderTextWin::LayoutIndexToTextIndex(size_t index) const {
     return index;
 
   DCHECK_LE(index, GetLayoutText().length());
-  const size_t text_index = gfx::UTF16OffsetToIndex(text(), 0, index);
+  const size_t text_index = UTF16OffsetToIndex(text(), 0, index);
   DCHECK_LE(text_index, text().length());
   return text_index;
 }
 
-bool RenderTextWin::IsCursorablePosition(size_t position) {
-  if (position == 0 || position == text().length())
+bool RenderTextWin::IsValidCursorIndex(size_t index) {
+  if (index == 0 || index == text().length())
     return true;
+  if (!IsValidLogicalIndex(index))
+    return false;
   EnsureLayout();
-
-  // Check that the index is at a valid code point (not mid-surrgate-pair),
-  // that it is not truncated from layout text (its glyph is shown on screen),
-  // and that its glyph has distinct bounds (not mid-multi-character-grapheme).
-  // An example of a multi-character-grapheme that is not a surrogate-pair is:
-  // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
-  return gfx::IsValidCodePointIndex(text(), position) &&
-         position < LayoutIndexToTextIndex(GetLayoutText().length()) &&
-         GetGlyphBounds(position) != GetGlyphBounds(position - 1);
+  // Disallow indices amid multi-character graphemes by checking glyph bounds.
+  // These characters are not surrogate-pairs, but may yield a single glyph:
+  //   \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
+  //   \x0e08\x0e33 - (cho chan + sara am) - a Thai consonant and vowel pair.
+  return GetGlyphBounds(index) != GetGlyphBounds(index - 1);
 }
 
 void RenderTextWin::ResetLayout() {
@@ -843,7 +836,7 @@ void RenderTextWin::DrawVisualText(Canvas* canvas) {
       for (size_t k = glyph_range.start(); k < glyph_range.end(); ++k) {
         pos[k - glyph_range.start()].set(
             SkIntToScalar(text_offset.x() + run->offsets[k].du + segment_x),
-            SkIntToScalar(text_offset.y() + run->offsets[k].dv));
+            SkIntToScalar(text_offset.y() - run->offsets[k].dv));
         segment_x += run->advance_widths[k];
       }
       pos.back().set(SkIntToScalar(text_offset.x() + segment_x),
@@ -860,8 +853,13 @@ void RenderTextWin::DrawVisualText(Canvas* canvas) {
         const Range intersection =
             colors().GetRange(it).Intersect(segment->char_range);
         const Range colored_glyphs = CharRangeToGlyphRange(*run, intersection);
+        // The range may be empty if a portion of a multi-character grapheme is
+        // selected, yielding two colors for a single glyph. For now, this just
+        // paints the glyph with a single style, but it should paint it twice,
+        // clipped according to selection bounds. See http://crbug.com/366786
+        if (colored_glyphs.is_empty())
+          continue;
         DCHECK(glyph_range.Contains(colored_glyphs));
-        DCHECK(!colored_glyphs.is_empty());
         const SkPoint& start_pos =
             pos[colored_glyphs.start() - glyph_range.start()];
         const SkPoint& end_pos =
@@ -1009,13 +1007,6 @@ void RenderTextWin::LayoutVisualText() {
 
     if (run->glyph_count > 0) {
       run->advance_widths.reset(new int[run->glyph_count]);
-      // TODO(asvitkine): Temporary instrumentation to debug a double-free
-      // crash where we're seeing these two being equal inexplicably. Hitting
-      // this implies that the malloc book-keeping is corrupt and it returned
-      // the same pointer for two different allocs, which we can debug further.
-      // http://crbug.com/348103
-      CHECK_NE(static_cast<void*>(run->logical_clusters.get()),
-               static_cast<void*>(run->advance_widths.get()));
       run->offsets.reset(new GOFFSET[run->glyph_count]);
       hr = ScriptPlace(cached_hdc_,
                        &run->script_cache,