summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-03-29 11:04:27 +0200
committerAndras Timar <andras.timar@collabora.com>2023-05-15 21:38:54 +0200
commit74c2ebf84201fd09fcb3b2078b3e6b45d06d25fa (patch)
treec80458cd2ede50dd831d357031b36ccce835c1cd /oox
parentcaf4aea97e08cb684d6ff8b71602a8d4f90fffda (diff)
MCGR: 1st additions to OOXML MCGR import
This change provides 1st changes to get Gradients with muti color stops imported from MSO in the oox import filter. It supports currently multiple ColorStops and transparency. Also 'border'(s) should work, but -remember- this is work in progress. Since it is work in progress it is currently and temporaily secured by ENV VAR "MCGR_TEST=0", so when not using this the master version will not be touched at all. The number defines various ColorStop tests, 0 for none, but some changes are active, e.g. MSO import. You may try 1 or 16 to see all your Gradients hard replaced by something using that feature. I will take care fo cleaning this up again when the feature progresses/gets complete. Change-Id: I92e10d8cd5150733741a6def20a542abf97bd903 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149682 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/fillproperties.cxx110
-rw-r--r--oox/source/drawingml/shapepropertymap.cxx16
-rw-r--r--oox/source/helper/modelobjecthelper.cxx12
3 files changed, 132 insertions, 6 deletions
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx
index 8904d8e8219a..ca7fcc48d120 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -27,9 +27,10 @@
#include <vcl/BitmapFilter.hxx>
#include <vcl/BitmapMonochromeFilter.hxx>
#include <docmodel/uno/UnoThemeColor.hxx>
+#include <basegfx/utils/gradienttools.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/Gradient2.hpp>
#include <com/sun/star/text/GraphicCrop.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
@@ -478,7 +479,112 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap,
case XML_gradFill:
// do not create gradient struct if property is not supported...
- if( rPropMap.supportsProperty( ShapeProperty::FillGradient ) )
+ static bool bMCGR(nullptr != std::getenv("MCGR_TEST"));
+
+ if( bMCGR && rPropMap.supportsProperty( ShapeProperty::FillGradient ) )
+ {
+ // use awt::Gradient2, prepare ColorStops
+ awt::Gradient2 aGradient;
+ basegfx::ColorStops aColorStops;
+ basegfx::ColorStops aTransparencyStops;
+ bool bContainsTransparency(false);
+
+ // set defaults
+ aGradient.Angle = 900;
+ aGradient.StartIntensity = 100;
+ aGradient.EndIntensity = 100;
+ aGradient.Style = awt::GradientStyle_LINEAR;
+
+ // convert to ColorStops, check for contained transparency
+ for (const auto& rCandidate : maGradientProps.maGradientStops)
+ {
+ const ::Color aColor(rCandidate.second.getColor(rGraphicHelper, nPhClr));
+ aColorStops.emplace_back(rCandidate.first, aColor.getBColor());
+ bContainsTransparency = bContainsTransparency || rCandidate.second.hasTransparency();
+ }
+
+ // if we have transparency, convert to ColorStops
+ if (bContainsTransparency)
+ {
+ for (const auto& rCandidate : maGradientProps.maGradientStops)
+ {
+ const double fTrans(rCandidate.second.getTransparency() * (1.0/100.0));
+ aTransparencyStops.emplace_back(rCandidate.first, basegfx::BColor(fTrans, fTrans, fTrans));
+ }
+ }
+
+ // "rotate with shape" set to false -> do not rotate
+ if (!maGradientProps.moRotateWithShape.value_or(true))
+ {
+ nShapeRotation = 0;
+ }
+
+ if (maGradientProps.moGradientPath.has_value())
+ {
+ IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.value_or( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) );
+ sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
+ aGradient.XOffset = getLimitedValue<sal_Int16, sal_Int32>(
+ nCenterX / PER_PERCENT, 0, 100);
+ sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
+ aGradient.YOffset = getLimitedValue<sal_Int16, sal_Int32>(
+ nCenterY / PER_PERCENT, 0, 100);
+
+ if( maGradientProps.moGradientPath.value() == XML_circle )
+ {
+ // Style should be radial at least when the horizontal center is at 50%.
+ // Otherwise import as a linear gradient, because it is the most similar to the MSO radial style.
+ // aGradient.Style = awt::GradientStyle_LINEAR;
+ if( aGradient.XOffset == 100 && aGradient.YOffset == 100 )
+ aGradient.Angle = 450;
+ else if( aGradient.XOffset == 0 && aGradient.YOffset == 100 )
+ aGradient.Angle = 3150;
+ else if( aGradient.XOffset == 100 && aGradient.YOffset == 0 )
+ aGradient.Angle = 1350;
+ else if( aGradient.XOffset == 0 && aGradient.YOffset == 0 )
+ aGradient.Angle = 2250;
+ else
+ aGradient.Style = awt::GradientStyle_RADIAL;
+ }
+ else
+ {
+ aGradient.Style = awt::GradientStyle_RECT;
+ }
+
+ basegfx::utils::reverseColorStops(aColorStops);
+ basegfx::utils::reverseColorStops(aTransparencyStops);
+ }
+ else if (!maGradientProps.maGradientStops.empty())
+ {
+ // aGradient.Style = awt::GradientStyle_LINEAR;
+ sal_Int32 nShadeAngle = maGradientProps.moShadeAngle.value_or( 0 );
+ // Adjust for flips
+ if ( bFlipH )
+ nShadeAngle = 180*60000 - nShadeAngle;
+ if ( bFlipV )
+ nShadeAngle = -nShadeAngle;
+ const sal_Int32 nDmlAngle = nShadeAngle + nShapeRotation;
+ // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
+ aGradient.Angle = static_cast< sal_Int16 >( (8100 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 );
+ }
+
+ // set ColorStops using UNO API
+ basegfx::utils::fillColorStopSequenceFromColorStops(aGradient.ColorStops, aColorStops);
+
+ // push gradient or named gradient to property map
+ if (rPropMap.setProperty(ShapeProperty::FillGradient, aGradient))
+ {
+ eFillStyle = FillStyle_GRADIENT;
+ }
+
+ // push gradient transparency to property map if it exists
+ if (!aTransparencyStops.empty())
+ {
+ basegfx::utils::fillColorStopSequenceFromColorStops(aGradient.ColorStops, aTransparencyStops);
+ rPropMap.setProperty(ShapeProperty::GradientTransparency, aGradient);
+ }
+ }
+
+ if( !bMCGR && rPropMap.supportsProperty( ShapeProperty::FillGradient ) )
{
sal_Int32 nEndTrans = 0;
sal_Int32 nStartTrans = 0;
diff --git a/oox/source/drawingml/shapepropertymap.cxx b/oox/source/drawingml/shapepropertymap.cxx
index 57014b4780a6..253b9259f7aa 100644
--- a/oox/source/drawingml/shapepropertymap.cxx
+++ b/oox/source/drawingml/shapepropertymap.cxx
@@ -19,7 +19,7 @@
#include <oox/drawingml/shapepropertymap.hxx>
-#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/Gradient2.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/drawing/Hatch.hpp>
@@ -166,7 +166,12 @@ bool ShapePropertyMap::setFillGradient( sal_Int32 nPropId, const Any& rValue )
return setAnyProperty( nPropId, rValue );
// create named gradient and push its name
- if( rValue.has< awt::Gradient >() )
+ if( rValue.has< awt::Gradient2 >() )
+ {
+ OUString aGradientName = mrModelObjHelper.insertFillGradient( rValue.get< awt::Gradient2 >() );
+ return !aGradientName.isEmpty() && setProperty( nPropId, aGradientName );
+ }
+ else if( rValue.has< awt::Gradient >() )
{
OUString aGradientName = mrModelObjHelper.insertFillGradient( rValue.get< awt::Gradient >() );
return !aGradientName.isEmpty() && setProperty( nPropId, aGradientName );
@@ -194,7 +199,12 @@ bool ShapePropertyMap::setFillHatch( sal_Int32 nPropId, const Any& rValue )
bool ShapePropertyMap::setGradientTrans( sal_Int32 nPropId, const Any& rValue )
{
// create named gradient and push its name
- if( rValue.has< awt::Gradient >() )
+ if( rValue.has< awt::Gradient2 >() )
+ {
+ OUString aGradientName = mrModelObjHelper.insertTransGrandient( rValue.get< awt::Gradient2 >() );
+ return !aGradientName.isEmpty() && setProperty( nPropId, aGradientName );
+ }
+ else if( rValue.has< awt::Gradient >() )
{
OUString aGradientName = mrModelObjHelper.insertTransGrandient( rValue.get< awt::Gradient >() );
return !aGradientName.isEmpty() && setProperty( nPropId, aGradientName );
diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx
index b68af8084fe0..e721d2ef3413 100644
--- a/oox/source/helper/modelobjecthelper.cxx
+++ b/oox/source/helper/modelobjecthelper.cxx
@@ -19,7 +19,7 @@
#include <oox/helper/modelobjecthelper.hxx>
-#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/Gradient2.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/drawing/Hatch.hpp>
@@ -123,11 +123,21 @@ OUString ModelObjectHelper::insertLineDash( const LineDash& rDash )
return maDashContainer.insertObject( gaDashNameBase, Any( rDash ), true );
}
+OUString ModelObjectHelper::insertFillGradient( const awt::Gradient2& rGradient )
+{
+ return maGradientContainer.insertObject( gaGradientNameBase, Any( rGradient ), true );
+}
+
OUString ModelObjectHelper::insertFillGradient( const awt::Gradient& rGradient )
{
return maGradientContainer.insertObject( gaGradientNameBase, Any( rGradient ), true );
}
+OUString ModelObjectHelper::insertTransGrandient( const awt::Gradient2& rGradient )
+{
+ return maTransGradContainer.insertObject( gaTransGradNameBase, Any( rGradient ), true );
+}
+
OUString ModelObjectHelper::insertTransGrandient( const awt::Gradient& rGradient )
{
return maTransGradContainer.insertObject( gaTransGradNameBase, Any( rGradient ), true );