+ penX += (glyph.advance + interGlyphExtraAdvance);
+ }
+
+ if(layout.isSplitToTwoHalves)
+ {
+ const GlyphIndex startIndexForGlyphInSecondHalf = layout.glyphIndexInSecondHalfLine;
+ const Length numberOfGlyphsInSecondHalfLine = layout.numberOfGlyphsInSecondHalfLine;
+ const GlyphIndex startIndexForGlyphPositionsnSecondHalf = layout.glyphIndexInSecondHalfLine - layoutParameters.startGlyphIndex;
+
+ for(GlyphIndex i = 0u; i < numberOfGlyphsInSecondHalfLine; ++i)
+ {
+ const GlyphInfo& glyph = *(glyphsBuffer + startIndexForGlyphInSecondHalf + i);
+ Vector2& position = *(glyphPositionsBuffer + startIndexForGlyphPositionsnSecondHalf + i);
+
+ position.x = penX + glyph.xBearing;
+ position.y = -glyph.yBearing;
+
+ penX += (glyph.advance + interGlyphExtraAdvance);
+ }
+ }
+ }
+
+ void SetGlyphPositions(const Parameters& layoutParameters,
+ Vector2* glyphPositionsBuffer,
+ LayoutBidiParameters& layoutBidiParameters,
+ const LineLayout& layout)
+ {
+ const Character* const textBuffer = layoutParameters.textModel->mLogicalModel->mText.Begin();
+ const BidirectionalLineInfoRun& bidiLine = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo[layoutBidiParameters.bidiLineIndex];
+ const GlyphInfo* const glyphsBuffer = layoutParameters.textModel->mVisualModel->mGlyphs.Begin();
+ const GlyphIndex* const charactersToGlyphsBuffer = layoutParameters.textModel->mVisualModel->mCharactersToGlyph.Begin();
+ const Length* const glyphsPerCharacterBuffer = layoutParameters.textModel->mVisualModel->mGlyphsPerCharacter.Begin();
+
+ CharacterIndex characterLogicalIndex = 0u;
+ CharacterIndex characterVisualIndex = bidiLine.characterRunForSecondHalfLine.characterIndex + *(bidiLine.visualToLogicalMapSecondHalf + characterLogicalIndex);
+ bool extendedToSecondHalf = false; // Whether the logical index is extended to second half
+
+ float penX = 0.f;
+
+ if(layout.isSplitToTwoHalves)
+ {
+ while(TextAbstraction::IsWhiteSpace(*(textBuffer + characterVisualIndex)))
+ {
+ const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex);
+ const GlyphInfo& glyph = *(glyphsBuffer + glyphIndex);
+
+ Vector2& position = *(glyphPositionsBuffer + glyphIndex - layoutParameters.startGlyphIndex);
+ position.x = penX;
+ position.y = -glyph.yBearing;
+
+ penX += glyph.advance;
+
+ ++characterLogicalIndex;
+ characterVisualIndex = bidiLine.characterRun.characterIndex + *(bidiLine.visualToLogicalMap + characterLogicalIndex);
+ }
+ }
+
+ if(characterLogicalIndex == bidiLine.characterRunForSecondHalfLine.numberOfCharacters)
+ {
+ extendedToSecondHalf = true;
+ characterLogicalIndex = 0u;
+ characterVisualIndex = bidiLine.characterRun.characterIndex + *(bidiLine.visualToLogicalMap + characterLogicalIndex);
+
+ while(TextAbstraction::IsWhiteSpace(*(textBuffer + characterVisualIndex)))
+ {
+ const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex);
+ const GlyphInfo& glyph = *(glyphsBuffer + glyphIndex);
+
+ Vector2& position = *(glyphPositionsBuffer + glyphIndex - layoutParameters.startGlyphIndex);
+ position.x = penX;
+ position.y = -glyph.yBearing;
+
+ penX += glyph.advance;
+
+ ++characterLogicalIndex;
+ characterVisualIndex = bidiLine.characterRun.characterIndex + *(bidiLine.visualToLogicalMap + characterLogicalIndex);
+ }
+ }
+
+ const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex);
+ const GlyphInfo& glyph = *(glyphsBuffer + glyphIndex);
+
+ penX += -glyph.xBearing;
+
+ // Traverses the characters of the right to left paragraph.
+ if(layout.isSplitToTwoHalves && !extendedToSecondHalf)
+ {
+ for(; characterLogicalIndex < bidiLine.characterRunForSecondHalfLine.numberOfCharacters;
+ ++characterLogicalIndex)
+ {
+ // Convert the character in the logical order into the character in the visual order.
+ const CharacterIndex characterVisualIndex = bidiLine.characterRunForSecondHalfLine.characterIndex + *(bidiLine.visualToLogicalMapSecondHalf + characterLogicalIndex);
+
+ // Get the number of glyphs of the character.
+ const Length numberOfGlyphs = *(glyphsPerCharacterBuffer + characterVisualIndex);
+
+ for(GlyphIndex index = 0u; index < numberOfGlyphs; ++index)
+ {
+ // Convert the character in the visual order into the glyph in the visual order.
+ const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex) + index;
+
+ DALI_ASSERT_DEBUG(glyphIndex < layoutParameters.textModel->mVisualModel->mGlyphs.Count());
+
+ const GlyphInfo& glyph = *(glyphsBuffer + glyphIndex);
+ Vector2& position = *(glyphPositionsBuffer + glyphIndex - layoutParameters.startGlyphIndex);
+
+ position.x = penX + glyph.xBearing;
+ position.y = -glyph.yBearing;
+
+ penX += (glyph.advance + layoutParameters.interGlyphExtraAdvance);
+ }
+ }
+ }
+
+ characterLogicalIndex = extendedToSecondHalf ? characterLogicalIndex : 0u;
+ for(; characterLogicalIndex < bidiLine.characterRun.numberOfCharacters;
+ ++characterLogicalIndex)
+ {
+ // Convert the character in the logical order into the character in the visual order.
+ const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *(bidiLine.visualToLogicalMap + characterLogicalIndex);
+
+ // Get the number of glyphs of the character.
+ const Length numberOfGlyphs = *(glyphsPerCharacterBuffer + characterVisualIndex);
+
+ for(GlyphIndex index = 0u; index < numberOfGlyphs; ++index)
+ {
+ // Convert the character in the visual order into the glyph in the visual order.
+ const GlyphIndex glyphIndex = *(charactersToGlyphsBuffer + characterVisualIndex) + index;
+
+ DALI_ASSERT_DEBUG(glyphIndex < layoutParameters.textModel->mVisualModel->mGlyphs.Count());
+
+ const GlyphInfo& glyph = *(glyphsBuffer + glyphIndex);
+ Vector2& position = *(glyphPositionsBuffer + glyphIndex - layoutParameters.startGlyphIndex);
+
+ position.x = penX + glyph.xBearing;
+ position.y = -glyph.yBearing;
+
+ penX += (glyph.advance + layoutParameters.interGlyphExtraAdvance);
+ }