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