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 .
21 #include <config_features.h>
22 #include <sal/log.hxx>
23 #if HAVE_FEATURE_OPENGL
24 #include <openglgdiimpl.hxx>
25 #include <opengl/zone.hxx>
26 #include <desktop/exithelper.h>
32 #include <salframe.hxx>
33 #include <basegfx/matrix/b2dhommatrix.hxx>
34 #include <basegfx/matrix/b2dhommatrixtools.hxx>
35 #include <FileDefinitionWidgetDraw.hxx>
37 // The only common SalFrame method
39 SalFrameGeometry
SalFrame::GetGeometry() const
41 // mirror frame coordinates at parent
42 SalFrame
*pParent
= GetParent();
43 if( pParent
&& AllSettings::GetLayoutRTL() )
45 SalFrameGeometry aGeom
= maGeometry
;
46 int parent_x
= aGeom
.nX
- pParent
->maGeometry
.nX
;
47 aGeom
.nX
= pParent
->maGeometry
.nX
+ pParent
->maGeometry
.nWidth
- maGeometry
.nWidth
- parent_x
;
54 SalGraphics::SalGraphics()
55 : m_nLayout( SalLayoutFlags::NONE
),
58 m_bAntiAliasB2DDraw(false)
60 // read global RTL settings
61 if( AllSettings::GetLayoutRTL() )
62 m_nLayout
= SalLayoutFlags::BiDiRtl
;
65 bool SalGraphics::initWidgetDrawBackends(bool bForce
)
67 bool bFileDefinitionsWidgetDraw
= !!getenv("VCL_DRAW_WIDGETS_FROM_FILE");
69 if (bFileDefinitionsWidgetDraw
|| bForce
)
71 m_pWidgetDraw
.reset(new vcl::FileDefinitionWidgetDraw(*this));
72 auto pFileDefinitionWidgetDraw
= static_cast<vcl::FileDefinitionWidgetDraw
*>(m_pWidgetDraw
.get());
73 if (!pFileDefinitionWidgetDraw
->isActive())
75 m_pWidgetDraw
.reset();
83 SalGraphics::~SalGraphics() COVERITY_NOEXCEPT_FALSE
85 // can't call ReleaseFonts here, as the destructor just calls this classes SetFont (pure virtual)!
88 #if HAVE_FEATURE_OPENGL
92 void disableOpenGLAndTerminateForRestart()
94 OpenGLZone::hardDisable();
96 TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART
);
101 rtl::Reference
<OpenGLContext
> SalGraphics::GetOpenGLContext() const
103 OpenGLSalGraphicsImpl
*pImpl
= dynamic_cast<OpenGLSalGraphicsImpl
*>(GetImpl());
106 // If we notice that OpenGL is broken the first time being called, it is not too late to call
107 // disableOpenGLAndTerminateForRestart(). The first time this will be called is from displaying
108 // the splash screen, so if OpenGL is broken, it is "early enough" for us to be able to disable
109 // OpenGL and terminate bluntly with EXITHELPER_NORMAL_RESTART, thus causing the wrapper process
110 // to restart us, then without using OpenGL.
111 static bool bFirstCall
= true;
112 rtl::Reference
<OpenGLContext
> xRet(pImpl
->GetOpenGLContext());
113 if (!xRet
.is() && bFirstCall
)
114 disableOpenGLAndTerminateForRestart();
123 bool SalGraphics::drawTransformedBitmap(
124 const basegfx::B2DPoint
& /* rNull */,
125 const basegfx::B2DPoint
& /* rX */,
126 const basegfx::B2DPoint
& /* rY */,
127 const SalBitmap
& /* rSourceBitmap */,
128 const SalBitmap
* /* pAlphaBitmap */)
130 // here direct support for transformed bitmaps can be implemented
134 long SalGraphics::mirror2( long x
, const OutputDevice
*pOutDev
) const
140 inline long SalGraphics::GetDeviceWidth(const OutputDevice
* pOutDev
) const
142 return (pOutDev
&& pOutDev
->IsVirtual())
143 ? pOutDev
->GetOutputWidthPixel() : GetGraphicsWidth();
146 void SalGraphics::mirror( long& x
, const OutputDevice
*pOutDev
) const
148 const long w
= GetDeviceWidth(pOutDev
);
151 if( pOutDev
&& pOutDev
->ImplIsAntiparallel() )
153 OutputDevice
*pOutDevRef
= const_cast<OutputDevice
*>(pOutDev
);
154 // mirror this window back
155 if( m_nLayout
& SalLayoutFlags::BiDiRtl
)
157 long devX
= w
-pOutDevRef
->GetOutputWidthPixel()-pOutDevRef
->GetOutOffXPixel(); // re-mirrored mnOutOffX
158 x
= devX
+ (x
- pOutDevRef
->GetOutOffXPixel());
162 long devX
= pOutDevRef
->GetOutOffXPixel(); // re-mirrored mnOutOffX
163 x
= pOutDevRef
->GetOutputWidthPixel() - (x
- devX
) + pOutDevRef
->GetOutOffXPixel() - 1;
166 else if( m_nLayout
& SalLayoutFlags::BiDiRtl
)
171 void SalGraphics::mirror( long& x
, long nWidth
, const OutputDevice
*pOutDev
, bool bBack
) const
173 const long w
= GetDeviceWidth(pOutDev
);
176 if( pOutDev
&& pOutDev
->ImplIsAntiparallel() )
178 OutputDevice
*pOutDevRef
= const_cast<OutputDevice
*>(pOutDev
);
179 // mirror this window back
180 if( m_nLayout
& SalLayoutFlags::BiDiRtl
)
182 long devX
= w
-pOutDevRef
->GetOutputWidthPixel()-pOutDevRef
->GetOutOffXPixel(); // re-mirrored mnOutOffX
184 x
= x
- devX
+ pOutDevRef
->GetOutOffXPixel();
186 x
= devX
+ (x
- pOutDevRef
->GetOutOffXPixel());
190 long devX
= pOutDevRef
->GetOutOffXPixel(); // re-mirrored mnOutOffX
192 x
= devX
+ (pOutDevRef
->GetOutputWidthPixel() + devX
) - (x
+ nWidth
);
194 x
= pOutDevRef
->GetOutputWidthPixel() - (x
- devX
) + pOutDevRef
->GetOutOffXPixel() - nWidth
;
197 else if( m_nLayout
& SalLayoutFlags::BiDiRtl
)
202 bool SalGraphics::mirror( sal_uInt32 nPoints
, const SalPoint
*pPtAry
, SalPoint
*pPtAry2
, const OutputDevice
*pOutDev
) const
204 const long w
= GetDeviceWidth(pOutDev
);
209 if( pOutDev
&& pOutDev
->ImplIsAntiparallel() )
211 OutputDevice
*pOutDevRef
= const_cast<OutputDevice
*>(pOutDev
);
212 // mirror this window back
213 if( m_nLayout
& SalLayoutFlags::BiDiRtl
)
215 long devX
= w
-pOutDevRef
->GetOutputWidthPixel()-pOutDevRef
->GetOutOffXPixel(); // re-mirrored mnOutOffX
216 for( i
=0, j
=nPoints
-1; i
<nPoints
; i
++,j
-- )
218 pPtAry2
[j
].mnX
= devX
+ (pPtAry
[i
].mnX
- pOutDevRef
->GetOutOffXPixel());
219 pPtAry2
[j
].mnY
= pPtAry
[i
].mnY
;
224 long devX
= pOutDevRef
->GetOutOffXPixel(); // re-mirrored mnOutOffX
225 for( i
=0, j
=nPoints
-1; i
<nPoints
; i
++,j
-- )
227 pPtAry2
[j
].mnX
= pOutDevRef
->GetOutputWidthPixel() - (pPtAry
[i
].mnX
- devX
) + pOutDevRef
->GetOutOffXPixel() - 1;
228 pPtAry2
[j
].mnY
= pPtAry
[i
].mnY
;
232 else if( m_nLayout
& SalLayoutFlags::BiDiRtl
)
234 for( i
=0, j
=nPoints
-1; i
<nPoints
; i
++,j
-- )
236 pPtAry2
[j
].mnX
= w
-1-pPtAry
[i
].mnX
;
237 pPtAry2
[j
].mnY
= pPtAry
[i
].mnY
;
246 void SalGraphics::mirror( vcl::Region
& rRgn
, const OutputDevice
*pOutDev
) const
248 if( rRgn
.HasPolyPolygonOrB2DPolyPolygon() )
250 const basegfx::B2DPolyPolygon
aPolyPoly(mirror(rRgn
.GetAsB2DPolyPolygon(), pOutDev
));
252 rRgn
= vcl::Region(aPolyPoly
);
256 RectangleVector aRectangles
;
257 rRgn
.GetRegionRectangles(aRectangles
);
260 for (auto & rectangle
: aRectangles
)
262 mirror(rectangle
, pOutDev
);
263 rRgn
.Union(rectangle
);
266 //ImplRegionInfo aInfo;
268 //Region aMirroredRegion;
269 //long nX, nY, nWidth, nHeight;
271 //bRegionRect = rRgn.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
272 //while ( bRegionRect )
274 // Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
275 // mirror( aRect, pOutDev, bBack );
276 // aMirroredRegion.Union( aRect );
277 // bRegionRect = rRgn.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
279 //rRgn = aMirroredRegion;
283 void SalGraphics::mirror( tools::Rectangle
& rRect
, const OutputDevice
*pOutDev
, bool bBack
) const
285 long nWidth
= rRect
.GetWidth();
286 long x
= rRect
.Left();
289 mirror( x
, nWidth
, pOutDev
, bBack
);
290 rRect
.Move( x
- x_org
, 0 );
293 basegfx::B2DPoint
SalGraphics::mirror( const basegfx::B2DPoint
& i_rPoint
, const OutputDevice
* i_pOutDev
) const
295 const basegfx::B2DHomMatrix
& rMirror(getMirror(i_pOutDev
));
297 if(rMirror
.isIdentity())
303 return rMirror
* i_rPoint
;
307 basegfx::B2DPolyPolygon
SalGraphics::mirror( const basegfx::B2DPolyPolygon
& i_rPoly
, const OutputDevice
* i_pOutDev
) const
309 const basegfx::B2DHomMatrix
& rMirror(getMirror(i_pOutDev
));
311 if(rMirror
.isIdentity())
317 basegfx::B2DPolyPolygon
aRet(i_rPoly
);
318 aRet
.transform(rMirror
);
324 const basegfx::B2DHomMatrix
& SalGraphics::getMirror( const OutputDevice
* i_pOutDev
) const
326 // get mirroring transformation
327 const long w
= GetDeviceWidth(i_pOutDev
);
328 SAL_WARN_IF( !w
, "vcl", "missing graphics width" );
330 if(w
!= m_aLastMirrorW
)
332 const_cast<SalGraphics
*>(this)->m_aLastMirrorW
= w
;
336 if(nullptr != i_pOutDev
&& !i_pOutDev
->IsRTLEnabled())
338 // Original code was (removed here already pOutDevRef->i_pOutDev):
339 // // mirror this window back
340 // double devX = w-i_pOutDev->GetOutputWidthPixel()-i_pOutDev->GetOutOffXPixel(); // re-mirrored mnOutOffX
341 // aRet.setX( devX + (i_rPoint.getX() - i_pOutDev->GetOutOffXPixel()) );
342 // I do not really understand the comment 'mirror this window back', so cannot guarantee
343 // that this works as before, but I have reduced this (by re-placing and re-formatting) to
344 // a simple translation:
345 const_cast<SalGraphics
*>(this)->m_aLastMirror
= basegfx::utils::createTranslateB2DHomMatrix(
346 w
- i_pOutDev
->GetOutputWidthPixel() - (2 * i_pOutDev
->GetOutOffXPixel()),
351 // Original code was:
352 // aRet.setX( w-1-i_rPoint.getX() );
353 // -mirror X -> scale(-1.0, 1.0)
354 // -translate X -> translate(w-1, 0); but already mirrored, so use translate(1-w, 0)
355 // Checked this one, works as expected.
356 const_cast<SalGraphics
*>(this)->m_aLastMirror
= basegfx::utils::createScaleTranslateB2DHomMatrix(
365 const_cast<SalGraphics
*>(this)->m_aLastMirror
.identity();
369 return m_aLastMirror
;
372 basegfx::B2DHomMatrix
SalGraphics::mirror( const basegfx::B2DHomMatrix
& i_rMatrix
, const OutputDevice
*pOutDev
) const
374 // add mirroring transformation to i_rMatrix
375 const basegfx::B2DHomMatrix
& rMirror(getMirror(pOutDev
));
377 // Apply mirror to given matrix by multiply from left ('after' i_rMatrix).
378 // Identity checks and fast-paths are in the operator
379 return rMirror
* i_rMatrix
;
382 bool SalGraphics::SetClipRegion( const vcl::Region
& i_rClip
, const OutputDevice
*pOutDev
)
384 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
386 vcl::Region
aMirror( i_rClip
);
387 mirror( aMirror
, pOutDev
);
388 return setClipRegion( aMirror
);
390 return setClipRegion( i_rClip
);
393 void SalGraphics::DrawPixel( long nX
, long nY
, const OutputDevice
*pOutDev
)
395 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
396 mirror( nX
, pOutDev
);
400 void SalGraphics::DrawPixel( long nX
, long nY
, Color nColor
, const OutputDevice
*pOutDev
)
402 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
403 mirror( nX
, pOutDev
);
404 drawPixel( nX
, nY
, nColor
);
407 void SalGraphics::DrawLine( long nX1
, long nY1
, long nX2
, long nY2
, const OutputDevice
*pOutDev
)
409 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
411 mirror( nX1
, pOutDev
);
412 mirror( nX2
, pOutDev
);
414 drawLine( nX1
, nY1
, nX2
, nY2
);
417 void SalGraphics::DrawRect( long nX
, long nY
, long nWidth
, long nHeight
, const OutputDevice
*pOutDev
)
419 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
420 mirror( nX
, nWidth
, pOutDev
);
421 drawRect( nX
, nY
, nWidth
, nHeight
);
424 void SalGraphics::DrawPolyLine( sal_uInt32 nPoints
, SalPoint
const * pPtAry
, const OutputDevice
*pOutDev
)
426 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
428 std::unique_ptr
<SalPoint
[]> pPtAry2(new SalPoint
[nPoints
]);
429 bool bCopied
= mirror( nPoints
, pPtAry
, pPtAry2
.get(), pOutDev
);
430 drawPolyLine( nPoints
, bCopied
? pPtAry2
.get() : pPtAry
);
433 drawPolyLine( nPoints
, pPtAry
);
436 void SalGraphics::DrawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, const OutputDevice
*pOutDev
)
438 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
440 std::unique_ptr
<SalPoint
[]> pPtAry2(new SalPoint
[nPoints
]);
441 bool bCopied
= mirror( nPoints
, pPtAry
, pPtAry2
.get(), pOutDev
);
442 drawPolygon( nPoints
, bCopied
? pPtAry2
.get() : pPtAry
);
445 drawPolygon( nPoints
, pPtAry
);
448 void SalGraphics::DrawPolyPolygon( sal_uInt32 nPoly
, const sal_uInt32
* pPoints
, PCONSTSALPOINT
* pPtAry
, const OutputDevice
*pOutDev
)
450 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
452 // TODO: optimize, reduce new/delete calls
453 std::unique_ptr
<SalPoint
*[]> pPtAry2( new SalPoint
*[nPoly
] );
455 for(i
=0; i
<nPoly
; i
++)
457 sal_uLong nPoints
= pPoints
[i
];
458 pPtAry2
[i
] = new SalPoint
[ nPoints
];
459 mirror( nPoints
, pPtAry
[i
], pPtAry2
[i
], pOutDev
);
462 drawPolyPolygon( nPoly
, pPoints
, const_cast<PCONSTSALPOINT
*>(pPtAry2
.get()) );
464 for(i
=0; i
<nPoly
; i
++)
465 delete [] pPtAry2
[i
];
468 drawPolyPolygon( nPoly
, pPoints
, pPtAry
);
471 bool SalGraphics::DrawPolyPolygon(
472 const basegfx::B2DHomMatrix
& rObjectToDevice
,
473 const basegfx::B2DPolyPolygon
& i_rPolyPolygon
,
474 double i_fTransparency
,
475 const OutputDevice
* i_pOutDev
)
477 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (i_pOutDev
&& i_pOutDev
->IsRTLEnabled()) )
480 const basegfx::B2DHomMatrix
& rMirror(getMirror(i_pOutDev
));
482 if(!rMirror
.isIdentity())
484 if(rObjectToDevice
.isIdentity())
486 // There is no ObjectToDevice transformation set. We can just
487 // use rMirror, that would be the result of the linear combination
488 return drawPolyPolygon(
495 // Create the linear combination
496 basegfx::B2DHomMatrix
aLinearCombination(rObjectToDevice
);
497 basegfx::B2DHomMatrix
aObjectToDeviceInv(rObjectToDevice
);
499 aLinearCombination
= rMirror
* aLinearCombination
;
500 aObjectToDeviceInv
.invert();
501 aLinearCombination
= aObjectToDeviceInv
* aLinearCombination
;
503 return drawPolyPolygon(
511 return drawPolyPolygon(
517 bool SalGraphics::DrawPolyLineBezier( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, const PolyFlags
* pFlgAry
, const OutputDevice
* pOutDev
)
519 bool bResult
= false;
520 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
522 std::unique_ptr
<SalPoint
[]> pPtAry2(new SalPoint
[nPoints
]);
523 bool bCopied
= mirror( nPoints
, pPtAry
, pPtAry2
.get(), pOutDev
);
524 bResult
= drawPolyLineBezier( nPoints
, bCopied
? pPtAry2
.get() : pPtAry
, pFlgAry
);
527 bResult
= drawPolyLineBezier( nPoints
, pPtAry
, pFlgAry
);
531 bool SalGraphics::DrawPolygonBezier( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, const PolyFlags
* pFlgAry
, const OutputDevice
* pOutDev
)
533 bool bResult
= false;
534 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
536 std::unique_ptr
<SalPoint
[]> pPtAry2(new SalPoint
[nPoints
]);
537 bool bCopied
= mirror( nPoints
, pPtAry
, pPtAry2
.get(), pOutDev
);
538 bResult
= drawPolygonBezier( nPoints
, bCopied
? pPtAry2
.get() : pPtAry
, pFlgAry
);
541 bResult
= drawPolygonBezier( nPoints
, pPtAry
, pFlgAry
);
545 bool SalGraphics::DrawPolyPolygonBezier( sal_uInt32 i_nPoly
, const sal_uInt32
* i_pPoints
,
546 const SalPoint
* const* i_pPtAry
, const PolyFlags
* const* i_pFlgAry
, const OutputDevice
* i_pOutDev
)
549 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (i_pOutDev
&& i_pOutDev
->IsRTLEnabled()) )
551 // TODO: optimize, reduce new/delete calls
552 std::unique_ptr
<SalPoint
*[]> pPtAry2( new SalPoint
*[i_nPoly
] );
554 for(i
=0; i
<i_nPoly
; i
++)
556 sal_uLong nPoints
= i_pPoints
[i
];
557 pPtAry2
[i
] = new SalPoint
[ nPoints
];
558 mirror( nPoints
, i_pPtAry
[i
], pPtAry2
[i
], i_pOutDev
);
561 bRet
= drawPolyPolygonBezier( i_nPoly
, i_pPoints
, const_cast<PCONSTSALPOINT
const *>(pPtAry2
.get()), i_pFlgAry
);
563 for(i
=0; i
<i_nPoly
; i
++)
564 delete [] pPtAry2
[i
];
567 bRet
= drawPolyPolygonBezier( i_nPoly
, i_pPoints
, i_pPtAry
, i_pFlgAry
);
571 bool SalGraphics::DrawPolyLine(
572 const basegfx::B2DHomMatrix
& rObjectToDevice
,
573 const basegfx::B2DPolygon
& i_rPolygon
,
574 double i_fTransparency
,
575 const basegfx::B2DVector
& i_rLineWidth
,
576 basegfx::B2DLineJoin i_eLineJoin
,
577 css::drawing::LineCap i_eLineCap
,
578 double i_fMiterMinimumAngle
,
579 bool bPixelSnapHairline
,
580 const OutputDevice
* i_pOutDev
)
582 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (i_pOutDev
&& i_pOutDev
->IsRTLEnabled()) )
585 const basegfx::B2DHomMatrix
& rMirror(getMirror(i_pOutDev
));
587 if(!rMirror
.isIdentity())
589 // If we really have a mirroring to apply, we *could*
590 // use the ::mirror call to modify the B2DPolygon (and
591 // prepare the LineWidth scaling), but we also
592 // can add that mirroring to rObjectToDevice transformation
593 // by using linear combination of transformations and stay
594 // on having the transformation
595 if(rObjectToDevice
.isIdentity())
597 // There is no ObjectToDevice transformation set. We can just
598 // use rMirror, that would be the result of the linear combination
606 i_fMiterMinimumAngle
,
611 // To create the linear combination, we need to
612 // - multiply with rObjectToDevice to get to device-coordinates
613 // (what is a simple copy)
614 // - apply rMirror (multiply from left)
615 // - multiply with inverse of rObjectToDevice to get back from
616 // device-coordinates to object-coordinates
617 // this only makes sense to do when we *have* an ObjectToDevice
618 // transformation, so optimize that
619 basegfx::B2DHomMatrix
aLinearCombination(rObjectToDevice
);
620 basegfx::B2DHomMatrix
aObjectToDeviceInv(rObjectToDevice
);
622 aLinearCombination
= rMirror
* aLinearCombination
;
623 aObjectToDeviceInv
.invert();
624 aLinearCombination
= aObjectToDeviceInv
* aLinearCombination
;
633 i_fMiterMinimumAngle
,
639 // no mirroring set (or identity), use standard call
647 i_fMiterMinimumAngle
,
651 bool SalGraphics::DrawGradient( const tools::PolyPolygon
& rPolyPoly
, const Gradient
& rGradient
)
653 return drawGradient( rPolyPoly
, rGradient
);
656 bool SalGraphics::DrawGradient(basegfx::B2DPolyPolygon
const & rPolyPolygon
, SalGradient
const & rSalGradient
)
658 return implDrawGradient(rPolyPolygon
, rSalGradient
);
661 void SalGraphics::CopyArea( long nDestX
, long nDestY
,
662 long nSrcX
, long nSrcY
,
663 long nSrcWidth
, long nSrcHeight
,
664 const OutputDevice
*pOutDev
)
666 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
668 mirror( nDestX
, nSrcWidth
, pOutDev
);
669 mirror( nSrcX
, nSrcWidth
, pOutDev
);
671 copyArea( nDestX
, nDestY
, nSrcX
, nSrcY
, nSrcWidth
, nSrcHeight
, true/*bWindowInvalidate*/ );
674 void SalGraphics::CopyBits( const SalTwoRect
& rPosAry
,
675 SalGraphics
* pSrcGraphics
, const OutputDevice
*pOutDev
, const OutputDevice
*pSrcOutDev
)
677 if( ( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) ) ||
678 (pSrcGraphics
&& ( (pSrcGraphics
->GetLayout() & SalLayoutFlags::BiDiRtl
) || (pSrcOutDev
&& pSrcOutDev
->IsRTLEnabled()) ) ) )
680 SalTwoRect aPosAry2
= rPosAry
;
681 if( (pSrcGraphics
&& (pSrcGraphics
->GetLayout() & SalLayoutFlags::BiDiRtl
)) || (pSrcOutDev
&& pSrcOutDev
->IsRTLEnabled()) )
682 mirror( aPosAry2
.mnSrcX
, aPosAry2
.mnSrcWidth
, pSrcOutDev
);
683 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
684 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
685 copyBits( aPosAry2
, pSrcGraphics
);
688 copyBits( rPosAry
, pSrcGraphics
);
691 void SalGraphics::DrawBitmap( const SalTwoRect
& rPosAry
,
692 const SalBitmap
& rSalBitmap
, const OutputDevice
*pOutDev
)
694 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
696 SalTwoRect aPosAry2
= rPosAry
;
697 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
698 drawBitmap( aPosAry2
, rSalBitmap
);
701 drawBitmap( rPosAry
, rSalBitmap
);
704 void SalGraphics::DrawBitmap( const SalTwoRect
& rPosAry
,
705 const SalBitmap
& rSalBitmap
,
706 const SalBitmap
& rTransparentBitmap
, const OutputDevice
*pOutDev
)
708 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
710 SalTwoRect aPosAry2
= rPosAry
;
711 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
712 drawBitmap( aPosAry2
, rSalBitmap
, rTransparentBitmap
);
715 drawBitmap( rPosAry
, rSalBitmap
, rTransparentBitmap
);
718 void SalGraphics::DrawMask( const SalTwoRect
& rPosAry
,
719 const SalBitmap
& rSalBitmap
,
720 Color nMaskColor
, const OutputDevice
*pOutDev
)
722 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
724 SalTwoRect aPosAry2
= rPosAry
;
725 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
726 drawMask( aPosAry2
, rSalBitmap
, nMaskColor
);
729 drawMask( rPosAry
, rSalBitmap
, nMaskColor
);
732 std::shared_ptr
<SalBitmap
> SalGraphics::GetBitmap( long nX
, long nY
, long nWidth
, long nHeight
, const OutputDevice
*pOutDev
)
734 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
735 mirror( nX
, nWidth
, pOutDev
);
736 return getBitmap( nX
, nY
, nWidth
, nHeight
);
739 Color
SalGraphics::GetPixel( long nX
, long nY
, const OutputDevice
*pOutDev
)
741 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
742 mirror( nX
, pOutDev
);
743 return getPixel( nX
, nY
);
746 void SalGraphics::Invert( long nX
, long nY
, long nWidth
, long nHeight
, SalInvert nFlags
, const OutputDevice
*pOutDev
)
748 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
749 mirror( nX
, nWidth
, pOutDev
);
750 invert( nX
, nY
, nWidth
, nHeight
, nFlags
);
753 void SalGraphics::Invert( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, SalInvert nFlags
, const OutputDevice
*pOutDev
)
755 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
757 std::unique_ptr
<SalPoint
[]> pPtAry2(new SalPoint
[nPoints
]);
758 bool bCopied
= mirror( nPoints
, pPtAry
, pPtAry2
.get(), pOutDev
);
759 invert( nPoints
, bCopied
? pPtAry2
.get() : pPtAry
, nFlags
);
762 invert( nPoints
, pPtAry
, nFlags
);
765 bool SalGraphics::DrawEPS( long nX
, long nY
, long nWidth
, long nHeight
, void* pPtr
, sal_uInt32 nSize
, const OutputDevice
*pOutDev
)
767 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
768 mirror( nX
, nWidth
, pOutDev
);
769 return drawEPS( nX
, nY
, nWidth
, nHeight
, pPtr
, nSize
);
772 bool SalGraphics::HitTestNativeScrollbar( ControlPart nPart
, const tools::Rectangle
& rControlRegion
,
773 const Point
& aPos
, bool& rIsInside
, const OutputDevice
*pOutDev
)
775 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
778 tools::Rectangle
rgn( rControlRegion
);
779 pt
.setX( mirror2( pt
.X(), pOutDev
) );
780 mirror( rgn
, pOutDev
);
781 return forWidget()->hitTestNativeControl( ControlType::Scrollbar
, nPart
, rgn
, pt
, rIsInside
);
784 return forWidget()->hitTestNativeControl( ControlType::Scrollbar
, nPart
, rControlRegion
, aPos
, rIsInside
);
787 void SalGraphics::mirror( ImplControlValue
& rVal
, const OutputDevice
* pOutDev
) const
789 switch( rVal
.getType() )
791 case ControlType::Slider
:
793 SliderValue
* pSlVal
= static_cast<SliderValue
*>(&rVal
);
794 mirror(pSlVal
->maThumbRect
,pOutDev
);
797 case ControlType::Scrollbar
:
799 ScrollbarValue
* pScVal
= static_cast<ScrollbarValue
*>(&rVal
);
800 mirror(pScVal
->maThumbRect
,pOutDev
);
801 mirror(pScVal
->maButton1Rect
,pOutDev
);
802 mirror(pScVal
->maButton2Rect
,pOutDev
);
805 case ControlType::Spinbox
:
806 case ControlType::SpinButtons
:
808 SpinbuttonValue
* pSpVal
= static_cast<SpinbuttonValue
*>(&rVal
);
809 mirror(pSpVal
->maUpperRect
,pOutDev
);
810 mirror(pSpVal
->maLowerRect
,pOutDev
);
813 case ControlType::Toolbar
:
815 ToolbarValue
* pTVal
= static_cast<ToolbarValue
*>(&rVal
);
816 mirror(pTVal
->maGripRect
,pOutDev
);
823 bool SalGraphics::DrawNativeControl( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
,
824 ControlState nState
, const ImplControlValue
& aValue
,
825 const OUString
& aCaption
, const OutputDevice
*pOutDev
)
828 tools::Rectangle
aControlRegion(rControlRegion
);
829 if (aControlRegion
.IsEmpty())
832 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
834 mirror(aControlRegion
, pOutDev
);
835 std::unique_ptr
< ImplControlValue
> mirrorValue( aValue
.clone());
836 mirror( *mirrorValue
, pOutDev
);
837 bRet
= forWidget()->drawNativeControl(nType
, nPart
, aControlRegion
, nState
, *mirrorValue
, aCaption
);
840 bRet
= forWidget()->drawNativeControl(nType
, nPart
, aControlRegion
, nState
, aValue
, aCaption
);
842 if (bRet
&& m_pWidgetDraw
)
843 handleDamage(aControlRegion
);
847 bool SalGraphics::GetNativeControlRegion( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
, ControlState nState
,
848 const ImplControlValue
& aValue
,
849 tools::Rectangle
&rNativeBoundingRegion
, tools::Rectangle
&rNativeContentRegion
, const OutputDevice
*pOutDev
)
851 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
853 tools::Rectangle
rgn( rControlRegion
);
854 mirror( rgn
, pOutDev
);
855 std::unique_ptr
< ImplControlValue
> mirrorValue( aValue
.clone());
856 mirror( *mirrorValue
, pOutDev
);
857 if (forWidget()->getNativeControlRegion(nType
, nPart
, rgn
, nState
, *mirrorValue
, OUString(), rNativeBoundingRegion
, rNativeContentRegion
))
859 mirror( rNativeBoundingRegion
, pOutDev
, true );
860 mirror( rNativeContentRegion
, pOutDev
, true );
866 return forWidget()->getNativeControlRegion(nType
, nPart
, rControlRegion
, nState
, aValue
, OUString(), rNativeBoundingRegion
, rNativeContentRegion
);
869 bool SalGraphics::BlendBitmap( const SalTwoRect
& rPosAry
,
870 const SalBitmap
& rBitmap
,
871 const OutputDevice
*pOutDev
)
873 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
875 SalTwoRect aPosAry2
= rPosAry
;
876 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
877 return blendBitmap( aPosAry2
, rBitmap
);
880 return blendBitmap( rPosAry
, rBitmap
);
883 bool SalGraphics::BlendAlphaBitmap( const SalTwoRect
& rPosAry
,
884 const SalBitmap
& rSrcBitmap
,
885 const SalBitmap
& rMaskBitmap
,
886 const SalBitmap
& rAlphaBitmap
,
887 const OutputDevice
*pOutDev
)
889 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
891 SalTwoRect aPosAry2
= rPosAry
;
892 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
893 return blendAlphaBitmap( aPosAry2
, rSrcBitmap
, rMaskBitmap
, rAlphaBitmap
);
896 return blendAlphaBitmap( rPosAry
, rSrcBitmap
, rMaskBitmap
, rAlphaBitmap
);
899 bool SalGraphics::DrawAlphaBitmap( const SalTwoRect
& rPosAry
,
900 const SalBitmap
& rSourceBitmap
,
901 const SalBitmap
& rAlphaBitmap
,
902 const OutputDevice
*pOutDev
)
904 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
906 SalTwoRect aPosAry2
= rPosAry
;
907 mirror( aPosAry2
.mnDestX
, aPosAry2
.mnDestWidth
, pOutDev
);
908 return drawAlphaBitmap( aPosAry2
, rSourceBitmap
, rAlphaBitmap
);
911 return drawAlphaBitmap( rPosAry
, rSourceBitmap
, rAlphaBitmap
);
914 bool SalGraphics::DrawTransformedBitmap(
915 const basegfx::B2DPoint
& rNull
,
916 const basegfx::B2DPoint
& rX
,
917 const basegfx::B2DPoint
& rY
,
918 const SalBitmap
& rSourceBitmap
,
919 const SalBitmap
* pAlphaBitmap
,
920 const OutputDevice
* pOutDev
)
922 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
924 mirror(rNull
, pOutDev
);
928 return drawTransformedBitmap(rNull
, rX
, rY
, rSourceBitmap
, pAlphaBitmap
);
932 return drawTransformedBitmap(rNull
, rX
, rY
, rSourceBitmap
, pAlphaBitmap
);
936 bool SalGraphics::DrawAlphaRect( long nX
, long nY
, long nWidth
, long nHeight
,
937 sal_uInt8 nTransparency
, const OutputDevice
*pOutDev
)
939 if( (m_nLayout
& SalLayoutFlags::BiDiRtl
) || (pOutDev
&& pOutDev
->IsRTLEnabled()) )
940 mirror( nX
, nWidth
, pOutDev
);
942 return drawAlphaRect( nX
, nY
, nWidth
, nHeight
, nTransparency
);
945 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */