diff -r 000000000000 -r 8466d47a6819 emailuis/uicomponents/src/fstextviewerlayouter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailuis/uicomponents/src/fstextviewerlayouter.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,1038 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Visual aligning class +* +*/ + + +// removed __FS_ALFRED_SUPPORT flag +//#include +// removed __FS_ALFRED_SUPPORT flag +#include "emailtrace.h" +#include +#include +// SF +#include +#include +#include +// +#include +#include +#include +// +#include +// + +#include "fstextviewervisualizer.h" + +#include "fstextviewerlayouter.h" +#include "fsrichtextobject.h" +#include "fstextstylemanager.h" +#include "fsrichtext.h" +#include "fsrichtexttext.h" +#include "fsrichtextsmiley.h" +#include "fsrichtextpicture.h" +#include "fstextviewercoordinator.h" +#include "fstextviewervisualizerdata.h" +#include "fstextparser.h" + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +CFsTextViewerLayouter* CFsTextViewerLayouter::NewL( CAlfEnv* aEnv ) + { + FUNC_LOG; + CFsTextViewerLayouter* self = + new (ELeave) CFsTextViewerLayouter( aEnv ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// ~CFsTextViewerLayouter +// --------------------------------------------------------------------------- +CFsTextViewerLayouter::~CFsTextViewerLayouter() + { + FUNC_LOG; + iCurrentLineArray.Close(); + } + +// --------------------------------------------------------------------------- +// MeasureBidiTextBoundsWidth +// --------------------------------------------------------------------------- +TInt CFsTextViewerLayouter::MeasureBidiTextBoundsWidth( + const CFont& aFont, + const TDesC& aText, + CFont::TMeasureTextInput::TFlags aOrder) + { + FUNC_LOG; +// return AknBidiTextUtils::MeasureTextBoundsWidth( aFont, aText, aOrder); + CFont::TMeasureTextInput input; + input.iFlags = aOrder; + CFont::TMeasureTextOutput output; + + TInt textAdvance = aFont.MeasureText( aText, &input, &output ); + + TRect bounds = output.iBounds; + bounds.iTl.iX = Min(bounds.iTl.iX, 0); + bounds.iBr.iX = Max(bounds.iBr.iX, textAdvance); + return bounds.Width(); + } + + +// --------------------------------------------------------------------------- +// CalculateSizeL +// --------------------------------------------------------------------------- +TSize CFsTextViewerLayouter::CalculateSizeL( MFsRichTextObject* aObject ) + { + FUNC_LOG; + TSize retVal; + + switch ( aObject->GetType() ) + { + case MFsRichTextObject::EFsText: + { + if ( static_cast(aObject)->GetHotSpot() && static_cast(aObject)->GetText().Length() > 1 ) + { + CAlfTextVisual* tmp = CAlfTextVisual::AddNewL( *iControl, iVisualizer->BackgroundLayout() ); + tmp->SetTextL( static_cast(aObject)->GetText() ); + tmp->SetTextStyle( static_cast(aObject)->GetStyleId() ); + tmp->SetAlign( EAlfAlignHLeft, EAlfAlignVTop ); + tmp->SetPadding( 0 ); +// retVal = tmp->SubstringExtents( 0, static_cast(aObject)->GetText().Length() - 1 ).Size(); + retVal = tmp->TextExtents(); + // Platform layout change + //retVal.iWidth -= 4; + // Platform layout change + tmp->RemoveAndDestroyAllD(); + break; + } + + CFont* font; + User::LeaveIfNull( iScreenDev ); + + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( + static_cast(aObject)->GetStyleId() ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + if ( textStyle->IsBold() ) + { + fontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightBold ); + } + if ( textStyle->IsItalic() ) + { + fontSpec.iFontStyle.SetPosture( EPostureItalic ); + } + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( + font, fontSpec ) ); + +// TAknFontSpecification aknFs(EAknFontCategoryPrimary, fontSpec, iScreenDev); +// aknFs.SetTextPaneHeight( iScreenDev->VerticalTwipsToPixels(fontSpec.iHeight)); +// aknFs.SetTextPaneHeightIsDesignHeight( ETrue ); +// font = +// AknFontAccess::CreateLayoutFontFromSpecificationL( +// *iScreenDev, +// fontSpec.iTypeface, +// aknFs ); + + +// retVal = TSize( +// font->TextWidthInPixels( +// static_cast(aObject)->GetText() ), +// font->FontMaxHeight() ); + + CleanupStack::PopAndDestroy( typeface ); + TSize retVal1( MeasureBidiTextBoundsWidth( *font, static_cast(aObject)->GetText(), CFont::TMeasureTextInput::EFVisualOrder), font->FontMaxHeight() ); + + retVal = retVal1; + + const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( font ); + if ( layoutFont ) + { + retVal.iHeight = font->HeightInPixels(); + TInt textPaneHeight = layoutFont->TextPaneHeight(); + TInt textPaneTopToBaseline = layoutFont->TextPaneTopToBaseline(); + + retVal.iHeight += textPaneHeight - textPaneTopToBaseline; + retVal.iHeight += 1; + } + else + { + retVal.iHeight = Max(retVal.iHeight, font->HeightInPixels()); + retVal.iHeight += 5; // the best approximation - fails on big (>=72) fonts + } + iScreenDev->ReleaseFont( font ); +// if ( static_cast(aObject)->GetHotSpot() && static_cast(aObject)->GetText().Length() > 1 ) +// { +// retVal.iWidth += 3; +// } + break; + } + case MFsRichTextObject::EFsTexture: + { + retVal = static_cast + (aObject)->GetTextureSize(); + retVal.iWidth += 3; + break; + } + case MFsRichTextObject::EFsSmiley: + { + if ( iSmileyEnabled ) + { + retVal = static_cast + (aObject)->GetPictureObject()->GetTextureSize(); + } + else + { + CFont* font; + CFsRichTextText* object = + static_cast + (aObject)->GetTextObject(); + User::LeaveIfNull(iScreenDev); + + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( + object->GetStyleId() ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( font, fontSpec ) ); + + retVal = TSize( + font->TextWidthInPixels( object->GetText() ), + font->FontMaxHeight() ); + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + break; + } + } + default: + { + break; + } + } + return retVal; + } + +// --------------------------------------------------------------------------- +// FindMaxLengthL +// --------------------------------------------------------------------------- +TInt CFsTextViewerLayouter::FindMaxLengthL( MFsRichTextObject* aObject ) + { + FUNC_LOG; + TInt retVal = 0; + if ( aObject->GetType() == MFsRichTextObject::EFsText ) + { + CFont* font; + User::LeaveIfNull( iScreenDev ); + + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( + static_cast( aObject )->GetStyleId() ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( + font, fontSpec ) ); + + retVal = font->TextCount( static_cast(aObject)->GetText(), iDisplaySize.iWidth ) - 1; + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + } + return retVal; + } + +// --------------------------------------------------------------------------- +// PrepareRangedVisL +// --------------------------------------------------------------------------- +TFsRangedVisual* CFsTextViewerLayouter::PrepareRangedVisL( + MFsRichTextObject* aObject, + CAlfLayout* aLayout ) + { + FUNC_LOG; + TFsRangedVisual* retVal = new (ELeave) TFsRangedVisual; + retVal->iVisual = NULL; + retVal->iHotspot = EFalse; + retVal->iEmbed = EFalse; + + switch ( aObject->GetType() ) + { + case MFsRichTextObject::EFsText: + { + retVal->iStart = aObject->GetBeginOfObject(); + retVal->iEnd = aObject->GetEndOfObject(); + retVal->iIsActive = ETrue; + retVal->iLayout = aLayout; + retVal->iIsText = ETrue; + retVal->iTextColor = + static_cast(aObject)->GetTextColor(); + retVal->iTextStyleId = static_cast(aObject)->GetStyleId(); + retVal->iDirection = + static_cast(aObject)->GetTextDirection(); + retVal->iSmiley = EFalse; + break; + } + case MFsRichTextObject::EFsTexture: + { + retVal->iStart = aObject->GetBeginOfObject(); + retVal->iEnd = aObject->GetEndOfObject(); + retVal->iIsActive = ETrue; + retVal->iLayout = aLayout; + retVal->iIsText = EFalse; + retVal->iSmiley = EFalse; + break; + } + case MFsRichTextObject::EFsSmiley: + { + if ( iSmileyEnabled ) + { + retVal->iStart = aObject->GetBeginOfObject(); + retVal->iEnd = aObject->GetEndOfObject(); + retVal->iIsActive = ETrue; + retVal->iLayout = aLayout; + retVal->iIsText = EFalse; + retVal->iTextColor = + static_cast(aObject)->GetTextObject()->GetTextColor(); + retVal->iTextStyleId = + static_cast(aObject)->GetTextObject()->GetStyleId(); + } + else + { + retVal->iStart = aObject->GetBeginOfObject(); + retVal->iEnd = aObject->GetEndOfObject(); + retVal->iIsActive = ETrue; + retVal->iLayout = aLayout; + retVal->iIsText = ETrue; + retVal->iTextColor = + static_cast(aObject)->GetTextObject()->GetTextColor(); + retVal->iTextStyleId = + static_cast(aObject)->GetTextObject()->GetStyleId(); + } + retVal->iSmiley = ETrue; + break; + } + case MFsRichTextObject::EFsNewLine: + { + break; + } + default: + { + break; + } + } + + if ( retVal->iIsActive ) + { + if ( aObject->GetEmbeded() ) + { + retVal->iId = aObject->GetIdOfEmbeded(); + retVal->iEmbed = ETrue; + } + if ( aObject->GetHotSpot() ) + { + retVal->iHotspotType = aObject->GetTypeOfHotSpot(); + retVal->iId = aObject->GetIdOfHotSpot(); + retVal->iHotspot = ETrue; + } + } + + return retVal; + } + +// --------------------------------------------------------------------------- +// SetDisplaySize +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetDisplaySize( TSize aDisplaySize ) + { + FUNC_LOG; + iDisplaySize = aDisplaySize; + } + +// --------------------------------------------------------------------------- +// AppendObjectL +// --------------------------------------------------------------------------- +TBool CFsTextViewerLayouter::AppendObjectL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TBool aRegisterSelects ) + { + FUNC_LOG; + TRect objectRect; + TRect naturalRect; + TSize objectSize = CalculateSizeL( aObject ); + + if ( objectSize.iWidth > iDisplaySize.iWidth ) + { + if ( iLowestPicPosition > iCurrentLineOffset ) + { + iCurrentLineOffset = iLowestPicPosition; + ConstructLineL(); + } + if ( aObject->GetType() != MFsRichTextObject::EFsText ) + { + // Resizing object to fit display width + const TInt KScalingFactor = 65536; + const TInt KTwo = 2; + + TInt resizeFactor = KScalingFactor * iDisplaySize.iWidth / + objectSize.iWidth; + TInt height = objectSize.iHeight; + + objectSize.iWidth = iDisplaySize.iWidth; + + height = height * resizeFactor + KScalingFactor / KTwo; + objectSize.iHeight = height / KScalingFactor; + } + else + { + aParser->CutWord( + aObject->GetBeginOfObject(), + FindMaxLengthL( aObject ) ); + return EFalse; + } + } + + TFsRangedVisual* currentVisual; + currentVisual = PrepareRangedVisL( aObject, aLayout ); + if ( !aRegisterSelects ) + { + currentVisual->iEmbed = EFalse; + } + + if ( iMainDirection == TBidiText::ELeftToRight ) + { + objectRect = TRect( TPoint( iLastCol, iCurrentLineOffset ), objectSize ); + } + else + { + objectRect = TRect( TPoint( iLastCol - objectSize.iWidth, iCurrentLineOffset ), objectSize ); + } + iNewLine = EFalse; + naturalRect = objectRect; + if ( iHelper->NextFreeCol( objectRect, iMainDirection ) ) + { + ConstructLineL(); + delete currentVisual; + currentVisual = NULL; + AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); + } + else + { + if ( objectRect != naturalRect ) + { + currentVisual->iMoved = ETrue; + } + else + { + currentVisual->iMoved = EFalse; + } + + if ( iMainDirection == TBidiText::ELeftToRight ) + { + currentVisual->iRect = objectRect; + iLastCol = objectRect.iBr.iX; + iCurrentLineArray.Append( currentVisual ); + } + else + { + currentVisual->iRect = objectRect; + iLastCol = objectRect.iTl.iX; + iCurrentLineArray.Append( currentVisual ); + } + } + if ( objectRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) + { + iLineHeight = objectRect.Height(); + } + else if ( aObject->GetType() == MFsRichTextObject::EFsTexture || aObject->GetHotSpot() ) + { + iHelper->RegisterObstacleL( objectRect ); + if ( objectRect.iBr.iY > iLowestPicPosition ) + { + iLowestPicPosition = objectRect.iBr.iY; + } + } +// if ( text ) +// { +// delete text; +// } + return ETrue; + } + +// --------------------------------------------------------------------------- +// InsertObjectL +// --------------------------------------------------------------------------- +TBool CFsTextViewerLayouter::InsertObjectL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TBool aRegisterSelects ) + { + FUNC_LOG; + return AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); + // following lines are commented out to avoid warnings + /* + TBool retVal = EFalse; + + TSize objectSize = CalculateSizeL( aObject ); + if ( objectSize.iWidth > iDisplaySize.iWidth ) + { + aParser->CutWord( + aObject->GetBeginOfObject(), + FindMaxLengthL( aObject ) ); + return EFalse; + } + + if ( ( objectSize.iWidth > iDisplaySize.iWidth - iLastCol && iMainDirection == TBidiText::ELeftToRight ) + || ( objectSize.iWidth > iLastCol && iMainDirection == TBidiText::ERightToLeft ) ) + { + ConstructLineL(); + retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); + } + else //if ( 0 == iCurrentLineArray.Count() ) + { + retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); + }*/ + // +// else +// { +// if ( iMainDirection == TBidiText::ELeftToRight ) +// { +//// retVal = ReorderLineFromLeftL( aObject, aLayout, aParser, objectSize, aRegisterSelects ); +// } +// else +// { +//// retVal = ReorderLineFromRightL( aObject, aLayout, aParser, objectSize, aRegisterSelects ); +// } +// } + // following lines are commented out to avoid warnings + //return retVal; + // + } + +// --------------------------------------------------------------------------- +// ConstructLineL +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::ConstructLineL( TInt aHeight ) + { + FUNC_LOG; + TInt i = 0; + TInt dY; + RPointerArray finalLine; + + if ( 0 == iLineHeight ) + { + iLineHeight = aHeight; + } + + for ( i = 0; i < iCurrentLineArray.Count(); ++i ) + { + iCurrentLineArray[i]->iLineNumber = iLines; + if ( iCurrentLineArray[i]->iIsText ) + { + dY = iLineHeight - iCurrentLineArray[i]->iRect.Height(); + iCurrentLineArray[i]->iRect.iTl.iY += dY; + iCurrentLineArray[i]->iRect.iBr.iY += dY; + } + if ( i > 0 + && iCurrentLineArray[i]->iIsText + && finalLine[finalLine.Count() - 1]->iIsText +// && iCurrentLineArray[i]->iDirection == finalLine[finalLine.Count() - 1]->iDirection +// && iCurrentLineArray[i]->iDirection == iMainDirection + && iCurrentLineArray[i]->iTextStyleId == finalLine[finalLine.Count() - 1]->iTextStyleId + && iCurrentLineArray[i]->iTextColor == finalLine[finalLine.Count() - 1]->iTextColor + && ( !iCurrentLineArray[i]->iHotspot + || + iCurrentLineArray[i]->iId == finalLine[finalLine.Count() - 1]->iId + ) +// && !finalLine[finalLine.Count() - 1]->iHotspot + && !iCurrentLineArray[i]->iMoved +// && !iCurrentLineArray[i]->iEmbed +// && !finalLine[finalLine.Count() - 1]->iEmbed + ) + + { + JoinRangedVisuals( finalLine[finalLine.Count() - 1], iCurrentLineArray[i] ); + delete iCurrentLineArray[i]; + iCurrentLineArray[i] = NULL; + } + else + { + finalLine.Append( iCurrentLineArray[i] ); + } + } + + for ( i = 0; i < finalLine.Count(); ++i ) + { + iNavigator->AppendVisualL( finalLine[i] ); + } + finalLine.Close(); + + if ( iMainDirection == TBidiText::ELeftToRight ) + { + iLastCol = iLeftMargin; + } + else + { + iLastCol = iDisplaySize.iWidth + iLeftMargin; + } + + iNewLine = ETrue; + + iCurrentLineArray.Reset(); + iCurrentLineOffset += iLineHeight; + iLineHeight = 0; + ++iLines; + } + +// --------------------------------------------------------------------------- +// JoinRangedVisuals +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::JoinRangedVisuals( TFsRangedVisual* aFirst, TFsRangedVisual* aSecond ) + { + FUNC_LOG; +/* if ( aFirst->iRect.iTl.iX > aSecond->iRect.iTl.iX ) + { + aFirst->iRect.iTl.iX = aSecond->iRect.iTl.iX; + } + else + { + aFirst->iRect.iBr.iX = aSecond->iRect.iBr.iX; + } + */ + TInt a = aFirst->iRect.iTl.iX; + TInt b = aFirst->iRect.iBr.iX; + TInt c = aSecond->iRect.iTl.iX; + TInt d = aSecond->iRect.iBr.iX; + + TInt max = Max( Max(a, b), Max(d, c) ); + TInt min = Min( Min(a, b), Min(d, c) ); + aFirst->iRect.iTl.iX = min; + aFirst->iRect.iBr.iX = max; + aFirst->iStart = Min( aFirst->iStart, aSecond->iStart ); + aFirst->iEnd = Max( aFirst->iEnd, aSecond->iEnd ); + } + +// --------------------------------------------------------------------------- +// GetCurrentLineOffset +// --------------------------------------------------------------------------- +TInt CFsTextViewerLayouter::GetCurrentLineOffset() + { + FUNC_LOG; + return iCurrentLineOffset; + } + +// --------------------------------------------------------------------------- +// SetMargins +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetCurrentLineOffset( TInt aOffset ) + { + FUNC_LOG; + iCurrentLineOffset = aOffset; + } + +// --------------------------------------------------------------------------- +// SetMargins +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetMargins( const TInt aLeft, const TInt aRight ) + { + FUNC_LOG; + iLeftMargin = aLeft; + iRightMargin = aRight; + if ( iMainDirection == TBidiText::ELeftToRight ) + { + iLastCol = iLeftMargin; + } + else + { + iLastCol = iDisplaySize.iWidth + iLeftMargin; + } + } + +// --------------------------------------------------------------------------- +// SetHelper +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetHelper( CFsTextViewerCoordinator* aHelper ) + { + FUNC_LOG; + iHelper = aHelper; + } + +// --------------------------------------------------------------------------- +// SetNavigator +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetNavigator( CFsTextViewerVisualizerData* aNavigator ) + { + FUNC_LOG; + iNavigator = aNavigator; + } + +// --------------------------------------------------------------------------- +// Lines +// --------------------------------------------------------------------------- +TInt CFsTextViewerLayouter::Lines() + { + FUNC_LOG; + return iLines; + } + +// --------------------------------------------------------------------------- +// EnableSmileys +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::EnableSmileys( TBool aEnable ) + { + FUNC_LOG; + iSmileyEnabled = aEnable; + } + +// --------------------------------------------------------------------------- +// SetPosition +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetPosition( TInt aLine, TInt aLineOffset ) + { + FUNC_LOG; + iLines = aLine; + iCurrentLineOffset = aLineOffset; + } + +// --------------------------------------------------------------------------- +// ChangeDirection +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::ChangeDirection( TBidiText::TDirectionality aDirection ) + { + FUNC_LOG; + iMainDirection = aDirection; + if ( iMainDirection == TBidiText::ELeftToRight && iCurrentLineArray.Count() < 1 ) + { + iLastCol = iLeftMargin; + } + else if ( iMainDirection == TBidiText::ERightToLeft && iCurrentLineArray.Count() < 1 ) + { + iLastCol = iDisplaySize.iWidth + iLeftMargin; + } + } + +// --------------------------------------------------------------------------- +// SetDirection +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::SetDirection( TBidiText::TDirectionality aDirection ) + { + FUNC_LOG; + iMainDirection = aDirection; + if ( iMainDirection == TBidiText::ELeftToRight ) + { + iLastCol = iLeftMargin; + } + else + { + iLastCol = iDisplaySize.iWidth + iLeftMargin; + } + } + +// --------------------------------------------------------------------------- +// GetDirection +// --------------------------------------------------------------------------- +TBidiText::TDirectionality CFsTextViewerLayouter::GetDirection() + { + FUNC_LOG; + return iMainDirection; + } + +// --------------------------------------------------------------------------- +// IsNewLine +// --------------------------------------------------------------------------- +TBool CFsTextViewerLayouter::IsNewLine() + { + FUNC_LOG; + if ( iCurrentLineArray.Count() < 1 ) + { + return ETrue; + } + return EFalse; + } + +// --------------------------------------------------------------------------- +// ConstructL +// --------------------------------------------------------------------------- +void CFsTextViewerLayouter::ConstructL() + { + FUNC_LOG; + + } + +// --------------------------------------------------------------------------- +// CFsTextViewerLayouter +// --------------------------------------------------------------------------- +CFsTextViewerLayouter::CFsTextViewerLayouter( CAlfEnv* aEnv ) + { + FUNC_LOG; + iScreenDev = CCoeEnv::Static()->ScreenDevice(); + iEnv = aEnv; + iLines = 0; + iLowestPicPosition = 0; + iMainDirection = TBidiText::ELeftToRight; + } + +// --------------------------------------------------------------------------- +// ReorderLineFromLeftL +// --------------------------------------------------------------------------- +TBool CFsTextViewerLayouter::ReorderLineFromLeftL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TSize aObjectSize, TBool aRegisterSelects ) + { + FUNC_LOG; +// TBool retVal = EFalse; +// TInt i = iCurrentLineArray.Count() - 1; +// TInt dX = aObjectSize.iWidth; +// TInt moveFrom = 0; +// TRect translatedObject; +// TRect origRect; +// while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) +// { +// translatedObject = iCurrentLineArray[i]->iRect; +//// if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) +//// { +// iHelper->RemoveRect( iCurrentLineArray[i]->iRect ); +// translatedObject.iTl.iX += dX; +// translatedObject.iBr.iX += dX; +// origRect = translatedObject; +// if ( iHelper->NextFreeCol( translatedObject, iMainDirection ) ) +// { +// i = -100; +// } +// if ( origRect != translatedObject ) +// { +// iCurrentLineArray[i]->iMoved = ETrue; +// } +//// } +// moveFrom = i; +// --i; +// } +// if ( -101 == i ) +// { +// ConstructLineL(); +// retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); +// } +// else +// { +// TFsRangedVisual* currentVisual; +// currentVisual = PrepareRangedVisL( aObject, aLayout ); +// if ( !aRegisterSelects ) +// { +// currentVisual->iEmbed = EFalse; +// } +// currentVisual->iRect = TRect( iCurrentLineArray[moveFrom]->iRect.iTl, aObjectSize ); +// iCurrentLineArray.Insert( currentVisual, moveFrom ); +// for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i ) +// { +// if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) +// { +// iCurrentLineArray[i]->iRect.iTl.iX += dX; +// iCurrentLineArray[i]->iRect.iBr.iX += dX; +// } +// } +// if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) +// { +// iLineHeight = currentVisual->iRect.Height(); +// } +// } +// return retVal; + TBool retVal = EFalse; + TInt dX = aObjectSize.iWidth; + TInt moveFrom = 0; + TRect translatedObject; + TFsRangedVisual* visual = NULL; + TInt maxCol = 0; + // TInt tmp = 0; + + TInt i = iCurrentLineArray.Count() - 1; + while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) + { + if ( !iCurrentLineArray[i]->iIsText ) + { + iHelper->RemoveRect( iCurrentLineArray[i]->iRect ); + } + --i; + } + i = iCurrentLineArray.Count() - 1; + while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) + { + translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); + visual = iCurrentLineArray[i]; + translatedObject.iTl.iX += dX; + translatedObject.iBr.iX += dX; + // tmp = translatedObject.iTl.iX; + moveFrom = i; + if ( iHelper->NextFreeCol( translatedObject, TBidiText::ELeftToRight ) ) + { + i = -100; + } + --i; + } + if ( -101 == i ) + { + i = iCurrentLineArray.Count() - 1; + while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) + { + if ( !iCurrentLineArray[i]->iIsText ) + { + translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); + translatedObject.iTl.iX += dX; + translatedObject.iBr.iX += dX; + iHelper->RegisterObstacleL( iCurrentLineArray[i]->iRect ); + } + --i; + } + ConstructLineL(); + retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); + } + else + { + TFsRangedVisual* currentVisual; + currentVisual = PrepareRangedVisL( aObject, aLayout ); + currentVisual->iMoved = EFalse; + if ( !aRegisterSelects ) + { + currentVisual->iEmbed = EFalse; + } + + currentVisual->iRect = TRect( TPoint( iCurrentLineArray[moveFrom]->iRect.iTl.iX, iCurrentLineArray[moveFrom]->iRect.iTl.iY ), aObjectSize ); + iCurrentLineArray.Insert( currentVisual, moveFrom ); + + if ( aObject->GetType() == MFsRichTextObject::EFsTexture ) + { + iHelper->RegisterObstacleL( currentVisual->iRect ); + } + if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) + { + iLineHeight = currentVisual->iRect.Height(); + } + + for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i ) + { +// if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) +// { + visual = iCurrentLineArray[i]; + iCurrentLineArray[i]->iRect.iTl.iX += dX; + iCurrentLineArray[i]->iRect.iBr.iX += dX; + iHelper->NextFreeCol( iCurrentLineArray[i]->iRect, TBidiText::ELeftToRight ); + if ( !(visual->iIsText) ) + { + iHelper->RegisterObstacleL( visual->iRect ); + } + if ( visual->iRect.iBr.iX > maxCol ) + { + maxCol = visual->iRect.iBr.iX; + } + } + } + iLastCol = maxCol; + return retVal; + } + +// --------------------------------------------------------------------------- +// ReorderLineFromRightL +// --------------------------------------------------------------------------- +TBool CFsTextViewerLayouter::ReorderLineFromRightL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TSize aObjectSize, TBool aRegisterSelects ) + { + FUNC_LOG; + TBool retVal = EFalse; + TInt dX = aObjectSize.iWidth; + TInt moveFrom = 0; + TRect translatedObject; + TFsRangedVisual* visual = NULL; + + TInt i = iCurrentLineArray.Count() - 1; + while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) + { + if ( !iCurrentLineArray[i]->iIsText ) + { + iHelper->RemoveRect( iCurrentLineArray[i]->iRect ); + } + --i; + } + i = iCurrentLineArray.Count() - 1; + while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) + { + translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); + visual = iCurrentLineArray[i]; + translatedObject.iTl.iX -= dX; + translatedObject.iBr.iX -= dX; + moveFrom = i; + if ( iHelper->NextFreeCol( translatedObject, TBidiText::ERightToLeft ) ) + { + i = -100; + } + --i; + } + if ( -101 == i ) + { + i = iCurrentLineArray.Count() - 1; + while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) + { + if ( !iCurrentLineArray[i]->iIsText ) + { + translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); + translatedObject.iTl.iX -= dX; + translatedObject.iBr.iX -= dX; + iHelper->RegisterObstacleL( iCurrentLineArray[i]->iRect ); + } + --i; + } + ConstructLineL(); + retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); + } + else + { + TFsRangedVisual* currentVisual; + currentVisual = PrepareRangedVisL( aObject, aLayout ); + currentVisual->iMoved = EFalse; + if ( !aRegisterSelects ) + { + currentVisual->iEmbed = EFalse; + } + + currentVisual->iRect = TRect( TPoint( iCurrentLineArray[moveFrom]->iRect.iBr.iX - dX, iCurrentLineArray[moveFrom]->iRect.iTl.iY ), aObjectSize ); + iCurrentLineArray.Insert( currentVisual, moveFrom ); + + if ( aObject->GetType() == MFsRichTextObject::EFsTexture ) + { + iHelper->RegisterObstacleL( currentVisual->iRect ); + } + if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) + { + iLineHeight = currentVisual->iRect.Height(); + } + + for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i ) + { +// if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) +// { + visual = iCurrentLineArray[i]; + iCurrentLineArray[i]->iRect.iTl.iX -= dX; + iCurrentLineArray[i]->iRect.iBr.iX -= dX; + iHelper->NextFreeCol( iCurrentLineArray[i]->iRect, TBidiText::ERightToLeft ); + if ( !(visual->iIsText) ) + { + iHelper->RegisterObstacleL( visual->iRect ); + } + } + } + return retVal; + } +