Files
core/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp

583 lines
14 KiB
C++
Raw Blame History

#include "EmfPlayer.h"
#include "EmfFile.h"
namespace MetaFile
{
CEmfPlayer::CEmfPlayer(CEmfFile* pFile)
{
CEmfDC* pDC = new CEmfDC();
if (!pDC)
{
pFile->SetError();
return;
}
m_pEmfFile = pFile;
m_pDC = pDC;
m_vDCStack.push_back(pDC);
InitStockObjects();
};
CEmfPlayer::~CEmfPlayer()
{
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
{
CEmfDC* pDC = m_vDCStack.at(nIndex);
delete pDC;
}
m_vDCStack.clear();
for (CEmfObjectMap::iterator oIterator = m_mObjects.begin(); oIterator != m_mObjects.end(); oIterator++)
{
CEmfObjectBase* pOldObject = oIterator->second;
delete pOldObject;
}
m_mObjects.clear();
}
void CEmfPlayer::Clear()
{
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
{
CEmfDC* pDC = m_vDCStack.at(nIndex);
delete pDC;
}
m_vDCStack.clear();
for (CEmfObjectMap::iterator oIterator = m_mObjects.begin(); oIterator != m_mObjects.end(); oIterator++)
{
CEmfObjectBase* pOldObject = oIterator->second;
delete pOldObject;
}
m_mObjects.clear();
CEmfDC* pDC = new CEmfDC();
if (!pDC)
{
m_pEmfFile->SetError();
return;
}
m_pDC = pDC;
m_vDCStack.push_back(pDC);
InitStockObjects();
SelectObject(0x80000007); // BLACK_PEN
SelectObject(0x80000000); // WHITE_BRUSH
}
CEmfDC* CEmfPlayer::SaveDC()
{
if (!m_pDC)
{
m_pEmfFile->SetError();
return NULL;
}
CEmfDC* pNewDC = m_pDC->Copy();
if (!pNewDC)
{
m_pEmfFile->SetError();
return NULL;
}
m_vDCStack.push_back(pNewDC);
m_pDC = pNewDC;
return pNewDC;
}
CEmfDC* CEmfPlayer::RestoreDC()
{
if (m_vDCStack.size() <= 1)
{
m_pEmfFile->SetError();
return m_pDC;
}
CEmfDC* pDC = m_vDCStack.at(m_vDCStack.size() - 1);
m_vDCStack.pop_back();
delete pDC;
pDC = m_vDCStack.at(m_vDCStack.size() - 1);
m_pDC = pDC;
return m_pDC;
}
CEmfDC* CEmfPlayer::GetDC()
{
return m_pDC;
}
void CEmfPlayer::RegisterObject(unsigned int ulIndex, CEmfObjectBase* pObject)
{
CEmfObjectMap::const_iterator oPos = m_mObjects.find(ulIndex);
if (m_mObjects.end() != oPos)
{
CEmfObjectBase* pOldObject = oPos->second;
delete pOldObject;
m_mObjects.erase(ulIndex);
}
m_mObjects.insert(std::pair<unsigned int, CEmfObjectBase*>(ulIndex, pObject));
}
void CEmfPlayer::SelectObject(unsigned int ulIndex)
{
CEmfObjectMap::const_iterator oPos = m_mObjects.find(ulIndex);
if (m_mObjects.end() != oPos)
{
CEmfObjectBase* pObject = oPos->second;
switch (pObject->GetType())
{
case EMF_OBJECT_BRUSH: m_pDC->SetBrush((CEmfLogBrushEx*)pObject); break;
case EMF_OBJECT_FONT: m_pDC->SetFont((CEmfLogFont*)pObject); break;
case EMF_OBJECT_PEN: m_pDC->SetPen((CEmfLogPen*)pObject); break;
}
}
}
void CEmfPlayer::SelectPalette(unsigned int ulIndex)
{
// DEFAULT_PALETTE
if (ulIndex == 0x8000000F)
m_pDC->SetPalette(NULL);
CEmfObjectMap::const_iterator oPos = m_mObjects.find(ulIndex);
if (m_mObjects.end() != oPos)
{
CEmfObjectBase* pObject = oPos->second;
if (EMF_OBJECT_PALETTE == pObject->GetType())
m_pDC->SetPalette((CEmfLogPalette*)pObject);
}
}
void CEmfPlayer::DeleteObject(unsigned int ulIndex)
{
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> DC_BRUSH <20> DC_PEN
CEmfObjectMap::const_iterator oPos = m_mObjects.find(ulIndex);
if (m_mObjects.end() != oPos)
{
CEmfObjectBase* pObject = oPos->second;
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
{
CEmfDC* pDC = m_vDCStack.at(nIndex);
switch (pObject->GetType())
{
case EMF_OBJECT_BRUSH: pDC->RemoveBrush((CEmfLogBrushEx*)pObject); break;
case EMF_OBJECT_FONT: pDC->RemoveFont((CEmfLogFont*)pObject); break;
case EMF_OBJECT_PEN: pDC->RemovePen((CEmfLogPen*)pObject); break;
}
}
delete pObject;
m_mObjects.erase(ulIndex);
}
}
void CEmfPlayer::InitStockObjects()
{
InitStockBrush(false, 0xff, 0xff, 0xff, 0x80000000);
InitStockBrush(false, 0xc0, 0xc0, 0xc0, 0x80000001);
InitStockBrush(false, 0x80, 0x80, 0x80, 0x80000002);
InitStockBrush(false, 0x40, 0x40, 0x40, 0x80000003);
InitStockBrush(false, 0x00, 0x00, 0x00, 0x80000004);
InitStockBrush(true, 0x00, 0x00, 0x00, 0x80000005);
InitStockPen(false, 0xff, 0xff, 0xff, 0x80000006);
InitStockPen(false, 0x00, 0x00, 0x00, 0x80000007);
InitStockPen(true, 0x00, 0x00, 0x00, 0x80000008);
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// DC_BRUSH <20> DC_PEN <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
void CEmfPlayer::InitStockBrush(bool bNull, unsigned char r, unsigned char g, unsigned char b, unsigned int ulIndex)
{
CEmfLogBrushEx* pBrush = new CEmfLogBrushEx();
if (!pBrush)
return;
if (bNull)
pBrush->BrushStyle = BS_NULL;
else
{
pBrush->BrushStyle = BS_SOLID;
pBrush->Color.Set(r, g, b);
}
RegisterObject(ulIndex, (CEmfObjectBase*)pBrush);
}
void CEmfPlayer::InitStockPen(bool bNull, unsigned char r, unsigned char g, unsigned char b, unsigned int ulIndex)
{
CEmfLogPen* pPen = new CEmfLogPen();
if (!pPen)
return;
if (bNull)
pPen->PenStyle = PS_NULL;
else
{
pPen->PenStyle = PS_COSMETIC | PS_SOLID;
pPen->Color.Set(r, g, b);
}
RegisterObject(ulIndex, (CEmfObjectBase*)pPen);
}
CEmfDC::CEmfDC()
{
m_ulMapMode = MM_TEXT;
m_pBrush = NULL;
m_pPen = NULL;
m_pFont = NULL;
m_oTransform.Init();
m_oInverseTransform.Init();
m_oTextColor.Init();
m_oBgColor.Init();
m_ulTextAlign = TA_TOP | TA_LEFT | TA_NOUPDATECP;
m_ulBgMode = TRANSPARENT;
m_ulMiterLimit = 0;
m_ulFillMode = WINDING;
m_ulStretchMode = 0;
m_oWindow.Init();
m_oViewport.Init();
m_dPixelHeight = 1;
m_dPixelWidth = 1;
m_oCurPos.x = 0;
m_oCurPos.y = 0;
m_unArcDirection = AD_COUNTERCLOCKWISE;
}
CEmfDC::~CEmfDC()
{
}
CEmfDC* CEmfDC::Copy()
{
CEmfDC* pNewDC = new CEmfDC();
if (!pNewDC)
return NULL;
pNewDC->m_ulMapMode = m_ulMapMode;
pNewDC->m_pBrush = m_pBrush;
pNewDC->m_pPen = m_pPen;
pNewDC->m_pFont = m_pFont;
pNewDC->m_pPalette = m_pPalette;
pNewDC->m_oTransform.Copy(&m_oTransform);
pNewDC->m_oInverseTransform.Copy(&m_oInverseTransform);
pNewDC->m_oTextColor.Copy(&m_oTextColor);
pNewDC->m_oBgColor.Copy(&m_oBgColor);
pNewDC->m_ulTextAlign = m_ulTextAlign;
pNewDC->m_ulBgMode = m_ulBgMode;
pNewDC->m_ulMiterLimit = m_ulMiterLimit;
pNewDC->m_ulFillMode = m_ulFillMode;
pNewDC->m_ulStretchMode = m_ulStretchMode;
pNewDC->m_ulRop2Mode = m_ulRop2Mode;
pNewDC->m_dPixelHeight = m_dPixelHeight;
pNewDC->m_dPixelWidth = m_dPixelWidth;
pNewDC->m_oWindow.Copy(&m_oWindow);
pNewDC->m_oViewport.Copy(&m_oViewport);
pNewDC->m_oCurPos = m_oCurPos;
pNewDC->m_oClip = m_oClip;
pNewDC->m_unArcDirection = m_unArcDirection;
return pNewDC;
}
void CEmfDC::SetMapMode(unsigned int ulMapMode)
{
m_ulMapMode = ulMapMode;
switch (ulMapMode)
{
case MM_TEXT: // 1 unit = 1pt
{
SetPixelWidth(1);
SetPixelHeight(1);
break;
}
case MM_LOMETRIC: // 1 unit = 0.1mm
{
double dPixel = 0.1 * 72 / 25.4;
SetPixelWidth(dPixel);
SetPixelHeight(dPixel);
break;
}
case MM_HIMETRIC: // 1 unit = 0.01mm
{
double dPixel = 0.01 * 72 / 25.4;
SetPixelWidth(dPixel);
SetPixelHeight(dPixel);
break;
}
case MM_LOENGLISH: // 1 unit = 0.01 inch
{
double dPixel = 0.01 * 72;
SetPixelWidth(dPixel);
SetPixelHeight(dPixel);
break;
}
case MM_HIENGLISH: // 1 unit = 0.001 inch
{
double dPixel = 0.001 * 72;
SetPixelWidth(dPixel);
SetPixelHeight(dPixel);
break;
}
case MM_TWIPS: // 1 unit = 1/1440 inch
{
SetPixelWidth(0.05);
SetPixelHeight(0.05);
break;
}
case MM_ISOTROPIC:
case MM_ANISOTROPIC:
{
UpdatePixelMetrics();
break;
}
}
}
unsigned int CEmfDC::GetMapMode()
{
return m_ulMapMode;
}
TEmfXForm* CEmfDC::GetTransform()
{
return &m_oTransform;
}
TEmfXForm* CEmfDC::GetInverseTransform()
{
return &m_oInverseTransform;
}
void CEmfDC::MultiplyTransform(TEmfXForm& oForm, unsigned int ulMode)
{
m_oTransform.Multiply(oForm, ulMode);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TEmfXForm* pT = &m_oTransform;
double dDet = pT->M11 * pT->M22 - pT->M12 * pT->M21;
if (dDet < 0.0001 && dDet > 0.0001)
{
m_oInverseTransform.M11 = 1;
m_oInverseTransform.M12 = 0;
m_oInverseTransform.M21 = 0;
m_oInverseTransform.M22 = 1;
m_oInverseTransform.Dx = 0;
m_oInverseTransform.Dy = 0;
}
m_oInverseTransform.M11 = pT->M22 / dDet;
m_oInverseTransform.M12 = -pT->M12 / dDet;
m_oInverseTransform.M21 = -pT->M21 / dDet;
m_oInverseTransform.M22 = pT->M22 / dDet;
m_oInverseTransform.Dx = pT->Dy * pT->M21 / dDet - pT->Dx * pT->M22 / dDet;
m_oInverseTransform.Dy = pT->Dx * pT->M12 / dDet - pT->Dy * pT->M11 / dDet;
}
void CEmfDC::SetTextColor(TEmfColor& oColor)
{
m_oTextColor.Copy(&oColor);
}
TEmfColor& CEmfDC::GetTextColor()
{
return m_oTextColor;
}
void CEmfDC::SetBrush(CEmfLogBrushEx* pBrush)
{
m_pBrush = pBrush;
}
void CEmfDC::RemoveBrush(CEmfLogBrushEx* pBrush)
{
if (pBrush == m_pBrush)
m_pBrush = NULL;
}
CEmfLogBrushEx* CEmfDC::GetBrush()
{
return m_pBrush;
}
void CEmfDC::SetFont(CEmfLogFont* pFont)
{
m_pFont = pFont;
}
void CEmfDC::RemoveFont(CEmfLogFont* pFont)
{
if (pFont == m_pFont)
m_pFont = NULL;
}
CEmfLogFont* CEmfDC::GetFont()
{
return m_pFont;
}
void CEmfDC::SetTextAlign(unsigned int ulAlign)
{
m_ulTextAlign = ulAlign;
}
unsigned int CEmfDC::GetTextAlign()
{
return m_ulTextAlign;
}
void CEmfDC::SetBgMode(unsigned int ulBgMode)
{
m_ulBgMode = ulBgMode;
}
unsigned int CEmfDC::GetBgMode()
{
return m_ulBgMode;
}
void CEmfDC::SetBgColor(TEmfColor& oColor)
{
m_oBgColor.Copy(&oColor);
}
TEmfColor& CEmfDC::GetBgColor()
{
return m_oBgColor;
}
void CEmfDC::SetMiterLimit(unsigned int ulMiter)
{
m_ulMiterLimit = ulMiter;
}
unsigned int CEmfDC::GetMiterLimit()
{
return m_ulMiterLimit;
}
void CEmfDC::SetFillMode(unsigned int ulFillMode)
{
m_ulFillMode = ulFillMode;
}
unsigned int CEmfDC::GetFillMode()
{
return m_ulFillMode;
}
void CEmfDC::SetPen(CEmfLogPen* pPen)
{
m_pPen = pPen;
}
void CEmfDC::RemovePen(CEmfLogPen* pPen)
{
if (pPen == m_pPen)
m_pPen = NULL;
}
CEmfLogPen* CEmfDC::GetPen()
{
return m_pPen;
}
void CEmfDC::SetStretchMode(unsigned int& oMode)
{
m_ulStretchMode = oMode;
}
unsigned int CEmfDC::GetStretchMode()
{
return m_ulStretchMode;
}
double CEmfDC::GetPixelWidth()
{
return m_dPixelWidth;
}
double CEmfDC::GetPixelHeight()
{
return m_dPixelHeight;
}
void CEmfDC::SetPixelWidth(double dPixelW)
{
m_dPixelWidth = dPixelW;
}
void CEmfDC::SetPixelHeight(double dPixelH)
{
m_dPixelHeight = dPixelH;
}
void CEmfDC::SetWindowOrigin(TEmfPointL& oPoint)
{
m_oWindow.lX = oPoint.x;
m_oWindow.lY = oPoint.y;
UpdatePixelMetrics();
}
void CEmfDC::SetWindowExtents(TEmfSizeL& oPoint)
{
m_oWindow.ulW = oPoint.cx;
m_oWindow.ulH = oPoint.cy;
UpdatePixelMetrics();
}
TEmfWindow* CEmfDC::GetWindow()
{
return &m_oWindow;
}
void CEmfDC::SetViewportOrigin(TEmfPointL& oPoint)
{
m_oViewport.lX = oPoint.x;
m_oViewport.lY = oPoint.y;
UpdatePixelMetrics();
}
void CEmfDC::SetViewportExtents(TEmfSizeL& oPoint)
{
m_oViewport.ulW = oPoint.cx;
m_oViewport.ulH = oPoint.cy;
UpdatePixelMetrics();
}
TEmfWindow* CEmfDC::GetViewport()
{
return &m_oViewport;
}
bool CEmfDC::UpdatePixelMetrics()
{
unsigned int ulMapMode = m_ulMapMode;
if (MM_ISOTROPIC == ulMapMode)
{
if (0 == m_oWindow.ulW || 0 == m_oViewport.ulW)
return false;
double dPixel = (double)m_oViewport.ulW / (double)m_oWindow.ulW;
SetPixelHeight(dPixel);
SetPixelWidth(dPixel);
}
else if (MM_ANISOTROPIC == ulMapMode)
{
double dPixelX = (double)m_oViewport.ulW / (double)m_oWindow.ulW;
double dPixelY = (double)m_oViewport.ulH / (double)m_oWindow.ulH;
SetPixelWidth(dPixelX);
SetPixelHeight(dPixelY);
}
return true;
}
void CEmfDC::SetRop2Mode(unsigned int& nMode)
{
m_ulRop2Mode = nMode;
}
unsigned int CEmfDC::GetRop2Mode()
{
return m_ulRop2Mode;
}
void CEmfDC::SetPalette(CEmfLogPalette* pPalette)
{
m_pPalette = pPalette;
}
void CEmfDC::RemovePalette(CEmfLogPalette* pPalette)
{
if (m_pPalette == pPalette)
m_pPalette = NULL;
}
CEmfLogPalette* CEmfDC::GetPalette()
{
return m_pPalette;
}
void CEmfDC::SetCurPos(TEmfPointL& oPoint)
{
SetCurPos(oPoint.x, oPoint.y);
}
void CEmfDC::SetCurPos(int lX, int lY)
{
m_oCurPos.x = lX;
m_oCurPos.y = lY;
}
TEmfPointL& CEmfDC::GetCurPos()
{
return m_oCurPos;
}
CEmfClip* CEmfDC::GetClip()
{
return &m_oClip;
}
void CEmfDC::ClipToPath(CEmfPath* pPath, unsigned int unMode)
{
m_oClip.SetPath(pPath, unMode);
}
void CEmfDC::SetArcDirection(unsigned int unDirection)
{
m_unArcDirection = unDirection;
}
unsigned int CEmfDC::GetArcDirection()
{
return m_unArcDirection;
}
}