public void Parse(NumericToken numeric, ITokenScanner tokenScanner, CharacterMapBuilder builder, bool isLenientParsing) { /* * For example: * 3 begincodespacerange * <00> <80> * <8140> <9ffc> * <a0> <de> * endcodespacerange */ var ranges = new List <CodespaceRange>(numeric.Int); for (var i = 0; i < numeric.Int; i++) { if (!tokenScanner.MoveNext() || !(tokenScanner.CurrentToken is HexToken start)) { throw new InvalidOperationException("Codespace range contains an unexpected token: " + tokenScanner.CurrentToken); } if (!tokenScanner.MoveNext() || !(tokenScanner.CurrentToken is HexToken end)) { throw new InvalidOperationException("Codespace range contains an unexpected token: " + tokenScanner.CurrentToken); } ranges.Add(new CodespaceRange(start.Bytes, end.Bytes)); } builder.CodespaceRanges = ranges; }
public void Parse(NumericToken numeric, ITokenScanner tokenScanner, CharacterMapBuilder builder, bool isLenientParsing) { for (var i = 0; i < numeric.Int; i++) { if (!tokenScanner.MoveNext() || !(tokenScanner.CurrentToken is HexToken inputCode)) { throw new InvalidOperationException($"Base font characters definition contains invalid item at index {i}: {tokenScanner.CurrentToken}"); } if (!tokenScanner.MoveNext()) { throw new InvalidOperationException($"Base font characters definition contains invalid item at index {i}: {tokenScanner.CurrentToken}"); } if (tokenScanner.CurrentToken is NameToken characterName) { builder.AddBaseFontCharacter(inputCode.Bytes, characterName.Data); } else if (tokenScanner.CurrentToken is HexToken characterCode) { builder.AddBaseFontCharacter(inputCode.Bytes, characterCode.Bytes); } else { throw new InvalidOperationException($"Base font characters definition contains invalid item at index {i}: {tokenScanner.CurrentToken}"); } } }
public void Parse(NumericToken numeric, ITokenScanner scanner, CharacterMapBuilder builder, bool isLenientParsing) { for (var i = 0; i < numeric.Int; i++) { if (!scanner.TryReadToken(out HexToken startHexToken)) { throw new InvalidFontFormatException("Could not find the starting hex token for the CIDRange in this font."); } if (!scanner.TryReadToken(out HexToken endHexToken)) { throw new InvalidFontFormatException("Could not find the end hex token for the CIDRange in this font."); } if (!scanner.TryReadToken(out NumericToken mappedCode)) { throw new InvalidFontFormatException("Could not find the starting CID numeric token for the CIDRange in this font."); } var start = HexToken.ConvertHexBytesToInt(startHexToken); var end = HexToken.ConvertHexBytesToInt(endHexToken); var range = new CidRange(start, end, mappedCode.Int); builder.AddCidRange(range); } }
public CMap Parse(IInputBytes inputBytes) { var scanner = new CoreTokenScanner(inputBytes); var builder = new CharacterMapBuilder(); IToken previousToken = null; while (scanner.MoveNext()) { var token = scanner.CurrentToken; if (token is OperatorToken operatorToken) { switch (operatorToken.Data) { case "usecmap": { if (previousToken is NameToken name && TryParseExternal(name.Data, out var external)) { builder.UseCMap(external); } else { throw new InvalidOperationException("Unexpected token preceding external cmap call: " + previousToken); } break; }
public void Parse(NumericToken numeric, ITokenScanner tokenScanner, CharacterMapBuilder builder, bool isLenientParsing) { for (var i = 0; i < numeric.Int; i++) { if (!tokenScanner.MoveNext() || !(tokenScanner.CurrentToken is HexToken inputCode)) { if (tokenScanner.CurrentToken is OperatorToken op && (string.Equals(op.Data, "endbfchar", StringComparison.OrdinalIgnoreCase) || string.Equals(op.Data, "endcmap", StringComparison.OrdinalIgnoreCase))) { return; } throw new InvalidOperationException($"Base font characters definition contains invalid item at index {i}: {tokenScanner.CurrentToken}"); } if (!tokenScanner.MoveNext()) { throw new InvalidOperationException($"Base font characters definition contains invalid item at index {i}: {tokenScanner.CurrentToken}"); } if (tokenScanner.CurrentToken is NameToken characterName) { builder.AddBaseFontCharacter(inputCode.Bytes, characterName.Data); } else if (tokenScanner.CurrentToken is HexToken characterCode) { builder.AddBaseFontCharacter(inputCode.Bytes, characterCode.Bytes); } else { throw new InvalidOperationException($"Base font characters definition contains invalid item at index {i}: {tokenScanner.CurrentToken}"); } } }
public void CanParseWithHex() { var input = StringBytesTestConverter.Scanner("<8141> <8147> <8141>"); var builder = new CharacterMapBuilder(); parser.Parse(new NumericToken(1), input, builder, false); Assert.Equal(7, builder.BaseFontCharacterMap.Count); Assert.Equal("腁", builder.BaseFontCharacterMap[33089]); Assert.Equal(char.ConvertFromUtf32(33090), builder.BaseFontCharacterMap[33090]); }
public void CanParseWithArray() { var input = StringBytesTestConverter.Scanner("<0003> <0004> [<0020> <0041>]"); var builder = new CharacterMapBuilder(); parser.Parse(new NumericToken(1), input, builder, false); Assert.Equal(2, builder.BaseFontCharacterMap.Count); Assert.Equal(" ", builder.BaseFontCharacterMap[3]); Assert.Equal("A", builder.BaseFontCharacterMap[4]); }
public void CanParseTwoRowsWithDifferentFormat() { var input = StringBytesTestConverter.Scanner(@"<0019> <001B> <3C> <0001> <0003> [/happy /feet /penguin]"); var builder = new CharacterMapBuilder(); parser.Parse(new NumericToken(2), input, builder, false); Assert.Equal(6, builder.BaseFontCharacterMap.Count); Assert.Equal("happy", builder.BaseFontCharacterMap[1]); Assert.Equal("feet", builder.BaseFontCharacterMap[2]); Assert.Equal("penguin", builder.BaseFontCharacterMap[3]); Assert.Equal("<", builder.BaseFontCharacterMap[25]); }
public void Parse(NumericToken numeric, ITokenScanner tokenScanner, CharacterMapBuilder builder) { /* * For example: * 3 begincodespacerange * <00> <80> * <8140> <9ffc> * <a0> <de> * endcodespacerange */ var ranges = new List <CodespaceRange>(numeric.Int); for (var i = 0; i < numeric.Int; i++) { if (!tokenScanner.MoveNext()) { throw new InvalidOperationException("Codespace range have reach an unexpected end"); } if (tokenScanner.CurrentToken is OperatorToken operatorToken && operatorToken.Data == "endcodespacerange") { // Don't add this code space range break; } if (!(tokenScanner.CurrentToken is HexToken start)) { throw new InvalidOperationException("Codespace range contains an unexpected token: " + tokenScanner.CurrentToken); } if (!tokenScanner.MoveNext() || !(tokenScanner.CurrentToken is HexToken end)) { throw new InvalidOperationException("Codespace range contains an unexpected token: " + tokenScanner.CurrentToken); } ranges.Add(new CodespaceRange(start.Bytes, end.Bytes)); } builder.CodespaceRanges = ranges; }
public void ColorspaceParserError() { var parser = new CodespaceRangeParser(); var byteArrayInput = new ByteArrayInputBytes(OtherEncodings.StringAsLatin1Bytes("1 begincodespacerange\nendcodespacerange")); var tokenScanner = new CoreTokenScanner(byteArrayInput); Assert.True(tokenScanner.MoveNext()); Assert.True(tokenScanner.CurrentToken is NumericToken); var numeric = (NumericToken)tokenScanner.CurrentToken; Assert.True(tokenScanner.MoveNext()); Assert.True(tokenScanner.CurrentToken is OperatorToken); var opToken = (OperatorToken)tokenScanner.CurrentToken; Assert.Equal("begincodespacerange", opToken.Data); var cmapBuilder = new CharacterMapBuilder(); parser.Parse(numeric, tokenScanner, cmapBuilder); Assert.Empty(cmapBuilder.CodespaceRanges); }
public void Parse(NumericToken numeric, ITokenScanner scanner, CharacterMapBuilder builder, bool isLenientParsing) { var results = new List <CidCharacterMapping>(); for (var i = 0; i < numeric.Int; i++) { if (!scanner.TryReadToken(out HexToken sourceCode)) { throw new InvalidOperationException("The first token in a line for Cid Characters should be a hex, instead it was: " + scanner.CurrentToken); } if (!scanner.TryReadToken(out NumericToken destinationCode)) { throw new InvalidOperationException("The destination token in a line for Cid Character should be an integer, instead it was: " + scanner.CurrentToken); } var sourceInteger = sourceCode.Bytes.ToInt(sourceCode.Bytes.Count); var mapping = new CidCharacterMapping(sourceInteger, destinationCode.Int); results.Add(mapping); } builder.CidCharacterMappings = results; }
public void Parse(NumericToken numberOfOperations, ITokenScanner scanner, CharacterMapBuilder builder, bool isLenientParsing) { for (var i = 0; i < numberOfOperations.Int; i++) { // The start of the input code range. if (!scanner.TryReadToken(out HexToken lowSourceCode)) { throw new InvalidFontFormatException($"bfrange was missing the low source code: {scanner.CurrentToken}"); } // The inclusive end of the input code range. if (!scanner.TryReadToken(out HexToken highSourceCode)) { throw new InvalidFontFormatException($"bfrange was missing the high source code: {scanner.CurrentToken}"); } if (!scanner.MoveNext()) { throw new InvalidFontFormatException("bfrange ended unexpectedly after the high source code."); } List <byte> destinationBytes = null; ArrayToken destinationArray = null; switch (scanner.CurrentToken) { case ArrayToken arrayToken: destinationArray = arrayToken; break; case HexToken hexToken: destinationBytes = hexToken.Bytes.ToList(); break; case NumericToken _: throw new NotImplementedException("From the spec it seems this possible but the meaning is unclear..."); default: throw new InvalidOperationException(); } var done = false; var startCode = new List <byte>(lowSourceCode.Bytes); var endCode = highSourceCode.Bytes; if (destinationArray != null) { int arrayIndex = 0; while (!done) { if (Compare(startCode, endCode) >= 0) { done = true; } var destination = destinationArray.Data[arrayIndex]; if (destination is NameToken name) { builder.AddBaseFontCharacter(startCode, name.Data); } else if (destination is HexToken hex) { builder.AddBaseFontCharacter(startCode, hex.Bytes); } Increment(startCode, startCode.Count - 1); arrayIndex++; } continue; } while (!done) { if (Compare(startCode, endCode) >= 0) { done = true; } builder.AddBaseFontCharacter(startCode, destinationBytes); Increment(startCode, startCode.Count - 1); Increment(destinationBytes, destinationBytes.Count - 1); } } }
public CMap Parse(IInputBytes inputBytes, bool isLenientParsing) { var scanner = new CoreTokenScanner(inputBytes); var builder = new CharacterMapBuilder(); IToken previousToken = null; while (scanner.MoveNext()) { var token = scanner.CurrentToken; if (token is OperatorToken operatorToken) { switch (operatorToken.Data) { case "usecmap": { if (previousToken is NameToken name) { var external = ParseExternal(name.Data); builder.UseCMap(external); } else { throw new InvalidOperationException("Unexpected token preceding external cmap call: " + previousToken); } break; } case "begincodespacerange": { if (previousToken is NumericToken numeric) { CodespaceRangeParser.Parse(numeric, scanner, builder, isLenientParsing); } else { throw new InvalidOperationException("Unexpected token preceding start of codespace range: " + previousToken); } } break; case "beginbfchar": { if (previousToken is NumericToken numeric) { BaseFontCharacterParser.Parse(numeric, scanner, builder, isLenientParsing); } else { throw new InvalidOperationException("Unexpected token preceding start of base font characters: " + previousToken); } } break; case "beginbfrange": { if (previousToken is NumericToken numeric) { BaseFontRangeParser.Parse(numeric, scanner, builder, isLenientParsing); } else { throw new InvalidOperationException("Unexpected token preceding start of base font character ranges: " + previousToken); } } break; case "begincidchar": { if (previousToken is NumericToken numeric) { CidCharacterParser.Parse(numeric, scanner, builder, isLenientParsing); } else { throw new InvalidOperationException("Unexpected token preceding start of Cid character mapping: " + previousToken); } break; } case "begincidrange": { if (previousToken is NumericToken numeric) { CidRangeParser.Parse(numeric, scanner, builder, isLenientParsing); } else { throw new InvalidOperationException("Unexpected token preceding start of Cid ranges: " + previousToken); } } break; } } else if (token is NameToken name) { CidFontNameParser.Parse(name, scanner, builder, isLenientParsing); } previousToken = token; } return(builder.Build()); }
public void Parse(NameToken nameToken, ITokenScanner scanner, CharacterMapBuilder builder, bool isLenientParsing) { switch (nameToken.Data) { case "WMode": { if (scanner.TryReadToken(out NumericToken numeric)) { builder.WMode = numeric.Int; } break; } case "CMapName": { if (scanner.TryReadToken(out NameToken name)) { builder.Name = name.Data; } break; } case "CMapVersion": { if (!scanner.MoveNext()) { break; } var next = scanner.CurrentToken; if (next is NumericToken number) { builder.Version = number.Data.ToString(NumberFormatInfo.InvariantInfo); } else if (next is StringToken stringToken) { builder.Version = stringToken.Data; } break; } case "CMapType": { if (scanner.TryReadToken(out NumericToken numeric)) { builder.Type = numeric.Int; } break; } case "Registry": { if (scanner.TryReadToken(out StringToken stringToken)) { builder.SystemInfoBuilder.Registry = stringToken.Data; } break; } case "Ordering": { if (scanner.TryReadToken(out StringToken stringToken)) { builder.SystemInfoBuilder.Ordering = stringToken.Data; } break; } case "Supplement": { if (scanner.TryReadToken(out NumericToken numericToken)) { builder.SystemInfoBuilder.Supplement = numericToken.Int; } break; } case "CIDSystemInfo": { if (scanner.TryReadToken(out DictionaryToken dictionary)) { builder.CharacterIdentifierSystemInfo = GetCharacterIdentifier(dictionary, isLenientParsing); } break; } } }
public void Parse(NumericToken numeric, ITokenScanner scanner, CharacterMapBuilder builder, bool isLenientParsing) { for (var i = 0; i < numeric.Int; i++) { if (!scanner.TryReadToken(out HexToken lowSourceCode)) { // TODO: message throw new InvalidOperationException(); } if (!scanner.TryReadToken(out HexToken highSourceCode)) { // TODO: message throw new InvalidOperationException(); } if (!scanner.MoveNext()) { // TODO: message throw new InvalidOperationException(); } List <byte> destinationBytes = null; ArrayToken destinationArray = null; switch (scanner.CurrentToken) { case ArrayToken arrayToken: destinationArray = arrayToken; break; case HexToken hexToken: destinationBytes = hexToken.Bytes.ToList(); break; case NumericToken _: throw new NotImplementedException("From the spec it seems this possible but the meaning is unclear..."); default: throw new InvalidOperationException(); } var done = false; var startCode = new List <byte>(lowSourceCode.Bytes); var endCode = highSourceCode.Bytes; int arrayIndex = 0; while (!done) { if (Compare(startCode, endCode) >= 0) { done = true; } builder.AddBaseFontCharacter(startCode, destinationBytes); Increment(startCode, startCode.Count - 1); if (destinationArray == null) { Increment(destinationBytes, destinationBytes.Count - 1); } else { arrayIndex++; if (arrayIndex < destinationArray.Data.Count) { destinationBytes = ((HexToken)destinationArray.Data[arrayIndex]).Bytes.ToList(); } } } } }