Element renaming + custom text format

This commit is contained in:
MarcinZiabek
2022-02-21 00:57:53 +01:00
parent d73c694452
commit 68df390d0e
20 changed files with 133 additions and 81 deletions
+28
View File
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using SkiaSharp;
@@ -24,5 +25,32 @@ namespace QuestPDF.ReportSample
Latitude = Helpers.Random.NextDouble() * 180f - 90f
};
}
private static readonly ConcurrentDictionary<int, string> RomanNumeralCache = new ConcurrentDictionary<int, string>();
public static string FormatAsRomanNumeral(this int number)
{
if (number < 0 || number > 3999)
throw new ArgumentOutOfRangeException("Number should be in range from 1 to 3999");
return RomanNumeralCache.GetOrAdd(number, x =>
{
if (x >= 1000) return "M" + FormatAsRomanNumeral(x - 1000);
if (x >= 900) return "CM" + FormatAsRomanNumeral(x - 900);
if (x >= 500) return "D" + FormatAsRomanNumeral(x - 500);
if (x >= 400) return "CD" + FormatAsRomanNumeral(x - 400);
if (x >= 100) return "C" + FormatAsRomanNumeral(x - 100);
if (x >= 90) return "XC" + FormatAsRomanNumeral(x - 90);
if (x >= 50) return "L" + FormatAsRomanNumeral(x - 50);
if (x >= 40) return "XL" + FormatAsRomanNumeral(x - 40);
if (x >= 10) return "X" + FormatAsRomanNumeral(x - 10);
if (x >= 9) return "IX" + FormatAsRomanNumeral(x - 9);
if (x >= 5) return "V" + FormatAsRomanNumeral(x - 5);
if (x >= 4) return "IV" + FormatAsRomanNumeral(x - 4);
if (x >= 1) return "I" + FormatAsRomanNumeral(x - 1);
return string.Empty;
});
}
}
}
@@ -39,9 +39,9 @@ namespace QuestPDF.ReportSample.Layouts
page.Footer().AlignCenter().Text(text =>
{
text.CurrentPageNumber();
text.CurrentPageNumber(format: x => x?.FormatAsRomanNumeral() ?? "-----");
text.Span(" / ");
text.TotalPages();
text.TotalPages(format: x => x?.FormatAsRomanNumeral() ?? "-----");
});
});
}
@@ -47,14 +47,14 @@ namespace QuestPDF.ReportSample.Layouts
row.RelativeItem().Text(locationName);
row.ConstantItem(150).AlignRight().Text(text =>
{
text.BeginPageNumberOfLocation(locationName);
text.BeginPageNumberOfSection(locationName);
text.Span(" - ");
text.EndPageNumberOfLocation(locationName);
text.EndPageNumberOfSection(locationName);
var lengthStyle = TextStyle.Default.Color(Colors.Grey.Medium);
text.Span(" (", lengthStyle);
text.PageLengthOfLocation(locationName, x => x == 1 ? "1 page long" : $"{x} pages long", lengthStyle);
text.TotalPagesWithinSection(locationName, lengthStyle, x => x == 1 ? "1 page long" : $"{x} pages long");
text.Span(")", lengthStyle);
});
});
+1 -1
View File
@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
public class ExternalLinkTests
{
[Test]
public void Measure() => SimpleContainerTests.Measure<ExternalLink>();
public void Measure() => SimpleContainerTests.Measure<Hyperlink>();
// TODO: consider tests for the Draw method
}
+1 -1
View File
@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
public class InternalLinkTests
{
[Test]
public void Measure() => SimpleContainerTests.Measure<InternalLink>();
public void Measure() => SimpleContainerTests.Measure<SectionLink>();
// TODO: consider tests for the Draw method
}
+1 -1
View File
@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
public class InternalLocationTests
{
[Test]
public void Measure() => SimpleContainerTests.Measure<InternalLink>();
public void Measure() => SimpleContainerTests.Measure<SectionLink>();
// TODO: consider tests for the Draw method
}
+4 -4
View File
@@ -20,9 +20,9 @@ namespace QuestPDF.UnitTests.TestEngine
public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color);
public void DrawText(string text, Position position, TextStyle style) => DrawTextFunc(text, position, style);
public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size);
public void DrawExternalLink(string url, Size size) => throw new NotImplementedException();
public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException();
public void DrawLocation(string locationName) => throw new NotImplementedException();
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
public void DrawSection(string sectionName) => throw new NotImplementedException();
}
}
@@ -18,8 +18,8 @@ namespace QuestPDF.UnitTests.TestEngine
public void DrawText(string text, Position position, TextStyle style) => Operations.Add(new CanvasDrawTextOperation(text, position, style));
public void DrawImage(SKImage image, Position position, Size size) => Operations.Add(new CanvasDrawImageOperation(position, size));
public void DrawExternalLink(string url, Size size) => throw new NotImplementedException();
public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException();
public void DrawLocation(string locationName) => throw new NotImplementedException();
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
public void DrawSection(string sectionName) => throw new NotImplementedException();
}
}
+3 -3
View File
@@ -51,17 +51,17 @@ namespace QuestPDF.Drawing
}
public void DrawExternalLink(string url, Size size)
public void DrawHyperlink(string url, Size size)
{
}
public void DrawLocationLink(string locationName, Size size)
public void DrawSectionLink(string sectionName, Size size)
{
}
public void DrawLocation(string locationName)
public void DrawSection(string sectionName)
{
}
+5 -5
View File
@@ -37,19 +37,19 @@ namespace QuestPDF.Drawing
Canvas.DrawImage(image, new SKRect(vector.X, vector.Y, size.Width, size.Height));
}
public void DrawExternalLink(string url, Size size)
public void DrawHyperlink(string url, Size size)
{
Canvas.DrawUrlAnnotation(new SKRect(0, 0, size.Width, size.Height), url);
}
public void DrawLocationLink(string locationName, Size size)
public void DrawSectionLink(string sectionName, Size size)
{
Canvas.DrawLinkDestinationAnnotation(new SKRect(0, 0, size.Width, size.Height), locationName);
Canvas.DrawLinkDestinationAnnotation(new SKRect(0, 0, size.Width, size.Height), sectionName);
}
public void DrawLocation(string locationName)
public void DrawSection(string sectionName)
{
Canvas.DrawNamedDestinationAnnotation(new SKPoint(0, 0), locationName);
Canvas.DrawNamedDestinationAnnotation(new SKPoint(0, 0), sectionName);
}
public void Rotate(float angle)
@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class ExternalLink : ContainerElement
internal class Hyperlink : ContainerElement
{
public string Url { get; set; } = "https://www.questpdf.com";
@@ -14,7 +14,7 @@ namespace QuestPDF.Elements
if (targetSize.Type == SpacePlanType.Wrap)
return;
Canvas.DrawExternalLink(Url, targetSize);
Canvas.DrawHyperlink(Url, targetSize);
base.Draw(availableSpace);
}
}
@@ -2,7 +2,7 @@
namespace QuestPDF.Elements
{
internal class InternalLocation : ContainerElement, IStateResettable
internal class Section : ContainerElement, IStateResettable
{
public string LocationName { get; set; }
private bool IsRendered { get; set; }
@@ -16,11 +16,11 @@ namespace QuestPDF.Elements
{
if (!IsRendered)
{
Canvas.DrawLocation(LocationName);
Canvas.DrawSection(LocationName);
IsRendered = true;
}
PageContext.SetLocationPage(LocationName);
PageContext.SetSectionPage(LocationName);
base.Draw(availableSpace);
}
}
@@ -3,9 +3,9 @@ using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class InternalLink : ContainerElement
internal class SectionLink : ContainerElement
{
public string LocationName { get; set; }
public string SectionName { get; set; }
internal override void Draw(Size availableSpace)
{
@@ -14,7 +14,7 @@ namespace QuestPDF.Elements
if (targetSize.Type == SpacePlanType.Wrap)
return;
Canvas.DrawLocationLink(LocationName, targetSize);
Canvas.DrawSectionLink(SectionName, targetSize);
base.Draw(availableSpace);
}
}
@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
namespace QuestPDF.Elements.Text.Items
{
internal class TextBlockExternalLink : TextBlockSpan
internal class TextBlockHyperlink : TextBlockSpan
{
public string Url { get; set; }
@@ -15,7 +15,7 @@ namespace QuestPDF.Elements.Text.Items
public override void Draw(TextDrawingRequest request)
{
request.Canvas.Translate(new Position(0, request.TotalAscent));
request.Canvas.DrawExternalLink(Url, new Size(request.TextSize.Width, request.TextSize.Height));
request.Canvas.DrawHyperlink(Url, new Size(request.TextSize.Width, request.TextSize.Height));
request.Canvas.Translate(new Position(0, -request.TotalAscent));
base.Draw(request);
@@ -3,9 +3,9 @@ using QuestPDF.Infrastructure;
namespace QuestPDF.Elements.Text.Items
{
internal class TextBlockInternalLink : TextBlockSpan
internal class TextBlockSectionlLink : TextBlockSpan
{
public string LocationName { get; set; }
public string SectionName { get; set; }
public override TextMeasurementResult? Measure(TextMeasurementRequest request)
{
@@ -15,7 +15,7 @@ namespace QuestPDF.Elements.Text.Items
public override void Draw(TextDrawingRequest request)
{
request.Canvas.Translate(new Position(0, request.TotalAscent));
request.Canvas.DrawLocationLink(LocationName, new Size(request.TextSize.Width, request.TextSize.Height));
request.Canvas.DrawSectionLink(SectionName, new Size(request.TextSize.Width, request.TextSize.Height));
request.Canvas.Translate(new Position(0, -request.TotalAscent));
base.Draw(request);
+24 -6
View File
@@ -60,7 +60,7 @@ namespace QuestPDF.Fluent
public static void Placeholder(this IContainer element, string? text = null)
{
element.Component(new Elements.Placeholder
element.Component(new Placeholder
{
Text = text ?? string.Empty
});
@@ -99,27 +99,45 @@ namespace QuestPDF.Fluent
return element.Element(new Container());
}
[Obsolete("This element has been renamed since version 2022.3. Please use the Hyperlink method.")]
public static IContainer ExternalLink(this IContainer element, string url)
{
return element.Element(new ExternalLink
return element.Hyperlink(url);
}
public static IContainer Hyperlink(this IContainer element, string url)
{
return element.Element(new Hyperlink
{
Url = url
});
}
[Obsolete("This element has been renamed since version 2022.3. Please use the Section method.")]
public static IContainer Location(this IContainer element, string locationName)
{
return element.Element(new InternalLocation
return element.Section(locationName);
}
public static IContainer Section(this IContainer element, string sectionName)
{
return element.Element(new Section
{
LocationName = locationName
LocationName = sectionName
});
}
[Obsolete("This element has been renamed since version 2022.3. Please use the SectionLink method.")]
public static IContainer InternalLink(this IContainer element, string locationName)
{
return element.Element(new InternalLink
return element.SectionLink(locationName);
}
public static IContainer SectionLink(this IContainer element, string sectionName)
{
return element.Element(new SectionLink
{
LocationName = locationName
SectionName = sectionName
});
}
+39 -33
View File
@@ -90,81 +90,81 @@ namespace QuestPDF.Fluent
Span(Environment.NewLine);
}
private void PageNumber(Func<IPageContext, string> source, TextStyle? style = null)
private static Func<int?, string> DefaultTextFormat = x => (x ?? 123).ToString();
private void PageNumber(Func<IPageContext, int?> pageNumber, TextStyle? style, Func<int?, string>? format)
{
style ??= TextStyle.Default;
format ??= DefaultTextFormat;
AddItemToLastTextBlock(new TextBlockPageNumber()
{
Source = source,
Source = context => format(pageNumber(context)),
Style = style
});
}
public void CurrentPageNumber(Func<int?, string> format, TextStyle? style = null)
public void CurrentPageNumber(TextStyle? style = null, Func<int?, string>? format = null)
{
PageNumber(context => format(context.CurrentPage), style);
PageNumber(x => x.CurrentPage, style, format);
}
public void CurrentPageNumber(TextStyle? style = null)
public void TotalPages(TextStyle? style = null, Func<int?, string>? format = null)
{
CurrentPageNumber(x => x.ToString(), style);
PageNumber(x => x.GetLocation(PageContext.DocumentLocation)?.Length, style, format);
}
public void TotalPages(Func<int?, string> format, TextStyle? style = null)
{
PageNumber(context => format(context.GetLocation(PageContext.DocumentLocation)?.Length), style);
}
public void TotalPages(TextStyle? style = null)
{
TotalPages(x => x.ToString(), style);
}
[Obsolete("This element has been renamed since version 2022.3. Please use the BeginPageNumberOfSection method.")]
public void PageNumberOfLocation(string locationName, TextStyle? style = null)
{
BeginPageNumberOfLocation(locationName);
BeginPageNumberOfSection(locationName);
}
public void BeginPageNumberOfLocation(string locationName, TextStyle? style = null)
public void BeginPageNumberOfSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
{
PageNumber(context => (context.GetLocation(locationName)?.PageStart ?? 123).ToString(), style);
PageNumber(x => x.GetLocation(locationName)?.PageStart, style, format);
}
public void EndPageNumberOfLocation(string locationName, TextStyle? style = null)
public void EndPageNumberOfSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
{
PageNumber(context => (context.GetLocation(locationName)?.PageEnd ?? 123).ToString(), style);
PageNumber(x => x.GetLocation(locationName)?.PageEnd, style, format);
}
public void PageNumberWithinLocation(string locationName, Func<int?, string> format, TextStyle? style = null)
public void PageNumberWithinSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
{
PageNumber(context => format(context.CurrentPage + 1 - context.GetLocation(locationName)?.PageEnd), style);
PageNumber(x => x.CurrentPage + 1 - x.GetLocation(locationName)?.PageEnd, style, format);
}
public void PageLengthOfLocation(string locationName, Func<int?, string> format, TextStyle? style = null)
public void TotalPagesWithinSection(string locationName, TextStyle? style = null, Func<int?, string>? format = null)
{
PageNumber(context => format(context.GetLocation(locationName)?.Length), style);
PageNumber(x => x.GetLocation(locationName)?.Length, style, format);
}
public void InternalLocation(string? text, string locationName, TextStyle? style = null)
public void SectionLink(string? text, string sectionName, TextStyle? style = null)
{
if (IsNullOrEmpty(text))
return;
if (IsNullOrEmpty(locationName))
throw new ArgumentException(nameof(locationName));
if (IsNullOrEmpty(sectionName))
throw new ArgumentException(nameof(sectionName));
style ??= TextStyle.Default;
AddItemToLastTextBlock(new TextBlockInternalLink
AddItemToLastTextBlock(new TextBlockSectionlLink
{
Style = style,
Text = text,
LocationName = locationName
SectionName = sectionName
});
}
public void ExternalLocation(string? text, string url, TextStyle? style = null)
[Obsolete("This element has been renamed since version 2022.3. Please use the SectionLink method.")]
public void InternalLocation(string? text, string locationName, TextStyle? style = null)
{
SectionLink(text, locationName, style);
}
public void Hyperlink(string? text, string url, TextStyle? style = null)
{
if (IsNullOrEmpty(text))
return;
@@ -174,7 +174,7 @@ namespace QuestPDF.Fluent
style ??= TextStyle.Default;
AddItemToLastTextBlock(new TextBlockExternalLink
AddItemToLastTextBlock(new TextBlockHyperlink
{
Style = style,
Text = text,
@@ -182,6 +182,12 @@ namespace QuestPDF.Fluent
});
}
[Obsolete("This element has been renamed since version 2022.3. Please use the Hyperlink method.")]
public void ExternalLocation(string? text, string url, TextStyle? style = null)
{
Hyperlink(text, url, style);
}
public IContainer Element()
{
var container = new Container();
+3 -3
View File
@@ -10,9 +10,9 @@ namespace QuestPDF.Infrastructure
void DrawText(string text, Position position, TextStyle style);
void DrawImage(SKImage image, Position position, Size size);
void DrawExternalLink(string url, Size size);
void DrawLocationLink(string locationName, Size size);
void DrawLocation(string locationName);
void DrawHyperlink(string url, Size size);
void DrawSectionLink(string sectionName, Size size);
void DrawSection(string sectionName);
void Rotate(float angle);
void Scale(float scaleX, float scaleY);
+1 -1
View File
@@ -13,7 +13,7 @@ namespace QuestPDF.Infrastructure
internal interface IPageContext
{
int CurrentPage { get; }
void SetLocationPage(string name);
void SetSectionPage(string name);
DocumentLocation? GetLocation(string name);
}
}
+2 -2
View File
@@ -14,10 +14,10 @@ namespace QuestPDF.Infrastructure
internal void SetPageNumber(int number)
{
CurrentPage = number;
SetLocationPage(DocumentLocation);
SetSectionPage(DocumentLocation);
}
public void SetLocationPage(string name)
public void SetSectionPage(string name)
{
var location = GetLocation(name);