+ GetRunCache& bidiCache = mImpl->mGetBidirectionalCache;
+
+ // Set the character index and the number of characters into the cache.
+ bidiCache.characterIndex = characterIndex;
+ bidiCache.numberOfCharacters = numberOfCharacters;
+
+ if( ( 0u == characterIndex ) &&
+ ( mImpl->mText.Count() == numberOfCharacters ) )
+ {
+ bidiCache.firstRun = 0u;
+ bidiCache.numberOfRuns = mImpl->mBidirectionalParagraphInfo.Count();
+ return bidiCache.numberOfRuns;
+ }
+
+ // Initialize the number of bidi paragraphs and the index to the first paragraph.
+ bidiCache.firstRun = 0u;
+ bidiCache.numberOfRuns = 0;
+ bool firstParagraphFound = false;
+
+ const Vector<BidirectionalParagraphInfoRun>& modelBidirectionalParagraphInfo = mImpl->mBidirectionalParagraphInfo;
+
+ // Traverse the bidirectional paragraph info and count those bidi paragraphs within the range of characters.
+ for( Vector<BidirectionalParagraphInfoRun>::ConstIterator it = modelBidirectionalParagraphInfo.Begin(),
+ endIt = modelBidirectionalParagraphInfo.End();
+ it != endIt;
+ ++it )
+ {
+ const BidirectionalParagraphInfoRun& bidi = *it;
+
+ if( ( bidi.characterRun.characterIndex + bidi.characterRun.numberOfCharacters > characterIndex ) &&
+ ( characterIndex + numberOfCharacters > bidi.characterRun.characterIndex ) )
+ {
+ firstParagraphFound = true;
+ ++bidiCache.numberOfRuns;
+ }
+
+ if( !firstParagraphFound )
+ {
+ ++bidiCache.firstRun;
+ }
+ }
+
+ return bidiCache.numberOfRuns;
+}
+
+void LogicalModel::GetBidirectionalInfo( BidirectionalParagraphInfoRun* bidirectionalInfo,
+ CharacterIndex characterIndex,
+ Length numberOfCharacters ) const
+{
+ const Vector<BidirectionalParagraphInfoRun>& modelBidirectionalParagraphInfo = mImpl->mBidirectionalParagraphInfo;
+ GetRunCache& bidiCache = mImpl->mGetBidirectionalCache;
+
+ if( ( characterIndex != bidiCache.characterIndex ) ||
+ ( numberOfCharacters != bidiCache.numberOfCharacters ) )
+ {
+ GetNumberOfBidirectionalInfoRuns( characterIndex,
+ numberOfCharacters );
+ }
+
+ memcpy( bidirectionalInfo, modelBidirectionalParagraphInfo.Begin() + bidiCache.firstRun, bidiCache.numberOfRuns * sizeof( BidirectionalParagraphInfoRun ) );
+}
+
+void ReplaceBidirectionalInfo( CharacterIndex characterIndex,
+ Length numberOfCharactersToRemove,
+ const BidirectionalParagraphInfoRun* const bidirectionalInfo,
+ Length numberOfCharactersToInsert )
+{