[Libreoffice-commits] .: 2 commits - vcl/unx
Lubos Lunak
llunak at kemper.freedesktop.org
Tue Dec 14 10:01:12 PST 2010
vcl/unx/kde4/KDESalGraphics.cxx | 97 ++++++++++++++++++++++++++++------------
1 file changed, 69 insertions(+), 28 deletions(-)
New commits:
commit 06a5f348170691e9b3aa4ccf3c8c5d07889e3774
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Tue Dec 14 18:59:36 2010 +0100
simply use QRegion in Qt code instead of messing with Xlib
It's also optimizing for the common path (IMAGE_BASED_PAINTING).
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index d3cc804..bdfd0e2 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -305,7 +305,7 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
m_image->fill(KApplication::palette().color(QPalette::Window).rgb());
- XLIB_Region pTempClipRegion = 0;
+ QRegion* clipRegion = NULL;
if (type == CTRL_PUSHBUTTON)
{
@@ -532,28 +532,8 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
vclStateValue2StateFlag(nControlState, value) );
// draw just the border, see http://qa.openoffice.org/issues/show_bug.cgi?id=107945
- int nFrameWidth = getFrameWidth();
- pTempClipRegion = XCreateRegion();
- XRectangle xRect;
- xRect.x = widgetRect.left();
- xRect.y = widgetRect.top();
- xRect.width = widgetRect.width();
- xRect.height = widgetRect.height();
- XUnionRectWithRegion( &xRect, pTempClipRegion, pTempClipRegion );
- xRect.x += nFrameWidth;
- xRect.y += nFrameWidth;
-
- // do not crash for too small widgets, see http://qa.openoffice.org/issues/show_bug.cgi?id=112102
- if( xRect.width > 2*nFrameWidth && xRect.height > 2*nFrameWidth )
- {
- xRect.width -= 2*nFrameWidth;
- xRect.height -= 2*nFrameWidth;
-
- XLIB_Region pSubtract = XCreateRegion();
- XUnionRectWithRegion( &xRect, pSubtract, pSubtract );
- XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion );
- XDestroyRegion( pSubtract );
- }
+ int fw = getFrameWidth();
+ clipRegion = new QRegion( QRegion( widgetRect ).subtracted( widgetRect.adjusted( fw, fw, -fw, -fw )));
}
else if (type == CTRL_FIXEDBORDER)
{
@@ -603,11 +583,10 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
// See XRegionToQRegion() comment for a small catch (although not real hopefully).
QPixmap destPixmap = QPixmap::fromX11Pixmap( GetDrawable(), QPixmap::ExplicitlyShared );
QPainter paint( &destPixmap );
- if( pTempClipRegion && pClipRegion_ )
- paint.setClipRegion( XRegionToQRegion( pTempClipRegion )
- .intersected( XRegionToQRegion( pClipRegion_ )));
- else if( pTempClipRegion )
- paint.setClipRegion( XRegionToQRegion( pTempClipRegion ));
+ if( clipRegion && pClipRegion_ )
+ paint.setClipRegion( clipRegion->intersected( XRegionToQRegion( pClipRegion_ )));
+ else if( clipRegion )
+ paint.setClipRegion( *clipRegion );
else if( pClipRegion_ )
paint.setClipRegion( XRegionToQRegion( pClipRegion_ ));
paint.drawImage( widgetRect.left(), widgetRect.top(), *m_image,
@@ -615,11 +594,21 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither );
#else
GC gc = SelectFont();
-
if( gc )
{
- if( pTempClipRegion )
+ XLIB_Region pTempClipRegion = NULL;
+ if( clipRegion )
{
+ pTempClipRegion = XCreateRegion();
+ foreach( const QRect& r, clipRegion->rects())
+ {
+ XRectangle xr;
+ xr.x = r.x();
+ xr.y = r.y();
+ xr.width = r.width();
+ xr.height = r.height();
+ XUnionRectWithRegion( &xr, pTempClipRegion, pTempClipRegion );
+ }
if( pClipRegion_ )
XIntersectRegion( pTempClipRegion, pClipRegion_, pTempClipRegion );
XSetRegion( GetXDisplay(), gc, pTempClipRegion );
@@ -636,15 +625,14 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
XSetRegion( GetXDisplay(), gc, pClipRegion_ );
else
XSetClipMask( GetXDisplay(), gc, None );
+ XDestroyRegion( pTempClipRegion );
}
}
else
returnVal = false;
#endif
}
- if( pTempClipRegion )
- XDestroyRegion( pTempClipRegion );
-
+ delete clipRegion;
return returnVal;
}
commit bf4b61c7b7f2ca1d9641ab0cf5f88a68bc3930d0
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Tue Dec 14 18:45:15 2010 +0100
do not use QPixmap::handle(), as it may be 0
See comments in code for details. The usage of Xlib's Region type
internals is not nice, but seems to be ok in practice.
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 26b65b7..d3cc804 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -233,6 +233,39 @@ namespace
}
}
+#if QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 )
+#define IMAGE_BASED_PAINTING
+#else
+#undef IMAGE_BASED_PAINTING
+#endif
+
+#ifdef IMAGE_BASED_PAINTING
+// There is a small catch with this function, although hopefully only philosophical.
+// Officially Xlib's Region is an opaque data type, with only functions for manipulating it.
+// However, whoever designed it apparently didn't give it that much thought, as it's impossible
+// to find out what exactly a region actually is (except for really weird ways like XClipBox()
+// and repeated XPointInRegion(), which would be awfully slow). Fortunately, the header file
+// describing the structure actually happens to be installed too, and there's at least one
+// widely used software using it (Compiz). So access the data directly too and assume that
+// everybody who compiles with Qt4 support has Xlib new enough and good enough to support this.
+// In case this doesn't work for somebody, try #include <X11/region.h> instead, or build
+// without IMAGE_BASED_PAINTING (in which case QApplication::setGraphicsSystem( "native" ) may
+// be needed too).
+#include <X11/Xregion.h>
+static QRegion XRegionToQRegion( XLIB_Region xr )
+{
+ QRegion qr;
+ for( int i = 0;
+ i < xr->numRects;
+ ++i )
+ {
+ BOX& b = xr->rects[ i ];
+ qr |= QRect( b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1 ); // x2,y2 is outside, not the bottom-right corner
+ }
+ return qr;
+}
+#endif
+
BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
const Rectangle& rControlRegion, ControlState nControlState,
const ImplControlValue& value,
@@ -562,6 +595,25 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
if (returnVal)
{
+#ifdef IMAGE_BASED_PAINTING
+ // Create a wrapper QPixmap around the destination pixmap, allowing the use of QPainter.
+ // Using X11SalGraphics::CopyScreenArea() would require using QPixmap and if Qt uses
+ // other graphics system than native, QPixmap::handle() would be 0 (i.e. it wouldn't work),
+ // I have no idea how to create QPixmap with non-null handle() in such case, so go this way.
+ // See XRegionToQRegion() comment for a small catch (although not real hopefully).
+ QPixmap destPixmap = QPixmap::fromX11Pixmap( GetDrawable(), QPixmap::ExplicitlyShared );
+ QPainter paint( &destPixmap );
+ if( pTempClipRegion && pClipRegion_ )
+ paint.setClipRegion( XRegionToQRegion( pTempClipRegion )
+ .intersected( XRegionToQRegion( pClipRegion_ )));
+ else if( pTempClipRegion )
+ paint.setClipRegion( XRegionToQRegion( pTempClipRegion ));
+ else if( pClipRegion_ )
+ paint.setClipRegion( XRegionToQRegion( pClipRegion_ ));
+ paint.drawImage( widgetRect.left(), widgetRect.top(), *m_image,
+ 0, 0, widgetRect.width(), widgetRect.height(),
+ Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither );
+#else
GC gc = SelectFont();
if( gc )
@@ -588,6 +640,7 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
}
else
returnVal = false;
+#endif
}
if( pTempClipRegion )
XDestroyRegion( pTempClipRegion );
More information about the Libreoffice-commits
mailing list