2
0
Эх сурвалжийг харах

Prototype for the RTL mode

MarcinZiabek 3 жил өмнө
parent
commit
5ff9d03f20

+ 55 - 0
QuestPDF.Examples/RightToLeftExamples.cs

@@ -0,0 +1,55 @@
+using NUnit.Framework;
+using QuestPDF.Examples.Engine;
+using QuestPDF.Fluent;
+using QuestPDF.Helpers;
+
+namespace QuestPDF.Examples
+{
+    public class RightToLeftExamples
+    {
+        [Test]
+        public void Unconstrained()
+        {
+            RenderingTest
+                .Create()
+                .ProduceImages()
+                .PageSize(600, 600)
+                .ShowResults()
+                .Render(container =>
+                {
+                    container
+                        .AlignCenter()
+                        .AlignMiddle()
+                        .ContentFromRightToLeft()
+                        .Unconstrained()
+                        .Background(Colors.Red.Medium)
+                        .Height(200)
+                        .Width(200);
+                });
+        }
+        
+        [Test]
+        public void Row()
+        {
+            RenderingTest
+                .Create()
+                .ProduceImages()
+                .PageSize(600, 600)
+                .ShowResults()
+                .Render(container =>
+                {
+                    container
+                        .Padding(25)
+                        .ContentFromRightToLeft()
+                        .Border(1)
+                        .MinimalBox()
+                        .Row(row =>
+                        {
+                            row.ConstantItem(200).Background(Colors.Red.Lighten2).Height(200);
+                            row.ConstantItem(150).Background(Colors.Green.Lighten2).Height(200);
+                            row.ConstantItem(100).Background(Colors.Blue.Lighten2).Height(200);
+                        });
+                });
+        }
+    }
+}

+ 19 - 0
QuestPDF/Drawing/DocumentGenerator.cs

@@ -65,6 +65,7 @@ namespace QuestPDF.Drawing
             document.Compose(container);
             document.Compose(container);
             var content = container.Compose();
             var content = container.Compose();
             ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
             ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
+            ApplyContentDirection(content, ContentDirection.LeftToRight);
             
             
             var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null;
             var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null;
             
             
@@ -160,6 +161,24 @@ namespace QuestPDF.Drawing
 
 
             return debuggingState;
             return debuggingState;
         }
         }
+        
+        private static void ApplyContentDirection(Element? content, ContentDirection direction)
+        {
+            if (content == null)
+                return;
+
+            if (content is ContentDirectionSetter contentDirectionSetter)
+            {
+                ApplyContentDirection(contentDirectionSetter.Child, contentDirectionSetter.ContentDirection);
+                return;
+            }
+
+            if (content is IContentDirectionAware contentDirectionAware)
+                contentDirectionAware.ContentDirection = direction;
+            
+            foreach (var child in content.GetChildren())
+                ApplyContentDirection(child, direction);
+        }
 
 
         internal static void ApplyDefaultTextStyle(this Element? content, TextStyle documentDefaultTextStyle)
         internal static void ApplyDefaultTextStyle(this Element? content, TextStyle documentDefaultTextStyle)
         {
         {

+ 9 - 0
QuestPDF/Elements/ContentDirectionSetter.cs

@@ -0,0 +1,9 @@
+using QuestPDF.Infrastructure;
+
+namespace QuestPDF.Elements
+{
+    internal class ContentDirectionSetter : ContainerElement
+    {
+        public ContentDirection ContentDirection { get; set; }
+    }
+}

+ 7 - 2
QuestPDF/Elements/Row.cs

@@ -31,8 +31,10 @@ namespace QuestPDF.Elements
         public Position Offset { get; set; }
         public Position Offset { get; set; }
     }
     }
     
     
-    internal class Row : Element, ICacheable, IStateResettable
+    internal class Row : Element, ICacheable, IStateResettable, IContentDirectionAware
     {
     {
+        public ContentDirection ContentDirection { get; set; }
+        
         internal List<RowItem> Items { get; } = new();
         internal List<RowItem> Items { get; } = new();
         internal float Spacing { get; set; }
         internal float Spacing { get; set; }
 
 
@@ -62,7 +64,7 @@ namespace QuestPDF.Elements
             if (renderingCommands.Any(x => !x.RowItem.IsRendered && x.Measurement.Type == SpacePlanType.Wrap))
             if (renderingCommands.Any(x => !x.RowItem.IsRendered && x.Measurement.Type == SpacePlanType.Wrap))
                 return SpacePlan.Wrap();
                 return SpacePlan.Wrap();
 
 
-            var width = renderingCommands.Last().Offset.X + renderingCommands.Last().Size.Width;
+            var width = renderingCommands.Max(c => c.Offset.X + c.Size.Width);
             var height = renderingCommands.Max(x => x.Size.Height);
             var height = renderingCommands.Max(x => x.Size.Height);
             var size = new Size(width, height);
             var size = new Size(width, height);
 
 
@@ -152,6 +154,9 @@ namespace QuestPDF.Elements
             {
             {
                 command.Size = new Size(command.Size.Width, rowHeight);
                 command.Size = new Size(command.Size.Width, rowHeight);
                 command.Measurement = command.RowItem.Measure(command.Size);
                 command.Measurement = command.RowItem.Measure(command.Size);
+
+                if (ContentDirection == ContentDirection.RightToLeft)
+                    command.Offset = new Position(availableSpace.Width - command.Offset.X - command.Size.Width, 0);
             }
             }
             
             
             return renderingCommands;
             return renderingCommands;

+ 9 - 1
QuestPDF/Elements/Unconstrained.cs

@@ -3,8 +3,10 @@ using QuestPDF.Infrastructure;
 
 
 namespace QuestPDF.Elements
 namespace QuestPDF.Elements
 {
 {
-    internal class Unconstrained : ContainerElement, ICacheable
+    internal class Unconstrained : ContainerElement, IContentDirectionAware, ICacheable
     {
     {
+        public ContentDirection ContentDirection { get; set; }
+        
         internal override SpacePlan Measure(Size availableSpace)
         internal override SpacePlan Measure(Size availableSpace)
         {
         {
             var childSize = base.Measure(Size.Max);
             var childSize = base.Measure(Size.Max);
@@ -25,7 +27,13 @@ namespace QuestPDF.Elements
             if (measurement.Type == SpacePlanType.Wrap)
             if (measurement.Type == SpacePlanType.Wrap)
                 return;
                 return;
 
 
+            var translate = ContentDirection == ContentDirection.RightToLeft
+                ? new Position(-measurement.Width, 0)
+                : Position.Zero;
+            
+            Canvas.Translate(translate);
             base.Draw(measurement);
             base.Draw(measurement);
+            Canvas.Translate(translate.Reverse());
         }
         }
     }
     }
 }
 }

+ 26 - 0
QuestPDF/Fluent/ContentDirectionExtensions.cs

@@ -0,0 +1,26 @@
+using QuestPDF.Elements;
+using QuestPDF.Infrastructure;
+
+namespace QuestPDF.Fluent
+{
+    public static class ContentDirectionExtensions
+    {
+        private static IContainer ContentDirection(this IContainer element, ContentDirection direction)
+        {
+            return element.Element(new ContentDirectionSetter()
+            {
+                ContentDirection = direction
+            });
+        }
+        
+        public static IContainer ContentFromLeftToRight(this IContainer element)
+        {
+            return element.ContentDirection(Infrastructure.ContentDirection.LeftToRight);
+        }
+        
+        public static IContainer ContentFromRightToLeft(this IContainer element)
+        {
+            return element.ContentDirection(Infrastructure.ContentDirection.RightToLeft);
+        }
+    }
+}

+ 8 - 0
QuestPDF/Infrastructure/ContentDirection.cs

@@ -0,0 +1,8 @@
+namespace QuestPDF.Infrastructure
+{
+    internal enum ContentDirection
+    {
+        LeftToRight,
+        RightToLeft
+    }
+}

+ 7 - 0
QuestPDF/Infrastructure/IContentDirectionAware.cs

@@ -0,0 +1,7 @@
+namespace QuestPDF.Infrastructure
+{
+    internal interface IContentDirectionAware
+    {
+        public ContentDirection ContentDirection { get; set; }
+    }
+}