Prototype for the RTL mode
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ namespace QuestPDF.Drawing
|
||||
document.Compose(container);
|
||||
var content = container.Compose();
|
||||
ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
|
||||
ApplyContentDirection(content, ContentDirection.LeftToRight);
|
||||
|
||||
var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null;
|
||||
|
||||
@@ -160,6 +161,24 @@ namespace QuestPDF.Drawing
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Elements
|
||||
{
|
||||
internal class ContentDirectionSetter : ContainerElement
|
||||
{
|
||||
public ContentDirection ContentDirection { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,10 @@ namespace QuestPDF.Elements
|
||||
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 float Spacing { get; set; }
|
||||
|
||||
@@ -62,7 +64,7 @@ namespace QuestPDF.Elements
|
||||
if (renderingCommands.Any(x => !x.RowItem.IsRendered && x.Measurement.Type == SpacePlanType.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 size = new Size(width, height);
|
||||
|
||||
@@ -152,6 +154,9 @@ namespace QuestPDF.Elements
|
||||
{
|
||||
command.Size = new Size(command.Size.Width, rowHeight);
|
||||
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;
|
||||
|
||||
@@ -3,8 +3,10 @@ using QuestPDF.Infrastructure;
|
||||
|
||||
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)
|
||||
{
|
||||
var childSize = base.Measure(Size.Max);
|
||||
@@ -25,7 +27,13 @@ namespace QuestPDF.Elements
|
||||
if (measurement.Type == SpacePlanType.Wrap)
|
||||
return;
|
||||
|
||||
var translate = ContentDirection == ContentDirection.RightToLeft
|
||||
? new Position(-measurement.Width, 0)
|
||||
: Position.Zero;
|
||||
|
||||
Canvas.Translate(translate);
|
||||
base.Draw(measurement);
|
||||
Canvas.Translate(translate.Reverse());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace QuestPDF.Infrastructure
|
||||
{
|
||||
internal enum ContentDirection
|
||||
{
|
||||
LeftToRight,
|
||||
RightToLeft
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace QuestPDF.Infrastructure
|
||||
{
|
||||
internal interface IContentDirectionAware
|
||||
{
|
||||
public ContentDirection ContentDirection { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user