Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / source / gdi / salgdilayout.cxx
blob3b64a33fd6b8c701bbb53cd98f0470840a9a96a3
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 <memory>
21 #include <config_features.h>
22 #if HAVE_FEATURE_OPENGL
23 #include "openglgdiimpl.hxx"
24 #include <opengl/zone.hxx>
25 #include <desktop/exithelper.h>
26 #ifdef _WIN32
27 #include <svsys.h>
28 #endif
29 #endif
30 #include "salgdi.hxx"
31 #include "salframe.hxx"
32 #include <basegfx/numeric/ftools.hxx> //for F_PI180
34 // The only common SalFrame method
36 SalFrameGeometry SalFrame::GetGeometry()
38 // mirror frame coordinates at parent
39 SalFrame *pParent = GetParent();
40 if( pParent && AllSettings::GetLayoutRTL() )
42 SalFrameGeometry aGeom = maGeometry;
43 int parent_x = aGeom.nX - pParent->maGeometry.nX;
44 aGeom.nX = pParent->maGeometry.nX + pParent->maGeometry.nWidth - maGeometry.nWidth - parent_x;
45 return aGeom;
47 else
48 return maGeometry;
51 SalGraphics::SalGraphics()
52 : m_nLayout( SalLayoutFlags::NONE ),
53 m_bAntiAliasB2DDraw(false)
55 // read global RTL settings
56 if( AllSettings::GetLayoutRTL() )
57 m_nLayout = SalLayoutFlags::BiDiRtl;
60 SalGraphics::~SalGraphics()
64 #if HAVE_FEATURE_OPENGL
66 namespace
68 void disableOpenGLAndTerminateForRestart()
70 OpenGLZone::hardDisable();
71 #ifdef _WIN32
72 TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART);
73 #endif
77 rtl::Reference<OpenGLContext> SalGraphics::GetOpenGLContext() const
79 OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl());
80 if (pImpl)
82 // If we notice that OpenGL is broken the first time being called, it is not too late to call
83 // disableOpenGLAndTerminateForRestart(). The first time this will be called is from displaying
84 // the splash screen, so if OpenGL is broken, it is "early enough" for us to be able to disable
85 // OpenGL and terminate bluntly with EXITHELPER_NORMAL_RESTART, thus causing the wrapper process
86 // to restart us, then without using OpenGL.
87 static bool bFirstCall = true;
88 rtl::Reference<OpenGLContext> xRet(pImpl->GetOpenGLContext());
89 if (!xRet.is() && bFirstCall)
90 disableOpenGLAndTerminateForRestart();
91 bFirstCall = false;
92 return xRet;
94 return nullptr;
96 #endif
98 bool SalGraphics::drawTransformedBitmap(
99 const basegfx::B2DPoint& /* rNull */,
100 const basegfx::B2DPoint& /* rX */,
101 const basegfx::B2DPoint& /* rY */,
102 const SalBitmap& /* rSourceBitmap */,
103 const SalBitmap* /* pAlphaBitmap */)
105 // here direct support for transformed bitmaps can be implemented
106 return false;
109 void SalGraphics::mirror( long& x, const OutputDevice *pOutDev ) const
111 long w;
112 if( pOutDev && pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
113 w = pOutDev->GetOutputWidthPixel();
114 else
115 w = GetGraphicsWidth();
117 if( w )
119 if( pOutDev && pOutDev->ImplIsAntiparallel() )
121 OutputDevice *pOutDevRef = const_cast<OutputDevice*>(pOutDev);
122 // mirror this window back
123 if( (m_nLayout & SalLayoutFlags::BiDiRtl) )
125 long devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
126 x = devX + (x - pOutDevRef->GetOutOffXPixel());
128 else
130 long devX = pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
131 x = pOutDevRef->GetOutputWidthPixel() - (x - devX) + pOutDevRef->GetOutOffXPixel() - 1;
134 else if( (m_nLayout & SalLayoutFlags::BiDiRtl) )
135 x = w-1-x;
139 void SalGraphics::mirror( long& x, long& nWidth, const OutputDevice *pOutDev, bool bBack ) const
141 long w;
142 if( pOutDev && pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
143 w = pOutDev->GetOutputWidthPixel();
144 else
145 w = GetGraphicsWidth();
147 if( w )
149 if( pOutDev && pOutDev->ImplIsAntiparallel() )
151 OutputDevice *pOutDevRef = const_cast<OutputDevice*>(pOutDev);
152 // mirror this window back
153 if( (m_nLayout & SalLayoutFlags::BiDiRtl) )
155 long devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
156 if( bBack )
157 x = x - devX + pOutDevRef->GetOutOffXPixel();
158 else
159 x = devX + (x - pOutDevRef->GetOutOffXPixel());
161 else
163 long devX = pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
164 if( bBack )
165 x = devX + (pOutDevRef->GetOutputWidthPixel() + devX) - (x + nWidth);
166 else
167 x = pOutDevRef->GetOutputWidthPixel() - (x - devX) + pOutDevRef->GetOutOffXPixel() - nWidth;
170 else if( (m_nLayout & SalLayoutFlags::BiDiRtl) )
171 x = w-nWidth-x;
176 bool SalGraphics::mirror( sal_uInt32 nPoints, const SalPoint *pPtAry, SalPoint *pPtAry2, const OutputDevice *pOutDev ) const
178 long w;
179 if( pOutDev && pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
180 w = pOutDev->GetOutputWidthPixel();
181 else
182 w = GetGraphicsWidth();
184 if( w )
186 sal_uInt32 i, j;
188 if( pOutDev && pOutDev->ImplIsAntiparallel() )
190 OutputDevice *pOutDevRef = const_cast<OutputDevice*>(pOutDev);
191 // mirror this window back
192 if( (m_nLayout & SalLayoutFlags::BiDiRtl) )
194 long devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
195 for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
197 pPtAry2[j].mnX = devX + (pPtAry[i].mnX - pOutDevRef->GetOutOffXPixel());
198 pPtAry2[j].mnY = pPtAry[i].mnY;
201 else
203 long devX = pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
204 for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
206 pPtAry2[j].mnX = pOutDevRef->GetOutputWidthPixel() - (pPtAry[i].mnX - devX) + pOutDevRef->GetOutOffXPixel() - 1;
207 pPtAry2[j].mnY = pPtAry[i].mnY;
211 else if( (m_nLayout & SalLayoutFlags::BiDiRtl) )
213 for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
215 pPtAry2[j].mnX = w-1-pPtAry[i].mnX;
216 pPtAry2[j].mnY = pPtAry[i].mnY;
219 return true;
221 else
222 return false;
225 void SalGraphics::mirror( vcl::Region& rRgn, const OutputDevice *pOutDev ) const
227 if( rRgn.HasPolyPolygonOrB2DPolyPolygon() )
229 const basegfx::B2DPolyPolygon aPolyPoly(mirror(rRgn.GetAsB2DPolyPolygon(), pOutDev));
231 rRgn = vcl::Region(aPolyPoly);
233 else
235 RectangleVector aRectangles;
236 rRgn.GetRegionRectangles(aRectangles);
237 rRgn.SetEmpty();
239 for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
241 mirror(*aRectIter, pOutDev);
242 rRgn.Union(*aRectIter);
245 //ImplRegionInfo aInfo;
246 //bool bRegionRect;
247 //Region aMirroredRegion;
248 //long nX, nY, nWidth, nHeight;
250 //bRegionRect = rRgn.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
251 //while ( bRegionRect )
253 // Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
254 // mirror( aRect, pOutDev, bBack );
255 // aMirroredRegion.Union( aRect );
256 // bRegionRect = rRgn.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
258 //rRgn = aMirroredRegion;
262 void SalGraphics::mirror( tools::Rectangle& rRect, const OutputDevice *pOutDev, bool bBack ) const
264 long nWidth = rRect.GetWidth();
265 long x = rRect.Left();
266 long x_org = x;
268 mirror( x, nWidth, pOutDev, bBack );
269 rRect.Move( x - x_org, 0 );
272 basegfx::B2DPoint SalGraphics::mirror( const basegfx::B2DPoint& i_rPoint, const OutputDevice *i_pOutDev ) const
274 long w;
275 if( i_pOutDev && i_pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
276 w = i_pOutDev->GetOutputWidthPixel();
277 else
278 w = GetGraphicsWidth();
280 SAL_WARN_IF( !w, "vcl", "missing graphics width" );
282 basegfx::B2DPoint aRet( i_rPoint );
283 if( w )
285 if( i_pOutDev && !i_pOutDev->IsRTLEnabled() )
287 OutputDevice *pOutDevRef = const_cast<OutputDevice*>(i_pOutDev);
288 // mirror this window back
289 double devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel(); // re-mirrored mnOutOffX
290 aRet.setX( devX + (i_rPoint.getX() - pOutDevRef->GetOutOffXPixel()) );
292 else
293 aRet.setX( w-1-i_rPoint.getX() );
295 return aRet;
298 basegfx::B2DPolygon SalGraphics::mirror( const basegfx::B2DPolygon& i_rPoly, const OutputDevice *i_pOutDev ) const
300 long w;
301 if( i_pOutDev && i_pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
302 w = i_pOutDev->GetOutputWidthPixel();
303 else
304 w = GetGraphicsWidth();
306 SAL_WARN_IF( !w, "vcl", "missing graphics width" );
308 basegfx::B2DPolygon aRet;
309 if( w )
311 sal_Int32 nPoints = i_rPoly.count();
312 for( sal_Int32 i = 0; i < nPoints; i++ )
314 aRet.append( mirror( i_rPoly.getB2DPoint( i ), i_pOutDev ) );
315 if( i_rPoly.isPrevControlPointUsed( i ) )
316 aRet.setPrevControlPoint( i, mirror( i_rPoly.getPrevControlPoint( i ), i_pOutDev ) );
317 if( i_rPoly.isNextControlPointUsed( i ) )
318 aRet.setNextControlPoint( i, mirror( i_rPoly.getNextControlPoint( i ), i_pOutDev ) );
320 aRet.setClosed( i_rPoly.isClosed() );
321 aRet.flip();
323 else
324 aRet = i_rPoly;
325 return aRet;
328 basegfx::B2DPolyPolygon SalGraphics::mirror( const basegfx::B2DPolyPolygon& i_rPoly, const OutputDevice *i_pOutDev ) const
330 long w;
331 if( i_pOutDev && i_pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
332 w = i_pOutDev->GetOutputWidthPixel();
333 else
334 w = GetGraphicsWidth();
336 SAL_WARN_IF( !w, "vcl", "missing graphics width" );
338 basegfx::B2DPolyPolygon aRet;
339 if( w )
341 sal_Int32 nPoly = i_rPoly.count();
342 for( sal_Int32 i = 0; i < nPoly; i++ )
343 aRet.append( mirror( i_rPoly.getB2DPolygon( i ), i_pOutDev ) );
344 aRet.setClosed( i_rPoly.isClosed() );
345 aRet.flip();
347 else
348 aRet = i_rPoly;
349 return aRet;
352 bool SalGraphics::SetClipRegion( const vcl::Region& i_rClip, const OutputDevice *pOutDev )
354 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
356 vcl::Region aMirror( i_rClip );
357 mirror( aMirror, pOutDev );
358 return setClipRegion( aMirror );
360 return setClipRegion( i_rClip );
363 void SalGraphics::DrawPixel( long nX, long nY, const OutputDevice *pOutDev )
365 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
366 mirror( nX, pOutDev );
367 drawPixel( nX, nY );
370 void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor, const OutputDevice *pOutDev )
372 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
373 mirror( nX, pOutDev );
374 drawPixel( nX, nY, nSalColor );
377 void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2, const OutputDevice *pOutDev )
379 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
381 mirror( nX1, pOutDev );
382 mirror( nX2, pOutDev );
384 drawLine( nX1, nY1, nX2, nY2 );
387 void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev )
389 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
390 mirror( nX, nWidth, pOutDev );
391 drawRect( nX, nY, nWidth, nHeight );
394 void SalGraphics::DrawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry, const OutputDevice *pOutDev )
396 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
398 std::unique_ptr<SalPoint[]> pPtAry2(new SalPoint[nPoints]);
399 bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), pOutDev );
400 drawPolyLine( nPoints, bCopied ? pPtAry2.get() : pPtAry );
402 else
403 drawPolyLine( nPoints, pPtAry );
406 void SalGraphics::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, const OutputDevice *pOutDev )
408 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
410 std::unique_ptr<SalPoint[]> pPtAry2(new SalPoint[nPoints]);
411 bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), pOutDev );
412 drawPolygon( nPoints, bCopied ? pPtAry2.get() : pPtAry );
414 else
415 drawPolygon( nPoints, pPtAry );
418 void SalGraphics::DrawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry, const OutputDevice *pOutDev )
420 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
422 // TODO: optimize, reduce new/delete calls
423 std::unique_ptr<SalPoint*[]> pPtAry2( new SalPoint*[nPoly] );
424 sal_uLong i;
425 for(i=0; i<nPoly; i++)
427 sal_uLong nPoints = pPoints[i];
428 pPtAry2[i] = new SalPoint[ nPoints ];
429 mirror( nPoints, pPtAry[i], pPtAry2[i], pOutDev );
432 drawPolyPolygon( nPoly, pPoints, const_cast<PCONSTSALPOINT*>(pPtAry2.get()) );
434 for(i=0; i<nPoly; i++)
435 delete [] pPtAry2[i];
437 else
438 drawPolyPolygon( nPoly, pPoints, pPtAry );
441 bool SalGraphics::DrawPolyPolygon( const basegfx::B2DPolyPolygon& i_rPolyPolygon, double i_fTransparency, const OutputDevice* i_pOutDev )
443 bool bRet = false;
444 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) )
446 basegfx::B2DPolyPolygon aMirror( mirror( i_rPolyPolygon, i_pOutDev ) );
447 bRet = drawPolyPolygon( aMirror, i_fTransparency );
449 else
450 bRet = drawPolyPolygon( i_rPolyPolygon, i_fTransparency );
451 return bRet;
454 bool SalGraphics::DrawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const PolyFlags* pFlgAry, const OutputDevice* pOutDev )
456 bool bResult = false;
457 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
459 std::unique_ptr<SalPoint[]> pPtAry2(new SalPoint[nPoints]);
460 bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), pOutDev );
461 bResult = drawPolyLineBezier( nPoints, bCopied ? pPtAry2.get() : pPtAry, pFlgAry );
463 else
464 bResult = drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
465 return bResult;
468 bool SalGraphics::DrawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const PolyFlags* pFlgAry, const OutputDevice* pOutDev )
470 bool bResult = false;
471 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
473 std::unique_ptr<SalPoint[]> pPtAry2(new SalPoint[nPoints]);
474 bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), pOutDev );
475 bResult = drawPolygonBezier( nPoints, bCopied ? pPtAry2.get() : pPtAry, pFlgAry );
477 else
478 bResult = drawPolygonBezier( nPoints, pPtAry, pFlgAry );
479 return bResult;
482 bool SalGraphics::DrawPolyPolygonBezier( sal_uInt32 i_nPoly, const sal_uInt32* i_pPoints,
483 const SalPoint* const* i_pPtAry, const PolyFlags* const* i_pFlgAry, const OutputDevice* i_pOutDev )
485 bool bRet = false;
486 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) )
488 // TODO: optimize, reduce new/delete calls
489 std::unique_ptr<SalPoint*[]> pPtAry2( new SalPoint*[i_nPoly] );
490 sal_uLong i;
491 for(i=0; i<i_nPoly; i++)
493 sal_uLong nPoints = i_pPoints[i];
494 pPtAry2[i] = new SalPoint[ nPoints ];
495 mirror( nPoints, i_pPtAry[i], pPtAry2[i], i_pOutDev );
498 bRet = drawPolyPolygonBezier( i_nPoly, i_pPoints, const_cast<PCONSTSALPOINT const *>(pPtAry2.get()), i_pFlgAry );
500 for(i=0; i<i_nPoly; i++)
501 delete [] pPtAry2[i];
503 else
504 bRet = drawPolyPolygonBezier( i_nPoly, i_pPoints, i_pPtAry, i_pFlgAry );
505 return bRet;
508 bool SalGraphics::DrawPolyLine( const basegfx::B2DPolygon& i_rPolygon,
509 double i_fTransparency,
510 const basegfx::B2DVector& i_rLineWidth,
511 basegfx::B2DLineJoin i_eLineJoin,
512 css::drawing::LineCap i_eLineCap,
513 double i_fMiterMinimumAngle,
514 const OutputDevice* i_pOutDev )
516 bool bRet = false;
517 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) )
519 basegfx::B2DPolygon aMirror( mirror( i_rPolygon, i_pOutDev ) );
520 bRet = drawPolyLine( aMirror, i_fTransparency, i_rLineWidth, i_eLineJoin, i_eLineCap, i_fMiterMinimumAngle );
522 else
523 bRet = drawPolyLine( i_rPolygon, i_fTransparency, i_rLineWidth, i_eLineJoin, i_eLineCap, i_fMiterMinimumAngle );
524 return bRet;
527 bool SalGraphics::DrawGradient( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient )
529 return drawGradient( rPolyPoly, rGradient );
532 void SalGraphics::CopyArea( long nDestX, long nDestY,
533 long nSrcX, long nSrcY,
534 long nSrcWidth, long nSrcHeight,
535 const OutputDevice *pOutDev )
537 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
539 mirror( nDestX, nSrcWidth, pOutDev );
540 mirror( nSrcX, nSrcWidth, pOutDev );
542 copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, true/*bWindowInvalidate*/ );
545 void SalGraphics::CopyBits( const SalTwoRect& rPosAry,
546 SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev )
548 if( ( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) ) ||
549 (pSrcGraphics && ( (pSrcGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) ) )
551 SalTwoRect aPosAry2 = rPosAry;
552 if( (pSrcGraphics && (pSrcGraphics->GetLayout() & SalLayoutFlags::BiDiRtl)) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) )
553 mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcOutDev );
554 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
555 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
556 copyBits( aPosAry2, pSrcGraphics );
558 else
559 copyBits( rPosAry, pSrcGraphics );
562 void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
563 const SalBitmap& rSalBitmap, const OutputDevice *pOutDev )
565 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
567 SalTwoRect aPosAry2 = rPosAry;
568 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
569 drawBitmap( aPosAry2, rSalBitmap );
571 else
572 drawBitmap( rPosAry, rSalBitmap );
575 void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
576 const SalBitmap& rSalBitmap,
577 const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev )
579 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
581 SalTwoRect aPosAry2 = rPosAry;
582 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
583 drawBitmap( aPosAry2, rSalBitmap, rTransparentBitmap );
585 else
586 drawBitmap( rPosAry, rSalBitmap, rTransparentBitmap );
589 void SalGraphics::DrawMask( const SalTwoRect& rPosAry,
590 const SalBitmap& rSalBitmap,
591 SalColor nMaskColor, const OutputDevice *pOutDev )
593 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
595 SalTwoRect aPosAry2 = rPosAry;
596 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
597 drawMask( aPosAry2, rSalBitmap, nMaskColor );
599 else
600 drawMask( rPosAry, rSalBitmap, nMaskColor );
603 SalBitmap* SalGraphics::GetBitmap( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev )
605 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
606 mirror( nX, nWidth, pOutDev );
607 return getBitmap( nX, nY, nWidth, nHeight );
610 SalColor SalGraphics::GetPixel( long nX, long nY, const OutputDevice *pOutDev )
612 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
613 mirror( nX, pOutDev );
614 return getPixel( nX, nY );
617 void SalGraphics::Invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags, const OutputDevice *pOutDev )
619 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
620 mirror( nX, nWidth, pOutDev );
621 invert( nX, nY, nWidth, nHeight, nFlags );
624 void SalGraphics::Invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags, const OutputDevice *pOutDev )
626 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
628 std::unique_ptr<SalPoint[]> pPtAry2(new SalPoint[nPoints]);
629 bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), pOutDev );
630 invert( nPoints, bCopied ? pPtAry2.get() : pPtAry, nFlags );
632 else
633 invert( nPoints, pPtAry, nFlags );
636 bool SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize, const OutputDevice *pOutDev )
638 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
639 mirror( nX, nWidth, pOutDev );
640 return drawEPS( nX, nY, nWidth, nHeight, pPtr, nSize );
643 bool SalGraphics::HitTestNativeScrollbar( ControlPart nPart, const tools::Rectangle& rControlRegion,
644 const Point& aPos, bool& rIsInside, const OutputDevice *pOutDev )
646 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
648 Point pt( aPos );
649 tools::Rectangle rgn( rControlRegion );
650 mirror( pt.X(), pOutDev );
651 mirror( rgn, pOutDev );
652 return hitTestNativeControl( ControlType::Scrollbar, nPart, rgn, pt, rIsInside );
654 else
655 return hitTestNativeControl( ControlType::Scrollbar, nPart, rControlRegion, aPos, rIsInside );
658 void SalGraphics::mirror( ImplControlValue& rVal, const OutputDevice* pOutDev ) const
660 switch( rVal.getType() )
662 case ControlType::Slider:
664 SliderValue* pSlVal = static_cast<SliderValue*>(&rVal);
665 mirror(pSlVal->maThumbRect,pOutDev);
667 break;
668 case ControlType::Scrollbar:
670 ScrollbarValue* pScVal = static_cast<ScrollbarValue*>(&rVal);
671 mirror(pScVal->maThumbRect,pOutDev);
672 mirror(pScVal->maButton1Rect,pOutDev);
673 mirror(pScVal->maButton2Rect,pOutDev);
675 break;
676 case ControlType::Spinbox:
677 case ControlType::SpinButtons:
679 SpinbuttonValue* pSpVal = static_cast<SpinbuttonValue*>(&rVal);
680 mirror(pSpVal->maUpperRect,pOutDev);
681 mirror(pSpVal->maLowerRect,pOutDev);
683 break;
684 case ControlType::Toolbar:
686 ToolbarValue* pTVal = static_cast<ToolbarValue*>(&rVal);
687 mirror(pTVal->maGripRect,pOutDev);
689 break;
690 default: break;
694 bool SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
695 ControlState nState, const ImplControlValue& aValue,
696 const OUString& aCaption, const OutputDevice *pOutDev )
698 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
700 tools::Rectangle rgn( rControlRegion );
701 tools::Rectangle aNull;
702 if (rgn != aNull)
703 mirror(rgn, pOutDev);
704 std::unique_ptr< ImplControlValue > mirrorValue( aValue.clone());
705 mirror( *mirrorValue, pOutDev );
706 bool bRet = drawNativeControl( nType, nPart, rgn, nState, *mirrorValue, aCaption );
707 return bRet;
709 else
710 return drawNativeControl( nType, nPart, rControlRegion, nState, aValue, aCaption );
713 bool SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion, ControlState nState,
714 const ImplControlValue& aValue,
715 tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion, const OutputDevice *pOutDev )
717 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
719 tools::Rectangle rgn( rControlRegion );
720 mirror( rgn, pOutDev );
721 std::unique_ptr< ImplControlValue > mirrorValue( aValue.clone());
722 mirror( *mirrorValue, pOutDev );
723 if( getNativeControlRegion( nType, nPart, rgn, nState, *mirrorValue, OUString(),
724 rNativeBoundingRegion, rNativeContentRegion ) )
726 mirror( rNativeBoundingRegion, pOutDev, true );
727 mirror( rNativeContentRegion, pOutDev, true );
728 return true;
730 return false;
732 else
733 return getNativeControlRegion( nType, nPart, rControlRegion, nState, aValue, OUString(),
734 rNativeBoundingRegion, rNativeContentRegion );
737 bool SalGraphics::BlendBitmap( const SalTwoRect& rPosAry,
738 const SalBitmap& rBitmap,
739 const OutputDevice *pOutDev )
741 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
743 SalTwoRect aPosAry2 = rPosAry;
744 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
745 return blendBitmap( aPosAry2, rBitmap );
747 else
748 return blendBitmap( rPosAry, rBitmap );
751 bool SalGraphics::BlendAlphaBitmap( const SalTwoRect& rPosAry,
752 const SalBitmap& rSrcBitmap,
753 const SalBitmap& rMaskBitmap,
754 const SalBitmap& rAlphaBitmap,
755 const OutputDevice *pOutDev )
757 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
759 SalTwoRect aPosAry2 = rPosAry;
760 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
761 return blendAlphaBitmap( aPosAry2, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
763 else
764 return blendAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
767 bool SalGraphics::DrawAlphaBitmap( const SalTwoRect& rPosAry,
768 const SalBitmap& rSourceBitmap,
769 const SalBitmap& rAlphaBitmap,
770 const OutputDevice *pOutDev )
772 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
774 SalTwoRect aPosAry2 = rPosAry;
775 mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
776 return drawAlphaBitmap( aPosAry2, rSourceBitmap, rAlphaBitmap );
778 else
779 return drawAlphaBitmap( rPosAry, rSourceBitmap, rAlphaBitmap );
782 bool SalGraphics::DrawTransformedBitmap(
783 const basegfx::B2DPoint& rNull,
784 const basegfx::B2DPoint& rX,
785 const basegfx::B2DPoint& rY,
786 const SalBitmap& rSourceBitmap,
787 const SalBitmap* pAlphaBitmap,
788 const OutputDevice* pOutDev)
790 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
792 mirror(rNull, pOutDev);
793 mirror(rX, pOutDev);
794 mirror(rY, pOutDev);
796 return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap);
798 else
800 return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap);
804 bool SalGraphics::DrawAlphaRect( long nX, long nY, long nWidth, long nHeight,
805 sal_uInt8 nTransparency, const OutputDevice *pOutDev )
807 if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (pOutDev && pOutDev->IsRTLEnabled()) )
808 mirror( nX, nWidth, pOutDev );
810 return drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency );
813 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */