Compare commits

..

7 Commits

Author SHA1 Message Date
1f9078d5fb Merge pull request #979 from ONLYOFFICE/fix/emf-bugs
Fixed a crash in unix
2022-07-18 11:14:53 +03:00
dab91f313e fix bug #41715 2022-07-17 17:25:37 +03:00
34c4fbee25 for bug #41715 2022-07-16 17:56:12 +03:00
6438c9a88a Typo fixed 2022-07-07 20:38:37 +03:00
e1c87770bd Fixed Bitmap rendering error in Linux 2022-07-07 20:33:59 +03:00
b5d9d81704 Fixed crash conversion error on linux 2022-07-07 20:33:59 +03:00
dc92a8c07f Changed working with pointers to the interpreter 2022-07-07 20:33:20 +03:00
27 changed files with 635 additions and 486 deletions

View File

@ -94,6 +94,7 @@ namespace BinXlsxRW{
oDrawingConverter.SetMediaDstPath(sMediaDir);
oDrawingConverter.SetEmbedDstPath(sEmbedDir);
oDrawingConverter.SetTempPath(m_sTempDir);
BinXlsxRW::BinaryFileReader oBinaryFileReader;
return oBinaryFileReader.ReadFile(sSrcFileName, sDstPath, &oDrawingConverter, sXMLOptions, m_bIsMacro);
@ -257,7 +258,11 @@ namespace BinXlsxRW{
}
return bResult;
}
void CXlsxSerializer::setFontDir(const std::wstring& sFontDir)
void CXlsxSerializer::setTempDir(const std::wstring& sTempDir)
{
m_sTempDir = sTempDir;
}
void CXlsxSerializer::setFontDir(const std::wstring& sFontDir)
{
m_sFontDir = sFontDir;
}

View File

@ -51,6 +51,7 @@ namespace BinXlsxRW {
class CXlsxSerializer
{
private:
std::wstring m_sTempDir;
std::wstring m_sFontDir;
std::wstring m_sEmbeddedFontsDir;
NSBinPptxRW::CDrawingConverter* m_pExternalDrawingConverter;
@ -65,6 +66,7 @@ namespace BinXlsxRW {
//------------------------------------------------
static void CreateXlsxFolders (const std::wstring& sXmlOptions, const std::wstring& sDstPath, std::wstring& sMediaPath, std::wstring& sEmbedPath);
void setTempDir (const std::wstring& sTempDir);
void setFontDir (const std::wstring& sFontDir);
void setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir);
void setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter);

View File

@ -1004,6 +1004,10 @@ void CDrawingConverter::SetTempPath(const std::wstring& sPath)
{
m_pBinaryWriter->m_pCommon->m_pMediaManager->m_strTempMedia = sPath;
}
std::wstring CDrawingConverter::GetTempPath()
{
return ((m_pBinaryWriter) && (m_pBinaryWriter->m_pCommon) && (m_pBinaryWriter->m_pCommon->m_pMediaManager)) ? m_pBinaryWriter->m_pCommon->m_pMediaManager->m_strTempMedia : L"";
}
void CDrawingConverter::SetEmbedDstPath(const std::wstring& sPath)
{
m_pImageManager->SetDstEmbed(sPath);

View File

@ -222,7 +222,9 @@ namespace NSBinPptxRW
void SetSrcPath (const std::wstring& sPath, int nDocType = 1/*XMLWRITER_DOC_TYPE_DOCX*/);
void SetDstPath (const std::wstring& sPath);
void SetTempPath (const std::wstring& sPath);
std::wstring GetTempPath();
void SetMediaDstPath (const std::wstring& sMediaPath);
void SetEmbedDstPath (const std::wstring& sEmbedPath);

View File

@ -67,10 +67,8 @@ namespace MetaFile
void CXmlOutput::Clear()
{
if (NULL != m_pXmlWriter)
delete m_pXmlWriter;
else if (NULL != m_pXmlLiteReader)
delete m_pXmlLiteReader;
RELEASEOBJECT(m_pXmlWriter);
RELEASEOBJECT(m_pXmlLiteReader);
}
bool CXmlOutput::IsWriter() const

View File

@ -60,7 +60,19 @@
namespace MetaFile
{
class CEmfClip;
struct TRenderConditional
{
IMetaFileBase* m_pFile;
int m_lDrawPathType;
double m_dX; // Координаты левого верхнего угла
double m_dY; //
double m_dW; //
double m_dH; //
double m_dScaleX; // Коэффициенты сжатия/растяжения, чтобы
double m_dScaleY; // результирующая картинка была нужных размеров.
bool m_bStartedPath;
};
class CMetaFileRenderer : public IOutputDevice
{
@ -75,6 +87,7 @@ namespace MetaFile
m_dH = dHeight;
m_pRenderer = NULL;
m_pSecondConditional = NULL;
if (!pRenderer)
return;
@ -103,20 +116,38 @@ namespace MetaFile
//m_pRenderer->PathCommandEnd();
}
CMetaFileRenderer(const CMetaFileRenderer &oMetaFileRenderer, IMetaFileBase *pFile)
virtual ~CMetaFileRenderer()
{
m_pFile = pFile;
RELEASEOBJECT(m_pSecondConditional)
}
m_dX = oMetaFileRenderer.m_dX;
m_dY = oMetaFileRenderer.m_dY;
m_dW = oMetaFileRenderer.m_dW;
m_dH = oMetaFileRenderer.m_dH;
void CreateConditional(IMetaFileBase* pFile)
{
RELEASEOBJECT(m_pSecondConditional);
m_pRenderer = oMetaFileRenderer.m_pRenderer;
m_pSecondConditional = new TRenderConditional();
UpdateScale();
SaveConditional(*m_pSecondConditional);
m_bStartedPath = false;
m_pSecondConditional->m_pFile = pFile;
}
void ChangeConditional()
{
if (NULL != m_pSecondConditional)
{
TRenderConditional oRenderConditional;
SaveConditional(oRenderConditional);
SetConditional(*m_pSecondConditional);
*m_pSecondConditional = oRenderConditional;
}
}
IMetaFileBase* GetFile() const
{
return m_pFile;
}
void UpdateScale()
@ -134,10 +165,6 @@ namespace MetaFile
m_dScaleY = (nB - nT <= 0) ? 1 : m_dH / (double)(nB - nT);
}
~CMetaFileRenderer()
{
}
void Begin()
{
UpdateScale();
@ -736,6 +763,32 @@ namespace MetaFile
private:
void SaveConditional(TRenderConditional& oRenderConditional)
{
oRenderConditional.m_pFile = m_pFile;
oRenderConditional.m_lDrawPathType = m_lDrawPathType;
oRenderConditional.m_dX = m_dX;
oRenderConditional.m_dY = m_dY;
oRenderConditional.m_dW = m_dW;
oRenderConditional.m_dH = m_dH;
oRenderConditional.m_dScaleX = m_dScaleX;
oRenderConditional.m_dScaleY = m_dScaleY;
oRenderConditional.m_bStartedPath = m_bStartedPath;
}
void SetConditional(const TRenderConditional& oRenderConditional)
{
m_pFile = oRenderConditional.m_pFile;
m_lDrawPathType = oRenderConditional.m_lDrawPathType;
m_dX = oRenderConditional.m_dX;
m_dY = oRenderConditional.m_dY;
m_dW = oRenderConditional.m_dW;
m_dH = oRenderConditional.m_dH;
m_dScaleX = oRenderConditional.m_dScaleX;
m_dScaleY = oRenderConditional.m_dScaleY;
m_bStartedPath = oRenderConditional.m_bStartedPath;
}
void CheckStartPath(bool bMoveTo)
{
if (!m_bStartedPath)
@ -1111,6 +1164,8 @@ namespace MetaFile
double m_dScaleX; // Коэффициенты сжатия/растяжения, чтобы
double m_dScaleY; // результирующая картинка была нужных размеров.
bool m_bStartedPath;
TRenderConditional *m_pSecondConditional;
};
}
#endif // _METAFILE_COMMON_METAFILERENDERER_H

View File

@ -54,8 +54,7 @@ namespace MetaFile
~CEmfFile()
{
if (NULL != m_pParser)
delete m_pParser;
RELEASEOBJECT(m_pParser);
}
bool OpenFromEmfFile(const wchar_t* wsFilePath)

View File

@ -6,8 +6,7 @@ namespace MetaFile
CEmfInterpretator::CEmfInterpretator(const wchar_t* wsFilepath) :
unFileSize(0), unNumberRecords(0), ushNuberDescriptors(0)
{
m_pOutStream = new NSFile::CFileBinary();
bool result = m_pOutStream->CreateFileW(wsFilepath);
m_pOutStream = new NSFile::CFileBinary();
}
CEmfInterpretator::CEmfInterpretator(const CEmfInterpretator& oEmfInterpretator, const bool bIsLite)

View File

@ -18,6 +18,9 @@ namespace MetaFile
InterpretatorType GetType() const override;
void CreateConditional(IMetaFileBase* pFile) override {};
void ChangeConditional() override {};
void HANDLE_EMR_HEADER(const TEmfHeader& oTEmfHeader) override ;
void HANDLE_EMR_ALPHABLEND(const TEmfAlphaBlend& oTEmfAlphaBlend, CDataStream &oDataStream) override ;
void HANDLE_EMR_STRETCHDIBITS(const TEmfStretchDIBITS& oTEmfStretchDIBITS, CDataStream &oDataStream) override ;

View File

@ -1,22 +1,17 @@
#include "CEmfInterpretatorArray.h"
#include "CEmfInterpretator.h"
#include "CEmfInterpretatorXml.h"
#include "CEmfInterpretatorRender.h"
namespace MetaFile
{
CEmfInterpretatorArray::CEmfInterpretatorArray(){}
CEmfInterpretatorArray::CEmfInterpretatorArray(const CEmfInterpretatorArray &oInterpretator)
: m_arInterpretators(oInterpretator.m_arInterpretators){}
: m_arInterpretators(oInterpretator.m_arInterpretators)
{}
CEmfInterpretatorArray::~CEmfInterpretatorArray()
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)
delete pInterpretator;
m_arInterpretators.clear();
}
void CEmfInterpretatorArray::AddEmfInterpretator(const wchar_t *wsFilepath)
@ -51,6 +46,18 @@ namespace MetaFile
return InterpretatorType::Array;
}
void CEmfInterpretatorArray::CreateConditional(IMetaFileBase *pFile)
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)
pInterpretator->CreateConditional(pFile);
}
void CEmfInterpretatorArray::ChangeConditional()
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)
pInterpretator->ChangeConditional();
}
void CEmfInterpretatorArray::Begin()
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)

View File

@ -1,7 +1,10 @@
#ifndef CEMFINTERPRETATORARRAY_H
#define CEMFINTERPRETATORARRAY_H
#include "CEmfInterpretator.h"
#include "CEmfInterpretatorXml.h"
#include "CEmfInterpretatorBase.h"
#include "CEmfInterpretatorRender.h"
namespace MetaFile
{
@ -12,12 +15,17 @@ namespace MetaFile
CEmfInterpretatorArray(const CEmfInterpretatorArray& oInterpretator);
virtual ~CEmfInterpretatorArray();
CEmfInterpretatorArray& operator=(const CEmfInterpretatorArray& oEmfInterpretatorArray);
void AddEmfInterpretator(const wchar_t* wsFilepath);
void AddXmlInterpretator(const wchar_t* wsFilepath);
void AddRenderInterpretator(IOutputDevice* pIOutputDevice);
InterpretatorType GetType() const override;
void CreateConditional(IMetaFileBase* pFile) override;
void ChangeConditional() override;
void Begin() override;
void End() override;

View File

@ -1,10 +1,9 @@
#ifndef CEMFINTERPRETATORBASE_H
#define CEMFINTERPRETATORBASE_H
#include "../EmfTypes.h"
#include "../EmfObjects.h"
#include "../../CXmlOutput.h"
#include "../../Common/IOutputDevice.h"
#include "../../Common/MetaFile.h"
namespace MetaFile
{
@ -21,6 +20,9 @@ namespace MetaFile
public:
virtual InterpretatorType GetType() const = 0;
virtual void CreateConditional(IMetaFileBase*) = 0;
virtual void ChangeConditional() = 0;
virtual void HANDLE_EMR_HEADER(const TEmfHeader&) = 0;
virtual void HANDLE_EMR_ALPHABLEND(const TEmfAlphaBlend&, CDataStream&) = 0;
virtual void HANDLE_EMR_STRETCHDIBITS(const TEmfStretchDIBITS&, CDataStream&) = 0;

View File

@ -5,14 +5,23 @@ namespace MetaFile
CEmfInterpretatorRender::CEmfInterpretatorRender(IOutputDevice* pIOutputDevice) :
m_pMetaFileRenderer(static_cast<CMetaFileRenderer*>(pIOutputDevice)){}
CEmfInterpretatorRender::CEmfInterpretatorRender(const CEmfInterpretatorRender &oInterpretator, IMetaFileBase *pFile)
: m_pMetaFileRenderer(new CMetaFileRenderer(*oInterpretator.m_pMetaFileRenderer, pFile)){}
InterpretatorType CEmfInterpretatorRender::GetType() const
{
return InterpretatorType::Render;
}
void CEmfInterpretatorRender::CreateConditional(IMetaFileBase* pFile)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->CreateConditional(pFile);
}
void CEmfInterpretatorRender::ChangeConditional()
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->ChangeConditional();
}
void CEmfInterpretatorRender::Begin()
{
if (NULL != m_pMetaFileRenderer)

View File

@ -10,10 +10,12 @@ namespace MetaFile
{
public:
CEmfInterpretatorRender(IOutputDevice* pIOutputDevice);
CEmfInterpretatorRender(const CEmfInterpretatorRender& oInterpretator, IMetaFileBase* pFile);
InterpretatorType GetType() const override;
void CreateConditional(IMetaFileBase* pFile) override;
void ChangeConditional() override;
void Begin() override;
void End() override;

View File

@ -8,8 +8,17 @@ namespace MetaFile
m_wsXmlFilePath(wsFilePath){}
CEmfInterpretatorXml::CEmfInterpretatorXml(const CEmfInterpretatorXml &oInterpretator)
: m_pOutputXml(oInterpretator.m_pOutputXml),
m_wsXmlFilePath(oInterpretator.m_wsXmlFilePath){}
: m_pOutputXml(NULL),
m_wsXmlFilePath(oInterpretator.m_wsXmlFilePath)
{
if (NULL == oInterpretator.m_pOutputXml)
return;
if (oInterpretator.m_pOutputXml->IsWriter())
m_pOutputXml = new CXmlOutput(TypeXmlOutput::IsWriter);
else
m_pOutputXml = new CXmlOutput(TypeXmlOutput::IsReader);
}
CEmfInterpretatorXml::~CEmfInterpretatorXml()
{

View File

@ -30,6 +30,9 @@ namespace MetaFile
InterpretatorType GetType() const override;
void CreateConditional(IMetaFileBase* pFile) override {};
void ChangeConditional() override {};
void SetOutputDevice(const wchar_t *wsFilePath);
void HANDLE_EMR_HEADER(const TEmfHeader& oTEmfHeader) override ;

View File

@ -17,6 +17,7 @@ namespace MetaFile
ClearFile();
RELEASEOBJECT(m_pEmfPlusParser);
RELEASEOBJECT(m_pInterpretator);
}
bool CEmfParser::OpenFromFile(const wchar_t *wsFilePath)
@ -1392,8 +1393,13 @@ namespace MetaFile
}
m_pEmfPlusParser->SetStream(m_oStream.GetCurPtr(), m_ulRecordSize - 8);
m_pInterpretator->ChangeConditional();
m_pEmfPlusParser->PlayFile();
m_pInterpretator->ChangeConditional();
m_oStream.Skip(m_ulRecordSize - 8);
}
}

View File

@ -624,9 +624,7 @@ namespace MetaFile
}
CEmfParserBase::~CEmfParserBase()
{
RELEASEOBJECT(m_pInterpretator)
}
{}
void CEmfParserBase::PlayMetaFile(){}
@ -770,16 +768,14 @@ namespace MetaFile
void CEmfParserBase::SetInterpretator(IOutputDevice *pOutput)
{
if (NULL != m_pInterpretator)
delete m_pInterpretator;
RELEASEOBJECT(m_pInterpretator);
m_pInterpretator = new CEmfInterpretatorRender(pOutput);
}
void CEmfParserBase::SetInterpretator(const wchar_t *wsFilePath, InterpretatorType oInterpretatorType)
{
if (NULL != m_pInterpretator)
delete m_pInterpretator;
RELEASEOBJECT(m_pInterpretator);
if(oInterpretatorType == InterpretatorType::XML)
m_pInterpretator = new CEmfInterpretatorXml(wsFilePath);
@ -789,8 +785,7 @@ namespace MetaFile
void CEmfParserBase::SetInterpretator(IOutputDevice *pOutput, const wchar_t *wsFilePath)
{
if (NULL != m_pInterpretator)
delete m_pInterpretator;
RELEASEOBJECT(m_pInterpretator);
CEmfInterpretatorArray* pEmfInterpretatorArray = new CEmfInterpretatorArray;
pEmfInterpretatorArray->AddRenderInterpretator(pOutput);

View File

@ -1,15 +1,13 @@
#ifndef CEMFPARSERBASE_H
#define CEMFPARSERBASE_H
#include "../EmfTypes.h"
#include "../EmfObjects.h"
#include "../../Common/MetaFileUtils.h"
//#include "../EmfTypes.h"
//#include "../EmfObjects.h"
//#include "../../Common/MetaFileUtils.h"
#include "../EmfPlayer.h"
#include "../EmfPath.h"
#include "../../Common/MetaFile.h"
#include "../../../../fontengine/FontManager.h"
#include "../EmfInterpretator/CEmfInterpretatorBase.h"

View File

@ -73,8 +73,6 @@
#include "../EmfInterpretator/CEmfInterpretatorArray.h"
#include "../EmfInterpretator/CEmfInterpretatorRender.h"
#include "../../Common/CPathConverter.h"
namespace MetaFile
{
static std::map<unsigned short, std::wstring> ActionNamesEmfPlus =
@ -143,7 +141,7 @@ namespace MetaFile
{0x402D, L"EMFPLUS_TRANSLATEWORLDTRANSFORM"}
};
CEmfPlusParser::CEmfPlusParser(const CEmfInterpretatorBase *pEmfInterpretator, const TEmfHeader& oHeader)
CEmfPlusParser::CEmfPlusParser(CEmfInterpretatorBase *pEmfInterpretator, const TEmfHeader& oHeader)
: m_bBanEmfProcessing(false),
m_unLogicalDpiX(96),
m_unLogicalDpiY(96),
@ -153,32 +151,18 @@ namespace MetaFile
if (NULL != pEmfInterpretator)
{
if (pEmfInterpretator->GetType() == Emf)
{
m_pInterpretator = new CEmfInterpretator(*(CEmfInterpretator*)pEmfInterpretator);
}
else if (pEmfInterpretator->GetType() == Render)
{
m_pInterpretator = new CEmfInterpretatorRender(*(CEmfInterpretatorRender*)pEmfInterpretator, this);
}
else if (pEmfInterpretator->GetType() == XML)
{
m_pInterpretator = new CEmfInterpretatorXml(*(CEmfInterpretatorXml*)pEmfInterpretator);
}
else if (pEmfInterpretator->GetType() == Array)
{
m_pInterpretator = new CEmfInterpretatorArray(*(CEmfInterpretatorArray*)pEmfInterpretator);
}
m_pInterpretator = pEmfInterpretator;
m_pInterpretator->CreateConditional(this);
}
}
CEmfPlusParser::~CEmfPlusParser()
{
ClearFile();
RELEASEOBJECT(m_pInterpretator);
for (EmfPlusObjects::const_iterator pIter = m_mObjects.begin(); pIter != m_mObjects.end(); ++pIter)
delete[] pIter->second;
delete pIter->second;
}
bool CEmfPlusParser::OpenFromFile(const wchar_t *wsFilePath)
@ -723,39 +707,7 @@ namespace MetaFile
m_oStream >> unCustomStartCapSize;
unsigned int unStart = m_oStream.Tell();
m_oStream.Skip(4); //Version
int nType;
m_oStream >> nType;
if (CustomLineCapDataTypeDefault == nType)
{
TEmfPlusCustomLineCapData *pLineCapData = new TEmfPlusCustomLineCapData;
m_oStream >> *pLineCapData;
if (CustomLineCapDataFillPath == pLineCapData->unCustomLineCapDataFlags ||
CustomLineCapDataLinePath == pLineCapData->unCustomLineCapDataFlags)
{
m_oStream.Skip(4); // FillPathLength or LinePathLength
pLineCapData->pPath = ReadPath();
}
pEmfPlusPen->LineStartCapData = pLineCapData;
}
else if (CustomLineCapDataTypeAdjustableArrow == nType)
{
TEmfPlusCustomLineCapArrowData *pLineCapData = new TEmfPlusCustomLineCapArrowData;
m_oStream >> *pLineCapData;
pEmfPlusPen->LineStartCapData = pLineCapData;
}
m_oStream.Skip(unCustomStartCapSize - (m_oStream.Tell() - unStart));
m_oStream.Skip(unCustomStartCapSize); // EmfPlusCustomStartCapData object
}
if (unFlags & PEN_DATA_CUSTOMENDCAP)
{
@ -763,39 +715,7 @@ namespace MetaFile
m_oStream >> unCustomEndCapSize;
unsigned int unStart = m_oStream.Tell();
m_oStream.Skip(4); //Version
int nType;
m_oStream >> nType;
if (CustomLineCapDataTypeDefault == nType)
{
TEmfPlusCustomLineCapData *pLineCapData = new TEmfPlusCustomLineCapData;
m_oStream >> *pLineCapData;
if (CustomLineCapDataFillPath == pLineCapData->unCustomLineCapDataFlags ||
CustomLineCapDataLinePath == pLineCapData->unCustomLineCapDataFlags)
{
m_oStream.Skip(4); // FillPathLength or LinePathLength
pLineCapData->pPath = ReadPath();
}
pEmfPlusPen->LineEndCapData = pLineCapData;
}
else if (CustomLineCapDataTypeAdjustableArrow == nType)
{
TEmfPlusCustomLineCapArrowData *pLineCapData = new TEmfPlusCustomLineCapArrowData;
m_oStream >> *pLineCapData;
pEmfPlusPen->LineEndCapData = pLineCapData;
}
m_oStream.Skip(unCustomEndCapSize - (m_oStream.Tell() - unStart));
m_oStream.Skip(unCustomEndCapSize); // EmfPlusCustomEndCapData object
}
pEmfPlusPen->Brush = ReadBrush();
@ -915,6 +835,8 @@ namespace MetaFile
}
return pPath;
return NULL;
}
else
{
@ -924,7 +846,7 @@ namespace MetaFile
CEmfPlusPath *pPath = new CEmfPlusPath();
for (unsigned int unIndex = 0; unIndex < unPathPointCount; ++unIndex)
{
{
switch (ExpressValue(arPointTypes[unIndex], 0, 3))
{
case PathPointTypeStart: pPath->MoveTo(arPoints[unIndex].X, arPoints[unIndex].Y); break;
@ -994,6 +916,16 @@ namespace MetaFile
return NULL;
}
// std::vector<TEmfPlusPointF> CEmfPlusParser::ReadPointsF(unsigned int unPointCount)
// {
// std::vector<TEmfPlusPointF> arPoints(unPointCount);
// for (unsigned int unIndex = 0; unIndex < unPointCount; ++unIndex)
// m_oStream >> arPoints[unIndex];
// return arPoints;
// }
template<typename PointType>
std::vector<PointType> CEmfPlusParser::ReadPoints(unsigned int unPointCount)
{
@ -1327,8 +1259,7 @@ namespace MetaFile
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X, arPoints[2].Y - arPoints[0].Y,
(NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight);
if (NULL != pNewBuffer)
delete [] pNewBuffer;
RELEASEARRAYOBJECTS(pNewBuffer);
}
}
else if (MetafileDataTypeWmf == eMetafileType ||
@ -1407,8 +1338,7 @@ namespace MetaFile
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X, arPoints[2].Y - arPoints[0].Y,
(NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight);
if (NULL != pNewBuffer)
delete [] pNewBuffer;
RELEASEARRAYOBJECTS(pNewBuffer);
}
}
//TODO: общую часть в идеале нужно вынести
@ -1421,14 +1351,24 @@ namespace MetaFile
NSFile::CFileBinary oFile;
const std::wstring wsFilePath = oFile.GetTempPath() + L"\\temp.tmp";
const std::wstring wsFilePath = oFile.GetTempPath() + L"/temp.tmp";
if (!oFile.CreateFileW(wsFilePath))
return;
if (!oFile.WriteFile(pBuffer, unSize))
{
oFile.CloseFile();
return;
}
oFile.CreateFileW(wsFilePath);
oFile.WriteFile(pBuffer, unSize);
oFile.CloseFile();
Aggplus::CImage oImage(wsFilePath);
if (Aggplus::WrongState == oImage.GetLastStatus())
return;
unsigned int unWidth, unHeight;
unWidth = oImage.GetWidth();
@ -1711,13 +1651,13 @@ namespace MetaFile
m_oStream.ReadBytes(pString, unGlyphCount);
}
std::wstring wsString;
std::wstring wsString;
wsString = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)pString, unGlyphCount);
wsString = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)pString, unGlyphCount);
RELEASEARRAYOBJECTS(pString)
RELEASEARRAYOBJECTS(pString)
std::vector<TEmfPlusPointF> arGlyphPos = ReadPoints<TEmfPlusPointF>(unGlyphCount);
std::vector<TEmfPlusPointF> arGlyphPos = ReadPoints<TEmfPlusPointF>(unGlyphCount);
if (0x00000001 == unMatrixPresent)
{
@ -1969,7 +1909,12 @@ namespace MetaFile
CEmfPlusPath *pPath = GetPath(shOgjectIndex);
if (NULL != pPath)
{
{
if (pPath->m_pCommands.size() == 2)
{
LOGGING(L"TEST")
}
CEmfPlusPen *pEmfPlusPen = GetPen(unPenId);
if (NULL == pEmfPlusPen) return;
@ -1979,13 +1924,7 @@ namespace MetaFile
if (NULL != pEmfPlusPen->Brush)
m_pDC->SetBrush(pEmfPlusPen->Brush);
CPathConverter oPathConverter;
CEmfPath oNewPath, oLineCapPath;
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
oNewPath.DrawWithoutClean(m_pInterpretator, true, false);
oLineCapPath.DrawWithoutClean(m_pInterpretator, false, true);
pPath->DrawWithoutClean(m_pInterpretator, true, false);
if (NULL != pEmfPlusPen->Brush)
m_pDC->RemoveBrush(pEmfPlusPen->Brush);
@ -2468,6 +2407,10 @@ namespace MetaFile
{
LOGGING(L"Object Pen with index: " << shObjectIndex)
if (10 == shObjectIndex)
{
LOGGING(L"TEST")
}
CEmfPlusPen *pEmfPlusPen = ReadPen();
RegisterObject(pEmfPlusPen, shObjectIndex);

View File

@ -1,8 +1,8 @@
#ifndef CEMFPLUSPARSER_H
#define CEMFPLUSPARSER_H
#include "../../Common/MetaFileUtils.h"
#include "../../Common/MetaFile.h"
//#include "../../Common/MetaFileUtils.h"
//#include "../../Common/MetaFile.h"
#include "../EmfPlusObjects.h"
#include "CEmfParserBase.h"
#include "../EmfPlusTypes.h"
@ -13,7 +13,7 @@ namespace MetaFile
class CEmfPlusParser : public CEmfParserBase
{
public:
CEmfPlusParser(const CEmfInterpretatorBase *pEmfInterpretator, const TEmfHeader& oHeader);
CEmfPlusParser(CEmfInterpretatorBase *pEmfInterpretator, const TEmfHeader& oHeader);
virtual ~CEmfPlusParser();
bool OpenFromFile(const wchar_t* wsFilePath) override;

View File

@ -1463,7 +1463,8 @@ namespace NExtractTools
BYTE saveFileType;
SerializeCommon::ReadFileType(params.getXmlOptions(), fileType, nCodePage, sDelimiter, saveFileType);
_UINT32 nRes = CSVReader::ReadFromCsvToXlsx(sFrom, oXlsx, nCodePage, sDelimiter);
CSVReader csvReader;
_UINT32 nRes = csvReader.Read(sFrom, oXlsx, nCodePage, sDelimiter);
oXlsx.PrepareToWrite();
@ -1514,10 +1515,13 @@ namespace NExtractTools
m_oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64());
m_oCXlsxSerializer.setFontDir(params.getFontPath());
m_oCXlsxSerializer.setTempDir(sTemp);
std::wstring sMediaPath;
std::wstring sEmbedPath;
params.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV);
return m_oCXlsxSerializer.loadFromFile (sTempXlstFileEditor, sCSV, params.getXmlOptions(), sMediaPath, sEmbedPath);
}
// xlsx_dir -> csv

View File

@ -4499,7 +4499,7 @@ void BinaryWorksheetTableWriter::WriteCells(const OOX::Spreadsheet::CRow& oRows)
void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell)
{
int nCurPos;
//Ref
//Ref
int nRow = 0;
int nCol = 0;
if (oCell.isInitRef() && oCell.getRowCol(nRow, nCol))
@ -4520,7 +4520,7 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell)
m_oBcw.m_oStream.WriteLONG(*oCell.m_oStyle);
m_oBcw.WriteItemEnd(nCurPos);
}
//Type
//Type
if(oCell.m_oType.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Type);
@ -4534,8 +4534,8 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell)
WriteFormula(oCell.m_oFormula.get2());
m_oBcw.WriteItemEnd(nCurPos);
}
//Value
if(oCell.m_oValue.IsInit() && !oCell.m_oValue->ToString().empty())
//Value
if (oCell.m_oValue.IsInit() && !oCell.m_oValue->ToString().empty())
{
double dValue = 0;
@ -4552,6 +4552,13 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell)
m_oBcw.m_oStream.WriteDoubleReal(dValue);
m_oBcw.WriteItemEnd(nCurPos);
}
//ValueCache
if (oCell.m_oCacheValue.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::ValueCache);
m_oBcw.m_oStream.WriteStringW3(*oCell.m_oCacheValue);
m_oBcw.WriteItemEnd(nCurPos);
}
}
void BinaryWorksheetTableWriter::WriteFormula(OOX::Spreadsheet::CFormula& oFormula)
{
@ -7227,8 +7234,10 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring
{
case BinXlsxRW::c_oFileTypes::CSV:
{
CSVReader csvReader;
pXlsx = new OOX::Spreadsheet::CXlsx();
result = CSVReader::ReadFromCsvToXlsx(sInputDir, *pXlsx, nCodePage, sDelimiter);
result = csvReader.Read(sInputDir, *pXlsx, nCodePage, sDelimiter);
}break;
case BinXlsxRW::c_oFileTypes::XLSX:
case BinXlsxRW::c_oFileTypes::XLSB:

View File

@ -43,8 +43,17 @@
#include "../../Common/DocxFormat/Source/XlsxFormat/SharedStrings/SharedStrings.h"
#include "../../Common/DocxFormat/Source/XlsxFormat/Styles/Styles.h"
namespace CSVReader
class CSVReader::Impl
{
public:
Impl() {}
_UINT32 Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& wcDelimiter);
private:
void AddCell(std::wstring &sText, INT nStartCell, std::stack<INT> &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap);
std::map<std::wstring, unsigned int> mapDataNumber;
OOX::Spreadsheet::CStyles *m_pStyles = NULL;
//---------------------------------------------------------------------------------------------------------
const std::wstring ansi_2_unicode(const unsigned char* data, DWORD data_size)
{
std::wstring result;
@ -108,7 +117,6 @@ namespace CSVReader
//delete [] pStrUtf32;
}
}
const std::wstring utf16_2_unicode(const unsigned char* data, DWORD data_size)
{
if (sizeof(wchar_t) == 2)//utf16 -> utf16
@ -142,7 +150,6 @@ namespace CSVReader
return utf32Str;
}
}
const std::wstring utf32_2_unicode(const unsigned char* data, DWORD data_size)
{
if (sizeof(wchar_t) == 4)//utf32 -> utf32
@ -176,328 +183,390 @@ namespace CSVReader
return utf16Str;
}
}
};
//-----------------------------------------------------------------------------------------------
void AddCell(std::wstring &sText, INT nStartCell, std::stack<INT> &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap)
void CSVReader::Impl::AddCell(std::wstring &sText, INT nStartCell, std::stack<INT> &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap)
{
while (!oDeleteChars.empty())
{
while(!oDeleteChars.empty())
INT nIndex = oDeleteChars.top() - nStartCell;
sText.erase(nIndex, 1);
oDeleteChars.pop();
}
size_t length = sText.length();
// Пустую не пишем
if ((0 == length) || (sText[0] == L'\0'))
return;
OOX::Spreadsheet::CCell *pCell = new OOX::Spreadsheet::CCell();
pCell->m_oType.Init();
pCell->m_oCacheValue = sText; // как есть
WCHAR *pEndPtr;
double dValue = wcstod(sText.c_str(), &pEndPtr);
if ((0 == *pEndPtr) || (0 == *(pEndPtr + 1) && length > 1))
{
std::wstring data_format;
size_t pos = sText.find(L".");
if (pos != std::wstring::npos)
{
INT nIndex = oDeleteChars.top() - nStartCell;
sText.erase(nIndex, 1);
oDeleteChars.pop();
size_t fraction = sText.length() - pos - ((0 != *pEndPtr) ? 2 : 1);
for (size_t i = 0; i < fraction; ++i)
data_format += L"0";
}
// Пустую не пишем
if ((0 == sText.length()) || (sText[0] == L'\0'))
return;
if (false == data_format.empty()) data_format = L"." + data_format;
OOX::Spreadsheet::CCell *pCell = new OOX::Spreadsheet::CCell();
pCell->m_oType.Init();
WCHAR *pEndPtr;
double dValue = wcstod(sText.c_str(), &pEndPtr);
pCell->m_oValue.Init();
if (0 != *pEndPtr)
{
// Не число
pCell->m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeInlineStr);
pCell->m_oRichText.Init();
OOX::Spreadsheet::CText *pText = new OOX::Spreadsheet::CText();
pText->m_sText = sText;
pCell->m_oRichText->m_arrItems.push_back(pText);
wchar_t postfix = *pEndPtr;
data_format += postfix;
if (postfix == L'%')
{
pCell->m_oValue->m_sText = std::to_wstring(dValue / 100.);
}
else
pCell->m_oValue->m_sText = sText.substr(0, length - 1);
}
else
{
// Число
pCell->m_oValue.Init();
pCell->m_oValue->m_sText = sText;
}
if (bIsWrap)
if (false == data_format.empty())
{
// WrapStyle
pCell->m_oStyle = 1;
}
data_format = L"0" + data_format;
pCell->setRowCol(nRow, nCol);
oRow.m_arrItems.push_back(pCell);
std::map<std::wstring, unsigned int>::iterator pFind = mapDataNumber.find(data_format);
if (pFind != mapDataNumber.end())
{
pCell->m_oStyle = pFind->second;
}
else
{
if (!m_pStyles->m_oNumFmts.IsInit()) m_pStyles->m_oNumFmts.Init();
m_pStyles->m_oNumFmts->m_arrItems.push_back(new OOX::Spreadsheet::CNumFmt());
m_pStyles->m_oNumFmts->m_arrItems.back()->m_oFormatCode = data_format;
m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId.Init();
m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->SetValue(164 + m_pStyles->m_oNumFmts->m_arrItems.size());
// Normal + data format
OOX::Spreadsheet::CXfs* pXfs = new OOX::Spreadsheet::CXfs();
pXfs->m_oBorderId.Init(); pXfs->m_oBorderId->SetValue(0);
pXfs->m_oFillId.Init(); pXfs->m_oFillId->SetValue(0);
pXfs->m_oFontId.Init(); pXfs->m_oFontId->SetValue(0);
pXfs->m_oNumFmtId.Init(); pXfs->m_oNumFmtId->SetValue(m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->GetValue());
m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs);
pCell->m_oStyle = (unsigned int)(m_pStyles->m_oCellXfs->m_arrItems.size() - 1);
mapDataNumber.insert(std::make_pair(data_format, *pCell->m_oStyle));
}
}
}
_UINT32 ReadFromCsvToXlsx(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& sDelimiter)
else
{
NSFile::CFileBinary oFile;
if (false == oFile.OpenFile(sFileName)) return AVS_FILEUTILS_ERROR_CONVERT;
//-----------------------------------------------------------------------------------
pCell->m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeInlineStr);
pCell->m_oRichText.Init();
OOX::Spreadsheet::CText *pText = new OOX::Spreadsheet::CText();
pText->m_sText = sText;
pCell->m_oRichText->m_arrItems.push_back(pText);
}
if (bIsWrap)
{
pCell->m_oStyle = 1;
}
pCell->setRowCol(nRow, nCol);
oRow.m_arrItems.push_back(pCell);
}
_UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& sDelimiter)
{
NSFile::CFileBinary oFile;
if (false == oFile.OpenFile(sFileName)) return AVS_FILEUTILS_ERROR_CONVERT;
//-----------------------------------------------------------------------------------
// Создадим Workbook
oXlsx.CreateWorkbook();
oXlsx.CreateWorkbook();
// Создадим стили
oXlsx.CreateStyles();
oXlsx.CreateStyles();
// Добавим стили для wrap-а
oXlsx.m_pStyles->m_oCellXfs.Init();
oXlsx.m_pStyles->m_oCellXfs->m_oCount.Init();
oXlsx.m_pStyles->m_oCellXfs->m_oCount->SetValue(2);
oXlsx.m_pStyles->m_oCellXfs.Init();
oXlsx.m_pStyles->m_oCellXfs->m_oCount.Init();
oXlsx.m_pStyles->m_oCellXfs->m_oCount->SetValue(2);
// Normall default
OOX::Spreadsheet::CXfs* pXfs = NULL;
pXfs = new OOX::Spreadsheet::CXfs();
pXfs->m_oBorderId.Init();
pXfs->m_oBorderId->SetValue(0);
pXfs->m_oFillId.Init();
pXfs->m_oFillId->SetValue(0);
pXfs->m_oFontId.Init();
pXfs->m_oFontId->SetValue(0);
pXfs->m_oNumFmtId.Init();
pXfs->m_oNumFmtId->SetValue(0);
oXlsx.m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs);
// Wrap style
pXfs = new OOX::Spreadsheet::CXfs();
pXfs->m_oBorderId.Init();
pXfs->m_oBorderId->SetValue(0);
pXfs->m_oFillId.Init();
pXfs->m_oFillId->SetValue(0);
pXfs->m_oFontId.Init();
pXfs->m_oFontId->SetValue(0);
pXfs->m_oNumFmtId.Init();
pXfs->m_oNumFmtId->SetValue(0);
m_pStyles = oXlsx.m_pStyles;
pXfs->m_oApplyAlignment.Init();
pXfs->m_oApplyAlignment->SetValue(SimpleTypes::onoffTrue);
pXfs->m_oAligment.Init();
pXfs->m_oAligment->m_oWrapText.Init();
pXfs->m_oAligment->m_oWrapText->SetValue(SimpleTypes::onoffTrue);
oXlsx.m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs);
// Normall default
OOX::Spreadsheet::CXfs* pXfs = NULL;
pXfs = new OOX::Spreadsheet::CXfs();
pXfs->m_oBorderId.Init(); pXfs->m_oBorderId->SetValue(0);
pXfs->m_oFillId.Init(); pXfs->m_oFillId->SetValue(0);
pXfs->m_oFontId.Init(); pXfs->m_oFontId->SetValue(0);
pXfs->m_oNumFmtId.Init(); pXfs->m_oNumFmtId->SetValue(0);
smart_ptr<OOX::Spreadsheet::CWorksheet> pWorksheet(new OOX::Spreadsheet::CWorksheet(NULL));
pWorksheet->m_oSheetData.Init();
//-----------------------------------------------------------------------------------
DWORD nFileSize = 0;
BYTE* pFileData = new BYTE[oFile.GetFileSize() + 64];
oFile.ReadFile(pFileData, oFile.GetFileSize(), nFileSize);
oFile.CloseFile();
oXlsx.m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs);
// Wrap style
pXfs = new OOX::Spreadsheet::CXfs();
pXfs->m_oBorderId.Init(); pXfs->m_oBorderId->SetValue(0);
pXfs->m_oFillId.Init(); pXfs->m_oFillId->SetValue(0);
pXfs->m_oFontId.Init(); pXfs->m_oFontId->SetValue(0);
pXfs->m_oNumFmtId.Init(); pXfs->m_oNumFmtId->SetValue(0);
pXfs->m_oApplyAlignment.Init(); pXfs->m_oApplyAlignment->SetValue(SimpleTypes::onoffTrue);
pXfs->m_oAligment.Init(); pXfs->m_oAligment->m_oWrapText.Init();
pXfs->m_oAligment->m_oWrapText->SetValue(SimpleTypes::onoffTrue);
oXlsx.m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs);
smart_ptr<OOX::Spreadsheet::CWorksheet> pWorksheet(new OOX::Spreadsheet::CWorksheet(NULL));
pWorksheet->m_oSheetData.Init();
//-----------------------------------------------------------------------------------
DWORD nFileSize = 0;
BYTE* pFileData = new BYTE[oFile.GetFileSize() + 64];
oFile.ReadFile(pFileData, oFile.GetFileSize(), nFileSize);
oFile.CloseFile();
//skip bom
DWORD nInputBufferSize = nFileSize;
BYTE* pInputBuffer = pFileData;
if (nInputBufferSize >= 3 && 0xef == pInputBuffer[0] && 0xbb == pInputBuffer[1] && 0xbf == pInputBuffer[2])
{
nInputBufferSize -= 3;
pInputBuffer += 3;
}
else if (nInputBufferSize >= 2 && ((0xfe == pInputBuffer[0] && 0xff == pInputBuffer[1]) || (0xff == pInputBuffer[0] && 0xfe == pInputBuffer[1])))
{
nInputBufferSize -= 2;
pInputBuffer += 2;
}
std::wstring sFileDataW;
if (nCodePage == 1000)
{
sFileDataW = ansi_2_unicode(pInputBuffer, nInputBufferSize);
}
else if (nCodePage == 46)//utf-8
{
utf8_2_unicode(pInputBuffer, nInputBufferSize, sFileDataW);
}
else if (nCodePage == 48)//utf-16
{
sFileDataW = utf16_2_unicode(pInputBuffer, nInputBufferSize);
}
else if (nCodePage == 50) // utf-32
{
sFileDataW = utf32_2_unicode(pInputBuffer, nInputBufferSize);
}
else
{
const NSUnicodeConverter::EncodindId& oEncodindId = NSUnicodeConverter::Encodings[nCodePage];
NSUnicodeConverter::CUnicodeConverter oUnicodeConverter;
sFileDataW = oUnicodeConverter.toUnicode((const char*)pInputBuffer, nInputBufferSize, oEncodindId.Name);
}
//------------------------------------------------------------------------------------------------------------------------------
delete[]pFileData;
size_t nSize = sFileDataW.length();
if (nSize < 1 && nInputBufferSize > 0)
{//для синхронности вывода превью и нормального результата
const NSUnicodeConverter::EncodindId& oEncodindId = NSUnicodeConverter::Encodings[nCodePage];
NSUnicodeConverter::CUnicodeConverter oUnicodeConverter;
sFileDataW = oUnicodeConverter.toUnicode((const char*)pInputBuffer, nInputBufferSize, oEncodindId.Name);
nSize = sFileDataW.length();
//return AVS_FILEUTILS_ERROR_CONVERT_ICU;
}
WCHAR wcDelimiterLeading = L'\0';
WCHAR wcDelimiterTrailing = L'\0';
int nDelimiterSize = 0;
if (sDelimiter.length() > 0)
{
wcDelimiterLeading = sDelimiter[0];
nDelimiterSize = 1;
if (2 == sizeof(wchar_t) && 0xD800 <= wcDelimiterLeading && wcDelimiterLeading <= 0xDBFF && sDelimiter.length() > 1)
{
wcDelimiterTrailing = sDelimiter[1];
nDelimiterSize = 2;
}
}
const WCHAR wcNewLineN = _T('\n');
const WCHAR wcNewLineR = _T('\r');
const WCHAR wcQuote = _T('"');
const WCHAR wcTab = _T('\t');
bool bIsWrap = false;
WCHAR wcCurrent;
INT nStartCell = 0;
std::stack<INT> oDeleteChars;
bool bMsLimit = false;
bool bInQuote = false;
INT nIndexRow = 0;
INT nIndexCol = 0;
OOX::Spreadsheet::CRow *pRow = new OOX::Spreadsheet::CRow();
pRow->m_oR.Init();
pRow->m_oR->SetValue(nIndexRow + 1);
const WCHAR *pTemp = sFileDataW.c_str();
for (size_t nIndex = 0; nIndex < nSize; ++nIndex)
{
wcCurrent = pTemp[nIndex];
if (wcDelimiterLeading == wcCurrent && (L'\0' == wcDelimiterTrailing || (nIndex + 1 < nSize && wcDelimiterTrailing == pTemp[nIndex + 1])))
{
if (bInQuote)
continue;
// New Cell
std::wstring sCellText(pTemp + nStartCell, nIndex - nStartCell);
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
oDeleteChars = std::stack<INT>();
bIsWrap = false;
if (nIndex + nDelimiterSize == nSize)
{
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);
pRow = NULL;
}
if (nIndex + nDelimiterSize > 1000000)
{
nStartCell = 0;
sFileDataW.erase(0, nIndex + nDelimiterSize);
nIndex = 0; nSize -= (nIndex + nDelimiterSize);
pTemp = sFileDataW.c_str();
}
else
nStartCell = nIndex + nDelimiterSize;
}
else if (wcNewLineN == wcCurrent || wcNewLineR == wcCurrent)
{
if (bInQuote)
{
// Добавим Wrap
bIsWrap = true;
continue;
}
// New line
if (nStartCell != nIndex)
{
std::wstring sCellText(pTemp + nStartCell, nIndex - nStartCell);
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
bIsWrap = false;
}
if (wcNewLineR == wcCurrent && nIndex + 1 != nSize && wcNewLineN == pTemp[nIndex + 1])
{
// На комбинацию \r\n должен быть только 1 перенос
++nIndex;
}
if (nIndex + 1 > 1000000)
{
nStartCell = 0;
sFileDataW.erase(0, nIndex + 1);
nIndex = 0; nSize -= (nIndex + 1);
pTemp = sFileDataW.c_str();
}
else
nStartCell = nIndex + 1;
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);
pRow = new OOX::Spreadsheet::CRow();
pRow->m_oR.Init();
pRow->m_oR->SetValue(++nIndexRow + 1);
nIndexCol = 0;
if (pWorksheet->m_oSheetData->m_arrItems.size() > 1048576)
{
bMsLimit = true;
break; // ограниечние мс
}
}
else if (wcQuote == wcCurrent)
{
// Quote
if (false == bInQuote && nStartCell == nIndex && nIndex + 1 != nSize)
{
// Начало новой ячейки (только если мы сразу после разделителя и не в конце файла)
bInQuote = !bInQuote;
nStartCell = nIndex + 1;
}
else if ( bInQuote )
{
// Нужно удалить кавычку ограничитель
oDeleteChars.push(nIndex);
// Если следующий символ кавычка, то мы не закончили ограничитель строки (1997,Ford,E350,"Super, ""luxurious"" truck")
if (nIndex + 1 != nSize && wcQuote == pTemp[nIndex + 1])
++nIndex;
else
bInQuote = !bInQuote;
}
}
else if (wcTab == wcCurrent)
{
// delete tab if not delimiter
oDeleteChars.push(nIndex);
}
}
if (nStartCell != nSize && !bMsLimit)
{
// New line
std::wstring sCellText(pTemp + nStartCell, nSize - nStartCell);
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);
}
else
{
RELEASEOBJECT(pRow);
}
oXlsx.m_arWorksheets.push_back(pWorksheet.GetPointer());
smart_ptr<OOX::File> oWorksheetFile = pWorksheet.smart_dynamic_cast<OOX::File>();
const OOX::RId oRid = oXlsx.m_pWorkbook->Add(oWorksheetFile);
oXlsx.m_mapWorksheets.insert(std::make_pair(oRid.ToString(), pWorksheet.GetPointer())); // for bin
OOX::Spreadsheet::CSheet *pSheet = new OOX::Spreadsheet::CSheet();
pSheet->m_oName = L"Sheet1";
pSheet->m_oSheetId.Init();
pSheet->m_oSheetId->SetValue(1);
pSheet->m_oRid.Init();
pSheet->m_oRid->SetValue(oRid.ToString());
oXlsx.m_pWorkbook->m_oSheets.Init();
oXlsx.m_pWorkbook->m_oSheets->m_arrItems.push_back(pSheet);
return bMsLimit ? AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS : 0;
DWORD nInputBufferSize = nFileSize;
BYTE* pInputBuffer = pFileData;
if (nInputBufferSize >= 3 && 0xef == pInputBuffer[0] && 0xbb == pInputBuffer[1] && 0xbf == pInputBuffer[2])
{
nInputBufferSize -= 3;
pInputBuffer += 3;
}
else if (nInputBufferSize >= 2 && ((0xfe == pInputBuffer[0] && 0xff == pInputBuffer[1]) || (0xff == pInputBuffer[0] && 0xfe == pInputBuffer[1])))
{
nInputBufferSize -= 2;
pInputBuffer += 2;
}
std::wstring sFileDataW;
if (nCodePage == 1000)
{
sFileDataW = ansi_2_unicode(pInputBuffer, nInputBufferSize);
}
else if (nCodePage == 46)//utf-8
{
utf8_2_unicode(pInputBuffer, nInputBufferSize, sFileDataW);
}
else if (nCodePage == 48)//utf-16
{
sFileDataW = utf16_2_unicode(pInputBuffer, nInputBufferSize);
}
else if (nCodePage == 50) // utf-32
{
sFileDataW = utf32_2_unicode(pInputBuffer, nInputBufferSize);
}
else
{
const NSUnicodeConverter::EncodindId& oEncodindId = NSUnicodeConverter::Encodings[nCodePage];
NSUnicodeConverter::CUnicodeConverter oUnicodeConverter;
sFileDataW = oUnicodeConverter.toUnicode((const char*)pInputBuffer, nInputBufferSize, oEncodindId.Name);
}
//------------------------------------------------------------------------------------------------------------------------------
delete[]pFileData;
size_t nSize = sFileDataW.length();
if (nSize < 1 && nInputBufferSize > 0)
{//для синхронности вывода превью и нормального результата
const NSUnicodeConverter::EncodindId& oEncodindId = NSUnicodeConverter::Encodings[nCodePage];
NSUnicodeConverter::CUnicodeConverter oUnicodeConverter;
sFileDataW = oUnicodeConverter.toUnicode((const char*)pInputBuffer, nInputBufferSize, oEncodindId.Name);
nSize = sFileDataW.length();
//return AVS_FILEUTILS_ERROR_CONVERT_ICU;
}
WCHAR wcDelimiterLeading = L'\0';
WCHAR wcDelimiterTrailing = L'\0';
int nDelimiterSize = 0;
if (sDelimiter.length() > 0)
{
wcDelimiterLeading = sDelimiter[0];
nDelimiterSize = 1;
if (2 == sizeof(wchar_t) && 0xD800 <= wcDelimiterLeading && wcDelimiterLeading <= 0xDBFF && sDelimiter.length() > 1)
{
wcDelimiterTrailing = sDelimiter[1];
nDelimiterSize = 2;
}
}
const WCHAR wcNewLineN = _T('\n');
const WCHAR wcNewLineR = _T('\r');
const WCHAR wcQuote = _T('"');
const WCHAR wcTab = _T('\t');
bool bIsWrap = false;
WCHAR wcCurrent;
INT nStartCell = 0;
std::stack<INT> oDeleteChars;
bool bMsLimit = false;
bool bInQuote = false;
INT nIndexRow = 0;
INT nIndexCol = 0;
OOX::Spreadsheet::CRow *pRow = new OOX::Spreadsheet::CRow();
pRow->m_oR.Init();
pRow->m_oR->SetValue(nIndexRow + 1);
const WCHAR *pTemp = sFileDataW.c_str();
for (size_t nIndex = 0; nIndex < nSize; ++nIndex)
{
wcCurrent = pTemp[nIndex];
if (wcDelimiterLeading == wcCurrent && (L'\0' == wcDelimiterTrailing || (nIndex + 1 < nSize && wcDelimiterTrailing == pTemp[nIndex + 1])))
{
if (bInQuote)
continue;
// New Cell
std::wstring sCellText(pTemp + nStartCell, nIndex - nStartCell);
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
oDeleteChars = std::stack<INT>();
bIsWrap = false;
if (nIndex + nDelimiterSize == nSize)
{
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);
pRow = NULL;
}
if (nIndex + nDelimiterSize > 1000000)
{
nStartCell = 0;
sFileDataW.erase(0, nIndex + nDelimiterSize);
nIndex = 0; nSize -= (nIndex + nDelimiterSize);
pTemp = sFileDataW.c_str();
}
else
nStartCell = nIndex + nDelimiterSize;
}
else if (wcNewLineN == wcCurrent || wcNewLineR == wcCurrent)
{
if (bInQuote)
{
// Добавим Wrap
bIsWrap = true;
continue;
}
// New line
if (nStartCell != nIndex)
{
std::wstring sCellText(pTemp + nStartCell, nIndex - nStartCell);
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
bIsWrap = false;
}
if (wcNewLineR == wcCurrent && nIndex + 1 != nSize && wcNewLineN == pTemp[nIndex + 1])
{
// На комбинацию \r\n должен быть только 1 перенос
++nIndex;
}
if (nIndex + 1 > 1000000)
{
nStartCell = 0;
sFileDataW.erase(0, nIndex + 1);
nIndex = 0; nSize -= (nIndex + 1);
pTemp = sFileDataW.c_str();
}
else
nStartCell = nIndex + 1;
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);
pRow = new OOX::Spreadsheet::CRow();
pRow->m_oR.Init();
pRow->m_oR->SetValue(++nIndexRow + 1);
nIndexCol = 0;
if (pWorksheet->m_oSheetData->m_arrItems.size() > 1048576)
{
bMsLimit = true;
break; // ограниечние мс
}
}
else if (wcQuote == wcCurrent)
{
// Quote
if (false == bInQuote && nStartCell == nIndex && nIndex + 1 != nSize)
{
// Начало новой ячейки (только если мы сразу после разделителя и не в конце файла)
bInQuote = !bInQuote;
nStartCell = nIndex + 1;
}
else if (bInQuote)
{
// Нужно удалить кавычку ограничитель
oDeleteChars.push(nIndex);
// Если следующий символ кавычка, то мы не закончили ограничитель строки (1997,Ford,E350,"Super, ""luxurious"" truck")
if (nIndex + 1 != nSize && wcQuote == pTemp[nIndex + 1])
++nIndex;
else
bInQuote = !bInQuote;
}
}
else if (wcTab == wcCurrent)
{
// delete tab if not delimiter
oDeleteChars.push(nIndex);
}
}
if (nStartCell != nSize && !bMsLimit)
{
// New line
std::wstring sCellText(pTemp + nStartCell, nSize - nStartCell);
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);
}
else
{
RELEASEOBJECT(pRow);
}
oXlsx.m_arWorksheets.push_back(pWorksheet.GetPointer());
smart_ptr<OOX::File> oWorksheetFile = pWorksheet.smart_dynamic_cast<OOX::File>();
const OOX::RId oRid = oXlsx.m_pWorkbook->Add(oWorksheetFile);
oXlsx.m_mapWorksheets.insert(std::make_pair(oRid.ToString(), pWorksheet.GetPointer())); // for bin
OOX::Spreadsheet::CSheet *pSheet = new OOX::Spreadsheet::CSheet();
pSheet->m_oName = L"Sheet1";
pSheet->m_oSheetId.Init();
pSheet->m_oSheetId->SetValue(1);
pSheet->m_oRid.Init();
pSheet->m_oRid->SetValue(oRid.ToString());
oXlsx.m_pWorkbook->m_oSheets.Init();
oXlsx.m_pWorkbook->m_oSheets->m_arrItems.push_back(pSheet);
return bMsLimit ? AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS : 0;
}
//----------------------------------------------------------------------------------
CSVReader::CSVReader() : impl_(new CSVReader::Impl())
{
}
CSVReader::~CSVReader()
{
}
_UINT32 CSVReader::Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& sDelimiter)
{
return impl_->Read(sFileName, oXlsx, nCodePage, sDelimiter);
}

View File

@ -37,8 +37,14 @@
#include "../../Common/DocxFormat/Source/XlsxFormat/Worksheets/Worksheet.h"
#include "../../DesktopEditor/common/File.h"
namespace CSVReader
class CSVReader
{
void AddCell(std::wstring &sText, INT nStartCell, std::stack<INT> &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap);
_UINT32 ReadFromCsvToXlsx(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& wcDelimiter);
}
public:
CSVReader();
~CSVReader();
_UINT32 Read(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& wcDelimiter);
private:
class Impl;
boost::shared_ptr<Impl> impl_;
};

View File

@ -7517,8 +7517,14 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD
// Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается.
if (BinXlsxRW::c_oFileTypes::CSV == fileType)
sDstPath = NSSystemPath::GetDirectoryName(sDstPath);
{
sDstPath = pOfficeDrawingConverter->GetTempPath();
if (sDstPath.empty())
sDstPath = NSDirectory::GetTempPath();
sDstPath = NSDirectory::CreateDirectoryWithUniqueName(sDstPath);
}
OOX::Spreadsheet::CXlsx oXlsx;
std::wstring themePath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultDirectory().GetPath();

View File

@ -417,11 +417,12 @@ namespace CSVWriter
if (pCell->m_oType.IsInit())
format_type = (int)pCell->m_oType->GetValue();
if (pCell->m_oCacheValue.IsInit())
{
sCellValue = *pCell->m_oCacheValue;
}
else if (pCell->m_oValue.IsInit())
//if (pCell->m_oCacheValue.IsInit())
//{
// sCellValue = *pCell->m_oCacheValue;
//}
//else
if (pCell->m_oValue.IsInit())
{
sCellValue = pCell->m_oValue->ToString();
@ -445,7 +446,7 @@ namespace CSVWriter
OOX::Spreadsheet::CXfs* xfs = m_oXlsx.m_pStyles->m_oCellXfs->m_arrItems[*pCell->m_oStyle];
if (xfs)
{
if ((xfs->m_oApplyNumberFormat.IsInit()) && (xfs->m_oApplyNumberFormat->ToBool()))
if ((xfs->m_oApplyNumberFormat.IsInit()) && (xfs->m_oApplyNumberFormat->ToBool()) || !xfs->m_oApplyNumberFormat.IsInit())
{
if ((xfs->m_oNumFmtId.IsInit()) /*&& (xfs->m_oNumFmtId->GetValue() != 0*/)
{
@ -604,8 +605,6 @@ namespace CSVWriter
switch (format_type.get_value_or(SimpleTypes::Spreadsheet::celltypeStr))
{
case SimpleTypes::Spreadsheet::celltypePercentage: return value + L"%";
case SimpleTypes::Spreadsheet::celltypeDate: return convert_date_time(value, format_code, true, false);
case SimpleTypes::Spreadsheet::celltypeTime: return convert_date_time(value, format_code, false, true);
case SimpleTypes::Spreadsheet::celltypeDateTime: return convert_date_time(value, format_code);
@ -627,6 +626,7 @@ namespace CSVWriter
{
std::wstring format_code_tmp;
double dValue = XmlUtils::GetDouble(value);
bool bPercent = false;
int count_d = 0;
bool bFloat = false, bStart = true, bEnd = false;
@ -673,7 +673,13 @@ namespace CSVWriter
if ((bStart && count_d < 1) || bEnd)
{
format_code_tmp += format_code[i];
if (format_code[i] == L'%')
{
dValue *= 100.;
bPercent = true;
}
else
format_code_tmp += format_code[i];
}
}
}
@ -694,7 +700,7 @@ namespace CSVWriter
std::wstringstream stream;
stream << boost::wformat(format_code_tmp) % dValue;
return stream.str();
return stream.str() + (bPercent ? L"%" : L"");
}
catch (...)
{