--- fl_BlockLayout.cpp Sun May 07 05:37:10 2000 +++ \AbiWord\abi-0.7.9\src\text\fmt\xp\fl_BlockLayout.cpp Sun May 07 06:21:00 2000 @@ -59,7 +59,10 @@ ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// -#define IsZeroLengthTextRun(p) (((p)->getLength()==0) && ((p)->getType()==FPRUN_TEXT)) +inline UT_Bool IsZeroLengthTextRun(const fp_Run* p) +{ + return p->getLength() == 0 && p->getType() == FPRUN_TEXT; +} ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// @@ -279,9 +282,6 @@ { switch (p1[1]) { - case 'L': - iType = FL_TAB_LEFT; - break; case 'R': iType = FL_TAB_RIGHT; break; @@ -294,6 +294,7 @@ case 'B': iType = FL_TAB_BAR; break; + case 'L': // fall through default: iType = FL_TAB_LEFT; break; @@ -303,12 +304,9 @@ char pszPosition[32]; UT_uint32 iPosLen = p1 - pStart; - UT_ASSERT(iPosLen < 32); + UT_ASSERT(iPosLen < sizeof pszPosition); - for (i=0; iconvertDimension(pszPosition); @@ -631,7 +629,11 @@ void fl_BlockLayout::checkForBeginOnForcedBreak(void) { fp_Line* pFirstLine = getFirstLine(); + UT_ASSERT(pFirstLine); + fp_Run* pFirstRun = pFirstLine->getLastRun(); + UT_ASSERT(pFirstRun); + if (pFirstRun->canContainPoint()) { return; @@ -642,10 +644,13 @@ */ GR_Graphics* pG = m_pLayout->getGraphics(); + UT_ASSERT(pG); + fp_TextRun* pNewRun = new fp_TextRun(this, pG, m_pFirstRun->getBlockOffset(), 0); - pNewRun->setPrev(NULL); - pNewRun->setNext(m_pFirstRun); - m_pFirstRun->setPrev(pNewRun); + // TODO: Check for out-of-memory. Only assert for now + UT_ASSERT(pNewRun); + + m_pFirstRun->insertIntoRunListBeforeThis(*pNewRun); pFirstLine->insertRun(pNewRun); m_pFirstRun = pNewRun; @@ -655,7 +660,11 @@ void fl_BlockLayout::checkForEndOnForcedBreak(void) { fp_Line* pLastLine = getLastLine(); + UT_ASSERT(pLastLine); + fp_Run* pLastRun = pLastLine->getLastRun(); + UT_ASSERT(pLastRun); + if (pLastRun->canContainPoint()) { return; @@ -665,14 +674,13 @@ We add a zero-length text run on a line by itself. */ - fp_Line* pNewLine; - GR_Graphics* pG = m_pLayout->getGraphics(); fp_TextRun* pNewRun = new fp_TextRun(this, pG, pLastRun->getBlockOffset() + pLastRun->getLength(), 0); - pNewRun->setPrev(pLastRun); - pLastRun->setNext(pNewRun); - pNewLine = getNewLine(); + pLastRun->insertIntoRunListAfterThis(*pNewRun); + + fp_Line* pNewLine = getNewLine(); + UT_ASSERT(pNewLine); UT_ASSERT(pNewLine == m_pLastLine); // the line just contains the empty run @@ -716,6 +724,8 @@ int fl_BlockLayout::format() { + if (m_pFirstRun) + { if (m_bFixCharWidths) { fp_Run* pRun = m_pFirstRun; @@ -727,8 +737,6 @@ } } - if (m_pFirstRun) - { if (!m_pFirstLine) _stuffAllRunsOnALine(); @@ -769,6 +777,7 @@ fp_Line* fl_BlockLayout::getNewLine(void) { fp_Line* pLine = new fp_Line(); + // TODO: Handle out-of-memory UT_ASSERT(pLine); pLine->setBlock(this); @@ -877,14 +886,15 @@ PT_DocPosition dPos = getPosition(); UT_ASSERT(iPos >= dPos); - UT_uint32 iRelOffset = iPos - dPos; - if(iRelOffset < 0) iRelOffset = 0; + if (!m_pFirstLine || !m_pFirstRun) { // when we have no formatting information, can't find anything return NULL; } + const UT_uint32 iRelOffset = iPos - dPos; + fp_Run* pRun = m_pFirstRun; while (pRun) { @@ -951,6 +961,7 @@ return pRun; } } + pRun = pRun->getNext(); } @@ -965,13 +976,14 @@ { if (pRun->canContainPoint()) { - if(!pRun->getNext()) + fp_Run* nextRun = pRun->getNext(); + if (nextRun) { - pRun->findPointCoords(iRelOffset, x, y, height); + nextRun->findPointCoords(iRelOffset, x, y, height); } else { - pRun->getNext()->findPointCoords(iRelOffset, x, y, height); + pRun->findPointCoords(iRelOffset, x, y, height); } return pRun; } @@ -1977,14 +1989,7 @@ // the insert is right before this run. pRun->setBlockOffset(iRunBlockOffset + len); - pNewRun->setPrev(pRun->getPrev()); - pNewRun->setNext(pRun); - if (pRun->getPrev()) - { - pRun->getPrev()->setNext(pNewRun); - } - - pRun->setPrev(pNewRun); + pRun->insertIntoRunListBeforeThis(*pNewRun); if (m_pFirstRun == pRun) { @@ -2028,19 +2033,7 @@ // the insert is right before this run. pRun->setBlockOffset(iRunBlockOffset + len); - pNewRun->setPrev(pRun->getPrev()); - pNewRun->setNext(pRun); - if (pRun->getPrev()) - { - pRun->getPrev()->setNext(pNewRun); - } - - pRun->setPrev(pNewRun); - - if (m_pFirstRun == pRun) - { - m_pFirstRun = pNewRun; - } + pRun->insertIntoRunListBeforeThis(*pNewRun); pRun->getLine()->insertRunBefore(pNewRun, pRun); @@ -2065,8 +2058,7 @@ if (pLastRun) { - pLastRun->setNext(pNewRun); - pNewRun->setPrev(pLastRun); + pLastRun->insertIntoRunListAfterThis(*pNewRun); } else { @@ -2271,27 +2263,25 @@ if ((pRun->getLength() == 0) && (pRun->getType() != FPRUN_FMTMARK)) { + // delete this run fp_Line* pLine = pRun->getLine(); UT_ASSERT(pLine); pLine->removeRun(pRun, UT_TRUE); - if (pRun->getNext()) - { - pRun->getNext()->setPrev(pRun->getPrev()); - } - - if (pRun->getPrev()) - { - pRun->getPrev()->setNext(pRun->getNext()); - } - if (m_pFirstRun == pRun) { m_pFirstRun = pRun->getNext(); } + pRun->unlinkFromRunList(); + delete pRun; + + if (!m_pFirstRun) + { + _insertFakeTextRun(); + } } } @@ -2475,15 +2465,12 @@ delete pNuke; } + UT_ASSERT(pRun); + m_pFirstRun = pRun; // then link what's left - pLastRun->setNext(m_pFirstRun); - - if (m_pFirstRun) - { - m_pFirstRun->setPrev(pLastRun); - } + m_pFirstRun->insertIntoRunListAfterThis(*pLastRun); } else { @@ -2541,21 +2528,11 @@ // move all squiggles to previous block _mergeSquiggles(offset, pPrevBL); - // in case we've never checked this one - m_pLayout->dequeueBlock(this); - // update the display // pPrevBL->_lookupProperties(); // TODO: this may be needed pPrevBL->setNeedsReformat(); - - FV_View* pView = pSL->getDocLayout()->getView(); - if (pView) - { - pView->_setPoint(pcrx->getPosition()); } - } - else - { + // in case we've never checked this one m_pLayout->dequeueBlock(this); @@ -2564,7 +2541,6 @@ { pView->_setPoint(pcrx->getPosition()); } - } delete this; // TODO whoa! this construct is VERY dangerous. @@ -2775,6 +2751,7 @@ coalesceRuns(); else _insertFakeTextRun(); + setNeedsReformat(); // throw all the runs onto one jumbo line in the new block @@ -2823,6 +2800,8 @@ // another block follows). this is because because a section // cannot contain content. + UT_ASSERT(pcrx); + UT_ASSERT(pfnBindHandles); UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_InsertStrux); UT_ASSERT(pcrx->getStruxType()==PTX_Section); @@ -2830,6 +2809,7 @@ fl_DocSectionLayout* pDSL = (fl_DocSectionLayout*) m_pSectionLayout; fl_DocSectionLayout* pSL = new fl_DocSectionLayout(m_pLayout, sdh, pcrx->getIndexAP()); + if (!pSL) { UT_DEBUGMSG(("no memory for SectionLayout")); @@ -3097,9 +3077,9 @@ { if (pRun->getType() == FPRUN_FIELD) { - fp_FieldRun* pFieldRun = (fp_FieldRun*) pRun; + fp_FieldRun* pFieldRun = static_cast(pRun); - UT_Bool bSizeChanged = pFieldRun->calculateValue(); + const UT_Bool bSizeChanged = pFieldRun->calculateValue(); bResult = bResult || bSizeChanged; } @@ -3112,11 +3092,14 @@ UT_Bool fl_BlockLayout::findNextTabStop(UT_sint32 iStartX, UT_sint32 iMaxX, UT_sint32& iPosition, unsigned char& iType) { + UT_ASSERT(iStartX >= 0); + UT_uint32 iCountTabs = m_vecTabs.getItemCount(); UT_uint32 i; for (i=0; iiPosition > iMaxX) { @@ -3144,6 +3127,9 @@ } UT_ASSERT(m_iDefaultTabInterval > 0); + +#if 0 + // TMN: Original brute-force UT_sint32 iPos = 0; for (;;) { @@ -3160,10 +3146,24 @@ UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return UT_FALSE; +#else + // mathematical approach + const UT_sint32 iPos = (iStartX / m_iDefaultTabInterval + 1) * + m_iDefaultTabInterval; + iPosition = iPos; + iType = FL_TAB_LEFT; + + UT_ASSERT(iPos > iStartX); + + return UT_TRUE; +#endif + } UT_Bool fl_BlockLayout::findNextTabStopInLayoutUnits(UT_sint32 iStartX, UT_sint32 iMaxX, UT_sint32& iPosition, unsigned char& iType) { + UT_ASSERT(iStartX >= 0); + UT_uint32 iCountTabs = m_vecTabs.getItemCount(); UT_uint32 i; for (i=0; i 0); + +#if 0 + // TMN: Original brute-force UT_sint32 iPos = 0; for (;;) { @@ -3212,6 +3215,18 @@ UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return UT_FALSE; +#else + // mathematical approach + const UT_sint32 iPos = (iStartX / m_iDefaultTabIntervalLayoutUnits + 1) * + m_iDefaultTabIntervalLayoutUnits; + UT_ASSERT(iPos > iStartX); + + iPosition = iPos; + iType = FL_TAB_LEFT; + + return UT_TRUE; +#endif + } UT_Bool fl_BlockLayout::s_EnumTabStops(void * myThis, UT_uint32 k, UT_sint32 & iPosition, unsigned char & iType, UT_uint32 & iOffset) @@ -3223,6 +3238,7 @@ UT_uint32 iCountTabs = pBL->m_vecTabs.getItemCount(); if (k >= iCountTabs) return UT_FALSE; + fl_TabStop * pTab = (fl_TabStop *)pBL->m_vecTabs.getNthItem(k); iPosition = pTab->iPosition; @@ -3361,15 +3377,11 @@ pLine->removeRun(pRun); - if (pRun->getNext()) - pRun->getNext()->setPrev(pRun->getPrev()); - - if (pRun->getPrev()) - pRun->getPrev()->setNext(pRun->getNext()); - if (m_pFirstRun == pRun) m_pFirstRun = pRun->getNext(); + pRun->unlinkFromRunList(); + delete pRun; if (!m_pFirstRun) @@ -3377,6 +3389,8 @@ // I don't believe that we need to keep looping at this point. // We should not ever have two adjacent FmtMarks.... + UT_ASSERT(!pNextRun || pNextRun->getType() != FPRUN_FMTMARK); + break; } @@ -3405,13 +3419,12 @@ //fp_FieldRun* pFieldRun = static_cast(pRun); //pFieldRun->clearScreen(); //pFieldRun->lookupProperties(); - goto done; + break; } pRun = pRun->getNext(); } -done: // TODO is it necessary to force a reformat when changing a FmtMark setNeedsReformat(); @@ -3429,6 +3442,8 @@ void fl_BlockLayout::recheckIgnoredWords() { fp_Run *pRun = m_pFirstRun; + UT_ASSERT(pRun); + UT_uint32 runBlockOffset = pRun->getBlockOffset(); UT_uint32 runLength = pRun->getLength(); fl_PartOfBlock* pPOB; @@ -3491,6 +3506,7 @@ { // squiggle it pPOB->bIsIgnored = pDoc->isIgnore( &(pBlockText[wordBeginning]), wordLength); + _updateSquiggle(pPOB); } else { @@ -3502,8 +3518,6 @@ // forget about it delete pPOB; } // if valid word - - _updateSquiggle(pPOB); bUpdate = UT_TRUE; }