vcl/headless/svpgdi.cxx | 16 ++++++++++---- vcl/headless/svpinst.cxx | 2 - vcl/headless/svpvd.cxx | 33 ++++++++++++++++-------------- vcl/inc/headless/svpgdi.hxx | 2 + vcl/inc/headless/svpvd.hxx | 4 ++- vcl/inc/unx/gtk/gtkdata.hxx | 2 + vcl/unx/gtk/gtkdata.cxx | 1 vcl/unx/gtk/gtkinst.cxx | 6 +++-- vcl/unx/gtk3/gtk3gtkdata.cxx | 2 + vcl/unx/gtk3/gtk3gtkframe.cxx | 15 ++++++++++--- vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx | 2 - 11 files changed, 56 insertions(+), 29 deletions(-)
New commits: commit 2c24cc40e37ffb09d6a4fa88ca9d9b9d346982cc Author: Caolán McNamara <caol...@redhat.com> Date: Tue Nov 22 15:35:16 2016 +0000 Resolves: tdf#99508 ensure sufficient size for hidpi backing surface and match virtual device scale with widget device scale Change-Id: I1f35dcbaec94be12758ad6e4276bfd6bda4b1e88 Reviewed-on: https://gerrit.libreoffice.org/31080 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins <c...@libreoffice.org> Tested-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit d9a6e0023c9a192850b9db00f8120fbcc4256ec9) Reviewed-on: https://gerrit.libreoffice.org/31156 diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 63c60ca..36f44cb 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -374,6 +374,7 @@ bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight, SvpSalGraphics::SvpSalGraphics() : m_pSurface(nullptr) + , m_fScale(1.0) , m_aLineColor(MAKE_SALCOLOR(0x00, 0x00, 0x00)) , m_aFillColor(MAKE_SALCOLOR(0xFF, 0xFF, 0XFF)) , m_ePaintMode(OVERPAINT) @@ -388,6 +389,9 @@ SvpSalGraphics::~SvpSalGraphics() void SvpSalGraphics::setSurface(cairo_surface_t* pSurface) { m_pSurface = pSurface; +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + cairo_surface_get_device_scale(pSurface, &m_fScale, nullptr); +#endif ResetClipRegion(); } @@ -981,15 +985,17 @@ void SvpSalGraphics::copyBits( const SalTwoRect& rTR, #if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 12, 0) pCopy = cairo_surface_create_similar(source, cairo_surface_get_content(m_pSurface), - aTR.mnSrcWidth, - aTR.mnSrcHeight); + aTR.mnSrcWidth * m_fScale, + aTR.mnSrcHeight * m_fScale); #else pCopy = cairo_surface_create_similar_image(source, cairo_image_surface_get_format(m_pSurface), - aTR.mnSrcWidth, - aTR.mnSrcHeight); + aTR.mnSrcWidth * m_fScale, + aTR.mnSrcHeight * m_fScale); +#endif +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + cairo_surface_set_device_scale(pCopy, m_fScale, m_fScale); #endif - cairo_t* cr = cairo_create(pCopy); cairo_set_source_surface(cr, source, -aTR.mnSrcX, -aTR.mnSrcY); cairo_rectangle(cr, 0, 0, aTR.mnSrcWidth, aTR.mnSrcHeight); diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index a6b554c..8ba3380 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -272,7 +272,7 @@ SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics DeviceFormat eFormat, const SystemGraphicsData* /* pData */ ) { - SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat); + SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat, 1); pNew->SetSize( nDX, nDY ); return pNew; } diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx index f356d7d..ca28a52 100644 --- a/vcl/headless/svpvd.cxx +++ b/vcl/headless/svpvd.cxx @@ -57,14 +57,16 @@ bool SvpSalVirtualDevice::SetSize( long nNewDX, long nNewDY ) bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, sal_uInt8 *const pBuffer) { - B2IVector aDevSize( nNewDX, nNewDY ); - if( aDevSize.getX() == 0 ) - aDevSize.setX( 1 ); - if( aDevSize.getY() == 0 ) - aDevSize.setY( 1 ); - - if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != aDevSize.getX() || - cairo_image_surface_get_height(m_pSurface) != aDevSize.getY() ) + if (nNewDX == 0) + nNewDX = 1; + if (nNewDY == 0) + nNewDY = 1; + + nNewDX *= m_fScale; + nNewDY *= m_fScale; + + if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != nNewDX || + cairo_image_surface_get_height(m_pSurface) != nNewDY ) { if (m_pSurface) { @@ -74,22 +76,23 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, if (m_eFormat == DeviceFormat::BITMASK) { m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_A1, - aDevSize.getX(), - aDevSize.getY()); + nNewDX, nNewDY); } else { m_pSurface = pBuffer ? cairo_image_surface_create_for_data(pBuffer, CAIRO_FORMAT_ARGB32, - aDevSize.getX(), - aDevSize.getY(), - cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, aDevSize.getX())) + nNewDX, nNewDY, + cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nNewDX)) : cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - aDevSize.getX(), - aDevSize.getY()); + nNewDX, nNewDY); } +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + cairo_surface_set_device_scale(m_pSurface, m_fScale, m_fScale); +#endif + // update device in existing graphics for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin(); it != m_aGraphics.end(); ++it ) diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 85bb4b0..060c9f9 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -80,6 +80,7 @@ struct VCL_DLLPUBLIC DamageHandler class VCL_DLLPUBLIC SvpSalGraphics : public SalGraphics { cairo_surface_t* m_pSurface; + double m_fScale; SalColor m_aLineColor; SalColor m_aFillColor; PaintMode m_ePaintMode; @@ -235,6 +236,7 @@ public: cairo_t* getCairoContext(bool bXorModeAllowed) const; void releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, const basegfx::B2DRange& rExtents) const; static cairo_surface_t* createCairoSurface(const BitmapBuffer *pBuffer); + double getScale() const { return m_fScale; } void clipRegion(cairo_t* cr); }; diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx index 9256768..13f2c00 100644 --- a/vcl/inc/headless/svpvd.hxx +++ b/vcl/inc/headless/svpvd.hxx @@ -31,12 +31,14 @@ class VCL_DLLPUBLIC SvpSalVirtualDevice : public SalVirtualDevice { DeviceFormat m_eFormat; cairo_surface_t* m_pSurface; + double m_fScale; std::list< SvpSalGraphics* > m_aGraphics; public: - SvpSalVirtualDevice(DeviceFormat eFormat) + SvpSalVirtualDevice(DeviceFormat eFormat, double fScale) : m_eFormat(eFormat) , m_pSurface(nullptr) + , m_fScale(fScale) { } virtual ~SvpSalVirtualDevice(); diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx index 037d213..98c96dd 100644 --- a/vcl/inc/unx/gtk/gtkdata.hxx +++ b/vcl/inc/unx/gtk/gtkdata.hxx @@ -138,6 +138,7 @@ class GtkSalDisplay : public SalDisplay o3tl::enumarray<PointerStyle, GdkCursor*> m_aCursors; bool m_bStartupCompleted; bool m_bX11Display; + bool m_bOwnHiDpiScale; GdkCursor* getFromXBM( const unsigned char *pBitmap, const unsigned char *pMask, int nWidth, int nHeight, int nXHot, int nYHot ); @@ -147,6 +148,7 @@ public: GdkDisplay* GetGdkDisplay() const { return m_pGdkDisplay; } bool IsX11Display() const { return m_bX11Display; } + bool IsOwnHiDpiScale() const { return m_bOwnHiDpiScale; } GtkSalSystem* getSystem() const { return m_pSys; } diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx index 8db0513..3a22a6d 100644 --- a/vcl/unx/gtk/gtkdata.cxx +++ b/vcl/unx/gtk/gtkdata.cxx @@ -80,6 +80,7 @@ GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) : GetGenericData()->ErrorTrapPush(); // and leak the trap m_bX11Display = true; + m_bOwnHiDpiScale = true; gtk_widget_set_default_direction(AllSettings::GetLayoutRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); } diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx index 1aa17fd..76d2ff9 100644 --- a/vcl/unx/gtk/gtkinst.cxx +++ b/vcl/unx/gtk/gtkinst.cxx @@ -329,8 +329,10 @@ SalVirtualDevice* GtkInstance::CreateVirtualDevice( SalGraphics *pG, { EnsureInit(); #if GTK_CHECK_VERSION(3,0,0) - (void)pG; (void) pGd; - SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat); + (void) pGd; + SvpSalGraphics *pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(pG); + assert(pSvpSalGraphics); + SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice(eFormat, pSvpSalGraphics->getScale()); pNew->SetSize( nDX, nDY ); return pNew; #else diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx index ca210e0..4207995 100644 --- a/vcl/unx/gtk3/gtk3gtkdata.cxx +++ b/vcl/unx/gtk3/gtk3gtkdata.cxx @@ -81,6 +81,7 @@ GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) : GetGenericData()->ErrorTrapPush(); // and leak the trap m_bX11Display = GDK_IS_X11_DISPLAY( m_pGdkDisplay ); + m_bOwnHiDpiScale = false; #if GTK_CHECK_VERSION(3,10,0) #ifdef GDK_WINDOWING_X11 @@ -89,6 +90,7 @@ GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) : if (!getenv("GDK_SCALE")) { gdk_x11_display_set_window_scale(m_pGdkDisplay, 1); + m_bOwnHiDpiScale = true; } } #endif diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index b728782..cf3c426 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -1577,13 +1577,20 @@ void GtkSalFrame::AllocateFrame() if (m_pSurface) cairo_surface_destroy(m_pSurface); - #if GTK_CHECK_VERSION(3,10,0) +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + int scale = getDisplay()->IsOwnHiDpiScale() ? 1 : gtk_widget_get_scale_factor(m_pWindow); +#else + int scale = 1; +#endif m_pSurface = gdk_window_create_similar_image_surface(widget_get_window(m_pWindow), CAIRO_FORMAT_ARGB32, - aFrameSize.getX(), - aFrameSize.getY(), - 0); + aFrameSize.getX() * scale, + aFrameSize.getY() * scale, + scale); +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + cairo_surface_set_device_scale(m_pSurface, scale, scale); +#endif #else m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aFrameSize.getX(), diff --git a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx index f8e093d..52c3246 100644 --- a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx @@ -2495,7 +2495,7 @@ void GtkSalGraphics::GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY) int nScaleFactor = 1; #if GTK_CHECK_VERSION(3, 10, 0) - nScaleFactor = gdk_window_get_scale_factor(widget_get_window(mpWindow)); + nScaleFactor = GtkSalFrame::getDisplay()->IsOwnHiDpiScale() ? gtk_widget_get_scale_factor(mpWindow) : 1; #endif if (fResolution > 0.0)
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits