Fix for text layout. 19/66819/3
authorVictor Cebollada <v.cebollada@samsung.com>
Thu, 21 Apr 2016 06:40:04 +0000 (07:40 +0100)
committerVíctor Cebollada <v.cebollada@samsung.com>
Thu, 21 Apr 2016 09:55:18 +0000 (02:55 -0700)
* If a character is shaped in more than one glyph and this character is at the end of a text,
  each glyph was rendered in a different line.
  This is because the segmentation info says the last character is a MUST_BREAK. When the glyphs
  of the last character are traversed they get a MUST_BREAK and they are laid-out in a new line.

Change-Id: Ic88a196bd0787e819dba0e7a887b4486506e7a50
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
dali-toolkit/internal/file.list
dali-toolkit/internal/text/glyph-metrics-helper.cpp [new file with mode: 0644]
dali-toolkit/internal/text/glyph-metrics-helper.h [new file with mode: 0644]
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/metrics.h
dali-toolkit/internal/text/text-controller-impl.cpp

index ab7cac6..758160f 100644 (file)
@@ -91,6 +91,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/character-set-conversion.cpp \
    $(toolkit_src_dir)/text/clipping/text-clipper.cpp \
    $(toolkit_src_dir)/text/color-segmentation.cpp \
+   $(toolkit_src_dir)/text/glyph-metrics-helper.cpp \
    $(toolkit_src_dir)/text/logical-model-impl.cpp \
    $(toolkit_src_dir)/text/markup-processor.cpp \
    $(toolkit_src_dir)/text/markup-processor-color.cpp \
diff --git a/dali-toolkit/internal/text/glyph-metrics-helper.cpp b/dali-toolkit/internal/text/glyph-metrics-helper.cpp
new file mode 100644 (file)
index 0000000..9c7c8ec
--- /dev/null
@@ -0,0 +1,83 @@
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+Length GetNumberOfGlyphsOfGroup( GlyphIndex glyphIndex,
+                                 GlyphIndex lastGlyphPlusOne,
+                                 const Length* const charactersPerGlyphBuffer )
+{
+  Length numberOfGLyphsInGroup = 1u;
+
+  for( GlyphIndex index = glyphIndex; index < lastGlyphPlusOne; ++index )
+  {
+    if( 0u == *( charactersPerGlyphBuffer + index ) )
+    {
+      ++numberOfGLyphsInGroup;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  return numberOfGLyphsInGroup;
+}
+
+void GetGlyphsMetrics( GlyphIndex glyphIndex,
+                       Length numberOfGlyphs,
+                       GlyphMetrics& glyphMetrics,
+                       const GlyphInfo* const glyphsBuffer,
+                       MetricsPtr& metrics )
+{
+  const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex );
+
+  Text::FontMetrics fontMetrics;
+  metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics );
+
+  glyphMetrics.fontId = firstGlyph.fontId;
+  glyphMetrics.fontHeight = fontMetrics.height;
+  glyphMetrics.width = firstGlyph.width;
+  glyphMetrics.advance = firstGlyph.advance;
+  glyphMetrics.ascender = fontMetrics.ascender;
+  glyphMetrics.xBearing = firstGlyph.xBearing;
+
+  for( unsigned int i = 1u; i < numberOfGlyphs; ++i )
+  {
+    const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i );
+
+    glyphMetrics.advance += glyphInfo.advance;
+    glyphMetrics.width += glyphInfo.width;
+  }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/glyph-metrics-helper.h b/dali-toolkit/internal/text/glyph-metrics-helper.h
new file mode 100644 (file)
index 0000000..2c2c848
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef __DALI_TOOLKIT_TEXT_GLYPH_METRICS_HELPER_H__
+#define __DALI_TOOLKIT_TEXT_GLYPH_METRICS_HELPER_H__
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/metrics.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Some characters can be shaped in more than one glyph.
+ * This struct is used to retrieve metrics from these group of glyphs.
+ */
+struct GlyphMetrics
+{
+  GlyphMetrics()
+  : fontId( 0u ),
+    fontHeight( 0.f ),
+    width( 0.f ),
+    advance( 0.f ),
+    ascender( 0.f ),
+    xBearing( 0.f )
+  {}
+
+  ~GlyphMetrics()
+  {}
+
+  FontId fontId;     ///< The font id of the glyphs.
+  float  fontHeight; ///< The font's height of those glyphs.
+  float  width;      ///< The sum of all the widths of all the glyphs.
+  float  advance;    ///< The sum of all the advances of all the glyphs.
+  float  ascender;   ///< The font's ascender.
+  float  xBearing;   ///< The x bearing of the first glyph.
+};
+
+/**
+ * @brief Returns the number of glyphs of a group of glyphs.
+ *
+ * @param[in] glyphIndex The first glyph of the group.
+ * @param[in] lastGlyphPlusOne Index to one after the last glyph.
+ * @param[in] charactersPerGlyphBuffer The number of characters per glyph buffer.
+ *
+ * @return The number of glyphs of the group.
+ */
+Length GetNumberOfGlyphsOfGroup( GlyphIndex glyphIndex,
+                                 GlyphIndex lastGlyphPlusOne,
+                                 const Length* const charactersPerGlyphBuffer );
+
+/**
+ * @brief Get some glyph's metrics of a group of glyphs formed as a result of shaping one character.
+ *
+ * @param[in] glyphIndex The index to the first glyph.
+ * @param[in] numberOfGlyphs The number of glyphs.
+ * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing).
+ * @param[in] glyphsBuffer The glyphs buffer.
+ * @param[in] metrics Used to access metrics from FontClient.
+ */
+void GetGlyphsMetrics( GlyphIndex glyphIndex,
+                       Length numberOfGlyphs,
+                       GlyphMetrics& glyphMetrics,
+                       const GlyphInfo* const glyphsBuffer,
+                       MetricsPtr& metrics );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_GLYPH_METRICS_HELPER_H__
index 9d81116..8816e33 100644 (file)
@@ -24,8 +24,9 @@
 #include <dali/devel-api/text-abstraction/font-client.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
 #include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
 
 namespace Dali
 {
@@ -214,59 +215,81 @@ struct LayoutEngine::Impl
     LineLayout tmpLineLayout;
 
     const bool isMultiline = mLayout == MULTI_LINE_BOX;
-    const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u;
+
+    // The last glyph to be laid-out.
+    const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
 
     // If the first glyph has a negative bearing its absolute value needs to be added to the line length.
     // In the case the line starts with a right to left character, if the width is longer than the advance,
     // the difference needs to be added to the line length.
-    const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + lineLayout.glyphIndex );
+
+    // Check whether the first glyph comes from a character that is shaped in multiple glyphs.
+    const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( lineLayout.glyphIndex,
+                                                                   lastGlyphOfParagraphPlusOne,
+                                                                   parameters.charactersPerGlyphBuffer );
+
+    GlyphMetrics glyphMetrics;
+    GetGlyphsMetrics( lineLayout.glyphIndex,
+                      numberOfGLyphsInGroup,
+                      glyphMetrics,
+                      parameters.glyphsBuffer,
+                      mMetrics );
 
     // Set the direction of the first character of the line.
     lineLayout.characterIndex = *( parameters.glyphsToCharactersBuffer + lineLayout.glyphIndex );
     const CharacterDirection firstCharacterDirection = ( NULL == parameters.characterDirectionBuffer ) ? false : *( parameters.characterDirectionBuffer + lineLayout.characterIndex );
     CharacterDirection previousCharacterDirection = firstCharacterDirection;
 
-    const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+    const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
     float tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
 
-    float tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+    float tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
 
     tmpLineLayout.length += mCursorWidth; // Added to give some space to the cursor.
 
     // Calculate the line height if there is no characters.
-    FontId lastFontId = glyphInfo.fontId;
+    FontId lastFontId = glyphMetrics.fontId;
     UpdateLineHeight( lastFontId, tmpLineLayout );
 
     bool oneWordLaidOut = false;
 
-    const GlyphIndex lastGlyphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
     for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
-         glyphIndex < lastGlyphPlusOne;
-         ++glyphIndex )
+         glyphIndex < lastGlyphOfParagraphPlusOne; )
     {
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  glyph index : %d\n", glyphIndex );
-      const bool isLastGlyph = glyphIndex == lastGlyphIndex;
 
-      // Get the glyph info.
-      const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
+      // Check whether this glyph comes from a character that is shaped in multiple glyphs.
+      const Length numberOfGLyphsInGroup = GetNumberOfGlyphsOfGroup( glyphIndex,
+                                                                     lastGlyphOfParagraphPlusOne,
+                                                                     parameters.charactersPerGlyphBuffer );
+
+      GlyphMetrics glyphMetrics;
+      GetGlyphsMetrics( glyphIndex,
+                        numberOfGLyphsInGroup,
+                        glyphMetrics,
+                        parameters.glyphsBuffer,
+                        mMetrics );
+
+      const bool isLastGlyph = glyphIndex + numberOfGLyphsInGroup  == parameters.totalNumberOfGlyphs;
 
       // Check if the font of the current glyph is the same of the previous one.
       // If it's different the ascender and descender need to be updated.
-      if( lastFontId != glyphInfo.fontId )
+      if( lastFontId != glyphMetrics.fontId )
       {
-        UpdateLineHeight( glyphInfo.fontId, tmpLineLayout );
-        lastFontId = glyphInfo.fontId;
+        UpdateLineHeight( glyphMetrics.fontId, tmpLineLayout );
+        lastFontId = glyphMetrics.fontId;
       }
 
       // Get the character indices for the current glyph. The last character index is needed
       // because there are glyphs formed by more than one character but their break info is
       // given only for the last character.
-      const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex );
+      const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u );
+      const bool hasCharacters = charactersPerGlyph > 0u;
       const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex );
-      const CharacterIndex characterLastIndex = characterFirstIndex + ( ( 1u > charactersPerGlyph ) ? 0u : charactersPerGlyph - 1u );
+      const CharacterIndex characterLastIndex = characterFirstIndex + ( hasCharacters ? charactersPerGlyph - 1u : 0u );
 
       // Get the line break info for the current character.
-      const LineBreakInfo lineBreakInfo = *( parameters.lineBreakInfoBuffer + characterLastIndex );
+      const LineBreakInfo lineBreakInfo = hasCharacters ? *( parameters.lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK;
 
       // Get the word break info for the current character.
       const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex );
@@ -275,7 +298,7 @@ struct LayoutEngine::Impl
       tmpLineLayout.numberOfCharacters += charactersPerGlyph;
 
       // Increase the number of glyphs.
-      tmpLineLayout.numberOfGlyphs++;
+      tmpLineLayout.numberOfGlyphs += numberOfGLyphsInGroup;
 
       // Check whether is a white space.
       const Character character = *( parameters.textBuffer + characterFirstIndex );
@@ -293,12 +316,12 @@ struct LayoutEngine::Impl
       if( isWhiteSpace )
       {
         // Add the length to the length of white spaces at the end of the line.
-        tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // The advance is used as the width is always zero for the white spaces.
+        tmpLineLayout.wsLengthEndOfLine += glyphMetrics.advance; // The advance is used as the width is always zero for the white spaces.
       }
       else
       {
         // Add as well any previous white space length.
-        tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphInfo.advance;
+        tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + glyphMetrics.advance;
 
         // An extra space may be added to the line for the first and last glyph of the line.
         // If the bearing of the first glyph is negative, its positive value needs to be added.
@@ -318,7 +341,7 @@ struct LayoutEngine::Impl
             // |     Rll|
             //
 
-            tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+            tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
           }
           else // LTR
           {
@@ -331,7 +354,7 @@ struct LayoutEngine::Impl
             // |rrL     |
             //
 
-            const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+            const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
             tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
           }
         }
@@ -344,7 +367,7 @@ struct LayoutEngine::Impl
               //  -->
               // |lllR    |
 
-              const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+              const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
               tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
             }
             else // LTR
@@ -352,7 +375,7 @@ struct LayoutEngine::Impl
               //       <--
               // |   Lrrrr|
 
-              tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+              tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
             }
           }
           else if( characterDirection == firstCharacterDirection )
@@ -363,7 +386,7 @@ struct LayoutEngine::Impl
               // |llllllrr|
               // |Rr      |
 
-              tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
+              tmpExtraBearing = ( 0.f > glyphMetrics.xBearing ) ? -glyphMetrics.xBearing : 0.f;
             }
             else // LTR
             {
@@ -371,7 +394,7 @@ struct LayoutEngine::Impl
               // |llllrrrr|
               // |     llL|
 
-              const float extraWidth = glyphInfo.xBearing + glyphInfo.width - glyphInfo.advance;
+              const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
               tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
             }
           }
@@ -394,7 +417,7 @@ struct LayoutEngine::Impl
           if( tmpLineLayout.numberOfGlyphs > 0u )
           {
             tmpLineLayout.numberOfCharacters -= charactersPerGlyph;
-            --tmpLineLayout.numberOfGlyphs;
+            tmpLineLayout.numberOfGlyphs -= numberOfGLyphsInGroup;
             tmpLineLayout.length = previousTmpLineLength;
             tmpExtraBearing = previousTmpExtraBearing;
             tmpExtraWidth = previousTmpExtraWidth;
@@ -434,6 +457,7 @@ struct LayoutEngine::Impl
 
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  Must break\n" );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" );
+
         return;
       }
 
@@ -451,6 +475,7 @@ struct LayoutEngine::Impl
       }
 
       previousCharacterDirection = characterDirection;
+      glyphIndex += numberOfGLyphsInGroup;
     }
 
     lineLayout.extraBearing = tmpExtraBearing;
index 5e58f38..232360e 100644 (file)
@@ -22,6 +22,9 @@
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/devel-api/text-abstraction/font-client.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
 namespace Dali
 {
 
index 5571f94..7fcacc2 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali-toolkit/internal/text/bidirectional-support.h>
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
 #include <dali-toolkit/internal/text/multi-language-support.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
@@ -37,28 +38,6 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
-/**
- * @brief Some characters can be shaped in more than one glyph.
- * This struct is used to retrieve metrics from these group of glyphs.
- */
-struct GlyphMetrics
-{
-  GlyphMetrics()
-  : fontHeight( 0.f ),
-    advance( 0.f ),
-    ascender( 0.f ),
-    xBearing( 0.f )
-  {}
-
-  ~GlyphMetrics()
-  {}
-
-  float fontHeight; ///< The font's height of that glyphs.
-  float advance;    ///< The sum of all the advances of all the glyphs.
-  float ascender;   ///< The font's ascender.
-  float xBearing;   ///< The x bearing of the first glyph.
-};
-
 } // namespace
 
 namespace Dali
@@ -70,41 +49,6 @@ namespace Toolkit
 namespace Text
 {
 
-/**
- * @brief Get some glyph's metrics of a group of glyphs formed as a result of shaping one character.
- *
- * @param[in] glyphIndex The index to the first glyph.
- * @param[in] numberOfGlyphs The number of glyphs.
- * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing).
- * @param[in] visualModel The visual model.
- * @param[in] metrics Used to access metrics from FontClient.
- */
-void GetGlyphsMetrics( GlyphIndex glyphIndex,
-                       Length numberOfGlyphs,
-                       GlyphMetrics& glyphMetrics,
-                       VisualModelPtr& visualModel,
-                       MetricsPtr& metrics )
-{
-  const GlyphInfo* glyphsBuffer = visualModel->mGlyphs.Begin();
-
-  const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex );
-
-  Text::FontMetrics fontMetrics;
-  metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics );
-
-  glyphMetrics.fontHeight = fontMetrics.height;
-  glyphMetrics.advance = firstGlyph.advance;
-  glyphMetrics.ascender = fontMetrics.ascender;
-  glyphMetrics.xBearing = firstGlyph.xBearing;
-
-  for( unsigned int i = 1u; i < numberOfGlyphs; ++i )
-  {
-    const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i );
-
-    glyphMetrics.advance += glyphInfo.advance;
-  }
-}
-
 EventData::EventData( DecoratorPtr decorator )
 : mDecorator( decorator ),
   mImfManager(),
@@ -1585,6 +1529,9 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX,
   // Get the glyphs per character table.
   const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
 
+  // Get the glyph's info buffer.
+  const GlyphInfo* const glyphInfoBuffer = mVisualModel->mGlyphs.Begin();
+
   // If the vector is void, there is no right to left characters.
   const bool hasRightToLeftCharacters = NULL != visualToLogicalBuffer;
 
@@ -1623,7 +1570,7 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX,
       GetGlyphsMetrics( firstLogicalGlyphIndex,
                         numberOfGlyphs,
                         glyphMetrics,
-                        mVisualModel,
+                        glyphInfoBuffer,
                         mMetrics );
 
       // Get the position of the first glyph.
@@ -1802,6 +1749,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
   const Length* const charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
   const CharacterIndex* const glyphsToCharactersBuffer = mVisualModel->mGlyphsToCharacters.Begin();
   const Vector2* const glyphPositionsBuffer = mVisualModel->mGlyphPositions.Begin();
+  const GlyphInfo* const glyphInfoBuffer = mVisualModel->mGlyphs.Begin();
 
   // Convert the cursor position into the glyph position.
   const GlyphIndex primaryGlyphIndex = *( charactersToGlyphBuffer + index );
@@ -1813,7 +1761,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
   GetGlyphsMetrics( primaryGlyphIndex,
                     primaryNumberOfGlyphs,
                     glyphMetrics,
-                    mVisualModel,
+                    glyphInfoBuffer,
                     mMetrics );
 
   // Whether to add the glyph's advance to the cursor position.
@@ -1903,7 +1851,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     GetGlyphsMetrics( secondaryGlyphIndex,
                       secondaryNumberOfGlyphs,
                       glyphMetrics,
-                      mVisualModel,
+                      glyphInfoBuffer,
                       mMetrics );
 
     // Set the secondary cursor's position.