Fix bugs in HWPX/HWPML conversion

This commit is contained in:
Green
2025-09-27 17:56:13 +03:00
parent 49fc001aa3
commit 2cd69351c7
11 changed files with 279 additions and 115 deletions

View File

@ -121,6 +121,15 @@ enum class ENode
Script,
Point,
Segment,
StartNumber,
Hide,
PagePropertie,
PageMargin,
FootNotePropertie,
EndNotePropertie,
PageBorderFill,
PageOffset,
MasterPage,
//Only hwpx
Lineseg,
@ -134,7 +143,7 @@ enum class ENode
};
#define MAX_TYPES 2
#define MAX_NODES 117
#define MAX_NODES 126
static constexpr const char* NODE_NAMES[MAX_TYPES][MAX_NODES] =
{
@ -160,7 +169,7 @@ static constexpr const char* NODE_NAMES[MAX_TYPES][MAX_NODES] =
"hc:color",
"hc:imgBrush",
"hc:img",
"h:charProperties", //20
"hh:charProperties", //20
"hh:charPr",
"hh:fontRef",
"hh:ratio",
@ -253,6 +262,15 @@ static constexpr const char* NODE_NAMES[MAX_TYPES][MAX_NODES] =
"hp:script",
"hc:pt",
"hp:seg",
"hp:startNum",
"hp:visibility",
"hp:pagePr",
"hp:margin",
"hp:footNotePr",
"hp:endNotePr",
"hp:pageBorderFill",
"hp:offset",
"hp:masterPage",
"hp:lineseg",
"hp:linesegarray",
@ -377,6 +395,15 @@ static constexpr const char* NODE_NAMES[MAX_TYPES][MAX_NODES] =
"SCRIPT",
"POINT",
"SEGMENT",
"STARTNUMBER",
"HIDE",
"PAGEDEF",
"PAGEMARGIN",
"FOOTNOTESHAPE",
"ENDNOTESHAPE",
"PAGEBORDERFILL",
"PAGEOFFSET",
"MASTERPAGE",
"",
"",
@ -586,12 +613,37 @@ enum class EAttribute
TextShape,
Spacing,
Style,
TextDirection,
SpaceColumns,
TabStop,
OutlineShapeId,
PageStartsOn,
Page,
Figure,
Table,
Equation,
HideHeader,
HideFooter,
HideMasterPage,
HideBorder,
HideFill,
HidePageNumPos,
HideEmptyLine,
Landscape,
GutterType,
Header,
Footer,
Gutter,
TextBorder,
HeaderInside,
FooterInside,
FillArea,
PageBreak,
ColumnBreak,
};
#define MAX_ATTRIBUTES 177
#define MAX_ATTRIBUTES 202
//TODO:: добавить все аргументы
static constexpr const char* ATTRUBUTE_NAMES[MAX_TYPES][MAX_ATTRIBUTES] =
@ -773,9 +825,34 @@ static constexpr const char* ATTRUBUTE_NAMES[MAX_TYPES][MAX_ATTRIBUTES] =
"textShape",
"spacing",
"style",
"textDirection",
"spaceColumns",
"tabStop",
"outlineShapeIDRef",
"pageStartsOn",
"page",
"pic",
"tbl",
"equation",
"hideFirstHeader",
"hideFirstFooter",
"hideFirstMasterPage",
"border",
"fill",
"hideFirstPageNum",
"hideFirstEmptyLine",
"landscape",
"gutterType",
"header",
"footer",
"gutter",
"textBorder",
"headerInside",
"footerInside",
"fillArea",
"pageBreak",
"columnBreak",
"columnBreak"
},
// HWPML
{
@ -954,6 +1031,31 @@ static constexpr const char* ATTRUBUTE_NAMES[MAX_TYPES][MAX_ATTRIBUTES] =
"TextShape",
"Spacing",
"Style",
"TextDirection",
"SpaceColumns",
"TabStop",
"OutlineShape",
"PageStartsOn",
"Page",
"Figure",
"Table",
"Equation",
"Header",
"Footer",
"MasterPage",
"Border",
"Fill",
"PageNumPos",
"EmptyLine",
"Landscape",
"GutterType",
"Header",
"Footer",
"Gutter",
"TextBorder",
"HeaderInside",
"FooterInside",
"FillArea",
"PageBreak",
"ColumnBreak"
@ -1093,10 +1195,16 @@ enum class EValue
TopOuter,
BottomOuter,
TopInner, //110
BottomInner
BottomInner,
Both,
Even,
Odd,
LeftRight,
TopBottom,
Border
};
#define MAX_VALUES 111
#define MAX_VALUES 117
static constexpr const char* VALUE_NAMES[MAX_TYPES][MAX_VALUES] =
{
@ -1212,7 +1320,13 @@ static constexpr const char* VALUE_NAMES[MAX_TYPES][MAX_VALUES] =
"TOP_OUTER",
"BOTTOM_OUTER",
"TOP_INNER",
"BOTTOM_INNER"
"BOTTOM_INNER",
"BOTH",
"EVEN",
"ODD",
"LEFT_RIGHT",
"TOP_BOTTOM",
"BORDER"
},
//HWPML
{
@ -1326,7 +1440,13 @@ static constexpr const char* VALUE_NAMES[MAX_TYPES][MAX_VALUES] =
"TopOuter",
"BottomOuter",
"TopInner",
"BottomInner"
"BottomInner",
"Both",
"Even",
"Odd",
"LeftRight",
"TopBottom",
"Border"
}
};

View File

@ -82,12 +82,14 @@ CCtrlObjElement::CCtrlObjElement(const HWP_STRING& sCtrlID, CXMLReader& oReader,
void CCtrlObjElement::ParseChildren(CXMLReader& oReader, EHanType eType)
{
switch (eType)
{
case EHanType::HWPML: ParseHWPMLElement(oReader); return;
case EHanType::HWPX: ParseHWPXChildren(oReader); return;
default: break;
}
const std::string sNodeName{oReader.GetName()};
if (EHanType::HWPML == eType && "SHAPECOMPONENT" == sNodeName)
ParseHWPMLElement(oReader);
else if (EHanType::HWPX == eType)
ParseHWPXChildren(oReader);
else
CCtrlCommon::ParseChildren(oReader, eType);
}
void CCtrlObjElement::ParseRotationInfo(CXMLReader &oReader, EHanType eType)

View File

@ -40,60 +40,69 @@ CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID, int nSize, CHWPStrea
m_bFullFilled = true;
}
CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLReader& oReader)
CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLReader& oReader, EHanType eType)
: CCtrl(sCtrlID), m_pPage(nullptr)
{
std::string sType;
START_READ_ATTRIBUTES(oReader)
{
if ("textDirection" == sAttributeName)
if (GetAttributeName(EAttribute::TextDirection, eType) == sAttributeName)
{
sType = oReader.GetTextA();
if (EHanType::HWPX == eType)
{
sType = oReader.GetTextA();
if ("HORIZONTAL" == sType)
m_chTextDirection = 0;
else if ("VERTICAL" == sType)
m_chTextDirection = 1;
if ("HORIZONTAL" == sType)
m_chTextDirection = 0;
else if ("VERTICAL" == sType)
m_chTextDirection = 1;
}
else
m_chTextDirection = oReader.GetInt();
}
else if ("spaceColumns" == sAttributeName)
else if (GetAttributeName(EAttribute::SpaceColumns, eType) == sAttributeName)
m_shSpaceColumns = oReader.GetInt();
else if ("tabStop" == sAttributeName)
else if (GetAttributeName(EAttribute::TabStop, eType) == sAttributeName)
m_nTabStop = oReader.GetInt();
else if ("outlineShapeIDRef" == sAttributeName)
else if (GetAttributeName(EAttribute::OutlineShapeId, eType) == sAttributeName)
m_nOutlineNumberingID = oReader.GetInt();
else if (EHanType::HWPML == eType && "LineGrid" == sAttributeName)
m_shLineGrid = oReader.GetInt();
else if (EHanType::HWPML == eType && "CharGrid" == sAttributeName)
m_shCharGrid = oReader.GetInt();
}
END_READ_ATTRIBUTES(oReader)
WHILE_READ_NEXT_NODE_WITH_NAME(oReader)
{
if ("hp:startNum" == sNodeName)
if (GetNodeName(ENode::StartNumber, eType) == sNodeName)
{
START_READ_ATTRIBUTES(oReader)
{
if ("pageStartsOn" == sAttributeName)
if (GetAttributeName(EAttribute::PageStartsOn, eType) == sAttributeName)
{
sType = oReader.GetTextA();
if ("BOTH" == sType)
if (GetValueName(EValue::Both, eType) == sType)
m_chPageStartOn = 0;
else if ("EVEN" == sType)
else if (GetValueName(EValue::Even, eType) == sType)
m_chPageStartOn = 1;
else if ("ODD" == sType)
else if (GetValueName(EValue::Odd, eType) == sType)
m_chPageStartOn = 2;
}
else if ("page" == sAttributeName)
else if (GetAttributeName(EAttribute::Page, eType) == sAttributeName)
m_shPageNum = oReader.GetInt();
else if ("pic" == sAttributeName)
else if (GetAttributeName(EAttribute::Figure, eType) == sAttributeName)
m_shFigure = oReader.GetInt();
else if ("tbl" == sAttributeName)
else if (GetAttributeName(EAttribute::Table, eType) == sAttributeName)
m_shTable = oReader.GetInt();
else if ("equation" == sAttributeName)
else if (GetAttributeName(EAttribute::Equation, eType) == sAttributeName)
m_shEquation = oReader.GetInt();
}
END_READ_ATTRIBUTES(oReader)
}
else if ("hp:grid" == sNodeName)
else if (EHanType::HWPX == eType && "hp:grid" == sNodeName)
{
START_READ_ATTRIBUTES(oReader)
{
@ -104,71 +113,87 @@ CCtrlSectionDef::CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLReader& oReader)
}
END_READ_ATTRIBUTES(oReader)
}
else if ("hp:visibility" == sNodeName)
else if (GetNodeName(ENode::Hide, eType) == sNodeName)
{
START_READ_ATTRIBUTES(oReader)
{
if ("hideFirstHeader" == sAttributeName)
if (GetAttributeName(EAttribute::HideHeader, eType) == sAttributeName)
m_bHideHeader = oReader.GetBool();
else if ("hideFirstFooter" == sAttributeName)
else if (GetAttributeName(EAttribute::HideFooter, eType) == sAttributeName)
m_bHideFooter = oReader.GetBool();
else if ("hideFirstMasterPage" == sAttributeName)
else if (GetAttributeName(EAttribute::HideMasterPage, eType) == sAttributeName)
m_bHideMasterPage = oReader.GetBool();
else if ("border" == sAttributeName)
else if (GetAttributeName(EAttribute::HideBorder, eType) == sAttributeName)
{
sType = oReader.GetTextA();
if (EHanType::HWPX == eType)
{
sType = oReader.GetTextA();
if ("HIDE_FIRST" == sType)
{
m_bHideBorder = true;
m_bShowFirstBorder = false;
if ("HIDE_FIRST" == sType)
{
m_bHideBorder = true;
m_bShowFirstBorder = false;
}
else if ("SHOW_FIRST" == sType)
{
m_bHideBorder = true;
m_bShowFirstBorder = true;
}
else if ("SHOW_ALL" == sType)
{
m_bHideBorder = false;
m_bShowFirstBorder = false;
}
}
else if ("SHOW_FIRST" == sType)
else
{
m_bHideBorder = true;
m_bShowFirstBorder = true;
}
else if ("SHOW_ALL" == sType)
{
m_bHideBorder = false;
m_bShowFirstBorder = false;
m_bHideBorder = oReader.GetBool();
m_bShowFirstBorder = m_bHideBorder;
}
}
else if ("fill" == sAttributeName)
else if (GetAttributeName(EAttribute::HideFill, eType) == sAttributeName)
{
sType = oReader.GetTextA();
if (EHanType::HWPX == eType)
{
sType = oReader.GetTextA();
if ("HIDE_FIRST" == sType)
{
m_bHideFill = true;
m_bShowFirstFill = false;
if ("HIDE_FIRST" == sType)
{
m_bHideFill = true;
m_bShowFirstFill = false;
}
else if ("SHOW_FIRST" == sType)
{
m_bHideFill = true;
m_bShowFirstFill = true;
}
else if ("SHOW_ALL" == sType)
{
m_bHideFill = false;
m_bShowFirstFill = false;
}
}
else if ("SHOW_FIRST" == sType)
else
{
m_bHideFill = true;
m_bShowFirstFill = true;
}
else if ("SHOW_ALL" == sType)
{
m_bHideFill = false;
m_bShowFirstFill = false;
m_bHideFill = oReader.GetBool();
m_bShowFirstFill = m_bHideBorder;
}
}
else if ("hp:visibility" == sAttributeName)
else if (GetAttributeName(EAttribute::HidePageNumPos, eType) == sAttributeName)
m_bHidePageNumPos = oReader.GetBool();
else if ("hideFirstEmptyLine" == sAttributeName)
else if (GetAttributeName(EAttribute::HideEmptyLine, eType) == sAttributeName)
m_bHideEmptyLine = oReader.GetBool();
}
END_READ_ATTRIBUTES(oReader)
}
else if ("hp:pagePr" == sNodeName)
m_pPage = new CPage(oReader);
else if ("hp:footNotePr" == sNodeName ||
"hp:endNotePr" == sNodeName)
m_arNoteShapes.push_back(new CNoteShape(oReader));
else if ("hp:pageBorderFill" == sNodeName)
m_arBorderFills.push_back(new CPageBorderFill(oReader));
else if ("hp:masterPage" == sNodeName)
else if (GetNodeName(ENode::PagePropertie, eType) == sNodeName)
m_pPage = new CPage(oReader, eType);
else if (GetNodeName(ENode::FootNotePropertie, eType) == sNodeName ||
GetNodeName(ENode::EndNotePropertie, eType) == sNodeName)
m_arNoteShapes.push_back(new CNoteShape(oReader, eType));
else if (GetNodeName(ENode::PageBorderFill, eType) == sNodeName)
m_arBorderFills.push_back(new CPageBorderFill(oReader, eType));
else if (GetNodeName(ENode::MasterPage, eType) == sNodeName)
{
//TODO:: добавить реализацию
}

View File

@ -45,7 +45,7 @@ class CCtrlSectionDef : public CCtrl
public:
CCtrlSectionDef(const HWP_STRING& sCtrlID);
CCtrlSectionDef(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLReader& oReader);
CCtrlSectionDef(const HWP_STRING& sCtrlID, CXMLReader& oReader, EHanType eType);
~CCtrlSectionDef();
ECtrlObjectType GetCtrlType() const override;

View File

@ -96,7 +96,7 @@ bool CHWPPargraph::ParseHWPParagraph(CXMLReader& oReader, int nCharShapeID, EHan
const std::string sNodeName{oReader.GetName()};
if (GetNodeName(ENode::SectionDef, eType) == sNodeName)
m_arP.push_back(new CCtrlSectionDef(L"dces", oReader));
m_arP.push_back(new CCtrlSectionDef(L"dces", oReader, eType));
else if (GetNodeName(ENode::Char, eType) == sNodeName)
{
if (oReader.IsEmptyNode())

View File

@ -17,8 +17,10 @@ ENoteNumbering GetNoteNumbering(int nValue)
CNoteShape::CNoteShape()
{}
CNoteShape::CNoteShape(CXMLReader& oReader)
{}
CNoteShape::CNoteShape(CXMLReader& oReader, EHanType eType)
{
//TODO:: реализовать
}
CNoteShape* CNoteShape::Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
{

View File

@ -47,7 +47,7 @@ class CNoteShape
int m_nNoteLineColor;
public:
CNoteShape();
CNoteShape(CXMLReader& oReader);
CNoteShape(CXMLReader& oReader, EHanType eType);
static CNoteShape* Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
};

View File

@ -1,51 +1,57 @@
#include "Page.h"
#include "../Common/NodeNames.h"
namespace HWP
{
HWP::CPage::CPage()
{}
CPage::CPage(CXMLReader& oReader)
CPage::CPage(CXMLReader& oReader, EHanType eType)
{
START_READ_ATTRIBUTES(oReader)
{
if ("landscape" == sAttributeName)
m_bLandscape = "NARROWLY" == oReader.GetTextA();
else if ("width" == sAttributeName)
if (GetAttributeName(EAttribute::Landscape, eType) == sAttributeName)
{
if (EHanType::HWPX == eType)
m_bLandscape = "NARROWLY" == oReader.GetTextA();
else
m_bLandscape = oReader.GetBool();
}
else if (GetAttributeName(EAttribute::Width, eType) == sAttributeName)
m_nWidth = oReader.GetInt();
else if ("height" == sAttributeName)
else if (GetAttributeName(EAttribute::Height, eType) == sAttributeName)
m_nHeight = oReader.GetInt();
else if ("gutterType" == sAttributeName)
else if (GetAttributeName(EAttribute::GutterType, eType) == sAttributeName)
{
const std::string sType{oReader.GetTextA()};
if ("LEFT_ONELY" == sType)
if (GetValueName(EValue::LeftOnly, eType) == sType)
m_chGutterType = 0;
else if ("LEFT_RIGHT" == sType)
else if (GetValueName(EValue::LeftRight, eType) == sType)
m_chGutterType = 1;
else if ("TOP_BOTTOM" == sType)
else if (GetValueName(EValue::TopBottom, eType) == sType)
m_chGutterType = 2;
}
}
END_READ_ATTRIBUTES(oReader)
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, "hp:margin")
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, GetNodeName(ENode::PageMargin, eType))
{
START_READ_ATTRIBUTES(oReader)
{
if ("left" == sAttributeName)
if (GetAttributeName(EAttribute::Left, eType) == sAttributeName)
m_nMarginLeft = oReader.GetInt();
else if ("right" == sAttributeName)
else if (GetAttributeName(EAttribute::Right, eType) == sAttributeName)
m_nMarginRight = oReader.GetInt();
else if ("top" == sAttributeName)
else if (GetAttributeName(EAttribute::Top, eType) == sAttributeName)
m_nMarginTop = oReader.GetInt();
else if ("bottom" == sAttributeName)
else if (GetAttributeName(EAttribute::Bottom, eType) == sAttributeName)
m_nMarginBottom = oReader.GetInt();
else if ("header" == sAttributeName)
else if (GetAttributeName(EAttribute::Header, eType) == sAttributeName)
m_nMarginHeader = oReader.GetInt();
else if ("footer" == sAttributeName)
else if (GetAttributeName(EAttribute::Footer, eType) == sAttributeName)
m_nMarginFooter = oReader.GetInt();
else if ("gutter" == sAttributeName)
else if (GetAttributeName(EAttribute::Gutter, eType) == sAttributeName)
m_nMarginGutter = oReader.GetInt();
}

View File

@ -1,6 +1,7 @@
#ifndef PAGE_H
#define PAGE_H
#include "../HanType.h"
#include "../HWPStream.h"
#include "../Common/XMLReader.h"
@ -21,7 +22,7 @@ class CPage
int m_nMarginGutter;
public:
CPage();
CPage(CXMLReader& oReader);
CPage(CXMLReader& oReader, EHanType eType);
int GetWidth() const;
int GetHeight() const;

View File

@ -1,47 +1,54 @@
#include "PageBorderFill.h"
#include "../Common/NodeNames.h"
namespace HWP
{
CPageBorderFill::CPageBorderFill()
{}
CPageBorderFill::CPageBorderFill(CXMLReader& oReader)
CPageBorderFill::CPageBorderFill(CXMLReader& oReader, EHanType eType)
{
START_READ_ATTRIBUTES(oReader)
{
if ("borderFillIDRef" == sAttributeName)
if (GetAttributeName(EAttribute::BorderFillId, eType) == sAttributeName)
m_shBorderFill = oReader.GetInt();
else if ("textBorder" == sAttributeName)
m_bTextBorder = "PAPER" == oReader.GetTextA();
else if ("headerInside" == sAttributeName)
else if (GetAttributeName(EAttribute::TextBorder, eType) == sAttributeName)
{
if (EHanType::HWPX == eType)
m_bTextBorder = "PAPER" == oReader.GetTextA();
else
m_bTextBorder = oReader.GetBool();
}
else if (GetAttributeName(EAttribute::HeaderInside, eType) == sAttributeName)
m_bHeaderInside = oReader.GetBool();
else if ("footerInside" == sAttributeName)
else if (GetAttributeName(EAttribute::FooterInside, eType) == sAttributeName)
m_bFooterInside = oReader.GetBool();
else if ("fillArea" == sAttributeName)
else if (GetAttributeName(EAttribute::FillArea, eType) == sAttributeName)
{
const std::string sType{oReader.GetTextA()};
if ("PAPER" == sType)
if (GetValueName(EValue::Paper, eType) == sType)
m_chFillArea = 0;
else if ("PAGE" == sType)
else if (GetValueName(EValue::Page, eType) == sType)
m_chFillArea = 1;
else if ("BORDER" == sType)
else if (GetValueName(EValue::Border, eType) == sType)
m_chFillArea = 2;
}
}
END_READ_ATTRIBUTES(oReader)
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, "offset")
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, GetNodeName(ENode::PageOffset, eType))
{
START_READ_ATTRIBUTES(oReader)
{
if ("left" == sAttributeName)
if (GetAttributeName(EAttribute::Left, eType) == sAttributeName)
m_shOffsetLeft = oReader.GetInt();
else if ("right" == sAttributeName)
else if (GetAttributeName(EAttribute::Right, eType) == sAttributeName)
m_shOffsetRight = oReader.GetInt();
else if ("top" == sAttributeName)
else if (GetAttributeName(EAttribute::Top, eType) == sAttributeName)
m_shOffsetTop = oReader.GetInt();
else if ("bottom" == sAttributeName)
else if (GetAttributeName(EAttribute::Bottom, eType) == sAttributeName)
m_shOffsetBottom = oReader.GetInt();
}
END_READ_ATTRIBUTES(oReader)

View File

@ -1,6 +1,7 @@
#ifndef PAGEBORDERFILL_H
#define PAGEBORDERFILL_H
#include "../HanType.h"
#include "../HWPStream.h"
#include "../Common/XMLReader.h"
@ -19,7 +20,7 @@ class CPageBorderFill
short m_shBorderFill;
public:
CPageBorderFill();
CPageBorderFill(CXMLReader& oReader);
CPageBorderFill(CXMLReader& oReader, EHanType eType);
static CPageBorderFill* Parse(int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
};