+ const Length* const charactersPerGlyphBuffer = parameters.visualModel->mCharactersPerGlyph.Begin();
+ const CharacterIndex* const glyphsToCharactersBuffer = parameters.visualModel->mGlyphsToCharacters.Begin();
+ const Vector2* const glyphPositionsBuffer = parameters.visualModel->mGlyphPositions.Begin();
+ const float modelCharacterSpacing = parameters.visualModel->GetCharacterSpacing();
+
+ const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = parameters.visualModel->GetCharacterSpacingGlyphRuns();
+
+ // Get the metrics for the group of glyphs.
+ GetGlyphMetricsFromCharacterIndex(index, parameters.visualModel, parameters.logicalModel, metrics, glyphMetrics, glyphIndex, numberOfGlyphs);
+
+ // Convert the cursor position into the glyph position.
+ const GlyphIndex primaryGlyphIndex = glyphIndex;
+ const Length primaryNumberOfCharacters = *(charactersPerGlyphBuffer + primaryGlyphIndex);
+
+ // Whether to add the glyph's advance to the cursor position.
+ // i.e if the paragraph is left to right and the logical cursor is zero, the position is the position of the first glyph and the advance is not added,
+ // if the logical cursor is one, the position is the position of the first glyph and the advance is added.
+ // A 'truth table' was build and an online Karnaugh map tool was used to simplify the logic.
+ //
+ // FLCP A
+ // ------
+ // 0000 1
+ // 0001 1
+ // 0010 0
+ // 0011 0
+ // 0100 1
+ // 0101 0
+ // 0110 1
+ // 0111 0
+ // 1000 0
+ // 1001 1
+ // 1010 0
+ // 1011 1
+ // 1100 x
+ // 1101 x
+ // 1110 x
+ // 1111 x
+ //
+ // Where F -> isFirstPosition
+ // L -> isLastPosition
+ // C -> isCurrentRightToLeft
+ // P -> isRightToLeftParagraph
+ // A -> Whether to add the glyph's advance.
+
+ const bool addGlyphAdvance = ((isLastPositionOfLine && !isRightToLeftParagraph) ||
+ (isFirstPositionOfLine && isRightToLeftParagraph) ||
+ (!isFirstPositionOfLine && !isLastPosition && !isCurrentRightToLeft));
+
+ float glyphAdvance = addGlyphAdvance ? (glyphMetrics.advance) : 0.f;
+
+ if(!isLastPositionOfLine &&
+ (primaryNumberOfCharacters > 1u))
+ {
+ const CharacterIndex firstIndex = *(glyphsToCharactersBuffer + primaryGlyphIndex);
+
+ bool isCurrentRightToLeft = false;
+ if(bidiLineFetched) // If bidiLineFetched is false, it means the whole text is left to right.
+ {
+ isCurrentRightToLeft = *(directionsBuffer + index);
+ }
+
+ Length numberOfGlyphAdvance = (isFirstPositionOfLine ? 0 : 1u) + characterIndex - firstIndex;
+ if(isCurrentRightToLeft)
+ {
+ numberOfGlyphAdvance = primaryNumberOfCharacters - numberOfGlyphAdvance;
+ }
+
+ glyphAdvance = static_cast<float>(numberOfGlyphAdvance) * (glyphMetrics.advance) / static_cast<float>(primaryNumberOfCharacters);
+ }