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 <quikee@gmail.com>
Tested-by: Jenkins <ci@libreoffice.org>
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
Caolán McNamara
2016-11-22 15:35:16 +00:00
committed by Tomaž Vajngerl
parent d689ad29c2
commit d9a6e0023c
11 changed files with 43 additions and 27 deletions

View File

@@ -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,7 @@ SvpSalGraphics::~SvpSalGraphics()
void SvpSalGraphics::setSurface(cairo_surface_t* pSurface)
{
m_pSurface = pSurface;
cairo_surface_get_device_scale(pSurface, &m_fScale, nullptr);
ResetClipRegion();
}
@@ -981,14 +983,15 @@ 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
cairo_surface_set_device_scale(pCopy, m_fScale, m_fScale);
cairo_t* cr = cairo_create(pCopy);
cairo_set_source_surface(cr, source, -aTR.mnSrcX, -aTR.mnSrcY);

View File

@@ -281,7 +281,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;
}

View File

@@ -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 (nNewDX == 0)
nNewDX = 1;
if (nNewDY == 0)
nNewDY = 1;
if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != aDevSize.getX() ||
cairo_image_surface_get_height(m_pSurface) != aDevSize.getY() )
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,21 @@ 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);
}
cairo_surface_set_device_scale(m_pSurface, m_fScale, m_fScale);
// update device in existing graphics
for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin();
it != m_aGraphics.end(); ++it )

View File

@@ -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;
@@ -236,6 +237,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);
};

View File

@@ -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() override;

View File

@@ -137,6 +137,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 );
@@ -146,6 +147,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; }

View File

@@ -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);
}

View File

@@ -339,8 +339,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

View File

@@ -83,6 +83,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
@@ -91,6 +92,7 @@ GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) :
if (!getenv("GDK_SCALE"))
{
gdk_x11_display_set_window_scale(m_pGdkDisplay, 1);
m_bOwnHiDpiScale = true;
}
}
#endif

View File

@@ -1575,13 +1575,14 @@ void GtkSalFrame::AllocateFrame()
if (m_pSurface)
cairo_surface_destroy(m_pSurface);
#if GTK_CHECK_VERSION(3,10,0)
int scale = getDisplay()->IsOwnHiDpiScale() ? 1 : gtk_widget_get_scale_factor(m_pWindow);
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);
cairo_surface_set_device_scale(m_pSurface, scale, scale);
#else
m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
aFrameSize.getX(),

View File

@@ -3117,7 +3117,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)