emfio/qa/cppunit/emf/EmfImportTest.cxx | 22 +++++++++++----------- emfio/source/reader/emfreader.cxx | 12 ++++-------- 2 files changed, 15 insertions(+), 19 deletions(-)
New commits: commit aa616d930e7078b4226203c7c894e382c6f449b8 Author: Andras Timar <[email protected]> AuthorDate: Sun Feb 8 16:46:30 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Mon Feb 9 06:43:06 2026 +0100 Revert tdf#159306 EMF: fix PS_COSMETIC pen width regression Commit be9d6e414e4b forced all PS_COSMETIC pen widths to 1 in both EMR_CREATEPEN and EMR_EXTCREATEPEN handlers. Since PS_COSMETIC is 0x00000000 (same value as PS_SOLID), the check "if (nPenStyle == PS_COSMETIC)" matched every simple PS_SOLID pen, causing all line widths to be lost. This made all lines render as hairlines regardless of the actual width specified in the EMF file. The style sanitization check for invalid PS_STYLE_MASK values is retained, but the width forcing is removed. Pen widths from the file are now used as-is: width=0 produces a hairline, width>=1 produces a scaled line. This effectively reverts to the behavior established by tdf#140271 (commit 8932c8906ff3), which recognized that real-world EMF producers use EMR_CREATEPEN with widths > 1 and expect them to be honored. Change-Id: I9a3acf83ce03b4e646e9b95fe0db54f8ce403a49 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198904 Reviewed-by: Andras Timar <[email protected]> Tested-by: Jenkins diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 7dcb76160772..659424d97de8 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -1600,7 +1600,7 @@ CPPUNIT_TEST_FIXTURE(Test, testRoundRect) CPPUNIT_TEST_FIXTURE(Test, testCreatePen) { // Check import of EMF image with records: RESTOREDC, SAVEDC, MOVETOEX, LINETO, POLYLINE16, EXTTEXTOUTW with DxBuffer - // The CREATEPEN record is used with PS_COSMETIC line style, and in this case width must be set to 0 + // The CREATEPEN record is used with PS_COSMETIC line style, which sometimes will be displayed as solid hairline Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestCreatePen.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; @@ -1609,23 +1609,23 @@ CPPUNIT_TEST_FIXTURE(Test, testCreatePen) assertXPath(pDocument, aXPathPrefix + "mask/polypolygon", "path", u"m0 0h31250v18192h-31250z"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke", 758); + assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke", 748); assertXPathContent(pDocument, aXPathPrefix + "mask/polygonstroke[1]/polygon", - u"0,0 31225,0 31225,17742 0,17742"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[1]/line", "color", u"#ffffff"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[1]/line", "width", u"25"); + u"27875,16523 27875,1453"); + assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[1]/line", "color", u"#ff0000"); + assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[1]/line", "width", u"6"); assertXPathContent(pDocument, aXPathPrefix + "mask/polygonstroke[2]/polygon", - u"25,23 31200,23 31200,17719 25,17719"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[2]/line", "color", u"#ffffff"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[2]/line", "width", u"25"); + u"27975,16453 27875,16453"); + assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[2]/line", "color", u"#ff0000"); + assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[2]/line", "width", u"6"); assertXPathContent(pDocument, aXPathPrefix + "mask/polygonstroke[3]/polygon", - u"27875,16523 27875,1453"); + u"27925,16078 27875,16078"); assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[3]/line", "color", u"#ff0000"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[3]/line", "width", u"3"); + assertXPath(pDocument, aXPathPrefix + "mask/polygonstroke[3]/line", "width", u"6"); - assertXPath(pDocument, aXPathPrefix + "mask/polygonhairline", 0); + assertXPath(pDocument, aXPathPrefix + "mask/polygonhairline", 10); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion", 69); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "width", u"374"); diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx index b78e028cf283..310033fd1763 100644 --- a/emfio/source/reader/emfreader.cxx +++ b/emfio/source/reader/emfreader.cxx @@ -1260,10 +1260,8 @@ namespace emfio SAL_INFO("emfio", " Index: " << nIndex << " Style: 0x" << std::hex << nPenStyle << std::dec << " PenWidth: " << nPenWidth); - // PS_COSMETIC width is always fixed at one logical unit - // and is not affected by any geometric transformations like scaling - if (nPenStyle == PS_COSMETIC) - nPenWidth = 1; + if ((nPenStyle & PS_STYLE_MASK) > PS_INSIDEFRAME) + nPenStyle = PS_COSMETIC; CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>(ReadColor(), nPenStyle, nPenWidth)); } } @@ -1286,10 +1284,8 @@ namespace emfio else { SAL_INFO("emfio", " Style: 0x" << std::hex << nPenStyle << std::dec); - // PS_COSMETIC width is always fixed at one logical unit - // and is not affected by any geometric transformations like scaling - if (nPenStyle == PS_COSMETIC) - nWidth = 1; + if ((nPenStyle & PS_STYLE_MASK) > PS_INSIDEFRAME) + nPenStyle = PS_COSMETIC; SAL_INFO("emfio", " Width: " << nWidth); CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>(aColorRef, nPenStyle, nWidth)); }
