View Issue Details

IDProjectCategoryView StatusLast Update
0036444PatchesWidgetsetpublic2020-07-12 10:55
ReporterCudaText man Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionreopened 
PlatformUbunti 19 x64 
Product Version2.1 (SVN) 
Summary0036444: gtk3: LineTo must not include final x,y
DescriptionI made a patch to exclude final x/y, will make .diff after my prev patches are applied.
code in comments.
TagsNo tags attached.
Fixed in Revisionr62418
LazTarget-
WidgetsetGTK 3
Attached Files

Relationships

related to 0036430 resolvedJuha Manninen Lazarus gtk3: Canvas artifacts 2 
related to 0036472 resolvedJuha Manninen Patches gtk3: Canvas.Pixels[] 

Activities

Juha Manninen

2019-12-18 12:36

developer   ~0119909

Wasn't the same thing already in the related issue? Alexey, this is confusing.

CudaText man

2019-12-18 13:06

reporter   ~0119910

No, it was not. i still wait for applying my fix from
https://bugs.freepascal.org/view.php?id=36430

Juha Manninen

2019-12-18 19:02

developer   ~0119914

Ok, it was about Bezier curves and Polylines. The example did not show any difference really. Also hamidhb wrote that no offset is needed.
What should I do? I have only your word against all other evidence. :)

CudaText man

2019-12-18 20:19

reporter   ~0119920

Juha, no, it was NOT about bezier and polyline, it was about LINETO. i upload demo which paints Plus mark via MoveTo/LineTo (near bezeir). compare it with and w/o patch.

w/o patch, Plus sign is ugly.
w/o patch, Plus sign us blurred.

CudaText man

2019-12-18 20:21

reporter   ~0119921

Juha, on the same demo, compare that linked patch - about bezier and polyline.

w/o LINKED patch - bezier is not filled ok and 1 of 2 curves misses points.

Anton Kavalenka

2019-12-18 21:02

reporter   ~0119924

Pixel offset +0.5 is a must when clip rectangle is the same as painted rectangle.
row 0 and col 0 would be clipped if rectangle is not painted shifted by +0.5,+0.5

CudaText man

2019-12-18 21:10

reporter   ~0119926

Proof picture (before--after) added.
before_after.png (47,463 bytes)   
before_after.png (47,463 bytes)   

CudaText man

2019-12-18 22:46

reporter   ~0119936

And now here is the diff
line.diff (2,003 bytes)   
Index: lcl/interfaces/gtk3/gtk3objects.pas
===================================================================
--- lcl/interfaces/gtk3/gtk3objects.pas	(revision 62416)
+++ lcl/interfaces/gtk3/gtk3objects.pas	(working copy)
@@ -256,7 +256,7 @@
     function getBpp: integer;
     function getDepth: integer;
     function getDeviceSize: TPoint;
-    function LineTo(const X, Y: Integer): Boolean;
+    function LineTo(X, Y: Integer): Boolean;
     function MoveTo(const X, Y: Integer; OldPoint: PPoint): Boolean;
     function SetClipRegion(ARgn: TGtk3Region): Integer;
     procedure SetSourceColor(AColor: TColor);
@@ -1868,18 +1868,49 @@
   end;
 end;
 
-function TGtk3DeviceContext.LineTo(const X, Y: Integer): Boolean;
+function TGtk3DeviceContext.LineTo(X, Y: Integer): Boolean;
+const
+  PixelOffset = 0.5;
+var
+  FX, FY: Double;
+  X0, Y0: Integer;
 begin
   if not Assigned(Widget) then
     exit(False);
   ApplyPen;
-  cairo_line_to(Widget, X, Y);
+
+  // we must paint line until, but NOT including, (X,Y)
+  // let's offset X, Y by 1 px, but only for horizontal and vertical lines (yet?)
+  cairo_get_current_point(Widget, @FX, @FY);
+  X0 := Round(FX-PixelOffset);
+  Y0 := Round(FY-PixelOffset);
+  if X0 = X then
+  begin
+    if Y = Y0 then
+      exit
+    else
+    if Y > Y0 then
+      Dec(Y)
+    else
+      Inc(Y);
+  end
+  else
+  if Y0 = Y then
+  begin
+    if X > X0 then
+      Dec(X)
+    else
+      Inc(X);
+  end;
+
+  cairo_line_to(Widget, X+PixelOffset, Y+PixelOffset);
   cairo_stroke(Widget);
   Result := True;
 end;
 
-function TGtk3DeviceContext.MoveTo(const X, Y: Integer; OldPoint: PPoint
-  ): Boolean;
+function TGtk3DeviceContext.MoveTo(const X, Y: Integer; OldPoint: PPoint): Boolean;
+const
+  PixelOffset = 0.5;
 var
   dx: Double;
   dy: Double;
@@ -1892,7 +1923,7 @@
     OldPoint^.X := Round(dx);
     OldPoint^.Y := Round(dy);
   end;
-  cairo_move_to(Widget, X, Y);
+  cairo_move_to(Widget, X+PixelOffset, Y+PixelOffset);
   Result := True;
 end;
 
line.diff (2,003 bytes)   

Juha Manninen

2019-12-19 08:50

developer   ~0119940

Applied, thanks.

CudaText man

2019-12-20 20:42

reporter   ~0119978

I made more complex test and see it's still not ok.
test paints 6 lines so that 4 lines make square (with empty pixels in 4 corners) and 2 lines are crossed inside. compare how it looks in gtk2 (same as qt4) and see that gtk3 is not ok...

CudaText man

2019-12-20 20:42

reporter  

bad-yet.png (648 bytes)   
bad-yet.png (648 bytes)   

CudaText man

2019-12-20 20:43

reporter   ~0119979

I need to confirm this bad look, do you see it?

Juha Manninen

2019-12-20 21:53

developer   ~0119981

Yes, I can see the same error in my tests.

CudaText man

2019-12-22 14:02

reporter   ~0120013

Last edited: 2019-12-22 14:02

View 2 revisions

I found the sol!! it works for me.
Pls test?
gtk3/gtk3objects.pas

function TGtk3DeviceContext.LineTo(X, Y: Integer): Boolean;
var
  FX, FY: Double;
  X0, Y0: Double;
begin
  if not Assigned(Widget) then
    exit(False);
  ApplyPen;

  // we must paint line until, but NOT including, (X,Y)
  // seems Cairo lines paint in inverse logic: from (X0,Y0), NOT including it, until (X,Y), including it
  // so let's paint line inversed

  cairo_get_current_point(Widget, @FX, @FY);
  X0 := FX - PixelOffset;
  Y0 := FY - PixelOffset;

  cairo_move_to(Widget, X + PixelOffset, Y + PixelOffset);
  cairo_line_to(Widget, X0 + PixelOffset, Y0 + PixelOffset);
  cairo_stroke(Widget);
  cairo_move_to(Widget, X + PixelOffset, Y + PixelOffset);

  Result := True;
end;


CudaText man

2019-12-22 19:31

reporter   ~0120025

Something strange at my PC (Ubuntu 19 x64)-- now my patch don't give ok pixels, it's broken again, while previous patch (in trunk) gives ok look. seems some gtk3 setting is switching on/off. help?

Zeljan Rikalo

2019-12-23 11:46

developer   ~0120034

Is it cairo so crappy that we must use PixelOffset with all drawings ?

CudaText man

2019-12-23 12:04

reporter   ~0120035

Cairo needs 0.5 offset when painting lines, not sure about other fegures but seems yes

Zeljan Rikalo

2019-12-23 14:17

developer   ~0120039

That's pretty strange and does not smell good.

CudaText man

2020-01-01 21:29

reporter   ~0120176

I wanted to do such fix--
a) detect direction of line - one of 8 sides (W E S N and SW SE NW NE).
b) depending on side - make fix to starting and /or ending x/y of line, because i see that e.g. direction E needs one fix, and direction W needs another, and direction N need another one.
c) call Cairo with fixed coords
d) don't know what to do with other directions, e.g. angle 30deg or 10 deg

Ok approach?

Juha Manninen

2020-07-12 10:55

developer   ~0123917

I resolve this one. For future patches either reopen or open a new issue.

Issue History

Date Modified Username Field Change
2019-12-15 18:20 CudaText man New Issue
2019-12-18 12:35 Juha Manninen Relationship added related to 0036430
2019-12-18 12:36 Juha Manninen Note Added: 0119909
2019-12-18 13:06 CudaText man Note Added: 0119910
2019-12-18 19:02 Juha Manninen Note Added: 0119914
2019-12-18 20:19 CudaText man File Added: Canvas figures tests.zip
2019-12-18 20:19 CudaText man Note Added: 0119920
2019-12-18 20:21 CudaText man Note Added: 0119921
2019-12-18 21:02 Anton Kavalenka Note Added: 0119924
2019-12-18 21:10 CudaText man File Added: before_after.png
2019-12-18 21:10 CudaText man Note Added: 0119926
2019-12-18 22:46 CudaText man File Added: line.diff
2019-12-18 22:46 CudaText man Note Added: 0119936
2019-12-19 08:50 Juha Manninen Assigned To => Juha Manninen
2019-12-19 08:50 Juha Manninen Status new => resolved
2019-12-19 08:50 Juha Manninen Resolution open => fixed
2019-12-19 08:50 Juha Manninen Fixed in Revision => r62418
2019-12-19 08:50 Juha Manninen LazTarget => -
2019-12-19 08:50 Juha Manninen Widgetset GTK 3 => GTK 3
2019-12-19 08:50 Juha Manninen Note Added: 0119940
2019-12-20 20:42 CudaText man File Added: Canvas figures tests-2.zip
2019-12-20 20:42 CudaText man Note Added: 0119978
2019-12-20 20:42 CudaText man Status resolved => assigned
2019-12-20 20:42 CudaText man Resolution fixed => reopened
2019-12-20 20:42 CudaText man File Added: bad-yet.png
2019-12-20 20:43 CudaText man Note Added: 0119979
2019-12-20 21:53 Juha Manninen Note Added: 0119981
2019-12-22 14:02 CudaText man Note Added: 0120013
2019-12-22 14:02 CudaText man Note Edited: 0120013 View Revisions
2019-12-22 19:31 CudaText man Note Added: 0120025
2019-12-23 11:46 Zeljan Rikalo Note Added: 0120034
2019-12-23 12:04 CudaText man Note Added: 0120035
2019-12-23 14:17 Zeljan Rikalo Note Added: 0120039
2019-12-23 21:36 Juha Manninen Relationship added related to 0036472
2020-01-01 21:29 CudaText man Note Added: 0120176
2020-07-12 10:55 Juha Manninen Status assigned => resolved
2020-07-12 10:55 Juha Manninen Widgetset GTK 3 => GTK 3
2020-07-12 10:55 Juha Manninen Note Added: 0123917