summaryrefslogtreecommitdiff
path: root/xmloff/source/draw
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2021-04-06 18:54:51 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2021-04-07 10:03:15 +0200
commit79ef3c7ae3b2f7be5ba6fe38997e846fd9c7e0ee (patch)
treec36b3f4838cffbcabf628d88f572cc6fa001b0c2 /xmloff/source/draw
parent795a3ad8efa8b418f3c6477379c13560c3b4b890 (diff)
tdf#141467 xmloff,sc,sw: ODF export: reorder flys' ZOrder/z-index harder
Also keep the control layer distinct from the foreground, as a follow-up to tdf#133487. Try to improve the detection of already sorted indexes a bit to avoid unnecessary sorting. Hilariously the test docs require adding 3 additional items to the extension schema. Change-Id: I629d5b09294f679717677b9d89537d905ac4c404 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113696 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'xmloff/source/draw')
-rw-r--r--xmloff/source/draw/shapeexport.cxx43
1 files changed, 33 insertions, 10 deletions
diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
index 823f4dbefb3a..6dea19c1daf6 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -985,7 +985,7 @@ void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xS
namespace xmloff {
void FixZOrder(uno::Reference<drawing::XShapes> const& xShapes,
- std::function<bool(uno::Reference<beans::XPropertySet> const&)> const& rIsInBackground)
+ std::function<unsigned int (uno::Reference<beans::XPropertySet> const&)> const& rGetLayer)
{
uno::Reference<drawing::XShapes3> const xShapes3(xShapes, uno::UNO_QUERY);
assert(xShapes3.is());
@@ -993,29 +993,52 @@ void FixZOrder(uno::Reference<drawing::XShapes> const& xShapes,
{
return; // only SvxDrawPage implements this
}
- std::vector<sal_Int32> background;
- std::vector<sal_Int32> foreground;
+ struct Layer { std::vector<sal_Int32> shapes; sal_Int32 nMin = SAL_MAX_INT32; sal_Int32 nMax = 0; };
+ std::vector<Layer> layers;
// shapes are sorted by ZOrder
sal_Int32 const nCount(xShapes->getCount());
for (sal_Int32 i = 0; i < nCount; ++i)
{
uno::Reference<beans::XPropertySet> const xShape(xShapes->getByIndex(i), uno::UNO_QUERY);
- if (rIsInBackground(xShape))
+ unsigned int const nLayer(rGetLayer(xShape));
+ if (layers.size() <= nLayer)
{
- background.emplace_back(i);
+ layers.resize(nLayer + 1);
}
- else
+ layers[nLayer].shapes.emplace_back(i);
+ if (i < layers[nLayer].nMin)
+ {
+ layers[nLayer].nMin = i;
+ }
+ if (layers[nLayer].nMax < i)
+ {
+ layers[nLayer].nMax = i;
+ }
+ }
+ layers.erase(std::remove_if(layers.begin(), layers.end(),
+ [](Layer const& rLayer) { return rLayer.shapes.empty(); }),
+ layers.end());
+ bool isSorted(true);
+ for (size_t i = 1; i < layers.size(); ++i)
+ {
+ assert(layers[i].nMin != layers[i-1].nMax); // unique!
+ if (layers[i].nMin < layers[i-1].nMax)
{
- foreground.emplace_back(i);
+ isSorted = false;
+ break;
}
}
- if (background.empty() || foreground.empty())
+ if (isSorted)
{
return; // nothing to do
}
uno::Sequence<sal_Int32> aNewOrder(nCount);
- std::copy(background.begin(), background.end(), aNewOrder.begin());
- std::copy(foreground.begin(), foreground.end(), aNewOrder.begin() + background.size());
+ auto iterInsert(aNewOrder.begin());
+ for (auto const& rLayer : layers)
+ {
+ assert(rLayer.nMin <= rLayer.nMax); // empty layers have been removed
+ iterInsert = std::copy(rLayer.shapes.begin(), rLayer.shapes.end(), iterInsert);
+ }
try
{
xShapes3->sort(aNewOrder);