30#include <osl/diagnose.h>
31#include <rtl/string.hxx>
44, mbFinalEndOfLine(false)
46, mbFirstInTable(false)
121 const SwNode * pResult =
nullptr;
146 pResult->push_back(rTableBoxes[
n]);
150 pResult = pCellGrid->getTableBoxesOfRow(
this);
157 GridColsPtr pResult = std::make_shared<GridCols>();
162 if (calculateColumnsFromAllRows)
194 OSL_ENSURE(pFormat,
"Impossible");
202 bool bRelBoxSize =
false;
207 for (
const auto& rWidth : *pWidths)
212 nCalc = ( nCalc * nPageSize ) / nTableSz;
214 pResult->push_back( nCalc );
231 const size_t nNumOfLines = rTableLines.
size();
235 WidthsPtr pSeparators = std::make_shared<Widths>();
236 for (
size_t nLineIndex = 0; nLineIndex < nNumOfLines; ++nLineIndex )
238 const SwTableLine *pCurrentLine = rTableLines[nLineIndex];
240 size_t nBoxes = rTabBoxes.size();
244 sal_uInt32 nSeparatorPosition = 0;
245 for (
size_t nBoxIndex = 0; nBoxIndex < nBoxes; ++nBoxIndex)
247 const SwFrameFormat* pBoxFormat = rTabBoxes[ nBoxIndex ]->GetFrameFormat();
249 nSeparatorPosition += rLSz.
GetWidth();
250 pSeparators->push_back(nSeparatorPosition);
255 std::sort(pSeparators->begin(), pSeparators->end());
256 std::vector<sal_uInt32>::iterator it = std::unique(pSeparators->begin(), pSeparators->end());
257 pSeparators->erase(it, pSeparators->end());
261 pWidths = std::make_shared<Widths>();
262 sal_uInt32 nPreviousWidth = 0;
263 for (
const sal_uInt32 nCurrentWidth : *pSeparators)
265 pWidths->push_back(nCurrentWidth - nPreviousWidth);
266 nPreviousWidth = nCurrentWidth;
271 pWidths = pCellGrid->getWidthsOfRow(
this);
290 pWidths = std::make_shared<Widths>();
292 sal_uInt32 nBoxes = rTabBoxes.size();
296 for (sal_uInt32
n = 0;
n < nBoxes;
n++)
298 const SwFrameFormat* pBoxFormat = rTabBoxes[
n ]->GetFrameFormat();
301 pWidths->push_back(rLSz.
GetWidth());
305 pWidths = pCellGrid->getWidthsOfRow(
this);
312 RowSpansPtr pResult = std::make_shared<RowSpans>();
323 sal_uInt32 nBoxes = rTabBoxes.size();
327 for (sal_uInt32
n = 0;
n < nBoxes; ++
n)
329 pResult->push_back(rTabBoxes[
n]->getRowSpan());
333 pResult = pCellGrid->getRowSpansOfRow(
this);
342 static char buffer[256];
343 snprintf(buffer,
sizeof(buffer),
344 "<tableinner depth=\"%" SAL_PRIuUINT32
"\""
345 " cell=\"%" SAL_PRIuUINT32
"\""
346 " row=\"%" SAL_PRIuUINT32
"\""
349 " shadowsBefore=\"%" SAL_PRIuUINT32
"\""
350 " shadowsAfter=\"%" SAL_PRIuUINT32
"\""
351 " vertMerge=\"%s\"/>",
359 return std::string(buffer);
380 static char buffer[1024];
381 snprintf(buffer,
sizeof(buffer),
382 "<tableNodeInfo p=\"%p\" depth=\"%" SAL_PRIuUINT32
"\">"
385 std::string sResult(buffer);
387 for (
const auto& rInner :
mInners)
390 sResult += pInner->toString();
393 sResult +=
"</tableNodeInfo>";
406 mInners[
mnDepth] = std::make_shared<ww8::WW8TableNodeInfoInner>(
this);
414 pInner->setEndOfLine(bEndOfLine);
424 pInner->setEndOfCell(bEndOfCell);
435 pInner->setFirstInTable(bFirstInTable);
446 pInner->setVertMerge(bVertMerge);
506 return mInners.begin()->second->getDepth();
532 pResult =
mInners.begin()->second;
541 Inners_t::const_iterator aIt =
mInners.find(nDepth);
544 pResult = aIt->second;
563 while (aTableCellInfo.
getNext())
567 SAL_INFO(
"sw.ww8",
"<CellFrame>" );
568 SAL_INFO(
"sw.ww8",
"<rect top=\"" << aRect.
Top() <<
"\" bottom=\"" << aRect.
Bottom()
569 <<
"\" left=\"" << aRect.
Left() <<
"\" right=\"" << aRect.
Right() <<
"\"/>" );
573 if (pSttNd !=
nullptr)
575 SwPaM aPam(*pSttNd, 0);
589 if (pTmpSttNd == pSttNd)
598 SAL_INFO(
"sw.ww8",
"</CellFrame>" );
606 SAL_INFO(
"sw.ww8",
"<processSwTable>" );
622 for (
size_t n = 0;
n < rLines.
size(); ++
n)
626 pPrev =
processTableLine(pTable, pLine,
static_cast<sal_uInt32
>(
n), 1, pPrev, aLastRowEnds);
636 assert(!aLastRowEnds.empty());
637 for (
auto &
a : aLastRowEnds)
639 assert(
a.second->isEndOfLine());
640 a.second->setFinalEndOfLine(
true);
643 SAL_INFO(
"sw.ww8",
"</processSwTable>" );
654 SAL_INFO(
"sw.ww8",
"<processTableLine row=\"" << nRow <<
"\" depth=\"" << nDepth <<
"\">" );
658 for (
size_t n = 0;
n < rBoxes.size(); ++
n)
662 pPrev =
processTableBox(pTable, pBox, nRow,
static_cast<sal_uInt32
>(
n), nDepth,
n == rBoxes.size() - 1, pPrev, rLastRowEnds);
665 SAL_INFO(
"sw.ww8",
"</processTableLine>" );
678 SAL_INFO(
"sw.ww8",
"<processTableBoxLines depth=\"" << nDepth <<
"\" row=\"" << nRow
679 <<
"\" cell=\"" << nCell <<
"\">" );
686 for (
size_t n = 0;
n < rLines.
size(); ++
n)
691 for (
size_t nBox = 0; nBox < rBoxes.size(); ++nBox)
699 SwPaM aPaM(*pSttNd, 0);
700 SwPaM aEndPaM(*pEndNd, 0);
716 SAL_INFO(
"sw.ww8",
"</processTableBoxLines>" );
723 sal_Int32 nDepth = pEndOfCellInfo->
getDepth();
726 auto aIt = rLastRowEnds.find(nDepth);
727 if (aIt == rLastRowEnds.end() || (pInner->getRow() > aIt->second->getRow()))
728 rLastRowEnds[nDepth] = pInner.get();
741 SAL_INFO(
"sw.ww8",
"<processTableBox row=\"" << nRow <<
"\" cell=\"" << nCell
742 <<
"\" depth=\"" << nDepth <<
"\">" );
752 pNodeInfo->setEndOfCell(
true);
755 pNodeInfo->setEndOfLine(
true);
759 for (
size_t n = 0;
n < rLines.
size();
n++)
768 SwPaM aPaM(*pSttNd, 0);
771 sal_uInt32 nDepthInsideCell = 0;
779 if (nDepthInsideCell > 0)
780 pEndOfCellInfo.reset();
788 pPrev->
setNext(pNodeInfo.get());
790 pPrev = pNodeInfo.get();
792 if (nDepthInsideCell == 1 && rNode.
IsTextNode())
793 pEndOfCellInfo = pNodeInfo;
799 if (nDepthInsideCell == 0 && !pEndOfCellInfo)
800 pEndOfCellInfo = pNodeInfo;
804 if (pTmpSttNd == pSttNd)
814 pEndOfCellInfo->setEndOfCell(
true);
818 pEndOfCellInfo->setEndOfLine(
true);
824 SAL_INFO(
"sw.ww8",
"</processTableBox>" );
843 std::make_shared<ww8::WW8TableNodeInfo>(
this, pNode);
844 mMap.emplace(pNode, pNodeInfo);
847 pNodeInfo->setDepth(nDepth + pNodeInfo->getDepth());
849 pNodeInfo->setTable(pTable);
850 pNodeInfo->setTableBox(pTableBox);
852 pNodeInfo->setCell(nCell);
853 pNodeInfo->setRow(nRow);
861 pNodeInfo->setFirstInTable(
true);
869 pCellGrid->insert(*pRect, pNodeInfo.get());
870 pNodeInfo->setRect(*pRect);
874 SAL_INFO(
"sw.ww8", pNodeInfo->toString());
880(
const SwTable * pTable,
bool bCreate)
883 CellGridMap_t::iterator aIt =
mCellGridMap.find(pTable);
889 pResult = std::make_shared<ww8::WW8TableCellGrid>();
903 Map_t::iterator aIt =
mMap.find(pNode);
905 if (aIt !=
mMap.end())
906 pResult = (*aIt).second;
913 const SwNode * pResult =
nullptr;
921 if (pNextInfo !=
nullptr)
922 pResult = pNextInfo->
getNode();
925 const SwNode * pNextNode = pNodeInfo->getNextNode();
927 if (pNextNode !=
nullptr)
939 if (rInfo.
mpNode !=
nullptr)
959 if (
top() < aCellInfo.
top())
961 else if (
top() == aCellInfo.
top())
965 else if (
left() == aCellInfo.
left())
995 static char sBuffer[256];
997 snprintf(sBuffer,
sizeof(sBuffer),
998 "<cellinfo left=\"%" SAL_PRIdINT64
"\""
999 " right=\"%" SAL_PRIdINT64
"\""
1000 " top=\"%" SAL_PRIdINT64
"\""
1001 " bottom=\"%" SAL_PRIdINT64
"\""
1018 SAL_INFO(
"sw.ww8", pCellGrid->toString());
1021 pCellGrid->addShadowCells();
1022 return pCellGrid->connectCells(rLastRowEnds);
1037 RowTops_t::iterator aIt =
m_aRowTops.find(nTop);
1043 pResult = std::make_shared<ww8::WW8TableCellGridRow>();
1066 return getRow(nTop)->begin();
1071 return getRow(nTop)->end();
1078 CellInfo aCellInfo(rRect, pNodeInfo);
1080 if (pFormatFrameWidth !=
nullptr)
1084 pRow->insert(aCellInfo);
1089 SAL_INFO(
"sw.ww8",
"<addShadowCells>" );
1095 CellInfoMultiSet::const_iterator aCellIt =
getCellsBegin(*aTopsIt);
1096 CellInfoMultiSet::const_iterator aCellEndIt =
getCellsEnd(*aTopsIt);
1098 RowSpansPtr pRowSpans = std::make_shared<RowSpans>();
1100 bool bBeginningOfCell =
true;
1101 bool bVertMerge =
false;
1102 SwRect aRect = aCellIt->getRect();
1103 sal_Int32 nRowSpan = 1;
1104 while (aCellIt != aCellEndIt)
1108 if (bBeginningOfCell)
1110 RowTops_t::const_iterator aRowSpanIt(aTopsIt);
1114 *aRowSpanIt < aCellIt->
bottom())
1116 aRect.
Top(*aRowSpanIt);
1117 tools::ULong nFormatFrameWidth = aCellIt->getFormatFrameWidth();
1118 insert(aRect,
nullptr, &nFormatFrameWidth);
1127 *aRowSpanIt < aCellIt->
bottom())
1134 pRowSpans->push_back(nRowSpan);
1136 pRowSpans->push_back(-nRowSpan);
1145 if (aCellIt != aCellEndIt)
1147 bBeginningOfCell = (aRect.
Left() != aCellIt->left());
1148 aRect = aCellIt->getRect();
1154 pRow->setRowSpans(pRowSpans);
1158 SAL_INFO(
"sw.ww8",
"</addShadowCells>" );
1164 sal_uInt32 nRow = 0;
1169 CellInfoMultiSet::const_iterator aCellIt =
getCellsBegin(*aTopsIt);
1170 CellInfoMultiSet::const_iterator aCellEndIt =
getCellsEnd(*aTopsIt);
1174 sal_uInt32 nShadows = 0;
1175 sal_uInt32 nCell = 0;
1176 bool bBeginningOfCell =
true;
1178 sal_uInt32 nDepthInCell = 0;
1179 while (aCellIt != aCellEndIt)
1190 pEndOfCellInfo =
nullptr;
1193 if (nDepthInCell == 1 && pNode->
IsTextNode())
1194 pEndOfCellInfo = pNodeInfo;
1201 pLastNodeInfo->
setNext(pNodeInfo);
1204 pLastNodeInfo = pNodeInfo;
1211 if (nDepthInCell == 0 && !pEndOfCellInfo)
1212 pEndOfCellInfo = pNodeInfo;
1220 if (bBeginningOfCell)
1222 pWidths->push_back(aCellIt->getFormatFrameWidth());
1227 pTableBoxes->push_back(
nullptr);
1231 bBeginningOfCell =
false;
1233 if (aCellIt != aCellEndIt && aCellIt->left() != nCellX)
1236 bBeginningOfCell =
true;
1243 pEndOfCellInfo =
nullptr;
1249 if (!pEndOfCellInfo)
1251 pEndOfCellInfo = pLastNodeInfo;
1259 pRow->setTableBoxVector(pTableBoxes);
1260 pRow->setWidths(pWidths);
1266 return pLastNodeInfo;
1272 std::string sResult =
"<WW8TableCellGrid>";
1275 static char sBuffer[1024];
1278 sResult +=
"<row y=\"";
1279 sResult += OString::number(*aTopsIt);
1282 CellInfoMultiSet::const_iterator aCellIt =
getCellsBegin(*aTopsIt);
1283 CellInfoMultiSet::const_iterator aCellsEnd =
getCellsEnd(*aTopsIt);
1285 while (aCellIt != aCellsEnd)
1287 snprintf(sBuffer,
sizeof(sBuffer),
"<cellInfo top=\"%" SAL_PRIdINT64
"\" bottom=\"%" SAL_PRIdINT64
"\" left=\"%" SAL_PRIdINT64
"\" right=\"%" SAL_PRIdINT64
"\">",
1288 sal_Int64(aCellIt->top()), sal_Int64(aCellIt->bottom()), sal_Int64(aCellIt->left()), sal_Int64(aCellIt->right()));
1295 sResult +=
"<shadow/>\n";
1297 sResult +=
"</cellInfo>\n";
1303 if (pWidths !=
nullptr)
1305 sResult +=
"<widths>";
1307 Widths::const_iterator aItEnd = pWidths->end();
1308 for (Widths::const_iterator aIt = pWidths->begin();
1312 if (aIt != pWidths->begin())
1315 snprintf(sBuffer,
sizeof(sBuffer),
"%" SAL_PRIxUINT32
"", *aIt);
1319 sResult +=
"</widths>";
1325 sResult +=
"<rowspans>";
1327 RowSpans::const_iterator aItEnd = pRowSpans->end();
1328 for (RowSpans::const_iterator aIt = pRowSpans->begin();
1332 if (aIt != pRowSpans->begin())
1335 snprintf(sBuffer,
sizeof(sBuffer),
"%" SAL_PRIxUINT32
"", *aIt);
1339 sResult +=
"</rowspans>";
1342 sResult +=
"</row>\n";
1346 sResult +=
"</WW8TableCellGrid>\n";
1361 pResult = pRow->getTableBoxVector();
1377 pResult = pRow->getWidths();
1393 pResult = pRow->getRowSpans();
1413 SAL_INFO(
"sw.ww8",
"<gridRowInsert>" << rCellInfo.
toString() <<
"</gridRowInsert>" );
1446: m_aRect(aRect), m_pNodeInfo(pNodeInfo), m_nFormatFrameWidth(0)
1448 if (pNodeInfo !=
nullptr)
void GetTablePageSize(ww8::WW8TableNodeInfoInner const *pTableTextNodeInfoInner, tools::Long &rPageSize, bool &rRelBoxSize)
tools::Long GetWidth() const
Ends a section of nodes in the document model.
Base class of the Writer document model elements.
SwNodeOffset GetIndex() const
const SwStartNode * StartOfSectionNode() const
const SwEndNode * EndOfSectionNode() const
PaM is Point and Mark: a selection of the document model.
const SwPosition * GetPoint() const
Of course Writer needs its own rectangles.
void Top(const tools::Long nTop)
void Right(const tools::Long nRight)
void Bottom(const tools::Long nBottom)
void Left(const tools::Long nLeft)
Starts a section of nodes in the document model.
SwTableBox is one table cell in the document model.
SwFrameFormat * GetFrameFormat()
SwTableLines & GetTabLines()
const SwStartNode * GetSttNd() const
const SwTableBox * getTableBox() const
SwTableLine is one table row in the document model.
SwTableBoxes & GetTabBoxes()
SwTable is one table in the document model, containing rows (which contain cells).
SwTableNode * GetTableNode() const
SwTableLines & GetTabLines()
SwTableFormat * GetFrameFormat()
bool IsTableComplex() const
WW8TableNodeInfo * getTableNodeInfo() const
tools::Long height() const
tools::Long width() const
tools::ULong m_nFormatFrameWidth
bool operator<(const CellInfo &aCellInfo) const
std::string toString() const
CellInfo(const SwRect &aRect, WW8TableNodeInfo *pNodeInfo)
WW8TableNodeInfo * m_pNodeInfo
tools::Long bottom() const
void setFormatFrameWidth(tools::ULong nFormatFrameWidth)
tools::Long right() const
CellInfoMultiSet::const_iterator begin() const
void insert(const CellInfo &rCellInfo)
CellInfoMultiSet::const_iterator end() const
void setWidths(WidthsPtr const &pGridCols)
std::shared_ptr< WW8TableCellGridRow > Pointer_t
void setTableBoxVector(TableBoxVectorPtr const &pTableBoxVector)
std::shared_ptr< CellInfoMultiSet > m_pCellInfos
TableBoxVectorPtr m_pTableBoxVector
void setRowSpans(RowSpansPtr const &pRowSpans)
std::shared_ptr< WW8TableCellGrid > Pointer_t
WidthsPtr getWidthsOfRow(WW8TableNodeInfoInner const *pNodeInfo)
WW8TableCellGridRow::Pointer_t getRow(tools::Long nTop, bool bCreate=true)
RowSpansPtr getRowSpansOfRow(WW8TableNodeInfoInner const *pNodeInfo)
WW8TableNodeInfo * connectCells(RowEndInners_t &rLastRowEnds)
RowTops_t::const_iterator getRowTopsEnd() const
void insert(const SwRect &rRect, WW8TableNodeInfo *pNodeInfo, tools::ULong const *pFormatFrameWidth=nullptr)
CellInfoMultiSet::const_iterator getCellsBegin(tools::Long nTop)
CellInfoMultiSet::const_iterator getCellsEnd(tools::Long nTop)
RowTops_t::const_iterator getRowTopsBegin() const
TableBoxVectorPtr getTableBoxesOfRow(WW8TableNodeInfoInner const *pNodeInfo)
WW8TableNodeInfo * processTableBox(const SwTable *pTable, const SwTableBox *pTableBox, sal_uInt32 nRow, sal_uInt32 nCell, sal_uInt32 nDepth, bool bEndOfLine, WW8TableNodeInfo *pPrev, RowEndInners_t &rLastRowEnds)
WW8TableNodeInfo::Pointer_t getTableNodeInfo(const SwNode *pNode)
FirstInTableMap_t mFirstInTableMap
WW8TableCellGrid::Pointer_t getCellGridForTable(const SwTable *pTable, bool bCreate=true)
WW8TableNodeInfo * processTableLine(const SwTable *pTable, const SwTableLine *pTableLine, sal_uInt32 nRow, sal_uInt32 nDepth, WW8TableNodeInfo *pPrev, RowEndInners_t &rLastRowEnds)
WW8TableNodeInfo * reorderByLayout(const SwTable *pTable, RowEndInners_t &rLastRowEnds)
WW8TableNodeInfo * processSwTableByLayout(const SwTable *pTable, RowEndInners_t &rLastRowEnds)
void processSwTable(const SwTable *pTable)
WW8TableNodeInfo::Pointer_t insertTableNodeInfo(const SwNode *pNode, const SwTable *pTable, const SwTableBox *pTableBox, sal_uInt32 nRow, sal_uInt32 nCell, sal_uInt32 nDepth, SwRect const *pRect=nullptr)
WW8TableNodeInfo::Pointer_t processTableBoxLines(const SwTableBox *pBox, const SwTable *pTable, const SwTableBox *pBoxToSet, sal_uInt32 nRow, sal_uInt32 nCell, sal_uInt32 nDepth)
const SwNode * getNextNode(const SwNode *pNode)
CellGridMap_t mCellGridMap
void setTableBox(const SwTableBox *pTableBox)
const SwNode * getNode() const
const SwTableBox * mpTableBox
const SwTableBox * getTableBox() const
void setRect(const SwRect &rRect)
GridColsPtr getGridColsOfRow(AttributeOutputBase &rBase, bool calculateColumnsFromAllRows=false)
const SwTable * getTable() const
void setFinalEndOfLine(bool bEndOfLine)
sal_uInt32 mnShadowsBefore
WidthsPtr getColumnWidthsBasedOnAllRows() const
void setEndOfLine(bool bEndOfLine)
RowSpansPtr getRowSpansOfRow() const
std::string toString() const
void setCell(sal_uInt32 nCell)
void setFirstInTable(bool bFirstInTable)
TableBoxVectorPtr getTableBoxesOfRow() const
void setShadowsBefore(sal_uInt32 nShadowsBefore)
WW8TableNodeInfoInner(WW8TableNodeInfo *pParent)
WW8TableNodeInfo * mpParent
void setDepth(sal_uInt32 nDepth)
void setRow(sal_uInt32 nRow)
const SwRect & getRect() const
WidthsPtr getWidthsOfRow() const
void setEndOfCell(bool bEndOfCell)
void setVertMerge(bool bVertMerge)
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
void setTable(const SwTable *pTable)
sal_uInt32 mnShadowsAfter
void setShadowsAfter(sal_uInt32 nShadowsAfter)
WW8TableInfo * getParent() const
WW8TableNodeInfoInner::Pointer_t getFirstInner() const
void setNextNode(const SwNode *pNode)
void setShadowsAfter(sal_uInt32 nShadowsAfter)
void setRect(const SwRect &rRect)
void setVertMerge(bool bVertMerge)
void setCell(sal_uInt32 nCell)
void setEndOfLine(bool bEndOfLine)
void setNext(WW8TableNodeInfo *pNext)
WW8TableNodeInfo * getNext() const
void setEndOfCell(bool bEndOfCell)
const SwNode * getNode() const
void setTableBox(const SwTableBox *pTableBox)
sal_uInt32 getCell() const
void setShadowsBefore(sal_uInt32 nShadowsBefore)
void setDepth(sal_uInt32 nDepth)
WW8TableNodeInfo * mpNext
sal_uInt32 getDepth() const
void setFirstInTable(bool bFirstInTable)
WW8TableNodeInfo(WW8TableInfo *pParent, const SwNode *pTextNode)
const SwTableBox * getTableBox() const
std::shared_ptr< WW8TableNodeInfo > Pointer_t
void setRow(sal_uInt32 nRow)
std::string toString() const
WW8TableNodeInfoInner::Pointer_t getInnerForDepth(sal_uInt32 nDepth) const
bool operator<(const WW8TableNodeInfo &rInfo) const
void setTable(const SwTable *pTable)
sal_uInt32 getRow() const
const SwNode * mpNextNode
const char * dbg_out(const void *pVoid)
RegionData_Impl * mpParent
#define SAL_INFO(area, stream)
std::shared_ptr< T > make_shared(Args &&... args)
OUString toString(OptionInfo const *info)
static void updateFinalEndOfLine(RowEndInners_t &rLastRowEnds, WW8TableNodeInfo const *pEndOfCellInfo)
std::shared_ptr< RowSpans > RowSpansPtr
std::shared_ptr< GridCols > GridColsPtr
std::shared_ptr< TableBoxVector > TableBoxVectorPtr
std::multiset< CellInfo > CellInfoMultiSet
std::shared_ptr< Widths > WidthsPtr
std::map< sal_uInt32, WW8TableNodeInfoInner *, std::greater< sal_uInt32 > > RowEndInners_t
const unsigned int MAXTABLECELLS
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
std::vector< SwTableBox * > SwTableBoxes