View Issue Details

IDProjectCategoryView StatusLast Update
0036444PatchesWidgetsetpublic2020-01-01 21:29
ReporterCudaText man Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityhave not tried
Status assignedResolutionreopened 
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?

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