From 3eac847927a0cdfa40c3fea38c473ed2ad7faecc Mon Sep 17 00:00:00 2001 From: Balazs Varga Date: Wed, 21 Aug 2024 17:34:23 +0200 Subject: [PATCH] tdf#161826 - Add uniform Glow effect for texts in shapes - Add new text Glow effect properties for shapes - Using TextGlowPrimitive for rendering uniform text glow in shapes - Add/allow new UI Glow Effect for texts in shapes on sidebar (Only for Impress/Draw and Calc) - Import/Export ooxml files with Glow effect on texts in shapes (Only PPTX/XLSX) - Import/Export odf files with Glow effect on texts in shapes - Add unit test for glow text attributes in ODF - Add uni tests for OOXML import/export Note: Also this patch effects on tdf#144061 - Effects: Allow GLOW to apply to Text (as we have for shapes) Change-Id: I16586c01654f197f532129e4e06aa2ef9f214395 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172216 Reviewed-by: Balazs Varga Tested-by: Jenkins Reviewed-by: Regina Henschel --- ...d-can-be-private-symbols.functions.results | 2 + ...b-can-be-private-symbols.functions.results | 2 + .../clang/unusedfields.writeonly.results | 6 + drawinglayer/Library_drawinglayer.mk | 1 + .../source/attribute/sdrglowtextattribute.cxx | 37 +++++ .../attribute/sdrglowtextattribute.hxx | 45 ++++++ include/oox/drawingml/effectproperties.hxx | 89 ++++++++++ include/oox/export/drawingml.hxx | 1 + include/svx/strings.hrc | 3 + include/svx/svddef.hxx | 28 ++-- include/svx/svxids.hrc | 9 +- include/svx/unoshprp.hxx | 5 + include/xmloff/xmltoken.hxx | 3 + .../data/org/openoffice/Office/UI/Sidebar.xcu | 29 ++++ oox/inc/drawingml/textcharacterproperties.hxx | 10 +- oox/source/drawingml/effectproperties.cxx | 2 +- .../drawingml/effectpropertiescontext.cxx | 2 +- oox/source/drawingml/shape.cxx | 46 +++++- .../drawingml/textcharacterproperties.cxx | 1 + .../textcharacterpropertiescontext.cxx | 2 + oox/source/drawingml/themeelementscontext.cxx | 2 +- oox/source/export/drawingml.cxx | 33 +++- sc/sdi/drawsh.sdi | 4 + sc/source/ui/drawfunc/drawsh.cxx | 3 + .../OpenDocument-v1.3+libreoffice-schema.rng | 16 ++ .../unit/data/odp/shape-text-glow-effect.odp | Bin 0 -> 28028 bytes .../data/pptx/shape-text-glow-effect.pptx | Bin 0 -> 34693 bytes sd/qa/unit/export-tests-ooxml4.cxx | 16 ++ sd/qa/unit/export-tests.cxx | 41 +++++ sd/qa/unit/import-tests2.cxx | 16 ++ sd/sdi/_drvwsh.sdi | 15 ++ sd/source/ui/view/drviews2.cxx | 3 + sd/source/ui/view/drviewsf.cxx | 3 + static/CustomTarget_emscripten_fs_image.mk | 1 + svx/Library_svx.mk | 1 + svx/UIConfig_svx.mk | 1 + .../sdr/attribute/sdreffectstextattribute.hxx | 6 + .../attribute/sdrlineeffectstextattribute.hxx | 2 + .../sdrlinefilleffectstextattribute.hxx | 1 + .../sdr/primitive2d/sdrattributecreator.hxx | 2 + .../sdr/primitive2d/sdrdecompositiontools.hxx | 5 + svx/sdi/svx.sdi | 51 ++++++ .../sdr/attribute/sdreffectstextattribute.cxx | 8 +- .../attribute/sdrlineeffectstextattribute.cxx | 3 +- .../sdrlinefilleffectstextattribute.cxx | 3 +- .../sdr/primitive2d/sdrattributecreator.cxx | 70 +++++++- .../primitive2d/sdrcustomshapeprimitive2d.cxx | 23 ++- .../sdr/primitive2d/sdrdecompositiontools.cxx | 15 ++ .../primitive2d/sdrrectangleprimitive2d.cxx | 11 +- .../sdr/properties/customshapeproperties.cxx | 2 +- svx/source/sdr/properties/textproperties.cxx | 1 + svx/source/sidebar/PanelFactory.cxx | 5 + .../effect/TextEffectPropertyPanel.cxx | 153 ++++++++++++++++++ .../effect/TextEffectPropertyPanel.hxx | 58 +++++++ svx/source/svdraw/svdattr.cxx | 8 + svx/source/svdraw/svdedxv.cxx | 3 +- svx/source/unodraw/unoprov.cxx | 11 ++ svx/uiconfig/ui/sidebartexteffect.ui | 135 ++++++++++++++++ sw/sdi/drawsh.sdi | 21 +++ vcl/jsdialog/enabled.cxx | 1 + xmloff/inc/xmlprop.hxx | 3 + xmloff/source/core/xmltoken.cxx | 3 + xmloff/source/draw/sdpropls.cxx | 5 + xmloff/source/token/tokens.txt | 3 + 64 files changed, 1056 insertions(+), 34 deletions(-) create mode 100644 drawinglayer/source/attribute/sdrglowtextattribute.cxx create mode 100644 include/drawinglayer/attribute/sdrglowtextattribute.hxx create mode 100644 include/oox/drawingml/effectproperties.hxx create mode 100644 sd/qa/unit/data/odp/shape-text-glow-effect.odp create mode 100644 sd/qa/unit/data/pptx/shape-text-glow-effect.pptx create mode 100644 svx/source/sidebar/effect/TextEffectPropertyPanel.cxx create mode 100644 svx/source/sidebar/effect/TextEffectPropertyPanel.hxx create mode 100644 svx/uiconfig/ui/sidebartexteffect.ui diff --git a/bin/find-can-be-private-symbols.functions.results b/bin/find-can-be-private-symbols.functions.results index 7572709eeb6c..732a616b5953 100644 --- a/bin/find-can-be-private-symbols.functions.results +++ b/bin/find-can-be-private-symbols.functions.results @@ -11944,6 +11944,7 @@ drawinglayer::attribute::SdrFillGraphicAttribute::getTiling() const drawinglayer::attribute::SdrFillGraphicAttribute::operator=(drawinglayer::attribute::SdrFillGraphicAttribute const&) drawinglayer::attribute::SdrFillGraphicAttribute::operator==(drawinglayer::attribute::SdrFillGraphicAttribute const&) const drawinglayer::attribute::SdrGlowAttribute::operator=(drawinglayer::attribute::SdrGlowAttribute&&) +drawinglayer::attribute::SdrGlowTextAttribute::operator=(drawinglayer::attribute::SdrGlowTextAttribute&&) drawinglayer::attribute::SdrLightingAttribute::SdrLightingAttribute(drawinglayer::attribute::SdrLightingAttribute&&) drawinglayer::attribute::SdrLightingAttribute::getAmbientLightColor() const drawinglayer::attribute::SdrLightingAttribute::operator=(drawinglayer::attribute::SdrLightingAttribute const&) @@ -12251,6 +12252,7 @@ drawinglayer::primitive2d::WrongSpellPrimitive2D::create2DDecomposition(drawingl drawinglayer::primitive2d::WrongSpellPrimitive2D::getPrimitive2DID() const drawinglayer::primitive2d::WrongSpellPrimitive2D::operator==(drawinglayer::primitive2d::BasePrimitive2D const&) const drawinglayer::primitive2d::createEmbeddedGlowPrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, drawinglayer::attribute::SdrGlowAttribute const&) +drawinglayer::primitive2d::createEmbeddedTextGlowPrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, drawinglayer::attribute::SdrGlowTextAttribute const&) drawinglayer::primitive2d::createEmbeddedShadowPrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, drawinglayer::attribute::SdrShadowAttribute const&, basegfx::B2DHomMatrix const&, drawinglayer::primitive2d::Primitive2DContainer const*) drawinglayer::primitive2d::createEmbeddedSoftEdgePrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, int) drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(bool, basegfx::B2DRange const&, basegfx::B2DHomMatrix const&) diff --git a/bin/find-mergedlib-can-be-private-symbols.functions.results b/bin/find-mergedlib-can-be-private-symbols.functions.results index 0fa7ff44a5a7..5312bf9abdb4 100644 --- a/bin/find-mergedlib-can-be-private-symbols.functions.results +++ b/bin/find-mergedlib-can-be-private-symbols.functions.results @@ -12420,6 +12420,7 @@ drawinglayer::attribute::SdrFillGraphicAttribute::getTiling() const drawinglayer::attribute::SdrFillGraphicAttribute::operator=(drawinglayer::attribute::SdrFillGraphicAttribute const&) drawinglayer::attribute::SdrFillGraphicAttribute::operator==(drawinglayer::attribute::SdrFillGraphicAttribute const&) const drawinglayer::attribute::SdrGlowAttribute::operator=(drawinglayer::attribute::SdrGlowAttribute&&) +drawinglayer::attribute::SdrGlowTextAttribute::operator=(drawinglayer::attribute::SdrGlowTextAttribute&&) drawinglayer::attribute::SdrLightingAttribute::SdrLightingAttribute(drawinglayer::attribute::SdrLightingAttribute&&) drawinglayer::attribute::SdrLightingAttribute::getAmbientLightColor() const drawinglayer::attribute::SdrLightingAttribute::operator=(drawinglayer::attribute::SdrLightingAttribute const&) @@ -12720,6 +12721,7 @@ drawinglayer::primitive2d::WrongSpellPrimitive2D::getPrimitive2DID() const drawinglayer::primitive2d::WrongSpellPrimitive2D::operator==(drawinglayer::primitive2d::BasePrimitive2D const&) const drawinglayer::primitive2d::arePrimitive2DReferencesEqual(rtl::Reference const&, rtl::Reference const&) drawinglayer::primitive2d::createEmbeddedGlowPrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, drawinglayer::attribute::SdrGlowAttribute const&) +drawinglayer::primitive2d::createEmbeddedTextGlowPrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, drawinglayer::attribute::SdrGlowTextAttribute const&) drawinglayer::primitive2d::createEmbeddedShadowPrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, drawinglayer::attribute::SdrShadowAttribute const&, basegfx::B2DHomMatrix const&, drawinglayer::primitive2d::Primitive2DContainer const*) drawinglayer::primitive2d::createEmbeddedSoftEdgePrimitive(drawinglayer::primitive2d::Primitive2DContainer&&, int) drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(bool, basegfx::B2DRange const&, basegfx::B2DHomMatrix const&) diff --git a/compilerplugins/clang/unusedfields.writeonly.results b/compilerplugins/clang/unusedfields.writeonly.results index 9fc7025d4d47..109227ee1726 100644 --- a/compilerplugins/clang/unusedfields.writeonly.results +++ b/compilerplugins/clang/unusedfields.writeonly.results @@ -1046,6 +1046,12 @@ svx/source/sidebar/effect/EffectPropertyPanel.hxx:37 svx::sidebar::EffectPropertyPanel maGlowTransparencyController sfx2::sidebar::ControllerItem svx/source/sidebar/effect/EffectPropertyPanel.hxx:39 svx::sidebar::EffectPropertyPanel maSoftEdgeRadiusController sfx2::sidebar::ControllerItem +svx/source/sidebar/effect/TextEffectPropertyPanel.hxx:35 + svx::sidebar::TextEffectPropertyPanel maTGlowColorController sfx2::sidebar::ControllerItem +svx/source/sidebar/effect/TextEffectPropertyPanel.hxx:36 + svx::sidebar::TextEffectPropertyPanel maTGlowRadiusController sfx2::sidebar::ControllerItem +svx/source/sidebar/effect/TextEffectPropertyPanel.hxx:37 + svx::sidebar::TextEffectPropertyPanel maTGlowTransparencyController sfx2::sidebar::ControllerItem svx/source/sidebar/line/LinePropertyPanel.hxx:79 svx::sidebar::LinePropertyPanel maStyleControl sfx2::sidebar::ControllerItem svx/source/sidebar/line/LinePropertyPanel.hxx:80 diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk index 6409e379df6b..14e40870d7f1 100644 --- a/drawinglayer/Library_drawinglayer.mk +++ b/drawinglayer/Library_drawinglayer.mk @@ -94,6 +94,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ drawinglayer/source/attribute/sdrfillattribute \ drawinglayer/source/attribute/sdrfillgraphicattribute \ drawinglayer/source/attribute/sdrglowattribute \ + drawinglayer/source/attribute/sdrglowtextattribute \ drawinglayer/source/attribute/sdrlightattribute3d \ drawinglayer/source/attribute/sdrlightingattribute3d \ drawinglayer/source/attribute/sdrlineattribute \ diff --git a/drawinglayer/source/attribute/sdrglowtextattribute.cxx b/drawinglayer/source/attribute/sdrglowtextattribute.cxx new file mode 100644 index 000000000000..f456955624c3 --- /dev/null +++ b/drawinglayer/source/attribute/sdrglowtextattribute.cxx @@ -0,0 +1,37 @@ +/* -*- 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 + +namespace drawinglayer::attribute +{ +SdrGlowTextAttribute::SdrGlowTextAttribute(sal_Int32 nTextRadius, const Color& rTextColor) + : m_nTextRadius(nTextRadius) + , m_TextColor(rTextColor) +{ +} + +SdrGlowTextAttribute::SdrGlowTextAttribute() = default; + +SdrGlowTextAttribute::SdrGlowTextAttribute(const SdrGlowTextAttribute&) = default; + +SdrGlowTextAttribute::SdrGlowTextAttribute(SdrGlowTextAttribute&&) = default; + +SdrGlowTextAttribute& SdrGlowTextAttribute::operator=(const SdrGlowTextAttribute&) = default; + +SdrGlowTextAttribute& SdrGlowTextAttribute::operator=(SdrGlowTextAttribute&&) = default; + +bool SdrGlowTextAttribute::operator==(const SdrGlowTextAttribute& rCandidate) const +{ + return m_nTextRadius == rCandidate.m_nTextRadius && m_TextColor == rCandidate.m_TextColor; +} + +} // end of namespace drawinglayer::attribute + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/drawinglayer/attribute/sdrglowtextattribute.hxx b/include/drawinglayer/attribute/sdrglowtextattribute.hxx new file mode 100644 index 000000000000..6702bae72c14 --- /dev/null +++ b/include/drawinglayer/attribute/sdrglowtextattribute.hxx @@ -0,0 +1,45 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRGLOWTEXTATTRIBUTE_HXX +#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRGLOWTEXTATTRIBUTE_HXX + +#include +#include + +namespace drawinglayer::attribute +{ +class DRAWINGLAYER_DLLPUBLIC SdrGlowTextAttribute +{ +private: + sal_Int32 m_nTextRadius = 0; + Color m_TextColor; // Includes alpha! + +public: + SdrGlowTextAttribute(sal_Int32 nTextRadius, const Color& rTextColor); + SdrGlowTextAttribute(); + SdrGlowTextAttribute(const SdrGlowTextAttribute&); + SdrGlowTextAttribute(SdrGlowTextAttribute&&); + + bool operator==(const SdrGlowTextAttribute& rCandidate) const; + + SdrGlowTextAttribute& operator=(const SdrGlowTextAttribute&); + SdrGlowTextAttribute& operator=(SdrGlowTextAttribute&&); + + // data access + const Color& getTextColor() const { return m_TextColor; } + sal_Int32 getTextRadius() const { return m_nTextRadius; } + bool isDefault() const { return m_nTextRadius == 0; } +}; + +} // end of namespace drawinglayer::attribute + +#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRGLOWTEXTATTRIBUTE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/drawingml/effectproperties.hxx b/include/oox/drawingml/effectproperties.hxx new file mode 100644 index 000000000000..71b05af78752 --- /dev/null +++ b/include/oox/drawingml/effectproperties.hxx @@ -0,0 +1,89 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_OOX_DRAWINGML_EFFECTPROPERTIES_HXX +#define INCLUDED_OOX_DRAWINGML_EFFECTPROPERTIES_HXX + +#include +#include + +#include +#include +#include + +namespace model +{ +enum class RectangleAlignment; +} + +namespace oox::drawingml +{ +struct EffectGlowProperties +{ + std::optional moGlowRad; // size of glow effect + Color moGlowColor; + // TODO saturation and luminance missing + + void assignUsed(const EffectGlowProperties& rSourceProps); +}; + +struct EffectSoftEdgeProperties +{ + std::optional moRad; // size of effect + + void assignUsed(const EffectSoftEdgeProperties& rSourceProps); +}; + +struct EffectShadowProperties +{ + std::optional moShadowDist; + std::optional moShadowDir; + std::optional moShadowSx; + std::optional moShadowSy; + Color moShadowColor; + std::optional moShadowBlur; // size of blur effect + std::optional moShadowAlignment; + + /** Overwrites all members that are explicitly set in rSourceProps. */ + void assignUsed(const EffectShadowProperties& rSourceProps); +}; + +struct Effect +{ + OUString msName; + std::map maAttribs; + Color moColor; + + css::beans::PropertyValue getEffect(); +}; + +struct EffectProperties +{ + EffectShadowProperties maShadow; + EffectGlowProperties maGlow; + EffectSoftEdgeProperties maSoftEdge; + + /** Stores all effect properties, including those not supported by core yet */ + std::vector> m_Effects; + + EffectProperties() {} + EffectProperties(EffectProperties const& rOther) { assignUsed(rOther); } + + /** Overwrites all members that are explicitly set in rSourceProps. */ + void assignUsed(const EffectProperties& rSourceProps); + + /** Writes the properties to the passed property map. */ + void pushToPropMap(PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper) const; +}; + +} // namespace oox::drawingml + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 864aaebbb61c..14df9e9cad8c 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -339,6 +339,7 @@ protected: bool IsFontworkShape(const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet); void WriteGlowEffect(const css::uno::Reference& rXPropSet); + void WriteTextGlowEffect(const css::uno::Reference& rXPropSet); void WriteSoftEdgeEffect(const css::uno::Reference& rXPropSet); void WriteCustomGeometryPoint(const css::drawing::EnhancedCustomShapeParameterPair& rParamPair, const EnhancedCustomShape2d& rCustomShape2d, diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc index f2ee1a961725..23a9dc8c2d97 100644 --- a/include/svx/strings.hrc +++ b/include/svx/strings.hrc @@ -516,6 +516,9 @@ #define SIP_SA_GLOW_RADIUS NC_("SIP_SA_GLOW_RADIUS", "Radius of glow effect") #define SIP_SA_GLOW_COLOR NC_("SIP_SA_GLOW_COLOR", "Color of glow effect") #define SIP_SA_GLOW_TRANSPARENCY NC_("SIP_SA_GLOW_TRANSPARENCY", "Transparency of glow effect") +#define SIP_SA_GLOW_TEXT_RADIUS NC_("SIP_SA_GLOW_TEXT_RADIUS", "Radius of text glow effect") +#define SIP_SA_GLOW_TEXT_COLOR NC_("SIP_SA_GLOW_TEXT_COLOR", "Color of text glow effect") +#define SIP_SA_GLOW_TEXT_TRANSPARENCY NC_("SIP_SA_GLOW_TEXT_TRANSPARENCY", "Transparency of text glow effect") #define SIP_SA_SOFTEDGE_RADIUS NC_("SIP_SA_SOFTEDGE_RADIUS", "Radius of soft edge effect") #define STR_ObjNameSingulMEDIA NC_("STR_ObjNameSingulMEDIA", "Media object") #define STR_ObjNamePluralMEDIA NC_("STR_ObjNamePluralMEDIA", "Media objects") diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx index 500d68fc3916..f54c872f6c8d 100644 --- a/include/svx/svddef.hxx +++ b/include/svx/svddef.hxx @@ -432,20 +432,26 @@ constexpr sal_uInt16 SDRATTR_SOFTEDGE_FIRST(SDRATTR_GLOW_LA constexpr TypedWhichId SDRATTR_SOFTEDGE_RADIUS(SDRATTR_SOFTEDGE_FIRST+0); // 1245 constexpr sal_uInt16 SDRATTR_SOFTEDGE_LAST(SDRATTR_SOFTEDGE_RADIUS); // 1245 -constexpr sal_uInt16 SDRATTR_TEXTCOLUMNS_FIRST(SDRATTR_SOFTEDGE_LAST+1); // 1246 -constexpr TypedWhichId SDRATTR_TEXTCOLUMNS_NUMBER(SDRATTR_TEXTCOLUMNS_FIRST+0); // 1246 -constexpr TypedWhichId SDRATTR_TEXTCOLUMNS_SPACING(SDRATTR_TEXTCOLUMNS_FIRST+1); // 1247 -constexpr sal_uInt16 SDRATTR_TEXTCOLUMNS_LAST(SDRATTR_TEXTCOLUMNS_SPACING); // 1247 +constexpr sal_uInt16 SDRATTR_GLOW_TEXT_FIRST(SDRATTR_SOFTEDGE_LAST+1); // 1246 +constexpr TypedWhichId SDRATTR_GLOW_TEXT_RADIUS(SDRATTR_GLOW_TEXT_FIRST+0); // 1246 +constexpr TypedWhichId SDRATTR_GLOW_TEXT_COLOR(SDRATTR_GLOW_TEXT_FIRST+1); // 1247 +constexpr TypedWhichId SDRATTR_GLOW_TEXT_TRANSPARENCY(SDRATTR_GLOW_TEXT_FIRST+2);// 1248 +constexpr sal_uInt16 SDRATTR_GLOW_TEXT_LAST(SDRATTR_GLOW_TEXT_TRANSPARENCY); // 1248 -constexpr sal_uInt16 SDRATTR_WRITINGMODE2_FIRST(SDRATTR_TEXTCOLUMNS_LAST+1);// 1248 -constexpr TypedWhichId SDRATTR_WRITINGMODE2(SDRATTR_WRITINGMODE2_FIRST+0); // 1248 -constexpr sal_uInt16 SDRATTR_WRITINGMODE2_LAST(SDRATTR_WRITINGMODE2); // 1248 +constexpr sal_uInt16 SDRATTR_TEXTCOLUMNS_FIRST(SDRATTR_GLOW_TEXT_LAST+1); // 1249 +constexpr TypedWhichId SDRATTR_TEXTCOLUMNS_NUMBER(SDRATTR_TEXTCOLUMNS_FIRST+0); // 1249 +constexpr TypedWhichId SDRATTR_TEXTCOLUMNS_SPACING(SDRATTR_TEXTCOLUMNS_FIRST+1); // 1250 +constexpr sal_uInt16 SDRATTR_TEXTCOLUMNS_LAST(SDRATTR_TEXTCOLUMNS_SPACING); // 1250 -constexpr sal_uInt16 SDRATTR_EDGEOOXMLCURVE_FIRST(SDRATTR_WRITINGMODE2_LAST+1);// 1249 -constexpr TypedWhichId SDRATTR_EDGEOOXMLCURVE(SDRATTR_EDGEOOXMLCURVE_FIRST+0); // 1249 -constexpr sal_uInt16 SDRATTR_EDGEOOXMLCURVE_LAST(SDRATTR_EDGEOOXMLCURVE); // 1249 +constexpr sal_uInt16 SDRATTR_WRITINGMODE2_FIRST(SDRATTR_TEXTCOLUMNS_LAST+1);// 1251 +constexpr TypedWhichId SDRATTR_WRITINGMODE2(SDRATTR_WRITINGMODE2_FIRST+0); // 1251 +constexpr sal_uInt16 SDRATTR_WRITINGMODE2_LAST(SDRATTR_WRITINGMODE2); // 1251 -constexpr sal_uInt16 SDRATTR_END (SDRATTR_EDGEOOXMLCURVE_LAST); // 1249 +constexpr sal_uInt16 SDRATTR_EDGEOOXMLCURVE_FIRST(SDRATTR_WRITINGMODE2_LAST+1);// 1252 +constexpr TypedWhichId SDRATTR_EDGEOOXMLCURVE(SDRATTR_EDGEOOXMLCURVE_FIRST+0); // 1252 +constexpr sal_uInt16 SDRATTR_EDGEOOXMLCURVE_LAST(SDRATTR_EDGEOOXMLCURVE); // 1252 + +constexpr sal_uInt16 SDRATTR_END (SDRATTR_EDGEOOXMLCURVE_LAST); // 1252 #endif // INCLUDED_SVX_SVDDEF_HXX diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc index 68d02d4a86fc..895507c4696b 100644 --- a/include/svx/svxids.hrc +++ b/include/svx/svxids.hrc @@ -437,10 +437,17 @@ class XFillGradientItem; #define SID_ATTR_TRANSFORM_HORI_MIRROR TypedWhichId( SID_SVX_START + 317 ) #define SID_ATTR_TRANSFORM_ANCHOR TypedWhichId( SID_SVX_START + 318 ) #define SID_ATTR_TRANSFORM_VERT_ORIENT TypedWhichId( SID_SVX_START + 319 ) + #define SID_ATTR_GLOW_RADIUS ( SID_SVX_START + 320 ) #define SID_ATTR_GLOW_COLOR ( SID_SVX_START + 321 ) #define SID_ATTR_GLOW_TRANSPARENCY ( SID_SVX_START + 322 ) -#define SID_ATTR_SOFTEDGE_RADIUS ( SID_SVX_START + 323 ) + +#define SID_ATTR_GLOW_TEXT_RADIUS ( SID_SVX_START + 323 ) +#define SID_ATTR_GLOW_TEXT_COLOR ( SID_SVX_START + 324 ) +#define SID_ATTR_GLOW_TEXT_TRANSPARENCY ( SID_SVX_START + 325 ) + +#define SID_ATTR_SOFTEDGE_RADIUS ( SID_SVX_START + 326 ) + #define SID_SCAN ( SID_SVX_START + 330 ) #define SID_TWAIN_SELECT ( SID_SVX_START + 331 ) #define SID_TWAIN_TRANSFER ( SID_SVX_START + 332 ) diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx index c4fdfafacb2a..cbb2521684be 100644 --- a/include/svx/unoshprp.hxx +++ b/include/svx/unoshprp.hxx @@ -225,6 +225,11 @@ #define SOFTEDGE_PROPERTIES \ { u"SoftEdgeRadius"_ustr, SDRATTR_SOFTEDGE_RADIUS, cppu::UnoType::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, +#define GLOW_TEXT_PROPERTIES \ + { u"GlowTextEffectRadius"_ustr, SDRATTR_GLOW_TEXT_RADIUS, ::cppu::UnoType::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \ + { u"GlowTextEffectColor"_ustr, SDRATTR_GLOW_TEXT_COLOR, ::cppu::UnoType::get(), 0, 0}, \ + { u"GlowTextEffectTransparency"_ustr,SDRATTR_GLOW_TEXT_TRANSPARENCY,::cppu::UnoType::get(), 0, 0}, + #define SHADOW_PROPERTIES \ { UNO_NAME_SHADOW, SDRATTR_SHADOW, cppu::UnoType::get(), 0, 0}, \ { UNO_NAME_SHADOWCOLOR, SDRATTR_SHADOWCOLOR, ::cppu::UnoType::get(), 0, 0}, \ diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index f410ce69344a..aecf9a5bd4ae 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -979,8 +979,11 @@ namespace xmloff::token { XML_GENERATOR, XML_GEQ, XML_GLOW_RADIUS, + XML_GLOW_TEXT_RADIUS, XML_GLOW_COLOR, + XML_GLOW_TEXT_COLOR, XML_GLOW_TRANSPARENCY, + XML_GLOW_TEXT_TRANSPARENCY, XML_GOURAUD, XML_GRADIENT, XML_GRADIENT_ANGLE, diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu index 940aab4c0505..1e9475993207 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu @@ -724,6 +724,35 @@ + + + Text Effect + + + TextEffectPropertyPanel + + + PropertyDeck + + + + Calc, Draw, hidden ; + Calc, TextObject, hidden ; + DrawImpress, Draw, hidden ; + DrawImpress, TextObject, hidden ; + + + + private:resource/toolpanel/SvxPanelFactory/TextEffectPropertyPanel + + + 350 + + + false + + + Shadow diff --git a/oox/inc/drawingml/textcharacterproperties.hxx b/oox/inc/drawingml/textcharacterproperties.hxx index 9750407b817c..c806dde960f7 100644 --- a/oox/inc/drawingml/textcharacterproperties.hxx +++ b/oox/inc/drawingml/textcharacterproperties.hxx @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include #include #include @@ -32,6 +34,7 @@ namespace oox { class PropertySet; } namespace oox::drawingml { +struct EffectProperties; struct TextCharacterProperties { @@ -69,6 +72,8 @@ struct TextCharacterProperties /// In that case we use the default paragraph properties from the /// ... bool mbHasEmptyParaProperties; + /// For text effect properties in shapes + EffectPropertiesPtr mpEffectPropertiesPtr; std::vector maTextEffectsProperties; @@ -90,7 +95,10 @@ struct TextCharacterProperties PropertySet& rPropSet, const ::oox::core::XmlFilterBase& rFilter ) const; - TextCharacterProperties() : mbHasVisualRunProperties(false), mbHasEmptyParaProperties(false) {} + /** Get effect properties. */ + EffectProperties& getEffectProperties() const { return *mpEffectPropertiesPtr; } + + TextCharacterProperties() : mbHasVisualRunProperties(false), mbHasEmptyParaProperties(false), mpEffectPropertiesPtr(std::make_shared()) {} }; diff --git a/oox/source/drawingml/effectproperties.cxx b/oox/source/drawingml/effectproperties.cxx index 83df8d59c57f..b1850b17c6d6 100644 --- a/oox/source/drawingml/effectproperties.cxx +++ b/oox/source/drawingml/effectproperties.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "effectproperties.hxx" +#include #include #include #include diff --git a/oox/source/drawingml/effectpropertiescontext.cxx b/oox/source/drawingml/effectpropertiescontext.cxx index 9e5fbd983689..ea949017cae2 100644 --- a/oox/source/drawingml/effectpropertiescontext.cxx +++ b/oox/source/drawingml/effectpropertiescontext.cxx @@ -8,7 +8,7 @@ */ #include -#include "effectproperties.hxx" +#include #include #include #include diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index e3c08581f624..56e04caadbf1 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -29,7 +29,7 @@ #include #include #include -#include "effectproperties.hxx" +#include #include #include #include @@ -2162,6 +2162,50 @@ Reference< XShape > const & Shape::createAndInsert( u"SoftEdgeRadius"_ustr, Any(convertEmuToHmm(aEffectProperties.maSoftEdge.moRad.value()))); } + // Set text glow effect for shapes + if (mpTextBody && (!bDoNotInsertEmptyTextBody || !mpTextBody->isEmpty())) + { + const TextParagraphVector& rParagraphs = mpTextBody->getParagraphs(); + if (!rParagraphs.empty()) + { + EffectProperties aTextEffectProperties; + for (TextParagraphVector::const_iterator aPIt = rParagraphs.begin(), aPEnd = rParagraphs.end(); aPIt != aPEnd; ++aPIt) + { + const TextParagraph& rTextPara = **aPIt; + const TextCharacterProperties & rParaProps = rTextPara.getProperties().getTextCharacterProperties(); + if (rParaProps.getEffectProperties().maGlow.moGlowRad.has_value()) + { + aTextEffectProperties.assignUsed(rParaProps.getEffectProperties()); + goto found; + } + else + { + for (TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt) + { + const TextRun& rTextRun = **aRIt; + const TextCharacterProperties& rRunrops = rTextRun.getTextCharacterProperties(); + if (rRunrops.getEffectProperties().maGlow.moGlowRad.has_value()) + { + aTextEffectProperties.assignUsed(rRunrops.getEffectProperties()); + goto found; + } + } + } + } + + found: + if (aTextEffectProperties.maGlow.moGlowRad.has_value()) + { + xSet->setPropertyValue(u"GlowTextEffectRadius"_ustr, + uno::Any(convertEmuToHmm(aTextEffectProperties.maGlow.moGlowRad.value()))); + xSet->setPropertyValue(u"GlowTextEffectColor"_ustr, + uno::Any(aTextEffectProperties.maGlow.moGlowColor.getColor(rGraphicHelper))); + xSet->setPropertyValue(u"GlowTextEffectTransparency"_ustr, + uno::Any(aTextEffectProperties.maGlow.moGlowColor.getTransparency())); + } + } + } + // Set the stroke and fill-color properties of the OLE shape if (aServiceName == "com.sun.star.drawing.OLE2Shape" && mxOleObjectInfo && !mxOleObjectInfo->maShapeId.isEmpty()) diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx index eafa93bf2c46..a32512743085 100644 --- a/oox/source/drawingml/textcharacterproperties.cxx +++ b/oox/source/drawingml/textcharacterproperties.cxx @@ -70,6 +70,7 @@ void TextCharacterProperties::assignUsed( const TextCharacterProperties& rSource assignIfUsed( moTextOutlineProperties, rSourceProps.moTextOutlineProperties); maTextEffectsProperties = rSourceProps.maTextEffectsProperties; + mpEffectPropertiesPtr->assignUsed(*rSourceProps.mpEffectPropertiesPtr); maFillProperties.assignUsed( rSourceProps.maFillProperties ); } diff --git a/oox/source/drawingml/textcharacterpropertiescontext.cxx b/oox/source/drawingml/textcharacterpropertiescontext.cxx index 9bee9c88106a..711fa153b697 100644 --- a/oox/source/drawingml/textcharacterpropertiescontext.cxx +++ b/oox/source/drawingml/textcharacterpropertiescontext.cxx @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -129,6 +130,7 @@ ContextHandlerRef TextCharacterPropertiesContext::onCreateContext( sal_Int32 aEl // EG_EffectProperties case A_TOKEN( effectDag ): // CT_EffectContainer 5.1.10.25 case A_TOKEN( effectLst ): // CT_EffectList 5.1.10.26 + return new EffectPropertiesContext(*this, mrTextCharacterProperties.getEffectProperties()); break; case A_TOKEN( highlight ): // CT_Color return new ColorContext(*this, mrTextCharacterProperties.maHighlightColor); diff --git a/oox/source/drawingml/themeelementscontext.cxx b/oox/source/drawingml/themeelementscontext.cxx index 921841b6a307..537a24441a85 100644 --- a/oox/source/drawingml/themeelementscontext.cxx +++ b/oox/source/drawingml/themeelementscontext.cxx @@ -26,7 +26,7 @@ #include #include #include -#include "effectproperties.hxx" +#include #include #include #include diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 227d1aa43dcf..4369aa225390 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2761,6 +2761,13 @@ void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool else WriteSolidFill(COL_BLACK); } + + if (rXShapePropSet.is() && GetDocumentType() != DOCUMENT_DOCX) + { + mpFS->startElementNS(XML_a, XML_effectLst); + WriteTextGlowEffect(rXShapePropSet); + mpFS->endElementNS(XML_a, XML_effectLst); + } } } @@ -5573,7 +5580,7 @@ void DrawingML::WriteShapeEffect( std::u16string_view sName, const Sequence< Pro nEffectToken = FSNS( XML_a, XML_innerShdw ); bContainsColor = true; } - else if( sName == u"glow" ) + else if( sName == u"glow" || sName == u"glowtext" ) { nEffectToken = FSNS( XML_a, XML_glow ); bContainsColor = true; @@ -5916,6 +5923,30 @@ void DrawingML::WriteGlowEffect(const Reference< XPropertySet >& rXPropSet) WriteShapeEffect(u"glow", aGlowProps); } +void DrawingML::WriteTextGlowEffect(const Reference< XPropertySet >& rXPropSet) +{ + if (!rXPropSet->getPropertySetInfo()->hasPropertyByName(u"GlowTextEffectRadius"_ustr)) + { + return; + } + + sal_Int32 nRad = 0; + rXPropSet->getPropertyValue(u"GlowTextEffectRadius"_ustr) >>= nRad; + if (!nRad) + return; + + Sequence< PropertyValue > aGlowAttribs{ comphelper::makePropertyValue( + u"rad"_ustr, oox::drawingml::convertHmmToEmu(nRad)) }; + Sequence< PropertyValue > aGlowProps{ + comphelper::makePropertyValue(u"Attribs"_ustr, aGlowAttribs), + comphelper::makePropertyValue(u"RgbClr"_ustr, rXPropSet->getPropertyValue(u"GlowTextEffectColor"_ustr)), + comphelper::makePropertyValue(u"RgbClrTransparency"_ustr, rXPropSet->getPropertyValue(u"GlowTextEffectTransparency"_ustr)) + }; + // TODO other stuff like saturation or luminance + + WriteShapeEffect(u"glowtext", aGlowProps); +} + void DrawingML::WriteSoftEdgeEffect(const css::uno::Reference& rXPropSet) { if (!rXPropSet->getPropertySetInfo()->hasPropertyByName(u"SoftEdgeRadius"_ustr)) diff --git a/sc/sdi/drawsh.sdi b/sc/sdi/drawsh.sdi index 668608c549ab..87688e93f8f7 100644 --- a/sc/sdi/drawsh.sdi +++ b/sc/sdi/drawsh.sdi @@ -221,6 +221,10 @@ interface TableDraw SID_ATTR_GLOW_RADIUS [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] SID_ATTR_GLOW_TRANSPARENCY [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] + SID_ATTR_GLOW_TEXT_COLOR [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] + SID_ATTR_GLOW_TEXT_RADIUS [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] + SID_ATTR_GLOW_TEXT_TRANSPARENCY [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] + SID_ATTR_SOFTEDGE_RADIUS [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] SID_MOVE_SHAPE_HANDLE [ ExecMethod = ExecDrawAttr; ] SID_ATTR_TEXTCOLUMNS_NUMBER [ ExecMethod = ExecDrawAttr; StateMethod = GetDrawAttrState; ] diff --git a/sc/source/ui/drawfunc/drawsh.cxx b/sc/source/ui/drawfunc/drawsh.cxx index c818820a7cda..b0728829cf49 100644 --- a/sc/source/ui/drawfunc/drawsh.cxx +++ b/sc/source/ui/drawfunc/drawsh.cxx @@ -400,6 +400,9 @@ void ScDrawShell::ExecDrawAttr( SfxRequest& rReq ) case SID_ATTR_GLOW_COLOR: case SID_ATTR_GLOW_RADIUS: case SID_ATTR_GLOW_TRANSPARENCY: + case SID_ATTR_GLOW_TEXT_COLOR: + case SID_ATTR_GLOW_TEXT_RADIUS: + case SID_ATTR_GLOW_TEXT_TRANSPARENCY: case SID_ATTR_SOFTEDGE_RADIUS: case SID_ATTR_TEXTCOLUMNS_NUMBER: case SID_ATTR_TEXTCOLUMNS_SPACING: diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng index 4073fa6f1af2..9ec0e09f5a6d 100644 --- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng @@ -954,6 +954,22 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. + + + + + + + + + + + + + + + + diff --git a/sd/qa/unit/data/odp/shape-text-glow-effect.odp b/sd/qa/unit/data/odp/shape-text-glow-effect.odp new file mode 100644 index 0000000000000000000000000000000000000000..944d281cf99de155aa66272305baf6f9d07bcff2 GIT binary patch literal 28028 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 literal 0 HcmV?d00001 diff --git a/sd/qa/unit/export-tests-ooxml4.cxx b/sd/qa/unit/export-tests-ooxml4.cxx index 054e2232107a..38afc68be086 100644 --- a/sd/qa/unit/export-tests-ooxml4.cxx +++ b/sd/qa/unit/export-tests-ooxml4.cxx @@ -474,6 +474,22 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testShapeGlowEffect) CPPUNIT_ASSERT_EQUAL(sal_Int16(60), nTransparency); } +CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testShapeTextGlowEffect) +{ + createSdImpressDoc("pptx/shape-text-glow-effect.pptx"); + saveAndReload(u"Impress Office Open XML"_ustr); + uno::Reference xShape(getShapeFromPage(0, 0)); + sal_Int32 nRadius = -1; + xShape->getPropertyValue(u"GlowTextEffectRadius"_ustr) >>= nRadius; + CPPUNIT_ASSERT_EQUAL(sal_Int32(706), nRadius); // 20 pt = 706 mm/100 + Color nColor; + xShape->getPropertyValue(u"GlowTextEffectColor"_ustr) >>= nColor; + CPPUNIT_ASSERT_EQUAL(Color(0x4EA72E), nColor); + sal_Int16 nTransparency; + xShape->getPropertyValue(u"GlowTextEffectTransparency"_ustr) >>= nTransparency; + CPPUNIT_ASSERT_EQUAL(sal_Int16(5), nTransparency); +} + CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testUnderline) { createSdImpressDoc("underline.fodp"); diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index 04ce872ffe10..c5630158f0d7 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -1534,6 +1534,47 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, testGlow) "glow-transparency"_ostr, u"60%"_ustr); } +CPPUNIT_TEST_FIXTURE(SdExportTest, testGlowTextInShape) +{ + createSdImpressDoc("odp/shape-text-glow-effect.odp"); + saveAndReload(u"impress8"_ustr); + + uno::Reference xDP(getPage(0)); + uno::Reference xShape(xDP->getByIndex(0), uno::UNO_QUERY); + + // Check glow text properties in shapes + sal_Int32 nGlowEffectRad = 0; + CPPUNIT_ASSERT(xShape->getPropertyValue(u"GlowTextEffectRadius"_ustr) >>= nGlowEffectRad); + CPPUNIT_ASSERT_EQUAL(sal_Int32(706), nGlowEffectRad); // 20 pt = 706 mm/100 + Color nGlowEffectColor; + CPPUNIT_ASSERT(xShape->getPropertyValue(u"GlowTextEffectColor"_ustr) >>= nGlowEffectColor); + CPPUNIT_ASSERT_EQUAL(Color(0x4EA72E), nGlowEffectColor); + sal_Int16 nGlowEffectTransparency = 0; + CPPUNIT_ASSERT(xShape->getPropertyValue(u"GlowTextEffectTransparency"_ustr) + >>= nGlowEffectTransparency); + CPPUNIT_ASSERT_EQUAL(sal_Int16(5), nGlowEffectTransparency); + + // Test ODF element + xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); + + // check that we actually test graphic style + assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[3]"_ostr, + "family"_ostr, u"graphic"_ustr); + // check loext graphic attributes for th + assertXPath( + pXmlDoc, + "/office:document-content/office:automatic-styles/style:style[3]/style:graphic-properties"_ostr, + "glow-text-radius"_ostr, u"0.706cm"_ustr); + assertXPath( + pXmlDoc, + "/office:document-content/office:automatic-styles/style:style[3]/style:graphic-properties"_ostr, + "glow-text-color"_ostr, u"#4ea72e"_ustr); + assertXPath( + pXmlDoc, + "/office:document-content/office:automatic-styles/style:style[3]/style:graphic-properties"_ostr, + "glow-text-transparency"_ostr, u"5%"_ustr); +} + CPPUNIT_TEST_FIXTURE(SdExportTest, testSoftEdges) { createSdDrawDoc("odg/softedges.odg"); diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index d66e12a52663..a39bc847c784 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -1664,6 +1664,22 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testShapeGlowEffectPPTXImpoer) CPPUNIT_ASSERT_EQUAL(sal_Int16(60), nTransparency); } +CPPUNIT_TEST_FIXTURE(SdImportTest2, testShapeTextGlowEffectPPTXImport) +{ + createSdImpressDoc("pptx/shape-text-glow-effect.pptx"); + + uno::Reference xShape(getShapeFromPage(0, 0)); + sal_Int32 nRadius = -1; + xShape->getPropertyValue(u"GlowTextEffectRadius"_ustr) >>= nRadius; + CPPUNIT_ASSERT_EQUAL(sal_Int32(706), nRadius); // 20 pt = 706 mm/100 + Color nColor; + xShape->getPropertyValue(u"GlowTextEffectColor"_ustr) >>= nColor; + CPPUNIT_ASSERT_EQUAL(Color(0x4EA72E), nColor); + sal_Int16 nTransparency; + xShape->getPropertyValue(u"GlowTextEffectTransparency"_ustr) >>= nTransparency; + CPPUNIT_ASSERT_EQUAL(sal_Int16(5), nTransparency); +} + CPPUNIT_TEST_FIXTURE(SdImportTest2, testShapeBlurPPTXImport) { createSdImpressDoc("pptx/shape-blur-effect.pptx"); diff --git a/sd/sdi/_drvwsh.sdi b/sd/sdi/_drvwsh.sdi index 0d4bed12a9a7..f44bbfec51d7 100644 --- a/sd/sdi/_drvwsh.sdi +++ b/sd/sdi/_drvwsh.sdi @@ -2943,6 +2943,21 @@ interface DrawView ExecMethod = FuTemporary; StateMethod = GetAttrState; ] + SID_ATTR_GLOW_TEXT_COLOR + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + ] + SID_ATTR_GLOW_TEXT_RADIUS + [ + ExecMethod = FuTemporary; + StateMethod = GetAttrState; + ] + SID_ATTR_GLOW_TEXT_TRANSPARENCY + [ + ExecMethod = FuTemporary; + StateMethod = GetAttrState; + ] SID_ATTR_SOFTEDGE_RADIUS [ ExecMethod = FuTemporary; diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx index d464f1a8e955..9a8e86639865 100644 --- a/sd/source/ui/view/drviews2.cxx +++ b/sd/source/ui/view/drviews2.cxx @@ -3626,6 +3626,9 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) case SID_ATTR_GLOW_COLOR: case SID_ATTR_GLOW_RADIUS: case SID_ATTR_GLOW_TRANSPARENCY: + case SID_ATTR_GLOW_TEXT_COLOR: + case SID_ATTR_GLOW_TEXT_RADIUS: + case SID_ATTR_GLOW_TEXT_TRANSPARENCY: case SID_ATTR_SOFTEDGE_RADIUS: case SID_ATTR_TEXTCOLUMNS_NUMBER: case SID_ATTR_TEXTCOLUMNS_SPACING: diff --git a/sd/source/ui/view/drviewsf.cxx b/sd/source/ui/view/drviewsf.cxx index 1c1577b7ab91..037207137c75 100644 --- a/sd/source/ui/view/drviewsf.cxx +++ b/sd/source/ui/view/drviewsf.cxx @@ -440,6 +440,9 @@ void DrawViewShell::GetAttrState( SfxItemSet& rSet ) case SID_ATTR_GLOW_COLOR: case SID_ATTR_GLOW_RADIUS: case SID_ATTR_GLOW_TRANSPARENCY: + case SID_ATTR_GLOW_TEXT_COLOR: + case SID_ATTR_GLOW_TEXT_RADIUS: + case SID_ATTR_GLOW_TEXT_TRANSPARENCY: case SID_ATTR_SOFTEDGE_RADIUS: case SID_SET_SUB_SCRIPT: case SID_SET_SUPER_SCRIPT: diff --git a/static/CustomTarget_emscripten_fs_image.mk b/static/CustomTarget_emscripten_fs_image.mk index 46f587118c88..b83676900859 100644 --- a/static/CustomTarget_emscripten_fs_image.mk +++ b/static/CustomTarget_emscripten_fs_image.mk @@ -1308,6 +1308,7 @@ gb_emscripten_fs_image_files += \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/selectionmenu.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/sidebararea.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/sidebareffect.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/sidebartexteffect.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/sidebarempty.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/sidebarfontwork.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/svx/ui/sidebargallery.ui \ diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk index 75b20d54506d..0160bc2a4a6d 100644 --- a/svx/Library_svx.mk +++ b/svx/Library_svx.mk @@ -235,6 +235,7 @@ $(eval $(call gb_Library_add_exception_objects,svx,\ svx/source/sidebar/area/AreaPropertyPanelBase \ svx/source/sidebar/area/AreaTransparencyGradientPopup \ svx/source/sidebar/effect/EffectPropertyPanel \ + svx/source/sidebar/effect/TextEffectPropertyPanel \ svx/source/sidebar/fontwork/FontworkPropertyPanel \ svx/source/sidebar/shadow/ShadowPropertyPanel \ svx/source/sidebar/graphic/GraphicPropertyPanel \ diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk index 9a1553005a85..fdbf7027ab35 100644 --- a/svx/UIConfig_svx.mk +++ b/svx/UIConfig_svx.mk @@ -123,6 +123,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\ svx/uiconfig/ui/sidebararea \ svx/uiconfig/ui/sidebarempty \ svx/uiconfig/ui/sidebareffect \ + svx/uiconfig/ui/sidebartexteffect \ svx/uiconfig/ui/sidebarfontwork \ svx/uiconfig/ui/sidebarshadow \ svx/uiconfig/ui/sidebargallery \ diff --git a/svx/inc/sdr/attribute/sdreffectstextattribute.hxx b/svx/inc/sdr/attribute/sdreffectstextattribute.hxx index 95a7ffa3e356..f539dce750c3 100644 --- a/svx/inc/sdr/attribute/sdreffectstextattribute.hxx +++ b/svx/inc/sdr/attribute/sdreffectstextattribute.hxx @@ -22,6 +22,7 @@ #include #include #include +#include namespace drawinglayer::attribute @@ -35,6 +36,9 @@ namespace drawinglayer::attribute // glow effect SdrGlowAttribute maGlow; + // glow text effect + SdrGlowTextAttribute maGlowText; + // soft edge sal_Int32 mnSoftEdgeRadius = 0; @@ -43,6 +47,7 @@ namespace drawinglayer::attribute SdrShadowAttribute aShadow, SdrTextAttribute aTextAttribute, SdrGlowAttribute aGlow, + SdrGlowTextAttribute aGlowText, sal_Int32 nSoftEdgeRadius); SdrEffectsTextAttribute(); SdrEffectsTextAttribute(const SdrEffectsTextAttribute& rCandidate); @@ -58,6 +63,7 @@ namespace drawinglayer::attribute const SdrShadowAttribute& getShadow() const { return maShadow; } const SdrTextAttribute& getText() const { return maTextAttribute; } const SdrGlowAttribute& getGlow() const { return maGlow; } + const SdrGlowTextAttribute& getGlowText() const { return maGlowText; } sal_Int32 getSoftEdgeRadius() const { return mnSoftEdgeRadius; } }; diff --git a/svx/inc/sdr/attribute/sdrlineeffectstextattribute.hxx b/svx/inc/sdr/attribute/sdrlineeffectstextattribute.hxx index 3134b0b78b4e..345ceacf67c8 100644 --- a/svx/inc/sdr/attribute/sdrlineeffectstextattribute.hxx +++ b/svx/inc/sdr/attribute/sdrlineeffectstextattribute.hxx @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -40,6 +41,7 @@ namespace drawinglayer::attribute const SdrShadowAttribute& rShadow, const SdrTextAttribute& rTextAttribute, const SdrGlowAttribute& rGlow, + const SdrGlowTextAttribute& rGlowText, sal_Int32 nSoftEdgeRadius); SdrLineEffectsTextAttribute(); SdrLineEffectsTextAttribute(const SdrLineEffectsTextAttribute& rCandidate); diff --git a/svx/inc/sdr/attribute/sdrlinefilleffectstextattribute.hxx b/svx/inc/sdr/attribute/sdrlinefilleffectstextattribute.hxx index 0adb1e49ffc2..56b22f65fe91 100644 --- a/svx/inc/sdr/attribute/sdrlinefilleffectstextattribute.hxx +++ b/svx/inc/sdr/attribute/sdrlinefilleffectstextattribute.hxx @@ -41,6 +41,7 @@ namespace drawinglayer::attribute FillGradientAttribute aFillFloatTransGradient, const SdrTextAttribute& rTextAttribute, const SdrGlowAttribute& rGlow, + const SdrGlowTextAttribute& rGlowText, sal_Int32 nSoftEdgeRadius); SdrLineFillEffectsTextAttribute(); SdrLineFillEffectsTextAttribute(const SdrLineFillEffectsTextAttribute& rCandidate); diff --git a/svx/inc/sdr/primitive2d/sdrattributecreator.hxx b/svx/inc/sdr/primitive2d/sdrattributecreator.hxx index 92a2b102ffdb..1bc3cc2f2f28 100644 --- a/svx/inc/sdr/primitive2d/sdrattributecreator.hxx +++ b/svx/inc/sdr/primitive2d/sdrattributecreator.hxx @@ -26,12 +26,14 @@ // predefines class SfxItemSet; class SdrText; +class SvxFontHeightItem; namespace drawinglayer::attribute { class SdrLineAttribute; class SdrLineStartEndAttribute; class SdrShadowAttribute; class SdrGlowAttribute; + class SdrGlowTextAttribute; class SdrFillAttribute; class SdrTextAttribute; class FillGradientAttribute; diff --git a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx index e504acd41ab6..48df2f1e6f3d 100644 --- a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx +++ b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -78,6 +79,10 @@ namespace drawinglayer::primitive2d Primitive2DContainer&& rContent, const attribute::SdrGlowAttribute& rGlow); + Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedTextGlowPrimitive( + Primitive2DContainer&& rContent, + const attribute::SdrGlowTextAttribute& rGlow); + Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedSoftEdgePrimitive( Primitive2DContainer&& aContent, sal_Int32 nRadius); diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi index 51ab792cf969..ef8c9e32fd98 100644 --- a/svx/sdi/svx.sdi +++ b/svx/sdi/svx.sdi @@ -12698,6 +12698,57 @@ SdrPercentItem GlowTransparency SID_ATTR_GLOW_TRANSPARENCY GroupId = SfxGroupId::Document; ] +XColorItem GlowTextColor SID_ATTR_GLOW_TEXT_COLOR + +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::Document; +] + +SdrMetricItem GlowTextRadius SID_ATTR_GLOW_TEXT_RADIUS + +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::Document; +] + +SdrPercentItem GlowTextTransparency SID_ATTR_GLOW_TEXT_TRANSPARENCY + +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::Document; +] + SdrMetricItem SoftEdgeRadius SID_ATTR_SOFTEDGE_RADIUS [ diff --git a/svx/source/sdr/attribute/sdreffectstextattribute.cxx b/svx/source/sdr/attribute/sdreffectstextattribute.cxx index 30d8a6db1c1e..9275a965c421 100644 --- a/svx/source/sdr/attribute/sdreffectstextattribute.cxx +++ b/svx/source/sdr/attribute/sdreffectstextattribute.cxx @@ -28,10 +28,12 @@ namespace drawinglayer::attribute SdrShadowAttribute aShadow, SdrTextAttribute aTextAttribute, SdrGlowAttribute aGlow, + SdrGlowTextAttribute aGlowText, sal_Int32 nSoftEdgeRadius) : maShadow(std::move(aShadow)), maTextAttribute(std::move(aTextAttribute)), maGlow(std::move(aGlow)), + maGlowText(std::move(aGlowText)), mnSoftEdgeRadius(nSoftEdgeRadius) { } @@ -44,6 +46,7 @@ namespace drawinglayer::attribute : maShadow(rCandidate.getShadow()), maTextAttribute(rCandidate.getText()), maGlow(rCandidate.maGlow), + maGlowText(rCandidate.maGlowText), mnSoftEdgeRadius(rCandidate.mnSoftEdgeRadius) { } @@ -53,6 +56,7 @@ namespace drawinglayer::attribute maShadow = rCandidate.getShadow(); maTextAttribute = rCandidate.getText(); maGlow = rCandidate.maGlow; + maGlowText = rCandidate.maGlowText; mnSoftEdgeRadius = rCandidate.mnSoftEdgeRadius; return *this; @@ -61,7 +65,8 @@ namespace drawinglayer::attribute bool SdrEffectsTextAttribute::isDefault() const { return (getShadow().isDefault() - && getText().isDefault() && maGlow.isDefault() && getSoftEdgeRadius() == 0); + && getText().isDefault() && maGlow.isDefault() + && maGlowText.isDefault() && getSoftEdgeRadius() == 0); } bool SdrEffectsTextAttribute::operator==(const SdrEffectsTextAttribute& rCandidate) const @@ -69,6 +74,7 @@ namespace drawinglayer::attribute return (getShadow() == rCandidate.getShadow() && getText() == rCandidate.getText() && getGlow() == rCandidate.getGlow() + && getGlowText() == rCandidate.getGlowText() && getSoftEdgeRadius() == rCandidate.getSoftEdgeRadius()); } diff --git a/svx/source/sdr/attribute/sdrlineeffectstextattribute.cxx b/svx/source/sdr/attribute/sdrlineeffectstextattribute.cxx index c3f3dbcb18c4..ca9402c707a1 100644 --- a/svx/source/sdr/attribute/sdrlineeffectstextattribute.cxx +++ b/svx/source/sdr/attribute/sdrlineeffectstextattribute.cxx @@ -30,8 +30,9 @@ namespace drawinglayer::attribute const SdrShadowAttribute& rShadow, const SdrTextAttribute& rTextAttribute, const SdrGlowAttribute& rGlow, + const SdrGlowTextAttribute& rGlowText, sal_Int32 nSoftEdgeRadius) - : SdrEffectsTextAttribute(rShadow, rTextAttribute, rGlow, nSoftEdgeRadius), + : SdrEffectsTextAttribute(rShadow, rTextAttribute, rGlow, rGlowText, nSoftEdgeRadius), maLine(std::move(aLine)), maLineStartEnd(std::move(aLineStartEnd)) { diff --git a/svx/source/sdr/attribute/sdrlinefilleffectstextattribute.cxx b/svx/source/sdr/attribute/sdrlinefilleffectstextattribute.cxx index 4d57225b2fb3..a5b7ab9cac2f 100644 --- a/svx/source/sdr/attribute/sdrlinefilleffectstextattribute.cxx +++ b/svx/source/sdr/attribute/sdrlinefilleffectstextattribute.cxx @@ -32,8 +32,9 @@ namespace drawinglayer::attribute FillGradientAttribute aFillFloatTransGradient, const SdrTextAttribute& rTextAttribute, const SdrGlowAttribute& rGlow, + const SdrGlowTextAttribute& rGlowText, sal_Int32 nSoftEdgeRadius) - : SdrLineEffectsTextAttribute(rLine, rLineStartEnd, rShadow, rTextAttribute, rGlow, nSoftEdgeRadius), + : SdrLineEffectsTextAttribute(rLine, rLineStartEnd, rShadow, rTextAttribute, rGlow, rGlowText, nSoftEdgeRadius), maFill(std::move(aFill)), maFillFloatTransGradient(std::move(aFillFloatTransGradient)) { diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx index 4a1f2c6560e2..192e6b080acf 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -72,6 +72,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -80,12 +83,15 @@ #include #include #include +#include #include #include #include #include #include +#include + using namespace com::sun::star; namespace drawinglayer @@ -187,9 +193,12 @@ namespace drawinglayer attribute::SdrGlowAttribute createNewSdrGlowAttribute(const SfxItemSet& rSet) { sal_Int32 nRadius = rSet.Get(SDRATTR_GLOW_RADIUS).GetValue(); + if (!nRadius) return attribute::SdrGlowAttribute(); + Color aColor(rSet.Get(SDRATTR_GLOW_COLOR).GetColorValue()); + sal_uInt16 nTransparency(rSet.Get(SDRATTR_GLOW_TRANSPARENCY).GetValue()); if (nTransparency) aColor.SetAlpha(255 - std::round(nTransparency / 100.0 * 255.0)); @@ -198,6 +207,55 @@ namespace drawinglayer return glowAttr; } + attribute::SdrGlowTextAttribute createNewSdrGlowTextAttribute(const SfxItemSet& rSet, const SdrTextObj& rTextObj) + { + sal_Int32 nTextRadius = rSet.Get(SDRATTR_GLOW_TEXT_RADIUS).GetValue(); + + if (!nTextRadius) + return attribute::SdrGlowTextAttribute(); + + Color aTextColor(rSet.Get(SDRATTR_GLOW_TEXT_COLOR).GetColorValue()); + + sal_uInt16 nTextTransparency(rSet.Get(SDRATTR_GLOW_TEXT_TRANSPARENCY).GetValue()); + if (nTextTransparency) + aTextColor.SetAlpha(255 - std::round(nTextTransparency / 100.0 * 255.0)); + + // calculate rendering text glow radius from biggest Char size for the full text in shape + double nRadius = 0.0; + const SvxFontHeightItem& rItem = *rSet.GetItemIfSet(EE_CHAR_FONTHEIGHT); + sal_uInt32 nFontSize = rItem.GetHeight(); + + if (rTextObj.GetOutlinerParaObject()) + { + const EditTextObject& aEdit = rTextObj.GetOutlinerParaObject()->GetTextObject(); + for (sal_Int32 i = 0; i < aEdit.GetParagraphCount(); i++) + { + std::vector aAttribs; + aEdit.GetCharAttribs(i, aAttribs); + for (const auto& attrib : aAttribs) + { + if (const SvxFontHeightItem* pFontHeight = dynamic_cast(attrib.pAttr)) + { + if (nFontSize < pFontHeight->GetHeight()) + nFontSize = pFontHeight->GetHeight(); + } + } + } + } + + if (nFontSize) + { + // Rendering_glow_size = Original_glow_size / (154.39 * FontSize ^ -0,621) + // This is an approximate calculation similar to MSO text glow size which is + // depending on font size + nRadius = nTextRadius / (154.39 * pow(nFontSize, -0.621)); + nTextRadius = std::round(nRadius); + } + + attribute::SdrGlowTextAttribute glowTextAttr{ nTextRadius, aTextColor }; + return glowTextAttr; + } + sal_Int32 getSoftEdgeRadius(const SfxItemSet& rSet) { return rSet.Get(SDRATTR_SOFTEDGE_RADIUS).GetValue(); @@ -749,10 +807,11 @@ namespace drawinglayer::primitive2d // try shadow const attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet)); const attribute::SdrGlowAttribute aGlow(createNewSdrGlowAttribute(rSet)); + const attribute::SdrGlowTextAttribute aGlowText(createNewSdrGlowTextAttribute(rSet, pText->GetObject())); const sal_Int32 nSoftEdgeRadius(getSoftEdgeRadius(rSet)); return attribute::SdrEffectsTextAttribute(aShadow, std::move(aText), - aGlow, nSoftEdgeRadius); + aGlow, aGlowText, nSoftEdgeRadius); } attribute::SdrLineEffectsTextAttribute createNewSdrLineEffectsTextAttribute( @@ -796,13 +855,15 @@ namespace drawinglayer::primitive2d // try shadow attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet)); attribute::SdrGlowAttribute aGlow = createNewSdrGlowAttribute(rSet); + attribute::SdrGlowTextAttribute aGlowText = createNewSdrGlowTextAttribute(rSet, pText->GetObject()); const sal_Int32 nSoftEdgeRadius(getSoftEdgeRadius(rSet)); return attribute::SdrLineEffectsTextAttribute(std::move(aLine), std::move(aLineStartEnd), std::move(aShadow), std::move(aText), - std::move(aGlow), nSoftEdgeRadius); + std::move(aGlow), + std::move(aGlowText), nSoftEdgeRadius); } return attribute::SdrLineEffectsTextAttribute(); @@ -868,11 +929,14 @@ namespace drawinglayer::primitive2d // glow const attribute::SdrGlowAttribute aGlow = createNewSdrGlowAttribute(rSet); + // text glow + const attribute::SdrGlowTextAttribute aGlowText = createNewSdrGlowTextAttribute(rSet, pText->GetObject()); + const sal_Int32 nSoftEdgeRadius(getSoftEdgeRadius(rSet)); return attribute::SdrLineFillEffectsTextAttribute(aLine, std::move(aFill), aLineStartEnd, aShadow, std::move(aFillFloatTransGradient), - aText, aGlow, nSoftEdgeRadius); + aText, aGlow, aGlowText, nSoftEdgeRadius); } return attribute::SdrLineFillEffectsTextAttribute(); diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx index bfdd4922f1b3..88cc3cf9bc61 100644 --- a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx @@ -44,12 +44,20 @@ namespace drawinglayer::primitive2d getSdrSTAttribute().getSoftEdgeRadius()); } + // tdf#132199: put glow before shadow, to have shadow of the glow, not the opposite + if (!aRetval.empty() && !getSdrSTAttribute().getGlow().isDefault()) + { + // glow + aRetval = createEmbeddedGlowPrimitive(std::move(aRetval), getSdrSTAttribute().getGlow()); + } + // add text if(!getSdrSTAttribute().getText().isDefault()) { const basegfx::B2DPolygon& aUnitOutline(basegfx::utils::createUnitPolygon()); - aRetval.push_back( + Primitive2DContainer aTempContentText; + aTempContentText.push_back( createTextPrimitive( basegfx::B2DPolyPolygon(aUnitOutline), getTextBox(), @@ -57,13 +65,14 @@ namespace drawinglayer::primitive2d attribute::SdrLineAttribute(), false, getWordWrap())); - } - // tdf#132199: put glow before shadow, to have shadow of the glow, not the opposite - if (!aRetval.empty() && !getSdrSTAttribute().getGlow().isDefault()) - { - // glow - aRetval = createEmbeddedGlowPrimitive(std::move(aRetval), getSdrSTAttribute().getGlow()); + // put text glow before, shape glow and shadow + if (!aTempContentText.empty() && !getSdrSTAttribute().getGlowText().isDefault()) + { + // add text glow + aTempContentText = createEmbeddedTextGlowPrimitive(std::move(aTempContentText), getSdrSTAttribute().getGlowText()); + } + aRetval.append(std::move(aTempContentText)); } // add shadow diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index b6d97a9fa39b..a29d1cbb1900 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -931,6 +932,20 @@ sal_uInt32 SlideBackgroundFillPrimitive2D::getPrimitive2DID() const return aRetval; } + Primitive2DContainer createEmbeddedTextGlowPrimitive( + Primitive2DContainer&& rContent, + const attribute::SdrGlowTextAttribute& rGlow) + { + if (rContent.empty()) + return std::move(rContent); + + Primitive2DContainer aRetval(2); + aRetval[0] = new GlowPrimitive2D(rGlow.getTextColor(), rGlow.getTextRadius(), Primitive2DContainer(rContent)); + aRetval[1] = new GroupPrimitive2D(Primitive2DContainer(std::move(rContent))); + + return aRetval; + } + Primitive2DContainer createEmbeddedSoftEdgePrimitive(Primitive2DContainer&& aContent, sal_Int32 nRadius) { diff --git a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx index 2b1f10a81aa6..cdfd75a88b98 100644 --- a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx +++ b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx @@ -92,7 +92,8 @@ namespace drawinglayer::primitive2d // add text if(!getSdrLFSTAttribute().getText().isDefault()) { - aRetval.push_back( + Primitive2DContainer aTempContentText; + aTempContentText.push_back( createTextPrimitive( basegfx::B2DPolyPolygon(aUnitOutline), getTransform(), @@ -100,6 +101,14 @@ namespace drawinglayer::primitive2d getSdrLFSTAttribute().getLine(), false, false)); + + // put text glow before, shape glow and shadow + if (!aTempContentText.empty() && !getSdrLFSTAttribute().getGlowText().isDefault()) + { + // add text glow + aTempContentText = createEmbeddedTextGlowPrimitive(std::move(aTempContentText), getSdrLFSTAttribute().getGlowText()); + } + aRetval.append(std::move(aTempContentText)); } // add shadow diff --git a/svx/source/sdr/properties/customshapeproperties.cxx b/svx/source/sdr/properties/customshapeproperties.cxx index 2626d133d1b0..c63d7e4a4b3c 100644 --- a/svx/source/sdr/properties/customshapeproperties.cxx +++ b/svx/source/sdr/properties/customshapeproperties.cxx @@ -71,7 +71,7 @@ namespace sdr::properties // Graphic attributes, 3D properties, CustomShape // properties: SDRATTR_GRAF_FIRST, SDRATTR_CUSTOMSHAPE_LAST, - SDRATTR_GLOW_FIRST, SDRATTR_SOFTEDGE_LAST, + SDRATTR_GLOW_FIRST, SDRATTR_GLOW_TEXT_LAST, SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST, SDRATTR_WRITINGMODE2, SDRATTR_WRITINGMODE2, // Range from SdrTextObj: diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx index cefb8895878f..bf19b885db5c 100644 --- a/svx/source/sdr/properties/textproperties.cxx +++ b/svx/source/sdr/properties/textproperties.cxx @@ -54,6 +54,7 @@ namespace sdr::properties svl::Items SAL_CALL PanelFactory::createUIElement ( { xControl = EffectPropertyPanel::Create(pParent, pBindings); } + else if (rsResourceURL.endsWith("/TextEffectPropertyPanel")) + { + xControl = TextEffectPropertyPanel::Create(pParent, pBindings); + } else if (rsResourceURL.endsWith("/GraphicPropertyPanel")) { xControl = GraphicPropertyPanel::Create(pParent, pBindings); diff --git a/svx/source/sidebar/effect/TextEffectPropertyPanel.cxx b/svx/source/sidebar/effect/TextEffectPropertyPanel.cxx new file mode 100644 index 000000000000..ab8797ee904f --- /dev/null +++ b/svx/source/sidebar/effect/TextEffectPropertyPanel.cxx @@ -0,0 +1,153 @@ +/* -*- 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 + +#include "TextEffectPropertyPanel.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svx::sidebar +{ +TextEffectPropertyPanel::TextEffectPropertyPanel(weld::Widget* pParent, SfxBindings* pBindings) + : PanelLayout(pParent, u"TextEffectPropertyPanel"_ustr, u"svx/ui/sidebartexteffect.ui"_ustr) + , maTGlowColorController(SID_ATTR_GLOW_TEXT_COLOR, *pBindings, *this) + , maTGlowRadiusController(SID_ATTR_GLOW_TEXT_RADIUS, *pBindings, *this) + , maTGlowTransparencyController(SID_ATTR_GLOW_TEXT_TRANSPARENCY, *pBindings, *this) + , mxFTTTransparency(m_xBuilder->weld_label(u"texttransparency"_ustr)) + , mpBindings(pBindings) + , mxTGlowRadius( + m_xBuilder->weld_metric_spin_button(u"LB_GLOW_TEXT_RADIUS"_ustr, FieldUnit::POINT)) + , mxLBTGlowColor(new ColorListBox(m_xBuilder->weld_menu_button(u"LB_GLOW_TEXT_COLOR"_ustr), + [this] { return GetFrameWeld(); })) + , mxTGlowTransparency(m_xBuilder->weld_metric_spin_button(u"LB_GLOW_TEXT_TRANSPARENCY"_ustr, + FieldUnit::PERCENT)) + , mxFTTColor(m_xBuilder->weld_label(u"glowtextcolorlabel"_ustr)) +{ + Initialize(); +} + +TextEffectPropertyPanel::~TextEffectPropertyPanel() +{ + mxTGlowRadius.reset(); + mxLBTGlowColor.reset(); + mxTGlowTransparency.reset(); + mxFTTColor.reset(); + mxFTTTransparency.reset(); + + maTGlowColorController.dispose(); + maTGlowRadiusController.dispose(); + maTGlowTransparencyController.dispose(); +} + +void TextEffectPropertyPanel::Initialize() +{ + mxTGlowRadius->connect_value_changed(LINK(this, TextEffectPropertyPanel, ModifyTGlowRadiusHdl)); + mxLBTGlowColor->SetSelectHdl(LINK(this, TextEffectPropertyPanel, ModifyTGlowColorHdl)); + mxTGlowTransparency->connect_value_changed( + LINK(this, TextEffectPropertyPanel, ModifyTGlowTransparencyHdl)); +} + +IMPL_LINK_NOARG(TextEffectPropertyPanel, ModifyTGlowRadiusHdl, weld::MetricSpinButton&, void) +{ + SdrMetricItem aItem(SDRATTR_GLOW_TEXT_RADIUS, mxTGlowRadius->get_value(FieldUnit::MM_100TH)); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_GLOW_TEXT_RADIUS, SfxCallMode::RECORD, + { &aItem }); +} + +IMPL_LINK_NOARG(TextEffectPropertyPanel, ModifyTGlowColorHdl, ColorListBox&, void) +{ + XColorItem aItem(SDRATTR_GLOW_TEXT_COLOR, mxLBTGlowColor->GetSelectEntryColor()); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_GLOW_TEXT_COLOR, SfxCallMode::RECORD, + { &aItem }); +} + +IMPL_LINK_NOARG(TextEffectPropertyPanel, ModifyTGlowTransparencyHdl, weld::MetricSpinButton&, void) +{ + SdrPercentItem aItem(SDRATTR_GLOW_TEXT_TRANSPARENCY, + mxTGlowTransparency->get_value(FieldUnit::PERCENT)); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_GLOW_TEXT_TRANSPARENCY, SfxCallMode::RECORD, + { &aItem }); +} + +void TextEffectPropertyPanel::UpdateControls() +{ + const bool bTEnabled = mxTGlowRadius->get_value(FieldUnit::MM_100TH) != 0; + mxLBTGlowColor->set_sensitive(bTEnabled); + mxTGlowTransparency->set_sensitive(bTEnabled); + mxFTTColor->set_sensitive(bTEnabled); + mxFTTTransparency->set_sensitive(bTEnabled); +} + +void TextEffectPropertyPanel::NotifyItemUpdate(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + switch (nSID) + { + case SID_ATTR_GLOW_TEXT_COLOR: + { + if (eState >= SfxItemState::DEFAULT) + { + const XColorItem* pColorItem = dynamic_cast(pState); + if (pColorItem) + { + mxLBTGlowColor->SelectEntry(pColorItem->GetColorValue()); + } + } + } + break; + case SID_ATTR_GLOW_TEXT_RADIUS: + { + if (eState >= SfxItemState::DEFAULT) + { + const SdrMetricItem* pRadiusItem = dynamic_cast(pState); + if (pRadiusItem) + { + mxTGlowRadius->set_value(pRadiusItem->GetValue(), FieldUnit::MM_100TH); + } + } + } + break; + case SID_ATTR_GLOW_TEXT_TRANSPARENCY: + { + if (eState >= SfxItemState::DEFAULT) + { + if (auto pItem = dynamic_cast(pState)) + { + mxTGlowTransparency->set_value(pItem->GetValue(), FieldUnit::PERCENT); + } + } + } + break; + } + UpdateControls(); +} + +std::unique_ptr TextEffectPropertyPanel::Create(weld::Widget* pParent, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw css::lang::IllegalArgumentException( + u"no parent Window given to TextEffectPropertyPanel::Create"_ustr, nullptr, 0); + if (pBindings == nullptr) + throw css::lang::IllegalArgumentException( + u"no SfxBindings given to TextEffectPropertyPanel::Create"_ustr, nullptr, 2); + + return std::make_unique(pParent, pBindings); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx b/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx new file mode 100644 index 000000000000..5966d407b055 --- /dev/null +++ b/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx @@ -0,0 +1,58 @@ +/* -*- 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/. + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_EFFECT_TEXTEFFECTPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_EFFECT_TEXTEFFECTPROPERTYPANEL_HXX + +#include +#include + +class ColorListBox; + +namespace svx::sidebar +{ +class TextEffectPropertyPanel : public PanelLayout, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + TextEffectPropertyPanel(weld::Widget* pParent, SfxBindings* pBindings); + virtual ~TextEffectPropertyPanel() override; + + static std::unique_ptr Create(weld::Widget* pParent, SfxBindings* pBindings); + + virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState(const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override{}; + +private: + sfx2::sidebar::ControllerItem maTGlowColorController; + sfx2::sidebar::ControllerItem maTGlowRadiusController; + sfx2::sidebar::ControllerItem maTGlowTransparencyController; + std::unique_ptr mxFTTTransparency; + + SfxBindings* mpBindings; + + std::unique_ptr mxTGlowRadius; + std::unique_ptr mxLBTGlowColor; + std::unique_ptr mxTGlowTransparency; + std::unique_ptr mxFTTColor; + + void Initialize(); + void UpdateControls(); + + DECL_LINK(ModifyTGlowColorHdl, ColorListBox&, void); + DECL_LINK(ModifyTGlowRadiusHdl, weld::MetricSpinButton&, void); + DECL_LINK(ModifyTGlowTransparencyHdl, weld::MetricSpinButton&, void); +}; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx index cb6c197dfcd4..ab052e912031 100644 --- a/svx/source/svdraw/svdattr.cxx +++ b/svx/source/svdraw/svdattr.cxx @@ -429,6 +429,10 @@ static ItemInfoPackage& getItemInfoPackageSdr() { SDRATTR_SOFTEDGE_RADIUS, new SdrMetricItem(SDRATTR_SOFTEDGE_RADIUS, 0), SID_ATTR_SOFTEDGE_RADIUS, SFX_ITEMINFOFLAG_NONE }, + { SDRATTR_GLOW_TEXT_RADIUS, new SdrMetricItem(SDRATTR_GLOW_TEXT_RADIUS, 0), SID_ATTR_GLOW_TEXT_RADIUS, SFX_ITEMINFOFLAG_NONE }, + { SDRATTR_GLOW_TEXT_COLOR, new XColorItem(SDRATTR_GLOW_TEXT_COLOR, COL_BLACK), SID_ATTR_GLOW_TEXT_COLOR, SFX_ITEMINFOFLAG_NONE }, + { SDRATTR_GLOW_TEXT_TRANSPARENCY, new SdrPercentItem(SDRATTR_GLOW_TEXT_TRANSPARENCY, 0), SID_ATTR_GLOW_TEXT_TRANSPARENCY, SFX_ITEMINFOFLAG_NONE }, + { SDRATTR_TEXTCOLUMNS_NUMBER, new SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, 1), 0, SFX_ITEMINFOFLAG_NONE }, { SDRATTR_TEXTCOLUMNS_SPACING, new SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, 0), 0, SFX_ITEMINFOFLAG_NONE }, @@ -603,6 +607,10 @@ OUString SdrItemPool::GetItemName(sal_uInt16 nWhich) case SDRATTR_GLOW_COLOR : pResId = SIP_SA_GLOW_COLOR;break; case SDRATTR_GLOW_TRANSPARENCY : pResId = SIP_SA_GLOW_TRANSPARENCY;break; + case SDRATTR_GLOW_TEXT_RADIUS : pResId = SIP_SA_GLOW_TEXT_RADIUS; break; + case SDRATTR_GLOW_TEXT_COLOR : pResId = SIP_SA_GLOW_TEXT_COLOR; break; + case SDRATTR_GLOW_TEXT_TRANSPARENCY : pResId = SIP_SA_GLOW_TEXT_TRANSPARENCY; break; + case SDRATTR_SOFTEDGE_RADIUS : pResId = SIP_SA_SOFTEDGE_RADIUS; break; case SDRATTR_CAPTIONTYPE : pResId = SIP_SA_CAPTIONTYPE;break; diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index 6d0d1a57ad76..fd6315976a5e 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -2900,7 +2900,8 @@ static const WhichRangesContainer& GetFormatRangeImpl(bool bTextOnly, bool withP SDRATTR_MISC_LAST, // table cell formats SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST, SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST, SDRATTR_GLOW_FIRST, SDRATTR_GLOW_LAST, SDRATTR_SOFTEDGE_FIRST, - SDRATTR_SOFTEDGE_LAST, EE_PARA_START, EE_PARA_END, EE_CHAR_START, EE_CHAR_END>); + SDRATTR_SOFTEDGE_LAST, SDRATTR_GLOW_TEXT_FIRST, SDRATTR_GLOW_TEXT_LAST, + EE_PARA_START, EE_PARA_END, EE_CHAR_START, EE_CHAR_END>); static const WhichRangesContainer gTextOnly( svl::Items); diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx index 356894621c0a..6b88355a88b8 100644 --- a/svx/source/unodraw/unoprov.cxx +++ b/svx/source/unodraw/unoprov.cxx @@ -65,6 +65,7 @@ static std::span ImplGetSvxShapePropertyMap() LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -89,6 +90,7 @@ static std::span ImplGetSvxTextShapePropertyMap() LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -114,6 +116,7 @@ static std::span ImplGetSvxConnectorPropertyMap() LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -139,6 +142,7 @@ static std::span ImplGetSvxDimensioningPropertyMa LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -164,6 +168,7 @@ static std::span ImplGetSvxCirclePropertyMap() LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -191,6 +196,7 @@ static std::span ImplGetSvxPolyPolygonPropertyMap LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -221,6 +227,7 @@ static std::span ImplGetSvxGraphicObjectPropertyM LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES // #FontWork# @@ -366,6 +373,7 @@ static std::span ImplGetSvxAllPropertyMap() { GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES LINE_PROPERTIES LINE_PROPERTIES_START_END @@ -428,6 +436,7 @@ static std::span ImplGetSvxOle2PropertyMap() LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES FONTWORK_PROPERTIES @@ -682,6 +691,7 @@ static std::span ImplGetSvxCustomShapePropertyMap LINKTARGET_PROPERTIES GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES TEXT_PROPERTIES {u"UserDefinedAttributes"_ustr, SDRATTR_XMLATTRIBUTES, cppu::UnoType::get(), 0, 0}, @@ -764,6 +774,7 @@ static std::span ImplGetSvxDrawingDefaultsPr { GLOW_PROPERTIES SOFTEDGE_PROPERTIES + GLOW_TEXT_PROPERTIES SHADOW_PROPERTIES LINE_PROPERTIES_DEFAULTS FILL_PROPERTIES_BMP diff --git a/svx/uiconfig/ui/sidebartexteffect.ui b/svx/uiconfig/ui/sidebartexteffect.ui new file mode 100644 index 000000000000..e6484fc3d4fa --- /dev/null +++ b/svx/uiconfig/ui/sidebartexteffect.ui @@ -0,0 +1,135 @@ + + + + + + 150 + 1 + 10 + + + 100 + 1 + 10 + + + + True + False + + + + True + False + True + 6 + 3 + 6 + + + True + False + start + Text Glow + + + + + + 0 + 0 + 2 + + + + + True + False + Radius: + True + LB_GLOW_TEXT_RADIUS + 0 + + + 0 + 1 + + + + + True + False + Color: + True + LB_GLOW_TEXT_COLOR + 0 + + + 0 + 2 + + + + + True + False + Transparency: + True + LB_GLOW_TEXT_TRANSPARENCY + 0 + + + 0 + 3 + + + + + True + True + True + True + adjustment1 + + + 1 + 1 + + + + + True + True + False + center + 0 + True + + + + + + 1 + 2 + + + + + True + True + True + adjustment2 + + + 1 + 3 + + + + + 0 + 0 + + + + diff --git a/sw/sdi/drawsh.sdi b/sw/sdi/drawsh.sdi index 6655b6fb2eda..f0d13b306f09 100644 --- a/sw/sdi/drawsh.sdi +++ b/sw/sdi/drawsh.sdi @@ -189,6 +189,27 @@ interface TextDraw : TextDrawBase DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + SID_ATTR_GLOW_TEXT_COLOR + [ + ExecMethod = ExecDrawAttrArgs ; + StateMethod = GetDrawAttrState ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] + + SID_ATTR_GLOW_TEXT_RADIUS + [ + ExecMethod = ExecDrawAttrArgs ; + StateMethod = GetDrawAttrState ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] + + SID_ATTR_GLOW_TEXT_TRANSPARENCY + [ + ExecMethod = ExecDrawAttrArgs ; + StateMethod = GetDrawAttrState ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] + SID_ATTR_SOFTEDGE_RADIUS [ ExecMethod = ExecDrawAttrArgs ; diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx index 89c2654d9445..479e25fee7a9 100644 --- a/vcl/jsdialog/enabled.cxx +++ b/vcl/jsdialog/enabled.cxx @@ -381,6 +381,7 @@ bool isBuilderEnabledForSidebar(std::u16string_view rUIFile) || rUIFile == u"svx/ui/mediaplayback.ui" || rUIFile == u"svx/ui/sidebararea.ui" || rUIFile == u"svx/ui/sidebareffect.ui" + || rUIFile == u"svx/ui/sidebartexteffect.ui" || rUIFile == u"svx/ui/sidebarempty.ui" || rUIFile == u"svx/ui/sidebarfontwork.ui" || rUIFile == u"svx/ui/sidebargallery.ui" diff --git a/xmloff/inc/xmlprop.hxx b/xmloff/inc/xmlprop.hxx index 5b2793f9b2b6..b7acca175a1d 100644 --- a/xmloff/inc/xmlprop.hxx +++ b/xmloff/inc/xmlprop.hxx @@ -318,6 +318,9 @@ inline constexpr OUString PROP_GapWidth = u"GapWidth"_ustr; inline constexpr OUString PROP_GlowEffectColor = u"GlowEffectColor"_ustr; inline constexpr OUString PROP_GlowEffectRadius = u"GlowEffectRadius"_ustr; inline constexpr OUString PROP_GlowEffectTransparency = u"GlowEffectTransparency"_ustr; +inline constexpr OUString PROP_GlowTextEffectColor = u"GlowTextEffectColor"_ustr; +inline constexpr OUString PROP_GlowTextEffectRadius = u"GlowTextEffectRadius"_ustr; +inline constexpr OUString PROP_GlowTextEffectTransparency = u"GlowTextEffectTransparency"_ustr; inline constexpr OUString PROP_GraphicColorMode = u"GraphicColorMode"_ustr; inline constexpr OUString PROP_GraphicCrop = u"GraphicCrop"_ustr; inline constexpr OUString PROP_GraphicIsInverted = u"GraphicIsInverted"_ustr; diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 39ba7cc1b499..6f458260a69d 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -991,8 +991,11 @@ namespace xmloff::token { TOKEN( "generator", XML_GENERATOR ), TOKEN( "geq", XML_GEQ ), TOKEN( "glow-radius", XML_GLOW_RADIUS ), + TOKEN( "glow-text-radius", XML_GLOW_TEXT_RADIUS ), TOKEN( "glow-color", XML_GLOW_COLOR ), + TOKEN( "glow-text-color", XML_GLOW_TEXT_COLOR ), TOKEN( "glow-transparency", XML_GLOW_TRANSPARENCY ), + TOKEN( "glow-text-transparency", XML_GLOW_TEXT_TRANSPARENCY ), TOKEN( "gouraud", XML_GOURAUD ), TOKEN( "gradient", XML_GRADIENT ), TOKEN( "angle", XML_GRADIENT_ANGLE ), diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx index ce07c078e60a..b3c24a495d44 100644 --- a/xmloff/source/draw/sdpropls.cxx +++ b/xmloff/source/draw/sdpropls.cxx @@ -174,6 +174,11 @@ const XMLPropertyMapEntry aXMLSDProperties[] = // soft edge attributes GMAPV( PROP_SoftEdgeRadius, XML_NAMESPACE_LO_EXT, XML_SOFTEDGE_RADIUS, XML_TYPE_MEASURE , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED), + // glow text attributes + GMAPV(PROP_GlowTextEffectRadius, XML_NAMESPACE_LO_EXT, XML_GLOW_TEXT_RADIUS, XML_TYPE_MEASURE , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED), + GMAPV(PROP_GlowTextEffectColor, XML_NAMESPACE_LO_EXT, XML_GLOW_TEXT_COLOR, XML_TYPE_COLOR , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED), + GMAPV(PROP_GlowTextEffectTransparency, XML_NAMESPACE_LO_EXT, XML_GLOW_TEXT_TRANSPARENCY, XML_TYPE_PERCENT16, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED), + // graphic attributes GMAP( PROP_GraphicColorMode, XML_NAMESPACE_DRAW, XML_COLOR_MODE, XML_TYPE_COLOR_MODE, 0 ), // exists in SW, too, with same property name GMAP( PROP_AdjustLuminance, XML_NAMESPACE_DRAW, XML_LUMINANCE, XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same property name diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 29aa2c055658..9ade81537b5f 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -896,8 +896,11 @@ gcd generator geq glow-radius +glow-text-radius glow-color +glow-text-color glow-transparency +glow-text-transparency gouraud gradient angle