Merge pull request 'Fix flipY in tiles' (#651) from fix/docx-renderer into release/v9.3.0

Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/651
This commit is contained in:
Oleg Korshul
2026-02-09 18:23:25 +00:00
7 changed files with 60 additions and 8 deletions

View File

@ -648,11 +648,15 @@ namespace NSDocxRenderer
if ((nType > 0xFF) && (c_BrushTypeTexture == m_oCurrentPage.m_oBrush.Type)) if ((nType > 0xFF) && (c_BrushTypeTexture == m_oCurrentPage.m_oBrush.Type))
{ {
double x = 0, y = 0, w = 0, h = 0; double x = 0, y = 0, w = 0, h = 0;
if (m_oCurrentPage.IsCurrVectorClockwise())
h = -1; // to flip image later
if (m_oCurrentPage.m_oBrush.Image) if (m_oCurrentPage.m_oBrush.Image)
pInfo = m_oImageManager.WriteImage(m_oCurrentPage.m_oBrush.Image, x, y, w, h); pInfo = m_oImageManager.WriteImage(m_oCurrentPage.m_oBrush.Image, x, y, w, h);
else else
pInfo = m_oImageManager.WriteImage(m_oCurrentPage.m_oBrush.TexturePath, x, y, w, h); pInfo = m_oImageManager.WriteImage(m_oCurrentPage.m_oBrush.TexturePath);
} }
m_oCurrentPage.DrawPath(nType, pInfo); m_oCurrentPage.DrawPath(nType, pInfo);
return S_OK; return S_OK;
} }
@ -712,7 +716,7 @@ namespace NSDocxRenderer
} }
HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight) HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight)
{ {
m_oCurrentPage.WriteImage(m_oImageManager.WriteImage(sVal, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); m_oCurrentPage.WriteImage(m_oImageManager.WriteImage(sVal), fX, fY, fWidth, fHeight);
return S_OK; return S_OK;
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------

View File

@ -277,6 +277,10 @@ namespace NSDocxRenderer
m_arShapes.push_back(shape); m_arShapes.push_back(shape);
} }
} }
bool CPage::IsCurrVectorClockwise() const
{
return m_oCurrVectorGraphics.IsClockwise();
}
void CPage::AddText( void CPage::AddText(
const PUINT pUnicodes, const PUINT pUnicodes,

View File

@ -68,6 +68,7 @@ namespace NSDocxRenderer
void PathEnd(); void PathEnd();
void PathClose(); void PathClose();
void DrawPath(LONG lType, const std::shared_ptr<CImageInfo> pInfo); void DrawPath(LONG lType, const std::shared_ptr<CImageInfo> pInfo);
bool IsCurrVectorClockwise() const;
void AddText( void AddText(
const PUINT pUnicodes, const PUINT pUnicodes,

View File

@ -147,7 +147,7 @@ namespace NSDocxRenderer
return GenerateImageID(pImage); return GenerateImageID(pImage);
} }
std::shared_ptr<CImageInfo> CImageManager::WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height) std::shared_ptr<CImageInfo> CImageManager::WriteImage(const std::wstring& strFile)
{ {
Aggplus::CImage image(strFile); Aggplus::CImage image(strFile);
return GenerateImageID(&image); return GenerateImageID(&image);

View File

@ -20,14 +20,14 @@ namespace NSDocxRenderer
void Clear(); void Clear();
std::shared_ptr<CImageInfo> WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); std::shared_ptr<CImageInfo> WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height);
std::shared_ptr<CImageInfo> WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height); std::shared_ptr<CImageInfo> WriteImage(const std::wstring& strFile);
std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage); std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage);
static CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); static CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame);
static void FlipY(Aggplus::CImage* pImage);
private: private:
std::shared_ptr<CImageInfo> GenerateImageID(const std::wstring& strFileName); std::shared_ptr<CImageInfo> GenerateImageID(const std::wstring& strFileName);
void FlipY(Aggplus::CImage* pImage);
int m_lMaxSizeImage {1200}; int m_lMaxSizeImage {1200};
int m_lNextIDImage {0}; int m_lNextIDImage {0};
CCalculatorCRC32 m_oCRC; CCalculatorCRC32 m_oCRC;

View File

@ -195,7 +195,7 @@ namespace NSDocxRenderer
double x0 = m_arData.back().points.back().x; double x0 = m_arData.back().points.back().x;
double y0 = m_arData.back().points.back().y; double y0 = m_arData.back().points.back().y;
std::list<Point> points = {{x1, y1}, {x2, y2}, {x3, y3}}; std::vector<Point> points = {{x1, y1}, {x2, y2}, {x3, y3}};
ePathCommandType type = ePathCommandType::pctCurve; ePathCommandType type = ePathCommandType::pctCurve;
m_arData.push_back({type, points}); m_arData.push_back({type, points});
@ -308,6 +308,48 @@ namespace NSDocxRenderer
} }
} }
} }
void CVectorGraphics::Reverse()
{
}
bool CVectorGraphics::IsClockwise() const
{
if (m_arData.empty())
return false;
double area = 0;
double last_x = 0;
double last_y = 0;
bool is_first = true;
for (const auto& command : m_arData)
{
if (is_first)
{
is_first = false;
last_x = command.points.back().x;
last_y = command.points.back().y;
continue;
}
if (command.type == ePathCommandType::pctClose)
break;
const auto& points = command.points;
if (command.type == ePathCommandType::pctCurve)
{
area += 3.0 * ((points[2].y - last_y) * (points[0].x + points[1].x)
- (points[2].x - last_x) * (points[0].y + points[1].y)
+ points[0].y * (last_x - points[1].x)
- points[0].x * (last_y - points[1].y)
+ points[2].y * (points[1].x + last_x / 3.0)
- points[2].x * (points[1].y + last_y / 3.0)) / 20.0;
}
else
area += (points[0].y * last_x - points[0].x * last_y) / 2.0;
last_x = command.points.back().x;
last_y = command.points.back().y;
}
return area >= 0;
}
// ClipRegionTypeWinding = 0x0000; // ClipRegionTypeWinding = 0x0000;
// ClipRegionTypeEvenOdd = 0x0001; // ClipRegionTypeEvenOdd = 0x0001;

View File

@ -31,7 +31,7 @@ namespace NSDocxRenderer
struct CPathCommand struct CPathCommand
{ {
ePathCommandType type; ePathCommandType type;
std::list<Point> points; std::vector<Point> points;
}; };
CVectorGraphics() noexcept; CVectorGraphics() noexcept;
@ -79,6 +79,7 @@ namespace NSDocxRenderer
void Rotate(const double& rotation); void Rotate(const double& rotation);
void Transform(const Aggplus::CMatrix& matrix); void Transform(const Aggplus::CMatrix& matrix);
void DrawOnRenderer(IRenderer* renderer) const noexcept; void DrawOnRenderer(IRenderer* renderer) const noexcept;
bool IsClockwise() const;
static CVectorGraphics CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType = c_nWindingFillMode, bool isLuminosity = false); static CVectorGraphics CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType = c_nWindingFillMode, bool isLuminosity = false);