use standardencoding name for seac command in type 1 charstrings

This commit is contained in:
Eliot Jones
2019-05-11 15:57:19 +01:00
parent 5b5a0b7f55
commit 55d34e3998
3 changed files with 38 additions and 6 deletions

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.StartFinishOutline namespace UglyToad.PdfPig.Fonts.Type1.CharStrings.Commands.StartFinishOutline
{ {
using Encodings;
/// <summary> /// <summary>
/// Standard encoding accented character. /// Standard encoding accented character.
/// Makes an accented character from two other characters in the font program. /// Makes an accented character from two other characters in the font program.
@@ -21,11 +23,15 @@
var accentLeftSidebearingX = context.Stack.PopBottom(); var accentLeftSidebearingX = context.Stack.PopBottom();
var accentOriginX = context.Stack.PopBottom(); var accentOriginX = context.Stack.PopBottom();
var accentOriginY = context.Stack.PopBottom(); var accentOriginY = context.Stack.PopBottom();
var baseCharacterCode = context.Stack.PopBottom(); var baseCharacterCode = (int)context.Stack.PopBottom();
var accentCharacterCode = context.Stack.PopBottom(); var accentCharacterCode = (int)context.Stack.PopBottom();
var baseCharacter = context.GetCharacter((int)baseCharacterCode); // Both bchar and achar are codes that these characters are assigned in the Adobe StandardEncoding vector
var accentCharacter = context.GetCharacter((int) accentCharacterCode); var baseCharacterName = StandardEncoding.Instance.CodeToNameMap[baseCharacterCode];
var accentCharacterName = StandardEncoding.Instance.CodeToNameMap[accentCharacterCode];
var baseCharacter = context.GetCharacter(baseCharacterName);
var accentCharacter = context.GetCharacter(accentCharacterName);
// TODO: full seac implementation. // TODO: full seac implementation.
context.SetPath(baseCharacter); context.SetPath(baseCharacter);

View File

@@ -8,6 +8,7 @@
internal class Type1BuildCharContext internal class Type1BuildCharContext
{ {
private readonly Func<int, PdfPath> characterByIndexFactory; private readonly Func<int, PdfPath> characterByIndexFactory;
private readonly Func<string, PdfPath> characterByNameFactory;
public IReadOnlyDictionary<int, Type1CharStrings.CommandSequence> Subroutines { get; } public IReadOnlyDictionary<int, Type1CharStrings.CommandSequence> Subroutines { get; }
public decimal WidthX { get; set; } public decimal WidthX { get; set; }
@@ -32,9 +33,11 @@
public IReadOnlyList<PdfPoint> FlexPoints { get; } public IReadOnlyList<PdfPoint> FlexPoints { get; }
public Type1BuildCharContext(IReadOnlyDictionary<int, Type1CharStrings.CommandSequence> subroutines, public Type1BuildCharContext(IReadOnlyDictionary<int, Type1CharStrings.CommandSequence> subroutines,
Func<int, PdfPath> characterByIndexFactory) Func<int, PdfPath> characterByIndexFactory,
Func<string, PdfPath> characterByNameFactory)
{ {
this.characterByIndexFactory = characterByIndexFactory ?? throw new ArgumentNullException(nameof(characterByIndexFactory)); this.characterByIndexFactory = characterByIndexFactory ?? throw new ArgumentNullException(nameof(characterByIndexFactory));
this.characterByNameFactory = characterByNameFactory ?? throw new ArgumentNullException(nameof(characterByNameFactory));
Subroutines = subroutines ?? throw new ArgumentNullException(nameof(subroutines)); Subroutines = subroutines ?? throw new ArgumentNullException(nameof(subroutines));
} }
@@ -48,6 +51,11 @@
return characterByIndexFactory(characterCode); return characterByIndexFactory(characterCode);
} }
public PdfPath GetCharacter(string characterName)
{
return characterByNameFactory(characterName);
}
public void SetPath(PdfPath path) public void SetPath(PdfPath path)
{ {
Path = path ?? throw new ArgumentNullException(nameof(path)); Path = path ?? throw new ArgumentNullException(nameof(path));

View File

@@ -17,7 +17,7 @@
public IReadOnlyDictionary<int, CommandSequence> Subroutines { get; } public IReadOnlyDictionary<int, CommandSequence> Subroutines { get; }
public Type1CharStrings(IReadOnlyDictionary<string, CommandSequence> charStrings, IReadOnlyDictionary<int, string> charStringIndexToName, public Type1CharStrings(IReadOnlyDictionary<string, CommandSequence> charStrings, IReadOnlyDictionary<int, string> charStringIndexToName,
IReadOnlyDictionary<int, CommandSequence> subroutines) IReadOnlyDictionary<int, CommandSequence> subroutines)
{ {
this.charStringIndexToName = charStringIndexToName ?? throw new ArgumentNullException(nameof(charStringIndexToName)); this.charStringIndexToName = charStringIndexToName ?? throw new ArgumentNullException(nameof(charStringIndexToName));
@@ -71,8 +71,26 @@
glyphs[name] = path; glyphs[name] = path;
return path;
}, s =>
{
if (glyphs.TryGetValue(s, out var result))
{
return result;
}
if (!CharStrings.TryGetValue(s, out var charstring))
{
throw new InvalidOperationException($"Tried to retrieve Type 1 charstring by name {s} but it was not found in the charstrings.");
}
var path = Run(charstring);
glyphs[s] = path;
return path; return path;
}); });
foreach (var command in sequence.Commands) foreach (var command in sequence.Commands)
{ {
command.Match(x => context.Stack.Push(x), command.Match(x => context.Stack.Push(x),