summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drawinglayer/source/processor2d/cairopixelprocessor2d.cxx64
-rw-r--r--drawinglayer/source/processor2d/processor2dtools.cxx56
-rw-r--r--include/drawinglayer/processor2d/cairopixelprocessor2d.hxx20
3 files changed, 106 insertions, 34 deletions
diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 1bf2b7dd9324..a1b57ed7940a 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -866,9 +866,12 @@ basegfx::B2DRange getDiscreteViewRange(cairo_t* pRT)
namespace drawinglayer::processor2d
{
CairoPixelProcessor2D::CairoPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation,
- cairo_surface_t* pTarget)
+ cairo_surface_t* pTarget, tools::Long nOffsetPixelX,
+ tools::Long nOffsetPixelY, tools::Long nWidthPixel,
+ tools::Long nHeightPixel)
: BaseProcessor2D(rViewInformation)
, maBColorModifierStack()
+ , mpCreateForRectangle(nullptr)
, mpRT(nullptr)
, mbRenderSimpleTextDirect(
officecfg::Office::Common::Drawinglayer::RenderSimpleTextDirect::get())
@@ -878,19 +881,64 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const geometry::ViewInformation2D&
{
if (pTarget)
{
- cairo_t* pRT = cairo_create(pTarget);
- cairo_set_antialias(pRT, rViewInformation.getUseAntiAliasing() ? CAIRO_ANTIALIAS_DEFAULT
- : CAIRO_ANTIALIAS_NONE);
- cairo_set_fill_rule(pRT, CAIRO_FILL_RULE_EVEN_ODD);
- cairo_set_operator(pRT, CAIRO_OPERATOR_OVER);
- setRenderTarget(pRT);
+ bool bClipNeeded(false);
+
+ if (0 != nOffsetPixelX || 0 != nOffsetPixelY || 0 != nWidthPixel || 0 != nHeightPixel)
+ {
+ if (0 != nOffsetPixelX || 0 != nOffsetPixelY)
+ {
+ // if offset is used we need initial clip
+ bClipNeeded = true;
+ }
+ else
+ {
+ // no offset used, compare to real pixel size
+ const tools::Long nRealPixelWidth(cairo_image_surface_get_width(pTarget));
+ const tools::Long nRealPixelHeight(cairo_image_surface_get_height(pTarget));
+
+ if (nRealPixelWidth != nWidthPixel || nRealPixelHeight != nHeightPixel)
+ {
+ // if size differs we need initial clip
+ bClipNeeded = true;
+ }
+ }
+ }
+
+ if (bClipNeeded)
+ {
+ // optional: if the possibility to add an initial clip relative
+ // to the real pixel dimensions of the target surface is used,
+ // aplly it here using that nice existing method of cairo
+ mpCreateForRectangle = cairo_surface_create_for_rectangle(
+ pTarget, nOffsetPixelX, nOffsetPixelY, nWidthPixel, nHeightPixel);
+
+ if (nullptr != mpCreateForRectangle)
+ mpRT = cairo_create(mpCreateForRectangle);
+ }
+ else
+ {
+ // create RenderTarget for full target
+ mpRT = cairo_create(pTarget);
+ }
+
+ if (nullptr != mpRT)
+ {
+ // initialize some basic used values/settings
+ cairo_set_antialias(mpRT, rViewInformation.getUseAntiAliasing()
+ ? CAIRO_ANTIALIAS_DEFAULT
+ : CAIRO_ANTIALIAS_NONE);
+ cairo_set_fill_rule(mpRT, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_operator(mpRT, CAIRO_OPERATOR_OVER);
+ }
}
}
CairoPixelProcessor2D::~CairoPixelProcessor2D()
{
- if (mpRT)
+ if (nullptr != mpRT)
cairo_destroy(mpRT);
+ if (nullptr != mpCreateForRectangle)
+ cairo_surface_destroy(mpCreateForRectangle);
}
void CairoPixelProcessor2D::processBitmapPrimitive2D(
diff --git a/drawinglayer/source/processor2d/processor2dtools.cxx b/drawinglayer/source/processor2d/processor2dtools.cxx
index e11f64a11da9..7930e496664f 100644
--- a/drawinglayer/source/processor2d/processor2dtools.cxx
+++ b/drawinglayer/source/processor2d/processor2dtools.cxx
@@ -36,31 +36,18 @@ std::unique_ptr<BaseProcessor2D> createPixelProcessor2DFromOutputDevice(
OutputDevice& rTargetOutDev,
const drawinglayer::geometry::ViewInformation2D& rViewInformation2D)
{
- static bool bUsePrimitiveRenderer(
#if defined(_WIN32)
- // Windows: make dependent on TEST_SYSTEM_PRIMITIVE_RENDERER
- nullptr != std::getenv("TEST_SYSTEM_PRIMITIVE_RENDERER")
-#elif USE_HEADLESS_CODE
- // Linux/Cairo: activate to check tests/builds. Leave a
- // possibility to deactivate for easy test/request testing
- nullptr == std::getenv("DISABLE_SYSTEM_DEPENDENT_PRIMITIVE_RENDERER")
-
- // Use this if all is stable/tested for a while
- // true
-
- // Also possible: make dependent on ExperimentalMode
- // officecfg::Office::Common::Misc::ExperimentalMode::get()
-#else
- // all others: do not use, not (yet) supported
- false
-#endif
- );
+ // Windows: make dependent on TEST_SYSTEM_PRIMITIVE_RENDERER
+ static bool bUsePrimitiveRenderer(nullptr != std::getenv("TEST_SYSTEM_PRIMITIVE_RENDERER"));
- if(bUsePrimitiveRenderer)
+ if (bUsePrimitiveRenderer)
{
drawinglayer::geometry::ViewInformation2D aViewInformation2D(rViewInformation2D);
// if mnOutOffX/mnOutOffY is set (a 'hack' to get a cheap additional offset), apply it additionally
+ // NOTE: This will also need to take extended size of target device into
+ // consideration, using D2DPixelProcessor2D *will* have to clip
+ // against that. Thus for now this is *not* sufficient (see tdf#163125)
if(0 != rTargetOutDev.GetOutOffXPixel() || 0 != rTargetOutDev.GetOutOffYPixel())
{
basegfx::B2DHomMatrix aTransform(aViewInformation2D.getViewTransformation());
@@ -68,22 +55,45 @@ std::unique_ptr<BaseProcessor2D> createPixelProcessor2DFromOutputDevice(
aViewInformation2D.setViewTransformation(aTransform);
}
-#if defined(_WIN32)
SystemGraphicsData aData(rTargetOutDev.GetSystemGfxData());
std::unique_ptr<D2DPixelProcessor2D> aRetval(
std::make_unique<D2DPixelProcessor2D>(aViewInformation2D, aData.hDC));
if (aRetval->valid())
return aRetval;
+ }
#elif USE_HEADLESS_CODE
+ // Linux/Cairo: now globally activated in master. Leave a
+ // possibility to deactivate for easy test/request testing
+ static bool bUsePrimitiveRenderer(nullptr == std::getenv("DISABLE_SYSTEM_DEPENDENT_PRIMITIVE_RENDERER"));
+
+ if (bUsePrimitiveRenderer)
+ {
SystemGraphicsData aData(rTargetOutDev.GetSystemGfxData());
+ const Size aSizePixel(rTargetOutDev.GetOutputSizePixel());
+
+ // create CairoPixelProcessor2D, make use of the possibility to
+ // add an initial clip relative to the real pixel dimensions of
+ // the target surface. This is e.g. needed here due to the
+ // existance of 'virtual' target surfaces that internally use an
+ // offset and limitied pixel size, mainly used for UI elements.
+ // let the CairoPixelProcessor2D do this, it has internal,
+ // system-specific possibilities to do that in an elegant and
+ // efficient way (using cairo_surface_create_for_rectangle).
std::unique_ptr<CairoPixelProcessor2D> aRetval(
- std::make_unique<CairoPixelProcessor2D>(aViewInformation2D, static_cast<cairo_surface_t*>(aData.pSurface)));
+ std::make_unique<CairoPixelProcessor2D>(
+ rViewInformation2D, static_cast<cairo_surface_t*>(aData.pSurface),
+ rTargetOutDev.GetOutOffXPixel(), rTargetOutDev.GetOutOffYPixel(),
+ aSizePixel.getWidth(), aSizePixel.getHeight()));
+
if (aRetval->valid())
return aRetval;
-#endif
}
+#endif
- // default: create Pixel Vcl-Processor
+ // default: create VclPixelProcessor2D
+ // NOTE: Since this uses VCL OutputDevice in the VclPixelProcessor2D
+ // taking care of virtual devices is not needed, OutputDevice
+ // and VclPixelProcessor2D will traditionally take care of it
return std::make_unique<VclPixelProcessor2D>(rViewInformation2D, rTargetOutDev);
}
diff --git a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
index 026c6a0c3086..cd0f8a562e50 100644
--- a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
@@ -11,6 +11,7 @@
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
#include <basegfx/color/bcolormodifier.hxx>
+#include <tools/long.hxx>
#include <sal/config.h>
// cairo-specific
@@ -68,6 +69,10 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub
// the modifiedColorPrimitive stack
basegfx::BColorModifierStack maBColorModifierStack;
+ // cairo_surface_t created when initial clip from the constructor
+ // parameters is requested
+ cairo_surface_t* mpCreateForRectangle;
+
// cairo specific data
cairo_t* mpRT;
@@ -173,13 +178,22 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : pub
protected:
bool hasError() const { return cairo_status(mpRT) != CAIRO_STATUS_SUCCESS; }
- void setRenderTarget(cairo_t* mpNewRT) { mpRT = mpNewRT; }
bool hasRenderTarget() const { return nullptr != mpRT; }
public:
bool valid() const { return hasRenderTarget() && !hasError(); }
- CairoPixelProcessor2D(const geometry::ViewInformation2D& rViewInformation,
- cairo_surface_t* pTarget);
+ CairoPixelProcessor2D(
+ // the initial ViewInformation
+ const geometry::ViewInformation2D& rViewInformation,
+
+ // the cairo render target
+ cairo_surface_t* pTarget,
+
+ // optional: possibility to add an initial clip relative to
+ // the real pixel dimensions of the target surface
+ tools::Long nOffsetPixelX = 0, tools::Long nOffsetPixelY = 0, tools::Long nWidthPixel = 0,
+ tools::Long nHeightPixel = 0);
+
virtual ~CairoPixelProcessor2D() override;
// access to BColorModifierStack