From 405a2c1f59c60ac58362d0ce54c47d0866013401 Mon Sep 17 00:00:00 2001 From: Green Date: Fri, 13 Jun 2025 01:05:20 +0300 Subject: [PATCH] Fix bug in HWP/HWPX with breaks --- HwpFile/HwpDoc/Conversion/ConversionState.h | 24 +++++++++++++++-- HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp | 26 +++++++++---------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/HwpFile/HwpDoc/Conversion/ConversionState.h b/HwpFile/HwpDoc/Conversion/ConversionState.h index 22daf378b5..ae2f1e9389 100644 --- a/HwpFile/HwpDoc/Conversion/ConversionState.h +++ b/HwpFile/HwpDoc/Conversion/ConversionState.h @@ -18,7 +18,27 @@ struct TConversionState bool m_bOpenedR; bool m_bIsNote; bool m_bInTable; - ECtrlObjectType m_ePrevElementType; + + struct TLastNode + { + unsigned int m_unParaIndex; + enum class ELastNodeType + { + Empty, + Paragraph, + Table + } m_eType; + + TLastNode() + : m_unParaIndex(0), m_eType(ELastNodeType::Empty) + {} + + void Clear() + { + m_unParaIndex = 0; + m_eType = ELastNodeType::Empty; + } + } m_oLastNode; bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее) @@ -47,7 +67,7 @@ struct TConversionState std::map m_mOpenField; TConversionState() - : m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTable(false), m_ePrevElementType(ECtrlObjectType::Empty), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0), + : m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTable(false), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0), m_pSectionDef(nullptr), m_pColumnDef(nullptr), m_pPageNum(nullptr), m_pNewNumber(nullptr), m_pRelationships(nullptr), m_eBreakType(EBreakType::None) {} }; diff --git a/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp b/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp index 06b0e6936c..c98600f13b 100644 --- a/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp +++ b/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp @@ -282,6 +282,8 @@ void CConverter2OOXML::Convert() m_oDocXml.WriteString(L""); ++oState.m_ushSecdIndex; + + oState.m_oLastNode.Clear(); } } @@ -300,9 +302,10 @@ void CConverter2OOXML::WriteCharacter(const CCtrlCharacter* pCharacter, short sh case ECtrlCharType::PARAGRAPH_BREAK: { // Таблицы пишутся без тега , поэтому для них не открывается параграф - if (ECtrlObjectType::Table == oState.m_ePrevElementType && !oState.m_bInTable) + if (TConversionState::TLastNode::ELastNodeType::Table == oState.m_oLastNode.m_eType && + oState.m_unParaIndex == oState.m_oLastNode.m_unParaIndex && !oState.m_bInTable) { - oState.m_ePrevElementType = ECtrlObjectType::Character; + oState.m_oLastNode.m_eType = TConversionState::TLastNode::ELastNodeType::Table; break; } @@ -329,8 +332,6 @@ void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, short shParaS if (nullptr == pShape || oState.m_bInTextBox) return; - oState.m_ePrevElementType = ECtrlObjectType::Shape; - switch (pShape->GetShapeType()) { case EShapeType::Arc: @@ -380,8 +381,6 @@ void CConverter2OOXML::WriteNote(const CCtrlNote* pNote, short shParaShapeID, NS if (nullptr == pNote) return; - oState.m_ePrevElementType = ECtrlObjectType::Note; - oBuilder.WriteString(L""); CRunnerStyle oRunnerStyle; @@ -399,8 +398,6 @@ void CConverter2OOXML::WriteField(const CCtrlField* pShape, short shParaShapeID, if (nullptr == pShape) return; - oState.m_ePrevElementType = ECtrlObjectType::AutoNumber; - switch (pShape->GetType()) { case EFieldType::Hyperlink: @@ -680,7 +677,8 @@ void CConverter2OOXML::WriteTable(const CCtrlTable* pTable, short shParaShapeID, if (nullptr == pTable || pTable->Empty()) return; - oState.m_ePrevElementType = ECtrlObjectType::Table; + if (TConversionState::TLastNode::ELastNodeType::Table == oState.m_oLastNode.m_eType) + oBuilder.WriteString(L""); CloseParagraph(oBuilder, oState); @@ -768,6 +766,9 @@ void CConverter2OOXML::WriteTable(const CCtrlTable* pTable, short shParaShapeID, oBuilder.WriteString(L""); + oState.m_oLastNode.m_eType = TConversionState::TLastNode::ELastNodeType::Table; + oState.m_oLastNode.m_unParaIndex = oState.m_unParaIndex; + oState.m_bInTable = bTableInTable; } @@ -1763,6 +1764,9 @@ void CConverter2OOXML::CloseParagraph(NSStringUtils::CStringBuilder& oBuilder, T oBuilder.WriteString(L""); oState.m_bOpenedP = false; + + oState.m_oLastNode.m_unParaIndex = oState.m_unParaIndex; + oState.m_oLastNode.m_eType = TConversionState::TLastNode::ELastNodeType::Paragraph; } void CConverter2OOXML::WriteText(const CParaText* pParaText, const std::vector& arRangeTags, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) @@ -1875,8 +1879,6 @@ void CConverter2OOXML::WriteText(const HWP_STRING& wsText, short shParaShapeID, if (!oState.m_bOpenedP && wsText.empty()) return; - oState.m_ePrevElementType = ECtrlObjectType::ParaText; - OpenParagraph(shParaShapeID, shParaStyleID, oBuilder, oState); if (wsText.empty()) @@ -2057,8 +2059,6 @@ void CConverter2OOXML::WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short if (nullptr == pAutoNumber) return; - oState.m_ePrevElementType = ECtrlObjectType::AutoNumber; - unsigned short ushValue = 0; HWP_STRING wsType;