diff --git a/0001-Related-fdo-87242-init-VirtualDevice-with-size-of-su.patch b/0001-Related-fdo-87242-init-VirtualDevice-with-size-of-su.patch new file mode 100644 index 0000000..5875b6c --- /dev/null +++ b/0001-Related-fdo-87242-init-VirtualDevice-with-size-of-su.patch @@ -0,0 +1,559 @@ +From bc839c159d4ee94ef8ca08975cf65be37378ae04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 11 Dec 2014 16:20:49 +0000 +Subject: [PATCH] Related: fdo#87242 init VirtualDevice with size of surface + +otherwise vcl's clipping doesn't work quite right when the render text +with vcl apis fallback is used. + +Manually forced in my case, but it should happen in practice with vertical +text, so if there is a bug about vertical text not appearing in slideshows then +this is part of the fix for that. + +Windows and Mac remain unchanged as initialized with 1, 1. If the same problem +affects those platforms then they'll need to be adjusted to remember their +height/widths from the ctor and those values plugged in here instead + +(cherry picked from commit f95b0743da4239e047db8638c61f90f8bbe54306) +(cherry picked from commit e2be2c23c1ad61b3bd640be6f16d66f5cd925d38) + +Conflicts: + desktop/source/lib/init.cxx + +Related: fdo#87242 merge duplicate clip setup code + +favoring the vclcanvas one for the places where +they diverge + +(cherry picked from commit f88b5ab8692ee7ecf58b570e703d0e7f10cc2f0d) +(cherry picked from commit e0e96579ce3a248ee5d3b07ecf90f38e2020c555) + +Conflicts: + canvas/source/cairo/cairo_canvashelper_text.cxx + canvas/source/vcl/canvashelper.cxx + +Resolves: fdo#87242 reuse vcl clip for cairo during animations + +(cherry picked from commit 94d935eecbba0161de2616c2234b4a5d9d3cad88) +(cherry picked from commit 3a108b0600ce61f7960d561cee9989ab3a48780f) + +stray debugging code + +(cherry picked from commit 067b560335195b24eeedc4514956029ea975fbbf) +(cherry picked from commit fafc85559097166eceb67c4db4528cc9977e4184) + +Change-Id: I2f82f0db0cf446d7db21f0a7ee4f8c15c7ebdb42 +18e3d4e7659ebd4cb90c86718c1b1035671b4be3 +0a26d4c4092226732620c3852b0402ee45d4fa1d +953389e236739c01226365c33ab777fc3972b69d +--- + canvas/source/cairo/cairo_canvashelper.hxx | 3 + + canvas/source/cairo/cairo_canvashelper_text.cxx | 117 ++++++++++-------------- + canvas/source/cairo/cairo_quartz_cairo.cxx | 2 +- + canvas/source/cairo/cairo_win32_cairo.cxx | 2 +- + canvas/source/cairo/cairo_xlib_cairo.cxx | 7 +- + canvas/source/tools/canvastools.cxx | 75 +++++++++++++++ + canvas/source/vcl/canvashelper.cxx | 79 +--------------- + include/canvas/canvastools.hxx | 6 ++ + include/vcl/virdev.hxx | 3 +- + vcl/source/gdi/virdev.cxx | 6 +- + 10 files changed, 147 insertions(+), 153 deletions(-) + +diff --git a/canvas/source/cairo/cairo_canvashelper.hxx b/canvas/source/cairo/cairo_canvashelper.hxx +index 9258e7c..ccb03ac 100644 +--- a/canvas/source/cairo/cairo_canvashelper.hxx ++++ b/canvas/source/cairo/cairo_canvashelper.hxx +@@ -310,6 +310,9 @@ namespace cairocanvas + ::cairo::CairoSharedPtr mpCairo; + ::cairo::SurfaceSharedPtr mpSurface; + ::basegfx::B2ISize maSize; ++ ++ void clip_cairo_from_dev(::OutputDevice& rOutDev); ++ + }; + + /// also needed from SpriteHelper +diff --git a/canvas/source/cairo/cairo_canvashelper_text.cxx b/canvas/source/cairo/cairo_canvashelper_text.cxx +index d65f2de..78a2ddf 100644 +--- a/canvas/source/cairo/cairo_canvashelper_text.cxx ++++ b/canvas/source/cairo/cairo_canvashelper_text.cxx +@@ -127,73 +127,7 @@ namespace cairocanvas + + // TODO(P2): Don't change clipping all the time, maintain current clip + // state and change only when update is necessary +- +- // accumulate non-empty clips into one region +- // ========================================== +- +- Region aClipRegion; +- +- if( viewState.Clip.is() ) +- { +- ::basegfx::B2DPolyPolygon aClipPoly( +- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( +- viewState.Clip) ); +- +- if( aClipPoly.count() ) +- { +- // setup non-empty clipping +- ::basegfx::B2DHomMatrix aMatrix; +- aClipPoly.transform( +- ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix, +- viewState.AffineTransform ) ); +- +- aClipRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) ); +- } +- } +- +- if( renderState.Clip.is() ) +- { +- ::basegfx::B2DPolyPolygon aClipPoly( +- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( +- renderState.Clip) ); +- +- ::basegfx::B2DHomMatrix aMatrix; +- aClipPoly.transform( +- ::canvas::tools::mergeViewAndRenderTransform( aMatrix, +- viewState, +- renderState ) ); +- +- if( aClipPoly.count() ) +- { +- // setup non-empty clipping +- Region aRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) ); +- +- if( aClipRegion.IsEmpty() ) +- aClipRegion = aRegion; +- else +- aClipRegion.Intersect( aRegion ); +- } +- else +- { +- // clip polygon is empty +- aClipRegion.SetEmpty(); +- } +- } +- +- // setup accumulated clip region. Note that setting an +- // empty clip region denotes "clip everything" on the +- // OutputDevice (which is why we translate that into +- // SetClipRegion() here). When both view and render clip +- // are empty, aClipRegion remains default-constructed, +- // i.e. empty, too. +- if( aClipRegion.IsEmpty() ) +- { +- rOutDev.SetClipRegion(); +- } +- else +- { +- rOutDev.SetClipRegion( aClipRegion ); +- } ++ ::canvas::tools::clipOutDev(viewState, renderState, rOutDev); + + if( eColorType != IGNORE_COLOR ) + { +@@ -238,6 +172,31 @@ namespace cairocanvas + return nTransparency; + } + ++ class DeviceSettingsGuard ++ { ++ private: ++ OutputDevice *mpVirtualDevice; ++ cairo_t *mpCairo; ++ bool mbMappingWasEnabled; ++ public: ++ DeviceSettingsGuard(OutputDevice *pVirtualDevice, cairo_t *pCairo) ++ : mpVirtualDevice(pVirtualDevice) ++ , mpCairo(pCairo) ++ , mbMappingWasEnabled(mpVirtualDevice->IsMapModeEnabled()) ++ { ++ cairo_save(mpCairo); ++ mpVirtualDevice->Push(); ++ mpVirtualDevice->EnableMapMode(false); ++ } ++ ++ ~DeviceSettingsGuard() ++ { ++ mpVirtualDevice->EnableMapMode(mbMappingWasEnabled); ++ mpVirtualDevice->Pop(); ++ cairo_restore(mpCairo); ++ } ++ }; ++ + bool setupTextOutput( OutputDevice& rOutDev, + const rendering::XCanvas* pOwner, + ::Point& o_rOutPos, +@@ -247,14 +206,12 @@ namespace cairocanvas + { + setupOutDevState( rOutDev, pOwner, viewState, renderState, TEXT_COLOR ); + +- ::Font aVCLFont; +- + CanvasFont* pFont = dynamic_cast< CanvasFont* >( xFont.get() ); + + ENSURE_ARG_OR_THROW( pFont, + "CanvasHelper::setupTextOutput(): Font not compatible with this canvas" ); + +- aVCLFont = pFont->getVCLFont(); ++ ::Font aVCLFont = pFont->getVCLFont(); + + Color aColor( COL_BLACK ); + +@@ -273,10 +230,20 @@ namespace cairocanvas + + rOutDev.SetFont( aVCLFont ); + +- + return true; + } + ++ //set the clip of the rOutDev to the cairo surface ++ void CanvasHelper::clip_cairo_from_dev(::OutputDevice& rOutDev) ++ { ++ Region aRegion(rOutDev.GetClipRegion()); ++ if (!aRegion.IsEmpty() && !aRegion.IsNull()) ++ { ++ doPolyPolygonImplementation(aRegion.GetAsB2DPolyPolygon(), Clip, mpCairo.get(), ++ NULL, mpSurfaceProvider, rendering::FillRule_EVEN_ODD); ++ } ++ } ++ + uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawText( const rendering::XCanvas* pOwner, + const rendering::StringContext& text, + const uno::Reference< rendering::XCanvasFont >& xFont, +@@ -297,6 +264,8 @@ namespace cairocanvas + + if( mpVirtualDevice ) + { ++ DeviceSettingsGuard aGuard(mpVirtualDevice.get(), mpCairo.get()); ++ + #if defined CAIRO_HAS_WIN32_SURFACE + // FIXME: Some kind of work-araound... + cairo_rectangle (mpSurface->getCairo().get(), 0, 0, 0, 0); +@@ -330,6 +299,8 @@ namespace cairocanvas + // TODO(F2): alpha + mpVirtualDevice->SetLayoutMode( nLayoutMode ); + ++ clip_cairo_from_dev(*mpVirtualDevice); ++ + OSL_TRACE(":cairocanvas::CanvasHelper::drawText(O,t,f,v,r,d): %s", OUStringToOString( text.Text.copy( text.StartPosition, text.Length ), + RTL_TEXTENCODING_UTF8 ).getStr()); + +@@ -357,6 +328,8 @@ namespace cairocanvas + + if( mpVirtualDevice ) + { ++ DeviceSettingsGuard aGuard(mpVirtualDevice.get(), mpCairo.get()); ++ + #if defined CAIRO_HAS_WIN32_SURFACE + // FIXME: Some kind of work-araound... + cairo_rectangle( mpSurface->getCairo().get(), 0, 0, 0, 0); +@@ -371,6 +344,8 @@ namespace cairocanvas + if( !setupTextOutput( *mpVirtualDevice, pOwner, aOutpos, viewState, renderState, xLayoutedText->getFont() ) ) + return uno::Reference< rendering::XCachedPrimitive >(NULL); // no output necessary + ++ clip_cairo_from_dev(*mpVirtualDevice); ++ + // TODO(F2): What about the offset scalings? + pTextLayout->draw( mpSurface, *mpVirtualDevice, aOutpos, viewState, renderState ); + } +diff --git a/canvas/source/cairo/cairo_quartz_cairo.cxx b/canvas/source/cairo/cairo_quartz_cairo.cxx +index 07951ee..6b8b9aa 100644 +--- a/canvas/source/cairo/cairo_quartz_cairo.cxx ++++ b/canvas/source/cairo/cairo_quartz_cairo.cxx +@@ -269,7 +269,7 @@ namespace cairo + aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); + aSystemGraphicsData.rCGContext = getCGContext(); + return boost::shared_ptr( +- new VirtualDevice( &aSystemGraphicsData, getDepth() )); ++ new VirtualDevice( &aSystemGraphicsData, Size(1, 1), getDepth() )); + } + + /** +diff --git a/canvas/source/cairo/cairo_win32_cairo.cxx b/canvas/source/cairo/cairo_win32_cairo.cxx +index a70add9..8d53b4f 100644 +--- a/canvas/source/cairo/cairo_win32_cairo.cxx ++++ b/canvas/source/cairo/cairo_win32_cairo.cxx +@@ -197,7 +197,7 @@ namespace cairo + aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() ); + + return boost::shared_ptr( +- new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast(getDepth()) )); ++ new VirtualDevice( &aSystemGraphicsData, Size(1, 1), sal::static_int_cast(getDepth()) )); + } + + +diff --git a/canvas/source/cairo/cairo_xlib_cairo.cxx b/canvas/source/cairo/cairo_xlib_cairo.cxx +index 9b49c7e..79ab2a5 100644 +--- a/canvas/source/cairo/cairo_xlib_cairo.cxx ++++ b/canvas/source/cairo/cairo_xlib_cairo.cxx +@@ -277,8 +277,13 @@ namespace cairo + aSystemGraphicsData.hDrawable = getDrawable(); + aSystemGraphicsData.pXRenderFormat = getRenderFormat(); + ++ int width = cairo_xlib_surface_get_width(mpSurface.get()); ++ int height = cairo_xlib_surface_get_height(mpSurface.get()); ++ + return boost::shared_ptr( +- new VirtualDevice( &aSystemGraphicsData, std::max( getDepth(), 0 ) )); ++ new VirtualDevice(&aSystemGraphicsData, ++ Size(width, height), ++ std::max(getDepth(), 0))); + } + + /** +diff --git a/canvas/source/tools/canvastools.cxx b/canvas/source/tools/canvastools.cxx +index ae79cc9..6698f58 100644 +--- a/canvas/source/tools/canvastools.cxx ++++ b/canvas/source/tools/canvastools.cxx +@@ -1290,6 +1290,81 @@ namespace canvas + nColorSteps ) ); + } + ++ void clipOutDev(const rendering::ViewState& viewState, ++ const rendering::RenderState& renderState, ++ OutputDevice& rOutDev, ++ OutputDevice* p2ndOutDev) ++ { ++ // accumulate non-empty clips into one region ++ Region aClipRegion(true); ++ ++ if( viewState.Clip.is() ) ++ { ++ ::basegfx::B2DPolyPolygon aClipPoly( ++ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) ); ++ ++ if( aClipPoly.count() ) ++ { ++ // setup non-empty clipping ++ ::basegfx::B2DHomMatrix aMatrix; ++ aClipPoly.transform( ++ ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix, ++ viewState.AffineTransform ) ); ++ ++ aClipRegion = Region::GetRegionFromPolyPolygon( PolyPolygon( aClipPoly ) ); ++ } ++ else ++ { ++ // clip polygon is empty ++ aClipRegion.SetEmpty(); ++ } ++ } ++ ++ if( renderState.Clip.is() ) ++ { ++ ::basegfx::B2DPolyPolygon aClipPoly( ++ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) ); ++ ++ ::basegfx::B2DHomMatrix aMatrix; ++ aClipPoly.transform( ++ ::canvas::tools::mergeViewAndRenderTransform( aMatrix, ++ viewState, ++ renderState ) ); ++ ++ if( aClipPoly.count() ) ++ { ++ // setup non-empty clipping ++ Region aRegion = Region::GetRegionFromPolyPolygon( PolyPolygon( aClipPoly ) ); ++ aClipRegion.Intersect( aRegion ); ++ } ++ else ++ { ++ // clip polygon is empty ++ aClipRegion.SetEmpty(); ++ } ++ } ++ ++ // setup accumulated clip region. Note that setting an ++ // empty clip region denotes "clip everything" on the ++ // OutputDevice (which is why we translate that into ++ // SetClipRegion() here). When both view and render clip ++ // are empty, aClipRegion remains default-constructed, ++ // i.e. empty, too. ++ if( aClipRegion.IsNull() ) ++ { ++ rOutDev.SetClipRegion(); ++ ++ if( p2ndOutDev ) ++ p2ndOutDev->SetClipRegion(); ++ } ++ else ++ { ++ rOutDev.SetClipRegion( aClipRegion ); ++ ++ if( p2ndOutDev ) ++ p2ndOutDev->SetClipRegion( aClipRegion ); ++ } ++ } + } // namespace tools + + } // namespace canvas +diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx +index 0bd3954..5424e9e 100644 +--- a/canvas/source/vcl/canvashelper.cxx ++++ b/canvas/source/vcl/canvashelper.cxx +@@ -1236,78 +1236,7 @@ namespace vclcanvas + + // TODO(P2): Don't change clipping all the time, maintain current clip + // state and change only when update is necessary +- +- // accumulate non-empty clips into one region +- // ========================================== +- +- Region aClipRegion(true); +- +- if( viewState.Clip.is() ) +- { +- ::basegfx::B2DPolyPolygon aClipPoly( +- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) ); +- +- if( aClipPoly.count() ) +- { +- // setup non-empty clipping +- ::basegfx::B2DHomMatrix aMatrix; +- aClipPoly.transform( +- ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix, +- viewState.AffineTransform ) ); +- +- aClipRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) ); +- } +- else +- { +- // clip polygon is empty +- aClipRegion.SetEmpty(); +- } +- } +- +- if( renderState.Clip.is() ) +- { +- ::basegfx::B2DPolyPolygon aClipPoly( +- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) ); +- +- ::basegfx::B2DHomMatrix aMatrix; +- aClipPoly.transform( +- ::canvas::tools::mergeViewAndRenderTransform( aMatrix, +- viewState, +- renderState ) ); +- +- if( aClipPoly.count() ) +- { +- // setup non-empty clipping +- Region aRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) ); +- aClipRegion.Intersect( aRegion ); +- } +- else +- { +- // clip polygon is empty +- aClipRegion.SetEmpty(); +- } +- } +- +- // setup accumulated clip region. Note that setting an +- // empty clip region denotes "clip everything" on the +- // OutputDevice (which is why we translate that into +- // SetClipRegion() here). When both view and render clip +- // are empty, aClipRegion remains default-constructed, +- // i.e. empty, too. +- if( aClipRegion.IsNull() ) +- { +- rOutDev.SetClipRegion(); +- +- if( p2ndOutDev ) +- p2ndOutDev->SetClipRegion(); +- } +- else +- { +- rOutDev.SetClipRegion( aClipRegion ); +- +- if( p2ndOutDev ) +- p2ndOutDev->SetClipRegion( aClipRegion ); +- } ++ ::canvas::tools::clipOutDev(viewState, renderState, rOutDev, p2ndOutDev); + + Color aColor( COL_WHITE ); + +@@ -1373,18 +1302,16 @@ namespace vclcanvas + ENSURE_OR_THROW( mpOutDev.get(), + "outdev null. Are we disposed?" ); + +- setupOutDevState( viewState, renderState, TEXT_COLOR ); +- + OutputDevice& rOutDev( mpOutDev->getOutDev() ); + +- ::Font aVCLFont; ++ setupOutDevState( viewState, renderState, TEXT_COLOR ); + + CanvasFont* pFont = dynamic_cast< CanvasFont* >( xFont.get() ); + + ENSURE_ARG_OR_THROW( pFont, + "Font not compatible with this canvas" ); + +- aVCLFont = pFont->getVCLFont(); ++ ::Font aVCLFont = pFont->getVCLFont(); + + Color aColor( COL_BLACK ); + +diff --git a/include/canvas/canvastools.hxx b/include/canvas/canvastools.hxx +index de5a76c..3881537 100644 +--- a/include/canvas/canvastools.hxx ++++ b/include/canvas/canvastools.hxx +@@ -77,6 +77,7 @@ namespace com { namespace sun { namespace star { namespace awt + } } } } + + class Color; ++class OutputDevice; + + namespace canvas + { +@@ -579,6 +580,11 @@ namespace canvas + ::std::size_t mnEntries; + bool mbCaseSensitive; + }; ++ ++ CANVASTOOLS_DLLPUBLIC void clipOutDev(const css::rendering::ViewState& viewState, ++ const css::rendering::RenderState& renderState, ++ OutputDevice& rOutDev, ++ OutputDevice* p2ndOutDev=NULL); + } + } + +diff --git a/include/vcl/virdev.hxx b/include/vcl/virdev.hxx +index 87205c7..1c0a412 100644 +--- a/include/vcl/virdev.hxx ++++ b/include/vcl/virdev.hxx +@@ -110,7 +110,8 @@ public: + Any rendering will happen directly on the context and not on any intermediate bitmap. + Note: This might not be supported on all platforms ! + */ +- explicit VirtualDevice( const SystemGraphicsData *pData, sal_uInt16 nBitCount ); ++ explicit VirtualDevice(const SystemGraphicsData *pData, const Size &rSize, ++ sal_uInt16 nBitCount); + + virtual ~VirtualDevice(); + +diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx +index 6378785..9dcc286 100644 +--- a/vcl/source/gdi/virdev.cxx ++++ b/vcl/source/gdi/virdev.cxx +@@ -236,13 +236,15 @@ VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, sal_uInt16 nBitCount + mnAlphaDepth = sal::static_int_cast(nAlphaBitCount); + } + +-VirtualDevice::VirtualDevice( const SystemGraphicsData *pData, sal_uInt16 nBitCount ) ++VirtualDevice::VirtualDevice(const SystemGraphicsData *pData, const Size &rSize, ++ sal_uInt16 nBitCount) + : mpVirDev( NULL ), + meRefDevMode( REFDEV_NONE ) + { + SAL_INFO( "vcl.gdi", "VirtualDevice::VirtualDevice( " << nBitCount << " )" ); + +- ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount, pData ); ++ ImplInitVirDev(Application::GetDefaultDevice(), rSize.Width(), rSize.Height(), ++ nBitCount, pData); + } + + VirtualDevice::~VirtualDevice() +-- +1.9.3 + diff --git a/libreoffice.spec b/libreoffice.spec index 4389dd4..31421bf 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -46,7 +46,7 @@ Summary: Free Software Productivity Suite Name: libreoffice Epoch: 1 Version: %{libo_version}.0 -Release: 5%{?libo_prerelease}%{?dist} +Release: 6%{?libo_prerelease}%{?dist} License: (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and Artistic and MPLv2.0 and CC0 Group: Applications/Productivity URL: http://www.libreoffice.org/ @@ -326,6 +326,7 @@ Patch18: 0001-Revert-No-need-to-have-OpenCL-optional-at-configure-.patch Patch19: 0001-Don-t-treat-clew-as-part-of-an-external-clcc-module.patch Patch20: 0001-don-t-copy-stylesheet-s-HelpID-if-this-s-a-rename.patch Patch21: 0001-fdo-37682-paint-the-right-area.patch +Patch22: 0001-Related-fdo-87242-init-VirtualDevice-with-size-of-su.patch %define instdir %{_libdir} %define baseinstdir %{instdir}/libreoffice @@ -2290,6 +2291,9 @@ update-desktop-database %{_datadir}/applications &> /dev/null || : %endif %changelog +* Fri Dec 12 2014 Caolán McNamara - 1:4.4.0.0-6.beta2 +- Resolves: fdo#87242 fix unwanted text shadows during cairo animations + * Sat Dec 06 2014 David Tardon - 1:4.4.0.0-5.beta2 - update to 4.4.0 beta2 - move officehelper.py to pyuno package so it can be imported from python