1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
39 #include <sallayout.hxx>
40 #include <salframe.hxx>
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>
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...
78 #ifdef DISABLE_DYNLOADING
82 // Begin initializer and accessor public functions
84 OutputDevice::OutputDevice() :
85 mnRefCnt(1), // cf. VclPtrInstance and README.lifecycle
87 maFillColor( COL_WHITE
),
88 maTextLineColor( COL_TRANSPARENT
),
89 mxSettings( new AllSettings(Application::GetSettings()) )
92 mpUnoGraphicsList
= NULL
;
93 mpPrevGraphics
= NULL
;
94 mpNextGraphics
= NULL
;
98 mpFontCollection
= NULL
;
99 mpGetDevFontList
= NULL
;
100 mpGetDevSizeList
= NULL
;
101 mpOutDevStateStack
= new OutDevStateStack
;
104 mpExtOutDevData
= NULL
;
111 mnDPIScaleFactor
= 1;
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
;
129 mbMapIsDefault
= true;
130 mbClipRegion
= false;
131 mbBackground
= 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?
143 mbInitLineColor
= true;
144 mbInitFillColor
= true;
146 mbInitTextColor
= true;
147 mbInitClipRegion
= true;
148 mbClipRegionSet
= false;
152 mbTextBackground
= false;
153 mbTextSpecial
= false;
155 mbEnableRTL
= false; // mirroring must be explicitly allowed (typically for windows only)
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
;
180 mpOutDevData
->mpViewTransform
= NULL
;
181 mpOutDevData
->mpInverseViewTransform
= NULL
;
186 OutputDevice::~OutputDevice()
191 void OutputDevice::disposeOnce()
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 );
206 void OutputDevice::dispose()
208 if ( GetUnoGraphicsList() )
210 UnoWrapperBase
* pWrapper
= Application::GetUnoWrapper( false );
212 pWrapper
->ReleaseAllGraphics( this );
213 delete mpUnoGraphicsList
;
214 mpUnoGraphicsList
= NULL
;
217 mpOutDevData
->mpRotateDev
.disposeAndClear();
220 ImplInvalidateViewTransform();
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
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
252 && (mpFontCache
!= ImplGetSVData()->maGDIData
.mpScreenFontCache
)
253 && (ImplGetSVData()->maGDIData
.mpScreenFontCache
!= NULL
) )
259 // release ImplFontList specific to this OutputDevice
260 // TODO: refcount ImplFontList
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();
279 if ( !AcquireGraphics() )
281 SAL_WARN("vcl", "No mpGraphics set");
288 SalGraphics
const *OutputDevice::GetGraphics() const
290 DBG_TESTSOLARMUTEX();
294 if ( !AcquireGraphics() )
296 SAL_WARN("vcl", "No mpGraphics set");
303 void OutputDevice::SetConnectMetaFile( GDIMetaFile
* pMtf
)
308 void OutputDevice::SetSettings( const AllSettings
& rSettings
)
310 *mxSettings
= rSettings
;
313 mpAlphaVDev
->SetSettings( rSettings
);
316 SystemGraphicsData
OutputDevice::GetSystemGfxData() const
320 if ( !AcquireGraphics() )
321 return SystemGraphicsData();
324 return mpGraphics
->GetGraphicsData();
327 bool OutputDevice::SupportsCairo() const
329 #if ENABLE_CAIRO_CANVAS
332 if (!AcquireGraphics())
336 return mpGraphics
->SupportsCairo();
338 (void) this; // loplugin:staticmethods
343 cairo::SurfaceSharedPtr
OutputDevice::CreateSurface(const cairo::CairoSurfaceSharedPtr
& rSurface
) const
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
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
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
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
),
389 return css::uno::makeAny(aSeq
);
392 void OutputDevice::SetRefPoint()
396 mpMetaFile
->AddAction( new MetaRefPointAction( Point(), false ) );
399 maRefPoint
.X() = maRefPoint
.Y() = 0L;
402 mpAlphaVDev
->SetRefPoint();
405 void OutputDevice::SetRefPoint( const Point
& rRefPoint
)
409 mpMetaFile
->AddAction( new MetaRefPointAction( rRefPoint
, true ) );
412 maRefPoint
= rRefPoint
;
415 mpAlphaVDev
->SetRefPoint( rRefPoint
);
418 sal_uInt16
OutputDevice::GetBitCount() const
420 // we need a graphics instance
423 if ( !AcquireGraphics() )
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
;
463 xCanvasFactory
->createInstanceWithArgumentsAndContext(
464 "com.sun.star.rendering.Canvas", aArg
, xContext
),
465 css::uno::UNO_QUERY
);
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
487 if( !AcquireGraphics() )
489 const bool bHasSupport
= mpGraphics
->supportsOperation( eType
);
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() )
501 if ( ROP_INVERT
== meRasterOp
)
503 DrawRect( Rectangle( rDestPt
, rDestSize
) );
509 const Bitmap
aBmp( GetBitmap( rSrcPt
, rSrcSize
) );
510 mpMetaFile
->AddAction( new MetaBmpScaleAction( rDestPt
, rDestSize
, aBmp
) );
513 if ( !IsDeviceOutputNecessary() )
517 if ( !AcquireGraphics() )
520 if ( mbInitClipRegion
)
523 if ( mbOutputClipped
)
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
);
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() )
558 if ( ROP_INVERT
== meRasterOp
)
560 DrawRect( Rectangle( rDestPt
, rDestSize
) );
566 const Bitmap
aBmp( rOutDev
.GetBitmap( rSrcPt
, rSrcSize
) );
567 mpMetaFile
->AddAction( new MetaBmpScaleAction( rDestPt
, rDestSize
, aBmp
) );
570 if ( !IsDeviceOutputNecessary() )
574 if ( !AcquireGraphics() )
577 if ( mbInitClipRegion
)
580 if ( mbOutputClipped
)
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()));
594 if( rOutDev
.mpAlphaVDev
)
596 // alpha-blend source over destination
597 DrawBitmapEx( rDestPt
, rDestSize
, rOutDev
.GetBitmapEx(rSrcPt
, rSrcSize
) );
601 drawOutDevDirect( &rOutDev
, aPosAry
);
603 // #i32109#: make destination rectangle opaque - source has no alpha
604 mpAlphaVDev
->ImplFillOpaqueRectangle( Rectangle(rDestPt
, rDestSize
) );
609 if( rOutDev
.mpAlphaVDev
)
611 // alpha-blend source over destination
612 DrawBitmapEx( rDestPt
, rDestSize
, rOutDev
.GetBitmapEx(rSrcPt
, rSrcSize
) );
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() )
629 RasterOp eOldRop
= GetRasterOp();
630 SetRasterOp( ROP_OVERPAINT
);
632 if ( !IsDeviceOutputNecessary() )
636 if ( !AcquireGraphics() )
639 if ( mbInitClipRegion
)
642 if ( mbOutputClipped
)
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
);
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)
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
)
690 if ( (GetOutDevType() != pSrcDev
->GetOutDevType()) ||
691 (GetOutDevType() != OUTDEV_WINDOW
) )
693 if ( !pSrcDev
->mpGraphics
)
695 if ( !pSrcDev
->AcquireGraphics() )
698 pSrcGraphics
= pSrcDev
->mpGraphics
;
702 if ( static_cast<vcl::Window
*>(this)->mpWindowImpl
->mpFrameWindow
== static_cast<const vcl::Window
*>(pSrcDev
)->mpWindowImpl
->mpFrameWindow
)
706 if ( !pSrcDev
->mpGraphics
)
708 if ( !pSrcDev
->AcquireGraphics() )
711 pSrcGraphics
= pSrcDev
->mpGraphics
;
715 if ( !AcquireGraphics() )
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
);
743 mpGraphics
->CopyBits( rPosAry
, pSrcGraphics
, this, pSrcDev
);
747 // Layout public functions
749 void OutputDevice::EnableRTL( bool bEnable
)
751 mbEnableRTL
= bEnable
;
754 mpAlphaVDev
->EnableRTL( bEnable
);
757 bool OutputDevice::ImplIsAntiparallel() const
760 if( AcquireGraphics() )
762 if( ( (mpGraphics
->GetLayout() & SalLayoutFlags::BiDiRtl
) && ! IsRTLEnabled() ) ||
763 ( ! (mpGraphics
->GetLayout() & SalLayoutFlags::BiDiRtl
) && IsRTLEnabled() ) )
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
)
829 mpMetaFile
->AddAction( new MetaEPSAction( rPoint
, rSize
, rGfxLink
, aSubst
) );
832 if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
835 if( mbOutputClipped
)
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() )
848 if( mbInitClipRegion
)
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
;
862 Graphic( *pSubst
).Draw( this, rPoint
, rSize
);
863 mpMetaFile
= pOldMetaFile
;
868 mpAlphaVDev
->DrawEPS( rPoint
, rSize
, rGfxLink
, pSubst
);
873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */