692 lines
17 KiB
C++
692 lines
17 KiB
C++
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2023
|
||
*
|
||
* This program is a free software product. You can redistribute it and/or
|
||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||
* version 3 as published by the Free Software Foundation. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||
* street, Riga, Latvia, EU, LV-1050.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
#include "MetaFile.h"
|
||
#include "Common/MetaFileTypes.h"
|
||
#include "Common/MetaFileRenderer.h"
|
||
#include "../../raster/BgraFrame.h"
|
||
#include "../../graphics/pro/Graphics.h"
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
#include "Wmf/WmfInterpretator/CWmfInterpretatorSvg.h"
|
||
#include "Emf/EmfInterpretator/CEmfInterpretatorSvg.h"
|
||
#endif
|
||
|
||
namespace MetaFile
|
||
{
|
||
IMetaFile* Create(NSFonts::IApplicationFonts *pAppFonts)
|
||
{
|
||
return new CMetaFile(pAppFonts);
|
||
}
|
||
|
||
CMetaFile::CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : MetaFile::IMetaFile(pAppFonts)
|
||
{
|
||
m_pFontManager = NULL;
|
||
m_pAppFonts = pAppFonts;
|
||
// Создаем менеджер шрифтов с собственным кэшем
|
||
if (pAppFonts)
|
||
{
|
||
m_pFontManager = pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
|
||
pMeasurerCache->SetStreams(pAppFonts->GetStreams());
|
||
m_pFontManager->SetOwnerCache(pMeasurerCache);
|
||
}
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
m_oWmfFile.SetFontManager(m_pFontManager);
|
||
m_oEmfFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
m_oSvmFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
m_oSvgFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
m_lType = 0;
|
||
}
|
||
|
||
NSFonts::IFontManager* CMetaFile::get_FontManager()
|
||
{
|
||
return m_pFontManager;
|
||
}
|
||
|
||
CMetaFile::~CMetaFile()
|
||
{
|
||
Close();
|
||
RELEASEINTERFACE(m_pFontManager);
|
||
}
|
||
|
||
std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight)
|
||
{
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
if (c_lMetaWmf == m_lType)
|
||
{
|
||
m_oWmfFile.SetOutputDevice(InterpretatorType::Svg, unWidth, unHeight);
|
||
m_oWmfFile.PlayMetaFile();
|
||
return ((CWmfInterpretatorSvg*)m_oWmfFile.GetWmfParser()->GetInterpretator())->GetFile();
|
||
}
|
||
else if (c_lMetaEmf == m_lType)
|
||
{
|
||
m_oEmfFile.SetOutputDevice(InterpretatorType::Svg, unWidth, unHeight);
|
||
m_oEmfFile.PlayMetaFile();
|
||
return ((CEmfInterpretatorSvg*)m_oEmfFile.GetEmfParser()->GetInterpretator())->GetFile();
|
||
}
|
||
#endif
|
||
return L"";
|
||
}
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
void CMetaFile::ConvertToXml(const wchar_t *wsFilePath)
|
||
{
|
||
if (NULL == wsFilePath)
|
||
return;
|
||
|
||
m_oEmfFile.SetOutputDevice(wsFilePath, InterpretatorType::XML);
|
||
m_oEmfFile.PlayMetaFile();
|
||
}
|
||
|
||
void CMetaFile::ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t *wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight)
|
||
{
|
||
if (NULL == wsXmlFilePath || NULL == wsOutFilePath)
|
||
return;
|
||
|
||
m_oEmfFile.SetOutputDevice(NULL, wsXmlFilePath);
|
||
|
||
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
|
||
|
||
NSFonts::IFontManager* pFontManager = m_pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
|
||
pFontCache->SetStreams(m_pAppFonts->GetStreams());
|
||
pFontManager->SetOwnerCache(pFontCache);
|
||
|
||
pGrRenderer->SetFontManager(pFontManager);
|
||
|
||
if (-1 == nHeight)
|
||
{
|
||
double dX, dY, dW, dH;
|
||
GetBounds(&dX, &dY, &dW, &dH);
|
||
|
||
if (dW < 0)
|
||
dW = -dW;
|
||
if (dH < 0)
|
||
dH = -dH;
|
||
|
||
if (nWidth < 0) nWidth = (int)(dW * 96 / 25.4);
|
||
nHeight = (int)((double)nWidth * dH / dW);
|
||
}
|
||
|
||
double dWidth = 25.4 * nWidth / 96;
|
||
double dHeight = 25.4 * nHeight / 96;
|
||
|
||
BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4];
|
||
if (!pBgraData)
|
||
return;
|
||
|
||
unsigned int alfa = 0xffffff;
|
||
//дефолтный тон должен быть прозрачным, а не белым
|
||
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
|
||
for (int i = 0; i < nWidth * nHeight; i++)
|
||
{
|
||
((unsigned int*)pBgraData)[i] = alfa;
|
||
}
|
||
CBgraFrame oFrame;
|
||
oFrame.put_Data(pBgraData);
|
||
oFrame.put_Width(nWidth);
|
||
oFrame.put_Height(nHeight);
|
||
oFrame.put_Stride(-4 * nWidth);
|
||
|
||
pGrRenderer->CreateFromBgraFrame(&oFrame);
|
||
pGrRenderer->SetSwapRGB(false);
|
||
pGrRenderer->put_Width(dWidth);
|
||
pGrRenderer->put_Height(dHeight);
|
||
|
||
DrawOnRenderer(wsXmlFilePath, pGrRenderer, 0, 0, dWidth, dHeight);
|
||
|
||
oFrame.SaveFile(wsOutFilePath, unFileType);
|
||
|
||
RELEASEINTERFACE(pFontManager);
|
||
RELEASEINTERFACE(pGrRenderer);
|
||
}
|
||
|
||
bool CMetaFile::DrawOnRenderer(const wchar_t *wsXmlFilePath, IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
|
||
{
|
||
if (NULL == wsXmlFilePath || NULL == pRenderer)
|
||
return false;
|
||
|
||
pRenderer->BeginCommand(c_nImageType);
|
||
|
||
switch (m_lType)
|
||
{
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
case c_lMetaWmf:
|
||
{
|
||
CMetaFileRenderer oWmfOut(m_oWmfFile.GetWmfParser(), pRenderer, dX, dY, dWidth, dHeight);
|
||
m_oWmfFile.SetOutputDevice((IOutputDevice*)&oWmfOut);
|
||
m_oWmfFile.PlayMetaFile();
|
||
break;
|
||
}
|
||
case c_lMetaEmf:
|
||
{
|
||
CMetaFileRenderer oEmfOut(m_oEmfFile.GetEmfParser(), pRenderer, dX, dY, dWidth, dHeight);
|
||
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut, wsXmlFilePath);
|
||
m_oEmfFile.PlayMetaFile();
|
||
break;
|
||
}
|
||
#endif
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
case c_lMetaSvm:
|
||
{
|
||
CMetaFileRenderer oSvmOut(&m_oSvmFile, pRenderer, dX, dY, dWidth, dHeight);
|
||
m_oSvmFile.SetOutputDevice((IOutputDevice*)&oSvmOut);
|
||
m_oSvmFile.PlayMetaFile();
|
||
break;
|
||
}
|
||
#endif
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
case c_lMetaSvg:
|
||
{
|
||
m_oSvgFile.Draw(pRenderer, dX, dY, dWidth, dHeight);
|
||
break;
|
||
}
|
||
#endif
|
||
default:
|
||
break;
|
||
}
|
||
|
||
pRenderer->EndCommand(c_nImageType);
|
||
return true;
|
||
}
|
||
|
||
bool CMetaFile::LoadFromXmlFile(const wchar_t *wsFilePath)
|
||
{
|
||
RELEASEINTERFACE(m_pFontManager);
|
||
|
||
if (m_pAppFonts)
|
||
{
|
||
m_pFontManager = m_pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
|
||
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
|
||
m_pFontManager->SetOwnerCache(pMeasurerCache);
|
||
}
|
||
|
||
m_oWmfFile.SetFontManager(m_pFontManager);
|
||
m_oEmfFile.SetFontManager(m_pFontManager);
|
||
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
m_oSvmFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
m_oSvgFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF_XML
|
||
if (m_oEmfFile.OpenFromXmlFile(wsFilePath) == true)
|
||
{
|
||
m_oEmfFile.Scan();
|
||
|
||
if (!m_oEmfFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaEmf;
|
||
return true;
|
||
}
|
||
m_oEmfFile.Close();
|
||
}
|
||
#endif
|
||
|
||
return false;
|
||
}
|
||
|
||
void CMetaFile::ConvertToEmf(const wchar_t *wsFilePath)
|
||
{
|
||
if (m_lType != c_lMetaEmf || m_oEmfFile.GetEmfParser()->GetType() != EmfParserType::EmfxParser)
|
||
return;
|
||
|
||
m_oEmfFile.SetOutputDevice(wsFilePath, InterpretatorType::Emf);
|
||
m_oEmfFile.PlayMetaFile();
|
||
|
||
//TODO:: сохранение в *.emf файл
|
||
}
|
||
#endif
|
||
|
||
bool CMetaFile::LoadFromFile(const wchar_t *wsFilePath)
|
||
{
|
||
// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем
|
||
// FontManager, потому что сейчас в нем кэш без ограничения.
|
||
//------------------------------------------------------
|
||
|
||
RELEASEINTERFACE(m_pFontManager);
|
||
|
||
if (m_pAppFonts)
|
||
{
|
||
m_pFontManager = m_pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
|
||
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
|
||
m_pFontManager->SetOwnerCache(pMeasurerCache);
|
||
}
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
m_oWmfFile.SetFontManager(m_pFontManager);
|
||
m_oEmfFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
m_oSvmFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
m_oSvgFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
//------------------------------------------------------
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
// Сначала пытаемся открыть файл как Wmf
|
||
if (m_oWmfFile.OpenFromWmfFile(wsFilePath) == true)
|
||
{
|
||
m_oWmfFile.Scan();
|
||
|
||
if (!m_oWmfFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaWmf;
|
||
return true;
|
||
}
|
||
m_oWmfFile.Close();
|
||
}
|
||
// Это не Wmf
|
||
if (m_oEmfFile.OpenFromEmfFile(wsFilePath) == true)
|
||
{
|
||
m_oEmfFile.Scan();
|
||
|
||
if (!m_oEmfFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaEmf;
|
||
return true;
|
||
}
|
||
m_oEmfFile.Close();
|
||
}
|
||
#endif
|
||
// Это не Emf
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
if (m_oSvmFile.OpenFromFile(wsFilePath) == true)
|
||
{
|
||
m_oSvmFile.Scan();
|
||
|
||
if (!m_oSvmFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaSvm;
|
||
return true;
|
||
}
|
||
|
||
m_oSvmFile.Close();
|
||
}
|
||
#endif
|
||
// Это не svm
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
if (m_oSvgFile.OpenFromFile(wsFilePath) == true)
|
||
{
|
||
m_lType = c_lMetaSvg;
|
||
return true;
|
||
}
|
||
|
||
#endif
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CMetaFile::LoadFromBuffer(BYTE *pBuffer, unsigned int unSize)
|
||
{
|
||
if (NULL == pBuffer || 0 == unSize)
|
||
return false;
|
||
|
||
// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем
|
||
// FontManager, потому что сейчас в нем кэш без ограничения.
|
||
//------------------------------------------------------
|
||
|
||
RELEASEINTERFACE(m_pFontManager);
|
||
|
||
if (m_pAppFonts)
|
||
{
|
||
m_pFontManager = m_pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
|
||
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
|
||
m_pFontManager->SetOwnerCache(pMeasurerCache);
|
||
}
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
m_oWmfFile.SetFontManager(m_pFontManager);
|
||
m_oEmfFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
m_oSvmFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
m_oSvgFile.SetFontManager(m_pFontManager);
|
||
#endif
|
||
|
||
//------------------------------------------------------
|
||
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
// Сначала пытаемся открыть файл как Wmf
|
||
if (m_oWmfFile.ReadFromBuffer(pBuffer, unSize) == true)
|
||
{
|
||
m_oWmfFile.Scan();
|
||
|
||
if (!m_oWmfFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaWmf;
|
||
return true;
|
||
}
|
||
m_oWmfFile.Close();
|
||
}
|
||
// Это не Wmf
|
||
if (m_oEmfFile.ReadFromBuffer(pBuffer, unSize) == true)
|
||
{
|
||
m_oEmfFile.Scan();
|
||
|
||
if (!m_oEmfFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaEmf;
|
||
return true;
|
||
}
|
||
m_oEmfFile.Close();
|
||
}
|
||
#endif
|
||
// Это не Emf
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
if (m_oSvmFile.ReadFromBuffer(pBuffer, unSize) == true)
|
||
{
|
||
m_oSvmFile.Scan();
|
||
|
||
if (!m_oSvmFile.CheckError())
|
||
{
|
||
m_lType = c_lMetaSvm;
|
||
return true;
|
||
}
|
||
|
||
m_oSvmFile.Close();
|
||
}
|
||
#endif
|
||
// Это не svm
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
if (m_oSvgFile.ReadFromBuffer(pBuffer, unSize) == true)
|
||
{
|
||
m_lType = c_lMetaSvg;
|
||
return true;
|
||
}
|
||
#endif
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CMetaFile::LoadFromString(const std::wstring& data)
|
||
{
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
RELEASEINTERFACE(m_pFontManager);
|
||
|
||
if (m_pAppFonts)
|
||
{
|
||
m_pFontManager = m_pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
|
||
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
|
||
m_pFontManager->SetOwnerCache(pMeasurerCache);
|
||
}
|
||
|
||
m_oSvgFile.SetFontManager(m_pFontManager);
|
||
|
||
if (m_oSvgFile.ReadFromWString(data) == true)
|
||
{
|
||
m_lType = c_lMetaSvg;
|
||
return true;
|
||
}
|
||
#endif
|
||
return false;
|
||
}
|
||
|
||
void CMetaFile::SetTempDirectory(const std::wstring& dir)
|
||
{
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
m_oSvgFile.SetWorkingDirectory(dir);
|
||
#endif
|
||
}
|
||
|
||
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
|
||
{
|
||
if (NULL == pRenderer)
|
||
return false;
|
||
|
||
pRenderer->BeginCommand(c_nImageType);
|
||
|
||
switch (m_lType)
|
||
{
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
case c_lMetaWmf:
|
||
{
|
||
CMetaFileRenderer oWmfOut(m_oWmfFile.GetWmfParser(), pRenderer, dX, dY, dWidth, dHeight);
|
||
m_oWmfFile.SetOutputDevice((IOutputDevice*)&oWmfOut);
|
||
m_oWmfFile.PlayMetaFile();
|
||
break;
|
||
}
|
||
case c_lMetaEmf:
|
||
{
|
||
CMetaFileRenderer oEmfOut(m_oEmfFile.GetEmfParser(), pRenderer, dX, dY, dWidth, dHeight);
|
||
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut);
|
||
m_oEmfFile.PlayMetaFile();
|
||
break;
|
||
}
|
||
#endif
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
case c_lMetaSvm:
|
||
{
|
||
CMetaFileRenderer oSvmOut(&m_oSvmFile, pRenderer, dX, dY, dWidth, dHeight);
|
||
m_oSvmFile.SetOutputDevice((IOutputDevice*)&oSvmOut);
|
||
m_oSvmFile.PlayMetaFile();
|
||
break;
|
||
}
|
||
#endif
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
case c_lMetaSvg:
|
||
{
|
||
m_oSvgFile.Draw(pRenderer, dX, dY, dWidth, dHeight);
|
||
break;
|
||
}
|
||
#endif
|
||
default:
|
||
break;
|
||
}
|
||
|
||
pRenderer->EndCommand(c_nImageType);
|
||
return true;
|
||
}
|
||
|
||
void CMetaFile::Close()
|
||
{
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
m_oWmfFile.Close();
|
||
m_oEmfFile.Close();
|
||
#endif
|
||
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
m_oSvmFile.Close();
|
||
#endif
|
||
|
||
m_lType = 0;
|
||
}
|
||
|
||
int CMetaFile::GetType()
|
||
{
|
||
return m_lType;
|
||
}
|
||
|
||
void CMetaFile::GetBounds(double* pdX, double* pdY, double* pdW, double* pdH)
|
||
{
|
||
switch (m_lType)
|
||
{
|
||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||
case c_lMetaWmf:
|
||
{
|
||
const TRectL& oRect{m_oWmfFile.GetBounds()};
|
||
*pdX = oRect.Left;
|
||
*pdY = oRect.Top;
|
||
*pdW = oRect.Right - oRect.Left;
|
||
*pdH = oRect.Bottom - oRect.Top;
|
||
break;
|
||
}
|
||
case c_lMetaEmf:
|
||
{
|
||
const TRectL& oRect{m_oEmfFile.GetBounds()};
|
||
*pdX = oRect.Left;
|
||
*pdY = oRect.Top;
|
||
*pdW = oRect.Right - oRect.Left;
|
||
*pdH = oRect.Bottom - oRect.Top;
|
||
break;
|
||
}
|
||
#endif
|
||
#ifdef METAFILE_SUPPORT_SVM
|
||
case c_lMetaSvm:
|
||
{
|
||
const TRectL& oRect{m_oSvmFile.GetBounds()};
|
||
*pdX = oRect.Left;
|
||
*pdY = oRect.Top;
|
||
*pdW = oRect.Right - oRect.Left;
|
||
*pdH = oRect.Bottom - oRect.Top;
|
||
|
||
if (*pdW > 10000 || *pdH > 10000)
|
||
{
|
||
*pdW /= 10;
|
||
*pdH /= 10;
|
||
}
|
||
break;
|
||
}
|
||
#endif
|
||
#ifdef METAFILE_SUPPORT_SVG
|
||
case c_lMetaSvg:
|
||
{
|
||
m_oSvgFile.GetBounds(*pdX, *pdY, *pdW, *pdH);
|
||
break;
|
||
}
|
||
#endif
|
||
default:
|
||
{
|
||
*pdX = 0;
|
||
*pdY = 0;
|
||
*pdW = 0;
|
||
*pdH = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (*pdW < 0) *pdW = -*pdW;
|
||
if (*pdH < 0) *pdH = -*pdH;
|
||
}
|
||
|
||
void CMetaFile::ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight)
|
||
{
|
||
if (nWidth == 0 || nHeight == 0)
|
||
return;
|
||
|
||
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
|
||
|
||
NSFonts::IFontManager* pFontManager = m_pAppFonts->GenerateFontManager();
|
||
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
|
||
pFontCache->SetStreams(m_pAppFonts->GetStreams());
|
||
pFontManager->SetOwnerCache(pFontCache);
|
||
|
||
pGrRenderer->SetFontManager(pFontManager);
|
||
|
||
if (-1 == nHeight)
|
||
{
|
||
double dX, dY, dW, dH;
|
||
GetBounds(&dX, &dY, &dW, &dH);
|
||
|
||
if (dW < 0)
|
||
dW = -dW;
|
||
if (dH < 0)
|
||
dH = -dH;
|
||
|
||
if (nWidth < 0) nWidth = (int)(dW * 96 / 25.4);
|
||
nHeight = (int)((double)nWidth * dH / dW);
|
||
}
|
||
|
||
double dWidth = 25.4 * nWidth / 96;
|
||
double dHeight = 25.4 * nHeight / 96;
|
||
|
||
BYTE* pBgraData = (BYTE*)malloc(nWidth * nHeight * 4);
|
||
if (!pBgraData)
|
||
{
|
||
double dKoef = 2000.0 / (nWidth > nHeight ? nWidth : nHeight);
|
||
|
||
nWidth = (int)(dKoef * nWidth);
|
||
nHeight = (int)(dKoef * nHeight);
|
||
|
||
dWidth = 25.4 * nWidth / 96;
|
||
dHeight = 25.4 * nHeight / 96;
|
||
|
||
pBgraData = (BYTE*)malloc(nWidth * nHeight * 4);
|
||
}
|
||
|
||
if (!pBgraData)
|
||
return;
|
||
|
||
unsigned int alfa = 0xffffff;
|
||
//дефолтный тон должен быть прозрачным, а не белым
|
||
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
|
||
for (int i = 0; i < nWidth * nHeight; i++)
|
||
{
|
||
((unsigned int*)pBgraData)[i] = alfa;
|
||
}
|
||
CBgraFrame oFrame;
|
||
oFrame.put_Data(pBgraData);
|
||
oFrame.put_Width(nWidth);
|
||
oFrame.put_Height(nHeight);
|
||
oFrame.put_Stride(-4 * nWidth);
|
||
|
||
pGrRenderer->CreateFromBgraFrame(&oFrame);
|
||
pGrRenderer->SetSwapRGB(false);
|
||
pGrRenderer->put_Width(dWidth);
|
||
pGrRenderer->put_Height(dHeight);
|
||
|
||
DrawOnRenderer(pGrRenderer, 0, 0, dWidth, dHeight);
|
||
|
||
oFrame.SaveFile(wsOutFilePath, unFileType);
|
||
oFrame.put_Data(NULL);
|
||
RELEASEINTERFACE(pFontManager);
|
||
RELEASEINTERFACE(pGrRenderer);
|
||
|
||
if (pBgraData)
|
||
free(pBgraData);
|
||
}
|
||
}
|