update emoji autocorrect entries from po-files
[LibreOffice.git] / vcl / source / outdev / outdev.cxx
blob1c295599af19faf4601df2375cb8bff69ce8271a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
21 #include <tools/poly.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/ctrl.hxx>
25 #include <vcl/region.hxx>
26 #include <vcl/virdev.hxx>
27 #include <vcl/window.hxx>
28 #include <vcl/metaact.hxx>
29 #include <vcl/gdimtf.hxx>
30 #include <vcl/print.hxx>
31 #include <vcl/outdev.hxx>
32 #include <vcl/unowrap.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/sysdata.hxx>
36 #include <vcl/outdevstate.hxx>
38 #include <salgdi.hxx>
39 #include <sallayout.hxx>
40 #include <salframe.hxx>
41 #include <salvd.hxx>
42 #include <salprn.hxx>
43 #include <svdata.hxx>
44 #include <window.h>
45 #include <outdev.h>
46 #include <outdata.hxx>
47 #include <outdevstatestack.hxx>
49 #include "PhysicalFontCollection.hxx"
51 #include <basegfx/point/b2dpoint.hxx>
52 #include <basegfx/vector/b2dvector.hxx>
53 #include <basegfx/polygon/b2dpolygon.hxx>
54 #include <basegfx/polygon/b2dpolypolygon.hxx>
55 #include <basegfx/matrix/b2dhommatrix.hxx>
56 #include <basegfx/polygon/b2dpolygontools.hxx>
57 #include <basegfx/polygon/b2dpolypolygontools.hxx>
58 #include <basegfx/polygon/b2dlinegeometry.hxx>
60 #include <com/sun/star/awt/XGraphics.hpp>
61 #include <com/sun/star/uno/Sequence.hxx>
62 #include <com/sun/star/rendering/XCanvas.hpp>
63 #include <com/sun/star/rendering/CanvasFactory.hpp>
64 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
65 #include <comphelper/processfactory.hxx>
67 #include <config_cairo_canvas.h>
69 #include <numeric>
70 #include <stack>
72 #ifdef DISABLE_DYNLOADING
73 // Linking all needed LO code into one .so/executable, these already
74 // exist in the tools library, so put them in the anonymous namespace
75 // here to avoid clash...
76 namespace {
77 #endif
78 #ifdef DISABLE_DYNLOADING
80 #endif
82 // Begin initializer and accessor public functions
84 OutputDevice::OutputDevice() :
85 mnRefCnt(1), // cf. VclPtrInstance and README.lifecycle
86 maRegion(true),
87 maFillColor( COL_WHITE ),
88 maTextLineColor( COL_TRANSPARENT ),
89 mxSettings( new AllSettings(Application::GetSettings()) )
91 mpGraphics = NULL;
92 mpUnoGraphicsList = NULL;
93 mpPrevGraphics = NULL;
94 mpNextGraphics = NULL;
95 mpMetaFile = NULL;
96 mpFontEntry = NULL;
97 mpFontCache = NULL;
98 mpFontCollection = NULL;
99 mpGetDevFontList = NULL;
100 mpGetDevSizeList = NULL;
101 mpOutDevStateStack = new OutDevStateStack;
102 mpPDFWriter = NULL;
103 mpAlphaVDev = NULL;
104 mpExtOutDevData = NULL;
105 mnOutOffX = 0;
106 mnOutOffY = 0;
107 mnOutWidth = 0;
108 mnOutHeight = 0;
109 mnDPIX = 0;
110 mnDPIY = 0;
111 mnDPIScaleFactor = 1;
112 mnTextOffX = 0;
113 mnTextOffY = 0;
114 mnOutOffOrigX = 0;
115 mnOutOffLogicX = 0;
116 mnOutOffOrigY = 0;
117 mnOutOffLogicY = 0;
118 mnEmphasisAscent = 0;
119 mnEmphasisDescent = 0;
120 mnDrawMode = DrawModeFlags::Default;
121 mnTextLayoutMode = TEXT_LAYOUT_DEFAULT;
123 if( AllSettings::GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
124 mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
126 meOutDevType = OUTDEV_DONTKNOW;
127 meOutDevViewType = OUTDEV_VIEWTYPE_DONTKNOW;
128 mbMap = false;
129 mbMapIsDefault = true;
130 mbClipRegion = false;
131 mbBackground = false;
132 mbOutput = true;
133 mbDevOutput = false;
134 mbOutputClipped = false;
135 maTextColor = Color( COL_BLACK );
136 maOverlineColor = Color( COL_TRANSPARENT );
137 meTextAlign = maFont.GetAlign();
138 meRasterOp = ROP_OVERPAINT;
139 mnAntialiasing = AntialiasingFlags::NONE;
140 meTextLanguage = 0; // TODO: get default from configuration?
141 mbLineColor = true;
142 mbFillColor = true;
143 mbInitLineColor = true;
144 mbInitFillColor = true;
145 mbInitFont = true;
146 mbInitTextColor = true;
147 mbInitClipRegion = true;
148 mbClipRegionSet = false;
149 mbKerning = false;
150 mbNewFont = true;
151 mbTextLines = false;
152 mbTextBackground = false;
153 mbTextSpecial = false;
154 mbRefPoint = false;
155 mbEnableRTL = false; // mirroring must be explicitly allowed (typically for windows only)
157 // struct ImplMapRes
158 maMapRes.mnMapOfsX = 0;
159 maMapRes.mnMapOfsY = 0;
160 maMapRes.mnMapScNumX = 1;
161 maMapRes.mnMapScNumY = 1;
162 maMapRes.mnMapScDenomX = 1;
163 maMapRes.mnMapScDenomY = 1;
164 maMapRes.mfOffsetX = 0.0;
165 maMapRes.mfOffsetY = 0.0;
166 maMapRes.mfScaleX = 1.0;
167 maMapRes.mfScaleY = 1.0;
168 // struct ImplThresholdRes
169 maThresRes.mnThresLogToPixX = 0;
170 maThresRes.mnThresLogToPixY = 0;
171 maThresRes.mnThresPixToLogX = 0;
172 maThresRes.mnThresPixToLogY = 0;
174 // struct ImplOutDevData- see #i82615#
175 mpOutDevData = new ImplOutDevData;
176 mpOutDevData->mpRotateDev = NULL;
177 mpOutDevData->mpRecordLayout = NULL;
179 // #i75163#
180 mpOutDevData->mpViewTransform = NULL;
181 mpOutDevData->mpInverseViewTransform = NULL;
183 mbDisposed = false;
186 OutputDevice::~OutputDevice()
188 disposeOnce();
191 void OutputDevice::disposeOnce()
193 if ( mbDisposed )
194 return;
195 mbDisposed = true;
197 // catch badness where our OutputDevice sub-class was not
198 // wrapped safely in a VclPtr cosily.
199 // FIXME: as/when we make our destructors all protected,
200 // we should introduce this assert:
201 // assert( mnRefCnt > 0 );
203 dispose();
206 void OutputDevice::dispose()
208 if ( GetUnoGraphicsList() )
210 UnoWrapperBase* pWrapper = Application::GetUnoWrapper( false );
211 if ( pWrapper )
212 pWrapper->ReleaseAllGraphics( this );
213 delete mpUnoGraphicsList;
214 mpUnoGraphicsList = NULL;
217 mpOutDevData->mpRotateDev.disposeAndClear();
219 // #i75163#
220 ImplInvalidateViewTransform();
222 delete mpOutDevData;
223 mpOutDevData = NULL;
225 // for some reason, we haven't removed state from the stack properly
226 if ( !mpOutDevStateStack->empty() )
228 SAL_WARN( "vcl.gdi", "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
229 while ( !mpOutDevStateStack->empty() )
231 mpOutDevStateStack->pop_back();
234 delete mpOutDevStateStack;
235 mpOutDevStateStack = NULL;
237 // release the active font instance
238 if( mpFontEntry )
239 mpFontCache->Release( mpFontEntry );
241 // remove cached results of GetDevFontList/GetDevSizeList
242 // TODO: use smart pointers for them
243 delete mpGetDevFontList;
244 mpGetDevFontList = NULL;
246 delete mpGetDevSizeList;
247 mpGetDevSizeList = NULL;
249 // release ImplFontCache specific to this OutputDevice
250 // TODO: refcount ImplFontCache
251 if( mpFontCache
252 && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
253 && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
255 delete mpFontCache;
256 mpFontCache = NULL;
259 // release ImplFontList specific to this OutputDevice
260 // TODO: refcount ImplFontList
261 if( mpFontCollection
262 && (mpFontCollection != ImplGetSVData()->maGDIData.mpScreenFontList)
263 && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
265 mpFontCollection->Clear();
266 delete mpFontCollection;
267 mpFontCollection = NULL;
270 mpAlphaVDev.disposeAndClear();
273 SalGraphics* OutputDevice::GetGraphics()
275 DBG_TESTSOLARMUTEX();
277 if ( !mpGraphics )
279 if ( !AcquireGraphics() )
281 SAL_WARN("vcl", "No mpGraphics set");
285 return mpGraphics;
288 SalGraphics const *OutputDevice::GetGraphics() const
290 DBG_TESTSOLARMUTEX();
292 if ( !mpGraphics )
294 if ( !AcquireGraphics() )
296 SAL_WARN("vcl", "No mpGraphics set");
300 return mpGraphics;
303 void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
305 mpMetaFile = pMtf;
308 void OutputDevice::SetSettings( const AllSettings& rSettings )
310 *mxSettings = rSettings;
312 if( mpAlphaVDev )
313 mpAlphaVDev->SetSettings( rSettings );
316 SystemGraphicsData OutputDevice::GetSystemGfxData() const
318 if ( !mpGraphics )
320 if ( !AcquireGraphics() )
321 return SystemGraphicsData();
324 return mpGraphics->GetGraphicsData();
327 bool OutputDevice::SupportsCairo() const
329 #if ENABLE_CAIRO_CANVAS
330 if (!mpGraphics)
332 if (!AcquireGraphics())
333 return false;
336 return mpGraphics->SupportsCairo();
337 #else
338 (void) this; // loplugin:staticmethods
339 return false;
340 #endif
343 cairo::SurfaceSharedPtr OutputDevice::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
345 if (!mpGraphics)
347 if (!AcquireGraphics())
348 return cairo::SurfaceSharedPtr();
350 return mpGraphics->CreateSurface(rSurface);
353 cairo::SurfaceSharedPtr OutputDevice::CreateSurface(int x, int y, int width, int height) const
355 if (!mpGraphics)
357 if (!AcquireGraphics())
358 return cairo::SurfaceSharedPtr();
360 return mpGraphics->CreateSurface(*this, x, y, width, height);
363 cairo::SurfaceSharedPtr OutputDevice::CreateBitmapSurface(const BitmapSystemData& rData, const Size& rSize) const
365 if (!mpGraphics)
367 if (!AcquireGraphics())
368 return cairo::SurfaceSharedPtr();
370 return mpGraphics->CreateBitmapSurface(*this, rData, rSize);
373 css::uno::Any OutputDevice::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const ::basegfx::B2ISize& rSize) const
375 if (!mpGraphics)
377 if (!AcquireGraphics())
378 return css::uno::Any();
380 return mpGraphics->GetNativeSurfaceHandle(rSurface, rSize);
383 css::uno::Any OutputDevice::GetSystemGfxDataAny() const
385 const SystemGraphicsData aSysData = GetSystemGfxData();
386 css::uno::Sequence< sal_Int8 > aSeq( reinterpret_cast<sal_Int8 const *>(&aSysData),
387 aSysData.nSize );
389 return css::uno::makeAny(aSeq);
392 void OutputDevice::SetRefPoint()
395 if ( mpMetaFile )
396 mpMetaFile->AddAction( new MetaRefPointAction( Point(), false ) );
398 mbRefPoint = false;
399 maRefPoint.X() = maRefPoint.Y() = 0L;
401 if( mpAlphaVDev )
402 mpAlphaVDev->SetRefPoint();
405 void OutputDevice::SetRefPoint( const Point& rRefPoint )
408 if ( mpMetaFile )
409 mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, true ) );
411 mbRefPoint = true;
412 maRefPoint = rRefPoint;
414 if( mpAlphaVDev )
415 mpAlphaVDev->SetRefPoint( rRefPoint );
418 sal_uInt16 OutputDevice::GetBitCount() const
420 // we need a graphics instance
421 if ( !mpGraphics )
423 if ( !AcquireGraphics() )
424 return 0;
427 return (sal_uInt16)mpGraphics->GetBitCount();
430 void OutputDevice::SetOutOffXPixel(long nOutOffX)
432 mnOutOffX = nOutOffX;
435 void OutputDevice::SetOutOffYPixel(long nOutOffY)
437 mnOutOffY = nOutOffY;
440 sal_uLong OutputDevice::GetColorCount() const
443 const sal_uInt16 nBitCount = GetBitCount();
444 return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
447 css::uno::Reference< css::rendering::XCanvas > OutputDevice::GetCanvas() const
449 css::uno::Sequence< css::uno::Any > aArg(6);
451 aArg[ 0 ] = css::uno::makeAny( reinterpret_cast<sal_Int64>(this) );
452 aArg[ 2 ] = css::uno::makeAny( css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
453 aArg[ 3 ] = css::uno::makeAny( sal_False );
454 aArg[ 5 ] = GetSystemGfxDataAny();
456 css::uno::Reference<css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
458 // Create canvas instance with window handle
459 static css::uno::Reference<css::lang::XMultiComponentFactory > xCanvasFactory( css::rendering::CanvasFactory::create( xContext ) );
461 css::uno::Reference<css::rendering::XCanvas> xCanvas;
462 xCanvas.set(
463 xCanvasFactory->createInstanceWithArgumentsAndContext(
464 "com.sun.star.rendering.Canvas", aArg, xContext ),
465 css::uno::UNO_QUERY );
467 return xCanvas;
470 css::uno::Reference< css::awt::XGraphics > OutputDevice::CreateUnoGraphics()
472 UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
473 return pWrapper ? pWrapper->CreateGraphics( this ) : css::uno::Reference< css::awt::XGraphics >();
476 std::vector< VCLXGraphics* > *OutputDevice::CreateUnoGraphicsList()
478 mpUnoGraphicsList = new std::vector< VCLXGraphics* >();
479 return mpUnoGraphicsList;
482 // Helper public function
484 bool OutputDevice::SupportsOperation( OutDevSupportType eType ) const
486 if( !mpGraphics )
487 if( !AcquireGraphics() )
488 return false;
489 const bool bHasSupport = mpGraphics->supportsOperation( eType );
490 return bHasSupport;
493 // Direct OutputDevice drawing public functions
495 void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
496 const Point& rSrcPt, const Size& rSrcSize )
498 if( ImplIsRecordLayout() )
499 return;
501 if ( ROP_INVERT == meRasterOp )
503 DrawRect( Rectangle( rDestPt, rDestSize ) );
504 return;
507 if ( mpMetaFile )
509 const Bitmap aBmp( GetBitmap( rSrcPt, rSrcSize ) );
510 mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
513 if ( !IsDeviceOutputNecessary() )
514 return;
516 if ( !mpGraphics )
517 if ( !AcquireGraphics() )
518 return;
520 if ( mbInitClipRegion )
521 InitClipRegion();
523 if ( mbOutputClipped )
524 return;
526 long nSrcWidth = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
527 long nSrcHeight = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
528 long nDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() );
529 long nDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
531 if (nSrcWidth && nSrcHeight && nDestWidth && nDestHeight)
533 SalTwoRect aPosAry(ImplLogicXToDevicePixel(rSrcPt.X()), ImplLogicYToDevicePixel(rSrcPt.Y()),
534 nSrcWidth, nSrcHeight,
535 ImplLogicXToDevicePixel(rDestPt.X()), ImplLogicYToDevicePixel(rDestPt.Y()),
536 nDestWidth, nDestHeight);
538 const Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
539 Size( mnOutWidth, mnOutHeight ) );
541 AdjustTwoRect( aPosAry, aSrcOutRect );
543 if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
544 mpGraphics->CopyBits( aPosAry, NULL, this, NULL );
547 if( mpAlphaVDev )
548 mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize );
551 void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
552 const Point& rSrcPt, const Size& rSrcSize,
553 const OutputDevice& rOutDev )
555 if ( ImplIsRecordLayout() )
556 return;
558 if ( ROP_INVERT == meRasterOp )
560 DrawRect( Rectangle( rDestPt, rDestSize ) );
561 return;
564 if ( mpMetaFile )
566 const Bitmap aBmp( rOutDev.GetBitmap( rSrcPt, rSrcSize ) );
567 mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
570 if ( !IsDeviceOutputNecessary() )
571 return;
573 if ( !mpGraphics )
574 if ( !AcquireGraphics() )
575 return;
577 if ( mbInitClipRegion )
578 InitClipRegion();
580 if ( mbOutputClipped )
581 return;
583 SalTwoRect aPosAry(rOutDev.ImplLogicXToDevicePixel(rSrcPt.X()),
584 rOutDev.ImplLogicYToDevicePixel(rSrcPt.Y()),
585 rOutDev.ImplLogicWidthToDevicePixel(rSrcSize.Width()),
586 rOutDev.ImplLogicHeightToDevicePixel(rSrcSize.Height()),
587 ImplLogicXToDevicePixel(rDestPt.X()),
588 ImplLogicYToDevicePixel(rDestPt.Y()),
589 ImplLogicWidthToDevicePixel(rDestSize.Width()),
590 ImplLogicHeightToDevicePixel(rDestSize.Height()));
592 if( mpAlphaVDev )
594 if( rOutDev.mpAlphaVDev )
596 // alpha-blend source over destination
597 DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
599 else
601 drawOutDevDirect( &rOutDev, aPosAry );
603 // #i32109#: make destination rectangle opaque - source has no alpha
604 mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
607 else
609 if( rOutDev.mpAlphaVDev )
611 // alpha-blend source over destination
612 DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
614 else
616 // no alpha at all, neither in source nor destination device
617 drawOutDevDirect( &rOutDev, aPosAry );
622 void OutputDevice::CopyArea( const Point& rDestPt,
623 const Point& rSrcPt, const Size& rSrcSize,
624 bool bWindowInvalidate )
626 if ( ImplIsRecordLayout() )
627 return;
629 RasterOp eOldRop = GetRasterOp();
630 SetRasterOp( ROP_OVERPAINT );
632 if ( !IsDeviceOutputNecessary() )
633 return;
635 if ( !mpGraphics )
636 if ( !AcquireGraphics() )
637 return;
639 if ( mbInitClipRegion )
640 InitClipRegion();
642 if ( mbOutputClipped )
643 return;
645 long nSrcWidth = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
646 long nSrcHeight = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
647 if (nSrcWidth && nSrcHeight)
649 SalTwoRect aPosAry(ImplLogicXToDevicePixel(rSrcPt.X()), ImplLogicYToDevicePixel(rSrcPt.Y()),
650 nSrcWidth, nSrcHeight,
651 ImplLogicXToDevicePixel(rDestPt.X()), ImplLogicYToDevicePixel(rDestPt.Y()),
652 nSrcWidth, nSrcHeight);
654 const Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
655 Size( mnOutWidth, mnOutHeight ) );
657 AdjustTwoRect( aPosAry, aSrcOutRect );
659 CopyDeviceArea( aPosAry, bWindowInvalidate );
662 SetRasterOp( eOldRop );
664 if( mpAlphaVDev )
665 mpAlphaVDev->CopyArea( rDestPt, rSrcPt, rSrcSize, bWindowInvalidate );
668 // Direct OutputDevice drawing protected function
670 void OutputDevice::CopyDeviceArea( SalTwoRect& aPosAry, bool /*bWindowInvalidate*/)
672 if (aPosAry.mnSrcWidth == 0 || aPosAry.mnSrcHeight == 0 || aPosAry.mnDestWidth == 0 || aPosAry.mnDestHeight == 0)
673 return;
675 aPosAry.mnDestWidth = aPosAry.mnSrcWidth;
676 aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
677 mpGraphics->CopyBits(aPosAry, NULL, this, NULL);
680 // Direct OutputDevice drawing private function
682 void OutputDevice::drawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry )
684 SalGraphics* pSrcGraphics;
686 if ( this == pSrcDev )
687 pSrcGraphics = NULL;
688 else
690 if ( (GetOutDevType() != pSrcDev->GetOutDevType()) ||
691 (GetOutDevType() != OUTDEV_WINDOW) )
693 if ( !pSrcDev->mpGraphics )
695 if ( !pSrcDev->AcquireGraphics() )
696 return;
698 pSrcGraphics = pSrcDev->mpGraphics;
700 else
702 if ( static_cast<vcl::Window*>(this)->mpWindowImpl->mpFrameWindow == static_cast<const vcl::Window*>(pSrcDev)->mpWindowImpl->mpFrameWindow )
703 pSrcGraphics = NULL;
704 else
706 if ( !pSrcDev->mpGraphics )
708 if ( !pSrcDev->AcquireGraphics() )
709 return;
711 pSrcGraphics = pSrcDev->mpGraphics;
713 if ( !mpGraphics )
715 if ( !AcquireGraphics() )
716 return;
718 DBG_ASSERT( mpGraphics && pSrcDev->mpGraphics,
719 "OutputDevice::DrawOutDev(): We need more than one Graphics" );
724 // #102532# Offset only has to be pseudo window offset
725 const Rectangle aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ),
726 Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) );
728 AdjustTwoRect( rPosAry, aSrcOutRect );
730 if ( rPosAry.mnSrcWidth && rPosAry.mnSrcHeight && rPosAry.mnDestWidth && rPosAry.mnDestHeight )
732 // --- RTL --- if this is no window, but pSrcDev is a window
733 // mirroring may be required
734 // because only windows have a SalGraphicsLayout
735 // mirroring is performed here
736 if( (GetOutDevType() != OUTDEV_WINDOW) && pSrcGraphics && (pSrcGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) )
738 SalTwoRect aPosAry2 = rPosAry;
739 pSrcGraphics->mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcDev );
740 mpGraphics->CopyBits( aPosAry2, pSrcGraphics, this, pSrcDev );
742 else
743 mpGraphics->CopyBits( rPosAry, pSrcGraphics, this, pSrcDev );
747 // Layout public functions
749 void OutputDevice::EnableRTL( bool bEnable )
751 mbEnableRTL = bEnable;
753 if( mpAlphaVDev )
754 mpAlphaVDev->EnableRTL( bEnable );
757 bool OutputDevice::ImplIsAntiparallel() const
759 bool bRet = false;
760 if( AcquireGraphics() )
762 if( ( (mpGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) && ! IsRTLEnabled() ) ||
763 ( ! (mpGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) && IsRTLEnabled() ) )
765 bRet = true;
768 return bRet;
771 // note: the coordinates to be remirrored are in frame coordiantes !
773 void OutputDevice::ReMirror( Point &rPoint ) const
775 rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
777 void OutputDevice::ReMirror( Rectangle &rRect ) const
779 long nWidth = rRect.Right() - rRect.Left();
781 //long lc_x = rRect.nLeft - mnOutOffX; // normalize
782 //lc_x = mnOutWidth - nWidth - 1 - lc_x; // mirror
783 //rRect.nLeft = lc_x + mnOutOffX; // re-normalize
785 rRect.Left() = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.Left() + mnOutOffX;
786 rRect.Right() = rRect.Left() + nWidth;
789 void OutputDevice::ReMirror( vcl::Region &rRegion ) const
791 RectangleVector aRectangles;
792 rRegion.GetRegionRectangles(aRectangles);
793 vcl::Region aMirroredRegion;
795 for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
797 ReMirror(*aRectIter);
798 aMirroredRegion.Union(*aRectIter);
801 rRegion = aMirroredRegion;
805 bool OutputDevice::HasMirroredGraphics() const
807 return ( AcquireGraphics() && (mpGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) );
810 bool OutputDevice::ImplIsRecordLayout() const
812 return mpOutDevData->mpRecordLayout;
815 // EPS public function
817 bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
818 const GfxLink& rGfxLink, GDIMetaFile* pSubst )
820 bool bDrawn(true);
822 if ( mpMetaFile )
824 GDIMetaFile aSubst;
826 if( pSubst )
827 aSubst = *pSubst;
829 mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
832 if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
833 return bDrawn;
835 if( mbOutputClipped )
836 return bDrawn;
838 Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
840 if( !aRect.IsEmpty() )
842 // draw the real EPS graphics
843 if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
845 if( !mpGraphics && !AcquireGraphics() )
846 return bDrawn;
848 if( mbInitClipRegion )
849 InitClipRegion();
851 aRect.Justify();
852 bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
853 const_cast<sal_uInt8*>(rGfxLink.GetData()), rGfxLink.GetDataSize(), this );
856 // else draw the substitution graphics
857 if( !bDrawn && pSubst )
859 GDIMetaFile* pOldMetaFile = mpMetaFile;
861 mpMetaFile = NULL;
862 Graphic( *pSubst ).Draw( this, rPoint, rSize );
863 mpMetaFile = pOldMetaFile;
867 if( mpAlphaVDev )
868 mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
870 return bDrawn;
873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */