tdf#164476 CiaroSDPR: improve ControlPrimitive2D rendering
The task shows that for some situations the Controls do not get vbisualized. These *should* be child windows of the panel containing them, but fir some reason these seem to get incarnated by being 'painted'. Problem is that for SDPRs an OutputDevice to do so is not available - by purpose. Luckily it is possible to use a awt::XGraphics and 'paint' from there. It would also be possible to find out why the child windows do not get constructed and where this may need to be done, but for now just add 'painting' the Controls by using the path utilizing the awt::XGraphics mechanism. For that purpose, do set an awt::XGraphics at the CairoSDPR if it gets constructed using an OutputDevice. It may be that we need to think about how to solve this for SDPRs that get constructed from scratch, e.g. when using createPixelProcessor2DFromScratch. This would mean to somehow construct a awt::XGraphics from a cairo surface, probably using an OutputDevice as in-betwen step, but for now this change solves the problem. Change-Id: I3bc653deab7f0b2902081b0fdbd501dfcc78383b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180967 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This commit is contained in:
parent
163ddd7a84
commit
7c0d5fab2b
@ -55,8 +55,10 @@
|
||||
#include <basegfx/utils/systemdependentdata.hxx>
|
||||
#include <basegfx/utils/bgradient.hxx>
|
||||
#include <vcl/BitmapReadAccess.hxx>
|
||||
#include <officecfg/Office/Common.hxx>
|
||||
#include <vcl/vcllayout.hxx>
|
||||
#include <officecfg/Office/Common.hxx>
|
||||
#include <com/sun/star/awt/XView.hpp>
|
||||
#include <com/sun/star/awt/XControl.hpp>
|
||||
#include <unordered_map>
|
||||
#include <dlfcn.h>
|
||||
|
||||
@ -959,6 +961,7 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const geometry::ViewInformation2D&
|
||||
officecfg::Office::Common::Drawinglayer::RenderDecoratedTextDirect::get())
|
||||
, mnClipRecursionCount(0)
|
||||
, mbCairoCoordinateLimitWorkaroundActive(false)
|
||||
, maXGraphics()
|
||||
{
|
||||
if (nWidthPixel <= 0 || nHeightPixel <= 0)
|
||||
// no size, invalid
|
||||
@ -1002,6 +1005,7 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const geometry::ViewInformation2D&
|
||||
officecfg::Office::Common::Drawinglayer::RenderDecoratedTextDirect::get())
|
||||
, mnClipRecursionCount(0)
|
||||
, mbCairoCoordinateLimitWorkaroundActive(false)
|
||||
, maXGraphics()
|
||||
{
|
||||
// no target, nothing to initialize
|
||||
if (nullptr == pTarget)
|
||||
@ -3881,12 +3885,44 @@ void CairoPixelProcessor2D::processControlPrimitive2D(
|
||||
return;
|
||||
}
|
||||
|
||||
bool bDone(false);
|
||||
|
||||
try
|
||||
{
|
||||
if (getXGraphics().is())
|
||||
{
|
||||
// Needs to be drawn. Link new graphics and view
|
||||
const uno::Reference<awt::XControl>& rXControl(rControlPrimitive.getXControl());
|
||||
uno::Reference<awt::XView> xControlView(rXControl, uno::UNO_QUERY_THROW);
|
||||
const uno::Reference<awt::XGraphics> xOriginalGraphics(xControlView->getGraphics());
|
||||
xControlView->setGraphics(getXGraphics());
|
||||
|
||||
// get position
|
||||
const basegfx::B2DHomMatrix aObjectToPixel(
|
||||
getViewInformation2D().getObjectToViewTransformation()
|
||||
* rControlPrimitive.getTransform());
|
||||
const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0));
|
||||
|
||||
xControlView->draw(basegfx::fround(aTopLeftPixel.getX()),
|
||||
basegfx::fround(aTopLeftPixel.getY()));
|
||||
|
||||
// restore original graphics
|
||||
xControlView->setGraphics(xOriginalGraphics);
|
||||
bDone = true;
|
||||
}
|
||||
}
|
||||
catch (const uno::Exception&)
|
||||
{
|
||||
// #i116763# removing since there is a good alternative when the xControlView
|
||||
// is not found and it is allowed to happen
|
||||
// DBG_UNHANDLED_EXCEPTION();
|
||||
}
|
||||
|
||||
if (!bDone)
|
||||
{
|
||||
// process recursively and use the decomposition as Bitmap
|
||||
// NOTE: The VclPixelProcessor2D tries to paint it using
|
||||
// UNO API and awt::XView/awt::XGraphics to directly paint the
|
||||
// control. To do so would need the target OutDev which we
|
||||
// want to avoid here
|
||||
process(rControlPrimitive);
|
||||
}
|
||||
}
|
||||
|
||||
void CairoPixelProcessor2D::evaluateCairoCoordinateLimitWorkaround()
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <officecfg/Office/Common.hxx>
|
||||
#endif
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
namespace drawinglayer::processor2d
|
||||
{
|
||||
std::unique_ptr<BaseProcessor2D> createPixelProcessor2DFromScratch(
|
||||
@ -125,8 +127,15 @@ std::unique_ptr<BaseProcessor2D> createPixelProcessor2DFromOutputDevice(
|
||||
rTargetOutDev.GetOutputWidthPixel(), rTargetOutDev.GetOutputHeightPixel()));
|
||||
|
||||
if (aRetval->valid())
|
||||
{
|
||||
// if we construct a CairoPixelProcessor2D from OutputDevice,
|
||||
// additionally set the XGraphics that can be obtained from
|
||||
// there. It may be used e.g. to render FormControls directly
|
||||
aRetval->setXGraphics(rTargetOutDev.CreateUnoGraphics());
|
||||
|
||||
return aRetval;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// default: create VclPixelProcessor2D
|
||||
|
@ -657,21 +657,19 @@ void VclPixelProcessor2D::processControlPrimitive2D(
|
||||
return;
|
||||
}
|
||||
|
||||
// get awt::XControl from control primitive
|
||||
const uno::Reference<awt::XControl>& rXControl(rControlPrimitive.getXControl());
|
||||
bool bDone(false);
|
||||
|
||||
try
|
||||
{
|
||||
// remember old graphics and create new
|
||||
uno::Reference<awt::XView> xControlView(rXControl, uno::UNO_QUERY_THROW);
|
||||
const uno::Reference<awt::XGraphics> xOriginalGraphics(xControlView->getGraphics());
|
||||
const uno::Reference<awt::XGraphics> xNewGraphics(mpOutputDevice->CreateUnoGraphics());
|
||||
const uno::Reference<awt::XGraphics> xTargetGraphics(mpOutputDevice->CreateUnoGraphics());
|
||||
|
||||
if (xNewGraphics.is())
|
||||
if (xTargetGraphics.is())
|
||||
{
|
||||
// Needs to be drawn. Link new graphics and view
|
||||
xControlView->setGraphics(xNewGraphics);
|
||||
const uno::Reference<awt::XControl>& rXControl(rControlPrimitive.getXControl());
|
||||
uno::Reference<awt::XView> xControlView(rXControl, uno::UNO_QUERY_THROW);
|
||||
const uno::Reference<awt::XGraphics> xOriginalGraphics(xControlView->getGraphics());
|
||||
xControlView->setGraphics(xTargetGraphics);
|
||||
|
||||
// get position
|
||||
const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <basegfx/color/bcolormodifier.hxx>
|
||||
#include <tools/long.hxx>
|
||||
#include <sal/config.h>
|
||||
#include <com/sun/star/awt/XGraphics.hpp>
|
||||
|
||||
// cairo-specific
|
||||
#include <cairo.h>
|
||||
@ -89,6 +90,9 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub
|
||||
// calculated result of if we are in outsideCairoCoordinateLimits mode
|
||||
bool mbCairoCoordinateLimitWorkaroundActive;
|
||||
|
||||
// the XGraphics which may be set using setXGraphics()
|
||||
com::sun::star::uno::Reference<com::sun::star::awt::XGraphics> maXGraphics;
|
||||
|
||||
// helpers for direct paints
|
||||
void paintPolyPolygonRGBA(const basegfx::B2DPolyPolygon& rPolyPolygon,
|
||||
const basegfx::BColor& rColor, double fTransparency = 0.0);
|
||||
@ -188,10 +192,21 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub
|
||||
protected:
|
||||
bool hasError() const { return cairo_status(mpRT) != CAIRO_STATUS_SUCCESS; }
|
||||
bool hasRenderTarget() const { return nullptr != mpRT; }
|
||||
const com::sun::star::uno::Reference<com::sun::star::awt::XGraphics>& getXGraphics() const
|
||||
{
|
||||
return maXGraphics;
|
||||
}
|
||||
|
||||
public:
|
||||
bool valid() const { return hasRenderTarget() && !hasError(); }
|
||||
|
||||
// set a XGraphics for this CairoPixelProcessor2D when it is available
|
||||
void
|
||||
setXGraphics(const com::sun::star::uno::Reference<com::sun::star::awt::XGraphics>& rXGraphics)
|
||||
{
|
||||
maXGraphics = rXGraphics;
|
||||
}
|
||||
|
||||
// read access to CairoCoordinateLimitWorkaround mechanism
|
||||
bool isCairoCoordinateLimitWorkaroundActive() const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user