mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-10-15 19:54:52 +08:00
#6 more work on type 2 char string, stuck on a bug
This commit is contained in:
@@ -65,6 +65,32 @@
|
||||
Assert.NotNull(box);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanInterpretATildeSmallSymbol()
|
||||
{
|
||||
var fileBytes = GetFileBytes("MinionPro.bin");
|
||||
|
||||
var font = parser.Parse(new CompactFontFormatData(fileBytes));
|
||||
|
||||
// Calls a global subroutine which adds to the hints
|
||||
var box = font.GetCharacterBoundingBox("Atildesmall");
|
||||
|
||||
Assert.NotNull(box);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanInterpretUniF687Symbol()
|
||||
{
|
||||
var fileBytes = GetFileBytes("MinionPro.bin");
|
||||
|
||||
var font = parser.Parse(new CompactFontFormatData(fileBytes));
|
||||
|
||||
// Calls hugely nested subroutines
|
||||
var box = font.GetCharacterBoundingBox("uniF687");
|
||||
|
||||
Assert.NotNull(box);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanInterpretAllGlyphs()
|
||||
{
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Geometry;
|
||||
using Util;
|
||||
|
||||
/// <summary>
|
||||
/// The context used and updated when interpreting the commands for a charstring.
|
||||
@@ -41,6 +42,8 @@
|
||||
/// </summary>
|
||||
public decimal? Width { get; set; }
|
||||
|
||||
public List<Union<decimal, LazyType2Command>> All { get; } = new List<Union<decimal, LazyType2Command>>();
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="Type2BuildCharContext"/>.
|
||||
/// </summary>
|
||||
@@ -135,6 +138,7 @@
|
||||
{
|
||||
foreach (var command in subroutine.Commands)
|
||||
{
|
||||
All.Add(command);
|
||||
command.Match(x => Stack.Push(x),
|
||||
act => act.Run(this));
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Charsets;
|
||||
using Geometry;
|
||||
using Util;
|
||||
@@ -731,8 +732,9 @@
|
||||
for (var i = 0; i < charStringBytes.Count; i++)
|
||||
{
|
||||
var charString = charStringBytes[i];
|
||||
var name = charset.GetNameByGlyphId(i);
|
||||
var sequence = ParseSingle(charString, localSubroutineSequences, globalSubroutineSequences);
|
||||
charStrings[charset.GetNameByGlyphId(i)] = new Type2CharStrings.CommandSequence(sequence);
|
||||
charStrings[name] = new Type2CharStrings.CommandSequence(sequence);
|
||||
}
|
||||
|
||||
return new Type2CharStrings(charStrings, localSubroutineSequences, globalSubroutineSequences);
|
||||
@@ -837,6 +839,15 @@
|
||||
Dictionary<int, Type2CharStrings.CommandSequence> localSubroutines,
|
||||
Dictionary<int, Type2CharStrings.CommandSequence> globalSubroutines)
|
||||
{
|
||||
int SafeStemCount(int counts)
|
||||
{
|
||||
if (counts % 2 == 0)
|
||||
{
|
||||
return counts / 2;
|
||||
}
|
||||
|
||||
return (counts - 1) / 2;
|
||||
}
|
||||
// Do a first pass to substitute in all local and global subroutines prior to the first hintmask.
|
||||
var commandsToCountHints = BuildFullCommandSequence(precedingCommands, localSubroutines, globalSubroutines);
|
||||
|
||||
@@ -862,7 +873,7 @@
|
||||
if (x.Name == "hintmask" && !hasEncounteredInitialHintMask)
|
||||
{
|
||||
hasEncounteredInitialHintMask = true;
|
||||
stemCount += precedingNumbers / 2;
|
||||
stemCount += SafeStemCount(precedingNumbers);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -871,17 +882,22 @@
|
||||
precedingNumbers = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
stemCount += precedingNumbers / 2;
|
||||
|
||||
stemCount += SafeStemCount(precedingNumbers);
|
||||
precedingNumbers = 0;
|
||||
});
|
||||
|
||||
if (hasEncounteredInitialHintMask)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var fullStemCount = stemCount;
|
||||
// The vstem command can be left out, e.g. for 12 20 hstemhm 4 6 hintmask, 4 and 6 act as the vertical hints
|
||||
if (precedingNumbers > 0 && !hasEncounteredInitialHintMask)
|
||||
{
|
||||
fullStemCount += precedingNumbers / 2;
|
||||
fullStemCount += SafeStemCount(precedingNumbers);
|
||||
}
|
||||
|
||||
var minimumFullBytes = (int)Math.Ceiling(fullStemCount / 8d);
|
||||
@@ -943,9 +959,17 @@
|
||||
{
|
||||
// Replace the call to the local or global subroutine with the actual routine.
|
||||
var routine = wasLocalSubroutine ? localSubroutines[subroutineIndex] : globalSubroutines[subroutineIndex];
|
||||
results.RemoveAt(i);
|
||||
results.InsertRange(i , routine.Commands);
|
||||
i -= 1;
|
||||
results.RemoveRange(i-1, 2);
|
||||
|
||||
// Skip any return commands since they interfere with counting.
|
||||
results.InsertRange(i-1 , routine.Commands.Where(x =>
|
||||
{
|
||||
var isReturn = false;
|
||||
x.Match(_ => {}, y => isReturn = y.Name == "return");
|
||||
return !isReturn;
|
||||
}));
|
||||
|
||||
i -= 2;
|
||||
}
|
||||
|
||||
// Exit once we hit the first hintmask since all hints have now been declared.
|
||||
|
@@ -52,6 +52,8 @@
|
||||
{
|
||||
glyph = Run(sequence);
|
||||
|
||||
var svg = glyph.ToFullSvg();
|
||||
|
||||
glyphs[name] = glyph;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -70,6 +72,7 @@
|
||||
var hasRunStackClearingCommand = false;
|
||||
foreach (var command in sequence.Commands)
|
||||
{
|
||||
context.All.Add(command);
|
||||
command.Match(x => context.Stack.Push(x),
|
||||
x =>
|
||||
{
|
||||
|
@@ -2,10 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Charsets;
|
||||
using CharStrings;
|
||||
using Dictionaries;
|
||||
@@ -164,7 +161,7 @@
|
||||
return stringIndex[index - 391];
|
||||
}
|
||||
|
||||
// technically this maps to .notdef, but we PDFBox uses this
|
||||
// technically this maps to .notdef, but PDFBox uses this
|
||||
return "SID" + index;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user