mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-10-14 10:55:04 +08:00
test all predefined cmaps and fix bugs
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
namespace UglyToad.Pdf.Tests.Fonts.Parser
|
namespace UglyToad.Pdf.Tests.Fonts.Parser
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using IO;
|
||||||
using Pdf.Fonts.Parser;
|
using Pdf.Fonts.Parser;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@@ -84,5 +88,42 @@ end";
|
|||||||
Assert.Equal("a", cmap.BaseFontCharacterMap[68]);
|
Assert.Equal("a", cmap.BaseFontCharacterMap[68]);
|
||||||
Assert.Equal("x", cmap.BaseFontCharacterMap[91]);
|
Assert.Equal("x", cmap.BaseFontCharacterMap[91]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(PredefinedCMaps))]
|
||||||
|
public void CanParseAllPredefinedCMaps(string resourceName)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Parsing: " + resourceName);
|
||||||
|
|
||||||
|
var input = new ByteArrayInputBytes(ReadResourceBytes(resourceName));
|
||||||
|
|
||||||
|
var cmap = cMapParser.Parse(input, false);
|
||||||
|
|
||||||
|
Assert.NotNull(cmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] ReadResourceBytes(string name)
|
||||||
|
{
|
||||||
|
using (var resource = typeof(CMapParser).Assembly.GetManifestResourceStream(name))
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
resource.CopyTo(memoryStream);
|
||||||
|
|
||||||
|
return memoryStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> PredefinedCMaps()
|
||||||
|
{
|
||||||
|
var resources = typeof(CMapParser).Assembly.GetManifestResourceNames();
|
||||||
|
|
||||||
|
foreach (var resource in resources)
|
||||||
|
{
|
||||||
|
if (resource.Contains(".CMap."))
|
||||||
|
{
|
||||||
|
yield return new object[] {resource};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,6 +97,45 @@
|
|||||||
throw new InvalidOperationException("The Character Identifier System Information was never set.");
|
throw new InvalidOperationException("The Character Identifier System Information was never set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UseCMap(CMap other)
|
||||||
|
{
|
||||||
|
CodespaceRanges = Combine(CodespaceRanges, other.CodespaceRanges);
|
||||||
|
CidCharacterMappings = Combine(CidCharacterMappings, other.CidCharacterMappings);
|
||||||
|
CidRanges = Combine(CidRanges, other.CidRanges);
|
||||||
|
|
||||||
|
if (other.BaseFontCharacterMap != null)
|
||||||
|
{
|
||||||
|
foreach (var keyValuePair in other.BaseFontCharacterMap)
|
||||||
|
{
|
||||||
|
BaseFontCharacterMap[keyValuePair.Key] = keyValuePair.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IReadOnlyList<T> Combine<T>(IReadOnlyList<T> a, IReadOnlyList<T> b)
|
||||||
|
{
|
||||||
|
if (a == null && b == null)
|
||||||
|
{
|
||||||
|
return new T[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == null)
|
||||||
|
{
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b == null)
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new List<T>(a);
|
||||||
|
|
||||||
|
result.AddRange(b);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private int GetCodeFromArray(IReadOnlyList<byte> data, int length)
|
private int GetCodeFromArray(IReadOnlyList<byte> data, int length)
|
||||||
{
|
{
|
||||||
int code = 0;
|
int code = 0;
|
||||||
|
@@ -34,7 +34,19 @@
|
|||||||
switch (operatorToken.Data)
|
switch (operatorToken.Data)
|
||||||
{
|
{
|
||||||
case "usecmap":
|
case "usecmap":
|
||||||
throw new NotImplementedException("External CMap files not yet supported, please submit a pull request!");
|
{
|
||||||
|
if (previousToken is NameToken name)
|
||||||
|
{
|
||||||
|
var external = ParseExternal(name.Data.Name);
|
||||||
|
|
||||||
|
builder.UseCMap(external);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Unexpected token preceding external cmap call: " + previousToken);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "begincodespacerange":
|
case "begincodespacerange":
|
||||||
{
|
{
|
||||||
if (previousToken is NumericToken numeric)
|
if (previousToken is NumericToken numeric)
|
||||||
|
Reference in New Issue
Block a user