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 <szabolcs...@gmail.com> AuthorDate: Fri Apr 3 11:34:07 2020 +0200 Commit: László Németh <nem...@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 <nem...@numbertext.org> Reviewed-by: László Németh <nem...@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(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits