diff --git a/src/UglyToad.Pdf.Tests/Fonts/Parser/AdobeFontMetricsParserTests.cs b/src/UglyToad.Pdf.Tests/Fonts/Parser/AdobeFontMetricsParserTests.cs
new file mode 100644
index 00000000..edaeb7ae
--- /dev/null
+++ b/src/UglyToad.Pdf.Tests/Fonts/Parser/AdobeFontMetricsParserTests.cs
@@ -0,0 +1,83 @@
+namespace UglyToad.Pdf.Tests.Fonts.Parser
+{
+ using Pdf.Fonts.Parser;
+ using Xunit;
+
+ public class AdobeFontMetricsParserTests
+ {
+ private const string CourierAfmSnippet = @"
+StartFontMetrics 4.1
+
+Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+
+Comment Creation Date: Thu May 1 17:27:09 1997
+
+Comment UniqueID 43050
+
+Comment VMusage 39754 50779
+
+FontName Courier
+
+FullName Courier
+
+FamilyName Courier
+
+Weight Medium
+
+ItalicAngle 0
+
+IsFixedPitch true
+
+CharacterSet ExtendedRoman
+
+FontBBox -23 -250 715 805
+
+UnderlinePosition -100
+
+UnderlineThickness 50
+
+Version 003.000
+
+Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+
+EncodingScheme AdobeStandardEncoding
+
+CapHeight 562
+
+XHeight 426
+
+Ascender 629
+
+Descender -157
+
+StdHW 51
+
+StdVW 51
+
+StartCharMetrics 315
+
+C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
+
+C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
+
+C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
+
+C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ;
+
+C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ;
+
+C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ;";
+
+ private readonly AdobeFontMetricsParser parser = new AdobeFontMetricsParser();
+
+ [Fact]
+ public void CanParseAfmFile()
+ {
+ var input = StringBytesTestConverter.Convert(CourierAfmSnippet, false);
+
+ var metrics = parser.Parse(input.Bytes, false);
+
+ Assert.NotNull(metrics);
+ }
+ }
+}
diff --git a/src/UglyToad.Pdf/Fonts/Parser/AdobeFontMetricsParser.cs b/src/UglyToad.Pdf/Fonts/Parser/AdobeFontMetricsParser.cs
index 1d095051..c38a4563 100644
--- a/src/UglyToad.Pdf/Fonts/Parser/AdobeFontMetricsParser.cs
+++ b/src/UglyToad.Pdf/Fonts/Parser/AdobeFontMetricsParser.cs
@@ -1,11 +1,337 @@
namespace UglyToad.Pdf.Fonts.Parser
{
+ using System;
using IO;
+ using Tokenization.Scanner;
+ using Tokenization.Tokens;
internal class AdobeFontMetricsParser : IAdobeFontMetricsParser
{
+ ///
+ /// This is a comment in a AFM file.
+ ///
+ public const string Comment = "Comment";
+
+ ///
+ /// This is the constant used in the AFM file to start a font metrics item.
+ ///
+ public const string StartFontMetrics = "StartFontMetrics";
+
+ ///
+ /// This is the constant used in the AFM file to end a font metrics item.
+ ///
+ public const string EndFontMetrics = "EndFontMetrics";
+
+ ///
+ /// The font name.
+ ///
+ public const string FontName = "FontName";
+
+ ///
+ /// The full name.
+ ///
+ public const string FullName = "FullName";
+
+ ///
+ /// The family name.
+ ///
+ public const string FamilyName = "FamilyName";
+
+ ///
+ /// The weight.
+ ///
+ public const string Weight = "Weight";
+
+ ///
+ /// The bounding box.
+ ///
+ public const string FontBbox = "FontBBox";
+
+ ///
+ /// The version of the font.
+ ///
+ public const string Version = "Version";
+
+ ///
+ /// The notice.
+ ///
+ public const string Notice = "Notice";
+
+ ///
+ /// The encoding scheme.
+ ///
+ public const string EncodingScheme = "EncodingScheme";
+
+ ///
+ /// The mapping scheme.
+ ///
+ public const string MappingScheme = "MappingScheme";
+
+ ///
+ /// The escape character.
+ ///
+ public const string EscChar = "EscChar";
+
+ ///
+ /// The character set.
+ ///
+ public const string CharacterSet = "CharacterSet";
+
+ ///
+ /// The characters attribute.
+ ///
+ public const string Characters = "Characters";
+
+ ///
+ /// Whether this is a base font.
+ ///
+ public const string IsBaseFont = "IsBaseFont";
+
+ ///
+ /// The V Vector attribute.
+ ///
+ public const string VVector = "VVector";
+
+ ///
+ /// Whether V is fixed.
+ ///
+ public const string IsFixedV = "IsFixedV";
+
+ ///
+ /// The cap height.
+ ///
+ public const string CapHeight = "CapHeight";
+
+ ///
+ /// The X height.
+ ///
+ public const string XHeight = "XHeight";
+
+ ///
+ /// The ascender attribute.
+ ///
+ public const string Ascender = "Ascender";
+
+ ///
+ /// The descender attribute.
+ ///
+ public const string Descender = "Descender";
+
+ ///
+ /// The underline position.
+ ///
+ public const string UnderlinePosition = "UnderlinePosition";
+
+ ///
+ /// The underline thickness.
+ ///
+ public const string UnderlineThickness = "UnderlineThickness";
+
+ ///
+ /// The italic angle.
+ ///
+ public const string ItalicAngle = "ItalicAngle";
+
+ ///
+ /// The character width.
+ ///
+ public const string CharWidth = "CharWidth";
+
+ ///
+ /// Determines if fixed pitch.
+ ///
+ public const string IsFixedPitch = "IsFixedPitch";
+
+ ///
+ /// The start of the character metrics.
+ ///
+ public const string StartCharMetrics = "StartCharMetrics";
+
+ ///
+ /// The end of the character metrics.
+ ///
+ public const string EndCharMetrics = "EndCharMetrics";
+
+ ///
+ /// The character metrics c value.
+ ///
+ public const string CharmetricsC = "C";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsCh = "CH";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsWx = "WX";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW0X = "W0X";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW1X = "W1X";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsWy = "WY";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW0Y = "W0Y";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW1Y = "W1Y";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW = "W";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW0 = "W0";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsW1 = "W1";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsVv = "VV";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsN = "N";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsB = "B";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string CharmetricsL = "L";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string StdHw = "StdHW";
+
+ ///
+ /// The character metrics value.
+ ///
+ public const string StdVw = "StdVW";
+
+ ///
+ /// This is the start of the track kern data.
+ ///
+ public const string StartTrackKern = "StartTrackKern";
+
+ ///
+ /// This is the end of the track kern data.
+ ///
+ public const string EndTrackKern = "EndTrackKern";
+
+ ///
+ /// This is the start of the kern data.
+ ///
+ public const string StartKernData = "StartKernData";
+
+ ///
+ /// This is the end of the kern data.
+ ///
+ public const string EndKernData = "EndKernData";
+
+ ///
+ /// This is the start of the kern pairs data.
+ ///
+ public const string StartKernPairs = "StartKernPairs";
+
+ ///
+ /// This is the end of the kern pairs data.
+ ///
+ public const string EndKernPairs = "EndKernPairs";
+
+ ///
+ /// This is the start of the kern pairs data.
+ ///
+ public const string StartKernPairs0 = "StartKernPairs0";
+
+ ///
+ /// This is the start of the kern pairs data.
+ ///
+ public const string StartKernPairs1 = "StartKernPairs1";
+
+ ///
+ /// This is the start of the composite data section.
+ ///
+ public const string StartComposites = "StartComposites";
+
+ ///
+ /// This is the end of the composite data section.
+ ///
+ public const string EndComposites = "EndComposites";
+
+ ///
+ /// This is a composite character.
+ ///
+ public const string Cc = "CC";
+
+ ///
+ /// This is a composite character part.
+ ///
+ public const string Pcc = "PCC";
+
+ ///
+ /// This is a kern pair.
+ ///
+ public const string KernPairKp = "KP";
+
+ ///
+ /// This is a kern pair.
+ ///
+ public const string KernPairKph = "KPH";
+
+ ///
+ /// This is a kern pair.
+ ///
+ public const string KernPairKpx = "KPX";
+
+ public const string KernPairKpy = "KPY";
+
public FontMetrics Parse(IInputBytes bytes, bool useReducedDataSet)
{
+ var tokenizer = new CoreTokenScanner(bytes);
+
+ tokenizer.MoveNext();
+
+ var current = tokenizer.CurrentToken;
+
+ if (!(current is OperatorToken operatorToken) || operatorToken.Data != StartFontMetrics)
+ {
+ throw new InvalidOperationException($"The font metrics file started with {current} rather than {StartFontMetrics}.");
+ }
+
+ while (tokenizer.MoveNext())
+ {
+
+ }
+
return new FontMetrics();
}
}