include/docmodel/theme/FormatScheme.hxx  |   49 +++++++++---
 include/oox/export/ThemeExport.hxx       |    5 -
 include/oox/export/drawingml.hxx         |    3 
 oox/source/drawingml/misccontexts.cxx    |   42 ++++++++--
 oox/source/export/ThemeExport.cxx        |   13 ++-
 oox/source/export/drawingml.cxx          |  126 ++++++++++++++++++++++++++++++-
 sd/source/filter/eppt/pptx-epptooxml.cxx |    2 
 7 files changed, 215 insertions(+), 25 deletions(-)

New commits:
commit 6252959192c07973af698ce30fa67b1a29e4871e
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Wed Apr 12 11:18:42 2023 +0900
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Tue Apr 25 13:38:18 2023 +0200

    oox: add support for theme import and export of blip effects
    
    This adds support for (most) blip effects import, export and
    the document model.
    
    Change-Id: Iec15f4de22c31268019fa1a60432e40ae8f03635
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150262
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/include/docmodel/theme/FormatScheme.hxx 
b/include/docmodel/theme/FormatScheme.hxx
index 420d5c1b7584..fb65d24d2ba8 100644
--- a/include/docmodel/theme/FormatScheme.hxx
+++ b/include/docmodel/theme/FormatScheme.hxx
@@ -311,12 +311,49 @@ enum class RectangleAlignment
 constexpr sal_uInt16 RECTANGLE_ALIGNMENT_COUNT
     = static_cast<sal_uInt16>(RectangleAlignment::BottomRight) + 1;
 
-enum class ColorEffectType
+enum class BlipEffectType
 {
     None,
+    AlphaBiLevel,
+    AlphaCeiling,
+    AlphaFloor,
+    AlphaInverse,
+    AlphaModulate,
+    AlphaModulateFixed,
+    AlphaReplace,
     BiLevel,
+    Blur,
+    ColorChange,
+    ColorReplace,
+    DuoTone,
+    FillOverlay,
     Grayscale,
-    ColorChange
+    HSL,
+    Luminance,
+    Tint,
+};
+
+class BlipEffect
+{
+public:
+    BlipEffectType meType = BlipEffectType::None;
+
+    sal_Int32 mnThreshold = 0; // AlphaBiLevel, BiLevel
+    ColorDefinition maColor1; // AlphaInverse, ColorReplace, DuoTone, 
ColorChange (from)
+    ColorDefinition maColor2; // DuoTone, ColorChange (to)
+    sal_Int32 mnAmount = 0; // AlphaModulateFixed, Tint
+    sal_Int32 mnRadius = 0; // Blur
+    bool mbGrow = false; // Blur
+    sal_Int32 mnAlpha = 0; // AlphaReplace
+    bool mbUseAlpha = false; // ColorChange
+    sal_Int32 mnHue = 0; // HSL, Tint
+    sal_Int32 mnSaturation = 0; // HSL
+    sal_Int32 mnLuminance = 0; // HSL
+    sal_Int32 mnBrightness = 0; // Luminance
+    sal_Int32 mnContrast = 0; // Luminance
+
+    ColorDefinition& getColorFrom() { return maColor1; }
+    ColorDefinition& getColorTo() { return maColor2; }
 };
 
 class DOCMODEL_DLLPUBLIC BlipFill : public Fill
@@ -335,13 +372,7 @@ public:
     RectangleAlignment meTileAlignment = RectangleAlignment::TopLeft;
 
     css::uno::Reference<css::graphic::XGraphic> mxGraphic;
-
-    ColorEffectType meColorEffectType = ColorEffectType::None;
-
-    sal_Int32 mnBiLevelThreshold = 0;
-    ColorDefinition maColorFrom;
-    ColorDefinition maColorTo;
-    bool mbUseAlpha = false;
+    std::vector<BlipEffect> maBlipEffects;
 
     BlipFill()
         : Fill(FillType::Blip)
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index c9cf16cb1463..6cba4b06b6e0 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -264,7 +264,7 @@ public:
     {}
 
     OUString writeToStorage(Graphic const& rGraphic, bool bRelPathToMedia = 
false);
-    OUString writeBlip(Graphic const& rGraphic , bool bRelPathToMedia = false);
+    OUString writeBlip(Graphic const& rGraphic, std::vector<model::BlipEffect> 
const& rEffects, bool bRelPathToMedia = false);
 };
 
 class OOX_DLLPUBLIC DrawingML
diff --git a/oox/source/drawingml/misccontexts.cxx 
b/oox/source/drawingml/misccontexts.cxx
index bf3ec6e4fb03..26df16a17553 100644
--- a/oox/source/drawingml/misccontexts.cxx
+++ b/oox/source/drawingml/misccontexts.cxx
@@ -253,8 +253,9 @@ ColorChangeContext::ColorChangeContext( 
ContextHandler2Helper const & rParent,
     mbUseAlpha = rAttribs.getBool( XML_useA, true );
     if (mpBlipFill)
     {
-        mpBlipFill->meColorEffectType = model::ColorEffectType::ColorChange;
-        mpBlipFill->mbUseAlpha = mbUseAlpha;
+        auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
+        rEffect.meType = model::BlipEffectType::ColorChange;
+        rEffect.mbUseAlpha = mbUseAlpha;
     }
 }
 
@@ -272,11 +273,17 @@ ContextHandlerRef ColorChangeContext::onCreateContext(
     {
         case A_TOKEN(clrFrom):
             if (mpBlipFill)
-                pColorDefinition = &mpBlipFill->maColorFrom;
+            {
+                auto& rEffect = mpBlipFill->maBlipEffects.back();
+                pColorDefinition = &rEffect.getColorFrom();
+            }
             return new ColorContext(*this, mrBlipProps.maColorChangeFrom, 
pColorDefinition);
         case A_TOKEN(clrTo):
             if (mpBlipFill)
-                pColorDefinition = &mpBlipFill->maColorTo;
+            {
+                auto& rEffect = mpBlipFill->maBlipEffects.back();
+                pColorDefinition = &rEffect.getColorTo();
+            }
             return new ColorContext(*this, mrBlipProps.maColorChangeTo, 
pColorDefinition);
     }
     return nullptr;
@@ -325,12 +332,16 @@ ContextHandlerRef BlipContext::onCreateContext(
     {
         case A_TOKEN( biLevel ):
         {
-            mrBlipProps.moBiLevelThreshold = rAttribs.getInteger( XML_thresh );
+            sal_Int32 nTreshold = rAttribs.getInteger(XML_thresh, 0);
+
+            mrBlipProps.moBiLevelThreshold = nTreshold;
             mrBlipProps.moColorEffect = getBaseToken(nElement);
+
             if (mpBlipFill)
             {
-                mpBlipFill->meColorEffectType = 
model::ColorEffectType::BiLevel;
-                mpBlipFill->mnBiLevelThreshold = 
rAttribs.getInteger(XML_thresh, 0);
+                auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
+                rEffect.meType = model::BlipEffectType::BiLevel;
+                rEffect.mnThreshold = nTreshold;
             }
         }
         break;
@@ -340,7 +351,8 @@ ContextHandlerRef BlipContext::onCreateContext(
             mrBlipProps.moColorEffect = getBaseToken( nElement );
             if (mpBlipFill)
             {
-                mpBlipFill->meColorEffectType = 
model::ColorEffectType::Grayscale;
+                auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
+                rEffect.meType = model::BlipEffectType::Grayscale;
             }
         }
         break;
@@ -360,11 +372,25 @@ ContextHandlerRef BlipContext::onCreateContext(
         {
             mrBlipProps.moBrightness = rAttribs.getInteger( XML_bright );
             mrBlipProps.moContrast = rAttribs.getInteger( XML_contrast );
+
+            if (mpBlipFill)
+            {
+                auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
+                rEffect.meType = model::BlipEffectType::Luminance;
+                rEffect.mnBrightness = rAttribs.getInteger(XML_bright, 0);
+                rEffect.mnContrast = rAttribs.getInteger(XML_contrast, 0);
+            }
         }
         break;
         case A_TOKEN( alphaModFix ):
         {
             mrBlipProps.moAlphaModFix = rAttribs.getInteger(XML_amt);
+            if (mpBlipFill)
+            {
+                auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
+                rEffect.meType = model::BlipEffectType::AlphaModulateFixed;
+                rEffect.mnAmount = rAttribs.getInteger(XML_amt, 100 * 1000);
+            }
         }
         break;
     }
diff --git a/oox/source/export/ThemeExport.cxx 
b/oox/source/export/ThemeExport.cxx
index 16da603fa14c..88ff2d6364fc 100644
--- a/oox/source/export/ThemeExport.cxx
+++ b/oox/source/export/ThemeExport.cxx
@@ -581,13 +581,13 @@ OString 
convertRectangleAlignment(model::RectangleAlignment eFlipMode)
 }
 } // end anonymous ns
 
-void ThemeExport::writeBlip(model::BlipFill const& rBlipFil)
+void ThemeExport::writeBlip(model::BlipFill const& rBlipFill)
 {
-    if (!rBlipFil.mxGraphic.is())
+    if (!rBlipFill.mxGraphic.is())
         return;
     oox::drawingml::GraphicExport aExporter(mpFS, mpFilterBase, 
meDocumentType);
-    Graphic aGraphic(rBlipFil.mxGraphic);
-    aExporter.writeBlip(aGraphic, false);
+    Graphic aGraphic(rBlipFill.mxGraphic);
+    aExporter.writeBlip(aGraphic, rBlipFill.maBlipEffects, false);
 }
 
 void ThemeExport::writeBlipFill(model::BlipFill const& rBlipFill)
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index f58e76eda95e..aaad66b4d083 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1475,7 +1475,7 @@ const char* DrawingML::GetRelationCompPrefix() const
     return getRelationCompPrefix(meDocumentType);
 }
 
-OUString GraphicExport::writeBlip(Graphic const& rGraphic , bool 
bRelPathToMedia)
+OUString GraphicExport::writeBlip(Graphic const& rGraphic, 
std::vector<model::BlipEffect> const& rEffects, bool bRelPathToMedia)
 {
     OUString sRelId;
 
@@ -1483,8 +1483,114 @@ OUString GraphicExport::writeBlip(Graphic const& 
rGraphic , bool bRelPathToMedia
 
     mpFS->startElementNS(XML_a, XML_blip, FSNS(XML_r, XML_embed), sRelId);
 
-    //WriteImageBrightnessContrastTransparence(rXPropSet);
-    //WriteArtisticEffect(rXPropSet);
+    for (auto const& rEffect : rEffects)
+    {
+        switch (rEffect.meType)
+        {
+            case model::BlipEffectType::AlphaBiLevel:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaBiLevel, XML_thresh, 
OString::number(rEffect.mnThreshold));
+            }
+            break;
+            case model::BlipEffectType::AlphaCeiling:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaCeiling);
+            }
+            break;
+            case model::BlipEffectType::AlphaFloor:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaFloor);
+            }
+            break;
+            case model::BlipEffectType::AlphaInverse:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaInv);
+                // TODO: export rEffect.maColor1
+            }
+            break;
+            case model::BlipEffectType::AlphaModulate:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaMod);
+                // TODO
+            }
+            break;
+            case model::BlipEffectType::AlphaModulateFixed:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, 
OString::number(rEffect.mnAmount));
+            }
+            break;
+            case model::BlipEffectType::AlphaReplace:
+            {
+                mpFS->singleElementNS(XML_a, XML_alphaRepl, XML_a, 
OString::number(rEffect.mnAlpha));
+            }
+            break;
+            case model::BlipEffectType::BiLevel:
+            {
+                mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, 
OString::number(rEffect.mnThreshold));
+            }
+            break;
+            case model::BlipEffectType::Blur:
+            {
+                mpFS->singleElementNS(XML_a, XML_blur,
+                    XML_rad, OString::number(rEffect.mnRadius),
+                    XML_grow, rEffect.mbGrow ? "1" : "0");
+            }
+            break;
+            case model::BlipEffectType::ColorChange:
+            {
+                mpFS->startElementNS(XML_a, XML_clrChange, XML_useA, 
rEffect.mbUseAlpha ? "1" : "0");
+                mpFS->endElementNS(XML_a, XML_clrChange);
+            }
+            break;
+            case model::BlipEffectType::ColorReplace:
+            {
+                mpFS->startElementNS(XML_a, XML_clrRepl);
+                mpFS->endElementNS(XML_a, XML_clrRepl);
+            }
+            break;
+            case model::BlipEffectType::DuoTone:
+            {
+                mpFS->startElementNS(XML_a, XML_duotone);
+                mpFS->endElementNS(XML_a, XML_duotone);
+            }
+            break;
+            case model::BlipEffectType::FillOverlay:
+            {
+                mpFS->singleElementNS(XML_a, XML_fillOverlay);
+            }
+            break;
+            case model::BlipEffectType::Grayscale:
+            {
+                mpFS->singleElementNS(XML_a, XML_grayscl);
+            }
+            break;
+            case model::BlipEffectType::HSL:
+            {
+                mpFS->singleElementNS(XML_a, XML_hsl,
+                    XML_hue, OString::number(rEffect.mnHue),
+                    XML_sat, OString::number(rEffect.mnSaturation),
+                    XML_lum, OString::number(rEffect.mnLuminance));
+            }
+            break;
+            case model::BlipEffectType::Luminance:
+            {
+                mpFS->singleElementNS(XML_a, XML_lum,
+                    XML_bright, OString::number(rEffect.mnBrightness),
+                    XML_contrast, OString::number(rEffect.mnContrast));
+            }
+            break;
+            case model::BlipEffectType::Tint:
+            {
+                mpFS->singleElementNS(XML_a, XML_tint,
+                    XML_hue, OString::number(rEffect.mnHue),
+                    XML_amt, OString::number(rEffect.mnAmount));
+            }
+            break;
+
+            default:
+                break;
+        }
+    }
 
     mpFS->endElementNS(XML_a, XML_blip);
 
commit b09c377888e2e75859fff37fdf9408065eb522d6
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Tue Apr 11 19:24:25 2023 +0900
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Tue Apr 25 13:38:05 2023 +0200

    oox: write graphic (blip) in ThemeExport - BlipFill
    
    Share the graphic writing from DrawingML class, which needed a
    bit of refactoring and use it when writing the BlipFill when
    exporting a theme with ThemeExport.
    
    Change-Id: I89bf3be98f607b7641d231982af2f7a5e2c3d3a8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150261
    Tested-by: Tomaž Vajngerl <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/include/oox/export/ThemeExport.hxx 
b/include/oox/export/ThemeExport.hxx
index 50eb9f47cf81..766d6dfd8a0c 100644
--- a/include/oox/export/ThemeExport.hxx
+++ b/include/oox/export/ThemeExport.hxx
@@ -36,10 +36,11 @@ class OOX_DLLPUBLIC ThemeExport
 {
 private:
     oox::core::XmlFilterBase* mpFilterBase;
+    oox::drawingml::DocumentType meDocumentType;
     sax_fastparser::FSHelperPtr mpFS;
 
 public:
-    ThemeExport(oox::core::XmlFilterBase* pFilterBase);
+    ThemeExport(oox::core::XmlFilterBase* pFilterBase, 
oox::drawingml::DocumentType eDocumentType);
 
     void write(OUString const& rPath, model::Theme const& rTheme);
 
@@ -53,7 +54,7 @@ private:
     void writeBackgroundFillStyle(model::FillStyle const& rFillStyle);
     void writeFillStyle(model::FillStyle const& rFillStyle);
     void writeBlipFill(model::BlipFill const& rBlipFill);
-    static void writeBlip(model::BlipFill const& rBlipFil);
+    void writeBlip(model::BlipFill const& rBlipFill);
     void writePatternFill(model::PatternFill const& rPatternFill);
     void writeGradientFill(model::GradientFill const& rGradientFill);
     void writeSolidFill(model::SolidFill const& rSolidFill);
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 82deea172ef7..c9cf16cb1463 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -263,7 +263,8 @@ public:
         , meDocumentType(eDocumentType)
     {}
 
-    OUString write(const Graphic& rGraphic, bool bRelPathToMedia);
+    OUString writeToStorage(Graphic const& rGraphic, bool bRelPathToMedia = 
false);
+    OUString writeBlip(Graphic const& rGraphic , bool bRelPathToMedia = false);
 };
 
 class OOX_DLLPUBLIC DrawingML
diff --git a/oox/source/export/ThemeExport.cxx 
b/oox/source/export/ThemeExport.cxx
index 8f00058e0bb1..16da603fa14c 100644
--- a/oox/source/export/ThemeExport.cxx
+++ b/oox/source/export/ThemeExport.cxx
@@ -34,8 +34,10 @@ void writeRelativeRectangle(sax_fastparser::FSHelperPtr pFS, 
sal_Int32 nToken,
 }
 } // end anonymous namespace
 
-ThemeExport::ThemeExport(oox::core::XmlFilterBase* pFilterBase)
+ThemeExport::ThemeExport(oox::core::XmlFilterBase* pFilterBase,
+                         oox::drawingml::DocumentType eDocumentType)
     : mpFilterBase(pFilterBase)
+    , meDocumentType(eDocumentType)
 {
 }
 
@@ -579,7 +581,14 @@ OString 
convertRectangleAlignment(model::RectangleAlignment eFlipMode)
 }
 } // end anonymous ns
 
-void ThemeExport::writeBlip(model::BlipFill const& /*rBlipFil*/) {}
+void ThemeExport::writeBlip(model::BlipFill const& rBlipFil)
+{
+    if (!rBlipFil.mxGraphic.is())
+        return;
+    oox::drawingml::GraphicExport aExporter(mpFS, mpFilterBase, 
meDocumentType);
+    Graphic aGraphic(rBlipFil.mxGraphic);
+    aExporter.writeBlip(aGraphic, false);
+}
 
 void ThemeExport::writeBlipFill(model::BlipFill const& rBlipFill)
 {
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 97c5210d95f6..f58e76eda95e 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1475,7 +1475,23 @@ const char* DrawingML::GetRelationCompPrefix() const
     return getRelationCompPrefix(meDocumentType);
 }
 
-OUString GraphicExport::write(const Graphic& rGraphic , bool bRelPathToMedia)
+OUString GraphicExport::writeBlip(Graphic const& rGraphic , bool 
bRelPathToMedia)
+{
+    OUString sRelId;
+
+    sRelId = writeToStorage(rGraphic, bRelPathToMedia);
+
+    mpFS->startElementNS(XML_a, XML_blip, FSNS(XML_r, XML_embed), sRelId);
+
+    //WriteImageBrightnessContrastTransparence(rXPropSet);
+    //WriteArtisticEffect(rXPropSet);
+
+    mpFS->endElementNS(XML_a, XML_blip);
+
+    return sRelId;
+}
+
+OUString GraphicExport::writeToStorage(const Graphic& rGraphic , bool 
bRelPathToMedia)
 {
     GfxLink aLink = rGraphic.GetGfxLink ();
     BitmapChecksum aChecksum = rGraphic.GetChecksum();
@@ -1608,7 +1624,7 @@ OUString GraphicExport::write(const Graphic& rGraphic , 
bool bRelPathToMedia)
 OUString DrawingML::WriteImage( const Graphic& rGraphic , bool bRelPathToMedia 
)
 {
     GraphicExport exporter(mpFS, mpFB, meDocumentType);
-    return exporter.write(rGraphic, bRelPathToMedia);
+    return exporter.writeToStorage(rGraphic, bRelPathToMedia);
 }
 
 void DrawingML::WriteMediaNonVisualProperties(const 
css::uno::Reference<css::drawing::XShape>& xShape)
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx 
b/sd/source/filter/eppt/pptx-epptooxml.cxx
index a8dca7463fdd..023f29dc82c6 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -2000,7 +2000,7 @@ void PowerPointExport::WriteTheme(sal_Int32 nThemeNum, 
model::Theme* pTheme)
         return;
     OUString sThemePath = "ppt/theme/theme" + OUString::number(nThemeNum + 1) 
+ ".xml";
 
-    oox::ThemeExport aThemeExport(this);
+    oox::ThemeExport aThemeExport(this, DOCUMENT_PPTX);
 
     aThemeExport.write(sThemePath, *pTheme);
 }

Reply via email to