[Libreoffice-commits] core.git: include/oox oox/source sw/qa

Szabolcs (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 28 08:09:06 UTC 2020


 include/oox/drawingml/color.hxx                                         |    4 +
 include/oox/helper/attributelist.hxx                                    |    6 +
 oox/source/drawingml/color.cxx                                          |   37 +++++++++
 oox/source/drawingml/textcharacterpropertiescontext.cxx                 |    7 +
 oox/source/helper/attributelist.cxx                                     |   32 ++++++++
 sw/qa/extras/ooxmlimport/data/tdf131841_HighlightColorGroupedShape.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                                |   39 ++++++++++
 7 files changed, 121 insertions(+), 4 deletions(-)

New commits:
commit c431661ac716178305f64d98ce81aa8276bdbe8f
Author:     Szabolcs <szabolcs450 at gmail.com>
AuthorDate: Fri Apr 3 11:34:07 2020 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue Apr 28 10:08:33 2020 +0200

    tdf#131841 DOCX DrawingML shape import: Fixed missing HighlightColor
    
    Implemented highlight color in grouped shapes. It was missing
    completely.
    Co-Author: Balázs Regényi
    
    Change-Id: I51207d01a205fbb24abc51c0d69042d6747570a5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91619
    Tested-by: Jenkins
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/include/oox/drawingml/color.hxx b/include/oox/drawingml/color.hxx
index 2d33eb6e3136..23144a8fd5d5 100644
--- a/include/oox/drawingml/color.hxx
+++ b/include/oox/drawingml/color.hxx
@@ -45,6 +45,8 @@ public:
     static ::Color      getDmlPresetColor( sal_Int32 nToken, ::Color nDefaultRgb );
     /** Returns the RGB value for the passed VML color token, or nDefaultRgb on error. */
     static ::Color      getVmlPresetColor( sal_Int32 nToken, ::Color nDefaultRgb );
+    /** Returns the RGB value for the passed VML color token, or nDefaultRgb on error. */
+    static ::Color      getHighlightColor(sal_Int32 nToken, ::Color nDefaultRgb);
 
     /** Sets the color to unused state. */
     void                setUnused();
@@ -57,6 +59,8 @@ public:
     void                setHslClr( sal_Int32 nHue, sal_Int32 nSat, sal_Int32 nLum );
     /** Sets a predefined color from the a:prstClr element. */
     void                setPrstClr( sal_Int32 nToken );
+    /** Sets a predefined color from the w:highlight element. */
+    void                setHighlight(sal_Int32 nToken);
     /** Sets a scheme color from the a:schemeClr element. */
     void                setSchemeClr( sal_Int32 nToken );
     /** Sets the scheme name from the a:schemeClr element for interoperability purposes */
diff --git a/include/oox/helper/attributelist.hxx b/include/oox/helper/attributelist.hxx
index 2d65ad889699..0bf70a0f98ce 100644
--- a/include/oox/helper/attributelist.hxx
+++ b/include/oox/helper/attributelist.hxx
@@ -28,6 +28,7 @@
 #include <oox/dllapi.h>
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
+#include <oox/drawingml/color.hxx>
 
 namespace com { namespace sun { namespace star {
     namespace xml { namespace sax { class XFastAttributeList; } }
@@ -39,6 +40,8 @@ namespace sax_fastparser {
 
 namespace oox {
 
+    /* Get the color tokens from their string representatives. */
+    sal_Int32 getHighlightColorTokenFromString(const OUString& sColorName);
 
 /** Static helpers for conversion of strings to attribute values of various
     different data types.
@@ -91,6 +94,9 @@ public:
     /** Returns the token identifier of the value of the specified attribute. */
     OptValue< sal_Int32 > getToken( sal_Int32 nAttrToken ) const;
 
+    /** Returns the Color object of highlight of the text. */
+    oox::drawingml::Color getHighlightColor(sal_Int32 nAttrToken) const;
+
     /** Returns the string value of the specified attribute. */
     OptValue< OUString > getString( sal_Int32 nAttrToken ) const;
 
diff --git a/oox/source/drawingml/color.cxx b/oox/source/drawingml/color.cxx
index 5410d5fc7498..33e3c3dcd053 100644
--- a/oox/source/drawingml/color.cxx
+++ b/oox/source/drawingml/color.cxx
@@ -39,13 +39,15 @@ struct PresetColorsPool
 
     ColorVector         maDmlColors;        /// Predefined colors in DrawingML, indexed by XML token.
     ColorVector         maVmlColors;        /// Predefined colors in VML, indexed by XML token.
+    ColorVector         maHighlightColors;  /// Predefined colors in DrawingML for highlight, indexed by XML token.
 
     explicit            PresetColorsPool();
 };
 
 PresetColorsPool::PresetColorsPool() :
     maDmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ),
-    maVmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT )
+    maVmlColors( static_cast< size_t >( XML_TOKEN_COUNT ), API_RGB_TRANSPARENT ),
+    maHighlightColors( static_cast<size_t>(XML_TOKEN_COUNT), API_RGB_TRANSPARENT )
 {
     // predefined colors in DrawingML (map XML token identifiers to RGB values)
     static const std::pair<sal_Int32, ::Color> spnDmlColors[] =
@@ -138,6 +140,22 @@ PresetColorsPool::PresetColorsPool() :
     };
     for(auto const& nEntry : spnVmlColors)
         maVmlColors[ static_cast< size_t >(nEntry.first) ] = nEntry.second;
+
+    // predefined highlight colors in DML (map XML token identifiers to RGB values)
+    static const std::pair<sal_Int32, ::Color> spnHighlightColors[] =
+    {
+        // tdf#131841 Predefined color for OOXML highlight.
+        {XML_black,             ::Color(0x000000)},    {XML_blue,              ::Color(0x0000FF)},
+        {XML_cyan,              ::Color(0x00FFFF)},    {XML_darkBlue,          ::Color(0x00008B)},
+        {XML_darkCyan,          ::Color(0x008B8B)},    {XML_darkGray,          ::Color(0xA9A9A9)},
+        {XML_darkGreen,         ::Color(0x006400)},    {XML_darkMagenta,       ::Color(0x800080)},
+        {XML_darkRed,           ::Color(0x8B0000)},    {XML_darkYellow,        ::Color(0x808000)},
+        {XML_green,             ::Color(0x00FF00)},    {XML_lightGray,         ::Color(0xD3D3D3)},
+        {XML_magenta,           ::Color(0xFF00FF)},    {XML_red,               ::Color(0xFF0000)},
+        {XML_white,             ::Color(0xFFFFFF)},    {XML_yellow,            ::Color(0xFFFF00)}
+    };
+    for (auto const& nEntry : spnHighlightColors)
+        maHighlightColors[static_cast<size_t>(nEntry.first)] = nEntry.second;
 }
 
 struct StaticPresetColorsPool : public ::rtl::Static< PresetColorsPool, StaticPresetColorsPool > {};
@@ -220,6 +238,15 @@ Color::Color() :
     return (sal_Int32(nRgbValue) >= 0) ? nRgbValue : nDefaultRgb;
 }
 
+::Color Color::getHighlightColor(sal_Int32 nToken, ::Color nDefaultRgb)
+{
+    /*  Do not pass nDefaultRgb to ContainerHelper::getVectorElement(), to be
+        able to catch the existing vector entries without corresponding XML
+        token identifier. */
+    ::Color nRgbValue = ContainerHelper::getVectorElement( StaticPresetColorsPool::get().maHighlightColors, nToken, API_RGB_TRANSPARENT );
+    return (sal_Int32(nRgbValue) >= 0) ? nRgbValue : nDefaultRgb;
+}
+
 void Color::setUnused()
 {
     meMode = COLOR_UNUSED;
@@ -267,6 +294,14 @@ void Color::setPrstClr( sal_Int32 nToken )
         setSrgbClr( nRgbValue );
 }
 
+void Color::setHighlight(sal_Int32 nToken)
+{
+    ::Color nRgbValue = getHighlightColor(nToken, API_RGB_TRANSPARENT);
+    OSL_ENSURE( sal_Int32(nRgbValue) >= 0, "Color::setPrstClr - invalid preset color token" );
+    if ( sal_Int32(nRgbValue) >= 0 )
+        setSrgbClr( nRgbValue );
+}
+
 void Color::setSchemeClr( sal_Int32 nToken )
 {
     OSL_ENSURE( nToken != XML_TOKEN_INVALID, "Color::setSchemeClr - invalid color token" );
diff --git a/oox/source/drawingml/textcharacterpropertiescontext.cxx b/oox/source/drawingml/textcharacterpropertiescontext.cxx
index 5198b65b61ab..8c6eb4aee22a 100644
--- a/oox/source/drawingml/textcharacterpropertiescontext.cxx
+++ b/oox/source/drawingml/textcharacterpropertiescontext.cxx
@@ -100,10 +100,11 @@ ContextHandlerRef TextCharacterPropertiesContext::onCreateContext( sal_Int32 aEl
         case A_TOKEN( effectDag ):  // CT_EffectContainer 5.1.10.25
         case A_TOKEN( effectLst ):  // CT_EffectList 5.1.10.26
         break;
-
         case A_TOKEN( highlight ):  // CT_Color
-            return new ColorContext( *this, mrTextCharacterProperties.maHighlightColor );
-
+            return new ColorContext(*this, mrTextCharacterProperties.maHighlightColor);
+        case W_TOKEN( highlight ):
+            mrTextCharacterProperties.maHighlightColor = rAttribs.getHighlightColor(W_TOKEN(val));
+            break;
         // EG_TextUnderlineLine
         case A_TOKEN( uLnTx ):      // CT_TextUnderlineLineFollowText
             mrTextCharacterProperties.moUnderlineLineFollowText = true;
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx
index 4c9bfb46c3c5..feb0e37a15af 100644
--- a/oox/source/helper/attributelist.cxx
+++ b/oox/source/helper/attributelist.cxx
@@ -62,6 +62,30 @@ sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd )
 
 } // namespace
 
+#define STRING_TO_TOKEN(color) if (sColorName == #color) return XML_##color
+sal_Int32 getHighlightColorTokenFromString(const OUString& sColorName)
+{
+    STRING_TO_TOKEN(black);
+    STRING_TO_TOKEN(blue);
+    STRING_TO_TOKEN(cyan);
+    STRING_TO_TOKEN(darkBlue);
+    STRING_TO_TOKEN(darkCyan);
+    STRING_TO_TOKEN(darkGreen);
+    STRING_TO_TOKEN(darkMagenta);
+    STRING_TO_TOKEN(darkRed);
+    STRING_TO_TOKEN(darkYellow);
+    STRING_TO_TOKEN(darkGray);
+    STRING_TO_TOKEN(green);
+    STRING_TO_TOKEN(lightGray);
+    STRING_TO_TOKEN(magenta);
+    STRING_TO_TOKEN(red);
+    STRING_TO_TOKEN(white);
+    STRING_TO_TOKEN(yellow);
+    STRING_TO_TOKEN(none);
+
+    return XML_TOKEN_INVALID;
+}
+
 sal_Int32 AttributeConversion::decodeToken( const OUString& rValue )
 {
     return TokenMap::getTokenFromUnicode( rValue );
@@ -125,6 +149,14 @@ bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const
     return mxAttribs->hasAttribute( nAttrToken );
 }
 
+oox::drawingml::Color AttributeList::getHighlightColor(sal_Int32 nAttrToken) const
+{
+    OUString sColorVal = mxAttribs->getValue(nAttrToken);
+    oox::drawingml::Color aColor;
+    aColor.setHighlight(getHighlightColorTokenFromString(sColorVal));
+    return aColor;
+}
+
 // optional return values -----------------------------------------------------
 
 OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const
diff --git a/sw/qa/extras/ooxmlimport/data/tdf131841_HighlightColorGroupedShape.docx b/sw/qa/extras/ooxmlimport/data/tdf131841_HighlightColorGroupedShape.docx
new file mode 100644
index 000000000000..2fa41570a63a
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf131841_HighlightColorGroupedShape.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 7369dac8f1a7..396f2a6e1513 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1551,6 +1551,45 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108995, "xml_space.docx")
                          paragraph->getString());
 }
 
+DECLARE_OOXMLIMPORT_TEST(testGroupShapeTextHighlight, "tdf131841_HighlightColorGroupedShape.docx")
+{
+    // tdf#131841 Highligh color of text in grouped shapes was not imported.
+
+    // These are the possible highlight colors in MSO Word. Check that we import them properly.
+    const std::vector<sal_uInt32> xColors {
+        0xFFFF00UL, // yellow
+        0x00FF00UL, // green
+        0x00FFFFUL, // cyan
+        0xFF00FFUL, // magenta
+        0x0000FFUL, // blue
+        0xFF0000UL, // red
+        0x00008BUL, // dark blue
+        0x008B8BUL, // dark cyan
+        0x006400UL, // dark green
+        0x800080UL, // dark magenta
+        0x8B0000UL, // dark red
+        0x808000UL, // dark yellow
+        0xA9A9A9UL, // dark grey
+        0xD3D3D3UL, // light grey
+        0x000000UL  // black
+    };
+
+    // The grouped shape, consists of 15 rectangles.
+    uno::Reference<drawing::XShapes> xGroupShape(getShape(1), uno::UNO_QUERY);
+
+    // Iterate through all of the rectangles and check the colors of the texts.
+    // They should correspond to the list above.
+    for (size_t idx = 0; idx < xColors.size(); ++idx)
+    {
+        uno::Reference<text::XTextRange> xTextRange(xGroupShape->getByIndex(idx), uno::UNO_QUERY);
+        uno::Reference<text::XTextRange> firstParagraph = getParagraphOfText(1, xTextRange->getText());
+        uno::Reference<text::XTextRange> firstRun = getRun(firstParagraph, 1);
+        uno::Reference<beans::XPropertySet> props(firstRun, uno::UNO_QUERY_THROW);
+
+        CPPUNIT_ASSERT_EQUAL(xColors[idx], props->getPropertyValue("CharBackColor").get<sal_uInt32>());
+    }
+}
+
 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list