mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
start porting the afm parser from pdf box, so many comments!
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user