问题描述
我正在尝试根据我在C#应用程序中使用的一些矢量艺术来创建PDF。当我尝试从GraphicsPath映射点和类型时,我遇到两个主要问题。
I am trying to create a PDF based on some vector art I have in my C# application. I have two major problems when I try to map the points and types from a GraphicsPath.
- 有些路径只是缺失。
- 当子路径是内部边界时我需要以某种方式表明。即填写字母d中的圆圈。
我在NuGet上引用了iTextSharp 5.5.2。我在这里只使用AddString因为我想要一个简单的方法来演示在这个例子中创建一个复杂的路径。根据我的需要,我不会使用路径在PDF中放置文本。
I'm referencing iTextSharp 5.5.2 on NuGet. I'm only using AddString here because I want an easy way to demonstrate creating a complex path in this example. For my need I won't be using a path to place text in the PDF.
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PdfGen
{
class StackQuestion
{
public static void Main()
{
string filename = @"d:\itext.pdf";
using (var doc = new Document())
using (var fs = new FileStream(filename, FileMode.Create))
{
var writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
writer.DirectContent.SetColorFill(BaseColor.BLACK);
var path = new GraphicsPath(FillMode.Winding);
path.AddString("Hello World", FontFamily.GenericSerif,
(int)FontStyle.Regular, 25f, RectangleF.Empty,
StringFormat.GenericDefault);
AddPath(path, writer.DirectContent);
doc.Close();
}
System.Diagnostics.Process.Start(filename);
}
static void AddPath(GraphicsPath path, PdfContentByte to)
{
var view = to.PdfDocument.PageSize;
path.FillMode = System.Drawing.Drawing2D.FillMode.Winding;
var d = path.PathData;
for (int i = 0; i < d.Points.Length && i < d.Types.Length; i++)
{
var t = (PathPointType)d.Types[i];
var p = Fix(d.Points[i], view);
if (Match(t, PathPointType.Bezier))
{
var p2 = Fix(d.Points[++i], view);
if (d.Types.Length > i + 1 &&
Match((PathPointType)d.Types[i + 1],
PathPointType.Bezier3))
{
var p3 = Fix(d.Points[++i], view);
to.CurveTo(p.X, p.Y, p2.X, p2.Y, p3.X, p3.Y);
}
else
{
to.CurveTo(p.X, p.Y, p2.X, p2.Y);
}
}
if (Match(t, PathPointType.Line))
{
to.LineTo(p.X, p.Y);
}
if (Match(t, PathPointType.CloseSubpath))
{
to.ClosePath();
to.EoFill();
}
if (t == PathPointType.Start)
{
to.NewPath();
to.MoveTo(p.X, p.Y);
}
}
}
static bool Match(PathPointType type, PathPointType match)
{
return (type & match) == match;
}
static System.Drawing.PointF Fix(System.Drawing.PointF pt,
iTextSharp.text.Rectangle view)
{
return new System.Drawing.PointF(pt.X, view.Height - pt.Y);
}
}
}
推荐答案
我正在给自己发一个答案,以防其他人需要一个简单的函数在iTextSharp中绘制一个GraphicsPath。我在问题中的示例代码遇到两个问题:
I'm posting an answer to myself in case anyone else is in need of a simple function to plot out a GraphicsPath in iTextSharp. I had two problems with my sample code in the question:
- 因为mkl指出我试图经常填写
- 我没注意到PathPointType.Line是PathPointType.Bezier中的有效掩码,所以代码在曲线后面放回一条线。
更新代码:
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
namespace PdfGen
{
class StackQuestion
{
public static void Main()
{
string filename = @"d:\itext.pdf";
using (var doc = new Document())
using (var fs = new FileStream(filename, FileMode.Create))
{
var writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
writer.DirectContent.SetColorFill(BaseColor.BLACK);
var path = new GraphicsPath(FillMode.Winding);
path.AddString("Hello World", FontFamily.GenericSansSerif,
(int)FontStyle.Regular, 90f, PointF.Empty,
StringFormat.GenericDefault);
AddPath(path, writer.DirectContent);
writer.DirectContent.EoFill();
doc.Close();
}
System.Diagnostics.Process.Start(filename);
}
static void AddPath(GraphicsPath path, PdfContentByte to)
{
var view = to.PdfDocument.PageSize;
var d = path.PathData;
to.NewPath();
PointF? start = null;
for (int i = 0; i < d.Points.Length && i < d.Types.Length; i++)
{
var t = (PathPointType)d.Types[i];
var p = Fix(d.Points[i], view);
if (Match(t, PathPointType.Bezier))
{
var p2 = Fix(d.Points[++i], view);
if (d.Types.Length > i + 1 &&
Match((PathPointType)d.Types[i + 1],
PathPointType.Bezier))
{
var p3 = Fix(d.Points[++i], view);
to.CurveTo(p.X, p.Y, p2.X, p2.Y, p3.X, p3.Y);
}
else
{
to.CurveTo(p.X, p.Y, p2.X, p2.Y);
}
}
else if (Match(t, PathPointType.Line))
{
to.LineTo(p.X, p.Y);
}
if (Match(t, PathPointType.CloseSubpath))
{
if (start != null)
to.LineTo(start.Value.X, start.Value.Y);
start = null;
to.ClosePath();
}
if (t == PathPointType.Start)
{
if (start != null)
to.LineTo(start.Value.X, start.Value.Y);
start = p;
to.MoveTo(p.X, p.Y);
}
}
}
static bool Match(PathPointType type, PathPointType match)
{
return (type & match) == match;
}
static System.Drawing.PointF Fix(System.Drawing.PointF pt,
iTextSharp.text.Rectangle view)
{
return new System.Drawing.PointF(pt.X, view.Height - pt.Y);
}
}
}
这篇关于在PDF中绘制GraphicsPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!