diff --git a/canvas/source/vcl/bitmapbackbuffer.cxx b/canvas/source/vcl/bitmapbackbuffer.cxx index a7895f1034dd..1cc97351d9c0 100644 --- a/canvas/source/vcl/bitmapbackbuffer.cxx +++ b/canvas/source/vcl/bitmapbackbuffer.cxx @@ -105,6 +105,19 @@ namespace vclcanvas return *maBitmap; } + Size BitmapBackBuffer::getBitmapSizePixel() const + { + Size aSize = maBitmap->GetSizePixel(); + + if( mbVDevContentIsCurrent && mpVDev ) + { + mpVDev->EnableMapMode( FALSE ); + aSize = mpVDev->GetOutputSizePixel(); + } + + return aSize; + } + void BitmapBackBuffer::createVDev() const { if( !mpVDev ) @@ -151,5 +164,5 @@ namespace vclcanvas mbBitmapContentIsCurrent = false; mbVDevContentIsCurrent = true; } - } + diff --git a/canvas/source/vcl/bitmapbackbuffer.hxx b/canvas/source/vcl/bitmapbackbuffer.hxx index 04738300a186..7668aaaaf6b2 100644 --- a/canvas/source/vcl/bitmapbackbuffer.hxx +++ b/canvas/source/vcl/bitmapbackbuffer.hxx @@ -70,6 +70,7 @@ namespace vclcanvas @internal */ BitmapEx& getBitmapReference(); + Size getBitmapSizePixel() const; private: void createVDev() const; @@ -103,3 +104,4 @@ namespace vclcanvas } #endif /* #ifndef _VCLCANVAS_BITMAPBACKBUFFER_HXX_ */ + diff --git a/canvas/source/vcl/canvasbitmaphelper.cxx b/canvas/source/vcl/canvasbitmaphelper.cxx index 5656e4ba2429..5d5aa0dc8179 100644 --- a/canvas/source/vcl/canvasbitmaphelper.cxx +++ b/canvas/source/vcl/canvasbitmaphelper.cxx @@ -109,7 +109,7 @@ namespace vclcanvas if( !mpBackBuffer ) return geometry::IntegerSize2D(); - return ::vcl::unotools::integerSize2DFromSize( mpBackBuffer->getBitmapReference().GetSizePixel() ); + return ::vcl::unotools::integerSize2DFromSize( mpBackBuffer->getBitmapSizePixel() ); } void CanvasBitmapHelper::clear() diff --git a/svtools/source/brwbox/brwbox1.cxx b/svtools/source/brwbox/brwbox1.cxx index 05ab0e1b0c91..767283a8e425 100644 --- a/svtools/source/brwbox/brwbox1.cxx +++ b/svtools/source/brwbox/brwbox1.cxx @@ -1711,7 +1711,7 @@ BOOL BrowseBox::GoToColumnId( USHORT nColId, BOOL bMakeVisible, BOOL bRowColMove if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) ) return FALSE; - if ( nColId != nCurColId || bMakeVisible && !IsFieldVisible(nCurRow, nColId, TRUE)) + if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, TRUE))) { USHORT nNewPos = GetColumnPos(nColId); BrowserColumn* pColumn = pCols->GetObject( nNewPos ); diff --git a/svtools/source/config/securityoptions.cxx b/svtools/source/config/securityoptions.cxx index 6fdb314f9c74..8fbc9008d51e 100644 --- a/svtools/source/config/securityoptions.cxx +++ b/svtools/source/config/securityoptions.cxx @@ -901,7 +901,7 @@ sal_Bool SvtSecurityOptions_Impl::IsSecureURL( const OUString& sURL , INetProtocol aProtocol = aURL.GetProtocol(); // All other URLs must checked in combination with referer and internal information about security - if ( aProtocol != INET_PROT_MACRO && aProtocol != INET_PROT_SLOT || + if ( (aProtocol != INET_PROT_MACRO && aProtocol != INET_PROT_SLOT) || aURL.GetMainURL( INetURLObject::NO_DECODE ).matchIgnoreAsciiCaseAsciiL( "macro:///", 9 ) == 0) { // security check only for "macro" ( without app basic ) or "slot" protocols diff --git a/svtools/source/control/filectrl.cxx b/svtools/source/control/filectrl.cxx index 76893744688b..d820dce097ed 100644 --- a/svtools/source/control/filectrl.cxx +++ b/svtools/source/control/filectrl.cxx @@ -47,7 +47,7 @@ FileControl::FileControl( Window* pParent, WinBits nStyle, FileControlMode nFlags ) : Window( pParent, nStyle|WB_DIALOGCONTROL ), maEdit( this, (nStyle&(~WB_BORDER))|WB_NOTABSTOP ), - maButton( this, nStyle&(~WB_BORDER)|WB_NOLIGHTBORDER|WB_NOPOINTERFOCUS|WB_NOTABSTOP ), + maButton( this, (nStyle&(~WB_BORDER))|WB_NOLIGHTBORDER|WB_NOPOINTERFOCUS|WB_NOTABSTOP ), maButtonText( SvtResId( STR_FILECTRL_BUTTONTEXT ) ), mnFlags( nFlags ), mnInternalFlags( FILECTRL_ORIGINALBUTTONTEXT ) @@ -164,11 +164,11 @@ void FileControl::Resize() Size aOutSz = GetOutputSizePixel(); long nButtonTextWidth = maButton.GetTextWidth( maButtonText ); if ( ((mnInternalFlags & FILECTRL_ORIGINALBUTTONTEXT) == 0) || - nButtonTextWidth < aOutSz.Width()/3 && + ( nButtonTextWidth < aOutSz.Width()/3 && ( mnFlags & FILECTRL_RESIZEBUTTONBYPATHLEN ? ( maEdit.GetTextWidth( maEdit.GetText() ) <= aOutSz.Width() - nButtonTextWidth - ButtonBorder ) - : TRUE ) + : TRUE ) ) ) { maButton.SetText( maButtonText ); diff --git a/svtools/source/control/inettbc.cxx b/svtools/source/control/inettbc.cxx index 2f9e881e39c9..4a01a03ad759 100644 --- a/svtools/source/control/inettbc.cxx +++ b/svtools/source/control/inettbc.cxx @@ -374,8 +374,8 @@ void SvtMatchContext_Impl::ReadFolder( const String& rURL, sal_Bool bExectMatch = bPureHomePath || aText.CompareToAscii( "." ) == COMPARE_EQUAL - || aText.Len() > 1 && aText.Copy( aText.Len() - 2, 2 ).CompareToAscii( "/." ) == COMPARE_EQUAL - || aText.Len() > 1 && aText.Copy( aText.Len() - 3, 3 ).CompareToAscii( "/.." ) == COMPARE_EQUAL; + || (aText.Len() > 1 && aText.Copy( aText.Len() - 2, 2 ).CompareToAscii( "/." ) == COMPARE_EQUAL) + || (aText.Len() > 2 && aText.Copy( aText.Len() - 3, 3 ).CompareToAscii( "/.." ) == COMPARE_EQUAL); // for pure home pathes ( ~username ) the '.' at the end of rMatch // means that it poits to root catalog @@ -641,7 +641,7 @@ void SvtMatchContext_Impl::run() // if the user input is a valid URL, go on with it // otherwise it could be parsed smart with a predefined smart protocol // ( or if this is not set with the protocol of a predefined base URL ) - if( eProt == INET_PROT_NOT_VALID || eProt == eSmartProt || eSmartProt == INET_PROT_NOT_VALID && eProt == eBaseProt ) + if( eProt == INET_PROT_NOT_VALID || eProt == eSmartProt || (eSmartProt == INET_PROT_NOT_VALID && eProt == eBaseProt) ) { // not stopped yet ? if( schedule() ) diff --git a/svtools/source/filter.vcl/ixbm/xbmread.cxx b/svtools/source/filter.vcl/ixbm/xbmread.cxx index 7429ffcc90cd..32f73d62c195 100644 --- a/svtools/source/filter.vcl/ixbm/xbmread.cxx +++ b/svtools/source/filter.vcl/ixbm/xbmread.cxx @@ -157,7 +157,7 @@ long XBMReader::ParseDefine( const sal_Char* pDefine ) { long nRet = 0; char* pTmp = (char*) pDefine; - char cTmp; + unsigned char cTmp; // bis zum Ende gehen pTmp += ( strlen( pDefine ) - 1 ); diff --git a/vcl/aqua/inc/salgdi.h b/vcl/aqua/inc/salgdi.h index 4c52c06a7393..11abd6086ce7 100644 --- a/vcl/aqua/inc/salgdi.h +++ b/vcl/aqua/inc/salgdi.h @@ -157,6 +157,7 @@ public: void SetVirDevGraphics( CGLayerRef, CGContextRef, int nBitDepth = 0 ); void initResolution( NSWindow* ); + void copyResolution( AquaSalGraphics& ); void updateResolution(); bool IsWindowGraphics() const { return mbWindow; } diff --git a/vcl/aqua/source/gdi/salatslayout.cxx b/vcl/aqua/source/gdi/salatslayout.cxx index f47920004f7a..98700feba39d 100755 --- a/vcl/aqua/source/gdi/salatslayout.cxx +++ b/vcl/aqua/source/gdi/salatslayout.cxx @@ -301,7 +301,7 @@ void ATSLayout::AdjustLayout( ImplLayoutArgs& rArgs ) int nPixelWidth = rArgs.mnLayoutWidth; if( !nPixelWidth && rArgs.mpDXArray ) { // for now we are only interested in the layout width - // TODO: account for individual logical widths + // TODO: use all mpDXArray elements for layouting nPixelWidth = rArgs.mpDXArray[ mnCharCount - 1 ]; // workaround for ATSUI not using trailing spaces for justification @@ -309,14 +309,21 @@ void ATSLayout::AdjustLayout( ImplLayoutArgs& rArgs ) int i = mnCharCount; while( (--i > 0) && IsSpacingGlyph( rArgs.mpStr[mnMinCharPos+i]|GF_ISCHAR ) ) mnTrailingSpaceWidth += rArgs.mpDXArray[i] - rArgs.mpDXArray[i-1]; + if( i <= 0 ) + return; + // #i91685# trailing letters are left aligned (right aligned for RTL) + mnTrailingSpaceWidth += rArgs.mpDXArray[i]; + if( i > 0 ) + mnTrailingSpaceWidth -= rArgs.mpDXArray[i-1]; + InitGIA(); // ensure valid mpCharWidths[] + mnTrailingSpaceWidth -= Fixed2Vcl( mpCharWidths[i] ); + // ignore trailing space for calculating the available width nOrigWidth -= mnTrailingSpaceWidth; nPixelWidth -= mnTrailingSpaceWidth; - // trailing spaces can be leftmost spaces in RTL-layouts + // in RTL-layouts trailing spaces are leftmost // TODO: use BiDi-algorithm to thoroughly check this assumption if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL) mnBaseAdv = mnTrailingSpaceWidth; - - // TODO: use all mpDXArray elements for layouting } // return early if there is nothing to do if( !nPixelWidth ) diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index b1499e2c32d5..314753302534 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -416,6 +416,16 @@ void AquaSalGraphics::GetResolution( long& rDPIX, long& rDPIY ) rDPIY = static_cast(mfFakeDPIScale * mnRealDPIY); } +void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics ) +{ + if( !rGraphics.mnRealDPIY && rGraphics.mbWindow && rGraphics.mpFrame ) + rGraphics.initResolution( rGraphics.mpFrame->mpWindow ); + + mnRealDPIX = rGraphics.mnRealDPIX; + mnRealDPIY = rGraphics.mnRealDPIY; + mfFakeDPIScale = rGraphics.mfFakeDPIScale; +} + // ----------------------------------------------------------------------- USHORT AquaSalGraphics::GetBitCount() diff --git a/vcl/aqua/source/gdi/salvd.cxx b/vcl/aqua/source/gdi/salvd.cxx index 5ab2f27a8d42..d7690e4e38bd 100644 --- a/vcl/aqua/source/gdi/salvd.cxx +++ b/vcl/aqua/source/gdi/salvd.cxx @@ -87,7 +87,7 @@ AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX, if( pFrame && AquaSalFrame::isAlive( pFrame ) ) { mpGraphics->setGraphicsFrame( pFrame ); - mpGraphics->initResolution( pFrame->mpWindow ); + mpGraphics->copyResolution( *pGraphic ); } } diff --git a/vcl/inc/vcl/syschild.hxx b/vcl/inc/vcl/syschild.hxx index 1d4d0fafd7aa..29610e653b9d 100644 --- a/vcl/inc/vcl/syschild.hxx +++ b/vcl/inc/vcl/syschild.hxx @@ -46,7 +46,7 @@ class VCL_DLLPUBLIC SystemChildWindow : public Window { private: using Window::ImplInit; - SAL_DLLPRIVATE void ImplInitSysChild( Window* pParent, WinBits nStyle, SystemWindowData *pData, BOOL bShow = TRUE ); + SAL_DLLPRIVATE void ImplInitSysChild( Window* pParent, WinBits nStyle, SystemWindowData *pData, BOOL bShow = FALSE ); // Copy assignment is forbidden and not implemented. SAL_DLLPRIVATE SystemChildWindow (const SystemChildWindow &); diff --git a/vcl/source/gdi/base14.cxx b/vcl/source/gdi/base14.cxx index 7bdeb9f1fec7..17e616d196b4 100644 --- a/vcl/source/gdi/base14.cxx +++ b/vcl/source/gdi/base14.cxx @@ -646,7 +646,7 @@ const PDFWriterImpl::BuiltinFont PDFWriterImpl::m_aBuiltinFonts[ 14 ] = { "ZapfDingbats", // PSName 820, -143, // ascend, descend FAMILY_DONTKNOW, // family style - RTL_TEXTENCODING_SYMBOL, // charset + RTL_TEXTENCODING_ADOBE_DINGBATS, // charset PITCH_VARIABLE, // pitch WIDTH_NORMAL, // width type WEIGHT_NORMAL, // weight type diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 9293ebf1aab2..4959a505ec41 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -246,9 +246,12 @@ void PDFWriter::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, const void PDFWriter::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, const Size& rSrcSizePixel, const BitmapEx& rBitmap ) { + if ( !!rBitmap ) + { BitmapEx aBitmap( rBitmap ); aBitmap.Crop( Rectangle( rSrcPtPixel, rSrcSizePixel ) ); ((PDFWriterImpl*)pImplementation)->drawBitmap( rDestPt, rDestSize, aBitmap ); + } } void PDFWriter::DrawMask( const Point& rDestPt, const Bitmap& rBitmap, const Color& rMaskColor ) diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 05067ee2d024..3f648fda8589 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -6,9 +6,6 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: pdfwriter_impl.cxx,v $ - * $Revision: 1.132.72.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -1930,7 +1927,7 @@ static ImplDevFontAttributes GetDevFontAttributes( const PDFWriterImpl::BuiltinF aDFA.maName = String::CreateFromAscii( rBuiltin.m_pName ); aDFA.maStyleName = String::CreateFromAscii( rBuiltin.m_pStyleName ); aDFA.meFamily = rBuiltin.m_eFamily; - aDFA.mbSymbolFlag = (rBuiltin.m_eCharSet == RTL_TEXTENCODING_SYMBOL); + aDFA.mbSymbolFlag = (rBuiltin.m_eCharSet != RTL_TEXTENCODING_MS_1252 ); aDFA.mePitch = rBuiltin.m_ePitch; aDFA.meWeight = rBuiltin.m_eWeight; aDFA.meItalic = rBuiltin.m_eItalic; @@ -2033,7 +2030,7 @@ PDFSalLayout::PDFSalLayout( PDFWriterImpl& rPDFWriterImpl, mrBuiltinFont( rBuiltinFont ), mnPixelPerEM( nPixelPerEM ) { - mbIsSymbolFont = (rBuiltinFont.m_eCharSet == RTL_TEXTENCODING_SYMBOL); + mbIsSymbolFont = (rBuiltinFont.m_eCharSet != RTL_TEXTENCODING_MS_1252); SetOrientation( nOrientation ); } @@ -2045,41 +2042,35 @@ bool PDFSalLayout::LayoutText( ImplLayoutArgs& rArgs ) SetText( aText ); SetUnitsPerPixel( 1000 ); - rtl_UnicodeToTextConverter aConv = rtl_createTextToUnicodeConverter( RTL_TEXTENCODING_MS_1252 ); + rtl_UnicodeToTextConverter aConv = rtl_createTextToUnicodeConverter( mrBuiltinFont.m_eCharSet ); Point aNewPos( 0, 0 ); bool bRightToLeft; for( int nCharPos = -1; rArgs.GetNextPos( &nCharPos, &bRightToLeft ); ) { // TODO: handle unicode surrogates - // on the other hand builtin fonts don't support them anyway + // on the other hand the PDF builtin fonts don't support them anyway sal_Unicode cChar = rArgs.mpStr[ nCharPos ]; if( bRightToLeft ) cChar = static_cast(GetMirroredChar( cChar )); - if( cChar & 0xff00 ) + if( 1 ) // TODO: shortcut for ASCII? { - // some characters can be used by conversion - if( (cChar >= 0xf000) && mbIsSymbolFont ) - cChar -= 0xf000; - else - { - sal_Char aBuf[4]; - sal_uInt32 nInfo; - sal_Size nSrcCvtChars; + sal_Char aBuf[4]; + sal_uInt32 nInfo; + sal_Size nSrcCvtChars; - sal_Size nConv = rtl_convertUnicodeToText( aConv, - NULL, - &cChar, 1, - aBuf, 1, - RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR, - &nInfo, &nSrcCvtChars ); - // check whether conversion was possible - // else fallback font is needed as the standard fonts - // are handled via WinAnsi encoding - if( nConv > 0 ) - cChar = ((sal_Unicode)aBuf[0]) & 0x00ff; - } + sal_Size nConv = rtl_convertUnicodeToText( aConv, + NULL, + &cChar, 1, + aBuf, sizeof(aBuf)/sizeof(*aBuf), + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR, + &nInfo, &nSrcCvtChars ); + // check whether conversion was possible + // else fallback font is needed as the standard fonts + // are handled via WinAnsi encoding + if( nConv > 0 ) + cChar = ((sal_Unicode)aBuf[0]) & 0x00ff; } if( cChar & 0xff00 ) { @@ -2088,7 +2079,7 @@ bool PDFSalLayout::LayoutText( ImplLayoutArgs& rArgs ) } long nGlyphWidth = (long)mrBuiltinFont.m_aWidths[cChar] * mnPixelPerEM; - long nGlyphFlags = (nGlyphWidth > 0) ? 0 : GlyphItem::IS_IN_CLUSTER; + long nGlyphFlags = 0; // builtin fonts don't have diacritic glyphs if( bRightToLeft ) nGlyphFlags |= GlyphItem::IS_RTL_GLYPH; // TODO: get kerning from builtin fonts @@ -2782,7 +2773,7 @@ sal_Int32 PDFWriterImpl::emitBuiltinFont( const ImplFontData* pFont, sal_Int32 n "<m_pPSName, aLine ); aLine.append( "\n" ); - if( pBuiltinFont->m_eCharSet != RTL_TEXTENCODING_SYMBOL ) + if( pBuiltinFont->m_eCharSet == RTL_TEXTENCODING_MS_1252 ) aLine.append( "/Encoding/WinAnsiEncoding\n" ); aLine.append( ">>\nendobj\n\n" ); CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) ); diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index adbc2a8de06e..b074a658ac3b 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -5056,11 +5056,11 @@ MenuBarWindow::MenuBarWindow( Window* pParent ) : if( pResMgr ) { - Bitmap aBitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) ); - Bitmap aBitmapHC( ResId( SV_RESID_BITMAP_CLOSEDOCHC, *pResMgr ) ); + BitmapEx aBitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) ); + BitmapEx aBitmapHC( ResId( SV_RESID_BITMAP_CLOSEDOCHC, *pResMgr ) ); - aCloser.maImage = Image( aBitmap, Color( COL_LIGHTMAGENTA ) ); - aCloser.maImageHC = Image( aBitmapHC, Color( COL_LIGHTMAGENTA ) ); + aCloser.maImage = Image( aBitmap ); + aCloser.maImageHC = Image( aBitmapHC ); aCloser.SetOutStyle( TOOLBOX_STYLE_FLAT ); aCloser.SetBackground(); diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx index 0a738f829cc8..bb08477e82e9 100644 --- a/vcl/unx/gtk/app/gtkdata.cxx +++ b/vcl/unx/gtk/app/gtkdata.cxx @@ -126,6 +126,12 @@ void signalScreenSizeChanged( GdkScreen* pScreen, gpointer data ) pDisp->screenSizeChanged( pScreen ); } +void signalMonitorsChanged( GdkScreen* pScreen, gpointer data ) +{ + GtkSalDisplay* pDisp = (GtkSalDisplay*)data; + pDisp->monitorsChanged( pScreen ); +} + } GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event, @@ -192,6 +198,8 @@ void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen ) { rSD.m_aSize = Size( gdk_screen_get_width( pScreen ), gdk_screen_get_height( pScreen ) ); + if( ! m_aFrames.empty() ) + m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 ); } } else @@ -201,6 +209,36 @@ void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen ) } } +void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen ) +{ + if( pScreen ) + { + if( gdk_display_get_n_screens(m_pGdkDisplay) == 1 ) + { + int nScreen = gdk_screen_get_number( pScreen ); + if( nScreen == m_nDefaultScreen ) //To-Do, make m_aXineramaScreens a per-screen thing ? + { + gint nMonitors = gdk_screen_get_n_monitors(pScreen); + m_aXineramaScreens = std::vector(); + for (gint i = 0; i < nMonitors; ++i) + { + GdkRectangle dest; + gdk_screen_get_monitor_geometry(pScreen, i, &dest); + m_aXineramaScreens.push_back( Rectangle( Point(dest.x, + dest.y ), Size( dest.width, dest.height ) ) ); + } + m_bXinerama = m_aXineramaScreens.size() > 1; + if( ! m_aFrames.empty() ) + m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 ); + } + else + { + DBG_ERROR( "monitors for non-default screen changed, extend-me" ); + } + } + } +} + void GtkSalDisplay::initScreen( int nScreen ) const { if( nScreen < 0 || nScreen >= static_cast(m_aScreens.size()) ) @@ -626,7 +664,10 @@ void GtkXLib::Init() { GdkScreen *pScreen = gdk_display_get_screen( pGdkDisp, n ); if( pScreen ) + { g_signal_connect( G_OBJECT(pScreen), "size-changed", G_CALLBACK(signalScreenSizeChanged), m_pGtkSalDisplay ); + g_signal_connect( G_OBJECT(pScreen), "monitors-changed", G_CALLBACK(signalMonitorsChanged), m_pGtkSalDisplay ); + } } } diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx index 2692177c765a..73b4432342bf 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -114,10 +114,9 @@ extern "C" static bool hookLocks( oslModule pModule ) { typedef void (*GdkLockFn) (GCallback enter_fn, GCallback leave_fn); - rtl::OUString aSymbolName( RTL_CONSTASCII_USTRINGPARAM( "gdk_threads_set_lock_functions") ); GdkLockFn gdk_threads_set_lock_functions = - (GdkLockFn) osl_getFunctionSymbol( pModule, aSymbolName.pData ); + (GdkLockFn) osl_getAsciiFunctionSymbol( pModule, "gdk_threads_set_lock_functions" ); if ( !gdk_threads_set_lock_functions ) { #if OSL_DEBUG_LEVEL > 1 diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index b4a0974a5c18..9dbb218403d0 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -3435,10 +3435,12 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) // FIXME: need some way of fetching toolbar icon size. // aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_SMALL ); + /* #i35482# do not override HC mode per force // #i59364# high contrast mode bool bHC = ( aStyleSet.GetFaceColor().IsDark() || aStyleSet.GetWindowColor().IsDark() ); aStyleSet.SetHighContrastMode( bHC ); + */ // finally update the collected settings rSettings.SetStyleSettings( aStyleSet ); diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index 9ad5d8e13705..57f48df66c3c 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -417,6 +417,14 @@ GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) GtkSalFrame::~GtkSalFrame() { + for( unsigned int i = 0; i < sizeof(m_aGraphics)/sizeof(m_aGraphics[0]); ++i ) + { + if( !m_aGraphics[i].pGraphics ) + continue; + m_aGraphics[i].pGraphics->SetDrawable( None, m_nScreen ); + m_aGraphics[i].bInUse = false; + } + if( m_pParent ) m_pParent->m_aChildren.remove( this ); diff --git a/vcl/unx/headless/svpprn.cxx b/vcl/unx/headless/svpprn.cxx index e9d726464921..862eb99ab18d 100644 --- a/vcl/unx/headless/svpprn.cxx +++ b/vcl/unx/headless/svpprn.cxx @@ -195,7 +195,7 @@ static bool passFileToCommandLine( const String& rFilename, const String& rComma struct stat aStat; if( stat( aFilename.GetBuffer(), &aStat ) ) fprintf( stderr, "stat( %s ) failed\n", aFilename.GetBuffer() ); - fprintf( stderr, "Tmp file %s has modes: %o\n", aFilename.GetBuffer(), aStat.st_mode ); + fprintf( stderr, "Tmp file %s has modes: 0%03lo\n", aFilename.GetBuffer(), (long)aStat.st_mode ); #endif const char* argv[4]; if( ! ( argv[ 0 ] = getenv( "SHELL" ) ) ) diff --git a/vcl/unx/inc/plugins/gtk/gtkdata.hxx b/vcl/unx/inc/plugins/gtk/gtkdata.hxx index fd09bcca17e3..da0f95e8623f 100644 --- a/vcl/unx/inc/plugins/gtk/gtkdata.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkdata.hxx @@ -85,6 +85,7 @@ public: void startupNotificationCompleted() { m_bStartupCompleted = true; } void screenSizeChanged( GdkScreen* ); + void monitorsChanged( GdkScreen* ); }; diff --git a/vcl/unx/inc/salgdi.h b/vcl/unx/inc/salgdi.h index bfe25b84d150..16276cdeb5c9 100644 --- a/vcl/unx/inc/salgdi.h +++ b/vcl/unx/inc/salgdi.h @@ -87,7 +87,8 @@ protected: SalColormap *m_pDeleteColormap; Drawable hDrawable_; // use int m_nScreen; - void* pRenderFormat_; + void* m_pRenderFormat; + XID m_aRenderPicture; CairoFontsCache m_aCairoFontsCache; XLIB_Region pPaintRegion_; @@ -215,14 +216,14 @@ public: inline const SalVisual& GetVisual() const; inline Drawable GetDrawable() const { return hDrawable_; } void SetDrawable( Drawable d, int nScreen ); - inline void* GetXRenderFormat() { return pRenderFormat_; } - inline void SetXRenderFormat( void* pRenderFormat ) { pRenderFormat_ = pRenderFormat; } + XID GetXRenderPicture(); + void* GetXRenderFormat() const { return m_pRenderFormat; } + inline void SetXRenderFormat( void* pRenderFormat ) { m_pRenderFormat = pRenderFormat; } inline const SalColormap& GetColormap() const { return *m_pColormap; } using SalGraphics::GetPixel; inline Pixel GetPixel( SalColor nSalColor ) const; - int GetScreenNumber() const - { return m_nScreen; } + int GetScreenNumber() const { return m_nScreen; } // overload all pure virtual methods virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ); @@ -248,7 +249,7 @@ public: virtual void SetROPFillColor( SalROPColor nROPColor ); virtual void SetTextColor( SalColor nSalColor ); - virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); + virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); virtual void GetFontMetric( ImplFontMetricData* ); virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); virtual ImplFontCharMap* GetImplFontCharMap() const; diff --git a/vcl/unx/kde/kdedata.cxx b/vcl/unx/kde/kdedata.cxx index 6dae2bd55f33..d0da9ec0cbce 100644 --- a/vcl/unx/kde/kdedata.cxx +++ b/vcl/unx/kde/kdedata.cxx @@ -248,7 +248,7 @@ extern "C" { if( nMajor != 3 || nMinor < 2 || (nMinor == 2 && nMicro < 2) ) { #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "unsuitable qt version %d.%d.%d\n", nMajor, nMinor, nMicro ); + fprintf( stderr, "unsuitable qt version %d.%d.%d\n", (int)nMajor, (int)nMinor, (int)nMicro ); #endif return NULL; } diff --git a/vcl/unx/kde/salnativewidgets-kde.cxx b/vcl/unx/kde/salnativewidgets-kde.cxx index 6667520c3982..24358022d6a1 100644 --- a/vcl/unx/kde/salnativewidgets-kde.cxx +++ b/vcl/unx/kde/salnativewidgets-kde.cxx @@ -2035,10 +2035,12 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings ) // Scroll bar size aStyleSettings.SetScrollBarSize( kapp->style().pixelMetric( QStyle::PM_ScrollBarExtent ) ); + /* #i35482# do not override HC mode // #i59364# high contrast mode bool bHC = ( aStyleSettings.GetFaceColor().IsDark() || aStyleSettings.GetWindowColor().IsDark() ); aStyleSettings.SetHighContrastMode( bHC ); + */ rSettings.SetStyleSettings( aStyleSettings ); } diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx index 328129ef3e29..07955d426b8c 100644 --- a/vcl/unx/source/app/saldisp.cxx +++ b/vcl/unx/source/app/saldisp.cxx @@ -831,24 +831,28 @@ void SalDisplay::Init() int nDisplayScreens = ScreenCount( pDisp_ ); m_aScreens = std::vector(nDisplayScreens); - const char *value; + mbExactResolution = false; /* #i15507# * Xft resolution should take precedence since * it is what modern desktops use. */ - if ((value = XGetDefault (pDisp_, "Xft", "dpi"))) + const char* pValStr = XGetDefault( pDisp_, "Xft", "dpi" ); + if( pValStr != NULL ) { - rtl::OString str (value); - long dpi = (long) str.toDouble(); - aResolution_ = Pair( dpi, dpi ); - mbExactResolution = true; + const rtl::OString aValStr( pValStr ); + const long nDPI = (long) aValStr.toDouble(); + // guard against insane resolution + if( (nDPI >= 50) && (nDPI <= 500) ) + { + aResolution_ = Pair( nDPI, nDPI ); + mbExactResolution = true; + } } - else + if( mbExactResolution == false ) { aResolution_ = Pair( DPI( WidthOfScreen( DefaultScreenOfDisplay( pDisp_ ) ), DisplayWidthMM ( pDisp_, m_nDefaultScreen ) ), DPI( HeightOfScreen( DefaultScreenOfDisplay( pDisp_ ) ), DisplayHeightMM( pDisp_, m_nDefaultScreen ) ) ); - mbExactResolution = false; } nMaxRequestSize_ = XExtendedMaxRequestSize( pDisp_ ) * 4; diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx index ddff0043e792..db49c97de00c 100644 --- a/vcl/unx/source/gdi/salgdi.cxx +++ b/vcl/unx/source/gdi/salgdi.cxx @@ -1,1481 +1,1539 @@ -/************************************************************************* - * - * 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: salgdi.cxx,v $ - * $Revision: 1.53.16.1 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - -#include "Xproto.h" - -#include "salunx.h" -#include "saldata.hxx" -#include "saldisp.hxx" -#include "salgdi.h" -#include "salframe.h" -#include "salvd.h" -#include "xrender_peer.hxx" - -#include "vcl/printergfx.hxx" -#include "vcl/jobdata.hxx" - -#include "tools/debug.hxx" - -#include "basegfx/polygon/b2dpolygon.hxx" -#include "basegfx/polygon/b2dpolypolygon.hxx" -#include "basegfx/polygon/b2dpolypolygontools.hxx" -#include "basegfx/polygon/b2dpolygontools.hxx" -#include "basegfx/polygon/b2dpolygonclipper.hxx" -#include "basegfx/polygon/b2dlinegeometry.hxx" -#include "basegfx/matrix/b2dhommatrix.hxx" -#include "basegfx/polygon/b2dpolypolygoncutter.hxx" - -#include -#include -#include - -// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#define STATIC_POINTS 64 - -class SalPolyLine -{ - XPoint Points_[STATIC_POINTS]; - XPoint *pFirst_; -public: - inline SalPolyLine( ULONG nPoints ); - inline SalPolyLine( ULONG nPoints, const SalPoint *p ); - inline ~SalPolyLine(); - inline XPoint &operator [] ( ULONG n ) const - { return pFirst_[n]; } -}; - -inline SalPolyLine::SalPolyLine( ULONG nPoints ) - : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) -{} - -inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p ) - : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) -{ - for( ULONG i = 0; i < nPoints; i++ ) - { - pFirst_[i].x = (short)p[i].mnX; - pFirst_[i].y = (short)p[i].mnY; - } - pFirst_[nPoints] = pFirst_[0]; // close polyline -} - -inline SalPolyLine::~SalPolyLine() -{ if( pFirst_ != Points_ ) delete [] pFirst_; } - -#undef STATIC_POINTS -// -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -X11SalGraphics::X11SalGraphics() -{ - m_pFrame = NULL; - m_pVDev = NULL; - m_pDeleteColormap = NULL; - hDrawable_ = None; - pRenderFormat_ = NULL; - - pClipRegion_ = NULL; - pPaintRegion_ = NULL; - - pPenGC_ = NULL; - nPenPixel_ = 0; - nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black - - pFontGC_ = NULL; - for( int i = 0; i < MAX_FALLBACK; ++i ) - { - mXFont[i] = NULL; - mpServerFont[i] = NULL; - } - - nTextPixel_ = 0; - nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black - - pBrushGC_ = NULL; - nBrushPixel_ = 0; - nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White - hBrush_ = None; - - pMonoGC_ = NULL; - pCopyGC_ = NULL; - pMaskGC_ = NULL; - pInvertGC_ = NULL; - pInvert50GC_ = NULL; - pStippleGC_ = NULL; - pTrackingGC_ = NULL; - - bWindow_ = FALSE; - bPrinter_ = FALSE; - bVirDev_ = FALSE; - bPenGC_ = FALSE; - bFontGC_ = FALSE; - bBrushGC_ = FALSE; - bMonoGC_ = FALSE; - bCopyGC_ = FALSE; - bInvertGC_ = FALSE; - bInvert50GC_ = FALSE; - bStippleGC_ = FALSE; - bTrackingGC_ = FALSE; - bXORMode_ = FALSE; - bDitherBrush_ = FALSE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -X11SalGraphics::~X11SalGraphics() -{ - ReleaseFonts(); - freeResources(); -} - -// -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -void X11SalGraphics::freeResources() -{ - Display *pDisplay = GetXDisplay(); - - DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" ); - if( pClipRegion_ ) XDestroyRegion( pClipRegion_ ), pClipRegion_ = None; - - if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None; - if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None; - if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None; - if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None; - if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None; - if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None; - if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None; - if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None; - if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None; - if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None; - if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None; - if( m_pDeleteColormap ) - delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL; - - bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false; -} - -void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen ) -{ - if( nScreen != m_nScreen ) - { - freeResources(); - m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen ); - m_nScreen = nScreen; - } - hDrawable_ = aDrawable; - nPenPixel_ = GetPixel( nPenColor_ ); - nTextPixel_ = GetPixel( nTextColor_ ); - nBrushPixel_ = GetPixel( nBrushColor_ ); -} - -void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen ) -{ - m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); - hDrawable_ = aTarget; - m_nScreen = nScreen; - - bWindow_ = TRUE; - m_pFrame = pFrame; - m_pVDev = NULL; - - nPenPixel_ = GetPixel( nPenColor_ ); - nTextPixel_ = GetPixel( nTextColor_ ); - nBrushPixel_ = GetPixel( nBrushColor_ ); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::DeInit() -{ - hDrawable_ = None; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const -{ - Display *pDisplay = GetXDisplay(); - - int n = 0; - XLIB_Region Regions[3]; - - if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ ) - Regions[n++] = pClipRegion_; -// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ ) -// Regions[n++] = pPaintRegion_; - - if( pXReg && !XEmptyRegion( pXReg ) ) - Regions[n++] = pXReg; - - if( 0 == n ) - XSetClipMask( pDisplay, pGC, None ); - else if( 1 == n ) - XSetRegion( pDisplay, pGC, Regions[0] ); - else - { - XLIB_Region pTmpRegion = XCreateRegion(); - XIntersectRegion( Regions[0], Regions[1], pTmpRegion ); -// if( 3 == n ) -// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion ); - XSetRegion( pDisplay, pGC, pTmpRegion ); - XDestroyRegion( pTmpRegion ); - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -GC X11SalGraphics::SelectPen() -{ - Display *pDisplay = GetXDisplay(); - - if( !pPenGC_ ) - { - XGCValues values; - values.subwindow_mode = ClipByChildren; - values.fill_rule = EvenOddRule; // Pict import/ Gradient - values.graphics_exposures = False; - - pPenGC_ = XCreateGC( pDisplay, hDrawable_, - GCSubwindowMode | GCFillRule | GCGraphicsExposures, - &values ); - } - - if( !bPenGC_ ) - { - if( nPenColor_ != SALCOLOR_NONE ) - XSetForeground( pDisplay, pPenGC_, nPenPixel_ ); - XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy ); - SetClipRegion( pPenGC_ ); - bPenGC_ = TRUE; - } - - return pPenGC_; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -GC X11SalGraphics::SelectBrush() -{ - Display *pDisplay = GetXDisplay(); - - DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" ); - - if( !pBrushGC_ ) - { - XGCValues values; - // values.subwindow_mode = IncludeInferiors; - values.subwindow_mode = ClipByChildren; - values.fill_rule = EvenOddRule; // Pict import/ Gradient - values.graphics_exposures = False; - - pBrushGC_ = XCreateGC( pDisplay, hDrawable_, - GCSubwindowMode | GCFillRule | GCGraphicsExposures, - &values ); - } - - if( !bBrushGC_ ) - { - if( !bDitherBrush_ ) - { - XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); - XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ ); - #if defined(_USE_PRINT_EXTENSION_) - XSetBackground( pDisplay, pBrushGC_, - WhitePixel(pDisplay, DefaultScreen(pDisplay)) ); - #else - if( bPrinter_ ) - XSetTile( pDisplay, pBrushGC_, None ); - #endif - } - else - { - // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect - // changes of the tile. PROPERTY_BUG_Tile doesn't fix this ! - if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile) - XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); - - XSetFillStyle ( pDisplay, pBrushGC_, FillTiled ); - XSetTile ( pDisplay, pBrushGC_, hBrush_ ); - } - XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy ); - SetClipRegion( pBrushGC_ ); - - bBrushGC_ = TRUE; - } - - return pBrushGC_; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -GC X11SalGraphics::GetTrackingGC() -{ - const char dash_list[2] = {2, 2}; - - if( !pTrackingGC_ ) - { - XGCValues values; - - values.graphics_exposures = False; - values.foreground = m_pColormap->GetBlackPixel() - ^ m_pColormap->GetWhitePixel(); - values.function = GXxor; - values.line_width = 1; - values.line_style = LineOnOffDash; - - pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(), - GCGraphicsExposures | GCForeground | GCFunction - | GCLineWidth | GCLineStyle, - &values ); - XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 ); - } - - if( !bTrackingGC_ ) - { - SetClipRegion( pTrackingGC_ ); - bTrackingGC_ = TRUE; - } - - return pTrackingGC_; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::DrawLines( ULONG nPoints, - const SalPolyLine &rPoints, - GC pGC, - bool bClose - ) -{ - // errechne wie viele Linien XWindow auf einmal zeichnen kann - ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq)) - / sizeof(xPoint); - if( nMaxLines > nPoints ) nMaxLines = nPoints; - - // gebe alle Linien aus, die XWindows zeichnen kann. - ULONG n; - for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 ) - XDrawLines( GetXDisplay(), - GetDrawable(), - pGC, - &rPoints[n], - nMaxLines, - CoordModeOrigin ); - - if( n < nPoints ) - XDrawLines( GetXDisplay(), - GetDrawable(), - pGC, - &rPoints[n], - nPoints - n, - CoordModeOrigin ); - if( bClose ) - { - if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y ) - drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y ); - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// Dithern: Calculate a dither-pixmap and make a brush of it -#define P_DELTA 51 -#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA)) - -BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor ) -{ - static const short nOrdDither8Bit[ 8 ][ 8 ] = - { - { 0, 38, 9, 48, 2, 40, 12, 50}, - {25, 12, 35, 22, 28, 15, 37, 24}, - { 6, 44, 3, 41, 8, 47, 5, 44}, - {32, 19, 28, 16, 34, 21, 31, 18}, - { 1, 40, 11, 49, 0, 39, 10, 48}, - {27, 14, 36, 24, 26, 13, 36, 23}, - { 8, 46, 4, 43, 7, 45, 4, 42}, - {33, 20, 30, 17, 32, 20, 29, 16} - }; - - // test for correct depth (8bit) - if( GetColormap().GetVisual().GetDepth() != 8 ) - return FALSE; - - char pBits[64]; - char *pBitsPtr = pBits; - - // Set the pallette-entries for the dithering tile - UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor ); - UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor ); - UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor ); - - for( int nY = 0; nY < 8; nY++ ) - { - for( int nX = 0; nX < 8; nX++ ) - { - short nMagic = nOrdDither8Bit[nY][nX]; - UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic ); - UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic ); - UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic ); - - *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) ); - } - } - - // create the tile as ximage and an according pixmap -> caching - XImage *pImage = XCreateImage( GetXDisplay(), - GetColormap().GetXVisual(), - 8, - ZPixmap, - 0, // offset - pBits, // data - 8, 8, // width & height - 8, // bitmap_pad - 0 ); // (default) bytes_per_line - - if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile ) - { - if (hBrush_) - XFreePixmap (GetXDisplay(), hBrush_); - hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); - } - else - if( !hBrush_ ) - hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); - - // put the ximage to the pixmap - XPutImage( GetXDisplay(), - hBrush_, - GetDisplay()->GetCopyGC( m_nScreen ), - pImage, - 0, 0, // Source - 0, 0, // Destination - 8, 8 ); // width & height - - // destroy image-frame but not palette-data - pImage->data = NULL; - XDestroyImage( pImage ); - - return TRUE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const -{ - const SalDisplay *pDisplay = GetDisplay(); - - rDPIX = pDisplay->GetResolution().A(); - rDPIY = pDisplay->GetResolution().B(); - if( !pDisplay->GetExactResolution() && rDPIY < 96 ) - { - rDPIX = Divide( rDPIX * 96, rDPIY ); - rDPIY = 96; - } - else if ( rDPIY > 200 ) - { - rDPIX = Divide( rDPIX * 200, rDPIY ); - rDPIY = 200; - } - - // #i12705# equalize x- and y-resolution if they are close enough - if( rDPIX != rDPIY ) - { - // different x- and y- resolutions are usually artifacts of - // a wrongly calculated screen size. - //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30% - { -#ifdef DEBUG - printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n", - rDPIX,rDPIY,rDPIY,rDPIY); -#endif - rDPIX = rDPIY; // y-resolution is more trustworthy - } - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -USHORT X11SalGraphics::GetBitCount() // const -{ - return GetVisual().GetDepth(); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -long X11SalGraphics::GetGraphicsWidth() const -{ - if( m_pFrame ) - return m_pFrame->maGeometry.nWidth; - else if( m_pVDev ) - return m_pVDev->GetWidth(); - else - return 0; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -long X11SalGraphics::GetGraphicsHeight() const -{ - if( m_pFrame ) - return m_pFrame->maGeometry.nHeight; - else if( m_pVDev ) - return m_pVDev->GetHeight(); - else - return 0; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::ResetClipRegion() -{ - if( pClipRegion_ ) - { - bPenGC_ = FALSE; - bFontGC_ = FALSE; - bBrushGC_ = FALSE; - bMonoGC_ = FALSE; - bCopyGC_ = FALSE; - bInvertGC_ = FALSE; - bInvert50GC_ = FALSE; - bStippleGC_ = FALSE; - bTrackingGC_ = FALSE; - - XDestroyRegion( pClipRegion_ ); - pClipRegion_ = NULL; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::BeginSetClipRegion( ULONG ) -{ - if( pClipRegion_ ) - XDestroyRegion( pClipRegion_ ); - pClipRegion_ = XCreateRegion(); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -BOOL X11SalGraphics::unionClipRegion( long nX, long nY, long nDX, long nDY ) -{ - if (!nDX || !nDY) - return TRUE; - - XRectangle aRect; - aRect.x = (short)nX; - aRect.y = (short)nY; - aRect.width = (unsigned short)nDX; - aRect.height = (unsigned short)nDY; - - XUnionRectWithRegion( &aRect, pClipRegion_, pClipRegion_ ); - - return TRUE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -bool X11SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& ) -{ - // TODO: implement and advertise OutDevSupport_B2DClip support - return false; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::EndSetClipRegion() -{ - bPenGC_ = FALSE; - bFontGC_ = FALSE; - bBrushGC_ = FALSE; - bMonoGC_ = FALSE; - bCopyGC_ = FALSE; - bInvertGC_ = FALSE; - bInvert50GC_ = FALSE; - bStippleGC_ = FALSE; - bTrackingGC_ = FALSE; - - if( XEmptyRegion( pClipRegion_ ) ) - { - XDestroyRegion( pClipRegion_ ); - pClipRegion_= NULL; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetLineColor() -{ - if( nPenColor_ != SALCOLOR_NONE ) - { - nPenColor_ = SALCOLOR_NONE; - bPenGC_ = FALSE; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetLineColor( SalColor nSalColor ) -{ - if( nPenColor_ != nSalColor ) - { - nPenColor_ = nSalColor; - nPenPixel_ = GetPixel( nSalColor ); - bPenGC_ = FALSE; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetFillColor() -{ - if( nBrushColor_ != SALCOLOR_NONE ) - { - bDitherBrush_ = FALSE; - nBrushColor_ = SALCOLOR_NONE; - bBrushGC_ = FALSE; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetFillColor( SalColor nSalColor ) -{ - if( nBrushColor_ != nSalColor ) - { - bDitherBrush_ = FALSE; - nBrushColor_ = nSalColor; - nBrushPixel_ = GetPixel( nSalColor ); - if( TrueColor != GetColormap().GetVisual().GetClass() - && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_ - && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black - && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue - && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green - && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan - && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red - && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta - && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown - && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray - && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray - && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue - && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green - && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan - && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red - && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta - && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown - && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ) - bDitherBrush_ = GetDitherPixmap(nSalColor); - bBrushGC_ = FALSE; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor ) -{ - switch( nROPColor ) - { - case SAL_ROP_0 : // 0 - nPenPixel_ = (Pixel)0; - break; - case SAL_ROP_1 : // 1 - nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; - break; - case SAL_ROP_INVERT : // 2 - nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; - break; - } - nPenColor_ = GetColormap().GetColor( nPenPixel_ ); - bPenGC_ = FALSE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor ) -{ - switch( nROPColor ) - { - case SAL_ROP_0 : // 0 - nBrushPixel_ = (Pixel)0; - break; - case SAL_ROP_1 : // 1 - nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; - break; - case SAL_ROP_INVERT : // 2 - nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; - break; - } - bDitherBrush_ = FALSE; - nBrushColor_ = GetColormap().GetColor( nBrushPixel_ ); - bBrushGC_ = FALSE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::SetXORMode( bool bSet, bool ) -{ - if( !bXORMode_ == bSet ) - { - bXORMode_ = bSet; - bPenGC_ = FALSE; - bBrushGC_ = FALSE; - bMonoGC_ = FALSE; - bCopyGC_ = FALSE; - bInvertGC_ = FALSE; - bInvert50GC_ = FALSE; - bStippleGC_ = FALSE; - bTrackingGC_ = FALSE; - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawPixel( long nX, long nY ) -{ - if( nPenColor_ != SALCOLOR_NONE ) - XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY ); -} - -void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) -{ - if( nSalColor != SALCOLOR_NONE ) - { - Display *pDisplay = GetXDisplay(); - - if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ ) - { - SetLineColor( nSalColor ); - XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY ); - nPenColor_ = SALCOLOR_NONE; - bPenGC_ = False; - } - else - { - GC pGC = SelectPen(); - - if( nSalColor != nPenColor_ ) - XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) ); - - XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY ); - - if( nSalColor != nPenColor_ ) - XSetForeground( pDisplay, pGC, nPenPixel_ ); - } - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) -{ - if( nPenColor_ != SALCOLOR_NONE ) - { - if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine ) - { - GC aGC = SelectPen(); - XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1); - XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2); - XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 ); - } - else - XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(), - nX1, nY1, nX2, nY2 ); - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY ) -{ - if( nBrushColor_ != SALCOLOR_NONE ) - { - XFillRectangle( GetXDisplay(), - GetDrawable(), - SelectBrush(), - nX, nY, nDX, nDY ); - } - // Beschreibung DrawRect verkehrt, deshalb -1 - if( nPenColor_ != SALCOLOR_NONE ) - XDrawRectangle( GetXDisplay(), - GetDrawable(), - SelectPen(), - nX, nY, nDX-1, nDY-1 ); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry ) -{ - drawPolyLine( nPoints, pPtAry, false ); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry, bool bClose ) -{ - if( nPenColor_ != 0xFFFFFFFF ) - { - SalPolyLine Points( nPoints, pPtAry ); - - DrawLines( nPoints, Points, SelectPen(), bClose ); - } -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry ) -{ - if( nPoints == 0 ) - return; - - if( nPoints < 3 ) - { - if( !bXORMode_ ) - { - if( 1 == nPoints ) - drawPixel( pPtAry[0].mnX, pPtAry[0].mnY ); - else - drawLine( pPtAry[0].mnX, pPtAry[0].mnY, - pPtAry[1].mnX, pPtAry[1].mnY ); - } - return; - } - - SalPolyLine Points( nPoints, pPtAry ); - - nPoints++; - - /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case) - * do not draw the visible part of a polygon - * if it overlaps to the left of screen 0,y. - * This happens to be the case in the gradient drawn in the - * menubar background. workaround for the special case of - * of a rectangle overlapping to the left. - */ - if( nPoints == 5 && - Points[ 0 ].x == Points[ 1 ].x && - Points[ 1 ].y == Points[ 2 ].y && - Points[ 2 ].x == Points[ 3 ].x && - Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y - ) - { - bool bLeft = false; - bool bRight = false; - for(unsigned int i = 0; i < nPoints; i++ ) - { - if( Points[i].x < 0 ) - bLeft = true; - else - bRight= true; - } - if( bLeft && ! bRight ) - return; - if( bLeft && bRight ) - { - for( unsigned int i = 0; i < nPoints; i++ ) - if( Points[i].x < 0 ) - Points[i].x = 0; - } - } - - if( nBrushColor_ != SALCOLOR_NONE ) - XFillPolygon( GetXDisplay(), - GetDrawable(), - SelectBrush(), - &Points[0], nPoints, - Complex, CoordModeOrigin ); - - if( nPenColor_ != 0xFFFFFFFF ) - DrawLines( nPoints, Points, SelectPen(), true ); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly, - const sal_uInt32 *pPoints, - PCONSTSALPOINT *pPtAry ) -{ - if( nBrushColor_ != SALCOLOR_NONE ) - { - ULONG i, n; - XLIB_Region pXRegA = NULL; - - for( i = 0; i < nPoly; i++ ) { - n = pPoints[i]; - SalPolyLine Points( n, pPtAry[i] ); - if( n > 2 ) - { - XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule ); - if( !pXRegA ) - pXRegA = pXRegB; - else - { - XXorRegion( pXRegA, pXRegB, pXRegA ); - XDestroyRegion( pXRegB ); - } - } - } - - if( pXRegA ) - { - XRectangle aXRect; - XClipBox( pXRegA, &aXRect ); - - GC pGC = SelectBrush(); - SetClipRegion( pGC, pXRegA ); // ??? doppelt - XDestroyRegion( pXRegA ); - bBrushGC_ = FALSE; - - XFillRectangle( GetXDisplay(), - GetDrawable(), - pGC, - aXRect.x, aXRect.y, aXRect.width, aXRect.height ); - } - } - - if( nPenColor_ != SALCOLOR_NONE ) - for( ULONG i = 0; i < nPoly; i++ ) - drawPolyLine( pPoints[i], pPtAry[i], true ); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -sal_Bool X11SalGraphics::drawPolyLineBezier( ULONG, const SalPoint*, const BYTE* ) -{ - return sal_False; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -sal_Bool X11SalGraphics::drawPolygonBezier( ULONG, const SalPoint*, const BYTE* ) -{ - return sal_False; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*, - const SalPoint* const*, const BYTE* const* ) -{ - return sal_False; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -void X11SalGraphics::invert( ULONG nPoints, - const SalPoint* pPtAry, - SalInvert nFlags ) -{ - SalPolyLine Points ( nPoints, pPtAry ); - - GC pGC; - if( SAL_INVERT_50 & nFlags ) - pGC = GetInvert50GC(); - else - if ( SAL_INVERT_TRACKFRAME & nFlags ) - pGC = GetTrackingGC(); - else - pGC = GetInvertGC(); - - if( SAL_INVERT_TRACKFRAME & nFlags ) - DrawLines ( nPoints, Points, pGC, true ); - else - XFillPolygon( GetXDisplay(), - GetDrawable(), - pGC, - &Points[0], nPoints, - Complex, CoordModeOrigin ); -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG ) -{ - return FALSE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -SystemGraphicsData X11SalGraphics::GetGraphicsData() const -{ - SystemGraphicsData aRes; - - aRes.nSize = sizeof(aRes); - aRes.pDisplay = GetXDisplay(); - aRes.hDrawable = hDrawable_; - aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); - aRes.nScreen = m_nScreen; - aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth(); - aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap(); - aRes.pRenderFormat = pRenderFormat_; - return aRes; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -// B2DPolygon support methods - -namespace { // anonymous namespace to prevent export -// the methods and structures here are used by the -// B2DPolyPolygon->RenderTrapezoid conversion algorithm - -// compare two line segments -// assumption: both segments point downward -// assumption: they must have at least some y-overlap -// assumption: rA.p1.y <= rB.p1.y -bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB ) -{ - bool bAbove = (rA.p1.y <= rB.p1.y); - const XLineFixed& rU = bAbove ? rA : rB; - const XLineFixed& rL = bAbove ? rB : rA; - - const XFixed aXDiff = rU.p2.x - rU.p1.x; - const XFixed aYDiff = rU.p2.y - rU.p1.y; - - 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); - const sal_Int64 n2 = (sal_Int64)aYDiff * (rL.p1.x - rU.p1.x); - if( n1 != n2 ) - return ((n1 < n2) == bAbove); - } - - 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); - const sal_Int64 n4 = (sal_Int64)aYDiff * (rL.p2.x - rU.p1.x); - if( n3 != n4 ) - return ((n3 < n4) == bAbove); - } - - // both segments overlap - return false; -} - -struct HalfTrapezoid -{ - // assumptions: - // maLine.p1.y <= mnY < maLine.p2.y - XLineFixed maLine; - XFixed mnY; -}; - -struct HalfTrapCompare -{ - bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const - { - bool bIsTopLeft = false; - if( rA.mnY != rB.mnY ) // sort top-first if possible - bIsTopLeft = (rA.mnY < rB.mnY); - else // else sort left-first - bIsTopLeft = IsLeftOf( rA.maLine, rB.maLine ); - // adjust to priority_queue sorting convention - return !bIsTopLeft; - } -}; - -typedef std::priority_queue< HalfTrapezoid, std::vector, 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(); } -}; - -typedef std::vector TrapezoidVector; - -class TrapezoidXCompare -{ - const TrapezoidVector& mrVector; -public: - TrapezoidXCompare( const TrapezoidVector& rVector ) - : mrVector( rVector ) {} - bool operator()( int nA, int nB ) const - { return IsLeftOf( mrVector[nA].left, mrVector[nB].left ); } -}; - -typedef std::multiset< int, TrapezoidXCompare > ActiveTrapSet; - -class TrapezoidYCompare -{ - const TrapezoidVector& mrVector; -public: - TrapezoidYCompare( const TrapezoidVector& rVector ) - : mrVector( rVector ) {} - bool operator()( int nA, int nB ) const - { return (mrVector[nA].bottom < mrVector[nB].bottom); } -}; - -typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet; -} // end of anonymous namespace - -// draw a poly-polygon -bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency) -{ - // nothing to do for empty polypolygons - const int nPolygonCount = rPolyPoly.count(); - if( nPolygonCount <= 0 ) - return TRUE; - - // nothing to do if everything is transparent - if( (nBrushColor_ == SALCOLOR_NONE) - && (nPenColor_ == SALCOLOR_NONE) ) - return TRUE; - - // cannot handle pencolor!=brushcolor yet - if( (nPenColor_ != SALCOLOR_NONE) - && (nPenColor_ != nBrushColor_) ) - return FALSE; - - // TODO: remove the env-variable when no longer needed - static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" ); - if( pRenderEnv ) - return FALSE; - - // check xrender support for trapezoids - XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); - if( !rRenderPeer.AreTrapezoidsSupported() ) - return FALSE; - - // check xrender support for matching visual - Visual* pVisual = GetVisual().GetVisual(); - XRenderPictFormat* pVisualFormat = rRenderPeer.FindVisualFormat( pVisual ); - if( !pVisualFormat ) - return FALSE; - - // don't bother with polygons outside of visible area - const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() ); - const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rPolyPoly ); - const bool bNeedViewClip = !aPolyRange.isInside( aViewRange ); - if( !aPolyRange.overlaps( aViewRange ) ) - return TRUE; - - // convert the polypolygon to trapezoids - - // first convert the B2DPolyPolygon to HalfTrapezoids - HTQueue aHTQueue; - aHTQueue.reserve( 16384 ); // TODO: use decomposed number of points - for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx ) - { - ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx ); - - // get rid of bezier segments - if( aOuterPolygon.areControlPointsUsed() ) - aOuterPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aOuterPolygon, 0.125 ); - - // clip polygon against view - // (the call below for removing self intersections can be made much cheaper by this) - basegfx::B2DPolyPolygon aClippedPolygon( aOuterPolygon ); - if( bNeedViewClip ) - { - // TODO: move clipping before subdivision when clipPolyonRange learns to handle curves - aClippedPolygon = basegfx::tools::clipPolygonOnRange( aOuterPolygon, aViewRange, true, false ); - DBG_ASSERT( aClippedPolygon.count(), "polygon confirmed to overlap with view should not get here" ); - if( !aClippedPolygon.count() ) - continue; - } - - // test and remove self intersections - // TODO: make code intersection save, then remove this test - basegfx::B2DPolyPolygon aInnerPolyPoly(basegfx::tools::solveCrossovers( aClippedPolygon)); - const int nInnerPolyCount = aInnerPolyPoly.count(); - for( int nInnerPolyIdx = 0; nInnerPolyIdx < nInnerPolyCount; ++nInnerPolyIdx ) - { - ::basegfx::B2DPolygon aInnerPolygon = aInnerPolyPoly.getB2DPolygon( nInnerPolyIdx ); - const int nPointCount = aInnerPolygon.count(); - if( !nPointCount ) - continue; - - aHTQueue.reserve( aHTQueue.size() + 8 * nPointCount ); - - // convert polygon point pairs to HalfTrapezoids - // connect the polygon point with the first one if needed - XPointFixed aOldXPF = { 0, 0 }; - XPointFixed aNewXPF; - for( int nPointIdx = 0; nPointIdx <= nPointCount; ++nPointIdx, aOldXPF = aNewXPF ) - { - const int k = (nPointIdx < nPointCount) ? nPointIdx : 0; - const ::basegfx::B2DPoint& aPoint = aInnerPolygon.getB2DPoint( k ); - - // convert the B2DPoint into XRENDER units - if(getAntiAliasB2DDraw()) - { - aNewXPF.x = XDoubleToFixed( aPoint.getX() ); - aNewXPF.y = XDoubleToFixed( aPoint.getY() ); - } - else - { - aNewXPF.x = XDoubleToFixed( basegfx::fround( aPoint.getX() ) ); - aNewXPF.y = XDoubleToFixed( basegfx::fround( aPoint.getY() ) ); - } - - // 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; - if( aNewXPF.y < aOldXPF.y ) - { - aHT.maLine.p1 = aNewXPF; - aHT.maLine.p2 = aOldXPF; - } - else - { - aHT.maLine.p2 = aNewXPF; - aHT.maLine.p1 = aOldXPF; - } - - aHT.mnY = aHT.maLine.p1.y; - -#if 0 // ignore clipped HalfTrapezoids - if( aHT.mnY < 0 ) - aHT.mnY = 0; - else if( aHT.mnY > 10000 ) - continue; -#endif - - // queue up the HalfTrapezoid - aHTQueue.push( aHT ); - } - } - } - - if( aHTQueue.empty() ) - return TRUE; - - // then convert the HalfTrapezoids into full Trapezoids - TrapezoidVector aTrapVector; - aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess - - TrapezoidXCompare aTrapXCompare( aTrapVector ); - ActiveTrapSet aActiveTraps( aTrapXCompare ); - - TrapezoidYCompare aTrapYCompare( aTrapVector ); - VerticalTrapSet aVerticalTraps( aTrapYCompare ); - - while( !aHTQueue.empty() ) - { - XTrapezoid aTrapezoid; - - // convert a HalfTrapezoid pair - const HalfTrapezoid& rLeft = aHTQueue.top(); - aTrapezoid.top = rLeft.mnY; - aTrapezoid.bottom = rLeft.maLine.p2.y; - aTrapezoid.left = rLeft.maLine; - -#if 0 - // ignore empty trapezoids - if( aTrapezoid.bottom <= aTrapezoid.top ) - continue; -#endif - - aHTQueue.pop(); - if( aHTQueue.empty() ) // TODO: assert - break; - const HalfTrapezoid& rRight = aHTQueue.top(); - aTrapezoid.right = rRight.maLine; - aHTQueue.pop(); - - aTrapezoid.bottom = aTrapezoid.left.p2.y; - if( aTrapezoid.bottom > aTrapezoid.right.p2.y ) - aTrapezoid.bottom = aTrapezoid.right.p2.y; - - // keep the full Trapezoid candidate - aTrapVector.push_back( aTrapezoid ); - - // unless it splits an older trapezoid - bool bSplit = false; - for(;;) - { - // 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 ]; - - // 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 - if( rLeftTrap.bottom <= aTrapezoid.top ) - { - aActiveTraps.erase( aActiveTrapsIt ); - continue; - } - - // check if there is horizontal overlap - // aTrapezoid.left==rLeftTrap.right is allowed though - if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) ) - break; - - // split the old trapezoid and keep its upper part - // find the old trapezoids entry in the VerticalTrapSet and remove it - typedef std::pair VTSPair; - VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt ); - VerticalTrapSet::iterator aVTSit = aVTSPair.first; - for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ; - if( aVTSit != aVTSPair.second ) - aVerticalTraps.erase( aVTSit ); - // then update the old trapezoid's bottom - rLeftTrap.bottom = aTrapezoid.top; - // enter the updated old trapzoid in VerticalTrapSet - aVerticalTraps.insert( aVerticalTraps.begin(), *aActiveTrapsIt ); - // the old trapezoid is no longer active - aActiveTraps.erase( aActiveTrapsIt ); - - // the trapezoid causing the split has become obsolete - // so its both sides have to be re-queued - HalfTrapezoid aHT; - aHT.mnY = aTrapezoid.top; - aHT.maLine = aTrapezoid.left; - aHTQueue.push( aHT ); - aHT.maLine = aTrapezoid.right; - aHTQueue.push( aHT ); - - bSplit = true; - break; - } - - // keep or forget the resulting full Trapezoid - if( bSplit ) - aTrapVector.pop_back(); - else - { - aActiveTraps.insert( aTrapVector.size()-1 ); - aVerticalTraps.insert( aTrapVector.size()-1 ); - } - - // 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; - while( !aVerticalTraps.empty() ) - { - const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ]; - if( nNewTop < rOldTrap.bottom ) - break; - // the reference 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 ) - { - aHT.maLine = rOldTrap.left; - aHTQueue.push( aHT ); - } - if( rOldTrap.right.p2.y > rOldTrap.bottom ) - { - aHT.maLine = rOldTrap.right; - aHTQueue.push( aHT ); - } - } - } - - // create xrender Picture for polygon foreground - SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ]; - if( !rEntry.m_aPicture ) - { - Display* pXDisplay = GetXDisplay(); - - rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 ); - XRenderPictureAttributes aAttr; - aAttr.repeat = true; - - XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 ); - rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr ); - } - - // set polygon foreground color and opacity - XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency ); - rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); - - // notify xrender of target drawable - // TODO: cache the matching xrender picture in the X11SalGraphics - Picture aDst = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL ); - - // set clipping - if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) - rRenderPeer.SetPictureClipRegion( aDst, pClipRegion_ ); - - // render the trapezoids - const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8(); - rRenderPeer.CompositeTrapezoids( PictOpOver, - rEntry.m_aPicture, aDst, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() ); - - // release xrender-counterpart of target drawable - // TODO: use scoped xrender picture - rRenderPeer.FreePicture( aDst ); - - return TRUE; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin) -{ - const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); - if( !rRenderPeer.AreTrapezoidsSupported() ) - return false; - - // get the area polygon for the line polygon - basegfx::B2DPolygon aPolygon = rPolygon; - if( (rLineWidth.getX() != rLineWidth.getY()) - && !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 ); - } - - // 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)); - - 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 ); - } - - // temporarily adjust brush color to pen color - // since the line is drawn as an area-polygon - const SalColor aKeepBrushColor = nBrushColor_; - nBrushColor_ = nPenColor_; - - // draw each area polypolygon component individually - // to emulate the polypolygon winding rule "non-zero" - bool bDrawOk = true; - const int nPolyCount = aAreaPolyPoly.count(); - for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) - { - const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) ); - bDrawOk = drawPolyPolygon( aOnePoly, 0.0); - if( !bDrawOk ) - break; - } - - // restore the original brush GC - nBrushColor_ = aKeepBrushColor; - return bDrawOk; -} - -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/************************************************************************* + * + * 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 + * + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "Xproto.h" + +#include "salunx.h" +#include "saldata.hxx" +#include "saldisp.hxx" +#include "salgdi.h" +#include "salframe.h" +#include "salvd.h" +#include "xrender_peer.hxx" + +#include "vcl/printergfx.hxx" +#include "vcl/jobdata.hxx" + +#include "tools/debug.hxx" + +#include "basegfx/polygon/b2dpolygon.hxx" +#include "basegfx/polygon/b2dpolypolygon.hxx" +#include "basegfx/polygon/b2dpolypolygontools.hxx" +#include "basegfx/polygon/b2dpolygontools.hxx" +#include "basegfx/polygon/b2dpolygonclipper.hxx" +#include "basegfx/polygon/b2dlinegeometry.hxx" +#include "basegfx/matrix/b2dhommatrix.hxx" +#include "basegfx/polygon/b2dpolypolygoncutter.hxx" + +#include +#include +#include + +// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#define STATIC_POINTS 64 + +class SalPolyLine +{ + XPoint Points_[STATIC_POINTS]; + XPoint *pFirst_; +public: + inline SalPolyLine( ULONG nPoints ); + inline SalPolyLine( ULONG nPoints, const SalPoint *p ); + inline ~SalPolyLine(); + inline XPoint &operator [] ( ULONG n ) const + { return pFirst_[n]; } +}; + +inline SalPolyLine::SalPolyLine( ULONG nPoints ) + : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) +{} + +inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p ) + : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) +{ + for( ULONG i = 0; i < nPoints; i++ ) + { + pFirst_[i].x = (short)p[i].mnX; + pFirst_[i].y = (short)p[i].mnY; + } + pFirst_[nPoints] = pFirst_[0]; // close polyline +} + +inline SalPolyLine::~SalPolyLine() +{ if( pFirst_ != Points_ ) delete [] pFirst_; } + +#undef STATIC_POINTS +// -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +X11SalGraphics::X11SalGraphics() +{ + m_pFrame = NULL; + m_pVDev = NULL; + m_pDeleteColormap = NULL; + hDrawable_ = None; + m_aRenderPicture = 0; + m_pRenderFormat = NULL; + + pClipRegion_ = NULL; + pPaintRegion_ = NULL; + + pPenGC_ = NULL; + nPenPixel_ = 0; + nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black + + pFontGC_ = NULL; + for( int i = 0; i < MAX_FALLBACK; ++i ) + { + mXFont[i] = NULL; + mpServerFont[i] = NULL; + } + + nTextPixel_ = 0; + nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black + + pBrushGC_ = NULL; + nBrushPixel_ = 0; + nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White + hBrush_ = None; + + pMonoGC_ = NULL; + pCopyGC_ = NULL; + pMaskGC_ = NULL; + pInvertGC_ = NULL; + pInvert50GC_ = NULL; + pStippleGC_ = NULL; + pTrackingGC_ = NULL; + + bWindow_ = FALSE; + bPrinter_ = FALSE; + bVirDev_ = FALSE; + bPenGC_ = FALSE; + bFontGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + bXORMode_ = FALSE; + bDitherBrush_ = FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +X11SalGraphics::~X11SalGraphics() +{ + ReleaseFonts(); + freeResources(); +} + +// -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void X11SalGraphics::freeResources() +{ + Display *pDisplay = GetXDisplay(); + + DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" ); + if( pClipRegion_ ) XDestroyRegion( pClipRegion_ ), pClipRegion_ = None; + + if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None; + if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None; + if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None; + if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None; + if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None; + if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None; + if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None; + if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None; + if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None; + if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None; + if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None; + if( m_pDeleteColormap ) + delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL; + + if( m_aRenderPicture ) + XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0; + + bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false; +} + +void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen ) +{ + // shortcut if nothing changed + if( hDrawable_ == aDrawable ) + return; + + // free screen specific resources if needed + if( nScreen != m_nScreen ) + { + freeResources(); + m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen ); + m_nScreen = nScreen; + } + + hDrawable_ = aDrawable; + SetXRenderFormat( NULL ); + if( m_aRenderPicture ) + { + XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ); + m_aRenderPicture = 0; + } + + if( hDrawable_ ) + { + nPenPixel_ = GetPixel( nPenColor_ ); + nTextPixel_ = GetPixel( nTextColor_ ); + nBrushPixel_ = GetPixel( nBrushColor_ ); + } +} + +void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen ) +{ +#if 0 // TODO: use SetDrawable() instead + m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); + hDrawable_ = aTarget; + m_nScreen = nScreen; + SetXRenderFormat( NULL ); + if( m_aRenderPicture ) + XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0; + + nPenPixel_ = GetPixel( nPenColor_ ); + nTextPixel_ = GetPixel( nTextColor_ ); + nBrushPixel_ = GetPixel( nBrushColor_ ); +#else + m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); + m_nScreen = nScreen; + SetDrawable( aTarget, nScreen ); +#endif + + bWindow_ = TRUE; + m_pFrame = pFrame; + m_pVDev = NULL; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::DeInit() +{ + SetDrawable( None, m_nScreen ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const +{ + Display *pDisplay = GetXDisplay(); + + int n = 0; + XLIB_Region Regions[3]; + + if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ ) + Regions[n++] = pClipRegion_; +// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ ) +// Regions[n++] = pPaintRegion_; + + if( pXReg && !XEmptyRegion( pXReg ) ) + Regions[n++] = pXReg; + + if( 0 == n ) + XSetClipMask( pDisplay, pGC, None ); + else if( 1 == n ) + XSetRegion( pDisplay, pGC, Regions[0] ); + else + { + XLIB_Region pTmpRegion = XCreateRegion(); + XIntersectRegion( Regions[0], Regions[1], pTmpRegion ); +// if( 3 == n ) +// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion ); + XSetRegion( pDisplay, pGC, pTmpRegion ); + XDestroyRegion( pTmpRegion ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +GC X11SalGraphics::SelectPen() +{ + Display *pDisplay = GetXDisplay(); + + if( !pPenGC_ ) + { + XGCValues values; + values.subwindow_mode = ClipByChildren; + values.fill_rule = EvenOddRule; // Pict import/ Gradient + values.graphics_exposures = False; + + pPenGC_ = XCreateGC( pDisplay, hDrawable_, + GCSubwindowMode | GCFillRule | GCGraphicsExposures, + &values ); + } + + if( !bPenGC_ ) + { + if( nPenColor_ != SALCOLOR_NONE ) + XSetForeground( pDisplay, pPenGC_, nPenPixel_ ); + XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy ); + SetClipRegion( pPenGC_ ); + bPenGC_ = TRUE; + } + + return pPenGC_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +GC X11SalGraphics::SelectBrush() +{ + Display *pDisplay = GetXDisplay(); + + DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" ); + + if( !pBrushGC_ ) + { + XGCValues values; + // values.subwindow_mode = IncludeInferiors; + values.subwindow_mode = ClipByChildren; + values.fill_rule = EvenOddRule; // Pict import/ Gradient + values.graphics_exposures = False; + + pBrushGC_ = XCreateGC( pDisplay, hDrawable_, + GCSubwindowMode | GCFillRule | GCGraphicsExposures, + &values ); + } + + if( !bBrushGC_ ) + { + if( !bDitherBrush_ ) + { + XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); + XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ ); + #if defined(_USE_PRINT_EXTENSION_) + XSetBackground( pDisplay, pBrushGC_, + WhitePixel(pDisplay, DefaultScreen(pDisplay)) ); + #else + if( bPrinter_ ) + XSetTile( pDisplay, pBrushGC_, None ); + #endif + } + else + { + // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect + // changes of the tile. PROPERTY_BUG_Tile doesn't fix this ! + if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile) + XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); + + XSetFillStyle ( pDisplay, pBrushGC_, FillTiled ); + XSetTile ( pDisplay, pBrushGC_, hBrush_ ); + } + XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy ); + SetClipRegion( pBrushGC_ ); + + bBrushGC_ = TRUE; + } + + return pBrushGC_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +GC X11SalGraphics::GetTrackingGC() +{ + const char dash_list[2] = {2, 2}; + + if( !pTrackingGC_ ) + { + XGCValues values; + + values.graphics_exposures = False; + values.foreground = m_pColormap->GetBlackPixel() + ^ m_pColormap->GetWhitePixel(); + values.function = GXxor; + values.line_width = 1; + values.line_style = LineOnOffDash; + + pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(), + GCGraphicsExposures | GCForeground | GCFunction + | GCLineWidth | GCLineStyle, + &values ); + XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 ); + } + + if( !bTrackingGC_ ) + { + SetClipRegion( pTrackingGC_ ); + bTrackingGC_ = TRUE; + } + + return pTrackingGC_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::DrawLines( ULONG nPoints, + const SalPolyLine &rPoints, + GC pGC, + bool bClose + ) +{ + // errechne wie viele Linien XWindow auf einmal zeichnen kann + ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq)) + / sizeof(xPoint); + if( nMaxLines > nPoints ) nMaxLines = nPoints; + + // gebe alle Linien aus, die XWindows zeichnen kann. + ULONG n; + for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 ) + XDrawLines( GetXDisplay(), + GetDrawable(), + pGC, + &rPoints[n], + nMaxLines, + CoordModeOrigin ); + + if( n < nPoints ) + XDrawLines( GetXDisplay(), + GetDrawable(), + pGC, + &rPoints[n], + nPoints - n, + CoordModeOrigin ); + if( bClose ) + { + if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y ) + drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// Dithern: Calculate a dither-pixmap and make a brush of it +#define P_DELTA 51 +#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA)) + +BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor ) +{ + static const short nOrdDither8Bit[ 8 ][ 8 ] = + { + { 0, 38, 9, 48, 2, 40, 12, 50}, + {25, 12, 35, 22, 28, 15, 37, 24}, + { 6, 44, 3, 41, 8, 47, 5, 44}, + {32, 19, 28, 16, 34, 21, 31, 18}, + { 1, 40, 11, 49, 0, 39, 10, 48}, + {27, 14, 36, 24, 26, 13, 36, 23}, + { 8, 46, 4, 43, 7, 45, 4, 42}, + {33, 20, 30, 17, 32, 20, 29, 16} + }; + + // test for correct depth (8bit) + if( GetColormap().GetVisual().GetDepth() != 8 ) + return FALSE; + + char pBits[64]; + char *pBitsPtr = pBits; + + // Set the pallette-entries for the dithering tile + UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor ); + UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor ); + UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor ); + + for( int nY = 0; nY < 8; nY++ ) + { + for( int nX = 0; nX < 8; nX++ ) + { + short nMagic = nOrdDither8Bit[nY][nX]; + UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic ); + UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic ); + UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic ); + + *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) ); + } + } + + // create the tile as ximage and an according pixmap -> caching + XImage *pImage = XCreateImage( GetXDisplay(), + GetColormap().GetXVisual(), + 8, + ZPixmap, + 0, // offset + pBits, // data + 8, 8, // width & height + 8, // bitmap_pad + 0 ); // (default) bytes_per_line + + if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile ) + { + if (hBrush_) + XFreePixmap (GetXDisplay(), hBrush_); + hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); + } + else + if( !hBrush_ ) + hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); + + // put the ximage to the pixmap + XPutImage( GetXDisplay(), + hBrush_, + GetDisplay()->GetCopyGC( m_nScreen ), + pImage, + 0, 0, // Source + 0, 0, // Destination + 8, 8 ); // width & height + + // destroy image-frame but not palette-data + pImage->data = NULL; + XDestroyImage( pImage ); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const +{ + const SalDisplay *pDisplay = GetDisplay(); + + rDPIX = pDisplay->GetResolution().A(); + rDPIY = pDisplay->GetResolution().B(); + if( !pDisplay->GetExactResolution() && rDPIY < 96 ) + { + rDPIX = Divide( rDPIX * 96, rDPIY ); + rDPIY = 96; + } + else if ( rDPIY > 200 ) + { + rDPIX = Divide( rDPIX * 200, rDPIY ); + rDPIY = 200; + } + + // #i12705# equalize x- and y-resolution if they are close enough + if( rDPIX != rDPIY ) + { + // different x- and y- resolutions are usually artifacts of + // a wrongly calculated screen size. + //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30% + { +#ifdef DEBUG + printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n", + rDPIX,rDPIY,rDPIY,rDPIY); +#endif + rDPIX = rDPIY; // y-resolution is more trustworthy + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +USHORT X11SalGraphics::GetBitCount() // const +{ + return GetVisual().GetDepth(); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long X11SalGraphics::GetGraphicsWidth() const +{ + if( m_pFrame ) + return m_pFrame->maGeometry.nWidth; + else if( m_pVDev ) + return m_pVDev->GetWidth(); + else + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long X11SalGraphics::GetGraphicsHeight() const +{ + if( m_pFrame ) + return m_pFrame->maGeometry.nHeight; + else if( m_pVDev ) + return m_pVDev->GetHeight(); + else + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::ResetClipRegion() +{ + if( pClipRegion_ ) + { + bPenGC_ = FALSE; + bFontGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + + XDestroyRegion( pClipRegion_ ); + pClipRegion_ = NULL; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::BeginSetClipRegion( ULONG ) +{ + if( pClipRegion_ ) + XDestroyRegion( pClipRegion_ ); + pClipRegion_ = XCreateRegion(); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +BOOL X11SalGraphics::unionClipRegion( long nX, long nY, long nDX, long nDY ) +{ + if (!nDX || !nDY) + return TRUE; + + XRectangle aRect; + aRect.x = (short)nX; + aRect.y = (short)nY; + aRect.width = (unsigned short)nDX; + aRect.height = (unsigned short)nDY; + + XUnionRectWithRegion( &aRect, pClipRegion_, pClipRegion_ ); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +bool X11SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& ) +{ + // TODO: implement and advertise OutDevSupport_B2DClip support + return false; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::EndSetClipRegion() +{ + bPenGC_ = FALSE; + bFontGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + + if( XEmptyRegion( pClipRegion_ ) ) + { + XDestroyRegion( pClipRegion_ ); + pClipRegion_= NULL; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetLineColor() +{ + if( nPenColor_ != SALCOLOR_NONE ) + { + nPenColor_ = SALCOLOR_NONE; + bPenGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetLineColor( SalColor nSalColor ) +{ + if( nPenColor_ != nSalColor ) + { + nPenColor_ = nSalColor; + nPenPixel_ = GetPixel( nSalColor ); + bPenGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetFillColor() +{ + if( nBrushColor_ != SALCOLOR_NONE ) + { + bDitherBrush_ = FALSE; + nBrushColor_ = SALCOLOR_NONE; + bBrushGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetFillColor( SalColor nSalColor ) +{ + if( nBrushColor_ != nSalColor ) + { + bDitherBrush_ = FALSE; + nBrushColor_ = nSalColor; + nBrushPixel_ = GetPixel( nSalColor ); + if( TrueColor != GetColormap().GetVisual().GetClass() + && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_ + && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black + && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue + && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green + && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan + && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red + && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta + && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown + && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray + && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray + && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue + && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green + && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan + && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red + && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta + && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown + && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ) + bDitherBrush_ = GetDitherPixmap(nSalColor); + bBrushGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor ) +{ + switch( nROPColor ) + { + case SAL_ROP_0 : // 0 + nPenPixel_ = (Pixel)0; + break; + case SAL_ROP_1 : // 1 + nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + case SAL_ROP_INVERT : // 2 + nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + } + nPenColor_ = GetColormap().GetColor( nPenPixel_ ); + bPenGC_ = FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor ) +{ + switch( nROPColor ) + { + case SAL_ROP_0 : // 0 + nBrushPixel_ = (Pixel)0; + break; + case SAL_ROP_1 : // 1 + nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + case SAL_ROP_INVERT : // 2 + nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + } + bDitherBrush_ = FALSE; + nBrushColor_ = GetColormap().GetColor( nBrushPixel_ ); + bBrushGC_ = FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetXORMode( bool bSet, bool ) +{ + if( !bXORMode_ == bSet ) + { + bXORMode_ = bSet; + bPenGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPixel( long nX, long nY ) +{ + if( nPenColor_ != SALCOLOR_NONE ) + XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY ); +} + +void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) +{ + if( nSalColor != SALCOLOR_NONE ) + { + Display *pDisplay = GetXDisplay(); + + if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ ) + { + SetLineColor( nSalColor ); + XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY ); + nPenColor_ = SALCOLOR_NONE; + bPenGC_ = False; + } + else + { + GC pGC = SelectPen(); + + if( nSalColor != nPenColor_ ) + XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) ); + + XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY ); + + if( nSalColor != nPenColor_ ) + XSetForeground( pDisplay, pGC, nPenPixel_ ); + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + if( nPenColor_ != SALCOLOR_NONE ) + { + if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine ) + { + GC aGC = SelectPen(); + XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1); + XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2); + XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 ); + } + else + XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(), + nX1, nY1, nX2, nY2 ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY ) +{ + if( nBrushColor_ != SALCOLOR_NONE ) + { + XFillRectangle( GetXDisplay(), + GetDrawable(), + SelectBrush(), + nX, nY, nDX, nDY ); + } + // Beschreibung DrawRect verkehrt, deshalb -1 + if( nPenColor_ != SALCOLOR_NONE ) + XDrawRectangle( GetXDisplay(), + GetDrawable(), + SelectPen(), + nX, nY, nDX-1, nDY-1 ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry ) +{ + drawPolyLine( nPoints, pPtAry, false ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry, bool bClose ) +{ + if( nPenColor_ != 0xFFFFFFFF ) + { + SalPolyLine Points( nPoints, pPtAry ); + + DrawLines( nPoints, Points, SelectPen(), bClose ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry ) +{ + if( nPoints == 0 ) + return; + + if( nPoints < 3 ) + { + if( !bXORMode_ ) + { + if( 1 == nPoints ) + drawPixel( pPtAry[0].mnX, pPtAry[0].mnY ); + else + drawLine( pPtAry[0].mnX, pPtAry[0].mnY, + pPtAry[1].mnX, pPtAry[1].mnY ); + } + return; + } + + SalPolyLine Points( nPoints, pPtAry ); + + nPoints++; + + /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case) + * do not draw the visible part of a polygon + * if it overlaps to the left of screen 0,y. + * This happens to be the case in the gradient drawn in the + * menubar background. workaround for the special case of + * of a rectangle overlapping to the left. + */ + if( nPoints == 5 && + Points[ 0 ].x == Points[ 1 ].x && + Points[ 1 ].y == Points[ 2 ].y && + Points[ 2 ].x == Points[ 3 ].x && + Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y + ) + { + bool bLeft = false; + bool bRight = false; + for(unsigned int i = 0; i < nPoints; i++ ) + { + if( Points[i].x < 0 ) + bLeft = true; + else + bRight= true; + } + if( bLeft && ! bRight ) + return; + if( bLeft && bRight ) + { + for( unsigned int i = 0; i < nPoints; i++ ) + if( Points[i].x < 0 ) + Points[i].x = 0; + } + } + + if( nBrushColor_ != SALCOLOR_NONE ) + XFillPolygon( GetXDisplay(), + GetDrawable(), + SelectBrush(), + &Points[0], nPoints, + Complex, CoordModeOrigin ); + + if( nPenColor_ != 0xFFFFFFFF ) + DrawLines( nPoints, Points, SelectPen(), true ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly, + const sal_uInt32 *pPoints, + PCONSTSALPOINT *pPtAry ) +{ + if( nBrushColor_ != SALCOLOR_NONE ) + { + ULONG i, n; + XLIB_Region pXRegA = NULL; + + for( i = 0; i < nPoly; i++ ) { + n = pPoints[i]; + SalPolyLine Points( n, pPtAry[i] ); + if( n > 2 ) + { + XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule ); + if( !pXRegA ) + pXRegA = pXRegB; + else + { + XXorRegion( pXRegA, pXRegB, pXRegA ); + XDestroyRegion( pXRegB ); + } + } + } + + if( pXRegA ) + { + XRectangle aXRect; + XClipBox( pXRegA, &aXRect ); + + GC pGC = SelectBrush(); + SetClipRegion( pGC, pXRegA ); // ??? doppelt + XDestroyRegion( pXRegA ); + bBrushGC_ = FALSE; + + XFillRectangle( GetXDisplay(), + GetDrawable(), + pGC, + aXRect.x, aXRect.y, aXRect.width, aXRect.height ); + } + } + + if( nPenColor_ != SALCOLOR_NONE ) + for( ULONG i = 0; i < nPoly; i++ ) + drawPolyLine( pPoints[i], pPtAry[i], true ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sal_Bool X11SalGraphics::drawPolyLineBezier( ULONG, const SalPoint*, const BYTE* ) +{ + return sal_False; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sal_Bool X11SalGraphics::drawPolygonBezier( ULONG, const SalPoint*, const BYTE* ) +{ + return sal_False; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*, + const SalPoint* const*, const BYTE* const* ) +{ + return sal_False; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void X11SalGraphics::invert( ULONG nPoints, + const SalPoint* pPtAry, + SalInvert nFlags ) +{ + SalPolyLine Points ( nPoints, pPtAry ); + + GC pGC; + if( SAL_INVERT_50 & nFlags ) + pGC = GetInvert50GC(); + else + if ( SAL_INVERT_TRACKFRAME & nFlags ) + pGC = GetTrackingGC(); + else + pGC = GetInvertGC(); + + if( SAL_INVERT_TRACKFRAME & nFlags ) + DrawLines ( nPoints, Points, pGC, true ); + else + XFillPolygon( GetXDisplay(), + GetDrawable(), + pGC, + &Points[0], nPoints, + Complex, CoordModeOrigin ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG ) +{ + return FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +XID X11SalGraphics::GetXRenderPicture() +{ + if( !m_aRenderPicture ) + { + // check xrender support for matching visual + // find a XRenderPictFormat compatible with the Drawable + XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + XRenderPictFormat* pVisualFormat = static_cast(GetXRenderFormat()); + if( !pVisualFormat ) + { + Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); + pVisualFormat = rRenderPeer.FindVisualFormat( pVisual ); + if( !pVisualFormat ) + return 0; + // cache the XRenderPictFormat + SetXRenderFormat( static_cast(pVisualFormat) ); + } + + // get the matching xrender target for drawable + m_aRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL ); + } + +#if 0 + // setup clipping so the callers don't have to do it themselves + // TODO: avoid clipping if already set correctly + if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) + rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ ); +#endif + + return m_aRenderPicture; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +SystemGraphicsData X11SalGraphics::GetGraphicsData() const +{ + SystemGraphicsData aRes; + + aRes.nSize = sizeof(aRes); + aRes.pDisplay = GetXDisplay(); + aRes.hDrawable = hDrawable_; + aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); + aRes.nScreen = m_nScreen; + aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth(); + aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap(); + aRes.pRenderFormat = m_pRenderFormat; + return aRes; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +// B2DPolygon support methods + +namespace { // anonymous namespace to prevent export +// the methods and structures here are used by the +// B2DPolyPolygon->RenderTrapezoid conversion algorithm + +// compare two line segments +// assumption: both segments point downward +// assumption: they must have at least some y-overlap +// assumption: rA.p1.y <= rB.p1.y +bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB ) +{ + bool bAbove = (rA.p1.y <= rB.p1.y); + const XLineFixed& rU = bAbove ? rA : rB; + const XLineFixed& rL = bAbove ? rB : rA; + + const XFixed aXDiff = rU.p2.x - rU.p1.x; + const XFixed aYDiff = rU.p2.y - rU.p1.y; + + 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); + const sal_Int64 n2 = (sal_Int64)aYDiff * (rL.p1.x - rU.p1.x); + if( n1 != n2 ) + return ((n1 < n2) == bAbove); + } + + 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); + const sal_Int64 n4 = (sal_Int64)aYDiff * (rL.p2.x - rU.p1.x); + if( n3 != n4 ) + return ((n3 < n4) == bAbove); + } + + // both segments overlap + return false; +} + +struct HalfTrapezoid +{ + // assumptions: + // maLine.p1.y <= mnY < maLine.p2.y + XLineFixed maLine; + XFixed mnY; +}; + +struct HalfTrapCompare +{ + bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const + { + bool bIsTopLeft = false; + if( rA.mnY != rB.mnY ) // sort top-first if possible + bIsTopLeft = (rA.mnY < rB.mnY); + else // else sort left-first + bIsTopLeft = IsLeftOf( rA.maLine, rB.maLine ); + // adjust to priority_queue sorting convention + return !bIsTopLeft; + } +}; + +typedef std::priority_queue< HalfTrapezoid, std::vector, 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(); } +}; + +typedef std::vector TrapezoidVector; + +class TrapezoidXCompare +{ + const TrapezoidVector& mrVector; +public: + TrapezoidXCompare( const TrapezoidVector& rVector ) + : mrVector( rVector ) {} + bool operator()( int nA, int nB ) const + { return IsLeftOf( mrVector[nA].left, mrVector[nB].left ); } +}; + +typedef std::multiset< int, TrapezoidXCompare > ActiveTrapSet; + +class TrapezoidYCompare +{ + const TrapezoidVector& mrVector; +public: + TrapezoidYCompare( const TrapezoidVector& rVector ) + : mrVector( rVector ) {} + bool operator()( int nA, int nB ) const + { return (mrVector[nA].bottom < mrVector[nB].bottom); } +}; + +typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet; +} // end of anonymous namespace + +// draw a poly-polygon +bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency) +{ + // nothing to do for empty polypolygons + const int nPolygonCount = rPolyPoly.count(); + if( nPolygonCount <= 0 ) + return TRUE; + + // nothing to do if everything is transparent + if( (nBrushColor_ == SALCOLOR_NONE) + && (nPenColor_ == SALCOLOR_NONE) ) + return TRUE; + + // cannot handle pencolor!=brushcolor yet + if( (nPenColor_ != SALCOLOR_NONE) + && (nPenColor_ != nBrushColor_) ) + return FALSE; + + // TODO: remove the env-variable when no longer needed + static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" ); + if( pRenderEnv ) + return FALSE; + + // check xrender support for trapezoids + XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + if( !rRenderPeer.AreTrapezoidsSupported() ) + return FALSE; + Picture aDstPic = GetXRenderPicture(); + // check xrender support for this drawable + if( !aDstPic ) + return FALSE; + + // don't bother with polygons outside of visible area + const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() ); + const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rPolyPoly ); + const bool bNeedViewClip = !aPolyRange.isInside( aViewRange ); + if( !aPolyRange.overlaps( aViewRange ) ) + return true; + + // convert the polypolygon to trapezoids + + // first convert the B2DPolyPolygon to HalfTrapezoids + // #i100922# try to prevent priority-queue reallocations by reservering enough + int nHTQueueReserve = 0; + for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx ) + { + const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx ); + const int nPointCount = aOuterPolygon.count(); + nHTQueueReserve += aOuterPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount; + } + nHTQueueReserve = ((4*nHTQueueReserve) | 0x1FFF) + 1; + HTQueue aHTQueue; + aHTQueue.reserve( nHTQueueReserve ); + for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx ) + { + const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx ); + + // render-trapezoids should be inside the view => clip polygon against view range + basegfx::B2DPolyPolygon aClippedPolygon( aOuterPolygon ); + if( bNeedViewClip ) + { + aClippedPolygon = basegfx::tools::clipPolygonOnRange( aOuterPolygon, aViewRange, true, false ); + DBG_ASSERT( aClippedPolygon.count(), "polygon confirmed to overlap with view should not get here" ); + if( !aClippedPolygon.count() ) + continue; + } + + // render-trapezoids have linear edges => get rid of bezier segments + if( aClippedPolygon.areControlPointsUsed() ) + aClippedPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aClippedPolygon, 0.125 ); + + // test and remove self intersections + // TODO: make code intersection save, then remove this test + basegfx::B2DPolyPolygon aInnerPolyPoly(basegfx::tools::solveCrossovers( aClippedPolygon)); + const int nInnerPolyCount = aInnerPolyPoly.count(); + for( int nInnerPolyIdx = 0; nInnerPolyIdx < nInnerPolyCount; ++nInnerPolyIdx ) + { + ::basegfx::B2DPolygon aInnerPolygon = aInnerPolyPoly.getB2DPolygon( nInnerPolyIdx ); + const int nPointCount = aInnerPolygon.count(); + if( !nPointCount ) + continue; + + aHTQueue.reserve( aHTQueue.size() + 8 * nPointCount ); + + // convert polygon point pairs to HalfTrapezoids + // connect the polygon point with the first one if needed + XPointFixed aOldXPF = { 0, 0 }; + XPointFixed aNewXPF; + for( int nPointIdx = 0; nPointIdx <= nPointCount; ++nPointIdx, aOldXPF = aNewXPF ) + { + const int k = (nPointIdx < nPointCount) ? nPointIdx : 0; + const ::basegfx::B2DPoint& aPoint = aInnerPolygon.getB2DPoint( k ); + + // convert the B2DPoint into XRENDER units + if(getAntiAliasB2DDraw()) + { + aNewXPF.x = XDoubleToFixed( aPoint.getX() ); + aNewXPF.y = XDoubleToFixed( aPoint.getY() ); + } + else + { + aNewXPF.x = XDoubleToFixed( basegfx::fround( aPoint.getX() ) ); + aNewXPF.y = XDoubleToFixed( basegfx::fround( aPoint.getY() ) ); + } + + // 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; + if( aNewXPF.y < aOldXPF.y ) + { + aHT.maLine.p1 = aNewXPF; + aHT.maLine.p2 = aOldXPF; + } + else + { + aHT.maLine.p2 = aNewXPF; + aHT.maLine.p1 = aOldXPF; + } + + aHT.mnY = aHT.maLine.p1.y; + +#if 0 // ignore clipped HalfTrapezoids + if( aHT.mnY < 0 ) + aHT.mnY = 0; + else if( aHT.mnY > 10000 ) + continue; +#endif + + // queue up the HalfTrapezoid + aHTQueue.push( aHT ); + } + } + } + + if( aHTQueue.empty() ) + return TRUE; + + // then convert the HalfTrapezoids into full Trapezoids + TrapezoidVector aTrapVector; + aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess + + TrapezoidXCompare aTrapXCompare( aTrapVector ); + ActiveTrapSet aActiveTraps( aTrapXCompare ); + + TrapezoidYCompare aTrapYCompare( aTrapVector ); + VerticalTrapSet aVerticalTraps( aTrapYCompare ); + + while( !aHTQueue.empty() ) + { + XTrapezoid aTrapezoid; + + // convert a HalfTrapezoid pair + const HalfTrapezoid& rLeft = aHTQueue.top(); + aTrapezoid.top = rLeft.mnY; + aTrapezoid.bottom = rLeft.maLine.p2.y; + aTrapezoid.left = rLeft.maLine; + +#if 0 + // ignore empty trapezoids + if( aTrapezoid.bottom <= aTrapezoid.top ) + continue; +#endif + + aHTQueue.pop(); + if( aHTQueue.empty() ) // TODO: assert + break; + const HalfTrapezoid& rRight = aHTQueue.top(); + aTrapezoid.right = rRight.maLine; + aHTQueue.pop(); + + aTrapezoid.bottom = aTrapezoid.left.p2.y; + if( aTrapezoid.bottom > aTrapezoid.right.p2.y ) + aTrapezoid.bottom = aTrapezoid.right.p2.y; + + // keep the full Trapezoid candidate + aTrapVector.push_back( aTrapezoid ); + + // unless it splits an older trapezoid + bool bSplit = false; + for(;;) + { + // 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 ]; + + // 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 + if( rLeftTrap.bottom <= aTrapezoid.top ) + { + aActiveTraps.erase( aActiveTrapsIt ); + continue; + } + + // check if there is horizontal overlap + // aTrapezoid.left==rLeftTrap.right is allowed though + if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) ) + break; + + // split the old trapezoid and keep its upper part + // find the old trapezoids entry in the VerticalTrapSet and remove it + typedef std::pair VTSPair; + VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt ); + VerticalTrapSet::iterator aVTSit = aVTSPair.first; + for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ; + if( aVTSit != aVTSPair.second ) + aVerticalTraps.erase( aVTSit ); + // then update the old trapezoid's bottom + rLeftTrap.bottom = aTrapezoid.top; + // enter the updated old trapzoid in VerticalTrapSet + aVerticalTraps.insert( aVerticalTraps.begin(), *aActiveTrapsIt ); + // the old trapezoid is no longer active + aActiveTraps.erase( aActiveTrapsIt ); + + // the trapezoid causing the split has become obsolete + // so its both sides have to be re-queued + HalfTrapezoid aHT; + aHT.mnY = aTrapezoid.top; + aHT.maLine = aTrapezoid.left; + aHTQueue.push( aHT ); + aHT.maLine = aTrapezoid.right; + aHTQueue.push( aHT ); + + bSplit = true; + break; + } + + // keep or forget the resulting full Trapezoid + if( bSplit ) + aTrapVector.pop_back(); + else + { + aActiveTraps.insert( aTrapVector.size()-1 ); + aVerticalTraps.insert( aTrapVector.size()-1 ); + } + + // 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; + while( !aVerticalTraps.empty() ) + { + const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ]; + if( nNewTop < rOldTrap.bottom ) + break; + // the reference 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 ) + { + aHT.maLine = rOldTrap.left; + aHTQueue.push( aHT ); + } + if( rOldTrap.right.p2.y > rOldTrap.bottom ) + { + aHT.maLine = rOldTrap.right; + aHTQueue.push( aHT ); + } + } + } + + // create xrender Picture for polygon foreground + SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ]; + if( !rEntry.m_aPicture ) + { + Display* pXDisplay = GetXDisplay(); + + rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 ); + XRenderPictureAttributes aAttr; + aAttr.repeat = true; + + XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 ); + rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr ); + } + + // set polygon foreground color and opacity + XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency ); + rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); + + // set clipping + // TODO: move into GetXRenderPicture? + if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) + rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ ); + + // render the trapezoids + const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8(); + rRenderPeer.CompositeTrapezoids( PictOpOver, + rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() ); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin) +{ + const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + if( !rRenderPeer.AreTrapezoidsSupported() ) + return false; + + // get the area polygon for the line polygon + basegfx::B2DPolygon aPolygon = rPolygon; + if( (rLineWidth.getX() != rLineWidth.getY()) + && !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 ); + } + + // 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)); + + 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 ); + } + + // temporarily adjust brush color to pen color + // since the line is drawn as an area-polygon + const SalColor aKeepBrushColor = nBrushColor_; + nBrushColor_ = nPenColor_; + + // draw each area polypolygon component individually + // to emulate the polypolygon winding rule "non-zero" + bool bDrawOk = true; + const int nPolyCount = aAreaPolyPoly.count(); + for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) + { + const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) ); + bDrawOk = drawPolyPolygon( aOnePoly, 0.0); + if( !bDrawOk ) + break; + } + + // restore the original brush GC + nBrushColor_ = aKeepBrushColor; + return bDrawOk; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/vcl/unx/source/gdi/salgdi2.cxx b/vcl/unx/source/gdi/salgdi2.cxx index 5a01b7f13d39..1d8e80df0663 100644 --- a/vcl/unx/source/gdi/salgdi2.cxx +++ b/vcl/unx/source/gdi/salgdi2.cxx @@ -796,21 +796,15 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, if( rPeer.GetVersion() < 0x02 ) return false; + // create destination picture + Picture aDstPic = GetXRenderPicture(); + if( !aDstPic ) + return false; + const SalDisplay* pSalDisp = GetDisplay(); const SalVisual& rSalVis = pSalDisp->GetVisual( m_nScreen ); Display* pXDisplay = pSalDisp->GetDisplay(); - // create destination picture - // TODO: scoped Pixmap and Pictures - Visual* pDstXVisual = rSalVis.GetVisual(); - XRenderPictFormat* pDstVisFmt = rPeer.FindVisualFormat( pDstXVisual ); - if( !pDstVisFmt ) - return false; - - Picture aDstPic = rPeer.CreatePicture( hDrawable_, pDstVisFmt, 0, NULL ); - if( !aDstPic ) - return false; - // create source Picture int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth(); const X11SalBitmap& rSrcX11Bmp = static_cast( rSrcBitmap ); @@ -829,7 +823,12 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, if( !aSrcPM ) return false; - XRenderPictFormat* pSrcVisFmt = pDstVisFmt; + // create source picture + // TODO: use scoped picture + Visual* pSrcXVisual = rSalVis.GetVisual(); + XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual ); + if( !pSrcVisFmt ) + return false; Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL ); if( !aSrcPic ) return false; @@ -843,16 +842,16 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, // an XImage needs its data top_down // TODO: avoid wrongly oriented images in upper layers! const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize; - const char* pSrc = (char*)pAlphaBuffer->mpBits; + const char* pSrcBits = (char*)pAlphaBuffer->mpBits; char* pAlphaBits = new char[ nImageSize ]; if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) - memcpy( pAlphaBits, pSrc, nImageSize ); + memcpy( pAlphaBits, pSrcBits, nImageSize ); else { - char* pDst = pAlphaBits + nImageSize; + char* pDstBits = pAlphaBits + nImageSize; const int nLineSize = pAlphaBuffer->mnScanlineSize; - for(; (pDst -= nLineSize) >= pAlphaBits; pSrc += nLineSize ) - memcpy( pDst, pSrc, nLineSize ); + for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize ) + memcpy( pDstBits, pSrcBits, nLineSize ); } // the alpha values need to be inverted for XRender @@ -866,7 +865,7 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, *pCDst = ~*pCDst; const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8(); - XImage* pAlphaImg = XCreateImage( pXDisplay, pDstXVisual, 8, ZPixmap, 0, + XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0, pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight, pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize ); @@ -904,7 +903,6 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, rPeer.FreePicture( aAlphaPic ); XFreePixmap(pXDisplay, aAlphaPM); rPeer.FreePicture( aSrcPic ); - rPeer.FreePicture( aDstPic ); return true; } @@ -922,20 +920,10 @@ bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, return false; XRenderPeer& rPeer = XRenderPeer::GetInstance(); - if( rPeer.GetVersion() < 0x02 ) + if( rPeer.GetVersion() < 0x02 ) // TODO: replace with better test return false; - const SalDisplay* pSalDisp = GetDisplay(); - const SalVisual& rSalVis = pSalDisp->GetVisual( m_nScreen ); - - // create destination picture - // TODO: scoped Pixmap and Pictures - Visual* pDstXVisual = rSalVis.GetVisual(); - XRenderPictFormat* pDstVisFmt = rPeer.FindVisualFormat( pDstXVisual ); - if( !pDstVisFmt ) - return false; - - Picture aDstPic = rPeer.CreatePicture( hDrawable_, pDstVisFmt, 0, NULL ); + Picture aDstPic = GetXRenderPicture(); if( !aDstPic ) return false; @@ -948,9 +936,6 @@ bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, nX, nY, nWidth, nHeight ); - // cleanup - rPeer.FreePicture( aDstPic ); - return true; } diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index 9cbd9a075dff..d1a60cda4097 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -1023,29 +1023,22 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout ) void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout ) { - Display* pDisplay = GetXDisplay(); - XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); - - // find a XRenderPictFormat compatible with the Drawable - XRenderPictFormat* pVisualFormat = static_cast(GetXRenderFormat()); - if( !pVisualFormat ) - { - Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); - pVisualFormat = rRenderPeer.FindVisualFormat( pVisual ); - // cache the XRenderPictFormat - SetXRenderFormat( static_cast(pVisualFormat) ); - } - - DBG_ASSERT( pVisualFormat!=NULL, "no matching XRenderPictFormat for text" ); - if( !pVisualFormat ) + // get xrender target for this drawable + Picture aDstPic = GetXRenderPicture(); + if( !aDstPic ) return; // get a XRenderPicture for the font foreground + // TODO: move into own method + XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + XRenderPictFormat* pVisualFormat = (XRenderPictFormat*)GetXRenderFormat(); + DBG_ASSERT( pVisualFormat, "we already have a render picture, but XRenderPictFormat==NULL???"); const int nVisualDepth = pVisualFormat->depth; SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ nVisualDepth ]; if( !rEntry.m_aPicture ) { // create and cache XRenderPicture for the font foreground + Display* pDisplay = GetXDisplay(); #ifdef DEBUG int iDummy; unsigned uDummy; @@ -1067,12 +1060,10 @@ void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout ) XRenderColor aRenderColor = GetXRenderColor( nTextPixel_ ); rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); - // notify xrender of target drawable - Picture aDst = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL ); - // set clipping + // TODO: move into GetXRenderPicture()? if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) - rRenderPeer.SetPictureClipRegion( aDst, pClipRegion_ ); + rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ ); ServerFont& rFont = rLayout.GetServerFont(); X11GlyphPeer& rGlyphPeer = X11GlyphCache::GetInstance().GetPeer(); @@ -1096,12 +1087,9 @@ void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout ) unsigned int aRenderAry[ MAXGLYPHS ]; for( int i = 0; i < nGlyphs; ++i ) aRenderAry[ i ] = rGlyphPeer.GetGlyphId( rFont, aGlyphAry[i] ); - rRenderPeer.CompositeString32( rEntry.m_aPicture, aDst, + rRenderPeer.CompositeString32( rEntry.m_aPicture, aDstPic, aGlyphSet, aPos.X(), aPos.Y(), aRenderAry, nGlyphs ); } - - // cleanup - rRenderPeer.FreePicture( aDst ); } //-------------------------------------------------------------------------- diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx index b3fdfaef56ce..5f8c76fdb16f 100644 --- a/vcl/unx/source/gdi/salprnpsp.cxx +++ b/vcl/unx/source/gdi/salprnpsp.cxx @@ -248,7 +248,7 @@ static bool passFileToCommandLine( const String& rFilename, const String& rComma struct stat aStat; if( stat( aFilename.GetBuffer(), &aStat ) ) fprintf( stderr, "stat( %s ) failed\n", aFilename.GetBuffer() ); - fprintf( stderr, "Tmp file %s has modes: %o\n", aFilename.GetBuffer(), aStat.st_mode ); + fprintf( stderr, "Tmp file %s has modes: 0%03lo\n", aFilename.GetBuffer(), (long)aStat.st_mode ); #endif const char* argv[4]; if( ! ( argv[ 0 ] = getenv( "SHELL" ) ) ) diff --git a/vcl/unx/source/gdi/salvd.cxx b/vcl/unx/source/gdi/salvd.cxx index 915c42661fdc..66e582e231b7 100644 --- a/vcl/unx/source/gdi/salvd.cxx +++ b/vcl/unx/source/gdi/salvd.cxx @@ -121,16 +121,14 @@ void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap, if (m_pDeleteColormap != pOrigDeleteColormap) delete pOrigDeleteColormap; - hDrawable_ = pDevice->GetDrawable(); + const Drawable aVdevDrawable = pDevice->GetDrawable(); + SetDrawable( aVdevDrawable, m_nScreen ); + m_pVDev = pDevice; m_pFrame = NULL; bWindow_ = pDisplay->IsDisplay(); bVirDev_ = TRUE; - - nPenPixel_ = GetPixel( nPenColor_ ); - nTextPixel_ = GetPixel( nTextColor_ ); - nBrushPixel_ = GetPixel( nBrushColor_ ); } // -=-= SalVirDevData / SalVirtualDevice -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -274,3 +272,4 @@ void X11SalVirtualDevice::GetSize( long& rWidth, long& rHeight ) rWidth = GetWidth(); rHeight = GetHeight(); } + diff --git a/vcl/unx/source/gdi/xrender_peer.cxx b/vcl/unx/source/gdi/xrender_peer.cxx index 861bf0e454aa..d8f2045c6fde 100644 --- a/vcl/unx/source/gdi/xrender_peer.cxx +++ b/vcl/unx/source/gdi/xrender_peer.cxx @@ -82,7 +82,7 @@ void XRenderPeer::InitRenderLib() // we don't know if we are running on a system with xrender library // we don't want to install system libraries ourselves // => load them dynamically when they are there - OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrender.so.1" )); + const OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrender.so.1" )); mpRenderLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT ); if( !mpRenderLib ) { #ifdef DEBUG @@ -93,98 +93,81 @@ void XRenderPeer::InitRenderLib() return; } - OUString aQueryExtensionFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderQueryExtension")); oslGenericFunction pFunc; - pFunc = osl_getFunctionSymbol( mpRenderLib, aQueryExtensionFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderQueryExtension" ); if( !pFunc ) return; mpXRenderQueryExtension = (Bool(*)(Display*,int*,int*))pFunc; - OUString aQueryVersionFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderQueryVersion")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aQueryVersionFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderQueryVersion" ); if( !pFunc ) return; mpXRenderQueryVersion = (void(*)(Display*,int*,int*))pFunc; - OUString aVisFormatFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFindVisualFormat")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aVisFormatFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFindVisualFormat" ); if( !pFunc ) return; mpXRenderFindVisualFormat = (XRenderPictFormat*(*)(Display*,Visual*))pFunc; - OUString aStdFormatFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFindStandardFormat")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aStdFormatFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFindStandardFormat" ); if( !pFunc ) return; mpXRenderFindStandardFormat = (XRenderPictFormat*(*)(Display*,int))pFunc; - OUString aFmtFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFindFormat")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aFmtFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFindFormat" ); if( !pFunc ) return; mpXRenderFindFormat = (XRenderPictFormat*(*)(Display*,unsigned long, const XRenderPictFormat*,int))pFunc; - OUString aCreatGlyphFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderCreateGlyphSet")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aCreatGlyphFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderCreateGlyphSet" ); if( !pFunc ) return; mpXRenderCreateGlyphSet = (GlyphSet(*)(Display*,const XRenderPictFormat*))pFunc; - OUString aFreeGlyphFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFreeGlyphSet")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aFreeGlyphFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFreeGlyphSet" ); if( !pFunc ) return; mpXRenderFreeGlyphSet = (void(*)(Display*,GlyphSet))pFunc; - OUString aAddGlyphFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderAddGlyphs")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aAddGlyphFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderAddGlyphs" ); if( !pFunc ) return; mpXRenderAddGlyphs = (void(*)(Display*,GlyphSet,Glyph*,const XGlyphInfo*, int,const char*,int))pFunc; - OUString aFreeGlyphsFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFreeGlyphs")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aFreeGlyphsFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFreeGlyphs" ); if( !pFunc ) return; mpXRenderFreeGlyphs = (void(*)(Display*,GlyphSet,Glyph*,int))pFunc; - OUString aCompStringFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderCompositeString32")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aCompStringFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderCompositeString32" ); if( !pFunc ) return; mpXRenderCompositeString32 = (void(*)(Display*,int,Picture,Picture, const XRenderPictFormat*,GlyphSet,int,int,int,int,const unsigned*,int))pFunc; - OUString aCreatPicFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderCreatePicture")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aCreatPicFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderCreatePicture" ); if( !pFunc ) return; mpXRenderCreatePicture = (Picture(*)(Display*,Drawable,const XRenderPictFormat*, unsigned long,const XRenderPictureAttributes*))pFunc; - OUString aSetClipFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderSetPictureClipRegion")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aSetClipFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderSetPictureClipRegion" ); if( !pFunc ) return; mpXRenderSetPictureClipRegion = (void(*)(Display*,Picture,XLIB_Region))pFunc; - OUString aFreePicFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFreePicture")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aFreePicFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFreePicture" ); if( !pFunc ) return; mpXRenderFreePicture = (void(*)(Display*,Picture))pFunc; - OUString aRenderCompositeFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderComposite")); - pFunc = osl_getFunctionSymbol( mpRenderLib, aRenderCompositeFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderComposite" ); if( !pFunc ) return; mpXRenderComposite = (void(*)(Display*,int,Picture,Picture,Picture, int,int,int,int,int,int,unsigned,unsigned))pFunc; - OUString aFillRectangleFuncName(RTL_CONSTASCII_USTRINGPARAM("XRenderFillRectangle")); - pFunc=osl_getFunctionSymbol( mpRenderLib, aFillRectangleFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderFillRectangle" ); if( !pFunc ) return; mpXRenderFillRectangle = (void(*)(Display*,int,Picture,const XRenderColor*, int,int,unsigned int,unsigned int))pFunc; - OUString aCompositeTrapsFuncName( RTL_CONSTASCII_USTRINGPARAM("XRenderCompositeTrapezoids")); - pFunc=osl_getFunctionSymbol( mpRenderLib, aCompositeTrapsFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderCompositeTrapezoids" ); #if 0 // not having trapezoid support is supported if( !pFunc ) return; #endif mpXRenderCompositeTrapezoids = (void(*)(Display*,int,Picture,Picture, const XRenderPictFormat*,int,int,const XTrapezoid*,int))pFunc; - OUString aAddTrapsFuncName( RTL_CONSTASCII_USTRINGPARAM("XRenderAddTraps")); - pFunc=osl_getFunctionSymbol( mpRenderLib, aAddTrapsFuncName.pData); + pFunc = osl_getAsciiFunctionSymbol( mpRenderLib, "XRenderAddTraps" ); #if 0 // not having trapezoid support is supported if( !pFunc ) return; #endif diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx index 2177c9549eff..0c791ca8091f 100644 --- a/vcl/unx/source/plugadapt/salplug.cxx +++ b/vcl/unx/source/plugadapt/salplug.cxx @@ -79,8 +79,7 @@ static SalInstance* tryInstance( const OUString& rModuleBase ) SAL_LOADMODULE_DEFAULT ); if( aMod ) { - OUString aSym( RTL_CONSTASCII_USTRINGPARAM( "create_SalInstance" ) ); - salFactoryProc aProc = (salFactoryProc)osl_getFunctionSymbol( aMod, aSym.pData ); + salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" ); if( aProc ) { pInst = aProc( aMod ); @@ -113,7 +112,7 @@ static SalInstance* tryInstance( const OUString& rModuleBase ) { #if OSL_DEBUG_LEVEL > 1 std::fprintf( stderr, "could not load symbol %s from shared object %s\n", - OUStringToOString( aSym, RTL_TEXTENCODING_ASCII_US ).getStr(), + "create_SalInstance", OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() ); #endif osl_unloadModule( aMod ); diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index b99f0e2a6ce0..5a5703e10944 100644 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -100,18 +100,12 @@ VisualStylesAPI::VisualStylesAPI() if ( mhModule ) { - OUString queryFuncName( RTL_CONSTASCII_USTRINGPARAM( "OpenThemeData" ) ); - lpfnOpenThemeData = (OpenThemeData_Proc_T) osl_getSymbol( mhModule, queryFuncName.pData ); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "CloseThemeData" ) ); - lpfnCloseThemeData = (CloseThemeData_Proc_T) osl_getSymbol( mhModule, queryFuncName.pData ); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "GetThemeBackgroundContentRect" ) ); - lpfnGetThemeBackgroundContentRect = (GetThemeBackgroundContentRect_Proc_T) osl_getSymbol( mhModule, queryFuncName.pData ); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "DrawThemeBackground" ) ); - lpfnDrawThemeBackground = (DrawThemeBackground_Proc_T) osl_getSymbol( mhModule, queryFuncName.pData ); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "DrawThemeText" ) ); - lpfnDrawThemeText = (DrawThemeText_Proc_T) osl_getSymbol( mhModule, queryFuncName.pData ); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "GetThemePartSize" ) ); - lpfnGetThemePartSize = (GetThemePartSize_Proc_T) osl_getSymbol( mhModule, queryFuncName.pData ); + lpfnOpenThemeData = (OpenThemeData_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "OpenThemeData" ); + lpfnCloseThemeData = (CloseThemeData_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "CloseThemeData" ); + lpfnGetThemeBackgroundContentRect = (GetThemeBackgroundContentRect_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "GetThemeBackgroundContentRect" ); + lpfnDrawThemeBackground = (DrawThemeBackground_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "DrawThemeBackground" ); + lpfnDrawThemeText = (DrawThemeText_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "DrawThemeText" ); + lpfnGetThemePartSize = (GetThemePartSize_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "GetThemePartSize" ); } else { diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 0689b8710655..8d9347e7e352 100755 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -1172,62 +1172,52 @@ static bool InitUSP() if( !aUspModule ) return (bUspEnabled = false); - OUString queryFuncName( RTL_CONSTASCII_USTRINGPARAM( "ScriptIsComplex" ) ); pScriptIsComplex = (HRESULT (WINAPI*)(const WCHAR*,int,DWORD)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptIsComplex" ); bUspEnabled &= (NULL != pScriptIsComplex); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptItemize" ) ); pScriptItemize = (HRESULT (WINAPI*)(const WCHAR*,int,int, const SCRIPT_CONTROL*,const SCRIPT_STATE*,SCRIPT_ITEM*,int*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptItemize" ); bUspEnabled &= (NULL != pScriptItemize); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptShape" ) ); pScriptShape = (HRESULT (WINAPI*)(HDC,SCRIPT_CACHE*,const WCHAR*, int,int,SCRIPT_ANALYSIS*,WORD*,WORD*,SCRIPT_VISATTR*,int*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptShape" ); bUspEnabled &= (NULL != pScriptShape); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptPlace" ) ); pScriptPlace = (HRESULT (WINAPI*)(HDC, SCRIPT_CACHE*, const WORD*, int, const SCRIPT_VISATTR*,SCRIPT_ANALYSIS*,int*,GOFFSET*,ABC*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptPlace" ); bUspEnabled &= (NULL != pScriptPlace); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptGetLogicalWidths" ) ); pScriptGetLogicalWidths = (HRESULT (WINAPI*)(const SCRIPT_ANALYSIS*, int,int,const int*,const WORD*,const SCRIPT_VISATTR*,int*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptGetLogicalWidths" ); bUspEnabled &= (NULL != pScriptGetLogicalWidths); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptApplyLogicalWidth" ) ); pScriptApplyLogicalWidth = (HRESULT (WINAPI*)(const int*,int,int,const WORD*, const SCRIPT_VISATTR*,const int*,const SCRIPT_ANALYSIS*,ABC*,int*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptApplyLogicalWidth" ); bUspEnabled &= (NULL != pScriptApplyLogicalWidth); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptJustify" ) ); pScriptJustify = (HRESULT (WINAPI*)(const SCRIPT_VISATTR*,const int*, int,int,int,int*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptJustify" ); bUspEnabled &= (NULL != pScriptJustify); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptGetFontProperties" ) ); pScriptGetFontProperties = (HRESULT (WINAPI*)( HDC,SCRIPT_CACHE*,SCRIPT_FONTPROPERTIES*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptGetFontProperties" ); bUspEnabled &= (NULL != pScriptGetFontProperties); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptTextOut" ) ); pScriptTextOut = (HRESULT (WINAPI*)(const HDC,SCRIPT_CACHE*, int,int,UINT,const RECT*,const SCRIPT_ANALYSIS*,const WCHAR*, int,const WORD*,int,const int*,const int*,const GOFFSET*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptTextOut" ); bUspEnabled &= (NULL != pScriptTextOut); - queryFuncName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptFreeCache" ) ); pScriptFreeCache = (HRESULT (WINAPI*)(SCRIPT_CACHE*)) - osl_getSymbol( aUspModule, queryFuncName.pData ); + osl_getAsciiFunctionSymbol( aUspModule, "ScriptFreeCache" ); bUspEnabled &= (NULL != pScriptFreeCache); if( !bUspEnabled ) diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index 140e506686fc..57ad272bcf51 100644 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -358,16 +358,12 @@ SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, void *pFunc = NULL; if( pLib ) { - OUString queryFuncName( RTL_CONSTASCII_USTRINGPARAM( "SetLayeredWindowAttributes" ) ); - pFunc = osl_getSymbol( pLib, queryFuncName.pData ); + pFunc = osl_getAsciiFunctionSymbol( pLib, "SetLayeredWindowAttributes" ); } lpfnSetLayeredWindowAttributes = ( SetLayeredWindowAttributes_Proc_T ) pFunc; - if ( pFunc ) - bLayeredAPI = 1; - else - bLayeredAPI = 0; + bLayeredAPI = pFunc ? 1 : 0; } } static const char* pEnvTransparentFloats = getenv("SAL_TRANSPARENT_FLOATS" ); @@ -2113,8 +2109,7 @@ void WinSalFrame::StartPresentation( BOOL bStart ) { OUString aLibraryName( OUString::createFromAscii( aOS.szPathName ) ); oslModule mhSageInst = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT ); - OUString queryFuncName( RTL_CONSTASCII_USTRINGPARAM( "System_Agent_Enable" ) ); - pSalData->mpSageEnableProc = (SysAgt_Enable_PROC) osl_getSymbol( mhSageInst, queryFuncName.pData ); + pSalData->mpSageEnableProc = (SysAgt_Enable_PROC)osl_getAsciiFunctionSymbol( mhSageInst, "System_Agent_Enable" ); } else pSalData->mnSageStatus = DISABLE_AGENT;