From d750944db62ed5dbaaf610080092305c9b6a92ecd37fe7f757daa086505c81f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Wed, 27 May 2020 07:11:11 +0000 Subject: [PATCH] Accepting request 809054 from LibreOffice:6.4 - Fix bsc#1165849 - LO-L3: Shadow size for rectangle is only a fraction of Office 365 * bsc1165849-1.diff * bsc1165849-2.diff * bsc1165849-3.diff OBS-URL: https://build.opensuse.org/request/show/809054 OBS-URL: https://build.opensuse.org/package/show/LibreOffice:Factory/libreoffice?expand=0&rev=882 --- bsc1165849-1.diff | 132 +++++++++++++++++++++++++++++++++ bsc1165849-2.diff | 141 ++++++++++++++++++++++++++++++++++++ bsc1165849-3.diff | 173 ++++++++++++++++++++++++++++++++++++++++++++ libreoffice.changes | 8 ++ libreoffice.spec | 7 ++ 5 files changed, 461 insertions(+) create mode 100644 bsc1165849-1.diff create mode 100644 bsc1165849-2.diff create mode 100644 bsc1165849-3.diff diff --git a/bsc1165849-1.diff b/bsc1165849-1.diff new file mode 100644 index 0000000..3ddb4ae --- /dev/null +++ b/bsc1165849-1.diff @@ -0,0 +1,132 @@ +From b4ed373a15b1e8d90c94ec7030ee3d3785f7e8f9 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 8 May 2020 16:43:22 +0200 +Subject: [PATCH] Related: tdf#129916 svx: improve shadow size of custom shapes + +There are multiple problems with this bug document, the first is that +the shadow primitive got the default position (0) of the owning shape. +Do it the same way as commit 6454b6336b8de9a4c5899adeab552af6f794cdc4 +(tdf#130058 Import shadow size., 2020-04-14) did for graphic objects. + +This requires constructing a transform matrix in +ViewContactOfSdrObjCustomShape::createViewIndependentPrimitive2DSequence(), +include position and size in that as a start. + +(cherry picked from commit e2b0e614e1185c960b3015414919f69a1ed35aa0) + +Change-Id: Ia51df555c1984971afe7c52ba3f2658099a4e7b3 +--- + .../primitive2d/sdrcustomshapeprimitive2d.hxx | 5 ++++- + .../viewcontactofsdrobjcustomshape.cxx | 19 +++++++++++++------ + .../primitive2d/sdrcustomshapeprimitive2d.cxx | 14 +++++++++++--- + 3 files changed, 28 insertions(+), 10 deletions(-) + +diff --git a/svx/inc/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx b/svx/inc/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx +index 285185684f15..84488906470a 100644 +--- a/svx/inc/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx ++++ b/svx/inc/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx +@@ -47,6 +47,8 @@ namespace drawinglayer + // making exceptions with shadow generation + bool const mb3DShape : 1; + ++ basegfx::B2DHomMatrix maTransform; ++ + protected: + // local decomposition. + virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& aViewInformation) const override; +@@ -57,7 +59,8 @@ namespace drawinglayer + const Primitive2DContainer& rSubPrimitives, + const basegfx::B2DHomMatrix& rTextBox, + bool bWordWrap, +- bool b3DShape); ++ bool b3DShape, ++ const basegfx::B2DHomMatrix& rObjectMatrix); + + // data access + const attribute::SdrShadowTextAttribute& getSdrSTAttribute() const { return maSdrSTAttribute; } +diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx +index 8630b6dd1923..7a5c0487a13f 100644 +--- a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx ++++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx +@@ -157,13 +157,13 @@ namespace sdr + basegfx::B2DHomMatrix aTextBoxMatrix; + bool bWordWrap(false); + ++ // take unrotated snap rect as default, then get the ++ // unrotated text box. Rotation needs to be done centered ++ const tools::Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); ++ const basegfx::B2DRange aObjectRange = vcl::unotools::b2DRectangleFromRectangle(aObjectBound); ++ + if(bHasText) + { +- // take unrotated snap rect as default, then get the +- // unrotated text box. Rotation needs to be done centered +- const tools::Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); +- const basegfx::B2DRange aObjectRange = vcl::unotools::b2DRectangleFromRectangle(aObjectBound); +- + // #i101684# get the text range unrotated and absolute to the object range + const basegfx::B2DRange aTextRange(getCorrectedTextBoundRect()); + +@@ -238,6 +238,12 @@ namespace sdr + bWordWrap = GetCustomShapeObj().GetMergedItem(SDRATTR_TEXT_WORDWRAP).GetValue(); + } + ++ // fill object matrix ++ const basegfx::B2DHomMatrix aObjectMatrix(basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix( ++ aObjectRange.getWidth(), aObjectRange.getHeight(), ++ /*fShearX=*/0, /*fRotate=*/0, ++ aObjectRange.getMinX(), aObjectRange.getMinY())); ++ + // create primitive + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrCustomShapePrimitive2D( +@@ -245,7 +251,8 @@ namespace sdr + xGroup, + aTextBoxMatrix, + bWordWrap, +- b3DShape)); ++ b3DShape, ++ aObjectMatrix)); + xRetval = drawinglayer::primitive2d::Primitive2DContainer { xReference }; + } + +diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx +index fb3018f7ff88..3e0350aaf56c 100644 +--- a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx ++++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx +@@ -68,7 +68,13 @@ namespace drawinglayer + // shadow will be correct (using ColorModifierStack), but expensive. + if(!get3DShape()) + { +- aRetval = createEmbeddedShadowPrimitive(aRetval, getSdrSTAttribute().getShadow()); ++ basegfx::B2DTuple aScale; ++ basegfx::B2DTuple aTranslate; ++ double fRotate = 0; ++ double fShearX = 0; ++ maTransform.decompose(aScale, aTranslate, fRotate, fShearX); ++ aRetval = createEmbeddedShadowPrimitive(aRetval, getSdrSTAttribute().getShadow(), ++ aTranslate.getX(), aTranslate.getY()); + } + } + +@@ -80,13 +86,15 @@ namespace drawinglayer + const Primitive2DContainer& rSubPrimitives, + const basegfx::B2DHomMatrix& rTextBox, + bool bWordWrap, +- bool b3DShape) ++ bool b3DShape, ++ const basegfx::B2DHomMatrix& rTransform) + : BufferedDecompositionPrimitive2D(), + maSdrSTAttribute(rSdrSTAttribute), + maSubPrimitives(rSubPrimitives), + maTextBox(rTextBox), + mbWordWrap(bWordWrap), +- mb3DShape(b3DShape) ++ mb3DShape(b3DShape), ++ maTransform(rTransform) + { + } + +-- +2.26.1 + diff --git a/bsc1165849-2.diff b/bsc1165849-2.diff new file mode 100644 index 0000000..78f5713 --- /dev/null +++ b/bsc1165849-2.diff @@ -0,0 +1,141 @@ +From f9dcb113bc2f81ef6abd2044d8512cd4e02f176c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 11 May 2020 10:10:34 +0200 +Subject: [PATCH] Related: tdf#129916 svx: clean up duplicated matrix decompose + for shadow size + +Pass the object's transform matrix to createEmbeddedShadowPrimitive(), +this allows decomposing it only at a single place. Also, this will allow +creating the shadow based on the object size. + +(cherry picked from commit 4ba368a3dd793bdc703858f358e1af7112decadd) + +Conflicts: + svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx + svx/source/sdr/primitive2d/sdrdecompositiontools.cxx + +Change-Id: I8d8bf59934b00e13cda1da0398910aa9f1ce3c59 +--- + .../svx/sdr/primitive2d/sdrdecompositiontools.hxx | 4 ++-- + .../sdr/primitive2d/sdrcustomshapeprimitive2d.cxx | 7 +------ + .../sdr/primitive2d/sdrdecompositiontools.cxx | 13 +++++++++---- + svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx | 8 +------- + 4 files changed, 13 insertions(+), 19 deletions(-) + +diff --git a/include/svx/sdr/primitive2d/sdrdecompositiontools.hxx b/include/svx/sdr/primitive2d/sdrdecompositiontools.hxx +index 844da339c111..8635981dc0ae 100644 +--- a/include/svx/sdr/primitive2d/sdrdecompositiontools.hxx ++++ b/include/svx/sdr/primitive2d/sdrdecompositiontools.hxx +@@ -21,6 +21,7 @@ + #define INCLUDED_SVX_SDR_PRIMITIVE2D_SDRDECOMPOSITIONTOOLS_HXX + + #include ++#include + + #include + +@@ -72,8 +73,7 @@ namespace drawinglayer + Primitive2DContainer SVX_DLLPUBLIC createEmbeddedShadowPrimitive( + const Primitive2DContainer& rContent, + const attribute::SdrShadowAttribute& rShadow, +- sal_Int32 nGraphicTranslateX = 0, +- sal_Int32 nGraphicTranslateY = 0); ++ const basegfx::B2DHomMatrix& rObjectMatrix = basegfx::B2DHomMatrix()); + + } // end of namespace primitive2d + } // end of namespace drawinglayer +diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx +index 3e0350aaf56c..2334b1d7fef6 100644 +--- a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx ++++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx +@@ -68,13 +68,8 @@ namespace drawinglayer + // shadow will be correct (using ColorModifierStack), but expensive. + if(!get3DShape()) + { +- basegfx::B2DTuple aScale; +- basegfx::B2DTuple aTranslate; +- double fRotate = 0; +- double fShearX = 0; +- maTransform.decompose(aScale, aTranslate, fRotate, fShearX); + aRetval = createEmbeddedShadowPrimitive(aRetval, getSdrSTAttribute().getShadow(), +- aTranslate.getX(), aTranslate.getY()); ++ maTransform); + } + } + +diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +index d6822bfd1519..42c0bb60ecc9 100644 +--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx ++++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + + using namespace com::sun::star; +@@ -482,8 +483,7 @@ namespace drawinglayer + Primitive2DContainer createEmbeddedShadowPrimitive( + const Primitive2DContainer& rContent, + const attribute::SdrShadowAttribute& rShadow, +- sal_Int32 nGraphicTranslateX, +- sal_Int32 nGraphicTranslateY) ++ const basegfx::B2DHomMatrix& rObjectMatrix) + { + if(!rContent.empty()) + { +@@ -493,10 +493,15 @@ namespace drawinglayer + { + if(rShadow.getSize().getX() != 100000) + { ++ basegfx::B2DTuple aScale; ++ basegfx::B2DTuple aTranslate; ++ double fRotate = 0; ++ double fShearX = 0; ++ rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + // Scale the shadow +- aShadowOffset.translate(-nGraphicTranslateX, -nGraphicTranslateY); ++ aShadowOffset.translate(-aTranslate.getX(), -aTranslate.getY()); + aShadowOffset.scale(rShadow.getSize().getX() * 0.00001, rShadow.getSize().getY() * 0.00001); +- aShadowOffset.translate(nGraphicTranslateX, nGraphicTranslateY); ++ aShadowOffset.translate(aTranslate.getX(), aTranslate.getY()); + } + + aShadowOffset.translate(rShadow.getOffset().getX(), rShadow.getOffset().getY()); +diff --git a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx +index 676b26183b09..be25a1278e64 100644 +--- a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx ++++ b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx +@@ -35,7 +35,6 @@ namespace drawinglayer + void SdrGrafPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DContainer aRetval; +- basegfx::B2DTuple aTranslateGrf; + + // create unit outline polygon + const basegfx::B2DPolygon& aUnitOutline(basegfx::utils::createUnitPolygon()); +@@ -62,10 +61,6 @@ namespace drawinglayer + getTransform(), + getGraphicObject(), + getGraphicAttr())); +- double fRotate = 0; +- double fShearX = 0; +- basegfx::B2DTuple aScaleGrf; +- getTransform().decompose(aScaleGrf, aTranslateGrf, fRotate, fShearX); + aRetval.push_back(xGraphicContentPrimitive); + } + +@@ -127,8 +122,7 @@ namespace drawinglayer + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow(), +- aTranslateGrf.getX(), +- aTranslateGrf.getY()); ++ getTransform()); + } + + rContainer.insert(rContainer.end(), aRetval.begin(), aRetval.end()); +-- +2.26.1 + diff --git a/bsc1165849-3.diff b/bsc1165849-3.diff new file mode 100644 index 0000000..fe30a82 --- /dev/null +++ b/bsc1165849-3.diff @@ -0,0 +1,173 @@ +From 74f3a7b9161ede870fbe2642158601ea3eaa073e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 20 Nov 2019 10:18:37 +0100 +Subject: [PATCH] drawinglayer: handle more primitives in the xml dump + +In preparation of writing a test for semi-transparent shape text. + +Change-Id: I2dac94a6cd9da48de9a5e407ceab78fb8be933d7 +Reviewed-on: https://gerrit.libreoffice.org/83264 +Reviewed-by: Miklos Vajna +Tested-by: Jenkins +(cherry picked from commit b6d794e14e65697fbf47a5b425d9d264e26e0161) + +tdf#129916 svx: fix origin of scaled shadow + +We assumed that the top left corner is the origin for scaling, but that +is not necessarily the case. The intention is that the shadow direction +can be determined from its x and y offset, and the origin is the +opposite corner of the shape. + +(cherry picked from commit e21d522dddce2590ed435890ae8d5fe39658a71a) + +Conflicts: + svx/CppunitTest_svx_unit.mk + +Change-Id: I6759302767d20739b6e2be79d379740dd06f70f5 +--- + .../source/tools/primitive2dxmldump.cxx | 83 ++++++++++++++- + svx/qa/unit/sdr.cxx | 96 ++++++++++++++++++ + .../sdr/primitive2d/sdrdecompositiontools.cxx | 14 ++- + 4 files changed, 189 insertions(+), 4 deletions(-) + create mode 100644 svx/qa/unit/data/shadow-scale-origin.pptx + create mode 100644 svx/qa/unit/sdr.cxx + +diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx +index 65170ae096f2..64117de878bd 100644 +--- a/drawinglayer/source/tools/primitive2dxmldump.cxx ++++ b/drawinglayer/source/tools/primitive2dxmldump.cxx +@@ -34,6 +34,7 @@ + + #include + #include ++#include + + using namespace drawinglayer::primitive2d; + +@@ -155,7 +156,7 @@ void Primitive2dXmlDump::decomposeAndWrite( + if (!pBasePrimitive) + continue; + sal_uInt32 nId = pBasePrimitive->getPrimitive2DID(); +- if (maFilter[nId]) ++ if (nId < maFilter.size() && maFilter[nId]) + continue; + + OUString sCurrentElementTag = drawinglayer::primitive2d::idToString(nId); +@@ -336,9 +337,87 @@ void Primitive2dXmlDump::decomposeAndWrite( + + break; + ++ case PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D: ++ { ++ // SdrRectanglePrimitive2D is private to us. ++ rWriter.startElement("sdrrectangle"); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); ++ break; ++ } ++ ++ case PRIMITIVE2D_ID_SDRBLOCKTEXTPRIMITIVE2D: ++ { ++ // SdrBlockTextPrimitive2D is private to us. ++ rWriter.startElement("sdrblocktext"); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); ++ break; ++ } ++ ++ case PRIMITIVE2D_ID_TEXTHIERARCHYBLOCKPRIMITIVE2D: ++ { ++ // TextHierarchyBlockPrimitive2D. ++ rWriter.startElement("texthierarchyblock"); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); ++ break; ++ } ++ ++ case PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D: ++ { ++ // TextHierarchyParagraphPrimitive2D. ++ rWriter.startElement("texthierarchyparagraph"); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); ++ break; ++ } ++ ++ case PRIMITIVE2D_ID_TEXTHIERARCHYLINEPRIMITIVE2D: ++ { ++ // TextHierarchyLinePrimitive2D. ++ rWriter.startElement("texthierarchyline"); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); ++ break; ++ } ++ ++ case PRIMITIVE2D_ID_SHADOWPRIMITIVE2D: ++ { ++ // ShadowPrimitive2D. ++ rWriter.startElement("shadow"); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); ++ break; ++ } ++ + default: + { +- rWriter.element(OUStringToOString(sCurrentElementTag, RTL_TEXTENCODING_UTF8)); ++ rWriter.startElement("unhandled"); ++ rWriter.attribute("id", OUStringToOString(sCurrentElementTag, RTL_TEXTENCODING_UTF8)); ++ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; ++ pBasePrimitive->get2DDecomposition(aPrimitiveContainer, ++ drawinglayer::geometry::ViewInformation2D()); ++ decomposeAndWrite(aPrimitiveContainer, rWriter); ++ rWriter.endElement(); + } + break; + } +diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +index 42c0bb60ecc9..48575d3b4917 100644 +--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx ++++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +@@ -499,9 +499,19 @@ namespace drawinglayer + double fShearX = 0; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + // Scale the shadow +- aShadowOffset.translate(-aTranslate.getX(), -aTranslate.getY()); ++ double nTranslateX = aTranslate.getX(); ++ double nTranslateY = aTranslate.getY(); ++ ++ // The origin for scaling is the top left corner by default. A negative ++ // shadow offset changes the origin. ++ if (rShadow.getOffset().getX() < 0) ++ nTranslateX += aScale.getX(); ++ if (rShadow.getOffset().getY() < 0) ++ nTranslateY += aScale.getY(); ++ ++ aShadowOffset.translate(-nTranslateX, -nTranslateY); + aShadowOffset.scale(rShadow.getSize().getX() * 0.00001, rShadow.getSize().getY() * 0.00001); +- aShadowOffset.translate(aTranslate.getX(), aTranslate.getY()); ++ aShadowOffset.translate(nTranslateX, nTranslateY); + } + + aShadowOffset.translate(rShadow.getOffset().getX(), rShadow.getOffset().getY()); +-- +2.26.1 + diff --git a/libreoffice.changes b/libreoffice.changes index 4fb4338..4f57ba0 100644 --- a/libreoffice.changes +++ b/libreoffice.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue May 26 11:25:10 UTC 2020 - Andras Timar + +- Fix bsc#1165849 - LO-L3: Shadow size for rectangle is only a fraction of Office 365 + * bsc1165849-1.diff + * bsc1165849-2.diff + * bsc1165849-3.diff + ------------------------------------------------------------------- Thu May 21 09:12:27 UTC 2020 - Tomáš Chvátal diff --git a/libreoffice.spec b/libreoffice.spec index 24ff169..70c85e4 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -111,6 +111,10 @@ Patch14: bsc1160687-5.diff Patch15: bsc1160687-6.diff Patch16: bsc1160687-7.diff Patch17: bsc1160687-8.diff +# Bug 1165849 - LO-L3: Shadow size for rectangle is only a fraction of Office 365 +Patch18: bsc1165849-1.diff +Patch19: bsc1165849-2.diff +Patch20: bsc1165849-3.diff # try to save space by using hardlinks Patch990: install-with-hardlinks.diff # save time by relying on rpm check rather than doing stupid find+grep @@ -977,6 +981,9 @@ Provides %{langname} translations and additional resources (help files, etc.) fo %patch15 -p1 %patch16 -p1 %patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 %patch990 -p1 %patch991 -p1