const Length numberOfCharacters = utf32Characters.Count();
Vector<LineBreakInfo>& lineBreakInfo = mLogicalModel->mLineBreakInfo;
+ CharacterIndex startIndex = 0u;
+ Length requestedNumberOfCharacters = numberOfCharacters;
if( GET_LINE_BREAKS & operations )
{
// Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
lineBreakInfo.Resize( numberOfCharacters, TextAbstraction::LINE_NO_BREAK );
SetLineBreakInfo( utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
lineBreakInfo );
+
+ // Create the paragraph info.
+ mLogicalModel->CreateParagraphInfo( startIndex,
+ requestedNumberOfCharacters );
}
Vector<WordBreakInfo>& wordBreakInfo = mLogicalModel->mWordBreakInfo;
wordBreakInfo.Resize( numberOfCharacters, TextAbstraction::WORD_NO_BREAK );
SetWordBreakInfo( utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
wordBreakInfo );
}
{
// Retrieves the scripts used in the text.
multilanguageSupport.SetScripts( utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
scripts );
}
scripts,
fontDescriptionRuns,
defaultFontId,
+ startIndex,
+ requestedNumberOfCharacters,
validFonts );
}
}
SetBidirectionalInfo( utf32Characters,
scripts,
lineBreakInfo,
+ startIndex,
+ requestedNumberOfCharacters,
bidirectionalInfo );
if( 0u != bidirectionalInfo.Count() )
{
- // This paragraph has right to left text. Some characters may need to be mirrored.
- // TODO: consider if the mirrored string can be stored as well.
-
- textMirrored = GetMirroredText( utf32Characters,
- mirroredUtf32Characters,
- bidirectionalInfo );
-
// Only set the character directions if there is right to left characters.
Vector<CharacterDirection>& directions = mLogicalModel->mCharacterDirections;
- directions.Resize( numberOfCharacters );
-
GetCharactersDirection( bidirectionalInfo,
+ numberOfCharacters,
+ startIndex,
+ requestedNumberOfCharacters,
directions );
+
+ // This paragraph has right to left text. Some characters may need to be mirrored.
+ // TODO: consider if the mirrored string can be stored as well.
+
+ textMirrored = GetMirroredText( utf32Characters,
+ directions,
+ bidirectionalInfo,
+ startIndex,
+ requestedNumberOfCharacters,
+ mirroredUtf32Characters );
}
else
{
Vector<GlyphIndex> newParagraphGlyphs;
newParagraphGlyphs.Reserve( numberOfParagraphs );
+ GlyphIndex startGlyphIndex = 0u;
if( SHAPE_TEXT & operations )
{
const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
lineBreakInfo,
scripts,
validFonts,
+ startIndex,
+ startGlyphIndex,
+ requestedNumberOfCharacters,
glyphs,
glyphsToCharactersMap,
charactersPerGlyph,
newParagraphGlyphs );
// Create the 'number of glyphs' per character and the glyph to character conversion tables.
- mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters );
- mVisualModel->CreateCharacterToGlyphTable( numberOfCharacters );
+ mVisualModel->CreateGlyphsPerCharacterTable( startIndex, numberOfCharacters );
+ mVisualModel->CreateCharacterToGlyphTable( startIndex, numberOfCharacters );
}
const Length numberOfGlyphs = glyphs.Count();
if( GET_GLYPH_METRICS & operations )
{
- GlyphInfo* glyphsBuffer = glyphs.Begin();
+ GlyphInfo* glyphsBuffer = glyphs.Begin() + startGlyphIndex;
mMetrics->GetGlyphMetrics( glyphsBuffer, numberOfGlyphs );
// Update the width and advance of all new paragraph characters.
if( Gesture::Started == state ||
Gesture::Continuing == state )
{
- const Vector2& actualSize = mVisualModel->GetActualSize();
+ const Vector2& actualSize = mVisualModel->GetLayoutSize();
const Vector2 currentScroll = mEventData->mScrollPosition;
if( mEventData->mHorizontalScrollingEnabled )
else if( HANDLE_SCROLLING == state )
{
const float xSpeed = event.p2.mFloat;
- const Vector2& actualSize = mVisualModel->GetActualSize();
+ const Vector2& actualSize = mVisualModel->GetLayoutSize();
const Vector2 currentScrollPosition = mEventData->mScrollPosition;
mEventData->mScrollPosition.x += xSpeed;
cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + secondaryPosition.x + ( isCurrentRightToLeft ? 0.f : glyphMetrics.advance );
cursorInfo.secondaryPosition.y = cursorInfo.lineHeight - cursorInfo.secondaryCursorHeight - line.descender - ( glyphMetrics.fontHeight - glyphMetrics.ascender );
}
+
+ if( LayoutEngine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
+ {
+ // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.
+
+ // Note the white spaces laid-out at the end of the line might exceed the boundaries of the control.
+ // The reason is a wrapped line must not start with a white space so they are laid-out at the end of the line.
+
+ if( 0.f > cursorInfo.primaryPosition.x )
+ {
+ cursorInfo.primaryPosition.x = 0.f;
+ }
+
+ const float edgeWidth = mVisualModel->mControlSize.width - static_cast<float>( mEventData->mDecorator->GetCursorWidth() );
+ if( cursorInfo.primaryPosition.x > edgeWidth )
+ {
+ cursorInfo.primaryPosition.x = edgeWidth;
+ }
+ }
}
CharacterIndex Controller::Impl::CalculateNewCursorIndex( CharacterIndex index ) const
const float positionEnd = position.x + ( mEventData->mDecorator ? mEventData->mDecorator->GetCursorWidth() : 0.f );
// Transform the position to decorator coords.
- const float offset = mEventData->mScrollPosition.x + mAlignmentOffset.x;
+ const float alignment = IsShowingRealText() ? mAlignmentOffset.x : 0.f;
+ const float offset = mEventData->mScrollPosition.x + alignment;
const float decoratorPositionBegin = position.x + offset;
const float decoratorPositionEnd = positionEnd + offset;
if( decoratorPositionBegin < 0.f )
{
- mEventData->mScrollPosition.x = -position.x - mAlignmentOffset.x;
+ mEventData->mScrollPosition.x = -position.x - alignment;
}
else if( decoratorPositionEnd > mVisualModel->mControlSize.width )
{
- mEventData->mScrollPosition.x = mVisualModel->mControlSize.width - positionEnd - mAlignmentOffset.x;
+ mEventData->mScrollPosition.x = mVisualModel->mControlSize.width - positionEnd - alignment;
}
}
// Calculate the offset to match the cursor position before the character was deleted.
mEventData->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x - mAlignmentOffset.x;
- ClampHorizontalScroll( mVisualModel->GetActualSize() );
+ ClampHorizontalScroll( mVisualModel->GetLayoutSize() );
}
void Controller::Impl::RequestRelayout()