From f6305fca2125b1bf9e1d056a3701bd5cdb8a6362 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 17 Apr 2018 12:50:15 +0300 Subject: [PATCH] DocFormatReader - fix user file (table in table) --- .../DocDocxConverter/DocumentMapping.cpp | 87 +++++++++++------ .../TableCellPropertiesMapping.cpp | 94 ++++++++++++++----- .../TableCellPropertiesMapping.h | 21 +++-- .../DocDocxConverter/TableMapping.cpp | 15 ++- 4 files changed, 151 insertions(+), 66 deletions(-) diff --git a/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp index 59a665ce54..fa8af0e508 100755 --- a/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp @@ -1294,46 +1294,65 @@ namespace DocFileFormat ParagraphPropertyExceptions* papx_prev = NULL; short max_boundary = -1; - short count_column = 0; + + bool fEndNestingLevel = false; + + unsigned int iTap_current = 1; while ( tai.fInTable ) { - short current_count_column = 0; - //check all SPRMs of this TAPX + iTap_current = 1; + for ( std::list::iterator iter = papx->grpprl->begin(); iter != papx->grpprl->end(); iter++ ) { - //find the tDef SPRM DWORD code = iter->OpCode; switch(iter->OpCode) { - case sprmTDefTable: - case sprmOldTDefTable: + case sprmPFInnerTableCell: + case sprmPFInnerTtp: { - //SprmTDefTable tdef(iter->Arguments, iter->argumentsSize); - //int itcMac = tdef.numberOfColumns; + fEndNestingLevel = ( iter->Arguments[0] == 1 ) ? (true) : (false); + }break; - unsigned char itcMac = iter->Arguments[0]; - - short boundary1, boundary2; - for (unsigned char i = 0; i < itcMac; i++) - { - boundary1 = FormatUtils::BytesToInt16( iter->Arguments + 1, i * 2 , iter->argumentsSize ); - boundary2 = FormatUtils::BytesToInt16( iter->Arguments + 1, ( i + 1 ) * 2, iter->argumentsSize ); - - AddBoundary(boundary1, boundary2, boundaries); - } - if (max_boundary < boundary2) - max_boundary = boundary2; - - AddBoundary(boundary2, max_boundary, boundaries); + case sprmPItap: + { + iTap_current = FormatUtils::BytesToUInt32( iter->Arguments, 0, iter->argumentsSize ); }break; } } + if (nestingLevel == iTap_current) + { + for ( std::list::iterator iter = papx->grpprl->begin(); iter != papx->grpprl->end(); iter++ ) + { + //find the tDef SPRM + DWORD code = iter->OpCode; - if (current_count_column > count_column) - count_column = current_count_column; + switch(iter->OpCode) + { + case sprmTDefTable: + case sprmOldTDefTable: + { + unsigned char itcMac = iter->Arguments[0]; + short boundary1, boundary2; + for (unsigned char i = 0; i < itcMac; i++) + { + boundary1 = FormatUtils::BytesToInt16( iter->Arguments + 1, i * 2 , iter->argumentsSize ); + boundary2 = FormatUtils::BytesToInt16( iter->Arguments + 1, ( i + 1 ) * 2, iter->argumentsSize ); + + AddBoundary(boundary1, boundary2, boundaries); + } + if (max_boundary < boundary2) + max_boundary = boundary2; + + AddBoundary(boundary2, max_boundary, boundaries); + }break; + } + } + } + if (nestingLevel > 1 && fEndNestingLevel && !boundaries.empty()) + break; //get the next papx papx = findValidPapx( fcRowEnd ); tai = TableInfo( papx, m_document->nWordVersion ); @@ -1342,6 +1361,7 @@ namespace DocFileFormat if (papx_prev && papx_prev == papx ) break;//file(12).doc papx_prev = papx; + } if ( !boundaries.empty() ) @@ -1358,7 +1378,7 @@ namespace DocFileFormat void DocumentMapping::AddBoundary(short boundary1, short boundary2, std::map &boundaries) { - if (boundary2 - boundary1 < 10) + if (boundary2 - boundary1 < 3) return; std::map::iterator pFind = boundaries.find(boundary1); @@ -1582,10 +1602,8 @@ namespace DocFileFormat int cp = initialCp; int cpCellEnd = findCellEndCp( initialCp, nestingLevel ); - //start w:tc - m_pXmlWriter->WriteNodeBegin( L"w:tc" ); - - TableCellPropertiesMapping* tcpMapping = new TableCellPropertiesMapping( m_pXmlWriter, grid, gridIndex, cellIndex ); + XMLTools::CStringXmlWriter writerTcPr; + TableCellPropertiesMapping* tcpMapping = new TableCellPropertiesMapping( &writerTcPr, grid, gridIndex, cellIndex, nestingLevel ); if ( tapx != NULL ) { @@ -1594,8 +1612,19 @@ namespace DocFileFormat gridIndex = gridIndex + tcpMapping->GetGridSpan(); + bool bCoverCell = tcpMapping->IsCoverCell(); + RELEASEOBJECT( tcpMapping ); + if (bCoverCell) + { + return cpCellEnd; + } + + //start w:tc + m_pXmlWriter->WriteNodeBegin( L"w:tc" ); + m_pXmlWriter->WriteString(writerTcPr.GetXmlString()); + //write the paragraphs of the cell while ( cp < cpCellEnd ) { diff --git a/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.cpp index f469b53e22..8faf21b579 100644 --- a/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.cpp @@ -35,9 +35,11 @@ namespace DocFileFormat { - TableCellPropertiesMapping::TableCellPropertiesMapping (XMLTools::CStringXmlWriter* pWriter, const std::vector* grid, int gridIndex, int cellIndex) : + TableCellPropertiesMapping::TableCellPropertiesMapping (XMLTools::CStringXmlWriter* pWriter, + const std::vector* grid, int gridIndex, int cellIndex, unsigned int depth) : PropertiesMapping(pWriter) { + _depth = depth; _width = 0; _gridIndex = gridIndex; @@ -75,9 +77,25 @@ namespace DocFileFormat TablePropertyExceptions* tapx = static_cast(visited); int nComputedCellWidth = 0; - _gridSpan = 1; + _gridSpan = 0; + _bCoverCell = false; + unsigned int iTap_current = 1; + + for ( std::list::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++ ) + { + DWORD code = iter->OpCode; + + switch(iter->OpCode) + { + case sprmPItap: + { + iTap_current = FormatUtils::BytesToUInt32( iter->Arguments, 0, iter->argumentsSize ); + }break; + } + } std::list::const_reverse_iterator rend = tapx->grpprl->rend(); + for (std::list::const_reverse_iterator iter = tapx->grpprl->rbegin(); iter != rend; ++iter) { switch (iter->OpCode) @@ -113,16 +131,39 @@ namespace DocFileFormat { appendValueElement( _tcPr, L"noWrap", L"", true ); } - int ind = (std::min)(_cellIndex, (int)tdef.rgTc80.size() - 1); - int ind1 = ind; - while (ind1 < tdef.rgdxaCenter.size() - 1) + //int ind = (std::min)(_cellIndex, (int)tdef.rgTc80.size() - 1); + //int ind1 = ind; + //while (ind1 < tdef.rgdxaCenter.size() - 1) + //{ + // int sz = tdef.rgdxaCenter[ ind1 + 1] - tdef.rgdxaCenter[ ind1 ] ; + // if (sz > 1) + // break; + // ind1++; + //} + + if (tdef.rgTc80[_cellIndex].horzMerge == 1) { - int sz = tdef.rgdxaCenter[ ind1 + 1] - tdef.rgdxaCenter[ ind1 ] ; - if (sz > 1) - break; - ind1++; + for (size_t i = _cellIndex; i < tdef.rgTc80.size(); i++) + { + if (tdef.rgTc80[i].horzMerge < 1) + break; + + nComputedCellWidth += tdef.rgdxaCenter[ i + 1] - tdef.rgdxaCenter[ i ] ; + _gridSpan++; + } + } + else if (tdef.rgTc80[_cellIndex].horzMerge == 2) + {//skip cover cell + _gridSpan = 1; + nComputedCellWidth = 0; + _bCoverCell = true; + + } + else + { + _gridSpan = 1; + nComputedCellWidth += tdef.rgdxaCenter[ _cellIndex + 1] - tdef.rgdxaCenter[ _cellIndex ] ; } - nComputedCellWidth = tdef.rgdxaCenter[ ind1 + 1] - tdef.rgdxaCenter[ ind ] ; if (!IsTableBordersDefined(tapx->grpprl)) { @@ -292,23 +333,24 @@ namespace DocFileFormat _tcPr->AppendChild( tcW ); - if ( ( _gridIndex < (int)_grid->size() ) && ( nComputedCellWidth > _grid->at( _gridIndex ) ) ) + //if ( ( _gridIndex < (int)_grid->size() ) && ( nComputedCellWidth > _grid->at( _gridIndex ) ) ) + //{ + // //check the number of merged cells + // int w = _grid->at( _gridIndex ); + + // for ( size_t i = _gridIndex + 1; i < _grid->size(); i++ ) + // { + // _gridSpan++; + + // w += _grid->at( i ); + + // if ( w >= nComputedCellWidth ) + // { + // break; + // } + // } + if (_gridSpan > 1) { - //check the number of merged cells - int w = _grid->at( _gridIndex ); - - for ( size_t i = _gridIndex + 1; i < _grid->size(); i++ ) - { - _gridSpan++; - - w += _grid->at( i ); - - if ( w >= nComputedCellWidth ) - { - break; - } - } - appendValueElement( _tcPr, L"gridSpan", FormatUtils::IntToWideString( _gridSpan ), true ); } diff --git a/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.h b/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.h index 6a36377f60..358b34d093 100644 --- a/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.h +++ b/ASCOfficeDocFile/DocDocxConverter/TableCellPropertiesMapping.h @@ -58,7 +58,7 @@ namespace DocFileFormat public: virtual ~TableCellPropertiesMapping(); - TableCellPropertiesMapping (XMLTools::CStringXmlWriter* pWriter, const std::vector* grid, int gridIndex, int cellIndex); + TableCellPropertiesMapping (XMLTools::CStringXmlWriter* pWriter, const std::vector* grid, int gridIndex, int cellIndex, unsigned int depth); virtual void Apply( IVisitable* visited ); inline int GetGridSpan() const @@ -66,6 +66,11 @@ namespace DocFileFormat return _gridSpan; } + inline bool IsCoverCell() const + { + return _bCoverCell; + } + private: void apppendCellShading (unsigned char* sprmArg, int size, int cellIndex); @@ -79,18 +84,20 @@ namespace DocFileFormat XMLTools::XMLElement* _tcMar; XMLTools::XMLElement* _tcBorders; - const std::vector* _grid; - std::vector _tGrid; + const std::vector* _grid; + std::vector _tGrid; - short _width; - Global::CellWidthType _ftsWidth; - TC80 _tcDef; + short _width; + Global::CellWidthType _ftsWidth; + TC80 _tcDef; + unsigned int _depth; BorderCode* _brcTop; BorderCode* _brcLeft; BorderCode* _brcRight; BorderCode* _brcBottom; - int _gridSpan; + int _gridSpan; + bool _bCoverCell; }; } diff --git a/ASCOfficeDocFile/DocDocxConverter/TableMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/TableMapping.cpp index 80d619b135..1239032e26 100644 --- a/ASCOfficeDocFile/DocDocxConverter/TableMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/TableMapping.cpp @@ -118,12 +118,10 @@ namespace DocFileFormat //find cell end int cpCellEnd = documentMapping->findCellEndCp(cp, depth); - - //start w:tc - documentMapping->GetXMLWriter()->WriteNodeBegin( L"w:tc" ); //convert the properties - TableCellPropertiesMapping tcpMapping(documentMapping->GetXMLWriter(), grid, gridIndex, nCellIndex); + XMLTools::CStringXmlWriter writerTcPr; + TableCellPropertiesMapping tcpMapping(&writerTcPr, grid, gridIndex, nCellIndex, depth); if ( tapx != NULL ) { @@ -131,6 +129,15 @@ namespace DocFileFormat } gridIndex += tcpMapping.GetGridSpan(); + + if (tcpMapping.IsCoverCell()) + { + return; + } + //start w:tc + documentMapping->GetXMLWriter()->WriteNodeBegin( L"w:tc" ); + + documentMapping->GetXMLWriter()->WriteString(writerTcPr.GetXmlString()); documentMapping->_lastValidPapx = papxBackup; documentMapping->_lastValidSepx = sepxBackup;