From 69595f92112b9502626dcd7da133d754baa5a6a5 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 11 Jan 2024 18:18:27 +0300 Subject: [PATCH] Fix bug #65392 --- .../raster/Metafile/Common/MetaFileUtils.cpp | 72 ++-- .../Metafile/Emf/EmfParser/CEmfParser.cpp | 16 +- .../Metafile/Emf/EmfParser/CEmfParser.h | 5 +- .../Metafile/Emf/EmfParser/CEmfParserBase.h | 2 +- .../Metafile/Emf/EmfParser/CEmfPlusParser.cpp | 346 ++++++------------ .../Metafile/Emf/EmfParser/CEmfPlusParser.h | 3 +- DesktopEditor/raster/Metafile/Wmf/WmfFile.h | 2 +- .../CInterpretatorSvgBase.cpp | 12 +- .../Metafile/Wmf/WmfParser/CWmfParserBase.cpp | 27 +- 9 files changed, 172 insertions(+), 313 deletions(-) diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp index 00ae572d34..e12e9989a8 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp @@ -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(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& 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; } } diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp index e8f15c0d77..dcd8490029 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp @@ -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); diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h index f24b0e91a7..c70be08aed 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.h @@ -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; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h index 5984f1ac29..04de024d19 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h @@ -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); diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index 175a3379a9..684244fb56 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -86,9 +86,10 @@ #include "../../../BgraFrame.h" +#define MAX_PICTURE_SIZE 2000. + namespace MetaFile -{ - static std::map ActionNamesEmfPlus = +{ static std::map 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(pBuffer, unSizeBuffer, oSrcRect, arPoints); + case MetafileDataTypeWmf: + case MetafileDataTypeWmfPlaceable: + return DrawMetafile(pBuffer, unSizeBuffer, oSrcRect, arPoints); + } } -} + } - void CEmfPlusParser::DrawMetafile(BYTE *pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints, EEmfPlusMetafileDataType eMetafileType, unsigned int unImageAttributeIndex) + template + void CEmfPlusParser::DrawMetafile(BYTE *pBuffer, unsigned int unSize, const TEmfPlusRectF &oSrcRect, const std::vector &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(oParser.GetInterpretator()); + CInterpretatorSvgBase *pSvgInterpretator = dynamic_cast(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& arPoints) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h index 26c5eb0fe3..8679ef46c0 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.h @@ -77,7 +77,8 @@ namespace MetaFile void DrawLines(std::vector arPoints, bool bCloseFigure); void DrawImagePoints(unsigned int unImageIndex, unsigned int unImageAttributeIndex, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints); - void DrawMetafile(BYTE* pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints, EEmfPlusMetafileDataType eMetafileType, unsigned int unImageAttributeIndex); + template + void DrawMetafile(BYTE* pBuffer, unsigned int unSize, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints); void DrawBitmap(BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight, const TEmfPlusRectF& oSrcRect, const std::vector& arPoints); TEmfPlusARGB ApplyImageAttributes(TEmfPlusRectF& oRectangle, const CEmfPlusImageAttributes& oImageAttributes); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfFile.h b/DesktopEditor/raster/Metafile/Wmf/WmfFile.h index e8197568e0..712768bd89 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfFile.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfFile.h @@ -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(); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp index dd52fb8bc5..7c7b447c5e 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp @@ -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"); } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp index fe7caff839..c6a435773b 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp @@ -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);