LCOV - code coverage report
Current view: top level - vcl/unx/generic/gdi - gdiimpl.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 154 833 18.5 %
Date: 2015-06-13 12:38:46 Functions: 23 67 34.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <prex.h>
      21             : #include <X11/Xproto.h>
      22             : #include <postx.h>
      23             : 
      24             : #include "gdiimpl.hxx"
      25             : 
      26             : #include "vcl/salbtype.hxx"
      27             : #include <vcl/gradient.hxx>
      28             : 
      29             : #include "unx/salunx.h"
      30             : #include "unx/saldata.hxx"
      31             : #include "unx/saldisp.hxx"
      32             : #include "unx/salbmp.h"
      33             : #include "unx/salgdi.h"
      34             : #include "unx/salframe.h"
      35             : #include "unx/salvd.h"
      36             : #include <unx/x11/xlimits.hxx>
      37             : #include "xrender_peer.hxx"
      38             : 
      39             : #include "outdata.hxx"
      40             : 
      41             : #include "basegfx/polygon/b2dpolygon.hxx"
      42             : #include "basegfx/polygon/b2dpolypolygon.hxx"
      43             : #include "basegfx/polygon/b2dpolypolygontools.hxx"
      44             : #include "basegfx/polygon/b2dpolygontools.hxx"
      45             : #include "basegfx/polygon/b2dpolygonclipper.hxx"
      46             : #include "basegfx/polygon/b2dlinegeometry.hxx"
      47             : #include "basegfx/matrix/b2dhommatrix.hxx"
      48             : #include "basegfx/matrix/b2dhommatrixtools.hxx"
      49             : #include "basegfx/polygon/b2dpolypolygoncutter.hxx"
      50             : #include "basegfx/polygon/b2dtrapezoid.hxx"
      51             : 
      52             : #undef SALGDI2_TESTTRANS
      53             : 
      54             : #if (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
      55             : #define DBG_TESTTRANS( _def_drawable )                              \
      56             : {                                                                   \
      57             :     XCopyArea( pXDisp, _def_drawable, aDrawable, GetCopyGC(),       \
      58             :                0, 0,                                                \
      59             :                rPosAry.mnDestWidth, rPosAry.mnDestHeight,         \
      60             :                0, 0 );                                              \
      61             : }
      62             : #else // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
      63             : #define DBG_TESTTRANS( _def_drawable )
      64             : #endif // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
      65             : 
      66             : #define STATIC_POINTS 64
      67             : 
      68             : class SalPolyLine
      69             : {
      70             :     XPoint Points_[STATIC_POINTS];
      71             :     XPoint *pFirst_;
      72             : public:
      73           2 :     SalPolyLine(sal_uLong nPoints, const SalPoint *p)
      74           2 :         : pFirst_(nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_)
      75             :     {
      76          12 :         for( sal_uLong i = 0; i < nPoints; i++ )
      77             :         {
      78          10 :             pFirst_[i].x = (short)p[i].mnX;
      79          10 :             pFirst_[i].y = (short)p[i].mnY;
      80             :         }
      81           2 :         pFirst_[nPoints] = pFirst_[0]; // close polyline
      82           2 :     }
      83             : 
      84           2 :     ~SalPolyLine()
      85             :     {
      86           2 :         if( pFirst_ != Points_ )
      87           0 :             delete [] pFirst_;
      88           2 :     }
      89             : 
      90           2 :     XPoint &operator [] ( sal_uLong n ) const
      91             :     {
      92           2 :         return pFirst_[n];
      93             :     }
      94             : };
      95             : 
      96             : #undef STATIC_POINTS
      97             : 
      98             : namespace
      99             : {
     100           0 :     void setForeBack(XGCValues& rValues, const SalColormap& rColMap, const SalBitmap& rSalBitmap)
     101             :     {
     102           0 :         rValues.foreground = rColMap.GetWhitePixel();
     103           0 :         rValues.background = rColMap.GetBlackPixel();
     104             : 
     105             :         //fdo#33455 and fdo#80160 handle 1 bit depth pngs with palette entries
     106             :         //to set fore/back colors
     107           0 :         SalBitmap& rBitmap = const_cast<SalBitmap&>(rSalBitmap);
     108           0 :         if (BitmapBuffer* pBitmapBuffer = rBitmap.AcquireBuffer(BITMAP_READ_ACCESS))
     109             :         {
     110           0 :             const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
     111           0 :             if (rPalette.GetEntryCount() == 2)
     112             :             {
     113           0 :                 const BitmapColor aWhite(rPalette[rPalette.GetBestIndex(Color(COL_WHITE))]);
     114           0 :                 rValues.foreground = rColMap.GetPixel(ImplColorToSal(aWhite));
     115             : 
     116           0 :                 const BitmapColor aBlack(rPalette[rPalette.GetBestIndex(Color(COL_BLACK))]);
     117           0 :                 rValues.background = rColMap.GetPixel(ImplColorToSal(aBlack));
     118             :             }
     119           0 :             rBitmap.ReleaseBuffer(pBitmapBuffer, BITMAP_READ_ACCESS);
     120             :         }
     121           0 :     }
     122             : }
     123             : 
     124         208 : X11SalGraphicsImpl::X11SalGraphicsImpl(X11SalGraphics& rParent):
     125             :     mrParent(rParent),
     126             :     mnBrushColor( MAKE_SALCOLOR( 0xFF, 0xFF, 0XFF ) ),
     127             :     mpBrushGC(NULL),
     128             :     mnBrushPixel(0),
     129             :     mbPenGC(false),
     130             :     mbBrushGC(false),
     131             :     mbMonoGC(false),
     132             :     mbCopyGC(false),
     133             :     mbInvertGC(false),
     134             :     mbInvert50GC(false),
     135             :     mbStippleGC(false),
     136             :     mbTrackingGC(false),
     137             :     mbDitherBrush(false),
     138             :     mbXORMode(false),
     139             :     mpPenGC(NULL),
     140             :     mnPenColor( MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) ),
     141             :     mnPenPixel(0),
     142             :     mpMonoGC(NULL),
     143             :     mpCopyGC(NULL),
     144             :     mpMaskGC(NULL),
     145             :     mpInvertGC(NULL),
     146             :     mpInvert50GC(NULL),
     147             :     mpStippleGC(NULL),
     148         208 :     mpTrackingGC(NULL)
     149             : {
     150         208 : }
     151             : 
     152         392 : X11SalGraphicsImpl::~X11SalGraphicsImpl()
     153             : {
     154         392 : }
     155             : 
     156         388 : void X11SalGraphicsImpl::Init()
     157             : {
     158         388 :     mnPenPixel = mrParent.GetPixel( mnPenColor );
     159         388 :     mnBrushPixel = mrParent.GetPixel( mnBrushColor );
     160         388 : }
     161             : 
     162           0 : bool X11SalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY )
     163             : {
     164             :     //TODO lfrb: don't hardcode the depth
     165           0 :     Display* pDpy = mrParent.GetXDisplay();
     166           0 :     GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL );
     167             : 
     168           0 :     if( !aTmpGC )
     169             :     {
     170             :         SAL_WARN( "vcl", "Could not create GC from screen" );
     171           0 :         return false;
     172             :     }
     173             : 
     174             :     // Copy the background of the screen into a composite pixmap
     175             :     X11SalGraphics::CopyScreenArea( mrParent.GetXDisplay(),
     176             :                              mrParent.GetDrawable(), mrParent.GetScreenNumber(),
     177           0 :                              mrParent.GetVisual().GetDepth(),
     178           0 :                              pPixmap->GetDrawable(), pPixmap->GetScreen(),
     179           0 :                              pPixmap->GetDepth(),
     180             :                              aTmpGC,
     181           0 :                              nX, nY, pPixmap->GetWidth(), pPixmap->GetHeight(),
     182           0 :                              0, 0 );
     183             : 
     184           0 :     XFreeGC( pDpy, aTmpGC );
     185           0 :     return true;
     186             : }
     187             : 
     188           0 : bool X11SalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* /*Mask*/, int nX, int nY )
     189             : {
     190             :     // TODO: lfrb: Use the mask
     191           0 :     GC aFontGC = mrParent.GetFontGC();
     192             : 
     193             :     // The GC can't be null, otherwise we'd have no clip region
     194           0 :     if( aFontGC == NULL )
     195             :     {
     196             :         SAL_WARN( "vcl", "no valid GC to render pixmap" );
     197           0 :         return false;
     198             :     }
     199             : 
     200           0 :     if( !pPixmap )
     201           0 :         return false;
     202             : 
     203             :     X11SalGraphics::CopyScreenArea( mrParent.GetXDisplay(),
     204           0 :                              pPixmap->GetDrawable(), pPixmap->GetScreen(),
     205           0 :                              pPixmap->GetDepth(),
     206             :                              mrParent.GetDrawable(), mrParent.m_nXScreen,
     207           0 :                              mrParent.GetVisual().GetDepth(),
     208             :                              aFontGC,
     209             :                              0, 0,
     210           0 :                              pPixmap->GetWidth(), pPixmap->GetHeight(),
     211           0 :                              nX, nY );
     212           0 :     return true;
     213             : }
     214             : 
     215           0 : XID X11SalGraphicsImpl::GetXRenderPicture()
     216             : {
     217           0 :     XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
     218             : 
     219           0 :     if( !mrParent.m_aXRenderPicture )
     220             :     {
     221             :         // check xrender support for matching visual
     222           0 :         XRenderPictFormat* pXRenderFormat = mrParent.GetXRenderFormat();
     223           0 :         if( !pXRenderFormat )
     224           0 :             return 0;
     225             :         // get the matching xrender target for drawable
     226           0 :         mrParent.m_aXRenderPicture = rRenderPeer.CreatePicture( mrParent.hDrawable_, pXRenderFormat, 0, NULL );
     227             :     }
     228             : 
     229             :     {
     230             :         // reset clip region
     231             :         // TODO: avoid clip reset if already done
     232             :         XRenderPictureAttributes aAttr;
     233           0 :         aAttr.clip_mask = None;
     234           0 :         rRenderPeer.ChangePicture( mrParent.m_aXRenderPicture, CPClipMask, &aAttr );
     235             :     }
     236             : 
     237           0 :     return mrParent.m_aXRenderPicture;
     238             : }
     239             : 
     240         196 : void X11SalGraphicsImpl::freeResources()
     241             : {
     242         196 :     Display *pDisplay = mrParent.GetXDisplay();
     243             : 
     244         196 :     if( mpPenGC ) XFreeGC( pDisplay, mpPenGC ), mpPenGC = None;
     245         196 :     if( mpBrushGC ) XFreeGC( pDisplay, mpBrushGC ), mpBrushGC = None;
     246         196 :     if( mpMonoGC ) XFreeGC( pDisplay, mpMonoGC ), mpMonoGC = None;
     247         196 :     if( mpTrackingGC ) XFreeGC( pDisplay, mpTrackingGC ), mpTrackingGC = None;
     248         196 :     if( mpCopyGC ) XFreeGC( pDisplay, mpCopyGC ), mpCopyGC = None;
     249         196 :     if( mpMaskGC ) XFreeGC( pDisplay, mpMaskGC ), mpMaskGC = None;
     250         196 :     if( mpInvertGC ) XFreeGC( pDisplay, mpInvertGC ), mpInvertGC = None;
     251         196 :     if( mpInvert50GC ) XFreeGC( pDisplay, mpInvert50GC ), mpInvert50GC = None;
     252         196 :     if( mpStippleGC ) XFreeGC( pDisplay, mpStippleGC ), mpStippleGC = None;
     253         196 :     mbTrackingGC = mbPenGC = mbBrushGC = mbMonoGC = mbCopyGC = mbInvertGC = mbInvert50GC = mbStippleGC = false;
     254         196 : }
     255             : 
     256           2 : GC X11SalGraphicsImpl::CreateGC( Drawable hDrawable, unsigned long nMask )
     257             : {
     258             :     XGCValues values;
     259             : 
     260           2 :     values.graphics_exposures   = False;
     261           2 :     values.foreground           = mrParent.m_pColormap->GetBlackPixel()
     262           2 :                                   ^ mrParent.m_pColormap->GetWhitePixel();
     263           2 :     values.function             = GXxor;
     264           2 :     values.line_width           = 1;
     265           2 :     values.fill_style           = FillStippled;
     266           2 :     values.stipple              = mrParent.GetDisplay()->GetInvert50( mrParent.m_nXScreen );
     267           2 :     values.subwindow_mode       = ClipByChildren;
     268             : 
     269           2 :     return XCreateGC( mrParent.GetXDisplay(), hDrawable, nMask | GCSubwindowMode, &values );
     270             : }
     271             : 
     272           2 : inline GC X11SalGraphicsImpl::GetCopyGC()
     273             : {
     274           2 :     if( mbXORMode ) return GetInvertGC();
     275             : 
     276           2 :     if( !mpCopyGC )
     277           2 :         mpCopyGC = CreateGC( mrParent.GetDrawable() );
     278             : 
     279           2 :     if( !mbCopyGC )
     280             :     {
     281           2 :         mrParent.SetClipRegion( mpCopyGC );
     282           2 :         mbCopyGC = true;
     283             :     }
     284           2 :     return mpCopyGC;
     285             : }
     286             : 
     287           0 : GC X11SalGraphicsImpl::GetTrackingGC()
     288             : {
     289           0 :     const char    dash_list[2] = {2, 2};
     290             : 
     291           0 :     if( !mpTrackingGC )
     292             :     {
     293             :         XGCValues     values;
     294             : 
     295           0 :         values.graphics_exposures   = False;
     296           0 :         values.foreground           = mrParent.m_pColormap->GetBlackPixel()
     297           0 :                                       ^ mrParent.m_pColormap->GetWhitePixel();
     298           0 :         values.function             = GXxor;
     299           0 :         values.line_width           = 1;
     300           0 :         values.line_style           = LineOnOffDash;
     301             : 
     302             :         mpTrackingGC = XCreateGC( mrParent.GetXDisplay(), mrParent.GetDrawable(),
     303             :                                   GCGraphicsExposures | GCForeground | GCFunction
     304             :                                   | GCLineWidth | GCLineStyle,
     305           0 :                                   &values );
     306           0 :         XSetDashes( mrParent.GetXDisplay(), mpTrackingGC, 0, dash_list, 2 );
     307             :     }
     308             : 
     309           0 :     if( !mbTrackingGC )
     310             :     {
     311           0 :         mrParent.SetClipRegion( mpTrackingGC );
     312           0 :         mbTrackingGC = true;
     313             :     }
     314             : 
     315           0 :     return mpTrackingGC;
     316             : }
     317             : 
     318             : inline GC X11SalGraphicsImpl::GetMonoGC( Pixmap hPixmap )
     319             : {
     320             :     if( !mpMonoGC )
     321             :         mpMonoGC = CreateGC( hPixmap );
     322             : 
     323             :     if( !mbMonoGC )
     324             :     {
     325             :         mrParent.SetClipRegion( mpMonoGC );
     326             :         mbMonoGC = true;
     327             :     }
     328             : 
     329             :     return mpMonoGC;
     330             : }
     331             : 
     332           0 : GC X11SalGraphicsImpl::GetInvertGC()
     333             : {
     334           0 :     if( !mpInvertGC )
     335             :         mpInvertGC = CreateGC( mrParent.GetDrawable(),
     336             :                                GCGraphicsExposures
     337             :                                | GCForeground
     338             :                                | GCFunction
     339           0 :                                | GCLineWidth );
     340             : 
     341           0 :     if( !mbInvertGC )
     342             :     {
     343           0 :         mrParent.SetClipRegion( mpInvertGC );
     344           0 :         mbInvertGC = true;
     345             :     }
     346           0 :     return mpInvertGC;
     347             : }
     348             : 
     349           0 : GC X11SalGraphicsImpl::GetInvert50GC()
     350             : {
     351           0 :     if( !mpInvert50GC )
     352             :     {
     353             :         XGCValues values;
     354             : 
     355           0 :         values.graphics_exposures   = False;
     356           0 :         values.foreground           = mrParent.m_pColormap->GetWhitePixel();
     357           0 :         values.background           = mrParent.m_pColormap->GetBlackPixel();
     358           0 :         values.function             = GXinvert;
     359           0 :         values.line_width           = 1;
     360           0 :         values.line_style           = LineSolid;
     361             :         unsigned long nValueMask =
     362             :                                   GCGraphicsExposures
     363             :                                   | GCForeground
     364             :                                   | GCBackground
     365             :                                   | GCFunction
     366             :                                   | GCLineWidth
     367             :                                   | GCLineStyle
     368             :                                   | GCFillStyle
     369           0 :                                   | GCStipple;
     370             : 
     371           0 :         char* pEnv = getenv( "SAL_DO_NOT_USE_INVERT50" );
     372           0 :         if( pEnv && ! strcasecmp( pEnv, "true" ) )
     373             :         {
     374           0 :             values.fill_style = FillSolid;
     375           0 :             nValueMask &= ~ GCStipple;
     376             :         }
     377             :         else
     378             :         {
     379           0 :             values.fill_style           = FillStippled;
     380           0 :             values.stipple              = mrParent.GetDisplay()->GetInvert50( mrParent.m_nXScreen );
     381             :         }
     382             : 
     383             :         mpInvert50GC = XCreateGC( mrParent.GetXDisplay(), mrParent.GetDrawable(),
     384             :                                   nValueMask,
     385           0 :                                   &values );
     386             :     }
     387             : 
     388           0 :     if( !mbInvert50GC )
     389             :     {
     390           0 :         mrParent.SetClipRegion( mpInvert50GC );
     391           0 :         mbInvert50GC = true;
     392             :     }
     393           0 :     return mpInvert50GC;
     394             : }
     395             : 
     396           0 : inline GC X11SalGraphicsImpl::GetStippleGC()
     397             : {
     398           0 :     if( !mpStippleGC )
     399             :         mpStippleGC = CreateGC( mrParent.GetDrawable(),
     400             :                                 GCGraphicsExposures
     401             :                                 | GCFillStyle
     402           0 :                                 | GCLineWidth );
     403             : 
     404           0 :     if( !mbStippleGC )
     405             :     {
     406           0 :         XSetFunction( mrParent.GetXDisplay(), mpStippleGC, mbXORMode ? GXxor : GXcopy );
     407           0 :         mrParent.SetClipRegion( mpStippleGC );
     408           0 :         mbStippleGC = true;
     409             :     }
     410             : 
     411           0 :     return mpStippleGC;
     412             : }
     413             : 
     414         182 : GC X11SalGraphicsImpl::SelectBrush()
     415             : {
     416         182 :     Display *pDisplay = mrParent.GetXDisplay();
     417             : 
     418             :     DBG_ASSERT( mnBrushColor != SALCOLOR_NONE, "Brush Transparent" );
     419             : 
     420         182 :     if( !mpBrushGC )
     421             :     {
     422             :         XGCValues values;
     423         177 :         values.subwindow_mode       = ClipByChildren;
     424         177 :         values.fill_rule            = EvenOddRule;      // Pict import/ Gradient
     425         177 :         values.graphics_exposures   = False;
     426             : 
     427             :         mpBrushGC = XCreateGC( pDisplay, mrParent.hDrawable_,
     428             :                                GCSubwindowMode | GCFillRule | GCGraphicsExposures,
     429         177 :                                &values );
     430             :     }
     431             : 
     432         182 :     if( !mbBrushGC )
     433             :     {
     434         179 :         if( !mbDitherBrush )
     435             :         {
     436         179 :             XSetFillStyle ( pDisplay, mpBrushGC, FillSolid );
     437         179 :             XSetForeground( pDisplay, mpBrushGC, mnBrushPixel );
     438         179 :             if( mrParent.bPrinter_ )
     439           0 :                 XSetTile( pDisplay, mpBrushGC, None );
     440             :         }
     441             :         else
     442             :         {
     443           0 :             XSetFillStyle ( pDisplay, mpBrushGC, FillTiled );
     444           0 :             XSetTile      ( pDisplay, mpBrushGC, mrParent.hBrush_ );
     445             :         }
     446         179 :         XSetFunction  ( pDisplay, mpBrushGC, mbXORMode ? GXxor : GXcopy );
     447         179 :         mrParent.SetClipRegion( mpBrushGC );
     448             : 
     449         179 :         mbBrushGC = true;
     450             :     }
     451             : 
     452         182 :     return mpBrushGC;
     453             : }
     454             : 
     455           0 : GC X11SalGraphicsImpl::SelectPen()
     456             : {
     457           0 :     Display *pDisplay = mrParent.GetXDisplay();
     458             : 
     459           0 :     if( !mpPenGC )
     460             :     {
     461             :         XGCValues values;
     462           0 :         values.subwindow_mode       = ClipByChildren;
     463           0 :         values.fill_rule            = EvenOddRule;      // Pict import/ Gradient
     464           0 :         values.graphics_exposures   = False;
     465             : 
     466             :         mpPenGC = XCreateGC( pDisplay, mrParent.hDrawable_,
     467             :                              GCSubwindowMode | GCFillRule | GCGraphicsExposures,
     468           0 :                              &values );
     469             :     }
     470             : 
     471           0 :     if( !mbPenGC )
     472             :     {
     473           0 :         if( mnPenColor != SALCOLOR_NONE )
     474           0 :             XSetForeground( pDisplay, mpPenGC, mnPenPixel );
     475           0 :         XSetFunction  ( pDisplay, mpPenGC, mbXORMode ? GXxor : GXcopy );
     476           0 :         mrParent.SetClipRegion( mpPenGC );
     477           0 :         mbPenGC = true;
     478             :     }
     479             : 
     480           0 :     return mpPenGC;
     481             : }
     482             : 
     483           0 : void X11SalGraphicsImpl::DrawLines( sal_uLong              nPoints,
     484             :                                 const SalPolyLine &rPoints,
     485             :                                 GC                 pGC,
     486             :                                 bool               bClose
     487             :                                 )
     488             : {
     489             :     // calculate how many lines XWindow can draw in one go
     490           0 :     sal_uLong nMaxLines = (mrParent.GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
     491           0 :                       / sizeof(xPoint);
     492           0 :     if( nMaxLines > nPoints ) nMaxLines = nPoints;
     493             : 
     494             :     // print all lines that XWindows can draw
     495             :     sal_uLong n;
     496           0 :     for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
     497             :         XDrawLines( mrParent.GetXDisplay(),
     498             :                     mrParent.GetDrawable(),
     499             :                     pGC,
     500           0 :                     &rPoints[n],
     501             :                     nMaxLines,
     502           0 :                     CoordModeOrigin );
     503             : 
     504           0 :     if( n < nPoints )
     505             :         XDrawLines( mrParent.GetXDisplay(),
     506             :                     mrParent.GetDrawable(),
     507             :                     pGC,
     508           0 :                     &rPoints[n],
     509             :                     nPoints - n,
     510           0 :                     CoordModeOrigin );
     511           0 :     if( bClose )
     512             :     {
     513           0 :         if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
     514           0 :             drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
     515             :     }
     516           0 : }
     517             : 
     518           0 : void X11SalGraphicsImpl::copyBits( const SalTwoRect& rPosAry,
     519             :                                   SalGraphics      *pSSrcGraphics )
     520             : {
     521             :     X11SalGraphics* pSrcGraphics = pSSrcGraphics
     522             :         ? static_cast<X11SalGraphics*>(pSSrcGraphics)
     523           0 :         : &mrParent;
     524             : 
     525           0 :     if( rPosAry.mnSrcWidth <= 0
     526           0 :         || rPosAry.mnSrcHeight <= 0
     527           0 :         || rPosAry.mnDestWidth <= 0
     528           0 :         || rPosAry.mnDestHeight <= 0 )
     529             :     {
     530           0 :         return;
     531             :     }
     532             : 
     533             :     int n;
     534           0 :     if( pSrcGraphics == &mrParent )
     535             :     {
     536           0 :         n = 2;
     537             :     }
     538           0 :     else if( pSrcGraphics->bWindow_ )
     539             :     {
     540             :         // window or compatible virtual device
     541           0 :         if( pSrcGraphics->GetDisplay() == mrParent.GetDisplay() &&
     542           0 :             pSrcGraphics->m_nXScreen == mrParent.m_nXScreen &&
     543           0 :             pSrcGraphics->GetVisual().GetDepth() == mrParent.GetVisual().GetDepth()
     544             :             )
     545           0 :             n = 2; // same Display
     546             :         else
     547           0 :             n = 1; // printer or other display
     548             :     }
     549           0 :     else if( pSrcGraphics->bVirDev_ )
     550             :     {
     551             :         // printer compatible virtual device
     552           0 :         if( mrParent.bPrinter_ )
     553           0 :             n = 2; // printer or compatible virtual device == same display
     554             :         else
     555           0 :             n = 1; // window or compatible virtual device
     556             :     }
     557             :     else
     558           0 :         n = 0;
     559             : 
     560           0 :     if( n == 2
     561           0 :         && rPosAry.mnSrcWidth   == rPosAry.mnDestWidth
     562           0 :         && rPosAry.mnSrcHeight == rPosAry.mnDestHeight
     563             :         )
     564             :     {
     565             :         // #i60699# Need to generate graphics exposures (to repaint
     566             :         // obscured areas beneath overlapping windows), src and dest
     567             :         // are the same window.
     568           0 :         const bool bNeedGraphicsExposures( pSrcGraphics == &mrParent &&
     569           0 :                                            !mrParent.bVirDev_ &&
     570           0 :                                            pSrcGraphics->bWindow_ );
     571             : 
     572           0 :         GC pCopyGC = GetCopyGC();
     573             : 
     574           0 :         if( bNeedGraphicsExposures )
     575             :             XSetGraphicsExposures( mrParent.GetXDisplay(),
     576             :                                    pCopyGC,
     577           0 :                                    True );
     578             : 
     579             :         XCopyArea( mrParent.GetXDisplay(),
     580             :                    pSrcGraphics->GetDrawable(),     // source
     581             :                    mrParent.GetDrawable(),                   // destination
     582             :                    pCopyGC,                         // destination clipping
     583             :                    rPosAry.mnSrcX,     rPosAry.mnSrcY,
     584             :                    rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
     585           0 :                    rPosAry.mnDestX,    rPosAry.mnDestY );
     586             : 
     587           0 :         if( bNeedGraphicsExposures )
     588             :         {
     589           0 :             mrParent.YieldGraphicsExpose();
     590             : 
     591           0 :             if( pCopyGC )
     592             :                 XSetGraphicsExposures( mrParent.GetXDisplay(),
     593             :                                        pCopyGC,
     594           0 :                                        False );
     595           0 :         }
     596             :     }
     597           0 :     else if( n )
     598             :     {
     599             :         // #i60699# No chance to handle graphics exposures - we copy
     600             :         // to a temp bitmap first, into which no repaints are
     601             :         // technically possible.
     602             :         std::unique_ptr<SalBitmap> xDDB(pSrcGraphics->getBitmap( rPosAry.mnSrcX,
     603             :                                                                    rPosAry.mnSrcY,
     604             :                                                                    rPosAry.mnSrcWidth,
     605           0 :                                                                    rPosAry.mnSrcHeight ));
     606             : 
     607           0 :         if( !xDDB )
     608             :         {
     609             :             stderr0( "SalGraphics::CopyBits !pSrcGraphics->GetBitmap()\n" );
     610           0 :             return;
     611             :         }
     612             : 
     613           0 :         SalTwoRect aPosAry( rPosAry );
     614             : 
     615           0 :         aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0;
     616           0 :         drawBitmap( aPosAry, *xDDB );
     617             :     }
     618             :     else {
     619             :         stderr0( "X11SalGraphicsImpl::CopyBits from Printer not yet implemented\n" );
     620             :     }
     621             : }
     622             : 
     623           0 : void X11SalGraphicsImpl::copyArea ( long nDestX,    long nDestY,
     624             :                                 long nSrcX,     long nSrcY,
     625             :                                 long nSrcWidth, long nSrcHeight,
     626             :                                 sal_uInt16 )
     627             : {
     628           0 :     SalTwoRect aPosAry(nSrcX, nSrcY, nSrcWidth, nSrcHeight, nDestX, nDestY, nSrcWidth, nSrcHeight);
     629           0 :     copyBits(aPosAry, 0);
     630           0 : }
     631             : 
     632           2 : void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
     633             : {
     634           2 :     const SalDisplay*   pSalDisp = mrParent.GetDisplay();
     635           2 :     Display*            pXDisp = pSalDisp->GetDisplay();
     636           2 :     const Drawable      aDrawable( mrParent.GetDrawable() );
     637           2 :     const SalColormap&  rColMap = pSalDisp->GetColormap( mrParent.m_nXScreen );
     638           2 :     const long          nDepth = mrParent.GetDisplay()->GetVisual( mrParent.m_nXScreen ).GetDepth();
     639           2 :     GC                  aGC( GetCopyGC() );
     640             :     XGCValues           aOldVal, aNewVal;
     641           2 :     int                 nValues = GCForeground | GCBackground;
     642             : 
     643           2 :     if( rSalBitmap.GetBitCount() == 1 )
     644             :     {
     645             :         // set foreground/background values for 1Bit bitmaps
     646           0 :         XGetGCValues( pXDisp, aGC, nValues, &aOldVal );
     647           0 :         setForeBack(aNewVal, rColMap, rSalBitmap);
     648           0 :         XChangeGC( pXDisp, aGC, nValues, &aNewVal );
     649             :     }
     650             : 
     651           2 :     static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, mrParent.m_nXScreen, nDepth, rPosAry, aGC );
     652             : 
     653           2 :     if( rSalBitmap.GetBitCount() == 1 )
     654           0 :         XChangeGC( pXDisp, aGC, nValues, &aOldVal );
     655           2 :     XFlush( pXDisp );
     656           2 : }
     657             : 
     658           0 : void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry,
     659             :                                  const SalBitmap& rSrcBitmap,
     660             :                                  const SalBitmap& rMaskBitmap )
     661             : {
     662             :     DBG_ASSERT( !mrParent.bPrinter_, "Drawing of transparent bitmaps on printer devices is strictly forbidden" );
     663             : 
     664             :     // decide if alpha masking or transparency masking is needed
     665           0 :     BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( BITMAP_READ_ACCESS );
     666           0 :     if( pAlphaBuffer != NULL )
     667             :     {
     668           0 :         int nMaskFormat = pAlphaBuffer->mnFormat;
     669           0 :         const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, BITMAP_READ_ACCESS );
     670           0 :         if( nMaskFormat == BMP_FORMAT_8BIT_PAL )
     671           0 :             drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
     672             :     }
     673             : 
     674           0 :     drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
     675           0 : }
     676             : 
     677           0 : void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry,
     678             :                                        const SalBitmap& rSalBitmap,
     679             :                                        const SalBitmap& rTransBitmap )
     680             : {
     681           0 :     const SalDisplay*   pSalDisp = mrParent.GetDisplay();
     682           0 :     Display*            pXDisp = pSalDisp->GetDisplay();
     683           0 :     Drawable            aDrawable( mrParent.GetDrawable() );
     684             : 
     685             :     // figure work mode depth. If this is a VDev Drawable, use its
     686             :     // bitdepth to create pixmaps for, otherwise, XCopyArea will
     687             :     // refuse to work.
     688             :     const sal_uInt16    nDepth( mrParent.m_pVDev ?
     689           0 :                             static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() :
     690           0 :                             pSalDisp->GetVisual( mrParent.m_nXScreen ).GetDepth() );
     691             :     Pixmap          aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
     692           0 :                                         rPosAry.mnDestHeight, nDepth ) );
     693             :     Pixmap          aBG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
     694           0 :                                         rPosAry.mnDestHeight, nDepth ) );
     695             : 
     696           0 :     if( aFG && aBG )
     697             :     {
     698             :         GC                  aTmpGC;
     699             :         XGCValues           aValues;
     700           0 :         setForeBack(aValues, pSalDisp->GetColormap(mrParent.m_nXScreen), rSalBitmap);
     701           0 :         const int           nValues = GCFunction | GCForeground | GCBackground;
     702           0 :         SalTwoRect          aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
     703             : 
     704             :         // draw paint bitmap in pixmap #1
     705           0 :         aValues.function = GXcopy;
     706           0 :         aTmpGC = XCreateGC( pXDisp, aFG, nValues, &aValues );
     707           0 :         static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aFG, mrParent.m_nXScreen, nDepth, aTmpRect, aTmpGC );
     708             :         DBG_TESTTRANS( aFG );
     709             : 
     710             :         // draw background in pixmap #2
     711             :         XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
     712             :                    rPosAry.mnDestX, rPosAry.mnDestY,
     713             :                    rPosAry.mnDestWidth, rPosAry.mnDestHeight,
     714           0 :                    0, 0 );
     715             : 
     716             :         DBG_TESTTRANS( aBG );
     717             : 
     718             :         // mask out paint bitmap in pixmap #1 (transparent areas 0)
     719           0 :         aValues.function = GXand, aValues.foreground = 0x00000000, aValues.background = 0xffffffff;
     720           0 :         XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
     721           0 :         static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aFG, mrParent.m_nXScreen, 1, aTmpRect, aTmpGC );
     722             : 
     723             :         DBG_TESTTRANS( aFG );
     724             : 
     725             :         // #105055# For XOR mode, keep background behind bitmap intact
     726           0 :         if( !mbXORMode )
     727             :         {
     728             :             // mask out background in pixmap #2 (nontransparent areas 0)
     729           0 :             aValues.function = GXand, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
     730           0 :             XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
     731           0 :             static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aBG, mrParent.m_nXScreen, 1, aTmpRect, aTmpGC );
     732             : 
     733             :             DBG_TESTTRANS( aBG );
     734             :         }
     735             : 
     736             :         // merge pixmap #1 and pixmap #2 in pixmap #2
     737           0 :         aValues.function = GXxor, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
     738           0 :         XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
     739             :         XCopyArea( pXDisp, aFG, aBG, aTmpGC,
     740             :                    0, 0,
     741             :                    rPosAry.mnDestWidth, rPosAry.mnDestHeight,
     742           0 :                    0, 0 );
     743             :         DBG_TESTTRANS( aBG );
     744             : 
     745             :         // #105055# Disable XOR temporarily
     746           0 :         bool bOldXORMode( mbXORMode );
     747           0 :         mbXORMode = false;
     748             : 
     749             :         // copy pixmap #2 (result) to background
     750             :         XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(),
     751             :                    0, 0,
     752             :                    rPosAry.mnDestWidth, rPosAry.mnDestHeight,
     753           0 :                    rPosAry.mnDestX, rPosAry.mnDestY );
     754             : 
     755             :         DBG_TESTTRANS( aBG );
     756             : 
     757           0 :         mbXORMode = bOldXORMode;
     758             : 
     759           0 :         XFreeGC( pXDisp, aTmpGC );
     760           0 :         XFlush( pXDisp );
     761             :     }
     762             :     else
     763           0 :         drawBitmap( rPosAry, rSalBitmap );
     764             : 
     765           0 :     if( aFG )
     766           0 :         XFreePixmap( pXDisp, aFG );
     767             : 
     768           0 :     if( aBG )
     769           0 :         XFreePixmap( pXDisp, aBG );
     770           0 : }
     771             : 
     772           0 : bool X11SalGraphicsImpl::blendBitmap( const SalTwoRect&,
     773             :     const SalBitmap& )
     774             : {
     775           0 :     return false;
     776             : }
     777             : 
     778           0 : bool X11SalGraphicsImpl::blendAlphaBitmap( const SalTwoRect&,
     779             :     const SalBitmap&, const SalBitmap&, const SalBitmap& )
     780             : {
     781           0 :     return false;
     782             : }
     783             : 
     784           2 : bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR,
     785             :     const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
     786             : {
     787             :     // non 8-bit alpha not implemented yet
     788           2 :     if( rAlphaBmp.GetBitCount() != 8 )
     789           0 :         return false;
     790             : 
     791             :     // horizontal mirroring not implemented yet
     792           2 :     if( rTR.mnDestWidth < 0 )
     793           0 :         return false;
     794             : 
     795             :     // stretched conversion is not implemented yet
     796           2 :     if( rTR.mnDestWidth != rTR.mnSrcWidth )
     797           2 :         return false;
     798           0 :     if( rTR.mnDestHeight!= rTR.mnSrcHeight )
     799           0 :         return false;
     800             : 
     801             :     // create destination picture
     802           0 :     Picture aDstPic = GetXRenderPicture();
     803           0 :     if( !aDstPic )
     804           0 :         return false;
     805             : 
     806           0 :     const SalDisplay* pSalDisp = mrParent.GetDisplay();
     807           0 :     const SalVisual& rSalVis = pSalDisp->GetVisual( mrParent.m_nXScreen );
     808           0 :     Display* pXDisplay = pSalDisp->GetDisplay();
     809             : 
     810             :     // create source Picture
     811           0 :     int nDepth = mrParent.m_pVDev ? static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() : rSalVis.GetDepth();
     812           0 :     const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
     813           0 :     ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.hDrawable_, mrParent.m_nXScreen, nDepth, rTR );
     814           0 :     if( !pSrcDDB )
     815           0 :         return false;
     816             : 
     817             :     //#i75249# workaround for ImplGetDDB() giving us back a different depth than
     818             :     // we requested. E.g. mask pixmaps are always compatible with the drawable
     819             :     // TODO: find an appropriate picture format for these cases
     820             :     //       then remove the workaround below and the one for #i75531#
     821           0 :     if( nDepth != pSrcDDB->ImplGetDepth() )
     822           0 :         return false;
     823             : 
     824           0 :     Pixmap aSrcPM = pSrcDDB->ImplGetPixmap();
     825           0 :     if( !aSrcPM )
     826           0 :         return false;
     827             : 
     828             :     // create source picture
     829             :     // TODO: use scoped picture
     830           0 :     Visual* pSrcXVisual = rSalVis.GetVisual();
     831           0 :     XRenderPeer& rPeer = XRenderPeer::GetInstance();
     832           0 :     XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual );
     833           0 :     if( !pSrcVisFmt )
     834           0 :         return false;
     835           0 :     Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL );
     836           0 :     if( !aSrcPic )
     837           0 :         return false;
     838             : 
     839             :     // create alpha Picture
     840             : 
     841             :     // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
     842             :     // problem is that they don't provide an 8bit Pixmap on a non-8bit display
     843           0 :     BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( BITMAP_READ_ACCESS );
     844             : 
     845             :     // an XImage needs its data top_down
     846             :     // TODO: avoid wrongly oriented images in upper layers!
     847           0 :     const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
     848           0 :     const char* pSrcBits = reinterpret_cast<char*>(pAlphaBuffer->mpBits);
     849           0 :     char* pAlphaBits = new char[ nImageSize ];
     850           0 :     if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
     851           0 :         memcpy( pAlphaBits, pSrcBits, nImageSize );
     852             :     else
     853             :     {
     854           0 :         char* pDstBits = pAlphaBits + nImageSize;
     855           0 :         const int nLineSize = pAlphaBuffer->mnScanlineSize;
     856           0 :         for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
     857           0 :             memcpy( pDstBits, pSrcBits, nLineSize );
     858             :     }
     859             : 
     860             :     // the alpha values need to be inverted for XRender
     861             :     // TODO: make upper layers use standard alpha
     862           0 :     long* pLDst = reinterpret_cast<long*>(pAlphaBits);
     863           0 :     for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
     864           0 :         *pLDst = ~*pLDst;
     865             : 
     866           0 :     char* pCDst = reinterpret_cast<char*>(pLDst);
     867           0 :     for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
     868           0 :         *pCDst = ~*pCDst;
     869             : 
     870           0 :     const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
     871             :     XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
     872             :         pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
     873           0 :         pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
     874             : 
     875             :     Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_,
     876           0 :         rTR.mnDestWidth, rTR.mnDestHeight, 8 );
     877             : 
     878             :     XGCValues aAlphaGCV;
     879           0 :     aAlphaGCV.function = GXcopy;
     880           0 :     GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
     881             :     XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
     882           0 :         rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
     883           0 :     XFreeGC( pXDisplay, aAlphaGC );
     884           0 :     XFree( pAlphaImg );
     885           0 :     if( pAlphaBits != reinterpret_cast<char*>(pAlphaBuffer->mpBits) )
     886           0 :         delete[] pAlphaBits;
     887             : 
     888           0 :     const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, BITMAP_READ_ACCESS );
     889             : 
     890             :     XRenderPictureAttributes aAttr;
     891           0 :     aAttr.repeat = int(true);
     892           0 :     Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
     893           0 :     if( !aAlphaPic )
     894           0 :         return false;
     895             : 
     896             :     // set clipping
     897           0 :     if( mrParent.mpClipRegion && !XEmptyRegion( mrParent.mpClipRegion ) )
     898           0 :         rPeer.SetPictureClipRegion( aDstPic, mrParent.mpClipRegion );
     899             : 
     900             :     // paint source * mask over destination picture
     901             :     rPeer.CompositePicture( PictOpOver, aSrcPic, aAlphaPic, aDstPic,
     902             :         rTR.mnSrcX, rTR.mnSrcY, 0, 0,
     903           0 :         rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
     904             : 
     905           0 :     rPeer.FreePicture( aAlphaPic );
     906           0 :     XFreePixmap(pXDisplay, aAlphaPM);
     907           0 :     rPeer.FreePicture( aSrcPic );
     908           0 :     return true;
     909             : }
     910             : 
     911           0 : bool X11SalGraphicsImpl::drawTransformedBitmap(
     912             :     const basegfx::B2DPoint& rNull,
     913             :     const basegfx::B2DPoint& rX,
     914             :     const basegfx::B2DPoint& rY,
     915             :     const SalBitmap& rSourceBitmap,
     916             :     const SalBitmap* pAlphaBitmap)
     917             : {
     918             :     // here direct support for transformed bitmaps can be implemented
     919             :     (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
     920           0 :     return false;
     921             : }
     922             : 
     923           0 : bool X11SalGraphicsImpl::drawAlphaRect( long nX, long nY, long nWidth,
     924             :                                     long nHeight, sal_uInt8 nTransparency )
     925             : {
     926           0 :     if( ! mrParent.m_pFrame && ! mrParent.m_pVDev )
     927           0 :         return false;
     928             : 
     929           0 :     if( mbPenGC || !mbBrushGC || mbXORMode )
     930           0 :         return false; // can only perform solid fills without XOR.
     931             : 
     932           0 :     if( mrParent.m_pVDev && static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() < 8 )
     933           0 :         return false;
     934             : 
     935           0 :     Picture aDstPic = GetXRenderPicture();
     936           0 :     if( !aDstPic )
     937           0 :         return false;
     938             : 
     939           0 :     const double fTransparency = (100 - nTransparency) * (1.0/100);
     940           0 :     const XRenderColor aRenderColor = GetXRenderColor( mnBrushColor , fTransparency);
     941             : 
     942           0 :     XRenderPeer& rPeer = XRenderPeer::GetInstance();
     943             :     rPeer.FillRectangle( PictOpOver,
     944             :                          aDstPic,
     945             :                          &aRenderColor,
     946             :                          nX, nY,
     947           0 :                          nWidth, nHeight );
     948             : 
     949           0 :     return true;
     950             : }
     951             : 
     952           0 : void X11SalGraphicsImpl::drawBitmap( const SalTwoRect&,
     953             :                                  const SalBitmap&,
     954             :                                  SalColor )
     955             : {
     956             :     OSL_FAIL( "::DrawBitmap with transparent color not supported" );
     957           0 : }
     958             : 
     959           0 : void X11SalGraphicsImpl::drawMask( const SalTwoRect& rPosAry,
     960             :                                const SalBitmap &rSalBitmap,
     961             :                                SalColor nMaskColor )
     962             : {
     963           0 :     const SalDisplay*   pSalDisp = mrParent.GetDisplay();
     964           0 :     Display*            pXDisp = pSalDisp->GetDisplay();
     965           0 :     Drawable            aDrawable( mrParent.GetDrawable() );
     966             :     Pixmap              aStipple( limitXCreatePixmap( pXDisp, aDrawable,
     967             :                                                  rPosAry.mnDestWidth,
     968           0 :                                                  rPosAry.mnDestHeight, 1 ) );
     969             : 
     970           0 :     if( aStipple )
     971             :     {
     972           0 :         SalTwoRect  aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
     973             :         GC          aTmpGC;
     974             :         XGCValues   aValues;
     975             : 
     976             :         // create a stipple bitmap first (set bits are changed to unset bits and vice versa)
     977           0 :         aValues.function = GXcopyInverted;
     978           0 :         aValues.foreground = 1, aValues.background = 0;
     979           0 :         aTmpGC = XCreateGC( pXDisp, aStipple, GCFunction | GCForeground | GCBackground, &aValues );
     980           0 :         static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aStipple, mrParent.m_nXScreen, 1, aTwoRect, aTmpGC );
     981             : 
     982           0 :         XFreeGC( pXDisp, aTmpGC );
     983             : 
     984             :         // Set stipple and draw rectangle
     985           0 :         GC  aStippleGC( GetStippleGC() );
     986           0 :         int nX = rPosAry.mnDestX, nY = rPosAry.mnDestY;
     987             : 
     988           0 :         XSetStipple( pXDisp, aStippleGC, aStipple );
     989           0 :         XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
     990           0 :         XSetForeground( pXDisp, aStippleGC, mrParent.GetPixel( nMaskColor ) );
     991             :         XFillRectangle( pXDisp, aDrawable, aStippleGC,
     992             :                         nX, nY,
     993           0 :                         rPosAry.mnDestWidth, rPosAry.mnDestHeight );
     994           0 :         XFreePixmap( pXDisp, aStipple );
     995           0 :         XFlush( pXDisp );
     996             :     }
     997             :     else
     998           0 :         drawBitmap( rPosAry, rSalBitmap );
     999           0 : }
    1000             : 
    1001           0 : void X11SalGraphicsImpl::ResetClipRegion()
    1002             : {
    1003           0 :     if( mrParent.mpClipRegion )
    1004             :     {
    1005           0 :         mbPenGC         = false;
    1006           0 :         mrParent.bFontGC_ = false;
    1007           0 :         mbBrushGC       = false;
    1008           0 :         mbMonoGC        = false;
    1009           0 :         mbCopyGC        = false;
    1010           0 :         mbInvertGC      = false;
    1011           0 :         mbInvert50GC    = false;
    1012           0 :         mbStippleGC     = false;
    1013           0 :         mbTrackingGC    = false;
    1014             : 
    1015           0 :         XDestroyRegion( mrParent.mpClipRegion );
    1016           0 :         mrParent.mpClipRegion    = NULL;
    1017             :     }
    1018           0 : }
    1019             : 
    1020           3 : bool X11SalGraphicsImpl::setClipRegion( const vcl::Region& i_rClip )
    1021             : {
    1022           3 :     if( mrParent.mpClipRegion )
    1023           0 :         XDestroyRegion( mrParent.mpClipRegion );
    1024           3 :     mrParent.mpClipRegion = XCreateRegion();
    1025             : 
    1026           3 :     RectangleVector aRectangles;
    1027           3 :     i_rClip.GetRegionRectangles(aRectangles);
    1028             : 
    1029           6 :     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
    1030             :     {
    1031           3 :         const long nW(aRectIter->GetWidth());
    1032             : 
    1033           3 :         if(nW)
    1034             :         {
    1035           3 :             const long nH(aRectIter->GetHeight());
    1036             : 
    1037           3 :             if(nH)
    1038             :             {
    1039             :                 XRectangle aRect;
    1040             : 
    1041           3 :                 aRect.x = (short)aRectIter->Left();
    1042           3 :                 aRect.y = (short)aRectIter->Top();
    1043           3 :                 aRect.width = (unsigned short)nW;
    1044           3 :                 aRect.height = (unsigned short)nH;
    1045           3 :                 XUnionRectWithRegion(&aRect, mrParent.mpClipRegion, mrParent.mpClipRegion);
    1046             :             }
    1047             :         }
    1048             :     }
    1049             : 
    1050             :     //ImplRegionInfo aInfo;
    1051             :     //long nX, nY, nW, nH;
    1052             :     //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
    1053             :     //while( bRegionRect )
    1054             :     //{
    1055             :     //    if ( nW && nH )
    1056             :     //    {
    1057             :     //        XRectangle aRect;
    1058             :     //        aRect.x           = (short)nX;
    1059             :     //        aRect.y           = (short)nY;
    1060             :     //        aRect.width       = (unsigned short)nW;
    1061             :     //        aRect.height  = (unsigned short)nH;
    1062             : 
    1063             :     //        XUnionRectWithRegion( &aRect, mrParent.mpClipRegion, mrParent.mpClipRegion );
    1064             :     //    }
    1065             :     //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
    1066             :     //}
    1067             : 
    1068             :     // done, invalidate GCs
    1069           3 :     mbPenGC         = false;
    1070           3 :     mrParent.bFontGC_ = false;
    1071           3 :     mbBrushGC       = false;
    1072           3 :     mbMonoGC        = false;
    1073           3 :     mbCopyGC        = false;
    1074           3 :     mbInvertGC      = false;
    1075           3 :     mbInvert50GC    = false;
    1076           3 :     mbStippleGC     = false;
    1077           3 :     mbTrackingGC    = false;
    1078             : 
    1079           3 :     if( XEmptyRegion( mrParent.mpClipRegion ) )
    1080             :     {
    1081           0 :         XDestroyRegion( mrParent.mpClipRegion );
    1082           0 :         mrParent.mpClipRegion= NULL;
    1083             :     }
    1084           3 :     return true;
    1085             : }
    1086             : 
    1087         182 : void X11SalGraphicsImpl::SetLineColor()
    1088             : {
    1089         182 :     if( mnPenColor != SALCOLOR_NONE )
    1090             :     {
    1091         177 :         mnPenColor      = SALCOLOR_NONE;
    1092         177 :         mbPenGC         = false;
    1093             :     }
    1094         182 : }
    1095             : 
    1096           0 : void X11SalGraphicsImpl::SetLineColor( SalColor nSalColor )
    1097             : {
    1098           0 :     if( mnPenColor != nSalColor )
    1099             :     {
    1100           0 :         mnPenColor      = nSalColor;
    1101           0 :         mnPenPixel      = mrParent.GetPixel( nSalColor );
    1102           0 :         mbPenGC         = false;
    1103             :     }
    1104           0 : }
    1105             : 
    1106           0 : void X11SalGraphicsImpl::SetFillColor()
    1107             : {
    1108           0 :     if( mnBrushColor != SALCOLOR_NONE )
    1109             :     {
    1110           0 :         mbDitherBrush   = false;
    1111           0 :         mnBrushColor    = SALCOLOR_NONE;
    1112           0 :         mbBrushGC       = false;
    1113             :     }
    1114           0 : }
    1115             : 
    1116         177 : void X11SalGraphicsImpl::SetFillColor( SalColor nSalColor )
    1117             : {
    1118         177 :     if( mnBrushColor != nSalColor )
    1119             :     {
    1120           0 :         mbDitherBrush   = false;
    1121           0 :         mnBrushColor    = nSalColor;
    1122           0 :         mnBrushPixel    = mrParent.GetPixel( nSalColor );
    1123           0 :         if( TrueColor != mrParent.GetColormap().GetVisual().GetClass()
    1124           0 :             && mrParent.GetColormap().GetColor( mnBrushPixel ) != mnBrushColor
    1125           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
    1126           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
    1127           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
    1128           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
    1129           0 :             && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
    1130           0 :             && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
    1131           0 :             && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
    1132           0 :             && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
    1133           0 :             && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
    1134           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
    1135           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
    1136           0 :             && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
    1137           0 :             && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
    1138           0 :             && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
    1139           0 :             && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
    1140           0 :             && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
    1141           0 :             mbDitherBrush = mrParent.GetDitherPixmap(nSalColor);
    1142           0 :         mbBrushGC       = false;
    1143             :     }
    1144         177 : }
    1145             : 
    1146           0 : void X11SalGraphicsImpl::SetROPLineColor( SalROPColor nROPColor )
    1147             : {
    1148           0 :     switch( nROPColor )
    1149             :     {
    1150             :         case SAL_ROP_0 : // 0
    1151           0 :             mnPenPixel = (Pixel)0;
    1152           0 :             break;
    1153             :         case SAL_ROP_1 : // 1
    1154           0 :             mnPenPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
    1155           0 :             break;
    1156             :         case SAL_ROP_INVERT : // 2
    1157           0 :             mnPenPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
    1158           0 :             break;
    1159             :     }
    1160           0 :     mnPenColor  = mrParent.GetColormap().GetColor( mnPenPixel );
    1161           0 :     mbPenGC     = false;
    1162           0 : }
    1163             : 
    1164           0 : void X11SalGraphicsImpl::SetROPFillColor( SalROPColor nROPColor )
    1165             : {
    1166           0 :     switch( nROPColor )
    1167             :     {
    1168             :         case SAL_ROP_0 : // 0
    1169           0 :             mnBrushPixel = (Pixel)0;
    1170           0 :             break;
    1171             :         case SAL_ROP_1 : // 1
    1172           0 :             mnBrushPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
    1173           0 :             break;
    1174             :         case SAL_ROP_INVERT : // 2
    1175           0 :             mnBrushPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
    1176           0 :             break;
    1177             :     }
    1178           0 :     mbDitherBrush   = false;
    1179           0 :     mnBrushColor    = mrParent.GetColormap().GetColor( mnBrushPixel );
    1180           0 :     mbBrushGC       = false;
    1181           0 : }
    1182             : 
    1183        1002 : void X11SalGraphicsImpl::SetXORMode( bool bSet, bool )
    1184             : {
    1185        1002 :     if (mbXORMode != bSet)
    1186             :     {
    1187           0 :         mbXORMode   = bSet;
    1188           0 :         mbPenGC     = false;
    1189           0 :         mrParent.bFontGC_ = false;
    1190           0 :         mbBrushGC   = false;
    1191           0 :         mbMonoGC        = false;
    1192           0 :         mbCopyGC        = false;
    1193           0 :         mbInvertGC  = false;
    1194           0 :         mbInvert50GC    = false;
    1195           0 :         mbStippleGC = false;
    1196           0 :         mbTrackingGC    = false;
    1197             :     }
    1198        1002 : }
    1199             : 
    1200           0 : void X11SalGraphicsImpl::drawPixel( long nX, long nY )
    1201             : {
    1202           0 :     if( mnPenColor !=  SALCOLOR_NONE )
    1203           0 :         XDrawPoint( mrParent.GetXDisplay(), mrParent.GetDrawable(), SelectPen(), nX, nY );
    1204           0 : }
    1205             : 
    1206           0 : void X11SalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
    1207             : {
    1208           0 :     if( nSalColor != SALCOLOR_NONE )
    1209             :     {
    1210           0 :         Display *pDisplay = mrParent.GetXDisplay();
    1211             : 
    1212           0 :         if( (mnPenColor == SALCOLOR_NONE) && !mbPenGC )
    1213             :         {
    1214           0 :             SetLineColor( nSalColor );
    1215           0 :             XDrawPoint( pDisplay, mrParent.GetDrawable(), SelectPen(), nX, nY );
    1216           0 :             mnPenColor = SALCOLOR_NONE;
    1217           0 :             mbPenGC = False;
    1218             :         }
    1219             :         else
    1220             :         {
    1221           0 :             GC pGC = SelectPen();
    1222             : 
    1223           0 :             if( nSalColor != mnPenColor )
    1224           0 :                 XSetForeground( pDisplay, pGC, mrParent.GetPixel( nSalColor ) );
    1225             : 
    1226           0 :             XDrawPoint( pDisplay, mrParent.GetDrawable(), pGC, nX, nY );
    1227             : 
    1228           0 :             if( nSalColor != mnPenColor )
    1229           0 :                 XSetForeground( pDisplay, pGC, mnPenPixel );
    1230             :         }
    1231             :     }
    1232           0 : }
    1233             : 
    1234           0 : void X11SalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
    1235             : {
    1236           0 :     if( mnPenColor != SALCOLOR_NONE )
    1237             :     {
    1238             :         XDrawLine( mrParent.GetXDisplay(), mrParent.GetDrawable(),SelectPen(),
    1239           0 :                    nX1, nY1, nX2, nY2 );
    1240             :     }
    1241           0 : }
    1242             : 
    1243         180 : void X11SalGraphicsImpl::drawRect( long nX, long nY, long nDX, long nDY )
    1244             : {
    1245         180 :     if( mnBrushColor != SALCOLOR_NONE )
    1246             :     {
    1247             :         XFillRectangle( mrParent.GetXDisplay(),
    1248             :                         mrParent.GetDrawable(),
    1249             :                         SelectBrush(),
    1250         180 :                         nX, nY, nDX, nDY );
    1251             :     }
    1252             :     // description DrawRect is wrong; thus -1
    1253         180 :     if( mnPenColor != SALCOLOR_NONE )
    1254             :         XDrawRectangle( mrParent.GetXDisplay(),
    1255             :                         mrParent.GetDrawable(),
    1256             :                         SelectPen(),
    1257           0 :                         nX, nY, nDX-1, nDY-1 );
    1258         180 : }
    1259             : 
    1260           0 : void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
    1261             : {
    1262           0 :     drawPolyLine( nPoints, pPtAry, false );
    1263           0 : }
    1264             : 
    1265           0 : void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry, bool bClose )
    1266             : {
    1267           0 :     if( mnPenColor != SALCOLOR_NONE )
    1268             :     {
    1269           0 :         SalPolyLine Points( nPoints, pPtAry );
    1270             : 
    1271           0 :         DrawLines( nPoints, Points, SelectPen(), bClose );
    1272             :     }
    1273           0 : }
    1274             : 
    1275           2 : void X11SalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
    1276             : {
    1277           2 :     if( nPoints == 0 )
    1278           0 :         return;
    1279             : 
    1280           2 :     if( nPoints < 3 )
    1281             :     {
    1282           0 :         if( !mbXORMode )
    1283             :         {
    1284           0 :             if( 1 == nPoints  )
    1285           0 :                 drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
    1286             :             else
    1287             :                 drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
    1288           0 :                           pPtAry[1].mnX, pPtAry[1].mnY );
    1289             :         }
    1290           0 :         return;
    1291             :     }
    1292             : 
    1293           2 :     SalPolyLine Points( nPoints, pPtAry );
    1294             : 
    1295           2 :     nPoints++;
    1296             : 
    1297             :     /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
    1298             :      * do not draw the visible part of a polygon
    1299             :      * if it overlaps to the left of screen 0,y.
    1300             :      * This happens to be the case in the gradient drawn in the
    1301             :      * menubar background. workaround for the special case of
    1302             :      * of a rectangle overlapping to the left.
    1303             :      */
    1304           2 :     if( nPoints == 5 &&
    1305           0 :     Points[ 0 ].x == Points[ 1 ].x &&
    1306           0 :         Points[ 1 ].y == Points[ 2 ].y &&
    1307           0 :         Points[ 2 ].x == Points[ 3 ].x &&
    1308           2 :         Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
    1309             :        )
    1310             :     {
    1311           0 :         bool bLeft = false;
    1312           0 :         bool bRight = false;
    1313           0 :         for(unsigned int i = 0; i < nPoints; i++ )
    1314             :     {
    1315           0 :             if( Points[i].x < 0 )
    1316           0 :                 bLeft = true;
    1317             :             else
    1318           0 :                 bRight= true;
    1319             :     }
    1320           0 :     if( bLeft && ! bRight )
    1321           0 :         return;
    1322           0 :     if( bLeft && bRight )
    1323             :         {
    1324           0 :             for( unsigned int i = 0; i < nPoints; i++ )
    1325           0 :                 if( Points[i].x < 0 )
    1326           0 :                     Points[i].x = 0;
    1327             :         }
    1328             :     }
    1329             : 
    1330           2 :     if( mnBrushColor != SALCOLOR_NONE )
    1331             :         XFillPolygon( mrParent.GetXDisplay(),
    1332             :                       mrParent.GetDrawable(),
    1333             :                       SelectBrush(),
    1334           2 :                       &Points[0], nPoints,
    1335           4 :                       Complex, CoordModeOrigin );
    1336             : 
    1337           2 :     if( mnPenColor != SALCOLOR_NONE )
    1338           0 :         DrawLines( nPoints, Points, SelectPen(), true );
    1339             : }
    1340             : 
    1341           0 : void X11SalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly,
    1342             :                                    const sal_uInt32    *pPoints,
    1343             :                                    PCONSTSALPOINT  *pPtAry )
    1344             : {
    1345           0 :     if( mnBrushColor != SALCOLOR_NONE )
    1346             :     {
    1347             :         sal_uInt32      i, n;
    1348           0 :         Region          pXRegA  = NULL;
    1349             : 
    1350           0 :         for( i = 0; i < nPoly; i++ ) {
    1351           0 :             n = pPoints[i];
    1352           0 :             SalPolyLine Points( n, pPtAry[i] );
    1353           0 :             if( n > 2 )
    1354             :             {
    1355           0 :                 Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
    1356           0 :                 if( !pXRegA )
    1357           0 :                     pXRegA = pXRegB;
    1358             :                 else
    1359             :                 {
    1360           0 :                     XXorRegion( pXRegA, pXRegB, pXRegA );
    1361           0 :                     XDestroyRegion( pXRegB );
    1362             :                 }
    1363             :             }
    1364           0 :         }
    1365             : 
    1366           0 :         if( pXRegA )
    1367             :         {
    1368             :             XRectangle aXRect;
    1369           0 :             XClipBox( pXRegA, &aXRect );
    1370             : 
    1371           0 :             GC pGC = SelectBrush();
    1372           0 :             mrParent.SetClipRegion( pGC, pXRegA ); // ??? twice
    1373           0 :             XDestroyRegion( pXRegA );
    1374           0 :             mbBrushGC = false;
    1375             : 
    1376             :             XFillRectangle( mrParent.GetXDisplay(),
    1377             :                             mrParent.GetDrawable(),
    1378             :                             pGC,
    1379           0 :                             aXRect.x, aXRect.y, aXRect.width, aXRect.height );
    1380             :         }
    1381             :    }
    1382             : 
    1383           0 :    if( mnPenColor != SALCOLOR_NONE )
    1384           0 :        for( sal_uInt32 i = 0; i < nPoly; i++ )
    1385           0 :            drawPolyLine( pPoints[i], pPtAry[i], true );
    1386           0 : }
    1387             : 
    1388           0 : bool X11SalGraphicsImpl::drawPolyLineBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
    1389             : {
    1390           0 :     return false;
    1391             : }
    1392             : 
    1393           0 : bool X11SalGraphicsImpl::drawPolygonBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
    1394             : {
    1395           0 :     return false;
    1396             : }
    1397             : 
    1398           0 : bool X11SalGraphicsImpl::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
    1399             :                                                 const SalPoint* const*, const sal_uInt8* const* )
    1400             : {
    1401           0 :     return false;
    1402             : }
    1403             : 
    1404           0 : void X11SalGraphicsImpl::invert( long       nX,
    1405             :                                 long        nY,
    1406             :                                 long        nDX,
    1407             :                                 long        nDY,
    1408             :                                 SalInvert   nFlags )
    1409             : {
    1410             :     GC pGC;
    1411           0 :     if( SAL_INVERT_50 & nFlags )
    1412             :     {
    1413           0 :         pGC = GetInvert50GC();
    1414           0 :         XFillRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(), pGC, nX, nY, nDX, nDY );
    1415             :     }
    1416             :     else
    1417             :     {
    1418           0 :         if ( SAL_INVERT_TRACKFRAME & nFlags )
    1419             :         {
    1420           0 :             pGC = GetTrackingGC();
    1421           0 :             XDrawRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(),  pGC, nX, nY, nDX, nDY );
    1422             :         }
    1423             :         else
    1424             :         {
    1425           0 :             pGC = GetInvertGC();
    1426           0 :             XFillRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(),  pGC, nX, nY, nDX, nDY );
    1427             :         }
    1428             :     }
    1429           0 : }
    1430             : 
    1431           0 : void X11SalGraphicsImpl::invert( sal_uInt32 nPoints,
    1432             :                              const SalPoint* pPtAry,
    1433             :                              SalInvert nFlags )
    1434             : {
    1435           0 :     SalPolyLine Points ( nPoints, pPtAry );
    1436             : 
    1437             :     GC pGC;
    1438           0 :     if( SAL_INVERT_50 & nFlags )
    1439           0 :         pGC = GetInvert50GC();
    1440             :     else
    1441           0 :         if ( SAL_INVERT_TRACKFRAME & nFlags )
    1442           0 :             pGC = GetTrackingGC();
    1443             :         else
    1444           0 :             pGC = GetInvertGC();
    1445             : 
    1446           0 :     if( SAL_INVERT_TRACKFRAME & nFlags )
    1447           0 :         DrawLines ( nPoints, Points, pGC, true );
    1448             :     else
    1449             :         XFillPolygon( mrParent.GetXDisplay(),
    1450             :                       mrParent.GetDrawable(),
    1451             :                       pGC,
    1452           0 :                       &Points[0], nPoints,
    1453           0 :                       Complex, CoordModeOrigin );
    1454           0 : }
    1455             : 
    1456           0 : bool X11SalGraphicsImpl::drawEPS( long,long,long,long,void*,sal_uLong )
    1457             : {
    1458           0 :     return false;
    1459             : }
    1460             : 
    1461             : // draw a poly-polygon
    1462           0 : bool X11SalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency )
    1463             : {
    1464             :     // nothing to do for empty polypolygons
    1465           0 :     const int nOrigPolyCount = rOrigPolyPoly.count();
    1466           0 :     if( nOrigPolyCount <= 0 )
    1467           0 :         return true;
    1468             : 
    1469             :     // nothing to do if everything is transparent
    1470           0 :     if( (mnBrushColor == SALCOLOR_NONE)
    1471           0 :     &&  (mnPenColor == SALCOLOR_NONE) )
    1472           0 :         return true;
    1473             : 
    1474             :     // cannot handle pencolor!=brushcolor yet
    1475           0 :     if( (mnPenColor != SALCOLOR_NONE)
    1476           0 :     &&  (mnPenColor != mnBrushColor) )
    1477           0 :         return false;
    1478             : 
    1479             :     // TODO: remove the env-variable when no longer needed
    1480           0 :     static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
    1481           0 :     if( pRenderEnv )
    1482           0 :         return false;
    1483             : 
    1484             :     // snap to raster if requested
    1485           0 :     basegfx::B2DPolyPolygon aPolyPoly = rOrigPolyPoly;
    1486           0 :     const bool bSnapToRaster = !mrParent.getAntiAliasB2DDraw();
    1487           0 :     if( bSnapToRaster )
    1488           0 :         aPolyPoly = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges( aPolyPoly );
    1489             : 
    1490             :     // don't bother with polygons outside of visible area
    1491           0 :     const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
    1492           0 :     aPolyPoly = basegfx::tools::clipPolyPolygonOnRange( aPolyPoly, aViewRange, true, false );
    1493           0 :     if( !aPolyPoly.count() )
    1494           0 :         return true;
    1495             : 
    1496             :     // tesselate the polypolygon into trapezoids
    1497           0 :     basegfx::B2DTrapezoidVector aB2DTrapVector;
    1498           0 :     basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aPolyPoly );
    1499           0 :     const int nTrapCount = aB2DTrapVector.size();
    1500           0 :     if( !nTrapCount )
    1501           0 :         return true;
    1502           0 :     const bool bDrawn = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
    1503           0 :     return bDrawn;
    1504             : }
    1505             : 
    1506           0 : long X11SalGraphicsImpl::GetGraphicsHeight() const
    1507             : {
    1508           0 :     if( mrParent.m_pFrame )
    1509           0 :         return mrParent.m_pFrame->maGeometry.nHeight;
    1510           0 :     else if( mrParent.m_pVDev )
    1511           0 :         return static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetHeight();
    1512             :     else
    1513           0 :         return 0;
    1514             : }
    1515             : 
    1516           0 : bool X11SalGraphicsImpl::drawFilledTrapezoids( const ::basegfx::B2DTrapezoid* pB2DTraps, int nTrapCount, double fTransparency )
    1517             : {
    1518           0 :     if( nTrapCount <= 0 )
    1519           0 :         return true;
    1520             : 
    1521           0 :     Picture aDstPic = GetXRenderPicture();
    1522             :     // check xrender support for this drawable
    1523           0 :     if( !aDstPic )
    1524           0 :         return false;
    1525             : 
    1526             :      // convert the B2DTrapezoids into XRender-Trapezoids
    1527             :     typedef std::vector<XTrapezoid> TrapezoidVector;
    1528           0 :     TrapezoidVector aTrapVector( nTrapCount );
    1529           0 :     const basegfx::B2DTrapezoid* pB2DTrap = pB2DTraps;
    1530           0 :     for( int i = 0; i < nTrapCount; ++pB2DTrap, ++i )
    1531             :     {
    1532           0 :         XTrapezoid& rTrap = aTrapVector[ i ] ;
    1533             : 
    1534             :          // set y-coordinates
    1535           0 :         const double fY1 = pB2DTrap->getTopY();
    1536           0 :         rTrap.left.p1.y = rTrap.right.p1.y = rTrap.top = XDoubleToFixed( fY1 );
    1537           0 :         const double fY2 = pB2DTrap->getBottomY();
    1538           0 :         rTrap.left.p2.y = rTrap.right.p2.y = rTrap.bottom = XDoubleToFixed( fY2 );
    1539             : 
    1540             :          // set x-coordinates
    1541           0 :         const double fXL1 = pB2DTrap->getTopXLeft();
    1542           0 :         rTrap.left.p1.x = XDoubleToFixed( fXL1 );
    1543           0 :         const double fXR1 = pB2DTrap->getTopXRight();
    1544           0 :         rTrap.right.p1.x = XDoubleToFixed( fXR1 );
    1545           0 :         const double fXL2 = pB2DTrap->getBottomXLeft();
    1546           0 :         rTrap.left.p2.x = XDoubleToFixed( fXL2 );
    1547           0 :         const double fXR2 = pB2DTrap->getBottomXRight();
    1548           0 :         rTrap.right.p2.x = XDoubleToFixed( fXR2 );
    1549             :     }
    1550             : 
    1551             :     // get xrender Picture for polygon foreground
    1552             :     // TODO: cache it like the target picture which uses GetXRenderPicture()
    1553           0 :     XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
    1554           0 :     SalDisplay::RenderEntry& rEntry = mrParent.GetDisplay()->GetRenderEntries( mrParent.m_nXScreen )[ 32 ];
    1555           0 :     if( !rEntry.m_aPicture )
    1556             :     {
    1557           0 :         Display* pXDisplay = mrParent.GetXDisplay();
    1558             : 
    1559           0 :         rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_, 1, 1, 32 );
    1560             :         XRenderPictureAttributes aAttr;
    1561           0 :         aAttr.repeat = int(true);
    1562             : 
    1563           0 :         XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
    1564           0 :         rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
    1565             :     }
    1566             : 
    1567             :     // set polygon foreground color and opacity
    1568           0 :     XRenderColor aRenderColor = GetXRenderColor( mnBrushColor , fTransparency );
    1569           0 :     rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
    1570             : 
    1571             :     // set clipping
    1572             :     // TODO: move into GetXRenderPicture?
    1573           0 :     if( mrParent.mpClipRegion && !XEmptyRegion( mrParent.mpClipRegion ) )
    1574           0 :         rRenderPeer.SetPictureClipRegion( aDstPic, mrParent.mpClipRegion );
    1575             : 
    1576             :     // render the trapezoids
    1577           0 :     const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
    1578             :     rRenderPeer.CompositeTrapezoids( PictOpOver,
    1579           0 :         rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
    1580             : 
    1581           0 :     return true;
    1582             : }
    1583             : 
    1584           0 : bool X11SalGraphicsImpl::drawPolyLine(
    1585             :     const ::basegfx::B2DPolygon& rPolygon,
    1586             :     double fTransparency,
    1587             :     const ::basegfx::B2DVector& rLineWidth,
    1588             :     basegfx::B2DLineJoin eLineJoin,
    1589             :     com::sun::star::drawing::LineCap eLineCap)
    1590             : {
    1591           0 :     const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2);
    1592             : 
    1593             :     // #i101491#
    1594           0 :     if( !bIsHairline && (rPolygon.count() > 1000) )
    1595             :     {
    1596             :         // the used basegfx::tools::createAreaGeometry is simply too
    1597             :         // expensive with very big polygons; fallback to caller (who
    1598             :         // should use ImplLineConverter normally)
    1599             :         // AW: ImplLineConverter had to be removed since it does not even
    1600             :         // know LineJoins, so the fallback will now prepare the line geometry
    1601             :         // the same way.
    1602           0 :         return false;
    1603             :     }
    1604             : 
    1605             :     // temporarily adjust brush color to pen color
    1606             :     // since the line is drawn as an area-polygon
    1607           0 :     const SalColor aKeepBrushColor = mnBrushColor;
    1608           0 :     mnBrushColor = mnPenColor;
    1609             : 
    1610             :     // #i11575#desc5#b adjust B2D tesselation result to raster positions
    1611           0 :     basegfx::B2DPolygon aPolygon = rPolygon;
    1612           0 :     const double fHalfWidth = 0.5 * rLineWidth.getX();
    1613             : 
    1614             :     // #i122456# This is probably thought to happen to align hairlines to pixel positions, so
    1615             :     // it should be a 0.5 translation, not more. It will definitely go wrong with fat lines
    1616           0 :     aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(0.5, 0.5) );
    1617             : 
    1618             :     // shortcut for hairline drawing to improve performance
    1619           0 :     bool bDrawnOk = true;
    1620           0 :     if( bIsHairline )
    1621             :     {
    1622             :         // hairlines can benefit from a simplified tesselation
    1623             :         // e.g. for hairlines the linejoin style can be ignored
    1624           0 :         basegfx::B2DTrapezoidVector aB2DTrapVector;
    1625           0 :         basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() );
    1626             : 
    1627             :         // draw tesselation result
    1628           0 :         const int nTrapCount = aB2DTrapVector.size();
    1629           0 :         if( nTrapCount > 0 )
    1630           0 :             bDrawnOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
    1631             : 
    1632             :         // restore the original brush GC
    1633           0 :         mnBrushColor = aKeepBrushColor;
    1634           0 :         return bDrawnOk;
    1635             :     }
    1636             : 
    1637             :     // get the area polygon for the line polygon
    1638           0 :     if( (rLineWidth.getX() != rLineWidth.getY())
    1639           0 :     && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
    1640             :     {
    1641             :         // prepare for createAreaGeometry() with anisotropic linewidth
    1642           0 :         aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
    1643             :     }
    1644             : 
    1645             :     // create the area-polygon for the line
    1646           0 :     const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) );
    1647             : 
    1648           0 :     if( (rLineWidth.getX() != rLineWidth.getY())
    1649           0 :     && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
    1650             :     {
    1651             :         // postprocess createAreaGeometry() for anisotropic linewidth
    1652           0 :         aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
    1653             :     }
    1654             : 
    1655             :     // draw each area polypolygon component individually
    1656             :     // to emulate the polypolygon winding rule "non-zero"
    1657           0 :     const int nPolyCount = aAreaPolyPoly.count();
    1658           0 :     for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
    1659             :     {
    1660           0 :         const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
    1661           0 :         bDrawnOk = drawPolyPolygon( aOnePoly, fTransparency );
    1662           0 :         if( !bDrawnOk )
    1663           0 :             break;
    1664           0 :     }
    1665             : 
    1666             :     // restore the original brush GC
    1667           0 :     mnBrushColor = aKeepBrushColor;
    1668           0 :     return bDrawnOk;
    1669             : }
    1670             : 
    1671           0 : SalColor X11SalGraphicsImpl::getPixel( long nX, long nY )
    1672             : {
    1673           0 :     if( mrParent.bWindow_ && !mrParent.bVirDev_ )
    1674             :     {
    1675             :         XWindowAttributes aAttrib;
    1676             : 
    1677           0 :         XGetWindowAttributes( mrParent.GetXDisplay(), mrParent.GetDrawable(), &aAttrib );
    1678           0 :         if( aAttrib.map_state != IsViewable )
    1679             :         {
    1680             :             stderr0( "X11SalGraphics::GetPixel drawable not viewable\n" );
    1681           0 :             return 0;
    1682             :         }
    1683             :     }
    1684             : 
    1685             :     XImage *pXImage = XGetImage( mrParent.GetXDisplay(),
    1686             :                                      mrParent.GetDrawable(),
    1687             :                                  nX, nY,
    1688             :                                  1,  1,
    1689             :                                  AllPlanes,
    1690           0 :                                  ZPixmap );
    1691           0 :     if( !pXImage )
    1692             :     {
    1693             :         stderr0( "X11SalGraphics::GetPixel !XGetImage()\n" );
    1694           0 :         return 0;
    1695             :     }
    1696             : 
    1697             :     XColor aXColor;
    1698             : 
    1699           0 :     aXColor.pixel = XGetPixel( pXImage, 0, 0 );
    1700           0 :     XDestroyImage( pXImage );
    1701             : 
    1702           0 :     return mrParent.GetColormap().GetColor( aXColor.pixel );
    1703             : }
    1704             : 
    1705           5 : SalBitmap *X11SalGraphicsImpl::getBitmap( long nX, long nY, long nDX, long nDY )
    1706             : {
    1707           5 :     if( mrParent.bPrinter_ && !mrParent.bVirDev_ )
    1708           0 :         return NULL;
    1709             : 
    1710           5 :     bool bFakeWindowBG = false;
    1711             : 
    1712             :     // normalize
    1713           5 :     if( nDX < 0 )
    1714             :     {
    1715           0 :         nX += nDX;
    1716           0 :         nDX = -nDX;
    1717             :     }
    1718           5 :     if ( nDY < 0 )
    1719             :     {
    1720           0 :         nY += nDY;
    1721           0 :         nDY = -nDY;
    1722             :     }
    1723             : 
    1724           5 :     if( mrParent.bWindow_ && !mrParent.bVirDev_ )
    1725             :     {
    1726             :         XWindowAttributes aAttrib;
    1727             : 
    1728           0 :         XGetWindowAttributes( mrParent.GetXDisplay(), mrParent.GetDrawable(), &aAttrib );
    1729           0 :         if( aAttrib.map_state != IsViewable )
    1730           0 :             bFakeWindowBG = true;
    1731             :         else
    1732             :         {
    1733           0 :             long nOrgDX = nDX, nOrgDY = nDY;
    1734             : 
    1735             :             // clip to window size
    1736           0 :             if ( nX < 0 )
    1737             :             {
    1738           0 :                 nDX += nX;
    1739           0 :                 nX   = 0;
    1740             :             }
    1741           0 :             if ( nY < 0 )
    1742             :             {
    1743           0 :                 nDY += nY;
    1744           0 :                 nY   = 0;
    1745             :             }
    1746           0 :             if( nX + nDX > aAttrib.width )
    1747           0 :                 nDX = aAttrib.width  - nX;
    1748           0 :             if( nY + nDY > aAttrib.height )
    1749           0 :                 nDY = aAttrib.height - nY;
    1750             : 
    1751             :             // inside ?
    1752           0 :             if( nDX <= 0 || nDY <= 0 )
    1753             :             {
    1754           0 :                 bFakeWindowBG = true;
    1755           0 :                 nDX = nOrgDX;
    1756           0 :                 nDY = nOrgDY;
    1757             :             }
    1758             :         }
    1759             :     }
    1760             : 
    1761           5 :     X11SalBitmap* pSalBitmap = new X11SalBitmap;
    1762           5 :     sal_uInt16 nBitCount = GetBitCount();
    1763             : 
    1764           5 :     if( &mrParent.GetDisplay()->GetColormap( mrParent.m_nXScreen ) != &mrParent.GetColormap() )
    1765           0 :         nBitCount = 1;
    1766             : 
    1767           5 :     if( ! bFakeWindowBG )
    1768           5 :         pSalBitmap->ImplCreateFromDrawable( mrParent.GetDrawable(), mrParent.m_nXScreen, nBitCount, nX, nY, nDX, nDY );
    1769             :     else
    1770           0 :         pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
    1771             : 
    1772           5 :     return pSalBitmap;
    1773             : }
    1774             : 
    1775         348 : sal_uInt16 X11SalGraphicsImpl::GetBitCount() const
    1776             : {
    1777         348 :     return mrParent.GetVisual().GetDepth();
    1778             : }
    1779             : 
    1780           0 : long X11SalGraphicsImpl::GetGraphicsWidth() const
    1781             : {
    1782           0 :     if( mrParent.m_pFrame )
    1783           0 :         return mrParent.m_pFrame->maGeometry.nWidth;
    1784           0 :     else if( mrParent.m_pVDev )
    1785           0 :         return static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetWidth();
    1786             :     else
    1787           0 :         return 0;
    1788             : }
    1789             : 
    1790           0 : bool X11SalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/, const Gradient& /*rGradient*/)
    1791             : {
    1792           0 :     return false;
    1793           9 : }
    1794             : 
    1795             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11