This commit is contained in:
Kirill Polyakov
2024-01-11 18:18:27 +03:00
parent 1a8ada7858
commit 69595f9211
9 changed files with 172 additions and 313 deletions

View File

@ -44,7 +44,7 @@
#define DIB_RGB_COLORS 0x00
#endif
#define MINACCURACY 2
#define MINACCURACY 3
#define MAXACCURACY 10
namespace MetaFile
@ -1066,57 +1066,51 @@ namespace MetaFile
#endif
}
static int GetMinAccuracy(double dValue)
{
if (dValue == (int)dValue)
return 0;
if (dValue < 0.)
dValue = -dValue;
if (dValue > 1.)
return MINACCURACY;
unsigned int unAccuracy = 0;
while (unAccuracy < MAXACCURACY)
{
dValue *= 10;
if (dValue >= 1.)
break;
++unAccuracy;
}
if (MAXACCURACY == unAccuracy)
return 0;
else
return unAccuracy + 3;
}
std::wstring ConvertToWString(double dValue, int nAccuracy)
{
int nNewAccuracy = (-1 < nAccuracy) ? nAccuracy : GetMinAccuracy(dValue);
const double dAbsValue {std::abs(dValue)};
const double dRemainder{dAbsValue - std::floor(dAbsValue)};
if (0 == nNewAccuracy)
return std::to_wstring((int)dValue);
if (Equals(0., dRemainder))
return std::to_wstring(static_cast<int>(dValue));
if (nAccuracy < 0)
{
if (dAbsValue < 1.)
nAccuracy = MAXACCURACY;
else
nAccuracy = MINACCURACY;
}
std::wstringstream owsStream;
owsStream << std::fixed << std::setprecision(nNewAccuracy) << dValue;
owsStream << std::fixed << std::setprecision(nAccuracy) << dValue;
return owsStream.str();
std::wstring wsValue{owsStream.str()};
const size_t unDotPosition{wsValue.find_first_of(L'.')};
if (std::wstring::npos == unDotPosition)
return wsValue;
const size_t unFirstPosition{wsValue.find_first_not_of(L'0', unDotPosition + 1)};
if (std::wstring::npos == unFirstPosition)
return wsValue.substr(0, unDotPosition);
const size_t unLastPosition = wsValue.find_last_not_of(L'0', unFirstPosition + 2);
return wsValue.substr(0, unLastPosition + 1);
}
std::wstring ConvertToWString(const std::vector<double>& arValues, int nAccuracy)
{
std::wstringstream owsStream;
std::wstring wsValue;
for (double dValue : arValues)
owsStream << std::fixed << std::setprecision((-1 != nAccuracy) ? nAccuracy : GetMinAccuracy(dValue)) << dValue << L" ";
wsValue += ConvertToWString(dValue, nAccuracy) + L' ';
owsStream.seekp(-1, std::ios_base::end);
wsValue.pop_back();
return owsStream.str();
return wsValue;
}
}

View File

@ -249,13 +249,6 @@ namespace MetaFile
m_oStream.SetStream(pBuf, unSize);
}
void CEmfParser::SetInterpretator(IOutputDevice* pOutput)
{
CEmfParserBase::SetInterpretator(pOutput);
if (m_pEmfPlusParser)
RELEASEOBJECT(m_pEmfPlusParser);
}
bool CEmfParser::ReadImage(unsigned int offBmi, unsigned int cbBmi, unsigned int offBits, unsigned int cbBits, unsigned int ulSkip, BYTE **ppBgraBuffer, unsigned int *pulWidth, unsigned int *pulHeight)
{
int lHeaderOffset = offBmi - ulSkip;
@ -1542,11 +1535,14 @@ namespace MetaFile
TRectD oWmfRect = oWmfParser.GetBounds();
TRectL *pCurentRect = GetBounds();
double dScaleX = std::abs((pCurentRect->Right - pCurentRect->Left) / (oWmfRect.Right - oWmfRect.Left));
double dScaleY = std::abs((pCurentRect->Bottom - pCurentRect->Top) / (oWmfRect.Bottom - oWmfRect.Top));
const double dScaleX = std::abs((pCurentRect->Right - pCurentRect->Left) / (oWmfRect.Right - oWmfRect.Left));
const double dScaleY = std::abs((pCurentRect->Bottom - pCurentRect->Top) / (oWmfRect.Bottom - oWmfRect.Top));
pXmlWriter->WriteNodeBegin(L"g", true);
pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dScaleX) + L',' + ConvertToWString(dScaleY) + L')');
if (!Equals(1., dScaleX) || !Equals(1., dScaleY))
pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dScaleX) + L',' + ConvertToWString(dScaleY) + L')');
pXmlWriter->WriteNodeEnd(L"g", true, false);
((CWmfInterpretatorSvg*)oWmfParser.GetInterpretator())->SetXmlWriter(pXmlWriter);

View File

@ -20,12 +20,9 @@ namespace MetaFile
void ClearFile() override;
EmfParserType GetType() override;
EmfParserType GetType() override;
void SetStream(BYTE* pBuf, unsigned int unSize);
public:
virtual void SetInterpretator(IOutputDevice* pOutput) override;
private:
CEmfPlusParser *m_pEmfPlusParser;

View File

@ -86,7 +86,7 @@ namespace MetaFile
bool IsViewportFlippedY();
bool IsViewportFlippedX();
virtual void SetInterpretator(IOutputDevice* pOutput);
void SetInterpretator(IOutputDevice* pOutput);
void SetInterpretator(const wchar_t *wsFilePath, InterpretatorType oInterpretatorType, unsigned int unWidth = 0, unsigned int unHeight = 0);
void SetInterpretator(IOutputDevice* pOutput, const wchar_t *wsFilePath);
void SetInterpretator(InterpretatorType oInterpretatorType, double dWidth = 0, double dHeight = 0);

View File

@ -86,9 +86,10 @@
#include "../../../BgraFrame.h"
#define MAX_PICTURE_SIZE 2000.
namespace MetaFile
{
static std::map<unsigned short, std::wstring> ActionNamesEmfPlus =
{ static std::map<unsigned short, std::wstring> ActionNamesEmfPlus =
{
{0x4035, L"EMRPLUS_OFFSETCLIP"},
{0x4031, L"EMRPLUS_RESETCLIP"},
@ -1410,11 +1411,10 @@ namespace MetaFile
{
for (ULONG ulPosX = nBeginX * 4; ulPosX < nEndX * 4; ulPosX += 4)
{
pNewBuffer[ulPos + 0] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 0];
pNewBuffer[ulPos + 1] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 1];
pNewBuffer[ulPos + 2] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 2];
pNewBuffer[ulPos + 3] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 3];
ulPos += 4;
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 0];
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 1];
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 2];
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 3];
}
}
@ -1481,279 +1481,147 @@ namespace MetaFile
}
else if (ImageDataTypeMetafile == pImage->GetImageDataType())
{
DrawMetafile(pBuffer, unSizeBuffer, oSrcRect, arPoints, pImage->GetMetafileType(), unImageAttributeIndex);
switch ((int)pImage->GetMetafileType())
{
case MetafileDataTypeEmf:
case MetafileDataTypeEmfPlusOnly:
case MetafileDataTypeEmfPlusDual:
return DrawMetafile<CEmfParser>(pBuffer, unSizeBuffer, oSrcRect, arPoints);
case MetafileDataTypeWmf:
case MetafileDataTypeWmfPlaceable:
return DrawMetafile<CWmfParser>(pBuffer, unSizeBuffer, oSrcRect, arPoints);
}
}
}
}
void CEmfPlusParser::DrawMetafile(BYTE *pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector<TEmfPlusPointF>& arPoints, EEmfPlusMetafileDataType eMetafileType, unsigned int unImageAttributeIndex)
template<typename MetafileType>
void CEmfPlusParser::DrawMetafile(BYTE *pBuffer, unsigned int unSize, const TEmfPlusRectF &oSrcRect, const std::vector<TEmfPlusPointF> &arPoints)
{
if (NULL == pBuffer || 0 == unSize || MetafileDataTypeUnknown == eMetafileType)
if (NULL == pBuffer || 0 == unSize || 3 != arPoints.size())
return;
if (MetafileDataTypeEmf == eMetafileType ||
MetafileDataTypeEmfPlusOnly == eMetafileType ||
MetafileDataTypeEmfPlusDual == eMetafileType)
MetafileType oParser;
oParser.SetStream(pBuffer, unSize);
oParser.SetFontManager(GetFontManager());
oParser.Scan();
if (oParser.CheckError())
return;
const TRectL* pFileBounds = oParser.GetDCBounds();
const double dFileWidth = std::abs(pFileBounds->Right - pFileBounds->Left);
const double dFileHeight = std::abs(pFileBounds->Bottom - pFileBounds->Top);
const TRectL* pParentBounds = GetDCBounds();
const double dParentWidth = std::abs(pParentBounds->Right - pParentBounds->Left);
const double dParentHeight = std::abs(pParentBounds->Bottom - pParentBounds->Top);
if (InterpretatorType::Render == m_pInterpretator->GetType())
{
CEmfParser oEmfParser;
oEmfParser.SetStream(pBuffer, unSize);
oEmfParser.SetFontManager(GetFontManager());
oEmfParser.Scan();
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
if (!oEmfParser.CheckError() && InterpretatorType::Render == m_pInterpretator->GetType())
{
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
pGrRenderer->SetFontManager(GetFontManager());
pGrRenderer->SetFontManager(GetFontManager());
double dScale = ((CEmfInterpretatorRender*)m_pInterpretator)->GetRenderer()->GetWidth() * 96. / 25.4 / dParentWidth;
TRectL *pEmfBounds = oEmfParser.GetBounds();
const double dMaxWidth = std::max(MAX_PICTURE_SIZE, dParentWidth);
const double dMaxHeight = std::max(MAX_PICTURE_SIZE, dParentHeight);
CMetaFileRenderer* pMetaFileRenderer = (CMetaFileRenderer*)(((CEmfInterpretatorRender*)m_pInterpretator)->GetRenderer());
if (dFileWidth > dMaxWidth || dFileHeight > dMaxHeight)
dScale *= std::min(dMaxWidth / dFileWidth, dMaxHeight / dFileHeight);
const double dKoef = 96. / 25.4;
const int nWidth = dFileWidth * dScale;
const int nHeight = dFileHeight * dScale;
const int nParentWidth = pMetaFileRenderer->GetWidth() * dKoef;
const int nParentHeight = pMetaFileRenderer->GetHeight() * dKoef;
BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4];
int nWidth = abs(pEmfBounds->Right - pEmfBounds->Left) * pMetaFileRenderer->GetScaleX();
int nHeight = abs(pEmfBounds->Bottom - pEmfBounds->Top) * pMetaFileRenderer->GetScaleY();
if (!pBgraData)
return;
double dScale = 1.;
unsigned int alfa = 0xffffff;
//дефолтный тон должен быть прозрачным, а не белым
//memset(pBgraData, 0x00, nWidth * nHeight * 4);
for (int i = 0; i < nWidth * nHeight; i++)
((unsigned int*)pBgraData)[i] = alfa;
if (nWidth > nParentWidth || nHeight > nParentHeight)
{
dScale = std::min((double)nParentWidth / (double)nWidth, (double)nParentHeight / (double)nHeight);
const double dWidth = nWidth * 25.4 / 96;
const double dHeight = nHeight * 25.4 / 96;
nWidth *= dScale;
nHeight *= dScale;
}
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(4 * nWidth);
BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4];
pGrRenderer->CreateFromBgraFrame(&oFrame);
pGrRenderer->SetSwapRGB(false);
pGrRenderer->put_Width(dWidth);
pGrRenderer->put_Height(dHeight);
if (!pBgraData)
return;
pGrRenderer->BeginCommand(c_nImageType);
unsigned int alfa = 0xffffff;
//дефолтный тон должен быть прозрачным, а не белым
// memset(pBgraData, 0x00, nWidth * nHeight * 4);
for (int i = 0; i < nWidth * nHeight; i++)
{
((unsigned int*)pBgraData)[i] = alfa;
}
CMetaFileRenderer oEmfOut(&oParser, pGrRenderer, 0, 0, dWidth, dHeight);
oParser.SetInterpretator(&oEmfOut);
double dWidth = nWidth / dKoef;
double dHeight = nWidth / dKoef;
oParser.PlayFile();
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(4 * nWidth);
pGrRenderer->EndCommand(c_nImageType);
pGrRenderer->CreateFromBgraFrame(&oFrame);
pGrRenderer->SetSwapRGB(false);
pGrRenderer->put_Width(dWidth);
pGrRenderer->put_Height(dHeight);
BYTE* pPixels = oFrame.get_Data();
pGrRenderer->BeginCommand(c_nImageType);
TRectL oClipRect;
CMetaFileRenderer oEmfOut(&oEmfParser, pGrRenderer, 0, 0, dWidth, dHeight);
oEmfParser.SetInterpretator(&oEmfOut);
oClipRect.Left = oSrcRect.dX * dScale;
oClipRect.Top = oSrcRect.dY * dScale;
oClipRect.Right = (oSrcRect.dX + oSrcRect.dWidth) * dScale;
oClipRect.Bottom = (oSrcRect.dY + oSrcRect.dHeight) * dScale;
oEmfParser.PlayFile();
BYTE* pNewBuffer = GetClipedImage(pPixels, nWidth, nHeight, oClipRect);
pGrRenderer->EndCommand(c_nImageType);
const unsigned int unWidth = std::min(((unsigned int)fabs(oClipRect.Right - oClipRect.Left)), ((unsigned int)nWidth ));
const unsigned int unHeight = std::min(((unsigned int)fabs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)nHeight));
LONG lWidth = nWidth, lHeight = nHeight;
BYTE* pPixels = oFrame.get_Data();
//FlipYImage(pPixels, lWidth, lHeight); //Проверить на примерах, где WrapMode != WrapModeTileFlipXY
TRectL oClipRect;
oClipRect.Left = oSrcRect.dX * dScale;
oClipRect.Top = oSrcRect.dY * dScale;
oClipRect.Right = (oSrcRect.dX + oSrcRect.dWidth) * dScale;
oClipRect.Bottom = (oSrcRect.dY + oSrcRect.dHeight) * dScale;
BYTE* pNewBuffer = GetClipedImage(pPixels, lWidth, lHeight, oClipRect);
unsigned int unWidth = std::min(((unsigned int)fabs(oClipRect.Right - oClipRect.Left)), ((unsigned int)lWidth ));
unsigned int unHeight = std::min(((unsigned int)fabs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)lHeight));
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(),
(NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight);
RELEASEINTERFACE(pGrRenderer);
RELEASEARRAYOBJECTS(pNewBuffer);
}
else if (!oEmfParser.CheckError() && InterpretatorType::Svg == m_pInterpretator->GetType())
{
((CEmfParserBase*)&oEmfParser)->SetInterpretator(InterpretatorType::Svg);
oEmfParser.PlayFile();
TXForm *pXForm = m_pDC->GetTransform();
TRectD oRect;
oRect.Left = arPoints[0].X;
oRect.Top = arPoints[0].Y;
oRect.Right = arPoints[1].X - m_pDC->GetPixelWidth();
oRect.Bottom = arPoints[2].Y - m_pDC->GetPixelHeight();
TRectD oTempSrcRect;
TRectL *pEmfBounds = oEmfParser.GetBounds();
oTempSrcRect = oSrcRect.ToRectD();
oTempSrcRect.Left -= pEmfBounds->Left;
oTempSrcRect.Right -= pEmfBounds->Left + GetPixelWidth();
oTempSrcRect.Top -= pEmfBounds->Top;
oTempSrcRect.Bottom -= pEmfBounds->Top + GetPixelHeight();
TXForm oTransform;
oTransform.Copy(pXForm);
oTransform.Dx -= m_oHeader.oFramePx.Left;
oTransform.Dy -= m_oHeader.oFramePx.Top;
((CEmfInterpretatorSvg*)m_pInterpretator)->IncludeSvg(((CEmfInterpretatorSvg*)oEmfParser.GetInterpretator())->GetFile(), oRect, oTempSrcRect, &oTransform);
}
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(),
(NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight);
RELEASEINTERFACE(pGrRenderer);
RELEASEARRAYOBJECTS(pNewBuffer);
}
else if (MetafileDataTypeWmf == eMetafileType ||
MetafileDataTypeWmfPlaceable == eMetafileType)
else if (InterpretatorType::Svg == m_pInterpretator->GetType())
{
CWmfParser oWmfParser;
oWmfParser.SetStream(pBuffer, unSize);
oWmfParser.SetFontManager(GetFontManager());
oWmfParser.Scan();
((MetafileType*)&oParser)->SetInterpretator(InterpretatorType::Svg);
if (!oWmfParser.CheckError() && InterpretatorType::Render == m_pInterpretator->GetType())
{
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
pGrRenderer->SetFontManager(GetFontManager());
oParser.PlayFile();
TRectD oWmfBounds = oWmfParser.GetBounds();
TXForm *pXForm = m_pDC->GetTransform();
CMetaFileRenderer* pMetaFileRenderer = (CMetaFileRenderer*)(((CEmfInterpretatorRender*)m_pInterpretator)->GetRenderer());
TRectD oRect;
const double dKoef = 96. / 25.4;
oRect.Left = arPoints[0].X;
oRect.Top = arPoints[0].Y;
oRect.Right = arPoints[1].X - m_pDC->GetPixelWidth();
oRect.Bottom = arPoints[2].Y - m_pDC->GetPixelHeight();
const int nParentWidth = pMetaFileRenderer->GetWidth() * dKoef;
const int nParentHeight = pMetaFileRenderer->GetHeight() * dKoef;
TRectD oTempSrcRect{oSrcRect.ToRectD()};
oTempSrcRect.Left -= pFileBounds->Left;
oTempSrcRect.Right -= pFileBounds->Left + GetPixelWidth();
oTempSrcRect.Top -= pFileBounds->Top;
oTempSrcRect.Bottom -= pFileBounds->Top + GetPixelHeight();
int nWidth = abs(oWmfBounds.Right - oWmfBounds.Left) * pMetaFileRenderer->GetScaleX();
int nHeight = abs(oWmfBounds.Bottom - oWmfBounds.Top) * pMetaFileRenderer->GetScaleY();
TXForm oTransform;
double dScale = 1.;
oTransform.Copy(pXForm);
if (nWidth > nParentWidth || nHeight > nParentHeight)
{
dScale = std::min((double)nParentWidth / (double)nWidth, (double)nParentHeight / (double)nHeight);
oTransform.Dx -= m_oHeader.oFramePx.Left;
oTransform.Dy -= m_oHeader.oFramePx.Top;
nWidth *= dScale;
nHeight *= dScale;
}
CInterpretatorSvgBase* pParserSvgInterpretator = dynamic_cast<CInterpretatorSvgBase*>(oParser.GetInterpretator());
CInterpretatorSvgBase *pSvgInterpretator = dynamic_cast<CInterpretatorSvgBase*>(m_pInterpretator);
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;
}
double dWidth = nWidth / dKoef;
double dHeight = nWidth / dKoef;
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);
pGrRenderer->BeginCommand(c_nImageType);
CMetaFileRenderer oWmfOut(&oWmfParser, pGrRenderer, 0, 0, dWidth, dHeight);
oWmfParser.SetInterpretator(&oWmfOut);
oWmfParser.PlayFile();
pGrRenderer->EndCommand(c_nImageType);
LONG lWidth = nWidth, lHeight = nHeight;
BYTE* pPixels = oFrame.get_Data();
//FlipYImage(pPixels, lWidth, lHeight); //Проверить на примерах, где WrapMode != WrapModeTileFlipXY
TRectL oClipRect;
oClipRect.Left = oSrcRect.dX * dScale;
oClipRect.Top = oSrcRect.dY * dScale;
oClipRect.Right = (oSrcRect.dX + oSrcRect.dWidth) * dScale;
oClipRect.Bottom = (oSrcRect.dY + oSrcRect.dHeight) * dScale;
BYTE* pNewBuffer = GetClipedImage(pPixels, lWidth, lHeight, oClipRect);
unsigned int unWidth = std::min(((unsigned int)fabs(oClipRect.Right - oClipRect.Left)), ((unsigned int)lWidth ));
unsigned int unHeight = std::min(((unsigned int)fabs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)lHeight));
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(),
(NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight);
RELEASEINTERFACE(pGrRenderer);
RELEASEARRAYOBJECTS(pNewBuffer);
}
else if (!oWmfParser.CheckError() && InterpretatorType::Svg == m_pInterpretator->GetType())
{
((CWmfParserBase*)&oWmfParser)->SetInterpretator(InterpretatorType::Svg);
oWmfParser.PlayFile();
TXForm *pXForm = m_pDC->GetFinalTransform(GM_ADVANCED);
TRectD oRect;
oRect.Left = arPoints[0].X;
oRect.Top = arPoints[0].Y;
oRect.Right = arPoints[1].X - m_pDC->GetPixelWidth();
oRect.Bottom = arPoints[2].Y - m_pDC->GetPixelHeight();
TRectD oTempSrcRect = oSrcRect.ToRectD();
CEmfPlusImageAttributes *pImageAttributes = GetImageAttributes(unImageAttributeIndex);
if (NULL != pImageAttributes && WrapModeTileFlipY != pImageAttributes->eWrapMode && WrapModeTileFlipXY != pImageAttributes->eWrapMode)
{
double dTempValue = oTempSrcRect.Bottom;
oTempSrcRect.Bottom = oTempSrcRect.Top;
oTempSrcRect.Top = dTempValue;
}
TXForm oTransform;
oTransform.Copy(pXForm);
oTransform.Dx -= m_oHeader.oFramePx.Left;
oTransform.Dy -= m_oHeader.oFramePx.Top;
((CWmfInterpretatorSvg*)m_pInterpretator)->IncludeSvg(((CWmfInterpretatorSvg*)oWmfParser.GetInterpretator())->GetFile(), oRect, oTempSrcRect, &oTransform);
}
if (NULL != pParserSvgInterpretator && NULL != pSvgInterpretator)
pSvgInterpretator->IncludeSvg(pParserSvgInterpretator->GetFile(), oRect, oTempSrcRect, &oTransform);
}
//TODO: общую часть в идеале нужно вынести
}
void CEmfPlusParser::DrawBitmap(BYTE *pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight, const TEmfPlusRectF& oSrcRect, const std::vector<TEmfPlusPointF>& arPoints)

View File

@ -77,7 +77,8 @@ namespace MetaFile
void DrawLines(std::vector<TEmfPlusPointF> arPoints, bool bCloseFigure);
void DrawImagePoints(unsigned int unImageIndex, unsigned int unImageAttributeIndex, const TEmfPlusRectF& oSrcRect, const std::vector<TEmfPlusPointF>& arPoints);
void DrawMetafile(BYTE* pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector<TEmfPlusPointF>& arPoints, EEmfPlusMetafileDataType eMetafileType, unsigned int unImageAttributeIndex);
template <typename MetafileType>
void DrawMetafile(BYTE* pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector<TEmfPlusPointF>& arPoints);
void DrawBitmap(BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight, const TEmfPlusRectF& oSrcRect, const std::vector<TEmfPlusPointF>& arPoints);
TEmfPlusARGB ApplyImageAttributes(TEmfPlusRectF& oRectangle, const CEmfPlusImageAttributes& oImageAttributes);

View File

@ -71,7 +71,7 @@ namespace MetaFile
{
if (NULL != m_pParser)
{
NSFonts::IFontManager* pFont = m_pParser->GetFontManager();
NSFonts::IFontManager* pFont = m_pParser->GetFontManager();
delete m_pParser;
m_pParser = new CWmfParser();

View File

@ -153,12 +153,6 @@ namespace MetaFile
if (oNewClipRect.Top > oNewClipRect.Bottom)
std::swap(oNewClipRect.Top, oNewClipRect.Bottom);
NodeAttributes arNodeAttributes;
AddTransform(arNodeAttributes, pTransform);
WriteNodeBegin(L"g", arNodeAttributes);
wsNewSvg.erase(unFirstPos, unSecondPos - unFirstPos);
std::wstring wsClip = L"x=\"" + ConvertToWString(oRect.Left) + L"\" y=\"" + ConvertToWString(oRect.Top) + L"\" " +
@ -167,8 +161,12 @@ namespace MetaFile
wsNewSvg.insert(unFirstPos, wsClip);
m_pXmlWriter->WriteString(wsNewSvg);
NodeAttributes arNodeAttributes;
AddTransform(arNodeAttributes, pTransform);
WriteNodeBegin(L"g", arNodeAttributes);
m_pXmlWriter->WriteString(wsNewSvg);
WriteNodeEnd(L"g");
}

View File

@ -261,7 +261,17 @@ namespace MetaFile
oBB.Bottom = m_oBoundingBox.Bottom;
}
return oBB;
const double dFileDpi = GetDpi();
const double dRendererDpi = 96;
if (Equals(dFileDpi, dRendererDpi) && !Equals(0, dFileDpi))
return oBB;
TRectD oNewBB(oBB);
oNewBB *= dRendererDpi / dFileDpi;
return TRectL(oNewBB);
}
else
return m_oBoundingBox;
@ -1749,14 +1759,9 @@ namespace MetaFile
m_oEscapeBuffer.Clear();
return;
}
m_oBoundingBox = *oEmfParser.GetBounds();
if (NULL == m_pInterpretator)
{
m_oEscapeBuffer.Clear();
return HANDLE_META_EOF();
}
HANDLE_META_EOF();
else if (InterpretatorType::Render == m_pInterpretator->GetType())
{
CMetaFileRenderer oEmfOut(&oEmfParser, ((CWmfInterpretatorRender*)m_pInterpretator)->GetRenderer());
@ -1778,13 +1783,13 @@ namespace MetaFile
TRectD oCurrentRect = GetBounds();
double dScaleX = std::abs((oCurrentRect.Right - oCurrentRect.Left) / (m_oBoundingBox.Right - m_oBoundingBox.Left));
double dScaleY = std::abs((oCurrentRect.Bottom - oCurrentRect.Top) / (m_oBoundingBox.Bottom - m_oBoundingBox.Top));
const double dScaleX = std::abs((oCurrentRect.Right - oCurrentRect.Left) / (m_oBoundingBox.Right - m_oBoundingBox.Left));
const double dScaleY = std::abs((oCurrentRect.Bottom - oCurrentRect.Top) / (m_oBoundingBox.Bottom - m_oBoundingBox.Top));
pXmlWriter->WriteNodeBegin(L"g", true);
if (0 != dScaleX || 0 != dScaleY)
pXmlWriter->WriteAttribute(L"transform", L"scale(" + std::to_wstring(dScaleX) + L',' + std::to_wstring(dScaleY) + L')');
if (!Equals(1., dScaleX) || !Equals(1., dScaleY))
pXmlWriter->WriteAttribute(L"transform", L"scale(" + ConvertToWString(dScaleX) + L',' + ConvertToWString(dScaleY) + L')');
pXmlWriter->WriteNodeEnd(L"g", true, false);