implement more type 1 commands to modify the context

This commit is contained in:
Eliot Jones
2018-11-13 22:22:24 +00:00
parent 904f773525
commit b477b3b560
19 changed files with 178 additions and 26 deletions

View File

@@ -53,6 +53,11 @@
commands.Add(new Close());
}
public PdfRectangle GetBoundingRectangle()
{
return new PdfRectangle();
}
public string ToSvg()
{
var builder = new StringBuilder();
@@ -61,6 +66,11 @@
pathCommand.WriteSvg(builder);
}
if (builder.Length == 0)
{
return string.Empty;
}
if (builder[builder.Length - 1] == ' ')
{
builder.Remove(builder.Length - 1, 1);

View File

@@ -1,5 +1,6 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Arithmetic
{
using System;
using System.Collections.Generic;
/// <summary>
@@ -21,12 +22,32 @@
public static void Run(Type1BuildCharContext context)
{
var index = (int)context.Stack.PopTop();
var numberOfArguments = (int)context.Stack.PopTop();
var otherSubroutineArguments = new List<decimal>(numberOfArguments);
for (int j = 0; j < numberOfArguments; j++)
var index = (int) context.Stack.PopTop();
// What it should do
//var numberOfArguments = (int)context.Stack.PopTop();
//var otherSubroutineArguments = new List<decimal>(numberOfArguments);
//for (int j = 0; j < numberOfArguments; j++)
//{
// otherSubroutineArguments.Add(context.Stack.PopTop());
//}
switch (index)
{
otherSubroutineArguments.Add(context.Stack.PopTop());
case 0:
{
context.IsFlexing = false;
if (context.FlexPoints.Count < 7)
{
throw new NotSupportedException("There must be at least 7 flex points defined by an other subroutine.");
}
context.ClearFlexPoints();
break;
}
case 1:
context.IsFlexing = true;
break;
}
}
}

View File

@@ -17,7 +17,7 @@
public static void Run(Type1BuildCharContext context)
{
// Do nothing
}
}
}

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Arithmetic
{
using Geometry;
/// <summary>
/// Sets the current point to (x, y) in absolute character space coordinates without performing a charstring moveto command.
/// </summary>
@@ -20,6 +22,8 @@
var x = context.Stack.PopBottom();
var y = context.Stack.PopBottom();
context.CurrentPosition = new PdfPoint(x, y);
context.Stack.Clear();
}
}

View File

@@ -17,6 +17,7 @@
public static void Run(Type1BuildCharContext context)
{
// Ignored.
context.Stack.Clear();
}
}

View File

@@ -1,4 +1,5 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
// ReSharper disable UnusedVariable
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
{
/// <summary>
/// Declares the vertical ranges of three horizontal stem zones:
@@ -31,6 +32,8 @@
var y2 = context.Stack.PopBottom();
var dy2 = context.Stack.PopBottom();
// Ignored
context.Stack.Clear();
}
}

View File

@@ -1,4 +1,5 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
// ReSharper disable UnusedVariable
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
{
/// <summary>
/// Declares the vertical range of a horizontal stem zone between the y coordinates y and y+dy,
@@ -21,6 +22,8 @@
var y = context.Stack.PopBottom();
var dy = context.Stack.PopBottom();
// Ignored
context.Stack.Clear();
}
}

View File

@@ -1,4 +1,5 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
// ReSharper disable UnusedVariable
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
{
/// <summary>
/// Declares the horizontal ranges of three vertical stem zones.
@@ -31,6 +32,8 @@
var x2 = context.Stack.PopBottom();
var dx2 = context.Stack.PopBottom();
// Ignored
context.Stack.Clear();
}
}

View File

@@ -1,4 +1,5 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
// ReSharper disable UnusedVariable
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.Hint
{
/// <summary>
/// Declares the horizontal range of a vertical stem zone between the x coordinates x and x+dx,
@@ -21,6 +22,8 @@
var x = context.Stack.PopBottom();
var dx = context.Stack.PopBottom();
// Ignored
context.Stack.Clear();
}
}

View File

@@ -36,6 +36,11 @@ namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands
public decimal PopTop()
{
if (stack.Count == 0)
{
throw new InvalidOperationException("Cannot pop from the top of an empty stack, invalid charstring parsed.");
}
var result = stack[stack.Count - 1];
stack.RemoveAt(stack.Count - 1);
return result;
@@ -43,6 +48,11 @@ namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands
public decimal PopBottom()
{
if (stack.Count == 0)
{
throw new InvalidOperationException("Cannot pop from the bottom of an empty stack, invalid charstring parsed.");
}
var result = stack[0];
stack.RemoveAt(0);
return result;

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.PathConstruction
{
using Geometry;
/// <summary>
/// Relative move to for horizontal dimension only.
/// </summary>
@@ -19,6 +21,19 @@
{
var x = context.Stack.PopBottom();
var actualX = context.CurrentPosition.X + x;
var y = context.CurrentPosition.Y;
if (context.IsFlexing)
{
// TODO: flex support
}
else
{
context.CurrentPosition = new PdfPoint(actualX, y);
context.Path.MoveTo(actualX, y);
}
context.Stack.Clear();
}
}

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.PathConstruction
{
using Geometry;
/// <summary>
/// Horizontal vertical curve to command. Draws a Bézier curve when the first Bézier tangent is horizontal and the second Bézier tangent is vertical.
/// Equivalent to dx1 0 dx2 dy2 0 dy3 rrcurveto.
@@ -18,10 +20,22 @@
public static void Run(Type1BuildCharContext context)
{
var postControlPointDeltaX = context.Stack.PopBottom();
var preControlPointDeltaX = context.Stack.PopBottom();
var preControlPointDeltaY = context.Stack.PopBottom();
var endPointDeltaY = context.Stack.PopBottom();
var dx1 = context.Stack.PopBottom();
var dx2 = context.Stack.PopBottom();
var dy2 = context.Stack.PopBottom();
var dy3 = context.Stack.PopBottom();
var x1 = context.CurrentPosition.X + dx1;
var y1 = context.CurrentPosition.Y;
var x2 = x1 + dx2;
var y2 = y1 + dy2;
var x3 = x2;
var y3 = y2 + dy3;
context.Path.BezierCurveTo(x1, y1, x2, y2, x3, y3);
context.CurrentPosition = new PdfPoint(x3, y3);
context.Stack.Clear();
}

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.PathConstruction
{
using Geometry;
/// <summary>
/// Vertical move to. Moves relative to the current point.
/// </summary>
@@ -19,6 +21,19 @@
{
var deltaY = context.Stack.PopBottom();
if (context.IsFlexing)
{
// TODO: flex commands
}
else
{
var y = context.CurrentPosition.Y + deltaY;
var x = context.CurrentPosition.X;
context.CurrentPosition = new PdfPoint(x, y);
context.Path.MoveTo(x, y);
}
context.Stack.Clear();
}
}

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.PathConstruction
{
using Geometry;
/// <summary>
/// Vertical-horizontal curveto.
/// Equivalent to 0 dy1 dx2 dy2 dx3 0 rrcurveto.
@@ -19,10 +21,22 @@
public static void Run(Type1BuildCharContext context)
{
var postControlPointDeltaY = context.Stack.PopBottom();
var preControlPointDeltaX = context.Stack.PopBottom();
var preControlPointDeltaY = context.Stack.PopBottom();
var endPointDeltaX = context.Stack.PopBottom();
var dy1 = context.Stack.PopBottom();
var dx2 = context.Stack.PopBottom();
var dy2 = context.Stack.PopBottom();
var dx3 = context.Stack.PopBottom();
var x1 = context.CurrentPosition.X;
var y1 = context.CurrentPosition.Y + dy1;
var x2 = x1 + dx2;
var y2 = y1 + dy2;
var x3 = x2 + dx3;
var y3 = y2;
context.Path.BezierCurveTo(x1, y1, x2, y2, x3, y3);
context.CurrentPosition = new PdfPoint(x3, y3);
context.Stack.Clear();
}

View File

@@ -25,8 +25,8 @@
var leftSidebearingPointX = context.Stack.PopBottom();
var characterWidthVectorX = context.Stack.PopBottom();
context.LeftSideBearing = leftSidebearingPointX;
context.Width = characterWidthVectorX;
context.LeftSideBearingX = leftSidebearingPointX;
context.WidthX = characterWidthVectorX;
context.CurrentPosition = new PdfPoint(leftSidebearingPointX, 0);

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.StartFinishOutline
{
using Geometry;
/// <summary>
/// Sets left sidebearing and the character width vector.
/// This command also sets the current point to(sbx, sby), but does not place the point in the character path.
@@ -23,6 +25,14 @@
var characterWidthX = context.Stack.PopBottom();
var characterWidthY = context.Stack.PopBottom();
context.LeftSideBearingX = leftSidebearingX;
context.LeftSideBearingY = leftSidebearingY;
context.WidthX = characterWidthX;
context.WidthY = characterWidthY;
context.CurrentPosition = new PdfPoint(leftSidebearingX, leftSidebearingY);
context.Stack.Clear();
}
}

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.StartFinishOutline
{
using System;
/// <summary>
/// Standard encoding accented character.
/// Makes an accented character from two other characters in the font program.
@@ -24,6 +26,12 @@
var baseCharacterCode = context.Stack.PopBottom();
var accentCharacterCode = context.Stack.PopBottom();
var baseCharacter = context.GetCharacter((int)baseCharacterCode);
var accentCharacter = context.GetCharacter((int) accentCharacterCode);
// TODO
throw new NotImplementedException("Not done yet...");
context.Stack.Clear();
}
}

View File

@@ -1,12 +1,17 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands
{
using System.Collections.Generic;
using Geometry;
internal class Type1BuildCharContext
{
public decimal Width { get; set; }
public decimal WidthX { get; set; }
public decimal LeftSideBearing { get; set; }
public decimal WidthY { get; set; }
public decimal LeftSideBearingX { get; set; }
public decimal LeftSideBearingY { get; set; }
public bool IsFlexing { get; set; }
@@ -17,5 +22,22 @@
public Type1Stack Stack { get; } = new Type1Stack();
public Type1Stack PostscriptStack { get; } = new Type1Stack();
public IReadOnlyList<PdfPoint> FlexPoints { get; }
public void AddFlexPoint(PdfPoint point)
{
}
public CharacterPath GetCharacter(int characterCode)
{
return null;
}
public void ClearFlexPoints()
{
}
}
}

View File

@@ -36,9 +36,5 @@
<EmbeddedResource Include="Resources\CMap\*" />
<EmbeddedResource Include="Resources\GlyphList\*" />
</ItemGroup>
<ItemGroup>
<Folder Include="Fonts\Type1\CharStrings\Commands\Subroutine\" />
</ItemGroup>
</Project>