Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d39819bf8d | |||
| 5f636beb9d | |||
| 10683776bb | |||
| f2c47c4fd3 |
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using QuestPDF.Examples.Engine;
|
||||
using QuestPDF.Fluent;
|
||||
@@ -43,19 +44,41 @@ namespace QuestPDF.Examples
|
||||
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(300, 300)
|
||||
.PageSize(400, 600)
|
||||
.ProduceImages()
|
||||
.ShowResults()
|
||||
.Render(container =>
|
||||
{
|
||||
container.Extend().Canvas((canvas, size) =>
|
||||
{
|
||||
var bar = new BarChart
|
||||
container
|
||||
.Background(Colors.White)
|
||||
.Padding(25)
|
||||
.Stack(stack =>
|
||||
{
|
||||
Entries = entries,
|
||||
IsAnimated = false,
|
||||
};
|
||||
bar.Draw(canvas, (int)size.Width, (int)size.Height);
|
||||
});
|
||||
stack
|
||||
.Item()
|
||||
.PaddingBottom(10)
|
||||
.Text("Chart example", TextStyle.Default.Size(20).SemiBold().Color(Colors.Blue.Medium));
|
||||
|
||||
stack
|
||||
.Item()
|
||||
.Border(1)
|
||||
.ExtendHorizontal()
|
||||
.Height(300)
|
||||
.Canvas((canvas, size) =>
|
||||
{
|
||||
var chart = new BarChart
|
||||
{
|
||||
Entries = entries,
|
||||
|
||||
LabelOrientation = Orientation.Horizontal,
|
||||
ValueLabelOrientation = Orientation.Horizontal,
|
||||
|
||||
IsAnimated = false,
|
||||
};
|
||||
|
||||
chart.DrawContent(canvas, (int)size.Width, (int)size.Height);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@ namespace QuestPDF.Examples
|
||||
.PageSize(PageSizes.A4)
|
||||
.ProducePdf()
|
||||
.ShowResults()
|
||||
.Render(x => x.Image(new byte[] { 1, 2, 3 }));
|
||||
//.Render(x => GenerateStructure(x, 16));
|
||||
.Render(x => GenerateStructure(x, 16));
|
||||
}
|
||||
|
||||
private void GenerateStructure(IContainer container, int level)
|
||||
@@ -33,7 +32,7 @@ namespace QuestPDF.Examples
|
||||
if (level % 3 == 0)
|
||||
{
|
||||
container
|
||||
.Border(level / 10f)
|
||||
.Border(level / 4f)
|
||||
.BorderColor(Colors.Black)
|
||||
.Row(row =>
|
||||
{
|
||||
@@ -44,7 +43,7 @@ namespace QuestPDF.Examples
|
||||
else
|
||||
{
|
||||
container
|
||||
.Border(level / 10f)
|
||||
.Border(level / 4f)
|
||||
.BorderColor(Colors.Black)
|
||||
.Stack(stack =>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using NUnit.Framework;
|
||||
using QuestPDF.Drawing.Exceptions;
|
||||
using QuestPDF.Examples.Engine;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
@@ -10,23 +11,66 @@ namespace QuestPDF.Examples
|
||||
[Test]
|
||||
public void Stack()
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 360)
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Background(Colors.White)
|
||||
.Padding(15)
|
||||
.Grid(grid =>
|
||||
{
|
||||
grid.Spacing(15);
|
||||
|
||||
grid.Item().Background(Colors.Grey.Medium).Text(Placeholders.LoremIpsum());
|
||||
grid.Item().DebugPointer("Test").Background(Colors.Grey.Lighten1).Height(1000); // <-- problem
|
||||
grid.Item().Background(Colors.Grey.Lighten2).Height(150);
|
||||
});
|
||||
});
|
||||
Assert.Throws<DocumentLayoutException>(() =>
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 360)
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Padding(10)
|
||||
.Width(100)
|
||||
.Background(Colors.Grey.Lighten3)
|
||||
.DebugPointer("Example debug pointer")
|
||||
.Stack(x =>
|
||||
{
|
||||
x.Item().Text("Test");
|
||||
x.Item().Width(150);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Simple()
|
||||
{
|
||||
Assert.Throws<DocumentLayoutException>(() =>
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 360)
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Padding(10)
|
||||
.Width(100)
|
||||
.Background(Colors.Grey.Lighten3)
|
||||
.Width(150)
|
||||
.Text("Test");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DebugPointer()
|
||||
{
|
||||
Assert.Throws<DocumentLayoutException>(() =>
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(500, 360)
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
.Background(Colors.Grey.Lighten3)
|
||||
.Padding(10)
|
||||
.Width(100)
|
||||
.DebugPointer("Example debug pointer")
|
||||
.Width(150)
|
||||
.Text("Example");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using QuestPDF.Drawing.Exceptions;
|
||||
using QuestPDF.Examples.Engine;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
@@ -36,12 +37,15 @@ namespace QuestPDF.Examples
|
||||
[Test]
|
||||
public void Exception()
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(PageSizes.A5)
|
||||
.ProducePdf()
|
||||
.ShowResults()
|
||||
.Render(page => page.Image("non_existent.png"));
|
||||
Assert.Throws<DocumentComposeException>(() =>
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(PageSizes.A2)
|
||||
.ProducePdf()
|
||||
.ShowResults()
|
||||
.Render(page => page.Image("non_existent.png"));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@ namespace QuestPDF.Examples
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(350, 280)
|
||||
.ProducePdf()
|
||||
.ShowResults()
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace QuestPDF.UnitTests
|
||||
Color = Colors.Red.Medium
|
||||
})
|
||||
.DrawElement(new Size(400, 300))
|
||||
.ExpectCanvasDrawRectangle(new Position(0, 0), new Size(400, 300), Colors.Red.Medium)
|
||||
.ExpectCanvasDrawFilledRectangle(new Position(0, 0), new Size(400, 300), Colors.Red.Medium)
|
||||
.CheckDrawResult();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace QuestPDF.UnitTests
|
||||
Child = x.CreateChild()
|
||||
})
|
||||
.DrawElement(new Size(400, 300))
|
||||
.ExpectCanvasDrawRectangle(new Position(0, 0), new Size(400, 300), Colors.Red.Medium)
|
||||
.ExpectCanvasDrawFilledRectangle(new Position(0, 0), new Size(400, 300), Colors.Red.Medium)
|
||||
.ExpectChildDraw(new Size(400, 300))
|
||||
.CheckDrawResult();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using NUnit.Framework;
|
||||
using System.Drawing;
|
||||
using NUnit.Framework;
|
||||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Elements;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using QuestPDF.UnitTests.TestEngine;
|
||||
using Size = QuestPDF.Infrastructure.Size;
|
||||
|
||||
namespace QuestPDF.UnitTests
|
||||
{
|
||||
@@ -32,7 +34,29 @@ namespace QuestPDF.UnitTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Draw_HorizontalRight_VerticalTop()
|
||||
public void Draw_SameWidths_Optimized()
|
||||
{
|
||||
TestPlan
|
||||
.For(x => new Border
|
||||
{
|
||||
Top = 10,
|
||||
Right = 10,
|
||||
Bottom = 10,
|
||||
Left = 10,
|
||||
|
||||
Color = Colors.Red.Medium,
|
||||
|
||||
Child = x.CreateChild()
|
||||
})
|
||||
.DrawElement(new Size(400, 300))
|
||||
.ExpectChildDraw(new Size(400, 300))
|
||||
.ExpectCanvasDrawStrokedRectangle(new Size(400, 300), Colors.Red.Medium, 10)
|
||||
.ExpectChildDraw(new Size(400, 300))
|
||||
.CheckDrawResult();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Draw_VariousWidths()
|
||||
{
|
||||
TestPlan
|
||||
.For(x => new Border
|
||||
@@ -48,10 +72,10 @@ namespace QuestPDF.UnitTests
|
||||
})
|
||||
.DrawElement(new Size(400, 300))
|
||||
.ExpectChildDraw(new Size(400, 300))
|
||||
.ExpectCanvasDrawRectangle(new Position(-20, -5), new Size(430, 10), Colors.Red.Medium) // top
|
||||
.ExpectCanvasDrawRectangle(new Position(-20, -5), new Size(40, 320), Colors.Red.Medium) // left
|
||||
.ExpectCanvasDrawRectangle(new Position(-20, 285), new Size(430, 30), Colors.Red.Medium) // bottom
|
||||
.ExpectCanvasDrawRectangle(new Position(390, -5), new Size(20, 320), Colors.Red.Medium) // right
|
||||
.ExpectCanvasDrawFilledRectangle(new Position(-20, -5), new Size(430, 10), Colors.Red.Medium) // top
|
||||
.ExpectCanvasDrawFilledRectangle(new Position(-20, -5), new Size(40, 320), Colors.Red.Medium) // left
|
||||
.ExpectCanvasDrawFilledRectangle(new Position(-20, 285), new Size(430, 30), Colors.Red.Medium) // bottom
|
||||
.ExpectCanvasDrawFilledRectangle(new Position(390, -5), new Size(20, 320), Colors.Red.Medium) // right
|
||||
.ExpectChildDraw(new Size(400, 300))
|
||||
.CheckDrawResult();
|
||||
}
|
||||
|
||||
@@ -11,13 +11,15 @@ namespace QuestPDF.UnitTests.TestEngine
|
||||
public Action<float, float> ScaleFunc { get; set; }
|
||||
public Action<SKImage, Position, Size> DrawImageFunc { get; set; }
|
||||
public Action<string, Position, TextStyle> DrawTextFunc { get; set; }
|
||||
public Action<Position, Size, string> DrawRectFunc { get; set; }
|
||||
public Action<Position, Size, string> DrawFilledRectangleFunc { get; set; }
|
||||
public Action<Size, string, float> DrawStrokedRectangleFunc { get; set; }
|
||||
|
||||
public void Translate(Position vector) => TranslateFunc(vector);
|
||||
public void Rotate(float angle) => RotateFunc(angle);
|
||||
public void Scale(float scaleX, float scaleY) => ScaleFunc(scaleX, scaleY);
|
||||
|
||||
public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color);
|
||||
public void DrawFilledRectangle(Position vector, Size size, string color) => DrawFilledRectangleFunc(vector, size, color);
|
||||
public void DrawStrokedRectangle(Size size, string color, float width) => DrawStrokedRectangleFunc(size, color, width);
|
||||
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);
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace QuestPDF.UnitTests.TestEngine
|
||||
public void Rotate(float angle) => Operations.Add(new CanvasRotateOperation(angle));
|
||||
public void Scale(float scaleX, float scaleY) => Operations.Add(new CanvasScaleOperation(scaleX, scaleY));
|
||||
|
||||
public void DrawRectangle(Position vector, Size size, string color) => Operations.Add(new CanvasDrawRectangleOperation(vector, size, color));
|
||||
public void DrawFilledRectangle(Position vector, Size size, string color) => Operations.Add(new CanvasDrawFilledRectangleOperation(vector, size, color));
|
||||
public void DrawStrokedRectangle(Size size, string color, float width) => Operations.Add(new CanvasDrawStrokedRectangleOperation(size, color, width));
|
||||
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));
|
||||
|
||||
|
||||
+2
-2
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace QuestPDF.UnitTests.TestEngine.Operations
|
||||
{
|
||||
internal class CanvasDrawRectangleOperation : OperationBase
|
||||
internal class CanvasDrawFilledRectangleOperation : OperationBase
|
||||
{
|
||||
public Position Position { get; }
|
||||
public Size Size { get; }
|
||||
public string Color { get; }
|
||||
|
||||
public CanvasDrawRectangleOperation(Position position, Size size, string color)
|
||||
public CanvasDrawFilledRectangleOperation(Position position, Size size, string color)
|
||||
{
|
||||
Position = position;
|
||||
Size = size;
|
||||
@@ -0,0 +1,18 @@
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.UnitTests.TestEngine.Operations
|
||||
{
|
||||
internal class CanvasDrawStrokedRectangleOperation : OperationBase
|
||||
{
|
||||
public Size Size { get; }
|
||||
public string Color { get; }
|
||||
public float Width { get; set; }
|
||||
|
||||
public CanvasDrawStrokedRectangleOperation(Size size, string color, float width)
|
||||
{
|
||||
Size = size;
|
||||
Color = color;
|
||||
Width = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,17 +70,27 @@ namespace QuestPDF.UnitTests.TestEngine
|
||||
Assert.AreEqual(expected.ScaleX, scaleX, "Scale X");
|
||||
Assert.AreEqual(expected.ScaleY, scaleY, "Scale Y");
|
||||
},
|
||||
DrawRectFunc = (position, size, color) =>
|
||||
DrawFilledRectangleFunc = (position, size, color) =>
|
||||
{
|
||||
var expected = GetExpected<CanvasDrawRectangleOperation>();
|
||||
var expected = GetExpected<CanvasDrawFilledRectangleOperation>();
|
||||
|
||||
Assert.AreEqual(expected.Position.X, position.X, "Draw rectangle: X");
|
||||
Assert.AreEqual(expected.Position.Y, position.Y, "Draw rectangle: Y");
|
||||
Assert.AreEqual(expected.Position.X, position.X, "Draw filled rectangle: X");
|
||||
Assert.AreEqual(expected.Position.Y, position.Y, "Draw filled rectangle: Y");
|
||||
|
||||
Assert.AreEqual(expected.Size.Width, size.Width, "Draw rectangle: width");
|
||||
Assert.AreEqual(expected.Size.Height, size.Height, "Draw rectangle: height");
|
||||
Assert.AreEqual(expected.Size.Width, size.Width, "Draw filled rectangle: width");
|
||||
Assert.AreEqual(expected.Size.Height, size.Height, "Draw filled rectangle: height");
|
||||
|
||||
Assert.AreEqual(expected.Color, color, "Draw rectangle: color");
|
||||
Assert.AreEqual(expected.Color, color, "Draw filled rectangle: color");
|
||||
},
|
||||
DrawStrokedRectangleFunc = (size, color, width) =>
|
||||
{
|
||||
var expected = GetExpected<CanvasDrawStrokedRectangleOperation>();
|
||||
|
||||
Assert.AreEqual(expected.Size.Width, size.Width, "Draw stroked rectangle: width");
|
||||
Assert.AreEqual(expected.Size.Height, size.Height, "Draw stroked rectangle: height");
|
||||
|
||||
Assert.AreEqual(expected.Color, color, "Draw stroked rectangle: color");
|
||||
Assert.AreEqual(expected.Width, width, "Draw stroked rectangle: width");
|
||||
},
|
||||
DrawTextFunc = (text, position, style) =>
|
||||
{
|
||||
@@ -196,9 +206,14 @@ namespace QuestPDF.UnitTests.TestEngine
|
||||
return AddOperation(new CanvasRotateOperation(angle));
|
||||
}
|
||||
|
||||
public TestPlan ExpectCanvasDrawRectangle(Position position, Size size, string color)
|
||||
public TestPlan ExpectCanvasDrawFilledRectangle(Position position, Size size, string color)
|
||||
{
|
||||
return AddOperation(new CanvasDrawRectangleOperation(position, size, color));
|
||||
return AddOperation(new CanvasDrawFilledRectangleOperation(position, size, color));
|
||||
}
|
||||
|
||||
public TestPlan ExpectCanvasDrawStrokedRectangle(Size size, string color, float width)
|
||||
{
|
||||
return AddOperation(new CanvasDrawStrokedRectangleOperation(size, color, width));
|
||||
}
|
||||
|
||||
public TestPlan ExpectCanvasDrawText(string text, Position position, TextStyle style)
|
||||
|
||||
@@ -46,16 +46,10 @@ namespace QuestPDF.Drawing
|
||||
var metadata = document.GetMetadata();
|
||||
var pageContext = new PageContext();
|
||||
|
||||
DebuggingState debuggingState = null;
|
||||
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
debuggingState = ApplyDebugging(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
var debuggingState = metadata.ApplyDebugging ? ApplyDebugging(content) : null;
|
||||
|
||||
if (metadata.ApplyCaching)
|
||||
ApplyCaching(content);
|
||||
}
|
||||
|
||||
RenderPass(pageContext, new FreeCanvas(), content, metadata, debuggingState);
|
||||
RenderPass(pageContext, canvas, content, metadata, debuggingState);
|
||||
|
||||
@@ -23,7 +23,10 @@ namespace QuestPDF.Drawing
|
||||
/// (likely due to infinite layout), the exception is thrown.
|
||||
/// </summary>
|
||||
public int DocumentLayoutExceptionThreshold { get; set; } = 250;
|
||||
|
||||
|
||||
public bool ApplyCaching { get; set; } = !System.Diagnostics.Debugger.IsAttached;
|
||||
public bool ApplyDebugging { get; set; } = System.Diagnostics.Debugger.IsAttached;
|
||||
|
||||
public static DocumentMetadata Default => new DocumentMetadata();
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,12 @@ namespace QuestPDF.Drawing
|
||||
|
||||
}
|
||||
|
||||
public void DrawRectangle(Position vector, Size size, string color)
|
||||
public void DrawFilledRectangle(Position vector, Size size, string color)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void DrawStrokedRectangle(Size size, string color, float width)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace QuestPDF.Drawing.Proxy
|
||||
title += debugPointer.Highlight ? " 🌟" : string.Empty;
|
||||
}
|
||||
|
||||
if (item.SpacePlan.Type == SpacePlanType.Wrap)
|
||||
if (item.SpacePlan.Type != SpacePlanType.FullRender)
|
||||
title = "🔥 " + title;
|
||||
|
||||
builder.AppendLine(indent + title);
|
||||
@@ -109,7 +109,7 @@ namespace QuestPDF.Drawing.Proxy
|
||||
Value = x.GetValue(element)
|
||||
})
|
||||
.Where(x => !(x.Value is IElement))
|
||||
.Where(x => !(x.Value is IEnumerable<IElement>))
|
||||
.Where(x => x.Value is string || !(x.Value is IEnumerable))
|
||||
.Where(x => !(x.Value is TextStyle))
|
||||
.Select(x => $"{x.Property}: {FormatValue(x.Value)}");
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Concurrent;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace QuestPDF.Drawing
|
||||
{
|
||||
internal class SkiaCache
|
||||
{
|
||||
private static ConcurrentDictionary<string, SKPaint> RectangleFillPaints = new ConcurrentDictionary<string, SKPaint>();
|
||||
private static ConcurrentDictionary<string, SKPaint> RectangleStrokePaints = new ConcurrentDictionary<string, SKPaint>();
|
||||
|
||||
public static SKPaint GetRectangleFillPaint(string color)
|
||||
{
|
||||
return RectangleFillPaints.GetOrAdd(color, _ => Convert());
|
||||
|
||||
SKPaint Convert()
|
||||
{
|
||||
return new SKPaint
|
||||
{
|
||||
Color = SKColor.Parse(color),
|
||||
Style = SKPaintStyle.Fill
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static SKPaint GetRectangleStrokePaint(string color, float width)
|
||||
{
|
||||
var key = $"{color}|{width}";
|
||||
return RectangleStrokePaints.GetOrAdd(key, _ => Convert());
|
||||
|
||||
SKPaint Convert()
|
||||
{
|
||||
return new SKPaint
|
||||
{
|
||||
Color = SKColor.Parse(color),
|
||||
Style = SKPaintStyle.Stroke,
|
||||
StrokeWidth = width
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,20 @@ namespace QuestPDF.Drawing
|
||||
Canvas.Translate(vector.X, vector.Y);
|
||||
}
|
||||
|
||||
public void DrawRectangle(Position vector, Size size, string color)
|
||||
public void DrawFilledRectangle(Position vector, Size size, string color)
|
||||
{
|
||||
if (size.Width < Size.Epsilon || size.Height < Size.Epsilon)
|
||||
return;
|
||||
|
||||
var paint = color.ColorToPaint();
|
||||
var paint = SkiaCache.GetRectangleFillPaint(color);
|
||||
Canvas.DrawRect(vector.X, vector.Y, size.Width, size.Height, paint);
|
||||
}
|
||||
|
||||
public void DrawStrokedRectangle(Size size, string color, float width)
|
||||
{
|
||||
var paint = SkiaCache.GetRectangleStrokePaint(color, width);
|
||||
Canvas.DrawRect(0, 0, size.Width, size.Height, paint);
|
||||
}
|
||||
|
||||
public void DrawText(string text, Position vector, TextStyle style)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace QuestPDF.Drawing
|
||||
if (Type == SpacePlanType.Wrap)
|
||||
return Type.ToString();
|
||||
|
||||
return $"{Type} | width {Width:N2} | height {Height:N2}";
|
||||
return $"{Type} (Width: {Width:N2}, Height: {Height:N2})";
|
||||
}
|
||||
|
||||
public static implicit operator Size(SpacePlan spacePlan)
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace QuestPDF.Elements
|
||||
|
||||
internal override void Draw(Size availableSpace)
|
||||
{
|
||||
Canvas.DrawRectangle(Position.Zero, availableSpace, Color);
|
||||
Canvas.DrawFilledRectangle(Position.Zero, availableSpace, Color);
|
||||
base.Draw(availableSpace);
|
||||
}
|
||||
}
|
||||
|
||||
+42
-22
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
@@ -15,31 +16,50 @@ namespace QuestPDF.Elements
|
||||
internal override void Draw(Size availableSpace)
|
||||
{
|
||||
base.Draw(availableSpace);
|
||||
|
||||
Canvas.DrawRectangle(
|
||||
new Position(-Left/2, -Top/2),
|
||||
new Size(availableSpace.Width + Left/2 + Right/2, Top),
|
||||
Color);
|
||||
|
||||
Canvas.DrawRectangle(
|
||||
new Position(-Left/2, -Top/2),
|
||||
new Size(Left, availableSpace.Height + Top/2 + Bottom/2),
|
||||
Color);
|
||||
|
||||
Canvas.DrawRectangle(
|
||||
new Position(-Left/2, availableSpace.Height-Bottom/2),
|
||||
new Size(availableSpace.Width + Left/2 + Right/2, Bottom),
|
||||
Color);
|
||||
|
||||
Canvas.DrawRectangle(
|
||||
new Position(availableSpace.Width-Right/2, -Top/2),
|
||||
new Size(Right, availableSpace.Height + Top/2 + Bottom/2),
|
||||
Color);
|
||||
|
||||
if (HasEqualWidthOnAllSides())
|
||||
{
|
||||
Canvas.DrawStrokedRectangle(availableSpace, Color, Top);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCustomRectangle(availableSpace);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
private void DrawCustomRectangle(Size size)
|
||||
{
|
||||
return $"Border: Top({Top}) Right({Right}) Bottom({Bottom}) Left({Left}) Color({Color})";
|
||||
Canvas.DrawFilledRectangle(
|
||||
new Position(-Left / 2, -Top / 2),
|
||||
new Size(size.Width + Left / 2 + Right / 2, Top),
|
||||
Color);
|
||||
|
||||
Canvas.DrawFilledRectangle(
|
||||
new Position(-Left / 2, -Top / 2),
|
||||
new Size(Left, size.Height + Top / 2 + Bottom / 2),
|
||||
Color);
|
||||
|
||||
Canvas.DrawFilledRectangle(
|
||||
new Position(-Left / 2, size.Height - Bottom / 2),
|
||||
new Size(size.Width + Left / 2 + Right / 2, Bottom),
|
||||
Color);
|
||||
|
||||
Canvas.DrawFilledRectangle(
|
||||
new Position(size.Width - Right / 2, -Top / 2),
|
||||
new Size(Right, size.Height + Top / 2 + Bottom / 2),
|
||||
Color);
|
||||
}
|
||||
|
||||
private bool HasEqualWidthOnAllSides()
|
||||
{
|
||||
return IsClose(Top, Bottom) &&
|
||||
IsClose(Left, Right) &&
|
||||
IsClose(Top, Left);
|
||||
}
|
||||
|
||||
private static bool IsClose(float x, float y)
|
||||
{
|
||||
return Math.Abs(x - y) < Size.Epsilon;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,9 @@ namespace QuestPDF.Elements
|
||||
if (Handler == null || skiaCanvas == null)
|
||||
return;
|
||||
|
||||
var currentMatrix = skiaCanvas.TotalMatrix;
|
||||
var originalMatrix = skiaCanvas.TotalMatrix;
|
||||
Handler.Invoke(skiaCanvas, availableSpace);
|
||||
skiaCanvas.SetMatrix(currentMatrix);
|
||||
skiaCanvas.SetMatrix(originalMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ namespace QuestPDF.Elements.Text.Items
|
||||
|
||||
var text = Text.Substring(request.StartIndex, request.EndIndex - request.StartIndex);
|
||||
|
||||
request.Canvas.DrawRectangle(new Position(0, request.TotalAscent), new Size(request.TextSize.Width, request.TextSize.Height), Style.BackgroundColor);
|
||||
request.Canvas.DrawFilledRectangle(new Position(0, request.TotalAscent), new Size(request.TextSize.Width, request.TextSize.Height), Style.BackgroundColor);
|
||||
request.Canvas.DrawText(text, Position.Zero, Style);
|
||||
|
||||
// draw underline
|
||||
@@ -124,7 +124,7 @@ namespace QuestPDF.Elements.Text.Items
|
||||
|
||||
void DrawLine(float offset, float thickness)
|
||||
{
|
||||
request.Canvas.DrawRectangle(new Position(0, offset - thickness / 2f), new Size(request.TextSize.Width, thickness), Style.Color);
|
||||
request.Canvas.DrawFilledRectangle(new Position(0, offset - thickness / 2f), new Size(request.TextSize.Width, thickness), Style.Color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,10 @@ namespace QuestPDF.Elements.Text
|
||||
public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
|
||||
public List<ITextBlockItem> Children { get; set; } = new List<ITextBlockItem>();
|
||||
|
||||
public Queue<ITextBlockItem> RenderingQueue { get; set; }
|
||||
public int CurrentElementIndex { get; set; }
|
||||
public string Text => string.Join(" ", Children.Where(x => x is TextBlockSpan).Cast<TextBlockSpan>().Select(x => x.Text));
|
||||
|
||||
private Queue<ITextBlockItem> RenderingQueue { get; set; }
|
||||
private int CurrentElementIndex { get; set; }
|
||||
|
||||
public void ResetState()
|
||||
{
|
||||
|
||||
@@ -6,7 +6,8 @@ namespace QuestPDF.Infrastructure
|
||||
{
|
||||
void Translate(Position vector);
|
||||
|
||||
void DrawRectangle(Position vector, Size size, string color);
|
||||
void DrawFilledRectangle(Position vector, Size size, string color);
|
||||
void DrawStrokedRectangle(Size size, string color, float width);
|
||||
void DrawText(string text, Position position, TextStyle style);
|
||||
void DrawImage(SKImage image, Position position, Size size);
|
||||
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public override string ToString() => $"(W: {Width}, H: {Height})";
|
||||
public override string ToString() => $"(Width: {Width}, Height: {Height})";
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<Authors>MarcinZiabek</Authors>
|
||||
<Company>CodeFlint</Company>
|
||||
<PackageId>QuestPDF</PackageId>
|
||||
<Version>2021.12.0-alpha0</Version>
|
||||
<Version>2021.12.0</Version>
|
||||
<PackageDescription>QuestPDF is an open-source, modern and battle-tested library that can help you with generating PDF documents by offering friendly, discoverable and predictable C# fluent API.</PackageDescription>
|
||||
<PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/Resources/ReleaseNotes.txt"))</PackageReleaseNotes>
|
||||
<LangVersion>8</LangVersion>
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
- Added support for generating documents in the XPS file format.
|
||||
- Improved debugging experience for layout-related exceptions. To make the library predictable, it is (by design) very strict about layouting rules and throws an exception when a constraint cannot be met. In this release, each exception contains an element stack that contains all information needed to identify the issue. By default, this feature is enabled only when debugger is attached.
|
||||
- Improved layouting algorithm performance by introducing additional caching layer. This cache reduces the layouting time by half. By default, this feature is enabled only when debugger is not attached (mostly release mode).
|
||||
- Reduced GA pressure put by the layouting algorithm. Previously, every element measurement operation was represented by an object and the paging support was done via class hierarchy. New solution uses structs (which are value-types) and enums. This also makes the code more readable and easier to follow.
|
||||
- Added support for generating XPS files which are easier to print in the Windows environment. This was possible due to existing support in SkiaSharp. This change was proposed by **sbrkich**, thank you!
|
||||
|
||||
Reference in New Issue
Block a user