webengine/wmlengine/src/lmgr/src/BoxFormat.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 03 May 2010 13:32:15 +0300
changeset 68 92a765b5b3e7
parent 0 dd21522fd290
permissions -rw-r--r--
Revision: 201015 Kit: 201018

/*
* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Description : The class handles formatting of the bidiflowbox
*
*/



#include "cstack.h"
#include "nwx_logger.h"
#include "nw_lmgr_linebox.h"
#include "nw_lmgr_nobrbox.h"
#include "LMgrObjectBoxOOC.h"
#include "nw_gdi_utils.h"
#include "BoxFormat.h"
#include "nw_lmgr_posflowbox.h"
#include "LMgrMarkerText.h"
#include "LMgrMarkerImage.h"
#include "LMgrAnonBlock.h"
#include "GDIDevicecontext.h"
#include "nw_lmgr_accesskey.h"
#include "nw_lmgr_verticaltablecellbox.h"

#define NW_LMgr_maxMarkerLen (NW_Uint8)2

const TInt KFlowBoxLineSpacing = 4;

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_FlowBox_FormatBox(NW_LMgr_Box_t* parentFormatBox,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_PropertyValue_t positionVal;
    NW_LMgr_PropertyValue_t floatVal;
    NW_LMgr_PropertyValue_t propertyVal;
    NW_LMgr_Box_t *flow;
    TBrowserStatusCode status = KBrsrSuccess;

    /* for convenience */
    flow = parentFormatBox;

    positionVal.token = NW_CSS_PropValue_none;
    (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_position,
                                       NW_CSS_ValueType_Token, &positionVal);
    if(positionVal.token == NW_CSS_PropValue_position_absolute &&
		NW_Settings_GetDisableSmallScreenLayout())
        {
//        NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( box );
//        NW_ASSERT(rootBox != NULL);
        // We have to insert a new box into the tree, to keep track of the positioned subtree
        NW_LMgr_ContainerBox_t* parent = NW_LMgr_Box_GetParent(box);
        
		if (!NW_Object_IsInstanceOf(parent, &NW_LMgr_PosFlowBox_Class))
            {
            /*
            NW_LMgr_PosFlowBox_t* newParent = NW_LMgr_PosFlowBox_New(5);
            if (newParent == NULL)
                {
                return KBrsrOutOfMemory;
                }
            TInt childIndex = NW_LMgr_ContainerBox_GetChildIndex (parent, box);
            NW_ASSERT (childIndex >= 0);
            NW_LMgr_ContainerBox_RemoveChild (parent, box);
            NW_LMgr_ContainerBox_InsertChildAt (parent, NW_LMgr_BoxOf(newParent), (NW_ADT_Vector_Metric_t)childIndex);
            NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(newParent), box);

            NW_LMgr_PropertyValue_t visibilityVal;
            visibilityVal.token = NW_CSS_PropValue_visible;
            (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_visibility,
                                                  NW_CSS_ValueType_Token, &visibilityVal);
            NW_LMgr_PropertyValue_t displayVal;
            displayVal.token = NW_CSS_PropValue_display_inline;
            (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_display,
                                                  NW_CSS_ValueType_Token, &displayVal);
           
            if ((visibilityVal.token != NW_CSS_PropValue_hidden) && (displayVal.token != NW_CSS_PropValue_none))
                {
                NW_LMgr_PosFlowBox_AddPositionedBox(newParent);
                //NW_ADT_DynamicVector_InsertAt(rootBox->positionedAbsObjects, &newParent, NW_ADT_Vector_AtEnd);
                }

            */

            // Per CSS2 spec, remove float property, and set display to block:
            // 2. Otherwise, ’position’ has the value ’absolute’ or ’fixed’, ’display’ is set to
            // ’block’ and ’float’ is set to ’none’. The position of the box will be determined
            // by the ’top’, ’right’, ’bottom’ and ’left’ properties and the box’s containing
            // block.
            NW_LMgr_Property_t prop;
            prop.type = NW_CSS_ValueType_Token;
            prop.value.token = NW_CSS_PropValue_none;
            NW_LMgr_Box_SetProperty(box, NW_CSS_Prop_float, &prop);
            return KBrsrContinue;
            }
        }

    /* inline is the default display property value in CSS */
    propertyVal.token = NW_CSS_PropValue_display_inline;
    (void)NW_LMgr_Box_GetPropertyValue (box, NW_CSS_Prop_display,
                                        NW_CSS_ValueType_Token, &propertyVal);

    floatVal.token = NW_CSS_PropValue_none;
    (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_float,
                                       NW_CSS_ValueType_Token, &floatVal);

    //Floats do not work within tables. The Titan workaround was to
    //disable them. The same is done here. Note that this condition is
    //tested by looking at the parentFormatBox.  (e.g. flow).
    if ((floatVal.token != NW_CSS_PropValue_none) &&
        !(NW_Object_IsClass (flow, &NW_LMgr_StaticTableCellBox_Class)) &&
        !(NW_Object_IsClass (flow, &NW_LMgr_VerticalTableCellBox_Class)) )
        {
        status = NW_LMgr_BidiFlowBox_Float(flow, box, parentContext);
        if (status != KBrsrFailure)
        {
            return status;
            }
        }

    switch (propertyVal.token)
        {
        case NW_CSS_PropValue_display_block:
        /* This is handle special case Epoc32 boxes */
        if ( ( NW_Object_IsInstanceOf(box, &NW_FBox_InputBox_Class) ) ||
             ( NW_Object_IsInstanceOf(box, &NW_LMgr_ActiveContainerBox_Class) ) ||
             ( NW_Object_IsDerivedFrom(box, &NW_LMgr_ImgContainerBox_Class) &&
               NW_LMgr_ImgContainerBox_ImageIsBroken( box ) == NW_TRUE ) )
            {
            status = NW_LMgr_BidiFlowBox_FlowInline(flow, box, parentContext);
            }
        else
            {
              if (NW_Object_IsInstanceOf (box, &NW_LMgr_MediaBox_Class) ||
                  NW_Object_IsInstanceOf (box, &NW_FBox_FormBox_Class) ||
                  NW_Object_IsClass (box, &NW_LMgr_EmptyBox_Class) ||
                  NW_Object_IsInstanceOf (box, &NW_LMgr_FormatBox_Class))
                  {
                  status = NW_LMgr_BidiFlowBox_HandleBlock(flow, box, parentContext);
                  }
              //status = NWLMgr_BidiFlowBox_HandleBlock(flow, box, parentContext);
            }
        break;
        case NW_CSS_PropValue_display_inline:
          status = NW_LMgr_BidiFlowBox_FlowInline(flow, box, parentContext);
          break;
        case NW_CSS_PropValue_display_listItem:
        if (NW_Object_IsInstanceOf(box, &NW_FBox_FormBox_Class))
            {
            status = NW_LMgr_BidiFlowBox_FlowInline(flow, box, parentContext);
            }
        else if (NW_Object_IsInstanceOf(box, &NW_LMgr_BidiFlowBox_Class))
            {
            status = NW_LMgr_BidiFlowBox_ListItem(flow, box, parentContext);
            }
        else if  (NW_Object_IsInstanceOf(box, &NW_LMgr_FormatBox_Class))
            {
            status = NW_LMgr_BidiFlowBox_HandleBlock(flow, box, parentContext);
            }
        break;

        case NW_CSS_PropValue_display_directKey:
            status = NW_LMgr_BidiFlowBox_DirectKey(flow, box, parentContext);
            status = NW_LMgr_BidiFlowBox_FlowInline(flow, box, parentContext);
            break;

        case NW_CSS_PropValue_none:
        /* Flow boxes can't handle other display types */
        default:
          break;
        }

    return status;
    }


TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PostFormat(NW_LMgr_Box_t* flow,
        NW_LMgr_ContainerBox_t *whose,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_TRY(status)
        {

        NW_LMgr_Box_t *flowBox = NW_LMgr_BoxOf(flow);


        /* If we are formatting someone else's children, carry on, otherwise .. */

        if (NW_LMgr_ContainerBoxOf(flow) == whose)
            {
            /* Flush any leftover inline content */
            status = NW_LMgr_BidiFlowBox_Flush(flow, parentContext, NW_TRUE);
            _NW_THROW_ON_ERROR(status);

            /* If we are the rootbox, flush all pending floats */
            if (NW_Object_IsClass(flow, &NW_LMgr_RootBox_Class))
                {
                status = NW_LMgr_BidiFlowBox_AdvanceToClear(flow,
                         parentContext,
                         NW_CSS_PropValue_both);
                _NW_THROW_ON_ERROR(status);
                }
            /* Remove the extra pixels of space from the last line */
            if (parentContext->lineNumber > 0 )
                {
                NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( flowBox );
                boxBounds.dimension.height =
                    (NW_GDI_Metric_t)(boxBounds.dimension.height - KFlowBoxLineSpacing);
                NW_LMgr_Box_SetFormatBounds( flowBox, boxBounds );
                }
            /* Flush the pending vertical margin, if there is one */
            if ((NW_Object_IsClass(flowBox, &NW_LMgr_RootBox_Class))
                || IsClosedBottom(flowBox))
                {
                NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( flowBox );
                boxBounds.dimension.height =
                    (NW_GDI_Metric_t)(boxBounds.dimension.height +
                                      parentContext->pendingMargin);
                NW_LMgr_Box_SetFormatBounds( flowBox, boxBounds );
                }

            }
        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }




TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_FlowBox_PostFormatBox(NW_LMgr_Box_t* parentFormatBox,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_PropertyValue_t floatVal;
    NW_LMgr_PropertyValue_t propertyVal;
    NW_LMgr_Box_t *flow;
    TBrowserStatusCode status = KBrsrSuccess;

    /* for convenience */
    flow = parentFormatBox;

    floatVal.token = NW_CSS_PropValue_none;
    (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_float,
                                       NW_CSS_ValueType_Token, &floatVal);

    //Floats do not work within tables in Small Screen OFF mode. The
    //Titan workaround was to disable them. The same is done here. Note
    //that this condition is tested by looking at the parentFormatBox
    //(e.g. flow).
    //  if (floatVal.token != NW_CSS_PropValue_none)
    if ((floatVal.token != NW_CSS_PropValue_none) &&
        !(NW_Object_IsClass (flow, &NW_LMgr_StaticTableCellBox_Class)))
        {
           return NW_LMgr_BidiFlowBox_PostFlowFloat(flow, box, parentContext);
        }

    /* inline is the default display property value in CSS */
    propertyVal.token = NW_CSS_PropValue_display_inline;
    (void)NW_LMgr_Box_GetPropertyValue (box, NW_CSS_Prop_display,
                                        NW_CSS_ValueType_Token, &propertyVal);

    switch (propertyVal.token)
        {
        case NW_CSS_PropValue_display_block:
          /* This is handle special case Epoc32 boxes */
          if ( ( NW_Object_IsInstanceOf(box, &NW_FBox_InputBox_Class) ) ||
               ( NW_Object_IsDerivedFrom(box, &NW_LMgr_ImgContainerBox_Class) &&
                 NW_LMgr_ImgContainerBox_ImageIsBroken( box ) == NW_TRUE ) )
            {
              status = NW_LMgr_BidiFlowBox_PostFlowInline(flow, box, parentContext);
            }
          else
            {
              status = NW_LMgr_BidiFlowBox_PostFlowBlock(flow, box, parentContext);
            }
          break;
        case NW_CSS_PropValue_display_inline:
        case NW_CSS_PropValue_display_directKey:
          status = NW_LMgr_BidiFlowBox_PostFlowInline(flow, box, parentContext);
          break;
        case NW_CSS_PropValue_display_listItem:
          if (NW_Object_IsInstanceOf(box, &NW_FBox_FormBox_Class))
            {
              status = NW_LMgr_BidiFlowBox_PostFlowInline(flow, box, parentContext);
            }
          else
            {
              status = NW_LMgr_BidiFlowBox_PostFlowBlock(flow, box, parentContext);
            }
          break;
        case NW_CSS_PropValue_none:
          /* Flow boxes can't handle other display types */
        default:
          break;
        }

    return status;
    }


/* ----------------------------------------------------------------------------*/
/* Add an inline box to the flow.
 * The typechecking here is done to enforce a box-model schema that
 * defines which kinds of boxes can be flowed in each formatting context.
 */


TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_FlowInline(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_GDI_Metric_t displayWidth;
    CGDIDeviceContext* deviceContext;
    NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( box );
    NW_Bool smallScreenOn = NW_LMgr_RootBox_GetSmallScreenOn( rootBox );

    TBrowserStatusCode status = KBrsrSuccess;

    /* Inline a format */
    if (NW_Object_IsInstanceOf(box, &NW_LMgr_FormatBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInline(flow, box, parentContext);
        }

    /* Inline a table */
    else if (NW_Object_IsClass(box, &NW_LMgr_StaticTableBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInline(flow, box, parentContext);
        }

    /* Inline a container of some other kind */
    else if (NW_Object_IsInstanceOf (box, &NW_LMgr_ContainerBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInlineContainer(flow, NW_LMgr_ContainerBoxOf(box), parentContext);
        }

    /* If the box is a split box, we have already formatted it */
    else if (NW_Object_IsInstanceOf (box, &NW_LMgr_SplitTextBox_Class))
        {
        status = KBrsrSuccess;
        }

    /* Inline a media box */
    else if (NW_Object_IsInstanceOf (box, &NW_LMgr_MediaBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInline(flow, box, parentContext);
        }

    /* Inline a form box */
    else if (NW_Object_IsInstanceOf (box, &NW_FBox_FormBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInline(flow, box, parentContext);

    if( smallScreenOn )
      {
       deviceContext = NW_LMgr_RootBox_GetDeviceContext (rootBox);
       displayWidth = deviceContext->DisplayBounds()->dimension.width;
       if (NW_LMgr_RootBox_IsPageRTL(rootBox))
         {
         displayWidth += RIGHT_ORIGIN;
         }


       NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );

       if(( boxBounds.point.x + boxBounds.dimension.width) >= displayWidth)
       {
           boxBounds.dimension.width = displayWidth - boxBounds.point.x - 4;
           NW_LMgr_Box_SetFormatBounds( box, boxBounds );
       }
     }
   }

    /* Inline a break box */
    else if (NW_Object_IsClass (box, &NW_LMgr_BreakBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleBreak(flow, box, parentContext);
        }

    /* Inline an empty box */
    else if (NW_Object_IsClass (box, &NW_LMgr_EmptyBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInline(flow, box, parentContext);
        }
    /* Inline a object box */ //R
    //else if (ObjectUtils::IsObjectBox (*box, EFalse))
    //  {
    //  status = NW_LMgr_BidiFlowBox_HandleInline(flow, box, parentContext);
    //  }
    /* Otherwise its a schema violation */
    else
        {
        NW_ASSERT(0);
        }
     return status;

    }


TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PostFlowInline(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {

    TBrowserStatusCode status = KBrsrSuccess;

    /* Inline a container of some other kind */
    if (NW_Object_IsInstanceOf (box, &NW_LMgr_ContainerBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleInlineContainerPost(flow, NW_LMgr_ContainerBoxOf(box), parentContext);
        }

    return status;
    }

/* ----------------------------------------------------------------------------*/
/* Add a block formatted box to the flow */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_FlowBlock(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    TBrowserStatusCode status = KBrsrSuccess;

    if (NW_Object_IsInstanceOf (box, &NW_LMgr_MediaBox_Class) ||
        NW_Object_IsInstanceOf (box, &NW_FBox_FormBox_Class) ||
        NW_Object_IsClass (box, &NW_LMgr_EmptyBox_Class) ||
        NW_Object_IsInstanceOf (box, &NW_LMgr_FormatBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleBlock(flow, box, parentContext);
        }

    /* Otherwise its a schema violation */
    else
        {
        NW_ASSERT(0);
        }

    return status;
    }

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PostFlowBlock(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    TBrowserStatusCode status = KBrsrSuccess;

    if (NW_Object_IsInstanceOf (box, &NW_LMgr_MediaBox_Class) ||
        NW_Object_IsInstanceOf (box, &NW_FBox_FormBox_Class) ||
        NW_Object_IsClass (box, &NW_LMgr_EmptyBox_Class) ||
        NW_Object_IsInstanceOf (box, &NW_LMgr_FormatBox_Class))
        {
        status = NW_LMgr_BidiFlowBox_HandleBlockPost(flow, box, parentContext);
        }

    return status;
    }

// This method handles the postformatting for the floated object.
TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PostFlowFloat(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    TBrowserStatusCode status = KBrsrSuccess;

    if (NW_Object_IsInstanceOf (box, &NW_LMgr_MediaBox_Class) ||
        NW_Object_IsInstanceOf (box, &NW_FBox_FormBox_Class) ||
        NW_Object_IsClass (box, &NW_LMgr_EmptyBox_Class) ||
        NW_Object_IsInstanceOf (box, &NW_LMgr_FormatBox_Class))
        {
        NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;

        if (placedFloats == NULL)
            {
            return KBrsrLmgrNotClear;
            }

        // Add the float to the vector
        void *floatPtr = NW_ADT_DynamicVector_InsertAt(placedFloats, &box, NW_ADT_Vector_AtEnd);
        if (floatPtr == NULL)
            {
            status = KBrsrOutOfMemory;
            }
        else
            {
            // Reformat any boxes that are already on the line
            status = NW_LMgr_BidiFlowBox_ReformatLine(flow, parentContext);
            }
        }
    /* Otherwise its a schema violation */
    else
        {
        NW_ASSERT(0);
        }

    return status;
    }


/* --------------------------------------------------------------------------*/
/* Add a float box to the flow */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_Float(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_ADT_DynamicVector_t *pendingFloats = parentContext->pendingFloats;
    NW_ADT_DynamicVector_t *placedFloats = parentContext->pendingFloats;

    NW_TRY(status)
        {
        /* If the float parentContext is not set, remove the box */
        /* This will be the case if a particular flow does not support
         * floats (e.g., table cells) */
        if (pendingFloats == NULL || placedFloats == NULL)
            {
            NW_THROW_STATUS(status, KBrsrFailure);
            }

        /* Float the box */
        if (NW_Object_IsInstanceOf (box, &NW_LMgr_FormatBox_Class) ||
            NW_Object_IsInstanceOf (box, &NW_LMgr_MediaBox_Class) ||
            NW_Object_IsClass (box, &NW_LMgr_StaticTableBox_Class) ||
            NW_Object_IsClass (box, &NW_LMgr_EmptyBox_Class))
            {

            status = NW_LMgr_BidiFlowBox_HandleFloat(flow, box, parentContext);
            if (status == KBrsrLmgrNotClear)
                {
                NW_THROW_OOM_ON_NULL
                (NW_ADT_DynamicVector_InsertAt(pendingFloats, &box,
                                               NW_ADT_Vector_AtEnd),
                 status);
                }
            }
        else
            { /* Otherwise its a schema violation */
            NW_LMgr_Box_RemoveProperty(box, NW_CSS_Prop_float);
            NW_THROW_STATUS(status, KBrsrFailure);
            }
        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }

/* Update the flow to a new line. This updates the formatting context and takes
 * care of any floaters that are either waiting to be placed or are going out
 * of scope.
 *
 * returns: KBrsrSuccess, KBrsrOutOfMemory, KBrsrUnexpectedError
 */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_NewLine(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* context,
        NW_GDI_Metric_t delta,
        NW_Bool indentNewLine)
    {
    NW_ADT_Vector_Metric_t floatCount, index;
    NW_LMgr_Box_t *floatBox;
    NW_ADT_DynamicVector_t *pendingFloats = context->pendingFloats;

    NW_TRY(status)
        {
        /* Add the delta */
        context->y = (NW_GDI_Metric_t)(context->y + delta);

        NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( flow );

        boxBounds.dimension.height = (NW_GDI_Metric_t)
                boxBounds.dimension.height + delta;
        NW_LMgr_Box_SetFormatBounds( flow, boxBounds );

        /* Reset the whitespace flag */
        context->pendingWhitespace = NW_FALSE;

        /* Update the context */
        context->lineStart = NW_LMgr_FlowBox_GetLineStart(flow, context,
                             context->y);
        context->lineEnd = NW_LMgr_FlowBox_GetLineEnd(flow, context, context->y);
        if (context->direction == NW_GDI_FlowDirection_LeftRight)
            {
            if (indentNewLine)
                {
                context->x = (NW_GDI_Metric_t)(context->lineStart
                                               + NW_LMgr_FlowBox_GetIndentation(flow,
                                                                                context));
                }
            else
                {
                context->x = context->lineStart;
                }
            }
        else
            {
            context->x = (NW_GDI_Metric_t)(context->lineEnd
                                           - NW_LMgr_FlowBox_GetIndentation(flow,
                                                                            context));
            }

        /* Flush the current line */
        status = NW_LMgr_BidiFlowBox_Flush(flow, context, NW_TRUE);
        _NW_THROW_ON_ERROR(status);

        /* If the float context is missing, nothing to do */
        if (pendingFloats == NULL)
            {
            NW_THROW_SUCCESS(status);
            }

        /* Look for any pending floats */
        floatCount = NW_ADT_Vector_GetSize(pendingFloats);
        for (index = 0; index < floatCount;)
            {
            floatBox =
                *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (pendingFloats, index);
            NW_ASSERT(floatBox != NULL);

            status = NW_LMgr_BidiFlowBox_HandleFloat(flow, floatBox, context);
            if (status != KBrsrLmgrNotClear)
                {
                (void)NW_ADT_DynamicVector_RemoveAt(pendingFloats, index);
                floatCount--;
                }
            else
                {
                index++;
                }
            }
        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }

NW_Image_AbstractImage_t*
TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetListStyleImage(NW_LMgr_Box_t* flowBox,
        NW_LMgr_PropertyValueToken_t token)
    {
    NW_Image_AbstractImage_t *image;
    NW_LMgr_RootBox_t* rootBox;
    NW_Int8 imageId;

    if (token == 0)
        {
        return NULL;
        }

    /* get the root box */
    rootBox = NW_LMgr_Box_GetRootBox(flowBox);
    if (rootBox == NULL)
        {
        return NULL;
        }

    imageId = NW_Image_Invalid;
    switch (token)
        {
        case NW_CSS_PropValue_square:
        imageId = NW_Image_Square;
        break;
        case NW_CSS_PropValue_disc:
        imageId = NW_Image_Disc;
        break;
        case NW_CSS_PropValue_circle:
        imageId = NW_Image_Circle;
        break;
        default:
        return NULL;
        }

    /* get the image from the canned images dictionary */
    NW_ASSERT(rootBox->cannedImages != NULL);
    image = CONST_CAST(NW_Image_AbstractImage_t*, NW_Image_CannedImages_GetImage( rootBox->cannedImages,
                       imageId ));

    return image;
    }

NW_LMgr_Box_t* TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetMarker(NW_LMgr_Box_t* flowBox,
        NW_LMgr_Box_t* item,
        NW_LMgr_FormatContext_t* context,
        NW_LMgr_PropertyValueToken_t* markerVerticalAlign,
        NW_Bool* style)
    {
    NW_LMgr_Property_t listProp;
    NW_LMgr_Property_t dirProp;
    NW_LMgr_PropertyValue_t listImage;
    NW_Text_t *bulletText = NULL;
    NW_LMgr_Box_t* marker = NULL;
    NW_Ucs2 *bulletString = NULL;
    NW_Image_AbstractImage_t *image = NULL;
    NW_Image_Virtual_t *virtualImage = NULL;

    NW_TRY(status)
        {
        /* By default Left to Right */
        dirProp.value.token = NW_CSS_PropValue_ltr;
        /* Get flow direction */
        dirProp.type = NW_CSS_ValueType_Token;
        status = NW_LMgr_Box_GetProperty(NW_LMgr_BoxOf(flowBox), NW_CSS_Prop_textDirection, &dirProp);

        /* Set the marker default */
        *markerVerticalAlign = NW_CSS_PropValue_baseline;

        *style = NW_FALSE;

        /* Get the list-style-type property */
        listProp.value.token = NW_CSS_PropValue_disc;
        status = NW_LMgr_PropertyList_Get(item->propList,
                                          NW_CSS_Prop_listStyleType,
                                          &listProp);
        if ((status == KBrsrNotFound) || (listProp.type & NW_CSS_ValueType_DefaultStyle))
            {
            status = NW_LMgr_Box_GetProperty(NW_LMgr_BoxOf(item->parent),
                                             NW_CSS_Prop_listStyleType,
                                             &listProp);
            }

        /* Get the list-style-image property */
        listImage.object = NULL;
        (void)NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(item),
                                           NW_CSS_Prop_listStyleImage,
                                           NW_CSS_ValueType_Image, &listImage);

        if (listImage.object != NULL)
            {
            image = (NW_Image_AbstractImage_t*)listImage.object;
            }
        else
            {
            /* Look for a canned image */
            image = (NW_Image_AbstractImage_t*)
                    NW_LMgr_BidiFlowBox_GetListStyleImage(flowBox, listProp.value.token);

            /* Canned images are the only ones that are middle aligned */
            if (image != NULL)
                {
                /* center the image */
                *markerVerticalAlign = NW_CSS_PropValue_middle;
                }
            }

        if (image != NULL)
            {
            NW_GDI_Dimension3D_t size;

            /* Get the virtual image */
            virtualImage = NW_Image_Virtual_New(image);
            NW_THROW_OOM_ON_NULL(virtualImage, status);

            /* Get the width of the image, if it is greater than the default left margin
            replace the image by the default disc this is to fix bug SQ02061441511 - Vishy 06/19/2002 */
            (void) NW_Image_AbstractImage_GetSize (image, &size);

            //
            NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( flowBox );
            //
            if( NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) && ( size.width < NW_VerticalLayout_MinImageWidth1 ||
                size.height < NW_VerticalLayout_MinImageHeight1 ||
                (size.width < NW_VerticalLayout_MinImageWidth2 && size.height > NW_VerticalLayout_MinImageHeight2)))
                {
                /* ignore the image */
                NW_Object_Delete(virtualImage);
                virtualImage = NULL;

                image = (NW_Image_AbstractImage_t*)
                        NW_LMgr_BidiFlowBox_GetListStyleImage(flowBox, listProp.value.token);

                if (image == NULL)
                    {
                    image = (NW_Image_AbstractImage_t*)
                            NW_LMgr_BidiFlowBox_GetListStyleImage(flowBox, NW_CSS_PropValue_disc);
                    }

                /* Canned images are the only ones that are middle aligned */
                if (image != NULL)
                    {
                    /* center the image */
                    *markerVerticalAlign = NW_CSS_PropValue_middle;
                    /* Get the virtual image */
                    virtualImage = NW_Image_Virtual_New(image);
                    NW_THROW_OOM_ON_NULL(virtualImage, status);
                    }
                }
        
            /* Associate the image with the box */
            if (virtualImage != NULL)
                {
                marker = (NW_LMgr_Box_t*)
                         LMgrMarkerImage_New(1, (NW_Image_AbstractImage_t*)virtualImage, NULL, NW_FALSE );
                NW_THROW_OOM_ON_NULL(marker, status);
                // image container takes image ownership
                virtualImage = NULL;
                }
            }
        else if (listProp.value.token != NW_CSS_PropValue_none)
            {
            *style = NW_TRUE;
            switch (listProp.value.token)
                {
                case NW_CSS_PropValue_lowerAlpha:
                bulletString = NW_LMgr_ListBullets_StringFromUInt('a',
                               context->listCount);
                break;
                case NW_CSS_PropValue_upperAlpha:
                bulletString = NW_LMgr_ListBullets_StringFromUInt('A',
                               context->listCount);
                break;
                case NW_CSS_PropValue_lowerRoman:
                bulletString = NW_LMgr_ListBullets_StringFromUInt('r',
                               context->listCount);
                break;
                case NW_CSS_PropValue_upperRoman:
                bulletString = NW_LMgr_ListBullets_StringFromUInt('R',
                               context->listCount);
                break;
                case NW_CSS_PropValue_decimal:
                default:
                bulletString = NW_LMgr_ListBullets_StringFromUInt('d',
                               context->listCount);
                *style = NW_FALSE;
                break;
                }
            if (bulletString)
                {
                bulletText = (NW_Text_t*)NW_Text_UCS2_New(bulletString,
                             NW_Str_Strlen(bulletString),
                             NW_Text_Flags_TakeOwnership);
                bulletString = NULL;
                NW_THROW_OOM_ON_NULL(bulletText, status);

                marker = (NW_LMgr_Box_t*)LMgrMarkerText_New(1, bulletText);
                NW_THROW_OOM_ON_NULL(marker, status);
                }
            else
                {
                NW_THROW_STATUS(status, KBrsrOutOfMemory);
                }
            }
        }
    NW_CATCH(status)
        {
        NW_Mem_Free(bulletString);
        NW_Object_Delete(bulletText);
        NW_Object_Delete(marker);
        NW_Object_Delete(virtualImage);
        marker = NULL;
        }
    NW_FINALLY {
        /* To fix TI compiler warning */
        (void) status;
        return marker;
    }
    NW_END_TRY
    }

NW_LMgr_Box_t* TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetDirectKeyMarker(NW_LMgr_Box_t* item)
    {
    NW_LMgr_AccessKey_t* ak;
    NW_Uint32 val;
    NW_Bool result;
    NW_Ucs2 *string = NULL;
    NW_Text_t *text = NULL;
    NW_LMgr_Box_t* marker = NULL;
    NW_LMgr_PropertyValue_t propValue;

    NW_TRY(status)
        {
        /* Set the marker default */
        status = NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(item),
                                                  NW_CSS_Prop_accesskey,
                                                  NW_CSS_ValueType_Object,
                                                  &propValue);

        if (status == KBrsrSuccess)
            {
            ak = (NW_LMgr_AccessKey_t*)(propValue.object);
            result = NW_LMgr_AccessKey_GetDirectKey (ak, &val);
            if (result == NW_TRUE)
                {
                string = NW_Str_New(NW_LMgr_maxMarkerLen);
                NW_THROW_OOM_ON_NULL(string, status);
                NW_Str_Strcat(string, (const NW_Ucs2 *) &val);
                NW_Str_StrcatConst(string, ".");
                }
            }

        if (string)
          {
          text = (NW_Text_t*)NW_Text_UCS2_New(string,
                 NW_Str_Strlen(string),
                 NW_Text_Flags_TakeOwnership);
          string = NULL;
          NW_THROW_OOM_ON_NULL(text, status);

          marker = (NW_LMgr_Box_t*)LMgrMarkerText_New(1, text);
          NW_THROW_OOM_ON_NULL(marker, status);
          }
       else
          {
          NW_THROW_STATUS(status, KBrsrOutOfMemory);
          }
        }
    NW_CATCH(status)
        {
        NW_Mem_Free(string);
        NW_Object_Delete(text);
        NW_Object_Delete(marker);
        marker = NULL;
        }
    NW_FINALLY
        {
        /* To fix TI compiler warning */
        (void) status;
        return marker;
        }
    NW_END_TRY
    }

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_ListItem(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* item,
        NW_LMgr_FormatContext_t* context)
    {
    NW_LMgr_ContainerBox_t* markerContainer = NULL;
    NW_LMgr_Box_t* marker = NULL;
    NW_Bool insidePosition;
    NW_LMgr_Property_t prop;
    NW_LMgr_Property_t dirProp;
    NW_LMgr_PropertyValue_t propValue;
    NW_LMgr_PropertyValueToken_t markerVerticalAlign;
    NW_GDI_Dimension2D_t extent;
    NW_GDI_Metric_t markerOffset = 2;
    NW_LMgr_Box_t *currentFlow = NULL;
    NW_Bool ownsMarker = NW_TRUE;
    NW_Bool styleMarker = NW_FALSE;
    NW_GDI_Rectangle_t boundsFlow;
    NW_GDI_Metric_t marginFlow, borderFlow, paddingFlow;

    /* Check that the box type is legal */
    if (!NW_Object_IsClass(item, &NW_LMgr_BidiFlowBox_Class))
        {
        return KBrsrSuccess;
        }

    NW_TRY(status)
        {

        // Find the first block element.
        // This is where we're going to put the marker.
        currentFlow = item;
        markerContainer = NW_LMgr_ContainerBoxOf(currentFlow);
        currentFlow = (NW_LMgr_Box_t*)NW_LMgr_BidiFlowBox_GetFirstBlock(currentFlow);
        if (currentFlow && NW_Object_IsInstanceOf(currentFlow, &NW_LMgr_ContainerBox_Class))
            {
            markerContainer = NW_LMgr_ContainerBoxOf(currentFlow);
            }
 
        /* Get list-style-position */
        insidePosition = NW_FALSE;
        propValue.token = NW_CSS_PropValue_outside;
        (void)NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(item),
                                           NW_CSS_Prop_listStylePosition,
                                           NW_CSS_ValueType_Token, &propValue);
        if (propValue.token == NW_CSS_PropValue_inside)
            {
            insidePosition = NW_TRUE;
            }

        /* If this is the first item, check for any start values */
        if (context->itemsHandled == 0)
            {
            status = NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(flow),
                                                  NW_CSS_Prop_listValue,
                                                  NW_CSS_ValueType_Integer,
                                                  &propValue);
            if (status == KBrsrSuccess)
                {
                /* Reset the list count */
                context->listCount = propValue.integer - 1;
                }
            }

        /* Do we have an explicit value set on the item */
        status = NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(item),
                                              NW_CSS_Prop_listValue,
                                              NW_CSS_ValueType_Integer,
                                              &propValue);
        if (status == KBrsrSuccess)
            {
            /* Reset the list count */
            context->listCount = propValue.integer - 1;
            }

        /* Get the appropriate marker */
        marker = NW_LMgr_BidiFlowBox_GetMarker(flow, item, context,
                                              &markerVerticalAlign, &styleMarker);

        /* Increment the list count */
        context->listCount = (NW_Uint32)(context->listCount + 1);

        /* Increment the itemsHandled counter */
        context->itemsHandled ++;

        if (marker)
            {
            // Add the marker to the new cell
            status = NW_LMgr_ContainerBox_InsertChildAt(markerContainer, marker, 0);
            NW_THROW_ON_ERROR(status);

            // Give up ownership of marker
            ownsMarker = NW_FALSE;

            /* Set vertical alignment */
            prop.type = NW_CSS_ValueType_Token;
            prop.value.token = markerVerticalAlign;
            status = NW_LMgr_Box_SetProperty(marker,
                                             NW_CSS_Prop_verticalAlign, &prop);
            NW_THROW_ON_ERROR(status);

            /* Size the marker */
            if (NW_Object_IsInstanceOf(marker, &LMgrMarkerText_Class))
                {
                status = NW_LMgr_AbstractTextBox_GetDimensions(NW_LMgr_AbstractTextBoxOf(marker), &extent);
                }
            else
                {
                status = NW_LMgr_Box_GetMinimumContentSize(marker, &extent);
                }
            NW_THROW_ON_ERROR(status);

            boundsFlow = NW_LMgr_Box_GetFormatBounds( flow );
            marginFlow = (NW_GDI_Metric_t)(NW_LMgr_Box_GetModelProp(flow, NW_CSS_Prop_leftMargin));
            borderFlow = (NW_GDI_Metric_t)(NW_LMgr_Box_GetModelProp(flow, NW_CSS_Prop_leftBorderWidth));
            paddingFlow = (NW_GDI_Metric_t)(NW_LMgr_Box_GetModelProp(flow, NW_CSS_Prop_leftPadding));

            /* By default Left to Right */
            dirProp.value.token = NW_CSS_PropValue_ltr;
            /* Get flow direction */
            dirProp.type = NW_CSS_ValueType_Token;
            status = NW_LMgr_Box_GetProperty(NW_LMgr_BoxOf(item), NW_CSS_Prop_textDirection, &dirProp);

            if (dirProp.value.token == NW_CSS_PropValue_ltr)
                {
                if (!insidePosition)
                    {
                    // If the item has a position of "outside":
                    // according to CSS spec, marker is placed outside the list item;
                    // adjust startMargin to push list item rightward;
                    // make the margin of marker negative, so it'll be on the left of the list item
                    prop.type = NW_CSS_ValueType_Px;
                    prop.value.integer = (NW_GDI_Metric_t)( - extent.width );
                    status = NW_LMgr_Box_SetProperty(marker,
                                                     NW_CSS_Prop_leftMargin, &prop);
                    NW_THROW_ON_ERROR(status);

                    // startMargin = start of content block (boundsFlow.point.x+marginFlow+borderFlow+paddingFlow)
                    //               +
                    //               marker width (extent.width)
                    context->startMargin = (NW_GDI_Metric_t)( boundsFlow.point.x + 
                                                              marginFlow + borderFlow + paddingFlow + 
                                                              extent.width );
                    }
                else
                    {
                    /* Offset the marker */
                    prop.type = NW_CSS_ValueType_Px;
                    prop.value.integer = markerOffset;
                    status = NW_LMgr_Box_SetProperty (marker,
                                                      NW_CSS_Prop_rightMargin, &prop);
                    NW_THROW_ON_ERROR(status);
                    }
                }
            else
                { /* dirProp.value.token == NW_CSS_PropValue_rtl */
                if (!insidePosition)
                    {
                    /* If the item is outside, display it on the left of the list item */
                    prop.type = NW_CSS_ValueType_Px;
                    prop.value.integer = (NW_GDI_Metric_t)( - extent.width );
                    status = NW_LMgr_Box_SetProperty(marker,
                                                     NW_CSS_Prop_rightMargin, &prop);
                    NW_THROW_ON_ERROR(status);

                    context->startMargin = (NW_GDI_Metric_t)( boundsFlow.point.x + 
                                                              marginFlow + borderFlow + paddingFlow + 
                                                              extent.width );
                    }
                else
                    {
                    /* Offset the marker */
                    prop.type = NW_CSS_ValueType_Px;
                    prop.value.integer = markerOffset;
                    status = NW_LMgr_Box_SetProperty (marker,
                                                      NW_CSS_Prop_leftMargin, &prop);
                    NW_THROW_ON_ERROR(status);
                    }
                }
            }

        /* Finally handle the item as a regular block */
        status = NW_LMgr_BidiFlowBox_HandleBlock(flow, item, context);
        NW_THROW_ON_ERROR(status);
        }
    NW_CATCH(status)
        {
        if (ownsMarker)
            {
            NW_Object_Delete(marker);
            }
        }
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_DirectKey(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* item,
        NW_LMgr_FormatContext_t* context)
{
    NW_LMgr_Property_t  prop;
    NW_LMgr_Box_t* marker = NULL;
    NW_LMgr_Box_t *currentFlow = NULL;
    NW_GDI_Dimension2D_t extent;
    NW_Bool ownsMarker = NW_TRUE;

    /* Check that the box type is legal */
    if (!NW_Object_IsClass(item, &NW_LMgr_ActiveContainerBox_Class))
        {
        return KBrsrSuccess;
        }

    NW_TRY(status)
        {

        // Find the first container element.
        // This is where we're going to put the marker.
        currentFlow = item;

        /* Get the appropriate marker */
        marker = NW_LMgr_BidiFlowBox_GetDirectKeyMarker(item);

        if (marker)
            {
            // Add the marker to the new cell
            status = NW_LMgr_ContainerBox_InsertChild (NW_LMgr_ContainerBoxOf(flow), marker, currentFlow);
            NW_THROW_ON_ERROR(status);

            // Give up ownership of marker
            ownsMarker = NW_FALSE;

            /* Set vertical alignment */
            prop.type = NW_CSS_ValueType_Token;
            prop.value.token = NW_CSS_PropValue_baseline;;
            status = NW_LMgr_Box_SetProperty(marker,
                                             NW_CSS_Prop_verticalAlign, &prop);
            NW_THROW_ON_ERROR(status);
            /* Size the marker */
            status = NW_LMgr_Box_GetMinimumContentSize(marker, &extent);
            NW_THROW_ON_ERROR(status);
            }
        status = NW_LMgr_BidiFlowBox_HandleInline(flow, marker, context);
        }
    NW_CATCH(status)
        {
       if ((marker != NULL) && ownsMarker)
            {
            NW_Object_Delete(marker);
            }
        }
    NW_FINALLY
        {
        return status;
        }
    NW_END_TRY
    }

/* method to adjust the current line of elements according to
 * their alignment. This returns the line height resulting from vertical
 * alignment adjustment.
 *
 * returns: KBrsrSuccess, KBrsrOutOfMemory, KBrsrUnexpectedError
 */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_Flush(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext, NW_Bool addLineSpacing)
    {
    NW_GDI_Metric_t lineHeight = 0;
    NW_GDI_Metric_t lineBase = 0;
    NW_LMgr_PropertyValue_t tAlign;
    NW_LMgr_Property_t baselineProp;
    NW_GDI_Metric_t space;
    NW_LMgr_Box_t* lastBox;
    NW_ADT_Vector_Metric_t numBoxes;
    NW_GDI_Metric_t flowBoxLineSpacing;

    NW_REQUIRED_PARAM(flow);
    NW_ASSERT(flow != NULL);
    NW_ASSERT(parentContext != NULL);

    numBoxes = NW_LMgr_LineBox_GetCount(parentContext->currentLine);
    if (numBoxes == 0)
        {
        return KBrsrSuccess;  /* Nothing to flush */
        }

    NW_TRY(status)
        {
        /* We should ignore trailing space at EOL */
        lastBox = NW_LMgr_LineBox_GetBox(parentContext->currentLine, (NW_ADT_Vector_Metric_t)(numBoxes - 1));
        if (lastBox != NULL)
            {
            if (NW_Object_IsInstanceOf(lastBox, &NW_LMgr_AbstractTextBox_Class))
                {
                NW_LMgr_AbstractTextBox_CompressTrailing(NW_LMgr_AbstractTextBoxOf(lastBox));
                }
            }

        /* Get the available space for the line */
        space = ((NW_GDI_Metric_t)
                 (parentContext->lineEnd - parentContext->lineStart));

        /* Get the alignment property, or default to left align if not specified */
        if (parentContext->direction == NW_GDI_FlowDirection_LeftRight)
            {
            tAlign.token = NW_CSS_PropValue_left;
            }
        else
            {
            tAlign.token = NW_CSS_PropValue_right;
            }

            (void) NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(flow),
                                           NW_CSS_Prop_textAlign,
                                           NW_CSS_ValueType_Token, &tAlign);

        /* Shift horizontally */
        (void)NW_LMgr_LineBox_HAlign(parentContext->currentLine, tAlign.token, space,
                                     parentContext->direction);

        /* Position boxes vertically according to their alignment props */
        status = NW_LMgr_LineBox_VAlign(parentContext->currentLine, parentContext->y,
                                        &lineBase, &lineHeight);
        _NW_THROW_ON_ERROR(status);

        /* Flush any inline containers */
        status = NW_LMgr_BidiFlowBox_FlushInlineContainers(flow, parentContext);
        _NW_THROW_ON_ERROR(status);

        /* Clear the line box, we're done */
        status = NW_LMgr_LineBox_Clear(parentContext->currentLine);
        _NW_THROW_ON_ERROR(status);

        /* Update the parentContext */
        flowBoxLineSpacing = (addLineSpacing == NW_TRUE ? KFlowBoxLineSpacing : 0);

        parentContext->y = (NW_GDI_Metric_t)(parentContext->y + lineHeight + flowBoxLineSpacing);

        NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( flow );
        boxBounds.dimension.height =
            (NW_GDI_Metric_t)( boxBounds.dimension.height + lineHeight + flowBoxLineSpacing);
        NW_LMgr_Box_SetFormatBounds( flow, boxBounds );

        /* Set the baseline on the flow box */
        if (parentContext->lineNumber == 0)
            {
            baselineProp.type = NW_CSS_ValueType_Px;
            baselineProp.value.integer = lineBase;
            status = NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(flow),
                                             NW_CSS_Prop_flowBaseline,
                                             &baselineProp);
            _NW_THROW_ON_ERROR(status);
            }
        parentContext->lineNumber = (NW_Uint16)(parentContext->lineNumber + 1);
        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }


/* --------------------------------------------------------------------------*/
/* A method to find the next clear position. */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_AdvanceToClear(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext,
        NW_LMgr_PropertyValueToken_t clearToken)
    {
    NW_ADT_Vector_Metric_t index, floatCount;
    NW_LMgr_PropertyValue_t floatValue;
    NW_GDI_Metric_t clearPosition, floatBottom;
    NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;
    NW_LMgr_FrameInfo_t margin;
    NW_LMgr_Box_t *floatBox;

    NW_REQUIRED_PARAM(flow);

    NW_TRY(status)
        {
        if (placedFloats == NULL)
            {
            NW_THROW_SUCCESS(status);
            }
        if (clearToken == NW_CSS_PropValue_none)
            {
            NW_THROW_SUCCESS(status);
            }
        do
            {
            /* Look for the floats */
            floatCount = NW_ADT_Vector_GetSize(placedFloats);
            clearPosition = parentContext->y;

            for (index = 0; index < floatCount; index++)
                {

                floatBox =
                    *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (placedFloats, index);
                NW_ASSERT(floatBox != NULL);

                floatValue.token = NW_CSS_PropValue_none;
                NW_LMgr_Box_GetPropertyValue(floatBox, NW_CSS_Prop_float,
                                             NW_CSS_ValueType_Token, &floatValue);

                NW_LMgr_Box_GetMargins(floatBox, &margin, NULL, ELMgrFrameBottom );

                if (((floatValue.token == NW_CSS_PropValue_left)
                     && (clearToken == NW_CSS_PropValue_left))
                    || ((floatValue.token == NW_CSS_PropValue_right)
                        && (clearToken == NW_CSS_PropValue_right))
                    || (clearToken == NW_CSS_PropValue_both))
                    {
                    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( floatBox );
                    floatBottom = (NW_GDI_Metric_t)(boxBounds.point.y
                                                    + boxBounds.dimension.height
                                                    + margin.bottom);
                    if (floatBottom > clearPosition)
                        {
                        clearPosition = floatBottom;
                        }
                    }
                }

            if (clearPosition > parentContext->y)
                {
                status = NW_LMgr_BidiFlowBox_NewLine(flow, parentContext,
                         (NW_GDI_Metric_t)(clearPosition
                                           - parentContext->y), NW_TRUE);
                _NW_THROW_ON_ERROR(status);
                }

            /* The newline method might have emitted a pending float.  If that was
               the case, we should check that we're still clear */
            }
        while (floatCount
               != NW_ADT_Vector_GetSize(placedFloats));
        }
    NW_CATCH(status)
    {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }

/* --------------------------------------------------------------------------*/
/* A method to find the next clear position during reformatting a line. */
TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_AdvanceToClearReformat(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext,
        NW_LMgr_PropertyValueToken_t clearToken)
    {
    NW_ADT_Vector_Metric_t index, floatCount;
    NW_LMgr_PropertyValue_t floatValue;
    NW_GDI_Metric_t clearPosition, floatBottom;
    NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;
    NW_LMgr_FrameInfo_t margin;
    NW_LMgr_Box_t *floatBox;
	NW_GDI_Metric_t delta;

    NW_REQUIRED_PARAM(flow);

    NW_TRY(status)
        {
        if (placedFloats == NULL)
            {
            NW_THROW_SUCCESS(status);
            }
        if (clearToken == NW_CSS_PropValue_none)
            {
            NW_THROW_SUCCESS(status);
            }
        do
            {
            /* Look for the floats */
            floatCount = NW_ADT_Vector_GetSize(placedFloats);
            clearPosition = parentContext->y;

            for (index = 0; index < floatCount; index++)
                {

                floatBox =
                    *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (placedFloats, index);
                NW_ASSERT(floatBox != NULL);

                floatValue.token = NW_CSS_PropValue_none;
                NW_LMgr_Box_GetPropertyValue(floatBox, NW_CSS_Prop_float,
                                             NW_CSS_ValueType_Token, &floatValue);

                NW_LMgr_Box_GetMargins(floatBox, &margin, NULL, ELMgrFrameBottom );

                if (((floatValue.token == NW_CSS_PropValue_left)
                     && (clearToken == NW_CSS_PropValue_left))
                    || ((floatValue.token == NW_CSS_PropValue_right)
                        && (clearToken == NW_CSS_PropValue_right))
                    || (clearToken == NW_CSS_PropValue_both))
                    {
                    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( floatBox );
                    floatBottom = (NW_GDI_Metric_t)(boxBounds.point.y
                                                    + boxBounds.dimension.height
                                                    + margin.bottom);
                    if (floatBottom > clearPosition)
                        {
                        clearPosition = floatBottom;
                        }
                    }
                }

            if (clearPosition > parentContext->y)
                {
                /*status = NW_LMgr_BidiFlowBox_NewLine(flow, parentContext,
                         (NW_GDI_Metric_t)(clearPosition
                                           - parentContext->y), NW_TRUE);
                _NW_THROW_ON_ERROR(status);*/

				 /* Add the delta */

				delta = clearPosition - parentContext->y;

				parentContext->y = (NW_GDI_Metric_t)(parentContext->y + delta);

				NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( flow );

				boxBounds.dimension.height = (NW_GDI_Metric_t)
                boxBounds.dimension.height + delta;
				NW_LMgr_Box_SetFormatBounds( flow, boxBounds );

				/* Reset the whitespace flag */
				parentContext->pendingWhitespace = NW_FALSE;

				/* Update the context */
				parentContext->lineStart = NW_LMgr_FlowBox_GetLineStart(flow, parentContext,
									 parentContext->y);
				parentContext->lineEnd = NW_LMgr_FlowBox_GetLineEnd(flow, parentContext, parentContext->y);
				if (parentContext->direction == NW_GDI_FlowDirection_LeftRight)
					{
						parentContext->x = (NW_GDI_Metric_t)(parentContext->lineStart
													   + NW_LMgr_FlowBox_GetIndentation(flow,
																						parentContext));

					}
				else
					{
					parentContext->x = (NW_GDI_Metric_t)(parentContext->lineEnd
												   - NW_LMgr_FlowBox_GetIndentation(flow,
																					parentContext));
					}

				/* Flush the current line */
				status = NW_LMgr_BidiFlowBox_Flush(flow, parentContext, NW_TRUE);
				_NW_THROW_ON_ERROR(status);
                }


            /* The newline method might have emitted a pending float.  If that was
               the case, we should check that we're still clear */
            }
        while (floatCount
               != NW_ADT_Vector_GetSize(placedFloats));
        }
    NW_CATCH(status)
    {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }
NW_GDI_Metric_t TLMgr_BoxFormatter::NW_LMgr_FlowBox_GetIndentation(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_GDI_Metric_t indent = 0;
    NW_LMgr_PropertyValue_t tIndent;
    NW_LMgr_PropertyValue_t tAlign;

    if (parentContext->lineNumber == 0)
        {
        /* Get the text alignment */
        tAlign.token = NW_CSS_PropValue_left;
        NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(flow), NW_CSS_Prop_textAlign,
                                     NW_CSS_ValueType_Token, &tAlign);

        if (tAlign.token == NW_CSS_PropValue_left)
            {
            /* Get the text indent */
            tIndent.integer = 0;
            NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(flow), NW_CSS_Prop_textIndent,
                                         NW_CSS_ValueType_Px, &tIndent);

            indent = (NW_GDI_Metric_t)tIndent.integer;
            }
        }
    return indent;
    }

/* A method that takes care of any inline containers whose children
 * were formatted by the flow and are now in the line box.
 * The method does two things: (1) if a container did not fit
 * entirely on the line, this container is split;  (2) all
 * containers whose children are in the line box are resized.
 */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_FlushInlineContainers(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_LineBox_t *lineBox = parentContext->currentLine;
    NW_LMgr_PropertyValue_t propValue;
    NW_LMgr_Box_t *child = NULL;
    NW_LMgr_Box_t *nextSibling = NULL;
    NW_LMgr_Box_t *splitBox;
    NW_LMgr_ContainerBox_t *parent = NULL;
    NW_LMgr_ContainerBox_t *parentTemp;
    NW_ADT_Vector_Metric_t childCount;
    NW_ADT_Vector_Metric_t childIndex;
    NW_ADT_Vector_Metric_t i, boxesOnLine;
    NW_ADT_Vector_Metric_t index;
    NW_Bool ltr;

    NW_TRY(status)
        {
        boxesOnLine = NW_LMgr_LineBox_GetCount(parentContext->currentLine);

        // Return if no boxes in the line.
        if (boxesOnLine == 0)
            {
            NW_THROW_SUCCESS(status);
            }

        // Determine the direction -- LTR or RTL.
        ltr = (parentContext->direction == NW_GDI_FlowDirection_LeftRight)
            ? NW_TRUE : NW_FALSE;

        // First, split any containers that did not fit on the line.

        // Get the last box on the line. The index of which depends on
        // direction. If LTR, it truely is the last box.  If RTL, it's
        // reversed and is 0.
        index = (NW_ADT_Vector_Metric_t)((ltr) ? (boxesOnLine - 1) : 0);
        child = NW_LMgr_LineBox_GetBox(lineBox, index);
        

        // Traverse tree up to containing flow and split any inline containers
        // found on the way.
        parent = NW_LMgr_Box_GetParent(child);

        while (parent && parent != NW_LMgr_ContainerBoxOf(flow))
            {

            // Get the display property.
            propValue.token = NW_CSS_PropValue_display_inline;
            (void)NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(parent),
                                               NW_CSS_Prop_display,
                                               NW_CSS_ValueType_Token, &propValue);

            // Check that the container is inline.
            if (propValue.token == NW_CSS_PropValue_display_inline || propValue.token == NW_CSS_PropValue_display_directKey)
                {

                childCount = NW_LMgr_ContainerBox_GetChildCount(parent);
                childIndex = NW_LMgr_ContainerBox_GetChildIndex(parent, child);

                //If <br/> tag in <a> and there is empty text before closing 
                //tags then don't create text box of zero dimension as it will 
                //not hightlight the anchor text in <a> tag.

                 if( (parent && NW_Object_IsInstanceOf( parent, &NW_LMgr_ActiveContainerBox_Class ) )
                     && ( child && NW_Object_IsInstanceOf(child, &NW_LMgr_BreakBox_Class) ) )
                 {
                  if (childIndex < childCount - 1)
                  {
                   nextSibling = 
                       NW_LMgr_ContainerBox_GetChild (parent,(NW_ADT_Vector_Metric_t) ( childIndex + 1));
                   if(nextSibling && NW_Object_IsClass( nextSibling, &NW_LMgr_TextBox_Class ) )
                   {
                    NW_Text_t* aTextData = NW_LMgr_TextBox_GetText(NW_LMgr_TextBoxOf(nextSibling) );
                    NW_Text_Length_t len = NW_Text_GetCharCount(aTextData);
                    NW_Uint32 i =0;
                    NW_Bool onlySplChar = NW_TRUE;
                 

                    //If there is only special character then don't create split box.

                     if(aTextData)
                     {
                      NW_Ucs2* storage = (NW_Ucs2*)NW_Text_GetUCS2Buffer (aTextData, 0, NULL, NULL);

                      for(i=0; i < len ; i++)
                       {
                        
                        if(storage[i] <=  ( (NW_Ucs2) 0x0020) )
                        {
                            continue;
                        }
                        else
                        {
                            onlySplChar = NW_FALSE;
                            break;
                        }
                       }//end for(..)
                     }//end if(aTextData) 

                    if(onlySplChar)
                    {
					 //Remove this box from the box tree list, since <br/> is already a whilespace
						status = NW_LMgr_ContainerBox_RemoveChild(parent,nextSibling);
						_NW_THROW_ON_ERROR(status);
						childCount = NW_LMgr_ContainerBox_GetChildCount(parent);
						childIndex = NW_LMgr_ContainerBox_GetChildIndex(parent, child);
                    }//endof onlySplChar
                   }//endof nextSibling
                  }//endof childIndex
                 }

                // If current box is not the last box in the container,
                // split the container.
                if (childIndex < childCount - 1)
                    {

                    splitBox =
                        NW_LMgr_ContainerBox_SplitAtIndex(parent,
                                                          ((NW_ADT_Vector_Metric_t)
                                                           (childIndex + 1)));
                    NW_THROW_OOM_ON_NULL(splitBox, status);

                    // Insert the new box into the parent.
                    parentTemp = NW_LMgr_Box_GetParent((NW_LMgr_Box_t*)parent);
                    status = NW_LMgr_ContainerBox_InsertChild(parentTemp,
                             splitBox,
                             (NW_LMgr_Box_t*)parent);
                    _NW_THROW_ON_ERROR(status);

                    // Make the split box current.
                    parent = NW_LMgr_ContainerBoxOf(splitBox);
                    }
				else
					{
					if (NW_Object_IsClass (child, &NW_LMgr_BreakBox_Class))
						//If the current box is the last box in the container, 
						//don't split the container nor its parent.
						break; 
					}
                }//if (childIndex < childCount - 1)

            // Move one level up.
            child = NW_LMgr_BoxOf(parent);
            parent = NW_LMgr_Box_GetParent(child);
            }//endof while

        // Second, resize all inline container boxes.

        // Iterate through the children, starting from the 'last' one so as to
        // properly handle any embedded containers. The actual last one depends
        // on the direction -- LTR or RTL.
        for (i = 0; i < boxesOnLine; i++)
            {
            // Determine actual index based on the direction.
            index = (NW_ADT_Vector_Metric_t)((ltr) ? ((boxesOnLine - i) - 1) : i);
            NW_ASSERT(index < 0x7FFF);
            // Get the child.
            child = NW_LMgr_LineBox_GetBox(lineBox, index);
            // Resize all containers that start with this child.
            parent = NW_LMgr_Box_GetParent(child);

            while (parent && parent != NW_LMgr_ContainerBoxOf(flow))
                {
                if (NW_Object_IsClass(parent, &NW_LMgr_ContainerBox_Class) ||
                    NW_Object_IsClass(parent, &NW_LMgr_ActiveContainerBox_Class) ||
                    NW_Object_IsClass(parent, &NW_LMgr_NobrBox_Class))
                    {
                    // Only resize if this is the first child.
                    childIndex = NW_LMgr_ContainerBox_GetChildIndex(parent, child);
                    if (childIndex == 0)
                        {
                        status = NW_LMgr_Box_Resize((NW_LMgr_Box_t*)NW_LMgr_BoxOf(parent), parentContext);
                        _NW_THROW_ON_ERROR(status);
                        }
                    else
                        {
                        // The current container was not resized; therefore,
                        // no point in resizing any parent containers. Break
                        // so as to not continue climbing up the hierarchy.
                        break;
                        }
                    }

                // Move one level up.
                child = NW_LMgr_BoxOf(parent);
                parent = NW_LMgr_Box_GetParent(child);
                }
            }
        }
    NW_CATCH(status)
        {}
    NW_FINALLY
        {
        return status;
        }
    NW_END_TRY
    }

/* ----------------------------------------------------------------------------*/
/* method to reformat the line box after a float has been inserted.
 */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_ReformatLine(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_LineBox_t *lineBox = parentContext->currentLine;
    NW_ADT_Vector_Metric_t index, boxesOnLine;
    NW_LMgr_Box_t *childBox;
    NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( NW_LMgr_BoxOf( flow ) );

    // Reset the parentContext
    parentContext->x =
        (NW_GDI_Metric_t)(parentContext->lineStart
                          + NW_LMgr_FlowBox_GetIndentation(flow, parentContext));

    if( NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) )
        {
        CGDIDeviceContext* deviceContext;
        const NW_GDI_Rectangle_t* rectangle;

        deviceContext = NW_LMgr_RootBox_GetDeviceContext( rootBox );
        rectangle = deviceContext->DisplayBounds();

        // Reformat Line is created after placing floated objects. If we have already
        // occupied more than 2/3rd of display width, we want to push next objects on the next line
       if ((parentContext->lineEnd - parentContext->lineStart) < (rectangle->dimension.width) / 3)
            {
			NW_LMgr_PropertyValueToken_t clearToken =
				(parentContext->x > (2*rectangle->dimension.width) / 3)?
				NW_CSS_PropValue_left: NW_CSS_PropValue_right;
            NW_LMgr_BidiFlowBox_AdvanceToClearReformat(flow, parentContext, clearToken);
            }
        }

    boxesOnLine = NW_LMgr_LineBox_GetCount(parentContext->currentLine);

    /* If there are no boxes in the line, then no work to do */
    if (boxesOnLine == 0)
        {
        return KBrsrSuccess;
        }

    NW_TRY(status)
        {
        parentContext->currentLine = NW_LMgr_LineBox_New();
        NW_THROW_OOM_ON_NULL(parentContext->currentLine, status);

        /* Reformat each box */
        for (index = 0; index < boxesOnLine; index++)
            {
            childBox = NW_LMgr_LineBox_GetBox(lineBox, index);
            status = NW_LMgr_BidiFlowBox_HandleInline(flow, childBox, parentContext);
            _NW_THROW_ON_ERROR(status)
            }

        /* Lose the old linebox */
        NW_Object_Delete(lineBox);
        }
    NW_CATCH(status)
        {
        if (parentContext->currentLine != NULL)
            {
            NW_Object_Delete(parentContext->currentLine);
            parentContext->currentLine = lineBox;
            }
        }
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }


NW_LMgr_Box_t* TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetFirstBlock(NW_LMgr_Box_t* flow)
    {
    NW_LMgr_ContainerBox_t *flowContainer = NW_LMgr_ContainerBoxOf(flow);
    NW_LMgr_Box_t *child;
    NW_LMgr_Box_t *firstBlock = NULL;
    NW_LMgr_PropertyValue_t propValue, floatVal;
    NW_Uint16 childIndex, childCount;

    childCount = NW_LMgr_ContainerBox_GetChildCount(flowContainer);
    for (childIndex = 0; childIndex < childCount; childIndex++)
        {
        child = NW_LMgr_ContainerBox_GetChild(flowContainer, childIndex );

        floatVal.token = NW_CSS_PropValue_none;
        (void)NW_LMgr_Box_GetPropertyValue(child, NW_CSS_Prop_float, NW_CSS_ValueType_Token, &floatVal);
        if (floatVal.token == NW_CSS_PropValue_none)
            {
            firstBlock = child;
            break;
            }
        }

    if (firstBlock == NULL)
        {
        return NULL;
        }
    else
        {
        propValue.token = NW_CSS_PropValue_display_inline;
        (void)NW_LMgr_Box_GetPropertyValue(firstBlock, NW_CSS_Prop_display,
                                           NW_CSS_ValueType_Token, &propValue);

        if ((propValue.token == NW_CSS_PropValue_display_block) ||
            (propValue.token == NW_CSS_PropValue_display_listItem))
            {
            return firstBlock;
            }
        else
            {
            return NULL;
            }
        }
    }



NW_LMgr_Box_t* TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetLastBlock(NW_LMgr_Box_t* flow)
    {
    NW_LMgr_ContainerBox_t *flowContainer = NW_LMgr_ContainerBoxOf(flow);
    NW_LMgr_Box_t *lastBlock = NULL;
    NW_Int16 childCount;
    NW_Int16 childIndex;
    NW_LMgr_PropertyValue_t propValue;
    NW_LMgr_PropertyValue_t floatVal;
    NW_LMgr_Box_t *child;

    childCount = NW_LMgr_ContainerBox_GetChildCount(flowContainer);

    if (childCount == 0)
        {
        return NULL;
        }
    else
        {
        for (childIndex = (NW_Int16)(childCount - 1); childIndex >= 0; childIndex --)
            {
            child = NW_LMgr_ContainerBox_GetChild(flowContainer, (NW_ADT_Vector_Metric_t)childIndex);

            floatVal.token = NW_CSS_PropValue_none;
            (void)NW_LMgr_Box_GetPropertyValue(child, NW_CSS_Prop_float, NW_CSS_ValueType_Token, &floatVal);
            if (floatVal.token == NW_CSS_PropValue_none)
                {
                lastBlock = child;
                }
            }
        }

    if (lastBlock == NULL)
        {
        return NULL;
        }
    else
        {
        propValue.token = NW_CSS_PropValue_display_inline;
        (void)NW_LMgr_Box_GetPropertyValue(lastBlock, NW_CSS_Prop_display,
                                           NW_CSS_ValueType_Token, &propValue);

        if ((propValue.token == NW_CSS_PropValue_display_block) ||
            (propValue.token == NW_CSS_PropValue_display_listItem))
            {
            return lastBlock;
            }
        else
            {
            return NULL;
            }
        }
    }

NW_Bool TLMgr_BoxFormatter::IsClosedTop(NW_LMgr_Box_t *box)
    {
    return (NW_Bool)
           ((NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_topPadding) > 0) ||
            ((NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_topBorderWidth) > 0) &&
             (NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_topBorderStyle) != NW_CSS_PropValue_none) &&
             (NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_topBorderStyle) != NW_CSS_PropValue_hidden)));
    }

NW_Bool TLMgr_BoxFormatter::IsClosedBottom(NW_LMgr_Box_t *box)
    {
    return (NW_Bool)
           ((NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_bottomPadding) > 0) ||
            ((NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_bottomBorderWidth) > 0) &&
             (NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_bottomBorderStyle) != NW_CSS_PropValue_none) &&
             (NW_LMgr_Box_GetModelProp(box, NW_CSS_Prop_bottomBorderStyle) != NW_CSS_PropValue_hidden)));
    }


/* ----------------------------------------------------------------------------*/
/* A method to account for any collapsing margins.  We look at
 * any block boxes adjacent to the current box and updated the
 * format context accordingly.
 */



TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_CollapseMargins(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext,
        NW_ADT_Vector_Metric_t index)
    {
    NW_LMgr_Box_t *current;
    NW_GDI_Metric_t topMargin = 0, bottomMargin = 0;
    NW_GDI_Metric_t finalPositive = 0, finalNegative = 0, finalMargin = 0;

    /* All boxes sharing a horizontal edge will have their margins collapsed. */
    NW_TRY(status)
        {
        if ((index == 0)
            && (NW_Object_IsInstanceOf(flow, &NW_LMgr_RootBox_Class)
                || IsClosedTop(NW_LMgr_BoxOf(flow))))
            {

            finalPositive = finalNegative = finalMargin = 0;

            current = box;
            do
                {
                topMargin =
                    (NW_GDI_Metric_t)NW_LMgr_Box_GetModelProp(current,
                            NW_CSS_Prop_topMargin);

                if (topMargin < 0)
                    {
                    finalNegative =
                        (NW_GDI_Metric_t)((finalNegative < -topMargin)
                                          ? -topMargin : finalNegative);
                    }
                else
                    {
                    finalPositive =
                        (NW_GDI_Metric_t)((finalPositive < topMargin)
                                          ? topMargin : finalPositive);
                    }

                if (IsClosedTop(current) ||
                    (!NW_Object_IsInstanceOf(current, &NW_LMgr_FlowBox_Class)))
                    {
                    break;
                    }
                }
            while ((current =
                        NW_LMgr_BidiFlowBox_GetFirstBlock(current))
                   != NULL);

            finalMargin = (NW_GDI_Metric_t)(finalPositive - finalNegative);

            /* Advance the current position */
            status = NW_LMgr_BidiFlowBox_NewLine(flow, parentContext, finalMargin, NW_TRUE);
            _NW_THROW_ON_ERROR(status);
            }
        else if (index != 0)
            {

            if (parentContext->pendingMargin < 0)
                {
                finalPositive = 0;
                finalNegative = (NW_GDI_Metric_t)( -(parentContext->pendingMargin));
                }
            else
                {
                finalPositive = parentContext->pendingMargin;
                finalNegative = 0;
                }

            current = box;
            do
                {
                topMargin =
                    (NW_GDI_Metric_t)NW_LMgr_Box_GetModelProp(current,
                            NW_CSS_Prop_topMargin);
                if (topMargin < 0)
                    {
                    finalNegative = (NW_GDI_Metric_t)((finalNegative < -topMargin)
                                                      ? -topMargin : finalNegative);
                    }
                else
                    {
                    finalPositive = (NW_GDI_Metric_t)((finalPositive < topMargin)
                                                      ? topMargin : finalPositive);
                    }
                if (IsClosedTop(current) ||
                    (!NW_Object_IsInstanceOf(current, &NW_LMgr_FlowBox_Class)))
                    {
                    break;
                    }
                }
            while ((current =
                        NW_LMgr_BidiFlowBox_GetFirstBlock(current))
                   != NULL);

            /* Calculate the collapsed margin */
            finalMargin = (NW_GDI_Metric_t)(finalPositive - finalNegative);

            /* Advance the current position & reset any pending margin */
            status = NW_LMgr_BidiFlowBox_NewLine (flow, parentContext, finalMargin, NW_TRUE);
            _NW_THROW_ON_ERROR(status);
            parentContext->pendingMargin = 0;
            }

        /* Calculate the bottom margin */
        current = box;
        do
            {
            bottomMargin =
                (NW_GDI_Metric_t)NW_LMgr_Box_GetModelProp(current,
                        NW_CSS_Prop_bottomMargin);

            if (current == box)
                {
                if (bottomMargin < 0)
                    {
                    finalPositive = 0;
                    finalNegative = (NW_GDI_Metric_t)( -bottomMargin);
                    }
                else
                    {
                    finalPositive = bottomMargin;
                    finalNegative = 0;
                    }
                }
            else
                {
                if (bottomMargin < 0)
                    {
                    finalNegative = (NW_GDI_Metric_t)((finalNegative < -bottomMargin)
                                                      ? -bottomMargin : finalNegative);
                    }
                else
                    {
                    finalPositive = (NW_GDI_Metric_t)((finalPositive < bottomMargin)
                                                      ? bottomMargin : finalPositive);
                    }
                }
            if (IsClosedBottom(current)
                || (!NW_Object_IsInstanceOf(current, &NW_LMgr_FlowBox_Class)))
                {
                break;
                }
            }
        while ((current =
                    NW_LMgr_BidiFlowBox_GetLastBlock(current))
               != NULL);

        /* Calculate the collapsed margin */
        finalMargin = (NW_GDI_Metric_t)(finalPositive - finalNegative);

        /* Set the parentContext variable */
        parentContext->pendingMargin = finalMargin;
        }
    NW_CATCH(status)
    {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }



/* --------------------------------------------------------------------------*/
/* Private method to calculate the left margin of the flow at position y.
 */

NW_GDI_Metric_t TLMgr_BoxFormatter::NW_LMgr_FlowBox_GetLineStart(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext,
        NW_GDI_Metric_t where)
    {
    NW_ADT_Vector_Metric_t floatCount, index;
    NW_GDI_Metric_t leftMargin;
    NW_GDI_Metric_t floatRight, floatTop, floatBottom;
    NW_LMgr_Box_t *floatBox;
    NW_LMgr_PropertyValue_t floatValue;
    NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;
    NW_LMgr_FrameInfo_t margin;

    NW_REQUIRED_PARAM(flow);

    leftMargin = parentContext->startMargin;

    if (placedFloats == NULL)
        {
        return leftMargin;
        }

    floatCount = NW_ADT_Vector_GetSize(NW_ADT_VectorOf(placedFloats));

    for (index = 0; index < floatCount; index++)
        {

        floatBox =
            *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (placedFloats, index);
        if( floatBox != flow )
          {
          NW_ASSERT(floatBox != NULL);

          floatValue.integer = NW_CSS_PropValue_none;
          NW_LMgr_Box_GetPropertyValue(floatBox, NW_CSS_Prop_float,
                                       NW_CSS_ValueType_Token, &floatValue);

          if (floatValue.token == NW_CSS_PropValue_left)
              {

              NW_LMgr_Box_GetMargins(floatBox, &margin, NULL, ELMgrFrameTop|ELMgrFrameBottom|ELMgrFrameRight );

              NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( floatBox );
              floatTop = (NW_GDI_Metric_t)(boxBounds.point.y - margin.top);
              floatBottom = (NW_GDI_Metric_t)(boxBounds.point.y
                                              + boxBounds.dimension.height
                                              + margin.bottom);
              floatRight = (NW_GDI_Metric_t)(boxBounds.point.x
                                             + boxBounds.dimension.width
                                             + margin.right);

              if ((where >= floatTop)
                  && (where < floatBottom)
                  && (leftMargin < floatRight))
                  {
                  leftMargin = floatRight;
                  }
              }
          }
        }
    return leftMargin;
    }


/* --------------------------------------------------------------------------*/
/* Private method to calculate the left margin of the flow at position y.
 */

NW_GDI_Metric_t TLMgr_BoxFormatter::NW_LMgr_FlowBox_GetLineEnd(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext,
        NW_GDI_Metric_t where)
    {
    NW_ADT_Vector_Metric_t floatCount, index;
    NW_GDI_Metric_t rightMargin;
    NW_GDI_Metric_t floatLeft, floatTop, floatBottom;
    NW_LMgr_Box_t *floatBox;
    NW_LMgr_PropertyValue_t floatValue;
    NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;
    NW_LMgr_FrameInfo_t margin;

    NW_REQUIRED_PARAM(flow);

    rightMargin = parentContext->endMargin;

    if (placedFloats == NULL)
        {
        return rightMargin;
        }

    floatCount = NW_ADT_Vector_GetSize(NW_ADT_VectorOf(placedFloats));

    for (index = 0; index < floatCount; index++)
        {

        floatBox =
            *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (placedFloats, index);
        NW_ASSERT(floatBox != NULL);

        if( floatBox != flow )
          {
          floatValue.integer = NW_CSS_PropValue_none;
          NW_LMgr_Box_GetPropertyValue(floatBox, NW_CSS_Prop_float,
                                       NW_CSS_ValueType_Token, &floatValue);

          if (floatValue.token == NW_CSS_PropValue_right)
              {

              NW_LMgr_Box_GetMargins(floatBox, &margin, NULL, ELMgrFrameTop|ELMgrFrameBottom|ELMgrFrameLeft );

              NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( floatBox );
              floatTop = (NW_GDI_Metric_t)(boxBounds.point.y - margin.top);
              floatBottom = (NW_GDI_Metric_t)(boxBounds.point.y
                                              + boxBounds.dimension.height
                                              + margin.bottom);
              floatLeft = (NW_GDI_Metric_t)(boxBounds.point.x
                                            - margin.left - 1);

              if ((where >= floatTop)
                  && (where < floatBottom)
                  && (rightMargin > floatLeft))
                  {
                  rightMargin = floatLeft;
                  }
              }
          }
        }
    return rightMargin;
    }
/* --------------------------------------------------------------------------*/
/* A method to test whether the flow is at the beginning of a line */


NW_Bool TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_AtNewLine(NW_LMgr_Box_t* flow,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_REQUIRED_PARAM(flow);

    if (parentContext->direction == NW_GDI_FlowDirection_LeftRight)
        {
        if (parentContext->x ==
            parentContext->lineStart + NW_LMgr_FlowBox_GetIndentation(flow, parentContext))
            {
            return NW_TRUE;
            }
        else
            {
            return NW_FALSE;
            }
        }
    else
        {
        if (parentContext->x ==
            parentContext->lineEnd - NW_LMgr_FlowBox_GetIndentation(flow, parentContext))
            {
            return NW_TRUE;
            }
        else
            {
            return NW_FALSE;
            }
        }

    }



/* --------------------------------------------------------------------------*/
/* A method to get the current formatting constraint */

void TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetConstraint(NW_LMgr_Box_t *flow,
        NW_LMgr_FormatContext_t *parentContext,
        NW_GDI_Metric_t *constraint)
    {
    NW_REQUIRED_PARAM(flow);

    /* Allow the remaining space on the current line for constraint width */
    if (parentContext->direction == NW_GDI_FlowDirection_LeftRight)
        {
        *constraint = (NW_GDI_Metric_t)(parentContext->lineEnd - parentContext->x);
        }
    else
        {
        *constraint = (NW_GDI_Metric_t)(parentContext->x - parentContext->lineStart);
        }

    if (*constraint < 0)
        {
        *constraint = 0;
        }
    }

/* ----------------------------------------------------------------------------*/
/* TODO: Add support for "auto" margins.
 */
void TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetBlockMargins (NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t *parentContext,
        NW_LMgr_FrameInfo_t *margin)
    {

    NW_GDI_Dimension2D_t boxSize;
    NW_LMgr_FrameInfo_t boxMargin, isAuto;

    NW_REQUIRED_PARAM(flow);

    /* Rule boxes get special handling */
    if (NW_Object_IsClass(box, &NW_LMgr_RuleBox_Class))
        {
        margin->left = margin->right = 0;
        return ;
        }

    NW_LMgr_Box_GetMargins(box, &boxMargin, &isAuto, ELMgrFrameLeft|ELMgrFrameRight );
    NW_LMgr_Box_GetSizeProperties(box, &boxSize);

    if (boxSize.width <= 0)
        {
        margin->left = boxMargin.left;
        margin->right = boxMargin.right;
        }
    else
        {
        if (isAuto.right && isAuto.left)
            {
            margin->left = (NW_GDI_Metric_t)((parentContext->endMargin - parentContext->startMargin - boxSize.width) / 2);
            margin->right = margin->left;
            }
        else if (isAuto.left)
            {
            margin->left = (NW_GDI_Metric_t)(parentContext->endMargin - parentContext->startMargin - boxSize.width - boxMargin.right);
            margin->right = boxMargin.right;
            }
        else
            {
            margin->left = boxMargin.left;
            margin->right = (NW_GDI_Metric_t)(parentContext->endMargin - parentContext->startMargin - boxSize.width - boxMargin.left);
            }
        }
    }

/* ----------------------------------------------------------------------------*/
/* Private method to place a child box at the current location in the flow.
 * Because a child can also be a container, we call the virtual shift method
 * to do the placing.  It will automatically shift all the children as well.
 */

void TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PlaceChild(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_REQUIRED_PARAM(flow);
    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );

    boxBounds.point.x = parentContext->x;
    boxBounds.point.y = parentContext->y;

    NW_LMgr_Box_SetFormatBounds( box, boxBounds );

    // This allow it to skip drawing images until they are "placed".
    if (NW_Object_IsInstanceOf(box, &NW_LMgr_ImgContainerBox_Class))
        {
        NW_LMgr_ImgContainerBox_ImageIsPlaced(box);
        }
    }

/* ----------------------------------------------------------------------------*/
/* Private method to place a child box at a specified location in the flow.
 * Because a child can also be a container, we call the virtual shift method
 * to do the placing.  It will automatically shift all the children as well.
 */

void TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PlaceChildAt(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_GDI_Metric_t x,
        NW_GDI_Metric_t y)
    {
    NW_REQUIRED_PARAM(flow);

    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
    boxBounds.point.x = x;
    boxBounds.point.y = y;
    NW_LMgr_Box_SetFormatBounds( box, boxBounds );

    // This allow it to skip drawing images until they are "placed".
    if (NW_Object_IsInstanceOf(box, &NW_LMgr_ImgContainerBox_Class))
        {
        NW_LMgr_ImgContainerBox_ImageIsPlaced(box);
        }
    }

/* --------------------------------------------------------------------------*/
/* A protected method to handle formatting of replaceable boxes */
TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleInline(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_PropertyValue_t whitespaceVal;
    NW_LMgr_PropertyValueToken_t whitespace;
    NW_LMgr_ContainerBox_t *parent;
    NW_GDI_Metric_t constraint;
    NW_LMgr_Box_t* splitBox;
    NW_LMgr_RootBox_t* rootBox;
    NW_LMgr_FrameInfo_t margin;
    NW_Bool finished = NW_FALSE;
    NW_Bool hasLeadingWS = NW_FALSE;
    NW_Bool hasTrailingWS = NW_FALSE;
    NW_Bool endsInNewline = NW_FALSE;
    NW_Bool atNewline = NW_FALSE;
    NW_Uint8 splitFlags;
    NW_Bool wrap = NW_FALSE;
    NW_LMgr_PropertyValue_t displayVal;
    NW_Bool ltr;
    NW_Bool wrapOn;

    NW_TRY(status)
        {
        // NW_LOG5(NW_LOG_LEVEL5, "HANDLE INLINE ::: flow %x, box %x , context %x, parentcontext y: %d, ht %d", flow, box,
        //                        parentContext, parentContext->y, box->bounds.dimension.height );

        /* Get the parent of the box */
        parent = NW_LMgr_Box_GetParent(box);
        rootBox = NW_LMgr_Box_GetRootBox( box );
        wrapOn = NW_LMgr_RootBox_GetWrapEnabled( rootBox );

        /* Get the whitespace property */
        whitespaceVal.token = NW_CSS_PropValue_normal;
        status = NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(flow),
                                              NW_CSS_Prop_whitespace,
                                              NW_CSS_ValueType_Token, &whitespaceVal);
        NW_THROW_ON(status, KBrsrOutOfMemory);
        whitespace = whitespaceVal.token;

        /* This var tells us how to treat whitespace */
        if (whitespace == NW_CSS_PropValue_normal)
            {
            wrap = NW_TRUE;
            }
        if(  wrapOn && (whitespace == NW_CSS_PropValue_nowrap))
            {
            NW_LMgr_Box_t *surroundingBlock = NW_LMgr_Box_FindBoxOfClass(box, &NW_LMgr_FlowBox_Class, NW_TRUE);
            if (!NW_Object_IsInstanceOf(surroundingBlock, &NW_LMgr_MarqueeBox_Class))
                {
                wrap = NW_TRUE;
                }
            }
        if( wrapOn && (whitespace == NW_CSS_PropValue_pre))
            {
            wrap = NW_TRUE;
            }
		NW_LMgr_Box_t *surroundingBlock = NW_LMgr_Box_FindBoxOfClass(box, &NW_LMgr_FlowBox_Class, NW_TRUE);

        NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( NW_LMgr_BoxOf( flow ) );

		if ( wrapOn && !NW_Object_IsInstanceOf(surroundingBlock, &NW_LMgr_MarqueeBox_Class) &&
			NW_LMgr_RootBox_GetSmallScreenOn( rootBox ))
			{
            wrap = NW_TRUE;
            }

        if (parentContext->direction == NW_GDI_FlowDirection_LeftRight)
            {
            ltr = NW_TRUE;
            }
        else
            {
            ltr = NW_FALSE;
            }


        /* Check whether we are at newline before adding the margin */
        atNewline = NW_LMgr_BidiFlowBox_AtNewLine(flow, parentContext);

        /* Get the box margins */
        NW_LMgr_Box_GetMargins(box, &margin, NULL, ELMgrFrameLeft|ELMgrFrameRight);

        /* Add any pending inline margin */
        if (ltr)
            {
            parentContext->x = (NW_GDI_Metric_t)(parentContext->x +
                                                 margin.left +
                                                 parentContext->pendingInlineMargin);
            }
        else
            {
            parentContext->x = (NW_GDI_Metric_t)(parentContext->x -
                                                 margin.right -
                                                 parentContext->pendingInlineMargin);
            }

        if (NW_Object_IsInstanceOf(box, &NW_LMgr_AbstractTextBox_Class))
            {
            status = NW_LMgr_AbstractTextBox_GetWS(NW_LMgr_AbstractTextBoxOf(box),
                                                   &hasLeadingWS,
                                                   &hasTrailingWS,
                                                   &endsInNewline);
            NW_THROW_ON_ERROR(status);

            if (whitespace != NW_CSS_PropValue_pre)
                {
                if (atNewline)
                    {
                    NW_LMgr_AbstractTextBox_CompressLeading(NW_LMgr_AbstractTextBoxOf(box));
                    }
                else if (parentContext->pendingWhitespace)
                    {
                    NW_LMgr_AbstractTextBox_CompressLeading(NW_LMgr_AbstractTextBoxOf(box));
                    }
                }
            }

        /* Get the display property */
        displayVal.token = NW_CSS_PropValue_display_inline;
        status = NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_display,
                                              NW_CSS_ValueType_Token, &displayVal);
        NW_THROW_ON(status, KBrsrOutOfMemory);
        /* This code deals with the cases for input and textarea boxes with block property */
        if ((displayVal.token == NW_CSS_PropValue_display_block) &&
            (!atNewline))
            {
            (void)NW_LMgr_BidiFlowBox_NewLine(flow, parentContext, 0, NW_TRUE);
            }


        while (!finished)
            {

            /* Set the initial constraint used for splitting and sizing boxes */
            NW_LMgr_BidiFlowBox_GetConstraint(flow, parentContext, &constraint);

            /* Get the box to size itself */
            status = NW_LMgr_Box_Resize(box, parentContext);
            NW_THROW_ON_ERROR(status);

            splitFlags = 0;
            if (atNewline)
                {
                splitFlags |= NW_LMgr_Box_SplitFlags_AtNewLine;
                }
            if (!parentContext->pendingWhitespace &&
                !hasLeadingWS)
                {
                splitFlags |= NW_LMgr_Box_SplitFlags_NoPendingWS;
                }
            if (!wrap)
                {
                splitFlags |= NW_LMgr_Box_SplitFlags_Nowrap;
                }

            /* Do the split */
            status = NW_LMgr_Box_Split(box, constraint, &splitBox, splitFlags);
            NW_THROW_ON(status, KBrsrOutOfMemory);

            if (status == KBrsrSuccess || (status == KBrsrLmgrNoSplit && (!wrap)) )
                {

                /* If split box is different than NULL, a new split box has been
                       created; before proceeding we need to insert the new split box
                       into the flow */
                if (splitBox != NULL)
                    {

                    /* Insert the split box into parent's child list just after the original */
                    status = NW_LMgr_ContainerBox_InsertChildAft (parent, splitBox, box);
                    NW_THROW_ON_ERROR(status);

                    /* If the box was split, it needs to resize */
                    status = NW_LMgr_Box_Resize (box, parentContext);
                    NW_THROW_ON(status, KBrsrOutOfMemory);
                    }

                /* For RTL we must modify parentContext beforehand */
                if (!ltr)
                    {
                    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
                    parentContext->x = (NW_GDI_Metric_t) (parentContext->x - boxBounds.dimension.width);
                    }

                /* The y placement that is set here will get readjusted when
                   the line is flushed */
                NW_LMgr_BidiFlowBox_PlaceChild(flow, box, parentContext);


                /* Add split box to current line */
                status = NW_LMgr_LineBox_Append(parentContext->currentLine, box, parentContext->direction);
                NW_THROW_ON_ERROR(status);

                /* Update the parentContext to reflect the addition of the new box */
                if (ltr)
                    {
                    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
                    parentContext->x = (NW_GDI_Metric_t) (parentContext->x + boxBounds.dimension.width);
                    }

                parentContext->pendingInlineMargin = 0;
                parentContext->pendingWhitespace = hasTrailingWS;


                if (splitBox == NULL)
                    {
                    /* Now we can add the remaining margin */
                    if (ltr)
                        {
                        parentContext->x = (NW_GDI_Metric_t) (parentContext->x + margin.right);
                        }
                    else
                        {
                        parentContext->x = (NW_GDI_Metric_t) (parentContext->x - margin.left);
                        }

                    /* If we are in a pre paragraph, we have to make sure that the text
                       box did not end in a newline.  If it did, we must jump to
                       the next line. */
                    if (endsInNewline)
                        {
                        (void)NW_LMgr_BidiFlowBox_NewLine(flow, parentContext, 0, NW_TRUE);
                        }

                    /* We're done */
                    finished = NW_TRUE;
                    }
                else
                    {
                    /* If the box was split, we must jump to the new line */
                    /* pass NW_FALSE because we don't indent the new line */
                    status = NW_LMgr_BidiFlowBox_NewLine(flow, parentContext, 0, NW_FALSE);
                    NW_THROW_ON_ERROR(status);
                    atNewline = NW_TRUE;

                    /* Now handle the split box */
                    box = splitBox;

                    /* Reset the WS values */
                    if (NW_Object_IsInstanceOf(box, &NW_LMgr_AbstractTextBox_Class))
                        {
                        status = NW_LMgr_AbstractTextBox_GetWS(NW_LMgr_AbstractTextBoxOf(box),
                                                               &hasLeadingWS,
                                                               &hasTrailingWS,
                                                               &endsInNewline);
                        NW_THROW_ON_ERROR(status);

                        NW_LMgr_AbstractTextBox_CompressLeading(NW_LMgr_AbstractTextBoxOf(box));
                        }
                    }
                }
            else
                {
                /* Jump to newline */
                (void)NW_LMgr_BidiFlowBox_NewLine(flow, parentContext, 0, NW_TRUE);
                atNewline = NW_TRUE;

                /* We need to add the margins again, because  the split did not succeed.
                 * If a split has already occurred, we will not redisplay the margins.
                 * The algorithm will have set the margin values to zero.  */

                if (ltr)
                    {
                    parentContext->x = (NW_GDI_Metric_t) (parentContext->x +
                                                          parentContext->pendingInlineMargin +
                                                          margin.left);
                    }
                else
                    {
                    parentContext->x = (NW_GDI_Metric_t) (parentContext->x -
                                                          parentContext->pendingInlineMargin -
                                                          margin.right);
                    }

                /* Reinit the WS parentContext */
                parentContext->pendingWhitespace = NW_FALSE;
                if (NW_Object_IsInstanceOf(box, &NW_LMgr_AbstractTextBox_Class))
                    {
                    NW_LMgr_AbstractTextBox_CompressLeading(NW_LMgr_AbstractTextBoxOf(box));
                    }
                }
            }
        if (displayVal.token == NW_CSS_PropValue_display_block)
            {
            (void)NW_LMgr_BidiFlowBox_NewLine(flow, parentContext, 0, NW_TRUE);
            }

        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    } NW_END_TRY;
    }



/* --------------------------------------------------------------------------*/
/*
 * A special case to handle containers inline: containers are
 * sometimes used as invisible boxes that link together a number of
 * children such as the contents of an HTML <a> element. This method
 * handles this case: the container children are flowed within
 * the parent flow parentContext--hence the box has no visible result in the
 * enclosing flow--but the children are maintained in the box tree as
 * children of the invisible container. This allows them to be treated
 * as a group for such purposes as handling an action (such as the <a>
 * element link handler).  */

/* TODO: We'd really like to get rid of this method so that no special
 * casing of containers (requiring runtime type checking) is
 * needed. This is actually the "real" container box "resize"
 * method. Unfortunately, this requires that the parent parentContext be
 * available (since containers don't have their own formatting
 * contexts). Currently there is no way to get this since contexts
 * aren't attached to objects that use them, so we can't walk up the
 * ancestor tree looking for one.
 */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleInlineContainer(NW_LMgr_Box_t* flow,
        NW_LMgr_ContainerBox_t* container,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_EmptyBox_t *emptyBox;
    NW_LMgr_Property_t prop;
    NW_LMgr_FrameInfo_t margin, padding, borderWidth;
    NW_LMgr_PropertyValue_t clearValue;

    NW_TRY(status)
        {

        clearValue.token = NW_CSS_PropValue_none;
        (void)NW_LMgr_Box_GetPropertyValue(NW_LMgr_BoxOf(container), NW_CSS_Prop_clear,
                                           NW_CSS_ValueType_Token, &clearValue);

        /* Advance to the next clear position, if necessary */
        status = NW_LMgr_BidiFlowBox_AdvanceToClear(flow, parentContext, clearValue.token);
        _NW_THROW_ON_ERROR(status);

        /* If the inline container is empty, we'll add an empty box to it
           as a placeholder */
        if (NW_LMgr_ContainerBox_GetChildCount(container) == 0)
            {
            emptyBox = NW_LMgr_EmptyBox_New(1);
            NW_THROW_OOM_ON_NULL(emptyBox, status);

            status = NW_LMgr_ContainerBox_AddChild(container,
                                                   NW_LMgr_BoxOf(emptyBox));
            _NW_THROW_ON_ERROR(status);

            /* We top-align the box (this is useful for empty anchors that point to
             * fragments */
            prop.type = NW_CSS_ValueType_Token;
            prop.value.token = NW_CSS_PropValue_top;
            status = NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(emptyBox),
                                             NW_CSS_Prop_verticalAlign, &prop);
            _NW_THROW_ON_ERROR(status);
            }

        /* Add our left margin to the pending left margin in the parentContext */
        NW_LMgr_Box_GetMargins(NW_LMgr_BoxOf(container), &margin, NULL, ELMgrFrameLeft );
        NW_LMgr_Box_GetPadding(NW_LMgr_BoxOf(container), &padding, ELMgrFrameLeft );
        NW_LMgr_Box_GetBorderWidth(NW_LMgr_BoxOf(container), &borderWidth, ELMgrFrameLeft );
        parentContext->pendingInlineMargin = (NW_GDI_Metric_t)
                                             (parentContext->pendingInlineMargin + margin.left + padding.left
                                              + borderWidth.left);

        /*
         * Flow the container children within the enclosing flow.
         * Note that the first argument to FlowChildren is the
         * enclosing flow and the second argument is the container
         * whose children will be flowed within the enclosing flow.
         */

          parentContext->formatChildren = NW_TRUE;
          parentContext->formatBox = flow;
          parentContext->newFormatContext = parentContext;
          parentContext->referenceCount++;
        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleInlineContainerPost(NW_LMgr_Box_t* /*flow*/,
        NW_LMgr_ContainerBox_t* container,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_FrameInfo_t margin, padding, borderWidth;

    /* If the inline container is empty, we'll add an empty box to it
       as a placeholder */
    /* Add our left margin to the pending left margin in the parentContext */
    NW_LMgr_Box_GetMargins(NW_LMgr_BoxOf(container), &margin, NULL, ELMgrFrameRight );
    NW_LMgr_Box_GetPadding(NW_LMgr_BoxOf(container), &padding, ELMgrFrameRight );
    NW_LMgr_Box_GetBorderWidth(NW_LMgr_BoxOf(container), &borderWidth, ELMgrFrameRight );

    /*
     * Flow the container children within the enclosing flow.
     * Note that the first argument to FlowChildren is the
     * enclosing flow and the second argument is the container
     * whose children will be flowed within the enclosing flow.
     */

    /* If we had no displayable children, our margins should be ignored */
    if (parentContext->pendingInlineMargin != 0)
        {
        parentContext->pendingInlineMargin = 0;
        }
    else
        {
        /* Otherwise, we add the right margin */
        parentContext->x = (NW_GDI_Metric_t) (parentContext->x + margin.right
                                              + padding.right + borderWidth.right);
        }

    return KBrsrSuccess;
    }

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleBlock (NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_GDI_Metric_t constraint;
    NW_LMgr_PropertyValue_t clearValue;
    NW_LMgr_FrameInfo_t margin;
    NW_Bool lineConstraint = NW_TRUE;
    NW_LMgr_ContainerBox_t* containerBox;
    NW_Uint16 childCount;
    NW_Uint16 childIndex;
    NW_LMgr_Box_t* childBox;
    NW_ADT_Vector_Metric_t index;
    NW_LMgr_EmptyBox_t *emptyBox;

    NW_TRY(status)
        {
       /* Get the "clear" property */
        clearValue.token = NW_CSS_PropValue_none;
        (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_clear,
                                           NW_CSS_ValueType_Token, &clearValue);

        /* This determines what kind of constraint we need */
        if (NW_Object_IsInstanceOf (box, &NW_LMgr_FlowBox_Class))
            {

            lineConstraint = NW_FALSE;

            containerBox = NW_LMgr_ContainerBoxOf (box);
            childCount = NW_LMgr_ContainerBox_GetChildCount (containerBox);
            
            //if this flow box doesn't have any child and also it has attribute height, then 
            //we need to create an empty textbox as its child. The reason is to fix the bug as:
            //<div height=xx color=red></div>
            //text here
            //if we don't create an empty box, there will be overlap between div section and text.
            if (childCount == 0)
            {
                NW_LMgr_Property_t property;
                status = NW_LMgr_Box_GetProperty (box, NW_CSS_Prop_height, &property);
                if (status == KBrsrSuccess)
                {
                    //creat an empty text box
                    emptyBox = NW_LMgr_EmptyBox_New(1);
                    NW_THROW_OOM_ON_NULL(emptyBox, status);

                    //add it as the flowbox child
                    status = NW_LMgr_ContainerBox_AddChild(containerBox, NW_LMgr_BoxOf(emptyBox));
                    _NW_THROW_ON_ERROR(status);
                }
            }

            for (childIndex = 0; childIndex < childCount; childIndex++)
                {

                childBox = NW_LMgr_ContainerBox_GetChild (containerBox, childIndex);
                if (NW_Object_IsClass (childBox, &NW_LMgr_StaticTableBox_Class))
                    {
                    lineConstraint = NW_TRUE;
                    }
                }
            }

        /* Move to new line */
        status = NW_LMgr_BidiFlowBox_NewLine (flow, parentContext, 0, NW_TRUE);
        _NW_THROW_ON_ERROR(status);

        /* Get the position of the current block in the flow */
        index = NW_LMgr_ContainerBox_GetChildIndex(NW_LMgr_ContainerBoxOf(flow), box);
//        NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( NW_LMgr_BoxOf( flow ) );

//        if( NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) )
//            {
            // Many times the flow is not the direct parent of the box
            // For e.g. <p><span>Foo
            // while formatting Foo, flowbox belongs to p and not to span, so
            // the box will not be a child of Flow. We want to avoid such cases.
            if ((index > 0) && (NW_LMgr_BoxOf(flow) == NW_LMgr_BoxOf(box->parent)))
                {
                // get the previous sibling
                NW_LMgr_Box_t* child =
                    NW_LMgr_ContainerBox_GetChild(NW_LMgr_ContainerBoxOf(flow), (NW_ADT_Vector_Metric_t)(index-1));
                NW_ASSERT(child);

                // if previous sibling of this flow box is not of type flow, remove extra line spacing
                // that was added in HandleInline of prev sibling. If the tree was normalized, i.e if the prevsibling
                // was surrounded by anonymous FlowBox, this subtraction would have occurred in PostFormat
                // For e.g <p><img/><div>Bar</div>
                // Here PostFormat of the anonymous FlowBox around <img> that was created in Initialize, would
                // have removed the extra spacing. But since we do not have anonymous FlowBox, we will have to
                // remove it in HandleBlock of div
                if (child && !NW_Object_IsInstanceOf(child, &NW_LMgr_FlowBox_Class))
                    {
                    TBool decreaseLineSpacing = ETrue;

                    // For e.g. <p>
                    //             <span><div>Foo</div>
                    //             <div>Bar</div>
                    //          </p>
                    // Here we do not have to remove the extra spacing, even though span is a container box,
                    // since PostFormat of first div will remove the extra spacing. SO, we look for the
                    // first child
                    if (NW_Object_IsInstanceOf(child, &NW_LMgr_ContainerBox_Class))
                        {
                        // if child is a containerbox - check if the last child is a FlowBox, if yes
                        // don't fo the following, because FlowBox PostFormat will take care of it
                        childCount = NW_LMgr_ContainerBox_GetChildCount(NW_LMgr_ContainerBoxOf(child));
                        if (childCount > 0)
                            {
                            NW_LMgr_Box_t* lastChild =
                                NW_LMgr_ContainerBox_GetChild(NW_LMgr_ContainerBoxOf(child), (NW_ADT_Vector_Metric_t)(childCount-1));
                            if (lastChild && NW_Object_IsInstanceOf(lastChild, &NW_LMgr_FlowBox_Class))
                                {
                                // PostFormat of this FlowBox will take care of this
                                decreaseLineSpacing = EFalse;
                                }
                            }
                        }
                    if (decreaseLineSpacing && (parentContext->y >= KFlowBoxLineSpacing))
                        {
                        parentContext->y = parentContext->y-KFlowBoxLineSpacing;
                        }
                    }
                }
//            }

        /* Get the horizontal margins for the box */
        NW_LMgr_BidiFlowBox_GetBlockMargins(flow, box, parentContext, &margin);

        /* Advance to the next clear position, if necessary */
        status = NW_LMgr_BidiFlowBox_AdvanceToClear(flow, parentContext, clearValue.token);
        _NW_THROW_ON_ERROR(status);

        /* Set the size constraint for boxes that need to be constrained in order
           to size themselves */
        if (!lineConstraint)
            {
            constraint = (NW_GDI_Metric_t)
                         (parentContext->endMargin - parentContext->startMargin - margin.left - margin.right);
            }
        else
            {
            constraint = (NW_GDI_Metric_t)
                         (parentContext->lineEnd - parentContext->lineStart - margin.left - margin.right);
            }

        status = NW_LMgr_Box_Constrain(box, constraint);
        NW_THROW_ON(status, KBrsrOutOfMemory);

        /* Collapse any margins */
        status = NW_LMgr_BidiFlowBox_CollapseMargins(flow, box, parentContext, index);
        _NW_THROW_ON_ERROR(status);

        // NW_LOG2(NW_LOG_LEVEL5, "Handle block::: after collapse margins : parentcontext y: %d, ht %d", parentContext->y, box->bounds.dimension.height);
        /* Set the (x,y) coordinates of the block */
        if (!lineConstraint)
            {
            NW_LMgr_BidiFlowBox_PlaceChildAt(flow, box,
                                                   (NW_GDI_Metric_t)(parentContext->startMargin + margin.left),
                                                   parentContext->y);
            }
        else
            {
            NW_LMgr_BidiFlowBox_PlaceChildAt(flow, box,
                                                   (NW_GDI_Metric_t)(parentContext->lineStart + margin.left),
                                                   parentContext->y);
            }

        /* Now have the box set its own idea of size */
        status = NW_LMgr_Box_Resize(box, parentContext);
        _NW_THROW_ON_ERROR(status);

        // Deepika: There should not be special handling. PostFormat should be called on leaf
        // node s as well - To be done later
        if (NW_Object_IsInstanceOf(box, &NW_LMgr_MediaBox_Class) ||
            NW_Object_IsInstanceOf(box, &NW_FBox_FormBox_Class) )
            {
            // In case of boxes which have fixed content size, e.g. RuleBox, there will not
            // be any children to be formatted. They will be leaf nodes and there won't be
            // any postformat performed on them. That's why we need to add new line here
            status =  NW_LMgr_BidiFlowBox_HandleBlockPost(flow, box, parentContext);
            _NW_THROW_ON_ERROR(status);
            }
        }

    NW_CATCH(status)
        { /* empty */
        }

    NW_FINALLY {
        return status;
    } NW_END_TRY;
    }

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleBlockPost (NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    /* We're assuming that block boxes are always followed by a newline too.
       If someone decides the CSS spec should be read differently, we can just
       remove newline call. */
    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
    TBrowserStatusCode status =  NW_LMgr_BidiFlowBox_NewLine(flow, parentContext,
            boxBounds.dimension.height, NW_TRUE);
    return status;

    }


/* --------------------------------------------------------------------------*/
/* returns: KBrsrLmgrNotClear, KBrsrSuccess */
TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_PlaceFloat(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_PropertyValue_t floatValue;
    NW_LMgr_FrameInfo_t margin;

    floatValue.token = NW_CSS_PropValue_none;
    (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_float,
                                       NW_CSS_ValueType_Token, &floatValue);

    NW_LMgr_Box_GetMargins(box, &margin, NULL, ELMgrFrameLeft|ELMgrFrameRight|ELMgrFrameTop);
    NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
    /* Check that there is enough room for the float */
    if (parentContext->lineEnd - parentContext->lineStart <=
        boxBounds.dimension.width + margin.left + margin.right)
        {
        if ( NW_Object_IsDerivedFrom(box, &NW_LMgr_ImgContainerBox_Class) &&
             NW_LMgr_ImgContainerBox_ImageIsBroken( box ) == NW_TRUE &&
             (parentContext->lineStart == 4))
            {
            boxBounds.dimension.width = (NW_GDI_Metric_t)(parentContext->lineEnd - parentContext->lineStart);
            NW_LMgr_Box_SetFormatBounds( box, boxBounds );
            }
        else
            {
            NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( box );

            if( NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) )
              {
              if(NW_LMgr_BidiFlowBox_AtNewLine(flow, parentContext))
                {
                boxBounds.dimension.width = (NW_GDI_Metric_t)(parentContext->lineEnd - parentContext->lineStart);
                NW_LMgr_Box_SetFormatBounds( box, boxBounds );
                }
              else
                {
                return KBrsrLmgrNotClear;
                }
              }
          }
      }

    /* Place the float in the flow */
    if (floatValue.token == NW_CSS_PropValue_left)
        {

        NW_LMgr_BidiFlowBox_PlaceChildAt(flow, box,
                                               ((NW_GDI_Metric_t)
                                                (parentContext->lineStart + margin.left)),
                                               ((NW_GDI_Metric_t)
                                                (parentContext->y + margin.top)));

        NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
        parentContext->lineStart =
            ((NW_GDI_Metric_t)
             (parentContext->lineStart + boxBounds.dimension.width
              + margin.left + margin.right));
        }
    else
        {
        NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
        NW_LMgr_BidiFlowBox_PlaceChildAt(flow, box,
                                               ((NW_GDI_Metric_t)
                                                (parentContext->lineEnd - margin.right
                                                 - boxBounds.dimension.width)),
                                               ((NW_GDI_Metric_t)
                                                (parentContext->y + margin.top)));
        parentContext->lineEnd =
            ((NW_GDI_Metric_t)
             (parentContext->lineEnd - boxBounds.dimension.width
              - margin.left - margin.right));
        }
    return KBrsrSuccess;
    }

/* --------------------------------------------------------------------------*/
/* A method to handle float boxes.
 * returns: KBrsrLmgrNotClear, KBrsrOutOfMemory,
 *          KBrsrUnexpectedError
 */
TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleFloat(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_PropertyValue_t clearValue;
    NW_Bool isClearLeft, isClearRight;
    NW_LMgr_PropertyValueToken_t clearToken;
    NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;

    if (placedFloats == NULL)
        {
        return KBrsrLmgrNotClear;
        }

    clearValue.token = NW_CSS_PropValue_none;
    (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_clear,
                                       NW_CSS_ValueType_Token, &clearValue);
    clearToken = clearValue.token;

    /* Get our parentContext info */
    isClearLeft = (NW_Bool)(parentContext->startMargin == parentContext->lineStart);
    isClearRight = (NW_Bool)(parentContext->endMargin == parentContext->lineEnd);

    /* If we are not clear, add the box to the list of pending floats */
    if (!(((clearToken == NW_CSS_PropValue_left) && isClearLeft)
          || ((clearToken == NW_CSS_PropValue_right) && isClearRight)
          || ((clearToken == NW_CSS_PropValue_both) && isClearLeft && isClearRight)
          || (clearToken == NW_CSS_PropValue_none))
       )
        {
        return KBrsrLmgrNotClear;
        }

    NW_TRY(status)
        {
        /* Format the float */
        if (NW_LMgr_Box_HasFixedContentSize(box))
            {
            // Resize the float using its intrinsic width/height
            status = NW_LMgr_Box_Resize(box, parentContext);
            _NW_THROW_ON_ERROR(status);

            // Place the float
            status = NW_LMgr_BidiFlowBox_PlaceFloat(flow, box, parentContext);
            _NW_THROW_ON_ERROR(status);

            // In case of boxes which have fixed content size, e.g. image, there will not
            // be any children to be formatted. They will be leaf nodes and there won't be
            // any postformat performed on them. That's why we need to add them to
            // placedFloat and reformat line boxes in this method, rather than in
            // PostFormatFloat

            // Add the float to the vector
            void *floatPtr = NW_ADT_DynamicVector_InsertAt(placedFloats, &box, NW_ADT_Vector_AtEnd);
            NW_THROW_OOM_ON_NULL(floatPtr, status);

            // Reformat any boxes that are already on the line
            status = NW_LMgr_BidiFlowBox_ReformatLine(flow, parentContext);
            _NW_THROW_ON_ERROR(status);

			// if floating fixed size box was inside an <a> tag currently ActiveContainerBox
			// will not get resized. So, we explicitly resize it here
			if (NW_Object_IsInstanceOf(box->parent, &NW_LMgr_ActiveContainerBox_Class))
				{
				status = NW_LMgr_ContainerBox_ResizeToChildren(box->parent);
				_NW_THROW_ON_ERROR(status);

				}
            }
        else
            {
            NW_LMgr_Property_t wprop;

            wprop.value.token = NW_CSS_PropValue_auto;
            wprop.type = NW_CSS_ValueType_Token;
            (void)NW_LMgr_Box_GetProperty(box, NW_CSS_Prop_width, &wprop);

            if ((wprop.type == NW_CSS_ValueType_Token)
                && (wprop.value.token == NW_CSS_PropValue_auto))
                {
                /* Set the auto width to 25% -- this is completely arbitrary,
                 but makes better sense than not showing the box altogether */
                wprop.type = NW_CSS_ValueType_Percentage;
                wprop.value.decimal = 25;
                status = NW_LMgr_Box_SetProperty(box, NW_CSS_Prop_width, &wprop);
                _NW_THROW_ON_ERROR(status);
                /* set the flag so that we know that this width was set by float */
                wprop.type = NW_CSS_ValueType_Token;
                wprop.value.token = NW_CSS_PropValue_flags_floatWidth;
                status = NW_LMgr_Box_SetProperty(box, NW_CSS_Prop_flags, &wprop);
                _NW_THROW_ON_ERROR(status);
                }
            /* Constrain using the width property */
            status = NW_LMgr_Box_Constrain(box, 0);
            if (status != KBrsrLmgrConstraintTooSmall)
                {
                /* just ignore too small */
                _NW_THROW_ON_ERROR(status);
                }

            /* Place the float */
            status = NW_LMgr_BidiFlowBox_PlaceFloat(flow, box, parentContext);
            _NW_THROW_ON_ERROR(status);

            /* Resize the float */
            status = NW_LMgr_Box_Resize(box, parentContext);
            _NW_THROW_ON_ERROR(status);
            }

        }
    NW_CATCH(status)
        {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }



/* ----------------------------------------------------------------------------*/
/* A private method to handle break boxes. */
TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_HandleBreak(NW_LMgr_Box_t* flow,
        NW_LMgr_Box_t* box,
        NW_LMgr_FormatContext_t* parentContext)
    {
    NW_LMgr_PropertyValue_t clearValue;

    NW_TRY(status)
        {
        /* Resize */

        status = NW_LMgr_Box_Resize(box, parentContext);
        _NW_THROW_ON_ERROR(status);

        /* Add the break box to the line */
        status = NW_LMgr_LineBox_Append(parentContext->currentLine, box, parentContext->direction);
        _NW_THROW_ON_ERROR(status);

        /* Set the (x,y) coordinates for the box */
        NW_LMgr_BidiFlowBox_PlaceChild(flow, box, parentContext);

        /* If the box dimensions (ht/width) are zero, we do not want this box to participate in
           the layout and create a new line (for e.g. in the vertical layout mode */
        NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( box );
        if ((boxBounds.dimension.height == 0) && (boxBounds.dimension.width == 0))
            NW_THROW_SUCCESS(status);

        /* Jump to the next line */
        status = NW_LMgr_BidiFlowBox_NewLine (flow, parentContext, 0, NW_TRUE);
        _NW_THROW_ON_ERROR(status);

        /* Get the "clear" property */
        clearValue.token = NW_CSS_PropValue_none;
        (void)NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_clear,
                                           NW_CSS_ValueType_Token, &clearValue);

        /* Advance to the next clear position, if necessary */
        status = NW_LMgr_BidiFlowBox_AdvanceToClear(flow, parentContext, clearValue.token);
        _NW_THROW_ON_ERROR(status);
        }
    NW_CATCH(status)
    {}
    NW_FINALLY {
        return status;
    }
    NW_END_TRY
    }



/* ------------------------------------------------------------------------- *
 * Function:     NW_LMgr_BidiFlowBox_Initialize
 * A public method to add any anonymous block container boxes to
 * a block container that contains both block and inline content.
 * This assures that all content in a block box participates
 * in the same format context (either block or inline).  This becomes
 * essential when margins are collapsed.  CSS2 p98.
 */

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_Initialize(NW_LMgr_BidiFlowBox_t *flow)
    {
    NW_ADT_Vector_Metric_t startInlineContent = 0;
    NW_ADT_Vector_Metric_t endInlineContent = 0;
    NW_ADT_Vector_Metric_t childIndex;
    NW_ADT_Vector_Metric_t childCount;
    NW_ADT_Vector_Metric_t i;
    NW_LMgr_Box_t *childBox;
    NW_LMgr_ContainerBox_t *container = NW_LMgr_ContainerBoxOf(flow);
    NW_LMgr_Box_t *inlineChild;
    NW_LMgr_PropertyValue_t dispValue;
    NW_LMgr_PropertyValue_t floatValue;
    NW_LMgr_Property_t prop;
    NW_Bool inlineStarted = NW_FALSE, inlineEnded = NW_FALSE;
    NW_Bool containsBlocks = NW_FALSE;
    NW_Bool childIsBlock = NW_FALSE;
    NW_LMgr_Box_t *anonBlock = NULL;
    NW_Bool canCollapse = NW_TRUE;
    
    NW_TRY(status) 
        {
        childIndex = 0;
        while (childIndex < NW_LMgr_ContainerBox_GetChildCount(container))
            {
            // Get the box at position i
            childBox = NW_LMgr_ContainerBox_GetChild(container, childIndex);
            
            if (NW_Object_IsInstanceOf(childBox, &NW_LMgr_SplitTextBox_Class))
                {
                NW_Object_Delete(childBox);
                childBox = NULL;
                continue;
                }
            
            childIndex++;
            }
        
        childCount = NW_LMgr_ContainerBox_GetChildCount(container);
        
        for (childIndex = 0; childIndex < childCount; childIndex++) 
            {
            // Get the box at position i
            childBox = NW_LMgr_ContainerBox_GetChild(container, childIndex);
            
            NW_LMgr_PropertyValue_t positionVal;
            
            positionVal.token = NW_CSS_PropValue_none;
            (void)NW_LMgr_Box_GetPropertyValue(childBox, NW_CSS_Prop_position,
                NW_CSS_ValueType_Token, &positionVal);
            if(positionVal.token == NW_CSS_PropValue_position_absolute)
                {
                // absolute positioned boxes should not cause a new format context to be created
                continue;
                }
            // If any of the children are block-level, set the flag
            dispValue.token = NW_CSS_PropValue_display_inline;
            (void)NW_LMgr_Box_GetPropertyValue(childBox, NW_CSS_Prop_display, NW_CSS_ValueType_Token, &dispValue);
            floatValue.token = NW_CSS_PropValue_none;
            (void)NW_LMgr_Box_GetPropertyValue(childBox, NW_CSS_Prop_float, NW_CSS_ValueType_Token, &floatValue);
            if (((dispValue.token == NW_CSS_PropValue_display_block) ||
                (dispValue.token == NW_CSS_PropValue_display_listItem)) &&
                (floatValue.token == NW_CSS_PropValue_none))
                {
                containsBlocks = NW_TRUE;
                childIsBlock = NW_TRUE;
                }
            
            /* We have found some inline content */
            else 
                {
                childIsBlock = NW_FALSE;
                
                if (!inlineStarted) 
                    {
                    startInlineContent = childIndex;
                    inlineStarted = NW_TRUE;
                    }
                }
            
                /* If we have encountered any inline content previously, and now we
                encounter a block following it, or we are the end of the container,
            we must enclose any inline elements with an anonymous block box. */
            if (childIsBlock && inlineStarted) 
                {
                endInlineContent = (NW_ADT_Vector_Metric_t)(childIndex - 1);
                inlineEnded = NW_TRUE;
                }
            
            else if (inlineStarted && (childIndex == childCount-1) && containsBlocks)
                {
                endInlineContent = childIndex;
                inlineEnded = NW_TRUE;
                }
            
            if (inlineEnded)
                {
                // Create the anonymous container */
                anonBlock = (NW_LMgr_Box_t*)LMgrAnonBlock_New(0);
                NW_THROW_OOM_ON_NULL(anonBlock, status);
                
                // Move the inline children to the new block box
                for (i = startInlineContent; i <= endInlineContent; i++)
                    {
                    inlineChild = NW_LMgr_ContainerBox_GetChild(container,
                        startInlineContent);
                    
                    // Get the minimum size
                    if (canCollapse)
                        {
                        if (NW_Object_IsInstanceOf(inlineChild, &NW_LMgr_AbstractTextBox_Class))
                            {
                            canCollapse = NW_LMgr_AbstractTextBox_IsBlank(NW_LMgr_AbstractTextBoxOf(inlineChild));
                            _NW_THROW_ON_ERROR(status);
                            }
                        else
                            {
                            canCollapse = NW_FALSE;
                            }
                        }
                    
                    // Add the child to the new flow
                    status =
                        NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf(anonBlock),
                        inlineChild);
                    _NW_THROW_ON_ERROR(status);
                    
                    childCount--;
                    childIndex--;
                    }
                
                // If the inline content appears to be empty,
                //   do not add it to the flow
                if (!canCollapse)
                    {
                    // Insert the new container
                    status = NW_LMgr_ContainerBox_InsertChildAt(container, anonBlock,
                        startInlineContent);
                    _NW_THROW_ON_ERROR(status);
                    
                    // Set the display property on the container
                    prop.type = NW_CSS_ValueType_Token;
                    prop.value.token = NW_CSS_PropValue_display_block;
                    status = NW_LMgr_Box_SetProperty(anonBlock,
                        NW_CSS_Prop_display, &prop);
                    _NW_THROW_ON_ERROR(status);
                    
                    // Update the variables
                    childCount ++;
                    childIndex ++;
                    }
                else
                    {
                    NW_Object_Delete(anonBlock);
                    }
                
                // Reset the variables
                anonBlock = NULL;
                inlineStarted = NW_FALSE;
                inlineEnded = NW_FALSE;
                }
            }
            
        }
        NW_CATCH(status) 
            {
            NW_Object_Delete(anonBlock);
            }
        NW_FINALLY 
            {
            return status;
            }
        NW_END_TRY

    }
      

/* ------------------------------------------------------------------------- *
 * Function:     NW_LMgr_BidiFlowBox_InitializeSSL
 * A public method to remove any empty text child box in small screen mode
 */

TBrowserStatusCode 
TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_InitializeSSL(NW_LMgr_BidiFlowBox_t *flow)
    {
    TBrowserStatusCode status = KBrsrSuccess;
    NW_ADT_Vector_Metric_t childIndex;
    NW_ADT_Vector_Metric_t childCount;
    NW_LMgr_Box_t *childBox;
    NW_LMgr_ContainerBox_t *container = NW_LMgr_ContainerBoxOf(flow);

    // remove empty text box
    childCount = NW_LMgr_ContainerBox_GetChildCount(container);

    for (childIndex = 0; childIndex < childCount; childIndex++) 
        {
        // Get the box at position i
        childBox = NW_LMgr_ContainerBox_GetChild(container, childIndex);

        if( NW_Object_IsInstanceOf(childBox, &NW_LMgr_AbstractTextBox_Class) &&
            NW_LMgr_AbstractTextBox_IsBlank(NW_LMgr_AbstractTextBoxOf(childBox)) )
            {
            NW_Object_Delete(childBox);
            childBox = NULL;

            childCount--;
            childIndex--;
            }
        }

    return status;
    }


TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_BidiFlowBox_GetListMargin(NW_LMgr_FlowBox_t* flowBox)
{
  TBrowserStatusCode status;
  NW_LMgr_Property_t prop;
  NW_LMgr_Property_t propMargin;
  NW_LMgr_PropertyName_t propName;
  NW_LMgr_ContainerBox_t* parent;

  NW_ASSERT(flowBox != NULL);
  parent = NW_LMgr_Box_GetParent(flowBox);

  prop.type = NW_CSS_ValueType_Token;
  prop.value.token = NW_CSS_PropValue_ltr;
  status = NW_LMgr_Box_GetProperty(NW_LMgr_BoxOf(flowBox), NW_CSS_Prop_textDirection, &prop);

  if (prop.value.token == NW_CSS_PropValue_ltr) {
    propName = NW_CSS_Prop_leftMargin;
  }
  else {
    propName = NW_CSS_Prop_rightMargin;
  }
  propMargin.type = NW_CSS_ValueType_Px;
  status = NW_LMgr_Box_GetPropertyFromList(NW_LMgr_BoxOf(parent), NW_CSS_Prop_listMargin, &propMargin);
  /* We set the value, it must be there */
  if (status == KBrsrSuccess)
  {
  status = NW_LMgr_Box_GetPropertyFromList(NW_LMgr_BoxOf(flowBox), propName, &propMargin);
  if (status != KBrsrSuccess) {
    /* The margin was not set yet */
    status = NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(flowBox), propName, &propMargin);
  }
  }
  return status;
}

TBrowserStatusCode TLMgr_BoxFormatter::NW_LMgr_ResizeToFloat(NW_LMgr_Box_t* flow, NW_LMgr_FormatContext_t* parentContext)
    {
    NW_GDI_Rectangle_t flowBounds = NW_LMgr_Box_GetFormatBounds(flow);
    NW_ADT_Vector_Metric_t floatCount, index;
    NW_LMgr_Box_t *floatBox;
    NW_LMgr_PropertyValue_t floatValue;
    NW_GDI_Metric_t floatBottom;
    NW_LMgr_FrameInfo_t margin;
    
    NW_ADT_DynamicVector_t *placedFloats = parentContext->placedFloats;
    if (placedFloats)
        {
        floatCount = NW_ADT_Vector_GetSize(NW_ADT_VectorOf(placedFloats));
        }
    else
        {
        floatCount = 0;
        }
    
    for (index = 0; index < floatCount; index++)
        {
        
        floatBox =
            *(NW_LMgr_Box_t**) NW_ADT_Vector_ElementAt (placedFloats, index);
        if( floatBox != flow && flow == (NW_LMgr_Box_t *)NW_LMgr_Box_GetParent(floatBox))
            {
            NW_ASSERT(floatBox != NULL);
            
            floatValue.integer = NW_CSS_PropValue_none;
            NW_LMgr_Box_GetPropertyValue(floatBox, NW_CSS_Prop_float,
                NW_CSS_ValueType_Token, &floatValue);
            
            
            NW_LMgr_Box_GetMargins(floatBox, &margin, NULL, ELMgrFrameBottom );
            
            NW_GDI_Rectangle_t boxBounds = NW_LMgr_Box_GetFormatBounds( floatBox );
            floatBottom = (NW_GDI_Metric_t)( boxBounds.point.y
                + boxBounds.dimension.height
                + margin.bottom);
            
            if( flowBounds.dimension.height + flowBounds.point.y < floatBottom) {
                flowBounds.dimension.height = floatBottom - flowBounds.point.y  ;
                NW_LMgr_Box_SetFormatBounds(flow, flowBounds);
                }
            }
        }
    
    return KBrsrSuccess;
    }