mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-10-14 10:55:04 +08:00
finish moving all parsing to token scanner
This commit is contained in:
@@ -1,15 +1,18 @@
|
||||
namespace UglyToad.PdfPig.Tests.Filters
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PdfPig.ContentStream;
|
||||
using PdfPig.Filters;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
public class Ascii85FilterTests
|
||||
{
|
||||
private readonly Ascii85Filter filter = new Ascii85Filter();
|
||||
|
||||
private readonly DictionaryToken dictionary = new DictionaryToken(new Dictionary<IToken, IToken>());
|
||||
|
||||
[Fact]
|
||||
public void DecodesWikipediaExample()
|
||||
{
|
||||
@@ -20,7 +23,7 @@ O<DJ+*.@<*K0@<6L(Df-\0Ec5e;DffZ(EZee.Bl.9pF""AGXBPCsi + DGm >@3BB / F * &OCAfu2
|
||||
l(DId<j@<? 3r@:F % a + D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G
|
||||
> uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c~>");
|
||||
|
||||
var result = filter.Decode(bytes, new PdfDictionary(), 0);
|
||||
var result = filter.Decode(bytes, dictionary, 0);
|
||||
|
||||
var text = Encoding.ASCII.GetString(result);
|
||||
|
||||
@@ -35,7 +38,7 @@ O<DJ+*.@<*K0@<6L(Df-\0Ec5e;DffZ(EZee.Bl.9pF""AGXBPCsi + DGm >@3BB / F * &OCAfu2
|
||||
{
|
||||
var bytes = Encoding.ASCII.GetBytes("9jqo^zBlbD-");
|
||||
|
||||
var result = filter.Decode(bytes, new PdfDictionary(), 1);
|
||||
var result = filter.Decode(bytes, dictionary, 1);
|
||||
|
||||
var text = Encoding.ASCII.GetString(result);
|
||||
|
||||
@@ -47,7 +50,7 @@ O<DJ+*.@<*K0@<6L(Df-\0Ec5e;DffZ(EZee.Bl.9pF""AGXBPCsi + DGm >@3BB / F * &OCAfu2
|
||||
{
|
||||
var bytes = Encoding.ASCII.GetBytes("qjzqo^");
|
||||
|
||||
Action action = () => filter.Decode(bytes, new PdfDictionary(), 0);
|
||||
Action action = () => filter.Decode(bytes, dictionary, 0);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(action);
|
||||
}
|
||||
@@ -57,7 +60,7 @@ O<DJ+*.@<*K0@<6L(Df-\0Ec5e;DffZ(EZee.Bl.9pF""AGXBPCsi + DGm >@3BB / F * &OCAfu2
|
||||
{
|
||||
var bytes = Encoding.ASCII.GetBytes("9jqo^B");
|
||||
|
||||
Action action = () => filter.Decode(bytes, new PdfDictionary(), 1);
|
||||
Action action = () => filter.Decode(bytes, dictionary, 1);
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(action);
|
||||
}
|
||||
@@ -102,7 +105,7 @@ T()<(%'A;f?Ma+CT;%+E_a:A0>K&EZek1D/aN,F)u&6DBNA*A0>f4BOu4*+EM76E,9eK+B3(_<%9""p.
|
||||
F*22=@:F%a+=SF4C'moi+=Li?EZeh0FD)e-@<>p#@;]TuBl.9kATKCFGA(],AKYo5BOu4*+CT;%+C#7pF_Pr+@VfTuDf0B:+=SF4C'moi+=
|
||||
Li?EZek1DKKT1F`2DD/TboKAKY](@:s.m/h%oBC'mC/$>""*cF*)G6@;Q?_DIdZpC&~>";
|
||||
|
||||
var result = filter.Decode(Encoding.ASCII.GetBytes(input), new PdfDictionary(), 0);
|
||||
var result = filter.Decode(Encoding.ASCII.GetBytes(input), dictionary, 0);
|
||||
|
||||
var text = Encoding.ASCII.GetString(result);
|
||||
|
||||
@@ -122,7 +125,7 @@ T()<(%'A;f?Ma+CT;%+E_a:A0>K&EZek1D/aN,F)u&6DBNA*A0>f4BOu4*+EM76E,9eK+B3(_<%9""p.
|
||||
F*22=@:F%a+=SF4C'moi+=Li?EZeh0FD)e-@<>p#@;]TuBl.9kATKCFGA(],AKYo5BOu4*+CT;%+C#7pF_Pr+@VfTuDf0B:+=SF4C'moi+=
|
||||
Li?EZek1DKKT1F`2DD/TboKAKY](@:s.m/h%oBC'mC/$>""*cF*)G6@;Q?_DIdZpC&";
|
||||
|
||||
var result = filter.Decode(Encoding.ASCII.GetBytes(input), new PdfDictionary(), 0);
|
||||
var result = filter.Decode(Encoding.ASCII.GetBytes(input), dictionary, 0);
|
||||
|
||||
var text = Encoding.ASCII.GetString(result);
|
||||
|
||||
|
@@ -1,13 +1,16 @@
|
||||
namespace UglyToad.PdfPig.Tests.Filters
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PdfPig.ContentStream;
|
||||
using PdfPig.Filters;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
public class AsciiHexDecodeFilterTests
|
||||
{
|
||||
private readonly DictionaryToken dictionary = new DictionaryToken(new Dictionary<IToken, IToken>());
|
||||
|
||||
[Fact]
|
||||
public void DecodesEncodedTextProperly()
|
||||
{
|
||||
@@ -16,7 +19,7 @@
|
||||
var input = Encoding.ASCII.GetBytes(
|
||||
"7368652073656C6C73207365617368656C6C73206F6E20746865207365612073686F7265");
|
||||
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
var decodedText = Encoding.ASCII.GetString(decoded);
|
||||
|
||||
@@ -31,7 +34,7 @@
|
||||
var input = Encoding.ASCII.GetBytes(
|
||||
"<7368652073656C6C73207365617368656C6C73206F6E20746865207365612073686F7265>");
|
||||
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
var decodedText = Encoding.ASCII.GetString(decoded);
|
||||
|
||||
@@ -47,7 +50,7 @@
|
||||
@"6F6E6365207 5706F6E206120 74696D6520696E
|
||||
20612067616C6178792046617220466172204177 6179");
|
||||
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
var decodedText = Encoding.ASCII.GetString(decoded);
|
||||
|
||||
@@ -61,7 +64,7 @@
|
||||
|
||||
var input = Encoding.ASCII.GetBytes("6f6e63652075706f6e20612074696d6520696e20612067616c61787920466172204661722041776179");
|
||||
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
var decodedText = Encoding.ASCII.GetString(decoded);
|
||||
|
||||
@@ -75,7 +78,7 @@
|
||||
{
|
||||
var input = Encoding.ASCII.GetBytes(inputString);
|
||||
|
||||
Action action = () => new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
Action action = () => new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(action);
|
||||
}
|
||||
@@ -85,7 +88,7 @@
|
||||
{
|
||||
var input = Encoding.ASCII.GetBytes("AE5>");
|
||||
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
var decodedText = Encoding.UTF7.GetString(decoded);
|
||||
|
||||
@@ -99,7 +102,7 @@
|
||||
|
||||
var input = Encoding.ASCII.GetBytes("6f6e63652075706f6e20612074696d6520696e20612067616c61787920466172204661722041776179> There is stuff following the EOD.");
|
||||
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, new PdfDictionary(), 1);
|
||||
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);
|
||||
|
||||
var decodedText = Encoding.ASCII.GetString(decoded);
|
||||
|
||||
|
@@ -1,9 +1,10 @@
|
||||
namespace UglyToad.PdfPig.Tests.Filters
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Parser.Parts;
|
||||
using PdfPig.ContentStream;
|
||||
using PdfPig.Filters;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
public class DecodeParameterResolverTests
|
||||
@@ -21,7 +22,7 @@
|
||||
[Fact]
|
||||
public void NegativeIndex_Throws()
|
||||
{
|
||||
Action action = () => resolver.GetFilterParameters(new PdfDictionary(), -1);
|
||||
Action action = () => resolver.GetFilterParameters(new DictionaryToken(new Dictionary<IToken, IToken>()), -1);
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(action);
|
||||
}
|
||||
@@ -29,9 +30,9 @@
|
||||
[Fact]
|
||||
public void EmptyDictionary_ReturnsEmptyDictionary()
|
||||
{
|
||||
var result = resolver.GetFilterParameters(new PdfDictionary(), 0);
|
||||
var result = resolver.GetFilterParameters(new DictionaryToken(new Dictionary<IToken, IToken>()), 0);
|
||||
|
||||
Assert.Empty(result);
|
||||
Assert.Empty(result.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
namespace UglyToad.PdfPig.Tests.Filters
|
||||
{
|
||||
using PdfPig.ContentStream;
|
||||
using System.Collections.Generic;
|
||||
using PdfPig.Filters;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
public class RunLengthFilterTests
|
||||
@@ -25,7 +26,7 @@
|
||||
1, 10, 19
|
||||
};
|
||||
|
||||
var decoded = filter.Decode(data, new PdfDictionary(), 1);
|
||||
var decoded = filter.Decode(data, new DictionaryToken(new Dictionary<IToken, IToken>()), 1);
|
||||
|
||||
var expectedResult = new byte[]
|
||||
{
|
||||
@@ -54,7 +55,7 @@
|
||||
90, 6, 7
|
||||
};
|
||||
|
||||
var decoded = filter.Decode(data, new PdfDictionary(), 0);
|
||||
var decoded = filter.Decode(data, new DictionaryToken(new Dictionary<IToken, IToken>()), 0);
|
||||
|
||||
var expectedResult = new byte[]
|
||||
{
|
||||
|
@@ -1,13 +1,13 @@
|
||||
namespace UglyToad.PdfPig.Tests.Graphics.Operations.TextState
|
||||
{
|
||||
using System;
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Graphics.Operations.TextState;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
public class SetFontAndSizeTests
|
||||
{
|
||||
private static readonly CosName Font1Name = CosName.Create("Font1");
|
||||
private static readonly NameToken Font1Name = NameToken.Create("Font1");
|
||||
|
||||
[Fact]
|
||||
public void HasCorrectSymbol()
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
var setFontAndSize = new SetFontAndSize(Font1Name, 12.75m);
|
||||
|
||||
Assert.Equal("Font1", setFontAndSize.Font.Name);
|
||||
Assert.Equal("Font1", setFontAndSize.Font.Data);
|
||||
Assert.Equal(12.75m, setFontAndSize.Size);
|
||||
}
|
||||
|
||||
|
@@ -3,8 +3,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Content;
|
||||
using IO;
|
||||
using PdfPig.ContentStream;
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Fonts;
|
||||
using PdfPig.Graphics;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
@@ -50,11 +48,11 @@
|
||||
|
||||
internal class TestResourceStore : IResourceStore
|
||||
{
|
||||
public void LoadResourceDictionary(PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public void LoadResourceDictionary(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
}
|
||||
|
||||
public IFont GetFont(CosName name)
|
||||
public IFont GetFont(NameToken name)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@@ -6,9 +6,8 @@
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using PdfPig.ContentStream;
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Filters;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
/*
|
||||
@@ -88,16 +87,21 @@
|
||||
var endStreamPosition = GetOffset(bytes, "endstream", streamPosition.end);
|
||||
|
||||
var streamBytes = BytesBetween(streamPosition.end + 1, endStreamPosition.start - 1, bytes);
|
||||
|
||||
var paramsDict = new PdfDictionary();
|
||||
paramsDict.Set(CosName.PREDICTOR, new CosFloat("12"));
|
||||
paramsDict.Set(CosName.COLUMNS, new CosFloat("4"));
|
||||
|
||||
var dict = new PdfDictionary();
|
||||
dict.Set(CosName.FILTER, CosName.FLATE_DECODE);
|
||||
dict.Set(CosName.DECODE_PARMS, paramsDict);
|
||||
var paramsDict = new DictionaryToken(new Dictionary<IToken, IToken>
|
||||
{
|
||||
{ NameToken.Predictor, new NumericToken(12) },
|
||||
{ NameToken.Columns, new NumericToken(4) }
|
||||
});
|
||||
|
||||
var dictionary = new DictionaryToken(new Dictionary<IToken, IToken>
|
||||
{
|
||||
{NameToken.Filter, NameToken.FlateDecode},
|
||||
{NameToken.DecodeParms, paramsDict}
|
||||
});
|
||||
|
||||
var filter = new FlateFilter(new DecodeParameterResolver(null), new PngPredictor(), null);
|
||||
var filtered = filter.Decode(streamBytes, dict, 0);
|
||||
var filtered = filter.Decode(streamBytes, dictionary, 0);
|
||||
|
||||
var expected =
|
||||
"1 0 15 0 1 0 216 0 1 2 160 0 1 2 210 0 1 3 84 0 1 4 46 0 1 7 165 0 1 70 229 0 1 72 84 0 1 96 235 0 1 98 18 0 2 0 12 0 2 0 12 1 2 0 12 2 2 0 12 3 2 0 12 4 2 0 12 5 2 0 12 6 2 0 12 7 2 0 12 8"
|
||||
|
@@ -1,6 +1,5 @@
|
||||
namespace UglyToad.PdfPig.Tests.Parser
|
||||
{
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Graphics;
|
||||
using PdfPig.Graphics.Core;
|
||||
using PdfPig.Graphics.Operations.General;
|
||||
@@ -9,6 +8,7 @@
|
||||
using PdfPig.Graphics.Operations.TextShowing;
|
||||
using PdfPig.Graphics.Operations.TextState;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
|
||||
public class PageContentParserTests
|
||||
@@ -42,7 +42,7 @@ ET";
|
||||
Assert.Equal(BeginText.Value, result[0]);
|
||||
|
||||
var font = Assert.IsType<SetFontAndSize>(result[1]);
|
||||
Assert.Equal(CosName.Create("F13"), font.Font);
|
||||
Assert.Equal(NameToken.Create("F13"), font.Font);
|
||||
Assert.Equal(48, font.Size);
|
||||
|
||||
var nextLine = Assert.IsType<MoveToNextLineWithOffset>(result[2]);
|
||||
|
@@ -1,7 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Tokenization;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
@@ -85,12 +84,12 @@
|
||||
|
||||
Assert.Equal(12m, AssertDataToken<NumericToken, decimal>(0, array).Data);
|
||||
Assert.Equal(10.453m, AssertDataToken<NumericToken, decimal>(1, array).Data);
|
||||
Assert.Equal(CosName.Create("Fonts"), AssertDataToken<NameToken, CosName>(2, array).Data);
|
||||
Assert.Equal(NameToken.Create("Fonts"), AssertDataToken<NameToken, string>(2, array).Data);
|
||||
|
||||
var inner = AssertArrayToken(array.Data[3]);
|
||||
|
||||
Assert.Equal(CosName.Create("F1"), AssertDataToken<NameToken, CosName>(0, inner).Data);
|
||||
Assert.Equal(CosName.Create("F3"), AssertDataToken<NameToken, CosName>(1, inner).Data);
|
||||
Assert.Equal(NameToken.Create("F1"), AssertDataToken<NameToken, string>(0, inner).Data);
|
||||
Assert.Equal(NameToken.Create("F3"), AssertDataToken<NameToken, string>(1, inner).Data);
|
||||
|
||||
Assert.Equal("Moreover", AssertDataToken<StringToken, string>(4, array).Data);
|
||||
}
|
||||
@@ -108,7 +107,7 @@
|
||||
|
||||
var array = AssertArrayToken(token);
|
||||
|
||||
Assert.Equal(CosName.Create("Bounds"), AssertDataToken<NameToken, CosName>(0, array).Data);
|
||||
Assert.Equal(NameToken.Create("Bounds"), AssertDataToken<NameToken, string>(0, array).Data);
|
||||
|
||||
var firstInner = AssertArrayToken(array.Data[1]);
|
||||
|
||||
@@ -150,7 +149,7 @@
|
||||
Assert.Equal(3.14m, AssertDataToken<NumericToken, decimal>(1, array).Data);
|
||||
Assert.False(AssertDataToken<BooleanToken, bool>(2, array).Data);
|
||||
Assert.Equal("Ralph", AssertDataToken<StringToken, string>(3, array).Data);
|
||||
Assert.Equal(CosName.Create("SomeName"), AssertDataToken<NameToken, CosName>(4, array).Data);
|
||||
Assert.Equal(NameToken.Create("SomeName"), AssertDataToken<NameToken, string>(4, array).Data);
|
||||
}
|
||||
|
||||
private static ArrayToken AssertArrayToken(IToken token)
|
||||
|
@@ -4,7 +4,6 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PdfPig.ContentStream;
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Tokenization;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
@@ -39,7 +38,7 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
|
||||
var dictionary = AssertDictionaryToken(token);
|
||||
|
||||
AssertDictionaryEntry<StringToken, string>(dictionary, CosName.NAME, "Barry Scott");
|
||||
AssertDictionaryEntry<StringToken, string>(dictionary, NameToken.Name, "Barry Scott");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -53,8 +52,7 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
|
||||
var dictionary = AssertDictionaryToken(token);
|
||||
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.TYPE,
|
||||
CosName.Create("Example"));
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Type, "Example");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -68,9 +66,9 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
|
||||
var dictionary = AssertDictionaryToken(token);
|
||||
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.FILTER, CosName.FLATE_DECODE);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, CosName.S, 36);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, CosName.LENGTH, 53);
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Filter, NameToken.FlateDecode.Data);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, NameToken.S, 36);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, NameToken.Length, 53);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -86,8 +84,8 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
|
||||
var reference = new IndirectReference(14, 0);
|
||||
|
||||
AssertDictionaryEntry<IndirectReferenceToken, IndirectReference>(dictionary, CosName.PAGES, reference);
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.TYPE, CosName.CATALOG);
|
||||
AssertDictionaryEntry<IndirectReferenceToken, IndirectReference>(dictionary, NameToken.Pages, reference);
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Type, NameToken.Catalog);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -114,11 +112,11 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
|
||||
var dictionary = AssertDictionaryToken(token);
|
||||
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.TYPE, CosName.Create("Example"));
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.SUBTYPE, CosName.Create("DictionaryExample"));
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, CosName.VERSION, 0.01m);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, CosName.Create("IntegerItem"), 12m);
|
||||
AssertDictionaryEntry<StringToken, string>(dictionary, CosName.Create("StringItem"), "a string");
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Type, "Example");
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Subtype, "DictionaryExample");
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, NameToken.Version, 0.01m);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, NameToken.Create("IntegerItem"), 12m);
|
||||
AssertDictionaryEntry<StringToken, string>(dictionary, NameToken.Create("StringItem"), "a string");
|
||||
|
||||
var subDictionary = GetIndex(5, dictionary);
|
||||
|
||||
@@ -126,10 +124,10 @@ namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
|
||||
var subDictionaryValue = Assert.IsType<DictionaryToken>(subDictionary.Value);
|
||||
|
||||
AssertDictionaryEntry<NumericToken, decimal>(subDictionaryValue, CosName.Create("Item1"), 0.4m);
|
||||
AssertDictionaryEntry<BooleanToken, bool>(subDictionaryValue, CosName.Create("Item2"), true);
|
||||
AssertDictionaryEntry<StringToken, string>(subDictionaryValue, CosName.Create("LastItem"), "not!");
|
||||
AssertDictionaryEntry<StringToken, string>(subDictionaryValue, CosName.Create("VeryLastItem"), "OK");
|
||||
AssertDictionaryEntry<NumericToken, decimal>(subDictionaryValue, NameToken.Create("Item1"), 0.4m);
|
||||
AssertDictionaryEntry<BooleanToken, bool>(subDictionaryValue, NameToken.Create("Item2"), true);
|
||||
AssertDictionaryEntry<StringToken, string>(subDictionaryValue, NameToken.Create("LastItem"), "not!");
|
||||
AssertDictionaryEntry<StringToken, string>(subDictionaryValue, NameToken.Create("VeryLastItem"), "OK");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -147,8 +145,8 @@ endobj
|
||||
|
||||
var reference = new IndirectReference(69, 0);
|
||||
|
||||
AssertDictionaryEntry<IndirectReferenceToken, IndirectReference>(dictionary, CosName.PAGES, reference);
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.TYPE, CosName.CATALOG);
|
||||
AssertDictionaryEntry<IndirectReferenceToken, IndirectReference>(dictionary, NameToken.Pages, reference);
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Type, NameToken.Catalog.Data);
|
||||
|
||||
Assert.Equal(2, dictionary.Data.Count);
|
||||
}
|
||||
@@ -164,7 +162,7 @@ endobj
|
||||
|
||||
var dictionary = AssertDictionaryToken(token);
|
||||
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, CosName.COUNT, 12);
|
||||
AssertDictionaryEntry<NumericToken, decimal>(dictionary, NameToken.Count, 12);
|
||||
|
||||
var subDictionaryToken = GetIndex(1, dictionary);
|
||||
|
||||
@@ -172,17 +170,17 @@ endobj
|
||||
|
||||
var subDictionary = Assert.IsType<DictionaryToken>(subDictionaryToken.Value);
|
||||
|
||||
AssertDictionaryEntry<StringToken, string>(subDictionary, CosName.NAME, "Glorp");
|
||||
AssertDictionaryEntry<StringToken, string>(subDictionary, NameToken.Name, "Glorp");
|
||||
|
||||
AssertDictionaryEntry<NameToken, CosName>(dictionary, CosName.TYPE, CosName.CATALOG);
|
||||
AssertDictionaryEntry<NameToken, string>(dictionary, NameToken.Type, NameToken.Catalog.Data);
|
||||
|
||||
Assert.Equal(3, dictionary.Data.Count);
|
||||
}
|
||||
|
||||
private static void AssertDictionaryEntry<TValue, TValueData>(DictionaryToken dictionary, CosName key,
|
||||
private static void AssertDictionaryEntry<TValue, TValueData>(DictionaryToken dictionary, NameToken key,
|
||||
TValueData value) where TValue : IDataToken<TValueData>
|
||||
{
|
||||
var result = dictionary.Data[key.Name];
|
||||
var result = dictionary.Data[key.Data];
|
||||
|
||||
var valueToken = Assert.IsType<TValue>(result);
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("Type", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("Type", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("Type", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("Type", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("XRef", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("XRef", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("Priorto1.2#INvalidHexHash", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("Priorto1.2#INvalidHexHash", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal(expected, AssertNameToken(token).Data.Name);
|
||||
Assert.Equal(expected, AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -109,7 +109,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal(expected, AssertNameToken(token).Data.Name);
|
||||
Assert.Equal(expected, AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("Invalid#AZBadHex", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("Invalid#AZBadHex", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("Invalid#Z", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("Invalid#Z", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
Assert.Equal("Hex#", AssertNameToken(token).Data.Name);
|
||||
Assert.Equal("Hex#", AssertNameToken(token).Data);
|
||||
}
|
||||
|
||||
private static NameToken AssertNameToken(IToken token)
|
||||
|
@@ -4,7 +4,6 @@ namespace UglyToad.PdfPig.Tests.Tokenization.Scanner
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IO;
|
||||
using PdfPig.Cos;
|
||||
using PdfPig.Tokenization.Scanner;
|
||||
using PdfPig.Tokenization.Tokens;
|
||||
using Xunit;
|
||||
@@ -36,7 +35,7 @@ namespace UglyToad.PdfPig.Tests.Tokenization.Scanner
|
||||
AssertCorrectToken<NumericToken, decimal>(tokens[1], 3.14m);
|
||||
AssertCorrectToken<BooleanToken, bool>(tokens[2], false);
|
||||
AssertCorrectToken<StringToken, string>(tokens[3], "Ralph");
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[4], CosName.Create("SomeName"));
|
||||
AssertCorrectToken<NameToken, string>(tokens[4], "SomeName");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -57,15 +56,15 @@ namespace UglyToad.PdfPig.Tests.Tokenization.Scanner
|
||||
tokens.Add(scanner.CurrentToken);
|
||||
}
|
||||
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[0], CosName.TYPE);
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[1], CosName.Create("Example"));
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[2], CosName.SUBTYPE);
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[3], CosName.Create("DictionaryExample"));
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[4], CosName.VERSION);
|
||||
AssertCorrectToken<NameToken, string>(tokens[0], NameToken.Type.Data);
|
||||
AssertCorrectToken<NameToken, string>(tokens[1], "Example");
|
||||
AssertCorrectToken<NameToken, string>(tokens[2], NameToken.Subtype.Data);
|
||||
AssertCorrectToken<NameToken, string>(tokens[3], "DictionaryExample");
|
||||
AssertCorrectToken<NameToken, string>(tokens[4], NameToken.Version.Data);
|
||||
AssertCorrectToken<NumericToken, decimal>(tokens[5], 0.01m);
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[6], CosName.Create("IntegerItem"));
|
||||
AssertCorrectToken<NameToken, string>(tokens[6], "IntegerItem");
|
||||
AssertCorrectToken<NumericToken, decimal>(tokens[7], 12m);
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[8], CosName.Create("StringItem"));
|
||||
AssertCorrectToken<NameToken, string>(tokens[8], "StringItem");
|
||||
AssertCorrectToken<StringToken, string>(tokens[9], "a string");
|
||||
}
|
||||
|
||||
@@ -106,11 +105,11 @@ endobj";
|
||||
tokens.Add(scanner.CurrentToken);
|
||||
}
|
||||
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[0], CosName.Create("Bounds"));
|
||||
AssertCorrectToken<NameToken, string>(tokens[0], "Bounds");
|
||||
Assert.IsType<ArrayToken>(tokens[1]);
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[2], CosName.Create("Font"));
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[3], CosName.Create("F1"));
|
||||
AssertCorrectToken<NameToken, CosName>(tokens[4], CosName.Create("Name"));
|
||||
AssertCorrectToken<NameToken, string>(tokens[2], "Font");
|
||||
AssertCorrectToken<NameToken, string>(tokens[3], "F1");
|
||||
AssertCorrectToken<NameToken, string>(tokens[4], "Name");
|
||||
AssertCorrectToken<StringToken, string>(tokens[5], "Bob");
|
||||
Assert.IsType<ArrayToken>(tokens[6]);
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
var name = Assert.IsType<NameToken>(objectToken.Data);
|
||||
|
||||
Assert.Equal(294, objectToken.Number.ObjectNumber);
|
||||
Assert.Equal(0, objectToken.Number.Generation);
|
||||
Assert.Equal(0, objectToken.Number.Generation);
|
||||
|
||||
Assert.Equal("WDKAAR+CMBX12", name.Data);
|
||||
|
||||
@@ -126,7 +126,7 @@ endobj
|
||||
/Type /Pages
|
||||
/Count 2
|
||||
/Parent 275 0 R
|
||||
/Kids [ 121 0 R 125 0 R ]
|
||||
/Kids [ 121 0 R 125 0 R ]
|
||||
>>
|
||||
endobj
|
||||
|
||||
@@ -275,6 +275,34 @@ endobj";
|
||||
var scanner = GetScanner(s, locationProvider);
|
||||
|
||||
var token = ReadToEnd(scanner)[1];
|
||||
|
||||
var stream = Assert.IsType<StreamToken>(token.Data);
|
||||
|
||||
Assert.Equal(52, stream.Data.Length);
|
||||
|
||||
var outputString = Encoding.UTF8.GetString(stream.Data);
|
||||
|
||||
Assert.Equal("%¥×³®í»š}%§X{{tøNåÝž¶ö¢ÖÞ¾–~´¼", outputString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadsStreamWithMissingLength()
|
||||
{
|
||||
const string s = @"
|
||||
12655 0 obj
|
||||
|
||||
<< /S 1245 >>
|
||||
|
||||
stream
|
||||
%¥×³®í»š}%§X{{tøNåÝž¶ö¢ÖÞgrehtyyy$&%&£$££(*¾–~´¼
|
||||
endstream
|
||||
endobj";
|
||||
|
||||
var scanner = GetScanner(s);
|
||||
|
||||
var token = ReadToEnd(scanner)[0];
|
||||
|
||||
Assert.Equal(12655, token.Number.ObjectNumber);
|
||||
|
||||
var stream = Assert.IsType<StreamToken>(token.Data);
|
||||
|
||||
|
@@ -1,13 +0,0 @@
|
||||
namespace UglyToad.PdfPig.Tests.Tokenization
|
||||
{
|
||||
using Xunit;
|
||||
|
||||
public class StreamTokenizerTests
|
||||
{
|
||||
[Fact]
|
||||
public void ReadsStream()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -59,7 +59,7 @@
|
||||
var transform = streamBytes;
|
||||
for (var i = 0; i < filters.Count; i++)
|
||||
{
|
||||
transform = filters[i].Decode(transform, Dictionary, i);
|
||||
//transform = filters[i].Decode(transform, Dictionary, i);
|
||||
}
|
||||
|
||||
decodedBytes = transform;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace UglyToad.PdfPig.Fonts
|
||||
{
|
||||
using ContentStream;
|
||||
using Tokenization.Tokens;
|
||||
|
||||
/// <summary>
|
||||
/// The bytes of the stream containing the font program.
|
||||
@@ -13,13 +13,13 @@
|
||||
/// </remarks>
|
||||
internal class DescriptorFontFile
|
||||
{
|
||||
public IndirectReference ObjectKey { get; }
|
||||
public IndirectReferenceToken ObjectKey { get; }
|
||||
|
||||
public byte[] FileBytes { get; }
|
||||
|
||||
public FontFileType FileType { get; }
|
||||
|
||||
public DescriptorFontFile(IndirectReference key, FontFileType fileType)
|
||||
public DescriptorFontFile(IndirectReferenceToken key, FontFileType fileType)
|
||||
{
|
||||
ObjectKey = key;
|
||||
FileBytes = new byte[0];
|
||||
|
@@ -2,7 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cos;
|
||||
using Tokenization.Tokens;
|
||||
|
||||
/// <summary>
|
||||
/// Maps character codes to glyph names from a PostScript encoding.
|
||||
@@ -57,7 +57,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetNamedEncoding(CosName name, out Encoding encoding)
|
||||
public static bool TryGetNamedEncoding(NameToken name, out Encoding encoding)
|
||||
{
|
||||
encoding = null;
|
||||
|
||||
@@ -66,25 +66,25 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.Equals(CosName.STANDARD_ENCODING))
|
||||
if (name.Equals(NameToken.StandardEncoding))
|
||||
{
|
||||
encoding = StandardEncoding.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name.Equals(CosName.WIN_ANSI_ENCODING))
|
||||
if (name.Equals(NameToken.WinAnsiEncoding))
|
||||
{
|
||||
encoding = WinAnsiEncoding.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name.Equals(CosName.MAC_EXPERT_ENCODING))
|
||||
if (name.Equals(NameToken.MacExpertEncoding))
|
||||
{
|
||||
encoding = MacExpertEncoding.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name.Equals(CosName.MAC_ROMAN_ENCODING))
|
||||
if (name.Equals(NameToken.MacRomanEncoding))
|
||||
{
|
||||
encoding = MacRomanEncoding.Instance;
|
||||
return true;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
namespace UglyToad.PdfPig.Fonts
|
||||
{
|
||||
using Cos;
|
||||
using Geometry;
|
||||
using Tokenization.Tokens;
|
||||
using Util.JetBrains.Annotations;
|
||||
|
||||
/// <summary>
|
||||
@@ -26,7 +26,7 @@
|
||||
/// The PostScript name for the font.
|
||||
/// </summary>
|
||||
/// <remarks>Required</remarks>
|
||||
public CosName FontName { get; }
|
||||
public NameToken FontName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The preferred font family.
|
||||
@@ -155,7 +155,7 @@
|
||||
[CanBeNull]
|
||||
public string CharSet { get; set; }
|
||||
|
||||
public FontDescriptor(CosName name, FontFlags flags)
|
||||
public FontDescriptor(NameToken name, FontFlags flags)
|
||||
{
|
||||
FontName = name;
|
||||
Flags = flags;
|
||||
|
@@ -1,12 +1,12 @@
|
||||
namespace UglyToad.PdfPig.Fonts
|
||||
{
|
||||
using Cos;
|
||||
using Tokenization.Tokens;
|
||||
|
||||
internal static class FontStretchExtensions
|
||||
{
|
||||
public static FontStretch ConvertToFontStretch(this CosName name)
|
||||
public static FontStretch ConvertToFontStretch(this NameToken name)
|
||||
{
|
||||
switch (name.Name)
|
||||
switch (name.Data)
|
||||
{
|
||||
case "UltraCondensed":
|
||||
return FontStretch.UltraCondensed;
|
||||
|
@@ -1,58 +1,45 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using ContentStream;
|
||||
using Cos;
|
||||
using Encodings;
|
||||
using Exceptions;
|
||||
using IO;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
using Util;
|
||||
|
||||
internal class EncodingReader : IEncodingReader
|
||||
{
|
||||
private readonly IPdfObjectParser pdfObjectParser;
|
||||
private readonly IPdfObjectScanner pdfScanner;
|
||||
|
||||
public EncodingReader(IPdfObjectParser pdfObjectParser)
|
||||
public EncodingReader(IPdfObjectScanner pdfScanner)
|
||||
{
|
||||
this.pdfObjectParser = pdfObjectParser;
|
||||
this.pdfScanner = pdfScanner;
|
||||
}
|
||||
|
||||
public Encoding Read(PdfDictionary fontDictionary, IRandomAccessRead reader, bool isLenientParsing, FontDescriptor descriptor = null)
|
||||
public Encoding Read(DictionaryToken fontDictionary, bool isLenientParsing, FontDescriptor descriptor = null)
|
||||
{
|
||||
if (!fontDictionary.TryGetValue(CosName.ENCODING, out var baseEncodingObject))
|
||||
if (!fontDictionary.TryGet(NameToken.Encoding, out var baseEncodingObject))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (baseEncodingObject is CosName name)
|
||||
if (baseEncodingObject is NameToken name)
|
||||
{
|
||||
return GetNamedEncoding(descriptor, name);
|
||||
}
|
||||
|
||||
PdfDictionary encodingDictionary;
|
||||
if (baseEncodingObject is CosObject reference)
|
||||
{
|
||||
encodingDictionary = DirectObjectFinder.Find<PdfDictionary>(reference, pdfObjectParser, reader, isLenientParsing);
|
||||
}
|
||||
else if (baseEncodingObject is PdfDictionary dictionary)
|
||||
{
|
||||
encodingDictionary = dictionary;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidFontFormatException($"The font encoding was not a named entry or dictionary, instead it was: {baseEncodingObject}.");
|
||||
}
|
||||
|
||||
var encoding = ReadEncodingDictionary(encodingDictionary, reader, isLenientParsing);
|
||||
DictionaryToken encodingDictionary = DirectObjectFinder.Get<DictionaryToken>(baseEncodingObject, pdfScanner);
|
||||
|
||||
var encoding = ReadEncodingDictionary(encodingDictionary);
|
||||
|
||||
return encoding;
|
||||
}
|
||||
|
||||
private Encoding ReadEncodingDictionary(PdfDictionary encodingDictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
private Encoding ReadEncodingDictionary(DictionaryToken encodingDictionary)
|
||||
{
|
||||
Encoding baseEncoding;
|
||||
if (encodingDictionary.TryGetName(CosName.BASE_ENCODING, out var baseEncodingName))
|
||||
if (encodingDictionary.TryGet(NameToken.BaseEncoding, out var baseEncodingToken) && baseEncodingToken is NameToken baseEncodingName)
|
||||
{
|
||||
if (!Encoding.TryGetNamedEncoding(baseEncodingName, out baseEncoding))
|
||||
{
|
||||
@@ -65,23 +52,12 @@
|
||||
baseEncoding = StandardEncoding.Instance;
|
||||
}
|
||||
|
||||
if (!encodingDictionary.TryGetValue(CosName.DIFFERENCES, out var differencesBase))
|
||||
if (!encodingDictionary.TryGet(NameToken.Differences, out var differencesBase))
|
||||
{
|
||||
return baseEncoding;
|
||||
}
|
||||
|
||||
var differenceArray = differencesBase as COSArray;
|
||||
if (differenceArray == null)
|
||||
{
|
||||
if (differencesBase is CosObject differencesObj)
|
||||
{
|
||||
differenceArray = DirectObjectFinder.Find<COSArray>(differencesObj, pdfObjectParser, reader, isLenientParsing);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidFontFormatException($"Differences was not an array: {differencesBase}.");
|
||||
}
|
||||
}
|
||||
var differenceArray = DirectObjectFinder.Get<ArrayToken>(differencesBase, pdfScanner);
|
||||
|
||||
var differences = ProcessDifferences(differenceArray);
|
||||
|
||||
@@ -90,22 +66,22 @@
|
||||
return newEncoding;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<(int, string)> ProcessDifferences(COSArray differenceArray)
|
||||
private static IReadOnlyList<(int, string)> ProcessDifferences(ArrayToken differenceArray)
|
||||
{
|
||||
var activeCode = differenceArray.getInt(0);
|
||||
var activeCode = differenceArray.GetNumeric(0).Int;
|
||||
var differences = new List<(int, string)>();
|
||||
|
||||
for (int i = 1; i < differenceArray.Count; i++)
|
||||
for (int i = 1; i < differenceArray.Data.Count; i++)
|
||||
{
|
||||
var entry = differenceArray.get(i);
|
||||
var entry = differenceArray.Data[i];
|
||||
|
||||
if (entry is ICosNumber numeric)
|
||||
if (entry is NumericToken numeric)
|
||||
{
|
||||
activeCode = numeric.AsInt();
|
||||
activeCode = numeric.Int;
|
||||
}
|
||||
else if (entry is CosName name)
|
||||
else if (entry is NameToken name)
|
||||
{
|
||||
differences.Add((activeCode, name.Name));
|
||||
differences.Add((activeCode, name.Data));
|
||||
activeCode++;
|
||||
}
|
||||
else
|
||||
@@ -117,7 +93,7 @@
|
||||
return differences;
|
||||
}
|
||||
|
||||
private static Encoding GetNamedEncoding(FontDescriptor descriptor, CosName encodingName)
|
||||
private static Encoding GetNamedEncoding(FontDescriptor descriptor, NameToken encodingName)
|
||||
{
|
||||
Encoding encoding;
|
||||
// Symbolic fonts default to standard encoding.
|
||||
|
@@ -1,75 +1,79 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser
|
||||
{
|
||||
using System.Linq;
|
||||
using ContentStream;
|
||||
using Cos;
|
||||
using Exceptions;
|
||||
using IO;
|
||||
using Parts;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
|
||||
internal static class FontDictionaryAccessHelper
|
||||
{
|
||||
public static int GetFirstCharacter(PdfDictionary dictionary)
|
||||
public static int GetFirstCharacter(DictionaryToken dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetItemOfType(CosName.FIRST_CHAR, out CosInt firstChar))
|
||||
if (!dictionary.TryGet(NameToken.FirstChar, out var firstChar) || !(firstChar is NumericToken number))
|
||||
{
|
||||
throw new InvalidFontFormatException($"No first character entry was found in the font dictionary for this TrueType font: {dictionary}.");
|
||||
}
|
||||
|
||||
return firstChar.AsInt();
|
||||
return number.Int;
|
||||
}
|
||||
|
||||
public static int GetLastCharacter(PdfDictionary dictionary)
|
||||
public static int GetLastCharacter(DictionaryToken dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetItemOfType(CosName.LAST_CHAR, out CosInt lastChar))
|
||||
if (!dictionary.TryGet(NameToken.LastChar, out var firstChar) || !(firstChar is NumericToken number))
|
||||
{
|
||||
throw new InvalidFontFormatException($"No last character entry was found in the font dictionary for this TrueType font: {dictionary}.");
|
||||
throw new InvalidFontFormatException($"No first character entry was found in the font dictionary for this TrueType font: {dictionary}.");
|
||||
}
|
||||
|
||||
return lastChar.AsInt();
|
||||
return number.Int;
|
||||
}
|
||||
|
||||
public static decimal[] GetWidths(IPdfObjectParser pdfObjectParser, PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public static decimal[] GetWidths(IPdfObjectScanner pdfScanner, DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
if (!dictionary.TryGetItemOfType(CosName.WIDTHS, out COSArray widthArray))
|
||||
if (!dictionary.TryGet(NameToken.Widths, out var token))
|
||||
{
|
||||
if (!dictionary.TryGetItemOfType(CosName.WIDTHS, out CosObject arr))
|
||||
throw new InvalidFontFormatException($"No widths array found for the font: {dictionary}.");
|
||||
}
|
||||
|
||||
var widthArray = DirectObjectFinder.Get<ArrayToken>(token, pdfScanner);
|
||||
|
||||
var result = new decimal[widthArray.Data.Count];
|
||||
for (int i = 0; i < widthArray.Data.Count; i++)
|
||||
{
|
||||
var arrayToken = widthArray.Data[i];
|
||||
|
||||
if (!(arrayToken is NumericToken number))
|
||||
{
|
||||
throw new InvalidFontFormatException($"No widths array was found in the font dictionary for this TrueType font: {dictionary}.");
|
||||
throw new InvalidFontFormatException($"Token which was not a number found in the widths array: {arrayToken}.");
|
||||
}
|
||||
|
||||
widthArray = DirectObjectFinder.Find<COSArray>(arr, pdfObjectParser, reader, isLenientParsing);
|
||||
result[i] = number.Data;
|
||||
}
|
||||
|
||||
return widthArray.Select(x => ((ICosNumber)x).AsDecimal()).ToArray();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static FontDescriptor GetFontDescriptor(IPdfObjectParser pdfObjectParser, FontDescriptorFactory fontDescriptorFactory, PdfDictionary dictionary,
|
||||
IRandomAccessRead reader, bool isLenientParsing)
|
||||
public static FontDescriptor GetFontDescriptor(IPdfObjectScanner pdfScanner, FontDescriptorFactory fontDescriptorFactory, DictionaryToken dictionary,
|
||||
bool isLenientParsing)
|
||||
{
|
||||
if (!dictionary.TryGetItemOfType(CosName.FONT_DESC, out CosObject obj))
|
||||
if (!dictionary.TryGet(NameToken.FontDesc, out var obj))
|
||||
{
|
||||
throw new InvalidFontFormatException($"No font descriptor indirect reference found in the TrueType font: {dictionary}.");
|
||||
}
|
||||
|
||||
var parsed = pdfObjectParser.Parse(obj.ToIndirectReference(), reader, isLenientParsing);
|
||||
|
||||
if (!(parsed is PdfDictionary descriptorDictionary))
|
||||
{
|
||||
throw new InvalidFontFormatException($"Expected a font descriptor dictionary but instead found {parsed}.");
|
||||
}
|
||||
|
||||
var descriptor = fontDescriptorFactory.Generate(descriptorDictionary, isLenientParsing);
|
||||
var parsed = DirectObjectFinder.Get<DictionaryToken>(obj, pdfScanner);
|
||||
|
||||
var descriptor = fontDescriptorFactory.Generate(parsed, isLenientParsing);
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static CosName GetName(IPdfObjectParser pdfObjectParser, PdfDictionary dictionary, FontDescriptor descriptor, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public static NameToken GetName(IPdfObjectScanner pdfScanner, DictionaryToken dictionary, FontDescriptor descriptor, bool isLenientParsing)
|
||||
{
|
||||
if (dictionary.TryGetName(CosName.BASE_FONT, out CosName name))
|
||||
if (dictionary.TryGet(NameToken.BaseFont, out var nameBase))
|
||||
{
|
||||
var name = DirectObjectFinder.Get<NameToken>(nameBase, pdfScanner);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -77,15 +81,7 @@
|
||||
{
|
||||
return descriptor.FontName;
|
||||
}
|
||||
|
||||
if (dictionary.TryGetValue(CosName.BASE_FONT, out var baseFont))
|
||||
{
|
||||
if (baseFont is CosObject baseFontObj)
|
||||
{
|
||||
return DirectObjectFinder.Find<CosName>(baseFontObj, pdfObjectParser, reader, isLenientParsing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new InvalidFontFormatException($"Could not find a name for this font {dictionary}.");
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,9 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser.Handlers
|
||||
{
|
||||
using ContentStream;
|
||||
using IO;
|
||||
using Tokenization.Tokens;
|
||||
|
||||
internal interface IFontHandler
|
||||
{
|
||||
IFont Generate(PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing);
|
||||
IFont Generate(DictionaryToken dictionary, bool isLenientParsing);
|
||||
}
|
||||
}
|
@@ -1,62 +1,62 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser.Handlers
|
||||
{
|
||||
using Cmap;
|
||||
using ContentStream;
|
||||
using Cos;
|
||||
using Encodings;
|
||||
using Exceptions;
|
||||
using Filters;
|
||||
using IO;
|
||||
using Parts;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Simple;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
using TrueType;
|
||||
using TrueType.Parser;
|
||||
|
||||
internal class TrueTypeFontHandler : IFontHandler
|
||||
{
|
||||
private readonly IPdfObjectParser pdfObjectParser;
|
||||
private readonly IFilterProvider filterProvider;
|
||||
private readonly CMapCache cMapCache;
|
||||
private readonly FontDescriptorFactory fontDescriptorFactory;
|
||||
private readonly TrueTypeFontParser trueTypeFontParser;
|
||||
private readonly IEncodingReader encodingReader;
|
||||
private readonly IPdfObjectScanner pdfScanner;
|
||||
|
||||
public TrueTypeFontHandler(IPdfObjectParser pdfObjectParser, IFilterProvider filterProvider,
|
||||
public TrueTypeFontHandler(IPdfObjectScanner pdfScanner, IFilterProvider filterProvider,
|
||||
CMapCache cMapCache,
|
||||
FontDescriptorFactory fontDescriptorFactory,
|
||||
TrueTypeFontParser trueTypeFontParser,
|
||||
IEncodingReader encodingReader)
|
||||
{
|
||||
this.pdfObjectParser = pdfObjectParser;
|
||||
this.filterProvider = filterProvider;
|
||||
this.cMapCache = cMapCache;
|
||||
this.fontDescriptorFactory = fontDescriptorFactory;
|
||||
this.trueTypeFontParser = trueTypeFontParser;
|
||||
this.encodingReader = encodingReader;
|
||||
this.pdfScanner = pdfScanner;
|
||||
}
|
||||
|
||||
public IFont Generate(PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary);
|
||||
|
||||
var lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary);
|
||||
|
||||
var widths = FontDictionaryAccessHelper.GetWidths(pdfObjectParser, dictionary, reader, isLenientParsing);
|
||||
var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing);
|
||||
|
||||
var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfObjectParser, fontDescriptorFactory, dictionary, reader, isLenientParsing);
|
||||
var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing);
|
||||
|
||||
// TODO: use the parsed font fully.
|
||||
//var font = ParseTrueTypeFont(descriptor, reader, isLenientParsing);
|
||||
|
||||
var name = FontDictionaryAccessHelper.GetName(pdfObjectParser, dictionary, descriptor, reader, isLenientParsing);
|
||||
var name = FontDictionaryAccessHelper.GetName(pdfScanner, dictionary, descriptor, isLenientParsing);
|
||||
|
||||
CMap toUnicodeCMap = null;
|
||||
if (dictionary.TryGetItemOfType(CosName.TO_UNICODE, out CosObject toUnicodeObj))
|
||||
if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj))
|
||||
{
|
||||
var toUnicode = pdfObjectParser.Parse(toUnicodeObj.ToIndirectReference(), reader, isLenientParsing) as PdfRawStream;
|
||||
var toUnicode = DirectObjectFinder.Get<StreamToken>(toUnicodeObj, pdfScanner);
|
||||
|
||||
var decodedUnicodeCMap = toUnicode?.Decode(filterProvider);
|
||||
var decodedUnicodeCMap = toUnicode.Decode(filterProvider);
|
||||
|
||||
if (decodedUnicodeCMap != null)
|
||||
{
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
Encoding encoding = encodingReader.Read(dictionary, reader, isLenientParsing, descriptor);
|
||||
Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor);
|
||||
|
||||
return new TrueTypeSimpleFont(name, firstCharacter, lastCharacter, widths, descriptor, toUnicodeCMap, encoding);
|
||||
}
|
||||
@@ -83,18 +83,18 @@
|
||||
$"Expected a TrueType font in the TrueType font descriptor, instead it was {descriptor.FontFile.FileType}.");
|
||||
}
|
||||
|
||||
var fontFileStream = pdfObjectParser.Parse(descriptor.FontFile.ObjectKey, reader, isLenientParsing) as PdfRawStream;
|
||||
//var fontFileStream = pdfObjectParser.Parse(descriptor.FontFile.ObjectKey, reader, isLenientParsing) as PdfRawStream;
|
||||
|
||||
if (fontFileStream == null)
|
||||
//if (fontFileStream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var fontFile = fontFileStream.Decode(filterProvider);
|
||||
//var fontFile = fontFileStream.Decode(filterProvider);
|
||||
|
||||
var font = trueTypeFontParser.Parse(new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile)));
|
||||
//var font = trueTypeFontParser.Parse(new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile)));
|
||||
|
||||
return font;
|
||||
//return font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,13 +4,10 @@
|
||||
using CidFonts;
|
||||
using Cmap;
|
||||
using Composite;
|
||||
using ContentStream;
|
||||
using Cos;
|
||||
using Exceptions;
|
||||
using Filters;
|
||||
using IO;
|
||||
using Parts;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
@@ -21,20 +18,18 @@
|
||||
private readonly CidFontFactory cidFontFactory;
|
||||
private readonly CMapCache cMapCache;
|
||||
private readonly IFilterProvider filterProvider;
|
||||
private readonly IPdfObjectParser pdfObjectParser;
|
||||
private readonly IPdfObjectScanner scanner;
|
||||
|
||||
public Type0FontHandler(CidFontFactory cidFontFactory, CMapCache cMapCache, IFilterProvider filterProvider, IPdfObjectParser pdfObjectParser,
|
||||
public Type0FontHandler(CidFontFactory cidFontFactory, CMapCache cMapCache, IFilterProvider filterProvider,
|
||||
IPdfObjectScanner scanner)
|
||||
{
|
||||
this.cidFontFactory = cidFontFactory;
|
||||
this.cMapCache = cMapCache;
|
||||
this.filterProvider = filterProvider;
|
||||
this.pdfObjectParser = pdfObjectParser;
|
||||
this.scanner = scanner;
|
||||
}
|
||||
|
||||
public IFont Generate(DictionaryToken dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var baseFont = dictionary.GetNameOrDefault(NameToken.BaseFont);
|
||||
|
||||
@@ -57,7 +52,7 @@
|
||||
descendantFontDictionary = (DictionaryToken) descendantObject;
|
||||
}
|
||||
|
||||
cidFont = ParseDescendant(descendantFontDictionary, reader, isLenientParsing);
|
||||
cidFont = ParseDescendant(descendantFontDictionary, isLenientParsing);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,7 +117,7 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
private ICidFont ParseDescendant(DictionaryToken dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
private ICidFont ParseDescendant(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var type = dictionary.GetNameOrDefault(NameToken.Type);
|
||||
if (type?.Equals(NameToken.Font) != true)
|
||||
@@ -130,7 +125,7 @@
|
||||
throw new InvalidFontFormatException($"Expected \'Font\' dictionary but found \'{type}\'");
|
||||
}
|
||||
|
||||
var result = cidFontFactory.Generate(dictionary, reader, isLenientParsing);
|
||||
var result = cidFontFactory.Generate(dictionary, isLenientParsing);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -2,13 +2,12 @@
|
||||
{
|
||||
using Cmap;
|
||||
using ContentStream;
|
||||
using Cos;
|
||||
using Encodings;
|
||||
using Exceptions;
|
||||
using Filters;
|
||||
using IO;
|
||||
using Parts;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Simple;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
@@ -17,41 +16,40 @@
|
||||
|
||||
internal class Type1FontHandler : IFontHandler
|
||||
{
|
||||
private readonly IPdfObjectParser pdfObjectParser;
|
||||
private readonly IPdfObjectScanner pdfScanner;
|
||||
private readonly CMapCache cMapCache;
|
||||
private readonly IFilterProvider filterProvider;
|
||||
private readonly FontDescriptorFactory fontDescriptorFactory;
|
||||
private readonly IEncodingReader encodingReader;
|
||||
private readonly IPdfObjectScanner scanner;
|
||||
private readonly Type1FontParser type1FontParser;
|
||||
|
||||
public Type1FontHandler(IPdfObjectParser pdfObjectParser, CMapCache cMapCache, IFilterProvider filterProvider,
|
||||
FontDescriptorFactory fontDescriptorFactory, IEncodingReader encodingReader,
|
||||
IPdfObjectScanner scanner,
|
||||
public Type1FontHandler(IPdfObjectScanner pdfScanner, CMapCache cMapCache, IFilterProvider filterProvider,
|
||||
FontDescriptorFactory fontDescriptorFactory,
|
||||
IEncodingReader encodingReader,
|
||||
Type1FontParser type1FontParser)
|
||||
{
|
||||
this.pdfObjectParser = pdfObjectParser;
|
||||
this.pdfScanner = pdfScanner;
|
||||
this.cMapCache = cMapCache;
|
||||
this.filterProvider = filterProvider;
|
||||
this.fontDescriptorFactory = fontDescriptorFactory;
|
||||
this.encodingReader = encodingReader;
|
||||
this.scanner = scanner;
|
||||
this.type1FontParser = type1FontParser;
|
||||
}
|
||||
|
||||
public IFont Generate(PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var usingStandard14Only = !dictionary.ContainsKey(CosName.FIRST_CHAR) || !dictionary.ContainsKey(CosName.WIDTHS);
|
||||
var usingStandard14Only = !dictionary.ContainsKey(NameToken.FirstChar) || !dictionary.ContainsKey(NameToken.Widths);
|
||||
|
||||
if (usingStandard14Only)
|
||||
{
|
||||
// TODO: some fonts combine standard 14 font with other metrics.
|
||||
if (!dictionary.TryGetName(CosName.BASE_FONT, out var standard14Name))
|
||||
if (!dictionary.TryGet(NameToken.BaseFont, out var baseFontToken)
|
||||
|| !(baseFontToken is NameToken standard14Name))
|
||||
{
|
||||
throw new InvalidFontFormatException($"The Type 1 font did not contain a first character entry but also did not reference a standard 14 font: {dictionary}");
|
||||
}
|
||||
|
||||
var metrics = Standard14.GetAdobeFontMetrics(standard14Name.Name);
|
||||
var metrics = Standard14.GetAdobeFontMetrics(standard14Name.Data);
|
||||
|
||||
return new Type1Standard14Font(metrics);
|
||||
}
|
||||
@@ -60,18 +58,18 @@
|
||||
|
||||
var lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary);
|
||||
|
||||
var widths = FontDictionaryAccessHelper.GetWidths(pdfObjectParser, dictionary, reader, isLenientParsing);
|
||||
var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing);
|
||||
|
||||
var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfObjectParser, fontDescriptorFactory, dictionary, reader, isLenientParsing);
|
||||
var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing);
|
||||
|
||||
var font = ParseType1Font(descriptor, isLenientParsing);
|
||||
|
||||
var name = FontDictionaryAccessHelper.GetName(pdfObjectParser, dictionary, descriptor, reader, isLenientParsing);
|
||||
var name = FontDictionaryAccessHelper.GetName(pdfScanner, dictionary, descriptor, isLenientParsing);
|
||||
|
||||
CMap toUnicodeCMap = null;
|
||||
if (dictionary.TryGetItemOfType(CosName.TO_UNICODE, out CosObject toUnicodeObj))
|
||||
if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj))
|
||||
{
|
||||
var toUnicode = pdfObjectParser.Parse(toUnicodeObj.ToIndirectReference(), reader, isLenientParsing) as PdfRawStream;
|
||||
var toUnicode = DirectObjectFinder.Get<StreamToken>(toUnicodeObj, pdfScanner);
|
||||
|
||||
var decodedUnicodeCMap = toUnicode?.Decode(filterProvider);
|
||||
|
||||
@@ -81,7 +79,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
Encoding encoding = encodingReader.Read(dictionary, reader, isLenientParsing, descriptor);
|
||||
Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor);
|
||||
|
||||
if (encoding == null && font?.Encoding.Count > 0)
|
||||
{
|
||||
@@ -98,14 +96,14 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
if (descriptor.FontFile.ObjectKey.ObjectNumber == 0)
|
||||
if (descriptor.FontFile.ObjectKey.Data.ObjectNumber == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var stream = scanner.Get(descriptor.FontFile.ObjectKey).Data as StreamToken;
|
||||
var stream = pdfScanner.Get(descriptor.FontFile.ObjectKey.Data).Data as StreamToken;
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
|
@@ -1,50 +1,50 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser.Handlers
|
||||
{
|
||||
using System;
|
||||
using Cmap;
|
||||
using ContentStream;
|
||||
using Core;
|
||||
using Cos;
|
||||
using Encodings;
|
||||
using Exceptions;
|
||||
using Filters;
|
||||
using Geometry;
|
||||
using IO;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Simple;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
using Util;
|
||||
|
||||
internal class Type3FontHandler : IFontHandler
|
||||
{
|
||||
private readonly IPdfObjectParser pdfObjectParser;
|
||||
private readonly CMapCache cMapCache;
|
||||
private readonly IFilterProvider filterProvider;
|
||||
private readonly IEncodingReader encodingReader;
|
||||
private readonly IPdfObjectScanner scanner;
|
||||
|
||||
public Type3FontHandler(IPdfObjectParser pdfObjectParser, CMapCache cMapCache, IFilterProvider filterProvider, IEncodingReader encodingReader)
|
||||
public Type3FontHandler(IPdfObjectScanner scanner, CMapCache cMapCache, IFilterProvider filterProvider,
|
||||
IEncodingReader encodingReader)
|
||||
{
|
||||
this.pdfObjectParser = pdfObjectParser;
|
||||
this.cMapCache = cMapCache;
|
||||
this.filterProvider = filterProvider;
|
||||
this.encodingReader = encodingReader;
|
||||
this.scanner = scanner;
|
||||
}
|
||||
|
||||
public IFont Generate(PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var boundingBox = GetBoundingBox(dictionary);
|
||||
|
||||
var fontMatrix = GetFontMatrix(dictionary, reader, isLenientParsing);
|
||||
var fontMatrix = GetFontMatrix(dictionary);
|
||||
|
||||
var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary);
|
||||
var lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary);
|
||||
var widths = FontDictionaryAccessHelper.GetWidths(pdfObjectParser, dictionary, reader, isLenientParsing);
|
||||
var widths = FontDictionaryAccessHelper.GetWidths(scanner, dictionary, isLenientParsing);
|
||||
|
||||
Encoding encoding = encodingReader.Read(dictionary, reader, isLenientParsing);
|
||||
Encoding encoding = encodingReader.Read(dictionary, isLenientParsing);
|
||||
|
||||
CMap toUnicodeCMap = null;
|
||||
if (dictionary.TryGetItemOfType(CosName.TO_UNICODE, out CosObject toUnicodeObj))
|
||||
if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj))
|
||||
{
|
||||
var toUnicode = pdfObjectParser.Parse(toUnicodeObj.ToIndirectReference(), reader, isLenientParsing) as PdfRawStream;
|
||||
var toUnicode = DirectObjectFinder.Get<StreamToken>(toUnicodeObj, scanner);
|
||||
|
||||
var decodedUnicodeCMap = toUnicode?.Decode(filterProvider);
|
||||
|
||||
@@ -54,86 +54,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
return new Type3Font(CosName.TYPE3, boundingBox, fontMatrix, encoding, firstCharacter,
|
||||
return new Type3Font(NameToken.Type3, boundingBox, fontMatrix, encoding, firstCharacter,
|
||||
lastCharacter, widths, toUnicodeCMap);
|
||||
}
|
||||
|
||||
private TransformationMatrix GetFontMatrix(PdfDictionary dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
private TransformationMatrix GetFontMatrix(DictionaryToken dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetValue(CosName.FONT_MATRIX, out var matrixObject))
|
||||
if (!dictionary.TryGet(NameToken.FontMatrix, out var matrixObject))
|
||||
{
|
||||
throw new InvalidFontFormatException($"No font matrix found: {dictionary}.");
|
||||
}
|
||||
|
||||
COSArray matrixArray;
|
||||
if (matrixObject is COSArray arr)
|
||||
{
|
||||
matrixArray = arr;
|
||||
}
|
||||
else if (matrixObject is CosObject obj)
|
||||
{
|
||||
matrixArray = DirectObjectFinder.Find<COSArray>(obj, pdfObjectParser, reader, isLenientParsing);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidFontFormatException($"The font matrix object was not an array or reference to an array: {matrixObject}.");
|
||||
}
|
||||
|
||||
return TransformationMatrix.FromValues(GetDecimal(matrixArray, 0), GetDecimal(matrixArray, 1),
|
||||
GetDecimal(matrixArray, 2), GetDecimal(matrixArray, 3), GetDecimal(matrixArray, 4), GetDecimal(matrixArray, 5));
|
||||
var matrixArray = DirectObjectFinder.Get<ArrayToken>(matrixObject, scanner);
|
||||
|
||||
return TransformationMatrix.FromValues(matrixArray.GetNumeric(0).Data, matrixArray.GetNumeric(1).Data,
|
||||
matrixArray.GetNumeric(2).Data, matrixArray.GetNumeric(3).Data, matrixArray.GetNumeric(4).Data,
|
||||
matrixArray.GetNumeric(5).Data);
|
||||
}
|
||||
|
||||
private Encoding GetEncoding(CosBase baseObject, IRandomAccessRead reader, bool isLenientParsing)
|
||||
|
||||
private static PdfRectangle GetBoundingBox(DictionaryToken dictionary)
|
||||
{
|
||||
if (baseObject is CosObject obj)
|
||||
{
|
||||
baseObject = pdfObjectParser.Parse(obj.ToIndirectReference(), reader, isLenientParsing);
|
||||
}
|
||||
|
||||
if (baseObject is CosName encodingName)
|
||||
{
|
||||
|
||||
}
|
||||
else if (baseObject is PdfDictionary dictionary)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidFontFormatException("");
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static decimal GetDecimal(COSArray array, int index)
|
||||
{
|
||||
if (index >= array.Count)
|
||||
{
|
||||
throw new InvalidFontFormatException($"The array did not contain enough entries to be the font matrix: {array}.");
|
||||
}
|
||||
|
||||
var item = array.get(index) as ICosNumber;
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
throw new InvalidFontFormatException($"The array did not contain a decimal at position {index}: {array}.");
|
||||
}
|
||||
|
||||
return item.AsDecimal();
|
||||
}
|
||||
|
||||
private static PdfRectangle GetBoundingBox(PdfDictionary dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetValue(CosName.FONT_BBOX, out var bboxObject))
|
||||
if (!dictionary.TryGet(NameToken.FontBbox, out var bboxObject))
|
||||
{
|
||||
throw new InvalidFontFormatException($"Type 3 font was invalid. No Font Bounding Box: {dictionary}.");
|
||||
}
|
||||
|
||||
if (bboxObject is COSArray bboxArray)
|
||||
if (bboxObject is ArrayToken bboxArray)
|
||||
{
|
||||
return new PdfRectangle(GetDecimal(bboxArray, 0), GetDecimal(bboxArray, 1),
|
||||
GetDecimal(bboxArray, 2), GetDecimal(bboxArray, 3));
|
||||
return new PdfRectangle(bboxArray.GetNumeric(0).Data, bboxArray.GetNumeric(1).Data,
|
||||
bboxArray.GetNumeric(2).Data, bboxArray.GetNumeric(3).Data);
|
||||
}
|
||||
|
||||
return new PdfRectangle(0, 0, 0, 0);
|
||||
|
@@ -1,11 +1,10 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser
|
||||
{
|
||||
using ContentStream;
|
||||
using Encodings;
|
||||
using IO;
|
||||
using Tokenization.Tokens;
|
||||
|
||||
internal interface IEncodingReader
|
||||
{
|
||||
Encoding Read(PdfDictionary fontDictionary, IRandomAccessRead reader, bool isLenientParsing, FontDescriptor descriptor = null);
|
||||
Encoding Read(DictionaryToken fontDictionary, bool isLenientParsing, FontDescriptor descriptor = null);
|
||||
}
|
||||
}
|
@@ -3,12 +3,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CidFonts;
|
||||
using ContentStream;
|
||||
using Exceptions;
|
||||
using Filters;
|
||||
using Geometry;
|
||||
using IO;
|
||||
using PdfPig.Parser;
|
||||
using PdfPig.Parser.Parts;
|
||||
using Tokenization.Scanner;
|
||||
using Tokenization.Tokens;
|
||||
@@ -20,23 +18,19 @@
|
||||
{
|
||||
private readonly FontDescriptorFactory descriptorFactory;
|
||||
private readonly TrueTypeFontParser trueTypeFontParser;
|
||||
private readonly IPdfObjectParser pdfObjectParser;
|
||||
private readonly IFilterProvider filterProvider;
|
||||
private readonly IPdfObjectScanner pdfScanner;
|
||||
|
||||
public CidFontFactory(FontDescriptorFactory descriptorFactory, TrueTypeFontParser trueTypeFontParser,
|
||||
IPdfObjectParser pdfObjectParser,
|
||||
IFilterProvider filterProvider,
|
||||
IPdfObjectScanner pdfScanner)
|
||||
public CidFontFactory(IPdfObjectScanner pdfScanner, FontDescriptorFactory descriptorFactory, TrueTypeFontParser trueTypeFontParser,
|
||||
IFilterProvider filterProvider)
|
||||
{
|
||||
this.descriptorFactory = descriptorFactory;
|
||||
this.trueTypeFontParser = trueTypeFontParser;
|
||||
this.pdfObjectParser = pdfObjectParser;
|
||||
this.filterProvider = filterProvider;
|
||||
this.pdfScanner = pdfScanner;
|
||||
}
|
||||
|
||||
public ICidFont Generate(DictionaryToken dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
public ICidFont Generate(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var type = dictionary.GetNameOrDefault(NameToken.Type);
|
||||
if (!NameToken.Font.Equals(type))
|
||||
@@ -53,11 +47,11 @@
|
||||
descriptor = descriptorFactory.Generate(descriptorDictionary, isLenientParsing);
|
||||
}
|
||||
|
||||
var fontProgram = ReadDescriptorFile(descriptor, reader, isLenientParsing);
|
||||
var fontProgram = ReadDescriptorFile(descriptor);
|
||||
|
||||
var baseFont = dictionary.GetNameOrDefault(NameToken.BaseFont);
|
||||
|
||||
var systemInfo = GetSystemInfo(dictionary, reader, isLenientParsing);
|
||||
var systemInfo = GetSystemInfo(dictionary);
|
||||
|
||||
var subType = dictionary.GetNameOrDefault(NameToken.Subtype);
|
||||
if (NameToken.CidFontType0.Equals(subType))
|
||||
@@ -89,14 +83,14 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
private ICidFontProgram ReadDescriptorFile(FontDescriptor descriptor, IRandomAccessRead reader, bool isLenientParsing)
|
||||
private ICidFontProgram ReadDescriptorFile(FontDescriptor descriptor)
|
||||
{
|
||||
if (descriptor?.FontFile == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var fontFileStream = pdfObjectParser.Parse(descriptor.FontFile.ObjectKey, reader, isLenientParsing) as PdfRawStream;
|
||||
var fontFileStream = DirectObjectFinder.Get<StreamToken>(descriptor.FontFile.ObjectKey, pdfScanner);
|
||||
|
||||
if (fontFileStream == null)
|
||||
{
|
||||
@@ -219,7 +213,7 @@
|
||||
return new VerticalWritingMetrics(dw2, verticalDisplacements, positionVectors);
|
||||
}
|
||||
|
||||
private CharacterIdentifierSystemInfo GetSystemInfo(DictionaryToken dictionary, IRandomAccessRead reader, bool isLenientParsing)
|
||||
private CharacterIdentifierSystemInfo GetSystemInfo(DictionaryToken dictionary)
|
||||
{
|
||||
if(!dictionary.TryGet(NameToken.CidSystemInfo, out var cidEntry))
|
||||
{
|
||||
@@ -236,14 +230,14 @@
|
||||
DirectObjectFinder.Get<DictionaryToken>(cidEntry, pdfScanner);
|
||||
}
|
||||
|
||||
var registry = SafeKeyAccess(cidDictionary, NameToken.Registry, reader, isLenientParsing);
|
||||
var ordering = SafeKeyAccess(cidDictionary, NameToken.Ordering, reader, isLenientParsing);
|
||||
var registry = SafeKeyAccess(cidDictionary, NameToken.Registry);
|
||||
var ordering = SafeKeyAccess(cidDictionary, NameToken.Ordering);
|
||||
var supplement = cidDictionary.GetIntOrDefault(NameToken.Supplement);
|
||||
|
||||
return new CharacterIdentifierSystemInfo(registry, ordering, supplement);
|
||||
}
|
||||
|
||||
private string SafeKeyAccess(DictionaryToken dictionary, NameToken keyName, IRandomAccessRead reader, bool isLenientParsing)
|
||||
private string SafeKeyAccess(DictionaryToken dictionary, NameToken keyName)
|
||||
{
|
||||
if (!dictionary.TryGet(keyName, out var token))
|
||||
{
|
||||
|
@@ -1,15 +1,14 @@
|
||||
namespace UglyToad.PdfPig.Fonts.Parser.Parts
|
||||
{
|
||||
using System;
|
||||
using ContentStream;
|
||||
using ContentStream.TypedAccessors;
|
||||
using Cos;
|
||||
using Geometry;
|
||||
using Tokenization.Tokens;
|
||||
using Util;
|
||||
using Util.JetBrains.Annotations;
|
||||
|
||||
internal class FontDescriptorFactory
|
||||
{
|
||||
public FontDescriptor Generate(PdfDictionary dictionary, bool isLenientParsing)
|
||||
public FontDescriptor Generate(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
if (dictionary == null)
|
||||
{
|
||||
@@ -28,31 +27,41 @@
|
||||
{
|
||||
FontFamily = family,
|
||||
Stretch = stretch,
|
||||
FontWeight = dictionary.GetDecimalOrDefault(CosName.FONT_WEIGHT, 0),
|
||||
FontWeight = GetDecimalOrDefault(dictionary, NameToken.FontWeight),
|
||||
BoundingBox = bounding,
|
||||
ItalicAngle = dictionary.GetDecimalOrDefault(CosName.ITALIC_ANGLE, 0),
|
||||
Ascent = dictionary.GetDecimalOrDefault(CosName.ASCENT, 0),
|
||||
Descent = dictionary.GetDecimalOrDefault(CosName.DESCENT, 0),
|
||||
Leading = dictionary.GetDecimalOrDefault(CosName.LEADING, 0),
|
||||
CapHeight = Math.Abs(dictionary.GetDecimalOrDefault(CosName.CAP_HEIGHT, 0)),
|
||||
XHeight = Math.Abs(dictionary.GetDecimalOrDefault(CosName.XHEIGHT, 0)),
|
||||
StemVertical = dictionary.GetDecimalOrDefault(CosName.STEM_V, 0),
|
||||
StemHorizontal = dictionary.GetDecimalOrDefault(CosName.STEM_H, 0),
|
||||
AverageWidth = dictionary.GetDecimalOrDefault(CosName.AVG_WIDTH, 0),
|
||||
MaxWidth = dictionary.GetDecimalOrDefault(CosName.MAX_WIDTH, 0),
|
||||
MissingWidth = dictionary.GetDecimalOrDefault(CosName.MISSING_WIDTH, 0),
|
||||
ItalicAngle = GetDecimalOrDefault(dictionary, NameToken.ItalicAngle),
|
||||
Ascent = GetDecimalOrDefault(dictionary, NameToken.Ascent),
|
||||
Descent = GetDecimalOrDefault(dictionary, NameToken.Descent),
|
||||
Leading = GetDecimalOrDefault(dictionary, NameToken.Leading),
|
||||
CapHeight = Math.Abs(GetDecimalOrDefault(dictionary, NameToken.CapHeight)),
|
||||
XHeight = Math.Abs(GetDecimalOrDefault(dictionary, NameToken.Xheight)),
|
||||
StemVertical = GetDecimalOrDefault(dictionary, NameToken.StemV),
|
||||
StemHorizontal = GetDecimalOrDefault(dictionary, NameToken.StemH),
|
||||
AverageWidth = GetDecimalOrDefault(dictionary, NameToken.AvgWidth),
|
||||
MaxWidth = GetDecimalOrDefault(dictionary, NameToken.MaxWidth),
|
||||
MissingWidth = GetDecimalOrDefault(dictionary, NameToken.MissingWidth),
|
||||
FontFile = fontFile,
|
||||
CharSet = charSet
|
||||
};
|
||||
}
|
||||
|
||||
private static CosName GetFontName(PdfDictionary dictionary, bool isLenientParsing)
|
||||
private static decimal GetDecimalOrDefault(DictionaryToken dictionary, NameToken name)
|
||||
{
|
||||
if (!dictionary.TryGetName(CosName.FONT_NAME, out var name))
|
||||
if (!dictionary.TryGet(name, out var token) || !(token is NumericToken number))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return number.Data;
|
||||
}
|
||||
|
||||
private static NameToken GetFontName(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
if (!dictionary.TryGet(NameToken.FontName, out var name) || !(name is NameToken nameToken))
|
||||
{
|
||||
if (isLenientParsing)
|
||||
{
|
||||
name = CosName.Create(string.Empty);
|
||||
nameToken = NameToken.Create(string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -60,32 +69,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
return nameToken;
|
||||
}
|
||||
|
||||
private static string GetFontFamily(PdfDictionary dictionary)
|
||||
private static string GetFontFamily(DictionaryToken dictionary)
|
||||
{
|
||||
if (dictionary.TryGetItemOfType<CosString>(CosName.FONT_FAMILY, out var value))
|
||||
if (dictionary.TryGet(NameToken.FontFamily, out var value) && value is StringToken fontFamily)
|
||||
{
|
||||
return value.GetString();
|
||||
return fontFamily.Data;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static FontStretch GetFontStretch(PdfDictionary dictionary)
|
||||
private static FontStretch GetFontStretch(DictionaryToken dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetName(CosName.FONT_STRETCH, out var stretch))
|
||||
if (!dictionary.TryGet(NameToken.FontStretch, out var stretch) || !(stretch is NameToken stretchName))
|
||||
{
|
||||
return FontStretch.Normal;
|
||||
}
|
||||
|
||||
return stretch.ConvertToFontStretch();
|
||||
return stretchName.ConvertToFontStretch();
|
||||
}
|
||||
|
||||
private static FontFlags GetFlags(PdfDictionary dictionary, bool isLenientParsing)
|
||||
private static FontFlags GetFlags(DictionaryToken dictionary, bool isLenientParsing)
|
||||
{
|
||||
var flags = dictionary.GetIntOrDefault(CosName.FLAGS, -1);
|
||||
var flags = dictionary.GetIntOrDefault(NameToken.Flags, -1);
|
||||
|
||||
if (flags == -1)
|
||||
{
|
||||
@@ -102,66 +111,66 @@
|
||||
return (FontFlags) flags;
|
||||
}
|
||||
|
||||
private static PdfRectangle GetBoundingBox(PdfDictionary dictionary)
|
||||
private static PdfRectangle GetBoundingBox(DictionaryToken dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetItemOfType<COSArray>(CosName.FONT_BBOX, out var box))
|
||||
if (!dictionary.TryGet(NameToken.FontBbox, out var box) || !(box is ArrayToken boxArray))
|
||||
{
|
||||
return new PdfRectangle(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (box.Count != 4)
|
||||
if (boxArray.Data.Count != 4)
|
||||
{
|
||||
return new PdfRectangle(0, 0, 0, 0);
|
||||
}
|
||||
var x1 = box.getInt(0);
|
||||
var y1 = box.getInt(1);
|
||||
var x2 = box.getInt(2);
|
||||
var y2 = box.getInt(3);
|
||||
var x1 = boxArray.GetNumeric(0).Data;
|
||||
var y1 = boxArray.GetNumeric(1).Data;
|
||||
var x2 = boxArray.GetNumeric(2).Data;
|
||||
var y2 = boxArray.GetNumeric(3).Data;
|
||||
|
||||
return new PdfRectangle(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
private static string GetCharSet(PdfDictionary dictionary)
|
||||
private static string GetCharSet(DictionaryToken dictionary)
|
||||
{
|
||||
if (!dictionary.TryGetName(CosName.CHAR_SET, out var set))
|
||||
if (!dictionary.TryGet(NameToken.CharSet, out var set) || !(set is NameToken setName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return set.Name;
|
||||
return setName.Data;
|
||||
}
|
||||
|
||||
[CanBeNull]
|
||||
private static DescriptorFontFile GetFontFile(PdfDictionary dictionary)
|
||||
private static DescriptorFontFile GetFontFile(DictionaryToken dictionary)
|
||||
{
|
||||
if (dictionary.TryGetValue(CosName.FONT_FILE, out var value))
|
||||
if (dictionary.TryGet(NameToken.FontFile, out var value))
|
||||
{
|
||||
if (!(value is CosObject obj))
|
||||
if (!(value is IndirectReferenceToken obj))
|
||||
{
|
||||
throw new NotSupportedException("We currently expect the FontFile to be an object reference.");
|
||||
}
|
||||
|
||||
return new DescriptorFontFile(obj.ToIndirectReference(), DescriptorFontFile.FontFileType.Type1);
|
||||
return new DescriptorFontFile(obj, DescriptorFontFile.FontFileType.Type1);
|
||||
}
|
||||
|
||||
if (dictionary.TryGetValue(CosName.FONT_FILE2, out value))
|
||||
if (dictionary.TryGet(NameToken.FontFile2, out value))
|
||||
{
|
||||
if (!(value is CosObject obj))
|
||||
if (!(value is IndirectReferenceToken obj))
|
||||
{
|
||||
throw new NotSupportedException("We currently expect the FontFile2 to be an object reference.");
|
||||
}
|
||||
|
||||
return new DescriptorFontFile(obj.ToIndirectReference(), DescriptorFontFile.FontFileType.TrueType);
|
||||
return new DescriptorFontFile(obj, DescriptorFontFile.FontFileType.TrueType);
|
||||
}
|
||||
|
||||
if (dictionary.TryGetValue(CosName.FONT_FILE3, out value))
|
||||
if (dictionary.TryGet(NameToken.FontFile3, out value))
|
||||
{
|
||||
if (!(value is CosObject obj))
|
||||
if (!(value is IndirectReferenceToken obj))
|
||||
{
|
||||
throw new NotSupportedException("We currently expect the FontFile3 to be an object reference.");
|
||||
}
|
||||
|
||||
return new DescriptorFontFile(obj.ToIndirectReference(), DescriptorFontFile.FontFileType.FromSubtype);
|
||||
return new DescriptorFontFile(obj, DescriptorFontFile.FontFileType.FromSubtype);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@@ -130,7 +130,7 @@
|
||||
|
||||
var width = displacement.X * fontSize * TextMatrices.TextMatrix.GetScalingFactorX() * transformationMatrix.A;
|
||||
|
||||
ShowGlyph(renderingMatrix, font, code, unicode, width, fontSize, pointSize);
|
||||
ShowGlyph(renderingMatrix, font, unicode, width, fontSize, pointSize);
|
||||
|
||||
decimal tx, ty;
|
||||
if (font.IsVertical)
|
||||
@@ -208,12 +208,12 @@
|
||||
TextMatrices.TextMatrix = newMatrix;
|
||||
}
|
||||
|
||||
private void ShowGlyph(TransformationMatrix renderingMatrix, IFont font, int characterCode, string unicode, decimal width, decimal fontSize,
|
||||
private void ShowGlyph(TransformationMatrix renderingMatrix, IFont font, string unicode, decimal width, decimal fontSize,
|
||||
decimal pointSize)
|
||||
{
|
||||
var location = new PdfPoint(renderingMatrix.E, renderingMatrix.F);
|
||||
|
||||
var letter = new Letter(unicode, location, width, fontSize, font.Name.Name, pointSize);
|
||||
var letter = new Letter(unicode, location, width, fontSize, font.Name.Data, pointSize);
|
||||
|
||||
Letters.Add(letter);
|
||||
}
|
||||
|
@@ -22,8 +22,8 @@
|
||||
private readonly IPageContentParser pageContentParser;
|
||||
private readonly IPdfObjectScanner pdfScanner;
|
||||
|
||||
public PageFactory(IResourceStore resourceStore, IFilterProvider filterProvider,
|
||||
IPageContentParser pageContentParser, IPdfObjectScanner pdfScanner)
|
||||
public PageFactory(IPdfObjectScanner pdfScanner, IResourceStore resourceStore, IFilterProvider filterProvider,
|
||||
IPageContentParser pageContentParser)
|
||||
{
|
||||
this.resourceStore = resourceStore;
|
||||
this.filterProvider = filterProvider;
|
||||
@@ -132,10 +132,10 @@
|
||||
CropBox cropBox;
|
||||
if (dictionary.TryGet(NameToken.CropBox, out var cropBoxObject) && cropBoxObject is ArrayToken cropBoxArray)
|
||||
{
|
||||
var x1 = cropBoxArray.GetNumeric(0).Data;
|
||||
var y1 = cropBoxArray.GetNumeric(1).Data;
|
||||
var x2 = cropBoxArray.GetNumeric(2).Data;
|
||||
var y2 = cropBoxArray.GetNumeric(3).Data;
|
||||
var x1 = cropBoxArray.GetNumeric(0).Int;
|
||||
var y1 = cropBoxArray.GetNumeric(1).Int;
|
||||
var x2 = cropBoxArray.GetNumeric(2).Int;
|
||||
var y2 = cropBoxArray.GetNumeric(3).Int;
|
||||
|
||||
cropBox = new CropBox(new PdfRectangle(x1, y1, x2, y2));
|
||||
}
|
||||
@@ -152,10 +152,10 @@
|
||||
MediaBox mediaBox;
|
||||
if (dictionary.TryGet(NameToken.MediaBox, out var mediaboxObject) && mediaboxObject is ArrayToken mediaboxArray)
|
||||
{
|
||||
var x1 = mediaboxArray.GetNumeric(0).Data;
|
||||
var y1 = mediaboxArray.GetNumeric(1).Data;
|
||||
var x2 = mediaboxArray.GetNumeric(2).Data;
|
||||
var y2 = mediaboxArray.GetNumeric(3).Data;
|
||||
var x1 = mediaboxArray.GetNumeric(0).Int;
|
||||
var y1 = mediaboxArray.GetNumeric(1).Int;
|
||||
var x2 = mediaboxArray.GetNumeric(2).Int;
|
||||
var y2 = mediaboxArray.GetNumeric(3).Int;
|
||||
|
||||
mediaBox = new MediaBox(new PdfRectangle(x1, y1, x2, y2));
|
||||
}
|
||||
|
@@ -79,24 +79,23 @@
|
||||
var trueTypeFontParser = new TrueTypeFontParser();
|
||||
var fontDescriptorFactory = new FontDescriptorFactory();
|
||||
|
||||
var cidFontFactory = new CidFontFactory(fontDescriptorFactory, trueTypeFontParser, pdfObjectParser, filterProvider);
|
||||
var encodingReader = new EncodingReader(pdfObjectParser);
|
||||
var pdfScanner = new PdfTokenScanner(inputBytes, new ObjectLocationProvider(crossReferenceTable, pool, bruteForceSearcher));
|
||||
var cidFontFactory = new CidFontFactory(pdfScanner, fontDescriptorFactory, trueTypeFontParser, filterProvider);
|
||||
var encodingReader = new EncodingReader(pdfScanner);
|
||||
|
||||
var cMapCache = new CMapCache(new CMapParser());
|
||||
|
||||
var pdfScanner = new PdfTokenScanner(inputBytes, new ObjectLocationProvider(crossReferenceTable, pool, bruteForceSearcher));
|
||||
var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory,
|
||||
cMapCache,
|
||||
filterProvider,
|
||||
pdfObjectParser),
|
||||
new TrueTypeFontHandler(pdfObjectParser, filterProvider, cMapCache, fontDescriptorFactory, trueTypeFontParser, encodingReader),
|
||||
new Type1FontHandler(pdfObjectParser, cMapCache, filterProvider, fontDescriptorFactory, encodingReader, pdfScanner, new Type1FontParser()),
|
||||
new Type3FontHandler(pdfObjectParser, cMapCache, filterProvider, encodingReader));
|
||||
filterProvider, pdfScanner),
|
||||
new TrueTypeFontHandler(pdfScanner, filterProvider, cMapCache, fontDescriptorFactory, trueTypeFontParser, encodingReader),
|
||||
new Type1FontHandler(pdfScanner, cMapCache, filterProvider, fontDescriptorFactory, encodingReader, new Type1FontParser()),
|
||||
new Type3FontHandler(pdfScanner, cMapCache, filterProvider, encodingReader));
|
||||
|
||||
var dynamicParser = container.Get<DynamicParser>();
|
||||
var resourceContainer = new ResourceContainer(pdfObjectParser, fontFactory);
|
||||
var resourceContainer = new ResourceContainer(pdfScanner, fontFactory);
|
||||
|
||||
var pageFactory = new PageFactory(resourceContainer, pdfObjectParser, filterProvider, new PageContentParser(new ReflectionGraphicsStateOperationFactory()));
|
||||
var pageFactory = new PageFactory(pdfScanner, resourceContainer, filterProvider, new PageContentParser(new ReflectionGraphicsStateOperationFactory()));
|
||||
var informationFactory = new DocumentInformationFactory();
|
||||
var catalogFactory = new CatalogFactory(pdfScanner);
|
||||
|
||||
@@ -110,7 +109,7 @@
|
||||
var caching = new ParsingCachingProviders(pool, bruteForceSearcher, resourceContainer);
|
||||
|
||||
|
||||
return new PdfDocument(log, reader, version, crossReferenceTable, isLenientParsing, caching, pageFactory, pdfObjectParser, catalog, information,
|
||||
return new PdfDocument(log, reader, version, crossReferenceTable, isLenientParsing, caching, pageFactory, catalog, information,
|
||||
pdfScanner);
|
||||
}
|
||||
|
||||
|
@@ -55,7 +55,6 @@
|
||||
bool isLenientParsing,
|
||||
ParsingCachingProviders cachingProviders,
|
||||
IPageFactory pageFactory,
|
||||
IPdfObjectParser pdfObjectParser,
|
||||
Catalog catalog,
|
||||
DocumentInformation information, IPdfObjectScanner pdfScanner)
|
||||
{
|
||||
@@ -68,7 +67,7 @@
|
||||
this.pdfScanner = pdfScanner;
|
||||
Information = information ?? throw new ArgumentNullException(nameof(information));
|
||||
Catalog = catalog ?? throw new ArgumentNullException(nameof(catalog));
|
||||
Pages = new Pages(log, Catalog, pdfObjectParser, pageFactory, reader, isLenientParsing, pdfScanner);
|
||||
Pages = new Pages(log, Catalog, pageFactory, reader, isLenientParsing, pdfScanner);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -35,7 +35,19 @@
|
||||
|
||||
public bool TryGetOffset(IndirectReference reference, out long offset)
|
||||
{
|
||||
return offsets.TryGetValue(reference, out offset);
|
||||
if (offsets.TryGetValue(reference, out offset))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var locations = searcher.GetObjectLocations();
|
||||
|
||||
if (locations.TryGetValue(reference, out offset))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UpdateOffset(IndirectReference reference, long offset)
|
||||
|
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ContentStream;
|
||||
|
||||
internal class ArrayToken : IDataToken<IReadOnlyList<IToken>>
|
||||
{
|
||||
@@ -10,7 +11,35 @@
|
||||
|
||||
public ArrayToken(IReadOnlyList<IToken> data)
|
||||
{
|
||||
Data = data ?? throw new ArgumentNullException(nameof(data));
|
||||
if (data == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
}
|
||||
|
||||
var previousPrevious = default(IToken);
|
||||
var previous = default(IToken);
|
||||
|
||||
var result = new List<IToken>();
|
||||
foreach (var token in data)
|
||||
{
|
||||
// Roll any "number number R" sequence into an indirect reference
|
||||
if (ReferenceEquals(token, OperatorToken.R) && previous is NumericToken generation && previousPrevious is NumericToken objectNumber)
|
||||
{
|
||||
// Clear the previous 2 tokens.
|
||||
result.RemoveRange(result.Count - 2, 2);
|
||||
|
||||
result.Add(new IndirectReferenceToken(new IndirectReference(objectNumber.Long, generation.Int)));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(token);
|
||||
}
|
||||
|
||||
previousPrevious = previous;
|
||||
previous = token;
|
||||
}
|
||||
|
||||
Data = result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
@@ -1,7 +1,11 @@
|
||||
namespace UglyToad.PdfPig.Tokenization.Tokens
|
||||
{
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
internal partial class NameToken
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, NameToken> NameMap = new ConcurrentDictionary<string, NameToken>();
|
||||
|
||||
#region A
|
||||
public static readonly NameToken A = new NameToken("A");
|
||||
public static readonly NameToken Aa = new NameToken("AA");
|
||||
|
@@ -1,13 +1,9 @@
|
||||
namespace UglyToad.PdfPig.Tokenization.Tokens
|
||||
{
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
internal partial class NameToken : IDataToken<string>
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, NameToken> NameMap = new ConcurrentDictionary<string, NameToken>();
|
||||
|
||||
public string Data { get; }
|
||||
|
||||
|
||||
private NameToken(string text)
|
||||
{
|
||||
NameMap[text] = this;
|
||||
@@ -47,7 +43,7 @@
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Data;
|
||||
return $"/{Data}";
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user