208 lines
6.0 KiB
C#
208 lines
6.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using QuestPDF.Drawing;
|
|
using QuestPDF.Elements;
|
|
using QuestPDF.Elements.Text;
|
|
using QuestPDF.Elements.Text.Items;
|
|
using QuestPDF.Infrastructure;
|
|
using static System.String;
|
|
|
|
namespace QuestPDF.Fluent
|
|
{
|
|
public class TextDescriptor
|
|
{
|
|
private ICollection<TextBlock> TextBlocks { get; } = new List<TextBlock>();
|
|
private TextStyle DefaultStyle { get; set; } = TextStyle.Default;
|
|
internal HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
|
|
private float Spacing { get; set; } = 0f;
|
|
|
|
public void DefaultTextStyle(TextStyle style)
|
|
{
|
|
DefaultStyle = style;
|
|
}
|
|
|
|
public void AlignLeft()
|
|
{
|
|
Alignment = HorizontalAlignment.Left;
|
|
}
|
|
|
|
public void AlignCenter()
|
|
{
|
|
Alignment = HorizontalAlignment.Center;
|
|
}
|
|
|
|
public void AlignRight()
|
|
{
|
|
Alignment = HorizontalAlignment.Right;
|
|
}
|
|
|
|
public void ParagraphSpacing(float value)
|
|
{
|
|
Spacing = value;
|
|
}
|
|
|
|
private void AddItemToLastTextBlock(ITextBlockItem item)
|
|
{
|
|
if (!TextBlocks.Any())
|
|
TextBlocks.Add(new TextBlock());
|
|
|
|
TextBlocks.Last().Children.Add(item);
|
|
}
|
|
|
|
public void Span(string? text, TextStyle? style = null)
|
|
{
|
|
if (IsNullOrEmpty(text))
|
|
return;
|
|
|
|
style ??= TextStyle.Default;
|
|
|
|
var items = text
|
|
.Replace("\r", string.Empty)
|
|
.Split(new[] { '\n' }, StringSplitOptions.None)
|
|
.Select(x => new TextBlockSpan
|
|
{
|
|
Text = x,
|
|
Style = style
|
|
})
|
|
.ToList();
|
|
|
|
AddItemToLastTextBlock(items.First());
|
|
|
|
items
|
|
.Skip(1)
|
|
.Select(x => new TextBlock
|
|
{
|
|
Children = new List<ITextBlockItem> { x }
|
|
})
|
|
.ToList()
|
|
.ForEach(TextBlocks.Add);
|
|
}
|
|
|
|
public void Line(string? text, TextStyle? style = null)
|
|
{
|
|
text ??= string.Empty;
|
|
Span(text + Environment.NewLine, style);
|
|
}
|
|
|
|
public void EmptyLine()
|
|
{
|
|
Span(Environment.NewLine);
|
|
}
|
|
|
|
private void PageNumber(string slotName, TextStyle? style = null)
|
|
{
|
|
if (IsNullOrEmpty(slotName))
|
|
throw new ArgumentException(nameof(slotName));
|
|
|
|
style ??= TextStyle.Default;
|
|
|
|
AddItemToLastTextBlock(new TextBlockPageNumber()
|
|
{
|
|
Style = style,
|
|
SlotName = slotName
|
|
});
|
|
}
|
|
|
|
public void CurrentPageNumber(TextStyle? style = null)
|
|
{
|
|
PageNumber(PageContext.CurrentPageSlot, style);
|
|
}
|
|
|
|
public void TotalPages(TextStyle? style = null)
|
|
{
|
|
PageNumber(PageContext.TotalPagesSlot, style);
|
|
}
|
|
|
|
public void PageNumberOfLocation(string locationName, TextStyle? style = null)
|
|
{
|
|
if (IsNullOrEmpty(locationName))
|
|
throw new ArgumentException(nameof(locationName));
|
|
|
|
PageNumber(locationName, style);
|
|
}
|
|
|
|
public void InternalLocation(string? text, string locationName, TextStyle? style = null)
|
|
{
|
|
if (IsNullOrEmpty(text))
|
|
return;
|
|
|
|
if (IsNullOrEmpty(locationName))
|
|
throw new ArgumentException(nameof(locationName));
|
|
|
|
style ??= TextStyle.Default;
|
|
|
|
AddItemToLastTextBlock(new TextBlockInternalLink
|
|
{
|
|
Style = style,
|
|
Text = text,
|
|
LocationName = locationName
|
|
});
|
|
}
|
|
|
|
public void ExternalLocation(string? text, string url, TextStyle? style = null)
|
|
{
|
|
if (IsNullOrEmpty(text))
|
|
return;
|
|
|
|
if (IsNullOrEmpty(url))
|
|
throw new ArgumentException(nameof(url));
|
|
|
|
style ??= TextStyle.Default;
|
|
|
|
AddItemToLastTextBlock(new TextBlockExternalLink
|
|
{
|
|
Style = style,
|
|
Text = text,
|
|
Url = url
|
|
});
|
|
}
|
|
|
|
public IContainer Element()
|
|
{
|
|
var container = new Container();
|
|
|
|
AddItemToLastTextBlock(new TextBlockElement
|
|
{
|
|
Element = container
|
|
});
|
|
|
|
return container.AlignBottom().Box();
|
|
}
|
|
|
|
internal void Compose(IContainer container)
|
|
{
|
|
TextBlocks.ToList().ForEach(x => x.Alignment = Alignment);
|
|
|
|
foreach (var textBlockSpan in TextBlocks.SelectMany(x => x.Children).Where(x => x is TextBlockSpan).Cast<TextBlockSpan>())
|
|
textBlockSpan.Style.ApplyParentStyle(DefaultStyle);
|
|
|
|
container.Stack(stack =>
|
|
{
|
|
stack.Spacing(Spacing);
|
|
|
|
foreach (var textBlock in TextBlocks)
|
|
stack.Item().Element(textBlock);
|
|
});
|
|
}
|
|
}
|
|
|
|
public static class TextExtensions
|
|
{
|
|
public static void Text(this IContainer element, Action<TextDescriptor> content)
|
|
{
|
|
var descriptor = new TextDescriptor();
|
|
|
|
if (element is Alignment alignment)
|
|
descriptor.Alignment = alignment.Horizontal;
|
|
|
|
content?.Invoke(descriptor);
|
|
descriptor.Compose(element);
|
|
}
|
|
|
|
public static void Text(this IContainer element, object? text, TextStyle? style = null)
|
|
{
|
|
element.Text(x => x.Span(text?.ToString(), style));
|
|
}
|
|
}
|
|
} |