@@ -122,7 +122,127 @@ namespace QuestPDF.Examples
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void LetterSpacing()
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 700)
|
||||
.ProduceImages()
|
||||
.ShowResults()
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Padding(20)
|
||||
.Column(column =>
|
||||
{
|
||||
var letterSpacing = new[] { -1f, 0f, 2f };
|
||||
var paragraph = Placeholders.Sentence();
|
||||
|
||||
foreach (var spacing in letterSpacing)
|
||||
{
|
||||
column
|
||||
.Item()
|
||||
.Border(1)
|
||||
.Padding(10)
|
||||
.Column(nestedColumn =>
|
||||
{
|
||||
nestedColumn.Item()
|
||||
.Text(paragraph)
|
||||
.FontSize(16)
|
||||
.LetterSpacing(spacing);
|
||||
|
||||
nestedColumn.Item()
|
||||
.Text($"Letter spacing of {spacing} pt")
|
||||
.FontSize(10)
|
||||
.Italic()
|
||||
.FontColor(Colors.Blue.Medium);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LetterSpacing_Arabic()
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 700)
|
||||
.ProduceImages()
|
||||
.ShowResults()
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Padding(50)
|
||||
.Column(column =>
|
||||
{
|
||||
var letterSpacing = new[] { -1f, 0f, 2f };
|
||||
var paragraph = "ينا الألم. في بعض الأحيان ونظراً للالتزامات التي يفرضها علينا";
|
||||
foreach (var spacing in letterSpacing)
|
||||
{
|
||||
column
|
||||
.Item()
|
||||
.Border(1)
|
||||
.Padding(10)
|
||||
.Column(nestedColumn =>
|
||||
{
|
||||
nestedColumn.Item()
|
||||
.Text(paragraph)
|
||||
.FontSize(16)
|
||||
.FontFamily(Fonts.Calibri)
|
||||
.LetterSpacing(spacing);
|
||||
|
||||
nestedColumn.Item()
|
||||
.Text($"Letter spacing of {spacing} pt")
|
||||
.FontSize(10)
|
||||
.Italic()
|
||||
.FontColor(Colors.Blue.Medium);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void LetterSpacing_Unicode()
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 700)
|
||||
.ProduceImages()
|
||||
.ShowResults()
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Padding(50)
|
||||
.Column(column =>
|
||||
{
|
||||
var letterSpacing = new[] { 0f, 20f };
|
||||
var paragraph = "Ţ̴̡̧̤̮̺̤̗͎̱̹͙͎͖͂̿̓́̉̊̀̍͜h̵̞̘͇̾̎̏̅į̵̹̖͔͉̰̎̉̄̐̏͑͂̅̃̃͘͝s̷͓͉̭̭̯̬̥̻̰̩̦̑̀̀͌́̒̍̒̌̇͛̀͛́̎ ̷̡̡̟͕̳̺̝̼͇͔̬̟̖͍̈́̽͜͝͝i̶͔͚̟̊̐͛́͛̄̌ṡ̸̡̤̪͙͍̥͙̟̼̝̰̥͈̿̓̄̿̓͠ ̶̢̦̙͍̯̖̱̰̯͕͔͎̯̝̎͑t̸͖̲̱̼̎͐̎̉̾̎̾̌̅̔̏͘ȩ̶̝̫̙͓̙̣̔̀̌̔̋̂̑̈́̏̀̈͘̕͜͝s̸̫̝̮̻̼͐̅̄̎̎̑͝ț̷̨̢̨̻͈̮̞̆͗̓͊̃̌͂̑̉̕̕͜͝͝";
|
||||
|
||||
foreach (var spacing in letterSpacing)
|
||||
{
|
||||
column.Item()
|
||||
.Text($"Letter spacing of {spacing} pt")
|
||||
.FontSize(10)
|
||||
.Italic()
|
||||
.FontColor(Colors.Blue.Medium);
|
||||
|
||||
column.Item()
|
||||
.PaddingVertical(50)
|
||||
.Text(paragraph)
|
||||
.FontSize(16)
|
||||
.FontFamily(Fonts.Calibri)
|
||||
.LetterSpacing(spacing);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SuperscriptSubscript_Simple()
|
||||
{
|
||||
|
||||
@@ -47,17 +47,24 @@ namespace QuestPDF.Drawing
|
||||
var xOffset = 0f;
|
||||
var yOffset = 0f;
|
||||
|
||||
uint lastCluster = glyphInfos.LastOrDefault().Cluster;
|
||||
|
||||
var glyphs = new ShapedGlyph[length];
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
//We need to advance xOffset by the current letter spacing after each unicode cluster.
|
||||
if (lastCluster != glyphInfos[i].Cluster)
|
||||
{
|
||||
lastCluster = glyphInfos[i].Cluster;
|
||||
xOffset += TextStyle.LetterSpacing ?? 0;
|
||||
}
|
||||
|
||||
glyphs[i] = new ShapedGlyph
|
||||
{
|
||||
Codepoint = (ushort)glyphInfos[i].Codepoint,
|
||||
Position = new SKPoint(xOffset + glyphPositions[i].XOffset * scaleX, yOffset - glyphPositions[i].YOffset * scaleY),
|
||||
Width = glyphPositions[i].XAdvance * scaleX
|
||||
};
|
||||
|
||||
};
|
||||
xOffset += glyphPositions[i].XAdvance * scaleX;
|
||||
yOffset += glyphPositions[i].YAdvance * scaleY;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,13 @@ namespace QuestPDF.Fluent
|
||||
descriptor.MutateTextStyle(x => x.LineHeight(value));
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
public static T LetterSpacing<T>(this T descriptor, float value) where T : TextSpanDescriptor
|
||||
{
|
||||
descriptor.MutateTextStyle(x => x.LetterSpacing(value));
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static T Italic<T>(this T descriptor, bool value = true) where T : TextSpanDescriptor
|
||||
{
|
||||
descriptor.MutateTextStyle(x => x.Italic(value));
|
||||
|
||||
@@ -48,7 +48,12 @@ namespace QuestPDF.Fluent
|
||||
{
|
||||
return style.Mutate(TextStyleProperty.LineHeight, value);
|
||||
}
|
||||
|
||||
|
||||
public static TextStyle LetterSpacing(this TextStyle style, float value)
|
||||
{
|
||||
return style.Mutate(TextStyleProperty.LetterSpacing, value);
|
||||
}
|
||||
|
||||
public static TextStyle Italic(this TextStyle style, bool value = true)
|
||||
{
|
||||
return style.Mutate(TextStyleProperty.IsItalic, value);
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace QuestPDF.Infrastructure
|
||||
internal string? FontFamily { get; set; }
|
||||
internal float? Size { get; set; }
|
||||
internal float? LineHeight { get; set; }
|
||||
internal float? LetterSpacing { get; set; }
|
||||
internal FontWeight? FontWeight { get; set; }
|
||||
internal FontPosition? FontPosition { get; set; }
|
||||
internal bool? IsItalic { get; set; }
|
||||
@@ -27,6 +28,7 @@ namespace QuestPDF.Infrastructure
|
||||
FontFamily = Fonts.Lato,
|
||||
Size = 12,
|
||||
LineHeight = 1.2f,
|
||||
LetterSpacing = 0,
|
||||
FontWeight = Infrastructure.FontWeight.Normal,
|
||||
FontPosition = Infrastructure.FontPosition.Normal,
|
||||
IsItalic = false,
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace QuestPDF.Infrastructure
|
||||
FontFamily,
|
||||
Size,
|
||||
LineHeight,
|
||||
LetterSpacing,
|
||||
FontWeight,
|
||||
FontPosition,
|
||||
IsItalic,
|
||||
@@ -102,6 +103,19 @@ namespace QuestPDF.Infrastructure
|
||||
|
||||
return origin with { LineHeight = castedValue };
|
||||
}
|
||||
|
||||
if(property == TextStyleProperty.LetterSpacing)
|
||||
{
|
||||
if (!overrideValue && origin.LetterSpacing != null)
|
||||
return origin;
|
||||
|
||||
var castedValue = (float?)value;
|
||||
|
||||
if (origin.LetterSpacing == castedValue)
|
||||
return origin;
|
||||
|
||||
return origin with { LetterSpacing = castedValue };
|
||||
}
|
||||
|
||||
if (property == TextStyleProperty.FontWeight)
|
||||
{
|
||||
@@ -246,6 +260,7 @@ namespace QuestPDF.Infrastructure
|
||||
result = MutateStyle(result, TextStyleProperty.FontFamily, parent.FontFamily, overrideStyle);
|
||||
result = MutateStyle(result, TextStyleProperty.Size, parent.Size, overrideStyle);
|
||||
result = MutateStyle(result, TextStyleProperty.LineHeight, parent.LineHeight, overrideStyle);
|
||||
result = MutateStyle(result, TextStyleProperty.LetterSpacing, parent.LetterSpacing, overrideStyle);
|
||||
result = MutateStyle(result, TextStyleProperty.FontWeight, parent.FontWeight, overrideStyle);
|
||||
result = MutateStyle(result, TextStyleProperty.FontPosition, parent.FontPosition, overrideStyle);
|
||||
result = MutateStyle(result, TextStyleProperty.IsItalic, parent.IsItalic, overrideStyle);
|
||||
|
||||
Reference in New Issue
Block a user