mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-10-14 10:55:04 +08:00
#21 enable document creation using standard 14 font to test output
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Content;
|
||||
using PdfPig.Fonts;
|
||||
using PdfPig.Geometry;
|
||||
using PdfPig.Util;
|
||||
using PdfPig.Writer;
|
||||
@@ -59,6 +61,27 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSinglePageStandard14FontHelloWorld()
|
||||
{
|
||||
var builder = new PdfDocumentBuilder();
|
||||
|
||||
var page = builder.AddPage(PageSize.A4);
|
||||
|
||||
var font = builder.AddStandard14Font(Standard14Font.Helvetica);
|
||||
|
||||
page.AddText("Hello World!", 12, new PdfPoint(25, 520), font);
|
||||
|
||||
var b = builder.Build();
|
||||
|
||||
using (var document = PdfDocument.Open(b))
|
||||
{
|
||||
var page1 = document.GetPage(1);
|
||||
|
||||
Assert.Equal(new[] {"Hello", "World!"}, page1.GetWords().Select(x => x.Text));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSinglePageHelloWorld()
|
||||
{
|
||||
|
@@ -36,23 +36,24 @@
|
||||
private static readonly HashSet<string> Standard14Names = new HashSet<string>();
|
||||
private static readonly Dictionary<string, string> Standard14Mapping = new Dictionary<string, string>(34);
|
||||
private static readonly Dictionary<string, FontMetrics> Standard14AfmMap = new Dictionary<string, FontMetrics>(34);
|
||||
private static readonly Dictionary<Standard14Font, FontMetrics> Standard14AfmTypeMap = new Dictionary<Standard14Font, FontMetrics>(14);
|
||||
|
||||
static Standard14()
|
||||
{
|
||||
AddAdobeFontMetrics("Courier-Bold");
|
||||
AddAdobeFontMetrics("Courier-BoldOblique");
|
||||
AddAdobeFontMetrics("Courier");
|
||||
AddAdobeFontMetrics("Courier-Oblique");
|
||||
AddAdobeFontMetrics("Helvetica");
|
||||
AddAdobeFontMetrics("Helvetica-Bold");
|
||||
AddAdobeFontMetrics("Helvetica-BoldOblique");
|
||||
AddAdobeFontMetrics("Helvetica-Oblique");
|
||||
AddAdobeFontMetrics("Symbol");
|
||||
AddAdobeFontMetrics("Times-Bold");
|
||||
AddAdobeFontMetrics("Times-BoldItalic");
|
||||
AddAdobeFontMetrics("Times-Italic");
|
||||
AddAdobeFontMetrics("Times-Roman");
|
||||
AddAdobeFontMetrics("ZapfDingbats");
|
||||
AddAdobeFontMetrics("Courier-Bold", Standard14Font.CourierBold);
|
||||
AddAdobeFontMetrics("Courier-BoldOblique", Standard14Font.CourierBoldOblique);
|
||||
AddAdobeFontMetrics("Courier", Standard14Font.Courier);
|
||||
AddAdobeFontMetrics("Courier-Oblique", Standard14Font.CourierOblique);
|
||||
AddAdobeFontMetrics("Helvetica", Standard14Font.Helvetica);
|
||||
AddAdobeFontMetrics("Helvetica-Bold", Standard14Font.HelveticaBold);
|
||||
AddAdobeFontMetrics("Helvetica-BoldOblique", Standard14Font.HelveticaBoldOblique);
|
||||
AddAdobeFontMetrics("Helvetica-Oblique", Standard14Font.HelveticaOblique);
|
||||
AddAdobeFontMetrics("Symbol", Standard14Font.Symbol);
|
||||
AddAdobeFontMetrics("Times-Bold", Standard14Font.TimesBold);
|
||||
AddAdobeFontMetrics("Times-BoldItalic", Standard14Font.TimesBoldItalic);
|
||||
AddAdobeFontMetrics("Times-Italic", Standard14Font.TimesItalic);
|
||||
AddAdobeFontMetrics("Times-Roman", Standard14Font.TimesRoman);
|
||||
AddAdobeFontMetrics("ZapfDingbats", Standard14Font.ZapfDingbats);
|
||||
|
||||
// alternative names from Adobe Supplement to the ISO 32000
|
||||
AddAdobeFontMetrics("CourierCourierNew", "Courier");
|
||||
@@ -79,12 +80,12 @@
|
||||
AddAdobeFontMetrics("Times,BoldItalic", "Times-BoldItalic");
|
||||
}
|
||||
|
||||
private static void AddAdobeFontMetrics(string fontName)
|
||||
private static void AddAdobeFontMetrics(string fontName, Standard14Font? type = null)
|
||||
{
|
||||
AddAdobeFontMetrics(fontName, fontName);
|
||||
AddAdobeFontMetrics(fontName, fontName, type);
|
||||
}
|
||||
|
||||
private static void AddAdobeFontMetrics(string fontName, string afmName)
|
||||
private static void AddAdobeFontMetrics(string fontName, string afmName, Standard14Font? type = null)
|
||||
{
|
||||
Standard14Names.Add(fontName);
|
||||
Standard14Mapping.Add(fontName, afmName);
|
||||
@@ -109,6 +110,10 @@
|
||||
}
|
||||
|
||||
Standard14AfmMap[fontName] = Parser.Parse(bytes, true);
|
||||
if (type.HasValue)
|
||||
{
|
||||
Standard14AfmTypeMap[type.Value] = Standard14AfmMap[fontName];
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -127,6 +132,11 @@
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public static FontMetrics GetAdobeFontMetrics(Standard14Font fontType)
|
||||
{
|
||||
return Standard14AfmTypeMap[fontType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a font with this name is a standard 14 font.
|
||||
@@ -157,4 +167,22 @@
|
||||
return mappedName;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum Standard14Font
|
||||
{
|
||||
TimesRoman = 0,
|
||||
TimesBold = 1,
|
||||
TimesItalic=2,
|
||||
TimesBoldItalic = 3,
|
||||
Helvetica = 4,
|
||||
HelveticaBold = 5,
|
||||
HelveticaOblique = 6,
|
||||
HelveticaBoldOblique = 7,
|
||||
Courier = 8,
|
||||
CourierBold = 9,
|
||||
CourierOblique = 10,
|
||||
CourierBoldOblique = 11,
|
||||
Symbol = 12,
|
||||
ZapfDingbats = 13
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.ClippingPaths
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class ModifyClippingByEvenOddIntersect : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.ClippingPaths
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class ModifyClippingByNonZeroWindingIntersect : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class CloseAndStrokePath : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class CloseFillPathEvenOddRuleAndStroke : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class CloseFillPathNonZeroWindingAndStroke : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class EndPath : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class FillPathEvenOddRule : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class FillPathEvenOddRuleAndStroke : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class FillPathNonZeroWinding : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class FillPathNonZeroWindingAndStroke : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class FillPathNonZeroWindingCompatibility : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetColorRenderingIntent : IGraphicsStateOperation
|
||||
@@ -12,5 +13,10 @@
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetFlatnessTolerance : IGraphicsStateOperation
|
||||
@@ -20,6 +21,11 @@
|
||||
operationContext.GetCurrentState().Flatness = Tolerance;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Tolerance} {Symbol}";
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Core;
|
||||
|
||||
@@ -28,6 +29,11 @@
|
||||
operationContext.GetCurrentState().CapStyle = Cap;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{(int) Cap} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Core;
|
||||
|
||||
@@ -21,6 +22,11 @@
|
||||
operationContext.GetCurrentState().LineDashPattern = Pattern;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Pattern.Array} {Pattern.Phase} {Symbol}";
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Core;
|
||||
|
||||
@@ -28,6 +29,11 @@
|
||||
operationContext.GetCurrentState().JoinStyle = Join;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{(int)Join} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetLineWidth : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.LineWidth = Width;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Width} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.General
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetMiterLimit : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.MiterLimit = Limit;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Limit} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal interface IGraphicsStateOperation
|
||||
@@ -7,5 +8,7 @@
|
||||
string Operator { get; }
|
||||
|
||||
void Run(IOperationContext operationContext, IResourceStore resourceStore);
|
||||
|
||||
void Write(Stream stream);
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Tokens;
|
||||
|
||||
@@ -23,6 +24,11 @@
|
||||
operationContext.ApplyXObject(xobject);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name} {Symbol}";
|
||||
|
@@ -0,0 +1,32 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Util;
|
||||
|
||||
internal static class OperationWriteHelper
|
||||
{
|
||||
private static readonly byte WhiteSpace = OtherEncodings.StringAsLatin1Bytes(" ")[0];
|
||||
private static readonly byte NewLine = OtherEncodings.StringAsLatin1Bytes("\n")[0];
|
||||
|
||||
public static void WriteText(this Stream stream, string text)
|
||||
{
|
||||
var bytes = OtherEncodings.StringAsLatin1Bytes(text);
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
public static void WriteWhiteSpace(this Stream stream)
|
||||
{
|
||||
stream.WriteByte(WhiteSpace);
|
||||
}
|
||||
|
||||
public static void WriteNewLine(this Stream stream)
|
||||
{
|
||||
stream.WriteByte(NewLine);
|
||||
}
|
||||
|
||||
public static void WriteDecimal(this Stream stream, decimal value)
|
||||
{
|
||||
stream.WriteText(value.ToString("G"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Geometry;
|
||||
|
||||
@@ -26,6 +27,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{ControlPoint1.X} {ControlPoint1.Y} {ControlPoint2.X} {ControlPoint2.Y} {End.X} {End.Y} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Geometry;
|
||||
|
||||
@@ -23,6 +24,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{ControlPoint1.X} {ControlPoint1.Y} {End.X} {End.Y} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Geometry;
|
||||
|
||||
@@ -27,6 +28,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{LowerLeft.X} {LowerLeft.Y} {Width} {Height} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Geometry;
|
||||
|
||||
@@ -23,6 +24,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{ControlPoint2.X} {ControlPoint2.Y} {End.X} {End.Y} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Geometry;
|
||||
|
||||
@@ -20,6 +21,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{End.X} {End.Y} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Geometry;
|
||||
|
||||
@@ -20,6 +21,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Point.X} {Point.Y} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.PathConstruction
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class CloseSubpath : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetNonStrokeColorDeviceCmyk : IGraphicsStateOperation
|
||||
@@ -28,6 +29,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{C} {M} {Y} {K} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetNonStrokeColorDeviceGray : IGraphicsStateOperation
|
||||
@@ -19,6 +20,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Gray} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetNonStrokeColorDeviceRgb : IGraphicsStateOperation
|
||||
@@ -25,6 +26,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{R} {G} {B} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetStrokeColorDeviceCmyk : IGraphicsStateOperation
|
||||
@@ -28,6 +29,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{C} {M} {Y} {K} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetStrokeColorDeviceGray : IGraphicsStateOperation
|
||||
@@ -19,6 +20,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Gray} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetStrokeColorDeviceRgb : IGraphicsStateOperation
|
||||
@@ -25,6 +26,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{R} {G} {B} {Symbol}";
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using PdfPig.Core;
|
||||
|
||||
@@ -37,6 +38,24 @@
|
||||
operationContext.GetCurrentState().CurrentTransformationMatrix = newCtm;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
stream.WriteDecimal(Value[0]);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Value[1]);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Value[2]);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Value[3]);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Value[4]);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Value[5]);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteText(Symbol);
|
||||
stream.WriteNewLine();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Value[0]} {Value[1]} {Value[2]} {Value[3]} {Value[4]} {Value[5]} {Symbol}";
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class Pop : IGraphicsStateOperation
|
||||
@@ -27,6 +28,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.SpecialGraphicsState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class Push : IGraphicsStateOperation
|
||||
@@ -22,5 +23,10 @@
|
||||
{
|
||||
context.PushState();
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class StrokePath : IGraphicsStateOperation
|
||||
@@ -18,6 +19,11 @@
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextObjects
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using PdfPig.Core;
|
||||
|
||||
@@ -20,6 +21,12 @@
|
||||
operationContext.TextMatrices.TextLineMatrix = TransformationMatrix.Identity;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
stream.WriteText(Symbol);
|
||||
stream.WriteNewLine();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextObjects
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using PdfPig.Core;
|
||||
|
||||
@@ -20,6 +21,12 @@
|
||||
operationContext.TextMatrices.TextLineMatrix = TransformationMatrix.Identity;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
stream.WriteText(Symbol);
|
||||
stream.WriteNewLine();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextPositioning
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
/// <summary>
|
||||
@@ -27,6 +28,11 @@
|
||||
tdOperation.Run(operationContext, resourceStore);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Symbol;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextPositioning
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using PdfPig.Core;
|
||||
|
||||
@@ -40,6 +41,16 @@
|
||||
operationContext.TextMatrices.TextMatrix = transformed;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
stream.WriteDecimal(Tx);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Ty);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteText(Symbol);
|
||||
stream.WriteNewLine();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Tx} {Ty} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextPositioning
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using TextState;
|
||||
|
||||
@@ -30,6 +31,11 @@
|
||||
tdOperation.Run(operationContext, resourceStore);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Tx} {Ty} {Symbol}";
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextPositioning
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using PdfPig.Core;
|
||||
|
||||
@@ -30,6 +31,11 @@
|
||||
operationContext.TextMatrices.TextLineMatrix = newMatrix;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Value[0]} {Value[1]} {Value[2]} {Value[3]} {Value[4]} {Value[5]} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextShowing
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using TextPositioning;
|
||||
using Util.JetBrains.Annotations;
|
||||
@@ -36,6 +37,11 @@
|
||||
showText.Run(operationContext, resourceStore);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Text} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextShowing
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using TextPositioning;
|
||||
using TextState;
|
||||
@@ -48,6 +49,11 @@
|
||||
showText.Run(operationContext, resourceStore);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{WordSpacing} {CharacterSpacing} {Text} {Symbol}";
|
||||
|
@@ -1,5 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextShowing
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using IO;
|
||||
using Util;
|
||||
@@ -50,6 +52,19 @@
|
||||
operationContext.ShowText(input);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
if (Text == null && Bytes != null)
|
||||
{
|
||||
throw new NotImplementedException("Support for writing hex not done yet.");
|
||||
}
|
||||
|
||||
stream.WriteText($"({Text})");
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteText(Symbol);
|
||||
stream.WriteNewLine();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Text} {Symbol}";
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Tokens;
|
||||
|
||||
@@ -36,5 +37,10 @@
|
||||
{
|
||||
operationContext.ShowPositionedText(Array);
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetCharacterSpacing : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.FontState.CharacterSpacing = Spacing;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Spacing} {Symbol}";
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Tokens;
|
||||
using Util.JetBrains.Annotations;
|
||||
@@ -37,6 +38,16 @@
|
||||
currentState.FontState.FontName = Font;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
stream.WriteText(Font.ToString());
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteDecimal(Size);
|
||||
stream.WriteWhiteSpace();
|
||||
stream.WriteText(Symbol);
|
||||
stream.WriteNewLine();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Font} {Size} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetHorizontalScaling : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.FontState.HorizontalScaling = Scale;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Scale} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetTextLeading : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.FontState.Leading = Leading;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Leading} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
using Core;
|
||||
|
||||
@@ -23,6 +24,11 @@
|
||||
currentState.FontState.RenderingMode = Mode;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Mode} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetTextRise : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.FontState.Rise = Rise;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Rise} {Symbol}";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Graphics.Operations.TextState
|
||||
{
|
||||
using System.IO;
|
||||
using Content;
|
||||
|
||||
internal class SetWordSpacing : IGraphicsStateOperation
|
||||
@@ -22,6 +23,11 @@
|
||||
currentState.FontState.WordSpacing = Spacing;
|
||||
}
|
||||
|
||||
public void Write(Stream stream)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Spacing} {Symbol}";
|
||||
|
15
src/UglyToad.PdfPig/Writer/IWritingFont.cs
Normal file
15
src/UglyToad.PdfPig/Writer/IWritingFont.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace UglyToad.PdfPig.Writer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Geometry;
|
||||
using Tokens;
|
||||
|
||||
internal interface IWritingFont
|
||||
{
|
||||
bool HasWidths { get; }
|
||||
|
||||
bool TryGetBoundingBox(char character, out PdfRectangle boundingBox);
|
||||
|
||||
IReadOnlyDictionary<IToken, IToken> GetDictionary(NameToken fontKeyName);
|
||||
}
|
||||
}
|
@@ -5,12 +5,15 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Content;
|
||||
using Fonts;
|
||||
using Fonts.TrueType;
|
||||
using Fonts.TrueType.Parser;
|
||||
using Geometry;
|
||||
using Graphics.Operations;
|
||||
using IO;
|
||||
using Tokens;
|
||||
using Util;
|
||||
using Util.JetBrains.Annotations;
|
||||
|
||||
internal class PdfDocumentBuilder
|
||||
{
|
||||
@@ -21,7 +24,7 @@
|
||||
private readonly Dictionary<Guid, FontStored> fonts = new Dictionary<Guid, FontStored>();
|
||||
|
||||
public IReadOnlyDictionary<int, PdfPageBuilder> Pages => pages;
|
||||
public IReadOnlyDictionary<Guid, TrueTypeFontProgram> Fonts => fonts.ToDictionary(x => x.Key, x => x.Value.FontProgram);
|
||||
public IReadOnlyDictionary<Guid, IWritingFont> Fonts => fonts.ToDictionary(x => x.Key, x => x.Value.FontProgram);
|
||||
|
||||
public AddedFont AddTrueTypeFont(IReadOnlyList<byte> fontFileBytes)
|
||||
{
|
||||
@@ -31,7 +34,7 @@
|
||||
var id = Guid.NewGuid();
|
||||
var i = fonts.Count;
|
||||
var added = new AddedFont(id, NameToken.Create($"F{i}"));
|
||||
fonts[id] = new FontStored(added, font);
|
||||
fonts[id] = new FontStored(added, new TrueTypeWritingFont(font));
|
||||
|
||||
return added;
|
||||
}
|
||||
@@ -41,6 +44,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
public AddedFont AddStandard14Font(Standard14Font type)
|
||||
{
|
||||
var id = Guid.NewGuid();
|
||||
var name = NameToken.Create($"F{fonts.Count}");
|
||||
var added = new AddedFont(id, name);
|
||||
fonts[id] = new FontStored(added, new Standard14WritingFont(Standard14.GetAdobeFontMetrics(type)));
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
public PdfPageBuilder AddPage(PageSize size, bool isPortrait = true)
|
||||
{
|
||||
if (!size.TryGetPdfRectangle(out var rectangle))
|
||||
@@ -97,27 +110,17 @@
|
||||
// Body
|
||||
foreach (var font in fonts)
|
||||
{
|
||||
var widths = new ArrayToken(new[] { new NumericToken(0), new NumericToken(255) });
|
||||
var widthsObj = WriteObject(widths, memory, objectLocations, ref number);
|
||||
var fontDictionary = font.Value.FontProgram.GetDictionary(font.Value.FontKey.Name);
|
||||
|
||||
// TODO
|
||||
// var descriptorRef = new IndirectReference(number++, 0);
|
||||
|
||||
var dictionary = new DictionaryToken(new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.Type, NameToken.Font },
|
||||
{ NameToken.Subtype, NameToken.TrueType },
|
||||
{ NameToken.FirstChar, new NumericToken(0) },
|
||||
{ NameToken.LastChar, new NumericToken(255) },
|
||||
{ NameToken.Encoding, NameToken.WinAnsiEncoding },
|
||||
{ NameToken.Widths, widthsObj },
|
||||
//{ NameToken.FontDesc, new IndirectReferenceToken(descriptorRef) }
|
||||
});
|
||||
var dictionary = new DictionaryToken(fontDictionary);
|
||||
|
||||
var fontObj = WriteObject(dictionary, memory, objectLocations, ref number);
|
||||
fontsWritten.Add(font.Key, fontObj);
|
||||
}
|
||||
|
||||
|
||||
var resources = new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.ProcSet, new ArrayToken(new []{ NameToken.Create("PDF"), NameToken.Create("Text") }) }
|
||||
@@ -133,22 +136,37 @@
|
||||
resources.Add(NameToken.Font, new IndirectReferenceToken(fontsDictionaryRef.Number));
|
||||
}
|
||||
|
||||
var page = new DictionaryToken(new Dictionary<IToken, IToken>
|
||||
var pageReferences = new List<IndirectReferenceToken>();
|
||||
foreach (var page in pages)
|
||||
{
|
||||
{ NameToken.Type, NameToken.Page },
|
||||
var pageDictionary = new Dictionary<IToken, IToken>
|
||||
{
|
||||
NameToken.Resources,
|
||||
new DictionaryToken(resources)
|
||||
},
|
||||
{ NameToken.MediaBox, RectangleToArray(pages[1].PageSize) }
|
||||
});
|
||||
{NameToken.Type, NameToken.Page},
|
||||
{
|
||||
NameToken.Resources,
|
||||
new DictionaryToken(resources)
|
||||
},
|
||||
{NameToken.MediaBox, RectangleToArray(page.Value.PageSize)}
|
||||
};
|
||||
|
||||
var pageRef = WriteObject(page, memory, objectLocations, ref number);
|
||||
if (page.Value.Operations.Count > 0)
|
||||
{
|
||||
var contentStream = WriteContentStream(page.Value.Operations);
|
||||
|
||||
var contentStreamObj = WriteObject(contentStream, memory, objectLocations, ref number);
|
||||
|
||||
pageDictionary[NameToken.Contents] = new IndirectReferenceToken(contentStreamObj.Number);
|
||||
}
|
||||
|
||||
var pageRef = WriteObject(new DictionaryToken(pageDictionary), memory, objectLocations, ref number);
|
||||
|
||||
pageReferences.Add(new IndirectReferenceToken(pageRef.Number));
|
||||
}
|
||||
|
||||
var pagesDictionary = new DictionaryToken(new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.Type, NameToken.Pages },
|
||||
{ NameToken.Kids, new ArrayToken(new [] { new IndirectReferenceToken(pageRef.Number) }) },
|
||||
{ NameToken.Kids, new ArrayToken(pageReferences) },
|
||||
{ NameToken.Count, new NumericToken(1) }
|
||||
});
|
||||
|
||||
@@ -168,14 +186,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
private static StreamToken WriteContentStream(IReadOnlyList<IGraphicsStateOperation> content)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
foreach (var operation in content)
|
||||
{
|
||||
operation.Write(memoryStream);
|
||||
}
|
||||
|
||||
var bytes = memoryStream.ToArray();
|
||||
|
||||
var streamDictionary = new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.Length, new NumericToken(bytes.Length) }
|
||||
};
|
||||
|
||||
var stream = new StreamToken(new DictionaryToken(streamDictionary), bytes);
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
private static ArrayToken RectangleToArray(PdfRectangle rectangle)
|
||||
{
|
||||
return new ArrayToken(new[]
|
||||
{
|
||||
new NumericToken(rectangle.BottomLeft.X),
|
||||
new NumericToken(rectangle.BottomLeft.Y),
|
||||
new NumericToken(rectangle.TopRight.X),
|
||||
new NumericToken(rectangle.TopRight.Y)
|
||||
new NumericToken(rectangle.BottomLeft.X),
|
||||
new NumericToken(rectangle.BottomLeft.Y),
|
||||
new NumericToken(rectangle.TopRight.X),
|
||||
new NumericToken(rectangle.TopRight.Y)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -198,17 +238,19 @@
|
||||
stream.WriteByte(Break);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class FontStored
|
||||
{
|
||||
[NotNull]
|
||||
public AddedFont FontKey { get; }
|
||||
|
||||
public TrueTypeFontProgram FontProgram { get; }
|
||||
[NotNull]
|
||||
public IWritingFont FontProgram { get; }
|
||||
|
||||
public FontStored(AddedFont fontKey, TrueTypeFontProgram fontProgram)
|
||||
public FontStored(AddedFont fontKey, IWritingFont fontProgram)
|
||||
{
|
||||
FontKey = fontKey;
|
||||
FontProgram = fontProgram;
|
||||
FontKey = fontKey ?? throw new ArgumentNullException(nameof(fontKey));
|
||||
FontProgram = fontProgram ?? throw new ArgumentNullException(nameof(fontProgram));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,5 +267,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@
|
||||
using Graphics.Operations;
|
||||
using Graphics.Operations.SpecialGraphicsState;
|
||||
using Graphics.Operations.TextObjects;
|
||||
using Graphics.Operations.TextPositioning;
|
||||
using Graphics.Operations.TextShowing;
|
||||
using Graphics.Operations.TextState;
|
||||
|
||||
@@ -59,24 +60,18 @@
|
||||
|
||||
try
|
||||
{
|
||||
var ctm = TransformationMatrix.FromValues(position.X, 0, position.Y, 0, 0, 0);
|
||||
|
||||
var realWidth = ctm.Transform(widthRect).Width;
|
||||
var realWidth = widthRect.Width;
|
||||
|
||||
if (realWidth + position.X > PageSize.Width)
|
||||
{
|
||||
throw new InvalidOperationException("Text would exceed the bounds.");
|
||||
}
|
||||
|
||||
operations.Add(new ModifyCurrentTransformationMatrix(new[]
|
||||
{
|
||||
position.X, 0, position.Y, 0, 0, 0
|
||||
}));
|
||||
|
||||
var beginText = BeginText.Value;
|
||||
|
||||
operations.Add(beginText);
|
||||
operations.Add(new SetFontAndSize(font.Name, fontSize));
|
||||
operations.Add(new MoveToNextLineWithOffset(position.X, position.Y));
|
||||
operations.Add(new ShowText(text));
|
||||
operations.Add(EndText.Value);
|
||||
|
||||
@@ -90,7 +85,7 @@
|
||||
return this;
|
||||
}
|
||||
|
||||
private static decimal CalculateGlyphSpaceTextWidth(string text, TrueTypeFontProgram font)
|
||||
private static decimal CalculateGlyphSpaceTextWidth(string text, IWritingFont font)
|
||||
{
|
||||
var width = 0m;
|
||||
for (var i = 0; i < text.Length; i++)
|
||||
|
47
src/UglyToad.PdfPig/Writer/Standard14WritingFont.cs
Normal file
47
src/UglyToad.PdfPig/Writer/Standard14WritingFont.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace UglyToad.PdfPig.Writer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Fonts;
|
||||
using Fonts.Encodings;
|
||||
using Geometry;
|
||||
using Tokens;
|
||||
|
||||
internal class Standard14WritingFont : IWritingFont
|
||||
{
|
||||
private readonly FontMetrics metrics;
|
||||
|
||||
public bool HasWidths { get; } = false;
|
||||
|
||||
public Standard14WritingFont(FontMetrics metrics)
|
||||
{
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
public bool TryGetBoundingBox(char character, out PdfRectangle boundingBox)
|
||||
{
|
||||
var encoding = StandardEncoding.Instance;
|
||||
boundingBox = default(PdfRectangle);
|
||||
if (!metrics.CharacterMetrics.TryGetValue(encoding.GetName(character), out var characterMetric))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boundingBox = new PdfRectangle(characterMetric.BoundingBox.Left, characterMetric.BoundingBox.Bottom,
|
||||
characterMetric.BoundingBox.Left + characterMetric.WidthX, characterMetric.BoundingBox.Top);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<IToken, IToken> GetDictionary(NameToken fontKeyName)
|
||||
{
|
||||
return new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.Type, NameToken.Font },
|
||||
{ NameToken.Subtype, NameToken.Type1 },
|
||||
{ NameToken.BaseFont, NameToken.Create(metrics.FontName) },
|
||||
{ NameToken.Encoding, NameToken.MacRomanEncoding },
|
||||
{ NameToken.Name, fontKeyName }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -36,6 +36,9 @@
|
||||
|
||||
private static readonly byte[] StartXref = OtherEncodings.StringAsLatin1Bytes("startxref");
|
||||
|
||||
private static readonly byte[] StreamStart = OtherEncodings.StringAsLatin1Bytes("stream");
|
||||
private static readonly byte[] StreamEnd = OtherEncodings.StringAsLatin1Bytes("endstream");
|
||||
|
||||
private static readonly byte StringStart = GetByte("(");
|
||||
private static readonly byte StringEnd = GetByte(")");
|
||||
|
||||
@@ -81,8 +84,9 @@
|
||||
case ObjectToken objectToken:
|
||||
WriteObject(objectToken, outputStream);
|
||||
break;
|
||||
case StreamToken _:
|
||||
throw new NotImplementedException();
|
||||
case StreamToken streamToken:
|
||||
WriteStream(streamToken, outputStream);
|
||||
break;
|
||||
case StringToken stringToken:
|
||||
WriteString(stringToken, outputStream);
|
||||
break;
|
||||
@@ -268,6 +272,17 @@
|
||||
WriteLineBreak(outputStream);
|
||||
}
|
||||
|
||||
private static void WriteStream(StreamToken streamToken, Stream outputStream)
|
||||
{
|
||||
WriteDictionary(streamToken.StreamDictionary, outputStream);
|
||||
WriteLineBreak(outputStream);
|
||||
outputStream.Write(StreamStart, 0, StreamStart.Length);
|
||||
WriteLineBreak(outputStream);
|
||||
outputStream.Write(streamToken.Data.ToArray(), 0, streamToken.Data.Count);
|
||||
WriteLineBreak(outputStream);
|
||||
outputStream.Write(StreamEnd, 0, StreamEnd.Length);
|
||||
}
|
||||
|
||||
private static void WriteString(StringToken stringToken, Stream outputStream)
|
||||
{
|
||||
outputStream.WriteByte(StringStart);
|
||||
|
33
src/UglyToad.PdfPig/Writer/TrueTypeWritingFont.cs
Normal file
33
src/UglyToad.PdfPig/Writer/TrueTypeWritingFont.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace UglyToad.PdfPig.Writer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Fonts.TrueType;
|
||||
using Geometry;
|
||||
using Tokens;
|
||||
|
||||
internal class TrueTypeWritingFont : IWritingFont
|
||||
{
|
||||
private readonly TrueTypeFontProgram font;
|
||||
|
||||
public TrueTypeWritingFont(TrueTypeFontProgram font)
|
||||
{
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
public bool HasWidths { get; } = true;
|
||||
|
||||
public bool TryGetBoundingBox(char character, out PdfRectangle boundingBox)
|
||||
{
|
||||
return font.TryGetBoundingBox(character, out boundingBox);
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<IToken, IToken> GetDictionary(NameToken fontKeyName)
|
||||
{
|
||||
return new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.Type, NameToken.Font },
|
||||
{ NameToken.Subtype, NameToken.TrueType }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user