/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// LazyInvalidate request. Take action. void ObjectContactOfPageView::setLazyInvalidate(ViewObjectContact& /*rVOC*/)
{ // do NOT call parent, but remember that something is to do by // starting the LazyInvalidateTimer
Start();
}
// call this to support evtl. preparations for repaint void ObjectContactOfPageView::PrepareProcessDisplay()
{ if(IsActive()) // there are still non-triggered LazyInvalidate events, trigger these
Invoke();
}
// From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism void ObjectContactOfPageView::Invoke()
{ // stop the timer
Stop();
// invalidate all LazyInvalidate VOCs new situations const sal_uInt32 nVOCCount(getViewObjectContactCount());
// Process the whole displaying. Only use given DisplayInfo, do not access other // OutputDevices then the given ones. void ObjectContactOfPageView::DoProcessDisplay(DisplayInfo& rDisplayInfo)
{
OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); if (!isOutputToRecordingMetaFile() // do those have outdev too?
&& (0 == aOutputSizePixel.getWidth() ||
0 == aOutputSizePixel.getHeight()))
{ return;
}
// visualize entered group when that feature is switched on and it's not // a print output. #i29129# No ghosted display for printing. bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter());
// Visualize entered groups: Set to ghosted as default // start. Do this only for the DrawPage, not for MasterPages if(bVisualizeEnteredGroup)
{
rDisplayInfo.SetGhostedDrawMode();
}
// #114359# save old and set clip region
OutputDevice* pOutDev = TryToGetOutputDevice();
OSL_ENSURE(nullptr != pOutDev, "ObjectContactOfPageView without OutDev, someone has overridden TryToGetOutputDevice wrong (!)"); bool bClipRegionPushed(false); const vcl::Region& rRedrawArea(rDisplayInfo.GetRedrawArea());
// tdf#153102 using the given RedrawArea is needed e.g. for Writer's // visual clipping against PageBounds (also for android viewer) if(!rRedrawArea.IsEmpty())
{
bClipRegionPushed = true;
pOutDev->Push(vcl::PushFlags::CLIPREGION);
pOutDev->IntersectClipRegion(rRedrawArea);
}
// Get start node and process DrawPage contents const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this);
// update current ViewInformation2D at the ObjectContact constdouble fCurrentTime(getPrimitiveAnimator().GetTime());
basegfx::B2DRange aViewRange;
// create ViewRange if(isOutputToRecordingMetaFile())
{ if (!rDisplayInfo.GetRedrawArea().IsEmpty())
{ // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this, // all existing objects will be collected as primitives and processed. // OD 2009-03-05 #i99876# perform the same also for SW on printing. // fdo#78149 same thing also needed for plain MetaFile // export, so why not do it always const tools::Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
aViewRange = vcl::unotools::b2DRectangleFromRectangle(aLogicClipRectangle);
}
} else
{ // use visible pixels, but transform to world coordinates
aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); // if a clip region is set, use it if(!rDisplayInfo.GetRedrawArea().IsEmpty())
{ // get logic clip range and create discrete one const tools::Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
basegfx::B2DRange aDiscreteClipRange = vcl::unotools::b2DRectangleFromRectangle(aLogicClipRectangle);
aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation());
// align the discrete one to discrete boundaries (pixel bounds). Also // expand X and Y max by one due to Rectangle definition source
aDiscreteClipRange.expand(basegfx::B2DTuple(
floor(aDiscreteClipRange.getMinX()),
floor(aDiscreteClipRange.getMinY())));
aDiscreteClipRange.expand(basegfx::B2DTuple(
1.0 + ceil(aDiscreteClipRange.getMaxX()),
1.0 + ceil(aDiscreteClipRange.getMaxY())));
// intersect current ViewRange with ClipRange
aViewRange.intersect(aDiscreteClipRange);
}
// transform to world coordinates
aViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
}
// update local ViewInformation2D
drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
aNewViewInformation2D.setViewTransformation(rTargetOutDev.GetViewTransformation());
aNewViewInformation2D.setViewport(aViewRange);
aNewViewInformation2D.setVisualizedPage(GetXDrawPageForSdrPage(GetSdrPage()));
aNewViewInformation2D.setViewTime(fCurrentTime); if (const SfxViewShell* pViewShell = SfxViewShell::Current())
aNewViewInformation2D.setAutoColor(pViewShell->GetColorConfigColor(svtools::DOCCOLOR)); if (static_cast<SdrPaintView&>(mrPageWindow.GetPageView().GetView()).IsTextEdit())
aNewViewInformation2D.setTextEditActive(true);
// this is the EditView repaint, provide that information, // but only if we do not export to metafile if (!isOutputToRecordingMetaFile())
aNewViewInformation2D.setEditViewActive(true);
#if HAVE_FEATURE_DESKTOP || defined( ANDROID ) // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D // and may use the MapMode from the Target OutDev in the DisplayInfo
rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo, xPrimitiveSequence); #else // Hmm, !HAVE_FEATURE_DESKTOP && !ANDROID means iOS, // right? But does it makes sense to use a different code // path for iOS than for Android; both use tiled rendering // etc now.
// HACK: this only works when we are drawing sdr shapes via // drawinglayer; but it can happen that the hierarchy contains // more than just the shapes, and then it fails. // // This is good enough for the tiled rendering for the moment, but // we need to come up with the real solution shortly.
// Only get the expensive hierarchy if we can be sure that the // returned sequence won't be empty anyway. bool bGetHierarchy = rRedrawArea.IsEmpty(); if (!bGetHierarchy)
{ // Not empty? Then not doing a full redraw, check if // getPrimitive2DSequenceHierarchy() is still needed. for (const rtl::Reference<SdrObject>& pObject : *GetSdrPage())
{ if (rRedrawArea.Overlaps(pObject->GetCurrentBoundRect()))
{
bGetHierarchy = true; break;
}
}
}
if (bGetHierarchy) // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D // and may use the MapMode from the Target OutDev in the DisplayInfo
rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo, xPrimitiveSequence); #endif
// if there is something to show, use a primitive processor to render it. There // is a choice between VCL and Canvas processors currently. The decision is made in // createProcessor2DFromOutputDevice and takes into account things like the // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered // currently using the shown boolean. Canvas is not yet the default. if(!xPrimitiveSequence.empty())
{ // prepare OutputDevice (historical stuff, maybe soon removed)
rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing
pOutDev->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::Default); // reset, default is no BiDi/RTL // create renderer
std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
drawinglayer::processor2d::createProcessor2DFromOutputDevice(
rTargetOutDev, getViewInformation2D()));
pProcessor2D->process(xPrimitiveSequence);
}
// #114359# restore old ClipReghion if(bClipRegionPushed)
{
pOutDev->Pop();
}
// Visualize entered groups: Reset to original DrawMode if(bVisualizeEnteredGroup)
{
rDisplayInfo.ClearGhostedDrawMode();
}
}
// test if visualizing of entered groups is switched on at all bool ObjectContactOfPageView::DoVisualizeEnteredGroup() const
{ returntrue;
}
// get active group's (the entered group) ViewContact const ViewContact* ObjectContactOfPageView::getActiveViewContact() const
{
SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList();
if(pActiveGroupList)
{ // tdf#122735 // Here it is necessary to check for SdrObject 1st, that may // return nullptr if it is not a SdrObject/SdrObjGroup. // Checking for SrPage OTOH will *always* try to return // something useful due to SdrObjGroup::getSdrPageFromSdrObjList // using getSdrPageFromSdrObject which will recursively go up the // hierarchy to get the SdrPage the SdrObject belongs to, so // this will *not* be nullptr for e.g. a SdrObjGroup if the // SdrObjGroup is inserted to a SdrPage. // NOTE: It is also possible to use dynamic_cast<SdrObjGroup*> // here, but getSdrObjectFromSdrObjList and // getSdrPageFromSdrObjListexist to not need to do that
SdrObject* pSdrObject(pActiveGroupList->getSdrObjectFromSdrObjList());
if(nullptr != pSdrObject)
{ // It is a group object return &(pSdrObject->GetViewContact());
} else
{
SdrPage* pSdrPage(pActiveGroupList->getSdrPageFromSdrObjList());
if(nullptr != pSdrPage)
{ // It's a Page itself return &(pSdrPage->GetViewContact());
}
}
} elseif(GetSdrPage())
{ // use page of associated SdrPageView return &(GetSdrPage()->GetViewContact());
}
return nullptr;
}
// Invalidate given rectangle at the window/output which is represented by // this ObjectContact. void ObjectContactOfPageView::InvalidatePartOfView(const basegfx::B2DRange& rRange) const
{ // invalidate at associated PageWindow
GetPageWindow().InvalidatePageWindow(rRange);
}
// Get info about the need to visualize GluePoints bool ObjectContactOfPageView::AreGluePointsVisible() const
{ bool bTiledRendering = comphelper::LibreOfficeKit::isActive(); return !bTiledRendering && GetPageWindow().GetPageView().GetView().ImpIsGlueVisible();
}
// check if text animation is allowed. bool ObjectContactOfPageView::IsTextAnimationAllowed() const
{ if (comphelper::IsFuzzing()) returntrue; // tdf#161765: Let the user choose which animation settings to use: OS's / LO's // New options: "System"/"No"/"Yes". // Do respect OS's animation setting if the user has selected the option "System" return MiscSettings::IsAnimatedTextAllowed();
}
// check if graphic animation is allowed. bool ObjectContactOfPageView::IsGraphicAnimationAllowed() const
{ if (comphelper::IsFuzzing()) returntrue; // tdf#161765: Let the user choose which animation settings to use: OS's / LO's and // don't override here LO's animation settings with OS's all-or-nothing animation setting, // but do respect OS's animation setting if the user has selected the option "System". // New options: "System"/"No"/"Yes" return MiscSettings::IsAnimatedGraphicAllowed();
}
// set all UNO controls displayed in the view to design/alive mode void ObjectContactOfPageView::SetUNOControlsDesignMode( bool _bDesignMode ) const
{ const sal_uInt32 nCount(getViewObjectContactCount());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.