Kaydet (Commit) 185c9724 authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski Kaydeden (comit) Thorsten Behrens

QT5 implement cairo rendering path

Instead of QImage, this uses cairo_surface_t internally and just
blits the composed image in the Qt5Widgets paint function.

To enable this rendering path set SAL_VCL_QT5_USE_CAIRO.

Change-Id: Ieddda9bad2596ce46d7d07d4d7060e40d44997db
üst 2ffb83da
......@@ -54,6 +54,7 @@ $(eval $(call gb_Library_use_libraries,vclplug_qt5,\
$(eval $(call gb_Library_use_externals,vclplug_qt5,\
boost_headers \
cairo \
icuuc \
qt5 \
epoxy \
......@@ -89,6 +90,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\
vcl/qt5/Qt5Object \
vcl/qt5/Qt5Printer \
vcl/qt5/Qt5Timer \
vcl/qt5/Qt5Tools \
vcl/qt5/Qt5VirtualDevice \
vcl/qt5/Qt5Widget \
))
......
......@@ -32,12 +32,27 @@
#include <saldatabasic.hxx>
#include <vcl/syswin.hxx>
Qt5Frame::Qt5Frame( Qt5Frame* pParent, SalFrameStyleFlags nStyle )
: m_bGraphicsInUse( false )
#include <cairo.h>
#include <headless/svpgdi.hxx>
static void SvpDamageHandler( void *handle,
sal_Int32 nExtentsX, sal_Int32 nExtentsY,
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight )
{
Qt5Frame* pThis = static_cast< Qt5Frame* >( handle );
pThis->Damage( nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight );
}
Qt5Frame::Qt5Frame( Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo )
: m_bUseCairo( bUseCairo )
, m_bGraphicsInUse( false )
{
Qt5Instance *pInst = static_cast<Qt5Instance*>( GetSalData()->m_pInstance );
pInst->insertFrame( this );
m_aDamageHandler.handle = this;
m_aDamageHandler.damaged = ::SvpDamageHandler;
if( nStyle & SalFrameStyleFlags::DEFAULT ) // ensure default style
{
nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE;
......@@ -85,11 +100,24 @@ Qt5Frame::~Qt5Frame()
pInst->eraseFrame( this );
}
void Qt5Frame::Damage( sal_Int32 nExtentsX, sal_Int32 nExtentsY,
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) const
{
m_pQWidget->update( nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight );
}
void Qt5Frame::TriggerPaintEvent()
{
QSize aSize( m_pQWidget->size() );
SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height(), true);
CallCallback(SalEvent::Paint, &aPaintEvt);
SalPaintEvent aPaintEvt( 0, 0, aSize.width(), aSize.height(), true );
CallCallback( SalEvent::Paint, &aPaintEvt );
}
void Qt5Frame::TriggerPaintEvent( QRect aRect )
{
SalPaintEvent aPaintEvt( aRect.x(), aRect.y(),
aRect.width(), aRect.height(), true );
CallCallback( SalEvent::Paint, &aPaintEvt );
}
SalGraphics* Qt5Frame::AcquireGraphics()
......@@ -97,22 +125,43 @@ SalGraphics* Qt5Frame::AcquireGraphics()
if( m_bGraphicsInUse )
return nullptr;
if( !m_pGraphics.get() )
{
m_pGraphics.reset( new Qt5Graphics( this ) );
m_pQImage.reset( new QImage( m_pQWidget->size(), QImage::Format_ARGB32 ) );
m_pGraphics->ChangeQImage( m_pQImage.get() );
TriggerPaintEvent();
}
m_bGraphicsInUse = true;
return m_pGraphics.get();
if( m_bUseCairo )
{
if( !m_pSvpGraphics.get() )
{
int width = m_pQWidget->size().width();
int height = m_pQWidget->size().height();
m_pSvpGraphics.reset( new SvpSalGraphics() );
m_pSurface.reset( cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ));
m_pSvpGraphics->setSurface( m_pSurface.get(), basegfx::B2IVector(width, height) );
cairo_surface_set_user_data( m_pSurface.get(), SvpSalGraphics::getDamageKey(),
&m_aDamageHandler, nullptr );
TriggerPaintEvent();
}
return m_pSvpGraphics.get();
}
else
{
if( !m_pQt5Graphics.get() )
{
m_pQt5Graphics.reset( new Qt5Graphics( this ) );
m_pQImage.reset( new QImage( m_pQWidget->size(), Qt5_DefaultFormat32 ) );
m_pQt5Graphics->ChangeQImage( m_pQImage.get() );
TriggerPaintEvent();
}
return m_pQt5Graphics.get();
}
}
void Qt5Frame::ReleaseGraphics( SalGraphics* pSalGraph )
{
(void) pSalGraph;
assert( pSalGraph == m_pGraphics.get() );
if( m_bUseCairo )
assert( pSalGraph == m_pSvpGraphics.get() );
else
assert( pSalGraph == m_pQt5Graphics.get() );
m_bGraphicsInUse = false;
}
......@@ -269,7 +318,6 @@ bool Qt5Frame::GetWindowState( SalFrameState* pState )
WindowStateMask::Height;
}
TriggerPaintEvent();
return true;
}
......
......@@ -21,7 +21,9 @@
#include <salframe.hxx>
#include <memory>
#include "Qt5Tools.hxx"
#include <headless/svpgdi.hxx>
class Qt5Graphics;
class Qt5Instance;
......@@ -29,15 +31,22 @@ class Qt5Widget;
class QWidget;
class QPaintDevice;
class QImage;
class SvpSalGraphics;
class Qt5Frame
: public SalFrame
{
friend class Qt5Widget;
std::unique_ptr< QWidget > m_pQWidget;
std::unique_ptr< QImage > m_pQImage;
std::unique_ptr< Qt5Graphics > m_pGraphics;
std::unique_ptr< QWidget > m_pQWidget;
const bool m_bUseCairo;
std::unique_ptr< QImage > m_pQImage;
std::unique_ptr< Qt5Graphics > m_pQt5Graphics;
UniqueCairoSurface m_pSurface;
std::unique_ptr< SvpSalGraphics> m_pSvpGraphics;
DamageHandler m_aDamageHandler;
bool m_bGraphicsInUse;
SalFrameStyleFlags m_nStyle;
Qt5Frame *m_pParent;
......@@ -53,14 +62,19 @@ class Qt5Frame
}
void TriggerPaintEvent();
void TriggerPaintEvent( QRect aRect );
public:
Qt5Frame( Qt5Frame* pParent,
SalFrameStyleFlags nSalFrameStyle );
SalFrameStyleFlags nSalFrameStyle,
bool bUseCairo );
virtual ~Qt5Frame() override;
QWidget* GetQWidget() const { return m_pQWidget.get(); }
void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY,
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) const;
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
......
......@@ -194,6 +194,7 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBi
PreparePainter();
const QImage *pImage = static_cast< const Qt5Bitmap* >( &rSalBitmap )->GetQImage();
assert( pImage );
m_pPainter->drawImage( QPoint( rPosAry.mnDestX, rPosAry.mnDestY ),
*pImage, QRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
......@@ -208,12 +209,24 @@ void Qt5Graphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSalBitmap,
const SalBitmap& rTransparentBitmap )
{
if( rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0
|| rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0 )
return;
assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
}
void Qt5Graphics::drawMask( const SalTwoRect& rPosAry,
const SalBitmap& rSalBitmap,
SalColor nMaskColor )
const SalBitmap& rSalBitmap,
SalColor nMaskColor )
{
if( rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0
|| rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0 )
return;
assert( rPosAry.mnSrcWidth == rPosAry.mnDestWidth );
assert( rPosAry.mnSrcHeight == rPosAry.mnDestHeight );
}
SalBitmap* Qt5Graphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
......
......@@ -27,8 +27,11 @@
#include "Qt5Object.hxx"
#include "Qt5Bitmap.hxx"
#include <headless/svpvd.hxx>
#include <QtCore/QThread>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtCore/QAbstractEventDispatcher>
#include <vclpluginapi.h>
......@@ -38,9 +41,10 @@
#include <headless/svpdummies.hxx>
#include <headless/svpbmp.hxx>
Qt5Instance::Qt5Instance( SalYieldMutex* pMutex )
Qt5Instance::Qt5Instance( SalYieldMutex* pMutex, bool bUseCairo )
: SalGenericInstance( pMutex )
, m_postUserEventId( -1 )
, m_bUseCairo( bUseCairo )
{
m_postUserEventId = QEvent::registerEventType();
......@@ -61,13 +65,13 @@ Qt5Instance::~Qt5Instance()
SalFrame* Qt5Instance::CreateChildFrame( SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle )
{
return new Qt5Frame( nullptr, nStyle );
return new Qt5Frame( nullptr, nStyle, m_bUseCairo );
}
SalFrame* Qt5Instance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
{
assert( !pParent || dynamic_cast<Qt5Frame*>( pParent ) );
return new Qt5Frame( static_cast<Qt5Frame*>( pParent ), nStyle );
return new Qt5Frame( static_cast<Qt5Frame*>( pParent ), nStyle, m_bUseCairo );
}
void Qt5Instance::DestroyFrame( SalFrame* pFrame )
......@@ -91,9 +95,18 @@ SalVirtualDevice* Qt5Instance::CreateVirtualDevice( SalGraphics* /* pGraphics */
DeviceFormat eFormat,
const SystemGraphicsData* /* pData */ )
{
Qt5VirtualDevice* pVD = new Qt5VirtualDevice( eFormat, 1 );
pVD->SetSize( nDX, nDY );
return pVD;
if ( m_bUseCairo )
{
SvpSalVirtualDevice *pVD = new SvpSalVirtualDevice( eFormat, 1 );
pVD->SetSize( nDX, nDY );
return pVD;
}
else
{
Qt5VirtualDevice* pVD = new Qt5VirtualDevice( eFormat, 1 );
pVD->SetSize( nDX, nDY );
return pVD;
}
}
SalTimer* Qt5Instance::CreateSalTimer()
......@@ -108,7 +121,10 @@ SalSystem* Qt5Instance::CreateSalSystem()
SalBitmap* Qt5Instance::CreateSalBitmap()
{
return new Qt5Bitmap();
if ( m_bUseCairo )
return new SvpSalBitmap();
else
return new Qt5Bitmap();
}
bool Qt5Instance::ImplYield( bool bWait, bool bHandleAllCurrentEvents )
......@@ -198,7 +214,7 @@ extern "C" {
VCLPLUG_QT5_PUBLIC SalInstance* create_SalInstance()
{
OString aVersion( qVersion() );
SAL_INFO( "vcl.kf5", "qt version string is " << aVersion );
SAL_INFO( "vcl.qt5", "qt version string is " << aVersion );
QApplication *pQApplication;
char **pFakeArgvFreeable = nullptr;
......@@ -261,7 +277,8 @@ extern "C" {
QApplication::setQuitOnLastWindowClosed(false);
Qt5Instance* pInstance = new Qt5Instance( new SalYieldMutex() );
const bool bUseCairo = (nullptr != getenv( "SAL_VCL_QT5_USE_CAIRO" ));
Qt5Instance* pInstance = new Qt5Instance( new SalYieldMutex(), bUseCairo );
// initialize SalData
new Qt5Data( pInstance );
......
......@@ -39,6 +39,7 @@ class Qt5Instance
osl::Condition m_aWaitingYieldCond;
int m_postUserEventId;
const bool m_bUseCairo;
public:
std::unique_ptr< QApplication > m_pQApplication;
......@@ -53,7 +54,7 @@ Q_SIGNALS:
bool ImplYieldSignal( bool bWait, bool bHandleAllCurrentEvents );
public:
explicit Qt5Instance( SalYieldMutex* pMutex );
explicit Qt5Instance( SalYieldMutex* pMutex, bool bUseCairo = false );
virtual ~Qt5Instance() override;
virtual SalFrame* CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) override;
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "Qt5Tools.hxx"
#include <cairo.h>
void CairoDeleter::operator()(cairo_surface_t *pSurface) const
{
cairo_surface_destroy( pSurface );
}
......@@ -25,8 +25,11 @@
#include <QtGui/QImage>
#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
#include <tools/gen.hxx>
#include <memory>
inline OUString toOUString(const QString& s)
{
// QString stores UTF16, just like OUString
......@@ -55,6 +58,8 @@ inline Size toSize( const QSize& rSize )
return Size( rSize.width(), rSize.height() );
}
static constexpr QImage::Format Qt5_DefaultFormat32 = QImage::Format_ARGB32;
inline QImage::Format getBitFormat( sal_uInt16 nBitCount )
{
switch ( nBitCount )
......@@ -63,7 +68,7 @@ inline QImage::Format getBitFormat( sal_uInt16 nBitCount )
case 8 : return QImage::Format_Indexed8;
case 16 : return QImage::Format_RGB16;
case 24 : return QImage::Format_RGB888;
case 32 : return QImage::Format_ARGB32;
case 32 : return Qt5_DefaultFormat32;
default :
std::abort();
break;
......@@ -79,11 +84,19 @@ inline sal_uInt16 getFormatBits( QImage::Format eFormat )
case QImage::Format_Indexed8 : return 8;
case QImage::Format_RGB16 : return 16;
case QImage::Format_RGB888 : return 24;
case QImage::Format_ARGB32 : return 32;
case Qt5_DefaultFormat32 : return 32;
default :
std::abort();
return 0;
}
}
typedef struct _cairo_surface cairo_surface_t;
struct CairoDeleter
{
void operator()(cairo_surface_t *pSurface) const;
};
typedef std::unique_ptr<cairo_surface_t, CairoDeleter> UniqueCairoSurface;
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -20,6 +20,7 @@
#include "Qt5VirtualDevice.hxx"
#include "Qt5Graphics.hxx"
#include "Qt5Tools.hxx"
#include <QtGui/QImage>
......@@ -76,9 +77,9 @@ bool Qt5VirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
else
{
if ( pBuffer )
m_pImage.reset( new QImage( pBuffer, nNewDX, nNewDY, QImage::Format_ARGB32 ) );
m_pImage.reset( new QImage( pBuffer, nNewDX, nNewDY, Qt5_DefaultFormat32 ) );
else
m_pImage.reset( new QImage( nNewDX, nNewDY, QImage::Format_ARGB32 ) );
m_pImage.reset( new QImage( nNewDX, nNewDY, Qt5_DefaultFormat32 ) );
}
m_pImage->setDevicePixelRatio( m_fScale );
......
......@@ -22,11 +22,15 @@
#include "Qt5Frame.hxx"
#include "Qt5Graphics.hxx"
#include "Qt5Tools.hxx"
#include <QtGui/QImage>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <cairo.h>
#include <headless/svpgdi.hxx>
Qt5Widget::Qt5Widget( Qt5Frame &rFrame, QWidget *parent, Qt::WindowFlags f )
: QWidget( parent, f )
, m_pFrame( &rFrame )
......@@ -41,14 +45,40 @@ Qt5Widget::~Qt5Widget()
void Qt5Widget::paintEvent( QPaintEvent *pEvent )
{
QPainter p( this );
p.drawImage( pEvent->rect().topLeft(), *m_pFrame->m_pQImage, pEvent->rect() );
if( m_pFrame->m_bUseCairo )
{
cairo_surface_t *pSurface = m_pFrame->m_pSurface.get();
cairo_surface_flush( pSurface );
QImage aImage( cairo_image_surface_get_data( pSurface ),
size().width(), size().height(), Qt5_DefaultFormat32 );
p.drawImage( QPoint( 0, 0 ), aImage );
p.drawImage( pEvent->rect().topLeft(), aImage, pEvent->rect() );
}
else
p.drawImage( pEvent->rect().topLeft(),
*m_pFrame->m_pQImage, pEvent->rect() );
}
void Qt5Widget::resizeEvent( QResizeEvent* )
{
QImage *pImage = new QImage( m_pFrame->m_pQWidget->size(), QImage::Format_ARGB32 );
m_pFrame->m_pGraphics->ChangeQImage( pImage );
m_pFrame->m_pQImage.reset( pImage );
if( m_pFrame->m_bUseCairo )
{
int width = size().width();
int height = size().height();
cairo_surface_t *pSurface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height );
cairo_surface_set_user_data( pSurface, SvpSalGraphics::getDamageKey(),
&m_pFrame->m_aDamageHandler, nullptr );
m_pFrame->m_pSvpGraphics->setSurface( pSurface, basegfx::B2IVector(width, height) );
m_pFrame->m_pSurface.reset( pSurface );
}
else
{
QImage *pImage = new QImage( size(), Qt5_DefaultFormat32 );
m_pFrame->m_pQt5Graphics->ChangeQImage( pImage );
m_pFrame->m_pQImage.reset( pImage );
}
m_pFrame->CallCallback( SalEvent::Resize, nullptr );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment