2014-09-11 2 views
1

Я пытаюсь создать PDF на основе какого-либо векторного искусства, которое у меня есть в моем приложении C#. У меня две основные проблемы, когда я пытаюсь отобразить точки и типы из GraphicsPath.Нарисуйте GraphicsPath в PDF

  1. Некоторые пути просто отсутствуют.
  2. Когда подводный путь является внутренней границей, мне нужно как-то указать это. т.е. круг в букве d заполняется.

Я ссылаюсь на iTextSharp 5.5.2 на NuGet. Я использую только AddString, потому что мне нужен простой способ продемонстрировать создание сложного пути в этом примере. Для моей потребности я не буду использовать путь для размещения текста в 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); 
     } 
    } 
} 
+0

Вы смотрели на вашем пути источника и проверил, есть ли что-нибудь своеобразное в проблемных местах? – mkl

+0

Кстати, вы даже нечетно заполняете, когда вы нажимаете на ближний путь. Почему бы не заполнить весь путь в конце? И вы уверены, что четный-нечетный, а не ненулевой обмотки? – mkl

+0

Это не похоже на проблему iText. Кажется, это основано на неправильном представлении о синтаксисе PDF. Лучший способ отладить это - посмотреть на синтаксис с помощью iText RUPS: http://itextpdf.com/product/itext_rups –

ответ

1

Я отправляю ответ на себя в случае, если кто-то нуждается в простой функции для построения графика оттуда GraphicsPath в iTextSharp. У меня было две проблемы с моим примером кода в вопросе:

  1. , как MKL указал я пытался заполнить слишком часто
  2. я не заметил, что PathPointType.Line является действительным маска в PathPointType.Bezier так код, помещающий линию обратно в начало координат после кривой.

Updatd Код:

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); 
     } 
    } 
}