summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2018-02-01 15:28:53 +0900
committerTomaž Vajngerl <quikee@gmail.com>2018-02-01 11:54:22 +0100
commite02efb621fe672aa52e56caa916cf5c3fd0a9cb8 (patch)
tree725947b541b4774722d9d4a9d11a2ac58463a753 /oox
parenta61747c2c375d1fe404c976d2a03125e4dc78d8f (diff)
Change bitmap table to store XBitmap instead of GraphicObject URL
As we want to get rid of GraphicObject URLs for the more robust image life-cycle handling, it was necessary to change the way bitmap table stores and handles images, so that they always store a Graphic object (wrapped in UNO object that provides the XGraphic and XBitmap interface). In addition this changes loading and saving from ODF (xmloff) and OOXML (oox) filters so they don't depend on GraphicObject URL anymore, but load or save directly to / from XGraphic or XBitmap. Change-Id: I2b88e10056e7d6c920249d59188f86b1a5a32d21 Reviewed-on: https://gerrit.libreoffice.org/49074 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/fillproperties.cxx19
-rw-r--r--oox/source/drawingml/shapepropertymap.cxx11
-rw-r--r--oox/source/export/chartexport.cxx21
-rw-r--r--oox/source/export/drawingml.cxx177
-rw-r--r--oox/source/helper/modelobjecthelper.cxx10
5 files changed, 203 insertions, 35 deletions
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx
index d2d2775a3e3d..acb0b25e7526 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -28,6 +28,7 @@
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/text/GraphicCrop.hpp>
#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
#include <com/sun/star/drawing/ColorMode.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
@@ -600,14 +601,24 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap,
if( maBlipProps.mxGraphic.is() && rPropMap.supportsProperty( ShapeProperty::FillBitmapUrl ) )
{
Reference< XGraphic > xGraphic = lclCheckAndApplyDuotoneTransform( maBlipProps, maBlipProps.mxGraphic, rGraphicHelper, nPhClr );
+ uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
// TODO: "rotate with shape" is not possible with our current core
OUString aGraphicUrl = rGraphicHelper.createGraphicObject( xGraphic );
// push bitmap or named bitmap to property map
- if( !aGraphicUrl.isEmpty() && rPropMap.supportsProperty( ShapeProperty::FillBitmapNameFromUrl ) && rPropMap.setProperty( ShapeProperty::FillBitmapNameFromUrl, aGraphicUrl ) )
- eFillStyle = FillStyle_BITMAP;
- else if( !aGraphicUrl.isEmpty() && rPropMap.setProperty( ShapeProperty::FillBitmapUrl, aGraphicUrl ) )
- eFillStyle = FillStyle_BITMAP;
+
+ if (!aGraphicUrl.isEmpty())
+ {
+ if (rPropMap.supportsProperty(ShapeProperty::FillBitmapNameFromUrl) &&
+ rPropMap.setProperty(ShapeProperty::FillBitmapNameFromUrl, xGraphic))
+ {
+ eFillStyle = FillStyle_BITMAP;
+ }
+ else if (rPropMap.setProperty(ShapeProperty::FillBitmapUrl, aGraphicUrl))
+ {
+ eFillStyle = FillStyle_BITMAP;
+ }
+ }
// set other bitmap properties, if bitmap has been inserted into the map
if( eFillStyle == FillStyle_BITMAP )
diff --git a/oox/source/drawingml/shapepropertymap.cxx b/oox/source/drawingml/shapepropertymap.cxx
index b1cf0239237e..53226434dfb1 100644
--- a/oox/source/drawingml/shapepropertymap.cxx
+++ b/oox/source/drawingml/shapepropertymap.cxx
@@ -23,6 +23,8 @@
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+
#include <oox/helper/modelobjecthelper.hxx>
#include <oox/token/properties.hxx>
@@ -194,12 +196,13 @@ bool ShapePropertyMap::setFillBitmapUrl( sal_Int32 nPropId, const Any& rValue )
return false;
}
-bool ShapePropertyMap::setFillBitmapNameFromUrl( const Any& rValue )
+bool ShapePropertyMap::setFillBitmapNameFromUrl(const Any& rValue)
{
- if( rValue.has< OUString >() )
+ if (rValue.has<uno::Reference<graphic::XGraphic>>())
{
- OUString aBitmapUrlName = mrModelObjHelper.insertFillBitmapUrl( rValue.get< OUString >() );
- return !aBitmapUrlName.isEmpty() && setProperty( PROP_FillBitmapName, aBitmapUrlName );
+ auto xGraphic = rValue.get<uno::Reference<graphic::XGraphic>>();
+ OUString aBitmapUrlName = mrModelObjHelper.insertFillBitmapXGraphic(xGraphic);
+ return !aBitmapUrlName.isEmpty() && setProperty(PROP_FillBitmapName, aBitmapUrlName);
}
return false;
}
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index 4c8bda4ea97b..684a8983503d 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -76,6 +76,7 @@
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceName.hpp>
@@ -1313,19 +1314,27 @@ void ChartExport::exportBitmapFill( const Reference< XPropertySet >& xPropSet )
uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
try
{
- uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY );
- uno::Any rValue = xBitmap->getByName( sFillBitmapName );
- OUString sBitmapURL;
- if( rValue >>= sBitmapURL )
+ uno::Reference< container::XNameAccess > xBitmapTable( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY );
+ uno::Any rValue = xBitmapTable->getByName( sFillBitmapName );
+ if (rValue.has<uno::Reference<awt::XBitmap>>())
{
- WriteBlipFill( xPropSet, sBitmapURL, XML_a, true, true );
+ uno::Reference<awt::XBitmap> xBitmap = rValue.get<uno::Reference<awt::XBitmap>>();
+ uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
+ if (xGraphic.is())
+ {
+ WriteXGraphicBlipFill(xPropSet, xGraphic, XML_a, true, true);
+ }
+ }
+ else if (rValue.has<OUString>()) // TODO: Remove, when not used anymore
+ {
+ OUString sBitmapURL = rValue.get<OUString>();
+ WriteBlipFill(xPropSet, sBitmapURL, XML_a, true, true);
}
}
catch (const uno::Exception & rEx)
{
SAL_INFO("oox", "ChartExport::exportBitmapFill " << rEx);
}
-
}
}
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 1deec7c82f74..d56077c5240a 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -64,6 +64,7 @@
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/style/LineSpacing.hpp>
@@ -1055,6 +1056,36 @@ void DrawingML::WriteMediaNonVisualProperties(const css::uno::Reference<css::dra
GetFS()->endElementNS(XML_p, XML_nvPr);
}
+void DrawingML::WriteImageBrightnessContrastTransparence(uno::Reference<beans::XPropertySet> const & rXPropSet)
+{
+ sal_Int16 nBright = 0;
+ sal_Int32 nContrast = 0;
+ sal_Int32 nTransparence = 0;
+
+ if (GetProperty(rXPropSet, "AdjustLuminance"))
+ nBright = mAny.get<sal_Int16>();
+ if (GetProperty(rXPropSet, "AdjustContrast"))
+ nContrast = mAny.get<sal_Int32>();
+ if (GetProperty(rXPropSet, "FillTransparence"))
+ nTransparence = mAny.get<sal_Int32>();
+
+
+ if (nBright || nContrast)
+ {
+ mpFS->singleElementNS(XML_a, XML_lum,
+ XML_bright, nBright ? I32S(nBright * 1000) : nullptr,
+ XML_contrast, nContrast ? I32S(nContrast * 1000) : nullptr,
+ FSEND);
+ }
+
+ if (nTransparence)
+ {
+ sal_Int32 nAlphaMod = (100 - nTransparence ) * PER_PERCENT;
+ mpFS->singleElementNS(XML_a, XML_alphaModFix,
+ XML_amt, I32S(nAlphaMod), FSEND);
+ }
+}
+
OUString DrawingML::WriteBlip( const Reference< XPropertySet >& rXPropSet, const OUString& rURL, bool bRelPathToMedia, const Graphic *pGraphic )
{
OUString sRelId;
@@ -1074,35 +1105,54 @@ OUString DrawingML::WriteBlip( const Reference< XPropertySet >& rXPropSet, const
if (!rURL.isEmpty() && mpTextExport)
mpTextExport->CacheRelId(nChecksum, sRelId);
}
- sal_Int16 nBright = 0;
- sal_Int32 nContrast = 0;
- sal_Int32 nTransparence = 0;
-
- GET( nBright, AdjustLuminance );
- GET( nContrast, AdjustContrast );
- GET( nTransparence, FillTransparence );
mpFS->startElementNS( XML_a, XML_blip,
- FSNS( XML_r, XML_embed), sRelId.toUtf8().getStr(),
- FSEND );
- if( nBright || nContrast )
+ FSNS( XML_r, XML_embed), sRelId.toUtf8().getStr(),
+ FSEND );
+
+ WriteImageBrightnessContrastTransparence(rXPropSet);
+
+ WriteArtisticEffect( rXPropSet );
+
+ mpFS->endElementNS( XML_a, XML_blip );
+
+ return sRelId;
+}
+
+OUString DrawingML::WriteXGraphicBlip(uno::Reference<beans::XPropertySet> const & rXPropSet,
+ uno::Reference<graphic::XGraphic> const & rxGraphic,
+ bool bRelPathToMedia)
+{
+ OUString sRelId;
+
+ if (!rxGraphic.is())
+ return sRelId;
+
+ Graphic aGraphic(rxGraphic);
+ if (mpTextExport)
{
- mpFS->singleElementNS( XML_a, XML_lum,
- XML_bright, nBright ? I32S( nBright*1000 ) : nullptr,
- XML_contrast, nContrast ? I32S( nContrast*1000 ) : nullptr,
- FSEND );
+ BitmapChecksum nChecksum = aGraphic.GetChecksum();
+ sRelId = mpTextExport->FindRelId(nChecksum);
}
-
- if( nTransparence )
+ if (sRelId.isEmpty())
{
- sal_Int32 nAlphaMod = (100 - nTransparence ) * PER_PERCENT;
- mpFS->singleElementNS( XML_a, XML_alphaModFix,
- XML_amt, I32S( nAlphaMod), FSEND );
+ sRelId = WriteImage(aGraphic, bRelPathToMedia);
+ if (mpTextExport)
+ {
+ BitmapChecksum nChecksum = aGraphic.GetChecksum();
+ mpTextExport->CacheRelId(nChecksum, sRelId);
+ }
}
- WriteArtisticEffect( rXPropSet );
+ mpFS->startElementNS(XML_a, XML_blip,
+ FSNS(XML_r, XML_embed), sRelId.toUtf8().getStr(),
+ FSEND);
- mpFS->endElementNS( XML_a, XML_blip );
+ WriteImageBrightnessContrastTransparence(rXPropSet);
+
+ WriteArtisticEffect(rXPropSet);
+
+ mpFS->endElementNS(XML_a, XML_blip);
return sRelId;
}
@@ -1128,6 +1178,28 @@ void DrawingML::WriteBlipMode( const Reference< XPropertySet >& rXPropSet, const
}
}
+void DrawingML::WriteXGraphicBlipMode(uno::Reference<beans::XPropertySet> const & rXPropSet,
+ uno::Reference<graphic::XGraphic> const & rxGraphic)
+{
+ BitmapMode eBitmapMode(BitmapMode_NO_REPEAT);
+ if (GetProperty(rXPropSet, "FillBitmapMode"))
+ mAny >>= eBitmapMode;
+
+ SAL_INFO("oox.shape", "fill bitmap mode: " << int(eBitmapMode));
+
+ switch (eBitmapMode)
+ {
+ case BitmapMode_REPEAT:
+ mpFS->singleElementNS(XML_a, XML_tile, FSEND);
+ break;
+ case BitmapMode_STRETCH:
+ WriteXGraphicStretch(rXPropSet, rxGraphic);
+ break;
+ default:
+ break;
+ }
+}
+
void DrawingML::WriteBlipOrNormalFill( const Reference< XPropertySet >& xPropSet, const OUString& rURLPropName )
{
// check for blip and otherwise fall back to normal fill
@@ -1183,6 +1255,33 @@ void DrawingML::WriteBlipFill( const Reference< XPropertySet >& rXPropSet, const
}
}
+void DrawingML::WriteXGraphicBlipFill(uno::Reference<beans::XPropertySet> const & rXPropSet,
+ uno::Reference<graphic::XGraphic> const & rxGraphic,
+ sal_Int32 nXmlNamespace, bool bWriteMode, bool bRelPathToMedia)
+{
+ if (!rxGraphic.is() )
+ return;
+
+ mpFS->startElementNS(nXmlNamespace , XML_blipFill, XML_rotWithShape, "0", FSEND);
+
+ WriteXGraphicBlip(rXPropSet, rxGraphic, bRelPathToMedia);
+
+ if (bWriteMode)
+ {
+ WriteXGraphicBlipMode(rXPropSet, rxGraphic);
+ }
+ else if(GetProperty(rXPropSet, "FillBitmapStretch"))
+ {
+ bool bStretch = mAny.get<bool>();
+
+ if (bStretch)
+ {
+ WriteXGraphicStretch(rXPropSet, rxGraphic);
+ }
+ }
+ mpFS->endElementNS(nXmlNamespace, XML_blipFill);
+}
+
void DrawingML::WritePattFill( const Reference< XPropertySet >& rXPropSet )
{
if ( GetProperty( rXPropSet, "FillHatch" ) )
@@ -1284,6 +1383,42 @@ void DrawingML::WriteStretch( const css::uno::Reference< css::beans::XPropertySe
mpFS->endElementNS( XML_a, XML_stretch );
}
+void DrawingML::WriteXGraphicStretch(uno::Reference<beans::XPropertySet> const & rXPropSet,
+ uno::Reference<graphic::XGraphic> const & rxGraphic)
+{
+ mpFS->startElementNS(XML_a, XML_stretch, FSEND);
+
+ bool bCrop = false;
+ if (GetProperty(rXPropSet, "GraphicCrop"))
+ {
+ css::text::GraphicCrop aGraphicCropStruct;
+ mAny >>= aGraphicCropStruct;
+
+ if ((0 != aGraphicCropStruct.Left)
+ || (0 != aGraphicCropStruct.Top)
+ || (0 != aGraphicCropStruct.Right)
+ || (0 != aGraphicCropStruct.Bottom))
+ {
+ Graphic aGraphic(rxGraphic);
+ Size aOriginalSize(aGraphic.GetPrefSize());
+ mpFS->singleElementNS(XML_a, XML_fillRect,
+ XML_l, I32S(((aGraphicCropStruct.Left) * 100000) / aOriginalSize.Width()),
+ XML_t, I32S(((aGraphicCropStruct.Top) * 100000) / aOriginalSize.Height()),
+ XML_r, I32S(((aGraphicCropStruct.Right) * 100000) / aOriginalSize.Width()),
+ XML_b, I32S(((aGraphicCropStruct.Bottom) * 100000) / aOriginalSize.Height()),
+ FSEND);
+ bCrop = true;
+ }
+ }
+
+ if (!bCrop)
+ {
+ mpFS->singleElementNS(XML_a, XML_fillRect, FSEND);
+ }
+
+ mpFS->endElementNS(XML_a, XML_stretch);
+}
+
void DrawingML::WriteTransformation(const tools::Rectangle& rRect,
sal_Int32 nXmlNamespace, bool bFlipH, bool bFlipV, sal_Int32 nRotation, bool bIsGroupShape)
{
diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx
index 79f53fe66d28..24f6e7fbb539 100644
--- a/oox/source/helper/modelobjecthelper.cxx
+++ b/oox/source/helper/modelobjecthelper.cxx
@@ -24,6 +24,8 @@
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
#include <oox/helper/containerhelper.hxx>
#include <oox/helper/helper.hxx>
#include <osl/diagnose.h>
@@ -134,6 +136,14 @@ OUString ModelObjectHelper::insertFillBitmapUrl( const OUString& rGraphicUrl )
return OUString();
}
+OUString ModelObjectHelper::insertFillBitmapXGraphic(uno::Reference<graphic::XGraphic> const & rxGraphic)
+{
+ uno::Reference<awt::XBitmap> xBitmap(rxGraphic, uno::UNO_QUERY);
+ if (xBitmap.is())
+ return maBitmapUrlContainer.insertObject(maBitmapUrlNameBase, Any(xBitmap), true);
+ return OUString();
+}
+
OUString ModelObjectHelper::getFillBitmapUrl( const OUString &rGraphicName )
{
Any aAny = maBitmapUrlContainer.getObject( rGraphicName );