Skip to content

Commit

Permalink
Stable layout ready
Browse files Browse the repository at this point in the history
  • Loading branch information
garryxiao committed Apr 25, 2024
1 parent 66f16ab commit 5dc0e7b
Show file tree
Hide file tree
Showing 14 changed files with 529 additions and 207 deletions.
25 changes: 15 additions & 10 deletions ConsoleApp1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

// Global styles
pdf.Style.FontSize = 12;
pdf.Style.Border = new PdfStyleBorder(PdfColor.Red, 8);
pdf.Style.Border = new PdfStyleBorder(PdfColor.Red, 6);

// Fonts
//await pdf.Fonts.LoadAsync("C:\\Windows\\Fonts\\simsun.ttc");
Expand All @@ -41,8 +41,9 @@
// Paragraphs
var p1 = new PdfDiv();
var img = await PdfImage.LoadAsync("D:\\etsoo.png");
img.Style.SetHeight(40).SetOpacity(0.3f);
img.Style.SetHeight(40).SetOpacity(0.9f);
p1.Add(img);
//p1.Style.SetBorder(PdfColor.Red).SetBackgroundColor("#f3f3f3").SetPadding(6);
await w.WriteAsync(p1);

var h1 = new PdfHeading(PdfHeading.Level.H1);
Expand All @@ -54,6 +55,13 @@
h1.Add(new PdfSuperscript("®"));
await w.WriteAsync(h1);

var hr = new PdfHR()
{
Color = PdfColor.Red
};
hr.Style.SetOpacity(0.5f);
await w.WriteAsync(hr);

var p2 = new PdfParagraph();
p2.Add("青岛亿速思维\n网络科技有限公司 粗体").Style.SetFontStyle(PdfFontStyle.Bold);
p2.Add(PdfLineBreak.New);
Expand All @@ -62,22 +70,19 @@
p2.Add("上海亿商网络科技有限公司 粗体 & 斜体").Style.SetFontStyle(PdfFontStyle.BoldItalic);
await w.WriteAsync(p2);

var hr = new PdfHR();
await w.WriteAsync(hr);

var p5 = new PdfParagraph();
p5.Style.SetFontSize(10)
.SetTextAlign(PdfTextAlign.Justify)
.SetLineHeight(16)
.SetBorder(PdfColor.Blue, 1)
.SetBackgroundColor("#f3f3f3")
.SetPadding(0);
.SetLineHeight(15)
.SetBorder(PdfColor.Blue, 0.75f, PdfStyleBorderStyle.Dotted)
.SetBackgroundColor("#f6f6f6")
.SetPadding(6);
p5.Add("亿速思维(ETSOO)自成立以来致力于自主研发,在过去的20年中一直秉持着对技术的不懈追求和创新精神,为中小企业提供高效的信息化管理解决方案。公司的使命在于为客户创造价值,通过持续创新和卓越的服务,助力企业实现数字化转型。ETSOO has been dedicated to independent research and development since its establishment, maintaining an unwavering pursuit of technology and spirit of innovation over the past 20 years. We specialize in providing efficient information management solutions for small and medium-sized enterprises. Our mission is to create value for our customers by facilitating digital transformation through continuous innovation and excellent service.");
await w.WriteAsync(p5);

var p6 = new PdfParagraph();
p6.Style.SetPosition(PdfPosition.Absolute)
.SetTop(160)
.SetTop(200)
.SetFontSize(36)
.SetColor(new PdfColor(255, 0, 0))
.SetOpacity(0.1f)
Expand Down
109 changes: 71 additions & 38 deletions com.etsoo.EasyPdf/Content/PdfBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public abstract class PdfBlock : IPdfElement
/// </summary>
public Vector2 BasePoint { get; set; }

/// <summary>
/// Start point
/// 开始点
/// </summary>
public Vector2 StartPoint;

/// <summary>
/// Current line
/// 当前行
Expand All @@ -38,6 +44,12 @@ public abstract class PdfBlock : IPdfElement
private RectangleF layout;
private bool hasBorder;

/// <summary>
/// Bottom adjust
/// 底部调整
/// </summary>
protected float BottomAdjust { get; private set; }

/// <summary>
/// Set parent style
/// 设置父样式
Expand All @@ -57,71 +69,82 @@ public virtual void SetParentStyle(PdfStyle parentStyle, float fontSize)
/// <param name="writer">Current writer</param>
/// <param name="style">Current style</param>
/// <param name="rect">Current rectangle</param>
/// <param name="point">Current point</param>
/// <param name="line">Current completed line</param>
/// <param name="newLine">New line</param>
/// <returns></returns>
protected virtual async Task NewLineActionAsync(IPdfPage page, PdfWriter writer, PdfStyle style, RectangleF rect, PdfBlockLine line, PdfBlockLine? newLine)
protected virtual async Task NewLineActionAsync(IPdfPage page, PdfWriter writer, PdfStyle style, RectangleF rect, PdfPoint point, PdfBlockLine line, PdfBlockLine? newLine)
{
var bgcolor = style.BackgroundColor;
if (line.Chunks.Length > 0 && (bgcolor.HasValue || hasBorder))
if (bgcolor.HasValue)
{
var adjust = PdfTextChunk.LineHeightAdjust + 1;

// Start point
var startPoint = line.Chunks.First().StartPoint;
var startPoint = line.Chunks.FirstOrDefault()?.StartPoint ?? StartPoint;

var x = layout.X;
var width = layout.Width;
var lineHeight = line.Height;
float y, height;

if (line.First)
{
// First line
height = startPoint.Y - layout.Y + line.Height;
height = startPoint.Y - layout.Y + lineHeight;

if (newLine == null)
{
// Also the last line
height += BottomAdjust;
}
else
{
height += adjust;
}

y = layout.Y + height;
}
else if (newLine == null)
{
// Last line
height = line.Height + style.Padding?.Bottom ?? 0;
y = startPoint.Y + height;
height = lineHeight + BottomAdjust;
y = startPoint.Y + adjust + height;
}
else
{
// Other lines
height = line.Height;
y = startPoint.Y + height;
height = lineHeight;
y = startPoint.Y + adjust + height;
}

// Line rectangle
var gPoint = page.CalculatePoint(new Vector2(x, y));
var lineRect = new RectangleF(gPoint.X, gPoint.Y, width, height);

// Draw background color
if (bgcolor.HasValue)
{
//await page.WriteBackgroundAsync(bgcolor.Value, lineRect);
}
await page.WriteBackgroundAsync(bgcolor.Value, lineRect);
}

// Draw border
if (hasBorder)
{
var border = style.Border!.DeepClone();
// Border
if (hasBorder && newLine == null)
{
var adjust = PdfTextChunk.LineHeightAdjust + 1;

if (line.Index == 0)
{
border.Bottom.Width = 0;
}
else if (newLine == null)
{
border.Top.Width = 0;
}
else
{
border.Bottom.Width = 0;
border.Top.Width = 0;
}
// Start point
var startPoint = line.Chunks.FirstOrDefault()?.StartPoint ?? StartPoint;

await page.WriteBorderAsync(border, lineRect);
}
var width = layout.Width;
var height = startPoint.Y - layout.Y + line.Height + BottomAdjust + adjust;
var x = layout.X;
var y = layout.Y + height;

// Line rectangle
var gPoint = page.CalculatePoint(new Vector2(x, y));
var lineRect = new RectangleF(gPoint.X, gPoint.Y, width, height);

// Draw border
await page.WriteBorderAsync(style.Border!, lineRect);
}

// Update current line reference
Expand All @@ -143,6 +166,9 @@ public virtual async ValueTask WriteAsync(IPdfPage page, PdfWriter writer)
if (Rendered)
throw new InvalidOperationException("The block has been rendered.");

// Back to most left
page.CurrentPoint.X = 0;

// Save graphics state
await page.SaveStateAsync();

Expand All @@ -158,6 +184,8 @@ public virtual async ValueTask WriteAsync(IPdfPage page, PdfWriter writer)
// Rectangle
var (layout, rect) = style.GetRectangle(page.ContentRect.Size, page.CurrentPoint);
this.layout = layout;

BottomAdjust = layout.Bottom - rect.Bottom;
hasBorder = style.Border?.HasBorder ?? false;

// Rotate
Expand Down Expand Up @@ -187,14 +215,20 @@ public virtual async ValueTask WriteAsync(IPdfPage page, PdfWriter writer)
Y = rect.Y
} : page.CurrentPoint;

// Start point
StartPoint = point.ToVector2();

// Write
await WriteInnerAsync(page, writer, style, rect, point);
var completed = await WriteInnerAsync(page, writer, style, rect, point);

// Store graphics state
await page.RestoreStateAsync();

// Adjust
AdjustBottom(point, style);
if (completed)
{
AdjustBottom(point, style);
}

// Update render status
Rendered = true;
Expand All @@ -208,9 +242,8 @@ public virtual async ValueTask WriteAsync(IPdfPage page, PdfWriter writer)
/// <param name="style">Style</param>
protected virtual void AdjustBottom(PdfPoint point, PdfStyle style)
{
var paddingBottom = style.Padding?.Bottom ?? 0;
var marginBottom = style.Margin?.Bottom ?? 0 + style.Border?.Bottom.Width ?? 0;
point.Y += paddingBottom + marginBottom;
var marginBottom = style.Margin?.Bottom ?? 0;
point.Y += BottomAdjust + marginBottom;
}

/// <summary>
Expand All @@ -222,7 +255,7 @@ protected virtual void AdjustBottom(PdfPoint point, PdfStyle style)
/// <param name="style">Current style</param>
/// <param name="rect">Current rectangle</param>
/// <param name="point">Current point</param>
/// <returns>Task</returns>
protected abstract ValueTask WriteInnerAsync(IPdfPage page, PdfWriter writer, PdfStyle style, RectangleF rect, PdfPoint point);
/// <returns>Completed or not</returns>
protected abstract ValueTask<bool> WriteInnerAsync(IPdfPage page, PdfWriter writer, PdfStyle style, RectangleF rect, PdfPoint point);
}
}
14 changes: 14 additions & 0 deletions com.etsoo.EasyPdf/Content/PdfBlockLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ public record PdfBlockLine
/// </summary>
public PdfBlockLineChunk[] Chunks => [.. chunks];

/// <summary>
/// Has text
/// 是否有文本
/// </summary>
public bool HasText => chunks.Any(c => c.Chars.Count > 0);

internal PdfBlockLine(int index)
{
Index = index;
Expand Down Expand Up @@ -306,6 +312,14 @@ public void AddChunk(PdfBlockLineChunk chunk)
MaxFontHeight = fontHeight;
}
}
else
{
// No font, like picture
if (chunk.Height > MaxFontHeight)
{
MaxFontHeight = chunk.Height;
}
}
}
}
}
14 changes: 0 additions & 14 deletions com.etsoo.EasyPdf/Content/PdfChunk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,26 +105,12 @@ public virtual async Task<bool> WriteAsync(PdfWriter writer, RectangleF rect, Pd
await writer.DefineOpacityAsync(opacity, true);
}

// Margin left
var marginLeft = style.Margin?.Left ?? 0;

// Margin right
var marginRight = style.Margin?.Right ?? 0;

// Start point
StartPoint = point.ToVector2();

// Margin left
point.X += marginLeft;
line.Width += marginLeft;

// Inner rendering
var newPage = await WriteInnerAsync(writer, style, rect, point, line, newLineAction);

// Margin right
point.X += marginRight;
line.Width += marginRight;

// End point
EndPoint = point.ToVector2();

Expand Down
Loading

0 comments on commit 5dc0e7b

Please sign in to comment.