emailuis/uicomponents/src/fstextviewerlayouter.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Visual aligning class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //<cmail> removed __FS_ALFRED_SUPPORT flag
       
    20 //#include <fsconfig.h>
       
    21 //</cmail> removed __FS_ALFRED_SUPPORT flag
       
    22 #include "emailtrace.h"
       
    23 #include <gdi.h>
       
    24 #include <w32std.h>
       
    25 // <cmail> SF
       
    26 #include <alf/alfenv.h>
       
    27 #include <alf/alftextstyle.h>
       
    28 #include <alf/alftextstylemanager.h>
       
    29 // </cmail>
       
    30 #include <AknLayoutFont.h>
       
    31 #include <AknFontAccess.h> 
       
    32 #include <AknBidiTextUtils.h>
       
    33 // <cmail>
       
    34 #include <alf/alftextvisual.h>
       
    35 // </cmail>
       
    36 
       
    37 #include "fstextviewervisualizer.h"
       
    38 
       
    39 #include "fstextviewerlayouter.h"
       
    40 #include "fsrichtextobject.h"
       
    41 #include "fstextstylemanager.h"
       
    42 #include "fsrichtext.h"
       
    43 #include "fsrichtexttext.h"
       
    44 #include "fsrichtextsmiley.h"
       
    45 #include "fsrichtextpicture.h"
       
    46 #include "fstextviewercoordinator.h"
       
    47 #include "fstextviewervisualizerdata.h"
       
    48 #include "fstextparser.h"
       
    49 
       
    50 // ---------------------------------------------------------------------------
       
    51 // NewL
       
    52 // ---------------------------------------------------------------------------
       
    53 CFsTextViewerLayouter* CFsTextViewerLayouter::NewL( CAlfEnv* aEnv )
       
    54     {
       
    55     FUNC_LOG;
       
    56     CFsTextViewerLayouter* self = 
       
    57         new (ELeave) CFsTextViewerLayouter( aEnv );
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL();
       
    60     CleanupStack::Pop( self );
       
    61     return self;
       
    62     }
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 // ~CFsTextViewerLayouter
       
    66 // ---------------------------------------------------------------------------
       
    67 CFsTextViewerLayouter::~CFsTextViewerLayouter()
       
    68     {
       
    69     FUNC_LOG;
       
    70     iCurrentLineArray.Close();
       
    71     }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // MeasureBidiTextBoundsWidth
       
    75 // ---------------------------------------------------------------------------
       
    76 TInt CFsTextViewerLayouter::MeasureBidiTextBoundsWidth(
       
    77     const CFont& aFont,
       
    78     const TDesC& aText,
       
    79     CFont::TMeasureTextInput::TFlags aOrder)
       
    80     {
       
    81     FUNC_LOG;
       
    82 //    return AknBidiTextUtils::MeasureTextBoundsWidth( aFont, aText, aOrder);
       
    83     CFont::TMeasureTextInput input; 
       
    84     input.iFlags = aOrder;
       
    85     CFont::TMeasureTextOutput output; 
       
    86     
       
    87     TInt textAdvance = aFont.MeasureText( aText, &input, &output );
       
    88 	
       
    89 	TRect bounds = output.iBounds;
       
    90 	bounds.iTl.iX = Min(bounds.iTl.iX, 0);
       
    91 	bounds.iBr.iX = Max(bounds.iBr.iX, textAdvance);    
       
    92     return bounds.Width();
       
    93     }
       
    94 
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // CalculateSizeL
       
    98 // ---------------------------------------------------------------------------
       
    99 TSize CFsTextViewerLayouter::CalculateSizeL( MFsRichTextObject* aObject )
       
   100     {
       
   101     FUNC_LOG;
       
   102     TSize retVal;
       
   103 
       
   104     switch ( aObject->GetType() )
       
   105         {
       
   106         case MFsRichTextObject::EFsText:
       
   107             {
       
   108             if ( static_cast<CFsRichTextText*>(aObject)->GetHotSpot() && static_cast<CFsRichTextText*>(aObject)->GetText().Length() > 1 )
       
   109                 {
       
   110                 CAlfTextVisual* tmp = CAlfTextVisual::AddNewL( *iControl, iVisualizer->BackgroundLayout() );
       
   111                 tmp->SetTextL( static_cast<CFsRichTextText*>(aObject)->GetText() );
       
   112                 tmp->SetTextStyle( static_cast<CFsRichTextText*>(aObject)->GetStyleId() );
       
   113                 tmp->SetAlign( EAlfAlignHLeft, EAlfAlignVTop );
       
   114                 tmp->SetPadding( 0 );
       
   115 //                retVal = tmp->SubstringExtents( 0, static_cast<CFsRichTextText*>(aObject)->GetText().Length() - 1 ).Size();
       
   116                 retVal = tmp->TextExtents();
       
   117                 // <cmail> Platform layout change
       
   118                 //retVal.iWidth -= 4;
       
   119                 // </cmail> Platform layout change
       
   120                 tmp->RemoveAndDestroyAllD();
       
   121                 break;
       
   122                 }
       
   123             
       
   124             CFont* font;
       
   125             User::LeaveIfNull( iScreenDev );
       
   126         
       
   127             CAlfTextStyle* textStyle(
       
   128                 iEnv->TextStyleManager().TextStyle(
       
   129                     static_cast<CFsRichTextText*>(aObject)->GetStyleId() ) );
       
   130 
       
   131             HBufC* typeface( textStyle->TypefaceNameL() );
       
   132             CleanupStack::PushL( typeface );
       
   133             TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() );
       
   134             if ( textStyle->IsBold() )
       
   135 				{
       
   136 				fontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightBold );
       
   137 				}
       
   138             if ( textStyle->IsItalic() )
       
   139             	{
       
   140             	fontSpec.iFontStyle.SetPosture( EPostureItalic );
       
   141             	}
       
   142 
       
   143             User::LeaveIfError(
       
   144                 iScreenDev->GetNearestFontInTwips(
       
   145                     font, fontSpec ) );
       
   146 
       
   147 //            TAknFontSpecification aknFs(EAknFontCategoryPrimary, fontSpec, iScreenDev);
       
   148 //            aknFs.SetTextPaneHeight( iScreenDev->VerticalTwipsToPixels(fontSpec.iHeight));
       
   149 //            aknFs.SetTextPaneHeightIsDesignHeight( ETrue );
       
   150 //            font = 
       
   151 //                AknFontAccess::CreateLayoutFontFromSpecificationL( 
       
   152 //                    *iScreenDev, 
       
   153 //                    fontSpec.iTypeface,
       
   154 //                    aknFs ); 
       
   155             
       
   156 
       
   157 //            retVal = TSize(
       
   158 //                    font->TextWidthInPixels(
       
   159 //                        static_cast<CFsRichTextText*>(aObject)->GetText() ), 
       
   160 //                    font->FontMaxHeight() );
       
   161             
       
   162             CleanupStack::PopAndDestroy( typeface );
       
   163             TSize retVal1( MeasureBidiTextBoundsWidth( *font, static_cast<CFsRichTextText*>(aObject)->GetText(), CFont::TMeasureTextInput::EFVisualOrder), font->FontMaxHeight() );
       
   164 
       
   165             retVal = retVal1;
       
   166     
       
   167             const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( font );
       
   168             if ( layoutFont )
       
   169             {
       
   170                 retVal.iHeight = font->HeightInPixels();
       
   171                 TInt textPaneHeight = layoutFont->TextPaneHeight();
       
   172                 TInt textPaneTopToBaseline = layoutFont->TextPaneTopToBaseline();
       
   173         
       
   174                 retVal.iHeight += textPaneHeight - textPaneTopToBaseline;
       
   175                 retVal.iHeight += 1;
       
   176                 }
       
   177             else
       
   178                 {
       
   179                 retVal.iHeight = Max(retVal.iHeight, font->HeightInPixels());
       
   180                 retVal.iHeight += 5; // the best approximation - fails on big (>=72) fonts
       
   181                 }
       
   182             iScreenDev->ReleaseFont( font );
       
   183 //            if ( static_cast<CFsRichTextText*>(aObject)->GetHotSpot() && static_cast<CFsRichTextText*>(aObject)->GetText().Length() > 1 )
       
   184 //                {
       
   185 //                retVal.iWidth += 3;
       
   186 //                }
       
   187             break;
       
   188             }
       
   189         case MFsRichTextObject::EFsTexture:
       
   190             {
       
   191             retVal = static_cast<CFsRichTextPicture*>
       
   192                 (aObject)->GetTextureSize();
       
   193             retVal.iWidth += 3;
       
   194             break;
       
   195             }
       
   196         case MFsRichTextObject::EFsSmiley:
       
   197             {
       
   198             if ( iSmileyEnabled )
       
   199                 {
       
   200                 retVal = static_cast<CFsRichTextSmiley*>
       
   201                      (aObject)->GetPictureObject()->GetTextureSize();
       
   202                 }
       
   203             else
       
   204                 {
       
   205                 CFont* font;
       
   206                 CFsRichTextText* object = 
       
   207                     static_cast<CFsRichTextSmiley*>
       
   208                      (aObject)->GetTextObject();
       
   209                 User::LeaveIfNull(iScreenDev);
       
   210         
       
   211                 CAlfTextStyle* textStyle(
       
   212                     iEnv->TextStyleManager().TextStyle(
       
   213                         object->GetStyleId() ) );
       
   214 
       
   215                 HBufC* typeface( textStyle->TypefaceNameL() );
       
   216                 CleanupStack::PushL( typeface );
       
   217                 TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() );
       
   218 
       
   219                 User::LeaveIfError(
       
   220                     iScreenDev->GetNearestFontInTwips( font, fontSpec ) );
       
   221 
       
   222                 retVal = TSize(
       
   223                         font->TextWidthInPixels( object->GetText() ), 
       
   224                         font->FontMaxHeight() );
       
   225                 iScreenDev->ReleaseFont( font );
       
   226                 CleanupStack::PopAndDestroy( typeface );
       
   227                 break;
       
   228                 }
       
   229             }
       
   230         default:
       
   231             {
       
   232             break;
       
   233             }
       
   234         }
       
   235     return retVal;
       
   236     }
       
   237 
       
   238 // ---------------------------------------------------------------------------
       
   239 // FindMaxLengthL
       
   240 // ---------------------------------------------------------------------------
       
   241 TInt CFsTextViewerLayouter::FindMaxLengthL( MFsRichTextObject* aObject )
       
   242     {
       
   243     FUNC_LOG;
       
   244     TInt retVal = 0;
       
   245     if ( aObject->GetType() == MFsRichTextObject::EFsText )
       
   246         {
       
   247         CFont* font;
       
   248         User::LeaveIfNull( iScreenDev );
       
   249             
       
   250         CAlfTextStyle* textStyle(
       
   251             iEnv->TextStyleManager().TextStyle(
       
   252                 static_cast<CFsRichTextText*>( aObject )->GetStyleId() ) );
       
   253 
       
   254         HBufC* typeface( textStyle->TypefaceNameL() );
       
   255         CleanupStack::PushL( typeface );
       
   256         TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() );
       
   257 
       
   258         User::LeaveIfError(
       
   259             iScreenDev->GetNearestFontInTwips(
       
   260                 font, fontSpec ) );
       
   261         
       
   262         retVal = font->TextCount( static_cast<CFsRichTextText*>(aObject)->GetText(), iDisplaySize.iWidth ) - 1;
       
   263         iScreenDev->ReleaseFont( font );
       
   264         CleanupStack::PopAndDestroy( typeface );
       
   265         }
       
   266     return retVal;
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // PrepareRangedVisL
       
   271 // ---------------------------------------------------------------------------
       
   272 TFsRangedVisual* CFsTextViewerLayouter::PrepareRangedVisL( 
       
   273                         MFsRichTextObject* aObject,
       
   274                         CAlfLayout* aLayout )
       
   275     {
       
   276     FUNC_LOG;
       
   277     TFsRangedVisual* retVal = new (ELeave) TFsRangedVisual;
       
   278     retVal->iVisual = NULL;
       
   279     retVal->iHotspot = EFalse;
       
   280     retVal->iEmbed = EFalse;
       
   281 
       
   282     switch ( aObject->GetType() )
       
   283         {
       
   284         case MFsRichTextObject::EFsText:
       
   285             {
       
   286             retVal->iStart = aObject->GetBeginOfObject();
       
   287             retVal->iEnd = aObject->GetEndOfObject();
       
   288             retVal->iIsActive = ETrue;
       
   289             retVal->iLayout = aLayout;
       
   290             retVal->iIsText = ETrue;
       
   291             retVal->iTextColor = 
       
   292                 static_cast<CFsRichTextText*>(aObject)->GetTextColor();
       
   293             retVal->iTextStyleId = static_cast<CFsRichTextText*>(aObject)->GetStyleId();
       
   294             retVal->iDirection = 
       
   295                 static_cast<CFsRichTextText*>(aObject)->GetTextDirection();
       
   296             retVal->iSmiley = EFalse;
       
   297             break;
       
   298             }
       
   299         case MFsRichTextObject::EFsTexture:
       
   300             {
       
   301             retVal->iStart = aObject->GetBeginOfObject(); 
       
   302             retVal->iEnd = aObject->GetEndOfObject();
       
   303             retVal->iIsActive = ETrue;
       
   304             retVal->iLayout = aLayout;
       
   305             retVal->iIsText = EFalse;
       
   306             retVal->iSmiley = EFalse;
       
   307             break;
       
   308             }
       
   309         case MFsRichTextObject::EFsSmiley:
       
   310             {
       
   311             if ( iSmileyEnabled )
       
   312                 {
       
   313                 retVal->iStart = aObject->GetBeginOfObject(); 
       
   314                 retVal->iEnd = aObject->GetEndOfObject();
       
   315                 retVal->iIsActive = ETrue;
       
   316                 retVal->iLayout = aLayout;
       
   317                 retVal->iIsText = EFalse;
       
   318                 retVal->iTextColor = 
       
   319                     static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetTextColor();
       
   320                 retVal->iTextStyleId = 
       
   321                     static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetStyleId();
       
   322                 }
       
   323             else
       
   324                 {
       
   325                 retVal->iStart = aObject->GetBeginOfObject(); 
       
   326                 retVal->iEnd = aObject->GetEndOfObject();
       
   327                 retVal->iIsActive = ETrue;
       
   328                 retVal->iLayout = aLayout;
       
   329                 retVal->iIsText = ETrue;
       
   330                 retVal->iTextColor = 
       
   331                     static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetTextColor();
       
   332                 retVal->iTextStyleId = 
       
   333                     static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetStyleId();
       
   334                 }
       
   335             retVal->iSmiley = ETrue;
       
   336             break;
       
   337             }
       
   338         case MFsRichTextObject::EFsNewLine:
       
   339             {
       
   340             break;
       
   341             }
       
   342         default:
       
   343             {
       
   344             break;
       
   345             }
       
   346         }
       
   347 
       
   348     if ( retVal->iIsActive )
       
   349         {
       
   350         if ( aObject->GetEmbeded() )
       
   351             {
       
   352             retVal->iId = aObject->GetIdOfEmbeded();
       
   353             retVal->iEmbed = ETrue;
       
   354             }
       
   355         if ( aObject->GetHotSpot() )
       
   356             {
       
   357             retVal->iHotspotType = aObject->GetTypeOfHotSpot();
       
   358             retVal->iId = aObject->GetIdOfHotSpot();
       
   359             retVal->iHotspot = ETrue;
       
   360             }
       
   361         }
       
   362 
       
   363     return retVal;
       
   364     }
       
   365 
       
   366 // ---------------------------------------------------------------------------
       
   367 // SetDisplaySize
       
   368 // ---------------------------------------------------------------------------
       
   369 void CFsTextViewerLayouter::SetDisplaySize( TSize aDisplaySize )
       
   370     {
       
   371     FUNC_LOG;
       
   372     iDisplaySize = aDisplaySize;
       
   373     }
       
   374 
       
   375 // ---------------------------------------------------------------------------
       
   376 // AppendObjectL
       
   377 // ---------------------------------------------------------------------------
       
   378 TBool CFsTextViewerLayouter::AppendObjectL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TBool aRegisterSelects )
       
   379     {
       
   380     FUNC_LOG;
       
   381     TRect objectRect;
       
   382     TRect naturalRect;
       
   383     TSize objectSize = CalculateSizeL( aObject );
       
   384     
       
   385     if ( objectSize.iWidth > iDisplaySize.iWidth )
       
   386         {
       
   387         if ( iLowestPicPosition > iCurrentLineOffset )
       
   388             {
       
   389             iCurrentLineOffset = iLowestPicPosition;
       
   390             ConstructLineL();
       
   391             }
       
   392         if ( aObject->GetType() != MFsRichTextObject::EFsText )
       
   393             {
       
   394             // Resizing object to fit display width
       
   395             const TInt KScalingFactor = 65536;
       
   396             const TInt KTwo = 2;
       
   397             
       
   398             TInt resizeFactor = KScalingFactor * iDisplaySize.iWidth /
       
   399                                 objectSize.iWidth;
       
   400             TInt height = objectSize.iHeight;
       
   401             
       
   402             objectSize.iWidth = iDisplaySize.iWidth;
       
   403             
       
   404             height = height * resizeFactor + KScalingFactor / KTwo;
       
   405             objectSize.iHeight = height / KScalingFactor;
       
   406             }
       
   407         else
       
   408             {
       
   409             aParser->CutWord(
       
   410                 aObject->GetBeginOfObject(),
       
   411                 FindMaxLengthL( aObject ) );
       
   412             return EFalse;
       
   413             }
       
   414         }
       
   415     
       
   416     TFsRangedVisual* currentVisual;
       
   417     currentVisual = PrepareRangedVisL( aObject, aLayout );
       
   418     if ( !aRegisterSelects )
       
   419         {
       
   420         currentVisual->iEmbed = EFalse;
       
   421         }
       
   422     
       
   423     if ( iMainDirection == TBidiText::ELeftToRight )
       
   424         {
       
   425         objectRect = TRect( TPoint( iLastCol, iCurrentLineOffset ), objectSize );
       
   426         }
       
   427     else
       
   428         {        
       
   429         objectRect = TRect( TPoint( iLastCol - objectSize.iWidth, iCurrentLineOffset ), objectSize );
       
   430         }
       
   431     iNewLine = EFalse;
       
   432     naturalRect = objectRect;
       
   433     if ( iHelper->NextFreeCol( objectRect, iMainDirection ) )
       
   434         {
       
   435         ConstructLineL();
       
   436         delete currentVisual;
       
   437         currentVisual = NULL;
       
   438         AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   439         }
       
   440     else
       
   441         {
       
   442         if ( objectRect != naturalRect )
       
   443             {
       
   444             currentVisual->iMoved = ETrue;
       
   445             }
       
   446         else 
       
   447             {
       
   448             currentVisual->iMoved = EFalse;
       
   449             }
       
   450         
       
   451         if ( iMainDirection == TBidiText::ELeftToRight )
       
   452             {
       
   453             currentVisual->iRect = objectRect;
       
   454             iLastCol = objectRect.iBr.iX;
       
   455             iCurrentLineArray.Append( currentVisual );
       
   456             }
       
   457         else
       
   458             {
       
   459             currentVisual->iRect = objectRect;
       
   460             iLastCol = objectRect.iTl.iX;
       
   461             iCurrentLineArray.Append( currentVisual );
       
   462             }
       
   463         }
       
   464     if ( objectRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture )
       
   465         {
       
   466         iLineHeight = objectRect.Height();
       
   467         }
       
   468     else if ( aObject->GetType() == MFsRichTextObject::EFsTexture || aObject->GetHotSpot() )
       
   469         {
       
   470         iHelper->RegisterObstacleL( objectRect );
       
   471         if ( objectRect.iBr.iY > iLowestPicPosition )
       
   472             {
       
   473             iLowestPicPosition = objectRect.iBr.iY;
       
   474             }
       
   475         }
       
   476 //    if ( text )
       
   477 //    	{
       
   478 //    	delete text;
       
   479 //    	}
       
   480     return ETrue;
       
   481     }
       
   482 
       
   483 // ---------------------------------------------------------------------------
       
   484 // InsertObjectL
       
   485 // ---------------------------------------------------------------------------
       
   486 TBool CFsTextViewerLayouter::InsertObjectL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TBool aRegisterSelects )
       
   487     {
       
   488     FUNC_LOG;
       
   489     return AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   490     //<cmail> following lines are commented out to avoid warnings
       
   491     /*
       
   492     TBool retVal = EFalse;
       
   493     
       
   494     TSize objectSize = CalculateSizeL( aObject );
       
   495     if ( objectSize.iWidth > iDisplaySize.iWidth )
       
   496         {
       
   497         aParser->CutWord( 
       
   498             aObject->GetBeginOfObject(),
       
   499             FindMaxLengthL( aObject ) );
       
   500         return EFalse;
       
   501         }
       
   502     
       
   503     if ( ( objectSize.iWidth > iDisplaySize.iWidth - iLastCol && iMainDirection == TBidiText::ELeftToRight )
       
   504             || ( objectSize.iWidth > iLastCol && iMainDirection == TBidiText::ERightToLeft ) )
       
   505         {
       
   506         ConstructLineL();
       
   507         retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   508         }
       
   509     else //if ( 0 == iCurrentLineArray.Count() )
       
   510         {
       
   511         retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   512         }*/
       
   513     //</cmail>    
       
   514 //    else
       
   515 //        {
       
   516 //        if ( iMainDirection == TBidiText::ELeftToRight )
       
   517 //            {
       
   518 ////            retVal = ReorderLineFromLeftL( aObject, aLayout, aParser, objectSize, aRegisterSelects );
       
   519 //            }
       
   520 //        else 
       
   521 //            {
       
   522 ////            retVal = ReorderLineFromRightL( aObject, aLayout, aParser, objectSize, aRegisterSelects );
       
   523 //            }
       
   524 //        }
       
   525     //<cmail> following lines are commented out to avoid warnings
       
   526     //return retVal;
       
   527     //</cmail>
       
   528     }
       
   529 
       
   530 // ---------------------------------------------------------------------------
       
   531 // ConstructLineL
       
   532 // ---------------------------------------------------------------------------
       
   533 void CFsTextViewerLayouter::ConstructLineL( TInt aHeight )
       
   534     {
       
   535     FUNC_LOG;
       
   536     TInt i = 0;
       
   537     TInt dY;
       
   538     RPointerArray<TFsRangedVisual> finalLine;
       
   539     
       
   540     if ( 0 == iLineHeight )
       
   541         {
       
   542         iLineHeight = aHeight;
       
   543         }
       
   544     
       
   545     for ( i = 0; i < iCurrentLineArray.Count(); ++i )
       
   546         {
       
   547         iCurrentLineArray[i]->iLineNumber = iLines;
       
   548         if ( iCurrentLineArray[i]->iIsText )
       
   549             {
       
   550             dY = iLineHeight - iCurrentLineArray[i]->iRect.Height();
       
   551             iCurrentLineArray[i]->iRect.iTl.iY += dY;
       
   552             iCurrentLineArray[i]->iRect.iBr.iY += dY;
       
   553             }
       
   554         if ( i > 0
       
   555                 && iCurrentLineArray[i]->iIsText 
       
   556                 && finalLine[finalLine.Count() - 1]->iIsText
       
   557 //                && iCurrentLineArray[i]->iDirection == finalLine[finalLine.Count() - 1]->iDirection
       
   558 //                && iCurrentLineArray[i]->iDirection == iMainDirection
       
   559                 && iCurrentLineArray[i]->iTextStyleId == finalLine[finalLine.Count() - 1]->iTextStyleId
       
   560                 && iCurrentLineArray[i]->iTextColor == finalLine[finalLine.Count() - 1]->iTextColor
       
   561                 && ( !iCurrentLineArray[i]->iHotspot 
       
   562                         ||
       
   563                         iCurrentLineArray[i]->iId == finalLine[finalLine.Count() - 1]->iId
       
   564                         )
       
   565 //                && !finalLine[finalLine.Count() - 1]->iHotspot
       
   566                 && !iCurrentLineArray[i]->iMoved
       
   567 //                && !iCurrentLineArray[i]->iEmbed
       
   568 //                && !finalLine[finalLine.Count() - 1]->iEmbed                
       
   569                  )
       
   570             
       
   571             {
       
   572             JoinRangedVisuals( finalLine[finalLine.Count() - 1], iCurrentLineArray[i] );
       
   573             delete iCurrentLineArray[i];
       
   574             iCurrentLineArray[i] = NULL;
       
   575             }
       
   576         else
       
   577             {
       
   578             finalLine.Append( iCurrentLineArray[i] );
       
   579             }
       
   580         }
       
   581     
       
   582     for ( i = 0; i < finalLine.Count(); ++i )
       
   583         {
       
   584         iNavigator->AppendVisualL( finalLine[i] );
       
   585         }
       
   586     finalLine.Close();
       
   587     
       
   588     if ( iMainDirection == TBidiText::ELeftToRight )
       
   589         {
       
   590         iLastCol = iLeftMargin;
       
   591         }
       
   592     else 
       
   593         {
       
   594         iLastCol = iDisplaySize.iWidth + iLeftMargin;
       
   595         }
       
   596     
       
   597     iNewLine = ETrue;
       
   598     
       
   599     iCurrentLineArray.Reset();
       
   600     iCurrentLineOffset += iLineHeight;
       
   601     iLineHeight = 0;
       
   602     ++iLines;
       
   603     }
       
   604 
       
   605 // ---------------------------------------------------------------------------
       
   606 // JoinRangedVisuals
       
   607 // ---------------------------------------------------------------------------
       
   608 void CFsTextViewerLayouter::JoinRangedVisuals( TFsRangedVisual* aFirst, TFsRangedVisual* aSecond )
       
   609     {
       
   610     FUNC_LOG;
       
   611 /*        if ( aFirst->iRect.iTl.iX > aSecond->iRect.iTl.iX )
       
   612             {
       
   613             aFirst->iRect.iTl.iX = aSecond->iRect.iTl.iX;
       
   614             }
       
   615         else 
       
   616             {
       
   617             aFirst->iRect.iBr.iX = aSecond->iRect.iBr.iX;
       
   618             }
       
   619             */
       
   620         TInt a = aFirst->iRect.iTl.iX;
       
   621         TInt b = aFirst->iRect.iBr.iX;
       
   622         TInt c = aSecond->iRect.iTl.iX;
       
   623         TInt d = aSecond->iRect.iBr.iX;
       
   624 
       
   625         TInt max = Max( Max(a, b), Max(d, c) );
       
   626         TInt min = Min( Min(a, b), Min(d, c) );
       
   627         aFirst->iRect.iTl.iX = min;
       
   628         aFirst->iRect.iBr.iX = max;
       
   629         aFirst->iStart = Min( aFirst->iStart, aSecond->iStart );
       
   630         aFirst->iEnd = Max( aFirst->iEnd, aSecond->iEnd );
       
   631     }
       
   632 
       
   633 // ---------------------------------------------------------------------------
       
   634 // GetCurrentLineOffset
       
   635 // ---------------------------------------------------------------------------
       
   636 TInt CFsTextViewerLayouter::GetCurrentLineOffset()
       
   637     {
       
   638     FUNC_LOG;
       
   639     return iCurrentLineOffset;
       
   640     }
       
   641 
       
   642 // ---------------------------------------------------------------------------
       
   643 // SetMargins
       
   644 // ---------------------------------------------------------------------------
       
   645 void CFsTextViewerLayouter::SetCurrentLineOffset( TInt aOffset )
       
   646     {
       
   647     FUNC_LOG;
       
   648     iCurrentLineOffset = aOffset;
       
   649     }
       
   650 
       
   651 // ---------------------------------------------------------------------------
       
   652 // SetMargins
       
   653 // ---------------------------------------------------------------------------
       
   654 void CFsTextViewerLayouter::SetMargins( const TInt aLeft, const TInt aRight )
       
   655     {
       
   656     FUNC_LOG;
       
   657     iLeftMargin = aLeft;
       
   658     iRightMargin = aRight;
       
   659     if ( iMainDirection == TBidiText::ELeftToRight )
       
   660         {
       
   661         iLastCol = iLeftMargin;
       
   662         }
       
   663     else 
       
   664         {
       
   665         iLastCol = iDisplaySize.iWidth + iLeftMargin;
       
   666         }
       
   667     }
       
   668 
       
   669 // ---------------------------------------------------------------------------
       
   670 // SetHelper
       
   671 // ---------------------------------------------------------------------------
       
   672 void CFsTextViewerLayouter::SetHelper( CFsTextViewerCoordinator* aHelper )
       
   673     {
       
   674     FUNC_LOG;
       
   675     iHelper = aHelper;
       
   676     }
       
   677 
       
   678 // ---------------------------------------------------------------------------
       
   679 // SetNavigator
       
   680 // ---------------------------------------------------------------------------
       
   681 void CFsTextViewerLayouter::SetNavigator( CFsTextViewerVisualizerData* aNavigator )
       
   682     {
       
   683     FUNC_LOG;
       
   684     iNavigator = aNavigator;
       
   685     }
       
   686 
       
   687 // ---------------------------------------------------------------------------
       
   688 // Lines
       
   689 // ---------------------------------------------------------------------------
       
   690 TInt CFsTextViewerLayouter::Lines()
       
   691     {
       
   692     FUNC_LOG;
       
   693     return iLines;
       
   694     }
       
   695 
       
   696 // ---------------------------------------------------------------------------
       
   697 // EnableSmileys
       
   698 // ---------------------------------------------------------------------------
       
   699 void CFsTextViewerLayouter::EnableSmileys( TBool aEnable )
       
   700     {
       
   701     FUNC_LOG;
       
   702     iSmileyEnabled = aEnable;
       
   703     }
       
   704 
       
   705 // ---------------------------------------------------------------------------
       
   706 // SetPosition
       
   707 // ---------------------------------------------------------------------------
       
   708 void CFsTextViewerLayouter::SetPosition( TInt aLine, TInt aLineOffset )
       
   709     {
       
   710     FUNC_LOG;
       
   711     iLines = aLine;
       
   712     iCurrentLineOffset = aLineOffset;
       
   713     }
       
   714 
       
   715 // ---------------------------------------------------------------------------
       
   716 // ChangeDirection
       
   717 // ---------------------------------------------------------------------------
       
   718 void CFsTextViewerLayouter::ChangeDirection( TBidiText::TDirectionality aDirection )
       
   719     {
       
   720     FUNC_LOG;
       
   721     iMainDirection = aDirection;
       
   722     if ( iMainDirection == TBidiText::ELeftToRight && iCurrentLineArray.Count() < 1 )
       
   723 		{
       
   724 		iLastCol = iLeftMargin;
       
   725 		}
       
   726 	else if ( iMainDirection == TBidiText::ERightToLeft && iCurrentLineArray.Count() < 1 )
       
   727 		{
       
   728 		iLastCol = iDisplaySize.iWidth + iLeftMargin;
       
   729 		}
       
   730     }
       
   731 
       
   732 // ---------------------------------------------------------------------------
       
   733 // SetDirection
       
   734 // ---------------------------------------------------------------------------
       
   735 void CFsTextViewerLayouter::SetDirection( TBidiText::TDirectionality aDirection )
       
   736     {
       
   737     FUNC_LOG;
       
   738     iMainDirection = aDirection;
       
   739     if ( iMainDirection == TBidiText::ELeftToRight )
       
   740         {
       
   741         iLastCol = iLeftMargin;
       
   742         }
       
   743     else 
       
   744         {
       
   745         iLastCol = iDisplaySize.iWidth + iLeftMargin;
       
   746         }
       
   747     }
       
   748 
       
   749 // ---------------------------------------------------------------------------
       
   750 // GetDirection
       
   751 // ---------------------------------------------------------------------------
       
   752 TBidiText::TDirectionality CFsTextViewerLayouter::GetDirection()
       
   753     {
       
   754     FUNC_LOG;
       
   755     return iMainDirection;
       
   756     }
       
   757 
       
   758 // ---------------------------------------------------------------------------
       
   759 // IsNewLine
       
   760 // ---------------------------------------------------------------------------
       
   761 TBool CFsTextViewerLayouter::IsNewLine()
       
   762     {
       
   763     FUNC_LOG;
       
   764     if ( iCurrentLineArray.Count() < 1 )
       
   765         {
       
   766         return ETrue;
       
   767         }
       
   768     return EFalse;
       
   769     }
       
   770 
       
   771 // ---------------------------------------------------------------------------
       
   772 // ConstructL
       
   773 // ---------------------------------------------------------------------------
       
   774 void CFsTextViewerLayouter::ConstructL()
       
   775     {
       
   776     FUNC_LOG;
       
   777     
       
   778     }
       
   779 
       
   780 // ---------------------------------------------------------------------------
       
   781 // CFsTextViewerLayouter
       
   782 // ---------------------------------------------------------------------------
       
   783 CFsTextViewerLayouter::CFsTextViewerLayouter( CAlfEnv* aEnv )
       
   784     {
       
   785     FUNC_LOG;
       
   786     iScreenDev = CCoeEnv::Static()->ScreenDevice();
       
   787     iEnv = aEnv;
       
   788     iLines = 0;
       
   789     iLowestPicPosition = 0;
       
   790     iMainDirection = TBidiText::ELeftToRight;
       
   791     }
       
   792 
       
   793 // ---------------------------------------------------------------------------
       
   794 // ReorderLineFromLeftL
       
   795 // ---------------------------------------------------------------------------
       
   796 TBool CFsTextViewerLayouter::ReorderLineFromLeftL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TSize aObjectSize, TBool aRegisterSelects )
       
   797     {
       
   798     FUNC_LOG;
       
   799 //    TBool retVal = EFalse;
       
   800 //    TInt i = iCurrentLineArray.Count() - 1;
       
   801 //    TInt dX = aObjectSize.iWidth;
       
   802 //    TInt moveFrom = 0;
       
   803 //    TRect translatedObject;
       
   804 //    TRect origRect;
       
   805 //    while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   806 //        {
       
   807 //        translatedObject = iCurrentLineArray[i]->iRect;
       
   808 ////        if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley )
       
   809 ////            {
       
   810 //            iHelper->RemoveRect( iCurrentLineArray[i]->iRect );
       
   811 //            translatedObject.iTl.iX += dX;
       
   812 //            translatedObject.iBr.iX += dX;
       
   813 //            origRect = translatedObject;
       
   814 //            if ( iHelper->NextFreeCol( translatedObject, iMainDirection ) )
       
   815 //                {
       
   816 //                i = -100;
       
   817 //                }
       
   818 //            if ( origRect != translatedObject )
       
   819 //                {
       
   820 //                iCurrentLineArray[i]->iMoved = ETrue;
       
   821 //                }
       
   822 ////            }
       
   823 //        moveFrom = i;
       
   824 //        --i;
       
   825 //        }
       
   826 //    if ( -101 == i )
       
   827 //        {
       
   828 //        ConstructLineL();
       
   829 //        retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   830 //        }
       
   831 //    else 
       
   832 //        {
       
   833 //        TFsRangedVisual* currentVisual; 
       
   834 //        currentVisual = PrepareRangedVisL( aObject, aLayout );
       
   835 //        if ( !aRegisterSelects )
       
   836 //            {
       
   837 //            currentVisual->iEmbed = EFalse;
       
   838 //            }
       
   839 //        currentVisual->iRect = TRect( iCurrentLineArray[moveFrom]->iRect.iTl, aObjectSize );
       
   840 //        iCurrentLineArray.Insert( currentVisual, moveFrom );
       
   841 //        for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i )
       
   842 //            {
       
   843 //            if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley )
       
   844 //                {
       
   845 //                iCurrentLineArray[i]->iRect.iTl.iX += dX;
       
   846 //                iCurrentLineArray[i]->iRect.iBr.iX += dX;
       
   847 //                }
       
   848 //            }
       
   849 //        if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture )
       
   850 //            {
       
   851 //            iLineHeight = currentVisual->iRect.Height();
       
   852 //            }
       
   853 //        }
       
   854 //    return retVal;
       
   855     TBool retVal = EFalse;
       
   856     TInt dX = aObjectSize.iWidth;
       
   857     TInt moveFrom = 0;
       
   858     TRect translatedObject;
       
   859     TFsRangedVisual* visual = NULL;
       
   860     TInt maxCol = 0;
       
   861     // <cmail>TInt tmp = 0;
       
   862     
       
   863     TInt i = iCurrentLineArray.Count() - 1;
       
   864     while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   865         {
       
   866         if ( !iCurrentLineArray[i]->iIsText )
       
   867             {
       
   868             iHelper->RemoveRect( iCurrentLineArray[i]->iRect );
       
   869             }
       
   870         --i;
       
   871         }
       
   872     i = iCurrentLineArray.Count() - 1;
       
   873     while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   874         {
       
   875         translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr );
       
   876         visual = iCurrentLineArray[i];
       
   877             translatedObject.iTl.iX += dX;
       
   878             translatedObject.iBr.iX += dX;
       
   879         // <cmail> tmp = translatedObject.iTl.iX;
       
   880         moveFrom = i;
       
   881         if ( iHelper->NextFreeCol( translatedObject, TBidiText::ELeftToRight ) )
       
   882                 {
       
   883                 i = -100;
       
   884                 }
       
   885         --i;
       
   886         }
       
   887     if ( -101 == i )
       
   888         {
       
   889         i = iCurrentLineArray.Count() - 1;
       
   890         while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   891             {
       
   892             if ( !iCurrentLineArray[i]->iIsText )
       
   893                 {
       
   894                 translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr );
       
   895                 translatedObject.iTl.iX += dX;
       
   896                 translatedObject.iBr.iX += dX;
       
   897                 iHelper->RegisterObstacleL( iCurrentLineArray[i]->iRect );
       
   898                 }
       
   899             --i;
       
   900             }
       
   901         ConstructLineL();
       
   902         retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   903         }
       
   904     else 
       
   905         {
       
   906         TFsRangedVisual* currentVisual; 
       
   907         currentVisual = PrepareRangedVisL( aObject, aLayout );
       
   908         currentVisual->iMoved = EFalse;
       
   909         if ( !aRegisterSelects )
       
   910             {
       
   911             currentVisual->iEmbed = EFalse;
       
   912             }
       
   913         
       
   914         currentVisual->iRect = TRect( TPoint( iCurrentLineArray[moveFrom]->iRect.iTl.iX, iCurrentLineArray[moveFrom]->iRect.iTl.iY ), aObjectSize );
       
   915         iCurrentLineArray.Insert( currentVisual, moveFrom );
       
   916         
       
   917         if ( aObject->GetType() == MFsRichTextObject::EFsTexture )
       
   918             {
       
   919             iHelper->RegisterObstacleL( currentVisual->iRect );
       
   920             }
       
   921         if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture )
       
   922             {
       
   923             iLineHeight = currentVisual->iRect.Height();
       
   924             }
       
   925         
       
   926         for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i )
       
   927                 {
       
   928 //            if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley )
       
   929 //                {
       
   930                 visual = iCurrentLineArray[i];
       
   931                 iCurrentLineArray[i]->iRect.iTl.iX += dX;
       
   932                 iCurrentLineArray[i]->iRect.iBr.iX += dX;
       
   933                 iHelper->NextFreeCol( iCurrentLineArray[i]->iRect, TBidiText::ELeftToRight );
       
   934                 if ( !(visual->iIsText) )
       
   935                     {
       
   936                     iHelper->RegisterObstacleL( visual->iRect );
       
   937                 }
       
   938                if ( visual->iRect.iBr.iX > maxCol )
       
   939             {
       
   940                    maxCol = visual->iRect.iBr.iX;
       
   941                    }
       
   942             }
       
   943         }
       
   944     iLastCol = maxCol;
       
   945     return retVal;
       
   946     }
       
   947 
       
   948 // ---------------------------------------------------------------------------
       
   949 // ReorderLineFromRightL
       
   950 // ---------------------------------------------------------------------------
       
   951 TBool CFsTextViewerLayouter::ReorderLineFromRightL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TSize aObjectSize, TBool aRegisterSelects )
       
   952     {
       
   953     FUNC_LOG;
       
   954     TBool retVal = EFalse;
       
   955     TInt dX = aObjectSize.iWidth;
       
   956     TInt moveFrom = 0;
       
   957     TRect translatedObject;
       
   958     TFsRangedVisual* visual = NULL;
       
   959     
       
   960     TInt i = iCurrentLineArray.Count() - 1;
       
   961     while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   962         {
       
   963         if ( !iCurrentLineArray[i]->iIsText )
       
   964             {
       
   965             iHelper->RemoveRect( iCurrentLineArray[i]->iRect );
       
   966             }
       
   967         --i;
       
   968         }
       
   969     i = iCurrentLineArray.Count() - 1;
       
   970     while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   971             {
       
   972         translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr );
       
   973         visual = iCurrentLineArray[i];
       
   974             translatedObject.iTl.iX -= dX;
       
   975             translatedObject.iBr.iX -= dX;
       
   976         moveFrom = i;
       
   977         if ( iHelper->NextFreeCol( translatedObject, TBidiText::ERightToLeft ) )
       
   978                 {
       
   979                 i = -100;
       
   980                 }
       
   981         --i;
       
   982         }
       
   983     if ( -101 == i  )
       
   984         {
       
   985         i = iCurrentLineArray.Count() - 1;
       
   986         while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection )
       
   987             {
       
   988             if ( !iCurrentLineArray[i]->iIsText )
       
   989                 {
       
   990                 translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr );
       
   991                 translatedObject.iTl.iX -= dX;
       
   992                 translatedObject.iBr.iX -= dX;
       
   993                 iHelper->RegisterObstacleL( iCurrentLineArray[i]->iRect );
       
   994                 }
       
   995             --i;
       
   996             }
       
   997         ConstructLineL();
       
   998         retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects );
       
   999         }
       
  1000     else 
       
  1001         {
       
  1002         TFsRangedVisual* currentVisual; 
       
  1003         currentVisual = PrepareRangedVisL( aObject, aLayout );
       
  1004         currentVisual->iMoved = EFalse;
       
  1005         if ( !aRegisterSelects )
       
  1006             {
       
  1007             currentVisual->iEmbed = EFalse;
       
  1008             }
       
  1009         
       
  1010         currentVisual->iRect = TRect( TPoint( iCurrentLineArray[moveFrom]->iRect.iBr.iX - dX, iCurrentLineArray[moveFrom]->iRect.iTl.iY ), aObjectSize );
       
  1011         iCurrentLineArray.Insert( currentVisual, moveFrom );
       
  1012         
       
  1013         if ( aObject->GetType() == MFsRichTextObject::EFsTexture )
       
  1014                 {
       
  1015             iHelper->RegisterObstacleL( currentVisual->iRect );
       
  1016             }
       
  1017         if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture )
       
  1018             {
       
  1019             iLineHeight = currentVisual->iRect.Height();
       
  1020             }
       
  1021         
       
  1022         for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i )
       
  1023             {
       
  1024 //            if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley )
       
  1025 //                {
       
  1026                 visual = iCurrentLineArray[i];
       
  1027                 iCurrentLineArray[i]->iRect.iTl.iX -= dX;
       
  1028                 iCurrentLineArray[i]->iRect.iBr.iX -= dX;
       
  1029                 iHelper->NextFreeCol( iCurrentLineArray[i]->iRect, TBidiText::ERightToLeft );
       
  1030                 if ( !(visual->iIsText) )
       
  1031                     {
       
  1032                     iHelper->RegisterObstacleL( visual->iRect );
       
  1033                     }
       
  1034             }
       
  1035         }
       
  1036     return retVal;
       
  1037     }
       
  1038