+ // Find where to insert the new paragraphs.
+ BidirectionalRunIndex bidiInfoIndex = 0u;
+ for(Vector<BidirectionalParagraphInfoRun>::ConstIterator it = bidirectionalInfo.Begin(),
+ endIt = bidirectionalInfo.End();
+ it != endIt;
+ ++it)
+ {
+ const BidirectionalParagraphInfoRun& run = *it;
+
+ if(startIndex < run.characterRun.characterIndex + run.characterRun.numberOfCharacters)
+ {
+ // Found where to insert the bidi info.
+ break;
+ }
+ ++bidiInfoIndex;
+ }
+
+ // Traverse the script runs. If there is one with a right to left script, create the bidirectional info for the paragraph containing that script is needed.
+ // From the bidirectional point of view, a paragraph is the piece of text between two LINE_MUST_BREAK.
+
+ // Index pointing the first character of the current paragraph.
+ CharacterIndex paragraphCharacterIndex = startIndex;
+
+ // Pointer to the text buffer.
+ const Character* textBuffer = text.Begin();
+
+ // Pointer to the line break info buffer.
+ const LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+
+ // Handle to the bidirectional info module in text-abstraction.
+ TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
+
+ const CharacterIndex lastCharacter = startIndex + numberOfCharacters;
+
+ bool hasRightToLeftScript = false;
+
+ for(Vector<ScriptRun>::ConstIterator it = scripts.Begin(),
+ endIt = scripts.End();
+ it != endIt;
+ ++it)
+ {
+ const ScriptRun& scriptRun = *it;
+ const CharacterIndex lastScriptRunIndex = scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters - 1u;
+
+ if(startIndex > lastScriptRunIndex)
+ {
+ // Skip the run as it has already been processed.
+ continue;
+ }
+
+ if(lastCharacter <= scriptRun.characterRun.characterIndex)
+ {
+ // Do not get bidirectional info beyond startIndex + numberOfCharacters.
+ break;
+ }
+
+ if(!hasRightToLeftScript && scriptRun.isRightToLeft)
+ {
+ // The script is right to left.
+ hasRightToLeftScript = true;
+ }
+
+ if(TextAbstraction::LINE_MUST_BREAK == *(lineBreakInfoBuffer + lastScriptRunIndex))
+ {
+ // A new paragraph has been found.
+
+ if(hasRightToLeftScript)
+ {
+ // The Bidirectional run must have the same number of characters than the paragraph.
+ BidirectionalParagraphInfoRun bidirectionalRun;
+ bidirectionalRun.characterRun.characterIndex = paragraphCharacterIndex;
+ bidirectionalRun.characterRun.numberOfCharacters = (lastScriptRunIndex - paragraphCharacterIndex) + 1u; // The must break character is part of the paragrah.
+
+ // Create the bidirectional info for the whole paragraph and store the index to the table with this info in the run.
+ bidirectionalRun.bidirectionalInfoIndex = bidirectionalSupport.CreateInfo(textBuffer + bidirectionalRun.characterRun.characterIndex,
+ bidirectionalRun.characterRun.numberOfCharacters,
+ matchSystemLanguageDirection,
+ layoutDirection);
+
+ bidirectionalRun.direction = bidirectionalSupport.GetParagraphDirection(bidirectionalRun.bidirectionalInfoIndex);
+
+ bidirectionalInfo.Insert(bidirectionalInfo.Begin() + bidiInfoIndex, bidirectionalRun);
+ ++bidiInfoIndex;
+ }
+
+ // Point to the next paragraph.
+ paragraphCharacterIndex = lastScriptRunIndex + 1u;
+
+ // Reset whether there is a right to left script.
+ hasRightToLeftScript = false;
+ }
+ }
+
+ // Update indices of the bidi runs.
+ for(Vector<BidirectionalParagraphInfoRun>::Iterator it = bidirectionalInfo.Begin() + bidiInfoIndex,
+ endIt = bidirectionalInfo.End();
+ it != endIt;
+ ++it)
+ {
+ BidirectionalParagraphInfoRun& run = *it;
+
+ run.characterRun.characterIndex += numberOfCharacters;
+ }