Browse Source

Content overflow: added RTL support

Marcin Ziąbek 2 years ago
parent
commit
d56c8fca37

+ 28 - 22
Source/QuestPDF.Examples/ElementExamples.cs

@@ -908,6 +908,8 @@ namespace QuestPDF.Examples
                 {
                 {
                     container.Padding(24).Row(row =>
                     container.Padding(24).Row(row =>
                     {
                     {
+                        row.Spacing(50);
+                        
                         row.RelativeItem().ContentFromLeftToRight().Element(GenerateOverflowPatterns);
                         row.RelativeItem().ContentFromLeftToRight().Element(GenerateOverflowPatterns);
                         row.RelativeItem().ContentFromRightToLeft().Element(GenerateOverflowPatterns);
                         row.RelativeItem().ContentFromRightToLeft().Element(GenerateOverflowPatterns);
                     });
                     });
@@ -916,43 +918,47 @@ namespace QuestPDF.Examples
                     {
                     {
                         container.Column(column =>
                         container.Column(column =>
                         {
                         {
-                            column.Spacing(100);
+                            column.Spacing(50);
 
 
                             column
                             column
                                 .Item()
                                 .Item()
-
-                                .Width(100)
-                                .Height(100)
-                                .Background(Colors.Grey.Lighten3)
-
-                                .ContentOverflowDebugArea()
-
+                                .Element(DrawTestcaseArea)
+                                
                                 .Width(50)
                                 .Width(50)
-                                .Height(150);
+                                .Height(150)
+                                
+                                .Text("Test");
                         
                         
                             column
                             column
                                 .Item()
                                 .Item()
-
-                                .Width(100)
-                                .Height(100)
-                                .Background(Colors.Grey.Lighten3)
-
-                                .ContentOverflowDebugArea()
+                                .Element(DrawTestcaseArea)
 
 
                                 .Width(150)
                                 .Width(150)
-                                .Height(50);
+                                .Height(50)
+                                
+                                .Text("Test");
                         
                         
                             column
                             column
                                 .Item()
                                 .Item()
+                                .Element(DrawTestcaseArea)
 
 
-                                .Width(100)
-                                .Height(100)
-                                .Background(Colors.Grey.Lighten3)
+                                .Width(200)
+                                .Height(150)
+                                
+                                .Text("Test");
 
 
-                                .ContentOverflowDebugArea()
+                            IContainer DrawTestcaseArea(IContainer container)
+                            {
+                                return container
+                                    .Height(200)
+                                    .Background(Colors.Grey.Lighten4)
 
 
-                                .Width(200)
-                                .Height(150);
+                                    .Width(100)
+                                    .Height(100)
+                                    .Background(Colors.Grey.Lighten1)
+                                    
+                                    .ContentOverflowDebugArea();
+                            }
                         });
                         });
                     }
                     }
                 });
                 });

+ 34 - 20
Source/QuestPDF/Elements/ContentOverflowDebugArea.cs

@@ -6,8 +6,10 @@ using SkiaSharp;
 
 
 namespace QuestPDF.Elements;
 namespace QuestPDF.Elements;
 
 
-internal class ContentOverflowDebugArea : ContainerElement
+internal class ContentOverflowDebugArea : ContainerElement, IContentDirectionAware
 {
 {
+    public ContentDirection ContentDirection { get; set; }
+    
     internal override SpacePlan Measure(Size availableSpace)
     internal override SpacePlan Measure(Size availableSpace)
     {
     {
         var childSize = base.Measure(availableSpace);
         var childSize = base.Measure(availableSpace);
@@ -28,15 +30,31 @@ internal class ContentOverflowDebugArea : ContainerElement
             return;
             return;
         }
         }
         
         
-        var overflowSpace = TryVerticalOverflow(availableSpace) 
-            ?? TryVerticalOverflow(availableSpace) 
+        var contentSpace = 
+            TryVerticalOverflow(availableSpace) 
+            ?? TryHorizontalOverflow(availableSpace) 
             ?? TryExpandedOverflow(availableSpace) 
             ?? TryExpandedOverflow(availableSpace) 
             ?? Size.Max;
             ?? Size.Max;
         
         
-        Child?.Draw(overflowSpace);
-
-        DrawTargetAreaBorder(overflowSpace);
-        DrawOverflowArea(availableSpace, overflowSpace);
+        var translate = ContentDirection == ContentDirection.RightToLeft
+            ? new Position(availableSpace.Width - contentSpace.Width, 0)
+            : Position.Zero;
+        
+        Canvas.Translate(translate);
+        Child?.Draw(contentSpace);
+        Canvas.Translate(translate.Reverse());
+        
+        var overflowTranslate = ContentDirection == ContentDirection.RightToLeft ? new Position(availableSpace.Width, 0) : Position.Zero;
+        var overflowScale = ContentDirection == ContentDirection.RightToLeft ? -1 : 1;
+        
+        Canvas.Translate(overflowTranslate);
+        Canvas.Scale(overflowScale, 1);
+        
+        DrawTargetAreaBorder(contentSpace);
+        DrawOverflowArea(availableSpace, contentSpace);
+        
+        Canvas.Scale(overflowScale, 1);
+        Canvas.Translate(overflowTranslate.Reverse());
     }
     }
 
 
     private Size? TryOverflow(Size targetSpace)
     private Size? TryOverflow(Size targetSpace)
@@ -89,7 +107,7 @@ internal class ContentOverflowDebugArea : ContainerElement
             borderColor);
             borderColor);
     }
     }
     
     
-    private void DrawOverflowArea(Size availableSpace, Size contentSize)
+    private void DrawOverflowArea(Size availableSpace, Size contentSpace)
     {
     {
         if (Canvas is not SkiaCanvasBase canvasBase)
         if (Canvas is not SkiaCanvasBase canvasBase)
             return;
             return;
@@ -100,11 +118,6 @@ internal class ContentOverflowDebugArea : ContainerElement
         ClipOverflowAreaVisibility();
         ClipOverflowAreaVisibility();
         DrawCheckerboardPattern();
         DrawCheckerboardPattern();
         skiaCanvas.Restore();
         skiaCanvas.Restore();
-        
-        if (Canvas is SkiaCanvasBase bases2)
-        {
-            bases2.Canvas.Restore();
-        }
 
 
         void DrawCheckerboardPattern()
         void DrawCheckerboardPattern()
         {
         {
@@ -113,8 +126,8 @@ internal class ContentOverflowDebugArea : ContainerElement
             const string lightCellColor = "#44f44336";
             const string lightCellColor = "#44f44336";
             const string darkCellColor = "#88f44336";
             const string darkCellColor = "#88f44336";
             
             
-            var boardSizeX = (int)Math.Ceiling(contentSize.Width / checkerboardSize);
-            var boardSizeY = (int)Math.Ceiling(contentSize.Height / checkerboardSize);
+            var boardSizeX = (int)Math.Ceiling(contentSpace.Width / checkerboardSize);
+            var boardSizeY = (int)Math.Ceiling(contentSpace.Height / checkerboardSize);
 
 
             foreach (var x in Enumerable.Range(0, boardSizeX))
             foreach (var x in Enumerable.Range(0, boardSizeX))
             {
             {
@@ -129,17 +142,18 @@ internal class ContentOverflowDebugArea : ContainerElement
             }
             }
         }
         }
 
 
+        // creates and applies an L-shaped clipping mask
         void ClipOverflowAreaVisibility()
         void ClipOverflowAreaVisibility()
         {
         {
             var path = new SKPath();
             var path = new SKPath();
 
 
-            var middleWidth = Math.Min(availableSpace.Width, contentSize.Width);
-            var middleHeight = Math.Min(availableSpace.Height, contentSize.Height);
+            var middleWidth = Math.Min(availableSpace.Width, contentSpace.Width);
+            var middleHeight = Math.Min(availableSpace.Height, contentSpace.Height);
             
             
             path.MoveTo(availableSpace.Width, 0);
             path.MoveTo(availableSpace.Width, 0);
-            path.LineTo(contentSize.Width, 0);
-            path.LineTo(contentSize.Width, contentSize.Height);
-            path.LineTo(0, contentSize.Height);
+            path.LineTo(contentSpace.Width, 0);
+            path.LineTo(contentSpace.Width, contentSpace.Height);
+            path.LineTo(0, contentSpace.Height);
             path.LineTo(0, middleHeight);
             path.LineTo(0, middleHeight);
             path.LineTo(middleWidth, middleHeight);
             path.LineTo(middleWidth, middleHeight);
             path.LineTo(middleWidth, 0);
             path.LineTo(middleWidth, 0);