mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Fix bug #65392
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user