Skip to content

Commit

Permalink
Merge pull request 'Fix Metafile conversion' (#228) from fix/bugs-met…
Browse files Browse the repository at this point in the history
…afile into hotfix/v8.3.1

Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/228
  • Loading branch information
K0R0L committed Feb 13, 2025
2 parents a93db0e + 612142f commit dbdf4bd
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 148 deletions.
156 changes: 96 additions & 60 deletions DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ namespace MetaFile
m_bStartedPath = false;
m_bUpdatedClip = true;

m_pRenderer->CommandLong(c_nPenWidth0As1px, 1);

//int alpha = 0xff;
//m_pRenderer->put_BrushAlpha1(alpha);
//m_pRenderer->put_BrushType(c_BrushTypeSolid);
Expand Down Expand Up @@ -1218,7 +1216,41 @@ namespace MetaFile
else if (PS_JOIN_MITER == ulPenJoin)
nJoinStyle = Aggplus::LineJoinMiter;

const double dWidth = pPen->GetWidth() * m_dScaleX;
double dWidth = pPen->GetWidth();

// Повторение кода из Graphics для вычисления минимальной ширины пера
double dM11, dM12, dM21, dM22, dDx, dDy;
m_pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);

Aggplus::CMatrix oMatrix;

oMatrix.SetElements(dM11, dM12, dM21, dM22, dDx, dDy);
oMatrix.Scale(1. / m_dScaleX, 1. / m_dScaleY);

// Вычисление минимально возможной ширины пера
// # Код явялется дублированным из Graphics
const double dSqrtDet = sqrt(abs(oMatrix.Determinant()));
const double dWidthMinSize = (dSqrtDet != 0) ? (1.0 / dSqrtDet) : dWidth;

if (0 == pPen->GetWidth())
{
double dX = 0.72, dY = 0.72;

oMatrix.Invert();
oMatrix.TransformPoint(dX, dY);
dX -= oMatrix.OffsetX();
dY -= oMatrix.OffsetY();
dWidth = std::min(abs(dX), abs(dY));
}
//------------------------
else
{
dWidth *= m_dScaleX;

if (dWidth < dWidthMinSize)
dWidth = dWidthMinSize;
}

const double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX;

BYTE nDashStyle = Aggplus::DashStyleSolid;
Expand All @@ -1228,80 +1260,84 @@ namespace MetaFile

pPen->GetDashData(pDataDash, unSizeDash);

if (NULL != pDataDash && 0 != unSizeDash)
if ((NULL != pDataDash && 0 != unSizeDash) || PS_SOLID != ulPenStyle)
{
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());
// Дублированный код из Graphics
// Без этого используется оригинальный код в Graphics, который отрисовывает уже неверно
double dDashWidth{dWidth};

double dM11, dTemp;
m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp);
double dDpi;
m_pRenderer->get_DpiX(&dDpi);
const double dNewWidth{dWidth * dM11 * dDpi / 25.4};
if (!Equals(dWidthMinSize, dWidth))
{
double dDet = oMatrix.Determinant();

std::vector<double> arDashes(unSizeDash);
if (fabs(dDet) < 0.0001)
dDashWidth *= dSqrtDet;
}
// -----------------------------

for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex)
arDashes[unIndex] = pDataDash[unIndex] * dNewWidth;
if (NULL != pDataDash && 0 != unSizeDash)
{
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());

m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);
std::vector<double> arDashes(unSizeDash);

nDashStyle = Aggplus::DashStyleCustom;
}
else if (PS_SOLID != ulPenStyle)
{
std::vector<double> arDashPattern;
for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex)
arDashes[unIndex] = pDataDash[unIndex] * dDashWidth;

double dM11, dTemp;
m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp);
double dDpi;
m_pRenderer->get_DpiX(&dDpi);
const double dNewWidth{dWidth * dM11 * dDpi / 25.4};
m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);

switch (ulPenStyle)
nDashStyle = Aggplus::DashStyleCustom;
}
else
{
case PS_DASH:
{
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
std::vector<double> arDashPattern;

break;
}
case PS_DOT:
switch (ulPenStyle)
{
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
case PS_DASH:
{
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);

break;
}
case PS_DASHDOT:
{
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
break;
}
case PS_DOT:
{
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);

break;
}
case PS_DASHDOT:
{
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);

break;
break;
}
case PS_DASHDOTDOT:
{
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);

break;
}
}
case PS_DASHDOTDOT:

if (!arDashPattern.empty())
{
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);

break;
m_pRenderer->PenDashPattern(arDashPattern.data(), arDashPattern.size());
nDashStyle = Aggplus::DashStyleCustom;
nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat;
nJoinStyle = Aggplus::LineJoinMiter;
}
}

if (!arDashPattern.empty())
{
m_pRenderer->PenDashPattern(arDashPattern.data(), arDashPattern.size());
nDashStyle = Aggplus::DashStyleCustom;
nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat;
nJoinStyle = Aggplus::LineJoinMiter;
}
}

m_pRenderer->put_PenDashStyle(nDashStyle);
Expand Down
16 changes: 14 additions & 2 deletions DesktopEditor/raster/Metafile/Common/MetaFileTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ namespace MetaFile
: r(_r), g(_g), b(_b), a(_a)
{}

TRGBA::TRGBA(int nValue) : r((nValue >> 0) & 0xFF), g((nValue >> 8) & 0xFF), b((nValue >> 16) & 0xFF), a((nValue >> 24) & 0xFF)
TRGBA::TRGBA(int nValue)
: r((nValue >> 0) & 0xFF), g((nValue >> 8) & 0xFF), b((nValue >> 16) & 0xFF), a((nValue >> 24) & 0xFF)
{}

void TRGBA::Set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a)
Expand Down Expand Up @@ -94,7 +95,18 @@ namespace MetaFile
return a;
}

TXForm::TXForm() : M11(1), M12(0), M21(0), M22(1), Dx(0), Dy(0)
TRGBA& TRGBA::operator=(const TRGBA& oRGBA)
{
r = oRGBA.r;
g = oRGBA.g;
b = oRGBA.b;
a = oRGBA.a;

return *this;
}

TXForm::TXForm()
: M11(1), M12(0), M21(0), M22(1), Dx(0), Dy(0)
{}

TXForm::TXForm(const TXForm &oXForm)
Expand Down
2 changes: 2 additions & 0 deletions DesktopEditor/raster/Metafile/Common/MetaFileTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,8 @@ namespace MetaFile
unsigned char GetGreen() const;
unsigned char GetBlue() const;
unsigned char GetAlpha() const;

TRGBA& operator=(const TRGBA& oRGBA);
};

struct TXForm
Expand Down
38 changes: 12 additions & 26 deletions DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@ namespace MetaFile
}
for (int nAddIndex = 0; nAddIndex < nAdditBytes; nAddIndex++)
{
int nByte = *pBuffer; pBuffer++; lBufLen--;
// int nByte = *pBuffer;
++pBuffer;
--lBufLen;
}
}
}
Expand Down Expand Up @@ -271,7 +273,9 @@ namespace MetaFile
}
for (int nAddIndex = 0; nAddIndex < nAdditBytes; nAddIndex++)
{
int nByte = *pBuffer; pBuffer++; lBufLen--;
// int nByte = *pBuffer;
++pBuffer;
--lBufLen;
}
}
}
Expand Down Expand Up @@ -490,7 +494,12 @@ namespace MetaFile
}

if (lBufLen < (nWidth + nAdd) * abs(nHeight))
{
if (pUncompressedBuffer)
delete[] pUncompressedBuffer;

return false;
}

pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
Expand Down Expand Up @@ -643,7 +652,7 @@ namespace MetaFile
*pulWidth = ulWidth;
*pulHeight = ulHeight;

return false;
return true;
}
else if (BI_BITCOUNT_5 == ushBitCount)
{
Expand Down Expand Up @@ -990,29 +999,6 @@ namespace MetaFile
}
}

std::wstring ascii_to_unicode(const char *src)
{
size_t nSize = mbstowcs(0, src, 0);
wchar_t* pBuffer = new wchar_t[nSize];
nSize = mbstowcs(pBuffer, src, nSize);
std::wstring sRes;
if (nSize != (size_t)-1)
sRes = std::wstring(pBuffer, nSize);
delete[] pBuffer;
return sRes;
}
std::string unicode_to_ascii(const wchar_t *src)
{
size_t nSize = wcstombs(0, src, 0);
char* pBuffer = new char[nSize];
nSize = wcstombs(pBuffer, src, nSize);
std::string sRes;
if (nSize != (size_t)-1)
sRes = std::string(pBuffer, nSize);
delete[] pBuffer;
return sRes;
}

std::wstring GetTempFilename(const std::wstring& sFolder)
{
std::wstring sTmpFile = NSFile::CFileBinary::CreateTempFileWithUniqueName(sFolder.empty() ? NSFile::CFileBinary::GetTempPath() : sFolder, L"wmf");
Expand Down
1 change: 0 additions & 1 deletion DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
*
*/
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../graphics/Image.h"

#include "../Common/MetaFileUtils.h"

Expand Down
10 changes: 10 additions & 0 deletions DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,8 @@ namespace MetaFile

if (!BanEMFProcesses())
HANDLE_EMR_CREATEBRUSHINDIRECT(ulBrushIndex, pBrush);
else
delete pBrush;
}

void CEmfParser::Read_EMR_SETTEXTCOLOR()
Expand Down Expand Up @@ -630,6 +632,8 @@ namespace MetaFile

if (!BanEMFProcesses())
HANDLE_EMR_EXTCREATEFONTINDIRECTW(ulIndex, pFont);
else
delete pFont;
}

void CEmfParser::Read_EMR_SETTEXTALIGN()
Expand Down Expand Up @@ -722,6 +726,8 @@ namespace MetaFile

if (!BanEMFProcesses())
HANDLE_EMR_EXTCREATEPEN(ulPenIndex, pPen, arUnused);
else
delete pPen;
}

void CEmfParser::Read_EMR_CREATEPEN()
Expand All @@ -744,6 +750,8 @@ namespace MetaFile

if (!BanEMFProcesses())
HANDLE_EMR_CREATEPEN(ulPenIndex, widthX, pPen);
else
delete pPen;
}

void CEmfParser::Read_EMR_SETPOLYFILLMODE()
Expand Down Expand Up @@ -1011,6 +1019,8 @@ namespace MetaFile

if (!BanEMFProcesses())
HANDLE_EMR_CREATEPALETTE(ulPaletteIndex, pPalette);
else
delete pPalette;
}

void CEmfParser::Read_EMR_SELECTPALETTE()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ namespace MetaFile
if (InterpretatorType::Svg == oInterpretatorType)
{
CEmfInterpretatorSvg *pEmfInterpretatorSvg = new CEmfInterpretatorSvg(this, dWidth, dHeight);
pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges);
pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::OptimizeSpeed);
m_pInterpretator = pEmfInterpretatorSvg;
}
}
Expand Down
4 changes: 0 additions & 4 deletions DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#ifndef CEMFPARSERBASE_H
#define CEMFPARSERBASE_H

//#include "../EmfTypes.h"
//#include "../EmfObjects.h"
//#include "../../Common/MetaFileUtils.h"

#include "../EmfPlayer.h"

#include "../../Common/MetaFile.h"
Expand Down
Loading

0 comments on commit dbdf4bd

Please sign in to comment.