Files
core/DesktopEditor/raster/Metafile/MetaFile.cpp
Ilya.Kirillov 320dce8da5 Исправлены баги при отрисовке текста. Исправлены баги с обновлением DeviceContext в WMF. Добавлена обработка CharSet в wmf.
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62364 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-20 23:59:55 +03:00

236 lines
6.2 KiB
C++

#include "MetaFile.h"
#include "../../graphics/GraphicsRenderer.h"
#include "../../raster/BgraFrame.h"
#include "Common/MetaFileRenderer.h"
#ifndef NEW_WMF
#include "Wmf/RendererOutput.h"
#endif
namespace MetaFile
{
CMetaFile::CMetaFile(CApplicationFonts *pAppFonts)
{
m_pAppFonts = pAppFonts;
// Ñîçäàåì ìåíåäæåð øðèôòîâ ñ ñîáñòâåííûì êýøåì
m_pFontManager = pAppFonts->GenerateFontManager();
CFontsCache* pMeasurerCache = new CFontsCache();
pMeasurerCache->SetStreams(pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
m_oWmfFile.SetFontManager(m_pFontManager);
m_oEmfFile.SetFontManager(m_pFontManager);
m_lType = 0;
}
CMetaFile::~CMetaFile()
{
Close();
RELEASEINTERFACE(m_pFontManager);
}
CFontManager* CMetaFile::get_FontManager()
{
return m_pFontManager;
}
bool CMetaFile::LoadFromFile(const wchar_t *wsFilePath)
{
// TODO: Ñåé÷àñ ïðè çàãðóçêå êàæäîé íîâîé êàðòèíêè ìû ïåðåñîçäàåì
// FontManager, ïîòîìó ÷òî ñåé÷àñ â íåì êýø áåç îãðàíè÷åíèÿ.
//------------------------------------------------------
RELEASEINTERFACE(m_pFontManager);
m_pFontManager = m_pAppFonts->GenerateFontManager();
CFontsCache* pMeasurerCache = new CFontsCache();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
m_oWmfFile.SetFontManager(m_pFontManager);
m_oEmfFile.SetFontManager(m_pFontManager);
//------------------------------------------------------
// Ñíà÷àëà ïûòàåìñÿ îòêðûòü ôàéë êàê Wmf
m_oWmfFile.OpenFromFile(wsFilePath);
#ifdef NEW_WMF
m_oWmfFile.Scan();
#else
m_oWmfFile.Scan(&m_oWmfRect);
#endif
if (!m_oWmfFile.CheckError())
{
m_lType = c_lMetaWmf;
return true;
}
// Ýòî íå Wmf, ïîïðîáóåì îòêðûòü åãî êàê Emf
m_oWmfFile.Close();
m_oEmfFile.OpenFromFile(wsFilePath);
m_oEmfFile.Scan();
if (!m_oEmfFile.CheckError())
{
m_lType = c_lMetaEmf;
return true;
}
// Ýòî íå Emf
m_oEmfFile.Close();
return false;
};
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer)
return false;
pRenderer->BeginCommand(c_nImageType);
if (c_lMetaWmf == m_lType)
{
#ifdef NEW_WMF
CMetaFileRenderer oWmfOut(&m_oWmfFile, pRenderer, dX, dY, dWidth, dHeight);
m_oWmfFile.SetOutputDevice((IOutputDevice*)&oWmfOut);
m_oWmfFile.PlayMetaFile();
#else
double dRendererDpix, dRendererDpiY;
pRenderer->get_DpiX(&dRendererDpix);
pRenderer->get_DpiY(&dRendererDpiY);
CRendererOutput oWmfOut(&m_oWmfFile, pRenderer, dX, dY, dWidth, dHeight);
double fSrcWidth, fSrcHeight;
float fW, fH;
m_oWmfFile.GetSize(&fW, &fH);
m_oWmfFile.GetDisplaySize(&fSrcWidth, &fSrcHeight, dRendererDpix, dRendererDpiY);
//m_oWmfFile.GetDisplaySize( &fSrcWidth, &fSrcHeight, 25.4, 25.4 );
TWmfRectF oRectB = m_oWmfFile.GetBounds();
//double dW = m_oRect.oBR.fX - m_oRect.oTL.fX;
//double dH = m_oRect.oBR.fY - m_oRect.oTL.fY;
double dW = oRectB.oBR.fX - oRectB.oTL.fX;
double dH = oRectB.oBR.fY - oRectB.oTL.fY;
double dScaleX = dWidth / dW;//fSrcWidth;
double dScaleY = dHeight / dH;//fSrcHeight;
//double dScaleX = dWidth / fSrcWidth;
//double dScaleY = dHeight / fSrcHeight;
double dSrcDpiX, dSrcDpiY;
m_oWmfFile.GetDpi(&dSrcDpiX, &dSrcDpiY);
double dDpiKoefX = dRendererDpix / dSrcDpiX;
double dDpiKoefY = dRendererDpiY / dSrcDpiY;
double dDpi = dSrcDpiY * fSrcHeight / fH;
oWmfOut.SetDpi(dRendererDpix, dDpi);
oWmfOut.SetWmfRect(oRectB);
oWmfOut.SetScales(dScaleX, dScaleY);
m_oWmfFile.SetOutputDevice(&oWmfOut);
TWmfRectF oRect;
m_oWmfFile.Play(&oRect);
#endif
}
else if (c_lMetaEmf == m_lType)
{
CMetaFileRenderer oEmfOut(&m_oEmfFile, pRenderer, dX, dY, dWidth, dHeight);
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut);
m_oEmfFile.PlayMetaFile();
}
pRenderer->EndCommand(c_nImageType);
return true;
};
void CMetaFile::Close()
{
m_oWmfFile.Close();
//m_oEmfFile.Close();
m_lType = 0;
};
int CMetaFile::GetType()
{
return m_lType;
}
void CMetaFile::GetBounds(double* pdX, double* pdY, double* pdW, double* pdH)
{
if (c_lMetaWmf == m_lType)
{
#ifdef NEW_WMF
const TRectD& oRect = m_oWmfFile.GetBounds();
*pdX = oRect.dLeft;
*pdY = oRect.dTop;
*pdW = oRect.dRight - oRect.dLeft;
*pdH = oRect.dBottom - oRect.dTop;
#else
*pdX = m_oWmfRect.oTL.fX;
*pdY = m_oWmfRect.oTL.fY;
*pdW = m_oWmfRect.oBR.fX - m_oWmfRect.oTL.fX;
*pdH = m_oWmfRect.oBR.fY - m_oWmfRect.oTL.fY;
#endif
}
else if (c_lMetaEmf == m_lType)
{
TEmfRectL* pRect = m_oEmfFile.GetBounds();
*pdX = pRect->lLeft;
*pdY = pRect->lTop;
*pdW = pRect->lRight - pRect->lLeft;
*pdH = pRect->lBottom - pRect->lTop;
}
else
{
*pdX = 0;
*pdY = 0;
*pdW = 0;
*pdH = 0;
}
};
void CMetaFile::ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight)
{
CFontManager *pFontManager = m_pAppFonts->GenerateFontManager();
CFontsCache* pFontCache = new CFontsCache();
pFontCache->SetStreams(m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
CGraphicsRenderer oRenderer;
oRenderer.SetFontManager(pFontManager);
if (-1 == nHeight)
{
double dX, dY, dW, dH;
GetBounds(&dX, &dY, &dW, &dH);
nHeight = (int)((double)nWidth * dH / dW);
}
//double dDpiX, dDpiY;
//oRenderer.get_DpiX(&dDpiX);
//oRenderer.get_DpiX(&dDpiY);
double dWidth = nWidth ;//* 72 / 25.4 / dDpiX;
double dHeight = nHeight ;//* 72 / 25.4 / dDpiY;
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(-4 * nWidth);
oRenderer.CreateFromBgraFrame(&oFrame);
oRenderer.SetSwapRGB(false);
oRenderer.put_Width(dWidth);
oRenderer.put_Height(dHeight);
DrawOnRenderer(&oRenderer, 0, 0, dWidth, dHeight);
oFrame.SaveFile(wsOutFilePath, unFileType);
RELEASEINTERFACE(pFontManager);
}
}