Rebased ref, commits from common ancestor: commit a89aefc93fa25001a99f1cec3d5d25bab16e60b6 Author: Juergen Funk <juergen.funk...@cib.de> Date: Wed Dec 13 12:00:22 2017 +0000
fix build: incompatible exception specs For gcc 4x and 5.2, we need to have matching, or more narrow, exception specs for overridden virtual methods. Change-Id: I2f2da8b8a9ac5639a3d885cd6851e1d0125651b1 diff --git a/filter/source/config/cache/typedetection.hxx b/filter/source/config/cache/typedetection.hxx index f948e6522697..ae75131a0fa6 100644 --- a/filter/source/config/cache/typedetection.hxx +++ b/filter/source/config/cache/typedetection.hxx @@ -383,17 +383,17 @@ private: public: using cppu::WeakComponentImplHelperBase::disposing; - virtual void SAL_CALL disposing(const css::lang::EventObject&) override + virtual void SAL_CALL disposing(const css::lang::EventObject&) throw () override { } // XTerminateListener - virtual void SAL_CALL queryTermination(const css::lang::EventObject&) override + virtual void SAL_CALL queryTermination(const css::lang::EventObject&) throw () override { m_pTypeDetection->cancel(); } - virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) override + virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) throw () override { } diff --git a/sfx2/inc/preventduplicateinteraction.hxx b/sfx2/inc/preventduplicateinteraction.hxx index f9097576e480..0f89169b6087 100644 --- a/sfx2/inc/preventduplicateinteraction.hxx +++ b/sfx2/inc/preventduplicateinteraction.hxx @@ -81,19 +81,19 @@ private: public: using cppu::WeakComponentImplHelperBase::disposing; - virtual void SAL_CALL disposing(const css::lang::EventObject&) override + virtual void SAL_CALL disposing(const css::lang::EventObject&) throw () override { } // XTerminateListener - virtual void SAL_CALL queryTermination(const css::lang::EventObject&) override + virtual void SAL_CALL queryTermination(const css::lang::EventObject&) throw () override { closewarningdialogs(); Application::PostUserEvent(LINK(this, WarningDialogsParent, TerminateDesktop)); throw css::frame::TerminationVetoException(); } - virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) override + virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) throw () override { } @@ -221,7 +221,8 @@ class PreventDuplicateInteraction : private ThreadHelpBase2 // uno interface public: - virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override; + virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) + throw(css::uno::RuntimeException, std::exception) override; /** @interface XInteractionHandler diff --git a/sfx2/source/appl/preventduplicateinteraction.cxx b/sfx2/source/appl/preventduplicateinteraction.cxx index 7ef25e70e82d..dd7263d51c6d 100644 --- a/sfx2/source/appl/preventduplicateinteraction.cxx +++ b/sfx2/source/appl/preventduplicateinteraction.cxx @@ -243,6 +243,7 @@ bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type& } void SAL_CALL PreventDuplicateInteraction::initialize(const css::uno::Sequence<css::uno::Any>& rArguments) + throw (css::uno::RuntimeException, std::exception) { // If we're re-initialized to set a specific new window as a parent then drop our temporary // dialog parent commit 5722c826a0eecc52892df4e839aa78f0861be80f Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Jul 22 18:00:59 2016 +0200 Remove now unused SwTextBoxHelper functions (Manually cherry picked from commit f7f5d27066b696ac4e33246d3794bde8058e8622) Change-Id: I39500424c79040b1887ea74081fdf0ea0bc5f009 Reviewed-on: https://gerrit.libreoffice.org/46331 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 98983bad9f42..32fc2167c72a 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -73,8 +73,6 @@ public: static SwFrameFormat* getOtherTextBoxFormat(const SwFrameFormat* pFormat, sal_uInt16 nType); /// If we have an associated TextFrame, then return that. static SwFrameFormat* getOtherTextBoxFormat(css::uno::Reference<css::drawing::XShape> xShape); - static SwFrameFormat* findTextBox(const SwFrameFormat* pShape); - static SwFrameFormat* findTextBox(const css::uno::Reference<css::drawing::XShape>& xShape); /// Return the textbox rectangle of a draw shape (in twips). static Rectangle getTextRectangle(SwFrameFormat* pShape, bool bAbsolute = true); @@ -91,17 +89,6 @@ public: /// Is pObject a textbox of a drawinglayer shape? static bool isTextBox(const SdrObject* pObject); - /// Look up TextFrames in a document, which are in fact TextBoxes. - static std::set<const SwFrameFormat*> findTextBoxes(const SwDoc* pDoc); - /** - * Look up TextFrames in a document, which are in fact TextBoxes. - * - * If rNode has a matching SwContentFrame, then only TextBoxes of rNode are - * returned. - */ - static std::set<const SwFrameFormat*> findTextBoxes(const SwNode& rNode); - /// Build a textbox -> shape format map. - static std::map<SwFrameFormat*, SwFrameFormat*> findShapes(const SwDoc* pDoc); /// Count number of shapes in the document, excluding TextBoxes. static sal_Int32 getCount(const SwDoc* pDoc); /// Count number of shapes on the page, excluding TextBoxes. diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 12464e37e4b6..23033eaeea38 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -126,27 +126,6 @@ void SwTextBoxHelper::destroy(SwFrameFormat* pShape) } } -std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc) -{ - std::set<const SwFrameFormat*> aTextBoxes; - - const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats(); - for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != rSpzFrameFormats.end(); ++it) - { - const SwFrameFormat* pFormat = *it; - - // A TextBox in the context of this class is a fly frame that has a - // matching (same RES_CNTNT) draw frame. - if (!pFormat->GetAttrSet().HasItem(RES_CNTNT) || !pFormat->GetContent().GetContentIdx()) - continue; - - if (pFormat->Which() == RES_FLYFRMFMT && nullptr != pFormat->GetOtherTextBoxFormat()) - aTextBoxes.insert(pFormat); - } - - return aTextBoxes; -} - bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pShape, sal_uInt16 nType) { assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT); @@ -169,49 +148,6 @@ bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pShape, sal_uInt16 nType) return true; } -std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwNode& rNode) -{ - const SwDoc* pDoc = rNode.GetDoc(); - const SwContentNode* pContentNode = nullptr; - const SwContentFrame* pContentFrame = nullptr; - bool bHaveViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(); - if (bHaveViewShell && (pContentNode = rNode.GetContentNode()) && (pContentFrame = pContentNode->getLayoutFrame(pDoc->getIDocumentLayoutAccess().GetCurrentLayout()))) - { - // We can use the layout information to iterate over only the frames which are anchored to us. - std::set<const SwFrameFormat*> aRet; - const SwSortedObjs* pSortedObjs = pContentFrame->GetDrawObjs(); - if (pSortedObjs) - { - for (SwAnchoredObject* pAnchoredObject : *pSortedObjs) - { - SwFrameFormat* pTextBox = getOtherTextBoxFormat(&pAnchoredObject->GetFrameFormat(), RES_DRAWFRMFMT); - if (pTextBox) - aRet.insert(pTextBox); - } - } - return aRet; - } - else - // If necessary, here we could manually limit the returned set to the - // ones which are anchored to rNode, but currently no need to do so. - return findTextBoxes(pDoc); -} - -std::map<SwFrameFormat*, SwFrameFormat*> SwTextBoxHelper::findShapes(const SwDoc* pDoc) -{ - std::map<SwFrameFormat*, SwFrameFormat*> aRet; - - const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats(); - for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != rSpzFrameFormats.end(); ++it) - { - SwFrameFormat* pTextBox = getOtherTextBoxFormat(*it, RES_DRAWFRMFMT); - if (pTextBox) - aRet[pTextBox] = *it; - } - - return aRet; -} - bool SwTextBoxHelper::isTextBox(const SdrObject* pObject) { const SwVirtFlyDrawObj* pVirtFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(pObject); @@ -312,39 +248,6 @@ SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XS return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT); } -SwFrameFormat* SwTextBoxHelper::findTextBox(const uno::Reference<drawing::XShape>& xShape) -{ - SwXShape* pShape = dynamic_cast<SwXShape*>(xShape.get()); - if (!pShape) - return nullptr; - - return findTextBox(pShape->GetFrameFormat()); -} - -SwFrameFormat* SwTextBoxHelper::findTextBox(const SwFrameFormat* pShape) -{ - SwFrameFormat* pRet = nullptr; - - // Only draw frames can have TextBoxes. - if (pShape && pShape->Which() == RES_DRAWFRMFMT && pShape->GetAttrSet().HasItem(RES_CNTNT)) - { - const SwFormatContent& rContent = pShape->GetContent(); - const SwFrameFormats& rSpzFrameFormats = *pShape->GetDoc()->GetSpzFrameFormats(); - for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != rSpzFrameFormats.end(); ++it) - { - SwFrameFormat* pFormat = *it; - // Only a fly frame can be a TextBox. - if (pFormat->Which() == RES_FLYFRMFMT && pFormat->GetAttrSet().HasItem(RES_CNTNT) && pFormat->GetContent() == rContent) - { - pRet = pFormat; - break; - } - } - } - - return pRet; -} - template < typename T > void lcl_queryInterface(SwFrameFormat* pShape, uno::Any& rAny) { commit db35f3d3a066305147721ad5dae1027415297035 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Jul 22 17:59:28 2016 +0200 Add convenience function getOtherTextBoxFormat Since we already have isTextBox to identify a text box, this just adds a call to SwFrameFormat::GetOtherTextBoxFormat() to actually return the corresponding SwFrameFormat. This gets rid off all the remaining occurences of the SwFrameFormat / Textbox sets and maps. (Manually cherry picked from commit f7f5d27066b696ac4e33246d3794bde8058e8622) Change-Id: Id5f05a1ff71e604658e7d8a0d0825f5671335b3f Reviewed-on: https://gerrit.libreoffice.org/46330 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index eb94bbc1d194..98983bad9f42 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -62,7 +62,17 @@ public: /// Similar to syncProperty(), but used by the internal API (e.g. for UI purposes). static void syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet& rSet); + /** + * If we have an associated TextFrame, then return that. + * + * @param nType Expected frame format type. + * Valid types are RES_DRAWFRMFMT and RES_FLYFRMFMT. + * + * @see isTextBox + */ + static SwFrameFormat* getOtherTextBoxFormat(const SwFrameFormat* pFormat, sal_uInt16 nType); /// If we have an associated TextFrame, then return that. + static SwFrameFormat* getOtherTextBoxFormat(css::uno::Reference<css::drawing::XShape> xShape); static SwFrameFormat* findTextBox(const SwFrameFormat* pShape); static SwFrameFormat* findTextBox(const css::uno::Reference<css::drawing::XShape>& xShape); /// Return the textbox rectangle of a draw shape (in twips). diff --git a/sw/source/core/doc/DocumentLayoutManager.cxx b/sw/source/core/doc/DocumentLayoutManager.cxx index 5fc0d4cc7483..254a4ee14ba7 100644 --- a/sw/source/core/doc/DocumentLayoutManager.cxx +++ b/sw/source/core/doc/DocumentLayoutManager.cxx @@ -494,7 +494,7 @@ SwFrameFormat *DocumentLayoutManager::CopyLayoutFormat( pDest->MakeFrames(); // If the draw format has a TextBox, then copy its fly format as well. - if (SwFrameFormat* pSourceTextBox = SwTextBoxHelper::findTextBox(&rSource)) + if (SwFrameFormat* pSourceTextBox = SwTextBoxHelper::getOtherTextBoxFormat(&rSource, RES_DRAWFRMFMT)) { SwFormatAnchor boxAnchor(rNewAnchor); if (FLY_AS_CHAR == boxAnchor.GetAnchorId()) diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 33571730300e..12464e37e4b6 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -115,7 +115,7 @@ void SwTextBoxHelper::destroy(SwFrameFormat* pShape) // If a TextBox was enabled previously if (pShape->GetAttrSet().HasItem(RES_CNTNT)) { - SwFrameFormat* pFormat = findTextBox(pShape); + SwFrameFormat* pFormat = pShape->GetOtherTextBoxFormat(); // Unlink the TextBox's text range from the original shape. pShape->ResetFormatAttr(RES_CNTNT); @@ -129,7 +129,6 @@ void SwTextBoxHelper::destroy(SwFrameFormat* pShape) std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc) { std::set<const SwFrameFormat*> aTextBoxes; - std::map<SwNodeIndex, const SwFrameFormat*> aFlyFormats, aDrawFormats; const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats(); for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != rSpzFrameFormats.end(); ++it) @@ -141,22 +140,8 @@ std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc) if (!pFormat->GetAttrSet().HasItem(RES_CNTNT) || !pFormat->GetContent().GetContentIdx()) continue; - const SwNodeIndex& rIndex = *pFormat->GetContent().GetContentIdx(); - - if (pFormat->Which() == RES_FLYFRMFMT) - { - if (aDrawFormats.find(rIndex) != aDrawFormats.end()) - aTextBoxes.insert(pFormat); - else - aFlyFormats[rIndex] = pFormat; - } - else if (pFormat->Which() == RES_DRAWFRMFMT) - { - if (aFlyFormats.find(rIndex) != aFlyFormats.end()) - aTextBoxes.insert(aFlyFormats[rIndex]); - else - aDrawFormats[rIndex] = pFormat; - } + if (pFormat->Which() == RES_FLYFRMFMT && nullptr != pFormat->GetOtherTextBoxFormat()) + aTextBoxes.insert(pFormat); } return aTextBoxes; @@ -199,7 +184,7 @@ std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwNode& rNod { for (SwAnchoredObject* pAnchoredObject : *pSortedObjs) { - SwFrameFormat* pTextBox = findTextBox(&pAnchoredObject->GetFrameFormat()); + SwFrameFormat* pTextBox = getOtherTextBoxFormat(&pAnchoredObject->GetFrameFormat(), RES_DRAWFRMFMT); if (pTextBox) aRet.insert(pTextBox); } @@ -219,7 +204,7 @@ std::map<SwFrameFormat*, SwFrameFormat*> SwTextBoxHelper::findShapes(const SwDoc const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats(); for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != rSpzFrameFormats.end(); ++it) { - SwFrameFormat* pTextBox = findTextBox(*it); + SwFrameFormat* pTextBox = getOtherTextBoxFormat(*it, RES_DRAWFRMFMT); if (pTextBox) aRet[pTextBox] = *it; } @@ -305,11 +290,26 @@ sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject) void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough) { - std::map<SwFrameFormat*, SwFrameFormat*> aMap = findShapes(pTextBox->GetDoc()); - std::map<SwFrameFormat*, SwFrameFormat*>::iterator it = aMap.find(const_cast<SwFrameFormat*>(pTextBox)); - if (it != aMap.end()) - // pTextBox is indeed a TextBox, it->second is its shape. - rWrapThrough = it->second->GetSurround().GetSurround() == SURROUND_THROUGHT; + SwFrameFormat *pShape = SwTextBoxHelper::getOtherTextBoxFormat(pTextBox, RES_FLYFRMFMT); + if (pShape) + rWrapThrough = pShape->GetSurround().GetSurround() == SURROUND_THROUGHT; +} + +SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(const SwFrameFormat* pFormat, sal_uInt16 nType) +{ + if (!isTextBox(pFormat, nType)) + return nullptr; + return pFormat->GetOtherTextBoxFormat(); +} + +SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XShape> xShape) +{ + SwXShape* pShape = dynamic_cast<SwXShape*>(xShape.get()); + if (!pShape) + return nullptr; + + SwFrameFormat *pFormat = pShape->GetFrameFormat(); + return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT); } SwFrameFormat* SwTextBoxHelper::findTextBox(const uno::Reference<drawing::XShape>& xShape) @@ -348,7 +348,7 @@ SwFrameFormat* SwTextBoxHelper::findTextBox(const SwFrameFormat* pShape) template < typename T > void lcl_queryInterface(SwFrameFormat* pShape, uno::Any& rAny) { - if (SwFrameFormat* pFormat = SwTextBoxHelper::findTextBox(pShape)) + if (SwFrameFormat* pFormat = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)) { uno::Reference<T> const xInterface( SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), @@ -426,7 +426,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, const OUString& rPrope syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION, uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top())))); } - if (SwFrameFormat* pFormat = findTextBox(pShape)) + if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)) { comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue); // That would be the btLr text direction which we don't support at a frame level, so do it at a character level. @@ -460,7 +460,7 @@ void SwTextBoxHelper::getProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uI nMemberId &= ~CONVERT_TWIPS; - if (SwFrameFormat* pFormat = findTextBox(pShape)) + if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)) { if (nWID == RES_CHAIN) { @@ -490,7 +490,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_u uno::Any aValue(rValue); nMemberId &= ~CONVERT_TWIPS; - if (SwFrameFormat* pFormat = findTextBox(pShape)) + if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)) { OUString aPropertyName; bool bAdjustX = false; @@ -631,9 +631,7 @@ void SwTextBoxHelper::saveLinks(const SwFrameFormats& rFormats, std::map<const S for (std::size_t i = 0; i < rFormats.size(); ++i) { const SwFrameFormat* pFormat = rFormats[i]; - if (pFormat->Which() != RES_DRAWFRMFMT) - continue; - if (SwFrameFormat* pTextBox = findTextBox(pFormat)) + if (SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) rLinks[pFormat] = pTextBox; } } @@ -670,7 +668,7 @@ void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrame void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet& rSet) { - if (SwFrameFormat* pFormat = findTextBox(&rShape)) + if (SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT)) { SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), aFrameFormatSetRange); diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index 2bd03bfce93c..1d036aa7d125 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -966,7 +966,7 @@ void SwDrawView::DeleteMarked() SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj(); SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall(pObject)); SwFrameFormat* pFormat = pDrawContact->GetFormat(); - if (SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(pFormat)) + if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) aTextBoxesToDelete.push_back(pTextBox); } diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index e41ee3965cde..2c8553b64efc 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -232,15 +232,13 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj ) if (!(nFlag & SW_ALLOW_TEXTBOX)) { // If the fly frame is a textbox of a shape, then select the shape instead. - std::map<SwFrameFormat*, SwFrameFormat*> aTextBoxShapes = SwTextBoxHelper::findShapes(mpDoc); for (size_t i = 0; i < rMrkList.GetMarkCount(); ++i) { SdrObject* pObject = rMrkList.GetMark(i)->GetMarkedSdrObj(); - SwContact* pDrawContact = static_cast<SwContact*>(GetUserCall(pObject)); - SwFrameFormat* pFormat = pDrawContact->GetFormat(); - if (aTextBoxShapes.find(pFormat) != aTextBoxShapes.end()) + SwFrameFormat* pFormat = GetUserCall(pObject)->GetFormat(); + if (SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT)) { - SdrObject* pShape = aTextBoxShapes[pFormat]->FindSdrObject(); + SdrObject* pShape = pShapeFormat->FindSdrObject(); pDView->UnmarkAll(); pDView->MarkObj(pShape, Imp()->GetPageView(), bAddSelect, bEnterGroup); break; diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index 66c131d80f6d..fa98ceaf5c4c 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -1294,11 +1294,10 @@ void SwFlyFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderA } mbValidSize = true; - std::map<SwFrameFormat*, SwFrameFormat*> aShapes = SwTextBoxHelper::findShapes(GetFormat()->GetDoc()); - if (aShapes.find(GetFormat()) != aShapes.end()) + if (SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(GetFormat(), RES_FLYFRMFMT)) { // This fly is a textbox of a draw shape. - SdrObject* pShape = aShapes[GetFormat()]->FindSdrObject(); + SdrObject* pShape = pShapeFormat->FindSdrObject(); if (SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>( pShape) ) { // The shape is a customshape: then inform it about the calculated fly size. diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx index 43ab530992ae..a0b91031522d 100644 --- a/sw/source/core/text/porfly.cxx +++ b/sw/source/core/text/porfly.cxx @@ -359,7 +359,7 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, const Point &rBase, if (rAnchor.GetAnchorId() == FLY_AS_CHAR) { // This is an inline draw shape, see if it has a textbox. - SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(pShape); + SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT); if (pTextBox) { // It has, so look up its text rectangle, and adjust the position diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index f05afd2652ab..fcd5bcf5f498 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -5428,7 +5428,7 @@ void DocxAttributeOutput::WriteTextBox(uno::Reference<drawing::XShape> xShape) DocxTableExportContext aTableExportContext; pushToTableExportContext(aTableExportContext); - SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(xShape); + SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(xShape); const SwPosition* pAnchor = pTextBox->GetAnchor().GetContentAnchor(); ww8::Frame aFrame(*pTextBox, *pAnchor); m_rExport.SdrExporter().writeDMLTextFrame(&aFrame, m_anchorId++, /*bTextBoxOnly=*/true); @@ -5441,7 +5441,7 @@ void DocxAttributeOutput::WriteVMLTextBox(uno::Reference<drawing::XShape> xShape DocxTableExportContext aTableExportContext; pushToTableExportContext(aTableExportContext); - SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(xShape); + SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(xShape); const SwPosition* pAnchor = pTextBox->GetAnchor().GetContentAnchor(); ww8::Frame aFrame(*pTextBox, *pAnchor); m_rExport.SdrExporter().writeVMLTextFrame(&aFrame, /*bTextBoxOnly=*/true); diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx index f303e8a379a6..48da64f56d56 100644 --- a/sw/source/filter/ww8/rtfsdrexport.cxx +++ b/sw/source/filter/ww8/rtfsdrexport.cxx @@ -39,8 +39,7 @@ RtfSdrExport::RtfSdrExport(RtfExport& rExport) m_nShapeType(ESCHER_ShpInst_Nil), m_nShapeFlags(0) , m_aShapeStyle(200), - m_pShapeTypeWritten(new bool[ ESCHER_ShpInst_COUNT ]), - m_aTextBoxes(SwTextBoxHelper::findTextBoxes(m_rExport.m_pDoc)) + m_pShapeTypeWritten(new bool[ ESCHER_ShpInst_COUNT ]) { mnGroupLevel = 1; memset(m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof(bool)); @@ -514,7 +513,7 @@ sal_Int32 RtfSdrExport::StartShape() const SwFrameFormat* pShape = FindFrameFormat(m_pSdrObject); if (pShape) { - if (SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(pShape)) + if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)) { ww8::Frame* pFrame = nullptr; for (ww8::FrameIter it = m_rExport.m_aFrames.begin(); it != m_rExport.m_aFrames.end(); ++it) diff --git a/sw/source/filter/ww8/rtfsdrexport.hxx b/sw/source/filter/ww8/rtfsdrexport.hxx index 15a7fbf7e705..eef0b5047a54 100644 --- a/sw/source/filter/ww8/rtfsdrexport.hxx +++ b/sw/source/filter/ww8/rtfsdrexport.hxx @@ -56,9 +56,6 @@ class RtfSdrExport : public EscherEx /// Remember which shape types we had already written. bool* m_pShapeTypeWritten; - /// List of TextBoxes in this document: they are exported as part of their shape, never alone. - std::set<const SwFrameFormat*> m_aTextBoxes; - public: explicit RtfSdrExport(RtfExport& rExport); virtual ~RtfSdrExport(); diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 2ded67656383..b8b8b588c296 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -204,7 +204,7 @@ static bool lcl_goIntoTextBox(SwEditWin& rEditWin, SwWrtShell& rSh) { SdrObject* pSdrObject = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pObjectFormat = ::FindFrameFormat(pSdrObject); - if (SwFrameFormat* pTextBoxFormat = SwTextBoxHelper::findTextBox(pObjectFormat)) + if (SwFrameFormat* pTextBoxFormat = SwTextBoxHelper::getOtherTextBoxFormat(pObjectFormat, RES_DRAWFRMFMT)) { SdrObject* pTextBox = pTextBoxFormat->FindRealSdrObject(); SdrView* pSdrView = rSh.GetDrawView(); @@ -4402,10 +4402,9 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) SdrPageView* pPV; if (pSdrView && pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER )) { - std::map<SwFrameFormat*, SwFrameFormat*> aTextBoxShapes = SwTextBoxHelper::findShapes(rSh.GetDoc()); - auto pDrawContact = GetUserCall(pObj); - SwFrameFormat* pFormat = pDrawContact->GetFormat(); - if (aTextBoxShapes.find(pFormat) == aTextBoxShapes.end()) + SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat(); + SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT); + if (!pShapeFormat) { pSdrView->UnmarkAllObj(); pSdrView->MarkObj(pObj,pPV); @@ -4413,7 +4412,7 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) else { // If the fly frame is a textbox of a shape, then select the shape instead. - SdrObject* pShape = aTextBoxShapes[pFormat]->FindSdrObject(); + SdrObject* pShape = pShapeFormat->FindSdrObject(); pSdrView->UnmarkAllObj(); pSdrView->MarkObj(pShape, pPV); } commit 8f47312716d0a36ecee5ebf6d4ebffce61d74df0 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Jul 22 17:50:52 2016 +0200 Switch isTextBox to use the format pointers This replaces all possible occurences of the text box format maps, which just want to know, if a SwFrameFormat is part of a text box to use the direct lookup via the isTextBox, which is now a cheap call. (Manually cherry picked from commit 0bcc5b3daebeb2a7d2b5ba132af4745cc6c78cd0) Change-Id: I3b4e2301f816aead1b719cd70a8ef118e685ccfc Reviewed-on: https://gerrit.libreoffice.org/46306 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index cce179607181..eb94bbc1d194 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -68,6 +68,19 @@ public: /// Return the textbox rectangle of a draw shape (in twips). static Rectangle getTextRectangle(SwFrameFormat* pShape, bool bAbsolute = true); + /** + * Is the frame format a text box? + * + * A text box consists of a coupled fly and draw format. Most times you + * just want to check for a single type, otherwise you get duplicate results. + * + * @param nType Expected frame format input type. + * Valid types are RES_DRAWFRMFMT and RES_FLYFRMFMT. + */ + static bool isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType); + /// Is pObject a textbox of a drawinglayer shape? + static bool isTextBox(const SdrObject* pObject); + /// Look up TextFrames in a document, which are in fact TextBoxes. static std::set<const SwFrameFormat*> findTextBoxes(const SwDoc* pDoc); /** @@ -77,16 +90,16 @@ public: * returned. */ static std::set<const SwFrameFormat*> findTextBoxes(const SwNode& rNode); - /// Is pObject a textbox of a drawinglayer shape? - static bool isTextBox(const SdrObject* pObject); /// Build a textbox -> shape format map. static std::map<SwFrameFormat*, SwFrameFormat*> findShapes(const SwDoc* pDoc); /// Count number of shapes in the document, excluding TextBoxes. - static sal_Int32 getCount(SdrPage* pPage, std::set<const SwFrameFormat*>& rTextBoxes); + static sal_Int32 getCount(const SwDoc* pDoc); + /// Count number of shapes on the page, excluding TextBoxes. + static sal_Int32 getCount(SdrPage* pPage); /// Get a shape by index, excluding TextBoxes. - static css::uno::Any getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::set<const SwFrameFormat*>& rTextBoxes) throw(css::lang::IndexOutOfBoundsException); + static css::uno::Any getByIndex(SdrPage* pPage, sal_Int32 nIndex) throw(css::lang::IndexOutOfBoundsException); /// Get the order of the shape, excluding TextBoxes. - static sal_Int32 getOrdNum(const SdrObject* pObject, std::set<const SwFrameFormat*>& rTextBoxes); + static sal_Int32 getOrdNum(const SdrObject* pObject); /// If pTextBox is a textbox, then set rWrapThrough to the surround of its shape. static void getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough); diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 119ff204d179..766ab7199419 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -858,9 +858,8 @@ void SwUiWriterTest::testFdo82191() { SwDoc* pDoc = createDoc("fdo82191.odt"); SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); // Make sure we have a single draw shape. - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage, aTextBoxes)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage)); SwDoc aClipboard; SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); @@ -870,9 +869,8 @@ void SwUiWriterTest::testFdo82191() pWrtShell->Copy(&aClipboard); pWrtShell->Paste(&aClipboard); - aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); // This was one: the textbox of the shape wasn't copied. - CPPUNIT_ASSERT_EQUAL(size_t(2), aTextBoxes.size()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), SwTextBoxHelper::getCount(pDoc)); } void SwUiWriterTest::testCommentedWord() @@ -3389,15 +3387,20 @@ void SwUiWriterTest::testTdf92648() { SwDoc* pDoc = createDoc("tdf92648.docx"); SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); // Make sure we have ten draw shapes. - CPPUNIT_ASSERT_EQUAL(sal_Int32(10), SwTextBoxHelper::getCount(pPage, aTextBoxes)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(10), SwTextBoxHelper::getCount(pPage)); // and the text boxes haven't got zero height - for (std::set<const SwFrameFormat*>::iterator it=aTextBoxes.begin(); it!=aTextBoxes.end(); ++it) + sal_Int32 nCount = 0; + for (const SwFrameFormat* pFormat : *pDoc->GetSpzFrameFormats()) { - SwFormatFrameSize aSize((*it)->GetFrameSize()); + if (!SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT)) + continue; + SwFormatFrameSize aSize(pFormat->GetFrameSize()); CPPUNIT_ASSERT(aSize.GetHeight() != 0); + ++nCount; } + // and we have had five of them. + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nCount); } void SwUiWriterTest::testTdf96515() @@ -3721,8 +3724,7 @@ void SwUiWriterTest::testTdf78727() SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); // This was 1: make sure we don't loose the TextBox anchored inside the // table that is moved inside a text frame. - std::set<const SwFrameFormat*> aSet; - CPPUNIT_ASSERT(SwTextBoxHelper::getCount(pPage, aSet) > 1); + CPPUNIT_ASSERT(SwTextBoxHelper::getCount(pPage) > 1); } // accepting change tracking gets stuck on change diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index e1291b6673ba..98ffdae260f3 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -79,15 +79,11 @@ size_t SwDoc::GetFlyCount( FlyCntType eType, bool bIgnoreTextBoxes ) const size_t nCount = 0; const SwNodeIndex* pIdx; - std::set<const SwFrameFormat*> aTextBoxes; - if (bIgnoreTextBoxes) - aTextBoxes = SwTextBoxHelper::findTextBoxes(this); - for ( size_t i = 0; i < nSize; ++i) { const SwFrameFormat* pFlyFormat = rFormats[ i ]; - if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFormat) != aTextBoxes.end()) + if (bIgnoreTextBoxes && SwTextBoxHelper::isTextBox(pFlyFormat, RES_FLYFRMFMT)) continue; if( RES_FLYFRMFMT == pFlyFormat->Which() @@ -131,15 +127,11 @@ SwFrameFormat* SwDoc::GetFlyNum( size_t nIdx, FlyCntType eType, bool bIgnoreText const SwNodeIndex* pIdx; size_t nCount = 0; - std::set<const SwFrameFormat*> aTextBoxes; - if (bIgnoreTextBoxes) - aTextBoxes = SwTextBoxHelper::findTextBoxes(this); - for( size_t i = 0; !pRetFormat && i < nSize; ++i ) { SwFrameFormat* pFlyFormat = rFormats[ i ]; - if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFormat) != aTextBoxes.end()) + if (bIgnoreTextBoxes && SwTextBoxHelper::isTextBox(pFlyFormat, RES_FLYFRMFMT)) continue; if( RES_FLYFRMFMT == pFlyFormat->Which() @@ -177,10 +169,6 @@ std::vector<SwFrameFormat const*> SwDoc::GetFlyFrameFormats( SwFrameFormats& rFormats = *GetSpzFrameFormats(); const size_t nSize = rFormats.size(); - std::set<const SwFrameFormat*> aTextBoxes; - if (bIgnoreTextBoxes) - aTextBoxes = SwTextBoxHelper::findTextBoxes(this); - std::vector<SwFrameFormat const*> ret; ret.reserve(nSize); @@ -188,7 +176,7 @@ std::vector<SwFrameFormat const*> SwDoc::GetFlyFrameFormats( { SwFrameFormat const*const pFlyFormat = rFormats[ i ]; - if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFormat) != aTextBoxes.end()) + if (bIgnoreTextBoxes && SwTextBoxHelper::isTextBox(pFlyFormat, RES_FLYFRMFMT)) { continue; } diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index c75908384ebf..33571730300e 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -162,6 +162,28 @@ std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc) return aTextBoxes; } +bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pShape, sal_uInt16 nType) +{ + assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT); + if (!pShape || pShape->Which() != nType || !pShape->GetAttrSet().HasItem(RES_CNTNT)) + return false; + + sal_uInt16 nOtherType = (pShape->Which() == RES_FLYFRMFMT) ? RES_DRAWFRMFMT : RES_FLYFRMFMT; + SwFrameFormat* pFormat = pShape->GetOtherTextBoxFormat(); + if (!pFormat) + return false; + + assert(pFormat->Which() == nOtherType); + if (pFormat->Which() != nOtherType) + return false; + + const SwFormatContent& rContent = pShape->GetContent(); + if (!pFormat->GetAttrSet().HasItem(RES_CNTNT) || pFormat->GetContent() != rContent) + return false; + + return true; +} + std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwNode& rNode) { const SwDoc* pDoc = rNode.GetDoc(); @@ -205,35 +227,39 @@ std::map<SwFrameFormat*, SwFrameFormat*> SwTextBoxHelper::findShapes(const SwDoc return aRet; } -/// If the passed SdrObject is in fact a TextFrame, that is used as a TextBox. -bool lcl_isTextBox(SdrObject* pSdrObject, std::set<const SwFrameFormat*>& rTextBoxes) -{ - SwVirtFlyDrawObj* pObject = dynamic_cast<SwVirtFlyDrawObj*>(pSdrObject); - return pObject && rTextBoxes.find(pObject->GetFormat()) != rTextBoxes.end(); -} - bool SwTextBoxHelper::isTextBox(const SdrObject* pObject) { const SwVirtFlyDrawObj* pVirtFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(pObject); if (!pVirtFlyDrawObj) return false; - std::set<const SwFrameFormat*> aTextBoxes = findTextBoxes(pVirtFlyDrawObj->GetFormat()->GetDoc()); - return aTextBoxes.find(pVirtFlyDrawObj->GetFormat()) != aTextBoxes.end(); + return isTextBox(pVirtFlyDrawObj->GetFormat(), RES_FLYFRMFMT); } -sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage, std::set<const SwFrameFormat*>& rTextBoxes) +sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage) { sal_Int32 nRet = 0; for (std::size_t i = 0; i < pPage->GetObjCount(); ++i) { - if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes)) + if (isTextBox(pPage->GetObj(i))) continue; ++nRet; } return nRet; } -uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::set<const SwFrameFormat*>& rTextBoxes) throw(lang::IndexOutOfBoundsException) +sal_Int32 SwTextBoxHelper::getCount(const SwDoc* pDoc) +{ + sal_Int32 nRet = 0; + const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats(); + for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != rSpzFrameFormats.end(); ++it) + { + if (isTextBox(*it, RES_FLYFRMFMT)) + ++nRet; + } + return nRet; +} + +uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex) throw(lang::IndexOutOfBoundsException) { if (nIndex < 0) throw lang::IndexOutOfBoundsException(); @@ -242,7 +268,7 @@ uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::set< sal_Int32 nCount = 0; // Current logical index. for (std::size_t i = 0; i < pPage->GetObjCount(); ++i) { - if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes)) + if (isTextBox(pPage->GetObj(i))) continue; if (nCount == nIndex) { @@ -258,14 +284,14 @@ uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::set< return uno::makeAny(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY)); } -sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject, std::set<const SwFrameFormat*>& rTextBoxes) +sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject) { if (const SdrPage* pPage = pObject->GetPage()) { sal_Int32 nOrder = 0; // Current logical order. for (std::size_t i = 0; i < pPage->GetObjCount(); ++i) { - if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes)) + if (isTextBox(pPage->GetObj(i))) continue; if (pPage->GetObj(i) == pObject) return nOrder; diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index b9ef741b2d35..080af8dc9386 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -1151,7 +1151,7 @@ class NestedUserCallHdl /// Notify the format's textbox that it should reconsider its position / size. void lcl_textBoxSizeNotify(SwFrameFormat* pFormat) { - if (SwTextBoxHelper::findTextBox(pFormat)) + if (SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT)) { // Just notify the textbox that the size has changed, the actual object size is not interesting. SfxItemSet aResizeSet(pFormat->GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 0); diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index 5506cb9b8e58..a33f4bb906bf 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -902,7 +902,6 @@ bool SwFEShell::Paste( SwDoc* pClpDoc ) if( !Imp()->GetDrawView() ) MakeDrawView(); - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pClpDoc); for ( auto pCpyFormat : *pClpDoc->GetSpzFrameFormats() ) { bool bInsWithFormat = true; @@ -972,7 +971,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc ) } // Ignore TextBoxes, they are already handled in sw::DocumentLayoutManager::CopyLayoutFormat(). - if (aTextBoxes.find(pCpyFormat) != aTextBoxes.end()) + if (SwTextBoxHelper::isTextBox(pCpyFormat, RES_FLYFRMFMT)) continue; aAnchor.SetAnchor( pPos ); diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx index d369ac46132a..2f387808b11e 100644 --- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx @@ -505,7 +505,7 @@ SwTwips SwAnchoredObjectPosition::ImplAdjustVertRelPos( const SwTwips nTopOfAnch pFrameFormat->SetFormatAttr(aSize); } nAdjustedRelPosY = nProposedRelPosY; - } else if ( SwTextBoxHelper::findTextBox(pFormat) ) + } else if ( SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT) ) // when the shape has a textbox, use only the proposed vertical position nAdjustedRelPosY = nProposedRelPosY; } diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx index 09ee314ace34..c37608ddb3ab 100644 --- a/sw/source/core/unocore/unocoll.cxx +++ b/sw/source/core/unocore/unocoll.cxx @@ -1080,13 +1080,11 @@ SwXFrameEnumeration<T>::SwXFrameEnumeration(const SwDoc* const pDoc) // #i104937# SwFrameFormat* pFormat( nullptr ); - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); - for( size_t i = 0; i < nSize; ++i ) { // #i104937# pFormat = (*pFormats)[i]; - if(pFormat->Which() != RES_FLYFRMFMT || aTextBoxes.find(pFormat) != aTextBoxes.end()) + if(pFormat->Which() != RES_FLYFRMFMT || SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT)) continue; const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx(); if(!pIdx || !pIdx->GetNodes().IsDocNodes()) diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index 47ebb0b719e5..8ecd6d4ba2a0 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -400,10 +400,9 @@ SwXShapesEnumeration::SwXShapesEnumeration(SwXDrawPage* const pDrawPage) SolarMutexGuard aGuard; ::std::insert_iterator<shapescontainer_t> pInserter = ::std::insert_iterator<shapescontainer_t>(m_aShapes, m_aShapes.begin()); sal_Int32 nCount = pDrawPage->getCount(); - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDrawPage->GetDoc()); for(sal_Int32 nIdx = 0; nIdx < nCount; nIdx++) { - uno::Reference<drawing::XShape> xShape(pDrawPage->getByIndex(nIdx, &aTextBoxes), uno::UNO_QUERY); + uno::Reference<drawing::XShape> xShape(pDrawPage->getByIndex(nIdx), uno::UNO_QUERY); *pInserter++ = uno::makeAny(xShape); } } @@ -526,13 +525,7 @@ sal_Int32 SwXDrawPage::getCount() throw( uno::RuntimeException, std::exception ) else { static_cast<SwXDrawPage*>(this)->GetSvxPage(); - - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); - - if (aTextBoxes.empty()) - return pDrawPage->getCount(); - else - return SwTextBoxHelper::getCount(pDrawPage->GetSdrPage(), aTextBoxes); + return SwTextBoxHelper::getCount(pDrawPage->GetSdrPage()); } } @@ -540,12 +533,6 @@ uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex) throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) { - return getByIndex(nIndex, nullptr); -} - -uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex, std::set<const SwFrameFormat*>* pTextBoxes) - throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception) -{ SolarMutexGuard aGuard; if(!pDoc) throw uno::RuntimeException(); @@ -553,17 +540,7 @@ uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex, std::set<const SwFrameFormat* throw lang::IndexOutOfBoundsException(); static_cast<SwXDrawPage*>(this)->GetSvxPage(); - std::set<const SwFrameFormat*> aTextBoxes; - if (!pTextBoxes) - { - // We got no set, so let's generate one. - aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); - pTextBoxes = &aTextBoxes; - } - if (pTextBoxes->empty()) - return pDrawPage->getByIndex( nIndex ); - else - return SwTextBoxHelper::getByIndex(pDrawPage->GetSdrPage(), nIndex, *pTextBoxes); + return SwTextBoxHelper::getByIndex(pDrawPage->GetSdrPage(), nIndex); } uno::Type SwXDrawPage::getElementType() throw( uno::RuntimeException, std::exception ) @@ -1564,7 +1541,7 @@ uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName) } else if (pEntry->nWID == FN_TEXT_BOX) { - bool bValue = SwTextBoxHelper::findTextBox(pFormat); + bool bValue = SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT); aRet <<= bValue; } else if (pEntry->nWID == RES_CHAIN) @@ -1770,8 +1747,7 @@ uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName) bConvert = false; if (bConvert) { - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pFormat->GetDoc()); - aRet <<= SwTextBoxHelper::getOrdNum(pObj, aTextBoxes); + aRet <<= SwTextBoxHelper::getOrdNum(pObj); } } } @@ -1852,7 +1828,7 @@ uno::Sequence< beans::PropertyState > SwXShape::getPropertyStates( else if (pEntry->nWID == FN_TEXT_BOX) { // The TextBox property is set, if we can find a textbox for this shape. - if (pFormat && SwTextBoxHelper::findTextBox(pFormat)) + if (pFormat && SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT)) pRet[nProperty] = beans::PropertyState_DIRECT_VALUE; else pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE; diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx index 2bb4a87ce860..15abdb2193bf 100644 --- a/sw/source/core/unocore/unoframe.cxx +++ b/sw/source/core/unocore/unoframe.cxx @@ -1750,8 +1750,7 @@ void SwXFrame::setPropertyValue(const OUString& rPropertyName, const ::uno::Any& aValue >>= nZOrder; // Don't set an explicit ZOrder on TextBoxes. - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); - if( nZOrder >= 0 && aTextBoxes.find(pFormat) == aTextBoxes.end()) + if( nZOrder >= 0 && !SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT) ) { SdrObject* pObject = GetOrCreateSdrObject( static_cast<SwFlyFrameFormat&>(*pFormat) ); diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index 71619b352d6b..9ae7b3cca044 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -165,19 +165,18 @@ struct FrameClientSortListLess namespace { - void lcl_CollectFrameAtNodeWithLayout(SwDoc* pDoc, const SwContentFrame* pCFrame, + void lcl_CollectFrameAtNodeWithLayout(const SwContentFrame* pCFrame, FrameClientSortList_t& rFrames, const sal_uInt16 nAnchorType) { auto pObjs = pCFrame->GetDrawObjs(); if(!pObjs) return; - const auto aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); for(const auto pAnchoredObj : *pObjs) { SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); // Filter out textboxes, which are not interesting at an UNO level. - if(aTextBoxes.find(&rFormat) != aTextBoxes.end()) + if(SwTextBoxHelper::isTextBox(&rFormat, RES_FLYFRMFMT)) continue; if(rFormat.GetAnchor().GetAnchorId() == nAnchorType) { @@ -211,7 +210,7 @@ void CollectFrameAtNode( const SwNodeIndex& rIdx, nullptr != (pCNd = rIdx.GetNode().GetContentNode()) && nullptr != (pCFrame = pCNd->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout())) ) { - lcl_CollectFrameAtNodeWithLayout(pDoc, pCFrame, rFrames, nChkType); + lcl_CollectFrameAtNodeWithLayout(pCFrame, rFrames, nChkType); } else { diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index 920f3b70b8f6..c45d88a6908c 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -716,8 +716,7 @@ lcl_ExportHints( const sal_Int32 nCurrentIndex, const bool bRightMoveForbidden, bool & o_rbCursorMoved, - sal_Int32 & o_rNextAttrPosition, - std::set<const SwFrameFormat*>& rTextBoxes) + sal_Int32 & o_rNextAttrPosition) { // if the attribute has a dummy character, then xRef is set (except META) // otherwise, the portion for the attribute is inserted into rPortions! @@ -887,7 +886,7 @@ lcl_ExportHints( break; // Robust #i81708 content in covered cells // Do not expose inline anchored textboxes. - if (rTextBoxes.find(pAttr->GetFlyCnt().GetFrameFormat()) != rTextBoxes.end()) + if (SwTextBoxHelper::isTextBox(pAttr->GetFlyCnt().GetFrameFormat(), RES_FLYFRMFMT)) break; pUnoCursor->Exchange(); @@ -1272,8 +1271,6 @@ static void lcl_CreatePortions( PortionStack_t PortionStack; PortionStack.push( PortionList_t(&i_rPortions, nullptr) ); - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pUnoCursor->GetNode()); - bool bAtEnd( false ); while (!bAtEnd) // every iteration consumes at least current character! { @@ -1324,7 +1321,7 @@ static void lcl_CreatePortions( // N.B.: side-effects nNextAttrIndex, bCursorMoved; may move cursor xRef = lcl_ExportHints(PortionStack, i_xParentText, pUnoCursor, pHints, i_nStartPos, i_nEndPos, nCurrentIndex, bAtEnd, - bCursorMoved, nNextAttrIndex, aTextBoxes); + bCursorMoved, nNextAttrIndex); if (PortionStack.empty()) { OSL_FAIL("CreatePortions: stack underflow"); diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index a5b2c38b72a6..01a546650e1d 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -145,7 +145,6 @@ struct DocxSdrExport::Impl css::uno::Reference<sax_fastparser::FastAttributeList> m_pDashLineStyleAttr; bool m_bDMLAndVMLDrawingOpen; /// List of TextBoxes in this document: they are exported as part of their shape, never alone. - std::set<const SwFrameFormat*> m_aTextBoxes; /// Preserved rotation for TextFrames. sal_Int32 m_nDMLandVMLTextFrameRotation; @@ -165,7 +164,6 @@ struct DocxSdrExport::Impl m_pFlyWrapAttrList(nullptr), m_pBodyPrAttrList(nullptr), m_bDMLAndVMLDrawingOpen(false), - m_aTextBoxes(SwTextBoxHelper::findTextBoxes(m_rExport.m_pDoc)), m_nDMLandVMLTextFrameRotation(0) { } @@ -1798,7 +1796,7 @@ bool DocxSdrExport::Impl::checkFrameBtlr(SwNode* pStartNode, bool bDML) bool DocxSdrExport::isTextBox(const SwFrameFormat& rFrameFormat) { - return m_pImpl->m_aTextBoxes.find(&rFrameFormat) != m_pImpl->m_aTextBoxes.end(); + return SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx index 77d4645db57e..f303e8a379a6 100644 --- a/sw/source/filter/ww8/rtfsdrexport.cxx +++ b/sw/source/filter/ww8/rtfsdrexport.cxx @@ -640,7 +640,7 @@ void RtfSdrExport::AddSdrObject(const SdrObject& rObj) bool RtfSdrExport::isTextBox(const SwFrameFormat& rFrameFormat) { - return m_aTextBoxes.find(&rFrameFormat) != m_aTextBoxes.end(); + return SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/xml/xmltble.cxx b/sw/source/filter/xml/xmltble.cxx index d1bb91069812..172c4e588c02 100644 --- a/sw/source/filter/xml/xmltble.cxx +++ b/sw/source/filter/xml/xmltble.cxx @@ -1097,8 +1097,7 @@ void SwXMLExport::ExportTable( const SwTableNode& rTableNd ) sal_uInt16 nPrefix = XML_NAMESPACE_TABLE; if (const SwFrameFormat* pFlyFormat = rTableNd.GetFlyFormat()) { - std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(rTableNd.GetDoc()); - if (aTextBoxes.find(pFlyFormat) != aTextBoxes.end()) + if (SwTextBoxHelper::isTextBox(pFlyFormat, RES_FLYFRMFMT)) nPrefix = XML_NAMESPACE_LO_EXT; } diff --git a/sw/source/uibase/shells/drawsh.cxx b/sw/source/uibase/shells/drawsh.cxx index 6c1fc4360ab9..332497da5c35 100644 --- a/sw/source/uibase/shells/drawsh.cxx +++ b/sw/source/uibase/shells/drawsh.cxx @@ -494,7 +494,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet) { SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj); // Allow creating a TextBox only in case this is a draw format without a TextBox so far. - if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::findTextBox(pFrameFormat)) + if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT)) { if (SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>( pObj) ) { @@ -517,7 +517,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet) { SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj); // Allow removing a TextBox only in case it has one. - if (pFrameFormat && SwTextBoxHelper::findTextBox(pFrameFormat)) + if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT)) bDisable = false; } diff --git a/sw/source/uibase/uiview/viewdraw.cxx b/sw/source/uibase/uiview/viewdraw.cxx index 2ab98fea04b9..fda4a3b2d244 100644 --- a/sw/source/uibase/uiview/viewdraw.cxx +++ b/sw/source/uibase/uiview/viewdraw.cxx @@ -438,7 +438,7 @@ static bool lcl_isTextBox(SdrObject* pObject) if (SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(pObject->GetUserCall())) { if (SwFrameFormat* pFormat = pDrawContact->GetFormat()) - return SwTextBoxHelper::findTextBox(pFormat); + return SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT); } return false; } commit 2dafbb537b6347a9b2f16d21a48d79a8caceddce Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Jul 22 17:23:40 2016 +0200 Link DRAW and FLY format for faster textbox lookup Currently we have to rebuild the list of text boxes for every lookup. Instead of a managed set, or a per-document list etc., this introduces direct pointers between the corresponding SwDrawFramFormat and SwFlyFrameFormat of a text box. (Manually cherry picked from commit 5bed080c77f99f22fd52ad6cf2d6274e7c1e12a8) Change-Id: Iefba2d153d9d8b3f1185aa305e9f463a50e78f89 Reviewed-on: https://gerrit.libreoffice.org/46305 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/sw/inc/frmfmt.hxx b/sw/inc/frmfmt.hxx index 4291ced05f6e..c2a19706160c 100644 --- a/sw/inc/frmfmt.hxx +++ b/sw/inc/frmfmt.hxx @@ -41,12 +41,15 @@ class SW_DLLPUBLIC SwFrameFormat: public SwFormat friend class SwDoc; friend class SwPageDesc; ///< Is allowed to call protected CTor. friend class ::sw::DocumentLayoutManager; ///< Is allowed to call protected CTor. + friend class SwTextBoxHelper; css::uno::WeakReference<css::uno::XInterface> m_wXObject; //UUUU DrawingLayer FillAttributes in a preprocessed form for primitive usage drawinglayer::attribute::SdrAllFillAttributesHelperPtr maFillAttributes; + SwFrameFormat *m_pOtherTextBoxFormat; + protected: SwFrameFormat( SwAttrPool& rPool, @@ -64,6 +67,9 @@ protected: virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNewValue ) override; + SwFrameFormat* GetOtherTextBoxFormat() const { return m_pOtherTextBoxFormat; } + void SetOtherTextBoxFormat( SwFrameFormat *pFormat ); + public: virtual ~SwFrameFormat(); diff --git a/sw/source/core/doc/DocumentLayoutManager.cxx b/sw/source/core/doc/DocumentLayoutManager.cxx index c5380df0b3de..5fc0d4cc7483 100644 --- a/sw/source/core/doc/DocumentLayoutManager.cxx +++ b/sw/source/core/doc/DocumentLayoutManager.cxx @@ -510,6 +510,10 @@ SwFrameFormat *DocumentLayoutManager::CopyLayoutFormat( SwFormatContent aContent(pDestTextBox->GetContent().GetContentIdx()->GetNode().GetStartNode()); aSet.Put(aContent); pDest->SetFormatAttr(aSet); + + // Link FLY and DRAW formats, so it becomes a text box + pDest->SetOtherTextBoxFormat(pDestTextBox); + pDestTextBox->SetOtherTextBoxFormat(pDest); } return pDest; diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 61402fe02c94..c75908384ebf 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -28,6 +28,7 @@ #include <sortedobjs.hxx> #include <cntfrm.hxx> #include <fmtsrnd.hxx> +#include <frmfmt.hxx> #include <editeng/unoprnms.hxx> #include <editeng/charrotateitem.hxx> @@ -55,6 +56,18 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape) uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(), uno::UNO_QUERY); xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>()); + // Link FLY and DRAW formats, so it becomes a text box (needed for syncProperty calls). + uno::Reference<text::XTextFrame> xRealTextFrame(xTextFrame, uno::UNO_QUERY); + SwXTextFrame* pTextFrame = dynamic_cast<SwXTextFrame *>(xRealTextFrame.get()); + assert(nullptr != pTextFrame); + SwFrameFormat* pFormat = pTextFrame->GetFrameFormat(); + + assert(nullptr != dynamic_cast<SwDrawFrameFormat*>(pShape)); + assert(nullptr != dynamic_cast<SwFlyFrameFormat*>(pFormat)); + + pShape->SetOtherTextBoxFormat(pFormat); + pFormat->SetOtherTextBoxFormat(pShape); + // Initialize properties. uno::Reference<beans::XPropertySet> xPropertySet(xTextFrame, uno::UNO_QUERY); uno::Any aEmptyBorder = uno::makeAny(table::BorderLine2()); diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx index 849af3b88ed0..4a67225681e4 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -2502,7 +2502,8 @@ SwFrameFormat::SwFrameFormat( const sal_uInt16* pWhichRange) : SwFormat(rPool, pFormatNm, (pWhichRange ? pWhichRange : aFrameFormatSetRange), pDrvdFrame, nFormatWhich), m_wXObject(), - maFillAttributes() + maFillAttributes(), + m_pOtherTextBoxFormat(nullptr) { } @@ -2514,7 +2515,8 @@ SwFrameFormat::SwFrameFormat( const sal_uInt16* pWhichRange) : SwFormat(rPool, rFormatNm, (pWhichRange ? pWhichRange : aFrameFormatSetRange), pDrvdFrame, nFormatWhich), m_wXObject(), - maFillAttributes() + maFillAttributes(), + m_pOtherTextBoxFormat(nullptr) { } @@ -2528,6 +2530,27 @@ SwFrameFormat::~SwFrameFormat() rAnchor.GetContentAnchor()->nNode.GetNode().RemoveAnchoredFly(this); } } + + if( nullptr != m_pOtherTextBoxFormat ) + { + m_pOtherTextBoxFormat->SetOtherTextBoxFormat( nullptr ); + m_pOtherTextBoxFormat = nullptr; + } +} + +void SwFrameFormat::SetOtherTextBoxFormat( SwFrameFormat *pFormat ) +{ + if( nullptr != pFormat ) + { + assert( (Which() == RES_DRAWFRMFMT && pFormat->Which() == RES_FLYFRMFMT) + || (Which() == RES_FLYFRMFMT && pFormat->Which() == RES_DRAWFRMFMT) ); + assert( nullptr == m_pOtherTextBoxFormat ); + } + else + { + assert( nullptr != m_pOtherTextBoxFormat ); + } + m_pOtherTextBoxFormat = pFormat; } bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const commit bc20bd3296efffe024235f82e40bca1ef116bce5 Author: Armin Le Grand <armin.le.gr...@cib.de> Date: Tue Dec 5 19:35:20 2017 +0100 SwFrameBorder: Converted BorderRectangle functionality to primitive usage, added a SwBorderRectanglePrimitive2D which now encapsulates the four Styles and the transformation of a single BorderLineRectangle. This is a preparation for later buffered primitive usage at SwFrame level Change-Id: I6689b94fe996ead8142553e8442e151e53d10e8a diff --git a/sw/inc/sw_primitivetypes2d.hxx b/sw/inc/sw_primitivetypes2d.hxx index 4ded8572088b..44509820f72c 100644 --- a/sw/inc/sw_primitivetypes2d.hxx +++ b/sw/inc/sw_primitivetypes2d.hxx @@ -25,6 +25,7 @@ #define PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SW| 0) #define PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE (PRIMITIVE2D_ID_RANGE_SW| 1) #define PRIMITIVE2D_ID_SWSIDEBARSHADOWPRIMITIVE (PRIMITIVE2D_ID_RANGE_SW| 2) +#define PRIMITIVE2D_ID_SWBORDERRECTANGLERIMITIVE (PRIMITIVE2D_ID_RANGE_SW| 3) #endif // INCLUDED_SW_INC_SW_PRIMITIVETYPES2D_HXX diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index b2e16581b253..207afbede1fa 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -62,6 +62,8 @@ #include <bodyfrm.hxx> #include <hffrm.hxx> #include <colfrm.hxx> +#include <sw_primitivetypes2d.hxx> + #include <svx/sdr/contact/viewobjectcontactredirector.hxx> #include <svx/sdr/contact/viewobjectcontact.hxx> #include <svx/sdr/contact/viewcontact.hxx> @@ -224,7 +226,6 @@ public: }; // Default zoom factor -const static double aMinDistScale = 0.73; const static double aEdgeScale = 0.5; //To optimize the expensive RetouchColor determination @@ -1183,42 +1184,6 @@ void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContex } /** - * Helper for twip adjustments on pixel base - * - * This method compares the x- or y-pixel position of two twip-points. - * If the x-/y-pixel positions are the same, the x-/y-pixel position of - * the second twip point is adjusted by a given amount of pixels -*/ -static void lcl_CompPxPosAndAdjustPos( const vcl::RenderContext& _rOut, - const Point& _rRefPt, - Point& _rCompPt, - const bool _bChkXPos, - const sal_Int8 _nPxAdjustment ) -{ - const Point aRefPxPt = _rOut.LogicToPixel( _rRefPt ); - Point aCompPxPt = _rOut.LogicToPixel( _rCompPt ); - - if ( _bChkXPos ) - { - if ( aCompPxPt.X() == aRefPxPt.X() ) - { - aCompPxPt.X() += _nPxAdjustment ; - const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt ); - _rCompPt.X() = aAdjustedCompPt.X(); - } - } - else - { - if ( aCompPxPt.Y() == aRefPxPt.Y() ) - { - aCompPxPt.Y() += _nPxAdjustment ; - const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt ); - _rCompPt.Y() = aAdjustedCompPt.Y(); - } - } -} - -/** * Method to pixel-align rectangle for drawing graphic object * * Because we are drawing graphics from the left-top-corner in conjunction @@ -1264,13 +1229,6 @@ static long lcl_AlignHeight( const long nHeight, SwPaintProperties& properties ) return nHeight; } -static long lcl_MinHeightDist( const long nDist, SwPaintProperties& properties ) -{ - if ( properties.aSScaleX < aMinDistScale || properties.aSScaleY < aMinDistScale ) - return nDist; - return ::lcl_AlignHeight( std::max( nDist, properties.nSMinDistPixelH ), properties); -} - /** * Calculate PrtArea plus surrounding plus shadow */ @@ -4473,298 +4431,254 @@ void SwFrame::PaintBorderLine( const SwRect& rRect, gProp.pSLines->AddLineRect( aOut, pColor, nStyle, pTab, nSubCol, gProp ); } -/** - * @note Only all lines once or all lines twice! - * - * OD 29.04.2003 #107169# - method called for left and right border rectangles. - * For a printer output device perform adjustment for non-overlapping top and - * bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate - * printer output device. - * NOTE: For printer output device left/right border rectangle <_iorRect> - * has to be already non-overlapping the outer top/bottom border rectangle. - */ -static void lcl_SubTopBottom( SwRect& _iorRect, - const SvxBoxItem& _rBox, - const SwBorderAttrs& _rAttrs, - const SwFrame& _rFrame, - const SwRectFn& _rRectFn, - const bool _bPrtOutputDev, - SwPaintProperties& properties ) +namespace drawinglayer { - const bool bCnt = _rFrame.IsContentFrame(); - if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() && - ( !bCnt || _rAttrs.GetTopLine( _rFrame ) ) - ) + namespace primitive2d { - // subtract distance between outer and inner line. - SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance(), properties ); - // OD 19.05.2003 #109667# - non-overlapping border rectangles: - // adjust x-/y-position, if inner top line is a hair line (width = 1) - bool bIsInnerTopLineHairline = false; - if ( !_bPrtOutputDev ) - { - // additionally subtract width of top outer line - // --> left/right inner/outer line doesn't overlap top outer line. - nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth(), properties ); - } - else + class SW_DLLPUBLIC SwBorderRectanglePrimitive2D : public BufferedDecompositionPrimitive2D { - // OD 29.04.2003 #107169# - additionally subtract width of top inner line - // --> left/right inner/outer line doesn't overlap top inner line. - nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth(), properties ); - bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1; - } - (_iorRect.*_rRectFn->fnSubTop)( -nDist ); - // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line - // is a hair line - if ( bIsInnerTopLineHairline ) - { - if ( _rFrame.IsVertical() ) + private: + /// the transformation defining the geometry of this BorderRectangle + basegfx::B2DHomMatrix maB2DHomMatrix; + + /// the four styles to be used + svx::frame::Style maStyleTop; + svx::frame::Style maStyleRight; + svx::frame::Style maStyleBottom; + svx::frame::Style maStyleLeft; + + protected: + /// local decomposition. + virtual Primitive2DContainer create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + /// constructor + SwBorderRectanglePrimitive2D( + const basegfx::B2DHomMatrix& rB2DHomMatrix, + const svx::frame::Style& rStyleTop, + const svx::frame::Style& rStyleRight, + const svx::frame::Style& rStyleBottom, + const svx::frame::Style& rStyleLeft); + + /// data read access + const basegfx::B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; } + const svx::frame::Style& getStyleTop() const { return maStyleTop; } + const svx::frame::Style& getStyleRight() const { return maStyleRight; } + const svx::frame::Style& getStyleBottom() const { return maStyleBottom; } + const svx::frame::Style& getStyleLeft() const { return maStyleLeft; } + + /// compare operator + virtual bool operator==(const BasePrimitive2D& rPrimitive) const override; + + /// get range + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override; + + /// provide unique ID + DeclPrimitive2DIDBlock() + }; + + Primitive2DContainer SwBorderRectanglePrimitive2D::create2DDecomposition( + const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DContainer aRetval; + basegfx::B2DPoint aTopLeft(getB2DHomMatrix() * basegfx::B2DPoint(0.0, 0.0)); + basegfx::B2DPoint aTopRight(getB2DHomMatrix() * basegfx::B2DPoint(1.0, 0.0)); + basegfx::B2DPoint aBottomLeft(getB2DHomMatrix() * basegfx::B2DPoint(0.0, 1.0)); + basegfx::B2DPoint aBottomRight(getB2DHomMatrix() * basegfx::B2DPoint(1.0, 1.0)); + + if(getStyleTop().IsUsed()) { - // right of border rectangle has to be checked and adjusted - Point aCompPt( _iorRect.Right(), 0 ); - Point aRefPt( aCompPt.X() + 1, aCompPt.Y() ); - lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()), - aRefPt, aCompPt, - true, -1 ); - _iorRect.Right( aCompPt.X() ); + // move top left/right inwards half border width + basegfx::B2DVector aDown(getB2DHomMatrix() * basegfx::B2DVector(0.0, 1.0)); + aDown.setLength(getStyleTop().GetWidth() * 0.5); + aTopLeft += aDown; + aTopRight += aDown; } - else + + if(getStyleBottom().IsUsed()) { - // top of border rectangle has to be checked and adjusted - Point aCompPt( 0, _iorRect.Top() ); - Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 ); - lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()), - aRefPt, aCompPt, - false, +1 ); - _iorRect.Top( aCompPt.Y() ); + // move bottom left/right inwards half border width + basegfx::B2DVector aUp(getB2DHomMatrix() * basegfx::B2DVector(0.0, -1.0)); + aUp.setLength(getStyleBottom().GetWidth() * 0.5); + aBottomLeft += aUp; + aBottomRight += aUp; } - } - } - if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() && - ( !bCnt || _rAttrs.GetBottomLine( _rFrame ) ) - ) - { - // subtract distance between outer and inner line. - SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance(), properties ); - // OD 19.05.2003 #109667# - non-overlapping border rectangles: - // adjust x-/y-position, if inner bottom line is a hair line (width = 1) - bool bIsInnerBottomLineHairline = false; - if ( !_bPrtOutputDev ) - { - // additionally subtract width of bottom outer line - // --> left/right inner/outer line doesn't overlap bottom outer line. - nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth(), properties ); - } - else - { - // OD 29.04.2003 #107169# - additionally subtract width of bottom inner line - // --> left/right inner/outer line doesn't overlap bottom inner line. - nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth(), properties ); - bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1; - } - (_iorRect.*_rRectFn->fnAddBottom)( -nDist ); - // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner - // bottom line is a hair line. - if ( bIsInnerBottomLineHairline ) - { - if ( _rFrame.IsVertical() ) + if(getStyleLeft().IsUsed()) { - // left of border rectangle has to be checked and adjusted - Point aCompPt( _iorRect.Left(), 0 ); - Point aRefPt( aCompPt.X() - 1, aCompPt.Y() ); - lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()), - aRefPt, aCompPt, - true, +1 ); - _iorRect.Left( aCompPt.X() ); + // move left top/bottom inwards half border width + basegfx::B2DVector aRight(getB2DHomMatrix() * basegfx::B2DVector(1.0, 0.0)); + aRight.setLength(getStyleLeft().GetWidth() * 0.5); + aTopLeft += aRight; + aBottomLeft += aRight; } - else + + if(getStyleRight().IsUsed()) { - // bottom of border rectangle has to be checked and adjusted - Point aCompPt( 0, _iorRect.Bottom() ); - Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 ); - lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()), - aRefPt, aCompPt, - false, -1 ); - _iorRect.Bottom( aCompPt.Y() ); + // move right top/bottom inwards half border width + basegfx::B2DVector aLeft(getB2DHomMatrix() * basegfx::B2DVector(-1.0, 0.0)); + aLeft.setLength(getStyleRight().GetWidth() * 0.5); + aTopRight += aLeft; + aBottomRight += aLeft; } - } - } -} - -static sal_uInt16 lcl_GetLineWidth( const SvxBorderLine* pLine ) -{ - if ( pLine != nullptr ) - return pLine->GetScaledWidth(); - return 0; -} - -static double lcl_GetExtent( const SvxBorderLine* pSideLine, const SvxBorderLine* pOppositeLine ) -{ - double nExtent = 0.0; - - if ( pSideLine && !pSideLine->isEmpty() ) - nExtent = -lcl_GetLineWidth( pSideLine ) / 2.0; - else if ( pOppositeLine ) - nExtent = lcl_GetLineWidth( pOppositeLine ) / 2.0; + // go round-robin, from TopLeft to TopRight, down, left and back up. That + // way, the borders will not need to be mirrored in any way + if(getStyleTop().IsUsed()) + { + // create BorderPrimitive(s) for top border + const basegfx::B2DVector aVector(aTopRight - aTopLeft); + svx::frame::StyleVectorTable aStartStyleVectorTable; + svx::frame::StyleVectorTable aEndStyleVectorTable; - return nExtent; -} + if(getStyleLeft().IsUsed()) + { + aStartStyleVectorTable.add(getStyleLeft(), aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false); + } -namespace -{ - void CreateBorderLinePrimitivesForRectangle( - drawinglayer::primitive2d::Primitive2DContainer& rBorderLineTarget, - const svx::frame::Style& rStyleTop, - const svx::frame::Style& rStyleRight, - const svx::frame::Style& rStyleBottom, - const svx::frame::Style& rStyleLeft, - basegfx::B2DPoint aTopLeft, - basegfx::B2DPoint aTopRight, - basegfx::B2DPoint aBottomLeft, - basegfx::B2DPoint aBottomRight) - { - if(rStyleTop.IsUsed()) - { - // move top left/right inwards half border width - aTopLeft.setY(aTopLeft.getY() + (rStyleTop.GetWidth() * 0.5)); - aTopRight.setY(aTopRight.getY() + (rStyleTop.GetWidth() * 0.5)); - } + if(getStyleRight().IsUsed()) + { + aEndStyleVectorTable.add(getStyleRight(), -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false); + } - if(rStyleBottom.IsUsed()) - { - // move bottom left/right inwards half border width - aBottomLeft.setY(aBottomLeft.getY() - (rStyleBottom.GetWidth() * 0.5)); - aBottomRight.setY(aBottomRight.getY() - (rStyleBottom.GetWidth() * 0.5)); - } + CreateBorderPrimitives( + aRetval, + aTopLeft, + aVector, + getStyleTop(), + aStartStyleVectorTable, + aEndStyleVectorTable, + nullptr); + } - if(rStyleLeft.IsUsed()) - { - // move left top/bottom inwards half border width - aTopLeft.setX(aTopLeft.getX() + (rStyleLeft.GetWidth() * 0.5)); - aBottomLeft.setX(aBottomLeft.getX() + (rStyleLeft.GetWidth() * 0.5)); - } + if(getStyleRight().IsUsed()) + { + // create BorderPrimitive(s) for right border + const basegfx::B2DVector aVector(aBottomRight - aTopRight); + svx::frame::StyleVectorTable aStartStyleVectorTable; + svx::frame::StyleVectorTable aEndStyleVectorTable; - if(rStyleRight.IsUsed()) - { - // move right top/bottom inwards half border width - aTopRight.setX(aTopRight.getX() - (rStyleRight.GetWidth() * 0.5)); - aBottomRight.setX(aBottomRight.getX() - (rStyleRight.GetWidth() * 0.5)); - } + if(getStyleTop().IsUsed()) + { + aStartStyleVectorTable.add(getStyleTop(), aVector, basegfx::B2DVector(aTopLeft - aTopRight), false); + } - // go round-robin, from TopLeft to TopRight, down, left and back up. That - // way, the borders will not need to be mirrored in any way - if(rStyleTop.IsUsed()) - { - // create BorderPrimitive(s) for top border - const basegfx::B2DVector aVector(aTopRight - aTopLeft); - svx::frame::StyleVectorTable aStartStyleVectorTable; - svx::frame::StyleVectorTable aEndStyleVectorTable; + if(getStyleBottom().IsUsed()) + { + aEndStyleVectorTable.add(getStyleBottom(), -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), false); + } - if(rStyleLeft.IsUsed()) - { - aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false); + CreateBorderPrimitives( + aRetval, + aTopRight, + aVector, + getStyleRight(), + aStartStyleVectorTable, + aEndStyleVectorTable, + nullptr); } - if(rStyleRight.IsUsed()) + if(getStyleBottom().IsUsed()) { - aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false); - } + // create BorderPrimitive(s) for bottom border + const basegfx::B2DVector aVector(aBottomLeft - aBottomRight); + svx::frame::StyleVectorTable aStartStyleVectorTable; + svx::frame::StyleVectorTable aEndStyleVectorTable; - CreateBorderPrimitives( - rBorderLineTarget, - aTopLeft, - aVector, - rStyleTop, - aStartStyleVectorTable, - aEndStyleVectorTable, - nullptr); - } + if(getStyleRight().IsUsed()) + { + aStartStyleVectorTable.add(getStyleRight(), aVector, basegfx::B2DVector(aTopRight - aBottomRight), false); + } - if(rStyleRight.IsUsed()) - { - // create BorderPrimitive(s) for right border - const basegfx::B2DVector aVector(aBottomRight - aTopRight); - svx::frame::StyleVectorTable aStartStyleVectorTable; - svx::frame::StyleVectorTable aEndStyleVectorTable; + if(getStyleLeft().IsUsed()) + { + aEndStyleVectorTable.add(getStyleLeft(), -aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), false); + } - if(rStyleTop.IsUsed()) - { - aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopLeft - aTopRight), false); + CreateBorderPrimitives( + aRetval, + aBottomRight, + aVector, + getStyleBottom(), + aStartStyleVectorTable, + aEndStyleVectorTable, + nullptr); } - if(rStyleBottom.IsUsed()) + if(getStyleLeft().IsUsed()) { - aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), false); + // create BorderPrimitive(s) for left border + const basegfx::B2DVector aVector(aTopLeft - aBottomLeft); + svx::frame::StyleVectorTable aStartStyleVectorTable; + svx::frame::StyleVectorTable aEndStyleVectorTable; + + if(getStyleBottom().IsUsed()) + { + aStartStyleVectorTable.add(getStyleBottom(), aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false); + } + + if(getStyleTop().IsUsed()) + { + aEndStyleVectorTable.add(getStyleTop(), -aVector, basegfx::B2DVector(aTopRight - aTopLeft), false); + } + + CreateBorderPrimitives( + aRetval, + aBottomLeft, + aVector, + getStyleLeft(), + aStartStyleVectorTable, + aEndStyleVectorTable, + nullptr); } - CreateBorderPrimitives( - rBorderLineTarget, - aTopRight, - aVector, - rStyleRight, - aStartStyleVectorTable, - aEndStyleVectorTable, - nullptr); + return aRetval; } - if(rStyleBottom.IsUsed()) + SwBorderRectanglePrimitive2D::SwBorderRectanglePrimitive2D( + const basegfx::B2DHomMatrix& rB2DHomMatrix, + const svx::frame::Style& rStyleTop, + const svx::frame::Style& rStyleRight, + const svx::frame::Style& rStyleBottom, + const svx::frame::Style& rStyleLeft) + : BufferedDecompositionPrimitive2D(), + maB2DHomMatrix(rB2DHomMatrix), + maStyleTop(rStyleTop), + maStyleRight(rStyleRight), + maStyleBottom(rStyleBottom), + maStyleLeft(rStyleLeft) { - // create BorderPrimitive(s) for bottom border - const basegfx::B2DVector aVector(aBottomLeft - aBottomRight); - svx::frame::StyleVectorTable aStartStyleVectorTable; - svx::frame::StyleVectorTable aEndStyleVectorTable; + } - if(rStyleRight.IsUsed()) + bool SwBorderRectanglePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BasePrimitive2D::operator==(rPrimitive)) { - aStartStyleVectorTable.add(rStyleRight, aVector, basegfx::B2DVector(aTopRight - aBottomRight), false); - } + const SwBorderRectanglePrimitive2D& rCompare = static_cast<const SwBorderRectanglePrimitive2D&>(rPrimitive); - if(rStyleLeft.IsUsed()) - { - aEndStyleVectorTable.add(rStyleLeft, -aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), false); + return (getB2DHomMatrix() == rCompare.getB2DHomMatrix() && + getStyleTop() == rCompare.getStyleTop() && + getStyleRight() == rCompare.getStyleRight() && + getStyleBottom() == rCompare.getStyleBottom() && + getStyleLeft() == rCompare.getStyleLeft()); } - CreateBorderPrimitives( - rBorderLineTarget, - aBottomRight, - aVector, - rStyleBottom, - aStartStyleVectorTable, - aEndStyleVectorTable, - nullptr); + return false; } - if(rStyleLeft.IsUsed()) + basegfx::B2DRange SwBorderRectanglePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const { - // create BorderPrimitive(s) for left border - const basegfx::B2DVector aVector(aTopLeft - aBottomLeft); - svx::frame::StyleVectorTable aStartStyleVectorTable; - svx::frame::StyleVectorTable aEndStyleVectorTable; + basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); - if(rStyleBottom.IsUsed()) - { - aStartStyleVectorTable.add(rStyleBottom, aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false); - } + aRetval.transform(getB2DHomMatrix()); + return aRetval; + } - if(rStyleTop.IsUsed()) - { - aEndStyleVectorTable.add(rStyleTop, -aVector, basegfx::B2DVector(aTopRight - aTopLeft), false); - } + // provide unique ID + ImplPrimitive2DIDBlock(SwBorderRectanglePrimitive2D, PRIMITIVE2D_ID_SWBORDERRECTANGLERIMITIVE) - CreateBorderPrimitives( - rBorderLineTarget, - aBottomLeft, - aVector, - rStyleLeft, - aStartStyleVectorTable, - aEndStyleVectorTable, - nullptr); - } - } -} // end of anonymous namespace + } // end of namespace primitive2d +} // end of namespace drawinglayer void PaintCharacterBorder( const SwFont& rFont, @@ -4814,20 +4728,24 @@ void PaintCharacterBorder( } } + const basegfx::B2DHomMatrix aBorderTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aAlignedRect.Width(), aAlignedRect.Height(), + aAlignedRect.Left(), aAlignedRect.Top())); + const svx::frame::Style aStyleTop(bTop ? rFont.GetAbsTopBorder(bVerticalLayout).get_ptr() : nullptr, 1.0); + const svx::frame::Style aStyleRight(bRight ? rFont.GetAbsRightBorder(bVerticalLayout).get_ptr() : nullptr, 1.0); + const svx::frame::Style aStyleBottom(bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout).get_ptr() : nullptr, 1.0); + const svx::frame::Style aStyleLeft(bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout).get_ptr() : nullptr, 1.0); drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget; - CreateBorderLinePrimitivesForRectangle( - aBorderLineTarget, - svx::frame::Style(bTop ? rFont.GetAbsTopBorder(bVerticalLayout).get_ptr() : nullptr, 1.0), - svx::frame::Style(bRight ? rFont.GetAbsRightBorder(bVerticalLayout).get_ptr() : nullptr, 1.0), - svx::frame::Style(bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout).get_ptr() : nullptr, 1.0), - svx::frame::Style(bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout).get_ptr() : nullptr, 1.0), - basegfx::B2DPoint(aAlignedRect.Left(), aAlignedRect.Top()), - basegfx::B2DPoint(aAlignedRect.Right(), aAlignedRect.Top()), - basegfx::B2DPoint(aAlignedRect.Left(), aAlignedRect.Bottom()), - basegfx::B2DPoint(aAlignedRect.Right(), aAlignedRect.Bottom())); - - // no need to use AddBorderLine and try to merge BorderLinePrimitives, in this combination - // tis cannot happen + + aBorderLineTarget.push_back( + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::SwBorderRectanglePrimitive2D( + aBorderTransform, + aStyleTop, + aStyleRight, + aStyleBottom, + aStyleLeft))); gProp.pBLines->AddBorderLines(aBorderLineTarget); } @@ -5140,46 +5058,27 @@ void SwFrame::PaintSwFrameShadowAndBorder( const SvxBorderLine* pTopBorder(rBox.GetTop()); const SvxBorderLine* pBottomBorder(rBox.GetBottom()); - // if R2L, exchange Right/Left - const bool bR2L(IsCellFrame() && IsRightToLeft()); - - if(bR2L) - { - std::swap(pLeftBorder, pRightBorder); - } - - // if ContentFrame and joined Prev/Next, reset top/bottom as needed - if(IsContentFrame()) - { - if(rAttrs.JoinedWithPrev(*this)) - { - pTopBorder = nullptr; - } - - if(rAttrs.JoinedWithNext(*this)) - { - pBottomBorder = nullptr; - } - } - if(nullptr != pLeftBorder || nullptr != pRightBorder || nullptr != pTopBorder || nullptr != pBottomBorder) { // now we have all SvxBorderLine(s) sorted out, create geometry + const basegfx::B2DHomMatrix aBorderTransform( + basegfx::tools::createScaleTranslateB2DHomMatrix( + aRect.Width(), aRect.Height(), + aRect.Left(), aRect.Top())); + const svx::frame::Style aStyleTop(pTopBorder, 1.0); + const svx::frame::Style aStyleRight(pRightBorder, 1.0); + const svx::frame::Style aStyleBottom(pBottomBorder, 1.0); + const svx::frame::Style aStyleLeft(pLeftBorder, 1.0); drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget; - CreateBorderLinePrimitivesForRectangle( - aBorderLineTarget, - svx::frame::Style(pTopBorder, 1.0), - svx::frame::Style(pRightBorder, 1.0), - svx::frame::Style(pBottomBorder, 1.0), - svx::frame::Style(pLeftBorder, 1.0), - basegfx::B2DPoint(aRect.Left(), aRect.Top()), // TopLeft - basegfx::B2DPoint(aRect.Right(), aRect.Top()), // TopRight - basegfx::B2DPoint(aRect.Left(), aRect.Bottom()), // BottomLeft - basegfx::B2DPoint(aRect.Right(), aRect.Bottom())); // BottomRight - - // no need to use AddBorderLine and try to merge BorderLinePrimitives, in this combination - // tis cannot happen + aBorderLineTarget.push_back( + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::SwBorderRectanglePrimitive2D( + aBorderTransform, + aStyleTop, + aStyleRight, + aStyleBottom, + aStyleLeft))); gProp.pBLines->AddBorderLines(aBorderLineTarget); } } commit 579c8ad3aeb299b4d2c5f49080eb6e6daf40281e Author: Armin Le Grand <armin.le.gr...@cib.de> Date: Tue Dec 5 15:28:08 2017 +0100 SwFrameBorder: Use enhanced FrameBorders for Character Adapted PaintCharacterBorder to also use new, enhanced FrameBorders. Adapted some places, cleaned up old code, enhanced tooling method CreateBorderLinePrimitivesForRectangle, tested including PDF, Pint, PrintPreview. Change-Id: If7b793b6520e899bde6f4211c993847af21ce7b9 diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx index 8a8f3a6bfb16..b78324072219 100644 --- a/include/svx/framelink.hxx +++ b/include/svx/framelink.hxx @@ -277,6 +277,41 @@ public: const std::vector< StyleVectorCombination >& getEntries() const{ return maEntries; } }; +/** + * Helper method to create the correct drawinglayer::primitive2d::BorderLinePrimitive2D + * for the given data, especially the correct drawinglayer::primitive2d::BorderLine entries + * including the correctly solved/created LineStartEnd extends + * + * rTarget : Here the evtl. created BorderLinePrimitive2D will be appended + * rOrigin : StartPoint of the Borderline + * rX : Vector of the Borderline + * rBorder : svx::frame::Style of the of the Borderline + * rStartStyleVectorTable : All other Borderlines which have to be taken into account because + * they have the same StartPoint as the current Borderline. These will be used to calculate + * the correct LineStartEnd extends tor the BorderLinePrimitive2D. The definition should be + * built up using svx::frame::StyleVectorTable and StyleVectorTable::add and includes: + * rStyle : the svx::frame::Style of one other BorderLine + * rMyVector : the Vector of the *new* to-be-defined BorderLine, identical to rX + * rOtherVector: the Vector of one other BorderLine (may be, but does not need to be normalized), + * always *pointing away* from the common StartPoint rOrigin + * bMirrored : define if rStyle of one other BorderLine shall be mirrored (e.g. bottom-right edges) + * With multiple BorderLines the definitions have to be CounterClockWise. This will be + * ensured by StyleVectorTable sorting the entries, but knowing this may allow more efficcient + * data creation. + * rEndStyleVectorTable: All other BorderLines that have the same EndPoint. There are differences to + * the Start definitions: + * - do not forget to consequently use -rX for rMyVector + * - definitions have to be ClockWise for the EndBorderLines, will be ensured by sorting + * + * If you take all this into account, you will gett correctly extended BorderLinePrimitive2D + * reprsentations for the new to be defined BorderLine. That extensions will overlap nicely + * with the corresponding BordreLines and take all multiple line definitions in the ::Style into + * account. + * The internal solver is *not limitied* to ::Style(s) with three parts (Left/Gap/Right), this is + * just due to svx::frame::Style's definitions. A new solver based on this one can be created + * anytime using more mulötiple borders based on the more flexible + * std::vector< drawinglayer::primitive2d::BorderLine > if needed. + */ SVX_DLLPUBLIC void CreateBorderPrimitives( drawinglayer::primitive2d::Primitive2DContainer& rTarget, /// target for created primitives const basegfx::B2DPoint& rOrigin, /// start point of borderline diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx index e8429bc6801e..db117bd99b2b 100644 --- a/svx/source/dialog/framelink.cxx +++ b/svx/source/dialog/framelink.cxx @@ -278,6 +278,8 @@ Style& Style::MirrorSelf() if (pTarget->mfSecn) { std::swap( pTarget->mfPrim, pTarget->mfSecn ); + // also need to swap colors + std::swap( pTarget->maColorPrim, pTarget->maColorSecn ); } if( pTarget->meRefMode != RefMode::REFMODE_CENTERED ) diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 320cfa09f83e..7e19619752fc 100644 ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits