--- /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
+*
+*/
+
+
+//<cmail> removed __FS_ALFRED_SUPPORT flag
+//#include <fsconfig.h>
+//</cmail> removed __FS_ALFRED_SUPPORT flag
+#include "emailtrace.h"
+#include <gdi.h>
+#include <w32std.h>
+// <cmail> SF
+#include <alf/alfenv.h>
+#include <alf/alftextstyle.h>
+#include <alf/alftextstylemanager.h>
+// </cmail>
+#include <AknLayoutFont.h>
+#include <AknFontAccess.h>
+#include <AknBidiTextUtils.h>
+// <cmail>
+#include <alf/alftextvisual.h>
+// </cmail>
+
+#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<CFsRichTextText*>(aObject)->GetHotSpot() && static_cast<CFsRichTextText*>(aObject)->GetText().Length() > 1 )
+ {
+ CAlfTextVisual* tmp = CAlfTextVisual::AddNewL( *iControl, iVisualizer->BackgroundLayout() );
+ tmp->SetTextL( static_cast<CFsRichTextText*>(aObject)->GetText() );
+ tmp->SetTextStyle( static_cast<CFsRichTextText*>(aObject)->GetStyleId() );
+ tmp->SetAlign( EAlfAlignHLeft, EAlfAlignVTop );
+ tmp->SetPadding( 0 );
+// retVal = tmp->SubstringExtents( 0, static_cast<CFsRichTextText*>(aObject)->GetText().Length() - 1 ).Size();
+ retVal = tmp->TextExtents();
+ // <cmail> Platform layout change
+ //retVal.iWidth -= 4;
+ // </cmail> Platform layout change
+ tmp->RemoveAndDestroyAllD();
+ break;
+ }
+
+ CFont* font;
+ User::LeaveIfNull( iScreenDev );
+
+ CAlfTextStyle* textStyle(
+ iEnv->TextStyleManager().TextStyle(
+ static_cast<CFsRichTextText*>(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<CFsRichTextText*>(aObject)->GetText() ),
+// font->FontMaxHeight() );
+
+ CleanupStack::PopAndDestroy( typeface );
+ TSize retVal1( MeasureBidiTextBoundsWidth( *font, static_cast<CFsRichTextText*>(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<CFsRichTextText*>(aObject)->GetHotSpot() && static_cast<CFsRichTextText*>(aObject)->GetText().Length() > 1 )
+// {
+// retVal.iWidth += 3;
+// }
+ break;
+ }
+ case MFsRichTextObject::EFsTexture:
+ {
+ retVal = static_cast<CFsRichTextPicture*>
+ (aObject)->GetTextureSize();
+ retVal.iWidth += 3;
+ break;
+ }
+ case MFsRichTextObject::EFsSmiley:
+ {
+ if ( iSmileyEnabled )
+ {
+ retVal = static_cast<CFsRichTextSmiley*>
+ (aObject)->GetPictureObject()->GetTextureSize();
+ }
+ else
+ {
+ CFont* font;
+ CFsRichTextText* object =
+ static_cast<CFsRichTextSmiley*>
+ (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<CFsRichTextText*>( 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<CFsRichTextText*>(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<CFsRichTextText*>(aObject)->GetTextColor();
+ retVal->iTextStyleId = static_cast<CFsRichTextText*>(aObject)->GetStyleId();
+ retVal->iDirection =
+ static_cast<CFsRichTextText*>(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<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetTextColor();
+ retVal->iTextStyleId =
+ static_cast<CFsRichTextSmiley*>(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<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetTextColor();
+ retVal->iTextStyleId =
+ static_cast<CFsRichTextSmiley*>(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 );
+ //<cmail> 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 );
+ }*/
+ //</cmail>
+// else
+// {
+// if ( iMainDirection == TBidiText::ELeftToRight )
+// {
+//// retVal = ReorderLineFromLeftL( aObject, aLayout, aParser, objectSize, aRegisterSelects );
+// }
+// else
+// {
+//// retVal = ReorderLineFromRightL( aObject, aLayout, aParser, objectSize, aRegisterSelects );
+// }
+// }
+ //<cmail> following lines are commented out to avoid warnings
+ //return retVal;
+ //</cmail>
+ }
+
+// ---------------------------------------------------------------------------
+// ConstructLineL
+// ---------------------------------------------------------------------------
+void CFsTextViewerLayouter::ConstructLineL( TInt aHeight )
+ {
+ FUNC_LOG;
+ TInt i = 0;
+ TInt dY;
+ RPointerArray<TFsRangedVisual> 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;
+ // <cmail>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;
+ // <cmail> 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;
+ }
+