/*!
 Draw container content
 \param pDA Draw arguments
 */
void fp_AnnotationContainer::draw(dg_DrawArgs* pDA)
{
	if(getPage() == NULL)
	{
		return;
	}
	fl_AnnotationLayout * pAL2 = static_cast<fl_AnnotationLayout *>(getSectionLayout());
	FL_DocLayout * pDL = pAL2->getDocLayout();
	m_iLabelWidth = 0;
	if(!pDL->displayAnnotations())
	  return;

	UT_DEBUGMSG(("Annotation: Drawing unbroken annotation %p x %d, y %d width %d height %d \n",this,getX(),getY(),getWidth(),getHeight()));

	UT_DEBUGMSG(("Annotation: Drawing PDA->xoff %d, pDA->yoff  %ld \n",pDA->xoff,pDA->yoff));

//
// Only draw the lines in the clipping region.
//
	dg_DrawArgs da = *pDA;

	UT_uint32 count = countCons();
	for (UT_uint32 i = 0; i<count; i++)
	{
		fp_ContainerObject* pContainer = static_cast<fp_ContainerObject*>(getNthCon(i));
		da.xoff = pDA->xoff + pContainer->getX();
		if(i == 0)
		{
		        fl_AnnotationLayout * pAL = static_cast<fl_AnnotationLayout *>(getSectionLayout());
			fp_AnnotationRun * pAR = pAL->getAnnotationRun();
			if(pAR)
			{		
			    m_iLabelWidth = pAR->getWidth();
      			    da.xoff = pDA->xoff + pContainer->getX() - m_iLabelWidth;
			    fp_Line * pLine = static_cast<fp_Line *>(pContainer);
			    da.yoff = pDA->yoff + pContainer->getY() + pLine->getAscent();
			    da.bDirtyRunsOnly = false;
			    m_iXLabel = da.xoff;
			    m_iYLabel = da.yoff;
			    pAR->draw(&da);
			    da.xoff = pDA->xoff + pContainer->getX();
			}
		}
		da.yoff = pDA->yoff + pContainer->getY();
		pContainer->draw(&da);
	}
	_drawBoundaries(pDA);
}
bool fl_EmbedLayout::doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx)
{
	UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_DeleteStrux);
//
// Remove all remaining structures
//
	if(getPrev())
	{
	  getPrev()->setNeedsReformat(getPrev());
	}
	collapse();
//	UT_ASSERT(pcrx->getStruxType()== PTX_SectionFootnote);
//
// Find the block that contains this layout.
//
	PT_DocPosition prevPos = pcrx->getPosition();
	fl_BlockLayout * pEncBlock =  m_pLayout->findBlockAtPosition(prevPos);
//
// Fix the offsets for the block
//
	m_bHasEndFootnote = false;
	pEncBlock->updateOffsets(prevPos,0,-getOldSize());
	getSectionLayout()->remove(this);	
	delete this;			// TODO whoa!  this construct is VERY dangerous.

	return true;
}
void fp_FrameContainer::setPage(fp_Page * pPage)
{
	if(pPage && (m_pPage != NULL) && m_pPage != pPage)
	{
		clearScreen();
		m_pPage->removeFrameContainer(this);
		getSectionLayout()->markAllRunsDirty();
		
		UT_GenericVector<fl_ContainerLayout *> AllLayouts;
		AllLayouts.clear();
		m_pPage->getAllLayouts(AllLayouts);
		UT_sint32 i = 0;
		for(i=0; i<AllLayouts.getItemCount(); i++)
		{
		      fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
		      pCL->collapse();
		      pCL->format();
	        }
		m_pPage->getOwningSection()->setNeedsSectionBreak(true,m_pPage);
		
	}
	m_pPage = pPage;
	if(pPage)
	{
		getFillType()->setParent(pPage->getFillType());
	}
	else
	{
		getFillType()->setParent(NULL);
	}
}
bool fp_Container::isOnScreen() const
{
	UT_return_val_if_fail(getSectionLayout(),false);
	
	FV_View *pView = getSectionLayout()->getDocLayout()->getView();

	if(!pView)
	{
		return false;
	}
	if(getPage())
	{
		return getPage()->isOnScreen();
	}
	return false;
}
fl_DocSectionLayout * fp_EndnoteContainer::getDocSectionLayout(void)
{
	fl_EndnoteLayout * pFL = static_cast<fl_EndnoteLayout *>(getSectionLayout());
	fl_DocSectionLayout * pDSL = static_cast<fl_DocSectionLayout *>(pFL->myContainingLayout());
	UT_ASSERT(pDSL && (pDSL->getContainerType() == FL_CONTAINER_DOCSECTION));
	return pDSL;
}
/*!
 * Draw the frame handles
 */
void  fp_FrameContainer::drawHandles(dg_DrawArgs * pDA)
{
        if(getView() == NULL)
	{
	     getSectionLayout()->format();
	     getSectionLayout()->setNeedsReformat(getSectionLayout());
	}
        if(getView() == NULL)
	{
	     return;
	}
	if(!getPage())
	{
	     return;
	}
	//
	// Only fill to the bottom of the viewed page.
	//
	GR_Graphics * pG = pDA->pG;
	UT_sint32 iFullHeight = getFullHeight();
	fl_DocSectionLayout * pDSL = getDocSectionLayout();
	UT_sint32 iMaxHeight = 0;
	if(!pG->queryProperties(GR_Graphics::DGP_PAPER) && (getView()->getViewMode() != VIEW_PRINT))
	{
	    iMaxHeight = pDSL->getActualColumnHeight();
	}
	else
	{
	    iMaxHeight = getPage()->getHeight();
	}
	UT_sint32 iBot = getFullY()+iFullHeight;
	if(iBot > iMaxHeight)
	{
	    iFullHeight = iFullHeight - (iBot-iMaxHeight);
	}
	UT_sint32 iXlow = pDA->xoff - m_iXpad;
	UT_sint32 iYlow = pDA->yoff - m_iYpad;

	UT_Rect box(iXlow + pDA->pG->tlu(2), iYlow + pDA->pG->tlu(2), getFullWidth() - pDA->pG->tlu(4), iFullHeight - pDA->pG->tlu(4));
	getPage()->expandDamageRect(box.left,box.top,box.width,box.height);
	getView()->drawSelectionBox(box, true);
}
void fp_EndnoteContainer::layout(void)
{
	_setMaxContainerHeight(0);
	UT_sint32 iY = 0, iPrevY = 0;
	iY= 0;
	UT_uint32 iCountContainers = countCons();
	fp_Container *pContainer, *pPrevContainer = NULL;
	for (UT_uint32 i=0; i < iCountContainers; i++)
	{
		pContainer = static_cast<fp_Container*>(getNthCon(i));
//
// This is to speedup redraws.
//
		if(pContainer->getHeight() > _getMaxContainerHeight())
			_setMaxContainerHeight(pContainer->getHeight());

		if(pContainer->getY() != iY)
		{
			pContainer->clearScreen();
		}
			
		pContainer->setY(iY);
		UT_sint32 iContainerHeight = pContainer->getHeight();
		UT_sint32 iContainerMarginAfter = pContainer->getMarginAfter();
		if (pPrevContainer)
		{
			pPrevContainer->setAssignedScreenHeight(iY - iPrevY);
		}
		iPrevY = iY;

		iY += iContainerHeight;
		iY += iContainerMarginAfter;
		pPrevContainer = pContainer;
	}

	// Correct height position of the last line
	if (pPrevContainer)
	{
		pPrevContainer->setAssignedScreenHeight(iY - iPrevY + 1);
	}

	UT_sint32 iNewHeight = iY;

	if (getHeight() == iNewHeight)
	{
		return;
	}
	setHeight(iNewHeight);
	fl_EndnoteLayout * pEL = static_cast<fl_EndnoteLayout *>(getSectionLayout());
	FL_DocLayout * pDL = pEL->getDocLayout();
	fl_DocSectionLayout * pDSL = pDL->getDocSecForEndnote(this);
	fp_Page * pPage = getPage();
	pDSL->setNeedsSectionBreak(true,pPage);
}
fl_DocSectionLayout * fp_AnnotationContainer::getDocSectionLayout(void)
{
	fl_AnnotationLayout * pFL = static_cast<fl_AnnotationLayout *>(getSectionLayout());
	fl_ContainerLayout * pDSL = pFL->myContainingLayout();
	while(pDSL && pDSL->getContainerType() != FL_CONTAINER_DOCSECTION)
	{
		pDSL = pDSL->myContainingLayout();
	}
	UT_ASSERT(pDSL && (pDSL->getContainerType() == FL_CONTAINER_DOCSECTION));
	return static_cast<fl_DocSectionLayout *>(pDSL);
}
/*!
 * Overload the setY method
 */
void fp_TOCContainer::setY(UT_sint32 i)
{
	bool bIsFirstBroken = false;
	UT_sint32 iOldY = getY();
	xxx_UT_DEBUGMSG(("fp_TOCContainer: setY set to %d \n",i));
	if(isThisBroken())
	{
		xxx_UT_DEBUGMSG(("setY: getMasterTOC %x FirstBrokenTOC %x this %x \n",getMasterTOC(),getMasterTOC()->getFirstBrokenTOC(),this));
		//	if(getMasterTOC()->getFirstBrokenTOC() != this)
		{
			xxx_UT_DEBUGMSG(("setY: Later broken TOC set to %d \n",i));
			fp_VerticalContainer::setY(i);
			return;
		}
		bIsFirstBroken = true;
	}
//
// Create an initial broken TOC if none exists
//
	if(!bIsFirstBroken && (getFirstBrokenTOC() == NULL))
	{
		VBreakAt(0);
	}
	iOldY = getY();
	if(i == iOldY)
	{
		return;
	}
	clearScreen();
//
// FIXME: Do I need to force another breakSection or will happen 
// automatically?
//
	xxx_UT_DEBUGMSG(("Set Reformat 1 now from TOC %x in TOCLayout %x \n",this,getSectionLayout()));
	getSectionLayout()->setNeedsReformat(getSectionLayout());
	fp_VerticalContainer::setY(i);
	adjustBrokenTOCs();
}
fp_Container * fp_AnnotationContainer::getNextContainerInSection() const
{

	fl_ContainerLayout * pCL = static_cast<fl_ContainerLayout *>(getSectionLayout());
	fl_ContainerLayout * pNext = pCL->getNext();
	while(pNext && pNext->getContainerType() == FL_CONTAINER_ENDNOTE)
	{
		pNext = pNext->getNext();
	}
	if(pNext)
	{
		return pNext->getFirstContainer();
	}
	return NULL;
}
fp_Container * fp_AnnotationContainer::getPrevContainerInSection() const
{

	fl_ContainerLayout * pCL = static_cast<fl_ContainerLayout *>(getSectionLayout());
	fl_ContainerLayout * pPrev = pCL->getPrev();
	while(pPrev && pPrev->getContainerType() == FL_CONTAINER_ENDNOTE)
	{
		pPrev = pPrev->getPrev();
	}
	if(pPrev)
	{
		return pPrev->getLastContainer();
	}
	return NULL;
}
void fp_FrameContainer::setPreferedPageNo(UT_sint32 i)
{
     if(m_iPreferedPageNo == i)
       return;
     m_iPreferedPageNo =  i;
     fl_FrameLayout * pFL = static_cast<fl_FrameLayout *>(getSectionLayout());
     FL_DocLayout * pDL = pFL->getDocLayout();
     if(pDL->isLayoutFilling())
       return;
     PD_Document * pDoc = pDL->getDocument();
     UT_UTF8String sVal;
     UT_UTF8String_sprintf(sVal,"%d",i);
     const char * attr = PT_PROPS_ATTRIBUTE_NAME;
     UT_UTF8String sAttVal = "pref-page:";
     sAttVal += sVal.utf8_str();
     
     pDoc->changeStruxAttsNoUpdate(pFL->getStruxDocHandle(),attr,sAttVal.utf8_str());
}
/*!
 * Return the DocSectionLayout that owns this
 */
fl_DocSectionLayout * fp_ContainerObject::getDocSectionLayout(void)
{
    fl_ContainerLayout * pCL = static_cast<fl_ContainerLayout *>(getSectionLayout());
    while(pCL && (pCL->getContainerType() != FL_CONTAINER_DOCSECTION) && (pCL->getContainerType() != FL_CONTAINER_HDRFTR))
    {
        xxx_UT_DEBUGMSG(("getDocSectionLayout: Container type %s \n",getContainerString()));
        pCL = pCL->myContainingLayout();
    }
    if(pCL && (pCL->getContainerType() == FL_CONTAINER_HDRFTR))
    {
        return static_cast<fl_HdrFtrSectionLayout *>(pCL)->getDocSectionLayout();
    }
    else if(pCL)
    {
        return static_cast<fl_DocSectionLayout *>(pCL);
    }
    return NULL;
}
void fp_FootnoteContainer::setPage(fp_Page * pPage)
{
	if(pPage && (m_pPage != NULL) && m_pPage != pPage)
	{
		clearScreen();
		m_pPage->removeFootnoteContainer(this);
		getSectionLayout()->markAllRunsDirty();
	}
	m_pPage = pPage;
	if(pPage)
	{
		getFillType()->setParent(pPage->getFillType());
	}
	else
	{
		getFillType()->setParent(NULL);
	}
}
void fp_EndnoteContainer::clearScreen(void)
{
	UT_DEBUGMSG(("Clearscreen on Endnote container %p , height = %d \n",this,getHeight()));
	fl_ContainerLayout * pCL = static_cast<fl_ContainerLayout *>(getSectionLayout());
	pCL->setNeedsRedraw();
	if(!m_bOnPage)
	{
		return;
	}
	if(m_bCleared)
	{
		return;
	}
	if(getColumn() && (getHeight() != 0))
	{
		if(getPage() == NULL)
		{
			return;
		}
		fl_DocSectionLayout * pDSL = getPage()->getOwningSection();
		if(pDSL == NULL)
		{
			return;
		}
		UT_sint32 iLeftMargin = pDSL->getLeftMargin();
		UT_sint32 iRightMargin = pDSL->getRightMargin();
		UT_sint32 iWidth = getPage()->getWidth();
		iWidth = iWidth - iLeftMargin - iRightMargin;
		UT_sint32 xoff,yoff;
		static_cast<fp_Column *>(getColumn())->getScreenOffsets(this,xoff,yoff);
		UT_sint32 srcX = getX();
		UT_sint32 srcY = getY();
		getFillType()->Fill(getGraphics(),srcX,srcY,xoff,yoff,iWidth,getHeight());
	}
	fp_Container * pCon = NULL;
	UT_sint32 i = 0;
	for(i=0; i< countCons(); i++)
	{
		xxx_UT_DEBUGMSG(("Clear screen on container %d in endnote \n",i));
		pCon = static_cast<fp_Container *>(getNthCon(i));
		pCon->clearScreen();
	}
	m_bCleared = true;
}
/*!
 * This method returns the padding to be applied between a line approaching
 * wrapped frame or image from the right. 
 * y Is the top of the line in logical units as defined relative to the
 * y position on the screen.
 * height is the height of the line.
 * If tight wrapping is set on a positioned object this number can be negative
 * which means the line can encroach into the rectangular region of the
 * image provided the region is transparent.
 */
UT_sint32 fp_FrameContainer::getRightPad(UT_sint32 y, UT_sint32 height)
{
  fl_FrameLayout *pFL = static_cast<fl_FrameLayout *>(getSectionLayout());
  UT_sint32 pad = pFL->getBoundingSpace();
  UT_Rect * pRect = getScreenRect();
  UT_sint32 yC = pRect->top;
  if(!isTightWrapped() || !isWrappingSet())
  {
    return pad;
  }
  if(FL_FRAME_TEXTBOX_TYPE == pFL->getFrameType())
  {
    return pad;
  }
  if(pFL->getBackgroundImage() == NULL)
  {
    return pad;
  }
  UT_sint32 iRight = pFL->getBackgroundImage()->GetOffsetFromRight(getGraphics(),pad,y - yC,height);
  xxx_UT_DEBUGMSG(("Local Y %d iRight %d width %d \n",y-yC,iRight,getFullWidth()));
  return iRight;
}
/*!
 * This deletes all the broken TOCs from this master TOC.
 * This routine assumes that a clear screen has been set already.
 */
void fp_TOCContainer::deleteBrokenTOCs(bool bClearFirst)
{
	if(isThisBroken())
	{
		return;
	}
	if(bClearFirst)
	{
		clearScreen();
		//
		// Remove broken TOC pointers
		//
		clearBrokenContainers();
	}
	if(getFirstBrokenTOC() == NULL)
	{
		return;
	}
	fp_TOCContainer * pBroke = NULL;
	fp_TOCContainer * pNext = NULL;
	pBroke = getFirstBrokenTOC();
	bool bFirst = true;
	while(pBroke )
	{
		pNext = static_cast<fp_TOCContainer *>(pBroke->getNext());
		if(!bFirst)
		{
		        fp_Container * pConBroke =  pBroke->getContainer();
			if(pConBroke)
			{
			    UT_sint32 i = pBroke->getContainer()->findCon(pBroke);
//
// First broken TOC is not in the container.
//
			    if(i >=0)
			    {
			        fp_Container * pCon = pBroke->getContainer();
				pBroke->setContainer(NULL);
				pCon->deleteNthCon(i);
			    }
			}
		}
		bFirst = false;
		xxx_UT_DEBUGMSG(("SEVIOR: Deleting broken TOC %x \n",pBroke));
		delete pBroke;
		if(pBroke == getLastBrokenTOC())
		{
			pBroke = NULL;
		}
		else
		{
			pBroke = pNext;
		}
	}
	setFirstBrokenTOC(NULL);
	setLastBrokenTOC(NULL);
	setNext(NULL);
	setPrev(NULL);
//	if(bClearFirst)
	{
		fl_TOCLayout * pTL = static_cast<fl_TOCLayout *>(getSectionLayout());
		fl_DocSectionLayout * pDSL = pTL->getDocSectionLayout();
		pDSL->deleteBrokenTablesFromHere(pTL);
	}
}
/*!
 * Returns true if the frame should be relocated before placing on a page
 */
bool fp_FrameContainer::isRelocate(void) const
{
     fl_FrameLayout * pFL = static_cast<fl_FrameLayout *>(getSectionLayout());
     return pFL->isRelocate();
}
/*!
 * Returns true if the supplied screen rectangle overlaps with frame
 * container. This method takes account of transparening and tight wrapping.
 */
bool fp_FrameContainer::overlapsRect(UT_Rect & rec)
{
     UT_Rect * pMyFrameRec = getScreenRect();
     fl_FrameLayout * pFL = static_cast<fl_FrameLayout *>(getSectionLayout());
     UT_sint32 iextra = pFL->getBoundingSpace() -2;
     pMyFrameRec->left -= iextra;
     pMyFrameRec->top -= iextra;
     pMyFrameRec->width += 2*iextra;
     pMyFrameRec->height += 2*iextra;
     xxx_UT_DEBUGMSG(("look at rec.left %d top %d width %d  \n",rec.left,rec.top,rec.width));
     if(rec.intersectsRect(pMyFrameRec))
     {
         if(!isTightWrapped())
	 {
	      delete pMyFrameRec;
	      return true;
	 }
	 UT_sint32 iTweak = getGraphics()->tlu(2);
	 pMyFrameRec->left += iextra + iTweak;
	 pMyFrameRec->top += iextra + iTweak;
	 pMyFrameRec->width -= (2*iextra + 2*iTweak);
	 pMyFrameRec->height -= (2*iextra + 2*iTweak);

	 UT_sint32 y = rec.top - pMyFrameRec->top;
	 UT_sint32 h = rec.height;
	 if(pFL->getBackgroundImage() == NULL)
	 {
	      delete pMyFrameRec;
	      return true;
	 }
	 UT_sint32 pad = pFL->getBoundingSpace();
	 UT_sint32 iLeft = pFL->getBackgroundImage()->GetOffsetFromLeft(getGraphics(),pad,y,h);
	 xxx_UT_DEBUGMSG(("iLeft projection %d \n",iLeft));
	 if(iLeft < -getWidth())
	 {
	   //
	   // Pure transparent.
	   //
	   xxx_UT_DEBUGMSG(("Overlaps pure transparent line top %d line height %d image top %d \n",rec.top,rec.height,y));
	      delete pMyFrameRec;
	      return false;
	 }
	 xxx_UT_DEBUGMSG(("iLeft in overlapRect %d Y %d \n",iLeft,y));
	 if(rec.left < pMyFrameRec->left)
	 {
              pMyFrameRec->left -= iLeft;
	      xxx_UT_DEBUGMSG(("Moves Image left border by %d to %d \n",-iLeft,pMyFrameRec->left));
	 }
	 else
	 {
	      UT_sint32 iRight = pFL->getBackgroundImage()->GetOffsetFromRight(getGraphics(),pad,y,h);
              pMyFrameRec->width += iRight;
	      xxx_UT_DEBUGMSG(("Reduce Image width by %d to %d \n",iRight,pMyFrameRec->width));
	 }
	 if(rec.intersectsRect(pMyFrameRec))
	 {
	   xxx_UT_DEBUGMSG(("Frame Still overlaps \n"));
	   delete pMyFrameRec;
	   return true;
	 }
	 xxx_UT_DEBUGMSG(("Tight Frame no longer overlaps \n"));
	 xxx_UT_DEBUGMSG(("Line Top %d Height %d left %d width %d \n",rec.top,rec.height,rec.left,rec.width));
	 xxx_UT_DEBUGMSG(("Image Top %d Height %d left %d width %d \n",pMyFrameRec->top,pMyFrameRec->height,pMyFrameRec->left,pMyFrameRec->width));
	 xxx_UT_DEBUGMSG(("Relative Top of line %d \n",y));
     }
     delete pMyFrameRec;
     return false;
}
UT_uint32 fp_AnnotationContainer::getPID(void)
{
        fl_AnnotationLayout * pAL = static_cast<fl_AnnotationLayout *>(getSectionLayout());
	return pAL->getAnnotationPID();
}
/*!
 Draw container content
 \param pDA Draw arguments
 */
void fp_FrameContainer::draw(dg_DrawArgs* pDA)
{
	FV_View * pView = getView();
	UT_return_if_fail( pView);
	
	xxx_UT_DEBUGMSG(("FrameContainer %x called, page %x \n",this,getPage()));
	if(getPage() == NULL)
	{
	     getSectionLayout()->format();
	     getSectionLayout()->setNeedsReformat(getSectionLayout());
	     if(getPage() == NULL)
	     {
			 return;
	     }
	}
	if(pView)
	{
		if(pView->getFrameEdit()->getFrameEditMode() == FV_FrameEdit_DRAG_EXISTING)
		{
			if((pView->getFrameEdit()->getFrameContainer() == this))
			{
				return;
			}
		}
	}
//
// Only draw the lines in the clipping region.
//
/*
	[Somewhere down here is where the logic to only draw the region of the frame which
	is within the complement of the union of all higher frames needs to be. We need to
	draw the applicable region of the rectangle we're on, then unify it with (if
	applicable) the higher union.] <-- Possibly obsolete comment, not sure.
	I think I might have landed on an alternative solution involving more rearranging
	of the storage of the FrameContainers, based on their z-index.  Not sure how far
	I got with that or if it worked either.  See also abi bug 7664 and the original
	discussions about defining the undefinedness of layered frame behaviour.
*/

	if(m_bOverWrote)
	{
		pDA->bDirtyRunsOnly = false;
	}
	dg_DrawArgs da = *pDA;
	GR_Graphics * pG = da.pG;
	UT_return_if_fail( pG);

	UT_sint32 x = pDA->xoff - m_iXpad;
	UT_sint32 y = pDA->yoff - m_iYpad;
	getPage()->expandDamageRect(x,y,getFullWidth(),getFullHeight());
	if(!pDA->bDirtyRunsOnly || m_bNeverDrawn)
	{
		if(m_bNeverDrawn)
		{
			pDA->bDirtyRunsOnly= false;
		} 
		UT_sint32 srcX,srcY;
		getSectionLayout()->checkGraphicTick(pG);
		srcX = -m_iXpad;
		srcY = -m_iYpad;
		//
		// Only fill to the bottom of the viewed page.
		//
		UT_sint32 iFullHeight = getFullHeight();
		fl_DocSectionLayout * pDSL = getDocSectionLayout();
		UT_sint32 iMaxHeight = 0;
		if(!pG->queryProperties(GR_Graphics::DGP_PAPER) && (pView->getViewMode() != VIEW_PRINT))
		{
		        iMaxHeight = pDSL->getActualColumnHeight();
		}
		else
		{
		        iMaxHeight = getPage()->getHeight();
		}
		UT_sint32 iBot = getFullY()+iFullHeight;
		if(iBot > iMaxHeight)
		{
		        iFullHeight = iFullHeight - (iBot-iMaxHeight);
		}
		getFillType()->Fill(pG,srcX,srcY,x,y,getFullWidth(),iFullHeight);
		m_bNeverDrawn = false;
	}
	UT_uint32 count = countCons();
	UT_DEBUGMSG(("Number of containers in frame %d \n",count));
	const UT_Rect * pPrevRect = pDA->pG->getClipRect();
	UT_Rect * pRect = getScreenRect();
	UT_Rect newRect;
	bool bRemoveRectAfter = false;
	bool bSetOrigClip = false;
	bool bSkip = false;
	if((pPrevRect == NULL) && pG->queryProperties(GR_Graphics::DGP_SCREEN))
	{
		pDA->pG->setClipRect(pRect);
		UT_DEBUGMSG(("Clip bottom is %d \n",pRect->top + pRect->height));
		bRemoveRectAfter = true;
	}
	else if(pPrevRect && !pRect->intersectsRect(pPrevRect))
	{
		bSkip = true;
		xxx_UT_DEBUGMSG(("External Clip bottom is %d \n",pRect->top + pRect->height));
	}
	else if(pPrevRect)
	{
		newRect.top = UT_MAX(pPrevRect->top,pRect->top);
		UT_sint32 iBotPrev = pPrevRect->height + pPrevRect->top;
		UT_sint32 iBot = pRect->height + pRect->top;
		newRect.height = UT_MIN(iBotPrev,iBot) - newRect.top;
		newRect.width = pPrevRect->width;
		newRect.left = pPrevRect->left;
		if((newRect.height > 0) && pDA->pG->queryProperties(GR_Graphics::DGP_SCREEN))
		{
			pDA->pG->setClipRect(&newRect);
			bSetOrigClip = true;
		}
		else
		{
			bSkip = true;
		}
	}
	if(!bSkip)
	{
		for (UT_uint32 i = 0; i<count; i++)
		{
			fp_ContainerObject* pContainer = static_cast<fp_ContainerObject*>(getNthCon(i));
			da.xoff = pDA->xoff + pContainer->getX();
			da.yoff = pDA->yoff + pContainer->getY();
			pContainer->draw(&da);
		}
	}
	m_bNeverDrawn = false;
	m_bOverWrote = false;
	if(bRemoveRectAfter)
	{
		pDA->pG->setClipRect(NULL);
	}
	if(bSetOrigClip)
	{
		pDA->pG->setClipRect(pPrevRect);
	}
	delete pRect;
	drawBoundaries(pDA);
}
/*! 
 * This method returns the value of the Annotation reference (or anchor)
 */
UT_sint32 fp_AnnotationContainer::getValue(void)
{
	fl_AnnotationLayout * pAL = static_cast<fl_AnnotationLayout *>(getSectionLayout());
	FL_DocLayout * pDL = pAL->getDocLayout();
	return pDL->getAnnotationVal(pAL->getAnnotationPID());
}
void fp_FrameContainer::layout(void)
{
	_setMaxContainerHeight(0);
	UT_sint32 iY = 0, iPrevY = 0;
	iY= 0;
	UT_uint32 iCountContainers = countCons();
	fp_Container *pContainer, *pPrevContainer = NULL;
	for (UT_uint32 i=0; i < iCountContainers; i++)
	{
		pContainer = static_cast<fp_Container*>(getNthCon(i));
//
// This is to speedup redraws.
//
		if(pContainer->getHeight() > _getMaxContainerHeight())
			_setMaxContainerHeight(pContainer->getHeight());

		if(pContainer->getY() != iY)
		{
			pContainer->clearScreen();
		}
		if(iY > getHeight())
		{
			pContainer->setY(-1000000);
		}
		else
		{
			pContainer->setY(iY);
		}
		UT_sint32 iContainerHeight = pContainer->getHeight();
		UT_sint32 iContainerMarginAfter = pContainer->getMarginAfter();
		if(pContainer->getContainerType() == FP_CONTAINER_TABLE)
		{
			fp_TableContainer * pTab = static_cast<fp_TableContainer *>(pContainer);
			iContainerHeight = pTab->getHeight();
			if(!pTab->isThisBroken() && (pTab->getFirstBrokenTable() == NULL))
			{
				/*fp_Container * pBroke = static_cast<fp_Container *> */(pTab->VBreakAt(0));
			}
		}

		iY += iContainerHeight;
		iY += iContainerMarginAfter;
		//iY +=  0.5;

		if (pPrevContainer)
		{
			pPrevContainer->setAssignedScreenHeight(iY - iPrevY);
		}
		pPrevContainer = pContainer;
		iPrevY = iY;
	}

	// Correct height position of the last line
	if (pPrevContainer)
	{
		if(iY > getHeight())
		{
			pPrevContainer->setAssignedScreenHeight(-1000000);
		}
		else
		{
			pPrevContainer->setAssignedScreenHeight(iY - iPrevY + 1);
		}
	}
	fl_FrameLayout * pFL = static_cast<fl_FrameLayout *>(getSectionLayout());
	if(pFL->expandHeight() && (iY > pFL->minHeight()))
	{
	     setHeight(iY+m_iYpad*2);
	}
}
/*!
 * Return a pointer to the Graphics class for this object
 */
GR_Graphics * fp_ContainerObject::getGraphics(void) const
{
	return getSectionLayout()->getDocLayout()->getGraphics();
}
/*! 
 * This method returns the value of the TOC reference (or anchor)
 */
UT_sint32 fp_TOCContainer::getValue(void)
{
	fl_TOCLayout * pTL = static_cast<fl_TOCLayout *>(getSectionLayout());
	return pTL->getTOCPID();
}
/*!
 * This method creates a new broken toccontainer, broken at the
 * offset given. 
 * If the new TOCcontainer is broken from a pre-existing 
 * broken TOC it is inserted into the holding vertical container after
 * the old broken TOC.
 * It also inserted into the linked list of containers in the vertical
 * container.
 * vpos is relative to the either the start of the TOC if it's the first
 * non-zero vpos or relative to the previous ybreak if it's further down.
 */
fp_ContainerObject * fp_TOCContainer::VBreakAt(UT_sint32 vpos)
{
//
// Do the case of creating the first broken TOC from the master TOC.
// 
	fp_TOCContainer * pBroke = NULL;
	if(!isThisBroken() && getLastBrokenTOC() == NULL)
	{
		if(getFirstBrokenTOC() != NULL)
		{
			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
			return NULL;
		}
		pBroke = new fp_TOCContainer(getSectionLayout(),this);
		UT_DEBUGMSG(("SEVIOR:!!!!!!! First broken TOC %p \n",pBroke));
		pBroke->setYBreakHere(vpos);
		pBroke->setYBottom(fp_VerticalContainer::getHeight());
		// leave this in!		UT_ASSERT(pBroke->getHeight());
		setFirstBrokenTOC(pBroke);
		setLastBrokenTOC(pBroke);
		pBroke->setContainer(getContainer());
		static_cast<fp_VerticalContainer *>(pBroke)->setHeight(pBroke->getHeight());
		static_cast<fp_VerticalContainer *>(pBroke)->setY(getY());
		return pBroke;
	}
//
// Now do the case of breaking a Master TOC.
//
	if(getMasterTOC() == NULL)
	{
		return getLastBrokenTOC()->VBreakAt(vpos);
	}
	UT_sint32 iTotalHeight = getTotalTOCHeight();
	if (vpos >= iTotalHeight)
	{
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
		return NULL;
	}

	pBroke = new fp_TOCContainer(getSectionLayout(),getMasterTOC());
	getMasterTOC()->setLastBrokenTOC(pBroke);

	xxx_UT_DEBUGMSG(("SEVIOR!!!!!!!!!!!  New broken TOC %x \n",getLastBrokenTOC()));

//
// vpos is relative to the container that contains this height but we need
// to add in the height above it.
//
	setYBottom(getYBreak() + vpos -1);
	UT_ASSERT(getHeight() >0);
	pBroke->setYBreakHere(getYBreak()+vpos);
	pBroke->setYBottom(iTotalHeight);
	UT_ASSERT(pBroke->getHeight() > 0);
	UT_sint32 i = -1;
//
// The structure of TOC linked list is as follows.
// NULL <= Master <==> Next <==> Next => NULL
//          first 
// ie terminated by NULL's in the getNext getPrev list. The second
// broken TOC points and is pointed to by the Master TOC
// 
	pBroke->setPrev(this);
	fp_Container * pUpCon = NULL;
	if(getMasterTOC()->getFirstBrokenTOC() == this)
	{
		pUpCon = getMasterTOC()->getContainer();
		pBroke->setPrev(getMasterTOC());
		pBroke->setNext(NULL);
		getMasterTOC()->setNext(pBroke);
		setNext(pBroke);
		if (pUpCon)
		{
			i = pUpCon->findCon(getMasterTOC());
		}
	}
	else
	{
		pBroke->setNext(NULL);
		setNext(pBroke);
		if(getYBreak() == 0 )
		{
			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
			pUpCon = getMasterTOC()->getContainer();
			if(pUpCon)
			{
				i = pUpCon->findCon(getMasterTOC());
			}
		}
		else
		{
			pUpCon = getContainer();
			if (pUpCon)
			{
				i = pUpCon->findCon(this);
			}
		}
	}
	if((i >= 0) && (i < pUpCon->countCons() -1))
	{
		pUpCon->insertConAt(pBroke,i+1);
	}
	else if((i >= 0) && (i == pUpCon->countCons() -1))
	{
		pUpCon->addCon(pBroke);
	}
	else
	{
		UT_DEBUGMSG(("Breaking a TOC that is not yet inserted\n"));
	}
	pBroke->setContainer(pUpCon);
	//
	// Now deal with issues from a container overlapping the top of the
	// of the new broken TOC.
	//
	// Skip this for now. Look at fp_TableContainer to see if it's needed later
	//
	static_cast<fp_VerticalContainer *>(pBroke)->setHeight(pBroke->getHeight());	
	return pBroke;
}
/*! 
 * This method returns the value of the footnote reference (or anchor)
 */
UT_sint32 fp_FootnoteContainer::getValue(void)
{
	fl_FootnoteLayout * pFL = static_cast<fl_FootnoteLayout *>(getSectionLayout());
	FL_DocLayout * pDL = pFL->getDocLayout();
	return pDL->getFootnoteVal(pFL->getFootnotePID());
}
void fl_EmbedLayout::setNeedsReformat(fl_ContainerLayout * /*pCL*/, UT_uint32 /*offset*/)
{
  m_bNeedsReformat = true;
  if(getSectionLayout())
    getSectionLayout()->setNeedsReformat(this);
}