start porting the afm parser from pdf box, so many comments!

This commit is contained in:
Eliot Jones
2017-12-03 00:10:40 +00:00
parent bb07bd5cd4
commit b4cddbec7b
2 changed files with 409 additions and 0 deletions

View File

@@ -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);
}
}
}

View File

@@ -1,11 +1,337 @@
namespace UglyToad.Pdf.Fonts.Parser
{
using System;
using IO;
using Tokenization.Scanner;
using Tokenization.Tokens;
internal class AdobeFontMetricsParser : IAdobeFontMetricsParser
{
/// <summary>
/// This is a comment in a AFM file.
/// </summary>
public const string Comment = "Comment";
/// <summary>
/// This is the constant used in the AFM file to start a font metrics item.
/// </summary>
public const string StartFontMetrics = "StartFontMetrics";
/// <summary>
/// This is the constant used in the AFM file to end a font metrics item.
/// </summary>
public const string EndFontMetrics = "EndFontMetrics";
/// <summary>
/// The font name.
/// </summary>
public const string FontName = "FontName";
/// <summary>
/// The full name.
/// </summary>
public const string FullName = "FullName";
/// <summary>
/// The family name.
/// </summary>
public const string FamilyName = "FamilyName";
/// <summary>
/// The weight.
/// </summary>
public const string Weight = "Weight";
/// <summary>
/// The bounding box.
/// </summary>
public const string FontBbox = "FontBBox";
/// <summary>
/// The version of the font.
/// </summary>
public const string Version = "Version";
/// <summary>
/// The notice.
/// </summary>
public const string Notice = "Notice";
/// <summary>
/// The encoding scheme.
/// </summary>
public const string EncodingScheme = "EncodingScheme";
/// <summary>
/// The mapping scheme.
/// </summary>
public const string MappingScheme = "MappingScheme";
/// <summary>
/// The escape character.
/// </summary>
public const string EscChar = "EscChar";
/// <summary>
/// The character set.
/// </summary>
public const string CharacterSet = "CharacterSet";
/// <summary>
/// The characters attribute.
/// </summary>
public const string Characters = "Characters";
/// <summary>
/// Whether this is a base font.
/// </summary>
public const string IsBaseFont = "IsBaseFont";
/// <summary>
/// The V Vector attribute.
/// </summary>
public const string VVector = "VVector";
/// <summary>
/// Whether V is fixed.
/// </summary>
public const string IsFixedV = "IsFixedV";
/// <summary>
/// The cap height.
/// </summary>
public const string CapHeight = "CapHeight";
/// <summary>
/// The X height.
/// </summary>
public const string XHeight = "XHeight";
/// <summary>
/// The ascender attribute.
/// </summary>
public const string Ascender = "Ascender";
/// <summary>
/// The descender attribute.
/// </summary>
public const string Descender = "Descender";
/// <summary>
/// The underline position.
/// </summary>
public const string UnderlinePosition = "UnderlinePosition";
/// <summary>
/// The underline thickness.
/// </summary>
public const string UnderlineThickness = "UnderlineThickness";
/// <summary>
/// The italic angle.
/// </summary>
public const string ItalicAngle = "ItalicAngle";
/// <summary>
/// The character width.
/// </summary>
public const string CharWidth = "CharWidth";
/// <summary>
/// Determines if fixed pitch.
/// </summary>
public const string IsFixedPitch = "IsFixedPitch";
/// <summary>
/// The start of the character metrics.
/// </summary>
public const string StartCharMetrics = "StartCharMetrics";
/// <summary>
/// The end of the character metrics.
/// </summary>
public const string EndCharMetrics = "EndCharMetrics";
/// <summary>
/// The character metrics c value.
/// </summary>
public const string CharmetricsC = "C";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsCh = "CH";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsWx = "WX";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW0X = "W0X";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW1X = "W1X";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsWy = "WY";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW0Y = "W0Y";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW1Y = "W1Y";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW = "W";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW0 = "W0";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsW1 = "W1";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsVv = "VV";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsN = "N";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsB = "B";
/// <summary>
/// The character metrics value.
/// </summary>
public const string CharmetricsL = "L";
/// <summary>
/// The character metrics value.
/// </summary>
public const string StdHw = "StdHW";
/// <summary>
/// The character metrics value.
/// </summary>
public const string StdVw = "StdVW";
/// <summary>
/// This is the start of the track kern data.
/// </summary>
public const string StartTrackKern = "StartTrackKern";
/// <summary>
/// This is the end of the track kern data.
/// </summary>
public const string EndTrackKern = "EndTrackKern";
/// <summary>
/// This is the start of the kern data.
/// </summary>
public const string StartKernData = "StartKernData";
/// <summary>
/// This is the end of the kern data.
/// </summary>
public const string EndKernData = "EndKernData";
/// <summary>
/// This is the start of the kern pairs data.
/// </summary>
public const string StartKernPairs = "StartKernPairs";
/// <summary>
/// This is the end of the kern pairs data.
/// </summary>
public const string EndKernPairs = "EndKernPairs";
/// <summary>
/// This is the start of the kern pairs data.
/// </summary>
public const string StartKernPairs0 = "StartKernPairs0";
/// <summary>
/// This is the start of the kern pairs data.
/// </summary>
public const string StartKernPairs1 = "StartKernPairs1";
/// <summary>
/// This is the start of the composite data section.
/// </summary>
public const string StartComposites = "StartComposites";
/// <summary>
/// This is the end of the composite data section.
/// </summary>
public const string EndComposites = "EndComposites";
/// <summary>
/// This is a composite character.
/// </summary>
public const string Cc = "CC";
/// <summary>
/// This is a composite character part.
/// </summary>
public const string Pcc = "PCC";
/// <summary>
/// This is a kern pair.
/// </summary>
public const string KernPairKp = "KP";
/// <summary>
/// This is a kern pair.
/// </summary>
public const string KernPairKph = "KPH";
/// <summary>
/// This is a kern pair.
/// </summary>
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();
}
}