fp_Column * fp_TOCContainer::getBrokenColumn(void) { if(!isThisBroken()) { return static_cast<fp_Column *>(fp_VerticalContainer::getColumn()); } fp_TOCContainer * pBroke = this; bool bStop = false; fp_Column * pCol = NULL; while(pBroke && pBroke->isThisBroken() && !bStop) { fp_Container * pCon = pBroke->getContainer(); if(pCon->isColumnType()) { if(pCon->getContainerType() == FP_CONTAINER_COLUMN) { pCol = static_cast<fp_Column *>(pCon); } else { pCol = static_cast<fp_Column *>(pCon->getColumn()); } bStop = true; } else { UT_ASSERT(0); } } if(pBroke && !bStop) { pCol = static_cast<fp_Column *>(pBroke->getContainer()); } return pCol; }
/*! * The caller to this method requests a break at the vertical height * given. It returns the actual break height, which will always be * less than or equal to the requested height. The function returns -1 * if the table does not need to be broken. */ UT_sint32 fp_TOCContainer::wantVBreakAt(UT_sint32 vpos) { if(isThisBroken()) { return getMasterTOC()->wantVBreakAt(vpos); } UT_sint32 count = countCons(); UT_sint32 i =0; UT_sint32 iYBreak = vpos; UT_sint32 iTotHeight = getTotalTOCHeight(); if (iYBreak > iTotHeight) { return -1; } else if (iYBreak > iTotHeight - FP_TABLE_MIN_BROKEN_HEIGHT) { iYBreak = iTotHeight - FP_TABLE_MIN_BROKEN_HEIGHT; } fp_Line * pLine; for(i=0; i< count; i++) { pLine = static_cast<fp_Line *>(getNthCon(i)); if((pLine->getY() <= vpos) && (pLine->getY() + pLine->getHeight() +pLine->getMarginAfter() > vpos)) { // // Line overlaps break point. Find break here // iYBreak = pLine->getY(); } } return iYBreak; }
void fp_TOCContainer::clearScreen(void) { if(getPage() == NULL) { return; } if(isThisBroken() && getContainer()) { xxx_UT_DEBUGMSG(("Doing Clear Screen on Broken TOC %x \n",this)); UT_sint32 iHeight = getHeight(); UT_sint32 iWidth = getContainer()->getWidth(); UT_sint32 srcX = getX(); UT_sint32 srcY = getY(); if(getFirstBrokenTOC() == this) { srcY = getMasterTOC()->getY(); } fp_Column * pCol = static_cast<fp_Column *>(getColumn()); UT_sint32 x,y; getPage()->getScreenOffsets(pCol,x,y); x += srcX; y += srcY; getFillType().setWidthHeight(getGraphics(),iWidth,iHeight); getFillType().Fill(getGraphics(),srcX,srcY,x,y,iWidth,iHeight); xxx_UT_DEBUGMSG(("x %d y %d width %d height %d \n",x,y,iWidth,iHeight)); return; } fp_Container * pCon = NULL; UT_sint32 i = 0; for(i=0; i< countCons(); i++) { pCon = static_cast<fp_Container *>(getNthCon(i)); pCon->clearScreen(); } }
void fp_TOCContainer::setContainer(fp_Container * pContainer) { xxx_UT_DEBUGMSG(("!!!!!-----!!!!TOC Container set to %x \n",pContainer)); if(isThisBroken()) { fp_Container::setContainer(pContainer); return; } if (pContainer == getContainer()) { return; } if (getContainer() && (pContainer != NULL)) { clearScreen(); } fp_Container::setContainer(pContainer); fp_TOCContainer * pBroke = getFirstBrokenTOC(); if(pBroke) { pBroke->setContainer(pContainer); } if(pContainer == NULL) { xxx_UT_DEBUGMSG(("Set master TOC %x container to NULL \n",this)); return; } setWidth(pContainer->getWidth()); }
fp_TOCContainer * fp_TOCContainer::getFirstBrokenTOC(void) const { if(isThisBroken()) { return getMasterTOC()->getFirstBrokenTOC(); } return m_pFirstBrokenTOC; }
void fp_TOCContainer::setLastBrokenTOC(fp_TOCContainer * pBroke) { if(isThisBroken()) { getMasterTOC()->setLastBrokenTOC(pBroke); } m_pLastBrokenTOC = pBroke; }
void fp_TOCContainer::setLastBrokenTOC(fp_TOCContainer * pBroke) { if(isThisBroken()) { fp_TOCContainer * pMaster = getMasterTOC(); pMaster->setLastBrokenTOC(pBroke); fp_TOCContainer * pNext = static_cast<fp_TOCContainer *>(pMaster); while(pNext) { pNext->setLastBrokenTOC( pBroke); pNext = static_cast<fp_TOCContainer *>(pNext->getNext()); } } m_pLastBrokenTOC = pBroke; }
void fp_TOCContainer::setFirstBrokenTOC(fp_TOCContainer * pBroke) { if(isThisBroken()) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); fp_TOCContainer * pMaster = getMasterTOC(); pMaster->setFirstBrokenTOC(pBroke); fp_TOCContainer * pNext = static_cast<fp_TOCContainer *>(pMaster); while(pNext) { pNext->setFirstBrokenTOC( pBroke); pNext = static_cast<fp_TOCContainer *>(pNext->getNext()); } } m_pFirstBrokenTOC = pBroke; }
/*! Draw container content \param pDA Draw arguments */ void fp_TOCContainer::draw(dg_DrawArgs* pDA) { if(getPage() == NULL) { return; } if(!isThisBroken() && getFirstBrokenTOC()) { getFirstBrokenTOC()->draw(pDA); return; } fp_TOCContainer * pMaster = this; if(getMasterTOC()) { pMaster = getMasterTOC(); } xxx_UT_DEBUGMSG(("TOC: Drawing broken TOC %x x %d, y %d width %d height %d \n",this,pDA->xoff,pDA->yoff,getWidth(),getHeight())); // // Only draw the lines in the clipping region. // dg_DrawArgs da = *pDA; UT_uint32 count = pMaster->countCons(); UT_sint32 iYStart = getYBreak(); UT_sint32 iYBottom = getYBottom(); xxx_UT_DEBUGMSG(("Drawing TOC, yBreak %d ybottom %d \n",iYStart,iYBottom)); for (UT_uint32 i = 0; i<count; i++) { fp_ContainerObject* pContainer = static_cast<fp_ContainerObject*>(pMaster->getNthCon(i)); if(pContainer->getY() < iYStart) { continue; } if(pContainer->getY() > iYBottom) { break; } da.xoff = pDA->xoff + pContainer->getX(); da.yoff = pDA->yoff + pContainer->getY() - iYStart; pContainer->draw(&da); } _drawBoundaries(pDA); }
void fp_TOCContainer::deleteBrokenAfter(bool bClearFirst) { if (!isThisBroken()) { if (getFirstBrokenTOC()) { return getFirstBrokenTOC()->deleteBrokenAfter(bClearFirst); } return; } if (bClearFirst) { clearScreen(); getMasterTOC()->clearBrokenContainers(); } fp_TOCContainer * pBroke = static_cast<fp_TOCContainer *>(getNext()); fp_TOCContainer * pNext = NULL; while(pBroke) { pNext = static_cast<fp_TOCContainer *> (pBroke->getNext()); if (pBroke->getContainer()) { UT_sint32 i = pBroke->getContainer()->findCon(pBroke); if (i >= 0) { pBroke->getContainer()->deleteNthCon(i); pBroke->setContainer(NULL); } } delete pBroke; pBroke = pNext; } setNext(NULL); if (!getPrev()) { getMasterTOC()->setNext(NULL); } getMasterTOC()->setLastBrokenTOC(this); setYBottom(getTotalTOCHeight()); }
UT_sint32 fp_TOCContainer::getBrokenNumber(void) { if(!isThisBroken()) { return 0; } fp_TOCContainer * pTOC = getMasterTOC()->getFirstBrokenTOC(); UT_sint32 i = 1; while(pTOC && pTOC != this) { pTOC = static_cast<fp_TOCContainer *>(pTOC->getNext()); i++; } if(!pTOC) { return -1; } return i; }
/*! * Return the height of this Table taking into account the possibility * of it being broken. */ UT_sint32 fp_TOCContainer::getHeight(void) const { UT_sint32 iFullHeight = fp_VerticalContainer::getHeight(); if(!isThisBroken()) { // // If this is a master table but it contains broken tables, we actually // want the height of the first broken table. The Master table is the // one that actually has a relevant Y value in the vertical container. // All other Y offsets from the broken tables are calculated relative to // it. // if(getFirstBrokenTOC() != NULL) { return getFirstBrokenTOC()->getHeight(); } return iFullHeight; } UT_sint32 iMyHeight = getYBottom() - getYBreak(); return iMyHeight; }
/*! * 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(); }
/*! * The caller to this method requests a break at the vertical height * given. It returns the actual break height, which will always be * less than or equal to the requested height. */ UT_sint32 fp_TOCContainer::wantVBreakAt(UT_sint32 vpos) { if(isThisBroken()) { return getMasterTOC()->wantVBreakAt(vpos); } UT_sint32 count = countCons(); UT_sint32 i =0; UT_sint32 iYBreak = vpos; fp_Line * pLine; for(i=0; i< count; i++) { pLine = static_cast<fp_Line *>(getNthCon(i)); if((pLine->getY() <= vpos) && (pLine->getY() + pLine->getHeight() +pLine->getMarginAfter() > vpos)) { // // Line overlaps break point. Find break here // iYBreak = pLine->getY(); } } return iYBreak; }
/*! * 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 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); } }
/*! * This method adjusts the m_iYBreak and m_iYBottom variables after a * setY method changes the start position of the top of the table. */ void fp_TOCContainer::adjustBrokenTOCs(void) { if(isThisBroken()) { // UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return; } if(getFirstBrokenTOC() == NULL) { return; } if(getFirstBrokenTOC() == getLastBrokenTOC()) { return; } // // FIXME. Both this code and the code in fp_TableContainer, somehow leads to bugs. I've clearly found // workarounds to what this is trying to achive. In pricinple this code should make laying out TOC's // faster. In parctice I suspect it leads to bugs in fb_ColumnBreaker. I'll leave these returns in place // for now, pending removal of the methods. // return; fp_TOCContainer * pBroke = getFirstBrokenTOC(); fp_VerticalContainer * pVC = static_cast<fp_VerticalContainer *>(getContainer()); UT_sint32 iNewHeight = pVC->getMaxHeight() - getY(); UT_sint32 ishift = iNewHeight - pBroke->getYBottom(); UT_sint32 iNewBot = pBroke->getYBottom() + ishift; UT_sint32 iTOCHeight = fp_VerticalContainer::getHeight(); UT_DEBUGMSG(("SEVIOR: ishift = %d iNewHeight %d pBroke->getYBottom() %d \n",ishift,iNewHeight,pBroke->getYBottom())); if(ishift == 0) { return; } if(iNewBot > iTOCHeight) { iNewBot = iTOCHeight; } pBroke->setYBottom(iNewBot); UT_ASSERT(pBroke->getHeight()); pBroke = static_cast<fp_TOCContainer *>(pBroke->getNext()); while(pBroke) { UT_sint32 iNewTop = pBroke->getYBreak(); iNewBot = pBroke->getYBottom(); pBroke->setYBreakHere(iNewTop + ishift); if(pBroke->getNext()) { pBroke->setYBottom(iNewBot+ishift); UT_ASSERT(pBroke->getHeight()); } else { pBroke->setYBottom(iTOCHeight); UT_ASSERT(pBroke->getHeight()); } xxx_UT_DEBUGMSG(("SEVIOR: Broken TOC %x YBreak adjusted to %d Shift is %d height is %d \n",pBroke,iNewTop+ishift,ishift,pBroke->getHeight())); fp_TOCContainer * pPrev = static_cast<fp_TOCContainer *>(pBroke->getPrev()); // // If the height of the previous plus the height of pBroke offset from // the previous position is less that the column height we can delete // this broken TOC. // UT_sint32 iMaxHeight = 0; bool bDeleteOK = false; if(pPrev) { iMaxHeight = static_cast<fp_VerticalContainer *>(pPrev->getContainer())->getMaxHeight(); xxx_UT_DEBUGMSG(("SEVIOR: sum %d maxheight %d \n",(pPrev->getY() + pPrev->getHeight() + pBroke->getHeight()), iMaxHeight)); } if(bDeleteOK && pPrev && (pPrev->getY() + pPrev->getHeight() + pBroke->getHeight() < iMaxHeight)) { // // FIXME: This if should be unnested.... // if(pPrev == this) { pPrev = getFirstBrokenTOC(); } xxx_UT_DEBUGMSG(("SEVIOR; In adjust - Deleting TOC. Max height %d prev Y %d prev Height %d cur Height %d \n",iMaxHeight, pPrev->getY(),pPrev->getHeight(),pBroke->getHeight())); // // Don't need this TOC any more. Delete it and all following TOCs. // after adjusting the previous TOC. // pPrev->setYBottom(iTOCHeight); UT_ASSERT(pPrev->getHeight()); pPrev->setNext( NULL); if(pPrev == getFirstBrokenTOC()) { setNext(NULL); getFirstBrokenTOC()->setYBreakHere(0); UT_ASSERT(getFirstBrokenTOC()->getHeight()); } setLastBrokenTOC(pPrev); xxx_UT_DEBUGMSG(("SEVIOR!!!!!!!!!!! 2 last broken TOC %x deleting %x Master TOC %x \n",getLastBrokenTOC(),pBroke,this)); xxx_UT_DEBUGMSG(("SEVIOR!!!!!!!!!!! 2 get first %x get last broken TOC %x \n",getFirstBrokenTOC(),getLastBrokenTOC())); fp_TOCContainer * pT = getFirstBrokenTOC(); UT_sint32 j = 0; while(pT) { xxx_UT_DEBUGMSG(("SEVIOR: TOC %d is %x \n",j,pT)); j++; pT = static_cast<fp_TOCContainer *>(pT->getNext()); } while(pBroke) { fp_TOCContainer * pNext = static_cast<fp_TOCContainer *>(pBroke->getNext()); UT_sint32 i = pBroke->getContainer()->findCon(pBroke); if(i >=0) { pBroke->getContainer()->deleteNthCon(i); } else { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); } xxx_UT_DEBUGMSG(("SEVIOR: Adjust - Delete TOC %x \n",pBroke)); delete pBroke; pBroke = pNext; } } else { pBroke = static_cast<fp_TOCContainer *>(pBroke->getNext()); } } }