idlehomescreen/xmluirendering/uiengine/src/xnuiengineimpl.cpp
changeset 0 f72a12da539e
child 1 5315654608de
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2002-2008 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:  Layout calculation and UI rendering mechanism implementations.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // System includes
       
    20 #include <utf.h>
       
    21 #include <eikapp.h>
       
    22 #include <AknUtils.h>
       
    23 #include <layoutmetadata.cdl.h>
       
    24 
       
    25 // User includes
       
    26 #include "xnuiengine.h"
       
    27 #include "xnuiengineimpl.h"
       
    28 #include "xnuistatelistener.h"
       
    29 #include "xnpointerarray.h"
       
    30 #include "xnodt.h"
       
    31 #include "xndomlist.h"
       
    32 #include "xndompropertyvalue.h"
       
    33 #include "xnmenuadapter.h"
       
    34 #include "xnpopupcontroladapter.h"
       
    35 #include "xnviewdata.h"
       
    36 #include "xnnodebreadthfirstiterator.h"
       
    37 #include "xntype.h"
       
    38 #include "xnnodepluginif.h"
       
    39 #include "xncomponentnodeimpl.h"
       
    40 #include "xnproperty.h"
       
    41 #include "xnappuiadapter.h"
       
    42 #include "xnviewadapter.h"
       
    43 #include "xnwidgetextensionadapter.h"
       
    44 #include "xnscrollablecontroladapter.h"
       
    45 #include "xnkeyeventdispatcher.h"
       
    46 #include <aknlayoutscalable_avkon.cdl.h>
       
    47 #include "xuikon_builds_cfg.hrh"
       
    48 #include "xndomdocument.h"
       
    49 #include "xndomnode.h"
       
    50 #include "xneditmode.h"
       
    51 #include "xnhittest.h"
       
    52 #include "xnnode.h"
       
    53 #include "xnpanic.h"
       
    54 #include "xneffectmanager.h"
       
    55 
       
    56 #ifdef _XN_PERFORMANCE_TEST_
       
    57 #include "xntimemon.h"
       
    58 #endif
       
    59 
       
    60 // CONSTANTS
       
    61 const TInt KXnBorderThin = 1;
       
    62 const TInt KXnBorderMedium = 3;
       
    63 const TInt KXnBorderThick = 5;
       
    64 const TInt KXnStackPriorityKeyEventDispatcher = 55;
       
    65 const TInt KFocusGrowValue = 3;
       
    66 
       
    67 _LIT8( KBoxNodeName, "box" );
       
    68 _LIT8( KButtonNodeName, "button" );
       
    69 _LIT8( KWidgetNodeName, "widget" );
       
    70 _LIT8( KWidgetExtensionNodeName, "widgetextension" );
       
    71 _LIT8( KScrollableBoxNodeName, "scrollablebox" );
       
    72 _LIT8( KMenuBar, "menubar" );
       
    73 _LIT8( KPopUpNodeName, "popup" );
       
    74 
       
    75 _LIT8( KPlugin, "plugin" );
       
    76 
       
    77 // LOCAL CONSTANTS AND MACROS
       
    78 static const TReal KIntConversionConstant = 0.5;
       
    79 static const TReal KIntPercentageConstant =
       
    80     static_cast< TReal >( 1 ) / static_cast< TReal >( 100 );
       
    81 static const TReal KInchesAsTwips = 1440;
       
    82 static const TReal KCentimetersAsInches = static_cast< TReal >( 1 ) / 2.54;
       
    83 static const TReal KCentimetersAsTwips = KCentimetersAsInches * KInchesAsTwips;
       
    84 static const TReal KMillimetersAsInches =
       
    85     KCentimetersAsInches / static_cast< TReal >( 10 );
       
    86 static const TReal KMillimetersAsTwips = KMillimetersAsInches * KInchesAsTwips;
       
    87 static const TReal KPointsAsInches =
       
    88     static_cast< TReal >( 1 ) / static_cast< TReal >( 72 );
       
    89 static const TReal KPointsAsTwips = KPointsAsInches * KInchesAsTwips;
       
    90 static const TReal KPicasAsInches =
       
    91     KPointsAsInches / static_cast< TReal >( 12 );
       
    92 static const TReal KPicasAsTwips = KPicasAsInches * KInchesAsTwips;
       
    93 
       
    94 // MODULE DATA STRUCTURES
       
    95 
       
    96 // LOCAL FUNCTION PROTOTYPES
       
    97 
       
    98 static TRect AddRect( const TRect& aOriginal, const TRect& aAdded );
       
    99 static TRect SubtractRect( const TRect& aOriginal, const TRect& aSubtracter );
       
   100 static TSize AutoStaticBTL( CXnNode& aNode, TInt aWidthToFit,
       
   101     TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
       
   102     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   103     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   104 static TSize AutoStaticLRL( CXnNode& aNode, TInt aWidthToFit,
       
   105     TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
       
   106     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   107     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   108 static TSize AutoStaticRLL( CXnNode& aNode, TInt aWidthToFit,
       
   109     TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
       
   110     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   111     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   112 static TSize AutoStaticTBL( CXnNode& aNode, TInt aWidthToFit,
       
   113     TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties,
       
   114     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   115     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   116 static void CalculateAbsolutePositionsL( CXnNode& aNode,
       
   117     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   118     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   119 static void CalculateBorderL( CXnNode& aNode,
       
   120     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   121     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   122 static void CalculateMarginL( CXnNode& aParent, CXnNode& aNode,
       
   123     CXnNode* aPreviousSibling, const TDesC8& aParentBlockProgression,
       
   124     const TDesC8& aParentDirection, TRect& aParentRect,
       
   125     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   126     TReal aVerticalUnitInPixels, TInt& aColumnWidth, TInt& aColumnMargin );
       
   127 static void CalculatePaddingL( const TRect& aParentRect, CXnNode& aNode,
       
   128     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   129     TReal aVerticalUnitInPixels );
       
   130 
       
   131 static void CalculateRectL( CXnNode& aNode, CXnNode& aParent,
       
   132     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   133     TReal aVerticalUnitInPixels );
       
   134 
       
   135 static void CalculateRelativePositionsL( const TRect& aRect, CXnNode& aNode,
       
   136     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   137     TReal aVerticalUnitInPixels );
       
   138 static TSize CalculateSpaceUsedByChildrenL( RPointerArray< CXnNode >& aChildren,
       
   139     CXnNode& aNode, const TDesC8& aParentBlockProgression,
       
   140     const TDesC8& aParentDirection, CGraphicsDevice& aScreenDevice,
       
   141     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   142 
       
   143 static TSize CalculateTotalDimensionsL( CXnNode& aNode, TBool aIgnoreAutoValues,
       
   144     TBool aIgnoreMinSizes, TRect& aParentRect,
       
   145     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   146     TReal aVerticalUnitInPixels );
       
   147 static TBool CutOnePixelFromPercentChildNodeL( CXnNode& aNode,
       
   148     const TDesC8& aParentBlockProgression );
       
   149 static void DetermineBorderWidthsL( CXnProperty* aBorderWidthProperty,
       
   150     TInt& aBordervertical, TInt& aBorderhorizontal,
       
   151     TRect& aParentRect, CGraphicsDevice& aGraphicsDevice,
       
   152     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   153 static TInt DisplayedChildrenCountL( CXnNode& aNode,
       
   154     RPointerArray< CXnNode >* aDisplayedChildren = NULL );
       
   155 static CXnNode* DisplayedParentL( CXnNode& aNode );
       
   156 static CXnDomPropertyValue* DomPropertyValueFromProperty(
       
   157     CXnProperty* aProperty );
       
   158 static void DropExceedingRectL( const TRect& aParentRect, CXnNode& aNode,
       
   159     TBool aDropRelativeNode = EFalse );
       
   160 static TBool CalculateExceedingArea( CXnNode& aParent, CXnNode& aChild,
       
   161     TInt& aLeftOffset, TInt& aRightOffset, TInt& aTopOffset,
       
   162     TInt& aBottomOffset );
       
   163 static void AdjustRectsL( CXnNode& aNode, TInt aLeftOffset, TInt aRightOffset,
       
   164     TInt aTopOffset, TInt aBottomOffset );
       
   165 static void ClearRects( CXnNode& aNode, TBool aRecurse = EFalse );
       
   166 static void FitChildrenIntoParentL( CXnNode& aNode,
       
   167     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   168     TReal aVerticalUnitInPixels );
       
   169 static TInt GetPositionL( CXnNode& aNode, 
       
   170     const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection );
       
   171 static TInt HasNodeAutoValuesL( CXnNode& aNode );
       
   172 static TInt HasNodeHorizontalAutoValuesL( CXnNode& aNode );
       
   173 static TInt HasNodeVerticalAutoValuesL( CXnNode& aNode );
       
   174 static TBool HasNodeMinSizesL( CXnNode& aNode );
       
   175 static TBool HasNodeMaxSizesL( CXnNode& aNode );
       
   176 static TInt HorizontalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
       
   177     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels );
       
   178 static TInt HorizontalValueToPixelsL( CXnDomPropertyValue* aValue,
       
   179     TReal aReferenceValue, CGraphicsDevice& aScreenDevice,
       
   180     TReal aHorizontalUnitInPixels );
       
   181 static void GrowToMinSizeL( CXnNode& aNode, TRect& aParentRect,
       
   182     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
       
   183     TReal aVerticalUnitInPixels );
       
   184 static void ShrinkToMaxSizeL( CXnNode& aNode, TRect& aParentRect,
       
   185     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
       
   186     TReal aVerticalUnitInPixels );
       
   187 static TBool IsAbsoluteL( CXnNode& aNode );
       
   188 static TBool IsLargerThanMaxSizeL( const TRect& aParentRect, CXnNode& aNode,
       
   189     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
       
   190     TReal aVerticalUnitInPixels );
       
   191 static TBool IsNodeDisplayedL( CXnNode& aNode );
       
   192 
       
   193 static TBool IsNodeTooltip( CXnNode& aNode );
       
   194 static TBool IsPropertyAutoL( CXnProperty& aProperty );
       
   195 static TBool IsPropertyNone( CXnProperty& aProperty );
       
   196 static TBool IsRelativeL( CXnNode& aNode );
       
   197 static TBool IsSmallerThanMinSizeL( const TRect& aParentRect, CXnNode& aNode,
       
   198     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
       
   199     TReal aVerticalUnitInPixels );
       
   200 static TBool IsValuePercentageL( CXnProperty& aProperty );
       
   201 static TInt PercentageToPixelsL( TReal& aPercentage, TReal aReferenceValue );
       
   202 static void PlaceAreasL( CXnNode& aNode,
       
   203     RPointerArray< CXnNode >& aLaidOutList,
       
   204     TInt aLayoutPhase, CGraphicsDevice& aGraphicsDevice,
       
   205     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   206 static void PriorizeChildrenL( CXnNode& aNode );
       
   207 static void CalculateAutoPropertiesOfNodesL(
       
   208     RPointerArray< CXnNode >* aAutoNodeArray, TInt& aWidthAutoCount,
       
   209     TInt& aHeightAutoCount );
       
   210 static void ProcessAutoAreasL( CXnNode& aParentNode,
       
   211     RPointerArray< CXnNode >* aArray, const TDesC8& aParentBlockProgression,
       
   212     const TDesC8& aParentDirection, CGraphicsDevice& aGraphicsDevice,
       
   213     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels );
       
   214 static void CalculateCollapseMarginsL( RPointerArray< CXnNode >& aChildren,
       
   215     RArray< TInt >& aCollapsedMarginsWidth, 
       
   216     RArray< TInt >& aCollapsedMarginsHeight,
       
   217     const TDesC8& aParentBlockProgression,
       
   218     const TDesC8& aParentDirection );
       
   219 static TSize CalculateSpaceUsedByAutoChildrenL(
       
   220     RPointerArray< CXnNode >& aAutoChildren,
       
   221     RPointerArray< CXnNode >& aCalculatedAutoChildren,
       
   222     CXnNode& aParent,
       
   223     const TDesC8& aParentBlockProgression,
       
   224     const TDesC8& aParentDirection,
       
   225     CGraphicsDevice& aScreenDevice );
       
   226 static void MoveAutoAreaL( TRect& parentRect,
       
   227     RPointerArray< CXnNode >& aChildren,
       
   228     const TDesC8& aParentBlockProgression,
       
   229     const TDesC8& aParentDirection );
       
   230 static TSize ScaleAutoAreaL( CXnNode& aNode, TInt aWidthToFit,
       
   231     TInt aHeightToFit, const TDesC8& aParentBlockProgression,
       
   232     const TDesC8& aParentDirection, TRect& aParentRect,
       
   233     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   234     TReal aVerticalUnitInPixels );
       
   235 static void FitAutoChildrenIntoParentL( RPointerArray< CXnNode >& aAutoChildren,
       
   236     RPointerArray< CXnNode >& aCalculatedAutoChildren, CXnNode& aParent,
       
   237     const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
       
   238     CGraphicsDevice& aGraphicsDevice );
       
   239 static TInt VerticalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
       
   240     CGraphicsDevice& aScreenDevice, TReal aVerticalUnitInPixels );
       
   241 static TInt VerticalValueToPixelsL( CXnDomPropertyValue* aValue,
       
   242     TReal aReferenceValue, CGraphicsDevice& aScreenDevice,
       
   243     TReal aVerticalUnitInPixels );
       
   244 static TBool IsStringValueL( CXnProperty& aProperty );
       
   245 static TInt HorizontalUnitsToPixelsL( TReal aUnits,
       
   246     TReal aHorizontalUnitInPixels );
       
   247 static TInt VerticalUnitsToPixelsL( TReal aUnits, TReal aVerticalUnitInPixels );
       
   248 static void ProcessAdaptiveAreasL( CXnNode& aParent,
       
   249     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   250     TReal aVerticalUnitInPixels );
       
   251 
       
   252 static void CalculateAdaptiveSizeL( CXnNode& aNode,
       
   253     const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
       
   254     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   255     TReal aVerticalUnitInPixels );
       
   256 
       
   257 static CXnNode* BuildTriggerNodeLC( CXnUiEngine& aUiEngine,
       
   258     const TDesC8& aTriggerName );
       
   259 static void UpdateInternalUnits( TReal&  aHorizontalUnitInPixels,
       
   260     TReal& aVerticalUnitInPixels, TRect aRect );
       
   261 static CXnNode* BuildScreenDeviceChangeTriggerNodeLC(
       
   262     CXnUiEngine& aUiEngine );
       
   263 static void FillFocusCandidatesL( CXnNode* aParent,
       
   264     RPointerArray< CXnNode >& aArray );
       
   265 static TInt DetermineStatusPaneLayout( CXnProperty* aProperty );
       
   266 static TBool SetAdaptivesL( CXnNode& aNode );
       
   267 
       
   268 static void FindNodeByClassL( CXnNode* aRootNode, const TDesC8& aClassId,
       
   269     CXnPointerArray& aArray, const TDesC8& aNamespace );
       
   270 static CXnNode* FindNodeByIdL( CXnNode* aRootNode, const TDesC8& aAreaId,
       
   271     const TDesC8& aNamespace );
       
   272 
       
   273 #ifdef _XN3_DEBUG_
       
   274 static void TraceTreeL( CXnNode* aRootNode );
       
   275 #endif
       
   276 
       
   277 // ============================= LOCAL FUNCTIONS ===============================
       
   278 // -----------------------------------------------------------------------------
       
   279 // GrowIfNeeded()
       
   280 // When a plugin is focused, the focus is a bit bigger than its control 
       
   281 // (this is a hack fix to get focus visible with WRT widgets).
       
   282 // Therefore we need to check if focused node is a plugin, 
       
   283 // or focused node has same size with its plugin, and grow dirty rect accordingly.
       
   284 // -----------------------------------------------------------------------------
       
   285 //
       
   286 static void GrowIfNeeded(CXnNode* aNode, TRect& aRect)
       
   287     {
       
   288     CXnNode* focusedNode(NULL);
       
   289     for( CXnNode* node = aNode; node; node = node->Parent() )
       
   290         {
       
   291         if( node->IsStateSet( XnPropertyNames::style::common::KFocus ) )
       
   292             {
       
   293             if( node->DomNode()->Name() == KPlugin )
       
   294                 {
       
   295                 CXnControlAdapter* adapter( node->Control() );
       
   296                 if(adapter)
       
   297                     {
       
   298                     aRect = adapter->Rect();
       
   299                     aRect.Grow( KFocusGrowValue, KFocusGrowValue );
       
   300                     }
       
   301                 break;
       
   302                 }
       
   303             focusedNode = node;
       
   304             }
       
   305         else if( node->DomNode()->Name() == KPlugin )
       
   306             {
       
   307             if( focusedNode && focusedNode->MarginRect() == node->Rect() )
       
   308                 {
       
   309                 CXnControlAdapter* adapter( focusedNode->Control() );
       
   310                 if(adapter)
       
   311                     {
       
   312                     aRect = adapter->Rect();
       
   313                     aRect.Grow( KFocusGrowValue, KFocusGrowValue );
       
   314                     }
       
   315                 }
       
   316             break;
       
   317             }
       
   318         }                            
       
   319     }      
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // -----------------------------------------------------------------------------
       
   323 static TBool IsSrollableBox( CXnNode& aNode )
       
   324     {
       
   325     if( aNode.Type()->Type() == KScrollableBoxNodeName )
       
   326         {
       
   327         return ETrue;
       
   328         }
       
   329     return EFalse;
       
   330     }
       
   331 
       
   332 // -----------------------------------------------------------------------------
       
   333 // FindNodeByClassL()
       
   334 // Finds recursively a node from current view by class
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 static void FindNodeByClassL( CXnNode* aRootNode, const TDesC8& aClassId,
       
   338     CXnPointerArray& aArray, const TDesC8& aNamespace )
       
   339     {
       
   340     ASSERT( aRootNode );
       
   341     
       
   342     if ( aNamespace != KNullDesC8 && aNamespace != aRootNode->Namespace() )
       
   343         {
       
   344         // Recursed to wrong namespace
       
   345         return;
       
   346         }
       
   347             
       
   348     CXnProperty* prop( aRootNode->ClassL() );
       
   349     
       
   350     if ( prop && prop->StringValue() == aClassId )
       
   351         {
       
   352         // Correct id found
       
   353         if ( aNamespace == KNullDesC8 )
       
   354             {
       
   355             aArray.Container().AppendL( aRootNode );
       
   356             }
       
   357         else if ( aNamespace == aRootNode->DomNode()->Namespace() )
       
   358             {
       
   359             // Namespace is defined and this node is in that namespace 
       
   360             // -> this is perfect match
       
   361             aArray.Container().AppendL( aRootNode );
       
   362             }        
       
   363         }
       
   364     
       
   365     // Recurse children
       
   366     RPointerArray< CXnNode >& children( aRootNode->Children() );
       
   367     
       
   368     for ( TInt i = 0; i < children.Count(); i++ )
       
   369         {
       
   370         FindNodeByClassL( children[i], aClassId, aArray, aNamespace );
       
   371         }
       
   372     }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // FindNodeByIdL()
       
   376 // Finds recursively a node from current view by id
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 static CXnNode* FindNodeByIdL( CXnNode* aRootNode, const TDesC8& aAreaId,        
       
   380     const TDesC8& aNamespace )
       
   381     {
       
   382     ASSERT( aRootNode );
       
   383     
       
   384     if ( aNamespace != KNullDesC8 && aNamespace != aRootNode->Namespace() )
       
   385         {
       
   386         // Recursed to wrong namespace
       
   387         return NULL;
       
   388         }
       
   389                 
       
   390     CXnProperty* prop( aRootNode->IdL() );
       
   391     
       
   392     if ( prop && prop->StringValue() == aAreaId )
       
   393         {
       
   394         // Correct id found
       
   395         if ( aNamespace == KNullDesC8 )
       
   396             {
       
   397             // No namespace defined, so this is the first found best match
       
   398             return aRootNode;
       
   399             }
       
   400         else if ( aNamespace == aRootNode->DomNode()->Namespace() )
       
   401             {
       
   402             // Namespace is defined and this node is in that namespace 
       
   403             // -> this is perfect match
       
   404             return aRootNode;
       
   405             }        
       
   406         }
       
   407         
       
   408     // No match found, recurse children
       
   409     RPointerArray< CXnNode >& children( aRootNode->Children() );
       
   410     
       
   411     for ( TInt i = 0; i < children.Count(); i++ )
       
   412         {
       
   413         CXnNode* retval( FindNodeByIdL( children[i], aAreaId, aNamespace ) );
       
   414         
       
   415         if ( retval )
       
   416             {
       
   417             return retval;
       
   418             }
       
   419         }
       
   420     
       
   421     return NULL;
       
   422     }
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // AutoStaticVerticalBTL()
       
   426 // Calculate properties set to AUTO when positioning is static, layout vertical
       
   427 // and direction right-to-left
       
   428 // -----------------------------------------------------------------------------
       
   429 //
       
   430 static TSize AutoStaticBTL( CXnNode& aNode, TInt aWidthToFit, TInt aHeightToFit,
       
   431     RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
       
   432     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   433     TReal aVerticalUnitInPixels )
       
   434     {
       
   435     // Static positioning, vertical, right to left
       
   436     TBool horizontalMarginProcessed = EFalse;
       
   437     TBool verticalMarginProcessed = EFalse;
       
   438     TBool allVerticalValuesProcessed = EFalse;
       
   439     TBool allHorizontalValuesProcessed = EFalse;
       
   440 
       
   441     CXnProperty* maxHeightProperty = aNode.MaxHeightL();
       
   442     CXnProperty* maxWidthProperty = aNode.MaxWidthL();
       
   443     CXnProperty* minHeightProperty = aNode.MinHeightL();
       
   444     CXnProperty* minWidthProperty = aNode.MinWidthL();
       
   445 
       
   446     TRect contentRect( aNode.Rect() );
       
   447     TRect paddingRect( aNode.PaddingRect() );
       
   448     TRect borderRect( aNode.BorderRect() );
       
   449     TRect marginRect( aNode.MarginRect() );
       
   450     TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
   451 
       
   452     TSize size = CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
       
   453         aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
   454 
       
   455     for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
   456         {
       
   457         // search for height property
       
   458         const TDesC8& attributeName = aAutoProperties[i];
       
   459         if ( attributeName == XnPropertyNames::style::common::KHeight )
       
   460             {
       
   461             // height was AUTO, all other vertical auto values are 0
       
   462             TInt newHeight = aHeightToFit - size.iHeight;
       
   463 
       
   464             //  Calculate the difference so that it can be returned
       
   465             TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
       
   466             TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
   467             TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
   468             TRect normalFlowBorderRectDiff( SubtractRect ( normalFlowBorderRect,
       
   469                 contentRect ) );
       
   470 
       
   471             // grow height to fill the void
       
   472             contentRect.SetHeight( newHeight );
       
   473             paddingRect = AddRect( contentRect, paddingRectDiff );
       
   474             borderRect = AddRect( contentRect, borderRectDiff );
       
   475             normalFlowBorderRect = AddRect( contentRect,
       
   476                 normalFlowBorderRectDiff );
       
   477             marginRect = AddRect( contentRect, marginRectDiff );
       
   478 
       
   479             size = TSize( size.iWidth, aHeightToFit );
       
   480             }
       
   481         }
       
   482 
       
   483     // if exactly one value is AUTO, value is computed to make equality true
       
   484     if ( aAutoProperties.Count() == 1 )
       
   485         {
       
   486         if ( !allHorizontalValuesProcessed )
       
   487             {
       
   488             const TDesC8& attributeName = aAutoProperties[0];
       
   489             if ( attributeName == XnPropertyNames::style::common::KWidth )
       
   490                 {
       
   491                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
   492                 if ( remainingWidth < 0 )
       
   493                     {
       
   494                     remainingWidth = 0;
       
   495                     }
       
   496                 //  Calculate the difference so that it can be returned
       
   497                 TRect paddingRectDiff( SubtractRect( paddingRect,
       
   498                     contentRect ) );
       
   499                 TRect borderRectDiff( SubtractRect( borderRect,
       
   500                     contentRect ) );
       
   501                 TRect marginRectDiff( SubtractRect( marginRect,
       
   502                     contentRect ) );
       
   503                 TRect normalFlowBorderRectDiff( SubtractRect(
       
   504                     normalFlowBorderRect, contentRect ) );
       
   505 
       
   506                 // grow width to fill the void
       
   507                 contentRect.SetWidth( remainingWidth );
       
   508                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
   509                 borderRect = AddRect( contentRect, borderRectDiff );
       
   510                 normalFlowBorderRect = AddRect( contentRect,
       
   511                     normalFlowBorderRectDiff );
       
   512                 marginRect = AddRect( contentRect, marginRectDiff );
       
   513 
       
   514                 size = TSize( aWidthToFit, size.iHeight );
       
   515                 }
       
   516 
       
   517             if ( attributeName ==
       
   518                  XnPropertyNames::style::common::KMarginLeft )
       
   519                 {
       
   520                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
   521                 if ( remainingWidth < 0 )
       
   522                     {
       
   523                     remainingWidth = 0;
       
   524                     }
       
   525                 contentRect.Move( remainingWidth, 0 );
       
   526                 borderRect.Move( remainingWidth, 0 );
       
   527                 normalFlowBorderRect.Move( remainingWidth, 0 );
       
   528                 marginRect.Resize( remainingWidth, 0 );
       
   529                 paddingRect.Move( remainingWidth, 0 );
       
   530                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
   531                 }
       
   532 
       
   533             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
   534                 {
       
   535                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
   536                 if ( remainingWidth < 0 )
       
   537                     {
       
   538                     remainingWidth = 0;
       
   539                     }
       
   540                 marginRect.Resize( remainingWidth, 0 );
       
   541                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
   542                 }
       
   543 
       
   544             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
   545                 {
       
   546                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
   547                 if ( remainingHeight < 0 )
       
   548                     {
       
   549                     remainingHeight = 0;
       
   550                     }
       
   551                 marginRect.Resize( 0, remainingHeight );
       
   552                 marginRect.Move( 0, -remainingHeight );
       
   553                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
   554                 }
       
   555 
       
   556             if ( attributeName == 
       
   557                  XnPropertyNames::style::common::KMarginBottom )
       
   558                 {
       
   559                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
   560                 if ( remainingHeight < 0 )
       
   561                     {
       
   562                     remainingHeight = 0;
       
   563                     }
       
   564                 marginRect.Resize( 0, remainingHeight );
       
   565                 marginRect.Move( 0, -remainingHeight );
       
   566                 paddingRect.Move( 0, -remainingHeight );
       
   567                 borderRect.Move( 0, -remainingHeight );
       
   568                 normalFlowBorderRect.Move( 0, -remainingHeight );
       
   569                 contentRect.Move( 0, -remainingHeight );
       
   570                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
   571                 }
       
   572             }
       
   573         }
       
   574     else
       
   575         {
       
   576         for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
   577             {
       
   578             const TDesC8& attributeName = aAutoProperties[i];
       
   579             if ( attributeName == XnPropertyNames::style::common::KWidth )
       
   580                 {
       
   581                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
   582                 if ( remainingWidth < 0 )
       
   583                     {
       
   584                     remainingWidth = 0;
       
   585                     }
       
   586                 //  Calculate the difference so that it can be returned
       
   587                 TRect paddingRectDiff( SubtractRect(
       
   588                     paddingRect, contentRect ) );
       
   589                 TRect borderRectDiff( SubtractRect(
       
   590                     borderRect, contentRect ) );
       
   591                 TRect marginRectDiff( SubtractRect(
       
   592                     marginRect, contentRect ) );
       
   593                 TRect normalFlowBorderRectDiff( SubtractRect(
       
   594                     normalFlowBorderRect, contentRect ) );
       
   595 
       
   596                 // grow width to fill the void
       
   597                 contentRect.SetWidth( remainingWidth );
       
   598                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
   599                 borderRect = AddRect( contentRect, borderRectDiff );
       
   600                 normalFlowBorderRect = AddRect(
       
   601                     contentRect, normalFlowBorderRectDiff );
       
   602                 marginRect = AddRect( contentRect, marginRectDiff );
       
   603 
       
   604                 size = TSize( aWidthToFit, size.iHeight );
       
   605                 }
       
   606 
       
   607             // several auto properties
       
   608             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
   609                 {
       
   610                 if ( !horizontalMarginProcessed )
       
   611                     {
       
   612                     // is right margin also set to AUTO?
       
   613                     CXnProperty* rightMargin = aNode.MarginRightL();
       
   614                     if ( rightMargin )
       
   615                         {
       
   616                         if ( IsPropertyAutoL( *rightMargin ) )
       
   617                             {
       
   618                             // both margins set to AUTO, values equal
       
   619                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
   620                             if ( remainingWidth < 0 )
       
   621                                 {
       
   622                                 remainingWidth = 0;
       
   623                                 }
       
   624                             // move rect right to fill the void
       
   625                             contentRect.Move( ( remainingWidth / 2 ), 0 );
       
   626                             marginRect.Resize( remainingWidth, 0 );
       
   627                             borderRect.Move( ( remainingWidth / 2 ), 0 );
       
   628                             normalFlowBorderRect.Move( (
       
   629                                 remainingWidth / 2 ), 0 );
       
   630                             paddingRect.Move( remainingWidth / 2, 0 );
       
   631                             horizontalMarginProcessed = ETrue;
       
   632                             size = TSize( size.iWidth + remainingWidth,
       
   633                                 size.iHeight );
       
   634                             }
       
   635                         else
       
   636                             {
       
   637                             // only left margin set to AUTO
       
   638                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
   639                             if ( remainingWidth < 0 )
       
   640                                 {
       
   641                                 remainingWidth = 0;
       
   642                                 }
       
   643                             // move rect right to fill the void
       
   644                             contentRect.Move( ( remainingWidth ), 0 );
       
   645                             marginRect.Resize( remainingWidth, 0 );
       
   646                             borderRect.Move( remainingWidth, 0 );
       
   647                             normalFlowBorderRect.Move( remainingWidth, 0 );
       
   648                             paddingRect.Move( remainingWidth, 0 );
       
   649                             horizontalMarginProcessed = ETrue;
       
   650                             size = TSize( size.iWidth + remainingWidth,
       
   651                                 size.iHeight );
       
   652                             }
       
   653                         }
       
   654                     }
       
   655                 }
       
   656             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
   657                 {
       
   658                 if ( !horizontalMarginProcessed )
       
   659                     {
       
   660                     // is left margin also set to AUTO?
       
   661                     CXnProperty* leftMargin = aNode.MarginLeftL();
       
   662                     if ( leftMargin )
       
   663                         {
       
   664                         if ( IsPropertyAutoL( *leftMargin ) )
       
   665                             {
       
   666                             // both margins set to AUTO, values equal
       
   667                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
   668                             if ( remainingWidth < 0 )
       
   669                                 {
       
   670                                 remainingWidth = 0;
       
   671                                 }
       
   672                             contentRect.Move( remainingWidth / 2, 0 );
       
   673                             marginRect.Resize( remainingWidth, 0 );
       
   674                             borderRect.Move( ( remainingWidth / 2 ), 0 );
       
   675                             normalFlowBorderRect.Move( ( 
       
   676                                 remainingWidth / 2 ), 0 );
       
   677                             paddingRect.Move( remainingWidth / 2, 0 );
       
   678                             horizontalMarginProcessed = ETrue;
       
   679                             size = TSize( size.iWidth + remainingWidth,
       
   680                                 size.iHeight );
       
   681                             }
       
   682                         else
       
   683                             {
       
   684                             // only right margin set to AUTO
       
   685                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
   686                             if ( remainingWidth < 0 )
       
   687                                 {
       
   688                                 remainingWidth = 0;
       
   689                                 }
       
   690                             marginRect.Resize( remainingWidth, 0 );
       
   691                             horizontalMarginProcessed = ETrue;
       
   692                             size = TSize( size.iWidth + remainingWidth,
       
   693                                 size.iHeight );
       
   694                             }
       
   695                         }
       
   696                     }
       
   697                 }
       
   698             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
   699                 {
       
   700                 if ( !verticalMarginProcessed &&
       
   701                      !allVerticalValuesProcessed )
       
   702                     {
       
   703                     // is bottom margin also set to AUTO?
       
   704                     CXnProperty* bottomMargin = aNode.MarginBottomL();
       
   705                     if ( bottomMargin )
       
   706                         {
       
   707                         if ( IsPropertyAutoL( *bottomMargin ) )
       
   708                             {
       
   709                             // both margins set to AUTO, values equal
       
   710                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
   711                             if ( remainingHeight < 0 )
       
   712                                 {
       
   713                                 remainingHeight = 0;
       
   714                                 }
       
   715                             contentRect.Move( 0, remainingHeight / 2 );
       
   716                             marginRect.Resize( 0, remainingHeight );
       
   717                             borderRect.Move( 0, ( remainingHeight / 2 ) );
       
   718                             normalFlowBorderRect.Move(
       
   719                                 0, ( remainingHeight / 2 ) );
       
   720                             paddingRect.Move( 0, remainingHeight / 2 );
       
   721                             verticalMarginProcessed = ETrue;
       
   722                             size = TSize( size.iWidth,
       
   723                                 size.iHeight + remainingHeight );
       
   724                             }
       
   725                         else
       
   726                             {
       
   727                             // only top margin set to AUTO
       
   728                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
   729                             if ( remainingHeight < 0 )
       
   730                                 {
       
   731                                 remainingHeight = 0;
       
   732                                 }
       
   733                             marginRect.Resize( 0, remainingHeight );
       
   734                             marginRect.Move( 0, -remainingHeight );
       
   735                             verticalMarginProcessed = ETrue;
       
   736                             size = TSize( size.iWidth,
       
   737                                 size.iHeight + remainingHeight );
       
   738                             }
       
   739                         }
       
   740                     }
       
   741                 }
       
   742             if ( attributeName == 
       
   743                  XnPropertyNames::style::common::KMarginBottom )
       
   744                 {
       
   745                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
   746                     {
       
   747                     // is top margin also set to AUTO?
       
   748                     CXnProperty* topMargin = aNode.MarginTopL();
       
   749                     if ( topMargin )
       
   750                         {
       
   751                         if ( IsPropertyAutoL( *topMargin ) )
       
   752                             {
       
   753                             // both margins set to AUTO, values equal
       
   754                             TInt remainingHeight =  aHeightToFit - size.iHeight;
       
   755                             if ( remainingHeight < 0 )
       
   756                                 {
       
   757                                 remainingHeight = 0;
       
   758                                 }
       
   759                             contentRect.Move( 0, -( remainingHeight / 2 ) );
       
   760                             marginRect.Resize( 0, remainingHeight );
       
   761                             marginRect.Move( 0, -remainingHeight );
       
   762                             borderRect.Move( 0, -( remainingHeight / 2 ) );
       
   763                             normalFlowBorderRect.Move(
       
   764                                 0, -( remainingHeight / 2 ) );
       
   765                             paddingRect.Move( 0, -( remainingHeight / 2 ) );
       
   766                             verticalMarginProcessed = ETrue;
       
   767                             size = TSize( size.iWidth,
       
   768                                 size.iHeight + remainingHeight );
       
   769                             }
       
   770                         else
       
   771                             {
       
   772                             // only bottom margin set to AUTO
       
   773                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
   774                             if ( remainingHeight < 0 )
       
   775                                 {
       
   776                                 remainingHeight = 0;
       
   777                                 }
       
   778                             contentRect.Move( 0, -remainingHeight );
       
   779                             marginRect.Resize( 0, remainingHeight );
       
   780                             marginRect.Move( 0, -remainingHeight );
       
   781                             borderRect.Move( 0, -remainingHeight );
       
   782                             normalFlowBorderRect.Move(
       
   783                                 0, -remainingHeight );
       
   784                             paddingRect.Move( 0, -remainingHeight );
       
   785                             verticalMarginProcessed = ETrue;
       
   786                             size = TSize( size.iWidth,
       
   787                                 size.iHeight + remainingHeight );
       
   788                             }
       
   789                         }
       
   790                     }
       
   791                 }
       
   792             }
       
   793         }
       
   794     aNode.SetRect( contentRect );
       
   795     aNode.SetPaddingRect( paddingRect );
       
   796     aNode.SetBorderRect( borderRect );
       
   797     aNode.SetMarginRect( marginRect );
       
   798     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
   799     return contentRect.Size();
       
   800     }
       
   801 
       
   802 // -----------------------------------------------------------------------------
       
   803 // AutoStaticLRL()
       
   804 // Calculate properties set to AUTO when positioning is static,
       
   805 // layout horizontal
       
   806 // and direction left-to-right
       
   807 // -----------------------------------------------------------------------------
       
   808 //
       
   809 static TSize AutoStaticLRL( CXnNode& aNode, TInt aWidthToFit, TInt aHeightToFit,
       
   810     RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
       
   811     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
   812     TReal aVerticalUnitInPixels )
       
   813     {
       
   814     // Static positioning, horizontal, left to right
       
   815     TBool horizontalMarginProcessed = EFalse;
       
   816     TBool verticalMarginProcessed = EFalse;
       
   817     TBool allVerticalValuesProcessed = EFalse;
       
   818     TBool allHorizontalValuesProcessed = EFalse;
       
   819 
       
   820     CXnProperty* maxHeightProperty = aNode.MaxHeightL();
       
   821     CXnProperty* maxWidthProperty = aNode.MaxWidthL();
       
   822     CXnProperty* minHeightProperty = aNode.MinHeightL();
       
   823     CXnProperty* minWidthProperty = aNode.MinWidthL();
       
   824 
       
   825     TRect contentRect = aNode.Rect();
       
   826     TRect paddingRect = aNode.PaddingRect();
       
   827     TRect borderRect = aNode.BorderRect();
       
   828     TRect marginRect = aNode.MarginRect();
       
   829     TRect normalFlowBorderRect = aNode.NormalFlowBorderRect();
       
   830     TSize size = CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
       
   831         aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
   832 
       
   833     for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
   834         {
       
   835         // search for width property
       
   836         const TDesC8& attributeName = aAutoProperties[i];
       
   837         if ( attributeName == XnPropertyNames::style::common::KWidth )
       
   838             {
       
   839             // width was AUTO, all other vertical auto values are 0
       
   840             TInt newWidth = aWidthToFit - size.iWidth;
       
   841 
       
   842             //  Calculate the difference so that it can be returned
       
   843             TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
       
   844             TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
   845             TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
   846             TRect normalFlowBorderRectDiff( SubtractRect( normalFlowBorderRect,
       
   847                 contentRect ) );
       
   848 
       
   849             // grow width to fill the void
       
   850             contentRect.SetWidth( newWidth );
       
   851             paddingRect = AddRect( contentRect, paddingRectDiff );
       
   852             borderRect = AddRect( contentRect, borderRectDiff );
       
   853             normalFlowBorderRect = AddRect(
       
   854                 contentRect, normalFlowBorderRectDiff );
       
   855             marginRect = AddRect( contentRect, marginRectDiff );
       
   856 
       
   857             size = TSize( aWidthToFit, size.iHeight );
       
   858             allHorizontalValuesProcessed = ETrue;
       
   859             }
       
   860         }
       
   861 
       
   862         // if exactly one value is AUTO, value is computed to make equality true
       
   863     if ( aAutoProperties.Count() == 1 )
       
   864         {
       
   865         if ( !allHorizontalValuesProcessed )
       
   866             {
       
   867             const TDesC8& attributeName = aAutoProperties[0];
       
   868             if ( attributeName == XnPropertyNames::style::common::KHeight )
       
   869                 {
       
   870                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
   871                 if ( remainingHeight < 0 )
       
   872                     {
       
   873                     remainingHeight = 0;
       
   874                     }
       
   875                 //  Calculate the difference so that it can be returned
       
   876                 TRect paddingRectDiff( SubtractRect(
       
   877                     paddingRect, contentRect ) );
       
   878                 TRect borderRectDiff( SubtractRect(
       
   879                     borderRect, contentRect ) );
       
   880                 TRect marginRectDiff( SubtractRect(
       
   881                     marginRect, contentRect ) );
       
   882                 TRect normalFlowBorderRectDiff( SubtractRect(
       
   883                     normalFlowBorderRect, contentRect ) );
       
   884 
       
   885                 // grow height to fill the void
       
   886                 contentRect.SetHeight( remainingHeight );
       
   887                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
   888                 borderRect = AddRect( contentRect, borderRectDiff );
       
   889                 normalFlowBorderRect = AddRect(
       
   890                     contentRect, normalFlowBorderRectDiff );
       
   891                 marginRect = AddRect( contentRect, marginRectDiff );
       
   892                 size = TSize( size.iWidth, aHeightToFit );
       
   893                 }
       
   894 
       
   895             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
   896                 {
       
   897                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
   898                 if ( remainingWidth < 0 )
       
   899                     {
       
   900                     remainingWidth = 0;
       
   901                     }
       
   902                 // move rect right to fill the void
       
   903                 contentRect.Move( remainingWidth, 0 );
       
   904                 paddingRect.Move( remainingWidth, 0 );
       
   905                 borderRect.Move( remainingWidth, 0 );
       
   906                 normalFlowBorderRect.Move( remainingWidth, 0 );
       
   907                 marginRect.Resize( remainingWidth, 0 );
       
   908                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
   909                 }
       
   910 
       
   911             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
   912                 {
       
   913                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
   914                 marginRect.Resize( remainingWidth, 0 );
       
   915                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
   916                 }
       
   917 
       
   918             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
   919                 {
       
   920                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
   921                 // move rect right to fill the void
       
   922                 contentRect.Move( 0, remainingHeight / 2 );
       
   923                 paddingRect.Move( 0, remainingHeight / 2 );
       
   924                 borderRect.Move( 0, remainingHeight / 2 );
       
   925                 normalFlowBorderRect.Move( 0, remainingHeight / 2 );
       
   926                 marginRect.Resize( 0, remainingHeight );
       
   927                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
   928                 }
       
   929 
       
   930             if ( attributeName ==
       
   931                  XnPropertyNames::style::common::KMarginBottom )
       
   932                 {
       
   933                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
   934                 if ( remainingHeight < 0 )
       
   935                     {
       
   936                     remainingHeight = 0;
       
   937                     }
       
   938                 marginRect.Resize( 0, remainingHeight );
       
   939                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
   940                 }
       
   941             }
       
   942         }
       
   943     else
       
   944         {
       
   945         for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
   946             {
       
   947             const TDesC8& attributeName = aAutoProperties[i];
       
   948             if ( attributeName == XnPropertyNames::style::common::KHeight )
       
   949                 {
       
   950                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
   951                 if ( remainingHeight < 0 )
       
   952                     {
       
   953                     remainingHeight = 0;
       
   954                     }
       
   955                 //  Calculate the difference so that it can be returned
       
   956                 TRect paddingRectDiff( SubtractRect(
       
   957                     paddingRect, contentRect ) );
       
   958                 TRect borderRectDiff( SubtractRect(
       
   959                     borderRect, contentRect ) );
       
   960                 TRect marginRectDiff( SubtractRect(
       
   961                     marginRect, contentRect ) );
       
   962                 TRect normalFlowBorderRectDiff( SubtractRect(
       
   963                     normalFlowBorderRect, contentRect ) );
       
   964 
       
   965                 // grow height to fill the void
       
   966                 contentRect.SetHeight( remainingHeight );
       
   967                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
   968                 borderRect = AddRect( contentRect, borderRectDiff );
       
   969                 normalFlowBorderRect = AddRect(
       
   970                     contentRect, normalFlowBorderRectDiff );
       
   971                 marginRect = AddRect( contentRect, marginRectDiff );
       
   972                 size = TSize( size.iWidth, aHeightToFit );
       
   973                 }
       
   974 
       
   975             // several auto properties
       
   976             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
   977                 {
       
   978                 if ( !horizontalMarginProcessed )
       
   979                     {
       
   980                     // is right margin also set to AUTO?
       
   981                     CXnProperty* rightMargin = aNode.MarginRightL();
       
   982                     if ( rightMargin )
       
   983                         {
       
   984                         if ( IsPropertyAutoL( *rightMargin ) )
       
   985                             {
       
   986                             // both margins set to AUTO, values equal
       
   987                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
   988                             if ( remainingWidth < 0 )
       
   989                                 {
       
   990                                 remainingWidth = 0;
       
   991                                 }
       
   992                             // move rect right to fill the void
       
   993                             contentRect.Move( ( remainingWidth / 2 ), 0 );
       
   994                             horizontalMarginProcessed = ETrue;
       
   995                             marginRect.Resize( ( remainingWidth ), 0 );
       
   996                             borderRect.Move( ( remainingWidth / 2 ), 0 );
       
   997                             normalFlowBorderRect.Move( (
       
   998                                 remainingWidth / 2 ), 0 );
       
   999                             paddingRect.Move( ( remainingWidth / 2 ), 0 );
       
  1000                             size = TSize( size.iWidth + remainingWidth,
       
  1001                                 size.iHeight );
       
  1002                             }
       
  1003                         else
       
  1004                             {
       
  1005                             // only left margin set to AUTO
       
  1006                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1007                             if ( remainingWidth < 0 )
       
  1008                                 {
       
  1009                                 remainingWidth = 0;
       
  1010                                 }
       
  1011                             // move rect right to fill the void
       
  1012                             contentRect.Move( remainingWidth, 0 );
       
  1013                             horizontalMarginProcessed = ETrue;
       
  1014                             marginRect.Move( remainingWidth, 0 );
       
  1015                             borderRect.Move( remainingWidth, 0 );
       
  1016                             normalFlowBorderRect.Move( remainingWidth, 0 );
       
  1017                             paddingRect.Move( remainingWidth, 0 );
       
  1018                             size = TSize( size.iWidth + remainingWidth,
       
  1019                                 size.iHeight );
       
  1020                             }
       
  1021                         }
       
  1022                     }
       
  1023                 }
       
  1024 
       
  1025             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
  1026                 {
       
  1027                 if ( !horizontalMarginProcessed )
       
  1028                     {
       
  1029                     // is left margin also set to AUTO?
       
  1030                     CXnProperty* leftMargin = aNode.MarginLeftL();
       
  1031                     if ( leftMargin )
       
  1032                         {
       
  1033                         if ( IsPropertyAutoL( *leftMargin ) )
       
  1034                             {
       
  1035                             // both margins set to AUTO, values equal
       
  1036                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1037                             if ( remainingWidth < 0 )
       
  1038                                 {
       
  1039                                 remainingWidth = 0;
       
  1040                                 }
       
  1041                             // move rect right to fill the void
       
  1042                             contentRect.Move( ( remainingWidth / 2 ), 0 );
       
  1043                             horizontalMarginProcessed = ETrue;
       
  1044                             marginRect.Resize( ( remainingWidth ), 0 );
       
  1045                             borderRect.Move( ( remainingWidth / 2 ), 0 );
       
  1046                             normalFlowBorderRect.Move( (
       
  1047                                 remainingWidth / 2 ), 0 );
       
  1048                             paddingRect.Move( ( remainingWidth / 2 ), 0 );
       
  1049                             size = TSize( size.iWidth + remainingWidth,
       
  1050                                 size.iHeight );
       
  1051                             }
       
  1052                         else
       
  1053                             {
       
  1054                             // only right margin set to AUTO
       
  1055                             horizontalMarginProcessed = ETrue;
       
  1056                             }
       
  1057                         }
       
  1058                     }
       
  1059                 }
       
  1060             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
  1061                 {
       
  1062                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
  1063                     {
       
  1064                     // is bottom margin also set to AUTO?
       
  1065                     CXnProperty* bottomMargin = aNode.MarginBottomL();
       
  1066                     if ( bottomMargin )
       
  1067                         {
       
  1068                         if ( IsPropertyAutoL( *bottomMargin ) )
       
  1069                             {
       
  1070                             // both margins set to AUTO, values equal
       
  1071                             TInt remainingHeight =  aHeightToFit - size.iHeight;
       
  1072                             if ( remainingHeight < 0 )
       
  1073                                 {
       
  1074                                 remainingHeight = 0;
       
  1075                                 }
       
  1076                             // move rect right to fill the void
       
  1077                             contentRect.Move( 0, ( remainingHeight / 2 ) );
       
  1078                             verticalMarginProcessed = ETrue;
       
  1079                             marginRect.Resize( 0, remainingHeight );
       
  1080                             borderRect.Move( 0, ( remainingHeight / 2 ) );
       
  1081                             normalFlowBorderRect.Move(
       
  1082                                 0, ( remainingHeight / 2 ) );
       
  1083                             paddingRect.Move( 0, ( remainingHeight / 2 ) );
       
  1084                             size = TSize( size.iWidth, 
       
  1085                                 size.iHeight + remainingHeight );
       
  1086                             }
       
  1087                         else
       
  1088                             {
       
  1089                             // only top margin set to AUTO
       
  1090                             TInt remainingHeight =  aHeightToFit - size.iHeight;
       
  1091                             if ( remainingHeight < 0 )
       
  1092                                 {
       
  1093                                 remainingHeight = 0;
       
  1094                                 }
       
  1095                             // move rect right to fill the void
       
  1096                             contentRect.Move( 0, remainingHeight );
       
  1097                             verticalMarginProcessed = ETrue;
       
  1098                             marginRect.Resize( 0, remainingHeight );
       
  1099                             borderRect.Move( 0, remainingHeight );
       
  1100                             normalFlowBorderRect.Move( 0, remainingHeight );
       
  1101                             paddingRect.Move( 0, remainingHeight );
       
  1102                             size = TSize( size.iWidth,
       
  1103                                 size.iHeight + remainingHeight );
       
  1104                             }
       
  1105                         }
       
  1106                     }
       
  1107                  }
       
  1108 
       
  1109             if ( attributeName ==
       
  1110                  XnPropertyNames::style::common::KMarginBottom )
       
  1111                 {
       
  1112                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
  1113                     {
       
  1114                     // is top margin also set to AUTO?
       
  1115                     CXnProperty* topMargin = aNode.MarginTopL();
       
  1116                     if ( topMargin )
       
  1117                         {
       
  1118                         if ( IsPropertyAutoL( *topMargin ) )
       
  1119                             {
       
  1120                             // both margins set to AUTO, values equal
       
  1121                             TInt remainingHeight =  aHeightToFit - size.iHeight;
       
  1122                             if ( remainingHeight < 0 )
       
  1123                                 {
       
  1124                                 remainingHeight = 0;
       
  1125                                 }
       
  1126                             // move rect right to fill the void
       
  1127                             contentRect.Move( 0, remainingHeight / 2 );
       
  1128                             verticalMarginProcessed = ETrue;
       
  1129                             marginRect.Resize( 0, remainingHeight );
       
  1130                             borderRect.Move( 0, remainingHeight / 2 );
       
  1131                             normalFlowBorderRect.Move(
       
  1132                                 0, remainingHeight / 2 );
       
  1133                             paddingRect.Move( 0, remainingHeight / 2 );
       
  1134                             size = TSize( size.iWidth,
       
  1135                                 size.iHeight + remainingHeight );
       
  1136                             }
       
  1137                         else
       
  1138                             {
       
  1139                             // only bottom margin set to AUTO
       
  1140                             TInt remainingHeight =  aHeightToFit - size.iHeight;
       
  1141                             if ( remainingHeight < 0 )
       
  1142                                 {
       
  1143                                 remainingHeight = 0;
       
  1144                                 }
       
  1145                             marginRect.Resize( 0, remainingHeight );
       
  1146                             verticalMarginProcessed = ETrue;
       
  1147                             size = TSize( size.iWidth, 
       
  1148                                 size.iHeight + remainingHeight );
       
  1149                             }
       
  1150                         }
       
  1151                     }
       
  1152                 }
       
  1153             }
       
  1154         }
       
  1155     aNode.SetRect( contentRect );
       
  1156     aNode.SetPaddingRect( paddingRect );
       
  1157     aNode.SetBorderRect( borderRect );
       
  1158     aNode.SetMarginRect( marginRect );
       
  1159     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  1160     return contentRect.Size();
       
  1161     }
       
  1162 
       
  1163 // -----------------------------------------------------------------------------
       
  1164 // AutoStaticRLL()
       
  1165 // Calculate properties set to AUTO when positioning is static,
       
  1166 // layout horizontal
       
  1167 // and direction right-to-left.
       
  1168 // -----------------------------------------------------------------------------
       
  1169 //
       
  1170 static TSize AutoStaticRLL( CXnNode& aNode, TInt aWidthToFit,
       
  1171     TInt aHeightToFit, RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
       
  1172     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  1173     TReal aVerticalUnitInPixels )
       
  1174     {
       
  1175     // Static positioning, horizontal, right to left
       
  1176     TBool horizontalMarginProcessed = EFalse;
       
  1177     TBool verticalMarginProcessed = EFalse;
       
  1178     TBool allVerticalValuesProcessed = EFalse;
       
  1179     TBool allHorizontalValuesProcessed = EFalse;
       
  1180 
       
  1181     CXnProperty* maxHeightProperty = aNode.MaxHeightL();
       
  1182     CXnProperty* maxWidthProperty = aNode.MaxWidthL();
       
  1183     CXnProperty* minHeightProperty = aNode.MinHeightL();
       
  1184     CXnProperty* minWidthProperty = aNode.MinWidthL();
       
  1185 
       
  1186     TRect contentRect( aNode.Rect() );
       
  1187     TRect paddingRect( aNode.PaddingRect() );
       
  1188     TRect borderRect( aNode.BorderRect() );
       
  1189     TRect marginRect( aNode.MarginRect() );
       
  1190     TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
  1191 
       
  1192     TSize size = CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
       
  1193         aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  1194 
       
  1195     for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
  1196         {
       
  1197         // search for height property
       
  1198         const TDesC8& attributeName = aAutoProperties[i];
       
  1199         if ( attributeName == XnPropertyNames::style::common::KWidth )
       
  1200             {
       
  1201             TInt newWidth = aWidthToFit - size.iWidth;
       
  1202 
       
  1203             //  Calculate the difference so that it can be returned
       
  1204             TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
       
  1205             TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  1206             TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  1207             TRect normalFlowBorderRectDiff( SubtractRect( normalFlowBorderRect,
       
  1208                 contentRect ) );
       
  1209 
       
  1210             // grow width to fill the void
       
  1211             contentRect.SetWidth( newWidth );
       
  1212             paddingRect = AddRect( contentRect, paddingRectDiff );
       
  1213             borderRect = AddRect( contentRect, borderRectDiff );
       
  1214             normalFlowBorderRect = AddRect( contentRect,
       
  1215                 normalFlowBorderRectDiff );
       
  1216             marginRect = AddRect( contentRect, marginRectDiff );
       
  1217 
       
  1218             size = TSize( aWidthToFit, size.iHeight );
       
  1219             allHorizontalValuesProcessed = ETrue;
       
  1220             }
       
  1221         }
       
  1222 
       
  1223     // if exactly one value is AUTO, value is computed to make equality true
       
  1224     if ( aAutoProperties.Count() == 1 )
       
  1225         {
       
  1226         if ( !allHorizontalValuesProcessed )
       
  1227             {
       
  1228             const TDesC8& attributeName = aAutoProperties[0];
       
  1229             if ( attributeName == XnPropertyNames::style::common::KHeight )
       
  1230                 {
       
  1231                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1232                 if ( remainingHeight < 0 )
       
  1233                     {
       
  1234                     remainingHeight = 0;
       
  1235                     }
       
  1236                 //  Calculate the difference so that it can be returned
       
  1237                 TRect paddingRectDiff( SubtractRect(
       
  1238                     paddingRect, contentRect ) );
       
  1239                 TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  1240                 TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  1241                 TRect normalFlowBorderRectDiff( SubtractRect(
       
  1242                     normalFlowBorderRect, contentRect ) );
       
  1243 
       
  1244                 // grow height to fill the void
       
  1245                 contentRect.SetHeight( remainingHeight );
       
  1246                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
  1247                 borderRect = AddRect( contentRect, borderRectDiff );
       
  1248                 normalFlowBorderRect = AddRect( contentRect,
       
  1249                     normalFlowBorderRectDiff );
       
  1250                 marginRect = AddRect( contentRect, marginRectDiff );
       
  1251 
       
  1252                 size = TSize( size.iWidth, aHeightToFit );
       
  1253                 }
       
  1254 
       
  1255             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
  1256                 {
       
  1257                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1258                 if ( remainingWidth < 0 )
       
  1259                     {
       
  1260                     remainingWidth = 0;
       
  1261                     }
       
  1262                 // move rect right to fill the void
       
  1263                 contentRect.Move( remainingWidth, 0 );
       
  1264                 paddingRect.Move( remainingWidth, 0 );
       
  1265                 borderRect.Move( remainingWidth, 0 );
       
  1266                 normalFlowBorderRect.Move( remainingWidth, 0 );
       
  1267                 marginRect.Resize( remainingWidth, 0 );
       
  1268                 marginRect.Move( -remainingWidth, 0 );
       
  1269                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
  1270                 }
       
  1271 
       
  1272             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
  1273                 {
       
  1274                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1275                 if ( remainingWidth < 0 )
       
  1276                     {
       
  1277                     remainingWidth = 0;
       
  1278                     }
       
  1279                 contentRect.Move( -remainingWidth, 0 );
       
  1280                 paddingRect.Move( -remainingWidth, 0 );
       
  1281                 borderRect.Move( -remainingWidth, 0 );
       
  1282                 normalFlowBorderRect.Move( -remainingWidth, 0 );
       
  1283                 marginRect.Move( -remainingWidth, 0 );
       
  1284                 marginRect.Resize( remainingWidth, 0 );
       
  1285 
       
  1286                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
  1287                 }
       
  1288 
       
  1289             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
  1290                 {
       
  1291                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1292                 if ( remainingHeight < 0 )
       
  1293                     {
       
  1294                     remainingHeight = 0;
       
  1295                     }
       
  1296                 // move rect right to fill the void
       
  1297                 contentRect.Move( 0, remainingHeight / 2 );
       
  1298                 paddingRect.Move( 0, remainingHeight / 2 );
       
  1299                 borderRect.Move( 0, remainingHeight / 2 );
       
  1300                 normalFlowBorderRect.Move( 0, remainingHeight / 2 );
       
  1301                 marginRect.Resize( 0, remainingHeight );
       
  1302                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
  1303                 }
       
  1304 
       
  1305             if ( attributeName ==
       
  1306                  XnPropertyNames::style::common::KMarginBottom )
       
  1307                 {
       
  1308                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1309                 if ( remainingHeight < 0 )
       
  1310                     {
       
  1311                     remainingHeight = 0;
       
  1312                     }
       
  1313                 marginRect.Resize( 0, remainingHeight );
       
  1314                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
  1315                 }
       
  1316             }
       
  1317         }
       
  1318     else
       
  1319         {
       
  1320         for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
  1321             {
       
  1322             const TDesC8& attributeName = aAutoProperties[i];
       
  1323             if ( attributeName == XnPropertyNames::style::common::KHeight )
       
  1324                 {
       
  1325                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1326                 if ( remainingHeight < 0 )
       
  1327                     {
       
  1328                     remainingHeight = 0;
       
  1329                     }
       
  1330                 //  Calculate the difference so that it can be returned
       
  1331                 TRect paddingRectDiff( SubtractRect(
       
  1332                     paddingRect, contentRect ) );
       
  1333                 TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  1334                 TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  1335                 TRect normalFlowBorderRectDiff( SubtractRect(
       
  1336                     normalFlowBorderRect, contentRect ) );
       
  1337 
       
  1338                 // grow height to fill the void
       
  1339                 contentRect.SetHeight( remainingHeight );
       
  1340                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
  1341                 borderRect = AddRect( contentRect, borderRectDiff );
       
  1342                 normalFlowBorderRect = AddRect( contentRect,
       
  1343                     normalFlowBorderRectDiff );
       
  1344                 marginRect = AddRect( contentRect, marginRectDiff );
       
  1345 
       
  1346                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
  1347                 }
       
  1348 
       
  1349             // several auto properties
       
  1350             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
  1351                 {
       
  1352                 if ( !horizontalMarginProcessed )
       
  1353                     {
       
  1354                     // is right margin also set to AUTO?
       
  1355                     CXnProperty* rightMargin = aNode.MarginRightL();
       
  1356                     if ( rightMargin )
       
  1357                         {
       
  1358                         if ( IsPropertyAutoL( *rightMargin ) )
       
  1359                             {
       
  1360                             // both margins set to AUTO, values equal
       
  1361                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1362                             if ( remainingWidth < 0 )
       
  1363                                 {
       
  1364                                 remainingWidth = 0;
       
  1365                                 }
       
  1366                             // move rect left
       
  1367                             contentRect.Move( -( remainingWidth / 2 ), 0 );
       
  1368                             marginRect.Resize( remainingWidth, 0 );
       
  1369                             marginRect.Move( -remainingWidth, 0 );
       
  1370                             borderRect.Move( -( remainingWidth / 2 ), 0 );
       
  1371                             normalFlowBorderRect.Move(
       
  1372                                 -( remainingWidth / 2 ), 0 );
       
  1373                             paddingRect.Move( -( remainingWidth / 2 ), 0 );
       
  1374                             horizontalMarginProcessed = ETrue;
       
  1375                             size = TSize( size.iWidth + remainingWidth,
       
  1376                                 size.iHeight );
       
  1377                             }
       
  1378                         else
       
  1379                             {
       
  1380                             // only left margin set to AUTO
       
  1381                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1382                             if ( remainingWidth < 0 )
       
  1383                                 {
       
  1384                                 remainingWidth = 0;
       
  1385                                 }
       
  1386                             // move rect left
       
  1387                             contentRect.Move( ( remainingWidth ), 0 );
       
  1388                             marginRect.Resize( remainingWidth, 0 );
       
  1389                             marginRect.Move( remainingWidth, 0 );
       
  1390                             horizontalMarginProcessed = ETrue;
       
  1391                             size = TSize( size.iWidth + remainingWidth,
       
  1392                                 size.iHeight );
       
  1393                             }
       
  1394                         }
       
  1395                     }
       
  1396                 }
       
  1397 
       
  1398             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
  1399                 {
       
  1400                 if ( !horizontalMarginProcessed )
       
  1401                     {
       
  1402                     // is left margin also set to AUTO?
       
  1403                     CXnProperty* leftMargin = aNode.MarginLeftL();
       
  1404                     if ( leftMargin )
       
  1405                         {
       
  1406                         if ( IsPropertyAutoL( *leftMargin ) )
       
  1407                             {
       
  1408                             // both margins set to AUTO, values equal
       
  1409                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1410                             if ( remainingWidth < 0 )
       
  1411                                 {
       
  1412                                 remainingWidth = 0;
       
  1413                                 }
       
  1414                             contentRect.Move( -( remainingWidth / 2 ), 0 );
       
  1415                             marginRect.Resize( remainingWidth, 0 );
       
  1416                             marginRect.Move( -remainingWidth, 0 );
       
  1417                             borderRect.Move( -( remainingWidth / 2 ), 0 );
       
  1418                             normalFlowBorderRect.Move(
       
  1419                                 -( remainingWidth / 2 ), 0 );
       
  1420                             paddingRect.Move( -( remainingWidth / 2 ), 0 );
       
  1421                             horizontalMarginProcessed = ETrue;
       
  1422                             size = TSize( size.iWidth + remainingWidth,
       
  1423                                 size.iHeight );
       
  1424                             }
       
  1425                         else
       
  1426                             {
       
  1427                             // only right margin set to AUTO
       
  1428                             TInt usedWidth = size.iWidth;
       
  1429                             TInt remainingWidth = aWidthToFit - usedWidth;
       
  1430                             if ( remainingWidth < 0 )
       
  1431                                 {
       
  1432                                 remainingWidth = 0;
       
  1433                                 }
       
  1434                             contentRect.Move( -remainingWidth, 0 );
       
  1435                             marginRect.Resize( remainingWidth, 0 );
       
  1436                             marginRect.Move( -remainingWidth, 0 );
       
  1437                             borderRect.Move( -remainingWidth, 0 );
       
  1438                             normalFlowBorderRect.Move( -remainingWidth, 0 );
       
  1439                             paddingRect.Move( -remainingWidth, 0 );
       
  1440                             horizontalMarginProcessed = ETrue;
       
  1441                             size = TSize( size.iWidth + remainingWidth,
       
  1442                                 size.iHeight );
       
  1443                             }
       
  1444                         }
       
  1445                     }
       
  1446                 }
       
  1447             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
  1448                 {
       
  1449                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
  1450                     {
       
  1451                     // is bottom margin also set to AUTO?
       
  1452                     CXnProperty* bottomMargin = aNode.MarginBottomL();
       
  1453                     if ( bottomMargin )
       
  1454                         {
       
  1455                         if ( IsPropertyAutoL( *bottomMargin ) )
       
  1456                             {
       
  1457                             // both margins set to AUTO, values equal
       
  1458                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1459                             if ( remainingHeight < 0 )
       
  1460                                 {
       
  1461                                 remainingHeight = 0;
       
  1462                                 }
       
  1463                             contentRect.Move( 0, ( remainingHeight / 2 ) );
       
  1464                             marginRect.Resize( 0, remainingHeight );
       
  1465                             borderRect.Move( 0, ( remainingHeight / 2 ) );
       
  1466                             normalFlowBorderRect.Move(
       
  1467                                 0, ( remainingHeight / 2 ) );
       
  1468                             paddingRect.Move( 0, ( remainingHeight / 2 ) );
       
  1469                             verticalMarginProcessed = ETrue;
       
  1470                             size = TSize( size.iWidth,
       
  1471                                 size.iHeight + remainingHeight );
       
  1472                             }
       
  1473                         else
       
  1474                             {
       
  1475                             // only top margin set to AUTO
       
  1476                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1477                             if ( remainingHeight < 0 )
       
  1478                                 {
       
  1479                                 remainingHeight = 0;
       
  1480                                 }
       
  1481                             contentRect.Move( 0, remainingHeight );
       
  1482                             marginRect.Resize( 0, remainingHeight );
       
  1483                             borderRect.Move( 0, remainingHeight );
       
  1484                             normalFlowBorderRect.Move( 0, remainingHeight );
       
  1485                             paddingRect.Move( 0, remainingHeight );
       
  1486                             verticalMarginProcessed = ETrue;
       
  1487                             size = TSize( size.iWidth,
       
  1488                                 size.iHeight + remainingHeight );
       
  1489                             }
       
  1490                         }
       
  1491                     }
       
  1492                 }
       
  1493 
       
  1494             if ( attributeName ==
       
  1495                  XnPropertyNames::style::common::KMarginBottom )
       
  1496                 {
       
  1497                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
  1498                     {
       
  1499                     // is top margin also set to AUTO?
       
  1500                     CXnProperty* topMargin = aNode.MarginTopL();
       
  1501                     if ( topMargin )
       
  1502                         {
       
  1503                         if ( IsPropertyAutoL( *topMargin ) )
       
  1504                             {
       
  1505                             // both margins set to AUTO, values equal
       
  1506                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1507                             if ( remainingHeight < 0 )
       
  1508                                 {
       
  1509                                 remainingHeight = 0;
       
  1510                                 }
       
  1511                             // move rect right to fill the void
       
  1512                             contentRect.Move( 0, ( remainingHeight / 2 ) );
       
  1513                             marginRect.Resize( 0, remainingHeight );
       
  1514                             borderRect.Move( 0, ( remainingHeight / 2 ) );
       
  1515                             normalFlowBorderRect.Move(
       
  1516                                 0, ( remainingHeight / 2 ) );
       
  1517                             paddingRect.Move( 0, ( remainingHeight / 2 ) );
       
  1518                             verticalMarginProcessed = ETrue;
       
  1519                             size = TSize( size.iWidth,
       
  1520                                 size.iHeight + remainingHeight );
       
  1521                             }
       
  1522                         else
       
  1523                             {
       
  1524                             // only bottom margin set to AUTO
       
  1525                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1526                             if ( remainingHeight < 0 )
       
  1527                                 {
       
  1528                                 remainingHeight = 0;
       
  1529                                 }
       
  1530                             // move rect right to fill the void
       
  1531                             marginRect.Resize( 0, remainingHeight );
       
  1532                             verticalMarginProcessed = ETrue;
       
  1533                             size = TSize( size.iWidth,
       
  1534                                 size.iHeight + remainingHeight );
       
  1535                             }
       
  1536                         }
       
  1537                     }
       
  1538                 }
       
  1539             }
       
  1540         }
       
  1541     aNode.SetRect( contentRect );
       
  1542     aNode.SetPaddingRect( paddingRect );
       
  1543     aNode.SetBorderRect( borderRect );
       
  1544     aNode.SetMarginRect( marginRect );
       
  1545     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  1546     return contentRect.Size();
       
  1547     }
       
  1548 
       
  1549 // -----------------------------------------------------------------------------
       
  1550 // SubtractRect()
       
  1551 // Calculate the difference of two rectangles and return it as
       
  1552 // -----------------------------------------------------------------------------
       
  1553 //
       
  1554 static TRect SubtractRect( const TRect& aOriginal, const TRect& aSubtracter )
       
  1555     {
       
  1556     return TRect( aOriginal.iTl.iX - aSubtracter.iTl.iX,
       
  1557         aOriginal.iTl.iY - aSubtracter.iTl.iY,
       
  1558         aOriginal.iBr.iX - aSubtracter.iBr.iX,
       
  1559         aOriginal.iBr.iY - aSubtracter.iBr.iY );
       
  1560     }
       
  1561 
       
  1562 // -----------------------------------------------------------------------------
       
  1563 // AddRect()
       
  1564 // Add two rectangles together and return the result
       
  1565 // -----------------------------------------------------------------------------
       
  1566 //
       
  1567 static TRect AddRect( const TRect& aOriginal, const TRect& aAdded )
       
  1568     {
       
  1569     return TRect( aOriginal.iTl.iX + aAdded.iTl.iX,
       
  1570         aOriginal.iTl.iY + aAdded.iTl.iY,
       
  1571         aOriginal.iBr.iX + aAdded.iBr.iX,
       
  1572         aOriginal.iBr.iY + aAdded.iBr.iY );
       
  1573     }
       
  1574 
       
  1575 // -----------------------------------------------------------------------------
       
  1576 // AutoStaticTBL()
       
  1577 // Calculate properties set to AUTO when positioning is static, layout vertical
       
  1578 // and direction left-to-right
       
  1579 // -----------------------------------------------------------------------------
       
  1580 //
       
  1581 static TSize AutoStaticTBL( CXnNode& aNode, TInt aWidthToFit, TInt aHeightToFit,
       
  1582     RArray< TPtrC8 >& aAutoProperties, TRect& aParentRect,
       
  1583     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  1584     TReal aVerticalUnitInPixels )
       
  1585     {
       
  1586     // Static positioning, vertical, left to right
       
  1587     TBool horizontalMarginProcessed( EFalse );
       
  1588     TBool verticalMarginProcessed( EFalse );
       
  1589     TBool allVerticalValuesProcessed( EFalse );
       
  1590 
       
  1591     TRect contentRect( aNode.Rect() );
       
  1592     TRect paddingRect( aNode.PaddingRect() );
       
  1593     TRect borderRect( aNode.BorderRect() );
       
  1594     TRect marginRect( aNode.MarginRect() );
       
  1595     TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
  1596 
       
  1597     TSize size( CalculateTotalDimensionsL( aNode, EFalse, ETrue, aParentRect,
       
  1598         aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
       
  1599 
       
  1600     for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
  1601         {
       
  1602         // search for height property
       
  1603         const TDesC8& attributeName = aAutoProperties[i];
       
  1604         if ( attributeName == XnPropertyNames::style::common::KHeight )
       
  1605             {
       
  1606             //  Calculate the difference so that it can be returned
       
  1607             TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
       
  1608             TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  1609             TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  1610             TRect normalFlowBorderRectDiff( SubtractRect( normalFlowBorderRect,
       
  1611                 contentRect ) );
       
  1612 
       
  1613             // grow height to fill the void
       
  1614             contentRect.SetHeight( aHeightToFit - size.iHeight );
       
  1615             paddingRect = AddRect( contentRect, paddingRectDiff );
       
  1616             borderRect = AddRect( contentRect, borderRectDiff );
       
  1617             normalFlowBorderRect = AddRect(
       
  1618                 contentRect, normalFlowBorderRectDiff );
       
  1619             marginRect = AddRect( contentRect, marginRectDiff );
       
  1620             size = TSize( size.iWidth, aHeightToFit );
       
  1621             allVerticalValuesProcessed = ETrue;
       
  1622             }
       
  1623         }
       
  1624 
       
  1625     // if exactly one value is AUTO, value is computed to make equality true
       
  1626     if ( aAutoProperties.Count() == 1 )
       
  1627         {
       
  1628         if ( !allVerticalValuesProcessed )
       
  1629             {
       
  1630             const TDesC8& attributeName = aAutoProperties[0];
       
  1631             if ( attributeName == XnPropertyNames::style::common::KWidth )
       
  1632                 {
       
  1633                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1634                 if ( remainingWidth < 0 )
       
  1635                     {
       
  1636                     remainingWidth = 0;
       
  1637                     }
       
  1638                 //  Calculate the difference so that it can be returned
       
  1639                 TRect paddingRectDiff( SubtractRect(
       
  1640                     paddingRect, contentRect ) );
       
  1641                 TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  1642                 TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  1643                 TRect normalFlowBorderRectDiff( SubtractRect(
       
  1644                     normalFlowBorderRect, contentRect ) );
       
  1645 
       
  1646                 // grow width to fill the void
       
  1647                 contentRect.SetWidth( remainingWidth );
       
  1648                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
  1649                 borderRect = AddRect( contentRect, borderRectDiff );
       
  1650                 normalFlowBorderRect = AddRect( contentRect,
       
  1651                     normalFlowBorderRectDiff );
       
  1652                 marginRect = AddRect( contentRect, marginRectDiff );
       
  1653                 size = TSize( aWidthToFit, size.iHeight );
       
  1654                 }
       
  1655 
       
  1656             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
  1657                 {
       
  1658                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1659                 if ( remainingWidth < 0 )
       
  1660                     {
       
  1661                     remainingWidth = 0;
       
  1662                     }
       
  1663                 // move rect right to fill the void
       
  1664                 contentRect.Move( remainingWidth, 0 );
       
  1665                 paddingRect.Move( remainingWidth, 0 );
       
  1666                 borderRect.Move( remainingWidth, 0 );
       
  1667                 normalFlowBorderRect.Move( remainingWidth, 0 );
       
  1668                 marginRect.Resize( remainingWidth, 0 );
       
  1669                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
  1670                 }
       
  1671 
       
  1672             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
  1673                 {
       
  1674                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1675                 if ( remainingWidth < 0 )
       
  1676                     {
       
  1677                     remainingWidth = 0;
       
  1678                     }
       
  1679                 marginRect.Resize( remainingWidth, 0 );
       
  1680                 size = TSize( size.iWidth + remainingWidth, size.iHeight );
       
  1681                 }
       
  1682 
       
  1683             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
  1684                 {
       
  1685                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1686                 if ( remainingHeight < 0 )
       
  1687                     {
       
  1688                     remainingHeight = 0;
       
  1689                     }
       
  1690                 // move rect right to fill the void
       
  1691                 contentRect.Move( 0, remainingHeight / 2 );
       
  1692                 paddingRect.Move( 0, remainingHeight / 2 );
       
  1693                 borderRect.Move( 0, remainingHeight / 2 );
       
  1694                 normalFlowBorderRect.Move( 0, remainingHeight / 2 );
       
  1695                 marginRect.Resize( 0, remainingHeight );
       
  1696                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
  1697                 }
       
  1698 
       
  1699             if ( attributeName ==
       
  1700                  XnPropertyNames::style::common::KMarginBottom )
       
  1701                 {
       
  1702                 TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1703                 if ( remainingHeight < 0 )
       
  1704                     {
       
  1705                     remainingHeight = 0;
       
  1706                     }
       
  1707                 // set margin rect
       
  1708                 marginRect.Resize( 0, remainingHeight );
       
  1709                 size = TSize( size.iWidth, size.iHeight + remainingHeight );
       
  1710                 }
       
  1711             }
       
  1712         }
       
  1713     else
       
  1714         {
       
  1715         for ( TInt i = 0; i < aAutoProperties.Count(); i++ )
       
  1716             {
       
  1717             const TDesC8& attributeName = aAutoProperties[i];
       
  1718             if ( attributeName == XnPropertyNames::style::common::KWidth )
       
  1719                 {
       
  1720                 TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1721                 if ( remainingWidth < 0 )
       
  1722                     {
       
  1723                     remainingWidth = 0;
       
  1724                     }
       
  1725                 //  Calculate the difference so that it can be returned
       
  1726                 TRect paddingRectDiff( SubtractRect(
       
  1727                     paddingRect, contentRect ) );
       
  1728                 TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  1729                 TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  1730                 TRect normalFlowBorderRectDiff( SubtractRect(
       
  1731                     normalFlowBorderRect, contentRect ) );
       
  1732 
       
  1733                 // grow width to fill the void
       
  1734                 contentRect.SetWidth( remainingWidth );
       
  1735                 paddingRect = AddRect( contentRect, paddingRectDiff );
       
  1736                 borderRect = AddRect( contentRect, borderRectDiff );
       
  1737                 normalFlowBorderRect = AddRect( contentRect,
       
  1738                     normalFlowBorderRectDiff );
       
  1739                 marginRect = AddRect( contentRect, marginRectDiff );
       
  1740                 size = TSize( aWidthToFit, size.iHeight );
       
  1741                 }
       
  1742 
       
  1743             // several auto properties
       
  1744             if ( attributeName == XnPropertyNames::style::common::KMarginLeft )
       
  1745                 {
       
  1746                 if ( !horizontalMarginProcessed )
       
  1747                     {
       
  1748                     // is right margin also set to AUTO?
       
  1749                     CXnProperty* rightMargin = aNode.MarginRightL();
       
  1750                     if ( rightMargin )
       
  1751                         {
       
  1752                         if ( IsPropertyAutoL( *rightMargin ) )
       
  1753                             {
       
  1754                             // both margins set to AUTO, values equal
       
  1755                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1756                             if ( remainingWidth < 0 )
       
  1757                                 {
       
  1758                                 remainingWidth = 0;
       
  1759                                 }
       
  1760                             // move rect right to fill the void
       
  1761                             contentRect.Move(( remainingWidth / 2 ), 0 );
       
  1762                             marginRect.Resize( remainingWidth, 0 );
       
  1763                             borderRect.Move( remainingWidth / 2, 0 );
       
  1764                             normalFlowBorderRect.Move( remainingWidth / 2, 0 );
       
  1765                             paddingRect.Move( remainingWidth / 2, 0 );
       
  1766                             horizontalMarginProcessed = ETrue;
       
  1767                             size = TSize( size.iWidth + remainingWidth,
       
  1768                                 size.iHeight );
       
  1769                             }
       
  1770                         else
       
  1771                             {
       
  1772                             // only left margin set to AUTO
       
  1773                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1774                             if ( remainingWidth < 0 )
       
  1775                                 {
       
  1776                                 remainingWidth = 0;
       
  1777                                 }
       
  1778                             // move rect right to fill the void
       
  1779                             contentRect.Move( remainingWidth, 0 );
       
  1780                             marginRect.Resize( remainingWidth, 0 );
       
  1781                             borderRect.Move( remainingWidth, 0 );
       
  1782                             normalFlowBorderRect.Move( remainingWidth, 0 );
       
  1783                             paddingRect.Move( remainingWidth, 0 );
       
  1784                             horizontalMarginProcessed = ETrue;
       
  1785                             size = TSize( size.iWidth + remainingWidth,
       
  1786                                 size.iHeight );
       
  1787                             }
       
  1788                         }
       
  1789                     }
       
  1790                 }
       
  1791 
       
  1792             if ( attributeName == XnPropertyNames::style::common::KMarginRight )
       
  1793                 {
       
  1794                 if ( !horizontalMarginProcessed )
       
  1795                     {
       
  1796                     // is left margin also set to AUTO?
       
  1797                     CXnProperty* leftMargin = aNode.MarginLeftL();
       
  1798                     if ( leftMargin )
       
  1799                         {
       
  1800                         if ( IsPropertyAutoL (*leftMargin ) )
       
  1801                             {
       
  1802                             // both margins set to AUTO, values equal
       
  1803                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1804                             if ( remainingWidth < 0 )
       
  1805                                 {
       
  1806                                 remainingWidth = 0;
       
  1807                                 }
       
  1808                             // move rect right to fill the void
       
  1809                             contentRect.Move( remainingWidth / 2, 0 );
       
  1810                             marginRect.Resize( remainingWidth, 0 );
       
  1811                             borderRect.Move( remainingWidth / 2, 0 );
       
  1812                             normalFlowBorderRect.Move( remainingWidth / 2, 0 );
       
  1813                             paddingRect.Move( remainingWidth / 2, 0 );
       
  1814                             horizontalMarginProcessed = ETrue;
       
  1815                             size = TSize( size.iWidth + remainingWidth,
       
  1816                                 size.iHeight );
       
  1817                             }
       
  1818                         else
       
  1819                             {
       
  1820                             // only right margin set to AUTO
       
  1821                             TInt remainingWidth = aWidthToFit - size.iWidth;
       
  1822                             if ( remainingWidth < 0 )
       
  1823                                 {
       
  1824                                 remainingWidth = 0;
       
  1825                                 }
       
  1826                             // move rect right to fill the void
       
  1827                             marginRect.Resize( remainingWidth, 0 );
       
  1828                             horizontalMarginProcessed = ETrue;
       
  1829                             size = TSize( size.iWidth + remainingWidth,
       
  1830                                 size.iHeight );
       
  1831                             }
       
  1832                         }
       
  1833                     }
       
  1834                 }
       
  1835 
       
  1836             if ( attributeName == XnPropertyNames::style::common::KMarginTop )
       
  1837                 {
       
  1838                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
  1839                     {
       
  1840                     // is bottom margin also set to AUTO?
       
  1841                     CXnProperty* bottomMargin = aNode.MarginBottomL();
       
  1842                     if ( bottomMargin )
       
  1843                         {
       
  1844                         if ( IsPropertyAutoL( *bottomMargin ) )
       
  1845                             {
       
  1846                             // both margins set to AUTO, values equal
       
  1847                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1848                             if ( remainingHeight < 0 )
       
  1849                                 {
       
  1850                                 remainingHeight = 0;
       
  1851                                 }
       
  1852                             // move rect right to fill the void
       
  1853                             contentRect.Move( 0, remainingHeight / 2 );
       
  1854                             marginRect.Resize( 0, remainingHeight );
       
  1855                             borderRect.Move( 0, remainingHeight / 2 );
       
  1856                             normalFlowBorderRect.Move( 0, remainingHeight / 2 );
       
  1857                             paddingRect.Move( 0, remainingHeight / 2 );
       
  1858                             verticalMarginProcessed = ETrue;
       
  1859                             size = TSize( size.iWidth,
       
  1860                                 size.iHeight + remainingHeight );
       
  1861                             }
       
  1862                         else
       
  1863                             {
       
  1864                             // only top margin set to AUTO
       
  1865                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1866                             if ( remainingHeight < 0 )
       
  1867                                 {
       
  1868                                 remainingHeight = 0;
       
  1869                                 }
       
  1870                             // move rect right to fill the void
       
  1871                             contentRect.Move( 0, remainingHeight );
       
  1872                             marginRect.Resize( 0, remainingHeight );
       
  1873                             borderRect.Move( 0, remainingHeight );
       
  1874                             normalFlowBorderRect.Move( 0, remainingHeight );
       
  1875                             paddingRect.Move( 0, remainingHeight );
       
  1876                             verticalMarginProcessed = ETrue;
       
  1877                             size = TSize( size.iWidth,
       
  1878                                 size.iHeight + remainingHeight );
       
  1879                             }
       
  1880                         }
       
  1881                     }
       
  1882                 }
       
  1883 
       
  1884             if ( attributeName ==
       
  1885                  XnPropertyNames::style::common::KMarginBottom )
       
  1886                 {
       
  1887                 if ( !verticalMarginProcessed && !allVerticalValuesProcessed )
       
  1888                     {
       
  1889                     // is top margin also set to AUTO?
       
  1890                     CXnProperty* topMargin = aNode.MarginTopL();
       
  1891                     if ( topMargin )
       
  1892                         {
       
  1893                         if ( IsPropertyAutoL( *topMargin ) )
       
  1894                             {
       
  1895                             // both margins set to AUTO, values equal
       
  1896                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1897                             if ( remainingHeight < 0 )
       
  1898                                 {
       
  1899                                 remainingHeight = 0;
       
  1900                                 }
       
  1901                             // move rect right to fill the void
       
  1902                             TRect normalFlowBorderRect(
       
  1903                                 aNode.NormalFlowBorderRect() );
       
  1904                             contentRect.Move( 0, remainingHeight / 2 );
       
  1905                             marginRect.Resize( 0, remainingHeight );
       
  1906                             borderRect.Move( 0, remainingHeight / 2 );
       
  1907                             normalFlowBorderRect.Move( 0, remainingHeight / 2 );
       
  1908                             paddingRect.Move( 0, remainingHeight / 2 );
       
  1909                             verticalMarginProcessed = ETrue;
       
  1910                             size = TSize( size.iWidth,
       
  1911                                 size.iHeight + remainingHeight );
       
  1912                             }
       
  1913                         else
       
  1914                             {
       
  1915                             // only bottom margin set to AUTO
       
  1916                             TInt remainingHeight = aHeightToFit - size.iHeight;
       
  1917                             if ( remainingHeight < 0 )
       
  1918                                 {
       
  1919                                 remainingHeight = 0;
       
  1920                                 }
       
  1921                             // move rect right to fill the void
       
  1922                             marginRect.Resize( 0, remainingHeight );
       
  1923                             verticalMarginProcessed = ETrue;
       
  1924                             size = TSize( size.iWidth,
       
  1925                                 size.iHeight + remainingHeight );
       
  1926                             }
       
  1927                         }
       
  1928                     }
       
  1929                 }
       
  1930             }
       
  1931         }
       
  1932     aNode.SetRect( contentRect );
       
  1933     aNode.SetPaddingRect( paddingRect );
       
  1934     aNode.SetBorderRect( borderRect );
       
  1935     aNode.SetMarginRect( marginRect );
       
  1936     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  1937     return contentRect.Size();
       
  1938     }
       
  1939 
       
  1940 // -----------------------------------------------------------------------------
       
  1941 // CalculateAbsolutePositionsL()
       
  1942 // Move the rect by it's absolute positioning.
       
  1943 // -----------------------------------------------------------------------------
       
  1944 //
       
  1945 static void CalculateAbsolutePositionsL( CXnNode& aNode, TRect& aParentRect,
       
  1946     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  1947     TReal aVerticalUnitInPixels )
       
  1948     {
       
  1949     CXnProperty* topProperty = aNode.TopL();
       
  1950     CXnProperty* bottomProperty = aNode.BottomL();
       
  1951     CXnProperty* leftProperty = aNode.LeftL();
       
  1952     CXnProperty* rightProperty = aNode.RightL();
       
  1953 
       
  1954     TBool verticalValuesProcessed = EFalse;
       
  1955     TBool horizontalValuesProcessed = EFalse;
       
  1956 
       
  1957     TInt top = 0;
       
  1958     TInt bottom = 0;
       
  1959     TInt left = 0;
       
  1960     TInt right = 0;
       
  1961 
       
  1962     TRect contentRect( aNode.Rect() );
       
  1963     TRect paddingRect( aNode.PaddingRect() );
       
  1964     TRect borderRect( aNode.BorderRect() );
       
  1965     TRect marginRect( aNode.MarginRect() );
       
  1966 
       
  1967     if ( HasNodeAutoValuesL( aNode ) )
       
  1968         {
       
  1969         CXnProperty* marginTopProperty = aNode.MarginTopL();
       
  1970         CXnProperty* marginBottomProperty = aNode.MarginBottomL();
       
  1971         CXnProperty* marginLeftProperty = aNode.MarginLeftL();
       
  1972         CXnProperty* marginRightProperty = aNode.MarginRightL();
       
  1973         CXnProperty* heightProperty = aNode.HeightL();
       
  1974         CXnProperty* widthProperty = aNode.WidthL();
       
  1975         CXnProperty* maxHeightProperty = aNode.MaxHeightL();
       
  1976         CXnProperty* maxWidthProperty = aNode.MaxWidthL();
       
  1977         CXnProperty* minHeightProperty = aNode.MinHeightL();
       
  1978         CXnProperty* minWidthProperty = aNode.MinWidthL();
       
  1979 
       
  1980         // move auto value node to it's parent's top left corner
       
  1981         TInt offsetx = 0;
       
  1982         TInt offsety = 0;
       
  1983 
       
  1984         offsetx = aParentRect.iTl.iX - marginRect.iTl.iX;
       
  1985         offsety = aParentRect.iTl.iY - marginRect.iTl.iY;
       
  1986 
       
  1987         contentRect.Move( offsetx, offsety );
       
  1988         paddingRect.Move( offsetx, offsety );
       
  1989         borderRect.Move( offsetx, offsety );
       
  1990         marginRect.Move( offsetx, offsety );
       
  1991 
       
  1992         // get values
       
  1993         if ( topProperty && !IsPropertyAutoL( *topProperty ) &&
       
  1994              !IsPropertyNone( *topProperty ) )
       
  1995             {
       
  1996             top = VerticalPixelValueL( topProperty, aParentRect.Height(),
       
  1997                 aGraphicsDevice, aVerticalUnitInPixels );
       
  1998             }
       
  1999         if ( bottomProperty && !IsPropertyAutoL( *bottomProperty ) &&
       
  2000              !IsPropertyNone( *bottomProperty ) )
       
  2001             {
       
  2002             bottom = VerticalPixelValueL( bottomProperty, aParentRect.Height(),
       
  2003                 aGraphicsDevice, aVerticalUnitInPixels );
       
  2004             }
       
  2005         if ( leftProperty && !IsPropertyAutoL( *leftProperty ) &&
       
  2006              !IsPropertyNone( *leftProperty ) )
       
  2007             {
       
  2008             left = HorizontalPixelValueL( leftProperty, aParentRect.Width(),
       
  2009                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  2010             }
       
  2011         if ( rightProperty && !IsPropertyAutoL( *rightProperty ) &&
       
  2012              !IsPropertyNone( *rightProperty ) )
       
  2013             {
       
  2014             right = HorizontalPixelValueL( rightProperty, aParentRect.Width(),
       
  2015                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  2016             }
       
  2017         // node has auto values
       
  2018         TSize spaceUsed( CalculateTotalDimensionsL( aNode, EFalse, EFalse,
       
  2019             aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  2020             aVerticalUnitInPixels ) );
       
  2021         TInt heightToUse =
       
  2022             aParentRect.Height() - spaceUsed.iHeight - top - bottom;
       
  2023         TInt widthToUse =
       
  2024             aParentRect.Width() - spaceUsed.iWidth - left - right;
       
  2025 
       
  2026         if ( heightToUse < 0 )
       
  2027             {
       
  2028             heightToUse = 0;
       
  2029             }
       
  2030         if ( widthToUse < 0 )
       
  2031             {
       
  2032             widthToUse = 0;
       
  2033             }
       
  2034         // vertical auto values
       
  2035         // (margin top, margin bottom, height, top, bottom)
       
  2036         if ( IsPropertyAutoL( *heightProperty ) )
       
  2037             {
       
  2038             contentRect.Resize( 0, heightToUse );
       
  2039             paddingRect.Resize( 0, heightToUse );
       
  2040             borderRect.Resize( 0, heightToUse );
       
  2041             marginRect.Resize( 0, heightToUse );
       
  2042 
       
  2043             if ( IsLargerThanMaxSizeL( aParentRect, aNode, aGraphicsDevice,
       
  2044                  aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
       
  2045                 {
       
  2046                 if ( !IsPropertyNone( *maxHeightProperty ) )
       
  2047                     {
       
  2048                     TInt maxheight = HorizontalPixelValueL( maxHeightProperty,
       
  2049                         aParentRect.Height(), aGraphicsDevice,
       
  2050                         aHorizontalUnitInPixels );
       
  2051                     if ( maxheight < contentRect.Height() )
       
  2052                         {
       
  2053                         TInt excessheight = contentRect.Height() - maxheight;
       
  2054                         contentRect.Resize( 0, -excessheight );
       
  2055                         paddingRect.Resize( 0, -excessheight );
       
  2056                         borderRect.Resize( 0, -excessheight );
       
  2057                         marginRect.Resize( 0, -excessheight );
       
  2058                         }
       
  2059                     }
       
  2060                 }
       
  2061             if ( IsSmallerThanMinSizeL( aParentRect, aNode, aGraphicsDevice,
       
  2062                  aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
       
  2063                 {
       
  2064                 if ( !IsPropertyNone( *minHeightProperty ) )
       
  2065                     {
       
  2066                     TInt minheight = HorizontalPixelValueL( minHeightProperty,
       
  2067                         aParentRect.Height(), aGraphicsDevice,
       
  2068                         aHorizontalUnitInPixels );
       
  2069                     if ( minheight > contentRect.Height() )
       
  2070                         {
       
  2071                         TInt missingheight = minheight - contentRect.Height();
       
  2072                         contentRect.Resize( 0, missingheight );
       
  2073                         paddingRect.Resize( 0, missingheight );
       
  2074                         borderRect.Resize( 0, missingheight );
       
  2075                         marginRect.Resize( 0, missingheight );
       
  2076                         }
       
  2077                     }
       
  2078                 }
       
  2079             verticalValuesProcessed = ETrue;
       
  2080             }
       
  2081 
       
  2082         if ( !verticalValuesProcessed )
       
  2083             {
       
  2084             if ( IsPropertyAutoL( *topProperty ) &&
       
  2085                  IsPropertyAutoL( *bottomProperty ) )
       
  2086                 {
       
  2087                 // move the box down
       
  2088                 contentRect.Move( 0, heightToUse / 2 );
       
  2089                 paddingRect.Move( 0, heightToUse / 2 );
       
  2090                 borderRect.Move( 0, heightToUse / 2 );
       
  2091                 marginRect.Move( 0, heightToUse / 2 );
       
  2092                 }
       
  2093             if ( IsPropertyAutoL( *topProperty ) &&
       
  2094                  !IsPropertyAutoL( *bottomProperty ) )
       
  2095                 {
       
  2096                 // move the box down
       
  2097                 contentRect.Move( 0, heightToUse );
       
  2098                 paddingRect.Move( 0, heightToUse );
       
  2099                 borderRect.Move( 0, heightToUse );
       
  2100                 marginRect.Move( 0, heightToUse );
       
  2101                 }
       
  2102             if ( IsPropertyAutoL( *marginTopProperty ) &&
       
  2103                  IsPropertyAutoL( *marginBottomProperty ) )
       
  2104                 {
       
  2105                 // both margins auto, equal values
       
  2106                 marginRect.Resize( 0, heightToUse );
       
  2107                 paddingRect.Move( 0, heightToUse / 2 );
       
  2108                 borderRect.Move( 0, heightToUse / 2 );
       
  2109                 contentRect.Move( 0, heightToUse / 2 );
       
  2110                 }
       
  2111             if ( !IsPropertyAutoL( *marginTopProperty ) &&
       
  2112                  IsPropertyAutoL( *marginBottomProperty ) )
       
  2113                 {
       
  2114                 // only top margin auto
       
  2115                 marginRect.Resize( 0, heightToUse );
       
  2116                 paddingRect.Move( 0, heightToUse );
       
  2117                 borderRect.Move( 0, heightToUse );
       
  2118                 contentRect.Move( 0, heightToUse );
       
  2119                 }
       
  2120             if ( IsPropertyAutoL( *marginTopProperty ) &&
       
  2121                  !IsPropertyAutoL( *marginBottomProperty ) )
       
  2122                 {
       
  2123                 // only bottom margin auto
       
  2124                 marginRect.Resize( 0, heightToUse );
       
  2125                 }
       
  2126             }
       
  2127 
       
  2128         // horizontal auto values
       
  2129         // (margin left, margin right, width)
       
  2130         if ( IsPropertyAutoL( *widthProperty ) )
       
  2131             {
       
  2132             contentRect.Resize( widthToUse, 0 );
       
  2133             paddingRect.Resize( widthToUse, 0 );;
       
  2134             borderRect.Resize( widthToUse, 0 );
       
  2135             marginRect.Resize( widthToUse, 0 );
       
  2136             if ( IsLargerThanMaxSizeL( aParentRect, aNode, aGraphicsDevice,
       
  2137                  aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
       
  2138                 {
       
  2139                 if ( !IsPropertyNone( *maxWidthProperty ) )
       
  2140                     {
       
  2141                     TInt maxwidth = HorizontalPixelValueL( maxWidthProperty,
       
  2142                         aParentRect.Width(), aGraphicsDevice,
       
  2143                         aHorizontalUnitInPixels );
       
  2144                     if ( maxwidth < contentRect.Width() )
       
  2145                         {
       
  2146                         TInt excesswidth = contentRect.Width() - maxwidth;
       
  2147                         contentRect.Resize( -excesswidth, 0 );
       
  2148                         paddingRect.Resize( -excesswidth, 0 );
       
  2149                         borderRect.Resize( -excesswidth, 0 );
       
  2150                         marginRect.Resize( -excesswidth, 0 );
       
  2151                         }
       
  2152                     }
       
  2153                 }
       
  2154             if ( IsSmallerThanMinSizeL( aParentRect, aNode, aGraphicsDevice,
       
  2155                  aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
       
  2156                 {
       
  2157                 if ( !IsPropertyNone( *minWidthProperty ) )
       
  2158                     {
       
  2159                     TInt minwidth = HorizontalPixelValueL( minWidthProperty,
       
  2160                         aParentRect.Width(), aGraphicsDevice,
       
  2161                         aHorizontalUnitInPixels );
       
  2162                     if ( minwidth > contentRect.Width() )
       
  2163                         {
       
  2164                         TInt missingwidth = minwidth - contentRect.Width();
       
  2165                         contentRect.Resize( missingwidth, 0 );
       
  2166                         paddingRect.Resize( missingwidth, 0 );
       
  2167                         borderRect.Resize( missingwidth, 0 );
       
  2168                         marginRect.Resize( missingwidth, 0 );
       
  2169                         }
       
  2170                     }
       
  2171                 }
       
  2172             horizontalValuesProcessed = ETrue;
       
  2173             }
       
  2174         if ( !horizontalValuesProcessed )
       
  2175             {
       
  2176             if ( IsPropertyAutoL( *leftProperty ) &&
       
  2177                  IsPropertyAutoL( *rightProperty ) )
       
  2178                 {
       
  2179                 // move the box left
       
  2180                 contentRect.Move( widthToUse / 2, 0 );
       
  2181                 paddingRect.Move( widthToUse / 2, 0 );
       
  2182                 borderRect.Move( widthToUse / 2, 0 );
       
  2183                 marginRect.Move( widthToUse / 2, 0 );
       
  2184                 }
       
  2185             if ( IsPropertyAutoL( *leftProperty ) &&
       
  2186                  !IsPropertyAutoL( *rightProperty ) )
       
  2187                 {
       
  2188                 // move the box left
       
  2189                 contentRect.Move( widthToUse, 0 );
       
  2190                 paddingRect.Move( widthToUse, 0 );
       
  2191                 borderRect.Move( widthToUse, 0 );
       
  2192                 marginRect.Move( widthToUse, 0 );
       
  2193                 }
       
  2194             if ( IsPropertyAutoL( *marginLeftProperty ) &&
       
  2195                  IsPropertyAutoL( *marginRightProperty ) )
       
  2196                 {
       
  2197                 // both margins auto, equal values
       
  2198                 marginRect.Resize( widthToUse, 0 );
       
  2199                 paddingRect.Move( widthToUse / 2, 0 );
       
  2200                 borderRect.Move( widthToUse / 2, 0 );
       
  2201                 contentRect.Move( widthToUse / 2, 0 );
       
  2202                 }
       
  2203             if ( !IsPropertyAutoL( *marginLeftProperty ) &&
       
  2204                  IsPropertyAutoL( *marginRightProperty ) )
       
  2205                 {
       
  2206                 // only right margin auto
       
  2207                 marginRect.Resize( widthToUse, 0 );
       
  2208                 paddingRect.Move( widthToUse, 0 );
       
  2209                 borderRect.Move( widthToUse, 0 );
       
  2210                 contentRect.Move( widthToUse, 0 );
       
  2211                 }
       
  2212             if ( IsPropertyAutoL( *marginLeftProperty ) &&
       
  2213                  !IsPropertyAutoL( *marginRightProperty ) )
       
  2214                 {
       
  2215                 // only left margin auto
       
  2216                 marginRect.Resize( widthToUse, 0 );
       
  2217                 }
       
  2218             }
       
  2219         }
       
  2220 
       
  2221     // Move the rect to desired position
       
  2222     if ( topProperty )
       
  2223         {
       
  2224         if ( !IsPropertyAutoL( *topProperty ) &&
       
  2225              !IsPropertyNone( *topProperty ) )
       
  2226             {
       
  2227             TInt y = VerticalPixelValueL( topProperty, aParentRect.Height(),
       
  2228                 aGraphicsDevice, aVerticalUnitInPixels );
       
  2229             contentRect.Move( 0, y );
       
  2230             paddingRect.Move( 0, y );
       
  2231             borderRect.Move( 0, y );
       
  2232             marginRect.Move( 0, y );
       
  2233             }
       
  2234         }
       
  2235     if ( leftProperty )
       
  2236         {
       
  2237         if ( !IsPropertyAutoL( *leftProperty ) &&
       
  2238              !IsPropertyNone( *leftProperty ) )
       
  2239             {
       
  2240             TInt x = HorizontalPixelValueL( leftProperty, aParentRect.Width(),
       
  2241                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  2242             contentRect.Move( x, 0 );
       
  2243             paddingRect.Move( x, 0 );
       
  2244             borderRect.Move( x, 0 );
       
  2245             marginRect.Move( x, 0 );
       
  2246             }
       
  2247         }
       
  2248     if ( bottomProperty )
       
  2249         {
       
  2250          if ( !IsPropertyAutoL( *bottomProperty ) &&
       
  2251               !IsPropertyNone( *bottomProperty ) )
       
  2252             {
       
  2253             TInt py = VerticalPixelValueL( bottomProperty,
       
  2254                 aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
       
  2255             contentRect.Move( 0, -py );
       
  2256             paddingRect.Move( 0, -py );
       
  2257             borderRect.Move( 0, -py );
       
  2258             marginRect.Move( 0, -py );
       
  2259             }
       
  2260         }
       
  2261     if ( rightProperty )
       
  2262         {
       
  2263         if ( !IsPropertyAutoL( *rightProperty ) &&
       
  2264              !IsPropertyNone( *rightProperty ) )
       
  2265             {
       
  2266             TInt px = HorizontalPixelValueL( rightProperty,
       
  2267                 aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
       
  2268             contentRect.Move( -px, 0 );
       
  2269             paddingRect.Move( -px, 0 );
       
  2270             borderRect.Move( -px, 0 );
       
  2271             marginRect.Move( -px, 0 );
       
  2272             }
       
  2273         }
       
  2274 
       
  2275     aNode.SetRect( contentRect );
       
  2276     aNode.SetPaddingRect( paddingRect );
       
  2277     aNode.SetBorderRect( borderRect );
       
  2278     aNode.SetMarginRect( marginRect );
       
  2279 
       
  2280     DropExceedingRectL( aParentRect, aNode );
       
  2281     }
       
  2282 
       
  2283 // -----------------------------------------------------------------------------
       
  2284 // CalculateBorderL()
       
  2285 // Move the rect by adding the border.
       
  2286 // -----------------------------------------------------------------------------
       
  2287 //
       
  2288 static void CalculateBorderL( CXnNode& aNode, TRect& aParentRect,
       
  2289     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  2290     TReal aVerticalUnitInPixels )
       
  2291     {
       
  2292     TInt offsetx = 0;
       
  2293     TInt offsety = 0;
       
  2294 
       
  2295     TInt borderleft = 0;
       
  2296     TInt borderright = 0;
       
  2297     TInt bordertop = 0;
       
  2298     TInt borderbottom = 0;
       
  2299 
       
  2300     CXnProperty* commonBorderStyle = aNode.BorderStyleL();
       
  2301     CXnProperty* borderImage = aNode.BorderImageL();
       
  2302     CXnProperty* borderStyle = aNode.BorderLeftStyleL();
       
  2303     CXnProperty* borderproperty = aNode.BorderLeftL();
       
  2304 
       
  2305     // if border width is defined
       
  2306     CXnProperty* borderwidthproperty = aNode.BorderWidthL();
       
  2307     if ( !borderproperty )
       
  2308         {
       
  2309         borderproperty = borderwidthproperty;
       
  2310         }
       
  2311 
       
  2312     if ( borderwidthproperty && ( ( commonBorderStyle &&
       
  2313          !IsPropertyNone( *commonBorderStyle ) ) ||
       
  2314         ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
       
  2315         {
       
  2316         TInt bordervertical = 0;
       
  2317         TInt borderhorizontal = 0;
       
  2318 
       
  2319         DetermineBorderWidthsL( borderwidthproperty, bordervertical,
       
  2320             borderhorizontal, aParentRect, aGraphicsDevice,
       
  2321             aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  2322 
       
  2323         borderleft = borderhorizontal;
       
  2324         borderright = borderhorizontal;
       
  2325         bordertop = bordervertical;
       
  2326         borderbottom = bordervertical;
       
  2327         }
       
  2328 
       
  2329     TInt ignore;
       
  2330     // use border width only if there is valid border style or border image
       
  2331     if ( borderproperty && ( ( borderStyle &&
       
  2332          !IsPropertyNone( *borderStyle ) ) ||
       
  2333         ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
       
  2334         ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
       
  2335         {
       
  2336         DetermineBorderWidthsL( borderproperty, ignore, borderleft,
       
  2337             aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  2338             aVerticalUnitInPixels );
       
  2339         }
       
  2340     borderStyle = aNode.BorderRightStyleL();
       
  2341     borderproperty = aNode.BorderRightL();
       
  2342     if ( !borderproperty )
       
  2343         {
       
  2344         borderproperty = borderwidthproperty;
       
  2345         }
       
  2346     if ( borderproperty && ( ( borderStyle &&
       
  2347          !IsPropertyNone( *borderStyle ) ) ||
       
  2348         ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
       
  2349         ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
       
  2350         {
       
  2351         DetermineBorderWidthsL( borderproperty, ignore, borderright,
       
  2352             aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  2353             aVerticalUnitInPixels );
       
  2354         }
       
  2355     borderStyle = aNode.BorderTopStyleL();
       
  2356     borderproperty = aNode.BorderTopL();
       
  2357     if ( !borderproperty )
       
  2358         {
       
  2359         borderproperty = borderwidthproperty;
       
  2360         }
       
  2361     if ( borderproperty && ( ( borderStyle &&
       
  2362          !IsPropertyNone( *borderStyle ) ) ||
       
  2363         ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
       
  2364         ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
       
  2365         {
       
  2366         DetermineBorderWidthsL( borderproperty, bordertop, ignore,
       
  2367             aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  2368             aVerticalUnitInPixels );
       
  2369         }
       
  2370     borderStyle = aNode.BorderBottomStyleL();
       
  2371     borderproperty = aNode.BorderBottomL();
       
  2372     if ( !borderproperty )
       
  2373         {
       
  2374         borderproperty = borderwidthproperty;
       
  2375         }
       
  2376     if ( borderproperty && ( ( borderStyle &&
       
  2377          !IsPropertyNone( *borderStyle ) ) ||
       
  2378         ( commonBorderStyle && !IsPropertyNone( *commonBorderStyle ) ) ||
       
  2379         ( borderImage && !IsPropertyNone( *borderImage ) ) ) )
       
  2380         {
       
  2381         DetermineBorderWidthsL( borderproperty, borderbottom, ignore,
       
  2382             aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  2383             aVerticalUnitInPixels );
       
  2384         }
       
  2385 
       
  2386     offsetx = borderleft; // move the client rect of the element this much right
       
  2387     offsety = bordertop; //  move the client rect of the element this much down
       
  2388 
       
  2389     TRect newrect( aNode.Rect() );
       
  2390     newrect.Move( offsetx, offsety );
       
  2391     aNode.SetRect( newrect );
       
  2392     // and move the padding rect also, Ari 5.8.2005
       
  2393     TRect paddingrect = aNode.PaddingRect();
       
  2394     TPoint origin( paddingrect.iTl );
       
  2395     paddingrect.Move( offsetx, offsety );
       
  2396     aNode.SetPaddingRect( paddingrect );
       
  2397 
       
  2398     TRect borderrect( origin, TSize(
       
  2399         borderleft + borderright + paddingrect.Width(),
       
  2400         bordertop + borderbottom + paddingrect.Height() ) );
       
  2401     TRect normalFlowBorderRect( origin, TSize(
       
  2402         borderleft + borderright + paddingrect.Width(),
       
  2403         bordertop + borderbottom + paddingrect.Height() ) );
       
  2404     aNode.SetBorderRect( borderrect );
       
  2405     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  2406     }
       
  2407 
       
  2408 // -----------------------------------------------------------------------------
       
  2409 // CalculateAbsoluteMarginL()
       
  2410 // Place child areas to parent rect and calculate margins.
       
  2411 // -----------------------------------------------------------------------------
       
  2412 //
       
  2413 static void CalculateAbsoluteMarginL( CXnNode& aParent, CXnNode& aNode,
       
  2414     CXnNode* aPreviousSibling, const TDesC8& aParentBlockProgression,
       
  2415     const TDesC8& aParentDirection, TRect& aParentRect,
       
  2416     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  2417     TReal aVerticalUnitInPixels )
       
  2418     {
       
  2419     TInt previousPosition = 0;
       
  2420     CXnProperty* marginProperty = NULL;
       
  2421     TInt marginLeft = 0;
       
  2422     TInt marginRight = 0;
       
  2423     TInt marginTop = 0;
       
  2424     TInt marginBottom = 0;
       
  2425 
       
  2426     marginProperty = aNode.MarginLeftL();
       
  2427 
       
  2428     if ( marginProperty )
       
  2429         {
       
  2430         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2431             {
       
  2432             marginLeft = HorizontalPixelValueL( marginProperty,
       
  2433                 aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
       
  2434             }
       
  2435         }
       
  2436 
       
  2437     marginProperty = aNode.MarginRightL();
       
  2438 
       
  2439     if ( marginProperty )
       
  2440         {
       
  2441         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2442             {
       
  2443             marginRight = HorizontalPixelValueL( marginProperty,
       
  2444                 aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
       
  2445             }
       
  2446         }
       
  2447 
       
  2448     marginProperty = aNode.MarginTopL();
       
  2449 
       
  2450     if ( marginProperty )
       
  2451         {
       
  2452         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2453             {
       
  2454             marginTop = VerticalPixelValueL( marginProperty,
       
  2455                 aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
       
  2456             }
       
  2457         }
       
  2458 
       
  2459     marginProperty = aNode.MarginBottomL();
       
  2460 
       
  2461     if ( marginProperty )
       
  2462         {
       
  2463         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2464             {
       
  2465             marginBottom = VerticalPixelValueL( marginProperty,
       
  2466                 aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
       
  2467             }
       
  2468         }
       
  2469 
       
  2470     TInt offsetx = 0;
       
  2471     TInt offsety = 0;
       
  2472 
       
  2473     if ( &aParent == &aNode )
       
  2474         {
       
  2475         aParentRect.Move( -aParentRect.iTl.iX, -aParentRect.iTl.iY );
       
  2476         }
       
  2477 
       
  2478     // if all properties are defined and block progression is LR, margin right
       
  2479     // is ignored and replaced by remaining
       
  2480     // if block progression is RL, same thing to margin left
       
  2481 
       
  2482     // previous sibling was found, get it's margin and previous coordinate to
       
  2483     // define next child's position
       
  2484     previousPosition = ( aPreviousSibling != NULL ) ?
       
  2485         GetPositionL( *aPreviousSibling, aParentBlockProgression,
       
  2486         aParentDirection ) : 0;
       
  2487 
       
  2488     // Move the rect considering previous child
       
  2489     // Margins are collapsed, larger is used
       
  2490     if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
       
  2491         {
       
  2492         if ( aParentBlockProgression ==
       
  2493              XnPropertyNames::style::common::block_progression::KLR ||
       
  2494              aParentBlockProgression ==
       
  2495              XnPropertyNames::style::common::block_progression::KRL )
       
  2496             {
       
  2497             // offset to parent rect's top left corner
       
  2498             if ( !aPreviousSibling )
       
  2499                 {
       
  2500                 offsetx = aParentRect.iTl.iX;
       
  2501                 }
       
  2502 
       
  2503             offsety = aParentRect.iTl.iY + marginTop;
       
  2504             TInt prevMarginRight = 0;
       
  2505 
       
  2506             if ( aPreviousSibling )
       
  2507                 {
       
  2508                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2509                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2510                 prevMarginRight =
       
  2511                     previousMarginRect.iBr.iX - previousBorderRect.iBr.iX;
       
  2512                 }
       
  2513 
       
  2514             if ( prevMarginRight > marginLeft )
       
  2515                 {
       
  2516                 offsetx += previousPosition + prevMarginRight;
       
  2517                 }
       
  2518             else
       
  2519                 {
       
  2520                 offsetx += previousPosition + marginLeft;
       
  2521                 }
       
  2522             }
       
  2523         else // TB or BT
       
  2524             {
       
  2525             // offset to parent rect's top left corner
       
  2526             offsetx = aParentRect.iTl.iX + marginLeft;
       
  2527 
       
  2528             if ( !aPreviousSibling )
       
  2529                 {
       
  2530                 offsety = aParentRect.iTl.iY;
       
  2531                 }
       
  2532 
       
  2533             TInt prevMarginBottom = 0;
       
  2534 
       
  2535             if ( aPreviousSibling )
       
  2536                 {
       
  2537                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2538                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2539                 prevMarginBottom =
       
  2540                     previousMarginRect.iBr.iY - previousBorderRect.iBr.iY;
       
  2541                 }
       
  2542 
       
  2543             if ( prevMarginBottom > marginTop )
       
  2544                 {
       
  2545                 offsety += previousPosition + prevMarginBottom;
       
  2546                 }
       
  2547             else
       
  2548                 {
       
  2549                 offsety += previousPosition + marginTop;
       
  2550                 }
       
  2551             }
       
  2552         }
       
  2553     else // RTL
       
  2554         {
       
  2555         if ( aParentBlockProgression ==
       
  2556              XnPropertyNames::style::common::block_progression::KLR ||
       
  2557              aParentBlockProgression ==
       
  2558              XnPropertyNames::style::common::block_progression::KRL )
       
  2559             {
       
  2560             // offset to parent rect's top right corner
       
  2561             if ( !aPreviousSibling )
       
  2562                 {
       
  2563                 offsetx = aParentRect.Width() - aNode.BorderRect().Width() +
       
  2564                     aParentRect.iTl.iX;
       
  2565                 }
       
  2566             else
       
  2567                 {
       
  2568                 offsetx = previousPosition - aNode.BorderRect().Width();
       
  2569                 }
       
  2570 
       
  2571             offsety = aParentRect.iTl.iY + marginTop;
       
  2572 
       
  2573             TInt prevMarginLeft = 0;
       
  2574 
       
  2575             if ( aPreviousSibling )
       
  2576                 {
       
  2577                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2578                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2579                 prevMarginLeft =
       
  2580                     previousBorderRect.iTl.iX - previousMarginRect.iTl.iX;
       
  2581                 }
       
  2582 
       
  2583             if ( prevMarginLeft > marginRight )
       
  2584                 {
       
  2585                 offsetx -= prevMarginLeft;
       
  2586                 }
       
  2587             else
       
  2588                 {
       
  2589                 offsetx -= marginRight;
       
  2590                 }
       
  2591             }
       
  2592         else // TB or BT
       
  2593             {
       
  2594             // offset to parent rect's bottom left corner
       
  2595             offsetx += aParentRect.iTl.iX + marginRight;
       
  2596 
       
  2597             if ( !aPreviousSibling )
       
  2598                 {
       
  2599                 // start from bottom of parent rect
       
  2600                 offsety = aParentRect.Height() - aNode.BorderRect().Height();
       
  2601                 }
       
  2602             else
       
  2603                 {
       
  2604                 offsety = previousPosition - aNode.BorderRect().Height();
       
  2605                 }
       
  2606 
       
  2607             TInt prevMarginTop = 0;
       
  2608 
       
  2609             if ( aPreviousSibling )
       
  2610                 {
       
  2611                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2612                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2613                 prevMarginTop =
       
  2614                     previousBorderRect.iTl.iY - previousMarginRect.iTl.iY;
       
  2615                 }
       
  2616 
       
  2617             // collapse margins
       
  2618             if ( prevMarginTop > marginBottom )
       
  2619                 {
       
  2620                 offsety -= prevMarginTop;
       
  2621                 }
       
  2622             else
       
  2623                 {
       
  2624                 offsety -= marginBottom;
       
  2625                 }
       
  2626             }
       
  2627         }
       
  2628 
       
  2629     TRect borderRect = TRect( aNode.BorderRect() );
       
  2630     TRect normalFlowBorderRect = TRect( aNode.NormalFlowBorderRect() );
       
  2631     // this is the top left corner of margin rect
       
  2632     TPoint origin( borderRect.iTl - TPoint( marginLeft, marginTop ) );
       
  2633 
       
  2634     if ( &aParent != &aNode )
       
  2635         {
       
  2636         // set content rect
       
  2637         TRect newRect( aNode.Rect() );
       
  2638         newRect.Move( offsetx, offsety );
       
  2639         aNode.SetRect( newRect );
       
  2640 
       
  2641         // set padding rect
       
  2642         TRect paddingRect( aNode.PaddingRect() );
       
  2643         paddingRect.Move( offsetx, offsety );
       
  2644         aNode.SetPaddingRect( paddingRect );
       
  2645 
       
  2646         // set border rect
       
  2647         borderRect.Move( offsetx, offsety );
       
  2648         normalFlowBorderRect.Move( offsetx, offsety );
       
  2649         // this is the top left corner of margin rect
       
  2650         origin = TPoint( borderRect.iTl - TPoint( marginLeft, marginTop ) );
       
  2651         aNode.SetBorderRect( borderRect );
       
  2652         aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  2653         }
       
  2654 
       
  2655     TRect marginRect( origin,
       
  2656         TSize( marginLeft + marginRight + borderRect.Width(),
       
  2657         marginTop + marginBottom + borderRect.Height() ) );
       
  2658 
       
  2659     aNode.SetMarginRect( marginRect );
       
  2660 
       
  2661     // Within this function, the rects are adjusted if the display-priority is 0
       
  2662     // and margin rect exceeds parent's content rect.
       
  2663     DropExceedingRectL( aParentRect, aNode );
       
  2664 
       
  2665     if( IsNodeTooltip( aNode ) || aNode.Type()->Type() == KWidgetExtensionNodeName || 
       
  2666          aNode.Type()->Type() == KPopUpNodeName )
       
  2667         {
       
  2668         // because tooltip has it's own window, move margin rect to 0,0
       
  2669         // and all other rects as much up left
       
  2670         TRect marginRect = aNode.MarginRect();
       
  2671 
       
  2672         TRect borderRect = aNode.BorderRect();
       
  2673         TRect paddingRect = aNode.PaddingRect();
       
  2674         TRect contentRect = aNode.Rect();
       
  2675         TInt x = marginRect.iTl.iX;
       
  2676         TInt y = marginRect.iTl.iY;
       
  2677         marginRect.Move( -x, -y );
       
  2678 
       
  2679         borderRect.Move( -x, -y );
       
  2680         paddingRect.Move( -x, -y );
       
  2681         contentRect.Move( -x, -y );
       
  2682 
       
  2683         aNode.SetMarginRect( marginRect );
       
  2684 
       
  2685         aNode.SetBorderRect( borderRect );
       
  2686         aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  2687         aNode.SetPaddingRect( paddingRect );
       
  2688         aNode.SetRect( contentRect );
       
  2689         }
       
  2690     }
       
  2691 
       
  2692 // -----------------------------------------------------------------------------
       
  2693 // CalculateAbsoluteMarginL()
       
  2694 // Place child areas to parent rect and calculate margins.
       
  2695 // -----------------------------------------------------------------------------
       
  2696 //
       
  2697 static void CalculateMarginL( CXnNode& aParent, CXnNode& aNode,
       
  2698     CXnNode* aPreviousSibling, const TDesC8& aParentBlockProgression,
       
  2699     const TDesC8& aParentDirection, TRect& aParentRect,
       
  2700     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  2701     TReal aVerticalUnitInPixels, TInt& aColumnWidth, TInt& aColumnMargin )
       
  2702     {
       
  2703     if( aParent.Control() && aParent.Control()->OwnsWindow() )
       
  2704         {
       
  2705         aParentRect = TRect( aParentRect.iTl - aParent.MarginRect().iTl, aParentRect.Size() );
       
  2706         }
       
  2707 
       
  2708     CXnProperty* marginProperty = NULL;
       
  2709     TInt marginLeft = 0;
       
  2710     TInt marginRight = 0;
       
  2711     TInt marginTop = 0;
       
  2712     TInt marginBottom = 0;
       
  2713 
       
  2714     marginProperty = aNode.MarginLeftL();
       
  2715     if ( marginProperty )
       
  2716         {
       
  2717         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2718             {
       
  2719             marginLeft = HorizontalPixelValueL(
       
  2720                 marginProperty, aParentRect.Width(),
       
  2721                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  2722             }
       
  2723         }
       
  2724 
       
  2725     marginProperty = aNode.MarginRightL();
       
  2726     if ( marginProperty )
       
  2727         {
       
  2728         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2729             {
       
  2730             marginRight = HorizontalPixelValueL(
       
  2731                 marginProperty, aParentRect.Width(),
       
  2732                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  2733             }
       
  2734         }
       
  2735 
       
  2736     marginProperty = aNode.MarginTopL();
       
  2737     if ( marginProperty )
       
  2738         {
       
  2739         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2740             {
       
  2741             marginTop = VerticalPixelValueL(
       
  2742                 marginProperty, aParentRect.Height(),
       
  2743                 aGraphicsDevice, aVerticalUnitInPixels );
       
  2744             }
       
  2745         }
       
  2746 
       
  2747     marginProperty = aNode.MarginBottomL();
       
  2748     if ( marginProperty )
       
  2749         {
       
  2750         if ( !IsPropertyAutoL( *marginProperty ) )
       
  2751             {
       
  2752             marginBottom = VerticalPixelValueL(
       
  2753                 marginProperty, aParentRect.Height(),
       
  2754                 aGraphicsDevice, aVerticalUnitInPixels );
       
  2755             }
       
  2756         }
       
  2757 
       
  2758     TInt offsetx = 0;
       
  2759     TInt offsety = 0;
       
  2760 
       
  2761     //What's this???
       
  2762     if ( &aParent == &aNode )
       
  2763         {
       
  2764         aParentRect.Move( -aParentRect.iTl.iX, -aParentRect.iTl.iY );
       
  2765         }
       
  2766 
       
  2767     // Move the rect considering previous child
       
  2768     // Margins are collapsed, larger is used
       
  2769     if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
       
  2770         {
       
  2771         //   LTR , TB
       
  2772         //  *********
       
  2773         //  | 1 | 4 |
       
  2774         //  | 2 | 5 |
       
  2775         //  | 3 | 6 |
       
  2776         //  *********
       
  2777         if ( aParentBlockProgression ==
       
  2778              XnPropertyNames::style::common::block_progression::KTB )
       
  2779             {
       
  2780             // First we need to know where to layout next sibling
       
  2781             // Try first under the previous sibling...
       
  2782             if ( aPreviousSibling )
       
  2783                 {
       
  2784                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2785                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2786                 TBool layoutUnderPrevious( EFalse );
       
  2787                 TInt height = aNode.MarginRect().Height();
       
  2788                 TInt prevMarginBottom =
       
  2789                     previousMarginRect.iBr.iY - previousBorderRect.iBr.iY;
       
  2790                 if ( prevMarginBottom < marginTop )
       
  2791                     {
       
  2792                     height -= prevMarginBottom;
       
  2793                     }
       
  2794                 else
       
  2795                     {
       
  2796                     height -= marginTop;
       
  2797                     }
       
  2798                 if(height <= aParentRect.iBr.iY - previousMarginRect.iBr.iY || IsSrollableBox(aNode))
       
  2799                     {
       
  2800                     layoutUnderPrevious = ETrue;
       
  2801                     }
       
  2802 
       
  2803                 // ...then to the next column
       
  2804                 if ( !layoutUnderPrevious )
       
  2805                     {
       
  2806                     TInt width =
       
  2807                         aNode.BorderRect().Width() + marginLeft + marginRight;
       
  2808                     if ( aColumnMargin < marginLeft )
       
  2809                         {
       
  2810                         width -= aColumnMargin;
       
  2811                         }
       
  2812                     else
       
  2813                         {
       
  2814                         width -= marginLeft;
       
  2815                         }
       
  2816                     if ( width + aColumnWidth <= aParentRect.Width() )
       
  2817                         {
       
  2818                         offsety = aParentRect.iTl.iY + marginTop;
       
  2819                         if ( aColumnMargin < marginLeft )
       
  2820                             {
       
  2821                             offsetx = aParentRect.iTl.iX + aColumnWidth -
       
  2822                                 aColumnMargin + marginLeft;
       
  2823                             }
       
  2824                         else
       
  2825                             {
       
  2826                             offsetx = aParentRect.iTl.iX + aColumnWidth;
       
  2827                             }
       
  2828                         }
       
  2829                     else
       
  2830                         {
       
  2831                         layoutUnderPrevious = ETrue;
       
  2832                         }
       
  2833                     }
       
  2834                 if ( layoutUnderPrevious )
       
  2835                     {
       
  2836                     offsetx = 
       
  2837                         aPreviousSibling->MarginRect().iTl.iX + marginLeft;
       
  2838                     if ( prevMarginBottom > marginTop )
       
  2839                         {
       
  2840                         // margin of this node is collapsed
       
  2841                         offsety = previousMarginRect.iBr.iY;
       
  2842                         }
       
  2843                     else
       
  2844                         {
       
  2845                         // margin of the previous node is collapsed
       
  2846                         offsety = previousBorderRect.iBr.iY + marginTop;
       
  2847                         }
       
  2848                     }
       
  2849                 }
       
  2850             else
       
  2851                 {
       
  2852                 // offset to parent rect's top left corner
       
  2853                 offsetx = aParentRect.iTl.iX + marginLeft;
       
  2854                 offsety = aParentRect.iTl.iY + marginTop;
       
  2855                 }
       
  2856             }
       
  2857 
       
  2858         //   LTR , BT
       
  2859         //  *********
       
  2860         //  | 3 | 6 |
       
  2861         //  | 2 | 5 |
       
  2862         //  | 1 | 4 |
       
  2863         //  *********
       
  2864         else if ( aParentBlockProgression ==
       
  2865                   XnPropertyNames::style::common::block_progression::KBT )
       
  2866             {
       
  2867             // First we need to know where to layout next sibling
       
  2868             // Try first above the previous sibling...
       
  2869             if ( aPreviousSibling )
       
  2870                 {
       
  2871                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2872                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2873                 TBool layoutAbovePrevious( EFalse );
       
  2874                 TInt height =
       
  2875                     aNode.BorderRect().Height() + marginTop + marginBottom;
       
  2876                 TInt prevMarginTop =
       
  2877                     previousBorderRect.iTl.iY - previousMarginRect.iTl.iY;
       
  2878                 if ( prevMarginTop < marginBottom )
       
  2879                     {
       
  2880                     height -= prevMarginTop;
       
  2881                     }
       
  2882                 else
       
  2883                     {
       
  2884                     height -= marginBottom;
       
  2885                     }
       
  2886                 if ( height <= previousMarginRect.iTl.iY - aParentRect.iTl.iY )
       
  2887                     {
       
  2888                     layoutAbovePrevious = ETrue;
       
  2889                     }
       
  2890 
       
  2891                 // ...then to the next column
       
  2892                 if ( !layoutAbovePrevious )
       
  2893                     {
       
  2894                     TInt width =
       
  2895                         aNode.BorderRect().Width() + marginLeft + marginRight;
       
  2896                     if ( aColumnMargin < marginLeft )
       
  2897                         {
       
  2898                         width -= aColumnMargin;
       
  2899                         }
       
  2900                     else
       
  2901                         {
       
  2902                         width -= marginLeft;
       
  2903                         }
       
  2904                     if ( width + aColumnWidth <= aParentRect.Width() )
       
  2905                         {
       
  2906                         offsety = aParentRect.iBr.iY - marginBottom -
       
  2907                             aNode.BorderRect().Height();
       
  2908                         if ( aColumnMargin < marginLeft )
       
  2909                             {
       
  2910                             offsetx = aParentRect.iTl.iX + aColumnWidth -
       
  2911                                 aColumnMargin + marginLeft;
       
  2912                             }
       
  2913                         else
       
  2914                             {
       
  2915                             offsetx = aParentRect.iTl.iX + aColumnWidth;
       
  2916                             }
       
  2917                         }
       
  2918                     else
       
  2919                         {
       
  2920                         layoutAbovePrevious = ETrue;
       
  2921                         }
       
  2922                     }
       
  2923                 if ( layoutAbovePrevious )
       
  2924                     {
       
  2925                     offsetx =
       
  2926                         aPreviousSibling->MarginRect().iTl.iX + marginLeft;
       
  2927                     if ( prevMarginTop > marginBottom )
       
  2928                         {
       
  2929                         // margin of this node is collapsed
       
  2930                         offsety = previousMarginRect.iTl.iY -
       
  2931                             aNode.BorderRect().Height();
       
  2932                         }
       
  2933                     else
       
  2934                         {
       
  2935                         // margin of the previous node is collapsed
       
  2936                         offsety = previousBorderRect.iTl.iY - marginBottom -
       
  2937                             aNode.BorderRect().Height();
       
  2938                         }
       
  2939                     }
       
  2940                 }
       
  2941             else
       
  2942                 {
       
  2943                 offsetx = aParentRect.iTl.iX + marginLeft;
       
  2944                 offsety = aParentRect.iBr.iY - marginBottom -
       
  2945                     aNode.BorderRect().Height();
       
  2946                 }
       
  2947             }
       
  2948 
       
  2949         //   LTR , LR
       
  2950         //  *********
       
  2951         //  | 5 | 6 |
       
  2952         //  | 3 | 4 |
       
  2953         //  | 1 | 2 |
       
  2954         //  *********
       
  2955         else if ( aParentBlockProgression ==
       
  2956                   XnPropertyNames::style::common::block_progression::KLR )
       
  2957             {
       
  2958             if ( aPreviousSibling )
       
  2959                 {
       
  2960                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  2961                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  2962                 TBool layoutNextToPrevious( EFalse );
       
  2963                 TInt width =
       
  2964                     aNode.BorderRect().Width() + marginRight + marginLeft;
       
  2965                 TInt prevMarginRight =
       
  2966                     previousMarginRect.iBr.iX - previousBorderRect.iBr.iX;
       
  2967                 if ( prevMarginRight < marginLeft )
       
  2968                     {
       
  2969                     width -= prevMarginRight;
       
  2970                     }
       
  2971                 else
       
  2972                     {
       
  2973                     width -= marginLeft;
       
  2974                     }
       
  2975                 if ( width <= aParentRect.iBr.iX - previousMarginRect.iBr.iX )
       
  2976                     {
       
  2977                     layoutNextToPrevious = ETrue;
       
  2978                     }
       
  2979 
       
  2980                 if ( !layoutNextToPrevious )
       
  2981                     {
       
  2982                     TInt height = aNode.BorderRect().Height() + marginTop +
       
  2983                         marginBottom;
       
  2984                     if ( aColumnMargin < marginBottom )
       
  2985                         {
       
  2986                         height -= aColumnMargin;
       
  2987                         }
       
  2988                     else
       
  2989                         {
       
  2990                         height -= marginBottom;
       
  2991                         }
       
  2992                     if ( height + aColumnWidth <= aParentRect.Height() )
       
  2993                         {
       
  2994                         offsetx = aParentRect.iTl.iX + marginLeft;
       
  2995                         if ( aColumnMargin < marginTop )
       
  2996                             {
       
  2997                             offsety = aParentRect.iBr.iY - aColumnWidth +
       
  2998                                 aColumnMargin - aNode.BorderRect().Height() -
       
  2999                                 marginBottom;
       
  3000                             }
       
  3001                         else
       
  3002                             {
       
  3003                             offsety = aParentRect.iBr.iY - aColumnWidth -
       
  3004                                 aNode.BorderRect().Height();
       
  3005                             }
       
  3006                         }
       
  3007                     else
       
  3008                         {
       
  3009                         layoutNextToPrevious = ETrue;
       
  3010                         }
       
  3011                     }
       
  3012                 if ( layoutNextToPrevious )
       
  3013                     {
       
  3014                     offsety = aPreviousSibling->MarginRect().iBr.iY -
       
  3015                         aNode.BorderRect().Height() - marginBottom;
       
  3016                     if ( prevMarginRight > marginLeft )
       
  3017                         {
       
  3018                         // margin of this node is collapsed
       
  3019                         offsetx = previousMarginRect.iBr.iX;
       
  3020                         }
       
  3021                     else
       
  3022                         {
       
  3023                         // margin of the previous node is collapsed
       
  3024                         offsetx = previousBorderRect.iBr.iX + marginLeft;
       
  3025                         }
       
  3026                     }
       
  3027                 }
       
  3028             else
       
  3029                 {
       
  3030                 offsetx = aParentRect.iTl.iX + marginLeft;
       
  3031                 offsety = aParentRect.iBr.iY - aNode.BorderRect().Height() -
       
  3032                     marginBottom;
       
  3033                 }
       
  3034             }
       
  3035 
       
  3036         //   LTR , RL
       
  3037         //  *********
       
  3038         //  | 1 | 2 |
       
  3039         //  | 3 | 4 |
       
  3040         //  | 5 | 6 |
       
  3041         //  *********
       
  3042 
       
  3043         else if ( aParentBlockProgression ==
       
  3044                   XnPropertyNames::style::common::block_progression::KRL )
       
  3045             {
       
  3046             if ( aPreviousSibling )
       
  3047                 {
       
  3048                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  3049                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  3050                 TBool layoutNextToPrevious( EFalse );
       
  3051                 TInt width =
       
  3052                     aNode.BorderRect().Width() + marginRight + marginLeft;
       
  3053                 TInt prevMarginRight =
       
  3054                     previousMarginRect.iBr.iX - previousBorderRect.iBr.iX;
       
  3055                 if ( prevMarginRight < marginLeft )
       
  3056                     {
       
  3057                     width -= prevMarginRight;
       
  3058                     }
       
  3059                 else
       
  3060                     {
       
  3061                     width -= marginLeft;
       
  3062                     }
       
  3063                 if ( width <= aParentRect.iBr.iX - previousMarginRect.iBr.iX )
       
  3064                     {
       
  3065                     layoutNextToPrevious = ETrue;
       
  3066                     }
       
  3067 
       
  3068                 if ( !layoutNextToPrevious )
       
  3069                     {
       
  3070                     TInt height =
       
  3071                         aNode.BorderRect().Height() + marginTop + marginBottom;
       
  3072                     if ( aColumnMargin < marginTop )
       
  3073                         {
       
  3074                         height -= aColumnMargin;
       
  3075                         }
       
  3076                     else
       
  3077                         {
       
  3078                         height -= marginTop;
       
  3079                         }
       
  3080                     if ( height + aColumnWidth <= aParentRect.Height() )
       
  3081                         {
       
  3082                         offsetx = aParentRect.iTl.iX + marginLeft;
       
  3083                         if ( aColumnMargin < marginTop )
       
  3084                             {
       
  3085                             offsety = aParentRect.iTl.iY + aColumnWidth -
       
  3086                                 aColumnMargin + marginTop;
       
  3087                             }
       
  3088                         else
       
  3089                             {
       
  3090                             offsety = aParentRect.iTl.iY + aColumnWidth;
       
  3091                             }
       
  3092                         }
       
  3093                     else
       
  3094                         {
       
  3095                         layoutNextToPrevious = ETrue;
       
  3096                         }
       
  3097                     }
       
  3098                 if ( layoutNextToPrevious )
       
  3099                     {
       
  3100                     offsety = aPreviousSibling->MarginRect().iTl.iY + marginTop;
       
  3101                     if ( prevMarginRight > marginLeft )
       
  3102                         {
       
  3103                         // margin of this node is collapsed
       
  3104                         offsetx = previousMarginRect.iBr.iX;
       
  3105                         }
       
  3106                     else
       
  3107                         {
       
  3108                         // margin of the previous node is collapsed
       
  3109                         offsetx = previousBorderRect.iBr.iX + marginLeft;
       
  3110                         }
       
  3111                     }
       
  3112                 }
       
  3113             else
       
  3114                 {
       
  3115                 offsetx = aParentRect.iTl.iX + marginLeft;
       
  3116                 offsety = aParentRect.iTl.iY + marginTop;
       
  3117                 }
       
  3118             }
       
  3119         }
       
  3120 
       
  3121     else
       
  3122         {
       
  3123         //   RTL , TB
       
  3124         //  *********
       
  3125         //  | 4 | 1 |
       
  3126         //  | 5 | 2 |
       
  3127         //  | 6 | 3 |
       
  3128         //  *********
       
  3129         if ( aParentBlockProgression ==
       
  3130              XnPropertyNames::style::common::block_progression::KTB )
       
  3131             {
       
  3132             if ( aPreviousSibling )
       
  3133                 {
       
  3134                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  3135                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  3136                 TBool layoutUnderPrevious( EFalse );
       
  3137                 TInt height = aNode.MarginRect().Height();
       
  3138                 TInt prevMarginBottom =
       
  3139                     previousMarginRect.iBr.iY - previousBorderRect.iBr.iY;
       
  3140                 if ( prevMarginBottom < marginTop )
       
  3141                     {
       
  3142                     height -= prevMarginBottom;
       
  3143                     }
       
  3144                 else
       
  3145                     {
       
  3146                     height -= marginTop;
       
  3147                     }
       
  3148                 if ( height <= aParentRect.iBr.iY - previousMarginRect.iBr.iY )
       
  3149                     {
       
  3150                     layoutUnderPrevious = ETrue;
       
  3151                     }
       
  3152 
       
  3153                 if ( !layoutUnderPrevious )
       
  3154                     {
       
  3155                     TInt width =
       
  3156                         aNode.BorderRect().Width() + marginLeft + marginRight;
       
  3157                     if ( aColumnMargin < marginLeft )
       
  3158                         {
       
  3159                         width -= aColumnMargin;
       
  3160                         }
       
  3161                     else
       
  3162                         {
       
  3163                         width -= marginLeft;
       
  3164                         }
       
  3165                     if ( width + aColumnWidth <= aParentRect.Width() )
       
  3166                         {
       
  3167                         offsety = aParentRect.iTl.iY + marginTop;
       
  3168                         if ( aColumnMargin < marginLeft )
       
  3169                             {
       
  3170                             offsetx = aParentRect.iBr.iX - aColumnWidth +
       
  3171                                 aColumnMargin - marginRight -
       
  3172                                 aNode.BorderRect().Width();
       
  3173                             }
       
  3174                         else
       
  3175                             {
       
  3176                             offsetx = aParentRect.iBr.iX - aColumnWidth -
       
  3177                                 aNode.BorderRect().Width();
       
  3178                             }
       
  3179                         }
       
  3180                     else
       
  3181                         {
       
  3182                         layoutUnderPrevious = ETrue;
       
  3183                         }
       
  3184                     }
       
  3185                 if ( layoutUnderPrevious )
       
  3186                     {
       
  3187                     offsetx = aPreviousSibling->MarginRect().iBr.iX -
       
  3188                         marginRight - aNode.BorderRect().Width();
       
  3189                     if ( prevMarginBottom > marginTop )
       
  3190                         {
       
  3191                         offsety = previousMarginRect.iBr.iY;
       
  3192                         }
       
  3193                     else
       
  3194                         {
       
  3195                         offsety = previousBorderRect.iBr.iY + marginTop;
       
  3196                         }
       
  3197                     }
       
  3198                 }
       
  3199             else
       
  3200                 {
       
  3201                 offsetx = aParentRect.iBr.iX - marginRight -
       
  3202                     aNode.BorderRect().Width();
       
  3203                 offsety = aParentRect.iTl.iY + marginTop;
       
  3204                 }
       
  3205             }
       
  3206 
       
  3207         //   RTL , BT
       
  3208         //  *********
       
  3209         //  | 6 | 3 |
       
  3210         //  | 5 | 2 |
       
  3211         //  | 4 | 1 |
       
  3212         //  *********
       
  3213         else if ( aParentBlockProgression ==
       
  3214                   XnPropertyNames::style::common::block_progression::KBT )
       
  3215             {
       
  3216             if ( aPreviousSibling )
       
  3217                 {
       
  3218                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  3219                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  3220                 TBool layoutAbovePrevious( EFalse );
       
  3221                 TInt height =
       
  3222                     aNode.BorderRect().Height() + marginTop + marginBottom;
       
  3223                 TInt prevMarginTop =
       
  3224                     previousBorderRect.iTl.iY - previousMarginRect.iTl.iY;
       
  3225                 if ( prevMarginTop < marginBottom )
       
  3226                     {
       
  3227                     height -= prevMarginTop;
       
  3228                     }
       
  3229                 else
       
  3230                     {
       
  3231                     height -= marginBottom;
       
  3232                     }
       
  3233                 if ( height <= previousMarginRect.iTl.iY - aParentRect.iTl.iY )
       
  3234                     {
       
  3235                     layoutAbovePrevious = ETrue;
       
  3236                     }
       
  3237 
       
  3238                 if ( !layoutAbovePrevious )
       
  3239                     {
       
  3240                     TInt width =
       
  3241                         aNode.BorderRect().Width() + marginLeft + marginRight;
       
  3242                     if ( aColumnMargin < marginRight )
       
  3243                         {
       
  3244                         width -= aColumnMargin;
       
  3245                         }
       
  3246                     else
       
  3247                         {
       
  3248                         width -= marginRight;
       
  3249                         }
       
  3250                     if ( width + aColumnWidth <= aParentRect.Width() )
       
  3251                         {
       
  3252                         offsety = aParentRect.iBr.iY - marginBottom -
       
  3253                             aNode.BorderRect().Height();
       
  3254                         if ( aColumnMargin < marginLeft )
       
  3255                             {
       
  3256                             offsetx = aParentRect.iBr.iX - aColumnWidth +
       
  3257                                 aColumnMargin - marginRight -
       
  3258                                 aNode.BorderRect().Width();
       
  3259                             }
       
  3260                         else
       
  3261                             {
       
  3262                             offsetx = aParentRect.iBr.iX - aColumnWidth -
       
  3263                                 aNode.BorderRect().Width();
       
  3264                             }
       
  3265                         }
       
  3266                     else
       
  3267                         {
       
  3268                         layoutAbovePrevious = ETrue;
       
  3269                         }
       
  3270                     }
       
  3271                 if ( layoutAbovePrevious )
       
  3272                     {
       
  3273                     offsetx = aPreviousSibling->MarginRect().iBr.iX -
       
  3274                         marginRight - aNode.BorderRect().Width();
       
  3275                     if ( prevMarginTop > marginBottom )
       
  3276                         {
       
  3277                         // margin of this node is collapsed
       
  3278                         offsety = previousMarginRect.iTl.iY -
       
  3279                             aNode.BorderRect().Height();
       
  3280                         }
       
  3281                     else
       
  3282                         {
       
  3283                         // margin of the previous node is collapsed
       
  3284                         offsety = previousBorderRect.iTl.iY - marginBottom -
       
  3285                             aNode.BorderRect().Height();
       
  3286                         }
       
  3287                     }
       
  3288                 }
       
  3289             else
       
  3290                 {
       
  3291                 offsetx = aParentRect.iBr.iX - marginRight -
       
  3292                     aNode.BorderRect().Width();
       
  3293                 offsety = aParentRect.iBr.iY - marginBottom -
       
  3294                     aNode.BorderRect().Height();
       
  3295                 }
       
  3296             }
       
  3297 
       
  3298         //   RTL , LR
       
  3299         //  *********
       
  3300         //  | 6 | 5 |
       
  3301         //  | 4 | 3 |
       
  3302         //  | 2 | 1 |
       
  3303         //  *********
       
  3304         else if ( aParentBlockProgression ==
       
  3305                   XnPropertyNames::style::common::block_progression::KLR )
       
  3306             {
       
  3307             if ( aPreviousSibling )
       
  3308                 {
       
  3309                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  3310                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  3311                 TBool layoutNextToPrevious( EFalse );
       
  3312                 TInt width =
       
  3313                     aNode.BorderRect().Width() + marginRight + marginLeft;
       
  3314                 TInt prevMarginLeft =
       
  3315                     previousBorderRect.iTl.iX - previousMarginRect.iTl.iX;
       
  3316                 if ( prevMarginLeft < marginRight )
       
  3317                     {
       
  3318                     width -= prevMarginLeft;
       
  3319                     }
       
  3320                 else
       
  3321                     {
       
  3322                     width -= marginRight;
       
  3323                     }
       
  3324                 if ( width <= previousMarginRect.iTl.iX - aParentRect.iTl.iX )
       
  3325                     {
       
  3326                     layoutNextToPrevious = ETrue;
       
  3327                     }
       
  3328 
       
  3329                 if ( !layoutNextToPrevious )
       
  3330                     {
       
  3331                     TInt height =
       
  3332                         aNode.BorderRect().Height() + marginTop + marginBottom;
       
  3333                     if ( aColumnMargin < marginBottom )
       
  3334                         {
       
  3335                         height -= aColumnMargin;
       
  3336                         }
       
  3337                     else
       
  3338                         {
       
  3339                         height -= marginBottom;
       
  3340                         }
       
  3341                     if ( height + aColumnWidth <= aParentRect.Height() )
       
  3342                         {
       
  3343                         offsetx = aParentRect.iBr.iX - marginRight -
       
  3344                             aNode.BorderRect().Width();
       
  3345                         if ( aColumnMargin < marginTop )
       
  3346                             {
       
  3347                             offsety = aParentRect.iBr.iY - aColumnWidth +
       
  3348                                 aColumnMargin - aNode.BorderRect().Height() -
       
  3349                                 marginBottom;
       
  3350                             }
       
  3351                         else
       
  3352                             {
       
  3353                             offsety = aParentRect.iBr.iY - aColumnWidth -
       
  3354                                 aNode.BorderRect().Height();
       
  3355                             }
       
  3356                         }
       
  3357                     else
       
  3358                         {
       
  3359                         layoutNextToPrevious = ETrue;
       
  3360                         }
       
  3361                     }
       
  3362                 if ( layoutNextToPrevious )
       
  3363                     {
       
  3364                     offsety = aPreviousSibling->MarginRect().iBr.iY -
       
  3365                         aNode.BorderRect().Height() - marginBottom;
       
  3366                     if ( prevMarginLeft > marginRight )
       
  3367                         {
       
  3368                         offsetx = previousMarginRect.iTl.iX -
       
  3369                             aNode.BorderRect().Width();
       
  3370                         }
       
  3371                     else
       
  3372                         {
       
  3373                         offsetx = previousBorderRect.iTl.iX - marginRight -
       
  3374                             aNode.BorderRect().Width();
       
  3375                         }
       
  3376                     }
       
  3377                 }
       
  3378             else
       
  3379                 {
       
  3380                 offsetx = aParentRect.iBr.iX - marginRight -
       
  3381                     aNode.BorderRect().Width();
       
  3382                 offsety = aParentRect.iBr.iY - marginBottom -
       
  3383                     aNode.BorderRect().Height();
       
  3384                 }
       
  3385             }
       
  3386 
       
  3387         //   RTL , RL
       
  3388         //  *********
       
  3389         //  | 2 | 1 |
       
  3390         //  | 4 | 3 |
       
  3391         //  | 6 | 5 |
       
  3392         //  *********
       
  3393         else if ( aParentBlockProgression ==
       
  3394                   XnPropertyNames::style::common::block_progression::KRL )
       
  3395             {
       
  3396             if ( aPreviousSibling )
       
  3397                 {
       
  3398                 TRect previousMarginRect = aPreviousSibling->MarginRect();
       
  3399                 TRect previousBorderRect = aPreviousSibling->BorderRect();
       
  3400                 TBool layoutNextToPrevious( EFalse );
       
  3401                 TInt width =
       
  3402                     aNode.BorderRect().Width() + marginRight + marginLeft;
       
  3403                 TInt prevMarginLeft =
       
  3404                     previousBorderRect.iTl.iX - previousMarginRect.iTl.iX;
       
  3405                 if ( prevMarginLeft < marginRight )
       
  3406                     {
       
  3407                     width -= prevMarginLeft;
       
  3408                     }
       
  3409                 else
       
  3410                     {
       
  3411                     width -= marginRight;
       
  3412                     }
       
  3413                 if ( width <= previousMarginRect.iTl.iX - aParentRect.iTl.iX )
       
  3414                     {
       
  3415                     layoutNextToPrevious = ETrue;
       
  3416                     }
       
  3417                 if ( !layoutNextToPrevious )
       
  3418                     {
       
  3419                     TInt height =
       
  3420                         aNode.BorderRect().Height() + marginTop + marginBottom;
       
  3421                     if ( aColumnMargin < marginTop )
       
  3422                         {
       
  3423                         height -= aColumnMargin;
       
  3424                         }
       
  3425                     else
       
  3426                         {
       
  3427                         height -= marginTop;
       
  3428                         }
       
  3429                     if ( height + aColumnWidth <= aParentRect.Height() )
       
  3430                         {
       
  3431                         offsetx = aParentRect.iBr.iX - marginRight -
       
  3432                             aNode.BorderRect().Width();
       
  3433                         if ( aColumnMargin < marginTop )
       
  3434                             {
       
  3435                             offsety = aParentRect.iTl.iY + aColumnWidth -
       
  3436                                 aColumnMargin + marginTop;
       
  3437                             }
       
  3438                         else
       
  3439                             {
       
  3440                             offsety = aParentRect.iTl.iY + aColumnWidth;
       
  3441                             }
       
  3442                         }
       
  3443                     else
       
  3444                         {
       
  3445                         layoutNextToPrevious = ETrue;
       
  3446                         }
       
  3447                     }
       
  3448                 if ( layoutNextToPrevious )
       
  3449                     {
       
  3450                     offsety = aPreviousSibling->MarginRect().iTl.iY + marginTop;
       
  3451                     if ( prevMarginLeft > marginRight )
       
  3452                         {
       
  3453                         offsetx = previousMarginRect.iTl.iX -
       
  3454                             aNode.BorderRect().Width();
       
  3455                         }
       
  3456                     else
       
  3457                         {
       
  3458                         offsetx = previousBorderRect.iTl.iX - marginRight -
       
  3459                             aNode.BorderRect().Width();
       
  3460                         }
       
  3461                     }
       
  3462                 }
       
  3463             else
       
  3464                 {
       
  3465                 offsetx = aParentRect.iBr.iX - marginRight -
       
  3466                     aNode.BorderRect().Width();
       
  3467                 offsety = aParentRect.iTl.iY + marginTop;
       
  3468                 }
       
  3469             }
       
  3470         }
       
  3471 
       
  3472     TRect borderRect = TRect( aNode.BorderRect() );
       
  3473     TRect normalFlowBorderRect = TRect( aNode.NormalFlowBorderRect() );
       
  3474     // this is the top left corner of margin rect
       
  3475     TPoint origin( borderRect.iTl - TPoint( marginLeft, marginTop ) );
       
  3476 
       
  3477     if ( &aParent != &aNode )
       
  3478         {
       
  3479         // set content rect
       
  3480         TRect newRect( aNode.Rect() );
       
  3481         newRect.Move( offsetx, offsety );
       
  3482         aNode.SetRect( newRect );
       
  3483 
       
  3484         // set padding rect
       
  3485         TRect paddingRect( aNode.PaddingRect() );
       
  3486         paddingRect.Move( offsetx, offsety );
       
  3487         aNode.SetPaddingRect( paddingRect );
       
  3488 
       
  3489         // set border rect
       
  3490         borderRect.Move( offsetx, offsety );
       
  3491         normalFlowBorderRect.Move( offsetx, offsety );
       
  3492         // this is the top left corner of margin rect
       
  3493         origin = TPoint( borderRect.iTl - TPoint( marginLeft, marginTop ) );
       
  3494         aNode.SetBorderRect( borderRect );
       
  3495         aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  3496         }
       
  3497 
       
  3498     TRect marginRect( origin,
       
  3499         TSize( marginLeft + marginRight + borderRect.Width(),
       
  3500         marginTop + marginBottom + borderRect.Height() ) );
       
  3501 
       
  3502     aNode.SetMarginRect( marginRect );
       
  3503 
       
  3504     // Within this function, the rects are adjusted if the display-priority is
       
  3505     // 0 and margin rect exceeds parent's content rect.
       
  3506     DropExceedingRectL( aParentRect, aNode );
       
  3507 
       
  3508     // Update column width & column margin width according to block
       
  3509     // progression & direction.
       
  3510     if ( aParentBlockProgression ==
       
  3511         XnPropertyNames::style::common::block_progression::KRL )
       
  3512         {
       
  3513         TInt newColumnWidth = marginRect.iBr.iY - aParentRect.iTl.iY;
       
  3514         if ( newColumnWidth > aColumnWidth )
       
  3515             {
       
  3516             aColumnWidth = newColumnWidth;
       
  3517             aColumnMargin = marginRect.iBr.iY - borderRect.iBr.iY;
       
  3518             }
       
  3519         }
       
  3520     else if ( aParentBlockProgression ==
       
  3521               XnPropertyNames::style::common::block_progression::KLR )
       
  3522         {
       
  3523         TInt newColumnWidth = aParentRect.iBr.iY - marginRect.iTl.iY;
       
  3524         if ( newColumnWidth > aColumnWidth )
       
  3525             {
       
  3526             aColumnWidth = newColumnWidth;
       
  3527             aColumnMargin = borderRect.iTl.iY - marginRect.iTl.iY;
       
  3528             }
       
  3529         }
       
  3530     else if ( aParentDirection ==
       
  3531               XnPropertyNames::style::common::direction::KLTR )
       
  3532         {
       
  3533         // same for tb and bt
       
  3534         TInt newColumnWidth = marginRect.iBr.iX - aParentRect.iTl.iX;
       
  3535         if ( newColumnWidth > aColumnWidth )
       
  3536             {
       
  3537             aColumnWidth = newColumnWidth;
       
  3538             aColumnMargin = marginRect.iBr.iX - borderRect.iBr.iX;
       
  3539             }
       
  3540         }
       
  3541     else if ( aParentDirection ==
       
  3542               XnPropertyNames::style::common::direction::KRTL )
       
  3543         {
       
  3544         // same for tb and bt
       
  3545         TInt newColumnWidth = aParentRect.iBr.iX - marginRect.iTl.iX;
       
  3546         if ( newColumnWidth > aColumnWidth )
       
  3547             {
       
  3548             aColumnWidth = newColumnWidth;
       
  3549             aColumnMargin = borderRect.iTl.iX - marginRect.iTl.iX;
       
  3550             }
       
  3551         }
       
  3552 
       
  3553     if ( IsNodeTooltip( aNode ) )
       
  3554         {
       
  3555         // because tooltip has it's own window, move margin rect to 0,0
       
  3556         // and all other rects as much up left
       
  3557         TRect marginRect = aNode.MarginRect();
       
  3558         TRect borderRect = aNode.BorderRect();
       
  3559         TRect paddingRect = aNode.PaddingRect();
       
  3560         TRect contentRect = aNode.Rect();
       
  3561         TInt x = marginRect.iTl.iX;
       
  3562         TInt y = marginRect.iTl.iY;
       
  3563         marginRect.Move( -x, -y );
       
  3564         borderRect.Move( -x, -y );
       
  3565         paddingRect.Move( -x, -y );
       
  3566         contentRect.Move( -x, -y );
       
  3567         aNode.SetMarginRect( marginRect );
       
  3568         aNode.SetBorderRect( borderRect );
       
  3569         aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  3570         aNode.SetPaddingRect( paddingRect );
       
  3571         aNode.SetRect( contentRect );
       
  3572         }
       
  3573     }
       
  3574 
       
  3575 // -----------------------------------------------------------------------------
       
  3576 // CalculatePaddingL()
       
  3577 // Move the rect by adding the padding.
       
  3578 // -----------------------------------------------------------------------------
       
  3579 //
       
  3580 static void CalculatePaddingL( const TRect& aParentRect, CXnNode& aNode,
       
  3581     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  3582     TReal aVerticalUnitInPixels )
       
  3583     {
       
  3584     TInt offsetx = 0;
       
  3585     TInt offsety = 0;
       
  3586 
       
  3587     TInt paddingleft = 0;
       
  3588     TInt paddingright = 0;
       
  3589     TInt paddingtop = 0;
       
  3590     TInt paddingbottom = 0;
       
  3591     TRect parentRect = aParentRect;
       
  3592 
       
  3593     CXnProperty* paddingproperty = aNode.PaddingLeftL();
       
  3594 
       
  3595     if ( paddingproperty )
       
  3596         {
       
  3597         TRAPD( error, paddingleft = HorizontalPixelValueL( paddingproperty,
       
  3598             parentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
       
  3599 
       
  3600         if ( error != KErrNone )
       
  3601             {
       
  3602             paddingleft = 0;
       
  3603             }
       
  3604         }
       
  3605 
       
  3606     paddingproperty = aNode.PaddingRightL();
       
  3607 
       
  3608     if ( paddingproperty )
       
  3609         {
       
  3610         TRAPD( error, paddingright = HorizontalPixelValueL( paddingproperty,
       
  3611             parentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
       
  3612 
       
  3613         if ( error != KErrNone )
       
  3614             {
       
  3615             paddingright = 0;
       
  3616             }
       
  3617         }
       
  3618 
       
  3619     paddingproperty = aNode.PaddingTopL();
       
  3620 
       
  3621     if ( paddingproperty )
       
  3622         {
       
  3623         TRAPD( error, paddingtop = VerticalPixelValueL( paddingproperty,
       
  3624             parentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3625 
       
  3626         if ( error != KErrNone )
       
  3627             {
       
  3628             paddingtop = 0;
       
  3629             }
       
  3630         }
       
  3631 
       
  3632     paddingproperty = aNode.PaddingBottomL();
       
  3633 
       
  3634     if ( paddingproperty )
       
  3635         {
       
  3636         TRAPD( error, paddingbottom = VerticalPixelValueL( paddingproperty,
       
  3637             parentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3638 
       
  3639         if ( error != KErrNone )
       
  3640             {
       
  3641             paddingbottom = 0;
       
  3642             }
       
  3643         }
       
  3644 
       
  3645     // move the client rect of the element this much right
       
  3646     offsetx = paddingleft;
       
  3647     //  move the client rect of the element this much down
       
  3648     offsety = paddingtop;
       
  3649 
       
  3650     TRect newrect( aNode.Rect() );
       
  3651     TPoint origin( newrect.iTl );
       
  3652     newrect.Move( offsetx, offsety );
       
  3653     aNode.SetRect( newrect );
       
  3654 
       
  3655     // set padding rect
       
  3656     TRect paddingrect( origin, TSize( paddingleft + paddingright +
       
  3657         newrect.Width(), paddingtop + paddingbottom + newrect.Height() ) );
       
  3658 
       
  3659     aNode.SetPaddingRect( paddingrect );
       
  3660     }
       
  3661 
       
  3662 // -----------------------------------------------------------------------------
       
  3663 // CalculateRectL()
       
  3664 // Creates rect for CXnComponent.
       
  3665 // -----------------------------------------------------------------------------
       
  3666 //
       
  3667 static void CalculateRectL( CXnNode& aNode, CXnNode& aParent,
       
  3668     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  3669     TReal aVerticalUnitInPixels )
       
  3670     {
       
  3671     TInt width = 0;
       
  3672     TInt height = 0;
       
  3673     TRect parentRect = aParent.Rect();
       
  3674     CXnProperty* widthproperty = aNode.WidthL();
       
  3675 
       
  3676     if ( widthproperty )
       
  3677         {
       
  3678         // if width is auto, it is set to 0 at this point and calculated later
       
  3679         if ( IsPropertyAutoL( *widthproperty ) )
       
  3680             {
       
  3681             width = 0;
       
  3682             }
       
  3683         else
       
  3684             {
       
  3685             width = HorizontalPixelValueL( widthproperty, parentRect.Width(),
       
  3686                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  3687             }
       
  3688         }
       
  3689 
       
  3690     CXnProperty* heightproperty = aNode.HeightL();
       
  3691 
       
  3692     if ( heightproperty )
       
  3693         {
       
  3694         // if height is auto, height is set to 0 at this point
       
  3695         // and calculated later
       
  3696         if ( IsPropertyAutoL( *heightproperty ) )
       
  3697             {
       
  3698             height = 0;
       
  3699             }
       
  3700         else
       
  3701             {
       
  3702             height = VerticalPixelValueL( heightproperty, parentRect.Height(),
       
  3703                 aGraphicsDevice, aVerticalUnitInPixels );
       
  3704             }
       
  3705         }
       
  3706 
       
  3707     // check that rect sizes are in max and min bounds
       
  3708     CXnProperty* maxheightproperty = aNode.MaxHeightL();
       
  3709     CXnProperty* minheightproperty = aNode.MinHeightL();
       
  3710     CXnProperty* maxwidthproperty = aNode.MaxWidthL();
       
  3711     CXnProperty* minwidthproperty = aNode.MinWidthL();
       
  3712 
       
  3713     if ( maxwidthproperty )
       
  3714         {
       
  3715         if ( !IsPropertyNone( *maxwidthproperty ) )
       
  3716             {
       
  3717             TInt maxwidth = HorizontalPixelValueL(
       
  3718                 maxwidthproperty, parentRect.Width(),
       
  3719                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  3720 
       
  3721             if ( width > maxwidth )
       
  3722                 {
       
  3723                 width = maxwidth;
       
  3724                 }
       
  3725             }
       
  3726         }
       
  3727 
       
  3728     if ( minwidthproperty )
       
  3729         {
       
  3730         if ( !IsPropertyNone( *minwidthproperty ) )
       
  3731             {
       
  3732             TInt minwidth = HorizontalPixelValueL(
       
  3733                 minwidthproperty, parentRect.Width(),
       
  3734                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  3735 
       
  3736             if ( width < minwidth )
       
  3737                 {
       
  3738                 width = minwidth;
       
  3739                 }
       
  3740             }
       
  3741         }
       
  3742 
       
  3743     if ( maxheightproperty )
       
  3744         {
       
  3745         if ( !IsPropertyNone( *maxheightproperty ) )
       
  3746             {
       
  3747             TInt maxheight = VerticalPixelValueL(
       
  3748                 maxheightproperty, parentRect.Height(),
       
  3749                 aGraphicsDevice, aVerticalUnitInPixels );
       
  3750 
       
  3751             if ( height > maxheight )
       
  3752                 {
       
  3753                 height = maxheight;
       
  3754                 }
       
  3755             }
       
  3756         }
       
  3757 
       
  3758     if ( minheightproperty )
       
  3759         {
       
  3760         if ( !IsPropertyNone( *minheightproperty ) )
       
  3761             {
       
  3762             TInt minheight = VerticalPixelValueL(
       
  3763                 minheightproperty, parentRect.Height(),
       
  3764                 aGraphicsDevice, aVerticalUnitInPixels );
       
  3765 
       
  3766             if ( height < minheight )
       
  3767                 {
       
  3768                 height = minheight;
       
  3769                 }
       
  3770             }
       
  3771         }
       
  3772 
       
  3773     if ( aNode.ViewNodeImpl() && height != 0 && width != 0 )
       
  3774         {
       
  3775         TRect rect( 0, 0, width, height );
       
  3776         TRect paddingrect( 0, 0, width, height );
       
  3777         TRect borderrect( 0, 0, width, height );
       
  3778         TRect normalFlowBorderRect( 0, 0, width, height );
       
  3779         TRect marginrect( 0, 0, width, height );
       
  3780 
       
  3781         aNode.SetRect( rect );
       
  3782         aNode.SetPaddingRect( paddingrect );
       
  3783         aNode.SetBorderRect( borderrect );
       
  3784         aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  3785         aNode.SetMarginRect( marginrect );
       
  3786         }
       
  3787     else if ( !aNode.ViewNodeImpl() )
       
  3788         {
       
  3789         TInt adaptive( aNode.IsAdaptive() );
       
  3790 
       
  3791         if ( adaptive && ( IsNodeTooltip( aNode ) || IsAbsoluteL( aNode ) ) )
       
  3792             {
       
  3793             CXnUiEngine* engine( aNode.UiEngine() );
       
  3794 
       
  3795             TSize maxSize( engine->ClientRect().Size() );
       
  3796 
       
  3797             if ( adaptive & XnAdaptive::EHeight )
       
  3798                 {
       
  3799                 height = maxSize.iHeight;
       
  3800                 }
       
  3801             if ( adaptive & XnAdaptive::EWidth )
       
  3802                 {
       
  3803                 width = maxSize.iWidth;
       
  3804                 }
       
  3805             }
       
  3806 
       
  3807         TRect rect( 0, 0, width, height );
       
  3808         TRect paddingrect( 0, 0, width, height );
       
  3809         TRect borderrect( 0, 0, width, height );
       
  3810         TRect normalFlowBorderRect( 0, 0, width, height );
       
  3811         TRect marginrect( 0, 0, width, height );
       
  3812 
       
  3813         aNode.SetRect( rect );
       
  3814         aNode.SetPaddingRect( paddingrect );
       
  3815         aNode.SetBorderRect( borderrect );
       
  3816         aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  3817         aNode.SetMarginRect( marginrect );
       
  3818         }
       
  3819     }
       
  3820 
       
  3821 // -----------------------------------------------------------------------------
       
  3822 // CalculateRelativePositionL()
       
  3823 // Move the rect by it's relative position.
       
  3824 // -----------------------------------------------------------------------------
       
  3825 //
       
  3826 static void CalculateRelativePositionsL( const TRect& aParentRect,
       
  3827     CXnNode& aNode, CGraphicsDevice& aGraphicsDevice,
       
  3828     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
       
  3829     {
       
  3830     CXnProperty* top = aNode.TopL();
       
  3831     CXnProperty* bottom = aNode.BottomL();
       
  3832     CXnProperty* left = aNode.LeftL();
       
  3833     CXnProperty* right = aNode.RightL();
       
  3834 
       
  3835     // Move rect by offset
       
  3836     TRect newRect( aNode.Rect() );
       
  3837     TRect paddingRect( aNode.PaddingRect() );
       
  3838     TRect borderRect( aNode.BorderRect() );
       
  3839     TRect marginRect( aNode.MarginRect() );
       
  3840 
       
  3841     TRect parentRect = aParentRect;
       
  3842 
       
  3843     if ( top && !IsPropertyAutoL( *top ) )
       
  3844         {
       
  3845         newRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
       
  3846             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3847         paddingRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
       
  3848             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3849         borderRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
       
  3850             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3851         marginRect.Move( 0, VerticalPixelValueL( top, parentRect.Height(),
       
  3852             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3853         }
       
  3854     if ( bottom && !IsPropertyAutoL( *bottom ) )
       
  3855         {
       
  3856         newRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
       
  3857             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3858         paddingRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
       
  3859             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3860         borderRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
       
  3861             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3862         marginRect.Move( 0, -VerticalPixelValueL( bottom, parentRect.Height(),
       
  3863             aGraphicsDevice, aVerticalUnitInPixels ) );
       
  3864         }
       
  3865     if ( left && !IsPropertyAutoL( *left ) )
       
  3866         {
       
  3867         newRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
       
  3868             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3869         paddingRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
       
  3870             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3871         borderRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
       
  3872             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3873         marginRect.Move( HorizontalPixelValueL( left, parentRect.Width(),
       
  3874             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3875         }
       
  3876     if ( right && !IsPropertyAutoL( *right ) )
       
  3877         {
       
  3878         newRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
       
  3879             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3880         paddingRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
       
  3881             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3882         borderRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
       
  3883             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3884         marginRect.Move( -HorizontalPixelValueL( right, parentRect.Width(),
       
  3885             aGraphicsDevice, aHorizontalUnitInPixels ), 0 );
       
  3886         }
       
  3887 
       
  3888     aNode.SetRect( newRect );
       
  3889     aNode.SetPaddingRect( paddingRect );
       
  3890     aNode.SetBorderRect( borderRect );
       
  3891     aNode.SetMarginRect( marginRect );
       
  3892 
       
  3893     DropExceedingRectL( parentRect, aNode, ETrue );
       
  3894     }
       
  3895 
       
  3896 // -----------------------------------------------------------------------------
       
  3897 // CalculateSpaceUsedByChildrenL()
       
  3898 // Return space used by node's children.
       
  3899 // -----------------------------------------------------------------------------
       
  3900 //
       
  3901 static TSize CalculateSpaceUsedByChildrenL( RPointerArray< CXnNode >& aChildren,
       
  3902     CXnNode& aNode, const TDesC8& aParentBlockProgression,
       
  3903     const TDesC8& aParentDirection, CGraphicsDevice& aScreenDevice,
       
  3904     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
       
  3905     {
       
  3906     TInt usedSiblingHeight( 0 );
       
  3907     TInt usedSiblingWidth( 0 );
       
  3908 
       
  3909     TRect rect( aNode.Rect() );
       
  3910 
       
  3911     TSize largestSize( 0, 0 );
       
  3912 
       
  3913     for ( TInt i = 0; i < aChildren.Count(); i++ )
       
  3914         {
       
  3915         CXnNode* node( aChildren[i] );
       
  3916 
       
  3917         if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
       
  3918              !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
       
  3919             {
       
  3920             TSize siblingSize = CalculateTotalDimensionsL( *node, ETrue,
       
  3921                 EFalse, rect, aScreenDevice, aHorizontalUnitInPixels,
       
  3922                 aVerticalUnitInPixels );
       
  3923 
       
  3924             if ( node->IsAdaptive() )
       
  3925                 {
       
  3926                 RPointerArray< CXnNode >& children( node->Children() );
       
  3927 
       
  3928                 CXnProperty* blockProgressionProperty(
       
  3929                     node->BlockProgressionL() );
       
  3930                 CXnProperty* directionProperty( node->DirectionL() );
       
  3931 
       
  3932                 const TDesC8* blockProgression(
       
  3933                     &XnPropertyNames::style::common::block_progression::KTB() );
       
  3934                 const TDesC8* direction(
       
  3935                     &XnPropertyNames::style::common::direction::KLTR() );
       
  3936 
       
  3937                 if ( directionProperty )
       
  3938                     {
       
  3939                     direction = &directionProperty->StringValue();
       
  3940                     }
       
  3941 
       
  3942                 if ( blockProgressionProperty )
       
  3943                     {
       
  3944                     blockProgression = &blockProgressionProperty->StringValue();
       
  3945                     }
       
  3946 
       
  3947                 siblingSize += CalculateSpaceUsedByChildrenL( children, aNode,
       
  3948                     *blockProgression, *direction,
       
  3949                     aScreenDevice, aHorizontalUnitInPixels,
       
  3950                     aVerticalUnitInPixels );
       
  3951                 }
       
  3952 
       
  3953             if ( siblingSize.iWidth > largestSize.iWidth )
       
  3954                 {
       
  3955                 largestSize.iWidth = siblingSize.iWidth;
       
  3956                 }
       
  3957             if ( siblingSize.iHeight > largestSize.iHeight )
       
  3958                 {
       
  3959                 largestSize.iHeight = siblingSize.iHeight;
       
  3960                 }
       
  3961 
       
  3962             if ( aParentBlockProgression ==
       
  3963                  XnPropertyNames::style::common::block_progression::KTB )
       
  3964                 {
       
  3965                 usedSiblingHeight += siblingSize.iHeight;
       
  3966                 usedSiblingWidth = largestSize.iWidth;
       
  3967                 }
       
  3968 
       
  3969             if ( aParentBlockProgression ==
       
  3970                  XnPropertyNames::style::common::block_progression::KLR ||
       
  3971                  aParentBlockProgression ==
       
  3972                  XnPropertyNames::style::common::block_progression::KRL )
       
  3973                 {
       
  3974                 usedSiblingWidth += siblingSize.iWidth;
       
  3975                 usedSiblingHeight = largestSize.iHeight;
       
  3976                 }
       
  3977 
       
  3978             // collapse margins
       
  3979             if ( aChildren.Count() < i )
       
  3980                 {
       
  3981                 CXnNode* next( aChildren[i + 1] );
       
  3982 
       
  3983                 if ( ( aParentBlockProgression ==
       
  3984                        XnPropertyNames::style::common::block_progression::KLR ||
       
  3985                        aParentBlockProgression ==
       
  3986                        XnPropertyNames::style::common::
       
  3987                        block_progression::KRL ) && aParentDirection ==
       
  3988                        XnPropertyNames::style::common::direction::KLTR )
       
  3989                     {
       
  3990                     TInt thisSiblingsRightMargin =
       
  3991                         node->MarginRect().iBr.iX - node->BorderRect().iBr.iX;
       
  3992                     TInt nextSiblingsLeftMargin =
       
  3993                         next->BorderRect().iTl.iX - next->MarginRect().iTl.iX;
       
  3994 
       
  3995                     if ( nextSiblingsLeftMargin > thisSiblingsRightMargin )
       
  3996                         {
       
  3997                         usedSiblingWidth -= thisSiblingsRightMargin;
       
  3998                         }
       
  3999                     }
       
  4000 
       
  4001                 if ( ( aParentBlockProgression ==
       
  4002                        XnPropertyNames::style::common::block_progression::KRL ||
       
  4003                        aParentBlockProgression ==
       
  4004                        XnPropertyNames::style::common
       
  4005                        ::block_progression::KLR ) && aParentDirection ==
       
  4006                        XnPropertyNames::style::common::direction::KRTL )
       
  4007                     {
       
  4008                     TInt thisSiblingsLeftMargin =
       
  4009                         node->MarginRect().iTl.iX - node->BorderRect().iTl.iX;
       
  4010                     TInt nextSiblingsRightMargin =
       
  4011                         next->BorderRect().iBr.iX - next->MarginRect().iBr.iX;
       
  4012 
       
  4013                     if ( nextSiblingsRightMargin > thisSiblingsLeftMargin )
       
  4014                         {
       
  4015                         usedSiblingWidth =- thisSiblingsLeftMargin;
       
  4016                         }
       
  4017                     }
       
  4018 
       
  4019                 if ( ( aParentBlockProgression ==
       
  4020                        XnPropertyNames::style::common::block_progression::KTB ||
       
  4021                        aParentBlockProgression ==
       
  4022                        XnPropertyNames::style::common::
       
  4023                        block_progression::KBT ) && aParentDirection ==
       
  4024                        XnPropertyNames::style::common::direction::KLTR )
       
  4025                     {
       
  4026                     TInt thisSiblingsBottomMargin =
       
  4027                         node->MarginRect().iBr.iY - node->BorderRect().iBr.iY;
       
  4028                     TInt nextSiblingsTopMargin =
       
  4029                         next->BorderRect().iTl.iY - next->MarginRect().iTl.iY;
       
  4030 
       
  4031                     if ( nextSiblingsTopMargin > thisSiblingsBottomMargin )
       
  4032                         {
       
  4033                         usedSiblingHeight -= thisSiblingsBottomMargin;
       
  4034                         }
       
  4035                     }
       
  4036 
       
  4037                 if ( ( aParentBlockProgression ==
       
  4038                        XnPropertyNames::style::common::block_progression::KTB ||
       
  4039                        aParentBlockProgression ==
       
  4040                        XnPropertyNames::style::common::
       
  4041                        block_progression::KBT ) && aParentDirection ==
       
  4042                        XnPropertyNames::style::common::direction::KRTL )
       
  4043                     {
       
  4044                     TInt thisSiblingsTopMargin =
       
  4045                         node->MarginRect().iTl.iY - node->BorderRect().iTl.iY;
       
  4046                     TInt nextSiblingsBottomMargin =
       
  4047                         next->BorderRect().iBr.iY - next->MarginRect().iBr.iY;
       
  4048 
       
  4049                     if ( nextSiblingsBottomMargin > thisSiblingsTopMargin )
       
  4050                         {
       
  4051                         usedSiblingHeight -= thisSiblingsTopMargin;
       
  4052                         }
       
  4053                     }
       
  4054                 }
       
  4055             }
       
  4056         }
       
  4057 
       
  4058     return TSize( usedSiblingWidth, usedSiblingHeight );
       
  4059     }
       
  4060 
       
  4061 // -----------------------------------------------------------------------------
       
  4062 // CalculateTotalDimensionsL()
       
  4063 // Scale dimensions for areas that have properties set to AUTO.
       
  4064 // -----------------------------------------------------------------------------
       
  4065 //
       
  4066 static TSize CalculateTotalDimensionsL( CXnNode& aNode, TBool aIgnoreAutoValues,
       
  4067     TBool aIgnoreMinSizes, TRect& aParentRect,
       
  4068     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  4069     TReal aVerticalUnitInPixels )
       
  4070     {
       
  4071     // AUTO areas return their defined dimensions if not ignored
       
  4072     // if ignored, 0 is returned as area dimensions
       
  4073     CXnProperty* width( aNode.WidthL() );
       
  4074     CXnProperty* height( aNode.HeightL() );
       
  4075     TInt adaptive( aNode.IsAdaptive() );
       
  4076     TBool autoNotFound( EFalse );
       
  4077 
       
  4078     if ( adaptive )
       
  4079         {
       
  4080         // Force to measure adaptive size
       
  4081         aIgnoreAutoValues = EFalse;
       
  4082         autoNotFound = ETrue;
       
  4083         }
       
  4084     if ( aIgnoreAutoValues )
       
  4085         {
       
  4086         TInt horizontalAuto( HasNodeHorizontalAutoValuesL( aNode ) );
       
  4087         TInt verticalAuto( HasNodeVerticalAutoValuesL( aNode ) );
       
  4088         if ( horizontalAuto && verticalAuto )
       
  4089             {
       
  4090             return TSize( 0, 0 );
       
  4091             }
       
  4092         else if ( horizontalAuto )
       
  4093             {
       
  4094             TInt h = VerticalPixelValueL( height, aParentRect.Height(),
       
  4095                 aGraphicsDevice, aVerticalUnitInPixels );
       
  4096             return TSize( 0, h );
       
  4097             }
       
  4098         else if ( verticalAuto )
       
  4099             {
       
  4100             TInt w = HorizontalPixelValueL( width, aParentRect.Width(),
       
  4101                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  4102             return TSize( w, 0 );
       
  4103             }
       
  4104         autoNotFound = ETrue;
       
  4105         }
       
  4106 
       
  4107     TInt x( 0 );
       
  4108     TInt y( 0 );
       
  4109 
       
  4110     if ( !aIgnoreMinSizes )
       
  4111         {
       
  4112         if ( !autoNotFound && HasNodeAutoValuesL( aNode ) )
       
  4113             {
       
  4114             // if auto values, check minimum sizes
       
  4115             if ( height )
       
  4116                 {
       
  4117                 if ( IsPropertyAutoL( *height ) )
       
  4118                     {
       
  4119                     CXnProperty* minheight( aNode.MinHeightL() );
       
  4120                     if ( minheight )
       
  4121                         {
       
  4122                         if ( !IsPropertyNone( *minheight ) )
       
  4123                             {
       
  4124                             y += VerticalPixelValueL( minheight,
       
  4125                                 aParentRect.Height(), aGraphicsDevice,
       
  4126                                 aVerticalUnitInPixels );
       
  4127                             }
       
  4128                         }
       
  4129                     }
       
  4130                 }
       
  4131             if ( width )
       
  4132                 {
       
  4133                 if ( IsPropertyAutoL( *width ) )
       
  4134                     {
       
  4135                     CXnProperty* minwidth( aNode.MinWidthL() );
       
  4136                     if ( minwidth )
       
  4137                         {
       
  4138                         if ( !IsPropertyNone( *minwidth ) )
       
  4139                             {
       
  4140                             x += HorizontalPixelValueL( minwidth,
       
  4141                                 aParentRect.Width(), aGraphicsDevice,
       
  4142                                 aHorizontalUnitInPixels );
       
  4143                             }
       
  4144                         }
       
  4145                     }
       
  4146                 }
       
  4147             }
       
  4148         }
       
  4149 
       
  4150     CXnProperty* marginLeft = aNode.MarginLeftL();
       
  4151     CXnProperty* marginRight = aNode.MarginRightL();
       
  4152     CXnProperty* borderLeft = aNode.BorderLeftL();
       
  4153     CXnProperty* borderRight = aNode.BorderRightL();
       
  4154     CXnProperty* paddingLeft = aNode.PaddingLeftL();
       
  4155     CXnProperty* paddingRight = aNode.PaddingRightL();
       
  4156     CXnProperty* marginTop = aNode.MarginTopL();
       
  4157     CXnProperty* marginBottom = aNode.MarginBottomL();
       
  4158     CXnProperty* borderTop = aNode.BorderTopL();
       
  4159     CXnProperty* borderBottom = aNode.BorderBottomL();
       
  4160     CXnProperty* paddingTop = aNode.PaddingTopL();
       
  4161     CXnProperty* paddingBottom = aNode.PaddingBottomL();
       
  4162     CXnProperty* borderWidth = aNode.BorderWidthL();
       
  4163     CXnProperty* borderStyle = aNode.BorderStyleL();
       
  4164     CXnProperty* borderImage = aNode.BorderImageL();
       
  4165     CXnProperty* borderLeftStyle = aNode.BorderLeftStyleL();
       
  4166     CXnProperty* borderRightStyle = aNode.BorderRightStyleL();
       
  4167     CXnProperty* borderTopStyle = aNode.BorderTopStyleL();
       
  4168     CXnProperty* borderBottomStyle = aNode.BorderBottomStyleL();
       
  4169 
       
  4170     TInt borderWidthValue( 0 );
       
  4171     TInt borderHeightValue( 0 );
       
  4172     TInt ignore;
       
  4173 
       
  4174     if ( marginLeft )
       
  4175         {
       
  4176         if ( autoNotFound || !IsPropertyAutoL( *marginLeft ) )
       
  4177             {
       
  4178             x += HorizontalPixelValueL( marginLeft, aParentRect.Width(),
       
  4179                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  4180             }
       
  4181         }
       
  4182     if ( marginRight )
       
  4183         {
       
  4184         if ( autoNotFound || !IsPropertyAutoL( *marginRight ) )
       
  4185             {
       
  4186             x += HorizontalPixelValueL( marginRight, aParentRect.Width(),
       
  4187                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  4188             }
       
  4189         }
       
  4190     if ( paddingLeft )
       
  4191         {
       
  4192         TRAP_IGNORE( x += HorizontalPixelValueL( paddingLeft,
       
  4193             aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
       
  4194         }
       
  4195     if ( paddingRight )
       
  4196         {
       
  4197         TRAP_IGNORE( x += HorizontalPixelValueL( paddingRight,
       
  4198             aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels ) );
       
  4199         }
       
  4200     if ( marginTop )
       
  4201         {
       
  4202         if ( autoNotFound || !IsPropertyAutoL( *marginTop ) )
       
  4203             {
       
  4204             y += VerticalPixelValueL( marginTop, aParentRect.Height(),
       
  4205                 aGraphicsDevice, aVerticalUnitInPixels );
       
  4206             }
       
  4207         }
       
  4208     if ( marginBottom )
       
  4209         {
       
  4210         if ( autoNotFound || !IsPropertyAutoL( *marginBottom ) )
       
  4211             {
       
  4212             y += VerticalPixelValueL( marginBottom, aParentRect.Height(),
       
  4213                 aGraphicsDevice, aVerticalUnitInPixels );
       
  4214             }
       
  4215         }
       
  4216     if ( paddingTop )
       
  4217         {
       
  4218         TRAP_IGNORE( y += VerticalPixelValueL( paddingTop,
       
  4219             aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
       
  4220         }
       
  4221     if ( paddingBottom )
       
  4222         {
       
  4223         TRAP_IGNORE( y += VerticalPixelValueL( paddingBottom,
       
  4224             aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels ) );
       
  4225         }
       
  4226     // is border image or border style defined?
       
  4227     // if not, borders are ignored
       
  4228     if ( borderWidth )
       
  4229         {
       
  4230         if ( borderImage || borderStyle )
       
  4231             {
       
  4232             DetermineBorderWidthsL( borderWidth, borderWidthValue,
       
  4233                 borderHeightValue, aParentRect, aGraphicsDevice,
       
  4234                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  4235             x += ( borderWidthValue * 2 );
       
  4236             y += ( borderHeightValue * 2 );
       
  4237             }
       
  4238         }
       
  4239     if ( borderLeft )
       
  4240         {
       
  4241         if ( borderImage || borderStyle || borderLeftStyle )
       
  4242             {
       
  4243             x -= borderWidthValue;
       
  4244             TInt borderLeftValue( 0 );
       
  4245             DetermineBorderWidthsL( borderLeft, ignore, borderLeftValue,
       
  4246                 aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  4247                 aVerticalUnitInPixels );
       
  4248             x += borderLeftValue;
       
  4249             }
       
  4250         }
       
  4251     if ( borderRight )
       
  4252         {
       
  4253         if ( borderImage || borderStyle || borderRightStyle )
       
  4254             {
       
  4255             x -= borderWidthValue;
       
  4256             TInt borderRightValue( 0 );
       
  4257             DetermineBorderWidthsL( borderRight, ignore, borderRightValue,
       
  4258                 aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  4259                 aVerticalUnitInPixels );
       
  4260             x += borderRightValue;
       
  4261             }
       
  4262         }
       
  4263     if ( borderTop )
       
  4264         {
       
  4265         if ( borderImage || borderStyle || borderTopStyle )
       
  4266             {
       
  4267             y -= borderHeightValue;
       
  4268             TInt borderTopValue( 0 );
       
  4269             DetermineBorderWidthsL( borderTop, borderTopValue, ignore,
       
  4270                 aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  4271                 aVerticalUnitInPixels );
       
  4272             y += borderTopValue;
       
  4273             }
       
  4274         }
       
  4275     if ( borderBottom )
       
  4276         {
       
  4277         if ( borderImage || borderStyle || borderBottomStyle )
       
  4278             {
       
  4279             y -= borderHeightValue;
       
  4280             TInt borderBottomValue( 0 );
       
  4281             DetermineBorderWidthsL( borderBottom, borderBottomValue, ignore,
       
  4282                 aParentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  4283                 aVerticalUnitInPixels );
       
  4284             y += borderBottomValue;
       
  4285             }
       
  4286         }
       
  4287 
       
  4288     TInt maxHeight( 0 );
       
  4289     TInt maxWidth( 0 );
       
  4290     TInt minHeight( 0 );
       
  4291     TInt minWidth( 0 );
       
  4292 
       
  4293     if ( HasNodeMinSizesL( aNode ) )
       
  4294         {
       
  4295         CXnProperty* heightproperty( aNode.HeightL() );
       
  4296         CXnProperty* widthproperty( aNode.WidthL() );
       
  4297         if ( heightproperty )
       
  4298             {
       
  4299             CXnProperty* minheightproperty( aNode.MinHeightL() );
       
  4300             if ( minheightproperty )
       
  4301                 {
       
  4302                 if ( !IsPropertyNone( *minheightproperty ) )
       
  4303                     {
       
  4304                     minHeight = VerticalPixelValueL( minheightproperty,
       
  4305                         aParentRect.Height(), aGraphicsDevice,
       
  4306                         aVerticalUnitInPixels );
       
  4307                     }
       
  4308                 }
       
  4309             }
       
  4310         if ( widthproperty )
       
  4311             {
       
  4312             CXnProperty* minwidthproperty( aNode.MinWidthL() );
       
  4313             if ( minwidthproperty )
       
  4314                 {
       
  4315                 if (!IsPropertyNone( *minwidthproperty ) )
       
  4316                     {
       
  4317                     minWidth = HorizontalPixelValueL( minwidthproperty,
       
  4318                         aParentRect.Width(), aGraphicsDevice,
       
  4319                         aHorizontalUnitInPixels );
       
  4320                     }
       
  4321                 }
       
  4322             }
       
  4323         }
       
  4324      if ( HasNodeMaxSizesL( aNode ) )
       
  4325         {
       
  4326         CXnProperty* heightProperty( aNode.HeightL() );
       
  4327         CXnProperty* widthProperty( aNode.WidthL() );
       
  4328         if ( heightProperty )
       
  4329             {
       
  4330             CXnProperty* maxHeightProperty( aNode.MaxHeightL() );
       
  4331             if ( maxHeightProperty )
       
  4332                 {
       
  4333                 if ( !IsPropertyNone( *maxHeightProperty ) )
       
  4334                     {
       
  4335                     maxHeight = VerticalPixelValueL( maxHeightProperty,
       
  4336                         aParentRect.Height(), aGraphicsDevice,
       
  4337                         aVerticalUnitInPixels );
       
  4338                     }
       
  4339                 }
       
  4340             }
       
  4341         if ( widthProperty )
       
  4342             {
       
  4343             CXnProperty* maxWidthProperty( aNode.MaxWidthL() );
       
  4344             if ( maxWidthProperty )
       
  4345                 {
       
  4346                 if ( !IsPropertyNone( *maxWidthProperty ) )
       
  4347                     {
       
  4348                     maxWidth = HorizontalPixelValueL( maxWidthProperty,
       
  4349                         aParentRect.Width(), aGraphicsDevice,
       
  4350                         aHorizontalUnitInPixels );
       
  4351                     }
       
  4352                 }
       
  4353             }
       
  4354         }
       
  4355     if ( width && height )
       
  4356         {
       
  4357         if ( ( adaptive & XnAdaptive::EWidth ) &&
       
  4358              ( adaptive & XnAdaptive::EHeight ) )
       
  4359             {
       
  4360             TSize available( aParentRect.Size() - TSize( x, y ) );
       
  4361             if ( available.iWidth > 0 )
       
  4362                 {
       
  4363                 if ( available.iWidth > maxWidth && maxWidth > 0 )
       
  4364                     {
       
  4365                     available.iWidth = maxWidth;
       
  4366                     }
       
  4367                 }
       
  4368             if ( available.iHeight > 0 )
       
  4369                 {
       
  4370                 if ( available.iHeight > maxHeight && maxHeight > 0 )
       
  4371                     {
       
  4372                     available.iHeight = maxHeight;
       
  4373                     }
       
  4374                 }
       
  4375             TSize size( aNode.MeasureAdaptiveContentL( available ) );
       
  4376             x += size.iWidth;
       
  4377             y += size.iHeight;
       
  4378             if ( minWidth > x )
       
  4379                 {
       
  4380                 x = minWidth;
       
  4381                 }
       
  4382             if ( minHeight > y )
       
  4383                 {
       
  4384                 y = minHeight;
       
  4385                 }
       
  4386             return TSize( x, y );
       
  4387             }
       
  4388         }
       
  4389     if ( width )
       
  4390         {
       
  4391         if ( adaptive & XnAdaptive::EWidth )
       
  4392             {
       
  4393             TSize available( aParentRect.Size() - TSize( x, y ) );
       
  4394             if ( available.iWidth > 0 )
       
  4395                 {
       
  4396                 if ( available.iWidth > maxWidth && maxWidth > 0 )
       
  4397                     {
       
  4398                     available.iWidth = maxWidth;
       
  4399                     }
       
  4400                 x += aNode.MeasureAdaptiveContentL( available ).iWidth;
       
  4401                 if ( minWidth > x )
       
  4402                     {
       
  4403                     x = minWidth;
       
  4404                     }
       
  4405                 }
       
  4406             }
       
  4407         else if ( autoNotFound || !IsPropertyAutoL( *width ) )
       
  4408             {
       
  4409             x += HorizontalPixelValueL( width, aParentRect.Width(),
       
  4410                 aGraphicsDevice, aHorizontalUnitInPixels );
       
  4411             }
       
  4412         }
       
  4413     if ( height )
       
  4414         {
       
  4415         if ( adaptive & XnAdaptive::EHeight )
       
  4416             {
       
  4417             TSize available( aParentRect.Size() - TSize( x, y ) );
       
  4418             if ( available.iHeight > 0 )
       
  4419                 {
       
  4420                 if ( available.iHeight > maxHeight && maxHeight > 0 )
       
  4421                     {
       
  4422                     available.iHeight = maxHeight;
       
  4423                     }
       
  4424                 y += aNode.MeasureAdaptiveContentL( available ).iHeight;
       
  4425                 if ( minHeight > y )
       
  4426                     {
       
  4427                     y = minHeight;
       
  4428                     }
       
  4429                 }
       
  4430             }
       
  4431         else if ( autoNotFound || !IsPropertyAutoL( *height ) )
       
  4432             {
       
  4433             y += VerticalPixelValueL( height, aParentRect.Height(),
       
  4434                 aGraphicsDevice, aVerticalUnitInPixels );
       
  4435             }
       
  4436         }
       
  4437     return TSize( x, y );
       
  4438     }
       
  4439 
       
  4440 // -----------------------------------------------------------------------------
       
  4441 // CutOnePixelFromPercentChildNodeL()
       
  4442 // If node has a child node with percentace defined sizes,
       
  4443 // one pixel may be cut off from it to fix possible rounding problem.
       
  4444 // -----------------------------------------------------------------------------
       
  4445 //
       
  4446 static TBool CutOnePixelFromPercentChildNodeL( CXnNode& aNode,
       
  4447     const TDesC8& aParentBlockProgression )
       
  4448     {
       
  4449     RPointerArray< CXnNode >& children = aNode.Children();
       
  4450     // find the last percent value node
       
  4451     // possible percent values:
       
  4452     // width
       
  4453     // height
       
  4454     // paddings
       
  4455     // margins
       
  4456     // borders
       
  4457     for ( TInt i = children.Count() -1; i < -1 ; --i )
       
  4458         {
       
  4459         CXnNode* currentNode = children[i];
       
  4460 
       
  4461         TInt x = 0;
       
  4462         TInt y = 0;
       
  4463 
       
  4464         CXnProperty* widthHeight;
       
  4465         CXnProperty* paddingTopLeft;
       
  4466         CXnProperty* paddingBottomRight;
       
  4467         CXnProperty* borderTopLeft;
       
  4468         CXnProperty* borderBottomRight;
       
  4469         CXnProperty* marginTopLeft;
       
  4470         CXnProperty* marginBottomRight;
       
  4471 
       
  4472         if ( ( aParentBlockProgression ==
       
  4473                XnPropertyNames::style::common::block_progression::KLR ) ||
       
  4474                aParentBlockProgression ==
       
  4475                XnPropertyNames::style::common::block_progression::KRL )
       
  4476             {
       
  4477             x = -1;
       
  4478             y = 0;
       
  4479             widthHeight = currentNode->WidthL();
       
  4480             paddingTopLeft = currentNode->PaddingLeftL();
       
  4481             paddingBottomRight = currentNode->PaddingRightL();
       
  4482             borderTopLeft = currentNode->BorderLeftL();
       
  4483             borderBottomRight = currentNode->BorderRightL();
       
  4484             marginTopLeft = currentNode->MarginLeftL();
       
  4485             marginBottomRight = currentNode->MarginRightL();
       
  4486             }
       
  4487         else
       
  4488             {
       
  4489             y = -1;
       
  4490             x = 0;
       
  4491             widthHeight = currentNode->HeightL();
       
  4492             paddingTopLeft = currentNode->PaddingTopL();
       
  4493             paddingBottomRight = currentNode->PaddingBottomL();
       
  4494             borderTopLeft = currentNode->BorderTopL();
       
  4495             borderBottomRight = currentNode->BorderBottomL();
       
  4496             marginTopLeft = currentNode->MarginTopL();
       
  4497             marginBottomRight = currentNode->MarginBottomL();
       
  4498             }
       
  4499         if ( widthHeight )
       
  4500             {
       
  4501             if ( IsValuePercentageL( *widthHeight ) )
       
  4502                 {
       
  4503                 // shrink width one pixel
       
  4504                 TRect rect( currentNode->Rect() );
       
  4505                 rect.Resize( x, y );
       
  4506                 currentNode->SetRect( rect );
       
  4507                 TRect paddingRect( currentNode->PaddingRect() );
       
  4508                 paddingRect.Resize( x, y );
       
  4509                 currentNode->SetPaddingRect( paddingRect );
       
  4510                 TRect borderRect( currentNode->BorderRect() );
       
  4511                 borderRect.Resize( x, y );
       
  4512                 TRect marginRect( currentNode->MarginRect() );
       
  4513 
       
  4514                 marginRect.Resize( x, y );
       
  4515 
       
  4516                 currentNode->SetMarginRect( marginRect );
       
  4517 
       
  4518                 return ETrue;
       
  4519                 }
       
  4520             }
       
  4521         if ( paddingTopLeft )
       
  4522             {
       
  4523             if ( IsValuePercentageL( *paddingTopLeft ) )
       
  4524                 {
       
  4525                 // shrink left padding one pixel
       
  4526                 TRect rect( currentNode->Rect() );
       
  4527                 rect.Move( x, y );
       
  4528                 currentNode->SetRect( rect );
       
  4529                 TRect paddingRect( currentNode->PaddingRect() );
       
  4530                 paddingRect.Resize( x, y );
       
  4531                 currentNode->SetPaddingRect( paddingRect );
       
  4532                 TRect borderRect( currentNode->BorderRect() );
       
  4533                 TRect normalFlowBorderRect(
       
  4534                     currentNode->NormalFlowBorderRect() );
       
  4535                 borderRect.Resize( x, y );
       
  4536                 normalFlowBorderRect.Resize( x, y );
       
  4537                 currentNode->SetBorderRect( borderRect );
       
  4538                 aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  4539                 TRect marginRect( currentNode->MarginRect() );
       
  4540 
       
  4541                 marginRect.Resize( x, y );
       
  4542 
       
  4543                 currentNode->SetMarginRect( marginRect );
       
  4544 
       
  4545                 return ETrue;
       
  4546                 }
       
  4547             }
       
  4548         if ( paddingBottomRight )
       
  4549             {
       
  4550             if ( IsValuePercentageL( *paddingBottomRight ) )
       
  4551                 {
       
  4552                 // shrink right padding one pixel
       
  4553                 TRect paddingRect( currentNode->PaddingRect() );
       
  4554                 paddingRect.Resize( x, y );
       
  4555                 currentNode->SetPaddingRect( paddingRect );
       
  4556                 TRect borderRect( currentNode->BorderRect() );
       
  4557                 TRect normalFlowBorderRect(
       
  4558                     currentNode->NormalFlowBorderRect() );
       
  4559                 borderRect.Resize( x, y );
       
  4560                 normalFlowBorderRect.Resize( x, y );
       
  4561                 currentNode->SetBorderRect( borderRect );
       
  4562                 aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  4563                 TRect marginRect( currentNode->MarginRect() );
       
  4564 
       
  4565                 marginRect.Resize( x, y );
       
  4566 
       
  4567                 currentNode->SetMarginRect( marginRect );
       
  4568 
       
  4569                 return ETrue;
       
  4570                 }
       
  4571             }
       
  4572         if ( borderTopLeft )
       
  4573             {
       
  4574             if ( IsValuePercentageL( *borderTopLeft ) )
       
  4575                 {
       
  4576                 TRect rect( currentNode->Rect() );
       
  4577                 rect.Move( x, y );
       
  4578                 currentNode->SetRect( rect );
       
  4579                 TRect paddingRect( currentNode->PaddingRect() );
       
  4580                 paddingRect.Move( x, y );
       
  4581                 currentNode->SetPaddingRect( paddingRect );
       
  4582                 TRect borderRect( currentNode->BorderRect() );
       
  4583                 TRect normalFlowBorderRect(
       
  4584                     currentNode->NormalFlowBorderRect() );
       
  4585                 borderRect.Resize( x, y );
       
  4586                 normalFlowBorderRect.Resize( x, y );
       
  4587                 currentNode->SetBorderRect( borderRect );
       
  4588                 aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  4589                 TRect marginRect( currentNode->MarginRect() );
       
  4590 
       
  4591                 marginRect.Resize( x, y );
       
  4592 
       
  4593                 currentNode->SetMarginRect( marginRect );
       
  4594 
       
  4595                 return ETrue;
       
  4596                 }
       
  4597             }
       
  4598         if ( borderBottomRight )
       
  4599             {
       
  4600             if ( IsValuePercentageL( *borderBottomRight ) )
       
  4601                 {
       
  4602                 TRect borderRect( currentNode->BorderRect() );
       
  4603                 TRect normalFlowBorderRect( currentNode->BorderRect() );
       
  4604                 borderRect.Resize( x, y );
       
  4605                 normalFlowBorderRect.Resize( x, y );
       
  4606                 currentNode->SetBorderRect( borderRect );
       
  4607                 aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  4608                 TRect marginRect( currentNode->MarginRect() );
       
  4609 
       
  4610                 marginRect.Resize( x, y );
       
  4611 
       
  4612                 currentNode->SetMarginRect( marginRect );
       
  4613 
       
  4614                 return ETrue;
       
  4615                 }
       
  4616             }
       
  4617         if ( marginTopLeft )
       
  4618             {
       
  4619             if ( IsValuePercentageL( *marginTopLeft ) )
       
  4620                 {
       
  4621                 TRect rect( currentNode->Rect() );
       
  4622                 rect.Move( x, y );
       
  4623                 currentNode->SetRect( rect );
       
  4624                 TRect paddingRect( currentNode->PaddingRect() );
       
  4625                 paddingRect.Move( x, y );
       
  4626                 currentNode->SetPaddingRect( paddingRect );
       
  4627                 TRect borderRect( currentNode->BorderRect() );
       
  4628                 TRect normalFlowBorderRect(
       
  4629                     currentNode->NormalFlowBorderRect() );
       
  4630                 borderRect.Move( x, y );
       
  4631                 normalFlowBorderRect.Move( x, y );
       
  4632                 currentNode->SetBorderRect( borderRect );
       
  4633                 aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  4634                 TRect marginRect( currentNode->MarginRect() );
       
  4635 
       
  4636                 marginRect.Resize( x, y );
       
  4637 
       
  4638                 currentNode->SetMarginRect( marginRect );
       
  4639 
       
  4640                 return ETrue;
       
  4641                 }
       
  4642             }
       
  4643         if ( marginBottomRight )
       
  4644             {
       
  4645             if ( IsValuePercentageL( *marginBottomRight ) )
       
  4646                 {
       
  4647                 TRect marginRect( currentNode->MarginRect() );
       
  4648 
       
  4649                 marginRect.Resize( x, y );
       
  4650 
       
  4651                 currentNode->SetMarginRect( marginRect );
       
  4652 
       
  4653                 return ETrue;
       
  4654                 }
       
  4655             }
       
  4656         }
       
  4657 
       
  4658     return EFalse;
       
  4659     }
       
  4660 
       
  4661 // -----------------------------------------------------------------------------
       
  4662 // DetermineBorderWidthsL()
       
  4663 // Determine border widths.
       
  4664 // -----------------------------------------------------------------------------
       
  4665 //
       
  4666 static void DetermineBorderWidthsL( CXnProperty* aBorderWidthProperty,
       
  4667     TInt& aBordervertical, TInt& aBorderhorizontal, TRect& aParentRect,
       
  4668     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  4669     TReal aVerticalUnitInPixels )
       
  4670     {
       
  4671     CXnDomList& propertyValueList =
       
  4672         aBorderWidthProperty->Property()->PropertyValueList();
       
  4673     for ( TInt i = propertyValueList.Length() - 1; i >= 0; --i )
       
  4674         {
       
  4675         CXnDomPropertyValue* value =
       
  4676             static_cast< CXnDomPropertyValue* >( propertyValueList.Item( i ) );
       
  4677         if ( value->PrimitiveValueType() == CXnDomPropertyValue::EString ||
       
  4678              value->PrimitiveValueType() == CXnDomPropertyValue::EIdent )
       
  4679             {
       
  4680             // border width was defined as string
       
  4681             const TDesC8& borderwidth = aBorderWidthProperty->StringValue();
       
  4682             if ( borderwidth ==
       
  4683                  XnPropertyNames::style::common::border_width::KThin )
       
  4684                 {
       
  4685                 aBordervertical = KXnBorderThin;
       
  4686                 aBorderhorizontal = KXnBorderThin;
       
  4687                 }
       
  4688             else if ( borderwidth ==
       
  4689                       XnPropertyNames::style::common::border_width::KMedium )
       
  4690                 {
       
  4691                 aBordervertical = KXnBorderMedium;
       
  4692                 aBorderhorizontal = KXnBorderMedium;
       
  4693                 }
       
  4694             else
       
  4695                 {
       
  4696                 aBordervertical = KXnBorderThick;
       
  4697                 aBorderhorizontal = KXnBorderThick;
       
  4698                 }
       
  4699             }
       
  4700         else
       
  4701             {
       
  4702             // border width was defined as int
       
  4703             aBordervertical = VerticalPixelValueL( aBorderWidthProperty,
       
  4704                 aParentRect.Height(), aGraphicsDevice, aVerticalUnitInPixels );
       
  4705             aBorderhorizontal = HorizontalPixelValueL( aBorderWidthProperty,
       
  4706                 aParentRect.Width(), aGraphicsDevice, aHorizontalUnitInPixels );
       
  4707             }
       
  4708         }
       
  4709     }
       
  4710 
       
  4711 // -----------------------------------------------------------------------------
       
  4712 // DisplayedChildrenCountL()
       
  4713 // Return number of node's displayed children.
       
  4714 // -----------------------------------------------------------------------------
       
  4715 //
       
  4716 static TInt DisplayedChildrenCountL( CXnNode& aNode,
       
  4717     RPointerArray< CXnNode >* aDisplayedChildren )
       
  4718     {
       
  4719     RPointerArray< CXnNode >& children = aNode.Children();
       
  4720     TInt displayedCount( 0 );
       
  4721 
       
  4722     for ( TInt i = 0; i < children.Count(); i++ )
       
  4723         {
       
  4724         CXnNode* node( children[i] );
       
  4725         if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
       
  4726              !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
       
  4727             {
       
  4728             if ( aDisplayedChildren )
       
  4729                 {
       
  4730                 aDisplayedChildren->AppendL( node );
       
  4731                 }
       
  4732             displayedCount++;
       
  4733             }
       
  4734         }
       
  4735 
       
  4736     return displayedCount;
       
  4737     }
       
  4738 
       
  4739 // -----------------------------------------------------------------------------
       
  4740 // DisplayedParentL()
       
  4741 // Return node's displayed parent.
       
  4742 // -----------------------------------------------------------------------------
       
  4743 //
       
  4744 static CXnNode* DisplayedParentL( CXnNode& aNode )
       
  4745     {
       
  4746     if ( aNode.ViewNodeImpl() )
       
  4747         {
       
  4748         return &aNode;
       
  4749         }
       
  4750     CXnNode* parent = aNode.Parent();
       
  4751     return parent;
       
  4752     }
       
  4753 
       
  4754 // -----------------------------------------------------------------------------
       
  4755 // DomPropertyValueFromProperty()
       
  4756 // Return DOM property value from property.
       
  4757 // -----------------------------------------------------------------------------
       
  4758 //
       
  4759 static CXnDomPropertyValue* DomPropertyValueFromProperty(
       
  4760     CXnProperty* aProperty )
       
  4761     {
       
  4762     if ( !aProperty )
       
  4763         {
       
  4764         return NULL;
       
  4765         }
       
  4766     CXnDomProperty* domProperty = aProperty->Property();
       
  4767     if ( !domProperty )
       
  4768         {
       
  4769         return NULL;
       
  4770         }
       
  4771     return static_cast<
       
  4772         CXnDomPropertyValue* >( domProperty->PropertyValueList().Item( 0 ) );
       
  4773     }
       
  4774 
       
  4775 // -----------------------------------------------------------------------------
       
  4776 // DomPropertyValueFromProperty()
       
  4777 // Return DOM property value from property.
       
  4778 // -----------------------------------------------------------------------------
       
  4779 // 
       
  4780 static TBool IsChildOfScrollableControl( CXnNode& aNode )
       
  4781     {
       
  4782     CXnNode* parent = &aNode;
       
  4783     while( parent )
       
  4784         {
       
  4785         if( IsSrollableBox( *parent ) )
       
  4786             {
       
  4787             return ETrue;
       
  4788             }
       
  4789         parent = parent->Parent();
       
  4790         }
       
  4791     return EFalse;
       
  4792     }
       
  4793 
       
  4794 // -----------------------------------------------------------------------------
       
  4795 // DropExceedingRectL()
       
  4796 // Drop node if node's margin rect exceeds it's parent's content rect.
       
  4797 // -----------------------------------------------------------------------------
       
  4798 //
       
  4799 static void DropExceedingRectL( const TRect& aParentRect, CXnNode& aNode,
       
  4800     TBool aDropRelativeNode )
       
  4801     {
       
  4802     if( IsChildOfScrollableControl( aNode ) )
       
  4803         {
       
  4804         return;
       
  4805         }
       
  4806     
       
  4807     if ( IsNodeTooltip( aNode ) )
       
  4808         {
       
  4809         // tooltip never dropped
       
  4810         return;
       
  4811         }
       
  4812 
       
  4813     CXnProperty* positionProp( aNode.PositionL() );
       
  4814 
       
  4815     if ( positionProp )
       
  4816         {
       
  4817         const TDesC8& value( positionProp->StringValue() );
       
  4818         if ( value == XnPropertyNames::style::common::position::KFloating )
       
  4819             {
       
  4820             // Don't change floating positioned box dimensions
       
  4821             return;
       
  4822             }
       
  4823         }
       
  4824 
       
  4825     TRect parentRect( aParentRect );
       
  4826     TRect marginRect( aNode.MarginRect() );
       
  4827 
       
  4828     // does the margin rect fit in its parent?
       
  4829     TInt parentLeft = parentRect.iTl.iX;
       
  4830     TInt parentRight = parentRect.iBr.iX;
       
  4831     TInt parentTop = parentRect.iTl.iY;
       
  4832     TInt parentBottom = parentRect.iBr.iY;
       
  4833 
       
  4834     TInt rectLeft = marginRect.iTl.iX;
       
  4835     TInt rectRight = marginRect.iBr.iX;
       
  4836     TInt rectTop = marginRect.iTl.iY;
       
  4837     TInt rectBottom = marginRect.iBr.iY;
       
  4838 
       
  4839     TInt priority = 0;
       
  4840     CXnProperty* priorityProperty = aNode.DisplayPriorityL();
       
  4841 
       
  4842     if ( priorityProperty )
       
  4843         {
       
  4844         TRAPD( error, priority = priorityProperty->FloatValueL() );
       
  4845         if ( error != KErrNone )
       
  4846             {
       
  4847             priority = 0;
       
  4848             }
       
  4849         }
       
  4850 
       
  4851     TInt leftOffset( 0 );
       
  4852     TInt rightOffset( 0 );
       
  4853     TInt topOffset( 0 );
       
  4854     TInt bottomOffset( 0 );
       
  4855 
       
  4856     if ( priority != 0 )
       
  4857         {
       
  4858         TBool drop = CalculateExceedingArea( *aNode.Parent(), aNode,
       
  4859             leftOffset, rightOffset, topOffset, bottomOffset );
       
  4860         if ( drop )
       
  4861             {
       
  4862             aNode.UiEngine()->SetNodeDroppedL( aNode, XnNodeLayout::EDropped );
       
  4863             }
       
  4864         }
       
  4865     // If display priority is 0 as much as possible must be shown, but
       
  4866     // parent's content rect must not be exceeded.
       
  4867     else
       
  4868         {
       
  4869         // This must not be done for tracster. It is a special component,
       
  4870         // which takes care
       
  4871         // of its final layout and therefore its children can exceed
       
  4872         // the parent's rect.
       
  4873         CXnNode* parent = aNode.Parent();
       
  4874 
       
  4875         // If the node is relatively positioned, and this is not called from
       
  4876         // CalculateRelativePositionsL(), then must not be cropped!!
       
  4877 
       
  4878         // Default is static
       
  4879         const TDesC8* value(
       
  4880             &XnPropertyNames::style::common::position::KStatic() );
       
  4881 
       
  4882         if ( positionProp && positionProp->StringValue() != KNullDesC8 )
       
  4883             {
       
  4884             value = &positionProp->StringValue();
       
  4885             }
       
  4886         if ( !aDropRelativeNode &&
       
  4887              XnPropertyNames::style::common::position::KRelative() == *value )
       
  4888             // relative nodes must not be adjusted, if this is not called
       
  4889             // from CalculateRelativePositionsL().
       
  4890             {
       
  4891             return;
       
  4892             }
       
  4893         if ( rectLeft < parentLeft )
       
  4894             {
       
  4895             leftOffset = parentLeft - rectLeft;
       
  4896             }
       
  4897         if ( rectRight > parentRight )
       
  4898             {
       
  4899             rightOffset = rectRight - parentRight;
       
  4900             }
       
  4901         if ( rectTop < parentTop )
       
  4902             {
       
  4903             topOffset = parentTop - rectTop;
       
  4904             }
       
  4905         if ( rectBottom > parentBottom )
       
  4906             {
       
  4907             bottomOffset = rectBottom - parentBottom;
       
  4908             }
       
  4909         AdjustRectsL( aNode, leftOffset, rightOffset, topOffset, bottomOffset );
       
  4910         }
       
  4911     }
       
  4912 
       
  4913 // -----------------------------------------------------------------------------
       
  4914 // CalculateExceedingArea()
       
  4915 // Calculates how much a dropped node affects to the area of its parent
       
  4916 // that is content based node.
       
  4917 // Returns whether a child's margin rect exceeds its parents content
       
  4918 // rect or not.
       
  4919 // -----------------------------------------------------------------------------
       
  4920 //
       
  4921 static TBool CalculateExceedingArea( CXnNode& aParent, CXnNode& aChild,
       
  4922     TInt& aLeftOffset, TInt& aRightOffset, TInt& aTopOffset,
       
  4923     TInt& aBottomOffset )
       
  4924     {
       
  4925     TBool ret( EFalse );
       
  4926 
       
  4927     TRect parentRect( aParent.Rect() );
       
  4928     TInt parentLeft = parentRect.iTl.iX;
       
  4929     TInt parentRight = parentRect.iBr.iX;
       
  4930     TInt parentTop = parentRect.iTl.iY;
       
  4931     TInt parentBottom = parentRect.iBr.iY;
       
  4932 
       
  4933     TRect marginRect( aChild.MarginRect() );
       
  4934     TInt rectLeft = marginRect.iTl.iX;
       
  4935     TInt rectRight = marginRect.iBr.iX;
       
  4936     TInt rectTop = marginRect.iTl.iY;
       
  4937     TInt rectBottom = marginRect.iBr.iY;
       
  4938 
       
  4939     TInt adaptive( aParent.IsAdaptive() );
       
  4940 
       
  4941     if ( rectLeft < parentLeft )
       
  4942         {
       
  4943         if ( adaptive & XnAdaptive::EWidth )
       
  4944             {
       
  4945             aLeftOffset = rectRight - parentLeft;
       
  4946             if ( aLeftOffset < 0 )
       
  4947                 {
       
  4948                 aLeftOffset = 0;
       
  4949                 }
       
  4950             }
       
  4951         ret = ETrue;
       
  4952         }
       
  4953     if ( rectRight > parentRight )
       
  4954         {
       
  4955         if ( adaptive & XnAdaptive::EWidth )
       
  4956             {
       
  4957             aRightOffset = parentRight - rectLeft;
       
  4958             if ( aRightOffset < 0 )
       
  4959                 {
       
  4960                 aRightOffset = 0;
       
  4961                 }
       
  4962             }
       
  4963         ret = ETrue;
       
  4964         }
       
  4965     if ( rectTop < parentTop )
       
  4966         {
       
  4967         if ( adaptive & XnAdaptive::EHeight )
       
  4968             {
       
  4969             aTopOffset = rectBottom - parentTop;
       
  4970             if ( aTopOffset < 0 )
       
  4971                 {
       
  4972                 aTopOffset = 0;
       
  4973                 }
       
  4974             }
       
  4975         ret = ETrue;
       
  4976         }
       
  4977     if ( rectBottom > parentBottom )
       
  4978         {
       
  4979         if ( adaptive & XnAdaptive::EHeight )
       
  4980             {
       
  4981             aBottomOffset = parentBottom - rectTop;
       
  4982             if ( aBottomOffset < 0 )
       
  4983                 {
       
  4984                 aBottomOffset = 0;
       
  4985                 }
       
  4986             }
       
  4987         ret = ETrue;
       
  4988         }
       
  4989     return ret;
       
  4990     }
       
  4991 
       
  4992 // -----------------------------------------------------------------------------
       
  4993 // AdjustRectsL()
       
  4994 // Adjust all the rects according to the given offsets.
       
  4995 // -----------------------------------------------------------------------------
       
  4996 //
       
  4997 static void AdjustRectsL( CXnNode& aNode, TInt aLeftOffset, TInt aRightOffset,
       
  4998     TInt aTopOffset, TInt aBottomOffset )
       
  4999     {
       
  5000     if ( aLeftOffset || aRightOffset || aTopOffset || aBottomOffset )
       
  5001         {
       
  5002 #ifdef _XN3_DEBUG_
       
  5003         CXnProperty* id( aNode.IdL() );
       
  5004 
       
  5005         if ( id )
       
  5006             {
       
  5007             TBuf8< 256 > debug;
       
  5008             debug.Append( _L8( "Node id: " ) );
       
  5009             debug.Append( id->StringValue() );
       
  5010             debug.Append( _L8( "doesn't fit to parent and will be adjusted" ) );
       
  5011 
       
  5012             RDebug::RawPrint( debug );
       
  5013             }
       
  5014 #endif
       
  5015 
       
  5016         // Adjust margin rect
       
  5017         TRect marginRect( aNode.MarginRect() );
       
  5018         TRect newRect = TRect( marginRect.iTl.iX + aLeftOffset,
       
  5019             marginRect.iTl.iY + aTopOffset, marginRect.iBr.iX - aRightOffset,
       
  5020             marginRect.iBr.iY - aBottomOffset );
       
  5021         aNode.SetMarginRect( newRect );
       
  5022 
       
  5023         // Adjust border rect
       
  5024         TRect borderRect( aNode.BorderRect() );
       
  5025         newRect = TRect( borderRect.iTl.iX + aLeftOffset,
       
  5026             borderRect.iTl.iY + aTopOffset, borderRect.iBr.iX - aRightOffset,
       
  5027             borderRect.iBr.iY - aBottomOffset );
       
  5028         aNode.SetBorderRect( newRect );
       
  5029 
       
  5030         // Adjust normal flow border rect
       
  5031         TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
  5032         newRect = TRect( normalFlowBorderRect.iTl.iX + aLeftOffset,
       
  5033             normalFlowBorderRect.iTl.iY + aTopOffset,
       
  5034             normalFlowBorderRect.iBr.iX - aRightOffset,
       
  5035             normalFlowBorderRect.iBr.iY - aBottomOffset );
       
  5036         aNode.SetNormalFlowBorderRect( newRect );
       
  5037 
       
  5038         // Adjust padding rect
       
  5039         TRect paddingRect( aNode.PaddingRect() );
       
  5040         newRect = TRect( paddingRect.iTl.iX + aLeftOffset,
       
  5041             paddingRect.iTl.iY + aTopOffset, paddingRect.iBr.iX - aRightOffset,
       
  5042             paddingRect.iBr.iY - aBottomOffset );
       
  5043         aNode.SetPaddingRect( newRect );
       
  5044 
       
  5045         // Adjust content rect
       
  5046         TRect contentRect( aNode.Rect() );
       
  5047         newRect = TRect( contentRect.iTl.iX + aLeftOffset,
       
  5048             contentRect.iTl.iY + aTopOffset, contentRect.iBr.iX - aRightOffset,
       
  5049             contentRect.iBr.iY - aBottomOffset );
       
  5050         aNode.SetRect( newRect );
       
  5051         }
       
  5052     }
       
  5053 
       
  5054 // -----------------------------------------------------------------------------
       
  5055 // ClearRects()
       
  5056 // Sets sizes of the rects to 0.
       
  5057 // -----------------------------------------------------------------------------
       
  5058 //
       
  5059 static void ClearRects( CXnNode& aNode, TBool aRecurse )
       
  5060     {
       
  5061     TRect empty;
       
  5062 
       
  5063     aNode.SetRect( empty );
       
  5064     aNode.SetPaddingRect( empty );
       
  5065     aNode.SetBorderRect( empty );
       
  5066     aNode.SetNormalFlowBorderRect( empty );
       
  5067     aNode.SetMarginRect( empty );
       
  5068 
       
  5069     CCoeControl* control( aNode.Control() );
       
  5070 
       
  5071     if ( control )
       
  5072         {
       
  5073         control->SetRect( empty );
       
  5074         }
       
  5075 
       
  5076     if ( aRecurse )
       
  5077         {
       
  5078         RPointerArray< CXnNode >& children( aNode.Children() );
       
  5079         for ( TInt i = 0; i < children.Count(); i++ )
       
  5080             {
       
  5081             ClearRects( *children[i], aRecurse );
       
  5082             }
       
  5083         }
       
  5084     }
       
  5085 
       
  5086 // -----------------------------------------------------------------------------
       
  5087 // FitChildrenIntoParentL()
       
  5088 // Drop child nodes until they fit into the parent. Also, if node has
       
  5089 // a child node with percentace defined sizes, one pixel may be cut off from it
       
  5090 // to fix possible rounding problem.
       
  5091 // -----------------------------------------------------------------------------
       
  5092 //
       
  5093 static void FitChildrenIntoParentL( CXnNode& aNode,
       
  5094     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  5095     TReal aVerticalUnitInPixels )
       
  5096     {
       
  5097 	if( IsSrollableBox( aNode ) )
       
  5098 	    {
       
  5099 	    return;
       
  5100 	    }
       
  5101     RPointerArray< CXnNode >& children( aNode.Children() );
       
  5102 
       
  5103     if ( children.Count() == 0 )
       
  5104         {
       
  5105         return;
       
  5106         }
       
  5107 
       
  5108     CXnProperty* blockProgressionProperty( aNode.BlockProgressionL() );
       
  5109     CXnProperty* directionProperty( aNode.DirectionL() );
       
  5110 
       
  5111     const TDesC8* blockProgression = NULL;
       
  5112 
       
  5113     if ( !blockProgressionProperty )
       
  5114         {
       
  5115         // using default
       
  5116         blockProgression =
       
  5117             &XnPropertyNames::style::common::block_progression::KTB();
       
  5118         }
       
  5119     else
       
  5120         {
       
  5121         blockProgression = &blockProgressionProperty->StringValue();
       
  5122         }
       
  5123 
       
  5124     const TDesC8* direction( NULL );
       
  5125 
       
  5126     if ( !directionProperty )
       
  5127         {
       
  5128         // use default
       
  5129         direction = &XnPropertyNames::style::common::direction::KLTR();
       
  5130         }
       
  5131     else
       
  5132         {
       
  5133         direction = &directionProperty->StringValue();
       
  5134         }
       
  5135 
       
  5136     TSize space = CalculateSpaceUsedByChildrenL( children, aNode,
       
  5137         *blockProgression, *direction, aGraphicsDevice,
       
  5138         aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  5139     TSize parentSize( aNode.Rect().Size() );
       
  5140 
       
  5141     while( ( ( parentSize.iHeight < space.iHeight ) &&
       
  5142              ( parentSize.iHeight > 0 ) ) ||
       
  5143            ( ( parentSize.iWidth < space.iWidth ) && 
       
  5144              ( parentSize.iWidth > 0 ) ) )
       
  5145         {
       
  5146         // if areas go over just one pixel,
       
  5147         // cut the pixel from a percent sized node
       
  5148         if ( ( parentSize.iHeight == space.iHeight - 1 ) ||
       
  5149              ( parentSize.iWidth == space.iWidth - 1 ) )
       
  5150             {
       
  5151             CutOnePixelFromPercentChildNodeL( aNode, *blockProgression );
       
  5152             // Childs are now in parent size
       
  5153             return;
       
  5154             }
       
  5155 
       
  5156         TInt childCount( DisplayedChildrenCountL( aNode ) );
       
  5157 
       
  5158         PriorizeChildrenL( aNode );
       
  5159 
       
  5160         if ( DisplayedChildrenCountL( aNode ) == childCount )
       
  5161             {
       
  5162             // cannot drop any more children, but they still don't fit
       
  5163             return;
       
  5164             }
       
  5165 
       
  5166         space = CalculateSpaceUsedByChildrenL( children, aNode,
       
  5167             *blockProgression, *direction, aGraphicsDevice,
       
  5168             aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  5169         }
       
  5170 
       
  5171     return;
       
  5172     }
       
  5173 
       
  5174 // -----------------------------------------------------------------------------
       
  5175 // GetPositionL()
       
  5176 // Return position coordinate of a CXnComponent. Returned position depends on
       
  5177 // given block progression.
       
  5178 // -----------------------------------------------------------------------------
       
  5179 //
       
  5180 static TInt GetPositionL( CXnNode& aNode, const TDesC8& aParentBlockProgression,
       
  5181     const TDesC8& aParentDirection )
       
  5182     {
       
  5183     TInt returnValue = 0;
       
  5184     if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
       
  5185         {
       
  5186         if ( aParentBlockProgression ==
       
  5187              XnPropertyNames::style::common::block_progression::KTB ||
       
  5188              aParentBlockProgression ==
       
  5189              XnPropertyNames::style::common::block_progression::KBT )
       
  5190             {
       
  5191             returnValue = aNode.NormalFlowBorderRect().iBr.iY;
       
  5192             }
       
  5193         else    // LR or RL
       
  5194             {
       
  5195             returnValue = aNode.NormalFlowBorderRect().iBr.iX;
       
  5196             }
       
  5197         }
       
  5198     else // RTL
       
  5199         {
       
  5200         if ( aParentBlockProgression ==
       
  5201              XnPropertyNames::style::common::block_progression::KTB ||
       
  5202              aParentBlockProgression ==
       
  5203              XnPropertyNames::style::common::block_progression::KBT )
       
  5204             {
       
  5205             returnValue = aNode.NormalFlowBorderRect().iTl.iY;
       
  5206             }
       
  5207         else    // LR or RL
       
  5208             {
       
  5209             returnValue = aNode.NormalFlowBorderRect().iTl.iX;
       
  5210             }
       
  5211         }
       
  5212     return returnValue;
       
  5213     }
       
  5214 
       
  5215 // -----------------------------------------------------------------------------
       
  5216 // HasNodeAutoValues()
       
  5217 // Check if node has properties set to AUTO.
       
  5218 // -----------------------------------------------------------------------------
       
  5219 //
       
  5220 static TInt HasNodeAutoValuesL( CXnNode& aNode )
       
  5221     {
       
  5222     return HasNodeHorizontalAutoValuesL( aNode ) ||
       
  5223         HasNodeVerticalAutoValuesL( aNode );
       
  5224     }
       
  5225 
       
  5226 // -----------------------------------------------------------------------------
       
  5227 // HasNodeHorizontalValues()
       
  5228 // Check if node has properties set to AUTO.
       
  5229 // -----------------------------------------------------------------------------
       
  5230 //
       
  5231 static TInt HasNodeHorizontalAutoValuesL( CXnNode& aNode )
       
  5232     {
       
  5233     TInt autoCount = 0;
       
  5234 
       
  5235     CXnProperty* width = aNode.WidthL();
       
  5236 
       
  5237     if ( width )
       
  5238         {
       
  5239         if ( IsPropertyAutoL( *width ) )
       
  5240              {
       
  5241              autoCount++;
       
  5242              }
       
  5243         }
       
  5244     else
       
  5245         {
       
  5246         // width is auto as default
       
  5247         autoCount++;
       
  5248         }
       
  5249 
       
  5250     CXnProperty* marginleft = aNode.MarginLeftL();
       
  5251 
       
  5252     if ( marginleft )
       
  5253         {
       
  5254         if ( IsPropertyAutoL( *marginleft ) )
       
  5255             {
       
  5256             autoCount++;
       
  5257             }
       
  5258         }
       
  5259 
       
  5260     CXnProperty* marginright = aNode.MarginRightL();
       
  5261 
       
  5262     if ( marginright )
       
  5263         {
       
  5264         if ( IsPropertyAutoL( *marginright ) )
       
  5265             {
       
  5266             autoCount++;
       
  5267             }
       
  5268         }
       
  5269 
       
  5270     if ( !IsAbsoluteL( aNode ) && !IsRelativeL( aNode ) )
       
  5271         {
       
  5272         return autoCount;
       
  5273         }
       
  5274 
       
  5275     CXnProperty* left = aNode.LeftL();
       
  5276 
       
  5277     if ( left )
       
  5278         {
       
  5279         if ( IsPropertyAutoL( *left ) )
       
  5280             {
       
  5281             autoCount++;
       
  5282             }
       
  5283         }
       
  5284 
       
  5285     CXnProperty* right = aNode.RightL();
       
  5286 
       
  5287     if ( right )
       
  5288         {
       
  5289         if ( IsPropertyAutoL( *right ) )
       
  5290             {
       
  5291             autoCount++;
       
  5292             }
       
  5293         }
       
  5294 
       
  5295     return autoCount;
       
  5296     }
       
  5297 
       
  5298 // -----------------------------------------------------------------------------
       
  5299 // HasNodeVerticalAutoValues()
       
  5300 // Check if node has properties set to AUTO.
       
  5301 // -----------------------------------------------------------------------------
       
  5302 //
       
  5303 static TInt HasNodeVerticalAutoValuesL( CXnNode& aNode )
       
  5304     {
       
  5305     TInt autoCount = 0;
       
  5306 
       
  5307     CXnProperty* height = aNode.HeightL();
       
  5308 
       
  5309     if ( height )
       
  5310         {
       
  5311         if ( IsPropertyAutoL( *height ) )
       
  5312             {
       
  5313             autoCount++;
       
  5314             }
       
  5315         }
       
  5316     else
       
  5317         {
       
  5318         // height is auto as default
       
  5319         autoCount++;
       
  5320         }
       
  5321 
       
  5322     CXnProperty* margintop = aNode.MarginTopL();
       
  5323 
       
  5324     if ( margintop )
       
  5325         {
       
  5326         if ( IsPropertyAutoL( *margintop ) )
       
  5327             {
       
  5328             autoCount++;
       
  5329             }
       
  5330         }
       
  5331 
       
  5332     CXnProperty* marginbottom = aNode.MarginBottomL();
       
  5333 
       
  5334     if ( marginbottom )
       
  5335         {
       
  5336         if ( IsPropertyAutoL( *marginbottom ) )
       
  5337             {
       
  5338             autoCount++;
       
  5339             }
       
  5340         }
       
  5341 
       
  5342     if ( !IsAbsoluteL( aNode ) && !IsRelativeL( aNode ) )
       
  5343         {
       
  5344         return autoCount;
       
  5345         }
       
  5346 
       
  5347     CXnProperty* top = aNode.TopL();
       
  5348 
       
  5349     if ( top )
       
  5350         {
       
  5351         if ( IsPropertyAutoL( *top ) )
       
  5352             {
       
  5353             autoCount++;
       
  5354             }
       
  5355         }
       
  5356 
       
  5357     CXnProperty* bottom = aNode.BottomL();
       
  5358 
       
  5359     if ( bottom )
       
  5360         {
       
  5361         if ( IsPropertyAutoL( *bottom ) )
       
  5362             {
       
  5363             autoCount++;
       
  5364             }
       
  5365         }
       
  5366 
       
  5367     return autoCount;
       
  5368     }
       
  5369 
       
  5370 // -----------------------------------------------------------------------------
       
  5371 // HasNodeMinSizesL()
       
  5372 // Check if node has minimum size values.
       
  5373 // -----------------------------------------------------------------------------
       
  5374 //
       
  5375 static TBool HasNodeMinSizesL( CXnNode& aNode )
       
  5376     {
       
  5377     CXnProperty* minWidth = aNode.MinWidthL();
       
  5378 
       
  5379     if ( minWidth )
       
  5380         {
       
  5381         if ( !IsPropertyNone( *minWidth ) )
       
  5382             {
       
  5383             return ETrue;
       
  5384             }
       
  5385         }
       
  5386 
       
  5387     CXnProperty* minHeight = aNode.MinHeightL();
       
  5388 
       
  5389     if ( minHeight )
       
  5390         {
       
  5391         if ( !IsPropertyNone( *minHeight ) )
       
  5392             {
       
  5393             return ETrue;
       
  5394             }
       
  5395         }
       
  5396 
       
  5397     return EFalse;
       
  5398     }
       
  5399 
       
  5400 // -----------------------------------------------------------------------------
       
  5401 // HasNodeMaxSizesL()
       
  5402 // Check if node has maximum size values.
       
  5403 // -----------------------------------------------------------------------------
       
  5404 //
       
  5405 static TBool HasNodeMaxSizesL( CXnNode& aNode )
       
  5406     {
       
  5407     CXnProperty* maxWidth = aNode.MaxWidthL();
       
  5408 
       
  5409     if ( maxWidth )
       
  5410         {
       
  5411         if ( !IsPropertyNone( *maxWidth ) )
       
  5412             {
       
  5413             return ETrue;
       
  5414             }
       
  5415         }
       
  5416 
       
  5417     CXnProperty* maxHeight = aNode.MaxHeightL();
       
  5418 
       
  5419     if ( maxHeight )
       
  5420         {
       
  5421         if ( !IsPropertyNone( *maxHeight ) )
       
  5422             {
       
  5423             return ETrue;
       
  5424             }
       
  5425         }
       
  5426 
       
  5427     return EFalse;
       
  5428     }
       
  5429 
       
  5430 // -----------------------------------------------------------------------------
       
  5431 // HorizontalCentimetersToPixelsL()
       
  5432 // Convert horizontal centimeter value to pixel value.
       
  5433 // -----------------------------------------------------------------------------
       
  5434 //
       
  5435 static TInt HorizontalCentimetersToPixelsL( TReal& aCentimeters,
       
  5436     CGraphicsDevice& aScreenDevice )
       
  5437     {
       
  5438     TReal twips = aCentimeters * KCentimetersAsTwips;
       
  5439     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  5440     return aScreenDevice.HorizontalTwipsToPixels( intTwips );
       
  5441     }
       
  5442 
       
  5443 // -----------------------------------------------------------------------------
       
  5444 // HorizontalInchesToPixelsL()
       
  5445 // Convert horizontal inch value to pixel value.
       
  5446 // -----------------------------------------------------------------------------
       
  5447 //
       
  5448 static TInt HorizontalInchesToPixelsL( TReal& aInches,
       
  5449     CGraphicsDevice& aScreenDevice )
       
  5450     {
       
  5451     TReal twips = aInches * KInchesAsTwips;
       
  5452     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  5453     return aScreenDevice.HorizontalTwipsToPixels( intTwips );
       
  5454     }
       
  5455 
       
  5456 // -----------------------------------------------------------------------------
       
  5457 // HorizontalMillimetersToPixelsL()
       
  5458 // Convert horizontal millimeter value to pixel value.
       
  5459 // -----------------------------------------------------------------------------
       
  5460 //
       
  5461 static TInt HorizontalMillimetersToPixelsL( TReal& aMillimeters,
       
  5462     CGraphicsDevice& aScreenDevice )
       
  5463     {
       
  5464     TReal twips = aMillimeters * KMillimetersAsTwips;
       
  5465     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  5466     return aScreenDevice.HorizontalTwipsToPixels( intTwips );
       
  5467     }
       
  5468 
       
  5469 // -----------------------------------------------------------------------------
       
  5470 // HorizontalPicasToPixelsL()
       
  5471 // Convert horizontal pica value to pixel value.
       
  5472 // -----------------------------------------------------------------------------
       
  5473 //
       
  5474 static TInt HorizontalPicasToPixelsL( TReal& aPicas,
       
  5475     CGraphicsDevice& aScreenDevice )
       
  5476     {
       
  5477     TReal twips = aPicas * KPicasAsTwips;
       
  5478     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  5479     return aScreenDevice.HorizontalTwipsToPixels( intTwips );
       
  5480     }
       
  5481 
       
  5482 // -----------------------------------------------------------------------------
       
  5483 // HorizontalPixelValueL()
       
  5484 // Convert horizontal property to pixel value.
       
  5485 // -----------------------------------------------------------------------------
       
  5486 //
       
  5487 static TInt HorizontalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
       
  5488     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels )
       
  5489     {
       
  5490     return HorizontalValueToPixelsL( DomPropertyValueFromProperty( aValue ),
       
  5491         static_cast< TReal >( aReferenceValue ), aScreenDevice,
       
  5492         aHorizontalUnitInPixels );
       
  5493     }
       
  5494 
       
  5495 // -----------------------------------------------------------------------------
       
  5496 // HorizontalPointsToPixelsL()
       
  5497 // Convert horizontal point value to pixel value.
       
  5498 // -----------------------------------------------------------------------------
       
  5499 //
       
  5500 static TInt HorizontalPointsToPixelsL( TReal& aPoints,
       
  5501     CGraphicsDevice& aScreenDevice )
       
  5502     {
       
  5503     TReal twips = aPoints * KPointsAsTwips;
       
  5504     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  5505     return aScreenDevice.HorizontalTwipsToPixels( intTwips );
       
  5506     }
       
  5507 
       
  5508 // -----------------------------------------------------------------------------
       
  5509 // HorizontalUnitsToPixelsL()
       
  5510 // Convert horizontal unit value to pixel value.
       
  5511 // -----------------------------------------------------------------------------
       
  5512 //
       
  5513 static TInt HorizontalUnitsToPixelsL( TReal aUnits, TReal aUnitInPixels )
       
  5514     {
       
  5515     TInt pixels = aUnits * aUnitInPixels;
       
  5516     return pixels;
       
  5517     }
       
  5518 
       
  5519 // -----------------------------------------------------------------------------
       
  5520 // VerticalUnitsToPixelsL()
       
  5521 // Convert vertical unit value to pixel value.
       
  5522 // -----------------------------------------------------------------------------
       
  5523 //
       
  5524 static TInt VerticalUnitsToPixelsL( TReal aUnits, TReal aUnitInPixels )
       
  5525     {
       
  5526     TInt pixels = aUnits * aUnitInPixels;
       
  5527     return pixels;
       
  5528     }
       
  5529 
       
  5530 // -----------------------------------------------------------------------------
       
  5531 // HorizontalValueToPixelsL()
       
  5532 // Convert horizontal property value to pixel value.
       
  5533 // -----------------------------------------------------------------------------
       
  5534 //
       
  5535 static TInt HorizontalValueToPixelsL( CXnDomPropertyValue* aValue,
       
  5536     TReal aReferenceValue, CGraphicsDevice& aScreenDevice, TReal aUnitInPixels )
       
  5537     {
       
  5538     if ( !aValue )
       
  5539         {
       
  5540         User::Leave( KXnErrHorizontalValueNULL );
       
  5541         }
       
  5542     CXnDomPropertyValue::TPrimitiveValueType valueType =
       
  5543         aValue->PrimitiveValueType();
       
  5544     //  Handle error cases first, inherit is handled elsewhere, none returns 0
       
  5545     switch ( valueType )
       
  5546         {
       
  5547         case CXnDomPropertyValue::EUnknown:
       
  5548         case CXnDomPropertyValue::EEms:
       
  5549         case CXnDomPropertyValue::EExs:
       
  5550         case CXnDomPropertyValue::EDeg:
       
  5551         case CXnDomPropertyValue::ERad:
       
  5552         case CXnDomPropertyValue::EGrad:
       
  5553         case CXnDomPropertyValue::EMs:
       
  5554         case CXnDomPropertyValue::ES:
       
  5555         case CXnDomPropertyValue::EHz:
       
  5556         case CXnDomPropertyValue::EKHz:
       
  5557         case CXnDomPropertyValue::EDimension:
       
  5558         case CXnDomPropertyValue::EString:
       
  5559         case CXnDomPropertyValue::EUri:
       
  5560         case CXnDomPropertyValue::EIdent:
       
  5561         case CXnDomPropertyValue::EAttr:
       
  5562         case CXnDomPropertyValue::ECounter:
       
  5563         case CXnDomPropertyValue::ERect:
       
  5564         case CXnDomPropertyValue::ERgbColor:
       
  5565         case CXnDomPropertyValue::ERgbaColor:
       
  5566         case CXnDomPropertyValue::EFunction:
       
  5567             break;
       
  5568         default:
       
  5569             {
       
  5570             TReal value = aValue->FloatValueL();
       
  5571             if ( valueType == CXnDomPropertyValue::ENumber ||
       
  5572                  valueType == CXnDomPropertyValue::EPx )
       
  5573                 {
       
  5574                 return static_cast< TInt >( value );
       
  5575                 }
       
  5576             else if ( valueType == CXnDomPropertyValue::EPercentage )
       
  5577                 {
       
  5578                 return PercentageToPixelsL( value, aReferenceValue );
       
  5579                 }
       
  5580             else if ( valueType == CXnDomPropertyValue::EIn )
       
  5581                 {
       
  5582                 return HorizontalInchesToPixelsL( value, aScreenDevice );
       
  5583                 }
       
  5584             else if ( valueType == CXnDomPropertyValue::ECm )
       
  5585                 {
       
  5586                 return HorizontalCentimetersToPixelsL( value, aScreenDevice );
       
  5587                 }
       
  5588             else if ( valueType == CXnDomPropertyValue::EMm )
       
  5589                 {
       
  5590                 return HorizontalMillimetersToPixelsL( value, aScreenDevice );
       
  5591                 }
       
  5592             else if ( valueType == CXnDomPropertyValue::EPt )
       
  5593                 {
       
  5594                 return HorizontalPointsToPixelsL( value, aScreenDevice );
       
  5595                 }
       
  5596             else if ( valueType == CXnDomPropertyValue::EPc )
       
  5597                 {
       
  5598                 return HorizontalPicasToPixelsL( value, aScreenDevice );
       
  5599                 }
       
  5600             else if ( valueType == CXnDomPropertyValue::EUnitValue )
       
  5601                 {
       
  5602                 return HorizontalUnitsToPixelsL( value, aUnitInPixels );
       
  5603                 }
       
  5604             }
       
  5605             break;
       
  5606         }
       
  5607 
       
  5608     return 0;
       
  5609     }
       
  5610 
       
  5611 // -----------------------------------------------------------------------------
       
  5612 // IsAbsoluteL()
       
  5613 // Check if node's positioning is absolute.
       
  5614 // -----------------------------------------------------------------------------
       
  5615 //
       
  5616 static TBool IsAbsoluteL( CXnNode& aNode )
       
  5617     {
       
  5618     CXnProperty* prop( aNode.PositionL() );
       
  5619 
       
  5620     if ( prop )
       
  5621         {
       
  5622         const TDesC8& value( prop->StringValue() );
       
  5623         if ( value == XnPropertyNames::style::common::position::KAbsolute ||
       
  5624              value == XnPropertyNames::style::common::position::KFloating )
       
  5625             {
       
  5626             return ETrue;
       
  5627             }
       
  5628          }
       
  5629 
       
  5630     return EFalse;
       
  5631     }
       
  5632 
       
  5633 // -----------------------------------------------------------------------------
       
  5634 // IsLargerThanMaxSizeL()
       
  5635 // Check if node rect size exceeds it's max sizes.
       
  5636 // -----------------------------------------------------------------------------
       
  5637 //
       
  5638 static TBool IsLargerThanMaxSizeL( const TRect& aParentRect, CXnNode& aNode,
       
  5639     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels, 
       
  5640     TReal aVerticalUnitInPixels )
       
  5641     {
       
  5642     TRect parentRect = aParentRect;
       
  5643     CXnProperty* heightProperty = aNode.HeightL();
       
  5644     CXnProperty* widthProperty = aNode.WidthL();
       
  5645 
       
  5646     if ( heightProperty )
       
  5647         {
       
  5648         CXnProperty* maxHeightProperty = aNode.MaxHeightL();
       
  5649         if ( maxHeightProperty )
       
  5650             {
       
  5651             if ( !IsPropertyNone( *maxHeightProperty ) )
       
  5652                 {
       
  5653                 TInt maxHeight = VerticalPixelValueL( maxHeightProperty,
       
  5654                     parentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
       
  5655                 TInt height = aNode.Rect().Height();
       
  5656                 if ( height > maxHeight )
       
  5657                     {
       
  5658                     // height larger than max
       
  5659                     return ETrue;
       
  5660                     }
       
  5661                 }
       
  5662             }
       
  5663         }
       
  5664 
       
  5665     if ( widthProperty )
       
  5666         {
       
  5667         CXnProperty* maxWidthProperty = aNode.MaxWidthL();
       
  5668         if ( maxWidthProperty )
       
  5669             {
       
  5670             if ( !IsPropertyNone( *maxWidthProperty ) )
       
  5671                 {
       
  5672                 TInt maxWidth = HorizontalPixelValueL( maxWidthProperty,
       
  5673                     parentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
       
  5674                 TInt width = aNode.Rect().Width();
       
  5675                 if ( width > maxWidth )
       
  5676                     {
       
  5677                     // width larger than max
       
  5678                     return ETrue;
       
  5679                     }
       
  5680                 }
       
  5681             }
       
  5682         }
       
  5683 
       
  5684     // width and height within limits
       
  5685     return EFalse;
       
  5686     }
       
  5687 
       
  5688 // -----------------------------------------------------------------------------
       
  5689 // IsNodeDisplayedL()
       
  5690 // Check if node is able to be displayed.
       
  5691 // -----------------------------------------------------------------------------
       
  5692 //
       
  5693 static TBool IsNodeDisplayedL( CXnNode& aNode )
       
  5694     {
       
  5695     if ( !aNode.IsLayoutCapable() )
       
  5696         {
       
  5697         return EFalse;
       
  5698         }
       
  5699 
       
  5700     // Am I displayed?
       
  5701     CXnProperty* displayProp( aNode.DisplayL() );
       
  5702 
       
  5703     if ( displayProp )
       
  5704         {
       
  5705         const TDesC8& display( displayProp->StringValue() );
       
  5706 
       
  5707         if ( display != XnPropertyNames::style::common::display::KBlock )
       
  5708             {
       
  5709             return EFalse;
       
  5710             }
       
  5711         }
       
  5712 
       
  5713     CXnNode* parent( aNode.Parent() );
       
  5714 
       
  5715     // Is my parent displayed?
       
  5716     for ( ; parent; parent = parent->Parent() )
       
  5717         {
       
  5718         CXnProperty* displayProp( parent->DisplayL() );
       
  5719 
       
  5720         if ( displayProp )
       
  5721             {
       
  5722             const TDesC8& display( displayProp->StringValue() );
       
  5723 
       
  5724             if ( display != XnPropertyNames::style::common::display::KBlock )
       
  5725                 {
       
  5726                 return EFalse;
       
  5727                 }
       
  5728             }
       
  5729         }
       
  5730 
       
  5731     return ETrue;
       
  5732     }
       
  5733 
       
  5734 // -----------------------------------------------------------------------------
       
  5735 // IsNodeTooltip()
       
  5736 // Check if node is a tooltip.
       
  5737 // -----------------------------------------------------------------------------
       
  5738 //
       
  5739 static TBool IsNodeTooltip( CXnNode& aNode )
       
  5740     {
       
  5741     _LIT8( tooltip, "tooltip" );
       
  5742 
       
  5743     if ( aNode.Type()->Type() == tooltip )
       
  5744         {
       
  5745         return ETrue;
       
  5746         }
       
  5747     return EFalse;
       
  5748     }
       
  5749 
       
  5750 // -----------------------------------------------------------------------------
       
  5751 // IsPropertyAutoL()
       
  5752 // Check if property is set to AUTO.
       
  5753 // -----------------------------------------------------------------------------
       
  5754 //
       
  5755 static TBool IsPropertyAutoL( CXnProperty& aProperty )
       
  5756     {
       
  5757     if ( &aProperty )
       
  5758         {
       
  5759         TBool returnValue;
       
  5760         TInt index = 0;
       
  5761         CXnDomProperty* domProperty = aProperty.Property();
       
  5762         CXnDomPropertyValue* domPropertyValue =
       
  5763             static_cast< CXnDomPropertyValue* >(
       
  5764             domProperty->PropertyValueList().Item( index ) );
       
  5765         returnValue = domPropertyValue->IsAutoIdent();
       
  5766         if ( !returnValue )
       
  5767             {
       
  5768             // if return value is string and not auto or none,
       
  5769             // return ETrue because auto is used as default value
       
  5770             if ( IsStringValueL( aProperty ) && !IsPropertyNone( aProperty ) )
       
  5771                 {
       
  5772                 return ETrue;
       
  5773                 }
       
  5774             }
       
  5775         return returnValue;
       
  5776         }
       
  5777     return EFalse;
       
  5778     }
       
  5779 
       
  5780 // -----------------------------------------------------------------------------
       
  5781 // IsPropertyNone()
       
  5782 // Check if property is set to NONE.
       
  5783 // -----------------------------------------------------------------------------
       
  5784 //
       
  5785 static TBool IsPropertyNone( CXnProperty& aProperty )
       
  5786     {
       
  5787     if ( &aProperty )
       
  5788         {
       
  5789           TInt index = 0;
       
  5790           CXnDomProperty* domProperty = aProperty.Property();
       
  5791           CXnDomPropertyValue* domPropertyValue =
       
  5792               static_cast< CXnDomPropertyValue* >(
       
  5793               domProperty->PropertyValueList().Item( index ) );
       
  5794           return domPropertyValue->IsNoneIdent();
       
  5795           }
       
  5796     return EFalse;
       
  5797     }
       
  5798 
       
  5799 // -----------------------------------------------------------------------------
       
  5800 // IsRelativeL()
       
  5801 // Check if node's positioning is absolute.
       
  5802 // -----------------------------------------------------------------------------
       
  5803 //
       
  5804 static TBool IsRelativeL( CXnNode& aNode )
       
  5805     {
       
  5806     CXnProperty* positioningProperty = aNode.PositionL();
       
  5807     if ( positioningProperty )
       
  5808         {
       
  5809         const TDesC8& positioning = positioningProperty->StringValue();
       
  5810         if ( positioning == XnPropertyNames::style::common::position::KRelative )
       
  5811             {
       
  5812             return ETrue;
       
  5813             }
       
  5814          }
       
  5815     return EFalse;
       
  5816     }
       
  5817 
       
  5818 // -----------------------------------------------------------------------------
       
  5819 // IsSmallerThanMinSizeL()
       
  5820 // Check if node rect size is smaller than it's min sizes.
       
  5821 // -----------------------------------------------------------------------------
       
  5822 //
       
  5823 static TBool IsSmallerThanMinSizeL( const TRect& aParentRect, CXnNode& aNode,
       
  5824     CGraphicsDevice& aScreenDevice, TReal aHorizontalUnitInPixels,
       
  5825     TReal aVerticalUnitInPixels )
       
  5826     {
       
  5827     TRect parentRect = aParentRect;
       
  5828     CXnProperty* heightproperty = aNode.HeightL();
       
  5829     CXnProperty* widthproperty = aNode.WidthL();
       
  5830 
       
  5831     if ( heightproperty )
       
  5832         {
       
  5833         CXnProperty* minheightproperty = aNode.MinHeightL();
       
  5834         if ( minheightproperty )
       
  5835             {
       
  5836             if ( !IsPropertyNone( *minheightproperty ) )
       
  5837                 {
       
  5838                 TInt minheight = VerticalPixelValueL( minheightproperty,
       
  5839                     parentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
       
  5840                 TInt height = aNode.Rect().Height();
       
  5841                 if ( height < minheight )
       
  5842                     {
       
  5843                     // height smaller than minimum
       
  5844                     return ETrue;
       
  5845                     }
       
  5846                 }
       
  5847             }
       
  5848         }
       
  5849     if ( widthproperty )
       
  5850         {
       
  5851         CXnProperty* minwidthproperty = aNode.MinWidthL();
       
  5852         if ( minwidthproperty )
       
  5853             {
       
  5854             if ( !IsPropertyNone( *minwidthproperty ) )
       
  5855                 {
       
  5856                 TInt minwidth = HorizontalPixelValueL( minwidthproperty,
       
  5857                     parentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
       
  5858                 TInt width = aNode.Rect().Width();
       
  5859                 if ( width < minwidth )
       
  5860                     {
       
  5861                     // width smaller than minimum
       
  5862                     return ETrue;
       
  5863                     }
       
  5864                 }
       
  5865             }
       
  5866         }
       
  5867     // width and height within limits
       
  5868     return EFalse;
       
  5869     }
       
  5870 
       
  5871 // -----------------------------------------------------------------------------
       
  5872 // IsStringValueL()
       
  5873 // Check if property value is string.
       
  5874 // -----------------------------------------------------------------------------
       
  5875 //
       
  5876 static TBool IsStringValueL( CXnProperty& aProperty )
       
  5877     {
       
  5878     CXnDomList& propertyValueList = aProperty.Property()->PropertyValueList();
       
  5879     CXnDomPropertyValue* value =
       
  5880         static_cast< CXnDomPropertyValue* >( propertyValueList.Item( 0 ) );
       
  5881     if ( value->PrimitiveValueType() == CXnDomPropertyValue::EString ||
       
  5882          value->PrimitiveValueType() == CXnDomPropertyValue::EIdent )
       
  5883         {
       
  5884         return ETrue;
       
  5885         }
       
  5886     return EFalse;
       
  5887     }
       
  5888 
       
  5889 // -----------------------------------------------------------------------------
       
  5890 // IsValuePercentageL()
       
  5891 // Check if property value is percentage.
       
  5892 // -----------------------------------------------------------------------------
       
  5893 //
       
  5894 static TBool IsValuePercentageL( CXnProperty& aProperty )
       
  5895     {
       
  5896     CXnDomProperty* domProperty = aProperty.Property();
       
  5897     CXnDomPropertyValue* domPropertyValue = static_cast<
       
  5898         CXnDomPropertyValue* >( domProperty->PropertyValueList().Item( 0 ) );
       
  5899     if ( !domPropertyValue )
       
  5900         {
       
  5901         User::Leave( KXnErrDomPropertyValueNULL );
       
  5902         }
       
  5903     CXnDomPropertyValue::TPrimitiveValueType valueType =
       
  5904         domPropertyValue->PrimitiveValueType();
       
  5905     if ( valueType == CXnDomPropertyValue::EPercentage )
       
  5906         {
       
  5907         return ETrue;
       
  5908         }
       
  5909     return EFalse;
       
  5910     }
       
  5911  
       
  5912 // -----------------------------------------------------------------------------
       
  5913 // PercentageToPixelsL()
       
  5914 // Convert percentage value to pixel value.
       
  5915 // -----------------------------------------------------------------------------
       
  5916 //
       
  5917 static TInt PercentageToPixelsL( TReal& aPercentage, TReal aReferenceValue )
       
  5918     {
       
  5919     TReal value = aReferenceValue * aPercentage * KIntPercentageConstant;
       
  5920     return static_cast< TInt >( value + KIntConversionConstant );
       
  5921     }
       
  5922 
       
  5923 // -----------------------------------------------------------------------------
       
  5924 // GetPreviousNodeL()
       
  5925 // -----------------------------------------------------------------------------
       
  5926 //
       
  5927 static CXnNode* GetPreviousNodeL( CXnNode& aNode )
       
  5928     {
       
  5929     CXnNode* returnValue = NULL;
       
  5930     CXnNode* parent = aNode.Parent();
       
  5931 
       
  5932     if ( !parent )
       
  5933         {
       
  5934         return returnValue;
       
  5935         }
       
  5936 
       
  5937     RPointerArray< CXnNode >& nodes = parent->Children();
       
  5938 
       
  5939     for ( TInt currentIndex = 0; currentIndex < nodes.Count(); currentIndex++ )
       
  5940         {
       
  5941         CXnNode* checkNode = nodes[currentIndex];
       
  5942         if ( &aNode == checkNode && currentIndex > 0 )
       
  5943             {
       
  5944             for ( TInt candidateIndex =
       
  5945                 currentIndex - 1; candidateIndex >= 0; candidateIndex-- )
       
  5946                 {
       
  5947                 checkNode = nodes[candidateIndex];
       
  5948                 if ( IsNodeDisplayedL( *checkNode ) &&
       
  5949                      !checkNode->IsDropped() && !IsAbsoluteL( *checkNode ) &&
       
  5950                      !IsNodeTooltip( *checkNode ) )
       
  5951                     {
       
  5952                     returnValue = nodes[candidateIndex];
       
  5953                     break;
       
  5954                     }
       
  5955                 }
       
  5956             }
       
  5957         }
       
  5958 
       
  5959     return returnValue;
       
  5960     }
       
  5961 
       
  5962 // -----------------------------------------------------------------------------
       
  5963 // PlaceAreasL()
       
  5964 // Move the area rects to their places. All positioning is done here.
       
  5965 // -----------------------------------------------------------------------------
       
  5966 //
       
  5967 static void PlaceAreasL( CXnNode& aNode, RPointerArray< CXnNode >& aLaidOutList,
       
  5968     TInt aLayoutPhase, CGraphicsDevice& aGraphicsDevice,
       
  5969     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
       
  5970     {
       
  5971     CXnNodeBreadthFirstIterator< CXnNode >* iterator = 
       
  5972             CXnNodeBreadthFirstIterator< CXnNode >::NewL( aNode );
       
  5973     CleanupStack::PushL( iterator );
       
  5974 
       
  5975     RPointerArray< CXnNode > absoluteNodes;
       
  5976     CleanupClosePushL( absoluteNodes );
       
  5977 
       
  5978     RPointerArray< CXnNode > relativeNodes;
       
  5979     CleanupClosePushL( relativeNodes );
       
  5980 
       
  5981     RPointerArray< CXnNode > autoNodes;
       
  5982     CleanupClosePushL( autoNodes );
       
  5983 
       
  5984     RPointerArray< CXnNode > adaptiveNodes;
       
  5985     CleanupClosePushL( adaptiveNodes );
       
  5986 
       
  5987     CXnProperty* parentBlockProgressionProperty( NULL );
       
  5988     CXnProperty* parentDirectionProperty( NULL );
       
  5989     const TDesC8* parentBlockProgression( NULL );
       
  5990     const TDesC8* parentDirection( NULL );
       
  5991 
       
  5992     CXnUiEngine* engine( aNode.UiEngine() );
       
  5993     TSize maxAvailableSize( engine->ClientRect().Size() );
       
  5994 
       
  5995     // Start to go through the tree
       
  5996     CXnNode* previous( NULL );
       
  5997 
       
  5998     CXnNode* parent( NULL );
       
  5999     TInt columnWidth;
       
  6000     TInt columnMargin;
       
  6001     TRect parentRect;
       
  6002 
       
  6003 #ifdef _XN3_DEBUG_
       
  6004     RDebug::Print( _L("Xuikon: Layout:") );
       
  6005     TBuf8< 256 > debug;
       
  6006 #endif
       
  6007 
       
  6008     // Place areas according their parents and positioning
       
  6009     for( CXnNode* node = iterator->Value(); node; node = iterator->NextL() )
       
  6010         {
       
  6011 #ifdef _XN3_DEBUG_
       
  6012         debug = node->Type()->Type();
       
  6013         CXnProperty* id( node->IdL() );
       
  6014         if ( id )
       
  6015             {
       
  6016             debug.Append( _L8( ", id: " ) );
       
  6017             debug.Append( id->StringValue() );
       
  6018             }
       
  6019 #endif
       
  6020 
       
  6021         if ( node->IsLaidOut() )
       
  6022             {
       
  6023 #ifdef _XN3_DEBUG_
       
  6024             debug.Append( _L8( ", already laidout" ) );
       
  6025             RDebug::RawPrint( debug );
       
  6026 #endif
       
  6027 
       
  6028             continue;
       
  6029             }
       
  6030 
       
  6031         if ( !IsNodeDisplayedL( *node ) || node->IsDropped() )
       
  6032             {
       
  6033 #ifdef _XN3_DEBUG_
       
  6034             debug.Append( _L8( ", not displayed or dropped" ) );
       
  6035             RDebug::RawPrint( debug );
       
  6036 #endif
       
  6037             continue;
       
  6038             }
       
  6039 
       
  6040 #ifdef _XN3_DEBUG_
       
  6041         RDebug::RawPrint( debug );
       
  6042 #endif
       
  6043 
       
  6044         switch ( aLayoutPhase )
       
  6045             {
       
  6046             case XnLayoutPhase::ELayout:
       
  6047                 if ( aLaidOutList.Find( node ) == KErrNotFound )
       
  6048                     {
       
  6049                     aLaidOutList.AppendL( node );
       
  6050                     }
       
  6051                 /* flow through */
       
  6052             case XnLayoutPhase::EMeasure:
       
  6053                 if ( node->ViewNodeImpl() )
       
  6054                     {
       
  6055                     // check that view's children fit into it
       
  6056                     FitChildrenIntoParentL( *node, aGraphicsDevice,
       
  6057                         aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6058                     continue;
       
  6059                     }
       
  6060                 engine->CheckAdaptiveContentL( *node, maxAvailableSize );
       
  6061                 if ( node->IsDropped() )
       
  6062                     {
       
  6063                     // Adaptive content check dropped this node
       
  6064                     continue;
       
  6065                     }
       
  6066                 break;
       
  6067             default:
       
  6068                 // Should not happen
       
  6069                 continue;
       
  6070             }
       
  6071 		
       
  6072         if( node->Type()->Type() == KScrollableBoxNodeName )            
       
  6073             {
       
  6074             CXnScrollableControlAdapter* cntrl = node->ScrollableControl();
       
  6075             if( cntrl )
       
  6076                 {
       
  6077                 cntrl->ResetState();
       
  6078                 }
       
  6079             }
       
  6080 				
       
  6081         CXnNode* tmpParent( DisplayedParentL( *node ) );
       
  6082 
       
  6083         // Is parent changed?
       
  6084         if ( tmpParent != parent )
       
  6085             {
       
  6086             columnWidth = 0;
       
  6087             columnMargin = 0;
       
  6088             if ( parent )
       
  6089                 {
       
  6090                  // Process auto areas
       
  6091                 ProcessAutoAreasL( *parent, &autoNodes, *parentBlockProgression,
       
  6092                     *parentDirection, aGraphicsDevice, aHorizontalUnitInPixels,
       
  6093                     aVerticalUnitInPixels );
       
  6094                 autoNodes.Reset();
       
  6095                 // Pocess relative areas
       
  6096                 for ( TInt i = 0; i < relativeNodes.Count(); i++ )
       
  6097                     {
       
  6098                     CalculateRelativePositionsL( parentRect, *relativeNodes[i],
       
  6099                     aGraphicsDevice, aHorizontalUnitInPixels,
       
  6100                     aVerticalUnitInPixels );
       
  6101                     }
       
  6102                 relativeNodes.Reset();
       
  6103                 // Process absolute areas
       
  6104                 for ( TInt i = 0; i < absoluteNodes.Count(); i++ )
       
  6105                     {
       
  6106                     CalculatePaddingL( parentRect, *absoluteNodes[i],
       
  6107                         aGraphicsDevice, aHorizontalUnitInPixels,
       
  6108                         aVerticalUnitInPixels );
       
  6109                     CalculateBorderL( *absoluteNodes[i], parentRect,
       
  6110                         aGraphicsDevice, aHorizontalUnitInPixels,
       
  6111                         aVerticalUnitInPixels );
       
  6112                     CalculateAbsoluteMarginL( *parent, *absoluteNodes[i], NULL,
       
  6113                         *parentBlockProgression, *parentDirection, parentRect,
       
  6114                         aGraphicsDevice, aHorizontalUnitInPixels,
       
  6115                         aVerticalUnitInPixels );
       
  6116                     CalculateAbsolutePositionsL( *absoluteNodes[i], parentRect,
       
  6117                         aGraphicsDevice, aHorizontalUnitInPixels,
       
  6118                         aVerticalUnitInPixels );
       
  6119                     }
       
  6120                 absoluteNodes.Reset();
       
  6121                 previous = NULL;
       
  6122                 }
       
  6123             // Get new parent properties
       
  6124             parent = tmpParent;
       
  6125             parentBlockProgressionProperty = parent->BlockProgressionL();
       
  6126             parentDirectionProperty = parent->DirectionL();
       
  6127             if ( !parentBlockProgressionProperty )
       
  6128                 {
       
  6129                 // block progression default is tb
       
  6130                 parentBlockProgression =
       
  6131                     &XnPropertyNames::style::common::block_progression::KTB();
       
  6132                 }
       
  6133             else
       
  6134                 {
       
  6135                 parentBlockProgression =
       
  6136                     &parentBlockProgressionProperty->StringValue();
       
  6137                 }
       
  6138             if ( !parentDirectionProperty )
       
  6139                 {
       
  6140                 // direction default is ltr
       
  6141                 parentDirection =
       
  6142                     &XnPropertyNames::style::common::direction::KLTR();
       
  6143                 }
       
  6144             else
       
  6145                 {
       
  6146                 parentDirection = &parentDirectionProperty->StringValue();
       
  6147                 }
       
  6148             }
       
  6149 
       
  6150         parentRect = parent->Rect();
       
  6151 
       
  6152         CalculateRectL( *node, *parent, aGraphicsDevice,
       
  6153             aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6154 
       
  6155         // Which positioning is used?
       
  6156         CXnProperty* positioningProp( node->PositionL() );
       
  6157         // Static is the default
       
  6158         const TDesC8* positioning(
       
  6159             &XnPropertyNames::style::common::position::KStatic() );
       
  6160 
       
  6161         if ( positioningProp )
       
  6162             {
       
  6163             const TDesC8& value( positioningProp->StringValue() );
       
  6164             if ( value != KNullDesC8 )
       
  6165                 {
       
  6166                 positioning = &value;
       
  6167                 }
       
  6168             }
       
  6169         // Adaptive nodes' _must_ be collected here
       
  6170         if ( node->IsAdaptive() && adaptiveNodes.Find( node ) == KErrNotFound )
       
  6171             {
       
  6172             // Postpone adaptive area processing
       
  6173             adaptiveNodes.AppendL( node );
       
  6174             }
       
  6175         // Tooltips are processed as absolute areas
       
  6176         TBool absolute( IsAbsoluteL( *node ) || IsNodeTooltip( *node ) );
       
  6177         if ( !node->ViewNodeImpl() && HasNodeAutoValuesL( *node ) && !absolute )
       
  6178             {
       
  6179             // if area has auto values, process it later
       
  6180             autoNodes.AppendL( node );
       
  6181             }
       
  6182         if ( absolute )
       
  6183             {
       
  6184             // Absolute positioning area found, take it out of normal flow
       
  6185             // Because of that, previous node is not set
       
  6186             // Absolute area is put to a array to be processed later
       
  6187             absoluteNodes.AppendL( node );
       
  6188             continue;
       
  6189             }
       
  6190         // static or relative positioning
       
  6191         CalculatePaddingL( parentRect, *node, aGraphicsDevice,
       
  6192             aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6193         CalculateBorderL( *node, parentRect, aGraphicsDevice,
       
  6194             aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6195         previous = GetPreviousNodeL( *node );
       
  6196         CalculateMarginL( *parent, *node, previous, *parentBlockProgression,
       
  6197             *parentDirection, parentRect, aGraphicsDevice,
       
  6198             aHorizontalUnitInPixels, aVerticalUnitInPixels, columnWidth,
       
  6199             columnMargin );
       
  6200         FitChildrenIntoParentL( *node, aGraphicsDevice, aHorizontalUnitInPixels,
       
  6201             aVerticalUnitInPixels );
       
  6202         if ( XnPropertyNames::style::common::position::KRelative() ==
       
  6203              *positioning )
       
  6204             {
       
  6205             // Relative positioning area found, add it's offset later
       
  6206             relativeNodes.AppendL( node );
       
  6207             }
       
  6208         previous = node;
       
  6209         }
       
  6210 
       
  6211     if ( parent )
       
  6212         {
       
  6213         // Are there auto nodes left?
       
  6214         ProcessAutoAreasL( *parent, &autoNodes, *parentBlockProgression,
       
  6215             *parentDirection, aGraphicsDevice, aHorizontalUnitInPixels,
       
  6216             aVerticalUnitInPixels );
       
  6217         // Are there relative nodes left?
       
  6218         for ( TInt i = 0; i < relativeNodes.Count(); i++ )
       
  6219             {
       
  6220             CalculateRelativePositionsL( parentRect, *relativeNodes[i],
       
  6221                 aGraphicsDevice, aHorizontalUnitInPixels,
       
  6222                 aVerticalUnitInPixels );
       
  6223             }
       
  6224         // Are there absolute nodes left?
       
  6225         for ( TInt i = 0; i < absoluteNodes.Count(); i++ )
       
  6226             {
       
  6227             CalculatePaddingL( parentRect, *absoluteNodes[i], aGraphicsDevice,
       
  6228                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6229             CalculateBorderL( *absoluteNodes[i], parentRect, aGraphicsDevice,
       
  6230                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6231             CalculateAbsoluteMarginL( *parent, *absoluteNodes[i], NULL,
       
  6232                 *parentBlockProgression, *parentDirection, parentRect,
       
  6233                 aGraphicsDevice, aHorizontalUnitInPixels,
       
  6234                 aVerticalUnitInPixels );
       
  6235             FitChildrenIntoParentL( *absoluteNodes[i], aGraphicsDevice,
       
  6236                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6237             CalculateAbsolutePositionsL( *absoluteNodes[i], parentRect,
       
  6238                 aGraphicsDevice, aHorizontalUnitInPixels,
       
  6239                 aVerticalUnitInPixels );
       
  6240             }
       
  6241         }
       
  6242 
       
  6243     for ( TInt i = 0; i < adaptiveNodes.Count(); i++ )
       
  6244         {
       
  6245         // Fix parent size to its childs content size
       
  6246         ProcessAdaptiveAreasL( *adaptiveNodes[i], aGraphicsDevice,
       
  6247             aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6248         }
       
  6249 
       
  6250     // close node arrays and destroy iterator
       
  6251     CleanupStack::PopAndDestroy( 5, iterator );
       
  6252     }
       
  6253 
       
  6254 // -----------------------------------------------------------------------------
       
  6255 // PriorizeChildrenL()
       
  6256 // Find a child node with highest priority value and drop all
       
  6257 // child nodes with highest priority.
       
  6258 // -----------------------------------------------------------------------------
       
  6259 //
       
  6260 static void PriorizeChildrenL( CXnNode& aNode )
       
  6261     {
       
  6262     RPointerArray< CXnNode >& children( aNode.Children() );
       
  6263 
       
  6264     CXnNode* candidate( NULL );
       
  6265     TInt highest( 0 );
       
  6266 
       
  6267     // Find the highest priority value among the children
       
  6268     for ( TInt i = 0; i < children.Count(); i++ )
       
  6269         {
       
  6270         CXnNode* node( children[i] );
       
  6271         if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
       
  6272              !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
       
  6273             {
       
  6274             CXnProperty* priorityProperty( node->DisplayPriorityL() );
       
  6275             if ( priorityProperty )
       
  6276                 {
       
  6277                 TInt priority( priorityProperty->FloatValueL() );
       
  6278                 if ( priority > highest )
       
  6279                     {
       
  6280                     // highest found, set new top priority
       
  6281                     highest = priority;
       
  6282                     candidate = node;
       
  6283                     }
       
  6284                 }
       
  6285             }
       
  6286         }
       
  6287     if ( candidate )
       
  6288         {
       
  6289         aNode.UiEngine()->SetNodeDroppedL(
       
  6290             *candidate, XnNodeLayout::EDropped  );
       
  6291         }
       
  6292     }
       
  6293 
       
  6294 // -----------------------------------------------------------------------------
       
  6295 // CalculateAutoPropertiesOfNodesL()
       
  6296 //
       
  6297 // -----------------------------------------------------------------------------
       
  6298 //
       
  6299 static void CalculateAutoPropertiesOfNodesL(
       
  6300     RPointerArray< CXnNode >* aAutoNodeArray, TInt& aWidthAutoCount,
       
  6301     TInt& aHeightAutoCount )
       
  6302     {
       
  6303     aWidthAutoCount = 0;
       
  6304     aHeightAutoCount = 0;
       
  6305 
       
  6306     // calculate the number of auto properties in each direction
       
  6307     for ( TInt i = 0; i < aAutoNodeArray->Count(); ++i )
       
  6308         {
       
  6309         CXnNode* tmp = ( *aAutoNodeArray )[i];
       
  6310         if ( !tmp->IsDropped() )
       
  6311             {
       
  6312             if ( HasNodeVerticalAutoValuesL( *tmp ) )
       
  6313                 {
       
  6314                 ++aHeightAutoCount;
       
  6315                 }
       
  6316             if ( HasNodeHorizontalAutoValuesL( *tmp ) )
       
  6317                 {
       
  6318                 ++aWidthAutoCount;
       
  6319                 }
       
  6320             }
       
  6321         }
       
  6322     if ( aWidthAutoCount == 0 )
       
  6323         {
       
  6324         aWidthAutoCount = 1;
       
  6325         }
       
  6326     if ( aHeightAutoCount == 0 )
       
  6327         {
       
  6328         aHeightAutoCount = 1;
       
  6329         }
       
  6330     }
       
  6331 
       
  6332 // -----------------------------------------------------------------------------
       
  6333 // ProcessAutoAreasL()
       
  6334 // Process nodes with layout properties defined as auto.
       
  6335 // -----------------------------------------------------------------------------
       
  6336 //
       
  6337 static void ProcessAutoAreasL( CXnNode& aParent,
       
  6338     RPointerArray< CXnNode >* aAutoNodeArray,
       
  6339     const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
       
  6340     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  6341     TReal aVerticalUnitInPixels )
       
  6342     {
       
  6343     TInt autoCount( aAutoNodeArray->Count() );
       
  6344 
       
  6345     if ( autoCount == 0 )
       
  6346         {
       
  6347         return;
       
  6348         }
       
  6349 
       
  6350     //  Just to be sure, drop others first if needed
       
  6351     FitChildrenIntoParentL( aParent, aGraphicsDevice, aHorizontalUnitInPixels,
       
  6352         aVerticalUnitInPixels );
       
  6353 
       
  6354     TInt originalHeightAutoCount( 0 );
       
  6355     TInt originalWidthAutoCount( 0 );
       
  6356 
       
  6357     CalculateAutoPropertiesOfNodesL( aAutoNodeArray, originalWidthAutoCount,
       
  6358         originalHeightAutoCount );
       
  6359 
       
  6360     TInt heightAutoCount( originalHeightAutoCount );
       
  6361     TInt widthAutoCount( originalWidthAutoCount );
       
  6362 
       
  6363     // calculate space to use (parent height and width - placed areas)
       
  6364     CXnNode* parent( &aParent );
       
  6365     TRect parentRect( parent->Rect() );
       
  6366     
       
  6367     if( parent->Control() && parent->Control()->OwnsWindow() )
       
  6368         {
       
  6369         parentRect = TRect( parentRect.iTl - parent->MarginRect().iTl, parentRect.Size() );
       
  6370         }
       
  6371 
       
  6372     TInt parentWidth( parentRect.Width() );
       
  6373     TInt parentHeight( parentRect.Height() );
       
  6374 
       
  6375     RPointerArray< CXnNode >& children( parent->Children() );
       
  6376 
       
  6377     RPointerArray< CXnNode > layoutedAutoNodes;
       
  6378     CleanupClosePushL( layoutedAutoNodes );
       
  6379 
       
  6380     TBool layoutedAutoNodesAdded( EFalse );
       
  6381     TBool layoutingHeight( EFalse );
       
  6382     TBool layoutingWidth( EFalse );
       
  6383 
       
  6384     TInt displayedChildCount( DisplayedChildrenCountL( aParent ) );
       
  6385 
       
  6386     do
       
  6387         {
       
  6388         layoutedAutoNodesAdded = EFalse;
       
  6389 
       
  6390         //  count the size used by the non auto nodes and
       
  6391         //  auto nodes which have been calculated
       
  6392         TSize calculatedAutosize = CalculateSpaceUsedByAutoChildrenL(
       
  6393             *aAutoNodeArray, layoutedAutoNodes, *parent,
       
  6394             aParentBlockProgression, aParentDirection, aGraphicsDevice );
       
  6395 
       
  6396         TInt usedSiblingHeight( calculatedAutosize.iHeight );
       
  6397         TInt usedSiblingWidth( calculatedAutosize.iWidth );
       
  6398 
       
  6399         if ( aParentBlockProgression ==
       
  6400              XnPropertyNames::style::common::block_progression::KTB ||
       
  6401              aParentBlockProgression ==
       
  6402              XnPropertyNames::style::common::block_progression::KBT )
       
  6403             {
       
  6404             // calculate space for each auto area
       
  6405             parentHeight = parentRect.Height() - usedSiblingHeight;
       
  6406             parentHeight = parentHeight / heightAutoCount;
       
  6407             layoutingHeight = ETrue;
       
  6408             }
       
  6409         else // assume that block progression is LR or RL
       
  6410             {
       
  6411             // calculate space for each auto area
       
  6412             parentWidth = parentRect.Width() - usedSiblingWidth;
       
  6413             parentWidth = parentWidth / widthAutoCount;
       
  6414             layoutingWidth = ETrue;
       
  6415             }
       
  6416         for ( TInt i = 0; i < autoCount; i++ )
       
  6417             {
       
  6418             CXnNode* node( ( *aAutoNodeArray )[i] );
       
  6419             if ( layoutedAutoNodes.Find( node ) != KErrNotFound )
       
  6420                 {
       
  6421                 //  The size has already been calculated and fixed
       
  6422                 continue;
       
  6423                 }
       
  6424             if ( node->IsDropped() )
       
  6425                 {
       
  6426                 //  The node is dropped, no need to recalculate
       
  6427                 continue;
       
  6428                 }
       
  6429             CXnProperty* heightProperty = node->HeightL();
       
  6430             CXnProperty* widthProperty = node->WidthL();
       
  6431             CXnProperty* marginLeft = node->MarginLeftL();
       
  6432             CXnProperty* marginRight = node->MarginRightL();
       
  6433             CXnProperty* marginTop = node->MarginTopL();
       
  6434             CXnProperty* marginBottom = node->MarginBottomL();
       
  6435             TInt freeHeight = parentHeight;
       
  6436             TInt freeWidth = parentWidth;
       
  6437             TBool verticalValuesAuto = IsPropertyAutoL( *heightProperty ) ||
       
  6438                 IsPropertyAutoL( *marginTop ) ||
       
  6439                 IsPropertyAutoL( *marginBottom );
       
  6440             if ( !verticalValuesAuto == !heightProperty )
       
  6441                 {
       
  6442                 verticalValuesAuto = ETrue;
       
  6443                 }
       
  6444             TBool horizontalValuesAuto = IsPropertyAutoL( *widthProperty ) ||
       
  6445                 IsPropertyAutoL( *marginLeft ) ||
       
  6446                 IsPropertyAutoL( *marginRight );
       
  6447             if ( !horizontalValuesAuto == !widthProperty )
       
  6448                 {
       
  6449                 horizontalValuesAuto = ETrue;
       
  6450                 }
       
  6451             TInt adaptive( node->IsAdaptive() );
       
  6452             // I have childs share the available space between them
       
  6453             if ( adaptive & XnAdaptive::EHeight )
       
  6454                 {
       
  6455                 // Give all available height to the adaptive node's children
       
  6456                 freeHeight = parentRect.Height() - usedSiblingHeight;
       
  6457                 }
       
  6458             if ( adaptive & XnAdaptive::EWidth )
       
  6459                 {
       
  6460                 // Give all available width to the adaptive node's children
       
  6461                 freeWidth = parentRect.Width() - usedSiblingWidth;
       
  6462                 }
       
  6463             ScaleAutoAreaL( *node, freeWidth, freeHeight,
       
  6464                 aParentBlockProgression, aParentDirection,
       
  6465                 parentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  6466                 aVerticalUnitInPixels );
       
  6467             FitChildrenIntoParentL( *node, aGraphicsDevice,
       
  6468                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  6469             //  handle autonodes which had auto width or height,
       
  6470             // but also min or max limit
       
  6471             if ( aParentBlockProgression ==
       
  6472                  XnPropertyNames::style::common::block_progression::KTB ||
       
  6473                  aParentBlockProgression ==
       
  6474                  XnPropertyNames::style::common::block_progression::KBT )
       
  6475                 {
       
  6476                 if ( IsPropertyAutoL( *heightProperty ) &&
       
  6477                    ( freeHeight != node->MarginRect().Height() ) )
       
  6478                     {
       
  6479                     if ( layoutedAutoNodes.Find( node ) == KErrNotFound )
       
  6480                         {
       
  6481                         //  The height has been callculated already
       
  6482                         // and it doesn't depend on the expected
       
  6483                         //  auto size anymore, mark the node as layouted
       
  6484                         // and reduce the parent free size
       
  6485                         layoutedAutoNodes.AppendL( node );
       
  6486                         heightAutoCount--;
       
  6487                         layoutedAutoNodesAdded = ETrue;
       
  6488                         }
       
  6489                     }
       
  6490                 }
       
  6491             if ( aParentBlockProgression ==
       
  6492                  XnPropertyNames::style::common::block_progression::KLR ||
       
  6493                  aParentBlockProgression ==
       
  6494                  XnPropertyNames::style::common::block_progression::KRL )
       
  6495                 {
       
  6496                 if ( IsPropertyAutoL( *widthProperty ) &&
       
  6497                    ( freeWidth != node->MarginRect().Width() ) )
       
  6498                     {
       
  6499                     if ( layoutedAutoNodes.Find ( node ) == KErrNotFound )
       
  6500                         {
       
  6501                         //  The width has been callculated already
       
  6502                         // and it doesn't depend on the expected
       
  6503                         // auto size anymore, mark the node as layouted
       
  6504                         // and reduce the parent free size
       
  6505                         layoutedAutoNodes.AppendL( node );
       
  6506                         widthAutoCount--;
       
  6507                         layoutedAutoNodesAdded = ETrue;
       
  6508                         }
       
  6509                     }
       
  6510                 }
       
  6511             }
       
  6512 
       
  6513         // drop areas if children don't fit
       
  6514         FitAutoChildrenIntoParentL( *aAutoNodeArray, layoutedAutoNodes,
       
  6515             *parent, aParentBlockProgression, aParentDirection,
       
  6516             aGraphicsDevice );
       
  6517 
       
  6518         //  if something was dropped, reset the layouted auto nodes array
       
  6519         TInt newDisplayedChildCount = DisplayedChildrenCountL( aParent );
       
  6520 
       
  6521         if ( displayedChildCount != newDisplayedChildCount )
       
  6522             {
       
  6523             // if nodes with auto values are dropped
       
  6524             // recalculate the auto counts
       
  6525             CalculateAutoPropertiesOfNodesL( aAutoNodeArray,
       
  6526                 originalWidthAutoCount, originalHeightAutoCount );
       
  6527 
       
  6528             //  recalculate everything again because something was dropped
       
  6529             layoutedAutoNodes.Reset();
       
  6530             displayedChildCount = newDisplayedChildCount;
       
  6531             heightAutoCount = originalHeightAutoCount;
       
  6532             widthAutoCount = originalWidthAutoCount;
       
  6533             layoutedAutoNodesAdded = ETrue;
       
  6534             }
       
  6535 
       
  6536         } 
       
  6537     while( layoutedAutoNodesAdded && ( ( heightAutoCount && layoutingHeight ) ||
       
  6538          ( widthAutoCount && layoutingWidth ) ) );
       
  6539 
       
  6540     MoveAutoAreaL( parentRect, children, aParentBlockProgression,
       
  6541         aParentDirection );
       
  6542 
       
  6543     CleanupStack::PopAndDestroy( &layoutedAutoNodes );
       
  6544     }
       
  6545 
       
  6546 // -----------------------------------------------------------------------------
       
  6547 // CalculateCollapseMarginsL()
       
  6548 // Return the amount the margins should be collapsed in two list. The list
       
  6549 // element contains the amount of margins collapsed in pixels to the previous
       
  6550 // layoutable, nondropped, static and nontooltip node.
       
  6551 // When calculating the movement of the node, this value should be decreased
       
  6552 // from the movement.
       
  6553 // When calculating the total size of the auto proerety nodes, this value
       
  6554 // should be decreased from the size taken.
       
  6555 // If the children list contains one of the above mentioned type of nodes,
       
  6556 // then the value for those are always 0.
       
  6557 // For example, if there are three children and the middle one has been
       
  6558 // dropped, the the returned list contains two elemnts, first is 0 and
       
  6559 // the second one is the amount of collapsed margins between the first and the
       
  6560 // last node.
       
  6561 // The caller is responsible of releasing the returned arrays.
       
  6562 // -----------------------------------------------------------------------------
       
  6563 //
       
  6564 static void CalculateCollapseMarginsL( RPointerArray< CXnNode >& aChildren,
       
  6565     RArray< TInt >& aCollapsedMarginsWidth,
       
  6566     RArray< TInt >& aCollapsedMarginsHeight,
       
  6567     const TDesC8& aParentBlockProgression,
       
  6568     const TDesC8& aParentDirection )
       
  6569     {
       
  6570     aCollapsedMarginsWidth.Reset();
       
  6571     aCollapsedMarginsHeight.Reset();
       
  6572 
       
  6573     //  Find first node which needs to be taken into account
       
  6574     CXnNode* previousNode = NULL;
       
  6575     TInt startIndex = aChildren.Count();
       
  6576     for ( TInt i = 0; !previousNode && i < aChildren.Count(); i++ )
       
  6577         {
       
  6578         if ( IsNodeDisplayedL( *aChildren[i] ) &&
       
  6579              !aChildren[i]->IsDropped() &&
       
  6580              !IsAbsoluteL(*aChildren[i]) &&
       
  6581              !IsNodeTooltip(*aChildren[i]) &&
       
  6582              aChildren[i]->IsLayoutCapable())
       
  6583             {
       
  6584             previousNode = aChildren[i];
       
  6585             startIndex = aChildren.Find( previousNode ) + 1;
       
  6586             }
       
  6587         }
       
  6588 
       
  6589     //  Add needed amount of collapsed margins as 0
       
  6590     for ( TInt i = 1; i < startIndex; i++ )
       
  6591         {
       
  6592         User::LeaveIfError( aCollapsedMarginsWidth.Append( 0 ) );
       
  6593         User::LeaveIfError( aCollapsedMarginsHeight.Append( 0 ) );
       
  6594         }
       
  6595 
       
  6596     //  Calculate collapsed for the rest of the nodes, 0 if not needed
       
  6597     for ( TInt i = startIndex; i < aChildren.Count() && previousNode; i++ )
       
  6598         {
       
  6599         CXnNode* node = aChildren[i];
       
  6600         TInt collapsedWidth = 0;
       
  6601         TInt collapsedHeight = 0;
       
  6602 
       
  6603         if ( IsNodeDisplayedL( *node ) && 
       
  6604              !node->IsDropped() &&
       
  6605              !IsAbsoluteL( *node ) &&
       
  6606              !IsNodeTooltip( *node ) &&
       
  6607              node->IsLayoutCapable() )
       
  6608             {
       
  6609             if ( ( aParentBlockProgression ==
       
  6610                    XnPropertyNames::style::common::block_progression::KLR ||
       
  6611                    aParentBlockProgression ==
       
  6612                    XnPropertyNames::style::common::block_progression::KRL ) &&
       
  6613                    aParentDirection ==
       
  6614                    XnPropertyNames::style::common::direction::KLTR )
       
  6615                 {
       
  6616                 TInt previousRightMargin = Abs( previousNode->
       
  6617                     MarginRect().iBr.iX - previousNode->BorderRect().iBr.iX );
       
  6618                 TInt nodeLeftMargin = Abs( node->BorderRect().iTl.iX -
       
  6619                     node->MarginRect().iTl.iX );
       
  6620 
       
  6621                 collapsedWidth = -( previousRightMargin > nodeLeftMargin ) ?
       
  6622                     nodeLeftMargin : previousRightMargin;
       
  6623                 }
       
  6624 
       
  6625             if ( ( aParentBlockProgression ==
       
  6626                    XnPropertyNames::style::common::block_progression::KRL || 
       
  6627                    aParentBlockProgression ==
       
  6628                    XnPropertyNames::style::common::block_progression::KLR ) &&
       
  6629                    aParentDirection ==
       
  6630                    XnPropertyNames::style::common::direction::KRTL )
       
  6631                 {
       
  6632                 TInt previousLeftMargin = Abs( previousNode->
       
  6633                     MarginRect().iTl.iX - previousNode->BorderRect().iTl.iX );
       
  6634                 TInt nodeRightMargin = Abs( node->BorderRect().iBr.iX -
       
  6635                     node->MarginRect().iBr.iX );
       
  6636 
       
  6637                 collapsedWidth = ( previousLeftMargin > nodeRightMargin ) ?
       
  6638                     nodeRightMargin : previousLeftMargin;
       
  6639                 }
       
  6640 
       
  6641             if ( ( aParentBlockProgression ==
       
  6642                    XnPropertyNames::style::common::block_progression::KTB ||
       
  6643                    aParentBlockProgression ==
       
  6644                    XnPropertyNames::style::common::block_progression::KBT ) &&
       
  6645                    aParentDirection ==
       
  6646                    XnPropertyNames::style::common::direction::KLTR )
       
  6647                 {
       
  6648                 TInt previousBottomMargin = Abs( previousNode->
       
  6649                     MarginRect().iBr.iY - previousNode->BorderRect().iBr.iY );
       
  6650                 TInt nodeTopMargin = Abs( node->BorderRect().iTl.iY -
       
  6651                     node->MarginRect().iTl.iY );
       
  6652 
       
  6653                 collapsedHeight = ( previousBottomMargin > nodeTopMargin ) ?
       
  6654                     nodeTopMargin : previousBottomMargin;
       
  6655                 }
       
  6656 
       
  6657             if ( ( aParentBlockProgression ==
       
  6658                    XnPropertyNames::style::common::block_progression::KTB ||
       
  6659                    aParentBlockProgression ==
       
  6660                    XnPropertyNames::style::common::block_progression::KBT ) &&
       
  6661                    aParentDirection ==
       
  6662                    XnPropertyNames::style::common::direction::KRTL )
       
  6663                 {
       
  6664                 TInt previousTopMargin = Abs( previousNode->\
       
  6665                     MarginRect().iTl.iY - previousNode->BorderRect().iTl.iY );
       
  6666                 TInt nodeBottomMargin = Abs( node->BorderRect().iBr.iY -
       
  6667                     node->MarginRect().iBr.iY );
       
  6668 
       
  6669                 collapsedHeight = -( ( previousTopMargin > nodeBottomMargin ) ?
       
  6670                     nodeBottomMargin : previousTopMargin );
       
  6671                 }
       
  6672             }
       
  6673         User::LeaveIfError( aCollapsedMarginsWidth.Append( collapsedWidth ) );
       
  6674         User::LeaveIfError( aCollapsedMarginsHeight.Append( collapsedHeight ) );
       
  6675         previousNode = node;
       
  6676         }
       
  6677     }
       
  6678 
       
  6679 // -----------------------------------------------------------------------------
       
  6680 // CalculateSpaceUsedByAutoChildrenL()
       
  6681 // Return space used by node's children including auto nodes which have
       
  6682 // been calculated.
       
  6683 // -----------------------------------------------------------------------------
       
  6684 //
       
  6685 static TSize CalculateSpaceUsedByAutoChildrenL(
       
  6686     RPointerArray< CXnNode >& aAutoChildren,
       
  6687     RPointerArray< CXnNode >& aCalculatedAutoChildren,
       
  6688     CXnNode& aParent, const TDesC8& aParentBlockProgression,
       
  6689     const TDesC8& aParentDirection, CGraphicsDevice& /*aScreenDevice*/ )
       
  6690     {
       
  6691     TInt usedSiblingHeight( 0 );
       
  6692     TInt usedSiblingWidth( 0 );
       
  6693 
       
  6694     TSize largestSize( 0, 0 );
       
  6695 
       
  6696     //  Calculate collapsed margins
       
  6697     RArray< TInt > collapsedMarginsWidth;
       
  6698     RArray< TInt > collapsedMarginsHeight;
       
  6699 
       
  6700     CleanupClosePushL( collapsedMarginsWidth );
       
  6701     CleanupClosePushL( collapsedMarginsHeight );
       
  6702 
       
  6703     RPointerArray< CXnNode >& children( aParent.Children() );
       
  6704 
       
  6705     CalculateCollapseMarginsL( children,
       
  6706                                collapsedMarginsWidth,
       
  6707                                collapsedMarginsHeight,
       
  6708                                aParentBlockProgression,
       
  6709                                aParentDirection );
       
  6710 
       
  6711     for ( TInt i = 0; i < children.Count(); i++ )
       
  6712         {
       
  6713         CXnNode* node( children[i] );
       
  6714         if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
       
  6715              !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
       
  6716             {
       
  6717             //  Calculate how much does the node takes space,
       
  6718             //  0 is used for auto nodes which have not been calculated
       
  6719             TSize siblingSize( node->MarginRect().Size() );
       
  6720             if ( aAutoChildren.Find( node ) != KErrNotFound &&
       
  6721                  aCalculatedAutoChildren.Find( node ) == KErrNotFound )
       
  6722                 {
       
  6723                 //  Node is auto node and its values have not been fixed yet
       
  6724                 //  The node may have auto in either direction
       
  6725                 // so that must be checked
       
  6726                 if ( HasNodeVerticalAutoValuesL( *node ) )
       
  6727                     {
       
  6728                     siblingSize.iHeight = 0;
       
  6729                     }
       
  6730                 if ( HasNodeHorizontalAutoValuesL( *node ) )
       
  6731                     {
       
  6732                     siblingSize.iWidth = 0;
       
  6733                     }
       
  6734                 }
       
  6735             // Update the largets found node rect
       
  6736             if ( siblingSize.iWidth > largestSize.iWidth )
       
  6737                 {
       
  6738                 largestSize.iWidth = siblingSize.iWidth;
       
  6739                 }
       
  6740             if ( siblingSize.iHeight > largestSize.iHeight )
       
  6741                 {
       
  6742                 largestSize.iHeight = siblingSize.iHeight;
       
  6743                 }
       
  6744             //  Add the used area
       
  6745             if ( aParentBlockProgression ==
       
  6746                  XnPropertyNames::style::common::block_progression::KTB ||
       
  6747                  aParentBlockProgression ==
       
  6748                  XnPropertyNames::style::common::block_progression::KBT )
       
  6749                 {
       
  6750                 usedSiblingHeight += siblingSize.iHeight;
       
  6751                 usedSiblingWidth = largestSize.iWidth;
       
  6752                 }
       
  6753             if ( aParentBlockProgression ==
       
  6754                  XnPropertyNames::style::common::block_progression::KLR ||
       
  6755                  aParentBlockProgression ==
       
  6756                  XnPropertyNames::style::common::block_progression::KRL )
       
  6757                 {
       
  6758                 usedSiblingWidth += siblingSize.iWidth;
       
  6759                 usedSiblingHeight = largestSize.iHeight;
       
  6760                 }
       
  6761             //  Find the children index from all children
       
  6762             TInt childrenIndex( children.Find( node ) );
       
  6763             //  No collapsing for just one node
       
  6764             if ( childrenIndex > 0 )
       
  6765                 {
       
  6766                 //  Take the collapsed margins into account
       
  6767                 // (the value is 0 if not collapsed)
       
  6768                 usedSiblingWidth -= collapsedMarginsWidth[childrenIndex - 1];
       
  6769                 usedSiblingHeight -= collapsedMarginsHeight[childrenIndex - 1];
       
  6770                 }
       
  6771             }
       
  6772         }
       
  6773     //  Collapsed arrays
       
  6774     CleanupStack::PopAndDestroy( 2 );
       
  6775 
       
  6776     return TSize( usedSiblingWidth, usedSiblingHeight );
       
  6777     }
       
  6778 
       
  6779 // -----------------------------------------------------------------------------
       
  6780 // MoveAutoAreaL()
       
  6781 // Move nodes after all auto properties have been handled.
       
  6782 // -----------------------------------------------------------------------------
       
  6783 //
       
  6784 static void MoveAutoAreaL( TRect& parentRect,
       
  6785     RPointerArray< CXnNode >& aChildren, const TDesC8& aParentBlockProgression,
       
  6786     const TDesC8& aParentDirection )
       
  6787     {
       
  6788     //  Calculate collapsed margins
       
  6789     RArray< TInt > collapsedMarginsWidth;
       
  6790     RArray< TInt > collapsedMarginsHeight;
       
  6791 
       
  6792     CleanupClosePushL( collapsedMarginsWidth );
       
  6793     CleanupClosePushL( collapsedMarginsHeight );
       
  6794 
       
  6795     CalculateCollapseMarginsL( aChildren, collapsedMarginsWidth,
       
  6796         collapsedMarginsHeight, aParentBlockProgression,
       
  6797         aParentDirection );
       
  6798 
       
  6799     CXnNode* previousNode( NULL );
       
  6800     TInt startIndex( aChildren.Count() );
       
  6801 
       
  6802     for ( TInt i = 0; !previousNode && i < aChildren.Count(); i++ )
       
  6803         {
       
  6804         CXnNode* node( aChildren[i] );
       
  6805         if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
       
  6806              !IsAbsoluteL (*node ) && !IsNodeTooltip( *node ) )
       
  6807             {
       
  6808             previousNode = node;
       
  6809             startIndex = i + 1;
       
  6810             }
       
  6811         }
       
  6812     if ( !previousNode )
       
  6813         {
       
  6814         //  Collapsed arrays
       
  6815         CleanupStack::PopAndDestroy( 2 );
       
  6816         return;
       
  6817         }
       
  6818 
       
  6819     //  Which way are the boxes layouted?
       
  6820     //
       
  6821     //  1) ltr, tb:  2) ltr, bt:  3) ltr, rl:  4) ltr, lr:
       
  6822     //     1 4          3 6          1 2 3        4 5 6
       
  6823     //     2 5          2 5          4 5 6        1 2 3
       
  6824     //     3 6          1 4
       
  6825     //
       
  6826     //  5) rtl, tb:  6) rtl, bt:  7) rtl, rl:  8) rtl, lr:
       
  6827     //     4 1          6 3          3 2 1        6 5 4
       
  6828     //     5 2          5 2          6 5 4        3 2 1
       
  6829     //     6 3          4 1
       
  6830     //
       
  6831 
       
  6832     TInt layoutType( 0 );
       
  6833     if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
       
  6834         {
       
  6835         if ( aParentBlockProgression ==
       
  6836              XnPropertyNames::style::common::block_progression::KTB )
       
  6837             {
       
  6838             layoutType = 1;
       
  6839             }
       
  6840         else if ( aParentBlockProgression ==
       
  6841                   XnPropertyNames::style::common::block_progression::KBT )
       
  6842             {
       
  6843             layoutType = 2;
       
  6844             }
       
  6845         else if ( aParentBlockProgression ==
       
  6846                   XnPropertyNames::style::common::block_progression::KRL )
       
  6847             {
       
  6848             layoutType = 3;
       
  6849             }
       
  6850         else if ( aParentBlockProgression ==
       
  6851                   XnPropertyNames::style::common::block_progression::KLR )
       
  6852             {
       
  6853             layoutType = 4;
       
  6854             }
       
  6855         }
       
  6856     else if ( aParentDirection ==
       
  6857               XnPropertyNames::style::common::direction::KRTL )
       
  6858         {
       
  6859         if ( aParentBlockProgression ==
       
  6860              XnPropertyNames::style::common::block_progression::KTB )
       
  6861             {
       
  6862             layoutType = 5;
       
  6863             }
       
  6864         else if ( aParentBlockProgression ==
       
  6865                   XnPropertyNames::style::common::block_progression::KBT )
       
  6866             {
       
  6867             layoutType = 6;
       
  6868             }
       
  6869         else if ( aParentBlockProgression ==
       
  6870                   XnPropertyNames::style::common::block_progression::KRL )
       
  6871             {
       
  6872             layoutType = 7;
       
  6873             }
       
  6874         else if ( aParentBlockProgression ==
       
  6875                   XnPropertyNames::style::common::block_progression::KLR )
       
  6876             {
       
  6877             layoutType = 8;
       
  6878             }
       
  6879         }
       
  6880     TRect previousContentRect( previousNode->Rect() );
       
  6881     TRect previousPaddingRect( previousNode->PaddingRect() );
       
  6882     TRect previousBorderRect( previousNode->BorderRect() );
       
  6883     TRect previousMarginRect( previousNode->MarginRect() );
       
  6884     TRect previousNormalFlowBorderRect( previousNode->NormalFlowBorderRect() );
       
  6885     TInt widthToMove = 0;
       
  6886     TInt heightToMove = 0;
       
  6887 
       
  6888     //  Move the first node to the correct place
       
  6889     switch ( layoutType )
       
  6890         {
       
  6891         case 1:
       
  6892             {
       
  6893             //  Top to parent top
       
  6894             heightToMove = parentRect.iTl.iY - previousMarginRect.iTl.iY;
       
  6895             }
       
  6896             break;
       
  6897         case 2:
       
  6898             {
       
  6899             //  Bottom to parent bottom
       
  6900             heightToMove = parentRect.iBr.iY - previousMarginRect.iBr.iY;
       
  6901             }
       
  6902             break;
       
  6903         case 3:
       
  6904             {
       
  6905             //  Left to parent left
       
  6906             widthToMove = parentRect.iTl.iX - previousMarginRect.iTl.iX;
       
  6907             }
       
  6908             break;
       
  6909         case 4:
       
  6910             {
       
  6911             heightToMove = parentRect.iBr.iY - previousMarginRect.iBr.iY;
       
  6912             widthToMove = parentRect.iTl.iX - previousMarginRect.iTl.iX;
       
  6913             }
       
  6914             break;
       
  6915         case 5: // flow through
       
  6916         case 7:
       
  6917             {
       
  6918             heightToMove = parentRect.iTl.iY - previousMarginRect.iTl.iY;
       
  6919             widthToMove = parentRect.iBr.iX - previousMarginRect.iBr.iX;
       
  6920             }
       
  6921             break;
       
  6922         case 6: // flow through
       
  6923         case 8:
       
  6924             {
       
  6925             heightToMove = parentRect.iBr.iY - previousMarginRect.iBr.iY;
       
  6926             widthToMove = parentRect.iBr.iX - previousMarginRect.iBr.iX;
       
  6927             }
       
  6928             break;
       
  6929         }
       
  6930 
       
  6931     //  Move rects
       
  6932     previousContentRect.Move( widthToMove, heightToMove );
       
  6933     previousPaddingRect.Move( widthToMove, heightToMove );
       
  6934     previousBorderRect.Move( widthToMove, heightToMove );
       
  6935     previousMarginRect.Move( widthToMove, heightToMove );
       
  6936     previousNormalFlowBorderRect.Move( widthToMove, heightToMove );
       
  6937 
       
  6938     //  Set rects
       
  6939     previousNode->SetRect( previousContentRect );
       
  6940     previousNode->SetPaddingRect( previousPaddingRect );
       
  6941     previousNode->SetBorderRect( previousBorderRect );
       
  6942     previousNode->SetMarginRect( previousMarginRect );
       
  6943     previousNode->SetNormalFlowBorderRect( previousNormalFlowBorderRect );
       
  6944 
       
  6945     for ( TInt i = startIndex; i < aChildren.Count() && previousNode; i++ )
       
  6946         {
       
  6947         CXnNode* node( aChildren[i] );
       
  6948 
       
  6949         if ( IsNodeDisplayedL( *node ) && !node->IsDropped() &&
       
  6950              !IsAbsoluteL( *node ) && !IsNodeTooltip( *node ) )
       
  6951             {
       
  6952             //  Get rects
       
  6953             TRect contentRect( node->Rect() );
       
  6954             TRect paddingRect( node->PaddingRect() );
       
  6955             TRect borderRect( node->BorderRect() );
       
  6956             TRect marginRect( node->MarginRect() );
       
  6957             TRect normalFlowBorderRect( node->NormalFlowBorderRect() );
       
  6958             previousMarginRect = previousNode->MarginRect();
       
  6959 
       
  6960             widthToMove = 0;
       
  6961             heightToMove = 0;
       
  6962 
       
  6963             //  Count movements
       
  6964             switch ( layoutType )
       
  6965                 {
       
  6966                 case 1:
       
  6967                     {
       
  6968                     //  Move node top to the previous bottom
       
  6969                     heightToMove = previousMarginRect.iBr.iY - marginRect.iTl.iY;
       
  6970                     heightToMove -= collapsedMarginsHeight[i - 1];
       
  6971                     }
       
  6972                     break;
       
  6973                 case 2:
       
  6974                     {
       
  6975                     //  Move node bottom to the previous top
       
  6976                     heightToMove = previousMarginRect.iTl.iY - marginRect.iBr.iY;
       
  6977                     heightToMove += collapsedMarginsHeight[i - 1];
       
  6978                     }
       
  6979                     break;
       
  6980                 case 3:
       
  6981                     {
       
  6982                     //  Move node left to the previous right
       
  6983                     widthToMove = previousMarginRect.iBr.iX - marginRect.iTl.iX;
       
  6984                     widthToMove -= collapsedMarginsWidth[i - 1];
       
  6985                     }
       
  6986                     break;
       
  6987                 case 4:
       
  6988                     {
       
  6989                     heightToMove = previousMarginRect.iTl.iY - marginRect.iTl.iY;
       
  6990                     widthToMove = previousMarginRect.iBr.iX - marginRect.iTl.iX;
       
  6991                     widthToMove -= collapsedMarginsWidth[i - 1];
       
  6992                     }
       
  6993                     break;
       
  6994                 case 5:
       
  6995                     {
       
  6996                     //  Move node top to the previous bottom
       
  6997                     heightToMove = previousMarginRect.iBr.iY - marginRect.iTl.iY;
       
  6998                     heightToMove -= collapsedMarginsHeight[i - 1];
       
  6999                     widthToMove = previousMarginRect.iTl.iX - marginRect.iTl.iX;
       
  7000                     }
       
  7001                     break;
       
  7002                 case 6:
       
  7003                     {
       
  7004                     //  Move node bottom to the previous top
       
  7005                     heightToMove = previousMarginRect.iTl.iY - marginRect.iBr.iY;
       
  7006                     heightToMove += collapsedMarginsHeight[i - 1];
       
  7007                     widthToMove = previousMarginRect.iTl.iX - marginRect.iTl.iX;
       
  7008                     }
       
  7009                     break;
       
  7010                 case 7:
       
  7011                     {
       
  7012                     //  Move node left to the previous right
       
  7013                     widthToMove = previousMarginRect.iTl.iX - marginRect.iBr.iX;
       
  7014                     widthToMove += collapsedMarginsWidth[i - 1];
       
  7015                     }
       
  7016                     break;
       
  7017                 case 8:
       
  7018                     {
       
  7019                     heightToMove = previousMarginRect.iTl.iY - marginRect.iTl.iY;
       
  7020                     widthToMove = previousMarginRect.iTl.iX - marginRect.iBr.iX;
       
  7021                     widthToMove += collapsedMarginsWidth[i - 1];
       
  7022                     }
       
  7023                     break;
       
  7024                 }
       
  7025 
       
  7026             //  Move rects
       
  7027             contentRect.Move( widthToMove, heightToMove );
       
  7028             paddingRect.Move( widthToMove, heightToMove );
       
  7029             borderRect.Move( widthToMove, heightToMove );
       
  7030             marginRect.Move( widthToMove, heightToMove );
       
  7031             normalFlowBorderRect.Move( widthToMove, heightToMove );
       
  7032 
       
  7033             //  Set rects
       
  7034             node->SetRect( contentRect );
       
  7035             node->SetPaddingRect( paddingRect );
       
  7036             node->SetBorderRect( borderRect );
       
  7037             node->SetMarginRect( marginRect );
       
  7038             node->SetNormalFlowBorderRect( normalFlowBorderRect );
       
  7039 
       
  7040             previousNode = node;
       
  7041             }
       
  7042         }
       
  7043 
       
  7044     //  Collapsed arrays
       
  7045     CleanupStack::PopAndDestroy( 2 );
       
  7046     }
       
  7047 
       
  7048 // -----------------------------------------------------------------------------
       
  7049 // ScaleAutoAreaL()
       
  7050 // Scale dimensions for areas that have properties set to AUTO.
       
  7051 // -----------------------------------------------------------------------------
       
  7052 //
       
  7053 static TSize ScaleAutoAreaL( CXnNode& aNode, TInt aWidthToFit,
       
  7054     TInt aHeightToFit, const TDesC8& aParentBlockProgression,
       
  7055     const TDesC8& aParentDirection, TRect& aParentRect,
       
  7056     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  7057     TReal aVerticalUnitInPixels )
       
  7058     {
       
  7059     // if only one value is auto, it is computed from equality
       
  7060     // if width is set to AUTO, all other values become 0
       
  7061     // if both margin left and right are set to AUTO, their computed
       
  7062     // values are equal
       
  7063     TSize sizeOfAutoArea( 0, 0 );
       
  7064 
       
  7065     RArray< TPtrC8 > autoArray;
       
  7066     CleanupClosePushL( autoArray );
       
  7067 
       
  7068     CXnProperty* top = aNode.TopL();
       
  7069     if ( IsPropertyAutoL( *top ) )
       
  7070         {
       
  7071         TPtrC8 propertyName = top->Property()->Name();
       
  7072         autoArray.Append( propertyName );
       
  7073         }
       
  7074     CXnProperty* bottom = aNode.BottomL();
       
  7075     if ( IsPropertyAutoL( *bottom ) )
       
  7076         {
       
  7077         TPtrC8 propertyName = bottom->Property()->Name();
       
  7078         autoArray.Append( propertyName );
       
  7079         }
       
  7080     CXnProperty* left = aNode.LeftL();
       
  7081     if ( IsPropertyAutoL( *left ) )
       
  7082         {
       
  7083         TPtrC8 propertyName = left->Property()->Name();
       
  7084         autoArray.Append( propertyName );
       
  7085         }
       
  7086     CXnProperty* right = aNode.RightL();
       
  7087     if ( IsPropertyAutoL( *right ) )
       
  7088         {
       
  7089         TPtrC8 propertyName = right->Property()->Name();
       
  7090         autoArray.Append( propertyName );
       
  7091         }
       
  7092     CXnProperty* width = aNode.WidthL();
       
  7093     if ( IsPropertyAutoL( *width ) )
       
  7094         {
       
  7095         TPtrC8 propertyName = width->Property()->Name();
       
  7096         autoArray.Append( propertyName );
       
  7097         }
       
  7098     if ( !width )
       
  7099         {
       
  7100         TPtrC8 propertyName = XnPropertyNames::style::common::KWidth();
       
  7101         autoArray.Append( propertyName );
       
  7102         }
       
  7103     CXnProperty* height = aNode.HeightL();
       
  7104     if ( IsPropertyAutoL( *height ) )
       
  7105         {
       
  7106         TPtrC8 propertyName = height->Property()->Name();
       
  7107         autoArray.Append( propertyName );
       
  7108         }
       
  7109     if ( !height )
       
  7110         {
       
  7111         TPtrC8 propertyName = XnPropertyNames::style::common::KHeight();
       
  7112         autoArray.Append( propertyName );
       
  7113         }
       
  7114     CXnProperty* marginTop = aNode.MarginTopL();
       
  7115     if ( IsPropertyAutoL( *marginTop ) )
       
  7116         {
       
  7117         TPtrC8 propertyName = marginTop->Property()->Name();
       
  7118         autoArray.Append( propertyName );
       
  7119         }
       
  7120     CXnProperty* marginBottom = aNode.MarginBottomL();
       
  7121     if ( IsPropertyAutoL( *marginBottom ) )
       
  7122         {
       
  7123         TPtrC8 propertyName = marginBottom->Property()->Name();
       
  7124         autoArray.Append( propertyName );
       
  7125         }
       
  7126     CXnProperty* marginLeft = aNode.MarginLeftL();
       
  7127     if ( IsPropertyAutoL( *marginLeft ) )
       
  7128         {
       
  7129         TPtrC8 propertyName = marginLeft->Property()->Name();
       
  7130         autoArray.Append( propertyName );
       
  7131         }
       
  7132     CXnProperty* marginRight = aNode.MarginRightL();
       
  7133     if ( IsPropertyAutoL( *marginRight ) )
       
  7134         {
       
  7135         TPtrC8 propertyName = marginRight->Property()->Name();
       
  7136         autoArray.Append( propertyName );
       
  7137         }
       
  7138 
       
  7139     if ( aParentDirection == XnPropertyNames::style::common::direction::KLTR )
       
  7140         {
       
  7141         if ( aParentBlockProgression ==
       
  7142              XnPropertyNames::style::common::block_progression::KTB ||
       
  7143              aParentBlockProgression ==
       
  7144              XnPropertyNames::style::common::block_progression::KBT )
       
  7145             {
       
  7146             sizeOfAutoArea = TSize( AutoStaticTBL( aNode, aWidthToFit,
       
  7147                 aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
       
  7148                 aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
       
  7149             }
       
  7150         else // block progression LR
       
  7151             {
       
  7152             sizeOfAutoArea = TSize( AutoStaticLRL( aNode, aWidthToFit,
       
  7153                 aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
       
  7154                 aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
       
  7155             }
       
  7156         }
       
  7157     else // direction RTL
       
  7158         {
       
  7159         if ( aParentBlockProgression ==
       
  7160              XnPropertyNames::style::common::block_progression::KTB ||
       
  7161              aParentBlockProgression ==
       
  7162              XnPropertyNames::style::common::block_progression::KBT )
       
  7163             {
       
  7164             sizeOfAutoArea = TSize( AutoStaticBTL( aNode, aWidthToFit,
       
  7165                 aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
       
  7166                 aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
       
  7167             }
       
  7168         else // block progression RL
       
  7169             {
       
  7170             sizeOfAutoArea = TSize( AutoStaticRLL( aNode, aWidthToFit,
       
  7171                 aHeightToFit, autoArray, aParentRect, aGraphicsDevice,
       
  7172                 aHorizontalUnitInPixels, aVerticalUnitInPixels ) );
       
  7173             }
       
  7174         }
       
  7175 
       
  7176     // if size not within min&max size limits, resize
       
  7177     // (min-size)
       
  7178     if ( HasNodeMinSizesL( aNode ) )
       
  7179         {
       
  7180         if ( IsSmallerThanMinSizeL( aParentRect, aNode, aGraphicsDevice,
       
  7181              aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
       
  7182             {
       
  7183             GrowToMinSizeL( aNode, aParentRect, aGraphicsDevice,
       
  7184                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  7185             }
       
  7186         }
       
  7187 
       
  7188      if ( HasNodeMaxSizesL( aNode ) )
       
  7189         {
       
  7190         if ( IsLargerThanMaxSizeL( aParentRect, aNode, aGraphicsDevice,
       
  7191              aHorizontalUnitInPixels, aVerticalUnitInPixels ) )
       
  7192             {
       
  7193             ShrinkToMaxSizeL( aNode, aParentRect, aGraphicsDevice,
       
  7194                 aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  7195             }
       
  7196         }
       
  7197 
       
  7198     CleanupStack::PopAndDestroy( &autoArray );
       
  7199 
       
  7200     //  Return the context rect size because the min-max
       
  7201     // test might have changed the size of autoarea
       
  7202     return aNode.Rect().Size();
       
  7203     }
       
  7204 
       
  7205 // -----------------------------------------------------------------------------
       
  7206 // GrowToMinSizeL()
       
  7207 //
       
  7208 // -----------------------------------------------------------------------------
       
  7209 //
       
  7210 static void GrowToMinSizeL( CXnNode& aNode, TRect& aParentRect,
       
  7211     CGraphicsDevice& aScreenDevice,
       
  7212     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
       
  7213     {
       
  7214     // grow to min size
       
  7215     CXnProperty* minWidthProperty = aNode.MinWidthL();
       
  7216     CXnProperty* minHeightProperty = aNode.MinHeightL();
       
  7217 
       
  7218     TRect contentRect( aNode.Rect() );
       
  7219     TRect paddingRect( aNode.PaddingRect() );
       
  7220     TRect borderRect( aNode.BorderRect() );
       
  7221     TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
  7222     TRect marginRect( aNode.MarginRect() );
       
  7223 
       
  7224     if ( minWidthProperty )
       
  7225         {
       
  7226         if ( !IsPropertyNone( *minWidthProperty ) )
       
  7227             {
       
  7228             TInt minWidth = HorizontalPixelValueL( minWidthProperty,
       
  7229                 aParentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
       
  7230             if ( contentRect.Width() < minWidth )
       
  7231                 {
       
  7232                 TInt widthToGrow = minWidth - contentRect.Width();
       
  7233                 contentRect.Resize( widthToGrow, 0 );
       
  7234                 paddingRect.Resize( widthToGrow, 0 );
       
  7235                 borderRect.Resize( widthToGrow, 0 );
       
  7236                 normalFlowBorderRect.Resize( widthToGrow, 0 );
       
  7237                 marginRect.Resize( widthToGrow, 0 );
       
  7238                 }
       
  7239             }
       
  7240         }
       
  7241 
       
  7242     if ( minHeightProperty )
       
  7243         {
       
  7244         if ( !IsPropertyNone( *minHeightProperty ) )
       
  7245             {
       
  7246             TInt minHeight = VerticalPixelValueL( minHeightProperty,
       
  7247                 aParentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
       
  7248             if ( contentRect.Height() < minHeight )
       
  7249                 {
       
  7250                 TInt heightToGrow = minHeight - contentRect.Height();
       
  7251                 contentRect.Resize( 0, heightToGrow );
       
  7252                 paddingRect.Resize( 0, heightToGrow );
       
  7253                 borderRect.Resize( 0, heightToGrow );
       
  7254                 normalFlowBorderRect.Resize( 0, heightToGrow );
       
  7255                 marginRect.Resize( 0, heightToGrow );
       
  7256                 }
       
  7257             }
       
  7258         }
       
  7259 
       
  7260     aNode.SetRect( contentRect );
       
  7261     aNode.SetPaddingRect( paddingRect );
       
  7262     aNode.SetBorderRect( borderRect );
       
  7263     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  7264     aNode.SetMarginRect( marginRect );
       
  7265     }
       
  7266 
       
  7267 // -----------------------------------------------------------------------------
       
  7268 // ShrinkToMaxSizeL()
       
  7269 // -----------------------------------------------------------------------------
       
  7270 //
       
  7271 static void ShrinkToMaxSizeL( CXnNode& aNode, TRect& aParentRect,
       
  7272     CGraphicsDevice& aScreenDevice,
       
  7273     TReal aHorizontalUnitInPixels, TReal aVerticalUnitInPixels )
       
  7274     {
       
  7275     // grow to min size
       
  7276     CXnProperty* maxWidthProperty = aNode.MaxWidthL();
       
  7277     CXnProperty* maxHeightProperty = aNode.MaxHeightL();
       
  7278 
       
  7279     TRect contentRect( aNode.Rect() );
       
  7280     TRect paddingRect( aNode.PaddingRect() );
       
  7281     TRect borderRect( aNode.BorderRect() );
       
  7282     TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
  7283     TRect marginRect( aNode.MarginRect() );
       
  7284 
       
  7285     if ( maxWidthProperty )
       
  7286         {
       
  7287         if ( !IsPropertyNone( *maxWidthProperty ) )
       
  7288             {
       
  7289             TInt maxWidth = HorizontalPixelValueL( maxWidthProperty,
       
  7290                 aParentRect.Width(), aScreenDevice, aHorizontalUnitInPixels );
       
  7291             if ( contentRect.Width() > maxWidth )
       
  7292                 {
       
  7293                 TInt widthToShrink = contentRect.Width() - maxWidth;
       
  7294                 contentRect.Resize( -widthToShrink, 0 );
       
  7295                 paddingRect.Resize( -widthToShrink, 0 );
       
  7296                 borderRect.Resize( -widthToShrink, 0 );
       
  7297                 normalFlowBorderRect.Resize( -widthToShrink, 0 );
       
  7298                 marginRect.Resize( -widthToShrink, 0 );
       
  7299                 }
       
  7300             }
       
  7301         }
       
  7302 
       
  7303     if ( maxHeightProperty )
       
  7304         {
       
  7305         if ( !IsPropertyNone( *maxHeightProperty ) )
       
  7306             {
       
  7307             TInt maxHeight = VerticalPixelValueL( maxHeightProperty,
       
  7308                 aParentRect.Height(), aScreenDevice, aVerticalUnitInPixels );
       
  7309             if ( contentRect.Height() > maxHeight )
       
  7310                 {
       
  7311                 TInt heightToShrink = contentRect.Height() - maxHeight;
       
  7312                 contentRect.Resize( 0, -heightToShrink );
       
  7313                 paddingRect.Resize( 0, -heightToShrink );
       
  7314                 borderRect.Resize( 0, -heightToShrink );
       
  7315                 normalFlowBorderRect.Resize( 0, -heightToShrink );
       
  7316                 marginRect.Resize( 0, -heightToShrink );
       
  7317                 }
       
  7318             }
       
  7319         }
       
  7320 
       
  7321     aNode.SetRect( contentRect );
       
  7322     aNode.SetPaddingRect( paddingRect );
       
  7323     aNode.SetBorderRect( borderRect );
       
  7324     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  7325     aNode.SetMarginRect( marginRect );
       
  7326     }
       
  7327 
       
  7328 // -----------------------------------------------------------------------------
       
  7329 // FitAutoChildrenIntoParentL()
       
  7330 //
       
  7331 // -----------------------------------------------------------------------------
       
  7332 //
       
  7333 static void FitAutoChildrenIntoParentL( RPointerArray< CXnNode >& aAutoChildren,
       
  7334     RPointerArray< CXnNode >& aCalculatedAutoChildren, CXnNode& aParent,
       
  7335     const TDesC8& aParentBlockProgression, const TDesC8& aParentDirection,
       
  7336     CGraphicsDevice& aGraphicsDevice )
       
  7337     {
       
  7338     if( IsSrollableBox( aParent ) )
       
  7339         {
       
  7340         return;
       
  7341         }
       
  7342     
       
  7343     TSize space = CalculateSpaceUsedByAutoChildrenL( aAutoChildren,
       
  7344         aCalculatedAutoChildren, aParent, aParentBlockProgression,
       
  7345         aParentDirection, aGraphicsDevice );
       
  7346 
       
  7347     TSize parentSize( aParent.Rect().Size() );
       
  7348 
       
  7349     while( ( ( parentSize.iHeight < space.iHeight ) &&
       
  7350              ( parentSize.iHeight > 0 ) ) ||
       
  7351            ( ( parentSize.iWidth < space.iWidth ) &&
       
  7352              ( parentSize.iWidth > 0 ) ) )
       
  7353         {
       
  7354         // if areas go over just one pixel, cut the pixel
       
  7355         // from a percent sized node
       
  7356         if ( ( parentSize.iHeight == space.iHeight - 1 ) ||
       
  7357              ( parentSize.iWidth == space.iWidth - 1 ) )
       
  7358             {
       
  7359             CutOnePixelFromPercentChildNodeL( aParent, aParentBlockProgression );
       
  7360             return;
       
  7361             }
       
  7362 
       
  7363         TInt childCount( DisplayedChildrenCountL( aParent ) );
       
  7364 
       
  7365         PriorizeChildrenL( aParent );
       
  7366 
       
  7367         if ( DisplayedChildrenCountL( aParent ) == childCount )
       
  7368             {
       
  7369             // cannot drop any more children, but they still don't fit
       
  7370             return;
       
  7371             }
       
  7372 
       
  7373         space = CalculateSpaceUsedByAutoChildrenL( aAutoChildren,
       
  7374             aCalculatedAutoChildren, aParent, aParentBlockProgression,
       
  7375             aParentDirection, aGraphicsDevice );
       
  7376         }
       
  7377     }
       
  7378 
       
  7379 // -----------------------------------------------------------------------------
       
  7380 // VerticalCentimetersToPixelsL()
       
  7381 // Convert vertical centimeter value to pixel value.
       
  7382 // -----------------------------------------------------------------------------
       
  7383 //
       
  7384 static TInt VerticalCentimetersToPixelsL( TReal& aCentimeters,
       
  7385     CGraphicsDevice& aScreenDevice )
       
  7386     {
       
  7387     TReal twips = aCentimeters * KCentimetersAsTwips;
       
  7388     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  7389     return aScreenDevice.VerticalTwipsToPixels( intTwips );
       
  7390     }
       
  7391 
       
  7392 // -----------------------------------------------------------------------------
       
  7393 // VerticalInchesToPixelsL()
       
  7394 // Convert vertical inch value to pixel value.
       
  7395 // -----------------------------------------------------------------------------
       
  7396 //
       
  7397 static TInt VerticalInchesToPixelsL( TReal& aInches,
       
  7398     CGraphicsDevice& aScreenDevice )
       
  7399     {
       
  7400     TReal twips = aInches * KInchesAsTwips;
       
  7401     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  7402     return aScreenDevice.VerticalTwipsToPixels( intTwips );
       
  7403     }
       
  7404 
       
  7405 // -----------------------------------------------------------------------------
       
  7406 // VerticalMillimetersToPixelsL()
       
  7407 // Convert vertical millimeter value to pixel value.
       
  7408 // -----------------------------------------------------------------------------
       
  7409 //
       
  7410 static TInt VerticalMillimetersToPixelsL( TReal& aMillimeters,
       
  7411     CGraphicsDevice& aScreenDevice )
       
  7412     {
       
  7413     TReal twips = aMillimeters * KMillimetersAsTwips;
       
  7414     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  7415     return aScreenDevice.VerticalTwipsToPixels( intTwips );
       
  7416     }
       
  7417 
       
  7418 // -----------------------------------------------------------------------------
       
  7419 // VerticalPicasToPixelsL()
       
  7420 // Convert vertical pica value to pixel value.
       
  7421 // -----------------------------------------------------------------------------
       
  7422 //
       
  7423 static TInt VerticalPicasToPixelsL( TReal& aPicas,
       
  7424     CGraphicsDevice& aScreenDevice )
       
  7425     {
       
  7426     TReal twips = aPicas * KPicasAsTwips;
       
  7427     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  7428     return aScreenDevice.VerticalTwipsToPixels( intTwips );
       
  7429     }
       
  7430 
       
  7431 // -----------------------------------------------------------------------------
       
  7432 // VerticalPixelValueL()
       
  7433 // Convert vertical property to pixel value.
       
  7434 // -----------------------------------------------------------------------------
       
  7435 //
       
  7436 static TInt VerticalPixelValueL( CXnProperty* aValue, TInt aReferenceValue,
       
  7437     CGraphicsDevice& aScreenDevice, TReal aVerticalUnitInPixels )
       
  7438     {
       
  7439     return VerticalValueToPixelsL( DomPropertyValueFromProperty( aValue ),
       
  7440         static_cast< TReal >( aReferenceValue ), aScreenDevice,
       
  7441         aVerticalUnitInPixels );
       
  7442     }
       
  7443 
       
  7444 // -----------------------------------------------------------------------------
       
  7445 // VerticalPointsToPixelsL()
       
  7446 // Convert vertical point value to pixel value.
       
  7447 // -----------------------------------------------------------------------------
       
  7448 //
       
  7449 static TInt VerticalPointsToPixelsL( TReal& aPoints,
       
  7450     CGraphicsDevice& aScreenDevice )
       
  7451     {
       
  7452     TReal twips = aPoints * KPointsAsTwips;
       
  7453     TInt intTwips = static_cast< TInt >( twips + KIntConversionConstant );
       
  7454     return aScreenDevice.VerticalTwipsToPixels( intTwips );
       
  7455     }
       
  7456 
       
  7457 // -----------------------------------------------------------------------------
       
  7458 // VerticalValueToPixelsL()
       
  7459 // Convert vertical property value to pixel value.
       
  7460 // -----------------------------------------------------------------------------
       
  7461 //
       
  7462 static TInt VerticalValueToPixelsL( CXnDomPropertyValue* aValue,
       
  7463     TReal aReferenceValue, CGraphicsDevice& aScreenDevice,
       
  7464     TReal aVerticalUnitInPixels )
       
  7465     {
       
  7466     if ( !aValue )
       
  7467         {
       
  7468         User::Leave( KXnErrDomPropertyValueNULL );
       
  7469         }
       
  7470     CXnDomPropertyValue::TPrimitiveValueType valueType =
       
  7471         aValue->PrimitiveValueType();
       
  7472     //  Handle error cases first, inherit is handled elsewhere, none returns 0
       
  7473     switch ( valueType )
       
  7474         {
       
  7475         case CXnDomPropertyValue::EUnknown:
       
  7476         case CXnDomPropertyValue::EEms:
       
  7477         case CXnDomPropertyValue::EExs:
       
  7478         case CXnDomPropertyValue::EDeg:
       
  7479         case CXnDomPropertyValue::ERad:
       
  7480         case CXnDomPropertyValue::EGrad:
       
  7481         case CXnDomPropertyValue::EMs:
       
  7482         case CXnDomPropertyValue::ES:
       
  7483         case CXnDomPropertyValue::EHz:
       
  7484         case CXnDomPropertyValue::EKHz:
       
  7485         case CXnDomPropertyValue::EDimension:
       
  7486         case CXnDomPropertyValue::EString:
       
  7487         case CXnDomPropertyValue::EUri:
       
  7488         case CXnDomPropertyValue::EIdent:
       
  7489         case CXnDomPropertyValue::EAttr:
       
  7490         case CXnDomPropertyValue::ECounter:
       
  7491         case CXnDomPropertyValue::ERect:
       
  7492         case CXnDomPropertyValue::ERgbColor:
       
  7493         case CXnDomPropertyValue::ERgbaColor:
       
  7494         case CXnDomPropertyValue::EFunction:
       
  7495             break;
       
  7496         default:
       
  7497             {
       
  7498             TReal value = aValue->FloatValueL();
       
  7499             if ( valueType == CXnDomPropertyValue::ENumber ||
       
  7500                  valueType == CXnDomPropertyValue::EPx )
       
  7501                 {
       
  7502                 return static_cast< TInt >( value );
       
  7503                 }
       
  7504             else if ( valueType == CXnDomPropertyValue::EPercentage )
       
  7505                 {
       
  7506                 return PercentageToPixelsL( value, aReferenceValue );
       
  7507                 }
       
  7508             else if ( valueType == CXnDomPropertyValue::EIn )
       
  7509                 {
       
  7510                 return VerticalInchesToPixelsL( value, aScreenDevice );
       
  7511                 }
       
  7512             else if ( valueType == CXnDomPropertyValue::ECm )
       
  7513                 {
       
  7514                 return VerticalCentimetersToPixelsL( value, aScreenDevice );
       
  7515                 }
       
  7516             else if ( valueType == CXnDomPropertyValue::EMm )
       
  7517                 {
       
  7518                 return VerticalMillimetersToPixelsL( value, aScreenDevice );
       
  7519                 }
       
  7520             else if ( valueType == CXnDomPropertyValue::EPt )
       
  7521                 {
       
  7522                 return VerticalPointsToPixelsL( value, aScreenDevice );
       
  7523                 }
       
  7524             else if ( valueType == CXnDomPropertyValue::EPc )
       
  7525                 {
       
  7526                 return VerticalPicasToPixelsL( value, aScreenDevice );
       
  7527                 }
       
  7528             else if ( valueType == CXnDomPropertyValue::EUnitValue )
       
  7529                 {
       
  7530                 return VerticalUnitsToPixelsL( value, aVerticalUnitInPixels );
       
  7531                 }
       
  7532             }
       
  7533             break;
       
  7534         }
       
  7535 
       
  7536     return 0;
       
  7537     }
       
  7538 
       
  7539 // -----------------------------------------------------------------------------
       
  7540 // ProcessAdaptiveAreasL()
       
  7541 // Process adaptive areas
       
  7542 // -----------------------------------------------------------------------------
       
  7543 //
       
  7544 static void ProcessAdaptiveAreasL( CXnNode& aParent,
       
  7545     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  7546     TReal aVerticalUnitInPixels )
       
  7547     {
       
  7548     CXnProperty* blockProgressionProperty( aParent.BlockProgressionL() );
       
  7549     CXnProperty* directionProperty( aParent.DirectionL() );
       
  7550     const TDesC8* blockProgression(
       
  7551         &XnPropertyNames::style::common::block_progression::KTB() );
       
  7552     const TDesC8* direction(
       
  7553         &XnPropertyNames::style::common::direction::KLTR() );
       
  7554 
       
  7555     if ( directionProperty )
       
  7556         {
       
  7557         direction = &directionProperty->StringValue();
       
  7558         }
       
  7559 
       
  7560     if ( blockProgressionProperty )
       
  7561         {
       
  7562         blockProgression = &blockProgressionProperty->StringValue();
       
  7563         }
       
  7564 
       
  7565     CalculateAdaptiveSizeL( aParent, *blockProgression, *direction,
       
  7566         aGraphicsDevice, aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  7567     }
       
  7568 
       
  7569 // -----------------------------------------------------------------------------
       
  7570 // CalculateAdaptiveSizeL()
       
  7571 // Fixes the adaptive node size to its layouted children size
       
  7572 // -----------------------------------------------------------------------------
       
  7573 //
       
  7574 static void CalculateAdaptiveSizeL( CXnNode& aNode,
       
  7575     const TDesC8& aParentBlockProgression, const TDesC8& /*aParentDirection*/,
       
  7576     CGraphicsDevice& aGraphicsDevice, TReal aHorizontalUnitInPixels,
       
  7577     TReal aVerticalUnitInPixels )
       
  7578     {
       
  7579     TInt adaptive( aNode.IsAdaptive() );
       
  7580     CXnNode* parent( aNode.Parent() );
       
  7581 
       
  7582     if ( !adaptive || !parent )
       
  7583         {
       
  7584         return;
       
  7585         }
       
  7586 
       
  7587     TInt adaptiveHeight( 0 );
       
  7588     TInt adaptiveWidth( 0 );
       
  7589 
       
  7590     RPointerArray< CXnNode > children;
       
  7591     CleanupClosePushL( children );
       
  7592 
       
  7593     TInt count( DisplayedChildrenCountL( aNode, &children ) );
       
  7594 
       
  7595     TSize size;
       
  7596 
       
  7597     if ( count == 0 )
       
  7598         {
       
  7599         TRect parentRect( parent->Rect() );
       
  7600         if( parent->Control() && parent->Control()->OwnsWindow() )
       
  7601             {
       
  7602             parentRect = TRect( parentRect.iTl - parent->MarginRect().iTl, parentRect.Size() );
       
  7603             }
       
  7604         // I don't have any displayed childrens, fix my own size
       
  7605         size = CalculateTotalDimensionsL( aNode, ETrue, EFalse,
       
  7606             parentRect, aGraphicsDevice, aHorizontalUnitInPixels,
       
  7607             aVerticalUnitInPixels );
       
  7608         adaptiveHeight = size.iHeight;
       
  7609         adaptiveWidth = size.iWidth;
       
  7610         }
       
  7611     else
       
  7612         {
       
  7613         TBool autoHeight( EFalse );
       
  7614         TBool autoWidth( EFalse );
       
  7615         TBool sizeKnown( EFalse );
       
  7616         for ( TInt i = 0; i < children.Count(); i++ )
       
  7617             {
       
  7618             CXnNode* node( children[i] );
       
  7619             if ( !IsNodeDisplayedL( *node ) )
       
  7620                 {
       
  7621                 continue;
       
  7622                 }
       
  7623             CXnProperty* heightProperty( node->HeightL() );
       
  7624             if ( !( node->IsAdaptive() & XnAdaptive::EHeight ) &&
       
  7625                   ( adaptive & XnAdaptive::EHeight ) &&
       
  7626                     IsPropertyAutoL( *heightProperty ) )
       
  7627                 {
       
  7628                 adaptiveHeight = node->MarginRect().Size().iHeight;
       
  7629                 autoHeight = ETrue;
       
  7630                 if ( !( adaptive & XnAdaptive::EWidth ) )
       
  7631                     {
       
  7632                     // Height is now known and width is not adaptive
       
  7633                     // -> size is now known
       
  7634                     sizeKnown = ETrue;
       
  7635                     }
       
  7636                 }
       
  7637             CXnProperty* widthProperty( node->WidthL() );
       
  7638             if ( !( node->IsAdaptive() & XnAdaptive::EWidth ) &&
       
  7639                   ( adaptive & XnAdaptive::EWidth ) &&
       
  7640                     IsPropertyAutoL( *widthProperty ) )
       
  7641                 {
       
  7642                 adaptiveWidth = node->MarginRect().Size().iWidth;
       
  7643                 autoWidth = ETrue;
       
  7644                 if ( !( adaptive & XnAdaptive::EHeight ) )
       
  7645                     {
       
  7646                     // Width is now known and height is not adaptive
       
  7647                     // -> size is now known
       
  7648                     sizeKnown = ETrue;
       
  7649                     }
       
  7650                 }
       
  7651             if ( autoWidth && autoHeight )
       
  7652                 {
       
  7653                 // Both auto -> size is now known
       
  7654                 sizeKnown = ETrue;
       
  7655                 }
       
  7656             if ( !sizeKnown )
       
  7657                 {
       
  7658                 // Fix adaptive sized child's size first
       
  7659                 ProcessAdaptiveAreasL( *node, aGraphicsDevice,
       
  7660                     aHorizontalUnitInPixels, aVerticalUnitInPixels );
       
  7661                 TSize marginSize( node->MarginRect().Size() );
       
  7662                 if ( aParentBlockProgression ==
       
  7663                      XnPropertyNames::style::common::block_progression::KTB ||
       
  7664                      aParentBlockProgression ==
       
  7665                      XnPropertyNames::style::common::block_progression::KBT )
       
  7666                     {
       
  7667                     if ( !autoHeight && ( adaptive & XnAdaptive::EHeight ) )
       
  7668                         {
       
  7669                         adaptiveHeight += marginSize.iHeight;
       
  7670                         }
       
  7671                     if ( !autoWidth && ( adaptive & XnAdaptive::EWidth ) )
       
  7672                         {
       
  7673                         if ( marginSize.iWidth > adaptiveWidth )
       
  7674                             {
       
  7675                             adaptiveWidth = marginSize.iWidth;
       
  7676                             }
       
  7677                         }
       
  7678                     }
       
  7679                 else if ( aParentBlockProgression ==
       
  7680                           XnPropertyNames::style::common::
       
  7681                           block_progression::KLR || aParentBlockProgression ==
       
  7682                           XnPropertyNames::style::common::
       
  7683                           block_progression::KRL )
       
  7684                     {
       
  7685                     if ( !autoHeight && ( adaptive & XnAdaptive::EHeight ) )
       
  7686                         {
       
  7687                         if ( marginSize.iHeight > adaptiveHeight )
       
  7688                             {
       
  7689                             adaptiveHeight = marginSize.iHeight;
       
  7690                             }
       
  7691                         }
       
  7692                     if ( !autoWidth && ( adaptive & XnAdaptive::EWidth ) )
       
  7693                         {
       
  7694                         adaptiveWidth += marginSize.iWidth;
       
  7695                         }
       
  7696                     }
       
  7697                 }
       
  7698             }
       
  7699         }
       
  7700 
       
  7701     TRect contentRect( aNode.Rect() );
       
  7702     TRect paddingRect( aNode.PaddingRect() );
       
  7703     TRect borderRect( aNode.BorderRect() );
       
  7704     TRect marginRect( aNode.MarginRect() );
       
  7705     TRect normalFlowBorderRect( aNode.NormalFlowBorderRect() );
       
  7706 
       
  7707     TRect paddingRectDiff( SubtractRect( paddingRect, contentRect ) );
       
  7708     TRect borderRectDiff( SubtractRect( borderRect, contentRect ) );
       
  7709     TRect marginRectDiff( SubtractRect( marginRect, contentRect ) );
       
  7710     TRect normalFlowBorderRectDiff( SubtractRect(
       
  7711         normalFlowBorderRect, contentRect ) );
       
  7712 
       
  7713     TInt dy( 0 );
       
  7714     TInt dx( 0 );
       
  7715 
       
  7716     if ( adaptive & XnAdaptive::EHeight )
       
  7717         {
       
  7718         if ( adaptiveHeight <= 0 )
       
  7719             {
       
  7720             adaptiveHeight = 0;
       
  7721             }
       
  7722         dy = contentRect.Size().iHeight - adaptiveHeight;
       
  7723         }
       
  7724     if ( adaptive & XnAdaptive::EWidth )
       
  7725         {
       
  7726         if ( adaptiveWidth <= 0 )
       
  7727             {
       
  7728             adaptiveWidth = 0;
       
  7729             }
       
  7730         dx = contentRect.Size().iWidth - adaptiveWidth;
       
  7731         }
       
  7732 
       
  7733     contentRect.Resize( -dx, -dy );
       
  7734 
       
  7735     paddingRect = AddRect( contentRect, paddingRectDiff );
       
  7736     borderRect = AddRect( contentRect, borderRectDiff );
       
  7737     marginRect = AddRect( contentRect, marginRectDiff );
       
  7738     normalFlowBorderRect = AddRect( contentRect, normalFlowBorderRectDiff );
       
  7739 
       
  7740     aNode.SetRect( contentRect );
       
  7741     aNode.SetPaddingRect( paddingRect );
       
  7742     aNode.SetBorderRect( borderRect );
       
  7743     aNode.SetMarginRect( marginRect );
       
  7744     aNode.SetNormalFlowBorderRect( normalFlowBorderRect );
       
  7745 
       
  7746     aNode.FixAdaptiveSizeL( contentRect.Size() );
       
  7747 
       
  7748     aNode.UiEngine()->CheckAdaptiveContentL( aNode, contentRect.Size() );
       
  7749 
       
  7750     CleanupStack::PopAndDestroy( &children );
       
  7751     }
       
  7752 
       
  7753 // -----------------------------------------------------------------------------
       
  7754 // BuildTriggerNodeLC
       
  7755 // Builds a trigger node
       
  7756 // -----------------------------------------------------------------------------
       
  7757 //
       
  7758 static CXnNode* BuildTriggerNodeLC( CXnUiEngine& aUiEngine,
       
  7759     const TDesC8& aTriggerName )
       
  7760     {
       
  7761     CXnNode* node = CXnNode::NewL();
       
  7762     CleanupStack::PushL( node );
       
  7763 
       
  7764     CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger );
       
  7765     CleanupStack::PushL( type );
       
  7766 
       
  7767     CXnNodeImpl* impl = CXnNodeImpl::NewL( type );
       
  7768     CleanupStack::Pop( type );
       
  7769 
       
  7770     node->SetImpl( impl );
       
  7771     node->SetUiEngine( aUiEngine );
       
  7772 
       
  7773     CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL(
       
  7774         aUiEngine.ODT()->DomDocument().StringPool() );
       
  7775 
       
  7776     CleanupStack::PushL( nameValue );
       
  7777 
       
  7778     nameValue->SetStringValueL( CXnDomPropertyValue::EString, aTriggerName );
       
  7779 
       
  7780     CXnProperty* name = CXnProperty::NewL(
       
  7781         XnPropertyNames::action::trigger::KName,
       
  7782         nameValue, aUiEngine.ODT()->DomDocument().StringPool() );
       
  7783 
       
  7784     CleanupStack::Pop( nameValue );
       
  7785 
       
  7786     CleanupStack::PushL( name );
       
  7787 
       
  7788     node->SetPropertyL( name );
       
  7789 
       
  7790     CleanupStack::Pop( name );
       
  7791 
       
  7792     //CleanupStack::Pop( node );
       
  7793 
       
  7794     return node;
       
  7795     }
       
  7796 
       
  7797 // -----------------------------------------------------------------------------
       
  7798 // UpdateInternalUnits
       
  7799 // Updates UiEngineImpl unit values
       
  7800 // -----------------------------------------------------------------------------
       
  7801 //
       
  7802 static void UpdateInternalUnits( TReal& aHorizontalUnitInPixels,
       
  7803     TReal& aVerticalUnitInPixels, TRect aRect )
       
  7804     {
       
  7805     TAknWindowComponentLayout referenceLayout =
       
  7806         AknLayoutScalable_Avkon::aid_value_unit2();
       
  7807     TRect parent( aRect );
       
  7808 
       
  7809     TAknLayoutRect rect;
       
  7810 
       
  7811     // TAknWindowLineLayout should go directly
       
  7812     //to LayoutRect/LayoutControl etc. methods
       
  7813     rect.LayoutRect( parent, referenceLayout.LayoutLine() );
       
  7814 
       
  7815     TReal rectWidth = rect.Rect().Width();
       
  7816 
       
  7817     if ( rectWidth == 0 )
       
  7818         {
       
  7819         aHorizontalUnitInPixels = 0;
       
  7820         }
       
  7821 
       
  7822     aHorizontalUnitInPixels = rectWidth / 10;
       
  7823 
       
  7824     TReal rectHeight = rect.Rect().Height();
       
  7825 
       
  7826     if ( rectHeight == 0 )
       
  7827         {
       
  7828         aVerticalUnitInPixels = 0;
       
  7829         }
       
  7830 
       
  7831     aVerticalUnitInPixels = rectHeight / 10;
       
  7832     }
       
  7833 
       
  7834 // -----------------------------------------------------------------------------
       
  7835 // BuildScreenDeviceChangeTriggerNodeLC
       
  7836 // Build trigger node for screen device change event
       
  7837 // -----------------------------------------------------------------------------
       
  7838 //
       
  7839 static CXnNode* BuildScreenDeviceChangeTriggerNodeLC( CXnUiEngine& aUiEngine )
       
  7840     {
       
  7841     CXnDomStringPool& sp( aUiEngine.ODT()->DomDocument().StringPool() );
       
  7842 
       
  7843     CXnNode* node = CXnNode::NewL();
       
  7844     CleanupStack::PushL( node );
       
  7845 
       
  7846     CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger );
       
  7847     CleanupStack::PushL( type );
       
  7848 
       
  7849     CXnNodeImpl* impl = CXnNodeImpl::NewL( type );
       
  7850     CleanupStack::Pop( type );
       
  7851 
       
  7852     node->SetImpl( impl );
       
  7853     node->SetUiEngine( aUiEngine );
       
  7854 
       
  7855     CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( sp );
       
  7856     CleanupStack::PushL( nameValue );
       
  7857 
       
  7858     nameValue->SetStringValueL( CXnDomPropertyValue::EString,
       
  7859         XnPropertyNames::action::trigger::name::KScreenDeviceChange );
       
  7860 
       
  7861     CXnProperty* name = CXnProperty::NewL(
       
  7862         XnPropertyNames::action::trigger::KName, nameValue, sp );
       
  7863     CleanupStack::Pop( nameValue );
       
  7864     CleanupStack::PushL( name );
       
  7865 
       
  7866     node->SetPropertyL( name );
       
  7867     CleanupStack::Pop( name );
       
  7868 
       
  7869     CXnDomPropertyValue* reasonValue = CXnDomPropertyValue::NewL( sp );
       
  7870     CleanupStack::PushL( reasonValue );
       
  7871 
       
  7872     const TDesC8* reasonString( NULL );
       
  7873 
       
  7874     if ( Layout_Meta_Data::IsLandscapeOrientation() )
       
  7875         {
       
  7876         reasonString = &XnPropertyNames::action::trigger::name::
       
  7877             uidefinitionmodification::reason::KLandscape;
       
  7878         }
       
  7879     else
       
  7880         {
       
  7881         reasonString = &XnPropertyNames::action::trigger::name::
       
  7882             uidefinitionmodification::reason::KPortrait;
       
  7883         }
       
  7884 
       
  7885     reasonValue->SetStringValueL( CXnDomPropertyValue::EString, *reasonString );
       
  7886 
       
  7887     CXnProperty* reason = CXnProperty::NewL( XnPropertyNames::action::trigger::
       
  7888         name::uidefinitionmodification::KReason, reasonValue, sp );
       
  7889 
       
  7890     CleanupStack::Pop( reasonValue );
       
  7891 
       
  7892     CleanupStack::PushL( reason );
       
  7893 
       
  7894     node->SetPropertyL( reason );
       
  7895 
       
  7896     CleanupStack::Pop( reason );
       
  7897 
       
  7898     return node;
       
  7899     }
       
  7900 
       
  7901 // -----------------------------------------------------------------------------
       
  7902 // FillFocusCandidatesL
       
  7903 // -----------------------------------------------------------------------------
       
  7904 //
       
  7905 static void FillFocusCandidatesL( CXnNode* aParent,
       
  7906     RPointerArray< CXnNode >& aArray )
       
  7907     {
       
  7908     RPointerArray< CXnNode >& children( aParent->Children() );
       
  7909 
       
  7910     aArray.AppendL( aParent );
       
  7911 
       
  7912     for ( TInt i = 0; i < children.Count(); i++ )
       
  7913         {
       
  7914         FillFocusCandidatesL( children[i], aArray );
       
  7915         }
       
  7916     }
       
  7917 
       
  7918 // -----------------------------------------------------------------------------
       
  7919 // DetermineStatusPaneLayout
       
  7920 // -----------------------------------------------------------------------------
       
  7921 //
       
  7922 static TInt DetermineStatusPaneLayout( CXnProperty* aProperty )
       
  7923     {
       
  7924     TInt spane( KErrNotFound );
       
  7925 
       
  7926     if ( aProperty )
       
  7927         {
       
  7928         const TDesC8& value( aProperty->StringValue() );
       
  7929 
       
  7930         // Currently supported status pane layout
       
  7931         if ( value == XnPropertyNames::view::statuspanelayout::KNone )
       
  7932             {
       
  7933             spane = R_AVKON_STATUS_PANE_LAYOUT_EMPTY;
       
  7934             }
       
  7935         if ( value == XnPropertyNames::view::statuspanelayout::KBasic )
       
  7936             {
       
  7937             spane = R_AVKON_STATUS_PANE_LAYOUT_IDLE;
       
  7938             }
       
  7939         else if ( value == XnPropertyNames::view::statuspanelayout::KBasicFlat )
       
  7940             {
       
  7941             spane = R_AVKON_STATUS_PANE_LAYOUT_IDLE_FLAT;
       
  7942             }
       
  7943         else if ( value ==
       
  7944                   XnPropertyNames::view::statuspanelayout::KWideScreen )
       
  7945             {
       
  7946             spane = R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE;
       
  7947             }
       
  7948         else if ( value ==
       
  7949                   XnPropertyNames::view::statuspanelayout::KWideScreenFlat )
       
  7950             {
       
  7951             spane = R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT;
       
  7952             }
       
  7953         else if ( value ==
       
  7954                   XnPropertyNames::view::statuspanelayout::
       
  7955                   KWideScreenFlat3Softkeys )
       
  7956             {
       
  7957             spane = R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT_NO_SOFTKEYS;
       
  7958             }
       
  7959         }
       
  7960 
       
  7961     return spane;
       
  7962     }
       
  7963 
       
  7964 // -----------------------------------------------------------------------------
       
  7965 // SetAdaptivesL
       
  7966 // -----------------------------------------------------------------------------
       
  7967 //
       
  7968 static TBool SetAdaptivesL( CXnNode& aNode )
       
  7969     {
       
  7970     TBool retval( EFalse );
       
  7971 
       
  7972     // Check if the node is adaptive
       
  7973     if ( aNode.IsAdaptive( ETrue ) && IsNodeDisplayedL( aNode ) )
       
  7974         {
       
  7975         retval = ETrue;
       
  7976         // Mark adaptive node to be measured
       
  7977         aNode.SetAdaptiveL( XnAdaptive::EMeasure );
       
  7978         }
       
  7979 
       
  7980     RPointerArray< CXnNode >& children( aNode.Children() );
       
  7981 
       
  7982     for ( TInt i = 0; i < children.Count(); i++ )
       
  7983         {
       
  7984         TBool ret( SetAdaptivesL( *children[i] ) );
       
  7985         if ( ret )
       
  7986             {
       
  7987             retval = ret;
       
  7988             }
       
  7989         }
       
  7990 
       
  7991     return retval;
       
  7992     }
       
  7993 
       
  7994 #ifdef _XN3_DEBUG_
       
  7995 // -----------------------------------------------------------------------------
       
  7996 // TraceTreeL
       
  7997 // -----------------------------------------------------------------------------
       
  7998 //
       
  7999 static void TraceTreeL( CXnNode* aRootNode )
       
  8000     {
       
  8001     CXnDepthFirstTreeIterator< CXnNode >* iterator = 
       
  8002             CXnDepthFirstTreeIterator< CXnNode >::NewL( *aRootNode );
       
  8003     CleanupStack::PushL( iterator );
       
  8004 
       
  8005     RDebug::Print( _L("Xuikon: UI tree:") );
       
  8006 
       
  8007     TBuf8< 256 > debug;
       
  8008 
       
  8009     TInt level( 0 );
       
  8010 
       
  8011     for( CXnNode* node = iterator->Value(); node;
       
  8012         node = iterator->NextL() )
       
  8013         {
       
  8014         debug = _L8( "Xuikon: " );
       
  8015 
       
  8016         level = iterator->Level();
       
  8017 
       
  8018         for ( TInt i = 0; i < level; i++ )
       
  8019             {
       
  8020             debug.Append( '  ' );
       
  8021             }
       
  8022 
       
  8023         debug.Append( node->Type()->Type() );
       
  8024 
       
  8025         CXnProperty* id( node->IdL() );
       
  8026 
       
  8027         if ( id )
       
  8028             {
       
  8029             debug.Append( _L8( ", id: " ) );
       
  8030             debug.Append( id->StringValue() );
       
  8031             }
       
  8032                             
       
  8033         debug.AppendFormat( _L8( ", laidout: %d" ), node->IsLaidOut() );
       
  8034         debug.AppendFormat( _L8( ", displayed: %d" ),
       
  8035             IsNodeDisplayedL( *node ) );
       
  8036 
       
  8037         CCoeControl* control( node->Control() );
       
  8038 
       
  8039         if ( control )
       
  8040             {
       
  8041             TBool visible( control->IsVisible() );
       
  8042             TRect rect( control->Rect() );
       
  8043             TPoint tl( rect.iTl );
       
  8044             TPoint br( rect.iBr );
       
  8045             debug.AppendFormat( _L8( ", visible %d:" ), visible );
       
  8046             debug.AppendFormat(
       
  8047                 _L8( ", Tl: %d %d, Br: %d %d" ), tl.iX, tl.iY, br.iX, br.iY );
       
  8048             }
       
  8049         else
       
  8050             {
       
  8051             debug.Append( _L8( ", no control" ) );
       
  8052             }
       
  8053         RDebug::RawPrint( debug );
       
  8054         }
       
  8055 
       
  8056     CleanupStack::PopAndDestroy( iterator );
       
  8057     }
       
  8058 #endif
       
  8059 
       
  8060 // ============================ MEMBER FUNCTIONS ===============================
       
  8061 
       
  8062 // -----------------------------------------------------------------------------
       
  8063 // CXnUiEngineImpl::CXnUiEngineImpl()
       
  8064 // C++ default constructor can NOT contain any code, that
       
  8065 // might leave.
       
  8066 // -----------------------------------------------------------------------------
       
  8067 //
       
  8068 CXnUiEngineImpl::CXnUiEngineImpl( CXnUiEngine& aUiEngine, 
       
  8069     CXnAppUiAdapter& aAdapter )     
       
  8070     : iUiEngine( &aUiEngine ), iAppUiAdapter( aAdapter ), 
       
  8071     iViewManager( aAdapter.ViewManager() )    
       
  8072     {
       
  8073     iAppUiAdapter.UiStateListener().AddObserver( *this );
       
  8074     
       
  8075     iViewManager.AddObserver( *this );
       
  8076     }
       
  8077 
       
  8078 // -----------------------------------------------------------------------------
       
  8079 // CXnUiEngineImpl::ConstructL()
       
  8080 // Symbian 2nd phase constructor can leave.
       
  8081 // -----------------------------------------------------------------------------
       
  8082 //
       
  8083 void CXnUiEngineImpl::ConstructL()
       
  8084     {                  
       
  8085     iEditMode = CXnEditMode::NewL( *iUiEngine );
       
  8086 
       
  8087     iHitTest = CXnHitTest::NewL();
       
  8088 
       
  8089     iCurrentGraphicsDevice = CCoeEnv::Static()->ScreenDevice();
       
  8090 
       
  8091     // Update the units here, even the refence client rect is only a quess.
       
  8092     // That is because we don't know the UI furniture yet. Units are
       
  8093     // needed in controls constructions
       
  8094     UpdateInternalUnits( 
       
  8095         iHorizontalUnitInPixels, 
       
  8096         iVerticalUnitInPixels,
       
  8097         iAppUiAdapter.ClientRect() );        
       
  8098     }
       
  8099 
       
  8100 // -----------------------------------------------------------------------------
       
  8101 // CXnUiEngineImpl::NewL()
       
  8102 // Two-phased constructor.
       
  8103 // -----------------------------------------------------------------------------
       
  8104 //
       
  8105 CXnUiEngineImpl* CXnUiEngineImpl::NewL( CXnUiEngine& aUiEngine,
       
  8106     CXnAppUiAdapter& aAdapter )
       
  8107     {
       
  8108     return new ( ELeave ) CXnUiEngineImpl( aUiEngine, aAdapter );
       
  8109     }
       
  8110 
       
  8111 // -----------------------------------------------------------------------------
       
  8112 // CXnUiEngineImpl::~CXnUiEngineImpl()
       
  8113 // C++ default destructor.
       
  8114 // -----------------------------------------------------------------------------
       
  8115 //
       
  8116 CXnUiEngineImpl::~CXnUiEngineImpl()
       
  8117     {        
       
  8118     iAppUiAdapter.UiStateListener().RemoveObserver( *this );
       
  8119     
       
  8120     iViewManager.RemoveObserver( *this );
       
  8121            
       
  8122     delete iEditMode;
       
  8123     delete iHitTest;
       
  8124 
       
  8125     iFocusCandidateList.Reset();
       
  8126     iRedrawRegions.ResetAndDestroy();
       
  8127     iDirtyList.Reset();
       
  8128     }
       
  8129 
       
  8130 // -----------------------------------------------------------------------------
       
  8131 // CXnUiEngineImpl::AppUiAdapter()
       
  8132 // -----------------------------------------------------------------------------
       
  8133 //
       
  8134 CXnAppUiAdapter& CXnUiEngineImpl::AppUiAdapter() const
       
  8135     {
       
  8136     return iAppUiAdapter;
       
  8137     }
       
  8138 
       
  8139 // -----------------------------------------------------------------------------
       
  8140 // CXnUiEngineImpl::LayoutUIL()
       
  8141 // -----------------------------------------------------------------------------
       
  8142 //
       
  8143 void CXnUiEngineImpl::LayoutUIL( CXnNode* /*aNode*/ )
       
  8144     {
       
  8145     if ( IsLayoutDisabled() )
       
  8146         {     
       
  8147         iLayoutControl |= XnLayoutControl::ELayoutUI;
       
  8148         return;
       
  8149         }
       
  8150 
       
  8151     iLayoutControl &= ~XnLayoutControl::ELayoutUI;
       
  8152 
       
  8153     if ( iDirtyList.Count() == 0 )
       
  8154         {
       
  8155         // Nothing to do, layout is up-to-date
       
  8156         return;
       
  8157         }
       
  8158 
       
  8159     DisableRenderUiLC();
       
  8160     CXnNode* candidate( StartLayoutFromL() );
       
  8161     PrepareRunLayoutL();
       
  8162     iDirtyList.Reset();
       
  8163 
       
  8164     // Run layout until it is fully calculated
       
  8165     do
       
  8166         {
       
  8167         iLayoutPhase = RunLayoutL( candidate );
       
  8168         }
       
  8169     while ( iLayoutPhase != XnLayoutPhase::ENone );
       
  8170 
       
  8171     CXnNode* focused( FocusedNode() );
       
  8172 
       
  8173     if ( focused && focused->IsDropped() )
       
  8174         {
       
  8175         // The currently focused node is dropped, run losevisualization
       
  8176         CXnNode* loseVisualisation =
       
  8177             BuildTriggerNodeLC( *iUiEngine,
       
  8178                 XnPropertyNames::action::trigger::name::KLoseVisualisation );
       
  8179 
       
  8180         focused->ReportXuikonEventL( *loseVisualisation );
       
  8181         CleanupStack::PopAndDestroy( loseVisualisation );
       
  8182 
       
  8183         if ( FocusedNode() == focused )
       
  8184             {
       
  8185             // Remove focus as losevisualization trigger didn't
       
  8186             // change focus from dropped node to another one
       
  8187             SetFocusedNodeL( NULL );
       
  8188             }
       
  8189         }
       
  8190 
       
  8191     if ( !FocusedNode() && iAppUiAdapter.FocusShown() )
       
  8192         {
       
  8193         // No focus, try if some of the focus candidates can be focused
       
  8194         RootNode()->RunFocusChangeL( iFocusCandidateList );
       
  8195         }
       
  8196         
       
  8197     iFocusCandidateList.Reset();
       
  8198 
       
  8199     iAppUiAdapter.EffectManager()->UiLayouted();
       
  8200     
       
  8201     // Layout is now recalculated
       
  8202     CleanupStack::PopAndDestroy(); // anonymous
       
  8203     }
       
  8204 
       
  8205 // -----------------------------------------------------------------------------
       
  8206 // PrepareRunLayoutL()
       
  8207 // Set dropped flags of all nodes in the tree to ENone.
       
  8208 // -----------------------------------------------------------------------------
       
  8209 //
       
  8210 void CXnUiEngineImpl::PrepareRunLayoutL()
       
  8211     {
       
  8212     if ( iLayoutPhase == XnLayoutPhase::ENone )
       
  8213         {
       
  8214         iLayoutPhase = XnLayoutPhase::ELayout;
       
  8215 
       
  8216         for ( TInt i = 0; i < iDirtyList.Count(); i++ )
       
  8217             {
       
  8218             CXnNode* dirty( iDirtyList[i] );
       
  8219 
       
  8220             // Clear dropped flags recursively
       
  8221             SetNodeDroppedL( *dirty, XnNodeLayout::ENone );
       
  8222 
       
  8223             if ( SetAdaptivesL( *dirty ) )
       
  8224                 {
       
  8225                 // Adaptive node causes measure phase
       
  8226                 iLayoutPhase = XnLayoutPhase::EMeasure;
       
  8227                 }
       
  8228             }
       
  8229         }
       
  8230     }
       
  8231 
       
  8232 // -----------------------------------------------------------------------------
       
  8233 // CXnUiEngineImpl::RunLayoutL()
       
  8234 // -----------------------------------------------------------------------------
       
  8235 //
       
  8236 TInt CXnUiEngineImpl::RunLayoutL( CXnNode* aNode )
       
  8237     {
       
  8238     TRect clientRect( ClientRect() );
       
  8239     // Move it to 0, 0
       
  8240     clientRect.Move( -clientRect.iTl.iX, -clientRect.iTl.iY );
       
  8241 
       
  8242     RPointerArray< CXnNode > laidOutList;
       
  8243     CleanupClosePushL( laidOutList );
       
  8244 
       
  8245     if ( IsNodeDisplayedL( *aNode ) )
       
  8246         {
       
  8247         if ( aNode->ViewNodeImpl() && !aNode ->IsLaidOut() )
       
  8248             {
       
  8249             aNode->SetMarginRect( clientRect );
       
  8250             aNode->SetBorderRect( clientRect );
       
  8251             aNode->SetNormalFlowBorderRect( clientRect );
       
  8252             aNode->SetPaddingRect( clientRect );
       
  8253             aNode->SetRect( clientRect );
       
  8254             }
       
  8255 
       
  8256         // Put areas to place
       
  8257         PlaceAreasL( *aNode, laidOutList, iLayoutPhase,
       
  8258             *iCurrentGraphicsDevice, iHorizontalUnitInPixels,
       
  8259             iVerticalUnitInPixels );
       
  8260         }
       
  8261 
       
  8262     TInt nextPhase;
       
  8263 
       
  8264     switch ( iLayoutPhase )
       
  8265         {
       
  8266         case XnLayoutPhase::EMeasure:
       
  8267             nextPhase = XnLayoutPhase::ELayout;
       
  8268             break;
       
  8269         case XnLayoutPhase::ELayout:
       
  8270             // Layout is now calculated
       
  8271             iCurrentView->SetLaidOutL();
       
  8272             iLayoutControl &= ~XnLayoutControl::EViewDirty;
       
  8273             // Check nodes which dimensions are changed
       
  8274             for ( TInt i = 0; i < laidOutList.Count(); i++ )
       
  8275                 {
       
  8276                 CXnNode* node( laidOutList[i] );
       
  8277                 if( IsSrollableBox( *node ) && node->ScrollableControl() )
       
  8278                     {
       
  8279                     node->ScrollableControl()->LayoutChangedL();
       
  8280                     }
       
  8281                 if ( /*IsNodeTooltip( *node ) ||*/ !node->IsLaidOut() )
       
  8282                     {
       
  8283                     continue;
       
  8284                     }
       
  8285                 CXnControlAdapter* adapter( node->Control() );
       
  8286                 if ( adapter )
       
  8287                     {
       
  8288                     TRect rect;
       
  8289                     
       
  8290                     if ( node->ViewNodeImpl() )
       
  8291                         {
       
  8292                         rect = ClientRect();
       
  8293                         
       
  8294                         // Move it to 0, 0
       
  8295                         rect.Move( -rect.iTl.iX, -rect.iTl.iY );                        
       
  8296                         }
       
  8297                     else
       
  8298                         {
       
  8299                         rect = node->BorderRect();
       
  8300                         }
       
  8301                     if ( adapter->Rect() != rect )
       
  8302                         {
       
  8303                         AddToRedrawListL( node, rect );
       
  8304                         
       
  8305                         adapter->SetRect( rect );
       
  8306                         CXnProperty* prop = node->GetPropertyL(
       
  8307                             XnPropertyNames::common::KSizeAware );
       
  8308                         if ( prop && prop->StringValue() ==
       
  8309                              XnPropertyNames::KTrue )
       
  8310                             {
       
  8311                             CXnNode* sizeChanged =
       
  8312                                 BuildTriggerNodeLC( *iUiEngine,
       
  8313                                 XnPropertyNames::action::trigger::name::
       
  8314                                 KSizeChanged );
       
  8315                             node->ReportXuikonEventL( *sizeChanged );
       
  8316                             CleanupStack::PopAndDestroy( sizeChanged );
       
  8317                             }
       
  8318                         }
       
  8319                     }
       
  8320                 }
       
  8321             /* flow through */
       
  8322         default:
       
  8323             nextPhase = XnLayoutPhase::ENone;
       
  8324             break;
       
  8325         }
       
  8326     CleanupStack::PopAndDestroy( &laidOutList );
       
  8327     return nextPhase;
       
  8328     }
       
  8329 
       
  8330 // -----------------------------------------------------------------------------
       
  8331 // CXnUiEngineImpl::RenderUIL()
       
  8332 // -----------------------------------------------------------------------------
       
  8333 //
       
  8334 void CXnUiEngineImpl::RenderUIL( CXnNode* /*aNode*/ )
       
  8335     {
       
  8336     if ( IsLayoutDisabled() )
       
  8337         {
       
  8338         // Layout is not up-to-date
       
  8339         iLayoutControl |= XnLayoutControl::ERenderUI;
       
  8340         return;
       
  8341         }
       
  8342     
       
  8343 #ifdef _XN3_DEBUG_
       
  8344     TraceTreeL(iCurrentView );
       
  8345 #endif                          
       
  8346 
       
  8347     for( TInt i=0; i<iRedrawRegions.Count(); i++)
       
  8348         {
       
  8349         CCoeControl* control = iRedrawRegions[i]->iControl;
       
  8350         RRegion& redrawRegion = iRedrawRegions[i]->iRegion;
       
  8351         
       
  8352         if( redrawRegion.CheckError() )
       
  8353             {                
       
  8354             // Mark tree rendered
       
  8355             iCurrentView->SetRenderedL();
       
  8356             // Error occured during dirty set, redraw whole window
       
  8357             control->DrawNow();                                              
       
  8358             }                                        
       
  8359         else 
       
  8360             {
       
  8361             if( !redrawRegion.IsEmpty() )                                        
       
  8362                 {
       
  8363                 // Mark tree rendered
       
  8364                 iCurrentView->SetRenderedL();
       
  8365                 TInt count( redrawRegion.Count() );
       
  8366                 
       
  8367                 if( count > 2 )
       
  8368                     {
       
  8369                     // Make bounding rect over the dirty areas
       
  8370                     TRect boundingRect( redrawRegion.BoundingRect() );
       
  8371                     
       
  8372                     control->DrawNow( boundingRect );
       
  8373                     }                               
       
  8374                 else
       
  8375                     {
       
  8376                     for( TInt i = 0; i < count; i++ )
       
  8377                         {
       
  8378                         // Draw every dirty area separately
       
  8379                         TRect redrawRect( redrawRegion[i] );
       
  8380     
       
  8381                         control->DrawNow( redrawRect );
       
  8382                         }
       
  8383                     }  
       
  8384                 }
       
  8385             }  
       
  8386         redrawRegion.Clear();  
       
  8387         }
       
  8388 
       
  8389     RefreshMenuL();
       
  8390 
       
  8391     if ( iLayoutControl & XnLayoutControl::EFirstPassDraw )
       
  8392         {
       
  8393         iViewManager.SetFirstPassDrawCompleteL();
       
  8394         iLayoutControl &= ~XnLayoutControl::EFirstPassDraw;
       
  8395         }
       
  8396 
       
  8397     iLayoutControl &= ~XnLayoutControl::ERenderUI;
       
  8398     
       
  8399     iAppUiAdapter.EffectManager()->UiRendered();
       
  8400     }
       
  8401 
       
  8402 // -----------------------------------------------------------------------------
       
  8403 // CXnUiEngineImpl::RootNode()
       
  8404 // -----------------------------------------------------------------------------
       
  8405 //
       
  8406 CXnNode* CXnUiEngineImpl::RootNode()
       
  8407     {
       
  8408     return iViewManager.RootNode();
       
  8409     }
       
  8410 
       
  8411 // -----------------------------------------------------------------------------
       
  8412 // CXnUiEngineImpl::ODT()
       
  8413 // -----------------------------------------------------------------------------
       
  8414 //
       
  8415 CXnODT* CXnUiEngineImpl::ODT()
       
  8416     {
       
  8417     return iViewManager.ODT();
       
  8418     }
       
  8419 
       
  8420 // -----------------------------------------------------------------------------
       
  8421 // CXnUiEngineImpl::FindNodeByIdL()
       
  8422 // -----------------------------------------------------------------------------
       
  8423 //
       
  8424 CXnNode* CXnUiEngineImpl::FindNodeByIdL( const TDesC& aAreaId,
       
  8425     const TDesC& aNamespace )
       
  8426     {
       
  8427     HBufC8* id = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aAreaId );
       
  8428     CleanupStack::PushL( id );
       
  8429 
       
  8430     HBufC8* ns = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aNamespace );
       
  8431     CleanupStack::PushL( ns );
       
  8432 
       
  8433     CXnNode* returnValue( FindNodeByIdL( *id, *ns ) );
       
  8434 
       
  8435     CleanupStack::PopAndDestroy( ns );
       
  8436     CleanupStack::PopAndDestroy( id );
       
  8437 
       
  8438     return returnValue;
       
  8439     }
       
  8440 
       
  8441 // -----------------------------------------------------------------------------
       
  8442 // CXnUiEngineImpl::FindNodeByIdL()
       
  8443 // -----------------------------------------------------------------------------
       
  8444 //
       
  8445 CXnNode* CXnUiEngineImpl::FindNodeByIdL( const TDesC8& aAreaId,
       
  8446     const TDesC8& aNamespace )
       
  8447     {
       
  8448     // Find the namespace where to start node id look-up 
       
  8449     CXnPluginData* pluginData( 
       
  8450         iViewManager.ActiveViewData().Plugin( aNamespace ) );
       
  8451 
       
  8452     if ( !pluginData )
       
  8453         {
       
  8454         return NULL;
       
  8455         }
       
  8456 
       
  8457     CXnNode* root( pluginData->Node()->LayoutNode() );
       
  8458 
       
  8459     return ::FindNodeByIdL( root, aAreaId, aNamespace );
       
  8460     }
       
  8461 
       
  8462 // -----------------------------------------------------------------------------
       
  8463 // CXnUiEngineImpl::FindNodeByClassL()
       
  8464 // -----------------------------------------------------------------------------
       
  8465 //
       
  8466 CXnPointerArray* CXnUiEngineImpl::FindNodeByClassL(
       
  8467     const TDesC& aClassId, const TDesC& aNamespace )
       
  8468     {
       
  8469     HBufC8* classId = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aClassId );
       
  8470     CleanupStack::PushL( classId );
       
  8471 
       
  8472     HBufC8* ns = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aNamespace );
       
  8473     CleanupStack::PushL( ns );
       
  8474     
       
  8475     CXnPointerArray* returnValue( FindNodeByClassL( *classId, *ns ) );
       
  8476 
       
  8477     CleanupStack::PopAndDestroy( ns );
       
  8478     CleanupStack::PopAndDestroy( classId );
       
  8479 
       
  8480     return returnValue;
       
  8481     }
       
  8482 
       
  8483 // -----------------------------------------------------------------------------
       
  8484 // CXnUiEngineImpl::FindNodeByClassL()
       
  8485 // -----------------------------------------------------------------------------
       
  8486 //
       
  8487 CXnPointerArray* CXnUiEngineImpl::FindNodeByClassL(
       
  8488     const TDesC8& aClassId, const TDesC8& aNamespace )
       
  8489     {
       
  8490     // Find the namespace where to start node class look-up
       
  8491     CXnPluginData* pluginData( 
       
  8492         iViewManager.ActiveViewData().Plugin( aNamespace ) );
       
  8493 
       
  8494     CXnPointerArray* array = CXnPointerArray::NewL();
       
  8495     CleanupStack::PushL( array );
       
  8496     
       
  8497     if ( pluginData )
       
  8498         {
       
  8499         CXnNode* root( pluginData->Node()->LayoutNode() );
       
  8500         ::FindNodeByClassL( root, aClassId, *array, aNamespace );
       
  8501         }
       
  8502 
       
  8503     CleanupStack::Pop( array );
       
  8504 
       
  8505     return array;
       
  8506     }
       
  8507 
       
  8508 // -----------------------------------------------------------------------------
       
  8509 // CXnUiEngineImpl::Resources()
       
  8510 // -----------------------------------------------------------------------------
       
  8511 //
       
  8512 CArrayPtrSeg< CXnResource >& CXnUiEngineImpl::Resources()
       
  8513     {
       
  8514     return iViewManager.Resources();
       
  8515     }
       
  8516 
       
  8517 // -----------------------------------------------------------------------------
       
  8518 // CXnUiEngineImpl::SetFocusedNodeL()
       
  8519 // -----------------------------------------------------------------------------
       
  8520 //
       
  8521 void CXnUiEngineImpl::SetFocusedNodeL( CXnNode* aFocusedNode, TInt aSource )
       
  8522     {
       
  8523     iKeyEventDispatcher->SetNodeL( aFocusedNode, aSource );
       
  8524     }
       
  8525 
       
  8526 // -----------------------------------------------------------------------------
       
  8527 // CXnUiEngine::FocusedNode
       
  8528 // Forwards the call to the ui engine implementation
       
  8529 // -----------------------------------------------------------------------------
       
  8530 //
       
  8531 CXnNode* CXnUiEngineImpl::FocusedNode()
       
  8532     {
       
  8533     return iKeyEventDispatcher->FocusedNode();
       
  8534     }
       
  8535 
       
  8536 // -----------------------------------------------------------------------------
       
  8537 // CXnUiEngineImpl::IsEditMode
       
  8538 // Returns ETrue if the current mode is edit, otherwise EFalse.
       
  8539 // -----------------------------------------------------------------------------
       
  8540 //
       
  8541 TBool CXnUiEngineImpl::IsEditMode()
       
  8542     {
       
  8543     return ( iEditMode->EditState() != CXnEditMode::ENone );
       
  8544     }
       
  8545 
       
  8546 // -----------------------------------------------------------------------------
       
  8547 // CXnUiEngineImpl::NotifyViewActivatedL()
       
  8548 // -----------------------------------------------------------------------------
       
  8549 // 
       
  8550 void CXnUiEngineImpl::NotifyViewActivatedL( const CXnViewData& /*aViewData*/ )
       
  8551     {
       
  8552     iCurrentView = iViewManager.ViewNode();
       
  8553 
       
  8554     iControlAdapterList = &iViewManager.Controls();
       
  8555     iCurrentViewControlAdapter = iCurrentView->Control();
       
  8556     
       
  8557     iLayoutControl |= XnLayoutControl::EFirstPassDraw;
       
  8558 
       
  8559     iDirtyList.Reset();
       
  8560 
       
  8561     iRedrawRegions.ResetAndDestroy();
       
  8562     
       
  8563     // Set status pane layout
       
  8564     CXnProperty* prop( iCurrentView->GetPropertyL( 
       
  8565         XnPropertyNames::view::KStatusPaneLayout ) );
       
  8566 
       
  8567     // Is there status pane declaration available
       
  8568     TInt spane( DetermineStatusPaneLayout( prop ) );
       
  8569 
       
  8570     if ( spane != KErrNotFound )
       
  8571         {
       
  8572         CEikStatusPane* sp( iAppUiAdapter.StatusPane() );
       
  8573 
       
  8574         if ( sp && sp->CurrentLayoutResId() != spane )
       
  8575             {
       
  8576             sp->SwitchLayoutL( spane );
       
  8577             sp->ApplyCurrentSettingsL();
       
  8578             }
       
  8579         }
       
  8580 
       
  8581     // Remove previous menubar and stylus popup node
       
  8582     iMenuNode = NULL;
       
  8583     iStylusPopupNode = NULL;
       
  8584 
       
  8585     iKeyEventDispatcher->ResetMenuNodeL();
       
  8586 
       
  8587     RPointerArray< CXnNode >& children( iCurrentView->Children() );
       
  8588 
       
  8589     for ( TInt count = children.Count() - 1; count >= 0 ; --count )
       
  8590         {
       
  8591         CXnNode* node( children[count] );
       
  8592 
       
  8593         // Check that the given type of a control is parent
       
  8594         // (or ancestor) of this control
       
  8595         const TDesC8& type( node->Type()->Type() );
       
  8596         
       
  8597         if ( type == KXnMenuBar )
       
  8598             {
       
  8599             iMenuNode = node;
       
  8600             XnMenuInterface::MXnMenuInterface* menuIf( NULL );
       
  8601             XnComponentInterface::MakeInterfaceL( menuIf, node->AppIfL() );
       
  8602             if ( menuIf )
       
  8603                 {
       
  8604                 menuIf->SetObserver( *this );
       
  8605                 }
       
  8606             }
       
  8607         else if ( type == _L8("styluspopup") )
       
  8608             {
       
  8609             iStylusPopupNode = node;
       
  8610             
       
  8611             static_cast< CXnPopupControlAdapter* > 
       
  8612 				( node->Control() )->SetObserver( *this );
       
  8613             }
       
  8614         }
       
  8615 
       
  8616     // Set menu node even if its NULL, to allow keyevent dispatcher
       
  8617     // to handle no softkeys
       
  8618     iKeyEventDispatcher->SetMenuNodeL( iMenuNode );
       
  8619 
       
  8620     ReportScreenDeviceChangeL();
       
  8621             
       
  8622     SetClientRectL( iAppUiAdapter.ClientRect(), EFalse );
       
  8623     
       
  8624     RootNode()->SetDirtyL();
       
  8625     iUiEngine->RenderUIL();
       
  8626     }
       
  8627 
       
  8628 // -----------------------------------------------------------------------------
       
  8629 // CXnUiEngineImpl::NotifyWidgetAdditionL()
       
  8630 // -----------------------------------------------------------------------------
       
  8631 //
       
  8632 void CXnUiEngineImpl::NotifyWidgetAdditionL(
       
  8633     const CXnPluginData& /*aPluginData*/ )
       
  8634     {
       
  8635     iLayoutControl |= XnLayoutControl::EFirstPassDraw;
       
  8636     }
       
  8637 
       
  8638 // -----------------------------------------------------------------------------
       
  8639 // CXnUiEngineImpl::DynInitMenuItemL()
       
  8640 // -----------------------------------------------------------------------------
       
  8641 //
       
  8642 TBool CXnUiEngineImpl::DynInitMenuItemL( CXnNodeAppIf& aMenuItem,
       
  8643     CXnNodeAppIf* aPlugin )
       
  8644     {       
       
  8645     // dynamic menuitem types reserved for HS internal use,
       
  8646     // internal menuitems' origin must be in active view namespace
       
  8647     _LIT( KAddWidget, "hs_add_widget" );
       
  8648     _LIT( KRemoveWidget, "hs_remove_widget" );
       
  8649     _LIT( KAddView, "hs_add_view" );
       
  8650     _LIT( KRemoveView, "hs_remove_view" );
       
  8651     _LIT( KOnline, "hs_online" );
       
  8652     _LIT( KOffline, "hs_offline" );
       
  8653                   
       
  8654     CXnProperty* prop( 
       
  8655         aMenuItem.GetPropertyL( XnPropertyNames::menu::KItemType ) );
       
  8656     
       
  8657     TBool retval( EFalse );            
       
  8658     
       
  8659     if( !prop )
       
  8660         {
       
  8661         // No type defined, declaration error
       
  8662         return retval;        
       
  8663         }
       
  8664                 
       
  8665     CXnViewData& viewData( iViewManager.ActiveViewData() );
       
  8666     
       
  8667     TInt viewAmount( iViewManager.ViewAmount() );
       
  8668     
       
  8669     // Check if the menuitem is in view namespace
       
  8670     TBool internal( aMenuItem.Namespace() == ActiveView()->Namespace() );
       
  8671 
       
  8672     HBufC* itemType( prop->StringValueL() );
       
  8673     CleanupStack::PushL( itemType );
       
  8674     
       
  8675     if ( internal )
       
  8676         {
       
  8677         if ( *itemType == KAddWidget )
       
  8678             {
       
  8679             if ( aPlugin )
       
  8680                 {
       
  8681                 CXnPluginData& data( viewData.Plugin( &aPlugin->Node() ) );
       
  8682                 
       
  8683                 if ( !data.Occupied() )
       
  8684                     {
       
  8685                     retval = ETrue;
       
  8686                     }
       
  8687                 }        
       
  8688             }   
       
  8689         else if ( *itemType == KRemoveWidget )
       
  8690             {                                          
       
  8691             CXnNode* node( ( aPlugin ) ? &aPlugin->Node() : FocusedNode() );
       
  8692 
       
  8693             if ( node )
       
  8694                 {
       
  8695                 CXnPluginData& data( viewData.Plugin( node ) );
       
  8696                 
       
  8697                 if ( data.Removable() && data.Occupied() )
       
  8698                     {
       
  8699                     retval = ETrue;
       
  8700                     }                              
       
  8701                 }            
       
  8702             }
       
  8703         else if ( *itemType == KAddView )
       
  8704             {
       
  8705             // checks Max pages value - from RootData
       
  8706             if ( viewAmount < iViewManager.MaxPages() )
       
  8707                 {
       
  8708                 retval = ETrue;
       
  8709                 }
       
  8710             }
       
  8711         else if ( *itemType == KRemoveView )
       
  8712             {
       
  8713             if ( viewData.Removable() && viewAmount > 1 )
       
  8714                 {
       
  8715                 retval = ETrue;
       
  8716                 }
       
  8717             }
       
  8718         else if ( *itemType == KOnline || *itemType == KOffline )
       
  8719             {
       
  8720             retval = iAppUiAdapter.DynInitMenuItemL( *itemType );
       
  8721             }       
       
  8722         }
       
  8723     else
       
  8724         {
       
  8725         const TDesC8& ns( aMenuItem.Namespace() );
       
  8726         
       
  8727         CXnPluginData* data( viewData.Plugin( ns ) );
       
  8728         
       
  8729         if ( data )
       
  8730             {
       
  8731             RPointerArray< CXnNode > nodes;
       
  8732             CleanupClosePushL( nodes );
       
  8733 
       
  8734             data->ContentSourceNodesL( nodes );
       
  8735             
       
  8736             RPointerArray< CXnNodeAppIf > list;
       
  8737             CleanupClosePushL( list );
       
  8738 
       
  8739             for ( TInt i = 0; i < nodes.Count(); i++ )
       
  8740                 {
       
  8741                 list.AppendL( &nodes[i]->AppIfL() );
       
  8742                 }
       
  8743             
       
  8744             retval = iAppUiAdapter.DynInitMenuItemL( *itemType, &list );
       
  8745             
       
  8746             CleanupStack::PopAndDestroy( 2, &nodes ); // list            
       
  8747             }               
       
  8748         }
       
  8749     
       
  8750     CleanupStack::PopAndDestroy( itemType );
       
  8751                   
       
  8752     return retval;
       
  8753     }
       
  8754 
       
  8755 // -----------------------------------------------------------------------------
       
  8756 // CXnUiEngineImpl::VerticalPixelValueL()
       
  8757 // -----------------------------------------------------------------------------
       
  8758 //
       
  8759 TInt CXnUiEngineImpl::VerticalPixelValueL(
       
  8760     CXnProperty* aValue, TInt aReferenceValue )
       
  8761     {
       
  8762     return ::VerticalPixelValueL( aValue, aReferenceValue,
       
  8763         *iCurrentGraphicsDevice, iVerticalUnitInPixels );
       
  8764     }
       
  8765 
       
  8766 // -----------------------------------------------------------------------------
       
  8767 // CXnUiEngineImpl::HorizontalPixelValueL()
       
  8768 // -----------------------------------------------------------------------------
       
  8769 //
       
  8770 TInt CXnUiEngineImpl::HorizontalPixelValueL(
       
  8771     CXnProperty* aValue, TInt aReferenceValue )
       
  8772     {
       
  8773     return ::HorizontalPixelValueL( aValue, aReferenceValue,
       
  8774         *iCurrentGraphicsDevice, iHorizontalUnitInPixels );
       
  8775     }
       
  8776 
       
  8777 // -----------------------------------------------------------------------------
       
  8778 // CXnUiEngineImpl::VerticalTwipValueL()
       
  8779 // -----------------------------------------------------------------------------
       
  8780 //
       
  8781 TInt CXnUiEngineImpl::VerticalTwipValueL( CXnProperty* aValue,
       
  8782     TInt aReferenceValue )
       
  8783     {
       
  8784     return iCurrentGraphicsDevice->VerticalPixelsToTwips(
       
  8785         VerticalPixelValueL( aValue, aReferenceValue ) );
       
  8786     }
       
  8787 
       
  8788 // -----------------------------------------------------------------------------
       
  8789 // CXnUiEngineImpl::HorizontalTwipValueL()
       
  8790 // -----------------------------------------------------------------------------
       
  8791 //
       
  8792 TInt CXnUiEngineImpl::HorizontalTwipValueL( CXnProperty* aValue,
       
  8793     TInt aReferenceValue )
       
  8794     {
       
  8795     return iCurrentGraphicsDevice->HorizontalPixelsToTwips(
       
  8796         HorizontalPixelValueL( aValue, aReferenceValue ) );
       
  8797     }
       
  8798 
       
  8799 // -----------------------------------------------------------------------------
       
  8800 // CXnUiEngineImpl::ViewManager()
       
  8801 // -----------------------------------------------------------------------------
       
  8802 //
       
  8803 CXnViewManager* CXnUiEngineImpl::ViewManager()
       
  8804     {
       
  8805     return &iViewManager;
       
  8806     }
       
  8807 
       
  8808 // -----------------------------------------------------------------------------
       
  8809 // CXnUiEngineImpl::ActiveView()
       
  8810 // -----------------------------------------------------------------------------
       
  8811 //
       
  8812 CXnNode* CXnUiEngineImpl::ActiveView()
       
  8813     {
       
  8814     return iViewManager.ViewNode();
       
  8815     }
       
  8816 
       
  8817 // -----------------------------------------------------------------------------
       
  8818 // CXnUiEngineImpl::RefreshMenuL
       
  8819 // Refresh current menu
       
  8820 // -----------------------------------------------------------------------------
       
  8821 //
       
  8822 void CXnUiEngineImpl::RefreshMenuL()
       
  8823     {
       
  8824     if ( iLayoutControl & XnLayoutControl::ERefreshMenu )
       
  8825         {
       
  8826         iKeyEventDispatcher->RefreshMenuL();
       
  8827         iLayoutControl &= ~XnLayoutControl::ERefreshMenu;
       
  8828         }
       
  8829     }
       
  8830 
       
  8831 // -----------------------------------------------------------------------------
       
  8832 // CXnUiEngineImpl::AddDirtyNodeL
       
  8833 // Add a dirty node. This method must be called via CXnNode SetDirtyL
       
  8834 // -----------------------------------------------------------------------------
       
  8835 //
       
  8836 void CXnUiEngineImpl::AddDirtyNodeL( CXnNode* aNode, TInt aLevel )
       
  8837     {
       
  8838     CXnViewData& data( iViewManager.ActiveViewData() );
       
  8839     
       
  8840     if ( !aNode || ( aNode != RootNode() && !data.Plugin( aNode->Namespace() ) ) )
       
  8841         {
       
  8842         // No node, or node doesn't belong to active view namespace
       
  8843         return;
       
  8844         }
       
  8845 
       
  8846     if ( aNode->Type()->Type() == KMenuBar )
       
  8847         {
       
  8848         iLayoutControl |= XnLayoutControl::ERefreshMenu;
       
  8849         return;
       
  8850         }
       
  8851 
       
  8852     if ( iLayoutControl & XnLayoutControl::EViewDirty )
       
  8853         {
       
  8854         // nothing to do
       
  8855         return;
       
  8856         }
       
  8857 
       
  8858     if ( aLevel == XnDirtyLevel::ERender )
       
  8859         {
       
  8860         if( aNode == RootNode() )        
       
  8861             {
       
  8862             TXnDirtyRegion* dirtyRegion = FindDirtyRegionL( *iCurrentView );
       
  8863             if( dirtyRegion )
       
  8864                 {
       
  8865                 dirtyRegion->iRegion.Clear();                
       
  8866                 }
       
  8867             aNode = iCurrentView;        
       
  8868             }
       
  8869 
       
  8870         // Add to redraw list
       
  8871         AddToRedrawListL( aNode );
       
  8872         }
       
  8873     else
       
  8874         {
       
  8875         // Add to dirty list for relayout and redraw
       
  8876         AddToDirtyListL( aNode );
       
  8877         }
       
  8878     }
       
  8879 
       
  8880 // -----------------------------------------------------------------------------
       
  8881 // CXnUiEngineImpl::ScreenDeviceSize
       
  8882 // Get the size of the current screen device
       
  8883 // -----------------------------------------------------------------------------
       
  8884 //
       
  8885 TSize CXnUiEngineImpl::ScreenDeviceSize() const
       
  8886     {
       
  8887     if ( iCurrentGraphicsDevice )
       
  8888         {
       
  8889         return iCurrentGraphicsDevice->SizeInPixels();
       
  8890         }
       
  8891 
       
  8892     return TSize( 0, 0 );
       
  8893     }
       
  8894 
       
  8895 // -----------------------------------------------------------------------------
       
  8896 // CXnUiEngineImpl::IsDialogDisplaying
       
  8897 // Whether the dialog is displaying or not.
       
  8898 // -----------------------------------------------------------------------------
       
  8899 //
       
  8900 TBool CXnUiEngineImpl::IsDialogDisplaying()
       
  8901     {    
       
  8902     return iAppUiAdapter.IsDisplayingControlBetweenPriorities(
       
  8903         ECoeStackPriorityDialog - 1, KXnStackPriorityKeyEventDispatcher - 1 );
       
  8904     }
       
  8905 
       
  8906 // -----------------------------------------------------------------------------
       
  8907 // CXnUiEngineImpl::HandleResourceChangeL
       
  8908 // Handles a change to the control's resources of type aType
       
  8909 // -----------------------------------------------------------------------------
       
  8910 //
       
  8911 void CXnUiEngineImpl::HandleResourceChangeL( TInt aType )
       
  8912     {    
       
  8913     if ( iMenuNode )
       
  8914         {
       
  8915         CXnControlAdapter* adapter( iMenuNode->Control() );
       
  8916         
       
  8917         if ( adapter )
       
  8918             {
       
  8919             adapter->HandleResourceChange( aType );
       
  8920             }        
       
  8921         }
       
  8922     
       
  8923     if ( aType == KEikDynamicLayoutVariantSwitch )
       
  8924         {
       
  8925         // Must return here if there is no current view or
       
  8926         // controladapterlist. This may occur when the phone
       
  8927         // is booted for the first time and the location/date
       
  8928         // query is visible.
       
  8929         if ( !ActiveView() )
       
  8930             {
       
  8931             return;
       
  8932             }
       
  8933 
       
  8934         // Update client rect
       
  8935         SetClientRectL( iAppUiAdapter.ClientRect(), EFalse );
       
  8936 
       
  8937         iEditMode->HandleScreenDeviceChangedL();
       
  8938         
       
  8939         // Force relayout
       
  8940         DisableRenderUiLC();
       
  8941         
       
  8942         RootNode()->SetDirtyL();
       
  8943 
       
  8944         ReportScreenDeviceChangeL();
       
  8945                 
       
  8946         for ( TInt i = 0; i < iControlAdapterList->Count(); i++ )
       
  8947             {
       
  8948             CXnControlAdapter* adapter( ( *iControlAdapterList )[i] );
       
  8949             
       
  8950             adapter->HandleScreenDeviceChangedL();
       
  8951             }
       
  8952         
       
  8953         ForceRenderUIL();
       
  8954         
       
  8955         CleanupStack::PopAndDestroy();
       
  8956         }
       
  8957     else if ( aType == KAknsMessageSkinChange )
       
  8958         {
       
  8959         // Force relayout
       
  8960         DisableRenderUiLC();
       
  8961         
       
  8962         RootNode()->SetDirtyL();
       
  8963 
       
  8964         for ( TInt i = 0; i < iControlAdapterList->Count(); i++ )
       
  8965             {
       
  8966             CXnControlAdapter* adapter( ( *iControlAdapterList )[i] );
       
  8967             adapter->SkinChanged();
       
  8968             }
       
  8969 
       
  8970         ForceRenderUIL();
       
  8971         
       
  8972         CleanupStack::PopAndDestroy();
       
  8973         }
       
  8974     }
       
  8975 
       
  8976 // -----------------------------------------------------------------------------
       
  8977 // CXnUiEngineImpl::IsMenuDisplaying
       
  8978 // Checks whether the menu is displaying or not.
       
  8979 // -----------------------------------------------------------------------------
       
  8980 //
       
  8981 TBool CXnUiEngineImpl::IsMenuDisplaying()
       
  8982     {
       
  8983     return iKeyEventDispatcher->IsMenuFocused();
       
  8984     }
       
  8985 
       
  8986 // -----------------------------------------------------------------------------
       
  8987 // CXnUiEngineImpl::MenubarNode
       
  8988 // Returns menubar node
       
  8989 // -----------------------------------------------------------------------------
       
  8990 //
       
  8991 CXnNode* CXnUiEngineImpl::MenuBarNode() const
       
  8992     {
       
  8993     return iMenuNode;
       
  8994     }
       
  8995 
       
  8996 // -----------------------------------------------------------------------------
       
  8997 // CXnUiEngineImpl::StylusPopupNode
       
  8998 // Returns stylus popup node
       
  8999 // -----------------------------------------------------------------------------
       
  9000 //
       
  9001 CXnNode* CXnUiEngineImpl::StylusPopupNode() const
       
  9002     {
       
  9003     return iStylusPopupNode;
       
  9004     }
       
  9005 
       
  9006 // -----------------------------------------------------------------------------
       
  9007 // CXnUiEngineImpl::AddPassiveFocusedNode
       
  9008 // -----------------------------------------------------------------------------
       
  9009 //
       
  9010 void CXnUiEngineImpl::AddPassiveFocusedNodeL( CXnNode* aNode )
       
  9011     {
       
  9012     iKeyEventDispatcher->AddPassiveFocusedNodeL( aNode );
       
  9013     }
       
  9014 
       
  9015 // -----------------------------------------------------------------------------
       
  9016 // CXnUiEngineImpl::RemovePassiveFocusedNode
       
  9017 // -----------------------------------------------------------------------------
       
  9018 //
       
  9019 void CXnUiEngineImpl::RemovePassiveFocusedNodeL( CXnNode* aNode )
       
  9020     {
       
  9021     iKeyEventDispatcher->RemovePassiveFocusedNodeL( aNode );
       
  9022     }
       
  9023 
       
  9024 // -----------------------------------------------------------------------------
       
  9025 // CXnUiEngineImpl::AddPassiveFocusedNode
       
  9026 // -----------------------------------------------------------------------------
       
  9027 //
       
  9028 void CXnUiEngineImpl::ClearPassiveFocusedNodesL()
       
  9029     {
       
  9030     iKeyEventDispatcher->ClearPassiveFocusedNodesL();
       
  9031     }
       
  9032 
       
  9033 // -----------------------------------------------------------------------------
       
  9034 // SetNodeDroppedL()
       
  9035 // Sets node's dropped state
       
  9036 // -----------------------------------------------------------------------------
       
  9037 //
       
  9038 void CXnUiEngineImpl::SetNodeDroppedL( CXnNode& aNode, TInt aDropped ) const
       
  9039     {
       
  9040     if ( aDropped != XnNodeLayout::ENone )
       
  9041         {
       
  9042         CXnNode* parent( aNode.Parent() );
       
  9043         TInt parentAdaptive( parent->IsAdaptive( ETrue ) );
       
  9044 
       
  9045         if ( iLayoutPhase == XnLayoutPhase::EMeasure )
       
  9046             {
       
  9047             if ( !parentAdaptive )
       
  9048                 {
       
  9049                 // Only adaptive childs can be dropped during measure phase
       
  9050                 return;
       
  9051                 }
       
  9052             }
       
  9053 
       
  9054 #ifdef _XN3_DEBUG_
       
  9055         CXnProperty* id( aNode.IdL() );
       
  9056 
       
  9057         if ( id )
       
  9058             {
       
  9059             TBuf8< 256 > debug;
       
  9060             debug.Append( _L8( "Node id: " ) );
       
  9061             debug.Append( id->StringValue() );
       
  9062             debug.Append( _L8( " will be set to dropped" ) );
       
  9063             RDebug::RawPrint( debug );
       
  9064             }
       
  9065 #endif
       
  9066 
       
  9067         // Node will be dropped
       
  9068         aNode.SetDropped( aDropped );
       
  9069 
       
  9070         // Get ride of its rects
       
  9071         ClearRects( aNode );
       
  9072 
       
  9073         if ( parentAdaptive )
       
  9074             {
       
  9075             // Is there adaptive content left after dropping?
       
  9076             CheckAdaptiveContentL( *parent, parent->Rect().Size() );
       
  9077             }
       
  9078         }
       
  9079     else
       
  9080         {
       
  9081         // Node is no more dropped
       
  9082         aNode.SetDropped( aDropped );
       
  9083         }
       
  9084     }
       
  9085 
       
  9086 // -----------------------------------------------------------------------------
       
  9087 // CheckAdaptiveContentL()
       
  9088 // Checks if node is adaptive, but doesn't have any content
       
  9089 // -----------------------------------------------------------------------------
       
  9090 //
       
  9091 void CXnUiEngineImpl::CheckAdaptiveContentL(
       
  9092     CXnNode& aNode, TSize aAvailableSize ) const
       
  9093     {
       
  9094     TInt adaptive( aNode.IsAdaptive( ETrue ) );
       
  9095     TBool isEmpty( EFalse );
       
  9096 
       
  9097     if ( adaptive )
       
  9098         {
       
  9099         if ( aAvailableSize == TSize::EUninitialized )
       
  9100             {
       
  9101             // Use max available size
       
  9102             aAvailableSize = ScreenDeviceSize();
       
  9103             }
       
  9104 
       
  9105         const TDesC8& name( aNode.Type()->Type() );
       
  9106 
       
  9107         if ( name == KBoxNodeName || name == KButtonNodeName )
       
  9108             {
       
  9109             RPointerArray< CXnNode > displayedChildren;
       
  9110             CleanupClosePushL( displayedChildren );
       
  9111 
       
  9112             TInt displayedCount( DisplayedChildrenCountL(
       
  9113                 aNode, &displayedChildren ) );
       
  9114 
       
  9115             if ( displayedCount == 0 )
       
  9116                 {
       
  9117                 isEmpty = ETrue;
       
  9118                 }
       
  9119             else
       
  9120                 {
       
  9121                 for ( TInt i = 0; i < displayedChildren.Count(); i++ )
       
  9122                     {
       
  9123                     CheckAdaptiveContentL( *displayedChildren[i],
       
  9124                         aAvailableSize );
       
  9125                     }
       
  9126 
       
  9127                 if ( DisplayedChildrenCountL( aNode ) == 0 )
       
  9128                     {
       
  9129                     isEmpty = ETrue;
       
  9130                     }
       
  9131                 }
       
  9132 
       
  9133             CleanupStack::PopAndDestroy( &displayedChildren );
       
  9134             }
       
  9135 
       
  9136         if ( isEmpty )
       
  9137             {
       
  9138             // No content available, drop adaptive node
       
  9139             SetNodeDroppedL( aNode, XnNodeLayout::EDropped );
       
  9140             }
       
  9141         }
       
  9142     }
       
  9143 
       
  9144 // -----------------------------------------------------------------------------
       
  9145 // CXnUiEngineImpl::AddFocusCandidateL
       
  9146 // -----------------------------------------------------------------------------
       
  9147 //
       
  9148 void CXnUiEngineImpl::AddFocusCandidateL( CXnNode* aNode )
       
  9149     {
       
  9150     if ( !aNode )
       
  9151         {
       
  9152         return;
       
  9153         }
       
  9154     TInt index( iFocusCandidateList.Find( aNode ) );
       
  9155     if ( index == KErrNotFound )
       
  9156         {
       
  9157         iFocusCandidateList.AppendL( aNode );
       
  9158         }
       
  9159     }
       
  9160 
       
  9161 // -----------------------------------------------------------------------------
       
  9162 // CXnUiEngineImpl::IsLayoutDisabled
       
  9163 // -----------------------------------------------------------------------------
       
  9164 //
       
  9165 TBool CXnUiEngineImpl::IsLayoutDisabled()
       
  9166     {
       
  9167     if ( !iCurrentView )
       
  9168         {
       
  9169         return ETrue;
       
  9170         }
       
  9171     
       
  9172     TBool retval( EFalse );
       
  9173     if ( iDisableCount > 0 &&
       
  9174          !( iLayoutControl & XnLayoutControl::EIgnoreState ) )
       
  9175         {
       
  9176         retval =  ETrue;
       
  9177         }
       
  9178     return retval;
       
  9179     }
       
  9180 
       
  9181 // -----------------------------------------------------------------------------
       
  9182 // AddToRedrawListL
       
  9183 // Mark Control's appearance to be redrawn
       
  9184 // -----------------------------------------------------------------------------    
       
  9185 //
       
  9186 void CXnUiEngineImpl::AddToRedrawListL( CXnNode* aNode, TRect aRect )
       
  9187     {   
       
  9188     CXnControlAdapter* aAdapter( aNode->Control() );
       
  9189            
       
  9190     if( !aAdapter ) 
       
  9191         {
       
  9192         return;
       
  9193         }
       
  9194 
       
  9195     if( aRect != TRect::EUninitialized )
       
  9196         {
       
  9197         // This is the new rect which will be set by layout algo
       
  9198         AddRedrawRectL( aRect, *aNode );
       
  9199         }
       
  9200     
       
  9201     TRect rect( aAdapter->Rect() );
       
  9202             
       
  9203     if( rect == TRect::EUninitialized )
       
  9204         {
       
  9205         // Don't add uninitialized rect
       
  9206         return;
       
  9207         }
       
  9208 
       
  9209     /*
       
  9210     if( aNode->IsStateSet( XnPropertyNames::style::common::KFocus ) )
       
  9211         {
       
  9212         const TDesC8& name( aNode->DomNode()->Name() );
       
  9213 
       
  9214         if( name == KPlugin )
       
  9215             {
       
  9216             rect.Grow( KFocusGrowValue, KFocusGrowValue );
       
  9217             }
       
  9218         else
       
  9219             {
       
  9220             TRect marginRect( aNode->MarginRect() );
       
  9221             
       
  9222             CXnNode* parent( aNode->Parent() );
       
  9223             
       
  9224             for( ; parent; parent = parent->Parent() )
       
  9225                 {
       
  9226                 if( parent->DomNode()->Name() == KPlugin )
       
  9227                     {
       
  9228                     if( parent->Rect() == marginRect )
       
  9229                         {
       
  9230                         rect.Grow( KFocusGrowValue, KFocusGrowValue );
       
  9231                         }
       
  9232                     
       
  9233                     break;
       
  9234                     } 
       
  9235                 }                
       
  9236             }
       
  9237         }
       
  9238         */
       
  9239     GrowIfNeeded(aNode, rect);    
       
  9240     AddRedrawRectL( rect, *aNode );                          
       
  9241     }
       
  9242 
       
  9243 // -----------------------------------------------------------------------------
       
  9244 // AddToDirtyListL
       
  9245 // Mark node to dirty list for relayout
       
  9246 // -----------------------------------------------------------------------------
       
  9247 //
       
  9248 void CXnUiEngineImpl::AddToDirtyListL( CXnNode* aNode )
       
  9249     {
       
  9250     CXnNode* nodeToRedrawList( aNode );
       
  9251     CXnNode* nodeToDirtyList( aNode );
       
  9252 
       
  9253     if ( aNode == RootNode() )
       
  9254         {
       
  9255         // Force relayout and redraw from current view
       
  9256         iDirtyList.Reset();
       
  9257         iDirtyList.AppendL( iCurrentView );
       
  9258         TXnDirtyRegion* dirtyRegion = FindDirtyRegionL( *iCurrentView );
       
  9259         if( dirtyRegion )
       
  9260             {
       
  9261             dirtyRegion->iRegion.Clear();        
       
  9262             }
       
  9263         iLayoutControl |= XnLayoutControl::EViewDirty;
       
  9264         nodeToDirtyList = nodeToRedrawList = iCurrentView;
       
  9265         nodeToDirtyList->ClearRenderedAndLaidOut();
       
  9266 
       
  9267         // Add to draw list for redraw
       
  9268         AddToRedrawListL( nodeToRedrawList );
       
  9269         }
       
  9270     else
       
  9271         {
       
  9272         if ( !IsAbsoluteL( *aNode ) && !IsNodeTooltip( *aNode ) )
       
  9273             {
       
  9274             // Check adaptives in normal flow
       
  9275             CXnNode* oldest( NULL );
       
  9276             CXnNode* adaptive( aNode );
       
  9277 
       
  9278             if ( !aNode->IsAdaptive( ETrue ) )
       
  9279                 {
       
  9280                 adaptive = aNode->Parent();
       
  9281                 }
       
  9282 
       
  9283             for ( ; adaptive && adaptive->IsAdaptive( ETrue );
       
  9284                 adaptive = adaptive->Parent() )
       
  9285                 {
       
  9286                 oldest = adaptive;
       
  9287                 }
       
  9288 
       
  9289             // Now we have found the oldest adaptive node if present
       
  9290             if ( oldest )
       
  9291                 {
       
  9292                 nodeToRedrawList = nodeToDirtyList = adaptive;
       
  9293                 }
       
  9294             }
       
  9295 
       
  9296         RPointerArray< CXnNode > dirtyList;
       
  9297         CleanupClosePushL( dirtyList );
       
  9298         TInt count( iDirtyList.Count() );
       
  9299         TBool found;
       
  9300 
       
  9301         // first, check that aNode's children are not in the dirty array
       
  9302         for ( TInt i = 0; i < count; ++i )
       
  9303             {
       
  9304             found = EFalse;
       
  9305             CXnNode* candidate( iDirtyList[i] );
       
  9306 
       
  9307             for ( CXnNode* node = candidate->Parent(); node && !found;
       
  9308                 node = node->Parent() )
       
  9309                 {
       
  9310                 if ( nodeToDirtyList == node )
       
  9311                     {
       
  9312                     found = ETrue;
       
  9313                     }
       
  9314                 }
       
  9315 
       
  9316             if ( !found )
       
  9317                 {
       
  9318                 // Put candidate back to list as child is not found
       
  9319                 dirtyList.AppendL( candidate );
       
  9320                 }
       
  9321             }
       
  9322 
       
  9323         found = EFalse;
       
  9324 
       
  9325         // second, check that aNode's parent is not in dirty array
       
  9326         for ( TInt i = 0; i < count && !found; ++i )
       
  9327             {
       
  9328             CXnNode* candidate( iDirtyList[i] );
       
  9329 
       
  9330             for ( CXnNode* node = nodeToDirtyList; node && !found;
       
  9331                 node = node->Parent() )
       
  9332                 {
       
  9333                 if ( node == candidate )
       
  9334                     {
       
  9335                     found = ETrue;
       
  9336                     }
       
  9337                 }
       
  9338             }
       
  9339 
       
  9340         if ( !found && iDirtyList.Find( nodeToDirtyList ) == KErrNotFound )
       
  9341             {
       
  9342             // Add node to dirty list as parent is neither found
       
  9343             dirtyList.AppendL( nodeToDirtyList );
       
  9344             nodeToDirtyList->ClearRenderedAndLaidOut();
       
  9345             
       
  9346             // Add to draw list for redraw
       
  9347             AddToRedrawListL( nodeToRedrawList );
       
  9348             }
       
  9349 
       
  9350         // finally update the dirty list
       
  9351         iDirtyList.Reset();
       
  9352         iDirtyList = dirtyList;
       
  9353 
       
  9354         CleanupStack::Pop( &dirtyList );
       
  9355         }
       
  9356     }
       
  9357 
       
  9358 // -----------------------------------------------------------------------------
       
  9359 // CXnUiEngineImpl::SetClientRectL
       
  9360 // -----------------------------------------------------------------------------
       
  9361 //
       
  9362 void CXnUiEngineImpl::SetClientRectL( TRect aRect, TBool aDrawNow )
       
  9363     {
       
  9364     if ( iClientRect != aRect )
       
  9365         {
       
  9366         iClientRect = aRect;
       
  9367         
       
  9368         UpdateInternalUnits( iHorizontalUnitInPixels, iVerticalUnitInPixels,
       
  9369             iClientRect );
       
  9370         
       
  9371         iAppUiAdapter.ViewAdapter().BgControl().SetRect( aRect );
       
  9372         
       
  9373         if ( aDrawNow )
       
  9374             {
       
  9375             RootNode()->SetDirtyL();
       
  9376             iUiEngine->RenderUIL();
       
  9377             }
       
  9378         }
       
  9379     }
       
  9380 
       
  9381 // -----------------------------------------------------------------------------
       
  9382 // CXnUiEngineImpl::ClientRect
       
  9383 // -----------------------------------------------------------------------------
       
  9384 //
       
  9385 TRect CXnUiEngineImpl::ClientRect() const
       
  9386     {
       
  9387     return iClientRect;
       
  9388     }
       
  9389 
       
  9390 // -----------------------------------------------------------------------------
       
  9391 // CXnUiEngineImpl::Editor
       
  9392 // -----------------------------------------------------------------------------
       
  9393 //
       
  9394 CXnEditor* CXnUiEngineImpl::Editor()const
       
  9395     {
       
  9396     return &iViewManager.Editor();
       
  9397     }
       
  9398 
       
  9399 // -----------------------------------------------------------------------------
       
  9400 // CXnUiEngineImpl::EditMode
       
  9401 // -----------------------------------------------------------------------------
       
  9402 //
       
  9403 CXnEditMode* CXnUiEngineImpl::EditMode()
       
  9404     {
       
  9405     return iEditMode;
       
  9406     }
       
  9407 
       
  9408 // -----------------------------------------------------------------------------
       
  9409 // CXnUiEngineImpl::StartLayoutFromL
       
  9410 // -----------------------------------------------------------------------------
       
  9411 //
       
  9412 CXnNode* CXnUiEngineImpl::StartLayoutFromL()
       
  9413     {
       
  9414     if ( iLayoutControl & XnLayoutControl::EViewDirty )
       
  9415         {
       
  9416         return iCurrentView;
       
  9417         }
       
  9418 
       
  9419     RPointerArray< CXnNode >parentArray;
       
  9420     CleanupClosePushL( parentArray );
       
  9421     TInt dirtyCount = iDirtyList.Count();
       
  9422     CXnNode* startNode( NULL );
       
  9423 
       
  9424     for ( TInt dirtyIndex = 0; dirtyIndex < dirtyCount; dirtyIndex++ )
       
  9425         {
       
  9426         startNode = iDirtyList[dirtyIndex];
       
  9427 
       
  9428         for ( ;startNode && startNode != iCurrentView; )
       
  9429             {
       
  9430             parentArray.Append( startNode->Parent() );
       
  9431             startNode = startNode->Parent();
       
  9432             }
       
  9433         }
       
  9434 
       
  9435     TInt parentCount = parentArray.Count();
       
  9436 
       
  9437     for ( TInt parentIndex = 0; parentIndex < parentCount; parentIndex++ )
       
  9438         {
       
  9439         TInt parentsFound = 0;
       
  9440 
       
  9441         for ( TInt checkIndex = 0; checkIndex < parentCount; checkIndex++ )
       
  9442             {
       
  9443             if ( parentArray[parentIndex] == parentArray[checkIndex] )
       
  9444                 {
       
  9445                 parentsFound++;
       
  9446 
       
  9447                 if ( parentsFound == dirtyCount )
       
  9448                     {
       
  9449                     startNode = parentArray[parentIndex];
       
  9450                     CleanupStack::PopAndDestroy( &parentArray );
       
  9451                     return startNode;
       
  9452                     }
       
  9453                 }
       
  9454             }
       
  9455         }
       
  9456 
       
  9457     CleanupStack::PopAndDestroy( &parentArray );
       
  9458 
       
  9459     return iCurrentView;
       
  9460     }
       
  9461 
       
  9462 // -----------------------------------------------------------------------------
       
  9463 // CXnUiEngineImpl::Plugins
       
  9464 // -----------------------------------------------------------------------------
       
  9465 //
       
  9466 RPointerArray< CXnNode >* CXnUiEngineImpl::Plugins()
       
  9467     {
       
  9468     return &iViewManager.PluginNodes();
       
  9469     }
       
  9470 
       
  9471 // -----------------------------------------------------------------------------
       
  9472 // CXnUiEngineImpl::ForceRenderUIL
       
  9473 // -----------------------------------------------------------------------------
       
  9474 //
       
  9475 void CXnUiEngineImpl::ForceRenderUIL( TBool aLayoutOnly )
       
  9476     {
       
  9477     iLayoutControl |= XnLayoutControl::EIgnoreState;
       
  9478     if ( aLayoutOnly )
       
  9479         {
       
  9480         LayoutUIL();
       
  9481         }
       
  9482     else
       
  9483         {
       
  9484         LayoutUIL();
       
  9485         RenderUIL();
       
  9486         }
       
  9487     iLayoutControl &= ~XnLayoutControl::EIgnoreState;
       
  9488     }
       
  9489 
       
  9490 // -----------------------------------------------------------------------------
       
  9491 // CXnUiEngineImpl::HitTest
       
  9492 // -----------------------------------------------------------------------------
       
  9493 //
       
  9494 CXnHitTest& CXnUiEngineImpl::HitTest() const
       
  9495     {
       
  9496     return *iHitTest;
       
  9497     }
       
  9498 
       
  9499 // -----------------------------------------------------------------------------
       
  9500 // CXnUiEngineImpl::PositionStylusPopupL
       
  9501 // -----------------------------------------------------------------------------
       
  9502 //
       
  9503 void CXnUiEngineImpl::PositionStylusPopupL( CXnNode& aNode,
       
  9504     CXnNode& aReference, const TPoint& aPosition )
       
  9505     {
       
  9506     CXnDomStringPool& sp( aNode.DomNode()->StringPool() );
       
  9507     TXnDirtyRegion* dirtyRegion = FindDirtyRegionL( *iCurrentView );
       
  9508     RRegion region;
       
  9509     region.Copy( dirtyRegion->iRegion );    
       
  9510     CleanupClosePushL( region );
       
  9511 
       
  9512     // Set initial position to (0, 0) to calculate popup metrics
       
  9513     CXnProperty* top = CXnProperty::NewL(
       
  9514         XnPropertyNames::style::common::KTop, 0,
       
  9515         CXnDomPropertyValue::EPx, sp );
       
  9516     CleanupStack::PushL( top );
       
  9517     aNode.SetPropertyL( top );
       
  9518     CleanupStack::Pop( top );
       
  9519     top = NULL;
       
  9520     CXnProperty* left = CXnProperty::NewL(
       
  9521         XnPropertyNames::style::common::KLeft, 0,
       
  9522         CXnDomPropertyValue::EPx, sp );
       
  9523     CleanupStack::PushL( left );
       
  9524     aNode.SetPropertyL( left );
       
  9525     CleanupStack::Pop( left );
       
  9526     left = NULL;
       
  9527 
       
  9528     // Make it visible
       
  9529     CXnProperty* display = CXnProperty::NewL(
       
  9530         XnPropertyNames::style::common::KDisplay,
       
  9531         XnPropertyNames::style::common::display::KBlock,
       
  9532         CXnDomPropertyValue::EString, sp );
       
  9533     CleanupStack::PushL( display );
       
  9534     aNode.SetPropertyL( display );
       
  9535     CleanupStack::Pop( display );
       
  9536 
       
  9537     if ( !aNode.IsLaidOut() || !aReference.IsLaidOut() )
       
  9538         {
       
  9539         ForceRenderUIL( ETrue );
       
  9540         }
       
  9541 
       
  9542     if ( !aNode.IsLaidOut() || !aReference.IsLaidOut() )
       
  9543         {
       
  9544         // Something went wrong
       
  9545         CleanupStack::PopAndDestroy( &region );
       
  9546 
       
  9547         return;
       
  9548         }
       
  9549 
       
  9550     TRect rectToFit( aReference.MarginRect() );
       
  9551     TRect marginRect( aNode.MarginRect() );
       
  9552 
       
  9553     if ( marginRect.Height() > rectToFit.Height() ||
       
  9554         marginRect.Width() > rectToFit.Width() )
       
  9555         {
       
  9556         // Won't fit even how much is moved
       
  9557         CleanupStack::PopAndDestroy( &region );
       
  9558 
       
  9559         return;
       
  9560         }
       
  9561 
       
  9562     TPoint tl;
       
  9563     TPoint br;
       
  9564 
       
  9565     // Remove the initial 0,0 from redraw region and rects
       
  9566     dirtyRegion->iRegion.Clear();
       
  9567     ClearRects( aNode, ETrue );
       
  9568     CXnProperty* positionHint( aNode.GetPropertyL(
       
  9569         XnPropertyNames::styluspopup::KPositionHint ) );
       
  9570 
       
  9571     // Default
       
  9572     const TDesC8* value( &XnPropertyNames::styluspopup::positionhint::KAbove );
       
  9573 
       
  9574     if ( positionHint )
       
  9575         {
       
  9576         value = &positionHint->StringValue();
       
  9577         }
       
  9578 
       
  9579     if ( *value == XnPropertyNames::styluspopup::positionhint::KAbove )
       
  9580         {
       
  9581         if ( AknLayoutUtils::LayoutMirrored() )
       
  9582             {
       
  9583             tl = aPosition;
       
  9584             tl.iY -= marginRect.Height();
       
  9585             tl.iX -= marginRect.Width();
       
  9586 
       
  9587             // Will the popup float out?
       
  9588             if ( !rectToFit.Contains( tl ) )
       
  9589                 {
       
  9590                 // top left floated out
       
  9591                 TInt y( rectToFit.iTl.iY - tl.iY + 1 );
       
  9592 
       
  9593                 if ( y >= 0 )
       
  9594                     {
       
  9595                     // y-coordinate floated out, move it position
       
  9596                     // so that it will be inside reference rect
       
  9597                     tl.iY = tl.iY + y;
       
  9598                     }
       
  9599 
       
  9600                 TInt x( rectToFit.iTl.iX - tl.iX + 1 );
       
  9601 
       
  9602                 if ( x >= 0 )
       
  9603                     {
       
  9604                     // x-coordinate floated out, move it position
       
  9605                     // so that it will be inside reference rect
       
  9606                     tl.iX = tl.iX + x;
       
  9607                     }
       
  9608                 }
       
  9609             }
       
  9610         else
       
  9611             {
       
  9612             tl = aPosition;
       
  9613             tl.iY -= marginRect.Height();
       
  9614 
       
  9615             // Will the popup float out?
       
  9616             if ( !rectToFit.Contains( tl ) )
       
  9617                 {
       
  9618                 // top left floated out
       
  9619                 TInt y( rectToFit.iTl.iY - tl.iY + 1 );
       
  9620 
       
  9621                 if ( y >= 0 )
       
  9622                     {
       
  9623                     // y-coordinate floated out, move it position
       
  9624                     // so that it will be inside reference rect
       
  9625                     tl.iY = tl.iY + y;
       
  9626                     }
       
  9627                 }
       
  9628 
       
  9629             br = TPoint( tl.iX + marginRect.Width(),
       
  9630                          tl.iY + marginRect.Height() );
       
  9631 
       
  9632             if ( !rectToFit.Contains( br ) )
       
  9633                 {
       
  9634                 // bottom right floated out
       
  9635                 TInt x( br.iX - rectToFit.iBr.iX + 1 );
       
  9636 
       
  9637                 if ( x >= 0 )
       
  9638                     {
       
  9639                     // x-coordinate floated out, move it position
       
  9640                     // so that it will be inside reference rect
       
  9641                     tl.iX = tl.iX - x;
       
  9642                     }
       
  9643                 }
       
  9644             }
       
  9645         }
       
  9646     else // value == XnPropertyNames::styluspopup::positionhint::KBelow
       
  9647         {
       
  9648         if ( AknLayoutUtils::LayoutMirrored() )
       
  9649             {
       
  9650             tl = aPosition;
       
  9651             tl.iX = tl.iX - marginRect.Width();
       
  9652 
       
  9653             if ( !rectToFit.Contains( tl ) )
       
  9654                 {
       
  9655                 // Top left floated out
       
  9656                 TInt x( rectToFit.iTl.iX - tl.iX + 1 );
       
  9657 
       
  9658                 if ( x >= 0 )
       
  9659                     {
       
  9660                     // x-coordinate floated out, move it position
       
  9661                     // so that it will be inside reference rect
       
  9662                     tl.iX = tl.iX + x;
       
  9663                     }
       
  9664                 }
       
  9665 
       
  9666             br = TPoint( tl.iX + marginRect.Width(),
       
  9667                          tl.iY + marginRect.Height() );
       
  9668 
       
  9669             if ( !rectToFit.Contains( br ) )
       
  9670                 {
       
  9671                 // bottom right floated out
       
  9672                 TInt y( br.iY - rectToFit.iBr.iY + 1 );
       
  9673 
       
  9674                 if ( y >= 0 )
       
  9675                     {
       
  9676                     // y-coordinate floated out, move it position
       
  9677                     // so that it will be inside reference rect
       
  9678                     tl.iY = tl.iY - y;
       
  9679                     }
       
  9680                 }
       
  9681             }
       
  9682         else
       
  9683             {
       
  9684             tl = aPosition;
       
  9685             br = TPoint( tl.iX + marginRect.Width(),
       
  9686                          tl.iY + marginRect.Height() );
       
  9687 
       
  9688             // Will the popup float out?
       
  9689             if ( !rectToFit.Contains( br ) )
       
  9690                 {
       
  9691                 // Bottom right floated out
       
  9692                 TInt x( br.iX - rectToFit.iBr.iX + 1 );
       
  9693 
       
  9694                 if ( x >= 0 )
       
  9695                     {
       
  9696                     // x-coordinate floated out, move it position
       
  9697                     // so that it will be inside reference rect
       
  9698                     tl.iX = tl.iX - x;
       
  9699                     }
       
  9700 
       
  9701                 TInt y( br.iY - rectToFit.iBr.iY + 1 );
       
  9702 
       
  9703                 if ( y >= 0 )
       
  9704                     {
       
  9705                     // y-coordinate floated out, move it position
       
  9706                     // so that it will be inside reference rect
       
  9707                     tl.iY = tl.iY - y;
       
  9708                     }
       
  9709                 }
       
  9710             }
       
  9711         }
       
  9712 
       
  9713     // Set positions
       
  9714     top = CXnProperty::NewL(
       
  9715         XnPropertyNames::style::common::KTop, tl.iY,
       
  9716         CXnDomPropertyValue::EPx, sp );
       
  9717     CleanupStack::PushL( top );
       
  9718     aNode.SetPropertyL( top );
       
  9719     CleanupStack::Pop( top );
       
  9720     left = CXnProperty::NewL(
       
  9721         XnPropertyNames::style::common::KLeft, tl.iX,
       
  9722         CXnDomPropertyValue::EPx, sp );
       
  9723     CleanupStack::PushL( left );
       
  9724     aNode.SetPropertyL( left );
       
  9725     CleanupStack::Pop( left );
       
  9726 
       
  9727     // Copy stored region back
       
  9728     dirtyRegion->iRegion.Copy( region );                 
       
  9729     CleanupStack::PopAndDestroy( &region );
       
  9730     }
       
  9731 
       
  9732 // -----------------------------------------------------------------------------
       
  9733 // CXnUiEngineImpl::GetThemeResource
       
  9734 // -----------------------------------------------------------------------------
       
  9735 //
       
  9736 TInt CXnUiEngineImpl::GetThemeResource( const TDesC& aPath, RFile& aFile )
       
  9737     {
       
  9738     TInt err = KErrNone;
       
  9739 
       
  9740     // parse file name and extension
       
  9741     TParsePtrC fileParser( aPath );
       
  9742     TPtrC filepath = fileParser.DriveAndPath();
       
  9743 
       
  9744     RFs session ( CCoeEnv::Static()->FsSession() );
       
  9745 
       
  9746     // open resource file
       
  9747     session.SetSessionPath( filepath );
       
  9748     session.ShareProtected();
       
  9749     err = aFile.Open( session, aPath, EFileShareReadersOnly );
       
  9750     if ( err != KErrNone )
       
  9751         {
       
  9752         aFile.Close();
       
  9753         }
       
  9754 
       
  9755     return err;
       
  9756     }
       
  9757 
       
  9758 // -----------------------------------------------------------------------------
       
  9759 // CXnUiEngineImpl::AnalyseAddedWidgetL
       
  9760 // -----------------------------------------------------------------------------
       
  9761 //
       
  9762 TBool CXnUiEngineImpl::AnalyseAddedWidgetL( CXnNode& aNode )
       
  9763     {
       
  9764     TBool retval( ETrue );
       
  9765 
       
  9766     // Force layout to analyse added widget's dimensions
       
  9767     ForceRenderUIL( ETrue );
       
  9768 
       
  9769     if ( aNode.IsAdaptive( ETrue ) )
       
  9770         {
       
  9771         // If widget place holder (plugin in view.xml) is adaptive, then
       
  9772         // we need to verify that added widget will fit to available space
       
  9773         retval = EFalse;
       
  9774 
       
  9775         CXnNode* parent( aNode.Parent() );
       
  9776         RPointerArray< CXnNode >& children( parent->Children() );
       
  9777         CXnProperty* prop( parent->BlockProgressionL() );
       
  9778 
       
  9779         const TDesC8* bp(
       
  9780             &XnPropertyNames::style::common::block_progression::KTB() );
       
  9781 
       
  9782         if ( prop )
       
  9783             {
       
  9784             bp = &prop->StringValue();
       
  9785             }
       
  9786 
       
  9787         prop = parent->DirectionL();
       
  9788 
       
  9789         const TDesC8* dir(
       
  9790             &XnPropertyNames::style::common::direction::KLTR() );
       
  9791 
       
  9792         if ( prop )
       
  9793             {
       
  9794             // use default
       
  9795             dir = &prop->StringValue();
       
  9796             }
       
  9797 
       
  9798         TSize space( CalculateSpaceUsedByChildrenL( children, *parent,
       
  9799             *bp, *dir, *iCurrentGraphicsDevice, iHorizontalUnitInPixels,
       
  9800             iVerticalUnitInPixels ) );
       
  9801 
       
  9802         TSize parentSize( parent->Rect().Size() );
       
  9803 
       
  9804         if ( *bp == XnPropertyNames::style::common::block_progression::KTB ||
       
  9805              *bp == XnPropertyNames::style::common::block_progression::KBT )
       
  9806             {
       
  9807             if ( parentSize.iHeight >= space.iHeight )
       
  9808                 {
       
  9809                 retval = ETrue;
       
  9810                 }
       
  9811             }
       
  9812         else // LR / RL
       
  9813             {
       
  9814             if ( parentSize.iWidth >= space.iWidth )
       
  9815                 {
       
  9816                 retval = ETrue;
       
  9817                 }
       
  9818             }
       
  9819         }
       
  9820 
       
  9821     return retval;
       
  9822     }
       
  9823 
       
  9824 
       
  9825 
       
  9826 // -----------------------------------------------------------------------------
       
  9827 // CXnUiEngineImpl::NotifyWidgetRemovalL( )
       
  9828 // Notify about widget removal
       
  9829 // -----------------------------------------------------------------------------
       
  9830 //
       
  9831 void CXnUiEngineImpl::NotifyWidgetRemovalL(
       
  9832     const CXnPluginData& /*aPluginData*/ )
       
  9833     {
       
  9834     }
       
  9835 
       
  9836 // -----------------------------------------------------------------------------
       
  9837 // CXnUiEngineImpl::NotifyConfigureWidgetL( )
       
  9838 // -----------------------------------------------------------------------------
       
  9839 //
       
  9840 void CXnUiEngineImpl::NotifyConfigureWidgetL( 
       
  9841     const CHsContentInfo& /*aContentInfo*/, CXnPluginData& /*aPluginData*/ )
       
  9842     {
       
  9843     }
       
  9844 
       
  9845 // -----------------------------------------------------------------------------
       
  9846 // CXnUiEngineImpl::NotifyViewDeactivatedL
       
  9847 // -----------------------------------------------------------------------------
       
  9848 //
       
  9849 void CXnUiEngineImpl::NotifyViewDeactivatedL( 
       
  9850     const CXnViewData& /*aViewData*/ )
       
  9851     {
       
  9852     }
       
  9853 
       
  9854 // -----------------------------------------------------------------------------
       
  9855 // -----------------------------------------------------------------------------
       
  9856 //               
       
  9857 void CXnUiEngineImpl::DisableRenderUiLC()
       
  9858     {         
       
  9859     CleanupStack::PushL( TCleanupItem( EnableRenderUi, this ) );
       
  9860     
       
  9861     iDisableCount++;
       
  9862     }
       
  9863 
       
  9864 // -----------------------------------------------------------------------------
       
  9865 // -----------------------------------------------------------------------------
       
  9866 //               
       
  9867 EXPORT_C /* static */ void CXnUiEngineImpl::EnableRenderUi( TAny* aAny )
       
  9868     {
       
  9869     CXnUiEngineImpl* self = static_cast< CXnUiEngineImpl* >( aAny );
       
  9870     
       
  9871     if ( self->iDisableCount > 0 )
       
  9872         {
       
  9873         self->iDisableCount--;
       
  9874         
       
  9875         if ( self->iDisableCount == 0 )
       
  9876             {
       
  9877             TRAP_IGNORE(                    
       
  9878             // Is menu refresh pending?
       
  9879             if ( ( self->iLayoutControl & XnLayoutControl::ERefreshMenu ) &&
       
  9880                    !self->IsMenuDisplaying() )
       
  9881                 {
       
  9882                 // RefreshMenuL will reset the state flag
       
  9883                 self->RefreshMenuL();
       
  9884                 }
       
  9885 
       
  9886             // Is layout pending?
       
  9887             if ( self->iLayoutControl & XnLayoutControl::ELayoutUI )
       
  9888                 {
       
  9889                 self->LayoutUIL();
       
  9890                 }
       
  9891 
       
  9892             // Is render pending?
       
  9893             if ( self->iLayoutControl & XnLayoutControl::ERenderUI )
       
  9894                 {
       
  9895                 self->RenderUIL();
       
  9896                 }
       
  9897                 );
       
  9898             }
       
  9899         }
       
  9900     }
       
  9901 
       
  9902 
       
  9903 // -----------------------------------------------------------------------------
       
  9904 // -----------------------------------------------------------------------------
       
  9905 //
       
  9906 void CXnUiEngineImpl::ReportScreenDeviceChangeL()
       
  9907     {
       
  9908     CXnNode* trigger( BuildScreenDeviceChangeTriggerNodeLC( *iUiEngine ) );
       
  9909     
       
  9910     // Notify current orientation to iCurrentView
       
  9911     iCurrentView->ReportXuikonEventL( *trigger );
       
  9912 
       
  9913     // Notify also plugins
       
  9914     RPointerArray<CXnNode> plugins = *Plugins();
       
  9915     for( TInt i=0; i<plugins.Count(); i++ )
       
  9916         {
       
  9917         CXnNode* pluginNode = plugins[i];
       
  9918         RPointerArray<CXnNode> pluginChildren = pluginNode->Children();
       
  9919         for( TInt ii=0; ii<pluginChildren.Count(); ii++ )
       
  9920             {
       
  9921             CXnDomNode* widgetNode = pluginChildren[ii]->DomNode();
       
  9922             if( widgetNode && widgetNode->Name() == KWidgetNodeName )
       
  9923                 {
       
  9924                 pluginChildren[ii]->ReportXuikonEventL( *trigger );
       
  9925                 }                    
       
  9926             }
       
  9927         }
       
  9928     
       
  9929     CleanupStack::PopAndDestroy(); // trigger    
       
  9930     }
       
  9931 
       
  9932 // -----------------------------------------------------------------------------
       
  9933 // -----------------------------------------------------------------------------
       
  9934 CCoeControl* CXnUiEngineImpl::WindowOwningControl( CXnNode& aNode )
       
  9935     {
       
  9936     CXnNode* parent = &aNode;
       
  9937     while( parent )
       
  9938         {
       
  9939         CXnControlAdapter* adapter = parent->Control();
       
  9940         if( adapter )
       
  9941             {
       
  9942             if( parent->ViewNodeImpl() && 
       
  9943                 adapter == iCurrentViewControlAdapter )
       
  9944                 {
       
  9945                 return adapter;
       
  9946                 }
       
  9947             else if( adapter->OwnsWindow() )
       
  9948                 {
       
  9949                 if( !IsNodeTooltip( *parent ) )
       
  9950                     {
       
  9951                     return adapter;
       
  9952                     }
       
  9953                 else
       
  9954                     {
       
  9955                     return NULL;
       
  9956                     }                
       
  9957                 }
       
  9958             }
       
  9959         parent = parent->Parent();
       
  9960         }
       
  9961     return NULL;
       
  9962     }
       
  9963 
       
  9964 // -----------------------------------------------------------------------------
       
  9965 // -----------------------------------------------------------------------------
       
  9966 TXnDirtyRegion* CXnUiEngineImpl::FindDirtyRegionL( CXnNode& aNode )
       
  9967     {
       
  9968     CCoeControl* control = WindowOwningControl( aNode );
       
  9969     if( !control )
       
  9970         {
       
  9971         return NULL;
       
  9972         }
       
  9973     for( TInt i=0; i<iRedrawRegions.Count(); i++ )
       
  9974         {
       
  9975         if( iRedrawRegions[i]->iControl == control )
       
  9976             {
       
  9977             return iRedrawRegions[i];
       
  9978             }
       
  9979         }
       
  9980     TXnDirtyRegion* region = new (ELeave) TXnDirtyRegion;
       
  9981     CleanupStack::PushL( region );
       
  9982     region->iControl = control;
       
  9983     iRedrawRegions.AppendL( region );
       
  9984     CleanupStack::Pop();
       
  9985     return region;
       
  9986     }
       
  9987 
       
  9988 // -----------------------------------------------------------------------------
       
  9989 // -----------------------------------------------------------------------------
       
  9990 void CXnUiEngineImpl::AddRedrawRectL( TRect aRect, CXnNode& aNode )
       
  9991     {
       
  9992     TXnDirtyRegion* dirtyReg = FindDirtyRegionL( aNode );
       
  9993     if( dirtyReg )
       
  9994         {
       
  9995         dirtyReg->iRegion.AddRect( aRect );        
       
  9996         dirtyReg->iRegion.Tidy();
       
  9997         }
       
  9998     }
       
  9999 
       
 10000 // -----------------------------------------------------------------------------
       
 10001 // SetEventDispatcher
       
 10002 // -----------------------------------------------------------------------------
       
 10003 void CXnUiEngineImpl::SetEventDispatcher( CXnKeyEventDispatcher* aDispatcher )
       
 10004     {
       
 10005     iKeyEventDispatcher = aDispatcher;
       
 10006     }
       
 10007 
       
 10008 // -----------------------------------------------------------------------------
       
 10009 // NotifyStatusPaneSizeChanged
       
 10010 // -----------------------------------------------------------------------------
       
 10011 void CXnUiEngineImpl::NotifyStatusPaneSizeChanged()
       
 10012     {
       
 10013     TRAP_IGNORE( iUiEngine->SetClientRectL( iAppUiAdapter.ClientRect() ) );
       
 10014     }
       
 10015     
       
 10016 // -----------------------------------------------------------------------------
       
 10017 // NotifyResourceChanged
       
 10018 // -----------------------------------------------------------------------------
       
 10019 void CXnUiEngineImpl::NotifyResourceChanged( TInt aType )
       
 10020     {
       
 10021     TRAP_IGNORE( HandleResourceChangeL( aType ) );
       
 10022     }
       
 10023 
       
 10024 // End of file