summaryrefslogtreecommitdiff
path: root/vcl/unx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/unx')
-rw-r--r--vcl/unx/gtk/a11y/atktext.cxx12
-rw-r--r--vcl/unx/gtk/a11y/atkutil.cxx13
-rw-r--r--vcl/unx/gtk/window/gtkframe.cxx21
-rw-r--r--vcl/unx/headless/svppspgraphics.cxx22
-rw-r--r--vcl/unx/inc/kde_headers.h97
-rw-r--r--vcl/unx/inc/plugins/gtk/gtkframe.hxx7
-rw-r--r--vcl/unx/inc/plugins/kde/kdedata.hxx2
-rw-r--r--vcl/unx/inc/salframe.h4
-rw-r--r--vcl/unx/inc/salunx.h6
-rw-r--r--vcl/unx/inc/sm.hxx2
-rw-r--r--vcl/unx/kde/kdedata.cxx2
-rw-r--r--vcl/unx/kde/salnativewidgets-kde.cxx7
-rw-r--r--vcl/unx/kde4/KDESalFrame.cxx33
-rw-r--r--vcl/unx/kde4/KDESalFrame.hxx2
-rw-r--r--vcl/unx/kde4/KDESalGraphics.cxx2
-rw-r--r--vcl/unx/kde4/KDEXLib.cxx13
-rw-r--r--vcl/unx/source/app/i18n_ic.cxx4
-rw-r--r--vcl/unx/source/app/i18n_im.cxx2
-rw-r--r--vcl/unx/source/app/randrwrapper.cxx8
-rw-r--r--vcl/unx/source/app/saldisp.cxx7
-rw-r--r--vcl/unx/source/app/salinst.cxx4
-rw-r--r--vcl/unx/source/app/saltimer.cxx3
-rw-r--r--vcl/unx/source/app/sm.cxx13
-rw-r--r--vcl/unx/source/dtrans/X11_selection.cxx40
-rw-r--r--vcl/unx/source/gdi/pspgraphics.cxx22
-rw-r--r--vcl/unx/source/gdi/salgdi.cxx434
-rw-r--r--vcl/unx/source/gdi/xrender_peer.cxx4
-rw-r--r--vcl/unx/source/gdi/xrender_peer.hxx14
-rw-r--r--vcl/unx/source/plugadapt/salplug.cxx58
-rw-r--r--vcl/unx/source/printer/printerinfomanager.cxx2
-rw-r--r--vcl/unx/source/printergfx/common_gfx.cxx66
-rw-r--r--vcl/unx/source/printergfx/glyphset.cxx38
-rw-r--r--vcl/unx/source/window/salframe.cxx10
33 files changed, 660 insertions, 314 deletions
diff --git a/vcl/unx/gtk/a11y/atktext.cxx b/vcl/unx/gtk/a11y/atktext.cxx
index 8d83ca008e4a..0a97e5ba1ca6 100644
--- a/vcl/unx/gtk/a11y/atktext.cxx
+++ b/vcl/unx/gtk/a11y/atktext.cxx
@@ -187,8 +187,16 @@ static accessibility::XAccessibleTextMarkup*
if( !pWrap->mpTextMarkup && pWrap->mpContext )
{
uno::Any any = pWrap->mpContext->queryInterface( accessibility::XAccessibleTextMarkup::static_type(NULL) );
- pWrap->mpTextMarkup = reinterpret_cast< accessibility::XAccessibleTextMarkup * > (any.pReserved);
- pWrap->mpTextMarkup->acquire();
+ /* Since this not a dedicated interface in Atk and thus has not
+ * been queried during wrapper initialization, we need to check
+ * the return value here.
+ */
+ if( typelib_TypeClass_INTERFACE == any.pType->eTypeClass )
+ {
+ pWrap->mpTextMarkup = reinterpret_cast< accessibility::XAccessibleTextMarkup * > (any.pReserved);
+ if( pWrap->mpTextMarkup )
+ pWrap->mpTextMarkup->acquire();
+ }
}
return pWrap->mpTextMarkup;
diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx
index 5206c8ce87ca..c92a69d3fb49 100644
--- a/vcl/unx/gtk/a11y/atkutil.cxx
+++ b/vcl/unx/gtk/a11y/atkutil.cxx
@@ -221,7 +221,7 @@ void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObj
if( accessibility::AccessibleStateType::FOCUSED == nState )
atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) );
}
- catch(lang::IndexOutOfBoundsException e)
+ catch(const lang::IndexOutOfBoundsException &e)
{
g_warning("Focused object has invalid index in parent");
}
@@ -577,7 +577,14 @@ static void handle_get_focus(::VclWindowEvent const * pEvent)
if( g_aWindowList.find(pWindow) == g_aWindowList.end() )
{
g_aWindowList.insert(pWindow);
- aDocumentFocusListener->attachRecursive(xAccessible, xContext, xStateSet);
+ try
+ {
+ aDocumentFocusListener->attachRecursive(xAccessible, xContext, xStateSet);
+ }
+ catch( const uno::Exception &e )
+ {
+ g_warning( "Exception caught processing focus events" );
+ }
}
#ifdef ENABLE_TRACING
else
@@ -608,7 +615,7 @@ static void handle_menu_highlighted(::VclMenuEvent const * pEvent)
}
}
}
- catch( uno::Exception e )
+ catch( const uno::Exception& e )
{
g_warning( "Exception caught processing menu highlight events" );
}
diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx
index eff7319d6efc..92ff2d3b8d8e 100644
--- a/vcl/unx/gtk/window/gtkframe.cxx
+++ b/vcl/unx/gtk/window/gtkframe.cxx
@@ -772,7 +772,10 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle )
m_aForeignTopLevelWindow = None;
m_nStyle = nStyle;
- GtkWindowType eWinType = ((nStyle & SAL_FRAME_STYLE_FLOAT) && ! (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION))
+ GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) &&
+ ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|
+ SAL_FRAME_STYLE_FLOAT_FOCUSABLE))
+ )
? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL;
if( nStyle & SAL_FRAME_STYLE_SYSTEMCHILD )
@@ -801,7 +804,7 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle )
bool bDecoHandling =
! isChild() &&
( ! (nStyle & SAL_FRAME_STYLE_FLOAT) ||
- (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) );
+ (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) );
/* #i100116# metacity has a peculiar behavior regarding WM_HINT accept focus and _NET_WM_USER_TIME
at some point that may be fixed in metacity and we will have to revisit this
@@ -832,6 +835,11 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle )
lcl_set_accept_focus( GTK_WINDOW(m_pWindow), FALSE, true );
bNoDecor = true;
}
+ else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) )
+ {
+ eType = GDK_WINDOW_TYPE_HINT_UTILITY;
+ }
+
if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) )
{
eType = GDK_WINDOW_TYPE_HINT_TOOLBAR;
@@ -869,7 +877,7 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle )
if( bDecoHandling )
{
gtk_window_set_resizable( GTK_WINDOW(m_pWindow), (nStyle & SAL_FRAME_STYLE_SIZEABLE) ? TRUE : FALSE );
- if( ( (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) || bMetaCityToolWindowHack )
+ if( ( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ) || bMetaCityToolWindowHack )
lcl_set_accept_focus( GTK_WINDOW(m_pWindow), FALSE, false );
}
@@ -2075,7 +2083,7 @@ void GtkSalFrame::ToTop( USHORT nFlags )
* to our window - which it of course won't since our input hint
* is set to false.
*/
- if( (m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
+ if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) )
XSetInputFocus( getDisplay()->GetDisplay(), GDK_WINDOW_XWINDOW( m_pWindow->window ), RevertToParent, CurrentTime );
}
else
@@ -2369,6 +2377,11 @@ void GtkSalFrame::createNewWindow( XLIB_Window aNewParent, bool bXEmbed, int nSc
}
}
+ // free xrender resources
+ for( unsigned int i = 0; i < sizeof(m_aGraphics)/sizeof(m_aGraphics[0]); i++ )
+ if( m_aGraphics[i].bInUse )
+ m_aGraphics[i].pGraphics->SetDrawable( None, m_nScreen );
+
// first deinit frame
if( m_pIMHandler )
{
diff --git a/vcl/unx/headless/svppspgraphics.cxx b/vcl/unx/headless/svppspgraphics.cxx
index 3e9d67bcbbe9..1311aaed4ee4 100644
--- a/vcl/unx/headless/svppspgraphics.cxx
+++ b/vcl/unx/headless/svppspgraphics.cxx
@@ -986,13 +986,6 @@ const void* PspGraphics::DoGetEmbedFontData( fontID aFont, const sal_Ucs* pUnico
return NULL;
// fill in font info
- switch( aFontInfo.m_eType )
- {
- case psp::fonttype::TrueType: rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF; break;
- case psp::fonttype::Type1: rInfo.m_nFontType = FontSubsetInfo::ANY_TYPE1; break;
- default:
- return NULL;
- }
rInfo.m_nAscent = aFontInfo.m_nAscend;
rInfo.m_nDescent = aFontInfo.m_nDescend;
rInfo.m_aPSName = rMgr.getPSName( aFont );
@@ -1029,9 +1022,22 @@ const void* PspGraphics::DoGetEmbedFontData( fontID aFont, const sal_Ucs* pUnico
rInfo.m_nCapHeight = yMax; // Well ...
for( int i = 0; i < 256; i++ )
-
pWidths[i] = (aMetrics[i].width > 0 ? aMetrics[i].width : 0);
+ switch( aFontInfo.m_eType )
+ {
+ case psp::fonttype::TrueType:
+ rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF;
+ break;
+ case psp::fonttype::Type1: {
+ const bool bPFA = ((*(unsigned char*)pFile) < 0x80);
+ rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB;
+ }
+ break;
+ default:
+ return NULL;
+ }
+
return pFile;
}
diff --git a/vcl/unx/inc/kde_headers.h b/vcl/unx/inc/kde_headers.h
deleted file mode 100644
index ccbffc99cb99..000000000000
--- a/vcl/unx/inc/kde_headers.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: kde_headers.h,v $
- * $Revision: 1.6 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef INCLUDED_VCL_KDE_HEADERS_H
-#define INCLUDED_VCL_KDE_HEADERS_H
-
-/* ********* Suppress warnings if needed */
-#include "sal/config.h"
-
-#if defined __GNUC__
-#pragma GCC system_header
-#endif
-
-
-/* ********* Hack, but needed because of conflicting types... */
-#define Region QtXRegion
-
-
-/* ********* Qt headers */
-#include <qaccessible.h>
-#include <qcheckbox.h>
-#include <qcombobox.h>
-#include <qfont.h>
-#include <qframe.h>
-#include <qlineedit.h>
-#include <qlistview.h>
-#include <qmainwindow.h>
-#include <qmenudata.h>
-#include <qpaintdevice.h>
-#include <qpainter.h>
-#include <qpushbutton.h>
-#include <qradiobutton.h>
-#include <qrangecontrol.h>
-#include <qstring.h>
-#include <qtabbar.h>
-#include <qtabwidget.h>
-#include <qtoolbar.h>
-#include <qtoolbutton.h>
-#include <qwidget.h>
-#include <qprogressbar.h>
-
-/* ********* See hack on top of this file */
-#undef Region
-
-
-/* ********* KDE base headers */
-#include <kaboutdata.h>
-#include <kapplication.h>
-#include <kcmdlineargs.h>
-#include <kconfig.h>
-#include <kdeversion.h>
-#include <kemailsettings.h>
-#include <kglobal.h>
-#include <kglobalsettings.h>
-#include <klocale.h>
-#include <kmainwindow.h>
-#include <kmenubar.h>
-#include <kprotocolmanager.h>
-#include <kstartupinfo.h>
-#include <kstyle.h>
-
-
-/* ********* KDE address book connectivity headers */
-#include <kabc/addressbook.h>
-#include <kabc/addressee.h>
-#include <kabc/field.h>
-#include <kabc/stdaddressbook.h>
-
-
-#endif
diff --git a/vcl/unx/inc/plugins/gtk/gtkframe.hxx b/vcl/unx/inc/plugins/gtk/gtkframe.hxx
index a8fc6f65d4ee..c2a147517ac8 100644
--- a/vcl/unx/inc/plugins/gtk/gtkframe.hxx
+++ b/vcl/unx/inc/plugins/gtk/gtkframe.hxx
@@ -242,9 +242,10 @@ class GtkSalFrame : public SalFrame
bool isFloatGrabWindow() const
{
return
- (m_nStyle & SAL_FRAME_STYLE_FLOAT) && // only a float can be floatgrab
- !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) && // tool tips are not
- !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION); // toolbars are also not
+ (m_nStyle & SAL_FRAME_STYLE_FLOAT) && // only a float can be floatgrab
+ !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) && // tool tips are not
+ !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && // toolbars are also not
+ !(m_nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE); // focusable floats are not
}
bool isChild( bool bPlug = true, bool bSysChild = true )
diff --git a/vcl/unx/inc/plugins/kde/kdedata.hxx b/vcl/unx/inc/plugins/kde/kdedata.hxx
index 831621e38cc1..04730b39fad2 100644
--- a/vcl/unx/inc/plugins/kde/kdedata.hxx
+++ b/vcl/unx/inc/plugins/kde/kdedata.hxx
@@ -75,7 +75,7 @@ public:
virtual SalGraphics* GetGraphics();
virtual void ReleaseGraphics( SalGraphics *pGraphics );
- virtual void updateGraphics();
+ virtual void updateGraphics( bool bClear );
virtual void UpdateSettings( AllSettings& rSettings );
virtual void Show( BOOL bVisible, BOOL bNoActivate );
};
diff --git a/vcl/unx/inc/salframe.h b/vcl/unx/inc/salframe.h
index 848f2250d31c..8dad0350a937 100644
--- a/vcl/unx/inc/salframe.h
+++ b/vcl/unx/inc/salframe.h
@@ -212,7 +212,9 @@ public:
virtual SalGraphics* GetGraphics();
virtual void ReleaseGraphics( SalGraphics* pGraphics );
- virtual void updateGraphics();
+ // call with true to clear graphics (setting None as drawable)
+ // call with false to setup graphics with window (GetWindow())
+ virtual void updateGraphics( bool bClear );
virtual BOOL PostEvent( void* pData );
diff --git a/vcl/unx/inc/salunx.h b/vcl/unx/inc/salunx.h
index cdf45fd30867..c1fee6c68d94 100644
--- a/vcl/unx/inc/salunx.h
+++ b/vcl/unx/inc/salunx.h
@@ -38,12 +38,6 @@
#include <time.h>
#include <sys/time.h>
#include <strings.h>
-#elif defined IRIX
-#ifdef __cplusplus
-#include <ctime>
-#endif
-#include <sys/time.h>
-#include <unistd.h>
#endif
#include <svunx.h>
#include <salstd.hxx>
diff --git a/vcl/unx/inc/sm.hxx b/vcl/unx/inc/sm.hxx
index 17bb40e2106a..09d2f5557e1d 100644
--- a/vcl/unx/inc/sm.hxx
+++ b/vcl/unx/inc/sm.hxx
@@ -69,7 +69,7 @@ public:
static bool checkDocumentsSaved();
static bool queryInteraction();
static void saveDone();
- static void interactionDone();
+ static void interactionDone( bool bCancelShutdown );
static String getExecName();
static VCL_DLLPUBLIC const ByteString& getSessionID();
diff --git a/vcl/unx/kde/kdedata.cxx b/vcl/unx/kde/kdedata.cxx
index 1b5a2f86dcee..9da57b6e790d 100644
--- a/vcl/unx/kde/kdedata.cxx
+++ b/vcl/unx/kde/kdedata.cxx
@@ -29,7 +29,7 @@
#include "precompiled_vcl.hxx"
#define _SV_SALDATA_CXX
-#include "kde_headers.h"
+#include <shell/kde_headers.h>
#include <unistd.h>
#include <fcntl.h>
diff --git a/vcl/unx/kde/salnativewidgets-kde.cxx b/vcl/unx/kde/salnativewidgets-kde.cxx
index 8046d22d75d3..cd461fc36c8f 100644
--- a/vcl/unx/kde/salnativewidgets-kde.cxx
+++ b/vcl/unx/kde/salnativewidgets-kde.cxx
@@ -32,7 +32,7 @@
#include "precompiled_vcl.hxx"
#define _SV_SALNATIVEWIDGETS_KDE_CXX
-#include "kde_headers.h"
+#include <shell/kde_headers.h>
#include <salunx.h>
#include <saldata.hxx>
@@ -2073,12 +2073,13 @@ void KDESalFrame::ReleaseGraphics( SalGraphics *pGraphics )
}
}
-void KDESalFrame::updateGraphics()
+void KDESalFrame::updateGraphics( bool bClear )
{
+ Drawable aDrawable = bClear ? None : GetWindow();
for( int i = 0; i < nMaxGraphics; i++ )
{
if( m_aGraphics[i].bInUse )
- m_aGraphics[i].pGraphics->SetDrawable( GetWindow(), GetScreenNumber() );
+ m_aGraphics[i].pGraphics->SetDrawable( aDrawable, GetScreenNumber() );
}
}
diff --git a/vcl/unx/kde4/KDESalFrame.cxx b/vcl/unx/kde4/KDESalFrame.cxx
index 796350a63d50..6177c4b2896a 100644
--- a/vcl/unx/kde4/KDESalFrame.cxx
+++ b/vcl/unx/kde4/KDESalFrame.cxx
@@ -181,7 +181,6 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
StyleSettings style( rSettings.GetStyleSettings() );
BOOL bSetTitleFont = false;
-
// General settings
QPalette pal = kapp->palette();
@@ -214,6 +213,14 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
pKey = "Theme";
if ( aGroup.hasKey( pKey ) )
style.SetPreferredSymbolsStyleName( readEntryUntranslated( &aGroup, pKey ) );
+
+ //toolbar
+ pKey = "toolbarFont";
+ if ( aGroup.hasKey( pKey ) )
+ {
+ Font aFont = toFont( aGroup.readEntry( pKey, QFont() ), rSettings.GetUILocale() );
+ style.SetToolFont( aFont );
+ }
}
Color aFore = toColor( pal.color( QPalette::Active, QPalette::WindowText ) );
@@ -288,7 +295,7 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
style.SetFloatTitleFont( aFont );
style.SetMenuFont( aFont ); // will be changed according to pMenuBar
- style.SetToolFont( aFont ); // will be changed according to pToolBar
+ //style.SetToolFont( aFont ); //already set above
style.SetLabelFont( aFont );
style.SetInfoFont( aFont );
style.SetRadioCheckFont( aFont );
@@ -300,11 +307,9 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
int flash_time = QApplication::cursorFlashTime();
style.SetCursorBlinkTime( flash_time != 0 ? flash_time/2 : STYLE_CURSOR_NOBLINKTIME );
- KMainWindow qMainWindow;
-
// Menu
style.SetSkipDisabledInMenus( TRUE );
- KMenuBar *pMenuBar = qMainWindow.menuBar();
+ KMenuBar* pMenuBar = new KMenuBar();
if ( pMenuBar )
{
// Color
@@ -337,22 +342,11 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
style.SetMenuFont( aFont );
}
- // Tool bar
- KToolBar *pToolBar = qMainWindow.toolBar();
- if ( pToolBar )
- {
- aFont = toFont( pToolBar->font(), rSettings.GetUILocale() );
- style.SetToolFont( aFont );
- }
+ delete pMenuBar;
// Scroll bar size
style.SetScrollBarSize( kapp->style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
- // #i59364# high contrast mode
- BOOL bHC = ( style.GetFaceColor().IsDark() ||
- style.GetWindowColor().IsDark() );
- style.SetHighContrastMode( bHC );
-
rSettings.SetStyleSettings( style );
}
@@ -369,12 +363,13 @@ void KDESalFrame::ReleaseGraphics( SalGraphics *pGraphics )
}
}
-void KDESalFrame::updateGraphics()
+void KDESalFrame::updateGraphics( bool bClear )
{
+ Drawable aDrawable = bClear ? None : GetWindow();
for( int i = 0; i < nMaxGraphics; i++ )
{
if( m_aGraphics[i].bInUse )
- m_aGraphics[i].pGraphics->SetDrawable( GetWindow(), GetScreenNumber() );
+ m_aGraphics[i].pGraphics->SetDrawable( aDrawable, GetScreenNumber() );
}
}
diff --git a/vcl/unx/kde4/KDESalFrame.hxx b/vcl/unx/kde4/KDESalFrame.hxx
index 11a22bd93ba5..de3a5af189ee 100644
--- a/vcl/unx/kde4/KDESalFrame.hxx
+++ b/vcl/unx/kde4/KDESalFrame.hxx
@@ -52,7 +52,7 @@ class KDESalFrame : public X11SalFrame
virtual SalGraphics* GetGraphics();
virtual void ReleaseGraphics( SalGraphics *pGraphics );
- virtual void updateGraphics();
+ virtual void updateGraphics( bool bClear );
virtual void UpdateSettings( AllSettings& rSettings );
virtual void Show( BOOL bVisible, BOOL bNoActivate );
}; \ No newline at end of file
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 2e8f0dcad96b..1c9882923b43 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -513,10 +513,12 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
}
else if (type == CTRL_FRAME)
{
+ pixmap.fill(KApplication::palette().color(QPalette::Window));
lcl_drawFrame( widgetRect, painter, QStyle::PE_Frame, nControlState, value );
}
else if (type == CTRL_FIXEDBORDER)
{
+ pixmap.fill(KApplication::palette().color(QPalette::Window));
lcl_drawFrame( widgetRect, painter, QStyle::PE_FrameWindow, nControlState, value );
}
else if (type == CTRL_WINDOW_BACKGROUND)
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 70b1796df7f0..dedda64d157e 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -77,24 +77,30 @@ void KDEXLib::Init()
pInputMethod->SetLocale();
XrmInitialize();
- KAboutData *kAboutData = new KAboutData( "OpenOffice.org",
- "OpenOffice.org",
+ KAboutData *kAboutData = new KAboutData("OpenOffice.org",
+ "kdelibs4",
ki18n( "OpenOffice.org" ),
"3.0.0",
ki18n( "OpenOffice.org with KDE Native Widget Support." ),
KAboutData::License_LGPL,
- ki18n( "Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 Novell, Inc"),
+ ki18n( "Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Novell, Inc"),
ki18n( "OpenOffice.org is an office suite.\n" ),
"http://kde.openoffice.org/index.html",
"dev@kde.openoffice.org" );
+
kAboutData->addAuthor( ki18n( "Jan Holesovsky" ),
ki18n( "Original author and maintainer of the KDE NWF." ),
"kendy@artax.karlin.mff.cuni.cz",
"http://artax.karlin.mff.cuni.cz/~kendy" );
+ kAboutData->addAuthor( ki18n("Roman Shtylman"),
+ ki18n( "Porting to KDE 4." ),
+ "shtylman@gmail.com", "http://shtylman.com" );
kAboutData->addAuthor( ki18n("Eric Bischoff"),
ki18n( "Accessibility fixes, porting to KDE 4." ),
"bischoff@kde.org" );
+ //kAboutData->setProgramIconName("OpenOffice");
+
m_nFakeCmdLineArgs = 1;
USHORT nIdx;
vos::OExtCommandLine aCommandLine;
@@ -135,6 +141,7 @@ void KDEXLib::Init()
m_pApplication = new VCLKDEApplication();
kapp->disableSessionManagement();
+ KApplication::setQuitOnLastWindowClosed(false);
Display* pDisp = QX11Info::display();
SalKDEDisplay *pSalDisplay = new SalKDEDisplay(pDisp);
diff --git a/vcl/unx/source/app/i18n_ic.cxx b/vcl/unx/source/app/i18n_ic.cxx
index cacffbcfdbb1..bb8f86d93e01 100644
--- a/vcl/unx/source/app/i18n_ic.cxx
+++ b/vcl/unx/source/app/i18n_ic.cxx
@@ -340,7 +340,7 @@ SalI18N_InputContext::SalI18N_InputContext ( SalFrame *pFrame ) :
if ( mnPreeditStyle != XIMPreeditNone )
{
-#if defined LINUX || defined FREEBSD || defined NETBSD || defined IRIX
+#if defined LINUX || defined FREEBSD || defined NETBSD
if ( mpPreeditAttributes != NULL )
#endif
mpAttributes = XVaAddToNestedList( mpAttributes,
@@ -348,7 +348,7 @@ SalI18N_InputContext::SalI18N_InputContext ( SalFrame *pFrame ) :
}
if ( mnStatusStyle != XIMStatusNone )
{
-#if defined LINUX || defined FREEBSD || defined NETBSD || defined IRIX
+#if defined LINUX || defined FREEBSD || defined NETBSD
if ( mpStatusAttributes != NULL )
#endif
mpAttributes = XVaAddToNestedList( mpAttributes,
diff --git a/vcl/unx/source/app/i18n_im.cxx b/vcl/unx/source/app/i18n_im.cxx
index ae472d6323f4..0a48c054167f 100644
--- a/vcl/unx/source/app/i18n_im.cxx
+++ b/vcl/unx/source/app/i18n_im.cxx
@@ -59,7 +59,7 @@
using namespace vcl;
#include "i18n_cb.hxx"
-#if defined(SOLARIS) || defined(LINUX) || defined(IRIX)
+#if defined(SOLARIS) || defined(LINUX)
extern "C" char * XSetIMValues(XIM im, ...);
#endif
diff --git a/vcl/unx/source/app/randrwrapper.cxx b/vcl/unx/source/app/randrwrapper.cxx
index 8d01b64d4680..4fbe5db97ab9 100644
--- a/vcl/unx/source/app/randrwrapper.cxx
+++ b/vcl/unx/source/app/randrwrapper.cxx
@@ -161,7 +161,13 @@ RandRWrapper::RandRWrapper( Display* pDisplay ) :
if( ! m_bValid )
{
rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrandr.so.2" ) );
- m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT );
+ // load and resolve dependencies immediately
+ // rationale: there are older distributions where libXrandr.so.2 is not linked
+ // with libXext.so, resulting in a missing symbol and terminating the office
+ // obviously they expected libXext to be linked in global symbolspace (that is
+ // linked by the application), which is not the case with us (because we want
+ // to be able to run in headless mode even without an installed X11 library)
+ m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT | SAL_LOADMODULE_NOW );
initFromModule();
}
if( m_bValid )
diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx
index 07955d426b8c..cfd568ac9b6c 100644
--- a/vcl/unx/source/app/saldisp.cxx
+++ b/vcl/unx/source/app/saldisp.cxx
@@ -38,16 +38,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
-#if defined(IRIX)
-#include <ctime>
-#endif
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
-#if defined(SOLARIS) || defined(IRIX)
+#if defined(SOLARIS)
#include <sal/alloca.h>
#include <osl/module.h>
#endif
@@ -898,7 +895,7 @@ void SalDisplay::Init()
sscanf( pProperties, "%li", &nProperties_ );
else
{
-#if defined DBG_UTIL || defined SUN || defined LINUX || defined FREEBSD || defined IRIX
+#if defined DBG_UTIL || defined SUN || defined LINUX || defined FREEBSD
nProperties_ |= PROPERTY_FEATURE_Maximize;
#endif
// Server Bugs & Properties
diff --git a/vcl/unx/source/app/salinst.cxx b/vcl/unx/source/app/salinst.cxx
index 1dc2d1404009..6b7753960290 100644
--- a/vcl/unx/source/app/salinst.cxx
+++ b/vcl/unx/source/app/salinst.cxx
@@ -50,7 +50,7 @@
#include "vcl/salwtype.hxx"
#include "vcl/salatype.hxx"
#include "vcl/helper.hxx"
-
+#include <tools/solarmutex.hxx>
#include "vos/mutex.hxx"
// -------------------------------------------------------------------------
@@ -63,6 +63,7 @@ SalYieldMutex::SalYieldMutex()
{
mnCount = 0;
mnThreadId = 0;
+ ::tools::SolarMutex::SetSolarMutex( this );
}
void SalYieldMutex::acquire()
@@ -141,6 +142,7 @@ X11SalInstance::~X11SalInstance()
delete pSalData;
SetSalData( NULL );
+ ::tools::SolarMutex::SetSolarMutex( 0 );
delete mpSalYieldMutex;
}
diff --git a/vcl/unx/source/app/saltimer.cxx b/vcl/unx/source/app/saltimer.cxx
index bf8aa202b066..afcecc0d0667 100644
--- a/vcl/unx/source/app/saltimer.cxx
+++ b/vcl/unx/source/app/saltimer.cxx
@@ -32,9 +32,6 @@
#include "precompiled_vcl.hxx"
#include <stdio.h>
-#if defined(IRIX)
-#include <ctime>
-#endif
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
diff --git a/vcl/unx/source/app/sm.cxx b/vcl/unx/source/app/sm.cxx
index ff981b04259b..c5605cec1dfb 100644
--- a/vcl/unx/source/app/sm.cxx
+++ b/vcl/unx/source/app/sm.cxx
@@ -114,7 +114,7 @@ void IceSalSession::queryInteraction()
void IceSalSession::interactionDone()
{
- SessionManagerClient::interactionDone();
+ SessionManagerClient::interactionDone( false );
}
void IceSalSession::saveDone()
@@ -129,6 +129,7 @@ void IceSalSession::saveDone()
bool IceSalSession::cancelShutdown()
{
+ SessionManagerClient::interactionDone( true );
return false;
}
@@ -368,6 +369,12 @@ void SessionManagerClient::SaveYourselfProc(
IMPL_STATIC_LINK_NOINSTANCE( SessionManagerClient, ShutDownHdl, void*, EMPTYARG )
{
+ if( pOneInstance )
+ {
+ SalSessionQuitEvent aEvent;
+ pOneInstance->CallCallback( &aEvent );
+ }
+
const std::list< SalFrame* >& rFrames = GetX11SalData()->GetDisplay()->getFrames();
SMprintf( rFrames.begin() != rFrames.end() ? "shutdown on first frame\n" : "shutdown event but no frame\n" );
if( rFrames.begin() != rFrames.end() )
@@ -526,12 +533,12 @@ bool SessionManagerClient::queryInteraction()
return bRet;
}
-void SessionManagerClient::interactionDone()
+void SessionManagerClient::interactionDone( bool bCancelShutdown )
{
if( aSmcConnection )
{
ICEConnectionObserver::lock();
- SmcInteractDone( aSmcConnection, False );
+ SmcInteractDone( aSmcConnection, bCancelShutdown ? True : False );
ICEConnectionObserver::unlock();
}
}
diff --git a/vcl/unx/source/dtrans/X11_selection.cxx b/vcl/unx/source/dtrans/X11_selection.cxx
index 3f7dfc2df709..c6036ae4f78e 100644
--- a/vcl/unx/source/dtrans/X11_selection.cxx
+++ b/vcl/unx/source/dtrans/X11_selection.cxx
@@ -219,28 +219,64 @@ SelectionManager::SelectionManager() :
m_aWindow( None ),
m_nSelectionTimeout( 0 ),
m_nSelectionTimestamp( CurrentTime ),
+ m_bDropEnterSent( true ),
m_aCurrentDropWindow( None ),
+ m_nDropTime( None ),
+ m_nLastDropAction( 0 ),
+ m_nLastX( 0 ),
+ m_nLastY( 0 ),
+ m_nDropTimestamp( 0 ),
m_bDropWaitingForCompletion( false ),
m_aDropWindow( None ),
m_aDropProxy( None ),
m_aDragSourceWindow( None ),
+ m_nLastDragX( 0 ),
+ m_nLastDragY( 0 ),
m_nNoPosX( 0 ),
m_nNoPosY( 0 ),
m_nNoPosWidth( 0 ),
m_nNoPosHeight( 0 ),
+ m_nDragButton( 0 ),
+ m_nUserDragAction( 0 ),
+ m_nTargetAcceptAction( 0 ),
+ m_nSourceActions( 0 ),
m_bLastDropAccepted( false ),
m_bDropSuccess( false ),
m_bDropSent( false ),
m_bWaitingForPrimaryConversion( false ),
+ m_nDragTimestamp( None ),
m_aMoveCursor( None ),
m_aCopyCursor( None ),
m_aLinkCursor( None ),
m_aNoneCursor( None ),
m_aCurrentCursor( None ),
- m_nCurrentProtocolVersion( nXdndProtocolRevision )
+ m_nCurrentProtocolVersion( nXdndProtocolRevision ),
+ m_nCLIPBOARDAtom( None ),
+ m_nTARGETSAtom( None ),
+ m_nTIMESTAMPAtom( None ),
+ m_nTEXTAtom( None ),
+ m_nINCRAtom( None ),
+ m_nCOMPOUNDAtom( None ),
+ m_nMULTIPLEAtom( None ),
+ m_nUTF16Atom( None ),
+ m_nImageBmpAtom( None ),
+ m_nXdndAware( None ),
+ m_nXdndEnter( None ),
+ m_nXdndLeave( None ),
+ m_nXdndPosition( None ),
+ m_nXdndStatus( None ),
+ m_nXdndDrop( None ),
+ m_nXdndFinished( None ),
+ m_nXdndSelection( None ),
+ m_nXdndTypeList( None ),
+ m_nXdndProxy( None ),
+ m_nXdndActionCopy( None ),
+ m_nXdndActionMove( None ),
+ m_nXdndActionLink( None ),
+ m_nXdndActionAsk( None ),
+ m_nXdndActionPrivate( None )
{
m_aDropEnterEvent.data.l[0] = None;
- m_bDropEnterSent = true;
m_aDragRunning.reset();
}
diff --git a/vcl/unx/source/gdi/pspgraphics.cxx b/vcl/unx/source/gdi/pspgraphics.cxx
index 009b14c56062..227d6cd7e9b2 100644
--- a/vcl/unx/source/gdi/pspgraphics.cxx
+++ b/vcl/unx/source/gdi/pspgraphics.cxx
@@ -1094,13 +1094,6 @@ const void* PspGraphics::DoGetEmbedFontData( fontID aFont, const sal_Ucs* pUnico
return NULL;
// fill in font info
- switch( aFontInfo.m_eType )
- {
- case psp::fonttype::TrueType: rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF; break;
- case psp::fonttype::Type1: rInfo.m_nFontType = FontSubsetInfo::ANY_TYPE1; break;
- default:
- return NULL;
- }
rInfo.m_nAscent = aFontInfo.m_nAscend;
rInfo.m_nDescent = aFontInfo.m_nDescend;
rInfo.m_aPSName = rMgr.getPSName( aFont );
@@ -1137,9 +1130,22 @@ const void* PspGraphics::DoGetEmbedFontData( fontID aFont, const sal_Ucs* pUnico
rInfo.m_nCapHeight = yMax; // Well ...
for( int i = 0; i < 256; i++ )
-
pWidths[i] = (aMetrics[i].width > 0 ? aMetrics[i].width : 0);
+ switch( aFontInfo.m_eType )
+ {
+ case psp::fonttype::TrueType:
+ rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF;
+ break;
+ case psp::fonttype::Type1: {
+ const bool bPFA = ((*(unsigned char*)pFile) < 0x80);
+ rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB;
+ }
+ break;
+ default:
+ return NULL;
+ }
+
return pFile;
}
diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx
index 34f2dfd4b935..5fe2295a8fed 100644
--- a/vcl/unx/source/gdi/salgdi.cxx
+++ b/vcl/unx/source/gdi/salgdi.cxx
@@ -50,6 +50,7 @@
#include "basegfx/polygon/b2dpolygonclipper.hxx"
#include "basegfx/polygon/b2dlinegeometry.hxx"
#include "basegfx/matrix/b2dhommatrix.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
#include <vector>
@@ -1028,11 +1029,12 @@ BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG )
XID X11SalGraphics::GetXRenderPicture()
{
+ XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+
if( !m_aRenderPicture )
{
// check xrender support for matching visual
// find a XRenderPictFormat compatible with the Drawable
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
XRenderPictFormat* pVisualFormat = static_cast<XRenderPictFormat*>(GetXRenderFormat());
if( !pVisualFormat )
{
@@ -1053,7 +1055,15 @@ XID X11SalGraphics::GetXRenderPicture()
// TODO: avoid clipping if already set correctly
if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
+ else
#endif
+ {
+ // reset clip region
+ // TODO: avoid clip reset if already done
+ XRenderPictureAttributes aAttr;
+ aAttr.clip_mask = None;
+ rRenderPeer.ChangePicture( m_aRenderPicture, CPClipMask, &aAttr );
+ }
return m_aRenderPicture;
}
@@ -1096,6 +1106,7 @@ bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB )
const XFixed aXDiff = rU.p2.x - rU.p1.x;
const XFixed aYDiff = rU.p2.y - rU.p1.y;
+ // compare upper point of lower segment with line through upper segment
if( (rU.p1.y != rL.p1.y) || (rU.p1.x != rL.p1.x) )
{
const sal_Int64 n1 = (sal_Int64)aXDiff * (rL.p1.y - rU.p1.y);
@@ -1104,6 +1115,7 @@ bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB )
return ((n1 < n2) == bAbove);
}
+ // compare lower point of lower segment with line through upper segment
if( (rU.p2.y != rL.p2.y) || (rU.p2.x != rL.p2.x) )
{
const sal_Int64 n3 = (sal_Int64)aXDiff * (rL.p2.y - rU.p1.y);
@@ -1122,10 +1134,14 @@ struct HalfTrapezoid
// maLine.p1.y <= mnY < maLine.p2.y
XLineFixed maLine;
XFixed mnY;
+
+ XFixed getXMin() const { return std::min( maLine.p1.x, maLine.p2.x); }
+ XFixed getXMax() const { return std::max( maLine.p1.x, maLine.p2.x); }
};
-struct HalfTrapCompare
+class HalfTrapCompare
{
+public:
bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const
{
bool bIsTopLeft = false;
@@ -1138,14 +1154,15 @@ struct HalfTrapCompare
}
};
-typedef std::priority_queue< HalfTrapezoid, std::vector<HalfTrapezoid>, HalfTrapCompare > HTQueueBase;
+typedef std::vector< HalfTrapezoid > HTVector;
+typedef std::priority_queue< HalfTrapezoid, HTVector, HalfTrapCompare > HTQueueBase;
// we need a priority queue with a reserve() to prevent countless reallocations
class HTQueue
: public HTQueueBase
{
public:
void reserve( size_t n ) { c.reserve( n ); }
- int capacity() { return c.capacity(); }
+ void swapvec( HTVector& v ) { c.swap( v ); }
};
typedef std::vector<XTrapezoid> TrapezoidVector;
@@ -1173,6 +1190,10 @@ public:
};
typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet;
+
+#ifndef DISABLE_SOLVECROSSOVER_WORKAROUND
+void splitIntersectingSegments( HTVector&);
+#endif // DISABLE_SOLVECROSSOVER_WORKAROUND
} // end of anonymous namespace
// draw a poly-polygon
@@ -1210,7 +1231,7 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
// don't bother with polygons outside of visible area
const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rOrigPolyPoly );
- const bool bNeedViewClip = !aPolyRange.isInside( aViewRange );
+ const bool bNeedViewClip = aPolyRange.isInside( aViewRange );
if( !aPolyRange.overlaps( aViewRange ) )
return true;
@@ -1237,6 +1258,15 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
if( !nClippedPolyCount )
continue;
+#ifndef DISABLE_SOLVECROSSOVER_WORKAROUND
+ for( int nClippedPolyIdx = 0; nClippedPolyIdx < nClippedPolyCount; ++nClippedPolyIdx )
+ {
+ const ::basegfx::B2DPolygon aSolvedPolygon = aClippedPolygon.getB2DPolygon( nClippedPolyIdx );
+ const int nPointCount = aSolvedPolygon.count();
+ aGoodPolyPoly.append( aSolvedPolygon );
+ nHTQueueReserve += aSolvedPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount;
+ }
+#else // DISABLE_SOLVECROSSOVER_WORKAROUND
// #i103259# polypoly.solveCrossover() fails to remove self-intersections
// but polygon.solveCrossover() works. Use it to build the intersection-free polypolygon
// TODO: if the self-intersection prevention is too expensive make the trap-algorithm tolerate intersections
@@ -1255,11 +1285,12 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
nHTQueueReserve += aSolvedPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount;
}
}
+#endif // DISABLE_SOLVECROSSOVER_WORKAROUND
}
// #i100922# try to prevent priority-queue reallocations by reservering enough
nHTQueueReserve = ((4*nHTQueueReserve) | 0x1FFF) + 1;
- HTQueue aHTQueue;
- aHTQueue.reserve( nHTQueueReserve );
+ HTVector aHTVector;
+ aHTVector.reserve( nHTQueueReserve );
// first convert the B2DPolyPolygon to HalfTrapezoids
const int nGoodPolyCount = aGoodPolyPoly.count();
@@ -1299,9 +1330,6 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
// check if enough data is available for a new HalfTrapezoid
if( nPointIdx == 0 )
continue;
- // ignore vertical segments
- if( aNewXPF.y == aOldXPF.y )
- continue;
// construct HalfTrapezoid as topdown segment
HalfTrapezoid aHT;
@@ -1326,14 +1354,33 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
#endif
// queue up the HalfTrapezoid
- aHTQueue.push( aHT );
+ aHTVector.push_back( aHT );
}
}
}
- if( aHTQueue.empty() )
+ if( aHTVector.empty() )
return TRUE;
+#ifndef DISABLE_SOLVECROSSOVER_WORKAROUND
+ // find intersecting halftraps and split them up
+ // TODO: remove when solveCrossOvers gets fast enough so its use can be enabled above
+ // FAQ: why should segment intersection be handled before adaptiveSubdivide()?
+ // Answer: because it is conceptually much faster
+ // Example: consider two intersecting circles with a diameter of 1000 pixels
+ // before subdivision: eight bezier segments
+ // after subdivision: more than a thousand line segments
+ // since even the best generic intersection finders have a complexity of O((n+k)*log(n+k))
+ // it shows that testing while the segment count is still low is a much better approach.
+ splitIntersectingSegments( aHTVector);
+#endif // DISABLE_SOLVECROSSOVER_WORKAROUND
+
+ // build queue from vector of intersection-free segments
+ // TODO: is replacing the priority-queue by a sorted vector worth it?
+ std::make_heap( aHTVector.begin(), aHTVector.end(), HalfTrapCompare());
+ HTQueue aHTQueue;
+ aHTQueue.swapvec( aHTVector);
+
// then convert the HalfTrapezoids into full Trapezoids
TrapezoidVector aTrapVector;
aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess
@@ -1349,24 +1396,28 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
XTrapezoid aTrapezoid;
// convert a HalfTrapezoid pair
+ // get the left side of the trapezoid
const HalfTrapezoid& rLeft = aHTQueue.top();
aTrapezoid.top = rLeft.mnY;
- aTrapezoid.bottom = rLeft.maLine.p2.y;
aTrapezoid.left = rLeft.maLine;
+ aHTQueue.pop();
-#if 0
- // ignore empty trapezoids
- if( aTrapezoid.bottom <= aTrapezoid.top )
+ // ignore left segment that would result in an empty trapezoid
+ if( aTrapezoid.left.p2.y <= aTrapezoid.top )
continue;
-#endif
- aHTQueue.pop();
- if( aHTQueue.empty() ) // TODO: assert
- break;
- const HalfTrapezoid& rRight = aHTQueue.top();
- aTrapezoid.right = rRight.maLine;
- aHTQueue.pop();
+ // get the right side of the trapezoid
+ aTrapezoid.right.p2.y = aTrapezoid.bottom;
+ while( !aHTQueue.empty() ) {
+ const HalfTrapezoid& rRight = aHTQueue.top();
+ aTrapezoid.right = rRight.maLine;
+ aHTQueue.pop();
+ // ignore right segment that would result in an empty trapezoid
+ if( aTrapezoid.right.p2.y > aTrapezoid.top )
+ break;
+ }
+ // the topmost endpoint determines the trapezoid bottom
aTrapezoid.bottom = aTrapezoid.left.p2.y;
if( aTrapezoid.bottom > aTrapezoid.right.p2.y )
aTrapezoid.bottom = aTrapezoid.right.p2.y;
@@ -1374,44 +1425,49 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
// keep the full Trapezoid candidate
aTrapVector.push_back( aTrapezoid );
- // unless it splits an older trapezoid
+ // unless it splits another trapezoid that is still active
bool bSplit = false;
- for(;;)
+ ActiveTrapSet::iterator aActiveTrapsIt = aActiveTraps.begin();
+ for(; aActiveTrapsIt != aActiveTraps.end(); ++aActiveTrapsIt )
{
- // check if the new trapezoid overlaps with an old trapezoid
- ActiveTrapSet::iterator aActiveTrapsIt
- = aActiveTraps.upper_bound( aTrapVector.size()-1 );
- if( aActiveTrapsIt == aActiveTraps.begin() )
- break;
- --aActiveTrapsIt;
-
XTrapezoid& rLeftTrap = aTrapVector[ *aActiveTrapsIt ];
+ // skip until first overlap candidate
+ // TODO: use stl::*er_bound() instead
+ if( IsLeftOf( aTrapezoid.left, rLeftTrap.left) )
+ continue;
+
// in the ActiveTrapSet there are still trapezoids where
// a vertical overlap with new trapezoids is no longer possible
// they could have been removed in the verticaltraps loop below
- // but this would have been expensive and is not needed as we can
- // simply ignore them now and remove them from the ActiveTrapSet
- // so they won't bother us in the future
+ // but this would be expensive and is not needed as we can
+ // simply ignore them until we stumble upon them here.
if( rLeftTrap.bottom <= aTrapezoid.top )
{
- aActiveTraps.erase( aActiveTrapsIt );
+ ActiveTrapSet::iterator it = aActiveTrapsIt;
+ if( aActiveTrapsIt != aActiveTraps.begin() )
+ --aActiveTrapsIt;
+ aActiveTraps.erase( it );
continue;
}
// check if there is horizontal overlap
// aTrapezoid.left==rLeftTrap.right is allowed though
if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) )
- break;
+ continue;
- // split the old trapezoid and keep its upper part
+ // prepare to split the old trapezoid and keep its upper part
// find the old trapezoids entry in the VerticalTrapSet and remove it
typedef std::pair<VerticalTrapSet::iterator, VerticalTrapSet::iterator> VTSPair;
VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt );
VerticalTrapSet::iterator aVTSit = aVTSPair.first;
- for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ;
- if( aVTSit != aVTSPair.second )
+ for(; aVTSit != aVTSPair.second; ++aVTSit )
+ {
+ if( *aVTSit != *aActiveTrapsIt )
+ continue;
aVerticalTraps.erase( aVTSit );
+ break;
+ }
// then update the old trapezoid's bottom
rLeftTrap.bottom = aTrapezoid.top;
// enter the updated old trapzoid in VerticalTrapSet
@@ -1444,24 +1500,26 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
// mark trapezoids that can no longer be split as inactive
// and recycle their sides which were not fully resolved
static const XFixed nMaxTop = +0x7FFFFFFF;
- XFixed nNewTop = aHTQueue.empty() ? nMaxTop : aHTQueue.top().mnY;
+ const XFixed nNewTop = aHTQueue.empty() ? nMaxTop : aHTQueue.top().mnY;
while( !aVerticalTraps.empty() )
{
+ // check the next trapezoid to be retired
const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ];
if( nNewTop < rOldTrap.bottom )
break;
- // the reference Trapezoid can no longer be split
+ // this trapezoid can no longer be split
aVerticalTraps.erase( aVerticalTraps.begin() );
// recycle its sides that were not fully resolved
HalfTrapezoid aHT;
aHT.mnY = rOldTrap.bottom;
- if( rOldTrap.left.p2.y > rOldTrap.bottom )
+
+ if( rOldTrap.left.p2.y > aHT.mnY )
{
aHT.maLine = rOldTrap.left;
aHTQueue.push( aHT );
}
- if( rOldTrap.right.p2.y > rOldTrap.bottom )
+ if( rOldTrap.right.p2.y > aHT.mnY )
{
aHT.maLine = rOldTrap.right;
aHTQueue.push( aHT );
@@ -1510,6 +1568,9 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const :
// the used basegfx::tools::createAreaGeometry is simply too
// expensive with very big polygons; fallback to caller (who
// should use ImplLineConverter normally)
+ // AW: ImplLineConverter had to be removed since it does not even
+ // know LineJoins, so the fallback will now prepare the line geometry
+ // the same way.
return false;
}
const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
@@ -1522,26 +1583,29 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const :
&& !basegfx::fTools::equalZero( rLineWidth.getY() ) )
{
// prepare for createAreaGeometry() with anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() );
- aPolygon.transform( aAnisoMatrix );
+ aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
+ }
+
+ // special handling for hairlines to improve the drawing performance
+ // TODO: revisit after basegfx performance related changes
+ const bool bIsHairline = (rLineWidth.getX() < 1.2) && (rLineWidth.getY() < 1.2);
+ if( bIsHairline )
+ {
+ // for hairlines the linejoin style becomes irrelevant
+ eLineJoin = basegfx::B2DLINEJOIN_NONE;
+ // createAreaGeometry is still too expensive when beziers are involved
+ if( aPolygon.areControlPointsUsed() )
+ aPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aPolygon, 0.125 );
}
- // AW: reSegment no longer needed; new createAreaGeometry will remove exteme positions
- // and create bezier polygons
- //if( aPolygon.areControlPointsUsed() )
- // aPolygon = basegfx::tools::reSegmentPolygonEdges( aPolygon, 8, true, false );
- //const basegfx::B2DPolyPolygon aAreaPolyPoly = basegfx::tools::createAreaGeometryForSimplePolygon(
- // aPolygon, 0.5*rLineWidth.getX(), eLineJoin );
- const basegfx::B2DPolyPolygon aAreaPolyPoly(basegfx::tools::createAreaGeometry(aPolygon, 0.5*rLineWidth.getX(), eLineJoin));
+ // create the area-polygon for the line
+ const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, 0.5*rLineWidth.getX(), eLineJoin) );
if( (rLineWidth.getX() != rLineWidth.getY())
&& !basegfx::fTools::equalZero( rLineWidth.getX() ) )
{
// postprocess createAreaGeometry() for anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() );
- aPolygon.transform( aAnisoMatrix );
+ aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
}
// temporarily adjust brush color to pen color
@@ -1568,3 +1632,259 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const :
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef DISABLE_SOLVECROSSOVER_WORKAROUND
+// TODO: move the intersection solver into basegfx
+// and then support bezier-intersection finding too
+
+namespace { // anonymous namespace to prevent export
+
+typedef HalfTrapezoid LineSeg;
+typedef HTVector LSVector;
+
+inline bool operator==( const LineSeg& r1, const LineSeg& r2)
+{
+ if( r1.maLine.p2.y != r2.maLine.p2.y) return false;
+ if( r1.maLine.p2.x != r2.maLine.p2.x) return false;
+ if( r1.maLine.p1.y != r2.maLine.p1.y) return false;
+ if( r1.maLine.p1.x != r2.maLine.p1.x) return false;
+ return true;
+}
+
+struct LSYMinCmp
+{
+ bool operator()( const LineSeg& r1, const LineSeg& r2) const
+ { return r2.maLine.p1.y < r1.maLine.p1.y; }
+};
+
+struct LSYMaxCmp
+{
+ bool operator()( const LineSeg& r1, const LineSeg& r2) const
+ { return r2.maLine.p2.y < r1.maLine.p2.y; }
+};
+
+struct LSXMinCmp
+{
+ bool operator()( const LineSeg& r1, const LineSeg& r2) const
+ { return( r1.getXMin() < r2.getXMin()); }
+};
+
+struct CutPoint
+{
+ XFixed mnSegmentId;
+ float mfCutParam;
+ XPointFixed maPoint;
+};
+
+struct CutPointCmp
+{
+ bool operator()( const CutPoint& r1, const CutPoint& r2) const
+ {
+ if( r1.mnSegmentId != r2.mnSegmentId)
+ return (r1.mnSegmentId < r2.mnSegmentId);
+ return (r1.mfCutParam < r2.mfCutParam);
+ }
+};
+
+bool findIntersection( const LineSeg& rLS1, const LineSeg& rLS2, CutPoint aCutPoints[2])
+{
+ // segments intersect at r1.p1 + s*(r1.p2-r1.p1) == r2.p1 + t*(r2.p2-r2.p1)
+ // when both segment-parameters are ((0 <s<1) && (0<t<1))
+ // (r1.p1 - r2.p1) == s * (r1.p1 - r1.p2) + t * (r2.p2 - r2.p1)
+ // =>
+ // (r1.p1x - r2.p1x) == s * (r1.p1x - r1.p2x) + t * (r2.p2x - r2.p1x)
+ // (r1.p1y - r2.p1y) == s * (r1.p1y - r1.p2y) + t * (r2.p2y - r2.p1y)
+ // check if lines are identical or parallel => not intersecting
+ const XLineFixed& r1 = rLS1.maLine;
+ const XLineFixed& r2 = rLS2.maLine;
+ const double fDet = (double)(r1.p1.x - r1.p2.x) * (r2.p2.y - r2.p1.y)
+ - (double)(r2.p2.x - r2.p1.x) * (r1.p1.y - r1.p2.y);
+ static const double fEps = 1e-8;
+ if( fabs(fDet) < fEps)
+ return false;
+ // check if intersecting with first segment
+ const double fS1 = (double)(r2.p2.y - r2.p1.y) * (r1.p1.x - r2.p1.x);
+ const double fS2 = (double)(r2.p2.x - r2.p1.x) * (r2.p1.y - r1.p1.y);
+ const double fS = (fS1 + fS2) / fDet;
+ if( (fS <= +fEps) || (fS >= 1-fEps))
+ return false;
+ // check if intersecting with second segment
+ const double fT1 = (double)(r1.p2.y - r1.p1.y) * (r1.p1.x - r2.p1.x);
+ const double fT2 = (double)(r1.p2.x - r1.p1.x) * (r2.p1.y - r1.p1.y);
+ const double fT = (fT1 + fT2) / fDet;
+ if( (fT <= +fEps) || (fT >= 1-fEps))
+ return false;
+ // force the intersection point to be exactly identical on both segments
+ aCutPoints[0].maPoint.x = (XFixed)(r1.p1.x + fS * (r1.p2.x - r1.p1.x));
+ aCutPoints[0].maPoint.y = (XFixed)(r1.p1.y + fS * (r1.p2.y - r1.p1.y));
+ aCutPoints[1].maPoint.x = aCutPoints[0].maPoint.x;
+ aCutPoints[1].maPoint.y = aCutPoints[0].maPoint.y;
+ aCutPoints[0].mnSegmentId = rLS1.mnY;
+ aCutPoints[0].mfCutParam = (float)fS;
+ aCutPoints[1].mnSegmentId = rLS2.mnY;
+ aCutPoints[1].mfCutParam = (float)fT;
+ return true;
+}
+
+typedef std::priority_queue< LineSeg, LSVector, LSYMinCmp> LSYMinQueueBase;
+typedef std::priority_queue< LineSeg, LSVector, LSYMaxCmp> LSYMaxQueueBase;
+typedef std::multiset< LineSeg, LSXMinCmp> LSXMinSet;
+typedef std::set< CutPoint, CutPointCmp> CutPointSet;
+
+class LSYMinQueue : public LSYMinQueueBase
+{
+public:
+ void reserve( size_t n) { c.reserve(n);}
+ void swapvec( LSVector& v) { c.swap(v);}
+};
+
+class LSYMaxQueue : public LSYMaxQueueBase
+{
+public:
+ void reserve( size_t n) { c.reserve(n);}
+};
+
+void addAndCutSegment( LSVector& rLSVector, const LineSeg& rLS, CutPointSet& rCutPointSet)
+{
+ // short circuit when no segment was cut
+ if( rCutPointSet.empty()) {
+ rLSVector.push_back( rLS);
+ return;
+ }
+
+ // find the first cut point for this segment
+ LineSeg aCS = rLS;
+ CutPoint aMinCutPoint;
+ aMinCutPoint.mnSegmentId = rLS.mnY;
+ aMinCutPoint.mfCutParam = 0.0;
+ CutPointSet::iterator itFirst = rCutPointSet.lower_bound( aMinCutPoint);
+ CutPointSet::iterator it = itFirst;
+ // iterate through all cut points of this segment
+ for(; it != rCutPointSet.end(); ++it) {
+ const CutPoint rCutPoint = (*it);
+ if( rCutPoint.mnSegmentId != rLS.mnY)
+ break;
+ // cut segment at the cutpoint
+ aCS.maLine.p2 = rCutPoint.maPoint;
+ rLSVector.push_back( aCS);
+ // prepare for next segment cut
+ aCS.maLine.p1 = aCS.maLine.p2;
+ }
+ // remove cutparams that will no longer be needed
+ // TODO: is it worth it or should we just keep the cutparams?
+ rCutPointSet.erase( itFirst, it);
+
+ // add segment part remaining after last cut
+ aCS.maLine.p2 = rLS.maLine.p2;
+ rLSVector.push_back( aCS);
+}
+
+void splitIntersectingSegments( LSVector& rLSVector)
+{
+ // get a unique id for each lineseg, temporarily abuse the mnY member
+ LSVector::iterator aLSit = rLSVector.begin();
+ for( int i = 0; aLSit != rLSVector.end(); ++aLSit) {
+ LineSeg& rLS = *aLSit;
+ rLS.mnY = i++;
+ }
+ // get an y-sorted queue from the input vector
+ LSYMinQueue aYMinQueue;
+ std::make_heap( rLSVector.begin(), rLSVector.end(), LSYMinCmp());
+ aYMinQueue.swapvec( rLSVector);
+
+ // prepare the result vector
+ // try to avoid reallocations by guessing a reasonable result size
+ rLSVector.reserve( aYMinQueue.size() * 3/2 );
+
+ // find all intersections
+ CutPointSet aCutPointSet;
+ LSXMinSet aXMinSet;
+ LSYMaxQueue aYMaxQueue;
+ aYMaxQueue.reserve( aYMinQueue.size());
+ // sweep-down and check all segment-pairs that overlap
+ while( !aYMinQueue.empty()) {
+ // get next input-segment
+ const LineSeg& rLS = aYMinQueue.top();
+ // retire obsoleted segments
+ const XFixed fYCur = rLS.maLine.p1.y;
+ while( !aYMaxQueue.empty()) {
+ // check next segment to be retired
+ const LineSeg& rOS = aYMaxQueue.top();
+ if( fYCur < rOS.maLine.p2.y)
+ break;
+ // emit resolved segment into result
+ addAndCutSegment( rLSVector, rOS, aCutPointSet);
+ // find segment to be retired in xmin-compare-set
+ LSXMinSet::iterator itR = aXMinSet.lower_bound( rOS);
+ while( !(*itR == rOS)) ++itR;
+ // retire segment from xmin-compare-set
+ aXMinSet.erase( itR);
+ // this segment is pining for the fjords
+ aYMaxQueue.pop();
+ }
+
+ // iterate over all segments that might overlap
+ // skip over the leftmost segments that cannot overlap
+ const XFixed fXMax = rLS.getXMax();
+ LSXMinSet::const_iterator itC = aXMinSet.begin();
+ for(; itC != aXMinSet.end(); ++itC)
+ if( (*itC).getXMin() <= fXMax)
+ break;
+ // TODO: if the linear search becomes too expensive
+ // then use an XMaxQueue based approach to replace it
+ const XFixed fXMin = rLS.getXMin();
+ for(; itC != aXMinSet.end(); ++itC) {
+ const LineSeg& rOS = *itC;
+ if( fXMin >= rOS.getXMax())
+ continue;
+ if( fXMax < rOS.getXMin())
+ break;
+ CutPoint aCutPoints[2];
+ if( !findIntersection( rLS, rOS, aCutPoints))
+ continue;
+ // remember cut parameters
+ // TODO: std::set seems to use individual allocations
+ // which results in perf-problems for many entries
+ // => pre-allocate nodes by using a non-default allocator
+ aCutPointSet.insert( aCutPoints[0]);
+ aCutPointSet.insert( aCutPoints[1]);
+ }
+ // add segment to xmin-compare-set
+ // TODO: do we have a good insertion hint?
+ aXMinSet.insert( /*itC,*/ rLS);
+ // register segment for retirement
+ aYMaxQueue.push( rLS);
+ aYMinQueue.pop();
+ }
+
+ // retire the remaining segments
+ aXMinSet.clear();
+ while( !aYMaxQueue.empty()) {
+ // emit segments and cut them up if needed
+ const LineSeg& rLS = aYMaxQueue.top();
+ addAndCutSegment( rLSVector, rLS, aCutPointSet);
+ aYMaxQueue.pop();
+ }
+
+ // get the segments ready to be consumed by the drawPolygon() caller
+ aLSit = rLSVector.begin();
+ LSVector::iterator aLSit2 = aLSit;
+ for(; aLSit != rLSVector.end(); ++aLSit) {
+ LineSeg& rLS = *aLSit;
+ // restore the segment top member
+ rLS.mnY = rLS.maLine.p1.y;
+ // remove horizontal segments for now
+ // TODO: until the trapezoid converter is adjusted to handle them
+ if( rLS.maLine.p1.y == rLS.maLine.p2.y )
+ continue;
+ *(aLSit2++) = rLS;
+ }
+ if(aLSit2 != aLSit)
+ rLSVector.resize( aLSit2 - rLSVector.begin() );
+}
+
+} // end anonymous namespace
+
+#endif // DISABLE_SOLVECROSSOVER_WORKAROUND
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
diff --git a/vcl/unx/source/gdi/xrender_peer.cxx b/vcl/unx/source/gdi/xrender_peer.cxx
index d8f2045c6fde..fc8de818fafd 100644
--- a/vcl/unx/source/gdi/xrender_peer.cxx
+++ b/vcl/unx/source/gdi/xrender_peer.cxx
@@ -142,6 +142,10 @@ void XRenderPeer::InitRenderLib()
mpXRenderCreatePicture = (Picture(*)(Display*,Drawable,const XRenderPictFormat*,
unsigned long,const XRenderPictureAttributes*))pFunc;
+ pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderChangePicture" );
+ if( !pFunc ) return;
+ mpXRenderChangePicture = (void(*)(Display*,Picture,unsigned long,const XRenderPictureAttributes*))pFunc;
+
pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderSetPictureClipRegion" );
if( !pFunc ) return;
mpXRenderSetPictureClipRegion = (void(*)(Display*,Picture,XLIB_Region))pFunc;
diff --git a/vcl/unx/source/gdi/xrender_peer.hxx b/vcl/unx/source/gdi/xrender_peer.hxx
index f1e2fd77a273..27c8fb3dcaeb 100644
--- a/vcl/unx/source/gdi/xrender_peer.hxx
+++ b/vcl/unx/source/gdi/xrender_peer.hxx
@@ -66,6 +66,8 @@ public:
const XRenderPictFormat& ) const;
Picture CreatePicture( Drawable, const XRenderPictFormat*,
unsigned long nDrawable, const XRenderPictureAttributes* ) const;
+ void ChangePicture( Picture, unsigned long nValueMask,
+ const XRenderPictureAttributes* ) const;
void SetPictureClipRegion( Picture, XLIB_Region ) const;
void CompositePicture( int nOp, Picture aSrc, Picture aMask, Picture aDst,
int nXSrc, int nYSrc, int nXMask, int nYMask,
@@ -103,6 +105,8 @@ private:
Picture (*mpXRenderCreatePicture)(Display*,Drawable, const XRenderPictFormat*,
unsigned long,const XRenderPictureAttributes*);
+ void (*mpXRenderChangePicture)(Display*,Picture,
+ unsigned long,const XRenderPictureAttributes*);
void (*mpXRenderSetPictureClipRegion)(Display*,Picture,XLIB_Region);
void (*mpXRenderFreePicture)(Display*,Picture);
void (*mpXRenderComposite)(Display*,int,Picture,Picture,Picture,
@@ -194,6 +198,16 @@ inline Picture XRenderPeer::CreatePicture( Drawable aDrawable,
#endif
}
+inline void XRenderPeer::ChangePicture( Picture aPicture,
+ unsigned long nValueMask, const XRenderPictureAttributes* pRenderAttr ) const
+{
+#ifdef XRENDER_LINK
+ XRenderChangePicture( mpDisplay, aPicture, nValueMask, pRenderAttr );
+#else
+ (*mpXRenderChangePicture)( mpDisplay, aPicture, nValueMask, pRenderAttr );
+#endif
+}
+
inline void XRenderPeer::SetPictureClipRegion( Picture aPicture,
XLIB_Region aXlibRegion ) const
{
diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx
index 14de25b13e4d..f1c63b8abee7 100644
--- a/vcl/unx/source/plugadapt/salplug.cxx
+++ b/vcl/unx/source/plugadapt/salplug.cxx
@@ -149,34 +149,53 @@ static const rtl::OUString& get_desktop_environment()
return aRet;
}
-static const char* autodetect_plugin()
+static SalInstance* autodetect_plugin()
{
+ static const char* pKDEFallbackList[] =
+ {
+ "kde4", "kde", "gtk", "gen", 0
+ };
+
+ static const char* pStandardFallbackList[] =
+ {
+ "gtk", "gen", 0
+ };
+
+ static const char* pHeadlessFallbackList[] =
+ {
+ "svp", 0
+ };
+
const rtl::OUString& desktop( get_desktop_environment() );
- const char * pRet = "gen";
+ const char ** pList = pStandardFallbackList;
+ int nListEntry = 0;
// no server at all: dummy plugin
if ( desktop.equalsAscii( desktop_strings[DESKTOP_NONE] ) )
- pRet = "svp";
+ pList = pHeadlessFallbackList;
else if ( desktop.equalsAscii( desktop_strings[DESKTOP_GNOME] ) )
- pRet = "gtk";
+ pList = pStandardFallbackList;
else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE] ) )
- pRet = "kde";
- else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE4] ) )
- pRet = "kde4";
- else
{
- // #i95296# use the much nicer looking gtk plugin
- // on desktops that set gtk variables (e.g. XFCE)
- static const char* pEnv = getenv( "GTK2_RC_FILES" );
- if( pEnv && *pEnv ) // check for existance and non emptiness
- pRet = "gtk";
+ pList = pKDEFallbackList;
+ nListEntry = 1;
}
+ else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE4] ) )
+ pList = pKDEFallbackList;
-#if OSL_DEBUG_LEVEL > 1
- std::fprintf( stderr, "plugin autodetection: %s\n", pRet );
-#endif
+ SalInstance* pInst = NULL;
+ while( pList[nListEntry] && pInst == NULL )
+ {
+ rtl::OUString aTry( rtl::OUString::createFromAscii( pList[nListEntry] ) );
+ pInst = tryInstance( aTry );
+ #if OSL_DEBUG_LEVEL > 1
+ if( pInst )
+ std::fprintf( stderr, "plugin autodetection: %s\n", pList[nListEntry] );
+ #endif
+ nListEntry++;
+ }
- return pRet;
+ return pInst;
}
static SalInstance* check_headless_plugin()
@@ -202,10 +221,7 @@ SalInstance *CreateSalInstance()
pInst = check_headless_plugin();
if( ! pInst && !(pUsePlugin && *pUsePlugin) )
- pUsePlugin = autodetect_plugin();
-
- if( ! pInst && pUsePlugin && *pUsePlugin )
- pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) );
+ pInst = autodetect_plugin();
// fallback to gen
if( ! pInst )
diff --git a/vcl/unx/source/printer/printerinfomanager.cxx b/vcl/unx/source/printer/printerinfomanager.cxx
index b3e5b4667a6a..53cd662db8e0 100644
--- a/vcl/unx/source/printer/printerinfomanager.cxx
+++ b/vcl/unx/source/printer/printerinfomanager.cxx
@@ -441,7 +441,7 @@ void PrinterInfoManager::initialize()
* porters: please append your platform to the Solaris
* case if your platform has SystemV printing per default.
*/
- #if defined SOLARIS || defined(IRIX)
+ #if defined SOLARIS
aValue = "lp";
#else
aValue = "lpr";
diff --git a/vcl/unx/source/printergfx/common_gfx.cxx b/vcl/unx/source/printergfx/common_gfx.cxx
index 632f0d70aa2f..9b305ff323ba 100644
--- a/vcl/unx/source/printergfx/common_gfx.cxx
+++ b/vcl/unx/source/printergfx/common_gfx.cxx
@@ -7,7 +7,6 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: common_gfx.cxx,v $
- * $Revision: 1.20.18.1 $
*
* This file is part of OpenOffice.org.
*
@@ -535,68 +534,47 @@ PrinterGfx::DrawPolyLineBezier (sal_uInt32 nPoints, const Point* pPath, const BY
const sal_uInt32 nBezString = 1024;
sal_Char pString[nBezString];
- if ( maLineColor.Is() && nPoints && pPath )
+ if ( nPoints > 1 && maLineColor.Is() && pPath )
{
PSSetColor (maLineColor);
PSSetColor ();
PSSetLineWidth ();
- if (pFlgAry[0] != POLY_NORMAL) //There must be a starting point to moveto
- {
- return;
- }
- else
- {
- snprintf(pString, nBezString, "%li %li moveto\n", pPath[0].X(), pPath[0].Y());
- WritePS(mpPageBody, pString);
- }
+ snprintf(pString, nBezString, "%li %li moveto\n", pPath[0].X(), pPath[0].Y());
+ WritePS(mpPageBody, pString);
// Handle the drawing of mixed lines mixed with curves
// - a normal point followed by a normal point is a line
// - a normal point followed by 2 control points and a normal point is a curve
for (unsigned int i=1; i<nPoints;)
{
- if (pFlgAry[i+1] != POLY_CONTROL) //If the next point is a POLY_NORMAL, we're drawing a line
+ if (pFlgAry[i] != POLY_CONTROL) //If the next point is a POLY_NORMAL, we're drawing a line
{
- if (i+1 >= nPoints) return; //Make sure we don't pass the end of the array
snprintf(pString, nBezString, "%li %li lineto\n", pPath[i].X(), pPath[i].Y());
i++;
}
else //Otherwise we're drawing a spline
{
- if (i+3 >= nPoints) return; //Make sure we don't pass the end of the array
- snprintf(pString, nBezString, "%li %li %li %li %li %li curveto\n",
- pPath[i+1].X(), pPath[i+1].Y(),
- pPath[i+2].X(), pPath[i+2].Y(),
- pPath[i+3].X(), pPath[i+3].Y());
+ if (i+2 >= nPoints)
+ return; //Error: wrong sequence of contol/normal points somehow
+ if ((pFlgAry[i] == POLY_CONTROL) && (pFlgAry[i+1] == POLY_CONTROL) &&
+ (pFlgAry[i+2] != POLY_CONTROL))
+ {
+ snprintf(pString, nBezString, "%li %li %li %li %li %li curveto\n",
+ pPath[i].X(), pPath[i].Y(),
+ pPath[i+1].X(), pPath[i+1].Y(),
+ pPath[i+2].X(), pPath[i+2].Y());
+ }
+ else
+ {
+ DBG_ERROR( "PrinterGfx::DrawPolyLineBezier: Strange output" );
+ }
i+=3;
}
WritePS(mpPageBody, pString);
}
- }
-
- // if eofill and stroke, save the current path
- if( maFillColor.Is() && maLineColor.Is())
- PSGSave();
-
- // first draw area
- if( maFillColor.Is() )
- {
- PSSetColor (maFillColor);
- PSSetColor ();
- WritePS (mpPageBody, "eofill\n");
- }
-
- // restore the current path
- if( maFillColor.Is() && maLineColor.Is())
- PSGRestore();
- // now draw outlines
- if( maLineColor.Is() )
- {
- PSSetColor (maLineColor);
- PSSetColor ();
- PSSetLineWidth ();
+ // now draw outlines
WritePS (mpPageBody, "stroke\n");
}
}
@@ -635,7 +613,7 @@ PrinterGfx::DrawPolygonBezier (sal_uInt32 nPoints, const Point* pPath, const BYT
}
else
{
- fprintf(stderr, "Strange output\n");
+ DBG_ERROR( "PrinterGfx::DrawPolygonBezier: Strange output" );
}
i+=3;
}
@@ -699,9 +677,7 @@ PrinterGfx::DrawPolyPolygonBezier (sal_uInt32 nPoly, const sal_uInt32 * pPoints,
}
else
{
-#if OSL_DEBUG_LEVEL > 1
- fprintf(stderr, "Strange output\n");
-#endif
+ DBG_ERROR( "PrinterGfx::DrawPolyPolygonBezier: Strange output" );
}
j+=3;
}
diff --git a/vcl/unx/source/printergfx/glyphset.cxx b/vcl/unx/source/printergfx/glyphset.cxx
index 156517d98220..5adff6683267 100644
--- a/vcl/unx/source/printergfx/glyphset.cxx
+++ b/vcl/unx/source/printergfx/glyphset.cxx
@@ -46,6 +46,7 @@
#include <set>
#include <map>
+#include <algorithm>
using namespace vcl;
using namespace psp;
@@ -785,6 +786,17 @@ GlyphSet::PSUploadEncoding(osl::File* pOutFile, PrinterGfx &rGfx)
return sal_True;
}
+struct EncEntry
+{
+ sal_uChar aEnc;
+ long aGID;
+
+ EncEntry() : aEnc( 0 ), aGID( 0 ) {}
+
+ bool operator<( const EncEntry& rRight ) const
+ { return aEnc < rRight.aEnc; }
+};
+
static void CreatePSUploadableFont( TrueTypeFont* pSrcFont, FILE* pTmpFile,
const char* pGlyphSetName, int nGlyphCount,
/*const*/ sal_uInt16* pRequestedGlyphs, /*const*/ sal_uChar* pEncoding,
@@ -796,17 +808,29 @@ static void CreatePSUploadableFont( TrueTypeFont* pSrcFont, FILE* pTmpFile,
if( bAllowType42 )
nTargetMask |= FontSubsetInfo::TYPE42_FONT;
+ std::vector< EncEntry > aSorted( nGlyphCount, EncEntry() );
+ for( int i = 0; i < nGlyphCount; i++ )
+ {
+ aSorted[i].aEnc = pEncoding[i];
+ aSorted[i].aGID = pRequestedGlyphs[i];
+ }
+
+ std::stable_sort( aSorted.begin(), aSorted.end() );
+
+ std::vector< sal_uChar > aEncoding( nGlyphCount );
+ std::vector< long > aRequestedGlyphs( nGlyphCount );
+
+ for( int i = 0; i < nGlyphCount; i++ )
+ {
+ aEncoding[i] = aSorted[i].aEnc;
+ aRequestedGlyphs[i] = aSorted[i].aGID;
+ }
+
FontSubsetInfo aInfo;
aInfo.LoadFont( pSrcFont );
-#if 1 // TODO: remove 16bit->long conversion when input args has been changed
- long aRequestedGlyphs[256];
- for( int i = 0; i < nGlyphCount; ++i )
- aRequestedGlyphs[i] = pRequestedGlyphs[i];
-#endif
-
aInfo.CreateFontSubset( nTargetMask, pTmpFile, pGlyphSetName,
- aRequestedGlyphs, pEncoding, nGlyphCount, NULL );
+ &aRequestedGlyphs[0], &aEncoding[0], nGlyphCount, NULL );
}
sal_Bool
diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx
index 6219b50d6ec3..68c99e05da77 100644
--- a/vcl/unx/source/window/salframe.cxx
+++ b/vcl/unx/source/window/salframe.cxx
@@ -930,12 +930,13 @@ void X11SalFrame::ReleaseGraphics( SalGraphics *pGraphics )
pGraphics_ = NULL;
}
-void X11SalFrame::updateGraphics()
+void X11SalFrame::updateGraphics( bool bClear )
{
+ Drawable aDrawable = bClear ? None : GetWindow();
if( pGraphics_ )
- pGraphics_->SetDrawable( GetWindow(), m_nScreen );
+ pGraphics_->SetDrawable( aDrawable, m_nScreen );
if( pFreeGraphics_ )
- pFreeGraphics_->SetDrawable( GetWindow(), m_nScreen );
+ pFreeGraphics_->SetDrawable( aDrawable, m_nScreen );
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
@@ -2726,6 +2727,7 @@ void X11SalFrame::createNewWindow( XLIB_Window aNewParent, int nScreen )
}
// first deinit frame
+ updateGraphics(true);
if( mpInputContext )
{
mpInputContext->UnsetICFocus( this );
@@ -2748,7 +2750,7 @@ void X11SalFrame::createNewWindow( XLIB_Window aNewParent, int nScreen )
Init( nStyle_ & ~SAL_FRAME_STYLE_PLUG, nScreen, NULL, true );
// update graphics if necessary
- updateGraphics();
+ updateGraphics(false);
if( m_aTitle.Len() )
SetTitle( m_aTitle );