Improved text positioning
This commit is contained in:
@@ -6,13 +6,14 @@ using QuestPDF.Examples.Engine;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace QuestPDF.Examples
|
||||
{
|
||||
public class TextExample : ExampleTestBase
|
||||
{
|
||||
[ShowResult]
|
||||
[ImageSize(1200, 500)]
|
||||
[ImageSize(1600, 500)]
|
||||
public void Test(IContainer container)
|
||||
{
|
||||
List<TextElement> Lorem()
|
||||
@@ -21,36 +22,32 @@ namespace QuestPDF.Examples
|
||||
{
|
||||
new TextElement()
|
||||
{
|
||||
Style = TextStyle.Default.Size(32).BackgroundColor(Colors.Red.Lighten3),
|
||||
Style = TextStyle.Default.Size(32).BackgroundColor(Placeholders.BackgroundColor()),
|
||||
Text = "Lorem ipsum "
|
||||
},
|
||||
new TextElement()
|
||||
{
|
||||
Style = TextStyle.Default.Size(24).BackgroundColor(Colors.Orange.Lighten3),
|
||||
Style = TextStyle.Default.Size(24).BackgroundColor(Placeholders.BackgroundColor()),
|
||||
Text = " dolor "
|
||||
},
|
||||
new TextElement()
|
||||
{
|
||||
Style = TextStyle.Default.Size(64).BackgroundColor(Colors.Yellow.Lighten3),
|
||||
Text = " sit "
|
||||
Style = TextStyle.Default.Size(64).BackgroundColor(Placeholders.BackgroundColor()),
|
||||
Text = " sijt "
|
||||
},
|
||||
new TextElement()
|
||||
{
|
||||
Style = TextStyle.Default.Size(32).BackgroundColor(Colors.Green.Lighten3),
|
||||
Style = TextStyle.Default.Size(32).BackgroundColor(Placeholders.BackgroundColor()),
|
||||
Text = " amet"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Func<List<TextElement>> Source = Lorem ;
|
||||
|
||||
Func<List<TextElement>> Source = () => Split(RandomText());
|
||||
|
||||
container
|
||||
.Padding(50)
|
||||
.Stack(row =>
|
||||
{
|
||||
row.Spacing(50);
|
||||
|
||||
row.Element().Box().Border(1).Stack(stack =>
|
||||
.Box().Border(1).Stack(stack =>
|
||||
{
|
||||
stack
|
||||
.Element()
|
||||
@@ -69,58 +66,62 @@ namespace QuestPDF.Examples
|
||||
{
|
||||
Elements = Source()
|
||||
});
|
||||
|
||||
|
||||
stack
|
||||
.Element()
|
||||
.Box()
|
||||
//.Background(Placeholders.BackgroundColor())
|
||||
.Element(new TextRun()
|
||||
{
|
||||
Elements = Split(Source())
|
||||
});
|
||||
});
|
||||
|
||||
row.Element().Box().Border(1).Stack(stack =>
|
||||
{
|
||||
stack
|
||||
.Element()
|
||||
.Box()
|
||||
.Background(Placeholders.BackgroundColor())
|
||||
.Element(new TextRun()
|
||||
{
|
||||
Elements = Dense(Source())
|
||||
Elements = Source()
|
||||
});
|
||||
|
||||
stack
|
||||
.Element()
|
||||
.Box()
|
||||
.Background(Placeholders.BackgroundColor())
|
||||
//.Background(Placeholders.BackgroundColor())
|
||||
.Element(new TextRun()
|
||||
{
|
||||
Elements = Dense(Source())
|
||||
Elements = Source()
|
||||
});
|
||||
|
||||
|
||||
stack
|
||||
.Element()
|
||||
.Box()
|
||||
.Background(Placeholders.BackgroundColor())
|
||||
//.Background(Placeholders.BackgroundColor())
|
||||
.Element(new TextRun()
|
||||
{
|
||||
Elements = Dense(Split(Source()))
|
||||
Elements = Source()
|
||||
});
|
||||
|
||||
stack
|
||||
.Element()
|
||||
.Box()
|
||||
//.Background(Placeholders.BackgroundColor())
|
||||
.Element(new TextRun()
|
||||
{
|
||||
Elements = Source()
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
List<TextElement> RandomText()
|
||||
{
|
||||
var sizes = new[] { 24, 32, 48, 64};
|
||||
|
||||
return Placeholders
|
||||
.Sentence()
|
||||
.Split(" ")
|
||||
.Select(x => new TextElement
|
||||
{
|
||||
Text = $"{x} ",
|
||||
Style = TextStyle.Default.Size(Placeholders.Random.Next(24, 64))
|
||||
Style = TextStyle
|
||||
.Default
|
||||
//.Size(sizes[Placeholders.Random.Next(0, 3)])
|
||||
.Size(24)
|
||||
.BackgroundColor(Placeholders.BackgroundColor())
|
||||
//.LineHeight((float)Placeholders.Random.NextDouble() / 2 + 1f)
|
||||
.LineHeight(1.2f)
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
@@ -137,11 +138,5 @@ namespace QuestPDF.Examples
|
||||
}))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
List<TextElement> Dense(List<TextElement> elements)
|
||||
{
|
||||
elements.ForEach(x => x.Style.IsDense = true);
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ namespace QuestPDF.Elements
|
||||
public struct TextMeasurement
|
||||
{
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
public SKRect Position { get; set; }
|
||||
}
|
||||
|
||||
@@ -44,9 +43,6 @@ namespace QuestPDF.Elements
|
||||
return new TextMeasurement
|
||||
{
|
||||
Position = rect,
|
||||
Height = style.IsDense
|
||||
? rect.Bottom + rect.Height
|
||||
: style.LineHeight * style.Size,
|
||||
Width = width
|
||||
};
|
||||
});
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace QuestPDF.Elements
|
||||
|
||||
var width = measurements.Sum(x => x.Width);
|
||||
//var height = measurements.Max(x => x.Height);
|
||||
var height = measurements.Max(x => x.Position.Bottom) + measurements.Max(x => x.Position.Height);
|
||||
|
||||
|
||||
//var height = measurements.Max(x => x.Position.Bottom) + measurements.Max(x => x.Position.Height);
|
||||
var height = Elements.Max(x => x.Style.Size * x.Style.LineHeight);
|
||||
|
||||
return new FullRender(width, height);
|
||||
}
|
||||
|
||||
@@ -26,23 +26,33 @@ namespace QuestPDF.Elements
|
||||
{
|
||||
var measurements = Elements.Select(x => x.Measure()).ToList();
|
||||
|
||||
var top = measurements.Max(x => x.Position.Height);
|
||||
var bottom = measurements.Max(x => x.Position.Bottom);
|
||||
var lineHeight = Elements.Max(x => x.Style.Size * x.Style.LineHeight);
|
||||
var textHeight = Elements.Max(x => x.Style.Size);
|
||||
|
||||
var lineHeightOffset = (lineHeight - textHeight) / 2;
|
||||
var baselineOffset = measurements.Max(x => -x.Position.Top);
|
||||
var offset = lineHeightOffset + baselineOffset;
|
||||
|
||||
var offset = measurements.Min(x => x.Position.Top);
|
||||
canvas.Translate(new Position(0, -offset));
|
||||
|
||||
foreach (var textElement in Elements)
|
||||
{
|
||||
var size = textElement.Measure();
|
||||
|
||||
canvas.DrawRectangle(new Position(0, -top), new Size(size.Width, bottom + top), textElement.Style.BackgroundColor);
|
||||
//canvas.DrawRectangle(new Position(0, 0), new Size(size.Width, lineHeight), textElement.Style.BackgroundColor);
|
||||
//canvas.DrawRectangle(new Position(size.Position.Left, size.Position.Top), new Size(size.Position.Width, size.Position.Height), textElement.Style.BackgroundColor);
|
||||
|
||||
canvas.Translate(new Position(0, offset));
|
||||
textElement.Draw(canvas);
|
||||
canvas.Translate(new Position(0, -offset));
|
||||
|
||||
canvas.Translate(new Position(size.Width, 0));
|
||||
}
|
||||
|
||||
canvas.Translate(new Position(-measurements.Sum(x => x.Width), offset));
|
||||
canvas.Translate(new Position(-measurements.Sum(x => x.Width), 0));
|
||||
|
||||
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,25 +155,25 @@ namespace QuestPDF.Helpers
|
||||
|
||||
private static readonly string[] BackgroundColors =
|
||||
{
|
||||
Colors.Red.Lighten2,
|
||||
Colors.Pink.Lighten2,
|
||||
Colors.Purple.Lighten2,
|
||||
Colors.DeepPurple.Lighten2,
|
||||
Colors.Indigo.Lighten2,
|
||||
Colors.Blue.Lighten2,
|
||||
Colors.LightBlue.Lighten2,
|
||||
Colors.Cyan.Lighten2,
|
||||
Colors.Teal.Lighten2,
|
||||
Colors.Green.Lighten2,
|
||||
Colors.LightGreen.Lighten2,
|
||||
Colors.Lime.Lighten2,
|
||||
Colors.Yellow.Lighten2,
|
||||
Colors.Amber.Lighten2,
|
||||
Colors.Orange.Lighten2,
|
||||
Colors.DeepOrange.Lighten2,
|
||||
Colors.Brown.Lighten2,
|
||||
Colors.Grey.Lighten2,
|
||||
Colors.BlueGrey.Lighten2
|
||||
Colors.Red.Lighten3,
|
||||
Colors.Pink.Lighten3,
|
||||
Colors.Purple.Lighten3,
|
||||
Colors.DeepPurple.Lighten3,
|
||||
Colors.Indigo.Lighten3,
|
||||
Colors.Blue.Lighten3,
|
||||
Colors.LightBlue.Lighten3,
|
||||
Colors.Cyan.Lighten3,
|
||||
Colors.Teal.Lighten3,
|
||||
Colors.Green.Lighten3,
|
||||
Colors.LightGreen.Lighten3,
|
||||
Colors.Lime.Lighten3,
|
||||
Colors.Yellow.Lighten3,
|
||||
Colors.Amber.Lighten3,
|
||||
Colors.Orange.Lighten3,
|
||||
Colors.DeepOrange.Lighten3,
|
||||
Colors.Brown.Lighten3,
|
||||
Colors.Grey.Lighten3,
|
||||
Colors.BlueGrey.Lighten3
|
||||
};
|
||||
|
||||
public static string BackgroundColor()
|
||||
|
||||
@@ -12,13 +12,12 @@ namespace QuestPDF.Infrastructure
|
||||
internal HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
|
||||
internal FontWeight FontWeight { get; set; } = FontWeight.Normal;
|
||||
internal bool IsItalic { get; set; } = false;
|
||||
internal bool IsDense { get; set; }
|
||||
|
||||
public static TextStyle Default => new TextStyle();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Color}|{BackgroundColor}|{FontType}|{Size}|{LineHeight}|{Alignment}|{FontWeight}|{IsItalic}|{IsDense}";
|
||||
return $"{Color}|{BackgroundColor}|{FontType}|{Size}|{LineHeight}|{Alignment}|{FontWeight}|{IsItalic}";
|
||||
}
|
||||
|
||||
internal TextStyle Clone() => (TextStyle)MemberwiseClone();
|
||||
|
||||
Reference in New Issue
Block a user