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