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 <QtGraphics.hxx>
22 #include <QtBitmap.hxx>
23 #include <QtPainter.hxx>
25 #include <sal/log.hxx>
27 #include <QtGui/QPainter>
28 #include <QtGui/QScreen>
29 #include <QtGui/QWindow>
30 #include <QtWidgets/QWidget>
33 #include <basegfx/polygon/b2dpolygontools.hxx>
34 #include <basegfx/polygon/b2dpolypolygontools.hxx>
36 QtGraphicsBackend::QtGraphicsBackend(QtFrame
* pFrame
, QImage
* pQImage
)
39 , m_oLineColor(std::in_place
, 0x00, 0x00, 0x00)
40 , m_oFillColor(std::in_place
, 0xFF, 0xFF, 0XFF)
41 , m_eCompositionMode(QPainter::CompositionMode_SourceOver
)
46 QtGraphicsBackend::~QtGraphicsBackend() {}
48 const basegfx::B2DPoint
aHalfPointOfs(0.5, 0.5);
50 static void AddPolygonToPath(QPainterPath
& rPath
, const basegfx::B2DPolygon
& rPolygon
,
51 bool bClosePath
, bool bPixelSnap
, bool bLineDraw
)
53 const int nPointCount
= rPolygon
.count();
54 // short circuit if there is nothing to do
58 const bool bHasCurves
= rPolygon
.areControlPointsUsed();
59 for (int nPointIdx
= 0, nPrevIdx
= 0;; nPrevIdx
= nPointIdx
++)
61 int nClosedIdx
= nPointIdx
;
62 if (nPointIdx
>= nPointCount
)
64 // prepare to close last curve segment if needed
65 if (bClosePath
&& (nPointIdx
== nPointCount
))
71 basegfx::B2DPoint aPoint
= rPolygon
.getB2DPoint(nClosedIdx
);
75 // snap device coordinates to full pixels
76 aPoint
.setX(basegfx::fround(aPoint
.getX()));
77 aPoint
.setY(basegfx::fround(aPoint
.getY()));
81 aPoint
+= aHalfPointOfs
;
84 // first point => just move there
85 rPath
.moveTo(aPoint
.getX(), aPoint
.getY());
89 bool bPendingCurve
= false;
92 bPendingCurve
= rPolygon
.isNextControlPointUsed(nPrevIdx
);
93 bPendingCurve
|= rPolygon
.isPrevControlPointUsed(nClosedIdx
);
96 if (!bPendingCurve
) // line segment
97 rPath
.lineTo(aPoint
.getX(), aPoint
.getY());
98 else // cubic bezier segment
100 basegfx::B2DPoint aCP1
= rPolygon
.getNextControlPoint(nPrevIdx
);
101 basegfx::B2DPoint aCP2
= rPolygon
.getPrevControlPoint(nClosedIdx
);
104 aCP1
+= aHalfPointOfs
;
105 aCP2
+= aHalfPointOfs
;
107 rPath
.cubicTo(aCP1
.getX(), aCP1
.getY(), aCP2
.getX(), aCP2
.getY(), aPoint
.getX(),
113 rPath
.closeSubpath();
116 static bool AddPolyPolygonToPath(QPainterPath
& rPath
, const basegfx::B2DPolyPolygon
& rPolyPoly
,
117 bool bPixelSnap
, bool bLineDraw
)
119 if (rPolyPoly
.count() == 0)
121 for (auto const& rPolygon
: rPolyPoly
)
123 AddPolygonToPath(rPath
, rPolygon
, true, bPixelSnap
, bLineDraw
);
128 void QtGraphicsBackend::setClipRegion(const vcl::Region
& rRegion
)
130 if (rRegion
.IsRectangle())
132 m_aClipRegion
= toQRect(rRegion
.GetBoundRect());
133 if (!m_aClipPath
.isEmpty())
136 m_aClipPath
.swap(aPath
);
139 else if (!rRegion
.HasPolyPolygonOrB2DPolyPolygon())
142 RectangleVector aRectangles
;
143 rRegion
.GetRegionRectangles(aRectangles
);
144 for (const auto& rRect
: aRectangles
)
145 aQRegion
+= toQRect(rRect
);
146 m_aClipRegion
= aQRegion
;
147 if (!m_aClipPath
.isEmpty())
150 m_aClipPath
.swap(aPath
);
156 const basegfx::B2DPolyPolygon
aPolyClip(rRegion
.GetAsB2DPolyPolygon());
157 AddPolyPolygonToPath(aPath
, aPolyClip
, !getAntiAlias(), false);
158 m_aClipPath
.swap(aPath
);
159 if (!m_aClipRegion
.isEmpty())
162 m_aClipRegion
.swap(aRegion
);
167 void QtGraphicsBackend::ResetClipRegion()
170 m_aClipRegion
= QRegion(m_pQImage
->rect());
172 m_aClipRegion
= QRegion();
173 if (!m_aClipPath
.isEmpty())
176 m_aClipPath
.swap(aPath
);
180 void QtGraphicsBackend::drawPixel(tools::Long nX
, tools::Long nY
)
182 QtPainter
aPainter(*this);
183 aPainter
.drawPoint(nX
, nY
);
184 aPainter
.update(nX
, nY
, 1, 1);
187 void QtGraphicsBackend::drawPixel(tools::Long nX
, tools::Long nY
, Color nColor
)
189 QtPainter
aPainter(*this);
190 aPainter
.setPen(toQColor(nColor
));
191 aPainter
.setPen(Qt::SolidLine
);
192 aPainter
.drawPoint(nX
, nY
);
193 aPainter
.update(nX
, nY
, 1, 1);
196 void QtGraphicsBackend::drawLine(tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
198 QtPainter
aPainter(*this);
199 aPainter
.drawLine(nX1
, nY1
, nX2
, nY2
);
205 aPainter
.update(nX1
, nY1
, nX2
- nX1
+ 1, nY2
- nY1
+ 1);
208 void QtGraphicsBackend::drawRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
211 if (!m_oFillColor
&& !m_oLineColor
)
214 QtPainter
aPainter(*this, true);
216 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, aPainter
.brush());
218 aPainter
.drawRect(nX
, nY
, nWidth
- 1, nHeight
- 1);
219 aPainter
.update(nX
, nY
, nWidth
, nHeight
);
222 void QtGraphicsBackend::drawPolyLine(sal_uInt32 nPoints
, const Point
* pPtAry
)
227 QtPainter
aPainter(*this);
228 QPoint
* pPoints
= new QPoint
[nPoints
];
229 QPoint
aTopLeft(pPtAry
->getX(), pPtAry
->getY());
230 QPoint aBottomRight
= aTopLeft
;
231 for (sal_uInt32 i
= 0; i
< nPoints
; ++i
, ++pPtAry
)
233 pPoints
[i
] = QPoint(pPtAry
->getX(), pPtAry
->getY());
234 if (pPtAry
->getX() < aTopLeft
.x())
235 aTopLeft
.setX(pPtAry
->getX());
236 if (pPtAry
->getY() < aTopLeft
.y())
237 aTopLeft
.setY(pPtAry
->getY());
238 if (pPtAry
->getX() > aBottomRight
.x())
239 aBottomRight
.setX(pPtAry
->getX());
240 if (pPtAry
->getY() > aBottomRight
.y())
241 aBottomRight
.setY(pPtAry
->getY());
243 aPainter
.drawPolyline(pPoints
, nPoints
);
245 aPainter
.update(QRect(aTopLeft
, aBottomRight
));
248 void QtGraphicsBackend::drawPolygon(sal_uInt32 nPoints
, const Point
* pPtAry
)
250 QtPainter
aPainter(*this, true);
251 QPolygon
aPolygon(nPoints
);
252 for (sal_uInt32 i
= 0; i
< nPoints
; ++i
, ++pPtAry
)
253 aPolygon
.setPoint(i
, pPtAry
->getX(), pPtAry
->getY());
254 aPainter
.drawPolygon(aPolygon
);
255 aPainter
.update(aPolygon
.boundingRect());
258 void QtGraphicsBackend::drawPolyPolygon(sal_uInt32 nPolyCount
, const sal_uInt32
* pPoints
,
259 const Point
** ppPtAry
)
261 // ignore invisible polygons
262 if (!m_oFillColor
&& !m_oLineColor
)
266 for (sal_uInt32 nPoly
= 0; nPoly
< nPolyCount
; nPoly
++)
268 const sal_uInt32 nPoints
= pPoints
[nPoly
];
271 const Point
* pPtAry
= ppPtAry
[nPoly
];
272 aPath
.moveTo(pPtAry
->getX(), pPtAry
->getY());
274 for (sal_uInt32 nPoint
= 1; nPoint
< nPoints
; nPoint
++, pPtAry
++)
275 aPath
.lineTo(pPtAry
->getX(), pPtAry
->getY());
276 aPath
.closeSubpath();
280 QtPainter
aPainter(*this, true);
281 aPainter
.drawPath(aPath
);
282 aPainter
.update(aPath
.boundingRect());
285 void QtGraphicsBackend::drawPolyPolygon(const basegfx::B2DHomMatrix
& rObjectToDevice
,
286 const basegfx::B2DPolyPolygon
& rPolyPolygon
,
287 double fTransparency
)
289 // ignore invisible polygons
290 if (!m_oFillColor
&& !m_oLineColor
)
292 if ((fTransparency
>= 1.0) || (fTransparency
< 0))
295 // Fallback: Transform to DeviceCoordinates
296 basegfx::B2DPolyPolygon
aPolyPolygon(rPolyPolygon
);
297 aPolyPolygon
.transform(rObjectToDevice
);
300 // ignore empty polygons
301 if (!AddPolyPolygonToPath(aPath
, aPolyPolygon
, !getAntiAlias(), m_oLineColor
.has_value()))
304 QtPainter
aPainter(*this, true, 255 * (1.0 - fTransparency
));
305 aPainter
.drawPath(aPath
);
306 aPainter
.update(aPath
.boundingRect());
309 bool QtGraphicsBackend::drawPolyLineBezier(sal_uInt32
/*nPoints*/, const Point
* /*pPtAry*/,
310 const PolyFlags
* /*pFlgAry*/)
315 bool QtGraphicsBackend::drawPolygonBezier(sal_uInt32
/*nPoints*/, const Point
* /*pPtAry*/,
316 const PolyFlags
* /*pFlgAry*/)
321 bool QtGraphicsBackend::drawPolyPolygonBezier(sal_uInt32
/*nPoly*/, const sal_uInt32
* /*pPoints*/,
322 const Point
* const* /*pPtAry*/,
323 const PolyFlags
* const* /*pFlgAry*/)
328 bool QtGraphicsBackend::drawPolyLine(const basegfx::B2DHomMatrix
& rObjectToDevice
,
329 const basegfx::B2DPolygon
& rPolyLine
, double fTransparency
,
331 const std::vector
<double>* pStroke
, // MM01
332 basegfx::B2DLineJoin eLineJoin
, css::drawing::LineCap eLineCap
,
333 double fMiterMinimumAngle
, bool bPixelSnapHairline
)
335 if (!m_oFillColor
&& !m_oLineColor
)
340 // MM01 check done for simple reasons
341 if (!rPolyLine
.count() || fTransparency
< 0.0 || fTransparency
> 1.0)
346 // MM01 need to do line dashing as fallback stuff here now
347 const double fDotDashLength(
348 nullptr != pStroke
? std::accumulate(pStroke
->begin(), pStroke
->end(), 0.0) : 0.0);
349 const bool bStrokeUsed(0.0 != fDotDashLength
);
350 assert(!bStrokeUsed
|| (bStrokeUsed
&& pStroke
));
351 basegfx::B2DPolyPolygon aPolyPolygonLine
;
356 basegfx::utils::applyLineDashing(rPolyLine
, // source
358 &aPolyPolygonLine
, // target for lines
359 nullptr, // target for gaps
360 fDotDashLength
); // full length if available
364 // no line dashing, just copy
365 aPolyPolygonLine
.append(rPolyLine
);
368 // Transform to DeviceCoordinates, get DeviceLineWidth, execute PixelSnapHairline
369 aPolyPolygonLine
.transform(rObjectToDevice
);
370 if (bPixelSnapHairline
)
372 aPolyPolygonLine
= basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aPolyPolygonLine
);
375 // tdf#124848 get correct LineWidth in discrete coordinates,
376 if (fLineWidth
== 0) // hairline
378 else // Adjust line width for object-to-device scale.
379 fLineWidth
= (rObjectToDevice
* basegfx::B2DVector(fLineWidth
, 0)).getLength();
381 // setup poly-polygon path
384 // MM01 todo - I assume that this is OKAY to be done in one run for Qt,
385 // but this NEEDS to be checked/verified
386 for (sal_uInt32
a(0); a
< aPolyPolygonLine
.count(); a
++)
388 const basegfx::B2DPolygon
aPolyLine(aPolyPolygonLine
.getB2DPolygon(a
));
389 AddPolygonToPath(aPath
, aPolyLine
, aPolyLine
.isClosed(), !getAntiAlias(), true);
392 QtPainter
aPainter(*this, false, 255 * (1.0 - fTransparency
));
394 // setup line attributes
395 QPen aPen
= aPainter
.pen();
396 aPen
.setWidth(fLineWidth
);
400 case basegfx::B2DLineJoin::Bevel
:
401 aPen
.setJoinStyle(Qt::BevelJoin
);
403 case basegfx::B2DLineJoin::Round
:
404 aPen
.setJoinStyle(Qt::RoundJoin
);
406 case basegfx::B2DLineJoin::NONE
:
407 case basegfx::B2DLineJoin::Miter
:
408 aPen
.setMiterLimit(1.0 / sin(fMiterMinimumAngle
/ 2.0));
409 aPen
.setJoinStyle(Qt::MiterJoin
);
415 default: // css::drawing::LineCap_BUTT:
416 aPen
.setCapStyle(Qt::FlatCap
);
418 case css::drawing::LineCap_ROUND
:
419 aPen
.setCapStyle(Qt::RoundCap
);
421 case css::drawing::LineCap_SQUARE
:
422 aPen
.setCapStyle(Qt::SquareCap
);
426 aPainter
.setPen(aPen
);
427 aPainter
.drawPath(aPath
);
428 aPainter
.update(aPath
.boundingRect());
432 bool QtGraphicsBackend::drawGradient(const tools::PolyPolygon
& /*rPolyPolygon*/,
433 const Gradient
& /*rGradient*/)
438 bool QtGraphicsBackend::implDrawGradient(basegfx::B2DPolyPolygon
const& /*rPolyPolygon*/,
439 SalGradient
const& /*rGradient*/)
444 void QtGraphicsBackend::drawScaledImage(const SalTwoRect
& rPosAry
, const QImage
& rImage
)
446 QtPainter
aPainter(*this);
447 QRect
aSrcRect(rPosAry
.mnSrcX
, rPosAry
.mnSrcY
, rPosAry
.mnSrcWidth
, rPosAry
.mnSrcHeight
);
448 QRect
aDestRect(rPosAry
.mnDestX
, rPosAry
.mnDestY
, rPosAry
.mnDestWidth
, rPosAry
.mnDestHeight
);
449 aPainter
.drawImage(aDestRect
, rImage
, aSrcRect
);
450 aPainter
.update(aDestRect
);
453 void QtGraphicsBackend::copyArea(tools::Long nDestX
, tools::Long nDestY
, tools::Long nSrcX
,
454 tools::Long nSrcY
, tools::Long nSrcWidth
, tools::Long nSrcHeight
,
455 bool /*bWindowInvalidate*/)
457 if (nDestX
== nSrcX
&& nDestY
== nSrcY
)
460 SalTwoRect
aTR(nSrcX
, nSrcY
, nSrcWidth
, nSrcHeight
, nDestX
, nDestY
, nSrcWidth
, nSrcHeight
);
462 QImage
* pImage
= m_pQImage
;
463 QImage aImage
= pImage
->copy(aTR
.mnSrcX
, aTR
.mnSrcY
, aTR
.mnSrcWidth
, aTR
.mnSrcHeight
);
468 drawScaledImage(aTR
, *pImage
);
471 void QtGraphicsBackend::copyBits(const SalTwoRect
& rPosAry
, SalGraphics
* pSrcGraphics
)
473 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
474 || rPosAry
.mnDestHeight
<= 0)
477 QImage aImage
, *pImage
;
478 SalTwoRect aPosAry
= rPosAry
;
484 = pImage
->copy(rPosAry
.mnSrcX
, rPosAry
.mnSrcY
, rPosAry
.mnSrcWidth
, rPosAry
.mnSrcHeight
);
490 pImage
= static_cast<QtGraphics
*>(pSrcGraphics
)->getQImage();
492 drawScaledImage(aPosAry
, *pImage
);
495 void QtGraphicsBackend::drawBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
)
497 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
498 || rPosAry
.mnDestHeight
<= 0)
501 const QImage
* pImage
= static_cast<const QtBitmap
*>(&rSalBitmap
)->GetQImage();
505 drawScaledImage(rPosAry
, *pImage
);
508 void QtGraphicsBackend::drawBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& /*rSalBitmap*/,
509 const SalBitmap
& /*rTransparentBitmap*/)
511 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
512 || rPosAry
.mnDestHeight
<= 0)
515 assert(rPosAry
.mnSrcWidth
== rPosAry
.mnDestWidth
);
516 assert(rPosAry
.mnSrcHeight
== rPosAry
.mnDestHeight
);
519 void QtGraphicsBackend::drawMask(const SalTwoRect
& rPosAry
, const SalBitmap
& /*rSalBitmap*/,
520 Color
/*nMaskColor*/)
522 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
523 || rPosAry
.mnDestHeight
<= 0)
526 assert(rPosAry
.mnSrcWidth
== rPosAry
.mnDestWidth
);
527 assert(rPosAry
.mnSrcHeight
== rPosAry
.mnDestHeight
);
530 std::shared_ptr
<SalBitmap
> QtGraphicsBackend::getBitmap(tools::Long nX
, tools::Long nY
,
531 tools::Long nWidth
, tools::Long nHeight
)
533 return std::make_shared
<QtBitmap
>(m_pQImage
->copy(nX
, nY
, nWidth
, nHeight
));
536 Color
QtGraphicsBackend::getPixel(tools::Long nX
, tools::Long nY
)
538 return Color(ColorTransparency
, m_pQImage
->pixel(nX
, nY
));
541 void QtGraphicsBackend::invert(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
542 tools::Long nHeight
, SalInvert nFlags
)
544 QtPainter
aPainter(*this);
545 if (SalInvert::N50
& nFlags
)
547 aPainter
.setCompositionMode(QPainter::RasterOp_SourceXorDestination
);
548 QBrush
aBrush(Qt::white
, Qt::Dense4Pattern
);
549 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, aBrush
);
553 if (SalInvert::TrackFrame
& nFlags
)
555 aPainter
.setCompositionMode(QPainter::RasterOp_SourceXorDestination
);
556 QPen
aPen(Qt::white
);
557 aPen
.setStyle(Qt::DotLine
);
558 aPainter
.setPen(aPen
);
559 aPainter
.drawRect(nX
, nY
, nWidth
, nHeight
);
563 aPainter
.setCompositionMode(QPainter::RasterOp_SourceXorDestination
);
564 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, Qt::white
);
567 aPainter
.update(nX
, nY
, nWidth
, nHeight
);
570 void QtGraphicsBackend::invert(sal_uInt32
/*nPoints*/, const Point
* /*pPtAry*/,
571 SalInvert
/*nFlags*/)
575 bool QtGraphicsBackend::drawEPS(tools::Long
/*nX*/, tools::Long
/*nY*/, tools::Long
/*nWidth*/,
576 tools::Long
/*nHeight*/, void* /*pPtr*/, sal_uInt32
/*nSize*/)
581 bool QtGraphicsBackend::blendBitmap(const SalTwoRect
&, const SalBitmap
& /*rBitmap*/)
586 bool QtGraphicsBackend::blendAlphaBitmap(const SalTwoRect
&, const SalBitmap
& /*rSrcBitmap*/,
587 const SalBitmap
& /*rMaskBitmap*/,
588 const SalBitmap
& /*rAlphaBitmap*/)
593 static QImage
getAlphaImage(const SalBitmap
& rSourceBitmap
, const SalBitmap
& rAlphaBitmap
)
595 assert(rSourceBitmap
.GetSize() == rAlphaBitmap
.GetSize());
596 assert(rAlphaBitmap
.GetBitCount() == 8 || rAlphaBitmap
.GetBitCount() == 1);
598 QImage aAlphaMask
= *static_cast<const QtBitmap
*>(&rAlphaBitmap
)->GetQImage();
600 const QImage
* pBitmap
= static_cast<const QtBitmap
*>(&rSourceBitmap
)->GetQImage();
601 QImage aImage
= pBitmap
->convertToFormat(Qt_DefaultFormat32
);
602 aImage
.setAlphaChannel(aAlphaMask
);
606 bool QtGraphicsBackend::drawAlphaBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& rSourceBitmap
,
607 const SalBitmap
& rAlphaBitmap
)
609 drawScaledImage(rPosAry
, getAlphaImage(rSourceBitmap
, rAlphaBitmap
));
613 bool QtGraphicsBackend::drawTransformedBitmap(const basegfx::B2DPoint
& rNull
,
614 const basegfx::B2DPoint
& rX
,
615 const basegfx::B2DPoint
& rY
,
616 const SalBitmap
& rSourceBitmap
,
617 const SalBitmap
* pAlphaBitmap
, double fAlpha
)
621 aImage
= *static_cast<const QtBitmap
*>(&rSourceBitmap
)->GetQImage();
623 aImage
= getAlphaImage(rSourceBitmap
, *pAlphaBitmap
);
625 const basegfx::B2DVector aXRel
= rX
- rNull
;
626 const basegfx::B2DVector aYRel
= rY
- rNull
;
628 QtPainter
aPainter(*this);
629 aPainter
.setOpacity(fAlpha
);
630 aPainter
.setTransform(QTransform(aXRel
.getX() / aImage
.width(), aXRel
.getY() / aImage
.width(),
631 aYRel
.getX() / aImage
.height(), aYRel
.getY() / aImage
.height(),
632 rNull
.getX(), rNull
.getY()));
633 aPainter
.drawImage(QPoint(0, 0), aImage
);
634 aPainter
.update(aImage
.rect());
638 bool QtGraphicsBackend::hasFastDrawTransformedBitmap() const { return false; }
640 bool QtGraphicsBackend::drawAlphaRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
641 tools::Long nHeight
, sal_uInt8 nTransparency
)
643 if (!m_oFillColor
&& !m_oLineColor
)
645 assert(nTransparency
<= 100);
646 if (nTransparency
> 100)
648 QtPainter
aPainter(*this, true, (100 - nTransparency
) * (255.0 / 100));
650 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, aPainter
.brush());
652 aPainter
.drawRect(nX
, nY
, nWidth
- 1, nHeight
- 1);
653 aPainter
.update(nX
, nY
, nWidth
, nHeight
);
657 sal_uInt16
QtGraphicsBackend::GetBitCount() const { return getFormatBits(m_pQImage
->format()); }
659 tools::Long
QtGraphicsBackend::GetGraphicsWidth() const { return m_pQImage
->width(); }
661 void QtGraphicsBackend::SetLineColor() { m_oLineColor
= std::nullopt
; }
663 void QtGraphicsBackend::SetLineColor(Color nColor
) { m_oLineColor
= nColor
; }
665 void QtGraphicsBackend::SetFillColor() { m_oFillColor
= std::nullopt
; }
667 void QtGraphicsBackend::SetFillColor(Color nColor
) { m_oFillColor
= nColor
; }
669 void QtGraphicsBackend::SetXORMode(bool bSet
, bool)
672 m_eCompositionMode
= QPainter::CompositionMode_Xor
;
674 m_eCompositionMode
= QPainter::CompositionMode_SourceOver
;
677 void QtGraphicsBackend::SetROPLineColor(SalROPColor
/*nROPColor*/) {}
679 void QtGraphicsBackend::SetROPFillColor(SalROPColor
/*nROPColor*/) {}
681 bool QtGraphicsBackend::supportsOperation(OutDevSupportType eType
) const
685 case OutDevSupportType::TransparentRect
:
692 void QtGraphics::GetResolution(sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
695 if ((pForceDpi
= getenv("SAL_FORCEDPI")))
697 OString
sForceDPI(pForceDpi
);
698 rDPIX
= rDPIY
= sForceDPI
.toInt32();
705 QScreen
* pScreen
= m_pFrame
->GetQWidget()->screen();
706 rDPIX
= pScreen
->logicalDotsPerInchX() * pScreen
->devicePixelRatio() + 0.5;
707 rDPIY
= pScreen
->logicalDotsPerInchY() * pScreen
->devicePixelRatio() + 0.5;
710 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */