View Issue Details

IDProjectCategoryView StatusLast Update
0037219LazarusLCLpublic2020-06-25 02:52
ReporterJoeny Ang Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.1 (SVN) 
Summary0037219: GTK2: TextRect and regions
DescriptionTCanvas.TextRect() yields different behaviors if a region is defined. No problems with TextOut().

Test:
In the attached test project, nothing is supposed to be written inside the rectangle when Region is checked.

Observations:
- TextStyle.Clipping = True
  If Rect is completely inside the region that is clipped, the text will be displayed, unclipped.
- TextStyle.Clipping = False
  After the first TextRect(), the region is removed (?); so succeeding canvas output will have no region defined.
- TextStyle.Clipping = False; TextStyle.Opaque = True
  Correct behavior

TagsNo tags attached.
Fixed in Revisionr63436
LazTarget-
WidgetsetGTK 2
Attached Files

Activities

Joeny Ang

2020-06-16 10:53

reporter  

Joeny Ang

2020-06-19 10:27

reporter   ~0123474

Last edited: 2020-06-19 10:39

View 2 revisions

Found out the following after doing some digging:
- NullRegion is equal to "no defined region", which shouldn't be. Without a defined region, the whole canvas can be drawn onto; with a NullRegion assigned, it should not be drawable.
- RestoreDC() does not always retore the saved region.

Patch:
- CreateEmptyRegion(): will return a region with an imaginary rect (-1, -1, 0, 0) defined. This will still be a NullRegion but will not allow any writing to the cavnas.
- CombineRgn(): after combining regions, will check if result is a NullRegion (0, 0, 0, 0), if so, recreate it using CreateEmptyRegion
- RestoreDC(): removed the check for region change

Not a really nice workaround, but works :)
combinergn-test-01.zip (110,885 bytes)
gtk2-textrect-and-regions.patch (2,188 bytes)   
--- lcl/interfaces/gtk2/gtk2winapi.inc
+++ lcl/interfaces/gtk2/gtk2winapi.inc
@@ -1866,6 +1866,13 @@
     Result := RegionType(D);
     //DebugLn('TGtk2WidgetSet.CombineRgn B Mode=',dbgs(fnCombineMode),
     //  ' S1=',GDKRegionAsString(S1),' S2=',GDKRegionAsString(S2),' D=',GDKRegionAsString(D),'');
+    if (Result = NullRegion) and
+      ((RegionType(S1) <> NullRegion) or ((RegionType(S2) <> NullRegion))) then
+    begin
+      DeleteObject(Dest);
+      Dest := CreateEmptyRegion;
+      Result := RegionType(D);
+    end;
   end;
 end;
 
@@ -7537,7 +7544,7 @@
   DevCtx: TGtkDeviceContext absolute DC;
 
   SavedDevCtx: TGtkDeviceContext;
-  ClipRegionChanged: Boolean;
+//  ClipRegionChanged: Boolean;
 begin
   if not IsValidDC(DC) then Exit(False);
   if SavedDC <= 0 then Exit(False);
@@ -7548,14 +7555,14 @@
 
     // TODO copy bitmap too
 
-    ClipRegionChanged := DevCtx.ClipRegion <> SavedDevCtx.ClipRegion;
-    
+//    ClipRegionChanged := DevCtx.ClipRegion <> SavedDevCtx.ClipRegion;
+
     // clear the GDIObjects in pSavedDC, so they are not freed by DeleteDC
     Result := DevCtx.CopyDataFrom(SavedDevCtx, True, True, True);
     DevCtx.SavedContext := SavedDevCtx.SavedContext;
     SavedDevCtx.SavedContext := nil;
 
-    if ClipRegionChanged then
+//    if ClipRegionChanged then
       DevCtx.SelectRegion;
 
     // free saved DC
--- lcl/interfaces/gtk2/gtk2widgetset.inc
+++ lcl/interfaces/gtk2/gtk2widgetset.inc
@@ -6046,10 +6046,24 @@
 function TGtk2WidgetSet.CreateEmptyRegion: hRGN;
 var
   GObject: PGdiObject;
+  R: TGDKRectangle;
+  RegionObj: PGdkRegion;
+  RRGN: PGDKRegion;
 begin
   GObject := NewGDIObject(gdiRegion);
-  GObject^.GDIRegionObject := gdk_region_new;
+  R.x := -1;
+  R.y := -1;
+  R.width := 1;
+  R.height := 1;
+  RRGN := gdk_region_new;
+  RegionObj := PGdkRegion(gdk_region_union_with_rect(RRGN,@R));
+  GObject^.GDIRegionObject := RegionObj;
+  gdk_region_destroy(RRGN);
   Result := HRGN({%H-}PtrUInt(GObject));
+
+//  GObject := NewGDIObject(gdiRegion);
+//  GObject^.GDIRegionObject := gdk_region_new;
+//  Result := HRGN({%H-}PtrUInt(GObject));
   //DebugLn('TGtk2WidgetSet.CreateEmptyRgn A RGN=',DbgS(Result));
 end;
 

Juha Manninen

2020-06-24 11:14

developer   ~0123550

Applied, thanks.
I removed the commented lines. They can be restored from revision control if needed.

Joeny Ang

2020-06-25 02:52

reporter   ~0123587

Great! Thanks :)

Issue History

Date Modified Username Field Change
2020-06-16 10:53 Joeny Ang New Issue
2020-06-16 10:53 Joeny Ang File Added: gtk2-textrect-and-regions-test-01..zip
2020-06-19 10:27 Joeny Ang Note Added: 0123474
2020-06-19 10:27 Joeny Ang File Added: combinergn-test-01.zip
2020-06-19 10:27 Joeny Ang File Added: gtk2-textrect-and-regions.patch
2020-06-19 10:27 Joeny Ang File Added: save-restore-dc-test-01.zip
2020-06-19 10:39 Joeny Ang Note Edited: 0123474 View Revisions
2020-06-24 11:13 Juha Manninen Assigned To => Juha Manninen
2020-06-24 11:13 Juha Manninen Status new => assigned
2020-06-24 11:14 Juha Manninen Status assigned => resolved
2020-06-24 11:14 Juha Manninen Resolution open => fixed
2020-06-24 11:14 Juha Manninen Fixed in Revision => r63436
2020-06-24 11:14 Juha Manninen LazTarget => -
2020-06-24 11:14 Juha Manninen Widgetset GTK 2 => GTK 2
2020-06-24 11:14 Juha Manninen Note Added: 0123550
2020-06-25 02:52 Joeny Ang Note Added: 0123587