}
void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo,
- Length numberOfRuns )
+ Length numberOfRuns,
+ CharacterIndex startIndex,
+ Length numberOfCharacters )
{
- if( 0u == numberOfRuns )
- {
- mVisualToLogicalMap.Clear();
- mLogicalToVisualMap.Clear();
- mVisualToLogicalCursorMap.Clear();
- }
- else
- {
- const Length numberOfCharacters = mText.Count();
- mVisualToLogicalMap.Resize( numberOfCharacters );
- mLogicalToVisualMap.Resize( numberOfCharacters );
+ mVisualToLogicalMap.Resize( numberOfCharacters );
+ mLogicalToVisualMap.Resize( numberOfCharacters );
- const Length numberOfCharactersPlus = numberOfCharacters + 1u;
- mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus );
+ const Length numberOfCharactersPlus = numberOfCharacters + 1u;
+ mVisualToLogicalCursorMap.Resize( numberOfCharactersPlus );
- CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin();
- CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin();
+ CharacterIndex* modelVisualToLogicalMapBuffer = mVisualToLogicalMap.Begin();
+ CharacterIndex* modelLogicalToVisualMapBuffer = mLogicalToVisualMap.Begin();
- CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin();
+ CharacterIndex* modelVisualToLogicalCursorMap = mVisualToLogicalCursorMap.Begin();
- CharacterIndex lastIndex = 0u;
- for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex )
- {
- const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex );
+ CharacterIndex lastIndex = startIndex;
+ for( unsigned int bidiIndex = 0u; bidiIndex < numberOfRuns; ++bidiIndex )
+ {
+ const BidirectionalLineInfoRun& bidiLineInfo = *( bidirectionalInfo + bidiIndex );
- if( lastIndex < bidiLineInfo.characterRun.characterIndex )
- {
- // Fill with the identity.
- for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex )
- {
- *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex;
- }
- }
+ if( bidiLineInfo.characterRun.characterIndex + bidiLineInfo.characterRun.numberOfCharacters <= startIndex )
+ {
+ // Skip this paragraph. It has been already processed.
+ continue;
+ }
- // Fill the conversion table of the run.
- for( CharacterIndex index = 0u;
- index < bidiLineInfo.characterRun.numberOfCharacters;
- ++index, ++lastIndex )
+ if( lastIndex < bidiLineInfo.characterRun.characterIndex )
+ {
+ // Fill with the identity.
+ for( ; lastIndex < bidiLineInfo.characterRun.characterIndex; ++lastIndex )
{
- *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index );
+ *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex;
}
}
- // Complete with the identity if there are some left to right characters after the last right to left.
- for( ; lastIndex < numberOfCharacters; ++lastIndex )
+ // Fill the conversion table of the run.
+ for( CharacterIndex index = 0u;
+ index < bidiLineInfo.characterRun.numberOfCharacters;
+ ++index, ++lastIndex )
{
- *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex;
+ *( modelVisualToLogicalMapBuffer + lastIndex ) = bidiLineInfo.characterRun.characterIndex + *( bidiLineInfo.visualToLogicalMap + index );
}
+ }
- // Sets the logical to visual conversion map.
- for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
- {
- *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index;
- }
+ // Complete with the identity if there are some left to right characters after the last right to left.
+ for( ; lastIndex < numberOfCharacters; ++lastIndex )
+ {
+ *( modelVisualToLogicalMapBuffer + lastIndex ) = lastIndex;
+ }
+
+ // Sets the logical to visual conversion map.
+ for( CharacterIndex index = startIndex; index < numberOfCharacters; ++index )
+ {
+ *( modelLogicalToVisualMapBuffer + *( modelVisualToLogicalMapBuffer + index ) ) = index;
+ }
- // Sets the visual to logical conversion map for cursor positions.
+ // Sets the visual to logical conversion map for cursor positions.
- const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count();
- BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin();
- BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer;
+ const Length numberOfBidirectionalParagraphs = mBidirectionalParagraphInfo.Count();
+ BidirectionalParagraphInfoRun* bidirectionalParagraphInfoBuffer = mBidirectionalParagraphInfo.Begin();
+ BidirectionalParagraphInfoRun* bidirectionalParagraph = bidirectionalParagraphInfoBuffer;
- const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin();
+ const CharacterDirection* const modelCharacterDirections = mCharacterDirections.Begin();
+
+ Length bidirectionalParagraphIndex = 0u;
+ bool isRightToLeftParagraph = false;
+ for( CharacterIndex index = startIndex; index < numberOfCharactersPlus; ++index )
+ {
+ if( bidirectionalParagraph &&
+ ( bidirectionalParagraph->characterRun.characterIndex == index ) )
+ {
+ isRightToLeftParagraph = *( modelCharacterDirections + index );
+ }
- Length bidirectionalParagraphIndex = 0u;
- bool isRightToLeftParagraph = false;
- for( CharacterIndex index = 0u; index < numberOfCharactersPlus; ++index )
+ if( 0u == index )
{
- if( bidirectionalParagraph &&
- ( bidirectionalParagraph->characterRun.characterIndex == index ) )
+ if( isRightToLeftParagraph )
{
- isRightToLeftParagraph = *( modelCharacterDirections + index );
+ *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
}
-
- if( 0u == index )
+ else // else logical position is zero.
{
- if( isRightToLeftParagraph )
- {
- *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
- }
- else // else logical position is zero.
- {
- *( modelVisualToLogicalCursorMap + index ) = 0u;
- }
+ *( modelVisualToLogicalCursorMap + index ) = 0u;
}
- else if( numberOfCharacters == index )
+ }
+ else if( numberOfCharacters == index )
+ {
+ if( isRightToLeftParagraph )
{
- if( isRightToLeftParagraph )
+ *( modelVisualToLogicalCursorMap + index ) = 0u;
+ }
+ else // else logical position is the number of characters.
+ {
+ *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
+ }
+ }
+ else
+ {
+ // Get the character indexed by index - 1 and index
+ // and calculate the logical position according the directions of
+ // both characters and the direction of the paragraph.
+
+ const CharacterIndex previousIndex = index - 1u;
+ const CharacterIndex logicalPosition0 = *( modelVisualToLogicalMapBuffer + previousIndex );
+ const CharacterIndex logicalPosition1 = *( modelVisualToLogicalMapBuffer + index );
+
+ const CharacterDirection direction0 = *( modelCharacterDirections + logicalPosition0 );
+ const CharacterDirection direction1 = *( modelCharacterDirections + logicalPosition1 );
+
+ if( direction0 == direction1 )
+ {
+ // Both glyphs have the same direction.
+ if( direction0 )
{
- *( modelVisualToLogicalCursorMap + index ) = 0u;
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
}
- else // else logical position is the number of characters.
+ else
{
- *( modelVisualToLogicalCursorMap + index ) = numberOfCharacters;
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
}
}
else
{
- // Get the character indexed by index - 1 and index
- // and calculate the logical position according the directions of
- // both characters and the direction of the paragraph.
-
- const CharacterIndex previousIndex = index - 1u;
- const CharacterIndex logicalPosition0 = *( modelVisualToLogicalMapBuffer + previousIndex );
- const CharacterIndex logicalPosition1 = *( modelVisualToLogicalMapBuffer + index );
-
- const CharacterDirection direction0 = *( modelCharacterDirections + logicalPosition0 );
- const CharacterDirection direction1 = *( modelCharacterDirections + logicalPosition1 );
-
- if( direction0 == direction1 )
+ if( isRightToLeftParagraph )
{
- // Both glyphs have the same direction.
- if( direction0 )
+ if( direction1 )
{
- *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u;
}
else
{
- *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
}
}
else
{
- if( isRightToLeftParagraph )
+ if( direction0 )
{
- if( direction1 )
- {
- *( modelVisualToLogicalCursorMap + index ) = logicalPosition1 + 1u;
- }
- else
- {
- *( modelVisualToLogicalCursorMap + index ) = logicalPosition0;
- }
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
}
else
{
- if( direction0 )
- {
- *( modelVisualToLogicalCursorMap + index ) = logicalPosition1;
- }
- else
- {
- *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u;
- }
+ *( modelVisualToLogicalCursorMap + index ) = logicalPosition0 + 1u;
}
}
}
+ }
- if( bidirectionalParagraph &&
- ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) )
+ if( bidirectionalParagraph &&
+ ( bidirectionalParagraph->characterRun.characterIndex + bidirectionalParagraph->characterRun.numberOfCharacters == index ) )
+ {
+ isRightToLeftParagraph = false;
+ ++bidirectionalParagraphIndex;
+ if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs )
{
- isRightToLeftParagraph = false;
- ++bidirectionalParagraphIndex;
- if( bidirectionalParagraphIndex < numberOfBidirectionalParagraphs )
- {
- bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex;
- }
- else
- {
- bidirectionalParagraph = NULL;
- }
+ bidirectionalParagraph = bidirectionalParagraphInfoBuffer + bidirectionalParagraphIndex;
+ }
+ else
+ {
+ bidirectionalParagraph = NULL;
}
}
}