You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2020/11/11 07:00:50 UTC

svn commit: r1883299 [1/2] - in /pdfbox/trunk/fontbox/src: main/java/org/apache/fontbox/afm/ test/java/org/apache/fontbox/afm/ test/resources/afm/

Author: lehmi
Date: Wed Nov 11 07:00:50 2020
New Revision: 1883299

URL: http://svn.apache.org/viewvc?rev=1883299&view=rev
Log:
PDFBOX-5001: unify boolean setter, DRY refactoring, add more tests

Added:
    pdfbox/trunk/fontbox/src/test/resources/afm/
    pdfbox/trunk/fontbox/src/test/resources/afm/Helvetica.afm
    pdfbox/trunk/fontbox/src/test/resources/afm/MalformedFloat.afm
    pdfbox/trunk/fontbox/src/test/resources/afm/MalformedInteger.afm
    pdfbox/trunk/fontbox/src/test/resources/afm/NoEndFontMetrics.afm
Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/AFMParser.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/FontMetrics.java
    pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/AFMParserTest.java
    pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/FontMetricsTest.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/AFMParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/AFMParser.java?rev=1883299&r1=1883298&r2=1883299&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/AFMParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/AFMParser.java Wed Nov 11 07:00:50 2020
@@ -333,12 +333,7 @@ public class AFMParser
      */
     private FontMetrics parseFontMetric(boolean reducedDataset) throws IOException
     {
-        String startFontMetrics = readString();
-        if( !START_FONT_METRICS.equals( startFontMetrics ) )
-        {
-            throw new IOException( "Error: The AFM file should start with " + START_FONT_METRICS +
-                                   " and not '" + startFontMetrics + "'" );
-        }
+        readCommand(START_FONT_METRICS);
         FontMetrics fontMetrics = new FontMetrics();
         fontMetrics.setAFMVersion( readFloat() );
         String nextCommand;
@@ -442,16 +437,16 @@ public class AFMParser
             case START_CHAR_METRICS:
                 charMetricsRead = parseCharMetrics(fontMetrics);
                 break;
-            case START_COMPOSITES:
+            case START_KERN_DATA:
                 if( !reducedDataset)
                 {
-                    parseComposites(fontMetrics);
+                    parseKernData(fontMetrics);
                 }
                 break;
-            case START_KERN_DATA:
+            case START_COMPOSITES:
                 if( !reducedDataset)
                 {
-                    parseKernData( fontMetrics );
+                    parseComposites(fontMetrics);
                 }
                 break;
             default:
@@ -485,12 +480,7 @@ public class AFMParser
                     fontMetrics.addTrackKern(new TrackKern(readInt(), readFloat(), readFloat(),
                             readFloat(), readFloat()));
                 }
-                String endTrackKern = readString();
-                if (!endTrackKern.equals(END_TRACK_KERN))
-                {
-                    throw new IOException( "Error: Expected '" + END_TRACK_KERN + "' actual '" +
-                            endTrackKern + "'");
-                }
+                readCommand(END_TRACK_KERN);
                 break;
             case START_KERN_PAIRS:
                 parseKernPairs(fontMetrics);
@@ -514,12 +504,7 @@ public class AFMParser
         {
             fontMetrics.addKernPair(parseKernPair());
         }
-        String endKernPairs = readString();
-        if (!endKernPairs.equals(END_KERN_PAIRS))
-        {
-            throw new IOException(
-                    "Error: Expected '" + END_KERN_PAIRS + "' actual '" + endKernPairs + "'");
-        }
+        readCommand(END_KERN_PAIRS);
     }
 
     private void parseKernPairs0(FontMetrics fontMetrics) throws IOException
@@ -529,12 +514,7 @@ public class AFMParser
         {
             fontMetrics.addKernPair0(parseKernPair());
         }
-        String endKernPairs = readString();
-        if (!endKernPairs.equals(END_KERN_PAIRS))
-        {
-            throw new IOException(
-                    "Error: Expected '" + END_KERN_PAIRS + "' actual '" + endKernPairs + "'");
-        }
+        readCommand(END_KERN_PAIRS);
     }
 
     private void parseKernPairs1(FontMetrics fontMetrics) throws IOException
@@ -544,12 +524,7 @@ public class AFMParser
         {
             fontMetrics.addKernPair1(parseKernPair());
         }
-        String endKernPairs = readString();
-        if (!endKernPairs.equals(END_KERN_PAIRS))
-        {
-            throw new IOException(
-                    "Error: Expected '" + END_KERN_PAIRS + "' actual '" + endKernPairs + "'");
-        }
+        readCommand(END_KERN_PAIRS);
     }
 
     /**
@@ -606,14 +581,7 @@ public class AFMParser
         for( int i=0; i<hexString.length(); i+=2 )
         {
             String hex = Character.toString(hexString.charAt(i)) + hexString.charAt(i + 1);
-            try
-            {
-                data[ i / 2 ] = (byte)Integer.parseInt( hex, BITS_IN_HEX );
-            }
-            catch( NumberFormatException e )
-            {
-                throw new IOException( "Error parsing AFM file:" + e );
-            }
+            data[i / 2] = (byte) parseInt(hex, BITS_IN_HEX);
         }
         return new String( data, StandardCharsets.ISO_8859_1 );
     }
@@ -625,12 +593,7 @@ public class AFMParser
         {
             fontMetrics.addComposite(parseComposite());
         }
-        String endComposites = readString();
-        if (!endComposites.equals(END_COMPOSITES))
-        {
-            throw new IOException(
-                    "Error: Expected '" + END_COMPOSITES + "' actual '" + endComposites + "'");
-        }
+        readCommand(END_COMPOSITES);
     }
 
     /**
@@ -654,15 +617,7 @@ public class AFMParser
         String name = tokenizer.nextToken();
         Composite composite = new Composite(name);
 
-        int partCount;
-        try
-        {
-            partCount = Integer.parseInt( tokenizer.nextToken() );
-        }
-        catch( NumberFormatException e )
-        {
-            throw new IOException( "Error parsing AFM document:" + e );
-        }
+        int partCount = parseInt(tokenizer.nextToken());
         for( int i=0; i<partCount; i++ )
         {
             String pcc = tokenizer.nextToken();
@@ -671,16 +626,9 @@ public class AFMParser
                 throw new IOException( "Expected '" + PCC + "' actual='" + pcc + "'" );
             }
             String partName = tokenizer.nextToken();
-            try
-            {
-                int x = Integer.parseInt( tokenizer.nextToken() );
-                int y = Integer.parseInt( tokenizer.nextToken() );
-                composite.addPart(new CompositePart(partName, x, y));
-            }
-            catch( NumberFormatException e )
-            {
-                throw new IOException( "Error parsing AFM document:" + e );
-            }
+            int x = parseInt(tokenizer.nextToken());
+            int y = parseInt(tokenizer.nextToken());
+            composite.addPart(new CompositePart(partName, x, y));
         }
         return composite;
     }
@@ -692,12 +640,7 @@ public class AFMParser
         {
             fontMetrics.addCharMetric(parseCharMetric());
         }
-        String endCharMetrics = readString();
-        if (!endCharMetrics.equals(END_CHAR_METRICS))
-        {
-            throw new IOException(
-                    "Error: Expected '" + END_CHAR_METRICS + "' actual '" + endCharMetrics + "'");
-        }
+        readCommand(END_CHAR_METRICS);
         return true;
     }
 
@@ -713,105 +656,98 @@ public class AFMParser
         CharMetric charMetric = new CharMetric();
         String metrics = readLine();
         StringTokenizer metricsTokenizer = new StringTokenizer( metrics );
-        try
+        while (metricsTokenizer.hasMoreTokens())
         {
-            while( metricsTokenizer.hasMoreTokens() )
+            String nextCommand = metricsTokenizer.nextToken();
+            switch (nextCommand)
             {
-                String nextCommand = metricsTokenizer.nextToken();
-                switch(nextCommand)
-                {
-                case CHARMETRICS_C:
-                    String charCodeC = metricsTokenizer.nextToken();
-                    charMetric.setCharacterCode(Integer.parseInt(charCodeC));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_CH:
-                    //Is the hex string <FF> or FF, the spec is a little
-                    //unclear, wait and see if it breaks anything.
-                    String charCodeCH = metricsTokenizer.nextToken();
-                    charMetric.setCharacterCode(Integer.parseInt(charCodeCH, BITS_IN_HEX));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_WX:
-                    charMetric.setWx(Float.parseFloat(metricsTokenizer.nextToken()));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W0X:
-                    charMetric.setW0x(Float.parseFloat(metricsTokenizer.nextToken()));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W1X:
-                    charMetric.setW1x(Float.parseFloat(metricsTokenizer.nextToken()));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_WY:
-                    charMetric.setWy(Float.parseFloat(metricsTokenizer.nextToken()));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W0Y:
-                    charMetric.setW0y(Float.parseFloat(metricsTokenizer.nextToken()));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W1Y:
-                    charMetric.setW1y(Float.parseFloat(metricsTokenizer.nextToken()));
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W:
-                    float[] w = new float[2];
-                    w[0] = Float.parseFloat(metricsTokenizer.nextToken());
-                    w[1] = Float.parseFloat(metricsTokenizer.nextToken());
-                    charMetric.setW( w );
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W0:
-                    float[] w0 = new float[2];
-                    w0[0] = Float.parseFloat(metricsTokenizer.nextToken());
-                    w0[1] = Float.parseFloat(metricsTokenizer.nextToken());
-                    charMetric.setW0( w0 );
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_W1:
-                    float[] w1 = new float[2];
-                    w1[0] = Float.parseFloat(metricsTokenizer.nextToken());
-                    w1[1] = Float.parseFloat(metricsTokenizer.nextToken());
-                    charMetric.setW1( w1 );
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_VV:
-                    float[] vv = new float[2];
-                    vv[0] = Float.parseFloat(metricsTokenizer.nextToken());
-                    vv[1] = Float.parseFloat(metricsTokenizer.nextToken());
-                    charMetric.setVv( vv );
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_N:
-                    charMetric.setName(metricsTokenizer.nextToken());
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_B:
-                    BoundingBox box = new BoundingBox();
-                    box.setLowerLeftX(Float.parseFloat(metricsTokenizer.nextToken()));
-                    box.setLowerLeftY(Float.parseFloat(metricsTokenizer.nextToken()));
-                    box.setUpperRightX(Float.parseFloat(metricsTokenizer.nextToken()));
-                    box.setUpperRightY(Float.parseFloat(metricsTokenizer.nextToken()));
-                    charMetric.setBoundingBox( box );
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                case CHARMETRICS_L:
-                    Ligature lig = new Ligature(metricsTokenizer.nextToken(),
-                            metricsTokenizer.nextToken());
-                    charMetric.addLigature( lig );
-                    verifySemicolon( metricsTokenizer );
-                    break;
-                default:
-                    throw new IOException( "Unknown CharMetrics command '" + nextCommand + "'" );
-                }
+            case CHARMETRICS_C:
+                String charCodeC = metricsTokenizer.nextToken();
+                charMetric.setCharacterCode(parseInt(charCodeC));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_CH:
+                // Is the hex string <FF> or FF, the spec is a little
+                // unclear, wait and see if it breaks anything.
+                String charCodeCH = metricsTokenizer.nextToken();
+                charMetric.setCharacterCode(parseInt(charCodeCH, BITS_IN_HEX));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_WX:
+                charMetric.setWx(parseFloat(metricsTokenizer.nextToken()));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W0X:
+                charMetric.setW0x(parseFloat(metricsTokenizer.nextToken()));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W1X:
+                charMetric.setW1x(parseFloat(metricsTokenizer.nextToken()));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_WY:
+                charMetric.setWy(parseFloat(metricsTokenizer.nextToken()));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W0Y:
+                charMetric.setW0y(parseFloat(metricsTokenizer.nextToken()));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W1Y:
+                charMetric.setW1y(parseFloat(metricsTokenizer.nextToken()));
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W:
+                float[] w = new float[2];
+                w[0] = parseFloat(metricsTokenizer.nextToken());
+                w[1] = parseFloat(metricsTokenizer.nextToken());
+                charMetric.setW(w);
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W0:
+                float[] w0 = new float[2];
+                w0[0] = parseFloat(metricsTokenizer.nextToken());
+                w0[1] = parseFloat(metricsTokenizer.nextToken());
+                charMetric.setW0(w0);
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_W1:
+                float[] w1 = new float[2];
+                w1[0] = parseFloat(metricsTokenizer.nextToken());
+                w1[1] = parseFloat(metricsTokenizer.nextToken());
+                charMetric.setW1(w1);
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_VV:
+                float[] vv = new float[2];
+                vv[0] = parseFloat(metricsTokenizer.nextToken());
+                vv[1] = parseFloat(metricsTokenizer.nextToken());
+                charMetric.setVv(vv);
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_N:
+                charMetric.setName(metricsTokenizer.nextToken());
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_B:
+                BoundingBox box = new BoundingBox();
+                box.setLowerLeftX(parseFloat(metricsTokenizer.nextToken()));
+                box.setLowerLeftY(parseFloat(metricsTokenizer.nextToken()));
+                box.setUpperRightX(parseFloat(metricsTokenizer.nextToken()));
+                box.setUpperRightY(parseFloat(metricsTokenizer.nextToken()));
+                charMetric.setBoundingBox(box);
+                verifySemicolon(metricsTokenizer);
+                break;
+            case CHARMETRICS_L:
+                Ligature lig = new Ligature(metricsTokenizer.nextToken(),
+                        metricsTokenizer.nextToken());
+                charMetric.addLigature(lig);
+                verifySemicolon(metricsTokenizer);
+                break;
+            default:
+                throw new IOException("Unknown CharMetrics command '" + nextCommand + "'");
             }
         }
-        catch( NumberFormatException e )
-        {
-            throw new IOException( "Error: Corrupt AFM document:"  + e );
-        }
         return charMetric;
     }
 
@@ -856,13 +792,23 @@ public class AFMParser
      */
     private int readInt() throws IOException
     {
+        return parseInt(readString(), 10);
+    }
+
+    private int parseInt(String intValue) throws IOException
+    {
+        return parseInt(intValue, 10);
+    }
+
+    private int parseInt(String intValue, int radix) throws IOException
+    {
         try
         {
-            return Integer.parseInt(readString());
+            return Integer.parseInt(intValue, radix);
         }
-        catch( NumberFormatException e )
+        catch (NumberFormatException e)
         {
-            throw new IOException( "Error parsing AFM document:" + e );
+            throw new IOException("Error parsing AFM document:" + e, e);
         }
     }
 
@@ -873,7 +819,19 @@ public class AFMParser
      */
     private float readFloat() throws IOException
     {
-        return Float.parseFloat(readString());
+        return parseFloat(readString());
+    }
+
+    private float parseFloat(String floatValue) throws IOException
+    {
+        try
+        {
+            return Float.parseFloat(floatValue);
+        }
+        catch (NumberFormatException e)
+        {
+            throw new IOException("Error parsing AFM document:" + e, e);
+        }
     }
 
     /**
@@ -933,6 +891,22 @@ public class AFMParser
     }
 
     /**
+     * Read the next string. Throw an exception if it differs from the expected command.
+     * 
+     * @param expectedCommand the expected command
+     * @throws IOException IF the read stgring differs from the expected command
+     */
+    private void readCommand(String expectedCommand) throws IOException
+    {
+        String command = readString();
+        if (!expectedCommand.equals(command))
+        {
+            throw new IOException(
+                    "Error: Expected '" + expectedCommand + "' actual '" + command + "'");
+        }
+    }
+
+    /**
      * This will determine if the byte is a whitespace character or not.
      *
      * @param character The character to test for whitespace.

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/FontMetrics.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/FontMetrics.java?rev=1883299&r1=1883298&r2=1883299&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/FontMetrics.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/afm/FontMetrics.java Wed Nov 11 07:00:50 2020
@@ -44,13 +44,13 @@ public class FontMetrics
     private String fontVersion;
     private String notice;
     private String encodingScheme;
-    private int mappingScheme;
-    private int escChar;
+    private int mappingScheme = 0;
+    private int escChar = 0;
     private String characterSet;
-    private int characters;
-    private boolean isBaseFont;
+    private int characters = 0;
+    private boolean isBaseFont = true;
     private float[] vVector;
-    private boolean isFixedV;
+    private Boolean isFixedV = null;
     private float capHeight;
     private float xHeight;
     private float ascender;
@@ -437,7 +437,7 @@ public class FontMetrics
      *
      * @return Value of property isBaseFont.
      */
-    public boolean isBaseFont()
+    public boolean getIsBaseFont()
     {
         return isBaseFont;
     }
@@ -477,9 +477,10 @@ public class FontMetrics
      *
      * @return Value of property isFixedV.
      */
-    public boolean isFixedV()
+    public boolean getIsFixedV()
     {
-        return isFixedV;
+        // if not set the default value depends on the existence of vVector
+        return isFixedV == null ? vVector != null : isFixedV;
     }
 
     /**
@@ -677,7 +678,7 @@ public class FontMetrics
      *
      * @return Value of property isFixedPitch.
      */
-    public boolean isFixedPitch()
+    public boolean getIsFixedPitch()
     {
         return isFixedPitch;
     }

Modified: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/AFMParserTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/AFMParserTest.java?rev=1883299&r1=1883298&r2=1883299&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/AFMParserTest.java (original)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/AFMParserTest.java Wed Nov 11 07:00:50 2020
@@ -17,10 +17,21 @@
 
 package org.apache.fontbox.afm;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import org.junit.Assert;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.fontbox.util.BoundingBox;
 import org.junit.Test;
 
 /**
@@ -30,15 +41,285 @@ import org.junit.Test;
 public class AFMParserTest
 {
     @Test
-    public void testEof() throws IOException
+    public void testStartFontMetrics() throws IOException
+    {
+        try
+        {
+            new AFMParser(new ByteArrayInputStream("huhu".getBytes(StandardCharsets.US_ASCII)))
+                    .parse();
+            fail("The AFMParser should have thrown an IOException because of a missing "
+                    + AFMParser.START_FONT_METRICS);
+        }
+        catch (IOException e)
+        {
+            // expected exception
+        }
+    }
+
+    @Test
+    public void testEndFontMetrics() throws IOException
+    {
+        AFMParser parser = new AFMParser(
+                new FileInputStream("src/test/resources/afm/NoEndFontMetrics.afm"));
+        try
+        {
+            parser.parse();
+            fail("The AFMParser should have thrown an IOException because of a missing "
+                    + AFMParser.END_FONT_METRICS);
+        }
+        catch (IOException e)
+        {
+            assertTrue(e.getMessage().contains("Unknown AFM key"));
+        }
+    }
+
+    @Test
+    public void testMalformedFloat() throws IOException
     {
+        AFMParser parser = new AFMParser(
+                new FileInputStream("src/test/resources/afm/MalformedFloat.afm"));
         try
         {
-            new AFMParser(new ByteArrayInputStream("huhu".getBytes(StandardCharsets.US_ASCII))).parse();
+            parser.parse();
+            fail("The AFMParser should have thrown an IOException because of a malformed float value");
         }
-        catch (IOException ex)
+        catch (IOException e)
         {
-            Assert.assertEquals("Error: The AFM file should start with StartFontMetrics and not 'huhu'", ex.getMessage());
+            assertTrue(e.getCause() instanceof NumberFormatException);
+            assertTrue(e.getMessage().contains("4,1ab"));
         }
     }
+
+    @Test
+    public void testMalformedInteger() throws IOException
+    {
+        AFMParser parser = new AFMParser(
+                new FileInputStream("src/test/resources/afm/MalformedInteger.afm"));
+        try
+        {
+            parser.parse();
+            fail("The AFMParser should have thrown an IOException because of a malformed int value");
+        }
+        catch (IOException e)
+        {
+            assertTrue(e.getCause() instanceof NumberFormatException);
+            assertTrue(e.getMessage().contains("3.4"));
+        }
+    }
+
+    @Test
+    public void testAFMParser() throws IOException
+    {
+        AFMParser parser = new AFMParser(
+                new FileInputStream("src/test/resources/afm/Helvetica.afm"));
+        FontMetrics fontMetrics = parser.parse();
+
+        assertEquals(4.1f, fontMetrics.getAFMVersion(), 0f);
+        assertEquals("Helvetica", fontMetrics.getFontName());
+        assertEquals("Helvetica", fontMetrics.getFullName());
+        assertEquals("Helvetica", fontMetrics.getFamilyName());
+        assertEquals("Medium", fontMetrics.getWeight());
+        BoundingBox fontBBox = fontMetrics.getFontBBox();
+        assertNotNull(fontBBox);
+        assertEquals(-166f, fontBBox.getLowerLeftX(),0f);
+        assertEquals(-225f, fontBBox.getLowerLeftY(), 0f);
+        assertEquals(1000f, fontBBox.getUpperRightX(), 0f);
+        assertEquals(931f, fontBBox.getUpperRightY(), 0f);
+        assertEquals("002.000", fontMetrics.getFontVersion());
+        assertEquals(
+                "Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.",
+                fontMetrics.getNotice());
+        assertEquals("AdobeStandardEncoding", fontMetrics.getEncodingScheme());
+        assertEquals(0, fontMetrics.getMappingScheme());
+        assertEquals(0, fontMetrics.getEscChar());
+        assertEquals("ExtendedRoman", fontMetrics.getCharacterSet());
+        assertEquals(0, fontMetrics.getCharacters());
+        assertTrue(fontMetrics.getIsBaseFont());
+        assertNull(fontMetrics.getVVector());
+        assertFalse(fontMetrics.getIsFixedV());
+        assertEquals(718f, fontMetrics.getCapHeight(), 0f);
+        assertEquals(523f, fontMetrics.getXHeight(), 0f);
+        assertEquals(718f, fontMetrics.getAscender(), 0f);
+        assertEquals(-207f, fontMetrics.getDescender(), 0f);
+        assertEquals(76f, fontMetrics.getStandardHorizontalWidth(), 0f);
+        assertEquals(88f, fontMetrics.getStandardVerticalWidth(), 0f);
+        List<String> comments = fontMetrics.getComments();
+        assertEquals(4, comments.size());
+        assertEquals(
+                "Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated.  All Rights Reserved.",
+                comments.get(0));
+        assertEquals("UniqueID 43054", comments.get(2));
+        assertEquals(-100f, fontMetrics.getUnderlinePosition(), 0f);
+        assertEquals(50f, fontMetrics.getUnderlineThickness(), 0f);
+        assertEquals(0f, fontMetrics.getItalicAngle(), 0f);
+        assertNull(fontMetrics.getCharWidth());
+        assertFalse(fontMetrics.getIsFixedPitch());
+        // char metrics
+        List<CharMetric> charMetrics = fontMetrics.getCharMetrics();
+        assertEquals(315, charMetrics.size());
+        // check "space" metrics
+        Optional<CharMetric> space = charMetrics.stream()//
+                .filter(c -> "space".equals(c.getName())).findFirst();
+        assertTrue(space.isPresent());
+        CharMetric spaceCharMetric = space.get();
+        assertEquals(278f, spaceCharMetric.getWx(), 0f);
+        assertEquals(32, spaceCharMetric.getCharacterCode());
+        BoundingBox spaceBBox = spaceCharMetric.getBoundingBox();
+        assertNotNull(spaceBBox);
+        assertEquals(0, spaceBBox.getLowerLeftX(), 0f);
+        assertEquals(0, spaceBBox.getLowerLeftY(), 0f);
+        assertEquals(0, spaceBBox.getUpperRightX(), 0f);
+        assertEquals(0, spaceBBox.getUpperRightY(), 0f);
+        assertTrue(spaceCharMetric.getLigatures().isEmpty());
+        assertNull(spaceCharMetric.getW());
+        assertNull(spaceCharMetric.getW0());
+        assertNull(spaceCharMetric.getW1());
+        assertNull(spaceCharMetric.getVv());
+        // check "ring" metrics
+        Optional<CharMetric> ring = charMetrics.stream()//
+                .filter(c -> "ring".equals(c.getName())).findFirst();
+        assertTrue(ring.isPresent());
+        CharMetric ringCharMetric = ring.get();
+        assertEquals(333f, ringCharMetric.getWx(), 0f);
+        assertEquals(202, ringCharMetric.getCharacterCode());
+        BoundingBox ringBBox = ringCharMetric.getBoundingBox();
+        assertNotNull(ringBBox);
+        assertEquals(75, ringBBox.getLowerLeftX(), 0f);
+        assertEquals(572, ringBBox.getLowerLeftY(), 0f);
+        assertEquals(259, ringBBox.getUpperRightX(), 0f);
+        assertEquals(756, ringBBox.getUpperRightY(), 0f);
+        assertTrue(ringCharMetric.getLigatures().isEmpty());
+        assertNull(ringCharMetric.getW());
+        assertNull(ringCharMetric.getW0());
+        assertNull(ringCharMetric.getW1());
+        assertNull(ringCharMetric.getVv());
+        // KernPairs
+        List<KernPair> kernPairs = fontMetrics.getKernPairs();
+        assertEquals(2705, kernPairs.size());
+        // check "KPX A Ucircumflex -50"
+        Optional<KernPair> A_Ucircumflex = kernPairs.stream() //
+                .filter(k -> "A".equals(k.getFirstKernCharacter())) //
+                .filter(k -> "Ucircumflex".equals(k.getSecondKernCharacter())) //
+                .findFirst();
+        assertTrue(A_Ucircumflex.isPresent());
+        assertEquals(-50f, A_Ucircumflex.get().getX(), 0f);
+        assertEquals(0f, A_Ucircumflex.get().getY(), 0f);
+        // check "KPX W agrave -40"
+        Optional<KernPair> W_agrave = kernPairs.stream() //
+                .filter(k -> "W".equals(k.getFirstKernCharacter())) //
+                .filter(k -> "agrave".equals(k.getSecondKernCharacter())) //
+                .findFirst();
+        assertTrue(W_agrave.isPresent());
+        assertEquals(-40f, W_agrave.get().getX(), 0f);
+        assertEquals(0f, W_agrave.get().getY(), 0f);
+        // KernPairs0
+        List<KernPair> kernPairs0 = fontMetrics.getKernPairs0();
+        assertTrue(kernPairs0.isEmpty());
+        // KernPairs1
+        List<KernPair> kernPairs1 = fontMetrics.getKernPairs1();
+        assertTrue(kernPairs1.isEmpty());
+        // composite data
+        List<Composite> composites = fontMetrics.getComposites();
+        assertTrue(composites.isEmpty());
+    }
+
+    @Test
+    public void testAFMParserReducedDataset() throws IOException
+    {
+        AFMParser parser = new AFMParser(
+                new FileInputStream("src/test/resources/afm/Helvetica.afm"));
+        FontMetrics fontMetrics = parser.parse(true);
+
+        assertEquals(4.1f, fontMetrics.getAFMVersion(), 0f);
+        assertEquals("Helvetica", fontMetrics.getFontName());
+        assertEquals("Helvetica", fontMetrics.getFullName());
+        assertEquals("Helvetica", fontMetrics.getFamilyName());
+        assertEquals("Medium", fontMetrics.getWeight());
+        BoundingBox fontBBox = fontMetrics.getFontBBox();
+        assertNotNull(fontBBox);
+        assertEquals(-166f, fontBBox.getLowerLeftX(), 0f);
+        assertEquals(-225f, fontBBox.getLowerLeftY(), 0f);
+        assertEquals(1000f, fontBBox.getUpperRightX(), 0f);
+        assertEquals(931f, fontBBox.getUpperRightY(), 0f);
+        assertEquals("002.000", fontMetrics.getFontVersion());
+        assertEquals(
+                "Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated.  All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.",
+                fontMetrics.getNotice());
+        assertEquals("AdobeStandardEncoding", fontMetrics.getEncodingScheme());
+        assertEquals(0, fontMetrics.getMappingScheme());
+        assertEquals(0, fontMetrics.getEscChar());
+        assertEquals("ExtendedRoman", fontMetrics.getCharacterSet());
+        assertEquals(0, fontMetrics.getCharacters());
+        assertTrue(fontMetrics.getIsBaseFont());
+        assertNull(fontMetrics.getVVector());
+        assertFalse(fontMetrics.getIsFixedV());
+        assertEquals(718f, fontMetrics.getCapHeight(), 0f);
+        assertEquals(523f, fontMetrics.getXHeight(), 0f);
+        assertEquals(718f, fontMetrics.getAscender(), 0f);
+        assertEquals(-207f, fontMetrics.getDescender(), 0f);
+        assertEquals(76f, fontMetrics.getStandardHorizontalWidth(), 0f);
+        assertEquals(88f, fontMetrics.getStandardVerticalWidth(), 0f);
+        List<String> comments = fontMetrics.getComments();
+        assertEquals(4, comments.size());
+        assertEquals(
+                "Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated.  All Rights Reserved.",
+                comments.get(0));
+        assertEquals("UniqueID 43054", comments.get(2));
+        assertEquals(-100f, fontMetrics.getUnderlinePosition(), 0f);
+        assertEquals(50f, fontMetrics.getUnderlineThickness(), 0f);
+        assertEquals(0f, fontMetrics.getItalicAngle(), 0f);
+        assertNull(fontMetrics.getCharWidth());
+        assertFalse(fontMetrics.getIsFixedPitch());
+        // char metrics
+        List<CharMetric> charMetrics = fontMetrics.getCharMetrics();
+        assertEquals(315, charMetrics.size());
+        // check "space" metrics
+        Optional<CharMetric> space = charMetrics.stream()//
+                .filter(c -> "space".equals(c.getName())).findFirst();
+        assertTrue(space.isPresent());
+        CharMetric spaceCharMetric = space.get();
+        assertEquals(278f, spaceCharMetric.getWx(), 0f);
+        assertEquals(32, spaceCharMetric.getCharacterCode());
+        BoundingBox spaceBBox = spaceCharMetric.getBoundingBox();
+        assertNotNull(spaceBBox);
+        assertEquals(0, spaceBBox.getLowerLeftX(), 0f);
+        assertEquals(0, spaceBBox.getLowerLeftY(), 0f);
+        assertEquals(0, spaceBBox.getUpperRightX(), 0f);
+        assertEquals(0, spaceBBox.getUpperRightY(), 0f);
+        assertTrue(spaceCharMetric.getLigatures().isEmpty());
+        assertNull(spaceCharMetric.getW());
+        assertNull(spaceCharMetric.getW0());
+        assertNull(spaceCharMetric.getW1());
+        assertNull(spaceCharMetric.getVv());
+        // check "ring" metrics
+        Optional<CharMetric> ring = charMetrics.stream()//
+                .filter(c -> "ring".equals(c.getName())).findFirst();
+        assertTrue(ring.isPresent());
+        CharMetric ringCharMetric = ring.get();
+        assertEquals(333f, ringCharMetric.getWx(), 0f);
+        assertEquals(202, ringCharMetric.getCharacterCode());
+        BoundingBox ringBBox = ringCharMetric.getBoundingBox();
+        assertNotNull(ringBBox);
+        assertEquals(75, ringBBox.getLowerLeftX(), 0f);
+        assertEquals(572, ringBBox.getLowerLeftY(), 0f);
+        assertEquals(259, ringBBox.getUpperRightX(), 0f);
+        assertEquals(756, ringBBox.getUpperRightY(), 0f);
+        assertTrue(ringCharMetric.getLigatures().isEmpty());
+        assertNull(ringCharMetric.getW());
+        assertNull(ringCharMetric.getW0());
+        assertNull(ringCharMetric.getW1());
+        assertNull(ringCharMetric.getVv());
+        // KernPairs, empty due to reducedDataset == true
+        List<KernPair> kernPairs = fontMetrics.getKernPairs();
+        assertTrue(kernPairs.isEmpty());
+        // KernPairs0
+        List<KernPair> kernPairs0 = fontMetrics.getKernPairs0();
+        assertTrue(kernPairs0.isEmpty());
+        // KernPairs1
+        List<KernPair> kernPairs1 = fontMetrics.getKernPairs1();
+        assertTrue(kernPairs1.isEmpty());
+        // composite data
+        List<Composite> composites = fontMetrics.getComposites();
+        assertTrue(composites.isEmpty());
+    }
 }

Modified: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/FontMetricsTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/FontMetricsTest.java?rev=1883299&r1=1883298&r2=1883299&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/FontMetricsTest.java (original)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/afm/FontMetricsTest.java Wed Nov 11 07:00:50 2020
@@ -89,8 +89,8 @@ public class FontMetricsTest
         assertEquals(0, fontMetrics.getEscChar());
         assertEquals("characterSet", fontMetrics.getCharacterSet());
         assertEquals(10, fontMetrics.getCharacters());
-        assertTrue(fontMetrics.isBaseFont());
-        assertTrue(fontMetrics.isFixedV());
+        assertTrue(fontMetrics.getIsBaseFont());
+        assertTrue(fontMetrics.getIsFixedV());
         assertEquals(10f, fontMetrics.getCapHeight(), 0f);
         assertEquals(20f, fontMetrics.getXHeight(), 0f);
         assertEquals(30f, fontMetrics.getAscender(), 0f);
@@ -100,7 +100,7 @@ public class FontMetricsTest
         assertEquals(70f, fontMetrics.getUnderlinePosition(), 0f);
         assertEquals(80f, fontMetrics.getUnderlineThickness(), 0f);
         assertEquals(90f, fontMetrics.getItalicAngle(), 0f);
-        assertTrue(fontMetrics.isFixedPitch());
+        assertTrue(fontMetrics.getIsFixedPitch());
     }
 
     @Test