fp_Run* fl_BlockLayout::findPointCoords(PT_DocPosition iPos, UT_Bool bEOL, UT_sint32& x, UT_sint32& y, UT_sint32& height) { // find the run which has this position inside it. PT_DocPosition dPos = getPosition(); UT_ASSERT(iPos >= dPos); 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) { UT_uint32 iWhere = pRun->containsOffset(iRelOffset); if (FP_RUN_JUSTAFTER == iWhere) { fp_Run* pNextRun = pRun->getNext(); if (bEOL) { const fp_Line* pNextLine = pNextRun ? pNextRun->getLine() : 0; if (pNextLine != pRun->getLine()) { pRun->findPointCoords(iRelOffset, x, y, height); return pRun; } if (pNextRun) { pRun->findPointCoords(iRelOffset, x, y, height); return pNextRun; } } if (pNextRun && pNextRun->containsOffset(iRelOffset) == FP_RUN_INSIDE) { pNextRun->findPointCoords(iRelOffset, x, y, height); return pNextRun; } } if (FP_RUN_INSIDE == iWhere) { pRun->findPointCoords(iRelOffset, x, y, height); return pRun; } pRun = pRun->getNext(); } pRun = m_pFirstRun; while (pRun) { UT_uint32 iWhere = pRun->containsOffset(iRelOffset); if ((FP_RUN_JUSTAFTER == iWhere)) { fp_Run* nextRun = pRun->getNext(); if (nextRun) { nextRun->lookupProperties(); nextRun->findPointCoords(iRelOffset, x, y, height); } else { pRun->findPointCoords(iRelOffset, x, y, height); } return pRun; } if (!pRun->getNext()) { // this is the last run, we're not going to get another chance, so try harder if (iRelOffset > (pRun->getBlockOffset() + pRun->getLength())) { pRun->findPointCoords(iRelOffset, x, y, height); return pRun; } } pRun = pRun->getNext(); } if (iRelOffset < m_pFirstRun->getBlockOffset()) { m_pFirstRun->findPointCoords(iRelOffset, x, y, height); return m_pFirstRun; } pRun = m_pFirstRun; while (pRun) { if (pRun->canContainPoint()) { fp_Run* nextRun = pRun->getNext(); if (nextRun) { nextRun->findPointCoords(iRelOffset, x, y, height); } else { pRun->findPointCoords(iRelOffset, x, y, height); } return pRun; } pRun = pRun->getNext(); } UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return NULL; }