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_aLineColor(0x00, 0x00, 0x00)
40 , m_aFillColor(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 bool 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
);
168 void QtGraphicsBackend::ResetClipRegion()
171 m_aClipRegion
= QRegion(m_pQImage
->rect());
173 m_aClipRegion
= QRegion();
174 if (!m_aClipPath
.isEmpty())
177 m_aClipPath
.swap(aPath
);
181 void QtGraphicsBackend::drawPixel(tools::Long nX
, tools::Long nY
)
183 QtPainter
aPainter(*this);
184 aPainter
.drawPoint(nX
, nY
);
185 aPainter
.update(nX
, nY
, 1, 1);
188 void QtGraphicsBackend::drawPixel(tools::Long nX
, tools::Long nY
, Color nColor
)
190 QtPainter
aPainter(*this);
191 aPainter
.setPen(toQColor(nColor
));
192 aPainter
.setPen(Qt::SolidLine
);
193 aPainter
.drawPoint(nX
, nY
);
194 aPainter
.update(nX
, nY
, 1, 1);
197 void QtGraphicsBackend::drawLine(tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
199 QtPainter
aPainter(*this);
200 aPainter
.drawLine(nX1
, nY1
, nX2
, nY2
);
215 aPainter
.update(nX1
, nY1
, nX2
- nX1
+ 1, nY2
- nY1
+ 1);
218 void QtGraphicsBackend::drawRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
221 if (SALCOLOR_NONE
== m_aFillColor
&& SALCOLOR_NONE
== m_aLineColor
)
224 QtPainter
aPainter(*this, true);
225 if (SALCOLOR_NONE
!= m_aFillColor
)
226 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, aPainter
.brush());
227 if (SALCOLOR_NONE
!= m_aLineColor
)
228 aPainter
.drawRect(nX
, nY
, nWidth
- 1, nHeight
- 1);
229 aPainter
.update(nX
, nY
, nWidth
, nHeight
);
232 void QtGraphicsBackend::drawPolyLine(sal_uInt32 nPoints
, const Point
* pPtAry
)
237 QtPainter
aPainter(*this);
238 QPoint
* pPoints
= new QPoint
[nPoints
];
239 QPoint
aTopLeft(pPtAry
->getX(), pPtAry
->getY());
240 QPoint aBottomRight
= aTopLeft
;
241 for (sal_uInt32 i
= 0; i
< nPoints
; ++i
, ++pPtAry
)
243 pPoints
[i
] = QPoint(pPtAry
->getX(), pPtAry
->getY());
244 if (pPtAry
->getX() < aTopLeft
.x())
245 aTopLeft
.setX(pPtAry
->getX());
246 if (pPtAry
->getY() < aTopLeft
.y())
247 aTopLeft
.setY(pPtAry
->getY());
248 if (pPtAry
->getX() > aBottomRight
.x())
249 aBottomRight
.setX(pPtAry
->getX());
250 if (pPtAry
->getY() > aBottomRight
.y())
251 aBottomRight
.setY(pPtAry
->getY());
253 aPainter
.drawPolyline(pPoints
, nPoints
);
255 aPainter
.update(QRect(aTopLeft
, aBottomRight
));
258 void QtGraphicsBackend::drawPolygon(sal_uInt32 nPoints
, const Point
* pPtAry
)
260 QtPainter
aPainter(*this, true);
261 QPolygon
aPolygon(nPoints
);
262 for (sal_uInt32 i
= 0; i
< nPoints
; ++i
, ++pPtAry
)
263 aPolygon
.setPoint(i
, pPtAry
->getX(), pPtAry
->getY());
264 aPainter
.drawPolygon(aPolygon
);
265 aPainter
.update(aPolygon
.boundingRect());
268 void QtGraphicsBackend::drawPolyPolygon(sal_uInt32 nPolyCount
, const sal_uInt32
* pPoints
,
269 const Point
** ppPtAry
)
271 // ignore invisible polygons
272 if (SALCOLOR_NONE
== m_aFillColor
&& SALCOLOR_NONE
== m_aLineColor
)
276 for (sal_uInt32 nPoly
= 0; nPoly
< nPolyCount
; nPoly
++)
278 const sal_uInt32 nPoints
= pPoints
[nPoly
];
281 const Point
* pPtAry
= ppPtAry
[nPoly
];
282 aPath
.moveTo(pPtAry
->getX(), pPtAry
->getY());
284 for (sal_uInt32 nPoint
= 1; nPoint
< nPoints
; nPoint
++, pPtAry
++)
285 aPath
.lineTo(pPtAry
->getX(), pPtAry
->getY());
286 aPath
.closeSubpath();
290 QtPainter
aPainter(*this, true);
291 aPainter
.drawPath(aPath
);
292 aPainter
.update(aPath
.boundingRect());
295 bool QtGraphicsBackend::drawPolyPolygon(const basegfx::B2DHomMatrix
& rObjectToDevice
,
296 const basegfx::B2DPolyPolygon
& rPolyPolygon
,
297 double fTransparency
)
299 // ignore invisible polygons
300 if (SALCOLOR_NONE
== m_aFillColor
&& SALCOLOR_NONE
== m_aLineColor
)
302 if ((fTransparency
>= 1.0) || (fTransparency
< 0))
305 // Fallback: Transform to DeviceCoordinates
306 basegfx::B2DPolyPolygon
aPolyPolygon(rPolyPolygon
);
307 aPolyPolygon
.transform(rObjectToDevice
);
310 // ignore empty polygons
311 if (!AddPolyPolygonToPath(aPath
, aPolyPolygon
, !getAntiAlias(), m_aLineColor
!= SALCOLOR_NONE
))
314 QtPainter
aPainter(*this, true, 255 * (1.0 - fTransparency
));
315 aPainter
.drawPath(aPath
);
316 aPainter
.update(aPath
.boundingRect());
320 bool QtGraphicsBackend::drawPolyLineBezier(sal_uInt32
/*nPoints*/, const Point
* /*pPtAry*/,
321 const PolyFlags
* /*pFlgAry*/)
326 bool QtGraphicsBackend::drawPolygonBezier(sal_uInt32
/*nPoints*/, const Point
* /*pPtAry*/,
327 const PolyFlags
* /*pFlgAry*/)
332 bool QtGraphicsBackend::drawPolyPolygonBezier(sal_uInt32
/*nPoly*/, const sal_uInt32
* /*pPoints*/,
333 const Point
* const* /*pPtAry*/,
334 const PolyFlags
* const* /*pFlgAry*/)
339 bool QtGraphicsBackend::drawPolyLine(const basegfx::B2DHomMatrix
& rObjectToDevice
,
340 const basegfx::B2DPolygon
& rPolyLine
, double fTransparency
,
342 const std::vector
<double>* pStroke
, // MM01
343 basegfx::B2DLineJoin eLineJoin
, css::drawing::LineCap eLineCap
,
344 double fMiterMinimumAngle
, bool bPixelSnapHairline
)
346 if (SALCOLOR_NONE
== m_aFillColor
&& SALCOLOR_NONE
== m_aLineColor
)
351 // MM01 check done for simple reasons
352 if (!rPolyLine
.count() || fTransparency
< 0.0 || fTransparency
> 1.0)
357 // MM01 need to do line dashing as fallback stuff here now
358 const double fDotDashLength(
359 nullptr != pStroke
? std::accumulate(pStroke
->begin(), pStroke
->end(), 0.0) : 0.0);
360 const bool bStrokeUsed(0.0 != fDotDashLength
);
361 assert(!bStrokeUsed
|| (bStrokeUsed
&& pStroke
));
362 basegfx::B2DPolyPolygon aPolyPolygonLine
;
367 basegfx::utils::applyLineDashing(rPolyLine
, // source
369 &aPolyPolygonLine
, // target for lines
370 nullptr, // target for gaps
371 fDotDashLength
); // full length if available
375 // no line dashing, just copy
376 aPolyPolygonLine
.append(rPolyLine
);
379 // Transform to DeviceCoordinates, get DeviceLineWidth, execute PixelSnapHairline
380 aPolyPolygonLine
.transform(rObjectToDevice
);
381 if (bPixelSnapHairline
)
383 aPolyPolygonLine
= basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aPolyPolygonLine
);
386 // tdf#124848 get correct LineWidth in discrete coordinates,
387 if (fLineWidth
== 0) // hairline
389 else // Adjust line width for object-to-device scale.
390 fLineWidth
= (rObjectToDevice
* basegfx::B2DVector(fLineWidth
, 0)).getLength();
392 // setup poly-polygon path
395 // MM01 todo - I assume that this is OKAY to be done in one run for Qt,
396 // but this NEEDS to be checked/verified
397 for (sal_uInt32
a(0); a
< aPolyPolygonLine
.count(); a
++)
399 const basegfx::B2DPolygon
aPolyLine(aPolyPolygonLine
.getB2DPolygon(a
));
400 AddPolygonToPath(aPath
, aPolyLine
, aPolyLine
.isClosed(), !getAntiAlias(), true);
403 QtPainter
aPainter(*this, false, 255 * (1.0 - fTransparency
));
405 // setup line attributes
406 QPen aPen
= aPainter
.pen();
407 aPen
.setWidth(fLineWidth
);
411 case basegfx::B2DLineJoin::Bevel
:
412 aPen
.setJoinStyle(Qt::BevelJoin
);
414 case basegfx::B2DLineJoin::Round
:
415 aPen
.setJoinStyle(Qt::RoundJoin
);
417 case basegfx::B2DLineJoin::NONE
:
418 case basegfx::B2DLineJoin::Miter
:
419 aPen
.setMiterLimit(1.0 / sin(fMiterMinimumAngle
/ 2.0));
420 aPen
.setJoinStyle(Qt::MiterJoin
);
426 default: // css::drawing::LineCap_BUTT:
427 aPen
.setCapStyle(Qt::FlatCap
);
429 case css::drawing::LineCap_ROUND
:
430 aPen
.setCapStyle(Qt::RoundCap
);
432 case css::drawing::LineCap_SQUARE
:
433 aPen
.setCapStyle(Qt::SquareCap
);
437 aPainter
.setPen(aPen
);
438 aPainter
.drawPath(aPath
);
439 aPainter
.update(aPath
.boundingRect());
443 bool QtGraphicsBackend::drawGradient(const tools::PolyPolygon
& /*rPolyPolygon*/,
444 const Gradient
& /*rGradient*/)
449 bool QtGraphicsBackend::implDrawGradient(basegfx::B2DPolyPolygon
const& /*rPolyPolygon*/,
450 SalGradient
const& /*rGradient*/)
455 void QtGraphicsBackend::drawScaledImage(const SalTwoRect
& rPosAry
, const QImage
& rImage
)
457 QtPainter
aPainter(*this);
458 QRect
aSrcRect(rPosAry
.mnSrcX
, rPosAry
.mnSrcY
, rPosAry
.mnSrcWidth
, rPosAry
.mnSrcHeight
);
459 QRect
aDestRect(rPosAry
.mnDestX
, rPosAry
.mnDestY
, rPosAry
.mnDestWidth
, rPosAry
.mnDestHeight
);
460 aPainter
.drawImage(aDestRect
, rImage
, aSrcRect
);
461 aPainter
.update(aDestRect
);
464 void QtGraphicsBackend::copyArea(tools::Long nDestX
, tools::Long nDestY
, tools::Long nSrcX
,
465 tools::Long nSrcY
, tools::Long nSrcWidth
, tools::Long nSrcHeight
,
466 bool /*bWindowInvalidate*/)
468 if (nDestX
== nSrcX
&& nDestY
== nSrcY
)
471 SalTwoRect
aTR(nSrcX
, nSrcY
, nSrcWidth
, nSrcHeight
, nDestX
, nDestY
, nSrcWidth
, nSrcHeight
);
473 QImage
* pImage
= m_pQImage
;
474 QImage aImage
= pImage
->copy(aTR
.mnSrcX
, aTR
.mnSrcY
, aTR
.mnSrcWidth
, aTR
.mnSrcHeight
);
479 drawScaledImage(aTR
, *pImage
);
482 void QtGraphicsBackend::copyBits(const SalTwoRect
& rPosAry
, SalGraphics
* pSrcGraphics
)
484 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
485 || rPosAry
.mnDestHeight
<= 0)
488 QImage aImage
, *pImage
;
489 SalTwoRect aPosAry
= rPosAry
;
495 = pImage
->copy(rPosAry
.mnSrcX
, rPosAry
.mnSrcY
, rPosAry
.mnSrcWidth
, rPosAry
.mnSrcHeight
);
501 pImage
= static_cast<QtGraphics
*>(pSrcGraphics
)->getQImage();
503 drawScaledImage(aPosAry
, *pImage
);
506 void QtGraphicsBackend::drawBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
)
508 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
509 || rPosAry
.mnDestHeight
<= 0)
512 const QImage
* pImage
= static_cast<const QtBitmap
*>(&rSalBitmap
)->GetQImage();
516 drawScaledImage(rPosAry
, *pImage
);
519 void QtGraphicsBackend::drawBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& /*rSalBitmap*/,
520 const SalBitmap
& /*rTransparentBitmap*/)
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 void QtGraphicsBackend::drawMask(const SalTwoRect
& rPosAry
, const SalBitmap
& /*rSalBitmap*/,
531 Color
/*nMaskColor*/)
533 if (rPosAry
.mnSrcWidth
<= 0 || rPosAry
.mnSrcHeight
<= 0 || rPosAry
.mnDestWidth
<= 0
534 || rPosAry
.mnDestHeight
<= 0)
537 assert(rPosAry
.mnSrcWidth
== rPosAry
.mnDestWidth
);
538 assert(rPosAry
.mnSrcHeight
== rPosAry
.mnDestHeight
);
541 std::shared_ptr
<SalBitmap
> QtGraphicsBackend::getBitmap(tools::Long nX
, tools::Long nY
,
542 tools::Long nWidth
, tools::Long nHeight
)
544 return std::make_shared
<QtBitmap
>(m_pQImage
->copy(nX
, nY
, nWidth
, nHeight
));
547 Color
QtGraphicsBackend::getPixel(tools::Long nX
, tools::Long nY
)
549 return Color(ColorTransparency
, m_pQImage
->pixel(nX
, nY
));
552 void QtGraphicsBackend::invert(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
553 tools::Long nHeight
, SalInvert nFlags
)
555 QtPainter
aPainter(*this);
556 if (SalInvert::N50
& nFlags
)
558 aPainter
.setCompositionMode(QPainter::RasterOp_SourceXorDestination
);
559 QBrush
aBrush(Qt::white
, Qt::Dense4Pattern
);
560 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, aBrush
);
564 if (SalInvert::TrackFrame
& nFlags
)
566 aPainter
.setCompositionMode(QPainter::RasterOp_SourceXorDestination
);
567 QPen
aPen(Qt::white
);
568 aPen
.setStyle(Qt::DotLine
);
569 aPainter
.setPen(aPen
);
570 aPainter
.drawRect(nX
, nY
, nWidth
, nHeight
);
574 aPainter
.setCompositionMode(QPainter::RasterOp_SourceXorDestination
);
575 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, Qt::white
);
578 aPainter
.update(nX
, nY
, nWidth
, nHeight
);
581 void QtGraphicsBackend::invert(sal_uInt32
/*nPoints*/, const Point
* /*pPtAry*/,
582 SalInvert
/*nFlags*/)
586 bool QtGraphicsBackend::drawEPS(tools::Long
/*nX*/, tools::Long
/*nY*/, tools::Long
/*nWidth*/,
587 tools::Long
/*nHeight*/, void* /*pPtr*/, sal_uInt32
/*nSize*/)
592 bool QtGraphicsBackend::blendBitmap(const SalTwoRect
&, const SalBitmap
& /*rBitmap*/)
597 bool QtGraphicsBackend::blendAlphaBitmap(const SalTwoRect
&, const SalBitmap
& /*rSrcBitmap*/,
598 const SalBitmap
& /*rMaskBitmap*/,
599 const SalBitmap
& /*rAlphaBitmap*/)
604 static QImage
getAlphaImage(const SalBitmap
& rSourceBitmap
, const SalBitmap
& rAlphaBitmap
)
606 assert(rSourceBitmap
.GetSize() == rAlphaBitmap
.GetSize());
607 assert(rAlphaBitmap
.GetBitCount() == 8 || rAlphaBitmap
.GetBitCount() == 1);
609 QImage aAlphaMask
= *static_cast<const QtBitmap
*>(&rAlphaBitmap
)->GetQImage();
610 aAlphaMask
.invertPixels();
612 const QImage
* pBitmap
= static_cast<const QtBitmap
*>(&rSourceBitmap
)->GetQImage();
613 QImage aImage
= pBitmap
->convertToFormat(Qt_DefaultFormat32
);
614 aImage
.setAlphaChannel(aAlphaMask
);
618 bool QtGraphicsBackend::drawAlphaBitmap(const SalTwoRect
& rPosAry
, const SalBitmap
& rSourceBitmap
,
619 const SalBitmap
& rAlphaBitmap
)
621 drawScaledImage(rPosAry
, getAlphaImage(rSourceBitmap
, rAlphaBitmap
));
625 bool QtGraphicsBackend::drawTransformedBitmap(const basegfx::B2DPoint
& rNull
,
626 const basegfx::B2DPoint
& rX
,
627 const basegfx::B2DPoint
& rY
,
628 const SalBitmap
& rSourceBitmap
,
629 const SalBitmap
* pAlphaBitmap
, double fAlpha
)
633 aImage
= *static_cast<const QtBitmap
*>(&rSourceBitmap
)->GetQImage();
635 aImage
= getAlphaImage(rSourceBitmap
, *pAlphaBitmap
);
637 const basegfx::B2DVector aXRel
= rX
- rNull
;
638 const basegfx::B2DVector aYRel
= rY
- rNull
;
640 QtPainter
aPainter(*this);
641 aPainter
.setOpacity(fAlpha
);
642 aPainter
.setTransform(QTransform(aXRel
.getX() / aImage
.width(), aXRel
.getY() / aImage
.width(),
643 aYRel
.getX() / aImage
.height(), aYRel
.getY() / aImage
.height(),
644 rNull
.getX(), rNull
.getY()));
645 aPainter
.drawImage(QPoint(0, 0), aImage
);
646 aPainter
.update(aImage
.rect());
650 bool QtGraphicsBackend::hasFastDrawTransformedBitmap() const { return false; }
652 bool QtGraphicsBackend::drawAlphaRect(tools::Long nX
, tools::Long nY
, tools::Long nWidth
,
653 tools::Long nHeight
, sal_uInt8 nTransparency
)
655 if (SALCOLOR_NONE
== m_aFillColor
&& SALCOLOR_NONE
== m_aLineColor
)
657 assert(nTransparency
<= 100);
658 if (nTransparency
> 100)
660 QtPainter
aPainter(*this, true, (100 - nTransparency
) * (255.0 / 100));
661 if (SALCOLOR_NONE
!= m_aFillColor
)
662 aPainter
.fillRect(nX
, nY
, nWidth
, nHeight
, aPainter
.brush());
663 if (SALCOLOR_NONE
!= m_aLineColor
)
664 aPainter
.drawRect(nX
, nY
, nWidth
- 1, nHeight
- 1);
665 aPainter
.update(nX
, nY
, nWidth
, nHeight
);
669 sal_uInt16
QtGraphicsBackend::GetBitCount() const { return getFormatBits(m_pQImage
->format()); }
671 tools::Long
QtGraphicsBackend::GetGraphicsWidth() const { return m_pQImage
->width(); }
673 void QtGraphicsBackend::SetLineColor() { m_aLineColor
= SALCOLOR_NONE
; }
675 void QtGraphicsBackend::SetLineColor(Color nColor
) { m_aLineColor
= nColor
; }
677 void QtGraphicsBackend::SetFillColor() { m_aFillColor
= SALCOLOR_NONE
; }
679 void QtGraphicsBackend::SetFillColor(Color nColor
) { m_aFillColor
= nColor
; }
681 void QtGraphicsBackend::SetXORMode(bool bSet
, bool)
684 m_eCompositionMode
= QPainter::CompositionMode_Xor
;
686 m_eCompositionMode
= QPainter::CompositionMode_SourceOver
;
689 void QtGraphicsBackend::SetROPLineColor(SalROPColor
/*nROPColor*/) {}
691 void QtGraphicsBackend::SetROPFillColor(SalROPColor
/*nROPColor*/) {}
693 bool QtGraphicsBackend::supportsOperation(OutDevSupportType eType
) const
697 case OutDevSupportType::B2DDraw
:
698 case OutDevSupportType::TransparentRect
:
705 void QtGraphics::GetResolution(sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
708 if ((pForceDpi
= getenv("SAL_FORCEDPI")))
710 OString
sForceDPI(pForceDpi
);
711 rDPIX
= rDPIY
= sForceDPI
.toInt32();
718 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
719 QScreen
* pScreen
= m_pFrame
->GetQWidget()->screen();
721 if (!m_pFrame
->GetQWidget()->window()->windowHandle())
724 QScreen
* pScreen
= m_pFrame
->GetQWidget()->window()->windowHandle()->screen();
726 rDPIX
= pScreen
->logicalDotsPerInchX() * pScreen
->devicePixelRatio() + 0.5;
727 rDPIY
= pScreen
->logicalDotsPerInchY() * pScreen
->devicePixelRatio() + 0.5;
730 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */