mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 08:09:34 +02:00
Qt5,Qt6: use floating point functions for primitives drawing on scaled displays. issue #41422
This commit is contained in:
parent
79707cbc54
commit
683afd5cbb
@ -465,6 +465,7 @@ type
|
|||||||
function getDeviceSize: TPoint;
|
function getDeviceSize: TPoint;
|
||||||
function getRegionType(ARegion: QRegionH): integer;
|
function getRegionType(ARegion: QRegionH): integer;
|
||||||
function getClipRegion: TQtRegion;
|
function getClipRegion: TQtRegion;
|
||||||
|
function preferFloatingPointDrawingFunctions: boolean; {when screen is scaled we use drawLineF, drawRectF etc.}
|
||||||
procedure setClipping(const AValue: Boolean);
|
procedure setClipping(const AValue: Boolean);
|
||||||
procedure setClipRect(const ARect: TRect);
|
procedure setClipRect(const ARect: TRect);
|
||||||
procedure setClipRegion(ARegion: QRegionH; AOperation: QtClipOperation = QtReplaceClip);
|
procedure setClipRegion(ARegion: QRegionH; AOperation: QtClipOperation = QtReplaceClip);
|
||||||
@ -3398,6 +3399,35 @@ begin
|
|||||||
Result := vRegion;
|
Result := vRegion;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TQtDeviceContext.preferFloatingPointDrawingFunctions: boolean;
|
||||||
|
const
|
||||||
|
AEpsilon: double = 0.01;
|
||||||
|
var
|
||||||
|
APixelRatio: QReal;
|
||||||
|
AWindow: QWindowH;
|
||||||
|
AWidget: QWidgetH;
|
||||||
|
AScreen: QScreenH;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if Assigned(Parent) then
|
||||||
|
begin
|
||||||
|
AWindow := QWidget_windowHandle(Parent);
|
||||||
|
if AWindow = nil then
|
||||||
|
begin
|
||||||
|
AWidget := QWidget_topLevelWidget(Parent);
|
||||||
|
AWindow := QWidget_windowHandle(AWidget);
|
||||||
|
if AWindow = nil then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
AScreen := QWindow_screen(AWindow);
|
||||||
|
if AScreen = nil then
|
||||||
|
exit;
|
||||||
|
APixelRatio := QScreen_devicePixelRatio(AScreen);
|
||||||
|
if Abs(APixelRatio - 1.00) > AEpsilon then
|
||||||
|
exit(True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TQtDeviceContext.setClipping(const AValue: Boolean);
|
procedure TQtDeviceContext.setClipping(const AValue: Boolean);
|
||||||
begin
|
begin
|
||||||
QPainter_setClipping(Widget, AValue);
|
QPainter_setClipping(Widget, AValue);
|
||||||
|
@ -4896,7 +4896,11 @@ begin
|
|||||||
Pt := TQtCustomControl(AHandle).viewport.ScrolledOffset;
|
Pt := TQtCustomControl(AHandle).viewport.ScrolledOffset;
|
||||||
Types.OffsetRect(Rect^, -Pt.X, -Pt.Y);
|
Types.OffsetRect(Rect^, -Pt.X, -Pt.Y);
|
||||||
end;
|
end;
|
||||||
|
if (Rect^.Width <= 0) or (Rect^.Height <= 0) then
|
||||||
|
begin
|
||||||
|
//DebugLn('WARNING: TQtWidgetSet.InvalidateRect() Rect is null ',dbgs(Rect^),' LCL=',dbgsName(TQtWidget(AHandle).LCLObject));
|
||||||
|
exit(True);
|
||||||
|
end;
|
||||||
// no need to handle bErase. Qt automatically erase rect on paint event according to docs
|
// no need to handle bErase. Qt automatically erase rect on paint event according to docs
|
||||||
TQtWidget(aHandle).Update(Rect);
|
TQtWidget(aHandle).Update(Rect);
|
||||||
end else
|
end else
|
||||||
@ -4966,8 +4970,9 @@ begin
|
|||||||
OldBkMode := SetBkMode(DC, TRANSPARENT);
|
OldBkMode := SetBkMode(DC, TRANSPARENT);
|
||||||
if TQtDeviceContext(DC).pen.getCosmetic then
|
if TQtDeviceContext(DC).pen.getCosmetic then
|
||||||
LastPos := TQtDeviceContext(DC).GetLineLastPixelPos(PenPos, LastPos);
|
LastPos := TQtDeviceContext(DC).GetLineLastPixelPos(PenPos, LastPos);
|
||||||
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) then
|
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) or
|
||||||
TQtDeviceContext(DC).drawLineF(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y)
|
TQtDeviceContext(DC).preferFloatingPointDrawingFunctions then
|
||||||
|
TQtDeviceContext(DC).drawLineF(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y)
|
||||||
else
|
else
|
||||||
TQtDeviceContext(DC).drawLine(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y);
|
TQtDeviceContext(DC).drawLine(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y);
|
||||||
|
|
||||||
@ -5321,7 +5326,8 @@ begin
|
|||||||
Result := IsValidDC(DC);
|
Result := IsValidDC(DC);
|
||||||
if Result then
|
if Result then
|
||||||
begin
|
begin
|
||||||
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) then
|
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) or
|
||||||
|
TQtDeviceContext(DC).preferFloatingPointDrawingFunctions then
|
||||||
begin
|
begin
|
||||||
GetMem(QtPointsF, NumPts * SizeOf(TQtPointF));
|
GetMem(QtPointsF, NumPts * SizeOf(TQtPointF));
|
||||||
for i := 0 to NumPts - 1 do
|
for i := 0 to NumPts - 1 do
|
||||||
@ -5407,8 +5413,9 @@ begin
|
|||||||
|
|
||||||
R := NormalizeRect(Rect(X1, Y1, X2, Y2));
|
R := NormalizeRect(Rect(X1, Y1, X2, Y2));
|
||||||
if IsRectEmpty(R) then Exit(True);
|
if IsRectEmpty(R) then Exit(True);
|
||||||
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) then
|
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) or
|
||||||
TQtDeviceContext(DC).drawRectF(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1)
|
TQtDeviceContext(DC).preferFloatingPointDrawingFunctions then
|
||||||
|
TQtDeviceContext(DC).drawRectF(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1)
|
||||||
else
|
else
|
||||||
TQtDeviceContext(DC).drawRect(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1);
|
TQtDeviceContext(DC).drawRect(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1);
|
||||||
Result := True;
|
Result := True;
|
||||||
|
@ -472,6 +472,7 @@ type
|
|||||||
function getDeviceSize: TPoint;
|
function getDeviceSize: TPoint;
|
||||||
function getRegionType(ARegion: QRegionH): integer;
|
function getRegionType(ARegion: QRegionH): integer;
|
||||||
function getClipRegion: TQtRegion;
|
function getClipRegion: TQtRegion;
|
||||||
|
function preferFloatingPointDrawingFunctions: boolean; {when screen is scaled we use drawLineF, drawRectF etc.}
|
||||||
procedure setClipping(const AValue: Boolean);
|
procedure setClipping(const AValue: Boolean);
|
||||||
procedure setClipRect(const ARect: TRect);
|
procedure setClipRect(const ARect: TRect);
|
||||||
procedure setClipRegion(ARegion: QRegionH; AOperation: QtClipOperation = QtReplaceClip);
|
procedure setClipRegion(ARegion: QRegionH; AOperation: QtClipOperation = QtReplaceClip);
|
||||||
@ -3568,6 +3569,25 @@ begin
|
|||||||
Result := vRegion;
|
Result := vRegion;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TQtDeviceContext.preferFloatingPointDrawingFunctions: boolean;
|
||||||
|
const
|
||||||
|
AEpsilon: double = 0.01;
|
||||||
|
var
|
||||||
|
APixelRatio: QReal;
|
||||||
|
AScreen: QScreenH;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
if Assigned(Parent) then
|
||||||
|
begin
|
||||||
|
AScreen := QWidget_screen(Parent);
|
||||||
|
if AScreen = nil then
|
||||||
|
exit;
|
||||||
|
APixelRatio := QScreen_devicePixelRatio(AScreen);
|
||||||
|
if Abs(APixelRatio - 1.00) > AEpsilon then
|
||||||
|
exit(True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TQtDeviceContext.setClipping(const AValue: Boolean);
|
procedure TQtDeviceContext.setClipping(const AValue: Boolean);
|
||||||
begin
|
begin
|
||||||
QPainter_setClipping(Widget, AValue);
|
QPainter_setClipping(Widget, AValue);
|
||||||
|
@ -4924,7 +4924,11 @@ begin
|
|||||||
Pt := TQtCustomControl(AHandle).viewport.ScrolledOffset;
|
Pt := TQtCustomControl(AHandle).viewport.ScrolledOffset;
|
||||||
Types.OffsetRect(Rect^, -Pt.X, -Pt.Y);
|
Types.OffsetRect(Rect^, -Pt.X, -Pt.Y);
|
||||||
end;
|
end;
|
||||||
|
if (Rect^.Width <= 0) or (Rect^.Height <= 0) then
|
||||||
|
begin
|
||||||
|
//DebugLn('WARNING: TQtWidgetSet.InvalidateRect() Rect is null ',dbgs(Rect^),' LCL=',dbgsName(TQtWidget(AHandle).LCLObject));
|
||||||
|
exit(True);
|
||||||
|
end;
|
||||||
// no need to handle bErase. Qt automatically erase rect on paint event according to docs
|
// no need to handle bErase. Qt automatically erase rect on paint event according to docs
|
||||||
TQtWidget(aHandle).Update(Rect);
|
TQtWidget(aHandle).Update(Rect);
|
||||||
end else
|
end else
|
||||||
@ -4994,8 +4998,9 @@ begin
|
|||||||
OldBkMode := SetBkMode(DC, TRANSPARENT);
|
OldBkMode := SetBkMode(DC, TRANSPARENT);
|
||||||
if TQtDeviceContext(DC).pen.getCosmetic then
|
if TQtDeviceContext(DC).pen.getCosmetic then
|
||||||
LastPos := TQtDeviceContext(DC).GetLineLastPixelPos(PenPos, LastPos);
|
LastPos := TQtDeviceContext(DC).GetLineLastPixelPos(PenPos, LastPos);
|
||||||
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) then
|
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) or
|
||||||
TQtDeviceContext(DC).drawLineF(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y)
|
TQtDeviceContext(DC).preferFloatingPointDrawingFunctions then
|
||||||
|
TQtDeviceContext(DC).drawLineF(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y)
|
||||||
else
|
else
|
||||||
TQtDeviceContext(DC).drawLine(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y);
|
TQtDeviceContext(DC).drawLine(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y);
|
||||||
if TQtDeviceContext(DC).pen.getStyle = QtCustomDashLine then
|
if TQtDeviceContext(DC).pen.getStyle = QtCustomDashLine then
|
||||||
@ -5393,7 +5398,8 @@ begin
|
|||||||
Result := IsValidDC(DC);
|
Result := IsValidDC(DC);
|
||||||
if Result then
|
if Result then
|
||||||
begin
|
begin
|
||||||
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) then
|
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) or
|
||||||
|
TQtDeviceContext(DC).preferFloatingPointDrawingFunctions then
|
||||||
begin
|
begin
|
||||||
GetMem(QtPointsF, NumPts * SizeOf(TQtPointF));
|
GetMem(QtPointsF, NumPts * SizeOf(TQtPointF));
|
||||||
for i := 0 to NumPts - 1 do
|
for i := 0 to NumPts - 1 do
|
||||||
@ -5479,8 +5485,9 @@ begin
|
|||||||
|
|
||||||
R := NormalizeRect(Rect(X1, Y1, X2, Y2));
|
R := NormalizeRect(Rect(X1, Y1, X2, Y2));
|
||||||
if IsRectEmpty(R) then Exit(True);
|
if IsRectEmpty(R) then Exit(True);
|
||||||
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) then
|
if QPainter_testRenderHint(TQtDeviceContext(DC).Widget, QPainterAntialiasing) or
|
||||||
TQtDeviceContext(DC).drawRectF(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1)
|
TQtDeviceContext(DC).preferFloatingPointDrawingFunctions then
|
||||||
|
TQtDeviceContext(DC).drawRectF(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1)
|
||||||
else
|
else
|
||||||
TQtDeviceContext(DC).drawRect(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1);
|
TQtDeviceContext(DC).drawRect(R.Left, R.Top, R.Right - R.Left - 1, R.Bottom - R.Top - 1);
|
||||||
Result := True;
|
Result := True;
|
||||||
|
Loading…
Reference in New Issue
Block a user