mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-20 16:18:03 +08:00
fix bug #53487
This commit is contained in:
@ -143,6 +143,41 @@ namespace DocFileFormat
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, int>> DocumentMapping::get_subsequence( int cpStart, int cpEnd, int fcStars, int fcEnd )
|
||||
{
|
||||
std::vector<std::pair<int, int>> outptu;
|
||||
|
||||
int currentFc = fcStars;
|
||||
int currentCp = cpStart;
|
||||
int oldElem = fcStars;
|
||||
int currentStart = fcStars;
|
||||
int currentStartcp = cpStart;
|
||||
|
||||
while ( cpEnd > currentCp)
|
||||
{
|
||||
currentCp ++;
|
||||
currentFc = m_document->FindFileCharPos(currentCp);
|
||||
if (currentFc < oldElem)
|
||||
{
|
||||
currentStart = currentFc;
|
||||
outptu.emplace_back(currentStartcp, currentCp - 1);
|
||||
currentStartcp = currentCp;
|
||||
}
|
||||
/*else if (currentFc > oldElem)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
// -1 //че-нить в лог написать
|
||||
}*/
|
||||
|
||||
oldElem = currentFc;
|
||||
}
|
||||
outptu.emplace_back(currentStartcp, currentCp);
|
||||
|
||||
return outptu;
|
||||
}
|
||||
|
||||
// Writes a Paragraph that starts at the given cp and
|
||||
// ends at the next paragraph end mark or section end mark
|
||||
|
||||
@ -178,13 +213,49 @@ namespace DocFileFormat
|
||||
bool sectionEnd = isSectionEnd(cpParaEnd);
|
||||
cpParaEnd++;
|
||||
|
||||
return writeParagraph(cp, cpParaEnd, sectionEnd);
|
||||
return writeParagraph(cp, cpParaEnd, sectionEnd, false, START_END_PARAGRAPH);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpParaEnd++;
|
||||
|
||||
return writeParagraph(cp, (std::min)(cpEnd, cpParaEnd), false);
|
||||
|
||||
int inpCpEnd = ( std::min )( cpEnd, cpParaEnd );
|
||||
int fc = m_document->FindFileCharPos( cp );
|
||||
int fcEnd = m_document->FindFileCharPos( inpCpEnd );
|
||||
|
||||
if ( fc < 0 || fcEnd < 0 || fc == fcEnd )
|
||||
return -1;
|
||||
|
||||
std::vector<std::pair<int, int>> cpStartEnd = get_subsequence( cp, inpCpEnd, fc, fcEnd );
|
||||
if (cpStartEnd.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( cpStartEnd.size() == 1 )
|
||||
{
|
||||
return writeParagraph(cpStartEnd.front().first, cpStartEnd.front().second, false, false, START_END_PARAGRAPH);
|
||||
}
|
||||
|
||||
int retCp = cpParaEnd;
|
||||
for (auto elem : cpStartEnd)
|
||||
{
|
||||
int curCpStart = elem.first;
|
||||
int curCpEnd = elem.second;
|
||||
|
||||
if (elem == cpStartEnd.front())
|
||||
{
|
||||
retCp = writeParagraph(curCpStart, curCpEnd, false, false, START_PARAGRAPH);
|
||||
}
|
||||
else if (elem == cpStartEnd.back())
|
||||
{
|
||||
retCp = writeParagraph(curCpStart, curCpEnd, false, false, END_PARAGRAPH);
|
||||
}
|
||||
else
|
||||
{
|
||||
retCp = writeParagraph(curCpStart, curCpEnd, false, false, NOSTART_NOEND_PARAGRAPH);
|
||||
}
|
||||
}
|
||||
return retCp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,29 +265,21 @@ namespace DocFileFormat
|
||||
// Writes a Paragraph that starts at the given cpStart and
|
||||
// ends at the given cpEnd
|
||||
|
||||
int DocumentMapping::writeParagraph (int initialCp, int cpEnd, bool sectionEnd, bool lastBad)
|
||||
int DocumentMapping::writeParagraph( int initialCp, int cpEnd, bool sectionEnd, bool lastBad, int paragraphState )
|
||||
{
|
||||
int cp = initialCp;
|
||||
int fc = m_document->FindFileCharPos(cp);
|
||||
int fcEnd = m_document->FindFileCharPos(cpEnd);
|
||||
|
||||
if (fc < 0 || fcEnd < 0 || fc == fcEnd)
|
||||
return -1;
|
||||
|
||||
ParagraphPropertyExceptions* papx = findValidPapx(fc);
|
||||
|
||||
// get all CHPX between these boundaries to determine the count of runs
|
||||
|
||||
|
||||
std::vector<CharacterPropertyExceptions*>* chpxs = m_document->GetCharacterPropertyExceptions(fc, fcEnd);
|
||||
std::vector<int>* chpxFcs = m_document->GetFileCharacterPositions(fc, fcEnd);
|
||||
|
||||
CharacterPropertyExceptions* paraEndChpx = NULL;
|
||||
|
||||
if (chpxFcs)
|
||||
{
|
||||
chpxFcs->push_back(fcEnd);
|
||||
}
|
||||
|
||||
if (chpxs)
|
||||
{
|
||||
// the last of these CHPX formats the paragraph end mark
|
||||
@ -224,7 +287,8 @@ namespace DocFileFormat
|
||||
}
|
||||
|
||||
// start paragraph
|
||||
|
||||
if ( paragraphState & START_PARAGRAPH )
|
||||
{
|
||||
m_pXmlWriter->WriteNodeBegin(L"w:p", true);
|
||||
|
||||
if (false == _paraId.empty())
|
||||
@ -232,6 +296,8 @@ namespace DocFileFormat
|
||||
m_pXmlWriter->WriteAttribute(L"w14:paraId", _paraId);
|
||||
}
|
||||
writeParagraphRsid(papx);
|
||||
}
|
||||
|
||||
|
||||
// ----------- check for section properties
|
||||
bool isBidi = false;
|
||||
@ -247,8 +313,8 @@ namespace DocFileFormat
|
||||
{
|
||||
// this is the last paragraph of this section
|
||||
// write properties with section properties
|
||||
|
||||
if (papx)
|
||||
|
||||
if ( papx && ( paragraphState & START_PARAGRAPH ) )
|
||||
{
|
||||
ParagraphPropertiesMapping oMapping(m_pXmlWriter, m_context, m_document, paraEndChpx, isBidi, findValidSepx(cpEnd), _sectionNr);
|
||||
papx->Convert(&oMapping);
|
||||
@ -261,8 +327,8 @@ namespace DocFileFormat
|
||||
else
|
||||
{
|
||||
// write properties
|
||||
|
||||
if (papx)
|
||||
|
||||
if ( papx && ( paragraphState & START_PARAGRAPH ) )
|
||||
{
|
||||
ParagraphPropertiesMapping oMapping(m_pXmlWriter, m_context, m_document, paraEndChpx, isBidi);
|
||||
papx->Convert(&oMapping);
|
||||
@ -372,12 +438,12 @@ namespace DocFileFormat
|
||||
}
|
||||
|
||||
//end paragraph
|
||||
m_pXmlWriter->WriteNodeEnd(L"w:p");
|
||||
if ( paragraphState & END_PARAGRAPH ) m_pXmlWriter->WriteNodeEnd( L"w:p" );
|
||||
}
|
||||
else
|
||||
{
|
||||
//end paragraph
|
||||
m_pXmlWriter->WriteNodeEnd(L"w:p");
|
||||
if ( paragraphState & END_PARAGRAPH ) m_pXmlWriter->WriteNodeEnd( L"w:p" );
|
||||
}
|
||||
|
||||
RELEASEOBJECT(chpxFcs);
|
||||
|
||||
Reference in New Issue
Block a user