core.git: Branch 'libreoffice-26-2' - drawinglayer/source emfio/qa
drawinglayer/source/tools/emfpimage.cxx | 55
emfio/qa/cppunit/emf/EmfImportTest.cxx |4 +-
2 files changed, 44 insertions(+), 15 deletions(-)
New commits:
commit 5c3bf1387bce8f899e0b3b5f5aaef827931763e9
Author: Bartosz Kosiorek
AuthorDate: Thu Mar 12 23:49:54 2026 +0100
Commit: Bartosz Kosiorek
CommitDate: Sat Mar 14 10:05:43 2026 +0100
tdf59814 tdf168886 EMF+ Use Frame size and DPI instead Bound
Previously, nested EMF images were sized based on rclBounds, which
only encompasses the drawn objects. This caused incorrect scaling
and offsets when the drawing did not fill the entire logical canvas.
Changes:
- Switched from rclBounds to rclFrame for logical canvas dimensions.
- Implemented DPI calculation using szlDevice and szlMillimeters
from the EMF header.
- Correctly mapped rclFrame (0.01mm units) to image pixel
coordinates (x, y, width, height).
Change-Id: I32f6679bedb26e86b069abd6b4d270a385ca7e89
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201589
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek
diff --git a/drawinglayer/source/tools/emfpimage.cxx
b/drawinglayer/source/tools/emfpimage.cxx
index bb18de52bb27..bb33eaf46622 100644
--- a/drawinglayer/source/tools/emfpimage.cxx
+++ b/drawinglayer/source/tools/emfpimage.cxx
@@ -65,35 +65,64 @@ namespace emfplushelper
if (mfType == 3 || mfType == 4 || mfType == 5)
{
sal_uInt32 dwRecordType, dwRecordSize, dSignature, nVersion;
-sal_Int32 rclBoundsLeft, rclBoundsTop, rclBoundsRight,
rclBoundsBottom;
+sal_Int32 rclFrameLeft, rclFrameTop, rclFrameRight,
rclFrameBottom;
mfStream.ReadUInt32(dwRecordType);
mfStream.ReadUInt32(dwRecordSize);
-mfStream.ReadInt32(rclBoundsLeft);
-mfStream.ReadInt32(rclBoundsTop);
-mfStream.ReadInt32(rclBoundsRight);
-mfStream.ReadInt32(rclBoundsBottom);
-
mfStream.SeekRel(16);
+mfStream.ReadInt32(rclFrameLeft);
+mfStream.ReadInt32(rclFrameTop);
+mfStream.ReadInt32(rclFrameRight);
+mfStream.ReadInt32(rclFrameBottom);
+
mfStream.ReadUInt32(dSignature);
mfStream.ReadUInt32(nVersion);
if (dwRecordType == 1 && dSignature == 0x464D4520)
{
-x = rclBoundsLeft;
-y = rclBoundsTop;
-width = rclBoundsRight - rclBoundsLeft;
-height = rclBoundsBottom - rclBoundsTop;
+mfStream.SeekRel(24);
+
+sal_Int32 szlDeviceWidth, szlDeviceHeight;
+sal_Int32 szlMillimetersWidth, szlMillimetersHeight;
+
+mfStream.ReadInt32(szlDeviceWidth);
+mfStream.ReadInt32(szlDeviceHeight);
+mfStream.ReadInt32(szlMillimetersWidth);
+mfStream.ReadInt32(szlMillimetersHeight);
+
+const double fPxPerMmX
+= (szlMillimetersWidth > 0)
+? static_cast(szlDeviceWidth) /
szlMillimetersWidth
+: 3.7795;
+const double fPxPerMmY
+= (szlMillimetersHeight > 0)
+? static_cast(szlDeviceHeight) /
szlMillimetersHeight
+: 3.7795;
+
+x = std::round(fPxPerMmX * rclFrameLeft / 100.0);
+y = std::round(fPxPerMmY * rclFrameTop / 100.0);
+width = std::round(fPxPerMmX * (rclFrameRight -
rclFrameLeft) / 100.0);
+height = std::round(fPxPerMmY * (rclFrameBottom -
rclFrameTop) / 100.0);
+
SAL_INFO("drawinglayer.emf", "EMF+ Nested EMF Header
detected.");
SAL_INFO("drawinglayer.emf",
-"EMF+ Bounds: [" << rclBoundsLeft << "," <<
rclBoundsTop << ", "
- << rclBoundsRight << ", " <<
rclBoundsBottom << "]");
+ "EMF+ DevicePx: " << szlDeviceWidth << "x" <<
szlDeviceHeight
+<< ", DeviceMm: " <<
szlMillimetersWidth << "x"
+<< szlMillimetersHeight);
+SAL_INFO("drawinglayer.emf", "EMF+ fPxPerMmX: " <<
fPxPerMmX << "x" << fPxPerMmY);
+SAL_INFO("drawinglayer.emf", "EMF+ Frame [0.01mm]: ["
+ << rclFrameLeft << ", " <<
rclFrameTop << ", "
+ << rclFrameRight << ", " <<
rclFrameBottom << "]");
SAL_INFO("drawinglayer.emf",
-"EMF+ Version:
core.git: Branch 'libreoffice-26-2' - drawinglayer/source emfio/qa svgio/qa
drawinglayer/source/tools/emfphelperdata.cxx | 75
++
drawinglayer/source/tools/emfpimage.cxx | 34
drawinglayer/source/tools/emfpimage.hxx | 12 +
drawinglayer/source/tools/primitive2dxmldump.cxx | 12 -
emfio/qa/cppunit/emf/EmfImportTest.cxx | 53
+++
emfio/qa/cppunit/emf/data/TestEmfPlusDrawImagePointsWithMetafile.emf |binary
svgio/qa/cppunit/SvgImportTest.cxx |8 -
7 files changed, 156 insertions(+), 38 deletions(-)
New commits:
commit 0afed6774e0fb39f99441c959f742e532dfaf764
Author: Bartosz Kosiorek
AuthorDate: Mon Feb 16 20:54:27 2026 +0100
Commit: Tomaž Vajngerl
CommitDate: Thu Mar 12 15:00:12 2026 +0100
tdf166084 tdf138087 tdf59814 EMF+ Fix scale and trans DrawImagePoints
Metafile
This commit fixes the incorrect positioning and scaling of Metafiles
rendered via EMF+ DrawImagePoints.
Key changes:
- Implemented a normalization matrix for Metafiles to properly map
source coordinates (SrcRect) to the destination.
- Updated EMFPImage to parse and store bounds from nested EMF headers,
ensuring correct dimensions (x, y, width, height) are available.
Change-Id: I07b4d99c334611a10e7faff42b76699f04fa1520
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201084
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek
(cherry picked from commit 4dccec254c0f3159356f9fb74c2f8863288331c6)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201163
Reviewed-by: Tomaž Vajngerl
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx
b/drawinglayer/source/tools/emfphelperdata.cxx
index ee8bcc0d29a9..ef4369f32372 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -30,19 +30,20 @@
#include
#include
#include
-#include
-#include
#include
#include
#include
#include
+#include
+#include
+#include
+#include
#include
#include
#include
#include
-#include
-#include
#include
+#include
#include
#include
#include
@@ -1542,11 +1543,8 @@ namespace emfplushelper
ReadPoint(rMS, x2, y2, flags); // upper-right
ReadPoint(rMS, x3, y3, flags); // lower-left
-SAL_INFO("drawinglayer.emf", "EMF+
destination points: "
-<< x1 << ","
<< y1 << " " << x2 << ","
-<< y2 << " "
<< x3 << "," << y3);
dx = x1;
-dy = y2;
+dy = y1;
dw = x2 - x1;
dh = y3 - y1;
fShearX = x3 - x1;
@@ -1556,7 +1554,7 @@ namespace emfplushelper
ReadRectangle(rMS, dx, dy, dw, dh, bool(flags
& 0x4000));
SAL_INFO("drawinglayer.emf",
-"EMF+ Rectangle: " << dx << "," <<
dy << " " << dw << "x" << dh);
+"EMF+ Destination rectangle: " << dx
<< "," << dy << " " << dw << "x" << dh);
Size aSize;
if (image->type == ImageDataTypeBitmap)
{
@@ -1588,22 +1586,15 @@ namespace emfplushelper
else if (sy + sh > aSize.Height())
dh = ((aSize.Height() - sy) / sh) * dh;
}
-else
-SAL_INFO(
-"drawinglayer.emf",
-"EMF+ TODO: Add support for SrcRect
to ImageDataTypeMetafile");
-const ::basegfx::B2DPoint aDstPoint(dx, dy);
-const ::basegfx::B2DSize aDstSize(dw, dh);
-
-const basegfx::B2DHomMatrix aTransformMatrix
-= maMapTransform
-* basegfx::B2DHomMatrix(
-/* Row 0, Column 0 */ aDstSize.getWidth(),
+
+const basegfx::B2DHomMatrix aDestMatrix =
+maMapTransform * basegfx::B2DHomMatrix(
+/* Row 0, Column 0 */ dw,
/* Row 0, Column 1 */ fShearX,
-/* Row 0, Column 2 */ aDstPoint.getX(),
+/* Row 0, Column 2 */ dx,
/* Row 1, Column 0 */ fShearY,
-/* Row 1, Column 1 */ aDstSize.getHe
core.git: Branch 'libreoffice-26-2' - drawinglayer/source emfio/qa
drawinglayer/source/tools/emfpbrush.cxx| 18 ++
drawinglayer/source/tools/emfpbrush.hxx|4
drawinglayer/source/tools/emfphelperdata.cxx | 69
--
drawinglayer/source/tools/emfppen.cxx |4
drawinglayer/source/tools/emfppen.hxx |2
drawinglayer/source/tools/primitive2dxmldump.cxx | 27 +++
emfio/qa/cppunit/emf/EmfImportTest.cxx | 46
++
emfio/qa/cppunit/emf/data/TestEmfPlusFillRectsWithTextureBrush.emf |binary
8 files changed, 155 insertions(+), 15 deletions(-)
New commits:
commit 71b257e4faf940a300753ba3fb8156271d51f9b0
Author: Bartosz Kosiorek
AuthorDate: Tue Feb 24 23:23:28 2026 +0100
Commit: Bartosz Kosiorek
CommitDate: Mon Mar 2 20:36:46 2026 +0100
tdf#129342 tdf#170985 EMF+ Implement BrushTypeTextureFill for bitmaps
This patch implements the missing TextureFill brush support for EMF+
records. Previously, texture fills were ignored, resulting in missing
backgrounds or shapes.
Change-Id: I61f80a9851f3929651f54b68d6d4d21e65720aa6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200547
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek
(cherry picked from commit 6c05a6339c27038b14d2f35f8f4b2b94335d6491)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200780
diff --git a/drawinglayer/source/tools/emfpbrush.cxx
b/drawinglayer/source/tools/emfpbrush.cxx
index d64d76085dc5..51fce424b70a 100644
--- a/drawinglayer/source/tools/emfpbrush.cxx
+++ b/drawinglayer/source/tools/emfpbrush.cxx
@@ -60,7 +60,7 @@ namespace emfplushelper
return u""_ustr;
}
-void EMFPBrush::Read(SvStream& s, EmfPlusHelperData const & rR)
+void EMFPBrush::Read(SvMemoryStream& s, EmfPlusHelperData const & rR,
sal_uInt32 dataSize, bool bUseWholeStream)
{
sal_uInt32 header;
@@ -99,7 +99,21 @@ namespace emfplushelper
}
case BrushTypeTextureFill:
{
-SAL_WARN("drawinglayer.emf", "EMF+ TODO: implement
BrushTypeTextureFill brush");
+s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
+SAL_INFO("drawinglayer.emf", "EMF+
TextureFill, flags: 0x"
+<< std::hex << additionalFlags
<< std::dec
+<< ", wrapMode: " << wrapMode);
+
+if (additionalFlags & 0x02) // BrushDataTransform
+{
+EmfPlusHelperData::readXForm(s, brush_transformation);
+hasTransformation = true;
+SAL_INFO("drawinglayer.emf",
+ "EMF+ Use brush
transformation: " << brush_transformation);
+}
+
+textureImage = std::make_unique();
+textureImage->Read(s, dataSize, bUseWholeStream);
break;
}
case BrushTypePathGradient:
diff --git a/drawinglayer/source/tools/emfpbrush.hxx
b/drawinglayer/source/tools/emfpbrush.hxx
index aee3fe02f60e..d50df7176133 100644
--- a/drawinglayer/source/tools/emfpbrush.hxx
+++ b/drawinglayer/source/tools/emfpbrush.hxx
@@ -20,6 +20,7 @@
#pragma once
#include "emfphelperdata.hxx"
+#include "emfpimage.hxx"
#include
namespace emfplushelper
@@ -114,6 +115,7 @@ namespace emfplushelper
std::unique_ptr<::Color[]> surroundColors;
std::unique_ptr path;
EmfPlusHatchStyle hatchStyle;
+std::unique_ptr textureImage;
EMFPBrush();
virtual ~EMFPBrush() override;
@@ -121,7 +123,7 @@ namespace emfplushelper
sal_uInt32 GetType() const { return type; }
const ::Color& GetColor() const { return solidColor; }
-void Read(SvStream& s, EmfPlusHelperData const & rR);
+void Read(SvMemoryStream& s, EmfPlusHelperData const & rR, sal_uInt32
dataSize, bool bUseWholeStream);
};
}
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx
b/drawinglayer/source/tools/emfphelperdata.cxx
index a6cc2f65f679..ee8bcc0d29a9 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -28,11 +28,14 @@
#include "emfpfont.hxx"
#include "emfpstringformat.hxx"
#include
+#include
+#include
#include
#include
+#include
+#include
#include
#include
-#include
#include
#include
#include
@@ -40,7 +43,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -272,14 +274,14 @@ namespace emfplushelper
{
EMFPBrush *brush = new EMFPBrush();
maEMFPObjects[index].reset(brush);
-brush->Read(rObjectStream, *this);
+brush->Read(rObjectStream, *this, dataSize, bUseWholeStream);
core.git: Branch 'libreoffice-26-2' - drawinglayer/source emfio/qa
drawinglayer/source/tools/emfphelperdata.cxx | 28 +++-
drawinglayer/source/tools/emfphelperdata.hxx |3
emfio/qa/cppunit/emf/EmfImportTest.cxx| 44 --
emfio/qa/cppunit/emf/data/TestEmfPlusSetPageTransform.emf |binary
4 files changed, 50 insertions(+), 25 deletions(-)
New commits:
commit 16249173928b18ab2ae91fd8c53045790be21a28
Author: Bartosz Kosiorek
AuthorDate: Sat Feb 14 18:22:57 2026 +0100
Commit: Xisco Fauli
CommitDate: Thu Feb 19 10:04:35 2026 +0100
tdf#168227 EMF+ Fix implementation of SetPageTransform
The implementation of SetPageTransform was incorrectly overwriting mnMmX
and mnMmY
with calculated pixel values.
These variables represent the Reference Device size from the EMF+ header
and should
remain constant. Overwriting them causes mappingChanged() to calculate an
incorrect
transformation matrix, as it relies on the original ratio between reference
millimeters and pixels. This led to incorrect scaling and cumulative errors
if multiple SetPageTransform records were present in the document.
This patch ensures that header constants are preserved and the Page Scale
is applied as a separate step in the transformation pipeline.
Change-Id: I7a957f57894cc079292e8f93c119dd0fdb456fb4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199380
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek
(cherry picked from commit 8b002437fbe29d5bac7ab0358a4e838a140d4e3c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199407
Reviewed-by: Xisco Fauli
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx
b/drawinglayer/source/tools/emfphelperdata.cxx
index 94cf9500c98a..a6cc2f65f679 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -442,6 +442,7 @@ namespace emfplushelper
// To evtl. correct and see where this came from, please compare with
the implementations
// of EmfPlusHelperData::MapToDevice and EmfPlusHelperData::Map* in
prev versions
maMapTransform = maWorldTransform;
+maMapTransform.scale(mfPageScaleX, mfPageScaleY);
maMapTransform *=
basegfx::utils::createScaleTranslateB2DHomMatrix(100.0 * mnMmX / mnPixX, 100.0
* mnMmY / mnPixY,
double(-mnFrameLeft), double(-mnFrameTop));
maMapTransform *= maBaseTransform;
@@ -906,7 +907,8 @@ namespace emfplushelper
SvMemoryStream& rMS,
wmfemfhelper::TargetHolders& rTargetHolders,
wmfemfhelper::PropertyHolders& rPropertyHolders)
-: mfPageScale(0.0),
+: mfPageScaleX(1.0),
+mfPageScaleY(1.0),
mnOriginX(0),
mnOriginY(0),
mnHDPI(0),
@@ -1750,19 +1752,14 @@ namespace emfplushelper
}
case EmfPlusRecordTypeSetPageTransform:
{
-rMS.ReadFloat(mfPageScale);
-SAL_INFO("drawinglayer.emf", "EMF+ Scale: " <<
mfPageScale << " unit: " << UnitTypeToString(flags));
+float pageScale;
+rMS.ReadFloat(pageScale);
+SAL_INFO("drawinglayer.emf", "EMF+ Scale: " <<
pageScale << " unit: " << UnitTypeToString(flags));
+
+mfPageScaleX = unitToPixel(pageScale, flags,
Direction::horizontal);
+mfPageScaleY = unitToPixel(pageScale, flags,
Direction::vertical);
+mappingChanged();
-if ((flags == UnitTypeDisplay) || (flags ==
UnitTypeWorld))
-{
-SAL_WARN("drawinglayer.emf", "EMF+ file error.
UnitTypeDisplay and UnitTypeWorld are not supported by SetPageTransform in EMF+
specification.");
-}
-else
-{
-mnMmX =
std::round(unitToPixel(static_cast(mnMmX) * mfPageScale, flags,
Direction::horizontal));
-mnMmY =
std::round(unitToPixel(static_cast(mnMmY) * mfPageScale, flags,
Direction::vertical));
-mappingChanged();
-}
break;
}
case EmfPlusRecordTypeSetRenderingOrigin:
@@ -1846,11 +1843,6 @@ namespace emfplushelper
rMS.ReadUInt32(stackIndex);
SAL_INFO("drawinglayer.emf", "EMF+ Begin
Container stack index: " << stackIndex << ", PageUnit: " << flags);
-if ((flags == UnitTypeDisplay) || (flags ==
UnitTypeWorld))
-{
-SAL_WARN("drawinglayer.emf", "EMF+ file error.
UnitTypeDisplay and UnitTypeWorld are not supported by BeginContainer in EMF+
specifica
core.git: Branch 'libreoffice-26-2' - drawinglayer/source
drawinglayer/source/primitive2d/textprimitive2d.cxx |5 + 1 file changed, 1 insertion(+), 4 deletions(-) New commits: commit 7c3a9cb27b5c2ce268c68730bcc0b68adb70e5d8 Author: Xisco Fauli AuthorDate: Tue Dec 9 16:52:22 2025 +0100 Commit: Xisco Fauli CommitDate: Thu Dec 11 09:29:19 2025 +0100 tdf#169730: partially revert the fix for tdf#168452 Revert the problematic part from e5f0dad2b38d2a3902a9cd6b9d434abc206590a4 "tdf#168452: support unicode-bidi in svg" until a better solution is found Change-Id: If21b0c38b5fd8bdade0538e4960353d156e17e2a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195307 Tested-by: Jenkins Reviewed-by: Xisco Fauli (cherry picked from commit d3df96b5482d10aa4c74c00d21fb3fcddeb6edd0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195351 diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx b/drawinglayer/source/primitive2d/textprimitive2d.cxx index ae1b049db574..b16c530f04c2 100644 --- a/drawinglayer/source/primitive2d/textprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx @@ -348,10 +348,7 @@ void TextSimplePortionPrimitive2D::createTextLayouter(TextLayouterDevice& rTextL // tdf#101686: This is LTR text, but the output device may have RTL state. vcl::text::ComplexTextLayoutFlags nLTRLayoutMode(rTextLayouter.getLayoutMode()); nLTRLayoutMode = nLTRLayoutMode & ~vcl::text::ComplexTextLayoutFlags::BiDiRtl; -if (getFontAttribute().getBiDiStrong()) -nLTRLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiStrong; -else -nLTRLayoutMode = nLTRLayoutMode & ~vcl::text::ComplexTextLayoutFlags::BiDiStrong; +nLTRLayoutMode = nLTRLayoutMode & ~vcl::text::ComplexTextLayoutFlags::BiDiStrong; rTextLayouter.setLayoutMode(nLTRLayoutMode); } }
