diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-04-06 18:54:51 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-04-07 10:03:15 +0200 |
commit | 79ef3c7ae3b2f7be5ba6fe38997e846fd9c7e0ee (patch) | |
tree | c36b3f4838cffbcabf628d88f572cc6fa001b0c2 /xmloff/source/draw | |
parent | 795a3ad8efa8b418f3c6477379c13560c3b4b890 (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.cxx | 43 |
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); |