mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 14:00:32 +08:00
718 lines
18 KiB
C++
718 lines
18 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 "WmfPlayer.h"
|
|
#include "WmfFile.h"
|
|
|
|
#include "WmfParser/CWmfParserBase.h"
|
|
|
|
namespace MetaFile
|
|
{
|
|
CWmfPlayer::CWmfPlayer(CWmfParserBase* pFile) : m_pParser(pFile)
|
|
{
|
|
CWmfDC* pDC = new CWmfDC();
|
|
if (!pDC)
|
|
{
|
|
m_pParser->SetError();
|
|
return;
|
|
}
|
|
|
|
m_pDC = pDC;
|
|
m_vDCStack.push_back(pDC);
|
|
m_ushIndex = 0;
|
|
};
|
|
CWmfPlayer::~CWmfPlayer()
|
|
{
|
|
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
|
|
{
|
|
CWmfDC* pDC = m_vDCStack.at(nIndex);
|
|
delete pDC;
|
|
}
|
|
m_vDCStack.clear();
|
|
|
|
for (CWmfObjectMap::iterator oIterator = m_mObjects.begin(); oIterator != m_mObjects.end(); oIterator++)
|
|
{
|
|
CWmfObjectBase* pOldObject = oIterator->second;
|
|
delete pOldObject;
|
|
}
|
|
m_mObjects.clear();
|
|
}
|
|
void CWmfPlayer::Clear()
|
|
{
|
|
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
|
|
{
|
|
CWmfDC* pDC = m_vDCStack.at(nIndex);
|
|
delete pDC;
|
|
}
|
|
m_vDCStack.clear();
|
|
|
|
for (CWmfObjectMap::iterator oIterator = m_mObjects.begin(); oIterator != m_mObjects.end(); oIterator++)
|
|
{
|
|
CWmfObjectBase* pOldObject = oIterator->second;
|
|
delete pOldObject;
|
|
}
|
|
m_mObjects.clear();
|
|
|
|
CWmfDC* pDC = new CWmfDC();
|
|
if (!pDC)
|
|
{
|
|
m_pParser->SetError();
|
|
return;
|
|
}
|
|
|
|
m_pDC = pDC;
|
|
m_vDCStack.push_back(pDC);
|
|
m_ushIndex = 0;
|
|
m_vAvailableIndexes.clear();
|
|
}
|
|
CWmfDC* CWmfPlayer::SaveDC()
|
|
{
|
|
if (!m_pDC)
|
|
{
|
|
m_pParser->SetError();
|
|
return NULL;
|
|
}
|
|
|
|
CWmfDC* pNewDC = m_pDC->Copy();
|
|
if (!pNewDC)
|
|
{
|
|
m_pParser->SetError();
|
|
return NULL;
|
|
}
|
|
|
|
m_vDCStack.push_back(pNewDC);
|
|
m_pDC = pNewDC;
|
|
return pNewDC;
|
|
}
|
|
CWmfDC* CWmfPlayer::RestoreDC()
|
|
{
|
|
if (m_vDCStack.size() <= 1)
|
|
{
|
|
m_pParser->SetError();
|
|
return m_pDC;
|
|
}
|
|
|
|
CWmfDC* 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;
|
|
}
|
|
CWmfDC* CWmfPlayer::GetDC()
|
|
{
|
|
return m_pDC;
|
|
}
|
|
void CWmfPlayer::RegisterObject(CWmfObjectBase* pObject)
|
|
{
|
|
// Найдем наименьший доступный индекс
|
|
unsigned short ushIndex = m_ushIndex;
|
|
int nAvailableIndex = -1;
|
|
if (m_vAvailableIndexes.size() > 0)
|
|
{
|
|
for (std::size_t nIterator = 0; nIterator != m_vAvailableIndexes.size(); ++nIterator)
|
|
{
|
|
if (ushIndex > m_vAvailableIndexes[nIterator])
|
|
{
|
|
ushIndex = m_vAvailableIndexes[nIterator];
|
|
nAvailableIndex = (int)nIterator;
|
|
}
|
|
}
|
|
}
|
|
|
|
CWmfObjectMap::const_iterator oPos = m_mObjects.find(ushIndex);
|
|
|
|
if (m_mObjects.end() != oPos)
|
|
DeleteObject(ushIndex);
|
|
|
|
m_mObjects.insert(std::pair<unsigned int, CWmfObjectBase*>(ushIndex, pObject));
|
|
|
|
if (-1 != nAvailableIndex)
|
|
m_vAvailableIndexes.erase(m_vAvailableIndexes.begin() + nAvailableIndex);
|
|
|
|
if (ushIndex == m_ushIndex)
|
|
m_ushIndex++;
|
|
}
|
|
void CWmfPlayer::SelectObject(unsigned short ushIndex)
|
|
{
|
|
CWmfObjectMap::const_iterator oPos = m_mObjects.find(ushIndex);
|
|
if (m_mObjects.end() != oPos)
|
|
{
|
|
CWmfObjectBase* pObject = oPos->second;
|
|
|
|
switch (pObject->GetType())
|
|
{
|
|
case WMF_OBJECT_BRUSH: m_pDC->SetBrush((CWmfBrush*)pObject); break;
|
|
case WMF_OBJECT_FONT: m_pDC->SetFont((CWmfFont*)pObject); break;
|
|
case WMF_OBJECT_PEN: m_pDC->SetPen((CWmfPen*)pObject); break;
|
|
case WMF_OBJECT_PALETTE: m_pDC->SetPalette((CWmfPalette*)pObject); break;
|
|
case WMF_OBJECT_REGION: m_pDC->SetRegion((CWmfRegion*)pObject); break;
|
|
case WMF_OBJECT_UNKNOWN:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
void CWmfPlayer::SelectPalette(unsigned short ushIndex)
|
|
{
|
|
CWmfObjectMap::const_iterator oPos = m_mObjects.find(ushIndex);
|
|
if (m_mObjects.end() != oPos)
|
|
{
|
|
CWmfObjectBase* pObject = oPos->second;
|
|
if (WMF_OBJECT_PALETTE == pObject->GetType())
|
|
m_pDC->SetPalette((CWmfPalette*)pObject);
|
|
}
|
|
}
|
|
void CWmfPlayer::DeleteObject(unsigned short ushIndex)
|
|
{
|
|
CWmfObjectMap::const_iterator oPos = m_mObjects.find(ushIndex);
|
|
if (m_mObjects.end() != oPos)
|
|
{
|
|
CWmfObjectBase* pObject = oPos->second;
|
|
|
|
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
|
|
{
|
|
CWmfDC* pDC = m_vDCStack.at(nIndex);
|
|
|
|
switch (pObject->GetType())
|
|
{
|
|
case WMF_OBJECT_BRUSH: pDC->RemoveBrush((CWmfBrush*)pObject); break;
|
|
case WMF_OBJECT_FONT: pDC->RemoveFont((CWmfFont*)pObject); break;
|
|
case WMF_OBJECT_PEN: pDC->RemovePen((CWmfPen*)pObject); break;
|
|
case WMF_OBJECT_PALETTE: pDC->RemovePalette((CWmfPalette*)pObject); break;
|
|
case WMF_OBJECT_REGION: pDC->RemoveRegion((CWmfRegion*)pObject); break;
|
|
case WMF_OBJECT_UNKNOWN:
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete pObject;
|
|
m_mObjects.erase(ushIndex);
|
|
}
|
|
|
|
if (ushIndex < m_ushIndex)
|
|
{
|
|
if (std::find(m_vAvailableIndexes.begin(), m_vAvailableIndexes.end(), ushIndex) != m_vAvailableIndexes.end())
|
|
{
|
|
// Данный индекс уже есть в списке доступных
|
|
}
|
|
else
|
|
{
|
|
m_vAvailableIndexes.push_back(ushIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
CWmfDC::CWmfDC()
|
|
{
|
|
m_pBrush = &m_oDefaultBrush;
|
|
m_pPen = &m_oDefaultPen;
|
|
m_pFont = &m_oDefaultFont;
|
|
m_pPalette = NULL;
|
|
m_pRegion = NULL;
|
|
m_ushMapMode = MM_TEXT;
|
|
m_dPixelWidth = 1;
|
|
m_dPixelHeight = 1;
|
|
m_oWindow.Init();
|
|
m_oViewport.Init();
|
|
m_oTextColor.Set(0, 0, 0);
|
|
m_oTextBgColor.Set(255, 255, 255);
|
|
m_oCurPos = {0, 0};
|
|
m_ushTextBgMode = OPAQUE;
|
|
m_ushLayout = LAYOUT_LTR;
|
|
m_ushPolyFillMode = ALTERNATE;
|
|
m_ushRop2Mode = R2_COPYPEN;
|
|
m_ushStretchBltMode = COLORONCOLOR;
|
|
m_ushTextAlign = TA_TOP | TA_LEFT | TA_NOUPDATECP;
|
|
m_ushCharSpacing = 0;
|
|
m_oTransform.Init();
|
|
m_oFinalTransform.Init();
|
|
m_oFinalTransform2.Init();
|
|
}
|
|
CWmfDC::~CWmfDC()
|
|
{
|
|
|
|
}
|
|
CWmfDC* CWmfDC::Copy() const
|
|
{
|
|
CWmfDC* pNewDC = new CWmfDC();
|
|
if (!pNewDC)
|
|
return NULL;
|
|
|
|
pNewDC->m_oClip.Copy(m_oClip);
|
|
pNewDC->m_pBrush = (m_pBrush == &m_oDefaultBrush ? &pNewDC->m_oDefaultBrush : m_pBrush);
|
|
pNewDC->m_pPen = (m_pPen == &m_oDefaultPen ? &pNewDC->m_oDefaultPen : m_pPen);
|
|
pNewDC->m_pPalette = m_pPalette;
|
|
pNewDC->m_pFont = m_pFont;
|
|
pNewDC->m_pRegion = m_pRegion;
|
|
pNewDC->m_ushMapMode = m_ushMapMode;
|
|
pNewDC->m_dPixelWidth = m_dPixelWidth;
|
|
pNewDC->m_dPixelHeight = m_dPixelHeight;
|
|
pNewDC->m_oWindow.Copy(m_oWindow);
|
|
pNewDC->m_oViewport.Copy(m_oViewport);
|
|
pNewDC->m_oTextColor = m_oTextColor;
|
|
pNewDC->m_oTextBgColor = m_oTextBgColor;
|
|
pNewDC->m_oCurPos = m_oCurPos;
|
|
pNewDC->m_ushTextBgMode = m_ushTextBgMode;
|
|
pNewDC->m_ushLayout = m_ushLayout;
|
|
pNewDC->m_ushPolyFillMode = m_ushPolyFillMode;
|
|
pNewDC->m_ushRop2Mode = m_ushRop2Mode;
|
|
pNewDC->m_ushStretchBltMode = m_ushStretchBltMode;
|
|
pNewDC->m_ushTextAlign = m_ushTextAlign;
|
|
pNewDC->m_ushCharSpacing = m_ushCharSpacing;
|
|
pNewDC->m_oTransform.Init();
|
|
pNewDC->m_oFinalTransform.Copy(&m_oFinalTransform);
|
|
pNewDC->m_oFinalTransform2.Copy(&m_oFinalTransform2);
|
|
|
|
return pNewDC;
|
|
}
|
|
|
|
CClip* CWmfDC::GetClip()
|
|
{
|
|
return &m_oClip;
|
|
}
|
|
void CWmfDC::SetBrush(CWmfBrush* pBrush)
|
|
{
|
|
m_pBrush = pBrush;
|
|
}
|
|
void CWmfDC::RemoveBrush(CWmfBrush* pBrush)
|
|
{
|
|
if (pBrush == m_pBrush)
|
|
m_pBrush = NULL;
|
|
}
|
|
const CWmfBrush* CWmfDC::GetBrush() const
|
|
{
|
|
return m_pBrush;
|
|
}
|
|
void CWmfDC::SetPen(CWmfPen* pPen)
|
|
{
|
|
m_pPen = pPen;
|
|
}
|
|
void CWmfDC::RemovePen(CWmfPen* pPen)
|
|
{
|
|
if (m_pPen == pPen)
|
|
m_pPen = NULL;
|
|
}
|
|
const CWmfPen* CWmfDC::GetPen() const
|
|
{
|
|
return m_pPen;
|
|
}
|
|
void CWmfDC::SetPalette(CWmfPalette* pPalette)
|
|
{
|
|
m_pPalette = pPalette;
|
|
}
|
|
void CWmfDC::RemovePalette(CWmfPalette* pPalette)
|
|
{
|
|
if (m_pPalette == pPalette)
|
|
m_pPalette = NULL;
|
|
}
|
|
const CWmfPalette* CWmfDC::GetPalette() const
|
|
{
|
|
return m_pPalette;
|
|
}
|
|
void CWmfDC::SetFont(CWmfFont* pFont)
|
|
{
|
|
m_pFont = pFont;
|
|
}
|
|
void CWmfDC::RemoveFont(CWmfFont* pFont)
|
|
{
|
|
if (m_pFont == pFont)
|
|
m_pFont = NULL;
|
|
}
|
|
const CWmfFont* CWmfDC::GetFont() const
|
|
{
|
|
return (NULL != m_pFont) ? m_pFont : &m_oDefaultFont;
|
|
}
|
|
void CWmfDC::SetRegion(CWmfRegion* pRegion)
|
|
{
|
|
m_pRegion = pRegion;
|
|
}
|
|
void CWmfDC::RemoveRegion(CWmfRegion* pRegion)
|
|
{
|
|
if (m_pRegion == pRegion)
|
|
m_pRegion = NULL;
|
|
}
|
|
const CWmfRegion* CWmfDC::GetRegion() const
|
|
{
|
|
return m_pRegion;
|
|
}
|
|
void CWmfDC::SetMapMode(unsigned short ushMapMode)
|
|
{
|
|
m_ushMapMode = ushMapMode;
|
|
|
|
switch (m_ushMapMode)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
UpdateFinalTransform();
|
|
}
|
|
unsigned int CWmfDC::GetMapMode() const
|
|
{
|
|
return m_ushMapMode;
|
|
}
|
|
double CWmfDC::GetPixelWidth() const
|
|
{
|
|
return m_dPixelWidth;
|
|
}
|
|
double CWmfDC::GetPixelHeight() const
|
|
{
|
|
return m_dPixelHeight;
|
|
}
|
|
void CWmfDC::SetPixelWidth(double dW)
|
|
{
|
|
m_dPixelWidth = dW;
|
|
}
|
|
void CWmfDC::SetPixelHeight(double dH)
|
|
{
|
|
m_dPixelHeight = dH;
|
|
}
|
|
const TWmfWindow& CWmfDC::GetWindow() const
|
|
{
|
|
return m_oWindow;
|
|
}
|
|
void CWmfDC::SetWindowOrg(short shX, short shY)
|
|
{
|
|
m_oWindow.x = shX;
|
|
m_oWindow.y = shY;
|
|
m_oWindow.bUnchangedOrg = false;
|
|
|
|
if (m_oViewport.bUnchangedOrg)
|
|
{
|
|
m_oViewport.x = shX;
|
|
m_oViewport.y = shY;
|
|
}
|
|
|
|
UpdateFinalTransform();
|
|
}
|
|
void CWmfDC::SetWindowExt(short shW, short shH)
|
|
{
|
|
m_oWindow.w = shW;
|
|
m_oWindow.h = shH;
|
|
m_oWindow.bUnchangedExt = false;
|
|
|
|
if (m_oViewport.bUnchangedExt)
|
|
{
|
|
m_oViewport.w = std::abs(shW);
|
|
m_oViewport.h = std::abs(shH);
|
|
}
|
|
|
|
if (MM_ISOTROPIC == m_ushMapMode)
|
|
FixIsotropic();
|
|
|
|
UpdatePixelMetrics();
|
|
UpdateFinalTransform();
|
|
}
|
|
void CWmfDC::SetWindowOff(short shX, short shY)
|
|
{
|
|
m_oWindow.x += shX;
|
|
m_oWindow.y += shY;
|
|
UpdateFinalTransform();
|
|
}
|
|
void CWmfDC::SetWindowScale(double dX, double dY)
|
|
{
|
|
m_oWindow.w = (short)(m_oWindow.w * dX);
|
|
m_oWindow.h = (short)(m_oWindow.h * dY);
|
|
UpdatePixelMetrics();
|
|
UpdateFinalTransform();
|
|
}
|
|
const TWmfWindow& CWmfDC::GetViewport() const
|
|
{
|
|
return m_oViewport;
|
|
}
|
|
void CWmfDC::SetViewportOrg(short shX, short shY)
|
|
{
|
|
m_oViewport.x = shX;
|
|
m_oViewport.y = shY;
|
|
m_oViewport.bUnchangedOrg = false;
|
|
|
|
if (m_oWindow.bUnchangedOrg)
|
|
{
|
|
m_oWindow.x = shX;
|
|
m_oWindow.y = shY;
|
|
}
|
|
|
|
UpdateFinalTransform();
|
|
}
|
|
void CWmfDC::SetViewportExt(short shW, short shH)
|
|
{
|
|
m_oViewport.w = shW;
|
|
m_oViewport.h = shH;
|
|
m_oViewport.bUnchangedExt = false;
|
|
|
|
if (m_oWindow.bUnchangedExt)
|
|
{
|
|
m_oWindow.w = shW;
|
|
m_oWindow.h = shH;
|
|
}
|
|
|
|
if (MM_ISOTROPIC == m_ushMapMode)
|
|
FixIsotropic();
|
|
|
|
UpdatePixelMetrics();
|
|
UpdateFinalTransform();
|
|
}
|
|
void CWmfDC::SetViewportOff(short shX, short shY)
|
|
{
|
|
m_oViewport.x += shX;
|
|
m_oViewport.y += shY;
|
|
// UpdatePixelMetrics();
|
|
UpdateFinalTransform();
|
|
}
|
|
void CWmfDC::SetViewportScale(double dX, double dY)
|
|
{
|
|
m_oViewport.w = (short)(m_oViewport.w * dX);
|
|
m_oViewport.h = (short)(m_oViewport.h * dY);
|
|
UpdatePixelMetrics();
|
|
UpdateFinalTransform();
|
|
}
|
|
bool CWmfDC::UpdatePixelMetrics()
|
|
{
|
|
if (1 >= std::abs(m_oWindow.w) || 1 >= std::abs(m_oViewport.w))
|
|
return false;
|
|
|
|
unsigned short ushMapMode = m_ushMapMode;
|
|
if (MM_ISOTROPIC == ushMapMode)
|
|
{
|
|
if (0 == m_oWindow.w || 0 == m_oViewport.w)
|
|
return false;
|
|
|
|
double dPixel = (double)m_oViewport.w / (double)m_oWindow.w;
|
|
SetPixelHeight(dPixel);
|
|
SetPixelWidth(dPixel);
|
|
}
|
|
else if (MM_ANISOTROPIC == ushMapMode)
|
|
{
|
|
double dPixelX = (double)m_oViewport.w / (double)m_oWindow.w;
|
|
double dPixelY = (double)m_oViewport.h / (double)m_oWindow.h;
|
|
|
|
SetPixelWidth(dPixelX);
|
|
SetPixelHeight(dPixelY);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
void CWmfDC::UpdateFinalTransform()
|
|
{
|
|
const TWmfWindow& oWindow{GetWindow()};
|
|
const TWmfWindow& oViewPort{GetViewport()};
|
|
|
|
double dM11 = ((oViewPort.w >= 0) ? 1. : -1.) * GetPixelWidth();
|
|
double dM22 = ((oViewPort.h >= 0) ? 1. : -1.) * GetPixelHeight();
|
|
|
|
TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.x * dM11), -(oWindow.y * dM22));
|
|
TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.x, oViewPort.y);
|
|
|
|
m_oFinalTransform.Init();
|
|
m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
|
m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
|
m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
|
|
|
m_oFinalTransform2.Init();
|
|
m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
|
m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
|
m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
|
}
|
|
|
|
void CWmfDC::FixIsotropic()
|
|
{
|
|
if (m_oViewport.w == m_oWindow.w && m_oViewport.h == m_oWindow.h)
|
|
return;
|
|
|
|
double dXDim = std::fabs((double)m_oViewport.w / m_oWindow.w);
|
|
double dYDim = std::fabs((double)m_oViewport.h / m_oWindow.h);
|
|
|
|
if (dXDim > dYDim)
|
|
{
|
|
int nMinCx = (m_oViewport.w >= 0) ? 1 : -1;
|
|
m_oViewport.w = std::floor(m_oViewport.w * dYDim / dXDim + 0.5);
|
|
if (!m_oViewport.w) m_oViewport.w = nMinCx;
|
|
}
|
|
else
|
|
{
|
|
int nMinCy = (m_oViewport.h >= 0) ? 1 : -1;
|
|
m_oViewport.h = std::floor(m_oViewport.h * dXDim / dYDim + 0.5);
|
|
if (!m_oViewport.h) m_oViewport.h = nMinCy;
|
|
}
|
|
}
|
|
|
|
void CWmfDC::SetTextColor(TRGBA& oColor)
|
|
{
|
|
m_oTextColor = oColor;
|
|
}
|
|
const TRGBA& CWmfDC::GetTextColor() const
|
|
{
|
|
return m_oTextColor;
|
|
}
|
|
void CWmfDC::SetTextBgColor(TRGBA& oColor)
|
|
{
|
|
m_oTextBgColor = oColor;
|
|
}
|
|
const TRGBA& CWmfDC::GetTextBgColor() const
|
|
{
|
|
return m_oTextBgColor;
|
|
}
|
|
const TPointS& CWmfDC::GetCurPos() const
|
|
{
|
|
return m_oCurPos;
|
|
}
|
|
void CWmfDC::SetCurPos(TPointS& oPoint)
|
|
{
|
|
m_oCurPos = oPoint;
|
|
}
|
|
void CWmfDC::SetCurPos(short shX, short shY)
|
|
{
|
|
m_oCurPos.X = shX;
|
|
m_oCurPos.Y = shY;
|
|
}
|
|
void CWmfDC::SetTextBgMode(unsigned short ushMode)
|
|
{
|
|
m_ushTextBgMode = ushMode;
|
|
}
|
|
unsigned short CWmfDC::GetTextBgMode() const
|
|
{
|
|
return m_ushTextBgMode;
|
|
}
|
|
void CWmfDC::SetLayout(unsigned short ushLayout)
|
|
{
|
|
m_ushLayout = ushLayout;
|
|
}
|
|
unsigned short CWmfDC::GetLayout() const
|
|
{
|
|
return m_ushLayout;
|
|
}
|
|
void CWmfDC::SetPolyFillMode(unsigned short ushMode)
|
|
{
|
|
m_ushPolyFillMode = ushMode;
|
|
}
|
|
unsigned short CWmfDC::GetPolyFillMode() const
|
|
{
|
|
return m_ushPolyFillMode;
|
|
}
|
|
void CWmfDC::SetRop2Mode(unsigned short ushMode)
|
|
{
|
|
m_ushRop2Mode = ushMode;
|
|
}
|
|
unsigned short CWmfDC::GetRop2Mode() const
|
|
{
|
|
return m_ushRop2Mode;
|
|
}
|
|
void CWmfDC::SetStretchBltMode(unsigned short ushMode)
|
|
{
|
|
m_ushStretchBltMode = ushMode;
|
|
}
|
|
unsigned short CWmfDC::GetStretchBltMode() const
|
|
{
|
|
return m_ushStretchBltMode;
|
|
}
|
|
void CWmfDC::SetTextAlign(unsigned short ushTextAlign)
|
|
{
|
|
m_ushTextAlign = ushTextAlign;
|
|
}
|
|
unsigned short CWmfDC::GetTextAlign() const
|
|
{
|
|
return m_ushTextAlign;
|
|
}
|
|
void CWmfDC::SetCharSpacing(unsigned short ushCharSpacing)
|
|
{
|
|
m_ushCharSpacing = ushCharSpacing;
|
|
}
|
|
unsigned short CWmfDC::GetCharSpacing() const
|
|
{
|
|
return m_ushCharSpacing;
|
|
}
|
|
const TXForm& CWmfDC::GetTransform() const
|
|
{
|
|
return m_oTransform;
|
|
}
|
|
const TXForm& CWmfDC::GetInverseTransform() const
|
|
{
|
|
return m_oTransform;
|
|
}
|
|
const TXForm& CWmfDC::GetFinalTransform(int iGraphicsMode) const
|
|
{
|
|
if (GM_COMPATIBLE == iGraphicsMode)
|
|
return m_oFinalTransform2;
|
|
|
|
return m_oFinalTransform;
|
|
}
|
|
unsigned int CWmfDC::GetMiterLimit() const
|
|
{
|
|
return 0;
|
|
}
|
|
}
|