uiacceltk/hitchcock/coretoolkit/src/HuiTextVisual.cpp
changeset 0 15bf7259bb7c
child 17 c9d868f1e20c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-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:   Implementation of CHuiTextVisual. CHuiTextVisual is a visual
       
    15 *                that draws text.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <AknsConstants.h>
       
    22 #include <AknsUtils.h>
       
    23 #include <AknPictographInterface.h>
       
    24 #include <AknPictographDrawerInterface.h>
       
    25 #include <AknUtils.h>
       
    26 #include "uiacceltk/HuiTextVisual.h"  // Class definition
       
    27 #include "HuiRenderPlugin.h"
       
    28 #include "uiacceltk/HuiControl.h"
       
    29 #include "uiacceltk/HuiDrawing.h"
       
    30 #include "uiacceltk/HuiTextMesh.h"  
       
    31 #include "uiacceltk/HuiUtil.h"
       
    32 #include "uiacceltk/huitextstyle.h"
       
    33 #include "uiacceltk/huitextstylemanager.h"
       
    34 #include "uiacceltk/huidropshadow.h"
       
    35 
       
    36 #include "HuiRosterImpl.h"
       
    37 
       
    38 // Internal class to handle Japanese pictograph animations.
       
    39 NONSHARABLE_CLASS(CHuiPictographAnimator) : public CBase, public MAknPictographAnimatorCallBack
       
    40     {
       
    41 public:
       
    42     CHuiPictographAnimator(CHuiTextVisual* aVisual, CHuiTextMesh* aTextMesh);
       
    43     ~CHuiPictographAnimator();
       
    44     TBool IsAnimating() const;
       
    45     void SetAnimating(TBool aAnimating);    
       
    46     // From MAknPictographAnimatorCallBack
       
    47     void DrawPictographArea();
       
    48 private:    
       
    49     CHuiTextVisual* iVisual;
       
    50     CHuiTextMesh* iTextMesh;    
       
    51     TBool iAnimating;
       
    52     };
       
    53     
       
    54 CHuiPictographAnimator::CHuiPictographAnimator(CHuiTextVisual* aVisual, CHuiTextMesh* aTextMesh)
       
    55     {
       
    56     iVisual = aVisual;
       
    57     iTextMesh = aTextMesh;	
       
    58     }
       
    59 
       
    60 CHuiPictographAnimator::~CHuiPictographAnimator()
       
    61     {	
       
    62     iVisual = NULL;
       
    63     iTextMesh = NULL;
       
    64     }
       
    65 
       
    66 TBool CHuiPictographAnimator::IsAnimating() const
       
    67     {
       
    68     return iAnimating;	
       
    69     }
       
    70 
       
    71 void CHuiPictographAnimator::SetAnimating(TBool aAnimating)
       
    72     {
       
    73     iAnimating = aAnimating;	
       
    74     }
       
    75 
       
    76 void CHuiPictographAnimator::DrawPictographArea()
       
    77     {
       
    78     // This condition might need some further consideration.
       
    79     if (iVisual->EffectiveOpacity() > 0.0 && 
       
    80         CHuiStatic::Env().RefreshMode() != EHuiRefreshModeManual)
       
    81         {
       
    82         SetAnimating(ETrue);
       
    83         // This BuildPictographsL()-call also keeps the animation ticker 
       
    84         // behind CAknPictographInterface alive.
       
    85         TRAP_IGNORE(iTextMesh->BuildPictographsL())
       
    86         iVisual->SetChanged();            
       
    87         }
       
    88     else
       
    89         {
       
    90         // No call made to CAknPictographInterface -> animation timer gets automatically freezed.
       
    91         SetAnimating(EFalse);                    
       
    92         }    
       
    93     }
       
    94 
       
    95 
       
    96 EXPORT_C CHuiTextVisual* CHuiTextVisual::AddNewL(CHuiControl& aOwnerControl,
       
    97                                                  CHuiLayout* aParentLayout)
       
    98     {
       
    99     CHuiTextVisual* text = STATIC_CAST(CHuiTextVisual*,
       
   100         aOwnerControl.AppendVisualL(EHuiVisualTypeText, aParentLayout));
       
   101     return text;
       
   102     }
       
   103 
       
   104 
       
   105 CHuiTextVisual::CHuiTextVisual(MHuiVisualOwner& aOwner)
       
   106         : CHuiVisual(aOwner),
       
   107           iLineWrapping(ELineWrapManual),
       
   108           iAlignHorizontal(EHuiAlignHCenter),
       
   109           iAlignVertical(EHuiAlignVCenter),
       
   110           iStyle(EHuiTextStyleNormal),
       
   111           iFontColor(KRgbWhite),
       
   112           iFontColorId(KAknsIIDNone)
       
   113     {
       
   114     }
       
   115 
       
   116 
       
   117 void CHuiTextVisual::ConstructL()
       
   118     {
       
   119     CHuiVisual::ConstructL();
       
   120     
       
   121     iTextMesh = CHuiStatic::Renderer().CreateTextMeshL();
       
   122     iTextMesh->SetRelatedVisual( this );
       
   123     
       
   124     iMeshUpdated = EFalse;
       
   125     iExtentsUpdated = EFalse;
       
   126     iPictographAnimator = new (ELeave) CHuiPictographAnimator(this, iTextMesh);
       
   127     // Ugly missing CCoeControl workaround, but CAknPictographInterface does not seem to use CCoeControl.
       
   128     CCoeControl* dummy = NULL;    
       
   129     iPictographInterface = CAknPictographInterface::NewL( *dummy, *iPictographAnimator ); // Returns NULL if not supported.
       
   130     if (iPictographInterface)
       
   131         {
       
   132         iTextMesh->InitPictographsL(iPictographInterface);    
       
   133         }
       
   134     }
       
   135 
       
   136 
       
   137 CHuiTextVisual::~CHuiTextVisual()
       
   138     {
       
   139     delete iText;
       
   140     delete iTextMesh;
       
   141     delete iPictographAnimator;    
       
   142     delete iPictographInterface;
       
   143     }
       
   144 
       
   145 
       
   146 EXPORT_C void CHuiTextVisual::SetStyle(THuiPreconfiguredTextStyle aStyle, THuiBackgroundType aBackgroundType)
       
   147     {
       
   148     SetTextStyle(aStyle);
       
   149     iStyle = aStyle;
       
   150     THuiTextStyle* textStyle = Env().TextStyleManager().TextStyle(aStyle);
       
   151     
       
   152     if( aBackgroundType == EHuiBackgroundTypeLight)
       
   153         {
       
   154         textStyle->SetTextColor(KRgbBlack);
       
   155         }
       
   156     else
       
   157         {
       
   158         textStyle->SetTextColor(KRgbWhite);
       
   159         }
       
   160     iBackgroundType = aBackgroundType;
       
   161     }
       
   162 
       
   163 
       
   164 EXPORT_C THuiPreconfiguredTextStyle CHuiTextVisual::Style() const
       
   165     {
       
   166     return iStyle;
       
   167     }
       
   168 
       
   169 
       
   170 EXPORT_C void CHuiTextVisual::SetMaxLineCount(TInt aMaxLineCount)
       
   171     {
       
   172     if(iTextMesh->SetMaxLineCount(aMaxLineCount))
       
   173         {
       
   174         iMeshUpdated = EFalse;
       
   175         iExtentsUpdated = EFalse;        
       
   176         SetChanged();
       
   177         }
       
   178     }
       
   179 
       
   180 
       
   181 EXPORT_C TInt CHuiTextVisual::MaxLineCount() const
       
   182     {
       
   183     return iTextMesh->MaxLineCount();
       
   184     }
       
   185 
       
   186 
       
   187 EXPORT_C CHuiTextVisual::TLineWrap CHuiTextVisual::Wrapping() const
       
   188     {
       
   189     return iLineWrapping;
       
   190     }
       
   191 
       
   192 
       
   193 EXPORT_C void CHuiTextVisual::SetWrapping(TLineWrap aWrap)
       
   194     {
       
   195     iLineWrapping = aWrap;
       
   196     switch(iLineWrapping)
       
   197         {
       
   198         case ELineWrapManual:
       
   199         case ELineWrapTruncate:
       
   200             iTextMesh->SetLineMode(CHuiTextMesh::ELineModeTruncate);
       
   201             break;
       
   202 
       
   203         case ELineWrapBreak:
       
   204             iTextMesh->SetLineMode(CHuiTextMesh::ELineModeWrap);
       
   205             break;
       
   206         }
       
   207     SetChanged();
       
   208     }
       
   209 
       
   210 
       
   211 EXPORT_C THuiBackgroundType CHuiTextVisual::BackgroundType() const
       
   212     {
       
   213     return iBackgroundType;
       
   214     }
       
   215 
       
   216 
       
   217 EXPORT_C void CHuiTextVisual::SetTextL(const TDesC& aText)
       
   218     {
       
   219     delete iText; iText = 0;
       
   220     iText = aText.AllocL();
       
   221 
       
   222     iMeshUpdated = EFalse;
       
   223     iExtentsUpdated = EFalse;    
       
   224     SetChanged();
       
   225     }
       
   226 
       
   227     
       
   228 EXPORT_C const TDesC& CHuiTextVisual::Text() const
       
   229     {
       
   230     if(iText)
       
   231         {
       
   232         return *iText;
       
   233         }
       
   234     _LIT(KNoText, "");
       
   235     return KNoText;
       
   236     }
       
   237 
       
   238 
       
   239 EXPORT_C void CHuiTextVisual::SetAlign(THuiAlignHorizontal aAlignHorizontal,
       
   240                                        THuiAlignVertical aAlignVertical)
       
   241     {
       
   242     iAlignHorizontal = aAlignHorizontal;
       
   243     iAlignVertical = aAlignVertical;
       
   244 
       
   245     SetChanged();
       
   246     }
       
   247 
       
   248 
       
   249 EXPORT_C void CHuiTextVisual::SetLineSpacing(TInt aLineSpacing, TLineSpacingUnits aUnits)
       
   250     {
       
   251     TInt lineSpacingInPixels = 0;
       
   252     
       
   253     if(aUnits == ETwips)
       
   254         {
       
   255         CWsScreenDevice* screenDev = CHuiStatic::ScreenDevice();
       
   256         lineSpacingInPixels = screenDev->VerticalTwipsToPixels(aLineSpacing);
       
   257         }
       
   258     else
       
   259         {
       
   260         lineSpacingInPixels = aLineSpacing;  
       
   261         }
       
   262         
       
   263     iTextMesh->SetLineSpacing(lineSpacingInPixels);     
       
   264     }
       
   265 
       
   266 
       
   267 EXPORT_C TSize CHuiTextVisual::TextExtents() const
       
   268     {
       
   269     if(!iText)
       
   270         {
       
   271         return TSize(0, 0);
       
   272         }
       
   273 
       
   274 	if (!iExtentsUpdated)
       
   275 		{
       
   276 		TRAPD(err, iTextMesh->SetTextL(*iText, EFalse));
       
   277 		if (err != KErrNone) 
       
   278 			{
       
   279 			HUI_DEBUG1(_L("CHuiTextVisual::TextExtents() - ERROR! Failed to update mesh with leave errorcode %i. Text extents are not currently available. "), err);
       
   280 			iExtentsUpdated = EFalse; // we have to retry soon..
       
   281             return TSize(0, 0);
       
   282 			}
       
   283 			
       
   284 	    iExtentsUpdated = ETrue;
       
   285 		}
       
   286 	
       
   287     return iTextMesh->Extents();
       
   288     }
       
   289 
       
   290 EXPORT_C TRect CHuiTextVisual::SubstringExtents(TUint aStart, TUint aEnd) const
       
   291     {
       
   292     if(!iText)
       
   293         {
       
   294         return TRect(0, 0, 0, 0);
       
   295         }
       
   296 
       
   297     // Retrieve the text style used when rasterizing this text.
       
   298     THuiTextStyle* textStyle = CHuiStatic::Env().TextStyleManager().TextStyle(iTextMesh->TextStyle());
       
   299     
       
   300     TSize begin(0,0); 
       
   301     TSize end(0,0);
       
   302     TRAP_IGNORE( 
       
   303         {
       
   304         begin = textStyle->LineExtentsL(iText->Mid(0, aStart));
       
   305         end = textStyle->LineExtentsL(iText->Mid(0, aEnd));
       
   306         })
       
   307 
       
   308     return TRect(begin.iWidth, 0, end.iWidth, end.iHeight);
       
   309     }
       
   310 
       
   311 const TUint8 color_s_to_lin[256] = {
       
   312    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
       
   313    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
       
   314    0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
       
   315    0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04,
       
   316    0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
       
   317    0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07,
       
   318    0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a,
       
   319    0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0d,
       
   320    0x0d, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10,
       
   321    0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x14,
       
   322    0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18,
       
   323    0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d,
       
   324    0x1e, 0x1f, 0x1f, 0x20, 0x21, 0x21, 0x22, 0x23,
       
   325    0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x29,
       
   326    0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d, 0x2e, 0x2f,
       
   327    0x30, 0x31, 0x32, 0x33, 0x33, 0x34, 0x35, 0x36,
       
   328    0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
       
   329    0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
       
   330    0x47, 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f,
       
   331    0x50, 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58,
       
   332    0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x61, 0x63,
       
   333    0x64, 0x65, 0x67, 0x68, 0x69, 0x6b, 0x6c, 0x6d,
       
   334    0x6f, 0x70, 0x72, 0x73, 0x74, 0x76, 0x77, 0x79,
       
   335    0x7a, 0x7c, 0x7d, 0x7f, 0x80, 0x82, 0x83, 0x85,
       
   336    0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x92,
       
   337    0x93, 0x95, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9f,
       
   338    0xa1, 0xa3, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xad,
       
   339    0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb8, 0xba, 0xbc,
       
   340    0xbe, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc,
       
   341    0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc,
       
   342    0xde, 0xe0, 0xe2, 0xe5, 0xe7, 0xe9, 0xeb, 0xed,
       
   343    0xef, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfd, 0xff };
       
   344 
       
   345 inline TRgb ConvertToLinear(TRgb aColor)
       
   346     {
       
   347     // perform sRGB->linear color conversion if the renderer is
       
   348     // openvg
       
   349     // NOTE: For emulator depending on the OpenVG SW version mapping may
       
   350     // be needed or not. Use/unuse ifdefs below if text colors are too dark/light.
       
   351 //#ifndef __WINSCW__
       
   352 //    if (CHuiStatic::Env().Renderer() == EHuiRendererVg10)
       
   353         {
       
   354         TUint32 color = aColor.Internal();
       
   355         return
       
   356             ((TUint32)color_s_to_lin[(color >> 0) & 0xff] << 16) |
       
   357             ((TUint32)color_s_to_lin[(color >> 8) & 0xff] << 8) |
       
   358             ((TUint32)color_s_to_lin[(color >> 16) & 0xff] << 0) |
       
   359             (color & 0xff000000);
       
   360         }
       
   361 //#endif    
       
   362     return aColor;
       
   363     }
       
   364 
       
   365     
       
   366 EXPORT_C void CHuiTextVisual::SetColor(const TRgb& aColor)
       
   367     {
       
   368 	iFontColor = ConvertToLinear(aColor);
       
   369     iFontColorId = KAknsIIDNone;
       
   370     iFontColorIndex = -1;
       
   371     iFontColorValid = ETrue;
       
   372     SetChanged();
       
   373     }
       
   374     
       
   375     
       
   376 EXPORT_C void CHuiTextVisual::SetColor(const TAknsItemID& aID,const TInt aIndex)
       
   377     {
       
   378     iFontColorId = aID;
       
   379     iFontColorIndex = aIndex;
       
   380     iFontColorValid = EFalse;
       
   381     SetChanged();
       
   382     }
       
   383     
       
   384 
       
   385 EXPORT_C void CHuiTextVisual::EnableShadow(TBool aDoEnable)
       
   386     {
       
   387     TRAP_IGNORE( EnableDropShadowL(aDoEnable) );
       
   388     }
       
   389     
       
   390 
       
   391 TBool CHuiTextVisual::PrepareDrawL()
       
   392 	{
       
   393     if (Flags() & EHuiVisualFlagDrawOnlyAsExternalContent)
       
   394     	{
       
   395    	    // This is used only as external content visual. Return now if we are not currently drawing
       
   396    	    // external content.
       
   397     	if (!Display() || !Display()->RosterImpl().IsDrawingExternalContent())
       
   398     		{
       
   399 			return ETrue;
       
   400     		}
       
   401     	}
       
   402 
       
   403     if(!iText)
       
   404         {
       
   405         return ETrue;
       
   406         }   
       
   407 
       
   408     TReal32 effectiveOpacity = EffectiveOpacity();
       
   409     if(effectiveOpacity <= 0)
       
   410         {
       
   411         return ETrue;
       
   412         }
       
   413         
       
   414     if ( DropShadowHandler() )
       
   415         {
       
   416         if ( DropShadowHandler()->iRadius.Changed() )
       
   417             {
       
   418             iMeshUpdated = EFalse;
       
   419             }
       
   420         }
       
   421 
       
   422     iTextMesh->EnableRasterizedShadow(TBool(DropShadowHandler()));
       
   423 
       
   424     // use directly target rect and thus rasterize the text only once
       
   425     // and not for each frame when the visual's size is changing
       
   426     THuiRealRect content = DisplayRectTarget();
       
   427     content.Shrink(PaddingInPixels());
       
   428     
       
   429     // In wrapping mode, let the mesh know how much space there is
       
   430     // for drawing into.
       
   431     TInt maxWidth = KMaxTInt;
       
   432     if(iLineWrapping != ELineWrapManual)
       
   433         {
       
   434         maxWidth = TInt(content.Width()+0.5f);
       
   435         }
       
   436 
       
   437     // Update the text mesh, if needed. Set max line width first to avoid
       
   438     // rendering with wrong max line width.
       
   439     if(iTextMesh->SetMaxLineWidth(maxWidth) || !iMeshUpdated) 
       
   440         {
       
   441         UpdateMeshL();
       
   442         }
       
   443         
       
   444     if (effectiveOpacity > 0 && 
       
   445         iPictographInterface &&
       
   446         iPictographAnimator && 
       
   447         !iPictographAnimator->IsAnimating())
       
   448         {
       
   449         iPictographAnimator->DrawPictographArea(); // restarts animation timer if needed    
       
   450         }
       
   451         
       
   452 	return ETrue;
       
   453 	}
       
   454 
       
   455 
       
   456 void CHuiTextVisual::DrawSelf(CHuiGc& aGc, const TRect& aDisplayRect) const
       
   457     {
       
   458     if(!iText)
       
   459         {
       
   460         return;
       
   461         }
       
   462 
       
   463     TReal32 effectiveOpacity = EffectiveOpacity();
       
   464     if(effectiveOpacity <= 0)
       
   465         {
       
   466         return;
       
   467         }        
       
   468     aGc.Enable(CHuiGc::EFeatureBlending);
       
   469     aGc.SetAlign(iAlignHorizontal, iAlignVertical);
       
   470     aGc.SetPenAlpha(TInt(effectiveOpacity * 255));
       
   471     
       
   472     // Set up the text color. Priority order is: explicit color set, then by skin ID, then by Hui Style
       
   473     TBool setDefaultColor = ETrue;
       
   474     if ( iFontColorValid )
       
   475         {
       
   476         setDefaultColor = EFalse;
       
   477         aGc.SetPenColor(iFontColor);
       
   478         }
       
   479     else if (iFontColorId != KAknsIIDNone)
       
   480         {
       
   481         TRgb color = KRgbGreen;
       
   482         setDefaultColor = ( CHuiStatic::GetCachedColor(
       
   483                   color, iFontColorId, iFontColorIndex )
       
   484                                 != KErrNone );
       
   485         if ( !setDefaultColor )
       
   486             {
       
   487             aGc.SetPenColor(color);
       
   488             }
       
   489         }
       
   490     else
       
   491         {
       
   492         // setDefaultColor equals to ETrue and so it's ok.
       
   493         }
       
   494 
       
   495     if ( setDefaultColor )
       
   496         {
       
   497         // Default is to use the color indicated by style
       
   498         aGc.SetPenColor(Skin().StyleTextColor(iStyle, iBackgroundType));
       
   499         }    
       
   500 
       
   501     HUI_DEBUGF3(_L("CHuiTextVisual::DrawSelf() -- iStyle=%i, iBackgroundType=%i, lightness=%f"),
       
   502                 iStyle, iBackgroundType, HuiUtil::ColorLightness(aGc.PenColor()));
       
   503 
       
   504     THuiRealRect content = aDisplayRect;
       
   505     content.Shrink(PaddingInPixels());
       
   506     content.iTl += LocalPointInPixels(iOffset.Now());
       
   507 
       
   508     if ( DropShadowHandler() )
       
   509         {
       
   510         aGc.DrawText(*iTextMesh, content, DropShadowHandler()->iOpacity.Now());
       
   511         }
       
   512     else
       
   513         {
       
   514         aGc.DrawText(*iTextMesh, content, 0.f);
       
   515         }
       
   516 
       
   517 
       
   518 	if(iHighlightEnd - iHighlightStart)
       
   519 		{
       
   520 		TPoint textPos(content.iTl.iX, content.iTl.iY);
       
   521 	        
       
   522 	     TSize textBounds = TextExtents();
       
   523 	        
       
   524 	   	switch(iAlignHorizontal)
       
   525 	        {
       
   526 	        case EHuiAlignHRight:
       
   527 	            textPos.iX = content.iBr.iX - textBounds.iWidth;
       
   528 	            break;
       
   529     
       
   530             case EHuiAlignHCenter:
       
   531 	            textPos.iX = content.Center().iX - textBounds.iWidth / 2; // or 2.f?
       
   532 	            break;
       
   533     
       
   534             default:
       
   535 	            break;
       
   536 	   	    }
       
   537 	        
       
   538 	   	switch(iAlignVertical)
       
   539 	       	{
       
   540 	        case EHuiAlignVBottom:
       
   541 	            textPos.iY = content.iBr.iY - textBounds.iHeight;
       
   542 	            break;
       
   543     
       
   544             case EHuiAlignVCenter:
       
   545 	            textPos.iY = content.Center().iY - textBounds.iHeight / 2; // or 2.f?
       
   546 	            break;
       
   547     
       
   548             default:
       
   549 	            break;
       
   550 	       	}
       
   551 	    
       
   552 		THuiRealRect textRect(textPos, textBounds);
       
   553 
       
   554 		// hackish, for now
       
   555 		TBool conversionRequired = ETrue;
       
   556 		if (iHighlightStart > iText->Length() || iHighlightEnd > iText->Length() )
       
   557 		    {
       
   558 		    conversionRequired = ETrue;
       
   559 		    }
       
   560 		
       
   561         const TBidiText::TDirectionality bidiDirection = TBidiText::TextDirectionality( *iText);
       
   562         if ( bidiDirection == TBidiText::ERightToLeft )	        
       
   563 			{
       
   564 			textRect.iBr.iX -= conversionRequired?SubstringExtents(0, iHighlightStart).Width():iHighlightStart;	    
       
   565 		    textRect.iTl.iX = textRect.iBr.iX - conversionRequired?SubstringExtents(iHighlightStart,iHighlightEnd).Width():iHighlightEnd;
       
   566 			}
       
   567 		else
       
   568 			{
       
   569 			textRect.iTl.iX += conversionRequired?SubstringExtents(0, iHighlightStart).Width():iHighlightStart;	    
       
   570 		   	textRect.iBr.iX = textRect.iTl.iX + conversionRequired?SubstringExtents(iHighlightStart,iHighlightEnd).Width():iHighlightEnd;
       
   571 			}
       
   572         
       
   573 	    aGc.SetPenColor(iHighlightColor);
       
   574 	    aGc.DrawRect(textRect);
       
   575 	    aGc.SetPenColor(iHighlightTextColor);
       
   576 
       
   577 		THuiTextStyle* textStyle = CHuiStatic::Env().TextStyleManager().TextStyle(iTextMesh->TextStyle());
       
   578 		
       
   579 		textRect.Move(- textPos.iX, - textPos.iY);
       
   580 		
       
   581 		textStyle->EnableClipping(textRect);
       
   582 		
       
   583 		TRAPD(error,UpdateMeshL());  
       
   584 				
       
   585 		if ( DropShadowHandler() )
       
   586         	{
       
   587         	aGc.DrawText(*iTextMesh, content, DropShadowHandler()->iOpacity.Now());
       
   588         	}
       
   589     	else
       
   590         	{
       
   591 	    	aGc.DrawText(*iTextMesh, content, 0.f);
       
   592         	}
       
   593 
       
   594 		textStyle->DisableClipping();
       
   595 	
       
   596 		TRAP(error,UpdateMeshL());  
       
   597 		
       
   598 	    }
       
   599 
       
   600     }
       
   601 
       
   602 
       
   603 TBool CHuiTextVisual::Changed() const
       
   604     {
       
   605     if(CHuiVisual::Changed())
       
   606         {
       
   607         return ETrue;
       
   608         }
       
   609     return (iOffset.Changed() );
       
   610     }
       
   611 
       
   612 
       
   613 void CHuiTextVisual::ClearChanged()
       
   614     {
       
   615     CHuiVisual::ClearChanged();
       
   616     iOffset.ClearChanged();
       
   617     }
       
   618 
       
   619 
       
   620 void CHuiTextVisual::UpdateMeshL() const
       
   621     {
       
   622     iTextMesh->Reset();
       
   623     iTextMesh->SetTextL(*iText, ETrue);
       
   624     iMeshUpdated = ETrue;
       
   625     iExtentsUpdated = ETrue;    
       
   626     }
       
   627 
       
   628 
       
   629 void CHuiTextVisual::NotifySkinChangedL()
       
   630     {
       
   631     iMeshUpdated = EFalse;
       
   632     iExtentsUpdated = EFalse;    
       
   633     SetChanged();
       
   634     }
       
   635 
       
   636 
       
   637 void CHuiTextVisual::ExpandRectWithContent(TRect& aRect) const
       
   638     {   
       
   639     if(!Clipping() && iText && iText->Length() )
       
   640         {
       
   641         TSize extents = TextExtents();
       
   642         TPoint tl = aRect.Center();
       
   643         
       
   644         // check top left X
       
   645         THuiAlignHorizontal usedHorizontalAlign = iAlignHorizontal;
       
   646         switch(iAlignHorizontal)
       
   647             {
       
   648             case EHuiAlignHLocale:
       
   649                 if(CHuiStatic::LayoutMirrored())
       
   650                     {
       
   651                     usedHorizontalAlign = EHuiAlignHRight;
       
   652                     }
       
   653                 else
       
   654                     {
       
   655                     usedHorizontalAlign = EHuiAlignHLeft;
       
   656                     }
       
   657                 break;
       
   658 
       
   659             case EHuiAlignHLocaleMirrored:
       
   660                 if(CHuiStatic::LayoutMirrored())
       
   661                     {
       
   662                     usedHorizontalAlign = EHuiAlignHLeft;
       
   663                     }
       
   664                 else
       
   665                     {
       
   666                     usedHorizontalAlign = EHuiAlignHRight;
       
   667                     }
       
   668                 break;
       
   669             case EHuiAlignHBidirectionalText:
       
   670                 {
       
   671                 TBool bidiInformationFound = EFalse;
       
   672                 const TBidiText::TDirectionality bidiDirection = TBidiText::TextDirectionality( *iText, &bidiInformationFound );
       
   673                 if ( bidiInformationFound )
       
   674                     {
       
   675                     if ( bidiDirection == TBidiText::ELeftToRight )
       
   676                         {
       
   677                         usedHorizontalAlign = EHuiAlignHLeft;
       
   678                         }
       
   679                     else // ERightToLeft
       
   680                         {
       
   681                         usedHorizontalAlign = EHuiAlignHRight;
       
   682                         }
       
   683                     }
       
   684                 else // fall back... use locale
       
   685                     {
       
   686                     if(CHuiStatic::LayoutMirrored())
       
   687                         {
       
   688                         usedHorizontalAlign = EHuiAlignHRight;
       
   689                         }
       
   690                     else
       
   691                         {
       
   692                         usedHorizontalAlign = EHuiAlignHLeft;
       
   693                         }
       
   694                     }
       
   695                 }
       
   696                 break;
       
   697             case EHuiAlignHBidirectionalTextMirrored:
       
   698                 {
       
   699                 TBool bidiInformationFound = EFalse;
       
   700                 const TBidiText::TDirectionality bidiDirection = TBidiText::TextDirectionality( *iText, &bidiInformationFound );
       
   701                 if ( bidiInformationFound )
       
   702                     {
       
   703                     if ( bidiDirection == TBidiText::ELeftToRight )
       
   704                         {
       
   705                         usedHorizontalAlign = EHuiAlignHRight;
       
   706                         }
       
   707                     else // ERightToLeft
       
   708                         {
       
   709                         usedHorizontalAlign = EHuiAlignHLeft;
       
   710                         }
       
   711                     }
       
   712                 else // fall back... use locale mirrored
       
   713                     {
       
   714                     if(CHuiStatic::LayoutMirrored())
       
   715                         {
       
   716                         usedHorizontalAlign = EHuiAlignHLeft;
       
   717                         }
       
   718                     else
       
   719                         {
       
   720                         usedHorizontalAlign = EHuiAlignHRight;
       
   721                         }
       
   722                     }
       
   723                 }
       
   724                 break;
       
   725             default:
       
   726                 break;
       
   727             }
       
   728         
       
   729         switch( usedHorizontalAlign )
       
   730             {
       
   731             case EHuiAlignHLeft:
       
   732                 tl.iX = aRect.iTl.iX;
       
   733                 break;
       
   734             case EHuiAlignHCenter:
       
   735                 tl.iX -= extents.iWidth/2;
       
   736                 break;
       
   737             case EHuiAlignHRight:
       
   738                 tl.iX = aRect.iBr.iX - extents.iWidth;
       
   739                 break;
       
   740             default:
       
   741                 break;
       
   742             }
       
   743             
       
   744         // check top left Y
       
   745         switch( iAlignVertical )
       
   746             {
       
   747             case EHuiAlignVTop:
       
   748                 tl.iY = aRect.iTl.iY;
       
   749                 break;
       
   750             case EHuiAlignVCenter:
       
   751                 tl.iY -= extents.iHeight/2;
       
   752                 break;
       
   753             case EHuiAlignVBottom:
       
   754                 tl.iY = aRect.iBr.iY - extents.iHeight;
       
   755                 break;
       
   756             default:
       
   757                 break;
       
   758             }
       
   759         
       
   760         TRect textExtendsRect(tl, extents);
       
   761         textExtendsRect.Grow(1,1); // fix rounding errors from Center() and /2 functions.
       
   762 
       
   763         textExtendsRect.Move(TPoint(LocalPointInPixels(iOffset.Now()))); 
       
   764                 
       
   765         aRect.BoundingRect(textExtendsRect);
       
   766        
       
   767         
       
   768         // add shadow
       
   769         CHuiDropShadow* shadowHandler = DropShadowHandler();
       
   770         if ( shadowHandler &&
       
   771              !HuiUtil::RealCompare( shadowHandler->iScale.Now(), 0.f ) &&
       
   772              !HuiUtil::RealCompare( shadowHandler->iOpacity.Now(), 0.f ) )
       
   773             {
       
   774             iTextMesh->ExpandRectWithShadow( aRect );
       
   775             }
       
   776         }
       
   777 
       
   778     CHuiVisual::ExpandRectWithContent(aRect);
       
   779     }
       
   780     
       
   781 
       
   782 EXPORT_C void CHuiTextVisual::SetTextStyle(TInt aTextStyleId)
       
   783     {
       
   784     iTextMesh->SetTextStyle(aTextStyleId);
       
   785     
       
   786     iMeshUpdated = EFalse;
       
   787     iExtentsUpdated = EFalse;
       
   788     iStyle = STATIC_CAST(THuiPreconfiguredTextStyle, aTextStyleId);
       
   789     SetChanged();
       
   790     }
       
   791 
       
   792 EXPORT_C TInt CHuiTextVisual::TextStyle() const
       
   793     {
       
   794     return iStyle;   
       
   795     }
       
   796 
       
   797 
       
   798 EXPORT_C void CHuiTextVisual::SetHighlightRange(TInt aStart, TInt aEnd, TRgb& aHighlightColor, TRgb& aHighlightTextColor)
       
   799 	{
       
   800 	/*
       
   801 	if((aStart < 0) || (aStart > iText->Length()) || (aEnd < 0))
       
   802 		return;
       
   803 	
       
   804 	if(aStart >= aEnd)
       
   805 		return;
       
   806 	
       
   807 	if(aEnd > iText->Length())
       
   808 		aEnd = iText->Length();
       
   809 	*/
       
   810     iHighlightStart = aStart;
       
   811     iHighlightEnd = aEnd;
       
   812       
       
   813     iHighlightColor = aHighlightColor;
       
   814     iHighlightTextColor = aHighlightTextColor;
       
   815     
       
   816     SetChanged();
       
   817 	}
       
   818 
       
   819 EXPORT_C void CHuiTextVisual::UpdateMeshL(const TDesC8& aBuffer)
       
   820     {
       
   821     iTextMesh->UpdateMeshL(aBuffer);
       
   822     if (!iText)
       
   823         {
       
   824         SetTextL(KNullDesC);
       
   825         }
       
   826 
       
   827     SetChanged();
       
   828     }