[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 4 commits - cui/qa cui/source cui/uiconfig include/svx oox/CppunitTest_oox_drawingml.mk oox/Module_oox.mk oox/qa oox/source sd/source sw/CppunitTest_sw_core_text.mk sw/inc sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon May 11 08:07:19 UTC 2020


 cui/qa/uitest/dialogs/chardlg.py                 |   49 +++++++++++
 cui/source/inc/chardlg.hxx                       |    3 
 cui/source/tabpages/chardlg.cxx                  |   40 ++++++++-
 cui/uiconfig/ui/effectspage.ui                   |   30 ++++++
 include/svx/flagsdef.hxx                         |    1 
 oox/CppunitTest_oox_drawingml.mk                 |   45 ++++++++++
 oox/Module_oox.mk                                |    1 
 oox/qa/unit/data/transparent-text.pptx           |binary
 oox/qa/unit/drawingml.cxx                        |  100 +++++++++++++++++++++++
 oox/source/drawingml/textcharacterproperties.cxx |   10 ++
 oox/source/export/drawingml.cxx                  |   12 ++
 oox/source/token/properties.txt                  |    1 
 sd/source/ui/dlg/dlgchar.cxx                     |    2 
 sw/CppunitTest_sw_core_text.mk                   |    1 
 sw/inc/unoprnms.hxx                              |    1 
 sw/qa/core/text/text.cxx                         |   32 +++++++
 sw/qa/extras/unowriter/unowriter.cxx             |   16 +++
 sw/source/core/text/inftxt.cxx                   |   75 +++++++++++++++++
 sw/source/core/unocore/unomap1.cxx               |    2 
 sw/source/core/unocore/unomapproperties.hxx      |    3 
 20 files changed, 421 insertions(+), 3 deletions(-)

New commits:
commit 8dcbd7aaca340b001b5c979ee097620de013588f
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Jan 6 20:35:08 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon May 11 09:58:30 2020 +0200

    sw: add rendering for semi-transparent text
    
    I considered passing the text color's alpha value down to the various
    vcl backends, but this would need changes everywhere (cairo, opengl, pdf
    export, etc). It's much easier to go via DrawTransparent(), that's how
    semi-transparent text in Draw/Impress already works.
    
    (cherry picked from commit bf540873f5e258452fed5006f65a403c95e7872a)
    
    Change-Id: I96f15e6764c3c88ba67dd72dc8708414d7c6050c

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index 9fe4fadbf357..cb901fde29f2 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -27,6 +27,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \
     test \
     unotest \
     utl \
+    vcl \
 ))
 
 $(eval $(call gb_CppunitTest_use_externals,sw_core_text,\
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 8074cbc9f45e..4e6d4fcdb14e 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -8,6 +8,9 @@
  */
 
 #include <swmodeltestbase.hxx>
+
+#include <vcl/gdimtf.hxx>
+
 #include <wrtsh.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/core/text/data/";
@@ -46,6 +49,35 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testFootnoteConnect)
     pWrtShell->DelLeft();
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testSemiTransparentText)
+{
+    // Create an in-memory empty document.
+    loadURL("private:factory/swriter", nullptr);
+
+    // Set text to half-transparent and type a character.
+    uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xParagraph.is());
+    sal_Int16 nTransparence = 50;
+    xParagraph->setPropertyValue("CharTransparence", uno::makeAny(nTransparence));
+    uno::Reference<text::XTextRange> xTextRange(xParagraph, uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xTextRange.is());
+    xTextRange->setString("x");
+
+    // Render the document to a metafile.
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    SwDocShell* pDocShell = pTextDoc->GetDocShell();
+    CPPUNIT_ASSERT(pDocShell);
+    std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
+    CPPUNIT_ASSERT(xMetaFile);
+
+    // Make sure that DrawTransparent() was used during rendering.
+    MetafileXmlDump dumper;
+    xmlDocPtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
+    CPPUNIT_ASSERT(pXmlDoc);
+    assertXPath(pXmlDoc, "//floattransparent");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 357360b69ec0..e9c6b6f2d1bc 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -73,6 +73,9 @@
 #include <unomid.h>
 #include <docsh.hxx>
 #include <strings.hrc>
+#include <vcl/gdimtf.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/gradient.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::linguistic2;
@@ -561,6 +564,71 @@ static bool lcl_IsDarkBackground( const SwTextPaintInfo& rInf )
     return pCol->IsDark();
 }
 
+namespace
+{
+/**
+ * Context class that captures the draw operations on rDrawInf's output device for transparency
+ * purposes.
+ */
+class SwTransparentTextGuard
+{
+    ScopedVclPtrInstance<VirtualDevice> m_aContentVDev;
+    GDIMetaFile m_aContentMetafile;
+    MapMode m_aNewMapMode;
+    SwRect m_aPorRect;
+    SwTextPaintInfo& m_rPaintInf;
+    SwDrawTextInfo& m_rDrawInf;
+
+public:
+    SwTransparentTextGuard(const SwLinePortion& rPor, SwTextPaintInfo& rPaintInf,
+                           SwDrawTextInfo& rDrawInf);
+    ~SwTransparentTextGuard();
+};
+
+SwTransparentTextGuard::SwTransparentTextGuard(const SwLinePortion& rPor,
+                                               SwTextPaintInfo& rPaintInf, SwDrawTextInfo& rDrawInf)
+    : m_aNewMapMode(rPaintInf.GetOut()->GetMapMode())
+    , m_rPaintInf(rPaintInf)
+    , m_rDrawInf(rDrawInf)
+{
+    rPaintInf.CalcRect(rPor, &m_aPorRect);
+    rDrawInf.SetOut(*m_aContentVDev);
+    m_aContentVDev->SetMapMode(rPaintInf.GetOut()->GetMapMode());
+    m_aContentMetafile.Record(m_aContentVDev.get());
+    m_aContentVDev->SetLineColor(rPaintInf.GetOut()->GetLineColor());
+    m_aContentVDev->SetFillColor(rPaintInf.GetOut()->GetFillColor());
+    m_aContentVDev->SetFont(rPaintInf.GetOut()->GetFont());
+    m_aContentVDev->SetDrawMode(rPaintInf.GetOut()->GetDrawMode());
+    m_aContentVDev->SetSettings(rPaintInf.GetOut()->GetSettings());
+    m_aContentVDev->SetRefPoint(rPaintInf.GetOut()->GetRefPoint());
+}
+
+SwTransparentTextGuard::~SwTransparentTextGuard()
+{
+    m_aContentMetafile.Stop();
+    m_aContentMetafile.WindStart();
+    m_aNewMapMode.SetOrigin(m_aPorRect.TopLeft());
+    m_aContentMetafile.SetPrefMapMode(m_aNewMapMode);
+    m_aContentMetafile.SetPrefSize(m_aPorRect.SSize());
+    m_rDrawInf.SetOut(*m_rPaintInf.GetOut());
+    Gradient aVCLGradient;
+    sal_uInt8 nTransPercentVcl = m_rPaintInf.GetFont()->GetColor().GetTransparency();
+    const Color aTransColor(nTransPercentVcl, nTransPercentVcl, nTransPercentVcl);
+    aVCLGradient.SetStyle(GradientStyle::Linear);
+    aVCLGradient.SetStartColor(aTransColor);
+    aVCLGradient.SetEndColor(aTransColor);
+    aVCLGradient.SetAngle(0);
+    aVCLGradient.SetBorder(0);
+    aVCLGradient.SetOfsX(0);
+    aVCLGradient.SetOfsY(0);
+    aVCLGradient.SetStartIntensity(100);
+    aVCLGradient.SetEndIntensity(100);
+    aVCLGradient.SetSteps(2);
+    m_rPaintInf.GetOut()->DrawTransparent(m_aContentMetafile, m_aPorRect.TopLeft(),
+                                          m_aPorRect.SSize(), aVCLGradient);
+}
+}
+
 void SwTextPaintInfo::DrawText_( const OUString &rText, const SwLinePortion &rPor,
                                 TextFrameIndex const nStart, TextFrameIndex const nLength,
                                 const bool bKern, const bool bWrong,
@@ -687,6 +755,13 @@ void SwTextPaintInfo::DrawText_( const OUString &rText, const SwLinePortion &rPo
             aFontPos.setY( 0 );
     }
 
+    // Handle semi-transparent text if necessary.
+    std::unique_ptr<SwTransparentTextGuard> pTransparentText;
+    if (m_pFnt->GetColor() != COL_AUTO && m_pFnt->GetColor().GetTransparency() != 0)
+    {
+        pTransparentText.reset(new SwTransparentTextGuard(rPor, *this, aDrawInf));
+    }
+
     if( GetTextFly().IsOn() )
     {
         // aPos needs to be the TopLeft, because we cannot calculate the
commit 237bd9763a353bdb54ecdc7d811fb85cb3b6cf49
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Jan 2 18:06:05 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon May 11 09:56:03 2020 +0200

    sw: add UNO API for semi-transparent text
    
    This makes the ODF filter work out of the box, since the same property
    was provided by Draw/Impress in the past already.
    
    (cherry picked from commit c48790b5cec73a49aed20c26b123c3656bb9eff9)
    
    Conflicts:
            sw/inc/unoprnms.hxx
    
    Change-Id: Ie6a053864c9fa41fad6ca4571d7d04a3756b7591

diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 91780b6530bd..eea6be637f62 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -125,6 +125,7 @@
 #define UNO_NAME_CHAR_DIFF_HEIGHT_COMPLEX "CharDiffHeightComplex"
 #define UNO_NAME_CHAR_ESCAPEMENT_HEIGHT "CharEscapementHeight"
 #define UNO_NAME_CHAR_COLOR "CharColor"
+#define UNO_NAME_CHAR_TRANSPARENCE "CharTransparence"
 #define UNO_NAME_HIDE_TAB_LEADER_AND_PAGE_NUMBERS "HideTabLeaderAndPageNumber"
 #define UNO_NAME_TAB_IN_TOC "TabInTOC"
 #define UNO_NAME_TOC_BOOKMARK "TOCBookmark"
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index a265bb29e728..d68b2b7ecf1d 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -895,6 +895,22 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf129839)
     CPPUNIT_ASSERT_EQUAL(css::uno::Any(css::text::VertOrientation::NONE), aOrient);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTransparentText)
+{
+    // Test the CharTransparence text portion property.
+
+    // Create a new document.
+    loadURL("private:factory/swriter", nullptr);
+
+    // Set a custom transparency.
+    uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY);
+    sal_Int16 nExpected = 42;
+    xParagraph->setPropertyValue("CharTransparence", uno::makeAny(nExpected));
+
+    // Get the transparency & verify.
+    CPPUNIT_ASSERT_EQUAL(nExpected, getProperty<sal_Int16>(xParagraph, "CharTransparence"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 7796adb8e798..4a8587ac81b9 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -231,6 +231,7 @@ const SfxItemPropertyMapEntry*  SwUnoPropertyMapProvider::GetCharStylePropertyMa
         { OUString(UNO_NAME_CHAR_HIGHLIGHT), RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
         { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP,     cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, 0},
         { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, 0},
+        { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},
         { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT,  cppu::UnoType<sal_Int16>::get(),                  PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
         { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT,  cppu::UnoType<bool>::get()  ,        PROPERTY_NONE, 0},
         { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT,  cppu::UnoType<sal_Int16>::get(),             PROPERTY_NONE, MID_ESC          },
@@ -292,6 +293,7 @@ const SfxItemPropertyMapEntry*  SwUnoPropertyMapProvider::GetAutoCharStyleProper
         { OUString(UNO_NAME_CHAR_HIGHLIGHT), RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
         { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP,     cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, 0},
         { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, 0},
+        { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},
         { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT,  cppu::UnoType<sal_Int16>::get(),                  PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
         { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT,  cppu::UnoType<bool>::get()  ,        PROPERTY_NONE, 0},
         { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT,  cppu::UnoType<sal_Int16>::get(),             PROPERTY_NONE, MID_ESC          },
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index bf75f3d133d6..0b211f392b67 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -121,6 +121,7 @@
         { OUString(UNO_NAME_PARA_BACK_COLOR),                     RES_BACKGROUND,                cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, MID_BACK_COLOR                         }, \
         { OUString(UNO_NAME_CHAR_CASE_MAP),                       RES_CHRATR_CASEMAP,            cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, 0                                      }, \
         { OUString(UNO_NAME_CHAR_COLOR),                          RES_CHRATR_COLOR,              cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, 0                                      }, \
+        { OUString(UNO_NAME_CHAR_TRANSPARENCE),                   RES_CHRATR_COLOR,              cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_COLOR_ALPHA }, \
         { OUString(UNO_NAME_CHAR_STRIKEOUT),                      RES_CHRATR_CROSSEDOUT,         cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_CROSS_OUT                          }, \
         { OUString(UNO_NAME_CHAR_CROSSED_OUT),                    RES_CHRATR_CROSSEDOUT,         cppu::UnoType<bool>::get(),       PropertyAttribute::MAYBEVOID, MID_CROSSED_OUT                        }, \
         { OUString(UNO_NAME_CHAR_ESCAPEMENT),                     RES_CHRATR_ESCAPEMENT,         cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, MID_ESC                                }, \
@@ -362,6 +363,7 @@
                     { OUString(UNO_NAME_PARA_GRAPHIC_LOCATION), RES_BACKGROUND,         cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION}, \
                     { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP,     cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, 0},\
                     { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, 0},\
+                    { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR,      cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, MID_COLOR_ALPHA},\
                     { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT,  cppu::UnoType<sal_Int16>::get(),                  PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},\
                     { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT,  cppu::UnoType<bool>::get()  ,        PROPERTY_NONE, 0},\
                     { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT,  cppu::UnoType<sal_Int16>::get(),             PROPERTY_NONE, MID_ESC          },\
@@ -466,6 +468,7 @@
 #define COMMON_ACCESSIBILITY_TEXT_ATTRIBUTE \
                     { OUString(UNO_NAME_CHAR_BACK_COLOR), RES_CHRATR_BACKGROUND,    cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE ,MID_BACK_COLOR        }, \
                     { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR,      cppu::UnoType<sal_Int32>::get(),           PROPERTY_NONE, 0},  \
+                    { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR,      cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE, MID_COLOR_ALPHA },  \
                     { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR,    cppu::UnoType<bool>::get()  ,       PROPERTY_NONE, 0},  \
                     { OUString(UNO_NAME_CHAR_EMPHASIS), RES_CHRATR_EMPHASIS_MARK,           cppu::UnoType<sal_Int16>::get(),   PROPERTY_NONE, MID_EMPHASIS},   \
                     { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT,  cppu::UnoType<sal_Int16>::get(),             PROPERTY_NONE, MID_ESC          },  \
commit b13886436dde34d33141138e7d1a20e7ca89c20b
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Nov 22 17:12:04 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon May 11 09:34:45 2020 +0200

    cui: add UI for semi-transparent shape text
    
    - Make font color only work with the RGB color, otherwise the preview
      would be white for e.g. half-transparent red.
    
    - Add label and widget to see already set transparency.
    
    - Add a flag to show these only for Draw/Impress and leave Writer/Calc
      unchanged.
    
    - Update returned item set to contain transparency in case the widget
      changes.
    
    (cherry picked from commit b4554b8eddd048532269df610e89ae739c46fab7)
    
    Change-Id: If77771076ff4b10a4a5d468a6583809a94deb57e

diff --git a/cui/qa/uitest/dialogs/chardlg.py b/cui/qa/uitest/dialogs/chardlg.py
new file mode 100644
index 000000000000..59cf10d18c29
--- /dev/null
+++ b/cui/qa/uitest/dialogs/chardlg.py
@@ -0,0 +1,49 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+
+# Test for cui/source/tabpages/chardlg.cxx.
+class Test(UITestCase):
+
+    def testSvxCharEffectsPage(self):
+        # Start Impress.
+        self.ui_test.create_doc_in_start_center("impress")
+        template = self.xUITest.getTopFocusWindow()
+        self.ui_test.close_dialog_through_button(template.getChild("cancel"))
+        doc = self.xUITest.getTopFocusWindow()
+        editWin = doc.getChild("impress_win")
+        # Select the title shape.
+        editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
+        editWin.executeAction("TYPE", mkPropertyValues({"TEXT": "t"}))
+        self.xUITest.executeCommand(".uno:SelectAll")
+
+        # Now use Format -> Character.
+        self.ui_test.execute_dialog_through_command(".uno:FontDialog")
+        xDialog = self.xUITest.getTopFocusWindow()
+        xTabs = xDialog.getChild("tabcontrol")
+        # Select RID_SVXPAGE_CHAR_EFFECTS.
+        select_pos(xTabs, "1")
+        xFontTransparency = xDialog.getChild("fonttransparencymtr")
+        for _ in range(5):
+            xFontTransparency.executeAction("UP", tuple())
+        self.ui_test.close_dialog_through_button(xDialog.getChild("ok"))
+
+        # Verify the result.
+        component = self.ui_test.get_component()
+        drawPage = component.getDrawPages().getByIndex(0)
+        shape = drawPage.getByIndex(0)
+
+        # Without the accompanying fix in place, this test would have failed with:
+        # AssertionError: 100 != 5
+        # i.e. the dialog did not set transparency to 5%, instead it left the character color at
+        # COL_AUTO.
+        self.assertEqual(shape.CharTransparence, 5)
+        self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx
index 9e4419d4406e..da382112af6f 100644
--- a/cui/source/inc/chardlg.hxx
+++ b/cui/source/inc/chardlg.hxx
@@ -171,6 +171,8 @@ private:
 
     std::unique_ptr<weld::Label> m_xFontColorFT;
     std::unique_ptr<ColorListBox> m_xFontColorLB;
+    std::unique_ptr<weld::Label> m_xFontTransparencyFT;
+    std::unique_ptr<weld::MetricSpinButton> m_xFontTransparencyMtr;
     std::unique_ptr<weld::Label> m_xEffectsFT;
     std::unique_ptr<weld::ComboBox> m_xEffectsLB;
     std::unique_ptr<weld::Label> m_xReliefFT;
@@ -207,6 +209,7 @@ private:
     DECL_LINK(TristClickHdl_Impl, weld::ToggleButton&, void);
     DECL_LINK(UpdatePreview_Impl, weld::ComboBox&, void);
     DECL_LINK(ColorBoxSelectHdl_Impl, ColorListBox&, void);
+    DECL_LINK(ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void);
 
 public:
     SvxCharEffectsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
index d7dca728de87..211ec9e15679 100644
--- a/cui/source/tabpages/chardlg.cxx
+++ b/cui/source/tabpages/chardlg.cxx
@@ -1319,6 +1319,9 @@ SvxCharEffectsPage::SvxCharEffectsPage(weld::Container* pPage, weld::DialogContr
     , m_bUnderlineColorDisabled(false)
     , m_xFontColorFT(m_xBuilder->weld_label("fontcolorft"))
     , m_xFontColorLB(new ColorListBox(m_xBuilder->weld_menu_button("fontcolorlb"), pController->getDialog()))
+    , m_xFontTransparencyFT(m_xBuilder->weld_label("fonttransparencyft"))
+    , m_xFontTransparencyMtr(
+          m_xBuilder->weld_metric_spin_button("fonttransparencymtr", FieldUnit::PERCENT))
     , m_xEffectsFT(m_xBuilder->weld_label("effectsft"))
     , m_xEffectsLB(m_xBuilder->weld_combo_box("effectslb"))
     , m_xReliefFT(m_xBuilder->weld_label("reliefft"))
@@ -1370,6 +1373,7 @@ SvxCharEffectsPage::~SvxCharEffectsPage()
 {
     m_xUnderlineColorLB.reset();
     m_xOverlineColorLB.reset();
+    m_xFontTransparencyMtr.reset();
     m_xFontColorLB.reset();
 }
 
@@ -1393,6 +1397,8 @@ void SvxCharEffectsPage::Initialize()
     }
 
     m_xFontColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+    m_xFontTransparencyMtr->connect_value_changed(
+        LINK(this, SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl));
 
     // handler
     Link<weld::ComboBox&,void> aLink = LINK( this, SvxCharEffectsPage, SelectListBoxHdl_Impl );
@@ -1558,7 +1564,19 @@ void SvxCharEffectsPage::ResetColor_Impl( const SfxItemSet& rSet )
 
             m_aPreviewWin.Invalidate();
 
-            m_xFontColorLB->SelectEntry(aColor);
+            Color aRGBColor = aColor;
+            if (aRGBColor.GetTransparency())
+            {
+                aRGBColor.SetTransparency(0);
+            }
+            m_xFontColorLB->SelectEntry(aRGBColor);
+
+            if (m_xFontTransparencyMtr->get_visible() && aColor != COL_AUTO)
+            {
+                double fTransparency = aColor.GetTransparency() * 100.0 / 255;
+                m_xFontTransparencyMtr->set_value(basegfx::fround(fTransparency),
+                                                  FieldUnit::PERCENT);
+            }
 
             m_aOrigFontColor = aColor;
             m_bOrigFontColor = true;
@@ -1579,6 +1597,14 @@ bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet& rSet )
     if (bChanged)
     {
         aSelectedColor = m_xFontColorLB->GetSelectEntryColor();
+
+        if (m_xFontTransparencyMtr->get_value_changed_from_saved())
+        {
+            double fTransparency
+                = m_xFontTransparencyMtr->get_value(FieldUnit::PERCENT) * 255.0 / 100;
+            aSelectedColor.SetTransparency(static_cast<sal_uInt8>(basegfx::fround(fTransparency)));
+        }
+
         if (m_bOrigFontColor)
             bChanged = aSelectedColor != m_aOrigFontColor;
         if (m_bEnableNoneFontColor && bChanged && aSelectedColor == COL_NONE_COLOR)
@@ -1662,6 +1688,11 @@ IMPL_LINK(SvxCharEffectsPage, ColorBoxSelectHdl_Impl, ColorListBox&, rBox, void)
     UpdatePreview_Impl();
 }
 
+IMPL_LINK_NOARG(SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void)
+{
+    m_bNewFontColor = true;
+}
+
 DeactivateRC SvxCharEffectsPage::DeactivatePage( SfxItemSet* _pSet )
 {
     if ( _pSet )
@@ -2064,6 +2095,7 @@ void SvxCharEffectsPage::ChangesApplied()
     m_xShadowBtn->save_state();
     m_xBlinkingBtn->save_state();
     m_xHiddenBtn->save_state();
+    m_xFontTransparencyMtr->save_value();
 }
 
 bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
@@ -2427,6 +2459,12 @@ void SvxCharEffectsPage::PageCreated(const SfxAllItemSet& aSet)
         if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
             // the writer uses SID_ATTR_BRUSH as font background
             m_bPreviewBackgroundToCharacter = true;
+        if ((nFlags & SVX_ENABLE_CHAR_TRANSPARENCY) != SVX_ENABLE_CHAR_TRANSPARENCY)
+        {
+            // Only show these in case client code explicitly wants this.
+            m_xFontTransparencyFT->hide();
+            m_xFontTransparencyMtr->hide();
+        }
     }
 }
 
diff --git a/cui/uiconfig/ui/effectspage.ui b/cui/uiconfig/ui/effectspage.ui
index 9a5cb1a89fe1..581b28912c16 100644
--- a/cui/uiconfig/ui/effectspage.ui
+++ b/cui/uiconfig/ui/effectspage.ui
@@ -584,6 +584,31 @@
                     <property name="top_attach">1</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="fonttransparencyft">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes" context="effectspage|fonttransparencyft">_Transparency:</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">fonttransparencymtr</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSpinButton" id="fonttransparencymtr">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="activates_default">True</property>
+                    <property name="adjustment">adjustmentPercent</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
                 <child>
                   <placeholder/>
                 </child>
@@ -636,4 +661,9 @@
       <widget name="fontcolorlb"/>
     </widgets>
   </object>
+  <object class="GtkAdjustment" id="adjustmentPercent">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
 </interface>
diff --git a/include/svx/flagsdef.hxx b/include/svx/flagsdef.hxx
index 1b09540e7198..750e5c9326fc 100644
--- a/include/svx/flagsdef.hxx
+++ b/include/svx/flagsdef.hxx
@@ -67,6 +67,7 @@ namespace o3tl
 #define SVX_RELATIVE_MODE       0x02
 // flags for SvxCharEffectsPage
 #define SVX_ENABLE_FLASH    0x04
+#define SVX_ENABLE_CHAR_TRANSPARENCY 0x08
 
 
 // Default values for Number Format Category List and Preview
diff --git a/sd/source/ui/dlg/dlgchar.cxx b/sd/source/ui/dlg/dlgchar.cxx
index d2c349c30545..8dc836ad01a6 100644
--- a/sd/source/ui/dlg/dlgchar.cxx
+++ b/sd/source/ui/dlg/dlgchar.cxx
@@ -56,6 +56,8 @@ void SdCharDlg::PageCreated(const OString& rId, SfxTabPage &rPage)
     }
     else if (rId == "RID_SVXPAGE_CHAR_EFFECTS")
     {
+        // Opt in for character transparency.
+        aSet.Put(SfxUInt32Item(SID_FLAG_TYPE, SVX_ENABLE_CHAR_TRANSPARENCY));
         rPage.PageCreated(aSet);
     }
     else if (rId == "RID_SVXPAGE_BACKGROUND")
commit 8c9d925e2030ee58f4fb2afd7f6e4737de1b2d9c
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Nov 21 17:53:35 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon May 11 09:32:18 2020 +0200

    oox: add PPTX import/export for semi-transparent shape text
    
    And start a drawingml test suite in oox, so the test and the tested code
    is close to each other (just like how it's done in chart2/ already).
    
    (cherry picked from commit 1e64d9ebaa231caef5fb062009b8f76465e415f4)
    
    Conflicts:
            oox/Module_oox.mk
    
    Change-Id: I9a2810691f12604d240e4394e6a5ff4e7f52f1c1

diff --git a/oox/CppunitTest_oox_drawingml.mk b/oox/CppunitTest_oox_drawingml.mk
new file mode 100644
index 000000000000..dd0288074e32
--- /dev/null
+++ b/oox/CppunitTest_oox_drawingml.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,oox_drawingml))
+
+$(eval $(call gb_CppunitTest_use_externals,oox_drawingml,\
+	boost_headers \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,oox_drawingml, \
+    oox/qa/unit/drawingml \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,oox_drawingml, \
+    comphelper \
+    cppu \
+    oox \
+    sal \
+    test \
+    unotest \
+    utl \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,oox_drawingml))
+
+$(eval $(call gb_CppunitTest_use_ure,oox_drawingml))
+$(eval $(call gb_CppunitTest_use_vcl,oox_drawingml))
+
+$(eval $(call gb_CppunitTest_use_rdb,oox_drawingml,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,oox_drawingml,\
+	officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,oox_drawingml))
+
+# vim: set noet sw=4 ts=4:
diff --git a/oox/Module_oox.mk b/oox/Module_oox.mk
index 540b9a8d2ba0..fe22e7344dd5 100644
--- a/oox/Module_oox.mk
+++ b/oox/Module_oox.mk
@@ -28,6 +28,7 @@ $(eval $(call gb_Module_add_check_targets,oox,\
 	CppunitTest_oox_mathml \
 	CppunitTest_oox_vml \
 	CppunitTest_oox_shape \
+	CppunitTest_oox_drawingml \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/oox/qa/unit/data/transparent-text.pptx b/oox/qa/unit/data/transparent-text.pptx
new file mode 100644
index 000000000000..b7b3ede4dc3d
Binary files /dev/null and b/oox/qa/unit/data/transparent-text.pptx differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
new file mode 100644
index 000000000000..e3c455c04867
--- /dev/null
+++ b/oox/qa/unit/drawingml.cxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+
+#include <comphelper/embeddedobjectcontainer.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <unotools/tempfile.hxx>
+
+using namespace ::com::sun::star;
+
+/// oox drawingml tests.
+class OoxDrawingmlTest : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+    uno::Reference<uno::XComponentContext> mxComponentContext;
+    uno::Reference<lang::XComponent> mxComponent;
+
+public:
+    void setUp() override;
+    void tearDown() override;
+    uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+    void loadAndReload(const OUString& rURL, const OUString& rFilterName);
+};
+
+void OoxDrawingmlTest::setUp()
+{
+    test::BootstrapFixture::setUp();
+
+    mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
+    mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void OoxDrawingmlTest::tearDown()
+{
+    if (mxComponent.is())
+        mxComponent->dispose();
+
+    test::BootstrapFixture::tearDown();
+}
+
+void OoxDrawingmlTest::loadAndReload(const OUString& rURL, const OUString& rFilterName)
+{
+    mxComponent = loadFromDesktop(rURL);
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= rFilterName;
+    utl::TempFile aTempFile;
+    xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+    mxComponent->dispose();
+    validate(aTempFile.GetFileName(), test::OOXML);
+    mxComponent = loadFromDesktop(aTempFile.GetURL());
+}
+
+char const DATA_DIRECTORY[] = "/oox/qa/unit/data/";
+
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTransparentText)
+{
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "transparent-text.pptx";
+    loadAndReload(aURL, "Impress Office Open XML");
+
+    uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xParagraph(
+        xShape->createEnumeration()->nextElement(), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xPortion(xParagraph->createEnumeration()->nextElement(),
+                                                 uno::UNO_QUERY);
+
+    sal_Int16 nTransparency = 0;
+    xPortion->getPropertyValue("CharTransparence") >>= nTransparency;
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 75
+    // - Actual  : 0
+    // i.e. the transparency of the character color was lost on import/export.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(75), nTransparency);
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx
index e2f5cc63c0a2..de47058e60ca 100644
--- a/oox/source/drawingml/textcharacterproperties.cxx
+++ b/oox/source/drawingml/textcharacterproperties.cxx
@@ -109,7 +109,15 @@ void TextCharacterProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFil
     }
 
     if ( maFillProperties.moFillType.has() )
-        rPropMap.setProperty( PROP_CharColor, maFillProperties.getBestSolidColor().getColor( rFilter.getGraphicHelper() ));
+    {
+        Color aColor = maFillProperties.getBestSolidColor();
+        rPropMap.setProperty(PROP_CharColor, aColor.getColor(rFilter.getGraphicHelper()));
+
+        if (aColor.hasTransparency())
+        {
+            rPropMap.setProperty(PROP_CharTransparence, aColor.getTransparency());
+        }
+    }
 
     if( moLang.has() && !moLang.get().isEmpty() )
     {
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 4259feb2ae81..8ca75aaa9522 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1883,13 +1883,23 @@ void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool
         ::Color color( *o3tl::doAccess<sal_uInt32>(mAny) );
         SAL_INFO("oox.shape", "run color: " << sal_uInt32(color) << " auto: " << sal_uInt32(COL_AUTO));
 
+        // WriteSolidFill() handles MAX_PERCENT as "no transparency".
+        sal_Int32 nTransparency = MAX_PERCENT;
+        if (rXPropSet->getPropertySetInfo()->hasPropertyByName("CharTransparence"))
+        {
+            rXPropSet->getPropertyValue("CharTransparence") >>= nTransparency;
+            // UNO scale is 0..100, OOXML scale is 0..100000; also UNO tracks transparency, OOXML
+            // tracks opacity.
+            nTransparency = MAX_PERCENT - (nTransparency * PER_PERCENT);
+        }
+
         // tdf#104219 In LibreOffice and MS Office, there are two types of colors:
         // Automatic and Fixed. OOXML is setting automatic color, by not providing color.
         if( color != COL_AUTO )
         {
             color.SetTransparency(0);
             // TODO: special handle embossed/engraved
-            WriteSolidFill( color );
+            WriteSolidFill(color, nTransparency);
         }
     }
 
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index f53b73f8b79e..2a9295367c11 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -82,6 +82,7 @@ CharPostureComplex
 CharShadowed
 CharStrikeout
 CharStyleName
+CharTransparence
 CharUnderline
 CharUnderlineColor
 CharUnderlineHasColor


More information about the Libreoffice-commits mailing list