Improved OFD format conversion

This commit is contained in:
Green
2025-04-01 00:39:17 +03:00
parent 925c40aa80
commit 7ceefa54cb
39 changed files with 887 additions and 190 deletions

View File

@ -30,7 +30,10 @@ INCLUDEPATH += \
HEADERS += \
OFDFile.h \
src/Content/ImageObject.h \
src/Content/PageBlock.h \
src/Content/PathObject.h \
src/IOFDElement.h \
src/OFDFile_Private.h \
src/Base.h \
src/Content/Content.h \
@ -40,8 +43,13 @@ HEADERS += \
src/Content/TextObject.h \
src/Document.h \
src/Page.h \
src/PublicRes.h \
src/Res.h \
src/Types/Color.h \
src/Types/ColorSpace.h \
src/Types/CompositeGraphicUnit.h \
src/Types/DrawParam.h \
src/Types/Font.h \
src/Types/MultiMedia.h \
src/Types/PageArea.h \
src/Utils/Types.h \
src/Utils/Utils.h \
@ -49,6 +57,8 @@ HEADERS += \
SOURCES += \
OFDFile.cpp \
src/Content/ImageObject.cpp \
src/Content/PageBlock.cpp \
src/Content/PathObject.cpp \
src/OFDFile_Private.cpp \
src/Base.cpp \
@ -58,8 +68,13 @@ SOURCES += \
src/Content/TextObject.cpp \
src/Document.cpp \
src/Page.cpp \
src/PublicRes.cpp \
src/Res.cpp \
src/Types/Color.cpp \
src/Types/ColorSpace.cpp \
src/Types/CompositeGraphicUnit.cpp \
src/Types/DrawParam.cpp \
src/Types/Font.cpp \
src/Types/MultiMedia.cpp \
src/Types/PageArea.cpp \
src/Utils/Types.cpp \
src/Utils/XmlReader.cpp

View File

@ -11,7 +11,7 @@ CContent::~CContent()
delete pLayer;
}
bool CContent::Read(CXmlReader& oLiteReader)
bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes)
{
if (L"ofd:Content" != oLiteReader.GetName())
return false;
@ -24,18 +24,18 @@ bool CContent::Read(CXmlReader& oLiteReader)
wsNodeName = oLiteReader.GetName();
if (L"ofd:Layer" == wsNodeName)
m_arLayers.push_back(new CLayer(oLiteReader));
m_arLayers.push_back(new CLayer(oLiteReader, pDocumentRes));
}
return false;
}
void CContent::Draw(IRenderer* pRenderer) const
void CContent::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer)
return;
for (const CLayer* pLayer : m_arLayers)
pLayer->Draw(pRenderer);
pLayer->Draw(pRenderer, pPublicRes);
}
}

View File

@ -12,8 +12,8 @@ public:
CContent();
~CContent();
bool Read(CXmlReader& oLiteReader);
void Draw(IRenderer* pRenderer) const;
bool Read(CXmlReader& oLiteReader, const CRes* pDocumentRes);
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const;
};
}

View File

@ -62,7 +62,7 @@ CGraphicUnit::CGraphicUnit(CXmlReader& oLiteReader)
oLiteReader.MoveToElement();
}
void CGraphicUnit::Apply(IRenderer* pRenderer)
void CGraphicUnit::Apply(IRenderer* pRenderer) const
{
if (nullptr == pRenderer)
return;
@ -72,7 +72,12 @@ void CGraphicUnit::Apply(IRenderer* pRenderer)
//Clipping
pRenderer->SetTransform(m_oCTM.m_dM11 * 96. / 25.4, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22 * 96. / 25.4, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy);
pRenderer->SetTransform(m_oCTM.m_dM11, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy);
}
TBox CGraphicUnit::GetBoundary() const
{
return m_oBoundary;
}
}

View File

@ -37,10 +37,14 @@ class CGraphicUnit
double m_dDashOffset;
std::vector<double> m_arDashPattern;
unsigned char m_uchAlpha;
friend class CPathObject;
public:
CGraphicUnit(CXmlReader& oLiteReader);
void Apply(IRenderer* pRenderer);
void Apply(IRenderer* pRenderer) const;
TBox GetBoundary() const;
};
}

View File

@ -1,32 +1,20 @@
#ifndef IPAGEBLOCK_H
#define IPAGEBLOCK_H
#include "../Utils/XmlReader.h"
#include "../IOFDElement.h"
#include "../../../DesktopEditor/graphics/IRenderer.h"
#include "../Res.h"
namespace OFD
{
class IPageBlock
class IPageBlock : public IOFDElement
{
unsigned int m_unID;
public:
IPageBlock(CXmlReader& oLiteReader)
{
if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute())
{
do
{
if (L"ID" == oLiteReader.GetName())
m_unID = oLiteReader.GetUInteger(true);
} while (oLiteReader.MoveToNextAttribute());
oLiteReader.MoveToElement();
}
};
: IOFDElement(oLiteReader){};
virtual ~IPageBlock(){};
virtual bool Read(CXmlReader& oLiteReader) = 0;
virtual void Draw(IRenderer* pRenderer) const = 0;
virtual void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const = 0;
};
}

View File

@ -0,0 +1,43 @@
#include "ImageObject.h"
namespace OFD
{
CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes)
: IPageBlock(oLiteReader), CGraphicUnit(oLiteReader)
{
if (nullptr == pDocumentRes || "ofd:ImageObject" != oLiteReader.GetNameA() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute())
return;
std::string sAttributeName;
do
{
sAttributeName = oLiteReader.GetNameA();
if ("ResourceID" == sAttributeName)
{
m_pMultiMedia = pDocumentRes->GetMultiMedia(oLiteReader.GetUInteger(true));
break;
}
} while(oLiteReader.MoveToNextAttribute());
oLiteReader.MoveToElement();
}
void CImageObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer || nullptr == m_pMultiMedia)
return;
CGraphicUnit::Apply(pRenderer);
const std::wstring wsFilePath = m_pMultiMedia->GetFilePath();
if (wsFilePath.empty())
return;
const TBox oBoundry{GetBoundary()};
pRenderer->DrawImageFromFile(wsFilePath, 0, 0, oBoundry.m_dWidth, oBoundry.m_dHeight);
}
}

View File

@ -0,0 +1,22 @@
#ifndef IMAGEOBJECT_H
#define IMAGEOBJECT_H
#include "IPageBlock.h"
#include "GraphicUnit.h"
#include "../Types/MultiMedia.h"
#include "../Res.h"
namespace OFD
{
class CImageObject : public IPageBlock, public CGraphicUnit
{
const CMultiMedia* m_pMultiMedia;
public:
CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes);
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override;
};
}
#endif // IMAGEOBJECT_H

View File

@ -2,15 +2,17 @@
#include "../../../OOXML/Base/Unit.h"
#include "TextObject.h"
#include "PathObject.h"
#include "PageBlock.h"
namespace OFD
{
CLayer::CLayer(CXmlReader& oLiteReader)
CLayer::CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes)
: IPageBlock(oLiteReader), m_eType(EType::Body)
{
CLayer::Read(oLiteReader);
if (L"ofd:Layer" != oLiteReader.GetName())
return;
CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes);
}
CLayer::~CLayer()
@ -19,39 +21,12 @@ CLayer::~CLayer()
delete pPageBlock;
}
bool CLayer::Read(CXmlReader& oLiteReader)
{
if (L"ofd:Layer" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
IPageBlock* pPageBlock = nullptr;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
pPageBlock = nullptr;
if (L"ofd:TextObject" == wsNodeName)
pPageBlock = new CTextObject(oLiteReader);
else if (L"ofd:PathObject" == wsNodeName)
pPageBlock = new CPathObject(oLiteReader);
if (nullptr != pPageBlock)
m_arPageBlocks.push_back(pPageBlock);
}
return true;
}
void CLayer::Draw(IRenderer* pRenderer) const
void CLayer::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer)
return;
for (const IPageBlock* pPageBlock : m_arPageBlocks)
pPageBlock->Draw(pRenderer);
pPageBlock->Draw(pRenderer, pPublicRes);
}
}

View File

@ -2,6 +2,7 @@
#define LAYER_H
#include "IPageBlock.h"
#include "../Res.h"
namespace OFD
{
@ -17,11 +18,10 @@ class CLayer : public IPageBlock
unsigned int m_unID;
std::vector<IPageBlock*> m_arPageBlocks;
public:
CLayer(CXmlReader& oLiteReader);
CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes);
~CLayer();
bool Read(CXmlReader& oLiteReader) override;
void Draw(IRenderer* pRenderer) const override;
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override;
};
}

View File

@ -0,0 +1,52 @@
#include "PageBlock.h"
#include "TextObject.h"
#include "PathObject.h"
#include "ImageObject.h"
namespace OFD
{
CPageBlock::CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes)
: IPageBlock(oLiteReader)
{
if ("ofd:PageBlock" != oLiteReader.GetNameA() || oLiteReader.IsEmptyNode())
return;
CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes);
}
void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vector<IPageBlock*>& arPageBlocks, const CRes* pDocumentRes)
{
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
IPageBlock* pPageBlock = nullptr;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
pPageBlock = nullptr;
if (L"ofd:TextObject" == wsNodeName)
pPageBlock = new CTextObject(oLiteReader);
else if (L"ofd:PathObject" == wsNodeName)
pPageBlock = new CPathObject(oLiteReader);
else if (L"ofd:PageBlock" == wsNodeName)
pPageBlock = new CPageBlock(oLiteReader, pDocumentRes);
else if (L"ofd:ImageObject" == wsNodeName)
pPageBlock = new CImageObject(oLiteReader, pDocumentRes);
if (nullptr != pPageBlock)
arPageBlocks.push_back(pPageBlock);
}
}
void CPageBlock::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer)
return;
for (const IPageBlock* pPageBlock : m_arPageBlocks)
pPageBlock->Draw(pRenderer, pPublicRes);
}
}

View File

@ -0,0 +1,21 @@
#ifndef PAGEBLOCK_H
#define PAGEBLOCK_H
#include "IPageBlock.h"
#include "../Res.h"
namespace OFD
{
class CPageBlock : public IPageBlock
{
std::vector<IPageBlock*> m_arPageBlocks;
public:
CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes);
static void ReadIntoContainer(CXmlReader& oLiteReader, std::vector<IPageBlock*>& arPageBlocks, const CRes* pDocumentRes);
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override;
};
}
#endif // PAGEBLOCK_H

View File

@ -7,26 +7,9 @@ CPathObject::CPathObject(CXmlReader& oLiteReader)
: IPageBlock(oLiteReader), CGraphicUnit(oLiteReader),
m_bStroke(true), m_bFill(true), m_eRule(ERule::NonZero),
m_pFillColor(nullptr), m_pStrokeColor(nullptr)
{
CPathObject::Read(oLiteReader);
}
CPathObject::~CPathObject()
{
for (const IPathElement* pElement : m_arElements)
delete pElement;
}
void CPathObject::AddElement(const IPathElement* pElement)
{
if (nullptr != pElement)
m_arElements.push_back(pElement);
}
bool CPathObject::Read(CXmlReader& oLiteReader)
{
if (L"ofd:PathObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid())
return false;
return;
if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute())
{
@ -114,7 +97,7 @@ bool CPathObject::Read(CXmlReader& oLiteReader)
}
case 'B':
{
AddElement(CBezierCurve3Element::ReadFromArray(arValues));
AddElement(CBezierCurveElement::ReadFromArray(arValues));
break;
}
case 'A':
@ -133,16 +116,78 @@ bool CPathObject::Read(CXmlReader& oLiteReader)
}
}
}
return true;
}
void CPathObject::Draw(IRenderer* pRenderer) const
CPathObject::~CPathObject()
{
for (const IPathElement* pElement : m_arElements)
delete pElement;
}
void CPathObject::AddElement(const IPathElement* pElement)
{
if (nullptr != pElement)
m_arElements.push_back(pElement);
}
void CPathObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer || m_arElements.empty())
return;
((CGraphicUnit*)this)->Apply(pRenderer);
pRenderer->BeginCommand(c_nPathType);
pRenderer->PathCommandStart();
for (const IPathElement* pElement : m_arElements)
pElement->Draw(pRenderer);
int nEndType = -1;
if (m_bStroke)
nEndType = c_nStroke;
if (m_bFill)
{
switch (m_eRule)
{
case ERule::NonZero:
{
nEndType = (-1 == nEndType ? c_nWindingFillMode : nEndType | c_nWindingFillMode);
break;
}
case ERule::Even_Odd:
{
nEndType = (-1 == nEndType ? c_nEvenOddFillMode : nEndType | c_nEvenOddFillMode);
break;
}
}
}
if (m_bFill && nullptr != m_pFillColor)
{
pRenderer->put_BrushType(c_BrushTypeSolid);
pRenderer->put_BrushColor1(m_pFillColor->ToInt(pPublicRes));
pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha());
}
else
pRenderer->put_BrushType(c_BrushTypeNotSet);
if (m_bStroke && nullptr != m_pStrokeColor)
{
pRenderer->put_PenSize(m_dLineWidth);
pRenderer->put_PenColor(m_pStrokeColor->ToInt(pPublicRes));
pRenderer->put_PenAlpha(m_pStrokeColor->GetAlpha());
}
else
pRenderer->put_PenSize(0.);
if (-1 != nEndType)
pRenderer->DrawPath(nEndType);
pRenderer->PathCommandEnd();
pRenderer->EndCommand(c_nPathType);
}
CStartElement::CStartElement()
@ -167,6 +212,12 @@ IPathElement* CStartElement::ReadFromArray(std::vector<std::string>& arValues)
return nullptr;
}
void CStartElement::Draw(IRenderer* pRenderer) const
{
if (nullptr != pRenderer)
pRenderer->PathCommandMoveTo(m_dX, m_dY);
}
CMoveElement::CMoveElement()
{}
@ -188,6 +239,12 @@ IPathElement* CMoveElement::ReadFromArray(std::vector<std::string>& arValues)
return nullptr;
}
void CMoveElement::Draw(IRenderer* pRenderer) const
{
if (nullptr != pRenderer)
pRenderer->PathCommandMoveTo(m_dX, m_dY);
}
CLineElement::CLineElement()
{}
@ -208,6 +265,12 @@ IPathElement* CLineElement::ReadFromArray(std::vector<std::string>& arValues)
return nullptr;
}
void CLineElement::Draw(IRenderer* pRenderer) const
{
if (nullptr != pRenderer)
pRenderer->PathCommandLineTo(m_dX, m_dY);
}
CBezierCurve2Element::CBezierCurve2Element()
{}
@ -229,15 +292,21 @@ IPathElement* CBezierCurve2Element::ReadFromArray(std::vector<std::string>& arVa
return nullptr;
}
CBezierCurve3Element::CBezierCurve3Element()
void CBezierCurve2Element::Draw(IRenderer* pRenderer) const
{
// if (nullptr != pRenderer)
// pRenderer->PathCommandCurveTo()
}
CBezierCurveElement::CBezierCurveElement()
{}
IPathElement* CBezierCurve3Element::ReadFromArray(std::vector<std::string>& arValues)
IPathElement* CBezierCurveElement::ReadFromArray(std::vector<std::string>& arValues)
{
if (arValues.size() < 4)
return nullptr;
CBezierCurve3Element *pElement = new CBezierCurve3Element();
CBezierCurveElement *pElement = new CBezierCurveElement();
if (nullptr == pElement)
return nullptr;
@ -250,6 +319,12 @@ IPathElement* CBezierCurve3Element::ReadFromArray(std::vector<std::string>& arVa
return nullptr;
}
void CBezierCurveElement::Draw(IRenderer* pRenderer) const
{
if (nullptr != pRenderer)
pRenderer->PathCommandCurveTo(m_dX1, m_dY1, m_dX2, m_dY2, m_dX3, m_dY3);
}
CArcElement::CArcElement()
{}
@ -273,6 +348,12 @@ IPathElement* CArcElement::ReadFromArray(std::vector<std::string>& arValues)
return nullptr;
}
void CArcElement::Draw(IRenderer* pRenderer) const
{
// if (nullptr != pRenderer)
// pRenderer->PathCommandArcTo(m_dX, m_dY, m_dRadiusX * 2., m_dRadiusY * 2., )
}
CCloseElement::CCloseElement()
{}
@ -281,4 +362,9 @@ IPathElement* CCloseElement::ReadFromArray(std::vector<std::string>& arValues)
return new CCloseElement();
}
void CCloseElement::Draw(IRenderer* pRenderer) const
{
if (nullptr != pRenderer)
pRenderer->PathCommandClose();
}
}

View File

@ -15,6 +15,7 @@ public:
virtual ~IPathElement(){};
static IPathElement* ReadFromArray(std::vector<std::string>& arValues) { return nullptr; };
virtual void Draw(IRenderer* pRenderer) const = 0;
};
class CStartElement : public IPathElement
@ -24,6 +25,7 @@ class CStartElement : public IPathElement
public:
CStartElement();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CMoveElement : public IPathElement
@ -33,6 +35,7 @@ class CMoveElement : public IPathElement
public:
CMoveElement();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CLineElement : public IPathElement
@ -42,6 +45,7 @@ class CLineElement : public IPathElement
public:
CLineElement();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CBezierCurve2Element : public IPathElement
@ -53,9 +57,10 @@ class CBezierCurve2Element : public IPathElement
public:
CBezierCurve2Element();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CBezierCurve3Element : public IPathElement
class CBezierCurveElement : public IPathElement
{
double m_dX1;
double m_dY1;
@ -64,8 +69,9 @@ class CBezierCurve3Element : public IPathElement
double m_dX3;
double m_dY3;
public:
CBezierCurve3Element();
CBezierCurveElement();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CArcElement : public IPathElement
@ -80,6 +86,7 @@ class CArcElement : public IPathElement
public:
CArcElement();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CCloseElement : public IPathElement
@ -87,6 +94,7 @@ class CCloseElement : public IPathElement
public:
CCloseElement();
static IPathElement* ReadFromArray(std::vector<std::string>& arValues);
void Draw(IRenderer* pRenderer) const override;
};
class CPathObject : public IPageBlock, public CGraphicUnit
@ -110,8 +118,7 @@ public:
CPathObject(CXmlReader& oLiteReader);
~CPathObject();
bool Read(CXmlReader& oLiteReader) override;
void Draw(IRenderer* pRenderer) const override;
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override;
};
}

View File

@ -45,26 +45,9 @@ CTextObject::CTextObject(CXmlReader& oLiteReader)
m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400),
m_bItalic(false),
m_pFillColor(nullptr), m_pStrokeColor(nullptr)
{
CTextObject::Read(oLiteReader);
}
CTextObject::~CTextObject()
{
if (nullptr != m_pFillColor)
delete m_pFillColor;
if (nullptr != m_pStrokeColor)
delete m_pStrokeColor;
for (const CTextCode* pTextCode : m_arTextCodes)
delete pTextCode;
}
bool CTextObject::Read(CXmlReader& oLiteReader)
{
if (L"ofd:TextObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid())
return false;
return;
if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute())
{
@ -121,11 +104,21 @@ bool CTextObject::Read(CXmlReader& oLiteReader)
else if (L"ofd:TextCode" == wsNodeName)
m_arTextCodes.push_back(new CTextCode(oLiteReader));
}
return true;
}
void CTextObject::Draw(IRenderer* pRenderer) const
CTextObject::~CTextObject()
{
if (nullptr != m_pFillColor)
delete m_pFillColor;
if (nullptr != m_pStrokeColor)
delete m_pStrokeColor;
for (const CTextCode* pTextCode : m_arTextCodes)
delete pTextCode;
}
void CTextObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer || m_arTextCodes.empty())
return;
@ -135,13 +128,13 @@ void CTextObject::Draw(IRenderer* pRenderer) const
if (m_bFill && nullptr != m_pFillColor)
{
pRenderer->put_BrushType(c_BrushTypeSolid);
pRenderer->put_BrushColor1(255);
pRenderer->put_BrushAlpha1(255);
pRenderer->put_BrushColor1(m_pFillColor->ToInt(pPublicRes));
pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha());
}
else
pRenderer->put_BrushType(c_BrushTypeNotSet);
pRenderer->put_FontSize(m_dSize);
pRenderer->put_FontSize(m_dSize * 72. / 25.4);
for (const CTextCode* pTextCode : m_arTextCodes)
pTextCode->Draw(pRenderer);

View File

@ -43,8 +43,7 @@ public:
CTextObject(CXmlReader& oLiteReader);
~CTextObject();
bool Read(CXmlReader& oLiteReader) override;
void Draw(IRenderer* pRenderer) const override;
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override;
};
}

View File

@ -3,10 +3,19 @@
namespace OFD
{
CCommonData::CCommonData()
: m_unMaxUnitID(0)
: m_unMaxUnitID(0), m_pPublicRes(nullptr), m_pDocumentRes(nullptr)
{}
bool CCommonData::Read(CXmlReader& oLiteReader)
CCommonData::~CCommonData()
{
if (nullptr != m_pPublicRes)
delete m_pPublicRes;
if (nullptr != m_pDocumentRes)
delete m_pDocumentRes;
}
bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath)
{
if (L"ofd:CommonData" != oLiteReader.GetName())
return false;
@ -22,11 +31,20 @@ bool CCommonData::Read(CXmlReader& oLiteReader)
m_oPageArea.Read(oLiteReader);
else if (L"ofd:PublicRes" == wsNodeName)
{
// m_oPublicRes.Read();
if (nullptr == m_pPublicRes)
m_pPublicRes = new CRes();
m_pPublicRes->Read(NSSystemPath::Combine(wsRootPath, oLiteReader.GetText2()));
}
else if (L"ofd:DocumentRes" == wsNodeName)
{
if(nullptr == m_pDocumentRes)
m_pDocumentRes = new CRes();
m_pDocumentRes->Read(NSSystemPath::Combine(wsRootPath, oLiteReader.GetText2()));
}
else if (L"ofd:MaxUnitID" == wsNodeName)
m_unMaxUnitID = oLiteReader.GetUInteger();
// else if (L"ofd:DocumentRes" == wsNodeName)
// else if (L"ofd:TemplatePage" == wsNodeName)
// else if (L"ofd:DefaultCS" == wsNodeName)
}
@ -45,6 +63,16 @@ void CCommonData::GetPageSize(double& dWidth, double& dHeight) const
dHeight = oPhysicalBox.m_dHeight;
}
const CRes* CCommonData::GetPublicRes() const
{
return m_pPublicRes;
}
const CRes* CCommonData::GetDocumentRes() const
{
return m_pDocumentRes;
}
CPermission::CPermission()
: m_bEdit(true), m_bAnnot(true), m_bExport(true),
m_bSignature(true), m_bWatermark(true), m_bPrintScreen(true)
@ -100,7 +128,7 @@ bool CDocument::Read(const std::wstring& wsFilePath)
wsNodeName = oLiteReader.GetName();
if (L"ofd:CommonData" == wsNodeName)
m_oCommonData.Read(oLiteReader);
m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath));
else if (L"ofd:Pages" == wsNodeName)
{
const int nPagesDepth = oLiteReader.GetDepth();
@ -127,7 +155,7 @@ bool CDocument::Read(const std::wstring& wsFilePath)
if (-1 == nID)
nID = m_mPages.size() + 1;
CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc));
CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc), m_oCommonData.GetDocumentRes());
if (nullptr != pPage)
m_mPages.insert(std::make_pair(m_mPages.size(), pPage));
@ -153,7 +181,7 @@ bool CDocument::DrawPage(IRenderer* pRenderer, int nPageIndex) const
if (itFound == m_mPages.cend())
return false;
itFound->second->Draw(pRenderer);
itFound->second->Draw(pRenderer, m_oCommonData.GetPublicRes());
return true;
}

View File

@ -2,7 +2,7 @@
#define DOCUMENT_H
#include "Page.h"
#include "PublicRes.h"
#include "Res.h"
#include "Types/PageArea.h"
@ -14,13 +14,18 @@ class CCommonData
{
unsigned int m_unMaxUnitID;
CPageArea m_oPageArea;
CPublicRes m_oPublicRes;
CRes* m_pPublicRes;
CRes* m_pDocumentRes;
public:
CCommonData();
~CCommonData();
bool Read(CXmlReader& oLiteReader);
bool Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath);
void GetPageSize(double& dWidth, double &dHeight) const;
const CRes* GetPublicRes() const;
const CRes* GetDocumentRes() const;
};
class CPermission

35
OFDFile/src/IOFDElement.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef IOFDELEMENT_H
#define IOFDELEMENT_H
#include "Utils/XmlReader.h"
namespace OFD
{
class IOFDElement
{
unsigned int m_unID;
public:
IOFDElement(CXmlReader& oLiteReader)
: m_unID(0)
{
if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute())
{
do
{
if (L"ID" == oLiteReader.GetName())
m_unID = oLiteReader.GetUInteger(true);
} while (oLiteReader.MoveToNextAttribute());
oLiteReader.MoveToElement();
}
};
virtual ~IOFDElement(){};
unsigned int GetID() const
{
return m_unID;
}
};
}
#endif // IOFDELEMENT_H

View File

@ -77,7 +77,7 @@ bool COFDFile_Private::LoadFromFile(const std::wstring& wsFilePath)
COfficeUtils oUtils(NULL);
if (S_OK != oUtils.ExtractToDirectory(wsFilePath,m_pTempFolder->getFullFilePath(L""), NULL, 0))
if (S_OK != oUtils.ExtractToDirectory(wsFilePath, m_pTempFolder->getFullFilePath(L""), NULL, 0))
return false;
return Read(m_pTempFolder);

View File

@ -6,11 +6,9 @@
namespace OFD
{
CPage::CPage()
{
{}
}
CPage* CPage::Read(const std::wstring& wsFilePath)
CPage* CPage::Read(const std::wstring& wsFilePath, const CRes* pDocumentRes)
{
if (wsFilePath.empty())
return nullptr;
@ -34,7 +32,7 @@ CPage* CPage::Read(const std::wstring& wsFilePath)
wsNodeName = oLiteReader.GetName();
if (L"ofd:Content" == wsNodeName)
pPage->m_oContent.Read(oLiteReader);
pPage->m_oContent.Read(oLiteReader, pDocumentRes);
else if (L"ofd:Area" == wsNodeName)
pPage->m_oArea.Read(oLiteReader);
}
@ -42,14 +40,14 @@ CPage* CPage::Read(const std::wstring& wsFilePath)
return pPage;
}
void CPage::Draw(IRenderer* pRenderer) const
void CPage::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const
{
if (nullptr == pRenderer)
return;
pRenderer->BeginCommand(c_nImageType);
m_oContent.Draw(pRenderer);
m_oContent.Draw(pRenderer, pPublicRes);
pRenderer->EndCommand(c_nImageType);
}
@ -61,7 +59,7 @@ void CPage::GetPageSize(double& dWidth, double& dHeight) const
if (oPhysicalBox.Empty())
return;
dWidth = oPhysicalBox.m_dWidth * 25.4 / 96.;
dHeight = oPhysicalBox.m_dHeight * 25.4 / 96.;
dWidth = oPhysicalBox.m_dWidth;
dHeight = oPhysicalBox.m_dHeight;
}
}

View File

@ -13,8 +13,8 @@ class CPage
public:
CPage();
static CPage* Read(const std::wstring& wsFilePath);
void Draw(IRenderer* pRenderer) const;
static CPage* Read(const std::wstring& wsFilePath, const CRes* pDocumentRes);
void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const;
void GetPageSize(double& dWidth, double& dHeight) const;
};

View File

@ -1,17 +0,0 @@
#include "PublicRes.h"
namespace OFD
{
CPublicRes::CPublicRes()
{
}
bool CPublicRes::Read(IFolder* pFolder)
{
if (nullptr == pFolder)
return false;
return false;
}
}

View File

@ -1,17 +0,0 @@
#ifndef PUBLICRES_H
#define PUBLICRES_H
#include "../../OfficeUtils/src/ZipFolder.h"
namespace OFD
{
class CPublicRes
{
public:
CPublicRes();
bool Read(IFolder* pFolder);
};
}
#endif // PUBLICRES_H

138
OFDFile/src/Res.cpp Normal file
View File

@ -0,0 +1,138 @@
#include "Res.h"
namespace OFD
{
CRes::CRes()
{}
CRes::~CRes()
{
#define CLEAR_VECTOR(type, arvaribles)\
for (const std::pair<unsigned int, type*>& oValue : arvaribles)\
delete oValue.second
CLEAR_VECTOR(CColorSpace, m_mColorSpaces);
CLEAR_VECTOR(CDrawParam, m_mDrawParams);
CLEAR_VECTOR(CFont, m_mFonts);
CLEAR_VECTOR(CMultiMedia, m_mMultiMedias);
CLEAR_VECTOR(CCompositeGraphicUnit, m_mCCompositeGraphicUnits);
}
template<class T>
inline void AddElementToMap(T* pElement, unsigned int unIndex, std::map<unsigned int, T*>& mElements)
{
if (nullptr == pElement)
return;
typename std::map<unsigned int, T*>::const_iterator itFound = mElements.find(unIndex);
if (mElements.cend() != itFound)
delete itFound->second;
mElements.insert(std::make_pair(unIndex, pElement));
}
bool CRes::Read(const std::wstring& wsFilePath)
{
if (wsFilePath.empty())
return false;
CXmlReader oLiteReader;
if (!oLiteReader.FromFile(wsFilePath) || !oLiteReader.ReadNextNode() || L"ofd:Res" != oLiteReader.GetName() || oLiteReader.IsEmptyNode())
return false;
std::wstring wsRootPath;
if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute())
{
std::string sNodeName;
do
{
sNodeName = oLiteReader.GetNameA();
if ("BaseLoc" == sNodeName)
{
wsRootPath = NSSystemPath::Combine(NSDirectory::GetFolderPath(wsFilePath), oLiteReader.GetText());
break;
}
} while (oLiteReader.MoveToNextAttribute());
}
oLiteReader.MoveToElement();
const int nDepth = oLiteReader.GetDepth();
std::string sNodeName;
#define PARSE_CONTINER(container_name, element_name, element_type, melements)\
if (container_name == sNodeName) \
{\
const int nDepth = oLiteReader.GetDepth();\
element_type* pElement = nullptr;\
while (oLiteReader.ReadNextSiblingNode(nDepth))\
{\
if (element_name == oLiteReader.GetNameA())\
{\
pElement = new element_type(oLiteReader);\
AddElementToMap(pElement, pElement->GetID(), melements);\
}\
}\
continue;\
}
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
sNodeName = oLiteReader.GetNameA();
PARSE_CONTINER("ofd:ColorSpaces", "ofd:ColorSpace", CColorSpace, m_mColorSpaces)
PARSE_CONTINER("ofd:DrawParams", "ofd:DrawParam", CDrawParam, m_mDrawParams)
PARSE_CONTINER("ofd:Fonts", "ofd:Font", CFont, m_mFonts)
PARSE_CONTINER("ofd:CompositeGraphicUnits", "ofd:CCompositeGraphicUnit", CCompositeGraphicUnit, m_mCCompositeGraphicUnits)
if ("ofd:MultiMedias" == sNodeName)
{
const int nDepth = oLiteReader.GetDepth();
CMultiMedia* pElement = nullptr;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
if ("ofd:MultiMedia" == oLiteReader.GetNameA())
{
pElement = new CMultiMedia(oLiteReader, wsRootPath);
AddElementToMap(pElement, pElement->GetID(), m_mMultiMedias);
}
}
continue;
}
}
return true;
}
#define RETURN_ELEMENT_FROM_MAP(element_type, mElements)\
const std::map<unsigned int, element_type*>::const_iterator itFound = mElements.find(unId);\
return (mElements.cend() != itFound) ? itFound->second : nullptr\
const CColorSpace* CRes::GetColorSpace(unsigned int unId) const
{
RETURN_ELEMENT_FROM_MAP(CColorSpace, m_mColorSpaces);
}
const CDrawParam* CRes::GetDrawParam(unsigned int unId) const
{
RETURN_ELEMENT_FROM_MAP(CDrawParam, m_mDrawParams);
}
const CFont* CRes::GetFont(unsigned int unId) const
{
RETURN_ELEMENT_FROM_MAP(CFont, m_mFonts);
}
const CMultiMedia* CRes::GetMultiMedia(unsigned int unId) const
{
RETURN_ELEMENT_FROM_MAP(CMultiMedia, m_mMultiMedias);
}
const CCompositeGraphicUnit* CRes::GetCompositeGraphicUnit(unsigned int unId) const
{
RETURN_ELEMENT_FROM_MAP(CCompositeGraphicUnit, m_mCCompositeGraphicUnits);
}
}

37
OFDFile/src/Res.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef RES_H
#define RES_H
#include <string>
#include "../../OfficeUtils/src/ZipFolder.h"
#include "Types/ColorSpace.h"
#include "Types/DrawParam.h"
#include "Types/Font.h"
#include "Types/MultiMedia.h"
#include "Types/CompositeGraphicUnit.h"
namespace OFD
{
class CRes
{
std::map<unsigned int, CColorSpace*> m_mColorSpaces;
std::map<unsigned int, CDrawParam*> m_mDrawParams;
std::map<unsigned int, CFont*> m_mFonts;
std::map<unsigned int, CMultiMedia*> m_mMultiMedias;
std::map<unsigned int, CCompositeGraphicUnit*> m_mCCompositeGraphicUnits;
public:
CRes();
~CRes();
bool Read(const std::wstring& wsFilePath);
const CColorSpace* GetColorSpace(unsigned int unId) const;
const CDrawParam* GetDrawParam(unsigned int unId) const;
const CFont* GetFont(unsigned int unId) const;
const CMultiMedia* GetMultiMedia(unsigned int unId) const;
const CCompositeGraphicUnit* GetCompositeGraphicUnit(unsigned int unId) const;
};
}
#endif // RES_H

View File

@ -3,7 +3,7 @@
namespace OFD
{
CColor::CColor(CXmlReader& oXmlReader)
: m_oValue{0, 0, 0}, m_nIndex(0), m_unColorSpace(0), m_chAlpha(255)
: m_oValues{0, 0, 0}, m_nIndex(0), m_unColorSpace(0), m_chAlpha(255)
{
Read(oXmlReader);
}
@ -25,12 +25,13 @@ bool CColor::Read(CXmlReader& oXmlReader)
{
const std::vector<double> arValues{oXmlReader.GetArrayDoubles(true)};
if (3 > arValues.size())
if (4 > arValues.size())
continue;
m_oValue.m_chRed = static_cast<BYTE>(arValues[0]);
m_oValue.m_chGreen = static_cast<BYTE>(arValues[1]);
m_oValue.m_chBlue = static_cast<BYTE>(arValues[2]);
m_oValues[0] = static_cast<BYTE>(arValues[0]);
m_oValues[1] = static_cast<BYTE>(arValues[1]);
m_oValues[2] = static_cast<BYTE>(arValues[2]);
m_oValues[3] = static_cast<BYTE>(arValues[3]);
}
else if ("Alpha" == sAttributeName)
m_chAlpha = oXmlReader.GetUInteger(true);
@ -43,9 +44,42 @@ bool CColor::Read(CXmlReader& oXmlReader)
return true;
}
int CColor::ToInt() const
int CColor::ToInt(const CRes* pPublicRes) const
{
return (255 << 24) | (m_oValue.m_chRed << 16) | (m_oValue.m_chGreen << 8) | (m_oValue.m_chBlue << 0);
if (nullptr != pPublicRes)
{
const CColorSpace *pColorSpace = pPublicRes->GetColorSpace(m_unColorSpace);
if (nullptr != pColorSpace)
{
switch(pColorSpace->GetType())
{
case CColorSpace::EType::GRAY:
return (255 << 24) | (128 << 16) | (128 << 8) | (128 << 0);
case CColorSpace::EType::RGB:
return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[1] << 8) | (m_oValues[2] << 0);
case CColorSpace::EType::CMYK:
{
const float cF = m_oValues[0] / 255.0f;
const float mF = m_oValues[1] / 255.0f;
const float yF = m_oValues[2] / 255.0f;
const float kF = m_oValues[3] / 255.0f;
const float r = (1.0f - cF) * (1.0f - kF);
const float g = (1.0f - mF) * (1.0f - kF);
const float b = (1.0f - yF) * (1.0f - kF);
const unsigned char rByte = static_cast<unsigned char>(r * 255);
const unsigned char gByte = static_cast<unsigned char>(g * 255);
const unsigned char bByte = static_cast<unsigned char>(b * 255);
return (rByte << 0) | (gByte << 8) | (bByte << 16);
}
}
}
}
return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[1] << 8) | (m_oValues[2] << 0);
}
BYTE CColor::GetAlpha() const

View File

@ -2,17 +2,13 @@
#define COLOR_H
#include "../Utils/XmlReader.h"
#include "../Res.h"
namespace OFD
{
class CColor
{
struct TColorChannels
{
BYTE m_chRed;
BYTE m_chGreen;
BYTE m_chBlue;
} m_oValue;
BYTE m_oValues[4];
int m_nIndex;
unsigned int m_unColorSpace;
@ -27,7 +23,7 @@ public:
bool Read(CXmlReader& oXmlReader);
int ToInt() const;
int ToInt(const CRes* pPublicRes) const;
BYTE GetAlpha() const;
};
}

View File

@ -0,0 +1,35 @@
#include "ColorSpace.h"
namespace OFD
{
CColorSpace::CColorSpace(CXmlReader& oXmlReader)
: IOFDElement(oXmlReader)
{
if (0 != oXmlReader.GetAttributesCount() && oXmlReader.MoveToFirstAttribute())
{
std::string sArgumentName;
do
{
sArgumentName = oXmlReader.GetNameA();
if ("Type" == sArgumentName)
{
const std::string sValue{oXmlReader.GetTextA()};
if ("Gray" == sValue)
m_eType = EType::GRAY;
else if ("RGB" == sValue)
m_eType = EType::RGB;
else if ("CMYK" == sValue)
m_eType = EType::CMYK;
}
} while (oXmlReader.MoveToNextAttribute());
}
oXmlReader.MoveToElement();
}
CColorSpace::EType CColorSpace::GetType() const
{
return m_eType;
}
}

View File

@ -0,0 +1,25 @@
#ifndef COLORSPACE_H
#define COLORSPACE_H
#include "../IOFDElement.h"
namespace OFD
{
class CColorSpace : public IOFDElement
{
public:
CColorSpace(CXmlReader& oXmlReader);
enum class EType
{
GRAY,
RGB,
CMYK
};
EType GetType() const;
private:
EType m_eType;
};
}
#endif // COLORSPACE_H

View File

@ -0,0 +1,8 @@
#include "CompositeGraphicUnit.h"
namespace OFD
{
CCompositeGraphicUnit::CCompositeGraphicUnit(CXmlReader& oXmlReader)
: IOFDElement(oXmlReader)
{}
}

View File

@ -0,0 +1,15 @@
#ifndef COMPOSITEGRAPHICUNIT_H
#define COMPOSITEGRAPHICUNIT_H
#include "../IOFDElement.h"
namespace OFD
{
class CCompositeGraphicUnit : public IOFDElement
{
public:
CCompositeGraphicUnit(CXmlReader& oXmlReader);
};
}
#endif // COMPOSITEGRAPHICUNIT_H

View File

@ -0,0 +1,8 @@
#include "DrawParam.h"
namespace OFD
{
CDrawParam::CDrawParam(CXmlReader& oXmlReader)
: IOFDElement(oXmlReader)
{}
}

View File

@ -0,0 +1,14 @@
#ifndef DRAWPARAM_H
#define DRAWPARAM_H
#include "../IOFDElement.h"
namespace OFD
{
class CDrawParam : public IOFDElement
{
public:
CDrawParam(CXmlReader& oXmlReader);
};
}
#endif // DRAWPARAM_H

View File

@ -0,0 +1,37 @@
#include "Font.h"
namespace OFD
{
CFont::CFont(CXmlReader& oXmlReader)
: IOFDElement(oXmlReader),
m_wsCharset(L"unicode"), m_bItalic(false), m_bBold(false),
m_bSerif(false), m_bFixedWidth(false)
{
if (0 != oXmlReader.GetAttributesCount() && oXmlReader.MoveToFirstAttribute())
{
std::string sArgumentName;
do
{
sArgumentName = oXmlReader.GetNameA();
if ("FontName" == sArgumentName)
m_wsFontName = oXmlReader.GetText();
else if ("FamilyName" == sArgumentName)
m_wsFamilyName = oXmlReader.GetText();
else if ("Charset" == sArgumentName)
m_wsCharset = oXmlReader.GetText();
else if ("Italic" == sArgumentName)
m_bItalic = oXmlReader.GetBoolean(true);
else if ("Bold" == sArgumentName)
m_bBold = oXmlReader.GetBoolean(true);
else if ("Serif" == sArgumentName)
m_bSerif = oXmlReader.GetBoolean(true);
else if ("FixedWidth" == sArgumentName)
m_bFixedWidth = oXmlReader.GetBoolean(true);
} while (oXmlReader.MoveToNextAttribute());
}
oXmlReader.MoveToElement();
}
}

25
OFDFile/src/Types/Font.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef FONT_H
#define FONT_H
#include "../IOFDElement.h"
namespace OFD
{
class CFont : public IOFDElement
{
public:
CFont(CXmlReader& oXmlReader);
private:
std::wstring m_wsFontName;
std::wstring m_wsFamilyName;
std::wstring m_wsCharset;
bool m_bItalic;
bool m_bBold;
bool m_bSerif;
bool m_bFixedWidth;
std::wstring m_wsFileName;
};
}
#endif // FONT_H

View File

@ -0,0 +1,54 @@
#include "MultiMedia.h"
#include "../../../DesktopEditor/common/Path.h"
namespace OFD
{
CMultiMedia::CMultiMedia(CXmlReader& oXmlReader, const std::wstring& wsRootPath)
: IOFDElement(oXmlReader), m_eType(EType::Image)
{
if (0 != oXmlReader.GetAttributesCount() && oXmlReader.MoveToFirstAttribute())
{
std::string sArgumentName;
do
{
sArgumentName = oXmlReader.GetNameA();
if ("Type" == sArgumentName)
{
const std::string sValue{oXmlReader.GetTextA()};
if ("Image" == sValue)
m_eType = EType::Image;
else if ("Audio" == sValue)
m_eType = EType::Audio;
else if ("Video" == sValue)
m_eType = EType::Video;
}
} while (oXmlReader.MoveToNextAttribute());
}
oXmlReader.MoveToElement();
const int nDepth = oXmlReader.GetDepth();
while (oXmlReader.ReadNextSiblingNode(nDepth))
{
if ("ofd:MediaFile" == oXmlReader.GetNameA())
{
m_wsFilePath = NSSystemPath::Combine(wsRootPath, oXmlReader.GetText2());
break;
}
}
}
CMultiMedia::EType CMultiMedia::GetType() const
{
return m_eType;
}
std::wstring CMultiMedia::GetFilePath() const
{
return m_wsFilePath;
}
}

View File

@ -0,0 +1,28 @@
#ifndef MULTIMEDIA_H
#define MULTIMEDIA_H
#include "../IOFDElement.h"
namespace OFD
{
class CMultiMedia : public IOFDElement
{
public:
CMultiMedia(CXmlReader& oXmlReader, const std::wstring& wsRootPath);
enum class EType
{
Image,
Audio,
Video
};
EType GetType() const;
std::wstring GetFilePath() const;
private:
EType m_eType;
std::wstring m_wsFilePath;
};
}
#endif // MULTIMEDIA_H

View File

@ -7,7 +7,8 @@ CPageArea::CPageArea()
bool CPageArea::Read(CXmlReader& oLiteReader)
{
if (L"ofd:PageArea" != oLiteReader.GetName())
if (L"ofd:PageArea" != oLiteReader.GetName() &&
L"ofd:Area" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();