diff options
Diffstat (limited to 'sw/source/core/doc/notxtfrm.cxx')
-rw-r--r-- | sw/source/core/doc/notxtfrm.cxx | 647 |
1 files changed, 339 insertions, 308 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx index c0b8984e6cf4..0255ff8b358c 100644 --- a/sw/source/core/doc/notxtfrm.cxx +++ b/sw/source/core/doc/notxtfrm.cxx @@ -70,12 +70,15 @@ #include <drawinglayer/processor2d/processor2dtools.hxx> #include <txtfly.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> -#include <basegfx/polygon/b2dpolygontools.hxx> #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx> +#include <osl/diagnose.h> // MM02 needed for VOC mechanism and getting the OC - may be moved to an own file #include <svx/sdrpagewindow.hxx> +#include <svx/svdoutl.hxx> +#include <svx/svdpage.hxx> #include <svx/svdpagv.hxx> +#include <svx/unopage.hxx> #include <svx/sdr/contact/viewcontact.hxx> #include <svx/sdr/contact/viewobjectcontact.hxx> #include <svx/sdr/contact/objectcontact.hxx> @@ -98,12 +101,12 @@ static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText, const SwViewShell &rSh, const SwNoTextFrame *pFrame, bool bDefect ) { - static vcl::Font aFont = [&]() + static vcl::Font aFont = []() { vcl::Font tmp; tmp.SetWeight( WEIGHT_BOLD ); tmp.SetStyleName( OUString() ); - tmp.SetFamilyName("Arial Unicode"); + tmp.SetFamilyName("Noto Sans"); tmp.SetFamily( FAMILY_SWISS ); tmp.SetTransparent( true ); return tmp; @@ -131,7 +134,7 @@ static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText, else if ( !rURL.GetURL().isEmpty() ) bVisited = rSh.GetDoc()->IsVisitedURL( rURL.GetURL() ); - SwFormat *pFormat = rSh.GetDoc()->getIDocumentStylePoolAccess().GetFormatFromPool( static_cast<sal_uInt16> + SwFormat *pFormat = rSh.GetDoc()->getIDocumentStylePoolAccess().GetFormatFromPool( o3tl::narrowing<sal_uInt16> (bVisited ? RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL ) ); aCol = pFormat->GetColor().GetValue(); eUnderline = pFormat->GetUnderline().GetLineStyle(); @@ -141,15 +144,11 @@ static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText, aFont.SetColor( aCol ); const BitmapEx& rBmp = const_cast<SwViewShell&>(rSh).GetReplacementBitmap(bDefect); - Graphic::DrawEx( rSh.GetOut(), rText, aFont, rBmp, rRect.Pos(), rRect.SSize() ); + Graphic::DrawEx(*rSh.GetOut(), rText, aFont, rBmp, rRect.Pos(), rRect.SSize()); } SwNoTextFrame::SwNoTextFrame(SwNoTextNode * const pNode, SwFrame* pSib ) -: SwContentFrame( pNode, pSib ), - // RotateFlyFrame3 - mpTransformableSwFrame(), - // MM02 - mpViewContact() +: SwContentFrame( pNode, pSib ) { mnFrameType = SwFrameType::NoTxt; } @@ -200,13 +199,13 @@ static void lcl_ClearArea( const SwFrame &rFrame, { for( const auto &rRegion : aRegion ) { - ::DrawGraphic( pItem, &rOut, aOrigRect, rRegion ); + ::DrawGraphic(pItem, rOut, aOrigRect, rRegion); } } } else { - rOut.Push( PushFlags::FILLCOLOR|PushFlags::LINECOLOR ); + rOut.Push( vcl::PushFlags::FILLCOLOR|vcl::PushFlags::LINECOLOR ); rOut.SetFillColor( rFrame.getRootFrame()->GetCurrShell()->Imp()->GetRetoucheColor()); rOut.SetLineColor(); for( const auto &rRegion : aRegion ) @@ -215,7 +214,7 @@ static void lcl_ClearArea( const SwFrame &rFrame, } } -void SwNoTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const +void SwNoTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect) const { if ( getFrameArea().IsEmpty() ) return; @@ -279,15 +278,15 @@ void SwNoTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect cons // size instead of scaling it if ( pGrfNd && rNoTNd.getIDocumentSettingAccess()->get( DocumentSettingId::CLIPPED_PICTURES ) ) { - const SwFlyFreeFrame *pFly = dynamic_cast< const SwFlyFreeFrame* >( FindFlyFrame() ); - if( pFly ) + auto pFindFly = FindFlyFrame(); + if (pFindFly && pFindFly->IsFlyFreeFrame()) { + const SwFlyFreeFrame *pFly = static_cast< const SwFlyFreeFrame* >( pFindFly ); bool bGetUnclippedFrame=true; - const SfxPoolItem* pItem; - if( pFly->GetFormat() && SfxItemState::SET == pFly->GetFormat()->GetItemState(RES_BOX, false, &pItem) ) + const SvxBoxItem* pBoxItem; + if( pFly->GetFormat() && (pBoxItem = pFly->GetFormat()->GetItemIfSet(RES_BOX, false)) ) { - const SvxBoxItem& rBox = *static_cast<const SvxBoxItem*>(pItem); - if( rBox.HasBorder( /*bTreatPaddingAsBorder*/true) ) + if( pBoxItem->HasBorder( /*bTreatPaddingAsBorder*/true) ) bGetUnclippedFrame = false; } @@ -301,7 +300,7 @@ void SwNoTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect cons SwRect aNormal( getFrameArea().Pos() + getFramePrintArea().Pos(), getFramePrintArea().SSize() ); aNormal.Justify(); // Normalized rectangle for the comparisons - if( aPaintArea.IsOver( aNormal ) ) + if( aPaintArea.Overlaps( aNormal ) ) { // Calculate the four to-be-deleted rectangles if( pSh->GetWin() ) @@ -644,7 +643,7 @@ double SwNoTextFrame::getLocalFrameRotation() const const SwRotationGrf& rSwRotationGrf(rSwAttrSet.GetRotationGrf()); const double fRotate = -toRadians(rSwRotationGrf.GetValue()); - return basegfx::normalizeToRange(fRotate, F_2PI); + return basegfx::normalizeToRange(fRotate, 2 * M_PI); } } @@ -652,6 +651,19 @@ double SwNoTextFrame::getLocalFrameRotation() const return 0.0; } +void SwNoTextFrame::dumpAsXml(xmlTextWriterPtr writer) const +{ + (void)xmlTextWriterStartElement(writer, reinterpret_cast<const xmlChar*>("notxt")); + dumpAsXmlAttributes(writer); + + (void)xmlTextWriterStartElement(writer, BAD_CAST("infos")); + dumpInfosAsXml(writer); + (void)xmlTextWriterEndElement(writer); + dumpChildrenAsXml(writer); + + (void)xmlTextWriterEndElement(writer); +} + /** Calculate the Bitmap's site, if needed */ void SwNoTextFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderAttrs * ) { @@ -670,7 +682,7 @@ void SwNoTextFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBord bool SwNoTextFrame::GetCharRect( SwRect &rRect, const SwPosition& rPos, SwCursorMoveState *pCMS, bool /*bAllowFarAway*/ ) const { - if ( &rPos.nNode.GetNode() != static_cast<SwNode const *>(GetNode()) ) + if ( &rPos.GetNode() != static_cast<SwNode const *>(GetNode()) ) return false; Calc(getRootFrame()->GetCurrShell()->GetOut()); @@ -682,7 +694,7 @@ bool SwNoTextFrame::GetCharRect( SwRect &rRect, const SwPosition& rPos, rRect.Justify(); // Is the Bitmap in the visible area at all? - if( !aFrameRect.IsOver( rRect ) ) + if( !aFrameRect.Overlaps( rRect ) ) { // If not, then the Cursor is on the Frame rRect = aFrameRect; @@ -703,9 +715,7 @@ bool SwNoTextFrame::GetCharRect( SwRect &rRect, const SwPosition& rPos, bool SwNoTextFrame::GetModelPositionForViewPoint(SwPosition* pPos, Point& , SwCursorMoveState*, bool ) const { - SwContentNode* pCNd = const_cast<SwContentNode*>(GetNode()); - pPos->nNode = *pCNd; - pPos->nContent.Assign( pCNd, 0 ); + pPos->Assign(*GetNode()); return true; } @@ -745,33 +755,24 @@ void SwNoTextFrame::SwClientNotify(const SwModify& rModify, const SfxHint& rHint } return; } - if(dynamic_cast<const sw::PreGraphicArrivedHint*>(&rHint)) + if(rHint.GetId() == SfxHintId::SwPreGraphicArrived + || rHint.GetId() == SfxHintId::SwGraphicPieceArrived + || rHint.GetId() == SfxHintId::SwLinkedGraphicStreamArrived) { OnGraphicArrived(); return; } - auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint); - if(!pLegacy) + else if (rHint.GetId() != SfxHintId::SwLegacyModify) return; + auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint); sal_uInt16 nWhich = pLegacy->GetWhich(); - // #i73788# - // no <SwContentFrame::Modify(..)> for RES_LINKED_GRAPHIC_STREAM_ARRIVED - if ( RES_GRAPHIC_PIECE_ARRIVED != nWhich && - RES_LINKED_GRAPHIC_STREAM_ARRIVED != nWhich ) - { - SwContentFrame::SwClientNotify(rModify, rHint); - } + SwContentFrame::SwClientNotify(rModify, rHint); bool bComplete = true; switch( nWhich ) { - case RES_GRAPHIC_PIECE_ARRIVED: - case RES_LINKED_GRAPHIC_STREAM_ARRIVED: - OnGraphicArrived(); - return; - case RES_OBJECTDYING: break; @@ -894,13 +895,10 @@ static bool paintUsingPrimitivesHelper( // embed the primitives to it. Use original TargetRange here so there is also // no need to embed the primitives to a MaskPrimitive for cropping. This works // only in this case where the graphic object cannot be rotated, though. - const drawinglayer::geometry::ViewInformation2D aViewInformation2D( - aMappingTransform, - rOutputDevice.GetViewTransformation(), - rTargetRange, - nullptr, - 0.0, - uno::Sequence< beans::PropertyValue >()); + drawinglayer::geometry::ViewInformation2D aViewInformation2D; + aViewInformation2D.setObjectTransformation(aMappingTransform); + aViewInformation2D.setViewTransformation(rOutputDevice.GetViewTransformation()); + aViewInformation2D.setViewport(rTargetRange); // get a primitive processor for rendering std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D( @@ -916,7 +914,7 @@ static bool paintUsingPrimitivesHelper( return false; } -// MM02 original using falölback to VOC and primitive-based version +// MM02 original using fallback to VOC and primitive-based version void paintGraphicUsingPrimitivesHelper( vcl::RenderContext & rOutputDevice, GraphicObject const& rGrfObj, @@ -930,11 +928,11 @@ void paintGraphicUsingPrimitivesHelper( // -> the primitive handles all crop and mirror stuff // -> the primitive renderer will create the needed pdf export data // -> if bitmap content, it will be cached system-dependent - drawinglayer::primitive2d::Primitive2DContainer aContent(1); - aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D( - rGraphicTransform, - rGrfObj, - rGraphicAttr); + drawinglayer::primitive2d::Primitive2DContainer aContent { + new drawinglayer::primitive2d::GraphicPrimitive2D( + rGraphicTransform, + rGrfObj, + rGraphicAttr) }; // MM02 use primitive-based version for visualization paintGraphicUsingPrimitivesHelper( @@ -967,15 +965,14 @@ void paintGraphicUsingPrimitivesHelper( // RegionBand-based implementation, so cannot use it here. if(rOutputDevice.IsClipRegion()) { - const basegfx::B2DPolyPolygon aClip(rOutputDevice.GetClipRegion().GetAsB2DPolyPolygon()); + basegfx::B2DPolyPolygon aClip(rOutputDevice.GetClipRegion().GetAsB2DPolyPolygon()); if(0 != aClip.count()) { - rContent.resize(1); - rContent[0] = + rContent = drawinglayer::primitive2d::Primitive2DContainer { new drawinglayer::primitive2d::MaskPrimitive2D( - aClip, - rContent); + std::move(aClip), + std::move(rContent)) }; } } @@ -983,13 +980,12 @@ void paintGraphicUsingPrimitivesHelper( { // Embed to ObjectInfoPrimitive2D when we have Name/Title/Description // information available - rContent.resize(1); - rContent[0] = + rContent = drawinglayer::primitive2d::Primitive2DContainer { new drawinglayer::primitive2d::ObjectInfoPrimitive2D( - rContent, + std::move(rContent), rName, rTitle, - rDescription); + rDescription) }; } basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); @@ -1007,8 +1003,12 @@ namespace { // anonymous namespace class ViewObjectContactOfSwNoTextFrame : public sdr::contact::ViewObjectContact { protected: - virtual drawinglayer::primitive2d::Primitive2DContainer createPrimitive2DSequence( - const sdr::contact::DisplayInfo& rDisplayInfo) const override; + virtual void createPrimitive2DSequence( + const sdr::contact::DisplayInfo& rDisplayInfo, + drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const override; + + // tdf#155190 disable this so superclass doesn't wrongly produce NonStruct + virtual bool isExportPDFTags() const override { return false; } public: ViewObjectContactOfSwNoTextFrame( @@ -1036,8 +1036,9 @@ public: explicit ViewContactOfSwNoTextFrame(const SwNoTextFrame& rSwNoTextFrame); }; -drawinglayer::primitive2d::Primitive2DContainer ViewObjectContactOfSwNoTextFrame::createPrimitive2DSequence( - const sdr::contact::DisplayInfo& /*rDisplayInfo*/) const +void ViewObjectContactOfSwNoTextFrame::createPrimitive2DSequence( + const sdr::contact::DisplayInfo& /*rDisplayInfo*/, + drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const { // MM02 get all the parameters formally used in paintGraphicUsingPrimitivesHelper ViewContactOfSwNoTextFrame& rVCOfNTF(static_cast<ViewContactOfSwNoTextFrame&>(GetViewContact())); @@ -1056,16 +1057,11 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContactOfSwNoTextFrame // MM02 this is the right place in the VOC-Mechanism to create // the primitives for visualization - these will be automatically // buffered and reused - drawinglayer::primitive2d::Primitive2DContainer aContent(1); - aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D( + rVisitor.visit(new drawinglayer::primitive2d::GraphicPrimitive2D( aGraphicTransform, rGrfObj, - aGraphicAttr); - - return aContent; + aGraphicAttr)); } - - return drawinglayer::primitive2d::Primitive2DContainer(); } ViewObjectContactOfSwNoTextFrame::ViewObjectContactOfSwNoTextFrame( @@ -1085,8 +1081,7 @@ sdr::contact::ViewObjectContact& ViewContactOfSwNoTextFrame::CreateObjectSpecifi ViewContactOfSwNoTextFrame::ViewContactOfSwNoTextFrame( const SwNoTextFrame& rSwNoTextFrame ) -: sdr::contact::ViewContact(), - mrSwNoTextFrame(rSwNoTextFrame) +: mrSwNoTextFrame(rSwNoTextFrame) { } } // end of anonymous namespace @@ -1148,193 +1143,19 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr { // Fix for bug fdo#33781 const AntialiasingFlags nFormerAntialiasingAtOutput( pOut->GetAntialiasing() ); - if (pShell->Imp()->GetDrawView()->IsAntiAliasing()) - { + if (SwDrawView::IsAntiAliasing()) pOut->SetAntialiasing( nFormerAntialiasingAtOutput | AntialiasingFlags::Enable ); - } - bool bContinue = true; - const GraphicObject& rGrfObj = pGrfNd->GetGrfObj(bPrn); + ImplPaintPictureGraphic( pOut, pGrfNd, bPrn, aAlignedGrfArea, pShell, rNoTNd ); - GraphicAttr aGrfAttr; - pGrfNd->GetGraphicAttr( aGrfAttr, this ); - - if( !bPrn ) - { - // #i73788# - if ( pGrfNd->IsLinkedInputStreamReady() ) - { - pGrfNd->UpdateLinkWithInputStream(); - } - // #i85717#, #i90395# - check, if asynchronous retrieval - // if input stream for the graphic is possible - else if ( ( rGrfObj.GetType() == GraphicType::Default || - rGrfObj.GetType() == GraphicType::NONE ) && - pGrfNd->IsLinkedFile() && - pGrfNd->IsAsyncRetrieveInputStreamPossible() ) - { - Size aTmpSz; - ::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj(); - if( !pGrfObj || - !pGrfObj->IsDataComplete() || - !(aTmpSz = pGrfNd->GetTwipSize()).Width() || - !aTmpSz.Height()) - { - pGrfNd->TriggerAsyncRetrieveInputStream(); // #i73788# - } - OUString aText( pGrfNd->GetTitle() ); - if ( aText.isEmpty() ) - GetRealURL( *pGrfNd, aText ); - ::lcl_PaintReplacement( aAlignedGrfArea, aText, *pShell, this, false ); - bContinue = false; - } - } - - if( bContinue ) - { - if( rGrfObj.GetGraphic().IsSupportedGraphic()) - { - const bool bAnimate = rGrfObj.IsAnimated() && - !pShell->IsPreview() && - !pShell->GetAccessibilityOptions()->IsStopAnimatedGraphics() && - // #i9684# Stop animation during printing/pdf export - pShell->GetWin(); - - if( bAnimate && - FindFlyFrame() != ::GetFlyFromMarked( nullptr, pShell )) - { - OutputDevice* pVout; - if( pOut == pShell->GetOut() && SwRootFrame::FlushVout() ) - { - pVout = pOut; - pOut = pShell->GetOut(); - } - else if( pShell->GetWin() && pOut->IsVirtual() ) - { - pVout = pOut; - pOut = pShell->GetWin(); - } - else - pVout = nullptr; - - OSL_ENSURE( !pOut->IsVirtual() || - pShell->GetViewOptions()->IsPDFExport() || pShell->isOutputToWindow(), - "pOut should not be a virtual device" ); - - pGrfNd->StartGraphicAnimation(pOut, aAlignedGrfArea.Pos(), - aAlignedGrfArea.SSize(), reinterpret_cast<sal_IntPtr>(this), - pVout ); - } - else - { - // MM02 To allow system-dependent buffering of the involved - // bitmaps it is necessary to re-use the involved primitives - // and their already executed decomposition (also for - // performance reasons). This is usually done in DrawingLayer - // by using the VOC-Mechanism (see descriptions elsewhere). - // To get that here, make the involved SwNoTextFrame (this) - // a sdr::contact::ViewContact supplier by supporting - // a GetViewContact() - call. For ObjectContact we can use - // the already existing ObjectContact from the involved - // DrawingLayer. For this, the helper classes - // ViewObjectContactOfSwNoTextFrame - // ViewContactOfSwNoTextFrame - // are created which support the VOC-mechanism in its minimal - // form. This allows automatic and view-dependent (multiple edit - // windows, print, etc.) re-use of the created primitives. - // Also: Will be very useful when completely changing the Writer - // repaint to VOC and Primitives, too. - static const char* pDisableMM02Goodies(getenv("SAL_DISABLE_MM02_GOODIES")); - static bool bUseViewObjectContactMechanism(nullptr == pDisableMM02Goodies); - // tdf#130951 for safety reasons use fallback if ViewObjectContactMechanism - // fails for some reason - usually could only be not to find the correct - // SdrPageWindow - bool bSucceeded(false); - - if(bUseViewObjectContactMechanism) - { - // MM02 use VOC-mechanism and buffer primitives - SwViewShellImp* pImp(pShell->Imp()); - SdrPageView* pPageView(nullptr != pImp - ? pImp->GetPageView() - : nullptr); - // tdf#130951 caution - target may be Window, use the correct OutputDevice - OutputDevice* pTarget(pShell->isOutputToWindow() - ? pShell->GetWin() - : pShell->GetOut()); - SdrPageWindow* pPageWindow(nullptr != pPageView && nullptr != pTarget - ? pPageView->FindPageWindow(*pTarget) - : nullptr); - - if(nullptr != pPageWindow) - { - sdr::contact::ObjectContact& rOC(pPageWindow->GetObjectContact()); - sdr::contact::ViewContact& rVC(GetViewContact()); - sdr::contact::ViewObjectContact& rVOC(rVC.GetViewObjectContact(rOC)); - sdr::contact::DisplayInfo aDisplayInfo; - - drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rVOC.getPrimitive2DSequence(aDisplayInfo)); - const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); - - paintGraphicUsingPrimitivesHelper( - *pOut, - aPrimitives, - aGraphicTransform, - nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(), - rNoTNd.GetTitle(), - rNoTNd.GetDescription()); - bSucceeded = true; - } - } - - if(!bSucceeded) - { - // MM02 fallback to direct paint with primitive-recreation - // which will block reusage of system-dependent bitmap data - const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); - - paintGraphicUsingPrimitivesHelper( - *pOut, - rGrfObj, - aGrfAttr, - aGraphicTransform, - nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(), - rNoTNd.GetTitle(), - rNoTNd.GetDescription()); - } - } - } - else - { - const char* pResId = nullptr; - - if( GraphicType::NONE == rGrfObj.GetType() ) - pResId = STR_COMCORE_READERROR; - else if ( !rGrfObj.GetGraphic().IsSupportedGraphic() ) - pResId = STR_COMCORE_CANT_SHOW; - - OUString aText; - if ( !pResId && - (aText = pGrfNd->GetTitle()).isEmpty() && - (!GetRealURL( *pGrfNd, aText ) || aText.isEmpty())) - { - pResId = STR_COMCORE_READERROR; - } - if (pResId) - aText = SwResId(pResId); - - ::lcl_PaintReplacement( aAlignedGrfArea, aText, *pShell, this, true ); - } - } - - if ( pShell->Imp()->GetDrawView()->IsAntiAliasing() ) + if ( SwDrawView::IsAntiAliasing() ) pOut->SetAntialiasing( nFormerAntialiasingAtOutput ); } else // bIsChart || pOLENd { // Fix for bug fdo#33781 const AntialiasingFlags nFormerAntialiasingAtOutput( pOut->GetAntialiasing() ); - if (pShell->Imp()->GetDrawView()->IsAntiAliasing()) + if (SwDrawView::IsAntiAliasing()) { AntialiasingFlags nNewAntialiasingAtOutput = nFormerAntialiasingAtOutput | AntialiasingFlags::Enable; @@ -1346,78 +1167,288 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr pOut->SetAntialiasing( nNewAntialiasingAtOutput ); } - bool bDone(false); + ImplPaintPictureBitmap( pOut, pOLENd, bIsChart, bPrn, aAlignedGrfArea, pShell ); - if(bIsChart) + // see #i99665# + if (SwDrawView::IsAntiAliasing()) { - basegfx::B2DRange aSourceRange; - const drawinglayer::primitive2d::Primitive2DContainer aSequence( - pOLENd->GetOLEObj().tryToGetChartContentAsPrimitive2DSequence( - aSourceRange, - bPrn)); + pOut->SetAntialiasing( nFormerAntialiasingAtOutput ); + } + } +} + +void SwNoTextFrame::ImplPaintPictureGraphic( vcl::RenderContext* pOut, + SwGrfNode* pGrfNd, bool bPrn, + const SwRect& rAlignedGrfArea, SwViewShell* pShell, + SwNoTextNode& rNoTNd ) const +{ + bool bContinue = true; + const GraphicObject& rGrfObj = pGrfNd->GetGrfObj(bPrn); - if(!aSequence.empty() && !aSourceRange.isEmpty()) + GraphicAttr aGrfAttr; + pGrfNd->GetGraphicAttr( aGrfAttr, this ); + + if( !bPrn ) + { + // #i73788# + if ( pGrfNd->IsLinkedInputStreamReady() ) + { + pGrfNd->UpdateLinkWithInputStream(); + } + // #i85717#, #i90395# - check, if asynchronous retrieval + // if input stream for the graphic is possible + else if ( ( rGrfObj.GetType() == GraphicType::Default || + rGrfObj.GetType() == GraphicType::NONE ) && + pGrfNd->IsLinkedFile() && + pGrfNd->IsAsyncRetrieveInputStreamPossible() ) + { + Size aTmpSz; + ::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj(); + if( !pGrfObj || + !pGrfObj->IsDataComplete() || + !(aTmpSz = pGrfNd->GetTwipSize()).Width() || + !aTmpSz.Height()) { - const basegfx::B2DRange aTargetRange( - aAlignedGrfArea.Left(), aAlignedGrfArea.Top(), - aAlignedGrfArea.Right(), aAlignedGrfArea.Bottom()); - - bDone = paintUsingPrimitivesHelper( - *pOut, - aSequence, - aSourceRange, - aTargetRange); + pGrfNd->TriggerAsyncRetrieveInputStream(); // #i73788# } + OUString aText( pGrfNd->GetTitle() ); + if ( aText.isEmpty() ) + GetRealURL( *pGrfNd, aText ); + ::lcl_PaintReplacement( rAlignedGrfArea, aText, *pShell, this, false ); + bContinue = false; } + } - if(!bDone && pOLENd) + if( !bContinue ) + return; + + if( !rGrfObj.GetGraphic().IsSupportedGraphic()) + { + ImplPaintPictureReplacement(rGrfObj, pGrfNd, rAlignedGrfArea, pShell); + return; + } + + const bool bAnimate = rGrfObj.IsAnimated() && + !pShell->IsPreview() && + !pShell->GetAccessibilityOptions()->IsStopAnimatedGraphics() && + // #i9684# Stop animation during printing/pdf export + pShell->GetWin(); + if( bAnimate && + FindFlyFrame() != ::GetFlyFromMarked( nullptr, pShell )) + { + ImplPaintPictureAnimate(pOut, pShell, pGrfNd, rAlignedGrfArea); + return; + } + + // MM02 To allow system-dependent buffering of the involved + // bitmaps it is necessary to re-use the involved primitives + // and their already executed decomposition (also for + // performance reasons). This is usually done in DrawingLayer + // by using the VOC-Mechanism (see descriptions elsewhere). + // To get that here, make the involved SwNoTextFrame (this) + // a sdr::contact::ViewContact supplier by supporting + // a GetViewContact() - call. For ObjectContact we can use + // the already existing ObjectContact from the involved + // DrawingLayer. For this, the helper classes + // ViewObjectContactOfSwNoTextFrame + // ViewContactOfSwNoTextFrame + // are created which support the VOC-mechanism in its minimal + // form. This allows automatic and view-dependent (multiple edit + // windows, print, etc.) re-use of the created primitives. + // Also: Will be very useful when completely changing the Writer + // repaint to VOC and Primitives, too. + static const char* pDisableMM02Goodies(getenv("SAL_DISABLE_MM02_GOODIES")); + static bool bUseViewObjectContactMechanism(nullptr == pDisableMM02Goodies); + // tdf#130951 for safety reasons use fallback if ViewObjectContactMechanism + // fails for some reason - usually could only be not to find the correct + // SdrPageWindow + bool bSucceeded(false); + + if(bUseViewObjectContactMechanism) + { + // MM02 use VOC-mechanism and buffer primitives + SwViewShellImp* pImp(pShell->Imp()); + SdrPageView* pPageView(nullptr != pImp + ? pImp->GetPageView() + : nullptr); + // tdf#130951 caution - target may be Window, use the correct OutputDevice + OutputDevice* pTarget((pShell->isOutputToWindow() && pShell->GetWin()) + ? pShell->GetWin()->GetOutDev() + : pShell->GetOut()); + SdrPageWindow* pPageWindow(nullptr != pPageView && nullptr != pTarget + ? pPageView->FindPageWindow(*pTarget) + : nullptr); + + if(nullptr != pPageWindow) { - // SwOLENode does not have a known GraphicObject, need to - // work with Graphic instead - const Graphic* pGraphic = pOLENd->GetGraphic(); - const Point aPosition(aAlignedGrfArea.Pos()); - const Size aSize(aAlignedGrfArea.SSize()); + sdr::contact::ObjectContact& rOC(pPageWindow->GetObjectContact()); + sdr::contact::ViewContact& rVC(GetViewContact()); + sdr::contact::ViewObjectContact& rVOC(rVC.GetViewObjectContact(rOC)); + sdr::contact::DisplayInfo aDisplayInfo; + + drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rVOC.getPrimitive2DSequence(aDisplayInfo)); + const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); + + paintGraphicUsingPrimitivesHelper( + *pOut, + aPrimitives, + aGraphicTransform, + nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(), + rNoTNd.GetTitle(), + rNoTNd.GetDescription()); + bSucceeded = true; + } + } - if ( pGraphic && pGraphic->GetType() != GraphicType::NONE ) - { - pGraphic->Draw( pOut, aPosition, aSize ); + if(!bSucceeded) + { + // MM02 fallback to direct paint with primitive-recreation + // which will block reusage of system-dependent bitmap data + const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); - // shade the representation if the object is activated outplace - uno::Reference < embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef(); - if ( xObj.is() && xObj->getCurrentState() == embed::EmbedStates::ACTIVE ) - { + paintGraphicUsingPrimitivesHelper( + *pOut, + rGrfObj, + aGrfAttr, + aGraphicTransform, + nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(), + rNoTNd.GetTitle(), + rNoTNd.GetDescription()); + } +} - ::svt::EmbeddedObjectRef::DrawShading( - tools::Rectangle( - aPosition, - aSize), - pOut); - } - } - else - { - ::svt::EmbeddedObjectRef::DrawPaintReplacement( - tools::Rectangle(aPosition, aSize), - pOLENd->GetOLEObj().GetCurrentPersistName(), - pOut); - } +void SwNoTextFrame::ImplPaintPictureAnimate(vcl::RenderContext* pOut, SwViewShell* pShell, + SwGrfNode* pGrfNd, const SwRect& rAlignedGrfArea) const +{ + OutputDevice* pVout; + if( pOut == pShell->GetOut() && SwRootFrame::FlushVout() ) + { + pVout = pOut; + pOut = pShell->GetOut(); + } + else if( pShell->GetWin() && pOut->IsVirtual() ) + { + pVout = pOut; + pOut = pShell->GetWin()->GetOutDev(); + } + else + pVout = nullptr; - sal_Int64 nMiscStatus = pOLENd->GetOLEObj().GetOleRef()->getStatus( pOLENd->GetAspect() ); - if ( !bPrn && dynamic_cast< const SwCursorShell *>( pShell ) != nullptr && - (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE)) + OSL_ENSURE( !pOut->IsVirtual() || + pShell->GetViewOptions()->IsPDFExport() || pShell->isOutputToWindow(), + "pOut should not be a virtual device" ); + + pGrfNd->StartGraphicAnimation(pOut, rAlignedGrfArea.Pos(), + rAlignedGrfArea.SSize(), reinterpret_cast<sal_IntPtr>(this), + pVout ); +} + +void SwNoTextFrame::ImplPaintPictureReplacement(const GraphicObject& rGrfObj, SwGrfNode* pGrfNd, + const SwRect& rAlignedGrfArea, SwViewShell* pShell) const +{ + TranslateId pResId; + + if( GraphicType::NONE == rGrfObj.GetType() ) + pResId = STR_COMCORE_READERROR; + else if ( !rGrfObj.GetGraphic().IsSupportedGraphic() ) + pResId = STR_COMCORE_CANT_SHOW; + + OUString aText; + if ( !pResId && + (aText = pGrfNd->GetTitle()).isEmpty() && + (!GetRealURL( *pGrfNd, aText ) || aText.isEmpty())) + { + pResId = STR_COMCORE_READERROR; + } + if (pResId) + aText = SwResId(pResId); + + ::lcl_PaintReplacement( rAlignedGrfArea, aText, *pShell, this, true ); +} + +void SwNoTextFrame::ImplPaintPictureBitmap( vcl::RenderContext* pOut, + SwOLENode* pOLENd, bool bIsChart, bool bPrn, const SwRect& rAlignedGrfArea, + SwViewShell* pShell ) const +{ + bool bDone(false); + + if(bIsChart) + { + basegfx::B2DRange aSourceRange; + const drawinglayer::primitive2d::Primitive2DContainer aSequence( + pOLENd->GetOLEObj().tryToGetChartContentAsPrimitive2DSequence( + aSourceRange, + bPrn)); + + if(!aSequence.empty() && !aSourceRange.isEmpty()) + { + const basegfx::B2DRange aTargetRange( + rAlignedGrfArea.Left(), rAlignedGrfArea.Top(), + rAlignedGrfArea.Right(), rAlignedGrfArea.Bottom()); + + Color aOldBackColor; + SvxDrawPage* pDrawPage = pOLENd->GetOLEObj().tryToGetChartDrawPage(); + SdrPage* pPage = pDrawPage ? pDrawPage->GetSdrPage() : nullptr; + if (pPage) { - const SwFlyFrame *pFly = FindFlyFrame(); - assert( pFly != nullptr ); - static_cast<SwFEShell*>(pShell)->ConnectObj( pOLENd->GetOLEObj().GetObject(), pFly->getFramePrintArea(), pFly->getFrameArea()); + SdrModel& rModel = pPage->getSdrModelFromSdrPage(); + SdrOutliner& rOutl = rModel.GetDrawOutliner(); + aOldBackColor = rOutl.GetBackgroundColor(); + rOutl.SetBackgroundColor(pPage->GetPageBackgroundColor()); } + + bDone = paintUsingPrimitivesHelper( + *pOut, + aSequence, + aSourceRange, + aTargetRange); + + if (pPage) + pPage->getSdrModelFromSdrPage().GetDrawOutliner().SetBackgroundColor(aOldBackColor); } + } - // see #i99665# - if (pShell->Imp()->GetDrawView()->IsAntiAliasing()) + if(bDone || !pOLENd) + return; + + // SwOLENode does not have a known GraphicObject, need to + // work with Graphic instead + const Graphic* pGraphic = pOLENd->GetGraphic(); + const Point aPosition(rAlignedGrfArea.Pos()); + const Size aSize(rAlignedGrfArea.SSize()); + + if ( pGraphic && pGraphic->GetType() != GraphicType::NONE ) + { + pGraphic->Draw(*pOut, aPosition, aSize); + + // shade the representation if the object is activated outplace + uno::Reference < embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef(); + if ( xObj.is() && xObj->getCurrentState() == embed::EmbedStates::ACTIVE ) { - pOut->SetAntialiasing( nFormerAntialiasingAtOutput ); + + ::svt::EmbeddedObjectRef::DrawShading( + tools::Rectangle( + aPosition, + aSize), + pOut); } } + else + { + ::svt::EmbeddedObjectRef::DrawPaintReplacement( + tools::Rectangle(aPosition, aSize), + pOLENd->GetOLEObj().GetCurrentPersistName(), + pOut); + } + + sal_Int64 nMiscStatus = pOLENd->GetOLEObj().GetOleRef()->getStatus( pOLENd->GetAspect() ); + if ( !bPrn && dynamic_cast< const SwCursorShell *>( pShell ) != nullptr && + (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE)) + { + const SwFlyFrame *pFly = FindFlyFrame(); + assert( pFly != nullptr ); + static_cast<SwFEShell*>(pShell)->ConnectObj( pOLENd->GetOLEObj().GetObject(), pFly->getFramePrintArea(), pFly->getFrameArea()); + } } bool SwNoTextFrame::IsTransparent() const @@ -1445,7 +1476,7 @@ bool SwNoTextFrame::IsTransparent() const if(isTransformableSwFrame()) { // we can be more specific - rotations of multiples of - // 90 degrees will leave no gaps. Go from [0.0 .. F_2PI] + // 90 degrees will leave no gaps. Go from [0.0 .. 2PI] // to [0 .. 360] and check modulo 90 const tools::Long nRot(static_cast<tools::Long>(basegfx::rad2deg(getLocalFrameRotation()))); const bool bMultipleOf90(0 == (nRot % 90)); |