19f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 59f62ea84SAndrew Rist * distributed with this work for additional information 69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 109f62ea84SAndrew Rist * 119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 129f62ea84SAndrew Rist * 139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 149f62ea84SAndrew Rist * software distributed under the License is distributed on an 159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 179f62ea84SAndrew Rist * specific language governing permissions and limitations 189f62ea84SAndrew Rist * under the License. 199f62ea84SAndrew Rist * 209f62ea84SAndrew Rist *************************************************************/ 219f62ea84SAndrew Rist 229f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <tools/ref.hxx> 28cdf0e10cSrcweir #include <tools/debug.hxx> 29cdf0e10cSrcweir #include <tools/poly.hxx> 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include <vcl/svapp.hxx> 32cdf0e10cSrcweir #include <vcl/ctrl.hxx> 33cdf0e10cSrcweir #include <vcl/region.hxx> 34cdf0e10cSrcweir #include <vcl/virdev.hxx> 35cdf0e10cSrcweir #include <vcl/window.hxx> 36cdf0e10cSrcweir #include <vcl/metaact.hxx> 37cdf0e10cSrcweir #include <vcl/gdimtf.hxx> 38cdf0e10cSrcweir #include <vcl/print.hxx> 39cdf0e10cSrcweir #include <vcl/outdev.hxx> 40cdf0e10cSrcweir #include <vcl/unowrap.hxx> 41cdf0e10cSrcweir // declare system types in sysdata.hxx 42cdf0e10cSrcweir #include <svsys.h> 43cdf0e10cSrcweir #include <vcl/sysdata.hxx> 44cdf0e10cSrcweir 45cdf0e10cSrcweir #include <salgdi.hxx> 46cdf0e10cSrcweir #include <sallayout.hxx> 47cdf0e10cSrcweir #include <salframe.hxx> 48cdf0e10cSrcweir #include <salvd.hxx> 49cdf0e10cSrcweir #include <salprn.hxx> 50cdf0e10cSrcweir #include <svdata.hxx> 51cdf0e10cSrcweir #include <window.h> 52cdf0e10cSrcweir #include <outdev.h> 53cdf0e10cSrcweir #include <region.h> 54cdf0e10cSrcweir #include <outdata.hxx> 55cdf0e10cSrcweir 56cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 57cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx> 58cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 59cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx> 60cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 61cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 62cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx> 63cdf0e10cSrcweir #include <basegfx/polygon/b2dlinegeometry.hxx> 64cdf0e10cSrcweir 65cdf0e10cSrcweir #include <com/sun/star/awt/XGraphics.hpp> 66cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx> 67cdf0e10cSrcweir #include <com/sun/star/rendering/XCanvas.hpp> 68cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 69cdf0e10cSrcweir #include <vcl/unohelp.hxx> 70cdf0e10cSrcweir 71cdf0e10cSrcweir #include <numeric> 72cdf0e10cSrcweir 73cdf0e10cSrcweir using namespace ::com::sun::star; 74cdf0e10cSrcweir 75cdf0e10cSrcweir DBG_NAME( OutputDevice ) 76cdf0e10cSrcweir DBG_NAME( Polygon ) 77cdf0e10cSrcweir DBG_NAME( PolyPolygon ) 78cdf0e10cSrcweir DBG_NAMEEX( Region ) 79cdf0e10cSrcweir 80cdf0e10cSrcweir // ----------------------------------------------------------------------- 81cdf0e10cSrcweir 82cdf0e10cSrcweir #ifdef DBG_UTIL 83cdf0e10cSrcweir const char* ImplDbgCheckOutputDevice( const void* pObj ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 86cdf0e10cSrcweir 87cdf0e10cSrcweir const OutputDevice* pOutDev = (OutputDevice*)pObj; 88cdf0e10cSrcweir 89cdf0e10cSrcweir if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) && 90cdf0e10cSrcweir (pOutDev->GetOutDevType() != OUTDEV_WINDOW) && 91cdf0e10cSrcweir (pOutDev->GetOutDevType() != OUTDEV_PRINTER) && 92cdf0e10cSrcweir (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) ) 93cdf0e10cSrcweir return "OutputDevice data overwrite"; 94cdf0e10cSrcweir 95cdf0e10cSrcweir return NULL; 96cdf0e10cSrcweir } 97cdf0e10cSrcweir #endif 98cdf0e10cSrcweir 99cdf0e10cSrcweir // ======================================================================= 100cdf0e10cSrcweir 101cdf0e10cSrcweir #define OUTDEV_POLYPOLY_STACKBUF 32 102cdf0e10cSrcweir 103cdf0e10cSrcweir // ======================================================================= 104cdf0e10cSrcweir 105cdf0e10cSrcweir struct ImplObjStack 106cdf0e10cSrcweir { 107cdf0e10cSrcweir ImplObjStack* mpPrev; 108cdf0e10cSrcweir MapMode* mpMapMode; 109cdf0e10cSrcweir Region* mpClipRegion; 110cdf0e10cSrcweir Color* mpLineColor; 111cdf0e10cSrcweir Color* mpFillColor; 112cdf0e10cSrcweir Font* mpFont; 113cdf0e10cSrcweir Color* mpTextColor; 114cdf0e10cSrcweir Color* mpTextFillColor; 115cdf0e10cSrcweir Color* mpTextLineColor; 116cdf0e10cSrcweir Color* mpOverlineColor; 117cdf0e10cSrcweir Point* mpRefPoint; 118cdf0e10cSrcweir TextAlign meTextAlign; 119cdf0e10cSrcweir RasterOp meRasterOp; 120cdf0e10cSrcweir sal_uLong mnTextLayoutMode; 121cdf0e10cSrcweir LanguageType meTextLanguage; 122cdf0e10cSrcweir sal_uInt16 mnFlags; 123cdf0e10cSrcweir }; 124cdf0e10cSrcweir 125cdf0e10cSrcweir // ----------------------------------------------------------------------- 126cdf0e10cSrcweir 127cdf0e10cSrcweir static void ImplDeleteObjStack( ImplObjStack* pObjStack ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_LINECOLOR ) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir if ( pObjStack->mpLineColor ) 132cdf0e10cSrcweir delete pObjStack->mpLineColor; 133cdf0e10cSrcweir } 134cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_FILLCOLOR ) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir if ( pObjStack->mpFillColor ) 137cdf0e10cSrcweir delete pObjStack->mpFillColor; 138cdf0e10cSrcweir } 139cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_FONT ) 140cdf0e10cSrcweir delete pObjStack->mpFont; 141cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_TEXTCOLOR ) 142cdf0e10cSrcweir delete pObjStack->mpTextColor; 143cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR ) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir if ( pObjStack->mpTextFillColor ) 146cdf0e10cSrcweir delete pObjStack->mpTextFillColor; 147cdf0e10cSrcweir } 148cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir if ( pObjStack->mpTextLineColor ) 151cdf0e10cSrcweir delete pObjStack->mpTextLineColor; 152cdf0e10cSrcweir } 153cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR ) 154cdf0e10cSrcweir { 155cdf0e10cSrcweir if ( pObjStack->mpOverlineColor ) 156cdf0e10cSrcweir delete pObjStack->mpOverlineColor; 157cdf0e10cSrcweir } 158cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_MAPMODE ) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir if ( pObjStack->mpMapMode ) 161cdf0e10cSrcweir delete pObjStack->mpMapMode; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_CLIPREGION ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir if ( pObjStack->mpClipRegion ) 166cdf0e10cSrcweir delete pObjStack->mpClipRegion; 167cdf0e10cSrcweir } 168cdf0e10cSrcweir if ( pObjStack->mnFlags & PUSH_REFPOINT ) 169cdf0e10cSrcweir { 170cdf0e10cSrcweir if ( pObjStack->mpRefPoint ) 171cdf0e10cSrcweir delete pObjStack->mpRefPoint; 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir delete pObjStack; 175cdf0e10cSrcweir } 176cdf0e10cSrcweir 177cdf0e10cSrcweir // ----------------------------------------------------------------------- 178cdf0e10cSrcweir 179cdf0e10cSrcweir bool OutputDevice::ImplIsAntiparallel() const 180cdf0e10cSrcweir { 181cdf0e10cSrcweir bool bRet = false; 182cdf0e10cSrcweir if( ImplGetGraphics() ) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) || 185cdf0e10cSrcweir ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) ) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir bRet = true; 188cdf0e10cSrcweir } 189cdf0e10cSrcweir } 190cdf0e10cSrcweir return bRet; 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir // ----------------------------------------------------------------------- 194cdf0e10cSrcweir 195cdf0e10cSrcweir 196cdf0e10cSrcweir bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics ) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 199cdf0e10cSrcweir 200cdf0e10cSrcweir if( !pGraphics ) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir if( !mpGraphics ) 203cdf0e10cSrcweir if( !ImplGetGraphics() ) 204cdf0e10cSrcweir return false; 205cdf0e10cSrcweir pGraphics = mpGraphics; 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir bool bClipRegion = pGraphics->SetClipRegion( rRegion, this ); 209cdf0e10cSrcweir OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" ); 210cdf0e10cSrcweir return bClipRegion; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir 214cdf0e10cSrcweir // ======================================================================= 215cdf0e10cSrcweir 216cdf0e10cSrcweir Polygon ImplSubdivideBezier( const Polygon& rPoly ) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir Polygon aPoly; 219cdf0e10cSrcweir 220cdf0e10cSrcweir // #100127# Use adaptive subdivide instead of fixed 25 segments 221cdf0e10cSrcweir rPoly.AdaptiveSubdivide( aPoly ); 222cdf0e10cSrcweir 223cdf0e10cSrcweir return aPoly; 224cdf0e10cSrcweir } 225cdf0e10cSrcweir 226cdf0e10cSrcweir // ======================================================================= 227cdf0e10cSrcweir 228cdf0e10cSrcweir PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly ) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir sal_uInt16 i, nPolys = rPolyPoly.Count(); 231cdf0e10cSrcweir PolyPolygon aPolyPoly( nPolys ); 232cdf0e10cSrcweir for( i=0; i<nPolys; ++i ) 233cdf0e10cSrcweir aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) ); 234cdf0e10cSrcweir 235cdf0e10cSrcweir return aPolyPoly; 236cdf0e10cSrcweir } 237cdf0e10cSrcweir 238cdf0e10cSrcweir // ======================================================================= 239cdf0e10cSrcweir 240cdf0e10cSrcweir // #100127# Extracted from OutputDevice::DrawPolyPolygon() 241cdf0e10cSrcweir void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir // AW: This crashes on empty PolyPolygons, avoid that 244cdf0e10cSrcweir if(!nPoly) 245cdf0e10cSrcweir return; 246cdf0e10cSrcweir 247cdf0e10cSrcweir sal_uInt32 aStackAry1[OUTDEV_POLYPOLY_STACKBUF]; 248cdf0e10cSrcweir PCONSTSALPOINT aStackAry2[OUTDEV_POLYPOLY_STACKBUF]; 249cdf0e10cSrcweir sal_uInt8* aStackAry3[OUTDEV_POLYPOLY_STACKBUF]; 250cdf0e10cSrcweir sal_uInt32* pPointAry; 251cdf0e10cSrcweir PCONSTSALPOINT* pPointAryAry; 252cdf0e10cSrcweir const sal_uInt8** pFlagAryAry; 253cdf0e10cSrcweir sal_uInt16 i = 0, j = 0, last = 0; 254cdf0e10cSrcweir sal_Bool bHaveBezier = sal_False; 255cdf0e10cSrcweir if ( nPoly > OUTDEV_POLYPOLY_STACKBUF ) 256cdf0e10cSrcweir { 257cdf0e10cSrcweir pPointAry = new sal_uInt32[nPoly]; 258cdf0e10cSrcweir pPointAryAry = new PCONSTSALPOINT[nPoly]; 259cdf0e10cSrcweir pFlagAryAry = new const sal_uInt8*[nPoly]; 260cdf0e10cSrcweir } 261cdf0e10cSrcweir else 262cdf0e10cSrcweir { 263cdf0e10cSrcweir pPointAry = aStackAry1; 264cdf0e10cSrcweir pPointAryAry = aStackAry2; 265cdf0e10cSrcweir pFlagAryAry = (const sal_uInt8**)aStackAry3; 266cdf0e10cSrcweir } 267cdf0e10cSrcweir do 268cdf0e10cSrcweir { 269cdf0e10cSrcweir const Polygon& rPoly = rPolyPoly.GetObject( i ); 270cdf0e10cSrcweir sal_uInt16 nSize = rPoly.GetSize(); 271cdf0e10cSrcweir if ( nSize ) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir pPointAry[j] = nSize; 274cdf0e10cSrcweir pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry(); 275cdf0e10cSrcweir pFlagAryAry[j] = rPoly.GetConstFlagAry(); 276cdf0e10cSrcweir last = i; 277cdf0e10cSrcweir 278cdf0e10cSrcweir if( pFlagAryAry[j] ) 279cdf0e10cSrcweir bHaveBezier = sal_True; 280cdf0e10cSrcweir 281cdf0e10cSrcweir ++j; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir 284cdf0e10cSrcweir ++i; 285cdf0e10cSrcweir } 286cdf0e10cSrcweir while ( i < nPoly ); 287cdf0e10cSrcweir 288cdf0e10cSrcweir if ( j == 1 ) 289cdf0e10cSrcweir { 290cdf0e10cSrcweir // #100127# Forward beziers to sal, if any 291cdf0e10cSrcweir if( bHaveBezier ) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) ) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) ); 296cdf0e10cSrcweir mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this ); 297cdf0e10cSrcweir } 298cdf0e10cSrcweir } 299cdf0e10cSrcweir else 300cdf0e10cSrcweir { 301cdf0e10cSrcweir mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this ); 302cdf0e10cSrcweir } 303cdf0e10cSrcweir } 304cdf0e10cSrcweir else 305cdf0e10cSrcweir { 306cdf0e10cSrcweir // #100127# Forward beziers to sal, if any 307cdf0e10cSrcweir if( bHaveBezier ) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) ) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly ); 312cdf0e10cSrcweir ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly ); 313cdf0e10cSrcweir } 314cdf0e10cSrcweir } 315cdf0e10cSrcweir else 316cdf0e10cSrcweir { 317cdf0e10cSrcweir mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this ); 318cdf0e10cSrcweir } 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir if ( pPointAry != aStackAry1 ) 322cdf0e10cSrcweir { 323cdf0e10cSrcweir delete[] pPointAry; 324cdf0e10cSrcweir delete[] pPointAryAry; 325cdf0e10cSrcweir delete[] pFlagAryAry; 326cdf0e10cSrcweir } 327cdf0e10cSrcweir } 328cdf0e10cSrcweir 329cdf0e10cSrcweir // ======================================================================= 330cdf0e10cSrcweir 331cdf0e10cSrcweir OutputDevice::OutputDevice() : 332cdf0e10cSrcweir maRegion( REGION_NULL ), 333cdf0e10cSrcweir maFillColor( COL_WHITE ), 334cdf0e10cSrcweir maTextLineColor( COL_TRANSPARENT ), 335cdf0e10cSrcweir maSettings( Application::GetSettings() ) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir DBG_CTOR( OutputDevice, ImplDbgCheckOutputDevice ); 338cdf0e10cSrcweir 339cdf0e10cSrcweir mpGraphics = NULL; 340cdf0e10cSrcweir mpUnoGraphicsList = NULL; 341cdf0e10cSrcweir mpPrevGraphics = NULL; 342cdf0e10cSrcweir mpNextGraphics = NULL; 343cdf0e10cSrcweir mpMetaFile = NULL; 344cdf0e10cSrcweir mpFontEntry = NULL; 345cdf0e10cSrcweir mpFontCache = NULL; 346cdf0e10cSrcweir mpFontList = NULL; 347cdf0e10cSrcweir mpGetDevFontList = NULL; 348cdf0e10cSrcweir mpGetDevSizeList = NULL; 349cdf0e10cSrcweir mpObjStack = NULL; 350cdf0e10cSrcweir mpOutDevData = NULL; 351cdf0e10cSrcweir mpPDFWriter = NULL; 352cdf0e10cSrcweir mpAlphaVDev = NULL; 353cdf0e10cSrcweir mpExtOutDevData = NULL; 354cdf0e10cSrcweir mnOutOffX = 0; 355cdf0e10cSrcweir mnOutOffY = 0; 356cdf0e10cSrcweir mnOutWidth = 0; 357cdf0e10cSrcweir mnOutHeight = 0; 358cdf0e10cSrcweir mnDPIX = 0; 359cdf0e10cSrcweir mnDPIY = 0; 360cdf0e10cSrcweir mnTextOffX = 0; 361cdf0e10cSrcweir mnTextOffY = 0; 362cdf0e10cSrcweir mnOutOffOrigX = 0; 363cdf0e10cSrcweir mnOutOffLogicX = 0; 364cdf0e10cSrcweir mnOutOffOrigY = 0; 365cdf0e10cSrcweir mnOutOffLogicY = 0; 366cdf0e10cSrcweir mnEmphasisAscent = 0; 367cdf0e10cSrcweir mnEmphasisDescent = 0; 368cdf0e10cSrcweir mnDrawMode = 0; 369cdf0e10cSrcweir mnTextLayoutMode = TEXT_LAYOUT_DEFAULT; 370cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL 371cdf0e10cSrcweir mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT; 372cdf0e10cSrcweir meOutDevType = OUTDEV_DONTKNOW; 373cdf0e10cSrcweir meOutDevViewType = OUTDEV_VIEWTYPE_DONTKNOW; 374cdf0e10cSrcweir mbMap = sal_False; 375cdf0e10cSrcweir mbMapIsDefault = sal_True; 376cdf0e10cSrcweir mbClipRegion = sal_False; 377cdf0e10cSrcweir mbBackground = sal_False; 378cdf0e10cSrcweir mbOutput = sal_True; 379cdf0e10cSrcweir mbDevOutput = sal_False; 380cdf0e10cSrcweir mbOutputClipped = sal_False; 381cdf0e10cSrcweir maTextColor = Color( COL_BLACK ); 382cdf0e10cSrcweir maOverlineColor = Color( COL_TRANSPARENT ); 383cdf0e10cSrcweir meTextAlign = maFont.GetAlign(); 384cdf0e10cSrcweir meRasterOp = ROP_OVERPAINT; 385cdf0e10cSrcweir mnAntialiasing = 0; 386cdf0e10cSrcweir meTextLanguage = 0; // TODO: get default from configuration? 387cdf0e10cSrcweir mbLineColor = sal_True; 388cdf0e10cSrcweir mbFillColor = sal_True; 389cdf0e10cSrcweir mbInitLineColor = sal_True; 390cdf0e10cSrcweir mbInitFillColor = sal_True; 391cdf0e10cSrcweir mbInitFont = sal_True; 392cdf0e10cSrcweir mbInitTextColor = sal_True; 393cdf0e10cSrcweir mbInitClipRegion = sal_True; 394cdf0e10cSrcweir mbClipRegionSet = sal_False; 395cdf0e10cSrcweir mbKerning = sal_False; 396cdf0e10cSrcweir mbNewFont = sal_True; 397cdf0e10cSrcweir mbTextLines = sal_False; 398cdf0e10cSrcweir mbTextSpecial = sal_False; 399cdf0e10cSrcweir mbRefPoint = sal_False; 400cdf0e10cSrcweir mbEnableRTL = sal_False; // mirroring must be explicitly allowed (typically for windows only) 401cdf0e10cSrcweir 402cdf0e10cSrcweir // struct ImplMapRes 403cdf0e10cSrcweir maMapRes.mnMapOfsX = 0; 404cdf0e10cSrcweir maMapRes.mnMapOfsY = 0; 405cdf0e10cSrcweir maMapRes.mnMapScNumX = 1; 406cdf0e10cSrcweir maMapRes.mnMapScNumY = 1; 407cdf0e10cSrcweir maMapRes.mnMapScDenomX = 1; 408cdf0e10cSrcweir maMapRes.mnMapScDenomY = 1; 409cdf0e10cSrcweir // struct ImplThresholdRes 410cdf0e10cSrcweir maThresRes.mnThresLogToPixX = 0; 411cdf0e10cSrcweir maThresRes.mnThresLogToPixY = 0; 412cdf0e10cSrcweir maThresRes.mnThresPixToLogX = 0; 413cdf0e10cSrcweir maThresRes.mnThresPixToLogY = 0; 414cdf0e10cSrcweir } 415cdf0e10cSrcweir 416cdf0e10cSrcweir // ----------------------------------------------------------------------- 417cdf0e10cSrcweir 418cdf0e10cSrcweir OutputDevice::~OutputDevice() 419cdf0e10cSrcweir { 420cdf0e10cSrcweir DBG_DTOR( OutputDevice, ImplDbgCheckOutputDevice ); 421cdf0e10cSrcweir 422cdf0e10cSrcweir if ( GetUnoGraphicsList() ) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False ); 425cdf0e10cSrcweir if ( pWrapper ) 426cdf0e10cSrcweir pWrapper->ReleaseAllGraphics( this ); 427cdf0e10cSrcweir delete mpUnoGraphicsList; 428cdf0e10cSrcweir mpUnoGraphicsList = NULL; 429cdf0e10cSrcweir } 430cdf0e10cSrcweir 431cdf0e10cSrcweir if ( mpOutDevData ) 432cdf0e10cSrcweir ImplDeInitOutDevData(); 433cdf0e10cSrcweir 434cdf0e10cSrcweir ImplObjStack* pData = mpObjStack; 435cdf0e10cSrcweir if ( pData ) 436cdf0e10cSrcweir { 437cdf0e10cSrcweir DBG_ERRORFILE( "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" ); 438cdf0e10cSrcweir while ( pData ) 439cdf0e10cSrcweir { 440cdf0e10cSrcweir ImplObjStack* pTemp = pData; 441cdf0e10cSrcweir pData = pData->mpPrev; 442cdf0e10cSrcweir ImplDeleteObjStack( pTemp ); 443cdf0e10cSrcweir } 444cdf0e10cSrcweir } 445cdf0e10cSrcweir 446cdf0e10cSrcweir // release the active font instance 447cdf0e10cSrcweir if( mpFontEntry ) 448cdf0e10cSrcweir mpFontCache->Release( mpFontEntry ); 449cdf0e10cSrcweir // remove cached results of GetDevFontList/GetDevSizeList 450cdf0e10cSrcweir // TODO: use smart pointers for them 451cdf0e10cSrcweir if( mpGetDevFontList ) 452cdf0e10cSrcweir delete mpGetDevFontList; 453cdf0e10cSrcweir if( mpGetDevSizeList ) 454cdf0e10cSrcweir delete mpGetDevSizeList; 455cdf0e10cSrcweir 456cdf0e10cSrcweir // release ImplFontCache specific to this OutputDevice 457cdf0e10cSrcweir // TODO: refcount ImplFontCache 458cdf0e10cSrcweir if( mpFontCache 459cdf0e10cSrcweir && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache) 460cdf0e10cSrcweir && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) ) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir delete mpFontCache; 463cdf0e10cSrcweir mpFontCache = NULL; 464cdf0e10cSrcweir } 465cdf0e10cSrcweir 466cdf0e10cSrcweir // release ImplFontList specific to this OutputDevice 467cdf0e10cSrcweir // TODO: refcount ImplFontList 468cdf0e10cSrcweir if( mpFontList 469cdf0e10cSrcweir && (mpFontList != ImplGetSVData()->maGDIData.mpScreenFontList) 470cdf0e10cSrcweir && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) ) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir mpFontList->Clear(); 473cdf0e10cSrcweir delete mpFontList; 474cdf0e10cSrcweir mpFontList = NULL; 475cdf0e10cSrcweir } 476cdf0e10cSrcweir 477cdf0e10cSrcweir delete mpAlphaVDev; 478cdf0e10cSrcweir } 479cdf0e10cSrcweir 480cdf0e10cSrcweir bool OutputDevice::supportsOperation( OutDevSupportType eType ) const 481cdf0e10cSrcweir { 482cdf0e10cSrcweir if( !mpGraphics ) 483cdf0e10cSrcweir if( !ImplGetGraphics() ) 484cdf0e10cSrcweir return false; 485cdf0e10cSrcweir const bool bHasSupport = mpGraphics->supportsOperation( eType ); 486cdf0e10cSrcweir return bHasSupport; 487cdf0e10cSrcweir } 488cdf0e10cSrcweir 489cdf0e10cSrcweir // ----------------------------------------------------------------------- 490cdf0e10cSrcweir 491cdf0e10cSrcweir void OutputDevice::EnableRTL( sal_Bool bEnable ) 492cdf0e10cSrcweir { 493cdf0e10cSrcweir mbEnableRTL = (bEnable != 0); 494cdf0e10cSrcweir if( meOutDevType == OUTDEV_VIRDEV ) 495cdf0e10cSrcweir { 496cdf0e10cSrcweir // virdevs default to not mirroring, they will only be set to mirroring 497cdf0e10cSrcweir // under rare circumstances in the UI, eg the valueset control 498cdf0e10cSrcweir // because each virdev has its own SalGraphics we can safely switch the SalGraphics here 499cdf0e10cSrcweir // ...hopefully 500cdf0e10cSrcweir if( ImplGetGraphics() ) 501cdf0e10cSrcweir mpGraphics->SetLayout( mbEnableRTL ? SAL_LAYOUT_BIDI_RTL : 0 ); 502cdf0e10cSrcweir } 503cdf0e10cSrcweir 504cdf0e10cSrcweir // convenience: for controls also switch layout mode 505cdf0e10cSrcweir if( dynamic_cast<Control*>(this) != 0 ) 506cdf0e10cSrcweir SetLayoutMode( bEnable ? TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT : TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_TEXTORIGIN_LEFT); 507cdf0e10cSrcweir 508cdf0e10cSrcweir Window* pWin = dynamic_cast<Window*>(this); 509cdf0e10cSrcweir if( pWin ) 510cdf0e10cSrcweir pWin->StateChanged( STATE_CHANGE_MIRRORING ); 511cdf0e10cSrcweir 512cdf0e10cSrcweir if( mpAlphaVDev ) 513cdf0e10cSrcweir mpAlphaVDev->EnableRTL( bEnable ); 514cdf0e10cSrcweir } 515cdf0e10cSrcweir 516cdf0e10cSrcweir sal_Bool OutputDevice::ImplHasMirroredGraphics() 517cdf0e10cSrcweir { 518cdf0e10cSrcweir // HOTFIX for #i55719# 519cdf0e10cSrcweir if( meOutDevType == OUTDEV_PRINTER ) 520cdf0e10cSrcweir return sal_False; 521cdf0e10cSrcweir 522cdf0e10cSrcweir return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) ); 523cdf0e10cSrcweir } 524cdf0e10cSrcweir 525cdf0e10cSrcweir // note: the coordiantes to be remirrored are in frame coordiantes ! 526cdf0e10cSrcweir 527cdf0e10cSrcweir void OutputDevice::ImplReMirror( Point &rPoint ) const 528cdf0e10cSrcweir { 529cdf0e10cSrcweir rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX; 530cdf0e10cSrcweir } 531cdf0e10cSrcweir void OutputDevice::ImplReMirror( Rectangle &rRect ) const 532cdf0e10cSrcweir { 533cdf0e10cSrcweir long nWidth = rRect.nRight - rRect.nLeft; 534cdf0e10cSrcweir 535cdf0e10cSrcweir //long lc_x = rRect.nLeft - mnOutOffX; // normalize 536cdf0e10cSrcweir //lc_x = mnOutWidth - nWidth - 1 - lc_x; // mirror 537cdf0e10cSrcweir //rRect.nLeft = lc_x + mnOutOffX; // re-normalize 538cdf0e10cSrcweir 539cdf0e10cSrcweir rRect.nLeft = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.nLeft + mnOutOffX; 540cdf0e10cSrcweir rRect.nRight = rRect.nLeft + nWidth; 541cdf0e10cSrcweir } 542cdf0e10cSrcweir void OutputDevice::ImplReMirror( Region &rRegion ) const 543cdf0e10cSrcweir { 544cdf0e10cSrcweir long nX; 545cdf0e10cSrcweir long nY; 546cdf0e10cSrcweir long nWidth; 547cdf0e10cSrcweir long nHeight; 548cdf0e10cSrcweir ImplRegionInfo aInfo; 549cdf0e10cSrcweir sal_Bool bRegionRect; 550cdf0e10cSrcweir Region aMirroredRegion; 551cdf0e10cSrcweir 552cdf0e10cSrcweir bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight ); 553cdf0e10cSrcweir while ( bRegionRect ) 554cdf0e10cSrcweir { 555cdf0e10cSrcweir Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) ); 556cdf0e10cSrcweir ImplReMirror( aRect ); 557cdf0e10cSrcweir aMirroredRegion.Union( aRect ); 558cdf0e10cSrcweir bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight ); 559cdf0e10cSrcweir } 560cdf0e10cSrcweir rRegion = aMirroredRegion; 561cdf0e10cSrcweir } 562cdf0e10cSrcweir 563cdf0e10cSrcweir 564cdf0e10cSrcweir // ----------------------------------------------------------------------- 565cdf0e10cSrcweir 566cdf0e10cSrcweir int OutputDevice::ImplGetGraphics() const 567cdf0e10cSrcweir { 568cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 569cdf0e10cSrcweir 570cdf0e10cSrcweir if ( mpGraphics ) 571cdf0e10cSrcweir return sal_True; 572cdf0e10cSrcweir 573cdf0e10cSrcweir mbInitLineColor = sal_True; 574cdf0e10cSrcweir mbInitFillColor = sal_True; 575cdf0e10cSrcweir mbInitFont = sal_True; 576cdf0e10cSrcweir mbInitTextColor = sal_True; 577cdf0e10cSrcweir mbInitClipRegion = sal_True; 578cdf0e10cSrcweir 579cdf0e10cSrcweir ImplSVData* pSVData = ImplGetSVData(); 580cdf0e10cSrcweir if ( meOutDevType == OUTDEV_WINDOW ) 581cdf0e10cSrcweir { 582cdf0e10cSrcweir Window* pWindow = (Window*)this; 583cdf0e10cSrcweir 584cdf0e10cSrcweir mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics(); 585cdf0e10cSrcweir // try harder if no wingraphics was available directly 586cdf0e10cSrcweir if ( !mpGraphics ) 587cdf0e10cSrcweir { 588cdf0e10cSrcweir // find another output device in the same frame 589cdf0e10cSrcweir OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics; 590cdf0e10cSrcweir while ( pReleaseOutDev ) 591cdf0e10cSrcweir { 592cdf0e10cSrcweir if ( ((Window*)pReleaseOutDev)->mpWindowImpl->mpFrame == pWindow->mpWindowImpl->mpFrame ) 593cdf0e10cSrcweir break; 594cdf0e10cSrcweir pReleaseOutDev = pReleaseOutDev->mpPrevGraphics; 595cdf0e10cSrcweir } 596cdf0e10cSrcweir 597cdf0e10cSrcweir if ( pReleaseOutDev ) 598cdf0e10cSrcweir { 599cdf0e10cSrcweir // steal the wingraphics from the other outdev 600cdf0e10cSrcweir mpGraphics = pReleaseOutDev->mpGraphics; 601cdf0e10cSrcweir pReleaseOutDev->ImplReleaseGraphics( sal_False ); 602cdf0e10cSrcweir } 603cdf0e10cSrcweir else 604cdf0e10cSrcweir { 605cdf0e10cSrcweir // if needed retry after releasing least recently used wingraphics 606cdf0e10cSrcweir while ( !mpGraphics ) 607cdf0e10cSrcweir { 608cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastWinGraphics ) 609cdf0e10cSrcweir break; 610cdf0e10cSrcweir pSVData->maGDIData.mpLastWinGraphics->ImplReleaseGraphics(); 611cdf0e10cSrcweir mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics(); 612cdf0e10cSrcweir } 613cdf0e10cSrcweir } 614cdf0e10cSrcweir } 615cdf0e10cSrcweir 616cdf0e10cSrcweir // update global LRU list of wingraphics 617cdf0e10cSrcweir if ( mpGraphics ) 618cdf0e10cSrcweir { 619cdf0e10cSrcweir mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics; 620cdf0e10cSrcweir pSVData->maGDIData.mpFirstWinGraphics = const_cast<OutputDevice*>(this); 621cdf0e10cSrcweir if ( mpNextGraphics ) 622cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this); 623cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastWinGraphics ) 624cdf0e10cSrcweir pSVData->maGDIData.mpLastWinGraphics = const_cast<OutputDevice*>(this); 625cdf0e10cSrcweir } 626cdf0e10cSrcweir } 627cdf0e10cSrcweir else if ( meOutDevType == OUTDEV_VIRDEV ) 628cdf0e10cSrcweir { 629cdf0e10cSrcweir const VirtualDevice* pVirDev = (const VirtualDevice*)this; 630cdf0e10cSrcweir 631cdf0e10cSrcweir if ( pVirDev->mpVirDev ) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir mpGraphics = pVirDev->mpVirDev->GetGraphics(); 634cdf0e10cSrcweir // if needed retry after releasing least recently used virtual device graphics 635cdf0e10cSrcweir while ( !mpGraphics ) 636cdf0e10cSrcweir { 637cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastVirGraphics ) 638cdf0e10cSrcweir break; 639cdf0e10cSrcweir pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics(); 640cdf0e10cSrcweir mpGraphics = pVirDev->mpVirDev->GetGraphics(); 641cdf0e10cSrcweir } 642cdf0e10cSrcweir // update global LRU list of virtual device graphics 643cdf0e10cSrcweir if ( mpGraphics ) 644cdf0e10cSrcweir { 645cdf0e10cSrcweir mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics; 646cdf0e10cSrcweir pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this); 647cdf0e10cSrcweir if ( mpNextGraphics ) 648cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this); 649cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastVirGraphics ) 650cdf0e10cSrcweir pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir } 653cdf0e10cSrcweir } 654cdf0e10cSrcweir else if ( meOutDevType == OUTDEV_PRINTER ) 655cdf0e10cSrcweir { 656cdf0e10cSrcweir const Printer* pPrinter = (const Printer*)this; 657cdf0e10cSrcweir 658cdf0e10cSrcweir if ( pPrinter->mpJobGraphics ) 659cdf0e10cSrcweir mpGraphics = pPrinter->mpJobGraphics; 660cdf0e10cSrcweir else if ( pPrinter->mpDisplayDev ) 661cdf0e10cSrcweir { 662cdf0e10cSrcweir const VirtualDevice* pVirDev = pPrinter->mpDisplayDev; 663cdf0e10cSrcweir mpGraphics = pVirDev->mpVirDev->GetGraphics(); 664cdf0e10cSrcweir // if needed retry after releasing least recently used virtual device graphics 665cdf0e10cSrcweir while ( !mpGraphics ) 666cdf0e10cSrcweir { 667cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastVirGraphics ) 668cdf0e10cSrcweir break; 669cdf0e10cSrcweir pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics(); 670cdf0e10cSrcweir mpGraphics = pVirDev->mpVirDev->GetGraphics(); 671cdf0e10cSrcweir } 672cdf0e10cSrcweir // update global LRU list of virtual device graphics 673cdf0e10cSrcweir if ( mpGraphics ) 674cdf0e10cSrcweir { 675cdf0e10cSrcweir mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics; 676cdf0e10cSrcweir pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this); 677cdf0e10cSrcweir if ( mpNextGraphics ) 678cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this); 679cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastVirGraphics ) 680cdf0e10cSrcweir pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this); 681cdf0e10cSrcweir } 682cdf0e10cSrcweir } 683cdf0e10cSrcweir else 684cdf0e10cSrcweir { 685cdf0e10cSrcweir mpGraphics = pPrinter->mpInfoPrinter->GetGraphics(); 686cdf0e10cSrcweir // if needed retry after releasing least recently used printer graphics 687cdf0e10cSrcweir while ( !mpGraphics ) 688cdf0e10cSrcweir { 689cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastPrnGraphics ) 690cdf0e10cSrcweir break; 691cdf0e10cSrcweir pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics(); 692cdf0e10cSrcweir mpGraphics = pPrinter->mpInfoPrinter->GetGraphics(); 693cdf0e10cSrcweir } 694cdf0e10cSrcweir // update global LRU list of printer graphics 695cdf0e10cSrcweir if ( mpGraphics ) 696cdf0e10cSrcweir { 697cdf0e10cSrcweir mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics; 698cdf0e10cSrcweir pSVData->maGDIData.mpFirstPrnGraphics = const_cast<OutputDevice*>(this); 699cdf0e10cSrcweir if ( mpNextGraphics ) 700cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this); 701cdf0e10cSrcweir if ( !pSVData->maGDIData.mpLastPrnGraphics ) 702cdf0e10cSrcweir pSVData->maGDIData.mpLastPrnGraphics = const_cast<OutputDevice*>(this); 703cdf0e10cSrcweir } 704cdf0e10cSrcweir } 705cdf0e10cSrcweir } 706cdf0e10cSrcweir 707cdf0e10cSrcweir if ( mpGraphics ) 708cdf0e10cSrcweir { 709cdf0e10cSrcweir mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp ); 710cdf0e10cSrcweir mpGraphics->setAntiAliasB2DDraw(mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW); 711cdf0e10cSrcweir return sal_True; 712cdf0e10cSrcweir } 713cdf0e10cSrcweir 714cdf0e10cSrcweir return sal_False; 715cdf0e10cSrcweir } 716cdf0e10cSrcweir 717cdf0e10cSrcweir // ----------------------------------------------------------------------- 718cdf0e10cSrcweir 719cdf0e10cSrcweir void OutputDevice::ImplReleaseGraphics( sal_Bool bRelease ) 720cdf0e10cSrcweir { 721cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 722cdf0e10cSrcweir 723cdf0e10cSrcweir if ( !mpGraphics ) 724cdf0e10cSrcweir return; 725cdf0e10cSrcweir 726cdf0e10cSrcweir // release the fonts of the physically released graphics device 727cdf0e10cSrcweir if( bRelease ) 728cdf0e10cSrcweir { 729cdf0e10cSrcweir #ifndef UNX 730cdf0e10cSrcweir // HACK to fix an urgent P1 printing issue fast 731cdf0e10cSrcweir // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions 732cdf0e10cSrcweir // so Printer::mpGraphics often points to a dead WinSalGraphics 733cdf0e10cSrcweir // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling 734cdf0e10cSrcweir if( meOutDevType != OUTDEV_PRINTER ) 735cdf0e10cSrcweir #endif 736cdf0e10cSrcweir mpGraphics->ReleaseFonts(); 737cdf0e10cSrcweir 738cdf0e10cSrcweir mbNewFont = true; 739cdf0e10cSrcweir mbInitFont = true; 740cdf0e10cSrcweir 741cdf0e10cSrcweir if ( mpFontEntry ) 742cdf0e10cSrcweir { 743cdf0e10cSrcweir mpFontCache->Release( mpFontEntry ); 744cdf0e10cSrcweir mpFontEntry = NULL; 745cdf0e10cSrcweir } 746cdf0e10cSrcweir 747cdf0e10cSrcweir if ( mpGetDevFontList ) 748cdf0e10cSrcweir { 749cdf0e10cSrcweir delete mpGetDevFontList; 750cdf0e10cSrcweir mpGetDevFontList = NULL; 751cdf0e10cSrcweir } 752cdf0e10cSrcweir 753cdf0e10cSrcweir if ( mpGetDevSizeList ) 754cdf0e10cSrcweir { 755cdf0e10cSrcweir delete mpGetDevSizeList; 756cdf0e10cSrcweir mpGetDevSizeList = NULL; 757cdf0e10cSrcweir } 758cdf0e10cSrcweir } 759cdf0e10cSrcweir 760cdf0e10cSrcweir ImplSVData* pSVData = ImplGetSVData(); 761cdf0e10cSrcweir if ( meOutDevType == OUTDEV_WINDOW ) 762cdf0e10cSrcweir { 763cdf0e10cSrcweir Window* pWindow = (Window*)this; 764cdf0e10cSrcweir 765cdf0e10cSrcweir if ( bRelease ) 766cdf0e10cSrcweir pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics ); 767cdf0e10cSrcweir // remove from global LRU list of window graphics 768cdf0e10cSrcweir if ( mpPrevGraphics ) 769cdf0e10cSrcweir mpPrevGraphics->mpNextGraphics = mpNextGraphics; 770cdf0e10cSrcweir else 771cdf0e10cSrcweir pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics; 772cdf0e10cSrcweir if ( mpNextGraphics ) 773cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = mpPrevGraphics; 774cdf0e10cSrcweir else 775cdf0e10cSrcweir pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics; 776cdf0e10cSrcweir } 777cdf0e10cSrcweir else if ( meOutDevType == OUTDEV_VIRDEV ) 778cdf0e10cSrcweir { 779cdf0e10cSrcweir VirtualDevice* pVirDev = (VirtualDevice*)this; 780cdf0e10cSrcweir 781cdf0e10cSrcweir if ( bRelease ) 782cdf0e10cSrcweir pVirDev->mpVirDev->ReleaseGraphics( mpGraphics ); 783cdf0e10cSrcweir // remove from global LRU list of virtual device graphics 784cdf0e10cSrcweir if ( mpPrevGraphics ) 785cdf0e10cSrcweir mpPrevGraphics->mpNextGraphics = mpNextGraphics; 786cdf0e10cSrcweir else 787cdf0e10cSrcweir pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics; 788cdf0e10cSrcweir if ( mpNextGraphics ) 789cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = mpPrevGraphics; 790cdf0e10cSrcweir else 791cdf0e10cSrcweir pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics; 792cdf0e10cSrcweir } 793cdf0e10cSrcweir else if ( meOutDevType == OUTDEV_PRINTER ) 794cdf0e10cSrcweir { 795cdf0e10cSrcweir Printer* pPrinter = (Printer*)this; 796cdf0e10cSrcweir 797cdf0e10cSrcweir if ( !pPrinter->mpJobGraphics ) 798cdf0e10cSrcweir { 799cdf0e10cSrcweir if ( pPrinter->mpDisplayDev ) 800cdf0e10cSrcweir { 801cdf0e10cSrcweir VirtualDevice* pVirDev = pPrinter->mpDisplayDev; 802cdf0e10cSrcweir if ( bRelease ) 803cdf0e10cSrcweir pVirDev->mpVirDev->ReleaseGraphics( mpGraphics ); 804cdf0e10cSrcweir // remove from global LRU list of virtual device graphics 805cdf0e10cSrcweir if ( mpPrevGraphics ) 806cdf0e10cSrcweir mpPrevGraphics->mpNextGraphics = mpNextGraphics; 807cdf0e10cSrcweir else 808cdf0e10cSrcweir pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics; 809cdf0e10cSrcweir if ( mpNextGraphics ) 810cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = mpPrevGraphics; 811cdf0e10cSrcweir else 812cdf0e10cSrcweir pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics; 813cdf0e10cSrcweir } 814cdf0e10cSrcweir else 815cdf0e10cSrcweir { 816cdf0e10cSrcweir if ( bRelease ) 817cdf0e10cSrcweir pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics ); 818cdf0e10cSrcweir // remove from global LRU list of printer graphics 819cdf0e10cSrcweir if ( mpPrevGraphics ) 820cdf0e10cSrcweir mpPrevGraphics->mpNextGraphics = mpNextGraphics; 821cdf0e10cSrcweir else 822cdf0e10cSrcweir pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics; 823cdf0e10cSrcweir if ( mpNextGraphics ) 824cdf0e10cSrcweir mpNextGraphics->mpPrevGraphics = mpPrevGraphics; 825cdf0e10cSrcweir else 826cdf0e10cSrcweir pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics; 827cdf0e10cSrcweir } 828cdf0e10cSrcweir } 829cdf0e10cSrcweir } 830cdf0e10cSrcweir 831cdf0e10cSrcweir mpGraphics = NULL; 832cdf0e10cSrcweir mpPrevGraphics = NULL; 833cdf0e10cSrcweir mpNextGraphics = NULL; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir 836cdf0e10cSrcweir // ----------------------------------------------------------------------- 837cdf0e10cSrcweir 838cdf0e10cSrcweir void OutputDevice::ImplInitOutDevData() 839cdf0e10cSrcweir { 840cdf0e10cSrcweir if ( !mpOutDevData ) 841cdf0e10cSrcweir { 842cdf0e10cSrcweir mpOutDevData = new ImplOutDevData; 843cdf0e10cSrcweir mpOutDevData->mpRotateDev = NULL; 844cdf0e10cSrcweir mpOutDevData->mpRecordLayout = NULL; 845cdf0e10cSrcweir 846cdf0e10cSrcweir // #i75163# 847cdf0e10cSrcweir mpOutDevData->mpViewTransform = NULL; 848cdf0e10cSrcweir mpOutDevData->mpInverseViewTransform = NULL; 849cdf0e10cSrcweir } 850cdf0e10cSrcweir } 851cdf0e10cSrcweir 852cdf0e10cSrcweir // ----------------------------------------------------------------------- 853cdf0e10cSrcweir 854cdf0e10cSrcweir // #i75163# 855cdf0e10cSrcweir void OutputDevice::ImplInvalidateViewTransform() 856cdf0e10cSrcweir { 857cdf0e10cSrcweir if(mpOutDevData) 858cdf0e10cSrcweir { 859cdf0e10cSrcweir if(mpOutDevData->mpViewTransform) 860cdf0e10cSrcweir { 861cdf0e10cSrcweir delete mpOutDevData->mpViewTransform; 862cdf0e10cSrcweir mpOutDevData->mpViewTransform = NULL; 863cdf0e10cSrcweir } 864cdf0e10cSrcweir 865cdf0e10cSrcweir if(mpOutDevData->mpInverseViewTransform) 866cdf0e10cSrcweir { 867cdf0e10cSrcweir delete mpOutDevData->mpInverseViewTransform; 868cdf0e10cSrcweir mpOutDevData->mpInverseViewTransform = NULL; 869cdf0e10cSrcweir } 870cdf0e10cSrcweir } 871cdf0e10cSrcweir } 872cdf0e10cSrcweir 873cdf0e10cSrcweir // ----------------------------------------------------------------------- 874cdf0e10cSrcweir 875cdf0e10cSrcweir sal_Bool OutputDevice::ImplIsRecordLayout() const 876cdf0e10cSrcweir { 877cdf0e10cSrcweir return mpOutDevData && mpOutDevData->mpRecordLayout; 878cdf0e10cSrcweir } 879cdf0e10cSrcweir 880cdf0e10cSrcweir // ----------------------------------------------------------------------- 881cdf0e10cSrcweir 882cdf0e10cSrcweir void OutputDevice::ImplDeInitOutDevData() 883cdf0e10cSrcweir { 884cdf0e10cSrcweir if ( mpOutDevData ) 885cdf0e10cSrcweir { 886cdf0e10cSrcweir if ( mpOutDevData->mpRotateDev ) 887cdf0e10cSrcweir delete mpOutDevData->mpRotateDev; 888cdf0e10cSrcweir 889cdf0e10cSrcweir // #i75163# 890cdf0e10cSrcweir ImplInvalidateViewTransform(); 891cdf0e10cSrcweir 892cdf0e10cSrcweir delete mpOutDevData; 893cdf0e10cSrcweir } 894cdf0e10cSrcweir } 895cdf0e10cSrcweir 896cdf0e10cSrcweir // ----------------------------------------------------------------------- 897cdf0e10cSrcweir 898cdf0e10cSrcweir void OutputDevice::ImplInitLineColor() 899cdf0e10cSrcweir { 900cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 901cdf0e10cSrcweir 902cdf0e10cSrcweir if( mbLineColor ) 903cdf0e10cSrcweir { 904cdf0e10cSrcweir if( ROP_0 == meRasterOp ) 905cdf0e10cSrcweir mpGraphics->SetROPLineColor( SAL_ROP_0 ); 906cdf0e10cSrcweir else if( ROP_1 == meRasterOp ) 907cdf0e10cSrcweir mpGraphics->SetROPLineColor( SAL_ROP_1 ); 908cdf0e10cSrcweir else if( ROP_INVERT == meRasterOp ) 909cdf0e10cSrcweir mpGraphics->SetROPLineColor( SAL_ROP_INVERT ); 910cdf0e10cSrcweir else 911cdf0e10cSrcweir mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) ); 912cdf0e10cSrcweir } 913cdf0e10cSrcweir else 914cdf0e10cSrcweir mpGraphics->SetLineColor(); 915cdf0e10cSrcweir 916cdf0e10cSrcweir mbInitLineColor = sal_False; 917cdf0e10cSrcweir } 918cdf0e10cSrcweir 919cdf0e10cSrcweir // ----------------------------------------------------------------------- 920cdf0e10cSrcweir 921cdf0e10cSrcweir void OutputDevice::ImplInitFillColor() 922cdf0e10cSrcweir { 923cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 924cdf0e10cSrcweir 925cdf0e10cSrcweir if( mbFillColor ) 926cdf0e10cSrcweir { 927cdf0e10cSrcweir if( ROP_0 == meRasterOp ) 928cdf0e10cSrcweir mpGraphics->SetROPFillColor( SAL_ROP_0 ); 929cdf0e10cSrcweir else if( ROP_1 == meRasterOp ) 930cdf0e10cSrcweir mpGraphics->SetROPFillColor( SAL_ROP_1 ); 931cdf0e10cSrcweir else if( ROP_INVERT == meRasterOp ) 932cdf0e10cSrcweir mpGraphics->SetROPFillColor( SAL_ROP_INVERT ); 933cdf0e10cSrcweir else 934cdf0e10cSrcweir mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) ); 935cdf0e10cSrcweir } 936cdf0e10cSrcweir else 937cdf0e10cSrcweir mpGraphics->SetFillColor(); 938cdf0e10cSrcweir 939cdf0e10cSrcweir mbInitFillColor = sal_False; 940cdf0e10cSrcweir } 941cdf0e10cSrcweir 942cdf0e10cSrcweir // ----------------------------------------------------------------------- 943cdf0e10cSrcweir 944cdf0e10cSrcweir void OutputDevice::ImplInitClipRegion() 945cdf0e10cSrcweir { 946cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 947cdf0e10cSrcweir 948cdf0e10cSrcweir if ( GetOutDevType() == OUTDEV_WINDOW ) 949cdf0e10cSrcweir { 950cdf0e10cSrcweir Window* pWindow = (Window*)this; 951cdf0e10cSrcweir Region aRegion; 952cdf0e10cSrcweir 953cdf0e10cSrcweir // Hintergrund-Sicherung zuruecksetzen 954cdf0e10cSrcweir if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin ) 955cdf0e10cSrcweir pWindow->ImplInvalidateAllOverlapBackgrounds(); 956cdf0e10cSrcweir if ( pWindow->mpWindowImpl->mbInPaint ) 957cdf0e10cSrcweir aRegion = *(pWindow->mpWindowImpl->mpPaintRegion); 958cdf0e10cSrcweir else 959cdf0e10cSrcweir { 960cdf0e10cSrcweir aRegion = *(pWindow->ImplGetWinChildClipRegion()); 961cdf0e10cSrcweir // --- RTL -- only this region is in frame coordinates, so re-mirror it 962cdf0e10cSrcweir // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) ! 963cdf0e10cSrcweir if( ImplIsAntiparallel() ) 964cdf0e10cSrcweir ImplReMirror ( aRegion ); 965cdf0e10cSrcweir } 966cdf0e10cSrcweir if ( mbClipRegion ) 967cdf0e10cSrcweir aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) ); 968cdf0e10cSrcweir if ( aRegion.IsEmpty() ) 969cdf0e10cSrcweir mbOutputClipped = sal_True; 970cdf0e10cSrcweir else 971cdf0e10cSrcweir { 972cdf0e10cSrcweir mbOutputClipped = sal_False; 973cdf0e10cSrcweir ImplSelectClipRegion( aRegion ); 974cdf0e10cSrcweir } 975cdf0e10cSrcweir mbClipRegionSet = sal_True; 976cdf0e10cSrcweir } 977cdf0e10cSrcweir else 978cdf0e10cSrcweir { 979cdf0e10cSrcweir if ( mbClipRegion ) 980cdf0e10cSrcweir { 981cdf0e10cSrcweir if ( maRegion.IsEmpty() ) 982cdf0e10cSrcweir mbOutputClipped = sal_True; 983cdf0e10cSrcweir else 984cdf0e10cSrcweir { 985cdf0e10cSrcweir mbOutputClipped = sal_False; 986cdf0e10cSrcweir 987cdf0e10cSrcweir // #102532# Respect output offset also for clip region 988cdf0e10cSrcweir Region aRegion( ImplPixelToDevicePixel( maRegion ) ); 989cdf0e10cSrcweir const bool bClipDeviceBounds( ! GetPDFWriter() 990cdf0e10cSrcweir && GetOutDevType() != OUTDEV_PRINTER ); 991cdf0e10cSrcweir if( bClipDeviceBounds ) 992cdf0e10cSrcweir { 993cdf0e10cSrcweir // #b6520266# Perform actual rect clip against outdev 994cdf0e10cSrcweir // dimensions, to generate empty clips whenever one of the 995cdf0e10cSrcweir // values is completely off the device. 996cdf0e10cSrcweir Rectangle aDeviceBounds( mnOutOffX, mnOutOffY, 997cdf0e10cSrcweir mnOutOffX+GetOutputWidthPixel()-1, 998cdf0e10cSrcweir mnOutOffY+GetOutputHeightPixel()-1 ); 999cdf0e10cSrcweir aRegion.Intersect( aDeviceBounds ); 1000cdf0e10cSrcweir } 1001cdf0e10cSrcweir ImplSelectClipRegion( aRegion ); 1002cdf0e10cSrcweir } 1003cdf0e10cSrcweir 1004cdf0e10cSrcweir mbClipRegionSet = sal_True; 1005cdf0e10cSrcweir } 1006cdf0e10cSrcweir else 1007cdf0e10cSrcweir { 1008cdf0e10cSrcweir if ( mbClipRegionSet ) 1009cdf0e10cSrcweir { 1010cdf0e10cSrcweir mpGraphics->ResetClipRegion(); 1011cdf0e10cSrcweir mbClipRegionSet = sal_False; 1012cdf0e10cSrcweir } 1013cdf0e10cSrcweir 1014cdf0e10cSrcweir mbOutputClipped = sal_False; 1015cdf0e10cSrcweir } 1016cdf0e10cSrcweir } 1017cdf0e10cSrcweir 1018cdf0e10cSrcweir mbInitClipRegion = sal_False; 1019cdf0e10cSrcweir } 1020cdf0e10cSrcweir 1021cdf0e10cSrcweir // ----------------------------------------------------------------------- 1022cdf0e10cSrcweir 1023cdf0e10cSrcweir void OutputDevice::ImplSetClipRegion( const Region* pRegion ) 1024cdf0e10cSrcweir { 1025cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 1026cdf0e10cSrcweir 1027cdf0e10cSrcweir if ( !pRegion ) 1028cdf0e10cSrcweir { 1029cdf0e10cSrcweir if ( mbClipRegion ) 1030cdf0e10cSrcweir { 1031cdf0e10cSrcweir maRegion = Region( REGION_NULL ); 1032cdf0e10cSrcweir mbClipRegion = sal_False; 1033cdf0e10cSrcweir mbInitClipRegion = sal_True; 1034cdf0e10cSrcweir } 1035cdf0e10cSrcweir } 1036cdf0e10cSrcweir else 1037cdf0e10cSrcweir { 1038cdf0e10cSrcweir maRegion = *pRegion; 1039cdf0e10cSrcweir mbClipRegion = sal_True; 1040cdf0e10cSrcweir mbInitClipRegion = sal_True; 1041cdf0e10cSrcweir } 1042cdf0e10cSrcweir } 1043cdf0e10cSrcweir 1044cdf0e10cSrcweir // ----------------------------------------------------------------------- 1045cdf0e10cSrcweir 1046cdf0e10cSrcweir void OutputDevice::SetClipRegion() 1047cdf0e10cSrcweir { 1048cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetClipRegion()" ); 1049cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1050cdf0e10cSrcweir 1051cdf0e10cSrcweir if ( mpMetaFile ) 1052cdf0e10cSrcweir mpMetaFile->AddAction( new MetaClipRegionAction( Region(), sal_False ) ); 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir ImplSetClipRegion( NULL ); 1055cdf0e10cSrcweir 1056cdf0e10cSrcweir if( mpAlphaVDev ) 1057cdf0e10cSrcweir mpAlphaVDev->SetClipRegion(); 1058cdf0e10cSrcweir } 1059cdf0e10cSrcweir 1060cdf0e10cSrcweir // ----------------------------------------------------------------------- 1061cdf0e10cSrcweir 1062cdf0e10cSrcweir void OutputDevice::SetClipRegion( const Region& rRegion ) 1063cdf0e10cSrcweir { 1064cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetClipRegion( rRegion )" ); 1065cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1066cdf0e10cSrcweir DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion ); 1067cdf0e10cSrcweir 1068cdf0e10cSrcweir if ( mpMetaFile ) 1069cdf0e10cSrcweir mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, sal_True ) ); 1070cdf0e10cSrcweir 1071cdf0e10cSrcweir if ( rRegion.GetType() == REGION_NULL ) 1072cdf0e10cSrcweir ImplSetClipRegion( NULL ); 1073cdf0e10cSrcweir else 1074cdf0e10cSrcweir { 1075cdf0e10cSrcweir Region aRegion = LogicToPixel( rRegion ); 1076cdf0e10cSrcweir ImplSetClipRegion( &aRegion ); 1077cdf0e10cSrcweir } 1078cdf0e10cSrcweir 1079cdf0e10cSrcweir if( mpAlphaVDev ) 1080cdf0e10cSrcweir mpAlphaVDev->SetClipRegion( rRegion ); 1081cdf0e10cSrcweir } 1082cdf0e10cSrcweir 1083cdf0e10cSrcweir // ----------------------------------------------------------------------- 1084cdf0e10cSrcweir 1085cdf0e10cSrcweir Region OutputDevice::GetClipRegion() const 1086cdf0e10cSrcweir { 1087cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1088cdf0e10cSrcweir 1089cdf0e10cSrcweir return PixelToLogic( maRegion ); 1090cdf0e10cSrcweir } 1091cdf0e10cSrcweir 1092cdf0e10cSrcweir // ----------------------------------------------------------------------- 1093cdf0e10cSrcweir 1094cdf0e10cSrcweir Region OutputDevice::GetActiveClipRegion() const 1095cdf0e10cSrcweir { 1096cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1097cdf0e10cSrcweir 1098cdf0e10cSrcweir if ( GetOutDevType() == OUTDEV_WINDOW ) 1099cdf0e10cSrcweir { 1100cdf0e10cSrcweir Region aRegion( REGION_NULL ); 1101cdf0e10cSrcweir Window* pWindow = (Window*)this; 1102cdf0e10cSrcweir if ( pWindow->mpWindowImpl->mbInPaint ) 1103cdf0e10cSrcweir { 1104cdf0e10cSrcweir aRegion = *(pWindow->mpWindowImpl->mpPaintRegion); 1105cdf0e10cSrcweir aRegion.Move( -mnOutOffX, -mnOutOffY ); 1106cdf0e10cSrcweir } 1107cdf0e10cSrcweir if ( mbClipRegion ) 1108cdf0e10cSrcweir aRegion.Intersect( maRegion ); 1109cdf0e10cSrcweir return PixelToLogic( aRegion ); 1110cdf0e10cSrcweir } 1111cdf0e10cSrcweir else 1112cdf0e10cSrcweir return GetClipRegion(); 1113cdf0e10cSrcweir } 1114cdf0e10cSrcweir 1115cdf0e10cSrcweir // ----------------------------------------------------------------------- 1116cdf0e10cSrcweir 1117cdf0e10cSrcweir void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove ) 1118cdf0e10cSrcweir { 1119cdf0e10cSrcweir DBG_TRACE( "OutputDevice::MoveClipRegion()" ); 1120cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1121cdf0e10cSrcweir 1122cdf0e10cSrcweir if ( mbClipRegion ) 1123cdf0e10cSrcweir { 1124cdf0e10cSrcweir if( mpMetaFile ) 1125cdf0e10cSrcweir mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) ); 1126cdf0e10cSrcweir 1127cdf0e10cSrcweir maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ), 1128cdf0e10cSrcweir ImplLogicHeightToDevicePixel( nVertMove ) ); 1129cdf0e10cSrcweir mbInitClipRegion = sal_True; 1130cdf0e10cSrcweir } 1131cdf0e10cSrcweir 1132cdf0e10cSrcweir if( mpAlphaVDev ) 1133cdf0e10cSrcweir mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove ); 1134cdf0e10cSrcweir } 1135cdf0e10cSrcweir 1136cdf0e10cSrcweir // ----------------------------------------------------------------------- 1137cdf0e10cSrcweir 1138cdf0e10cSrcweir void OutputDevice::IntersectClipRegion( const Rectangle& rRect ) 1139cdf0e10cSrcweir { 1140cdf0e10cSrcweir DBG_TRACE( "OutputDevice::IntersectClipRegion( rRect )" ); 1141cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1142cdf0e10cSrcweir 1143cdf0e10cSrcweir if ( mpMetaFile ) 1144cdf0e10cSrcweir mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) ); 1145cdf0e10cSrcweir 1146cdf0e10cSrcweir Rectangle aRect = LogicToPixel( rRect ); 1147cdf0e10cSrcweir maRegion.Intersect( aRect ); 1148cdf0e10cSrcweir mbClipRegion = sal_True; 1149cdf0e10cSrcweir mbInitClipRegion = sal_True; 1150cdf0e10cSrcweir 1151cdf0e10cSrcweir if( mpAlphaVDev ) 1152cdf0e10cSrcweir mpAlphaVDev->IntersectClipRegion( rRect ); 1153cdf0e10cSrcweir } 1154cdf0e10cSrcweir 1155cdf0e10cSrcweir // ----------------------------------------------------------------------- 1156cdf0e10cSrcweir 1157cdf0e10cSrcweir void OutputDevice::IntersectClipRegion( const Region& rRegion ) 1158cdf0e10cSrcweir { 1159cdf0e10cSrcweir DBG_TRACE( "OutputDevice::IntersectClipRegion( rRegion )" ); 1160cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1161cdf0e10cSrcweir DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion ); 1162cdf0e10cSrcweir 1163cdf0e10cSrcweir RegionType eType = rRegion.GetType(); 1164cdf0e10cSrcweir 1165cdf0e10cSrcweir if ( eType != REGION_NULL ) 1166cdf0e10cSrcweir { 1167cdf0e10cSrcweir if ( mpMetaFile ) 1168cdf0e10cSrcweir mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) ); 1169cdf0e10cSrcweir 1170cdf0e10cSrcweir Region aRegion = LogicToPixel( rRegion ); 1171cdf0e10cSrcweir maRegion.Intersect( aRegion ); 1172cdf0e10cSrcweir mbClipRegion = sal_True; 1173cdf0e10cSrcweir mbInitClipRegion = sal_True; 1174cdf0e10cSrcweir } 1175cdf0e10cSrcweir 1176cdf0e10cSrcweir if( mpAlphaVDev ) 1177cdf0e10cSrcweir mpAlphaVDev->IntersectClipRegion( rRegion ); 1178cdf0e10cSrcweir } 1179cdf0e10cSrcweir 1180cdf0e10cSrcweir // ----------------------------------------------------------------------- 1181cdf0e10cSrcweir 1182cdf0e10cSrcweir void OutputDevice::SetDrawMode( sal_uLong nDrawMode ) 1183cdf0e10cSrcweir { 1184cdf0e10cSrcweir DBG_TRACE1( "OutputDevice::SetDrawMode( %lx )", nDrawMode ); 1185cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1186cdf0e10cSrcweir 1187cdf0e10cSrcweir mnDrawMode = nDrawMode; 1188cdf0e10cSrcweir 1189cdf0e10cSrcweir if( mpAlphaVDev ) 1190cdf0e10cSrcweir mpAlphaVDev->SetDrawMode( nDrawMode ); 1191cdf0e10cSrcweir } 1192cdf0e10cSrcweir 1193cdf0e10cSrcweir // ----------------------------------------------------------------------- 1194cdf0e10cSrcweir 1195cdf0e10cSrcweir void OutputDevice::SetRasterOp( RasterOp eRasterOp ) 1196cdf0e10cSrcweir { 1197cdf0e10cSrcweir DBG_TRACE1( "OutputDevice::SetRasterOp( %d )", (int)eRasterOp ); 1198cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1199cdf0e10cSrcweir 1200cdf0e10cSrcweir if ( mpMetaFile ) 1201cdf0e10cSrcweir mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) ); 1202cdf0e10cSrcweir 1203cdf0e10cSrcweir if ( meRasterOp != eRasterOp ) 1204cdf0e10cSrcweir { 1205cdf0e10cSrcweir meRasterOp = eRasterOp; 1206cdf0e10cSrcweir mbInitLineColor = mbInitFillColor = sal_True; 1207cdf0e10cSrcweir 1208cdf0e10cSrcweir if( mpGraphics || ImplGetGraphics() ) 1209cdf0e10cSrcweir mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp ); 1210cdf0e10cSrcweir } 1211cdf0e10cSrcweir 1212cdf0e10cSrcweir if( mpAlphaVDev ) 1213cdf0e10cSrcweir mpAlphaVDev->SetRasterOp( eRasterOp ); 1214cdf0e10cSrcweir } 1215cdf0e10cSrcweir 1216cdf0e10cSrcweir // ----------------------------------------------------------------------- 1217cdf0e10cSrcweir 1218cdf0e10cSrcweir void OutputDevice::SetLineColor() 1219cdf0e10cSrcweir { 1220cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetLineColor()" ); 1221cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1222cdf0e10cSrcweir 1223cdf0e10cSrcweir if ( mpMetaFile ) 1224cdf0e10cSrcweir mpMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) ); 1225cdf0e10cSrcweir 1226cdf0e10cSrcweir if ( mbLineColor ) 1227cdf0e10cSrcweir { 1228cdf0e10cSrcweir mbInitLineColor = sal_True; 1229cdf0e10cSrcweir mbLineColor = sal_False; 1230cdf0e10cSrcweir maLineColor = Color( COL_TRANSPARENT ); 1231cdf0e10cSrcweir } 1232cdf0e10cSrcweir 1233cdf0e10cSrcweir if( mpAlphaVDev ) 1234cdf0e10cSrcweir mpAlphaVDev->SetLineColor(); 1235cdf0e10cSrcweir } 1236cdf0e10cSrcweir 1237cdf0e10cSrcweir // ----------------------------------------------------------------------- 1238cdf0e10cSrcweir 1239cdf0e10cSrcweir void OutputDevice::SetLineColor( const Color& rColor ) 1240cdf0e10cSrcweir { 1241cdf0e10cSrcweir DBG_TRACE1( "OutputDevice::SetLineColor( %lx )", rColor.GetColor() ); 1242cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1243cdf0e10cSrcweir 1244cdf0e10cSrcweir Color aColor( rColor ); 1245cdf0e10cSrcweir 1246cdf0e10cSrcweir if( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE | 1247cdf0e10cSrcweir DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE | 1248cdf0e10cSrcweir DRAWMODE_SETTINGSLINE ) ) 1249cdf0e10cSrcweir { 1250cdf0e10cSrcweir if( !ImplIsColorTransparent( aColor ) ) 1251cdf0e10cSrcweir { 1252cdf0e10cSrcweir if( mnDrawMode & DRAWMODE_BLACKLINE ) 1253cdf0e10cSrcweir { 1254cdf0e10cSrcweir aColor = Color( COL_BLACK ); 1255cdf0e10cSrcweir } 1256cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_WHITELINE ) 1257cdf0e10cSrcweir { 1258cdf0e10cSrcweir aColor = Color( COL_WHITE ); 1259cdf0e10cSrcweir } 1260cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_GRAYLINE ) 1261cdf0e10cSrcweir { 1262cdf0e10cSrcweir const sal_uInt8 cLum = aColor.GetLuminance(); 1263cdf0e10cSrcweir aColor = Color( cLum, cLum, cLum ); 1264cdf0e10cSrcweir } 1265cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_SETTINGSLINE ) 1266cdf0e10cSrcweir { 1267cdf0e10cSrcweir aColor = GetSettings().GetStyleSettings().GetFontColor(); 1268cdf0e10cSrcweir } 1269cdf0e10cSrcweir 1270cdf0e10cSrcweir if( mnDrawMode & DRAWMODE_GHOSTEDLINE ) 1271cdf0e10cSrcweir { 1272cdf0e10cSrcweir aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80, 1273cdf0e10cSrcweir ( aColor.GetGreen() >> 1 ) | 0x80, 1274cdf0e10cSrcweir ( aColor.GetBlue() >> 1 ) | 0x80); 1275cdf0e10cSrcweir } 1276cdf0e10cSrcweir } 1277cdf0e10cSrcweir } 1278cdf0e10cSrcweir 1279cdf0e10cSrcweir if( mpMetaFile ) 1280cdf0e10cSrcweir mpMetaFile->AddAction( new MetaLineColorAction( aColor, sal_True ) ); 1281cdf0e10cSrcweir 1282cdf0e10cSrcweir if( ImplIsColorTransparent( aColor ) ) 1283cdf0e10cSrcweir { 1284cdf0e10cSrcweir if ( mbLineColor ) 1285cdf0e10cSrcweir { 1286cdf0e10cSrcweir mbInitLineColor = sal_True; 1287cdf0e10cSrcweir mbLineColor = sal_False; 1288cdf0e10cSrcweir maLineColor = Color( COL_TRANSPARENT ); 1289cdf0e10cSrcweir } 1290cdf0e10cSrcweir } 1291cdf0e10cSrcweir else 1292cdf0e10cSrcweir { 1293cdf0e10cSrcweir if( maLineColor != aColor ) 1294cdf0e10cSrcweir { 1295cdf0e10cSrcweir mbInitLineColor = sal_True; 1296cdf0e10cSrcweir mbLineColor = sal_True; 1297cdf0e10cSrcweir maLineColor = aColor; 1298cdf0e10cSrcweir } 1299cdf0e10cSrcweir } 1300cdf0e10cSrcweir 1301cdf0e10cSrcweir if( mpAlphaVDev ) 1302cdf0e10cSrcweir mpAlphaVDev->SetLineColor( COL_BLACK ); 1303cdf0e10cSrcweir } 1304cdf0e10cSrcweir 1305cdf0e10cSrcweir // ----------------------------------------------------------------------- 1306cdf0e10cSrcweir 1307cdf0e10cSrcweir void OutputDevice::SetFillColor() 1308cdf0e10cSrcweir { 1309cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetFillColor()" ); 1310cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1311cdf0e10cSrcweir 1312cdf0e10cSrcweir if ( mpMetaFile ) 1313cdf0e10cSrcweir mpMetaFile->AddAction( new MetaFillColorAction( Color(), sal_False ) ); 1314cdf0e10cSrcweir 1315cdf0e10cSrcweir if ( mbFillColor ) 1316cdf0e10cSrcweir { 1317cdf0e10cSrcweir mbInitFillColor = sal_True; 1318cdf0e10cSrcweir mbFillColor = sal_False; 1319cdf0e10cSrcweir maFillColor = Color( COL_TRANSPARENT ); 1320cdf0e10cSrcweir } 1321cdf0e10cSrcweir 1322cdf0e10cSrcweir if( mpAlphaVDev ) 1323cdf0e10cSrcweir mpAlphaVDev->SetFillColor(); 1324cdf0e10cSrcweir } 1325cdf0e10cSrcweir 1326cdf0e10cSrcweir // ----------------------------------------------------------------------- 1327cdf0e10cSrcweir 1328cdf0e10cSrcweir void OutputDevice::SetFillColor( const Color& rColor ) 1329cdf0e10cSrcweir { 1330cdf0e10cSrcweir DBG_TRACE1( "OutputDevice::SetFillColor( %lx )", rColor.GetColor() ); 1331cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1332cdf0e10cSrcweir 1333cdf0e10cSrcweir Color aColor( rColor ); 1334cdf0e10cSrcweir 1335cdf0e10cSrcweir if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL | 1336cdf0e10cSrcweir DRAWMODE_GRAYFILL | DRAWMODE_NOFILL | 1337cdf0e10cSrcweir DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) ) 1338cdf0e10cSrcweir { 1339cdf0e10cSrcweir if( !ImplIsColorTransparent( aColor ) ) 1340cdf0e10cSrcweir { 1341cdf0e10cSrcweir if( mnDrawMode & DRAWMODE_BLACKFILL ) 1342cdf0e10cSrcweir { 1343cdf0e10cSrcweir aColor = Color( COL_BLACK ); 1344cdf0e10cSrcweir } 1345cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_WHITEFILL ) 1346cdf0e10cSrcweir { 1347cdf0e10cSrcweir aColor = Color( COL_WHITE ); 1348cdf0e10cSrcweir } 1349cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_GRAYFILL ) 1350cdf0e10cSrcweir { 1351cdf0e10cSrcweir const sal_uInt8 cLum = aColor.GetLuminance(); 1352cdf0e10cSrcweir aColor = Color( cLum, cLum, cLum ); 1353cdf0e10cSrcweir } 1354cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_NOFILL ) 1355cdf0e10cSrcweir { 1356cdf0e10cSrcweir aColor = Color( COL_TRANSPARENT ); 1357cdf0e10cSrcweir } 1358cdf0e10cSrcweir else if( mnDrawMode & DRAWMODE_SETTINGSFILL ) 1359cdf0e10cSrcweir { 1360cdf0e10cSrcweir aColor = GetSettings().GetStyleSettings().GetWindowColor(); 1361cdf0e10cSrcweir } 1362cdf0e10cSrcweir 1363cdf0e10cSrcweir if( mnDrawMode & DRAWMODE_GHOSTEDFILL ) 1364cdf0e10cSrcweir { 1365cdf0e10cSrcweir aColor = Color( (aColor.GetRed() >> 1) | 0x80, 1366cdf0e10cSrcweir (aColor.GetGreen() >> 1) | 0x80, 1367cdf0e10cSrcweir (aColor.GetBlue() >> 1) | 0x80); 1368cdf0e10cSrcweir } 1369cdf0e10cSrcweir } 1370cdf0e10cSrcweir } 1371cdf0e10cSrcweir 1372cdf0e10cSrcweir if ( mpMetaFile ) 1373cdf0e10cSrcweir mpMetaFile->AddAction( new MetaFillColorAction( aColor, sal_True ) ); 1374cdf0e10cSrcweir 1375cdf0e10cSrcweir if ( ImplIsColorTransparent( aColor ) ) 1376cdf0e10cSrcweir { 1377cdf0e10cSrcweir if ( mbFillColor ) 1378cdf0e10cSrcweir { 1379cdf0e10cSrcweir mbInitFillColor = sal_True; 1380cdf0e10cSrcweir mbFillColor = sal_False; 1381cdf0e10cSrcweir maFillColor = Color( COL_TRANSPARENT ); 1382cdf0e10cSrcweir } 1383cdf0e10cSrcweir } 1384cdf0e10cSrcweir else 1385cdf0e10cSrcweir { 1386cdf0e10cSrcweir if ( maFillColor != aColor ) 1387cdf0e10cSrcweir { 1388cdf0e10cSrcweir mbInitFillColor = sal_True; 1389cdf0e10cSrcweir mbFillColor = sal_True; 1390cdf0e10cSrcweir maFillColor = aColor; 1391cdf0e10cSrcweir } 1392cdf0e10cSrcweir } 1393cdf0e10cSrcweir 1394cdf0e10cSrcweir if( mpAlphaVDev ) 1395cdf0e10cSrcweir mpAlphaVDev->SetFillColor( COL_BLACK ); 1396cdf0e10cSrcweir } 1397cdf0e10cSrcweir 1398cdf0e10cSrcweir // ----------------------------------------------------------------------- 1399cdf0e10cSrcweir 1400cdf0e10cSrcweir void OutputDevice::SetBackground() 1401cdf0e10cSrcweir { 1402cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetBackground()" ); 1403cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1404cdf0e10cSrcweir 1405cdf0e10cSrcweir maBackground = Wallpaper(); 1406cdf0e10cSrcweir mbBackground = sal_False; 1407cdf0e10cSrcweir 1408cdf0e10cSrcweir if( mpAlphaVDev ) 1409cdf0e10cSrcweir mpAlphaVDev->SetBackground(); 1410cdf0e10cSrcweir } 1411cdf0e10cSrcweir 1412cdf0e10cSrcweir // ----------------------------------------------------------------------- 1413cdf0e10cSrcweir 1414cdf0e10cSrcweir void OutputDevice::SetBackground( const Wallpaper& rBackground ) 1415cdf0e10cSrcweir { 1416cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetBackground( rBackground )" ); 1417cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1418cdf0e10cSrcweir 1419cdf0e10cSrcweir maBackground = rBackground; 1420cdf0e10cSrcweir 1421cdf0e10cSrcweir if( rBackground.GetStyle() == WALLPAPER_NULL ) 1422cdf0e10cSrcweir mbBackground = sal_False; 1423cdf0e10cSrcweir else 1424cdf0e10cSrcweir mbBackground = sal_True; 1425cdf0e10cSrcweir 1426cdf0e10cSrcweir if( mpAlphaVDev ) 1427cdf0e10cSrcweir mpAlphaVDev->SetBackground( rBackground ); 1428cdf0e10cSrcweir } 1429cdf0e10cSrcweir 1430cdf0e10cSrcweir // ----------------------------------------------------------------------- 1431cdf0e10cSrcweir 1432cdf0e10cSrcweir void OutputDevice::SetRefPoint() 1433cdf0e10cSrcweir { 1434cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetRefPoint()" ); 1435cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1436cdf0e10cSrcweir 1437cdf0e10cSrcweir if ( mpMetaFile ) 1438cdf0e10cSrcweir mpMetaFile->AddAction( new MetaRefPointAction( Point(), sal_False ) ); 1439cdf0e10cSrcweir 1440cdf0e10cSrcweir mbRefPoint = sal_False; 1441cdf0e10cSrcweir maRefPoint.X() = maRefPoint.Y() = 0L; 1442cdf0e10cSrcweir 1443cdf0e10cSrcweir if( mpAlphaVDev ) 1444cdf0e10cSrcweir mpAlphaVDev->SetRefPoint(); 1445cdf0e10cSrcweir } 1446cdf0e10cSrcweir 1447cdf0e10cSrcweir // ----------------------------------------------------------------------- 1448cdf0e10cSrcweir 1449cdf0e10cSrcweir void OutputDevice::SetRefPoint( const Point& rRefPoint ) 1450cdf0e10cSrcweir { 1451cdf0e10cSrcweir DBG_TRACE( "OutputDevice::SetRefPoint( rRefPoint )" ); 1452cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1453cdf0e10cSrcweir 1454cdf0e10cSrcweir if ( mpMetaFile ) 1455cdf0e10cSrcweir mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, sal_True ) ); 1456cdf0e10cSrcweir 1457cdf0e10cSrcweir mbRefPoint = sal_True; 1458cdf0e10cSrcweir maRefPoint = rRefPoint; 1459cdf0e10cSrcweir 1460cdf0e10cSrcweir if( mpAlphaVDev ) 1461cdf0e10cSrcweir mpAlphaVDev->SetRefPoint( rRefPoint ); 1462cdf0e10cSrcweir } 1463cdf0e10cSrcweir 1464cdf0e10cSrcweir // ----------------------------------------------------------------------- 1465cdf0e10cSrcweir 1466cdf0e10cSrcweir void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) 1467cdf0e10cSrcweir { 1468cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawLine()" ); 1469cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1470cdf0e10cSrcweir 1471cdf0e10cSrcweir if ( mpMetaFile ) 1472cdf0e10cSrcweir mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) ); 1473cdf0e10cSrcweir 1474cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() ) 1475cdf0e10cSrcweir return; 1476cdf0e10cSrcweir 1477cdf0e10cSrcweir if ( !mpGraphics ) 1478cdf0e10cSrcweir { 1479cdf0e10cSrcweir if ( !ImplGetGraphics() ) 1480cdf0e10cSrcweir return; 1481cdf0e10cSrcweir } 1482cdf0e10cSrcweir 1483cdf0e10cSrcweir if ( mbInitClipRegion ) 1484cdf0e10cSrcweir ImplInitClipRegion(); 1485cdf0e10cSrcweir if ( mbOutputClipped ) 1486cdf0e10cSrcweir return; 1487cdf0e10cSrcweir 1488cdf0e10cSrcweir if ( mbInitLineColor ) 1489cdf0e10cSrcweir ImplInitLineColor(); 1490cdf0e10cSrcweir 1491cdf0e10cSrcweir // #i101598# support AA and snap for lines, too 1492cdf0e10cSrcweir if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 1493cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 1494cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 1495cdf0e10cSrcweir && IsLineColor()) 1496cdf0e10cSrcweir { 1497cdf0e10cSrcweir // at least transform with double precision to device coordinates; this will 1498cdf0e10cSrcweir // avoid pixel snap of single, appended lines 1499cdf0e10cSrcweir const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); 1500cdf0e10cSrcweir const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); 1501cdf0e10cSrcweir basegfx::B2DPolygon aB2DPolyLine; 1502cdf0e10cSrcweir 1503cdf0e10cSrcweir aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y())); 1504cdf0e10cSrcweir aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y())); 1505cdf0e10cSrcweir aB2DPolyLine.transform( aTransform ); 1506cdf0e10cSrcweir 1507cdf0e10cSrcweir if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 1508cdf0e10cSrcweir { 1509cdf0e10cSrcweir aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); 1510cdf0e10cSrcweir } 1511cdf0e10cSrcweir 1512*5aaf853bSArmin Le Grand if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this)) 1513cdf0e10cSrcweir { 1514cdf0e10cSrcweir return; 1515cdf0e10cSrcweir } 1516cdf0e10cSrcweir } 1517cdf0e10cSrcweir 1518cdf0e10cSrcweir const Point aStartPt(ImplLogicToDevicePixel(rStartPt)); 1519cdf0e10cSrcweir const Point aEndPt(ImplLogicToDevicePixel(rEndPt)); 1520cdf0e10cSrcweir 1521cdf0e10cSrcweir mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); 1522cdf0e10cSrcweir 1523cdf0e10cSrcweir if( mpAlphaVDev ) 1524cdf0e10cSrcweir mpAlphaVDev->DrawLine( rStartPt, rEndPt ); 1525cdf0e10cSrcweir } 1526cdf0e10cSrcweir 1527cdf0e10cSrcweir // ----------------------------------------------------------------------- 1528cdf0e10cSrcweir 1529cdf0e10cSrcweir void OutputDevice::impPaintLineGeometryWithEvtlExpand( 1530cdf0e10cSrcweir const LineInfo& rInfo, 1531cdf0e10cSrcweir basegfx::B2DPolyPolygon aLinePolyPolygon) 1532cdf0e10cSrcweir { 1533cdf0e10cSrcweir const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 1534cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 1535cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 1536cdf0e10cSrcweir && IsLineColor()); 1537cdf0e10cSrcweir basegfx::B2DPolyPolygon aFillPolyPolygon; 1538cdf0e10cSrcweir const bool bDashUsed(LINE_DASH == rInfo.GetStyle()); 1539cdf0e10cSrcweir const bool bLineWidthUsed(rInfo.GetWidth() > 1); 1540cdf0e10cSrcweir 1541cdf0e10cSrcweir if(bDashUsed && aLinePolyPolygon.count()) 1542cdf0e10cSrcweir { 1543cdf0e10cSrcweir ::std::vector< double > fDotDashArray; 1544cdf0e10cSrcweir const double fDashLen(rInfo.GetDashLen()); 1545cdf0e10cSrcweir const double fDotLen(rInfo.GetDotLen()); 1546cdf0e10cSrcweir const double fDistance(rInfo.GetDistance()); 1547cdf0e10cSrcweir 1548cdf0e10cSrcweir for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++) 1549cdf0e10cSrcweir { 1550cdf0e10cSrcweir fDotDashArray.push_back(fDashLen); 1551cdf0e10cSrcweir fDotDashArray.push_back(fDistance); 1552cdf0e10cSrcweir } 1553cdf0e10cSrcweir 1554cdf0e10cSrcweir for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++) 1555cdf0e10cSrcweir { 1556cdf0e10cSrcweir fDotDashArray.push_back(fDotLen); 1557cdf0e10cSrcweir fDotDashArray.push_back(fDistance); 1558cdf0e10cSrcweir } 1559cdf0e10cSrcweir 1560cdf0e10cSrcweir const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0)); 1561cdf0e10cSrcweir 1562cdf0e10cSrcweir if(fAccumulated > 0.0) 1563cdf0e10cSrcweir { 1564cdf0e10cSrcweir basegfx::B2DPolyPolygon aResult; 1565cdf0e10cSrcweir 1566cdf0e10cSrcweir for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++) 1567cdf0e10cSrcweir { 1568cdf0e10cSrcweir basegfx::B2DPolyPolygon aLineTraget; 1569cdf0e10cSrcweir basegfx::tools::applyLineDashing( 1570cdf0e10cSrcweir aLinePolyPolygon.getB2DPolygon(c), 1571cdf0e10cSrcweir fDotDashArray, 1572cdf0e10cSrcweir &aLineTraget); 1573cdf0e10cSrcweir aResult.append(aLineTraget); 1574cdf0e10cSrcweir } 1575cdf0e10cSrcweir 1576cdf0e10cSrcweir aLinePolyPolygon = aResult; 1577cdf0e10cSrcweir } 1578cdf0e10cSrcweir } 1579cdf0e10cSrcweir 1580cdf0e10cSrcweir if(bLineWidthUsed && aLinePolyPolygon.count()) 1581cdf0e10cSrcweir { 1582cdf0e10cSrcweir const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5); 1583cdf0e10cSrcweir 1584cdf0e10cSrcweir if(aLinePolyPolygon.areControlPointsUsed()) 1585cdf0e10cSrcweir { 1586cdf0e10cSrcweir // #i110768# When area geometry has to be created, do not 1587cdf0e10cSrcweir // use the fallback bezier decomposition inside createAreaGeometry, 1588cdf0e10cSrcweir // but one that is at least as good as ImplSubdivideBezier was. 1589cdf0e10cSrcweir // There, Polygon::AdaptiveSubdivide was used with default parameter 1590cdf0e10cSrcweir // 1.0 as quality index. 1591cdf0e10cSrcweir aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0); 1592cdf0e10cSrcweir } 1593cdf0e10cSrcweir 1594cdf0e10cSrcweir for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++) 1595cdf0e10cSrcweir { 1596cdf0e10cSrcweir aFillPolyPolygon.append(basegfx::tools::createAreaGeometry( 1597cdf0e10cSrcweir aLinePolyPolygon.getB2DPolygon(a), 1598cdf0e10cSrcweir fHalfLineWidth, 1599*5aaf853bSArmin Le Grand rInfo.GetLineJoin(), 1600*5aaf853bSArmin Le Grand rInfo.GetLineCap())); 1601cdf0e10cSrcweir } 1602cdf0e10cSrcweir 1603cdf0e10cSrcweir aLinePolyPolygon.clear(); 1604cdf0e10cSrcweir } 1605cdf0e10cSrcweir 1606cdf0e10cSrcweir GDIMetaFile* pOldMetaFile = mpMetaFile; 1607cdf0e10cSrcweir mpMetaFile = NULL; 1608cdf0e10cSrcweir 1609cdf0e10cSrcweir if(aLinePolyPolygon.count()) 1610cdf0e10cSrcweir { 1611cdf0e10cSrcweir for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++) 1612cdf0e10cSrcweir { 1613cdf0e10cSrcweir const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a)); 1614cdf0e10cSrcweir bool bDone(false); 1615cdf0e10cSrcweir 1616cdf0e10cSrcweir if(bTryAA) 1617cdf0e10cSrcweir { 1618*5aaf853bSArmin Le Grand bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this); 1619cdf0e10cSrcweir } 1620cdf0e10cSrcweir 1621cdf0e10cSrcweir if(!bDone) 1622cdf0e10cSrcweir { 1623cdf0e10cSrcweir const Polygon aPolygon(aCandidate); 1624cdf0e10cSrcweir mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this); 1625cdf0e10cSrcweir } 1626cdf0e10cSrcweir } 1627cdf0e10cSrcweir } 1628cdf0e10cSrcweir 1629cdf0e10cSrcweir if(aFillPolyPolygon.count()) 1630cdf0e10cSrcweir { 1631cdf0e10cSrcweir const Color aOldLineColor( maLineColor ); 1632cdf0e10cSrcweir const Color aOldFillColor( maFillColor ); 1633cdf0e10cSrcweir 1634cdf0e10cSrcweir SetLineColor(); 1635cdf0e10cSrcweir ImplInitLineColor(); 1636cdf0e10cSrcweir SetFillColor( aOldLineColor ); 1637cdf0e10cSrcweir ImplInitFillColor(); 1638cdf0e10cSrcweir 1639cdf0e10cSrcweir bool bDone(false); 1640cdf0e10cSrcweir 1641cdf0e10cSrcweir if(bTryAA) 1642cdf0e10cSrcweir { 1643cdf0e10cSrcweir bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this); 1644cdf0e10cSrcweir } 1645cdf0e10cSrcweir 1646cdf0e10cSrcweir if(!bDone) 1647cdf0e10cSrcweir { 1648cdf0e10cSrcweir for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++) 1649cdf0e10cSrcweir { 1650*5aaf853bSArmin Le Grand Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a)); 1651*5aaf853bSArmin Le Grand 1652*5aaf853bSArmin Le Grand // need to subdivide, mpGraphics->DrawPolygon ignores curves 1653*5aaf853bSArmin Le Grand aPolygon.AdaptiveSubdivide(aPolygon); 1654cdf0e10cSrcweir mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this); 1655cdf0e10cSrcweir } 1656cdf0e10cSrcweir } 1657cdf0e10cSrcweir 1658cdf0e10cSrcweir SetFillColor( aOldFillColor ); 1659cdf0e10cSrcweir SetLineColor( aOldLineColor ); 1660cdf0e10cSrcweir } 1661cdf0e10cSrcweir 1662cdf0e10cSrcweir mpMetaFile = pOldMetaFile; 1663cdf0e10cSrcweir } 1664cdf0e10cSrcweir 1665cdf0e10cSrcweir // ----------------------------------------------------------------------- 1666cdf0e10cSrcweir 1667cdf0e10cSrcweir void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt, 1668cdf0e10cSrcweir const LineInfo& rLineInfo ) 1669cdf0e10cSrcweir { 1670cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawLine()" ); 1671cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1672cdf0e10cSrcweir 1673cdf0e10cSrcweir if ( rLineInfo.IsDefault() ) 1674cdf0e10cSrcweir { 1675cdf0e10cSrcweir DrawLine( rStartPt, rEndPt ); 1676cdf0e10cSrcweir return; 1677cdf0e10cSrcweir } 1678cdf0e10cSrcweir 1679cdf0e10cSrcweir if ( mpMetaFile ) 1680cdf0e10cSrcweir mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) ); 1681cdf0e10cSrcweir 1682cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() ) 1683cdf0e10cSrcweir return; 1684cdf0e10cSrcweir 1685cdf0e10cSrcweir if( !mpGraphics && !ImplGetGraphics() ) 1686cdf0e10cSrcweir return; 1687cdf0e10cSrcweir 1688cdf0e10cSrcweir if ( mbInitClipRegion ) 1689cdf0e10cSrcweir ImplInitClipRegion(); 1690cdf0e10cSrcweir 1691cdf0e10cSrcweir if ( mbOutputClipped ) 1692cdf0e10cSrcweir return; 1693cdf0e10cSrcweir 1694cdf0e10cSrcweir const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) ); 1695cdf0e10cSrcweir const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) ); 1696cdf0e10cSrcweir const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); 1697cdf0e10cSrcweir const bool bDashUsed(LINE_DASH == aInfo.GetStyle()); 1698cdf0e10cSrcweir const bool bLineWidthUsed(aInfo.GetWidth() > 1); 1699cdf0e10cSrcweir 1700cdf0e10cSrcweir if ( mbInitLineColor ) 1701cdf0e10cSrcweir ImplInitLineColor(); 1702cdf0e10cSrcweir 1703cdf0e10cSrcweir if(bDashUsed || bLineWidthUsed) 1704cdf0e10cSrcweir { 1705cdf0e10cSrcweir basegfx::B2DPolygon aLinePolygon; 1706cdf0e10cSrcweir aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y())); 1707cdf0e10cSrcweir aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y())); 1708cdf0e10cSrcweir 1709cdf0e10cSrcweir impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon)); 1710cdf0e10cSrcweir } 1711cdf0e10cSrcweir else 1712cdf0e10cSrcweir { 1713cdf0e10cSrcweir mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); 1714cdf0e10cSrcweir } 1715cdf0e10cSrcweir 1716cdf0e10cSrcweir if( mpAlphaVDev ) 1717cdf0e10cSrcweir mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo ); 1718cdf0e10cSrcweir } 1719cdf0e10cSrcweir 1720cdf0e10cSrcweir // ----------------------------------------------------------------------- 1721cdf0e10cSrcweir 1722cdf0e10cSrcweir void OutputDevice::DrawRect( const Rectangle& rRect ) 1723cdf0e10cSrcweir { 1724cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawRect()" ); 1725cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1726cdf0e10cSrcweir 1727cdf0e10cSrcweir if ( mpMetaFile ) 1728cdf0e10cSrcweir mpMetaFile->AddAction( new MetaRectAction( rRect ) ); 1729cdf0e10cSrcweir 1730cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() ) 1731cdf0e10cSrcweir return; 1732cdf0e10cSrcweir 1733cdf0e10cSrcweir Rectangle aRect( ImplLogicToDevicePixel( rRect ) ); 1734cdf0e10cSrcweir 1735cdf0e10cSrcweir if ( aRect.IsEmpty() ) 1736cdf0e10cSrcweir return; 1737cdf0e10cSrcweir aRect.Justify(); 1738cdf0e10cSrcweir 1739cdf0e10cSrcweir if ( !mpGraphics ) 1740cdf0e10cSrcweir { 1741cdf0e10cSrcweir if ( !ImplGetGraphics() ) 1742cdf0e10cSrcweir return; 1743cdf0e10cSrcweir } 1744cdf0e10cSrcweir 1745cdf0e10cSrcweir if ( mbInitClipRegion ) 1746cdf0e10cSrcweir ImplInitClipRegion(); 1747cdf0e10cSrcweir if ( mbOutputClipped ) 1748cdf0e10cSrcweir return; 1749cdf0e10cSrcweir 1750cdf0e10cSrcweir if ( mbInitLineColor ) 1751cdf0e10cSrcweir ImplInitLineColor(); 1752cdf0e10cSrcweir if ( mbInitFillColor ) 1753cdf0e10cSrcweir ImplInitFillColor(); 1754cdf0e10cSrcweir 1755cdf0e10cSrcweir mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this ); 1756cdf0e10cSrcweir 1757cdf0e10cSrcweir if( mpAlphaVDev ) 1758cdf0e10cSrcweir mpAlphaVDev->DrawRect( rRect ); 1759cdf0e10cSrcweir } 1760cdf0e10cSrcweir 1761cdf0e10cSrcweir // ----------------------------------------------------------------------- 1762cdf0e10cSrcweir 1763cdf0e10cSrcweir void OutputDevice::DrawPolyLine( const Polygon& rPoly ) 1764cdf0e10cSrcweir { 1765cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawPolyLine()" ); 1766cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1767cdf0e10cSrcweir DBG_CHKOBJ( &rPoly, Polygon, NULL ); 1768cdf0e10cSrcweir 1769cdf0e10cSrcweir if( mpMetaFile ) 1770cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) ); 1771cdf0e10cSrcweir 1772cdf0e10cSrcweir sal_uInt16 nPoints = rPoly.GetSize(); 1773cdf0e10cSrcweir 1774cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() ) 1775cdf0e10cSrcweir return; 1776cdf0e10cSrcweir 1777cdf0e10cSrcweir // we need a graphics 1778cdf0e10cSrcweir if ( !mpGraphics ) 1779cdf0e10cSrcweir if ( !ImplGetGraphics() ) 1780cdf0e10cSrcweir return; 1781cdf0e10cSrcweir 1782cdf0e10cSrcweir if ( mbInitClipRegion ) 1783cdf0e10cSrcweir ImplInitClipRegion(); 1784cdf0e10cSrcweir if ( mbOutputClipped ) 1785cdf0e10cSrcweir return; 1786cdf0e10cSrcweir 1787cdf0e10cSrcweir if ( mbInitLineColor ) 1788cdf0e10cSrcweir ImplInitLineColor(); 1789cdf0e10cSrcweir 1790cdf0e10cSrcweir const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 1791cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 1792cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 1793cdf0e10cSrcweir && IsLineColor()); 1794cdf0e10cSrcweir 1795cdf0e10cSrcweir // use b2dpolygon drawing if possible 1796*5aaf853bSArmin Le Grand if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon())) 1797cdf0e10cSrcweir { 1798cdf0e10cSrcweir basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon()); 1799cdf0e10cSrcweir const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); 1800cdf0e10cSrcweir const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); 1801cdf0e10cSrcweir 1802cdf0e10cSrcweir // transform the polygon 1803cdf0e10cSrcweir aB2DPolyLine.transform( aTransform ); 1804cdf0e10cSrcweir 1805cdf0e10cSrcweir if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 1806cdf0e10cSrcweir { 1807cdf0e10cSrcweir aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); 1808cdf0e10cSrcweir } 1809cdf0e10cSrcweir 1810*5aaf853bSArmin Le Grand if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this)) 1811cdf0e10cSrcweir { 1812cdf0e10cSrcweir return; 1813cdf0e10cSrcweir } 1814cdf0e10cSrcweir } 1815cdf0e10cSrcweir 1816cdf0e10cSrcweir Polygon aPoly = ImplLogicToDevicePixel( rPoly ); 1817cdf0e10cSrcweir const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry(); 1818cdf0e10cSrcweir 1819cdf0e10cSrcweir // #100127# Forward beziers to sal, if any 1820cdf0e10cSrcweir if( aPoly.HasFlags() ) 1821cdf0e10cSrcweir { 1822cdf0e10cSrcweir const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry(); 1823cdf0e10cSrcweir if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) ) 1824cdf0e10cSrcweir { 1825cdf0e10cSrcweir aPoly = ImplSubdivideBezier(aPoly); 1826cdf0e10cSrcweir pPtAry = (const SalPoint*)aPoly.GetConstPointAry(); 1827cdf0e10cSrcweir mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this ); 1828cdf0e10cSrcweir } 1829cdf0e10cSrcweir } 1830cdf0e10cSrcweir else 1831cdf0e10cSrcweir { 1832cdf0e10cSrcweir mpGraphics->DrawPolyLine( nPoints, pPtAry, this ); 1833cdf0e10cSrcweir } 1834cdf0e10cSrcweir 1835cdf0e10cSrcweir if( mpAlphaVDev ) 1836cdf0e10cSrcweir mpAlphaVDev->DrawPolyLine( rPoly ); 1837cdf0e10cSrcweir } 1838cdf0e10cSrcweir 1839cdf0e10cSrcweir // ----------------------------------------------------------------------- 1840cdf0e10cSrcweir 1841cdf0e10cSrcweir void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo ) 1842cdf0e10cSrcweir { 1843cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawPolyLine()" ); 1844cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1845cdf0e10cSrcweir DBG_CHKOBJ( &rPoly, Polygon, NULL ); 1846cdf0e10cSrcweir 1847cdf0e10cSrcweir if ( rLineInfo.IsDefault() ) 1848cdf0e10cSrcweir { 1849cdf0e10cSrcweir DrawPolyLine( rPoly ); 1850cdf0e10cSrcweir return; 1851cdf0e10cSrcweir } 1852cdf0e10cSrcweir 1853cdf0e10cSrcweir // #i101491# 1854cdf0e10cSrcweir // Try direct Fallback to B2D-Version of DrawPolyLine 1855cdf0e10cSrcweir if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 1856cdf0e10cSrcweir && LINE_SOLID == rLineInfo.GetStyle()) 1857cdf0e10cSrcweir { 1858*5aaf853bSArmin Le Grand DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap()); 1859cdf0e10cSrcweir return; 1860cdf0e10cSrcweir } 1861cdf0e10cSrcweir 1862cdf0e10cSrcweir if ( mpMetaFile ) 1863cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) ); 1864cdf0e10cSrcweir 1865cdf0e10cSrcweir ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo); 1866cdf0e10cSrcweir } 1867cdf0e10cSrcweir 1868cdf0e10cSrcweir void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo) 1869cdf0e10cSrcweir { 1870cdf0e10cSrcweir sal_uInt16 nPoints(rPoly.GetSize()); 1871cdf0e10cSrcweir 1872cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() ) 1873cdf0e10cSrcweir return; 1874cdf0e10cSrcweir 1875cdf0e10cSrcweir Polygon aPoly = ImplLogicToDevicePixel( rPoly ); 1876cdf0e10cSrcweir 1877cdf0e10cSrcweir // #100127# LineInfo is not curve-safe, subdivide always 1878cdf0e10cSrcweir // 1879cdf0e10cSrcweir // What shall this mean? It's wrong to subdivide here when the 1880cdf0e10cSrcweir // polygon is a fat line. In that case, the painted geometry 1881cdf0e10cSrcweir // WILL be much different. 1882cdf0e10cSrcweir // I also have no idea how this could be related to the given ID 1883cdf0e10cSrcweir // which reads 'consolidate boost versions' in the task description. 1884cdf0e10cSrcweir // Removing. 1885cdf0e10cSrcweir // 1886cdf0e10cSrcweir //if( aPoly.HasFlags() ) 1887cdf0e10cSrcweir //{ 1888cdf0e10cSrcweir // aPoly = ImplSubdivideBezier( aPoly ); 1889cdf0e10cSrcweir // nPoints = aPoly.GetSize(); 1890cdf0e10cSrcweir //} 1891cdf0e10cSrcweir 1892cdf0e10cSrcweir // we need a graphics 1893cdf0e10cSrcweir if ( !mpGraphics && !ImplGetGraphics() ) 1894cdf0e10cSrcweir return; 1895cdf0e10cSrcweir 1896cdf0e10cSrcweir if ( mbInitClipRegion ) 1897cdf0e10cSrcweir ImplInitClipRegion(); 1898cdf0e10cSrcweir 1899cdf0e10cSrcweir if ( mbOutputClipped ) 1900cdf0e10cSrcweir return; 1901cdf0e10cSrcweir 1902cdf0e10cSrcweir if ( mbInitLineColor ) 1903cdf0e10cSrcweir ImplInitLineColor(); 1904cdf0e10cSrcweir 1905cdf0e10cSrcweir const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); 1906cdf0e10cSrcweir const bool bDashUsed(LINE_DASH == aInfo.GetStyle()); 1907cdf0e10cSrcweir const bool bLineWidthUsed(aInfo.GetWidth() > 1); 1908cdf0e10cSrcweir 1909cdf0e10cSrcweir if(bDashUsed || bLineWidthUsed) 1910cdf0e10cSrcweir { 1911cdf0e10cSrcweir impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon())); 1912cdf0e10cSrcweir } 1913cdf0e10cSrcweir else 1914cdf0e10cSrcweir { 1915cdf0e10cSrcweir // #100127# the subdivision HAS to be done here since only a pointer 1916cdf0e10cSrcweir // to an array of points is given to the DrawPolyLine method, there is 1917cdf0e10cSrcweir // NO way to find out there that it's a curve. 1918cdf0e10cSrcweir if( aPoly.HasFlags() ) 1919cdf0e10cSrcweir { 1920cdf0e10cSrcweir aPoly = ImplSubdivideBezier( aPoly ); 1921cdf0e10cSrcweir nPoints = aPoly.GetSize(); 1922cdf0e10cSrcweir } 1923cdf0e10cSrcweir 1924cdf0e10cSrcweir mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this); 1925cdf0e10cSrcweir } 1926cdf0e10cSrcweir 1927cdf0e10cSrcweir if( mpAlphaVDev ) 1928cdf0e10cSrcweir mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo ); 1929cdf0e10cSrcweir } 1930cdf0e10cSrcweir 1931cdf0e10cSrcweir // ----------------------------------------------------------------------- 1932cdf0e10cSrcweir 1933cdf0e10cSrcweir void OutputDevice::DrawPolygon( const Polygon& rPoly ) 1934cdf0e10cSrcweir { 1935cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawPolygon()" ); 1936cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 1937cdf0e10cSrcweir DBG_CHKOBJ( &rPoly, Polygon, NULL ); 1938cdf0e10cSrcweir 1939cdf0e10cSrcweir if( mpMetaFile ) 1940cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) ); 1941cdf0e10cSrcweir 1942cdf0e10cSrcweir sal_uInt16 nPoints = rPoly.GetSize(); 1943cdf0e10cSrcweir 1944cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() ) 1945cdf0e10cSrcweir return; 1946cdf0e10cSrcweir 1947cdf0e10cSrcweir // we need a graphics 1948cdf0e10cSrcweir if ( !mpGraphics ) 1949cdf0e10cSrcweir if ( !ImplGetGraphics() ) 1950cdf0e10cSrcweir return; 1951cdf0e10cSrcweir 1952cdf0e10cSrcweir if ( mbInitClipRegion ) 1953cdf0e10cSrcweir ImplInitClipRegion(); 1954cdf0e10cSrcweir if ( mbOutputClipped ) 1955cdf0e10cSrcweir return; 1956cdf0e10cSrcweir 1957cdf0e10cSrcweir if ( mbInitLineColor ) 1958cdf0e10cSrcweir ImplInitLineColor(); 1959cdf0e10cSrcweir if ( mbInitFillColor ) 1960cdf0e10cSrcweir ImplInitFillColor(); 1961cdf0e10cSrcweir 1962cdf0e10cSrcweir // use b2dpolygon drawing if possible 1963cdf0e10cSrcweir if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 1964cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 1965cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 1966cdf0e10cSrcweir && (IsLineColor() || IsFillColor())) 1967cdf0e10cSrcweir { 1968cdf0e10cSrcweir const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); 1969cdf0e10cSrcweir basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon()); 1970cdf0e10cSrcweir bool bSuccess(true); 1971cdf0e10cSrcweir 1972cdf0e10cSrcweir // transform the polygon and ensure closed 1973cdf0e10cSrcweir aB2DPolygon.transform(aTransform); 1974cdf0e10cSrcweir aB2DPolygon.setClosed(true); 1975cdf0e10cSrcweir 1976cdf0e10cSrcweir if(IsFillColor()) 1977cdf0e10cSrcweir { 1978cdf0e10cSrcweir bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this); 1979cdf0e10cSrcweir } 1980cdf0e10cSrcweir 1981cdf0e10cSrcweir if(bSuccess && IsLineColor()) 1982cdf0e10cSrcweir { 1983cdf0e10cSrcweir const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); 1984cdf0e10cSrcweir 1985cdf0e10cSrcweir if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 1986cdf0e10cSrcweir { 1987cdf0e10cSrcweir aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); 1988cdf0e10cSrcweir } 1989cdf0e10cSrcweir 1990*5aaf853bSArmin Le Grand bSuccess = mpGraphics->DrawPolyLine( 1991*5aaf853bSArmin Le Grand aB2DPolygon, 1992*5aaf853bSArmin Le Grand 0.0, 1993*5aaf853bSArmin Le Grand aB2DLineWidth, 1994*5aaf853bSArmin Le Grand basegfx::B2DLINEJOIN_NONE, 1995*5aaf853bSArmin Le Grand com::sun::star::drawing::LineCap_BUTT, 1996*5aaf853bSArmin Le Grand this); 1997cdf0e10cSrcweir } 1998cdf0e10cSrcweir 1999cdf0e10cSrcweir if(bSuccess) 2000cdf0e10cSrcweir { 2001cdf0e10cSrcweir return; 2002cdf0e10cSrcweir } 2003cdf0e10cSrcweir } 2004cdf0e10cSrcweir 2005cdf0e10cSrcweir Polygon aPoly = ImplLogicToDevicePixel( rPoly ); 2006cdf0e10cSrcweir const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry(); 2007cdf0e10cSrcweir 2008cdf0e10cSrcweir // #100127# Forward beziers to sal, if any 2009cdf0e10cSrcweir if( aPoly.HasFlags() ) 2010cdf0e10cSrcweir { 2011cdf0e10cSrcweir const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry(); 2012cdf0e10cSrcweir if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) ) 2013cdf0e10cSrcweir { 2014cdf0e10cSrcweir aPoly = ImplSubdivideBezier(aPoly); 2015cdf0e10cSrcweir pPtAry = (const SalPoint*)aPoly.GetConstPointAry(); 2016cdf0e10cSrcweir mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this ); 2017cdf0e10cSrcweir } 2018cdf0e10cSrcweir } 2019cdf0e10cSrcweir else 2020cdf0e10cSrcweir { 2021cdf0e10cSrcweir mpGraphics->DrawPolygon( nPoints, pPtAry, this ); 2022cdf0e10cSrcweir } 2023cdf0e10cSrcweir if( mpAlphaVDev ) 2024cdf0e10cSrcweir mpAlphaVDev->DrawPolygon( rPoly ); 2025cdf0e10cSrcweir } 2026cdf0e10cSrcweir 2027cdf0e10cSrcweir // ----------------------------------------------------------------------- 2028cdf0e10cSrcweir 2029cdf0e10cSrcweir void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly ) 2030cdf0e10cSrcweir { 2031cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawPolyPolygon()" ); 2032cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2033cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL ); 2034cdf0e10cSrcweir 2035cdf0e10cSrcweir if( mpMetaFile ) 2036cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) ); 2037cdf0e10cSrcweir 2038cdf0e10cSrcweir sal_uInt16 nPoly = rPolyPoly.Count(); 2039cdf0e10cSrcweir 2040cdf0e10cSrcweir if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() ) 2041cdf0e10cSrcweir return; 2042cdf0e10cSrcweir 2043cdf0e10cSrcweir // we need a graphics 2044cdf0e10cSrcweir if ( !mpGraphics ) 2045cdf0e10cSrcweir if ( !ImplGetGraphics() ) 2046cdf0e10cSrcweir return; 2047cdf0e10cSrcweir 2048cdf0e10cSrcweir if ( mbInitClipRegion ) 2049cdf0e10cSrcweir ImplInitClipRegion(); 2050cdf0e10cSrcweir if ( mbOutputClipped ) 2051cdf0e10cSrcweir return; 2052cdf0e10cSrcweir 2053cdf0e10cSrcweir if ( mbInitLineColor ) 2054cdf0e10cSrcweir ImplInitLineColor(); 2055cdf0e10cSrcweir if ( mbInitFillColor ) 2056cdf0e10cSrcweir ImplInitFillColor(); 2057cdf0e10cSrcweir 2058cdf0e10cSrcweir // use b2dpolygon drawing if possible 2059cdf0e10cSrcweir if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 2060cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 2061cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 2062cdf0e10cSrcweir && (IsLineColor() || IsFillColor())) 2063cdf0e10cSrcweir { 2064cdf0e10cSrcweir const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); 2065cdf0e10cSrcweir basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon()); 2066cdf0e10cSrcweir bool bSuccess(true); 2067cdf0e10cSrcweir 2068cdf0e10cSrcweir // transform the polygon and ensure closed 2069cdf0e10cSrcweir aB2DPolyPolygon.transform(aTransform); 2070cdf0e10cSrcweir aB2DPolyPolygon.setClosed(true); 2071cdf0e10cSrcweir 2072cdf0e10cSrcweir if(IsFillColor()) 2073cdf0e10cSrcweir { 2074cdf0e10cSrcweir bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this); 2075cdf0e10cSrcweir } 2076cdf0e10cSrcweir 2077cdf0e10cSrcweir if(bSuccess && IsLineColor()) 2078cdf0e10cSrcweir { 2079cdf0e10cSrcweir const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); 2080cdf0e10cSrcweir 2081cdf0e10cSrcweir if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 2082cdf0e10cSrcweir { 2083cdf0e10cSrcweir aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon); 2084cdf0e10cSrcweir } 2085cdf0e10cSrcweir 2086cdf0e10cSrcweir for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++) 2087cdf0e10cSrcweir { 2088*5aaf853bSArmin Le Grand bSuccess = mpGraphics->DrawPolyLine( 2089*5aaf853bSArmin Le Grand aB2DPolyPolygon.getB2DPolygon(a), 2090*5aaf853bSArmin Le Grand 0.0, 2091*5aaf853bSArmin Le Grand aB2DLineWidth, 2092*5aaf853bSArmin Le Grand basegfx::B2DLINEJOIN_NONE, 2093*5aaf853bSArmin Le Grand com::sun::star::drawing::LineCap_BUTT, 2094*5aaf853bSArmin Le Grand this); 2095cdf0e10cSrcweir } 2096cdf0e10cSrcweir } 2097cdf0e10cSrcweir 2098cdf0e10cSrcweir if(bSuccess) 2099cdf0e10cSrcweir { 2100cdf0e10cSrcweir return; 2101cdf0e10cSrcweir } 2102cdf0e10cSrcweir } 2103cdf0e10cSrcweir 2104cdf0e10cSrcweir if ( nPoly == 1 ) 2105cdf0e10cSrcweir { 2106cdf0e10cSrcweir // #100127# Map to DrawPolygon 2107cdf0e10cSrcweir Polygon aPoly = rPolyPoly.GetObject( 0 ); 2108cdf0e10cSrcweir if( aPoly.GetSize() >= 2 ) 2109cdf0e10cSrcweir { 2110cdf0e10cSrcweir GDIMetaFile* pOldMF = mpMetaFile; 2111cdf0e10cSrcweir mpMetaFile = NULL; 2112cdf0e10cSrcweir 2113cdf0e10cSrcweir DrawPolygon( aPoly ); 2114cdf0e10cSrcweir 2115cdf0e10cSrcweir mpMetaFile = pOldMF; 2116cdf0e10cSrcweir } 2117cdf0e10cSrcweir } 2118cdf0e10cSrcweir else 2119cdf0e10cSrcweir { 2120cdf0e10cSrcweir // #100127# moved real PolyPolygon draw to separate method, 2121cdf0e10cSrcweir // have to call recursively, avoiding duplicate 2122cdf0e10cSrcweir // ImplLogicToDevicePixel calls 2123cdf0e10cSrcweir ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) ); 2124cdf0e10cSrcweir } 2125cdf0e10cSrcweir if( mpAlphaVDev ) 2126cdf0e10cSrcweir mpAlphaVDev->DrawPolyPolygon( rPolyPoly ); 2127cdf0e10cSrcweir } 2128cdf0e10cSrcweir 2129cdf0e10cSrcweir // ----------------------------------------------------------------------- 2130cdf0e10cSrcweir 2131cdf0e10cSrcweir void OutputDevice::DrawPolygon( const ::basegfx::B2DPolygon& rB2DPolygon) 2132cdf0e10cSrcweir { 2133cdf0e10cSrcweir // AW: Do NOT paint empty polygons 2134cdf0e10cSrcweir if(rB2DPolygon.count()) 2135cdf0e10cSrcweir { 2136cdf0e10cSrcweir ::basegfx::B2DPolyPolygon aPP( rB2DPolygon ); 2137cdf0e10cSrcweir DrawPolyPolygon( aPP ); 2138cdf0e10cSrcweir } 2139cdf0e10cSrcweir } 2140cdf0e10cSrcweir 2141cdf0e10cSrcweir // ----------------------------------------------------------------------- 2142cdf0e10cSrcweir // Caution: This method is nearly the same as 2143cdf0e10cSrcweir // OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency), 2144cdf0e10cSrcweir // so when changes are made here do not forget to make change sthere, too 2145cdf0e10cSrcweir 2146cdf0e10cSrcweir void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly ) 2147cdf0e10cSrcweir { 2148cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawPolyPolygon(B2D&)" ); 2149cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2150cdf0e10cSrcweir 2151cdf0e10cSrcweir #if 0 2152cdf0e10cSrcweir // MetaB2DPolyPolygonAction is not implemented yet: 2153cdf0e10cSrcweir // according to AW adding it is very dangerous since there is a lot 2154cdf0e10cSrcweir // of code that uses the metafile actions directly and unless every 2155cdf0e10cSrcweir // place that does this knows about the new action we need to fallback 2156cdf0e10cSrcweir if( mpMetaFile ) 2157cdf0e10cSrcweir mpMetaFile->AddAction( new MetaB2DPolyPolygonAction( rB2DPolyPoly ) ); 2158cdf0e10cSrcweir #else 2159cdf0e10cSrcweir if( mpMetaFile ) 2160cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) ); 2161cdf0e10cSrcweir #endif 2162cdf0e10cSrcweir 2163cdf0e10cSrcweir // call helper 2164cdf0e10cSrcweir ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly); 2165cdf0e10cSrcweir } 2166cdf0e10cSrcweir 2167cdf0e10cSrcweir void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly) 2168cdf0e10cSrcweir { 2169cdf0e10cSrcweir // AW: Do NOT paint empty PolyPolygons 2170cdf0e10cSrcweir if(!rB2DPolyPoly.count()) 2171cdf0e10cSrcweir return; 2172cdf0e10cSrcweir 2173cdf0e10cSrcweir // we need a graphics 2174cdf0e10cSrcweir if( !mpGraphics ) 2175cdf0e10cSrcweir if( !ImplGetGraphics() ) 2176cdf0e10cSrcweir return; 2177cdf0e10cSrcweir 2178cdf0e10cSrcweir if( mbInitClipRegion ) 2179cdf0e10cSrcweir ImplInitClipRegion(); 2180cdf0e10cSrcweir if( mbOutputClipped ) 2181cdf0e10cSrcweir return; 2182cdf0e10cSrcweir 2183cdf0e10cSrcweir if( mbInitLineColor ) 2184cdf0e10cSrcweir ImplInitLineColor(); 2185cdf0e10cSrcweir if( mbInitFillColor ) 2186cdf0e10cSrcweir ImplInitFillColor(); 2187cdf0e10cSrcweir 2188cdf0e10cSrcweir if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 2189cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 2190cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 2191cdf0e10cSrcweir && (IsLineColor() || IsFillColor())) 2192cdf0e10cSrcweir { 2193cdf0e10cSrcweir const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); 2194cdf0e10cSrcweir basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly); 2195cdf0e10cSrcweir bool bSuccess(true); 2196cdf0e10cSrcweir 2197cdf0e10cSrcweir // transform the polygon and ensure closed 2198cdf0e10cSrcweir aB2DPolyPolygon.transform(aTransform); 2199cdf0e10cSrcweir aB2DPolyPolygon.setClosed(true); 2200cdf0e10cSrcweir 2201cdf0e10cSrcweir if(IsFillColor()) 2202cdf0e10cSrcweir { 2203cdf0e10cSrcweir bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this); 2204cdf0e10cSrcweir } 2205cdf0e10cSrcweir 2206cdf0e10cSrcweir if(bSuccess && IsLineColor()) 2207cdf0e10cSrcweir { 2208cdf0e10cSrcweir const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); 2209cdf0e10cSrcweir 2210cdf0e10cSrcweir if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 2211cdf0e10cSrcweir { 2212cdf0e10cSrcweir aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon); 2213cdf0e10cSrcweir } 2214cdf0e10cSrcweir 2215cdf0e10cSrcweir for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++) 2216cdf0e10cSrcweir { 2217*5aaf853bSArmin Le Grand bSuccess = mpGraphics->DrawPolyLine( 2218*5aaf853bSArmin Le Grand aB2DPolyPolygon.getB2DPolygon(a), 2219*5aaf853bSArmin Le Grand 0.0, 2220*5aaf853bSArmin Le Grand aB2DLineWidth, 2221*5aaf853bSArmin Le Grand basegfx::B2DLINEJOIN_NONE, 2222*5aaf853bSArmin Le Grand com::sun::star::drawing::LineCap_BUTT, 2223*5aaf853bSArmin Le Grand this); 2224cdf0e10cSrcweir } 2225cdf0e10cSrcweir } 2226cdf0e10cSrcweir 2227cdf0e10cSrcweir if(bSuccess) 2228cdf0e10cSrcweir { 2229cdf0e10cSrcweir return; 2230cdf0e10cSrcweir } 2231cdf0e10cSrcweir } 2232cdf0e10cSrcweir 2233cdf0e10cSrcweir // fallback to old polygon drawing if needed 2234cdf0e10cSrcweir const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly ); 2235cdf0e10cSrcweir const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon ); 2236cdf0e10cSrcweir ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon ); 2237cdf0e10cSrcweir } 2238cdf0e10cSrcweir 2239cdf0e10cSrcweir // ----------------------------------------------------------------------- 2240cdf0e10cSrcweir 2241cdf0e10cSrcweir bool OutputDevice::ImpTryDrawPolyLineDirect( 2242cdf0e10cSrcweir const basegfx::B2DPolygon& rB2DPolygon, 2243cdf0e10cSrcweir double fLineWidth, 2244*5aaf853bSArmin Le Grand basegfx::B2DLineJoin eLineJoin, 2245*5aaf853bSArmin Le Grand com::sun::star::drawing::LineCap eLineCap) 2246cdf0e10cSrcweir { 2247cdf0e10cSrcweir const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); 2248cdf0e10cSrcweir basegfx::B2DVector aB2DLineWidth(1.0, 1.0); 2249cdf0e10cSrcweir 2250cdf0e10cSrcweir // transform the line width if used 2251cdf0e10cSrcweir if( fLineWidth != 0.0 ) 2252cdf0e10cSrcweir { 2253cdf0e10cSrcweir aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth ); 2254cdf0e10cSrcweir } 2255cdf0e10cSrcweir 2256cdf0e10cSrcweir // transform the polygon 2257cdf0e10cSrcweir basegfx::B2DPolygon aB2DPolygon(rB2DPolygon); 2258cdf0e10cSrcweir aB2DPolygon.transform(aTransform); 2259cdf0e10cSrcweir 2260cdf0e10cSrcweir if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) 2261cdf0e10cSrcweir && aB2DPolygon.count() < 1000) 2262cdf0e10cSrcweir { 2263cdf0e10cSrcweir // #i98289#, #i101491# 2264cdf0e10cSrcweir // better to remove doubles on device coordinates. Also assume from a given amount 2265cdf0e10cSrcweir // of points that the single edges are not long enough to smooth 2266cdf0e10cSrcweir aB2DPolygon.removeDoublePoints(); 2267cdf0e10cSrcweir aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); 2268cdf0e10cSrcweir } 2269cdf0e10cSrcweir 2270cdf0e10cSrcweir // draw the polyline 2271*5aaf853bSArmin Le Grand return mpGraphics->DrawPolyLine( 2272*5aaf853bSArmin Le Grand aB2DPolygon, 2273*5aaf853bSArmin Le Grand 0.0, 2274*5aaf853bSArmin Le Grand aB2DLineWidth, 2275*5aaf853bSArmin Le Grand eLineJoin, 2276*5aaf853bSArmin Le Grand eLineCap, 2277*5aaf853bSArmin Le Grand this); 2278cdf0e10cSrcweir } 2279cdf0e10cSrcweir 2280cdf0e10cSrcweir void OutputDevice::DrawPolyLine( 2281cdf0e10cSrcweir const basegfx::B2DPolygon& rB2DPolygon, 2282cdf0e10cSrcweir double fLineWidth, 2283*5aaf853bSArmin Le Grand basegfx::B2DLineJoin eLineJoin, 2284*5aaf853bSArmin Le Grand com::sun::star::drawing::LineCap eLineCap) 2285cdf0e10cSrcweir { 2286cdf0e10cSrcweir DBG_TRACE( "OutputDevice::DrawPolyLine(B2D&)" ); 2287cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2288cdf0e10cSrcweir (void)eLineJoin; // ATM used in UNX, but not in WNT, access it for warning-free 2289*5aaf853bSArmin Le Grand (void)eLineCap; 2290cdf0e10cSrcweir 2291cdf0e10cSrcweir #if 0 // MetaB2DPolyLineAction is not implemented yet: 2292cdf0e10cSrcweir // according to AW adding it is very dangerous since there is a lot 2293cdf0e10cSrcweir // of code that uses the metafile actions directly and unless every 2294cdf0e10cSrcweir // place that does this knows about the new action we need to fallback 2295cdf0e10cSrcweir if( mpMetaFile ) 2296cdf0e10cSrcweir mpMetaFile->AddAction( new MetaB2DPolyLineAction( rB2DPolygon ) ); 2297cdf0e10cSrcweir #else 2298cdf0e10cSrcweir if( mpMetaFile ) 2299cdf0e10cSrcweir { 2300cdf0e10cSrcweir LineInfo aLineInfo; 2301cdf0e10cSrcweir if( fLineWidth != 0.0 ) 2302cdf0e10cSrcweir aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); 2303cdf0e10cSrcweir const Polygon aToolsPolygon( rB2DPolygon ); 2304cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) ); 2305cdf0e10cSrcweir } 2306cdf0e10cSrcweir #endif 2307cdf0e10cSrcweir 2308cdf0e10cSrcweir // AW: Do NOT paint empty PolyPolygons 2309cdf0e10cSrcweir if(!rB2DPolygon.count()) 2310cdf0e10cSrcweir return; 2311cdf0e10cSrcweir 2312cdf0e10cSrcweir // we need a graphics 2313cdf0e10cSrcweir if( !mpGraphics ) 2314cdf0e10cSrcweir if( !ImplGetGraphics() ) 2315cdf0e10cSrcweir return; 2316cdf0e10cSrcweir 2317cdf0e10cSrcweir if( mbInitClipRegion ) 2318cdf0e10cSrcweir ImplInitClipRegion(); 2319cdf0e10cSrcweir if( mbOutputClipped ) 2320cdf0e10cSrcweir return; 2321cdf0e10cSrcweir 2322cdf0e10cSrcweir if( mbInitLineColor ) 2323cdf0e10cSrcweir ImplInitLineColor(); 2324cdf0e10cSrcweir 2325cdf0e10cSrcweir const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) 2326cdf0e10cSrcweir && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) 2327cdf0e10cSrcweir && ROP_OVERPAINT == GetRasterOp() 2328cdf0e10cSrcweir && IsLineColor()); 2329cdf0e10cSrcweir 2330cdf0e10cSrcweir // use b2dpolygon drawing if possible 2331*5aaf853bSArmin Le Grand if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, eLineJoin, eLineCap)) 2332cdf0e10cSrcweir { 2333cdf0e10cSrcweir return; 2334cdf0e10cSrcweir } 2335cdf0e10cSrcweir 2336cdf0e10cSrcweir // #i101491# 2337cdf0e10cSrcweir // no output yet; fallback to geometry decomposition and use filled polygon paint 2338cdf0e10cSrcweir // when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon 2339cdf0e10cSrcweir // will do internal needed AA checks etc. 2340cdf0e10cSrcweir if(fLineWidth >= 2.5 2341cdf0e10cSrcweir && rB2DPolygon.count() 2342cdf0e10cSrcweir && rB2DPolygon.count() <= 1000) 2343cdf0e10cSrcweir { 2344cdf0e10cSrcweir const double fHalfLineWidth((fLineWidth * 0.5) + 0.5); 2345*5aaf853bSArmin Le Grand const basegfx::B2DPolyPolygon aAreaPolyPolygon( 2346*5aaf853bSArmin Le Grand basegfx::tools::createAreaGeometry( 2347*5aaf853bSArmin Le Grand rB2DPolygon, 2348*5aaf853bSArmin Le Grand fHalfLineWidth, 2349*5aaf853bSArmin Le Grand eLineJoin, 2350*5aaf853bSArmin Le Grand eLineCap)); 2351cdf0e10cSrcweir const Color aOldLineColor(maLineColor); 2352cdf0e10cSrcweir const Color aOldFillColor(maFillColor); 2353cdf0e10cSrcweir 2354cdf0e10cSrcweir SetLineColor(); 2355cdf0e10cSrcweir ImplInitLineColor(); 2356cdf0e10cSrcweir SetFillColor(aOldLineColor); 2357cdf0e10cSrcweir ImplInitFillColor(); 2358cdf0e10cSrcweir 2359cdf0e10cSrcweir // draw usig a loop; else the topology will paint a PolyPolygon 2360cdf0e10cSrcweir for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) 2361cdf0e10cSrcweir { 2362cdf0e10cSrcweir ImpDrawPolyPolygonWithB2DPolyPolygon( 2363cdf0e10cSrcweir basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a))); 2364cdf0e10cSrcweir } 2365cdf0e10cSrcweir 2366cdf0e10cSrcweir SetLineColor(aOldLineColor); 2367cdf0e10cSrcweir ImplInitLineColor(); 2368cdf0e10cSrcweir SetFillColor(aOldFillColor); 2369cdf0e10cSrcweir ImplInitFillColor(); 2370cdf0e10cSrcweir 2371cdf0e10cSrcweir if(bTryAA) 2372cdf0e10cSrcweir { 2373cdf0e10cSrcweir // when AA it is necessary to also paint the filled polygon's outline 2374cdf0e10cSrcweir // to avoid optical gaps 2375cdf0e10cSrcweir for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) 2376cdf0e10cSrcweir { 2377*5aaf853bSArmin Le Grand ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a)); 2378cdf0e10cSrcweir } 2379cdf0e10cSrcweir } 2380cdf0e10cSrcweir } 2381cdf0e10cSrcweir else 2382cdf0e10cSrcweir { 2383cdf0e10cSrcweir // fallback to old polygon drawing if needed 2384cdf0e10cSrcweir const Polygon aToolsPolygon( rB2DPolygon ); 2385cdf0e10cSrcweir LineInfo aLineInfo; 2386cdf0e10cSrcweir if( fLineWidth != 0.0 ) 2387cdf0e10cSrcweir aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); 2388cdf0e10cSrcweir ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo ); 2389cdf0e10cSrcweir } 2390cdf0e10cSrcweir } 2391cdf0e10cSrcweir 2392cdf0e10cSrcweir // ----------------------------------------------------------------------- 2393cdf0e10cSrcweir 2394cdf0e10cSrcweir sal_uInt32 OutputDevice::GetGCStackDepth() const 2395cdf0e10cSrcweir { 2396cdf0e10cSrcweir const ImplObjStack* pData = mpObjStack; 2397cdf0e10cSrcweir sal_uInt32 nDepth = 0; 2398cdf0e10cSrcweir while( pData ) 2399cdf0e10cSrcweir { 2400cdf0e10cSrcweir nDepth++; 2401cdf0e10cSrcweir pData = pData->mpPrev; 2402cdf0e10cSrcweir } 2403cdf0e10cSrcweir return nDepth; 2404cdf0e10cSrcweir } 2405cdf0e10cSrcweir 2406cdf0e10cSrcweir // ----------------------------------------------------------------------- 2407cdf0e10cSrcweir 2408cdf0e10cSrcweir void OutputDevice::Push( sal_uInt16 nFlags ) 2409cdf0e10cSrcweir { 2410cdf0e10cSrcweir DBG_TRACE( "OutputDevice::Push()" ); 2411cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2412cdf0e10cSrcweir 2413cdf0e10cSrcweir if ( mpMetaFile ) 2414cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPushAction( nFlags ) ); 2415cdf0e10cSrcweir 2416cdf0e10cSrcweir ImplObjStack* pData = new ImplObjStack; 2417cdf0e10cSrcweir pData->mpPrev = mpObjStack; 2418cdf0e10cSrcweir mpObjStack = pData; 2419cdf0e10cSrcweir 2420cdf0e10cSrcweir pData->mnFlags = nFlags; 2421cdf0e10cSrcweir 2422cdf0e10cSrcweir if ( nFlags & PUSH_LINECOLOR ) 2423cdf0e10cSrcweir { 2424cdf0e10cSrcweir if ( mbLineColor ) 2425cdf0e10cSrcweir pData->mpLineColor = new Color( maLineColor ); 2426cdf0e10cSrcweir else 2427cdf0e10cSrcweir pData->mpLineColor = NULL; 2428cdf0e10cSrcweir } 2429cdf0e10cSrcweir if ( nFlags & PUSH_FILLCOLOR ) 2430cdf0e10cSrcweir { 2431cdf0e10cSrcweir if ( mbFillColor ) 2432cdf0e10cSrcweir pData->mpFillColor = new Color( maFillColor ); 2433cdf0e10cSrcweir else 2434cdf0e10cSrcweir pData->mpFillColor = NULL; 2435cdf0e10cSrcweir } 2436cdf0e10cSrcweir if ( nFlags & PUSH_FONT ) 2437cdf0e10cSrcweir pData->mpFont = new Font( maFont ); 2438cdf0e10cSrcweir if ( nFlags & PUSH_TEXTCOLOR ) 2439cdf0e10cSrcweir pData->mpTextColor = new Color( GetTextColor() ); 2440cdf0e10cSrcweir if ( nFlags & PUSH_TEXTFILLCOLOR ) 2441cdf0e10cSrcweir { 2442cdf0e10cSrcweir if ( IsTextFillColor() ) 2443cdf0e10cSrcweir pData->mpTextFillColor = new Color( GetTextFillColor() ); 2444cdf0e10cSrcweir else 2445cdf0e10cSrcweir pData->mpTextFillColor = NULL; 2446cdf0e10cSrcweir } 2447cdf0e10cSrcweir if ( nFlags & PUSH_TEXTLINECOLOR ) 2448cdf0e10cSrcweir { 2449cdf0e10cSrcweir if ( IsTextLineColor() ) 2450cdf0e10cSrcweir pData->mpTextLineColor = new Color( GetTextLineColor() ); 2451cdf0e10cSrcweir else 2452cdf0e10cSrcweir pData->mpTextLineColor = NULL; 2453cdf0e10cSrcweir } 2454cdf0e10cSrcweir if ( nFlags & PUSH_OVERLINECOLOR ) 2455cdf0e10cSrcweir { 2456cdf0e10cSrcweir if ( IsOverlineColor() ) 2457cdf0e10cSrcweir pData->mpOverlineColor = new Color( GetOverlineColor() ); 2458cdf0e10cSrcweir else 2459cdf0e10cSrcweir pData->mpOverlineColor = NULL; 2460cdf0e10cSrcweir } 2461cdf0e10cSrcweir if ( nFlags & PUSH_TEXTALIGN ) 2462cdf0e10cSrcweir pData->meTextAlign = GetTextAlign(); 2463cdf0e10cSrcweir if( nFlags & PUSH_TEXTLAYOUTMODE ) 2464cdf0e10cSrcweir pData->mnTextLayoutMode = GetLayoutMode(); 2465cdf0e10cSrcweir if( nFlags & PUSH_TEXTLANGUAGE ) 2466cdf0e10cSrcweir pData->meTextLanguage = GetDigitLanguage(); 2467cdf0e10cSrcweir if ( nFlags & PUSH_RASTEROP ) 2468cdf0e10cSrcweir pData->meRasterOp = GetRasterOp(); 2469cdf0e10cSrcweir if ( nFlags & PUSH_MAPMODE ) 2470cdf0e10cSrcweir { 2471cdf0e10cSrcweir if ( mbMap ) 2472cdf0e10cSrcweir pData->mpMapMode = new MapMode( maMapMode ); 2473cdf0e10cSrcweir else 2474cdf0e10cSrcweir pData->mpMapMode = NULL; 2475cdf0e10cSrcweir } 2476cdf0e10cSrcweir if ( nFlags & PUSH_CLIPREGION ) 2477cdf0e10cSrcweir { 2478cdf0e10cSrcweir if ( mbClipRegion ) 2479cdf0e10cSrcweir pData->mpClipRegion = new Region( maRegion ); 2480cdf0e10cSrcweir else 2481cdf0e10cSrcweir pData->mpClipRegion = NULL; 2482cdf0e10cSrcweir } 2483cdf0e10cSrcweir if ( nFlags & PUSH_REFPOINT ) 2484cdf0e10cSrcweir { 2485cdf0e10cSrcweir if ( mbRefPoint ) 2486cdf0e10cSrcweir pData->mpRefPoint = new Point( maRefPoint ); 2487cdf0e10cSrcweir else 2488cdf0e10cSrcweir pData->mpRefPoint = NULL; 2489cdf0e10cSrcweir } 2490cdf0e10cSrcweir 2491cdf0e10cSrcweir if( mpAlphaVDev ) 2492cdf0e10cSrcweir mpAlphaVDev->Push(); 2493cdf0e10cSrcweir } 2494cdf0e10cSrcweir 2495cdf0e10cSrcweir // ----------------------------------------------------------------------- 2496cdf0e10cSrcweir 2497cdf0e10cSrcweir void OutputDevice::Pop() 2498cdf0e10cSrcweir { 2499cdf0e10cSrcweir DBG_TRACE( "OutputDevice::Pop()" ); 2500cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2501cdf0e10cSrcweir 2502cdf0e10cSrcweir if( mpMetaFile ) 2503cdf0e10cSrcweir mpMetaFile->AddAction( new MetaPopAction() ); 2504cdf0e10cSrcweir 2505cdf0e10cSrcweir GDIMetaFile* pOldMetaFile = mpMetaFile; 2506cdf0e10cSrcweir ImplObjStack* pData = mpObjStack; 2507cdf0e10cSrcweir mpMetaFile = NULL; 2508cdf0e10cSrcweir 2509cdf0e10cSrcweir if ( !pData ) 2510cdf0e10cSrcweir { 2511cdf0e10cSrcweir DBG_ERRORFILE( "OutputDevice::Pop() without OutputDevice::Push()" ); 2512cdf0e10cSrcweir return; 2513cdf0e10cSrcweir } 2514cdf0e10cSrcweir 2515cdf0e10cSrcweir if( mpAlphaVDev ) 2516cdf0e10cSrcweir mpAlphaVDev->Pop(); 2517cdf0e10cSrcweir 2518cdf0e10cSrcweir mpObjStack = pData->mpPrev; 2519cdf0e10cSrcweir 2520cdf0e10cSrcweir if ( pData->mnFlags & PUSH_LINECOLOR ) 2521cdf0e10cSrcweir { 2522cdf0e10cSrcweir if ( pData->mpLineColor ) 2523cdf0e10cSrcweir SetLineColor( *pData->mpLineColor ); 2524cdf0e10cSrcweir else 2525cdf0e10cSrcweir SetLineColor(); 2526cdf0e10cSrcweir } 2527cdf0e10cSrcweir if ( pData->mnFlags & PUSH_FILLCOLOR ) 2528cdf0e10cSrcweir { 2529cdf0e10cSrcweir if ( pData->mpFillColor ) 2530cdf0e10cSrcweir SetFillColor( *pData->mpFillColor ); 2531cdf0e10cSrcweir else 2532cdf0e10cSrcweir SetFillColor(); 2533cdf0e10cSrcweir } 2534cdf0e10cSrcweir if ( pData->mnFlags & PUSH_FONT ) 2535cdf0e10cSrcweir SetFont( *pData->mpFont ); 2536cdf0e10cSrcweir if ( pData->mnFlags & PUSH_TEXTCOLOR ) 2537cdf0e10cSrcweir SetTextColor( *pData->mpTextColor ); 2538cdf0e10cSrcweir if ( pData->mnFlags & PUSH_TEXTFILLCOLOR ) 2539cdf0e10cSrcweir { 2540cdf0e10cSrcweir if ( pData->mpTextFillColor ) 2541cdf0e10cSrcweir SetTextFillColor( *pData->mpTextFillColor ); 2542cdf0e10cSrcweir else 2543cdf0e10cSrcweir SetTextFillColor(); 2544cdf0e10cSrcweir } 2545cdf0e10cSrcweir if ( pData->mnFlags & PUSH_TEXTLINECOLOR ) 2546cdf0e10cSrcweir { 2547cdf0e10cSrcweir if ( pData->mpTextLineColor ) 2548cdf0e10cSrcweir SetTextLineColor( *pData->mpTextLineColor ); 2549cdf0e10cSrcweir else 2550cdf0e10cSrcweir SetTextLineColor(); 2551cdf0e10cSrcweir } 2552cdf0e10cSrcweir if ( pData->mnFlags & PUSH_OVERLINECOLOR ) 2553cdf0e10cSrcweir { 2554cdf0e10cSrcweir if ( pData->mpOverlineColor ) 2555cdf0e10cSrcweir SetOverlineColor( *pData->mpOverlineColor ); 2556cdf0e10cSrcweir else 2557cdf0e10cSrcweir SetOverlineColor(); 2558cdf0e10cSrcweir } 2559cdf0e10cSrcweir if ( pData->mnFlags & PUSH_TEXTALIGN ) 2560cdf0e10cSrcweir SetTextAlign( pData->meTextAlign ); 2561cdf0e10cSrcweir if( pData->mnFlags & PUSH_TEXTLAYOUTMODE ) 2562cdf0e10cSrcweir SetLayoutMode( pData->mnTextLayoutMode ); 2563cdf0e10cSrcweir if( pData->mnFlags & PUSH_TEXTLANGUAGE ) 2564cdf0e10cSrcweir SetDigitLanguage( pData->meTextLanguage ); 2565cdf0e10cSrcweir if ( pData->mnFlags & PUSH_RASTEROP ) 2566cdf0e10cSrcweir SetRasterOp( pData->meRasterOp ); 2567cdf0e10cSrcweir if ( pData->mnFlags & PUSH_MAPMODE ) 2568cdf0e10cSrcweir { 2569cdf0e10cSrcweir if ( pData->mpMapMode ) 2570cdf0e10cSrcweir SetMapMode( *pData->mpMapMode ); 2571cdf0e10cSrcweir else 2572cdf0e10cSrcweir SetMapMode(); 2573cdf0e10cSrcweir } 2574cdf0e10cSrcweir if ( pData->mnFlags & PUSH_CLIPREGION ) 2575cdf0e10cSrcweir ImplSetClipRegion( pData->mpClipRegion ); 2576cdf0e10cSrcweir if ( pData->mnFlags & PUSH_REFPOINT ) 2577cdf0e10cSrcweir { 2578cdf0e10cSrcweir if ( pData->mpRefPoint ) 2579cdf0e10cSrcweir SetRefPoint( *pData->mpRefPoint ); 2580cdf0e10cSrcweir else 2581cdf0e10cSrcweir SetRefPoint(); 2582cdf0e10cSrcweir } 2583cdf0e10cSrcweir 2584cdf0e10cSrcweir ImplDeleteObjStack( pData ); 2585cdf0e10cSrcweir 2586cdf0e10cSrcweir mpMetaFile = pOldMetaFile; 2587cdf0e10cSrcweir } 2588cdf0e10cSrcweir 2589cdf0e10cSrcweir // ----------------------------------------------------------------------- 2590cdf0e10cSrcweir 2591cdf0e10cSrcweir void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf ) 2592cdf0e10cSrcweir { 2593cdf0e10cSrcweir mpMetaFile = pMtf; 2594cdf0e10cSrcweir } 2595cdf0e10cSrcweir 2596cdf0e10cSrcweir // ----------------------------------------------------------------------- 2597cdf0e10cSrcweir 2598cdf0e10cSrcweir void OutputDevice::EnableOutput( sal_Bool bEnable ) 2599cdf0e10cSrcweir { 2600cdf0e10cSrcweir mbOutput = (bEnable != 0); 2601cdf0e10cSrcweir 2602cdf0e10cSrcweir if( mpAlphaVDev ) 2603cdf0e10cSrcweir mpAlphaVDev->EnableOutput( bEnable ); 2604cdf0e10cSrcweir } 2605cdf0e10cSrcweir 2606cdf0e10cSrcweir // ----------------------------------------------------------------------- 2607cdf0e10cSrcweir 2608cdf0e10cSrcweir void OutputDevice::SetSettings( const AllSettings& rSettings ) 2609cdf0e10cSrcweir { 2610cdf0e10cSrcweir maSettings = rSettings; 2611cdf0e10cSrcweir 2612cdf0e10cSrcweir if( mpAlphaVDev ) 2613cdf0e10cSrcweir mpAlphaVDev->SetSettings( rSettings ); 2614cdf0e10cSrcweir } 2615cdf0e10cSrcweir 2616cdf0e10cSrcweir // ----------------------------------------------------------------------- 2617cdf0e10cSrcweir 2618cdf0e10cSrcweir sal_uInt16 OutputDevice::GetBitCount() const 2619cdf0e10cSrcweir { 2620cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2621cdf0e10cSrcweir 2622cdf0e10cSrcweir if ( meOutDevType == OUTDEV_VIRDEV ) 2623cdf0e10cSrcweir return ((VirtualDevice*)this)->mnBitCount; 2624cdf0e10cSrcweir 2625cdf0e10cSrcweir // we need a graphics 2626cdf0e10cSrcweir if ( !mpGraphics ) 2627cdf0e10cSrcweir { 2628cdf0e10cSrcweir if ( !((OutputDevice*)this)->ImplGetGraphics() ) 2629cdf0e10cSrcweir return 0; 2630cdf0e10cSrcweir } 2631cdf0e10cSrcweir 2632cdf0e10cSrcweir return (sal_uInt16)mpGraphics->GetBitCount(); 2633cdf0e10cSrcweir } 2634cdf0e10cSrcweir 2635cdf0e10cSrcweir // ----------------------------------------------------------------------- 2636cdf0e10cSrcweir 2637cdf0e10cSrcweir sal_uInt16 OutputDevice::GetAlphaBitCount() const 2638cdf0e10cSrcweir { 2639cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2640cdf0e10cSrcweir 2641cdf0e10cSrcweir if ( meOutDevType == OUTDEV_VIRDEV && 2642cdf0e10cSrcweir mpAlphaVDev != NULL ) 2643cdf0e10cSrcweir { 2644cdf0e10cSrcweir return mpAlphaVDev->GetBitCount(); 2645cdf0e10cSrcweir } 2646cdf0e10cSrcweir 2647cdf0e10cSrcweir return 0; 2648cdf0e10cSrcweir } 2649cdf0e10cSrcweir 2650cdf0e10cSrcweir // ----------------------------------------------------------------------- 2651cdf0e10cSrcweir 2652cdf0e10cSrcweir sal_uLong OutputDevice::GetColorCount() const 2653cdf0e10cSrcweir { 2654cdf0e10cSrcweir DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); 2655cdf0e10cSrcweir 2656cdf0e10cSrcweir const sal_uInt16 nBitCount = GetBitCount(); 2657cdf0e10cSrcweir return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) ); 2658cdf0e10cSrcweir } 2659cdf0e10cSrcweir 2660cdf0e10cSrcweir // ----------------------------------------------------------------------- 2661cdf0e10cSrcweir 2662cdf0e10cSrcweir sal_Bool OutputDevice::HasAlpha() 2663cdf0e10cSrcweir { 2664cdf0e10cSrcweir return mpAlphaVDev != NULL; 2665cdf0e10cSrcweir } 2666cdf0e10cSrcweir 2667cdf0e10cSrcweir // ----------------------------------------------------------------------- 2668cdf0e10cSrcweir 2669cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > OutputDevice::CreateUnoGraphics() 2670cdf0e10cSrcweir { 2671cdf0e10cSrcweir UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); 2672cdf0e10cSrcweir return pWrapper ? pWrapper->CreateGraphics( this ) : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >(); 2673cdf0e10cSrcweir } 2674cdf0e10cSrcweir 2675cdf0e10cSrcweir // ----------------------------------------------------------------------- 2676cdf0e10cSrcweir 2677cdf0e10cSrcweir SystemGraphicsData OutputDevice::GetSystemGfxData() const 2678cdf0e10cSrcweir { 2679cdf0e10cSrcweir if ( !mpGraphics ) 2680cdf0e10cSrcweir { 2681cdf0e10cSrcweir if ( !ImplGetGraphics() ) 2682cdf0e10cSrcweir return SystemGraphicsData(); 2683cdf0e10cSrcweir } 2684cdf0e10cSrcweir 2685cdf0e10cSrcweir return mpGraphics->GetGraphicsData(); 2686cdf0e10cSrcweir } 2687cdf0e10cSrcweir 2688cdf0e10cSrcweir // ----------------------------------------------------------------------- 2689cdf0e10cSrcweir 2690cdf0e10cSrcweir ::com::sun::star::uno::Any OutputDevice::GetSystemGfxDataAny() const 2691cdf0e10cSrcweir { 2692cdf0e10cSrcweir ::com::sun::star::uno::Any aRet; 2693cdf0e10cSrcweir const SystemGraphicsData aSysData = GetSystemGfxData(); 2694cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData, 2695cdf0e10cSrcweir aSysData.nSize ); 2696cdf0e10cSrcweir 2697cdf0e10cSrcweir return uno::makeAny(aSeq); 2698cdf0e10cSrcweir } 2699cdf0e10cSrcweir 2700cdf0e10cSrcweir // ----------------------------------------------------------------------- 2701cdf0e10cSrcweir 2702cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > OutputDevice::GetCanvas() const 2703cdf0e10cSrcweir { 2704cdf0e10cSrcweir uno::Sequence< uno::Any > aArg(6); 2705cdf0e10cSrcweir 2706cdf0e10cSrcweir aArg[ 0 ] = uno::makeAny( reinterpret_cast<sal_Int64>(this) ); 2707cdf0e10cSrcweir aArg[ 2 ] = uno::makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) ); 2708cdf0e10cSrcweir aArg[ 3 ] = uno::makeAny( sal_False ); 2709cdf0e10cSrcweir aArg[ 5 ] = GetSystemGfxDataAny(); 2710cdf0e10cSrcweir 2711cdf0e10cSrcweir uno::Reference<lang::XMultiServiceFactory> xFactory = vcl::unohelper::GetMultiServiceFactory(); 2712cdf0e10cSrcweir 2713cdf0e10cSrcweir uno::Reference<rendering::XCanvas> xCanvas; 2714cdf0e10cSrcweir 2715cdf0e10cSrcweir // Create canvas instance with window handle 2716cdf0e10cSrcweir // ========================================= 2717cdf0e10cSrcweir if ( xFactory.is() ) 2718cdf0e10cSrcweir { 2719cdf0e10cSrcweir static uno::Reference<lang::XMultiServiceFactory> xCanvasFactory( 2720cdf0e10cSrcweir xFactory->createInstance( 2721cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( 2722cdf0e10cSrcweir "com.sun.star." 2723cdf0e10cSrcweir "rendering.CanvasFactory") ) ), 2724cdf0e10cSrcweir uno::UNO_QUERY ); 2725cdf0e10cSrcweir if(xCanvasFactory.is()) 2726cdf0e10cSrcweir { 2727cdf0e10cSrcweir xCanvas.set( 2728cdf0e10cSrcweir xCanvasFactory->createInstanceWithArguments( 2729cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( 2730cdf0e10cSrcweir "com.sun.star.rendering.Canvas" )), 2731cdf0e10cSrcweir aArg ), 2732cdf0e10cSrcweir uno::UNO_QUERY ); 2733cdf0e10cSrcweir } 2734cdf0e10cSrcweir } 2735cdf0e10cSrcweir 2736cdf0e10cSrcweir return xCanvas; 2737cdf0e10cSrcweir } 2738cdf0e10cSrcweir 2739cdf0e10cSrcweir // ----------------------------------------------------------------------- 2740