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/04/10 11:45:48 UTC

svn commit: r1876362 - in /pdfbox/trunk/fontbox/src: main/java/org/apache/fontbox/cmap/CMapParser.java main/java/org/apache/fontbox/cmap/CodespaceRange.java test/java/org/apache/fontbox/cmap/TestCodespaceRange.java

Author: lehmi
Date: Fri Apr 10 11:45:48 2020
New Revision: 1876362

URL: http://svn.apache.org/viewvc?rev=1876362&view=rev
Log:
PDFBOX-4810: refactor CodespaceRange to be in line with spec

Added:
    pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cmap/TestCodespaceRange.java   (with props)
Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CodespaceRange.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java?rev=1876362&r1=1876361&r2=1876362&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java Fri Apr 10 11:45:48 2020
@@ -236,10 +236,7 @@ public class CMapParser
             }
             byte[] startRange = (byte[]) nextToken;
             byte[] endRange = (byte[]) parseNextToken(cmapStream);
-            CodespaceRange range = new CodespaceRange();
-            range.setStart(startRange);
-            range.setEnd(endRange);
-            result.addCodespaceRange(range);
+            result.addCodespaceRange(new CodespaceRange(startRange, endRange));
         }
     }
 

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CodespaceRange.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CodespaceRange.java?rev=1876362&r1=1876361&r2=1876362&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CodespaceRange.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CodespaceRange.java Fri Apr 10 11:45:48 2020
@@ -16,8 +16,6 @@
  */
 package org.apache.fontbox.cmap;
 
-import static org.apache.fontbox.cmap.CMap.toInt;
-
 /**
  * This represents a single entry in the codespace range.
  *
@@ -25,17 +23,34 @@ import static org.apache.fontbox.cmap.CM
  */
 public class CodespaceRange
 {
-    private byte[] start;
-    private byte[] end;
-    private int startInt;
-    private int endInt;
-    private int codeLength = 0;
+    private final int[] start;
+    private final int[] end;
+    private final int codeLength;
     
     /**
-     * Creates a new instance of CodespaceRange.
+     * Creates a new instance of CodespaceRange. The length of both arrays has to be the same.<br>
+     * For one byte ranges startBytes and endBytes define a linear range of values. Double byte values define a rectangular
+     * range not a linear range. Examples: <br>
+     * <00> <20> defines a linear range from 0x00 up to 0x20.<br>
+     * <8140> to <9FFC> defines a rectangular range. The high byte has to be within 0x81 and 0x9F and the low byte has to be
+     * within 0x40 and 0xFC
+     * 
      */
-    public CodespaceRange()
+    public CodespaceRange(byte[] startBytes, byte[] endBytes)
     {
+        if (startBytes.length != endBytes.length)
+        {
+            throw new IllegalArgumentException(
+                    "The start and the end values must not have different lengths.");
+        }
+        start = new int[startBytes.length];
+        end = new int[endBytes.length];
+        for (int i = 0; i < startBytes.length; i++)
+        {
+            start[i] = startBytes[i] & 0xFF;
+            end[i] = endBytes[i] & 0xFF;
+        }
+        codeLength = endBytes.length;
     }
 
     /**
@@ -48,45 +63,6 @@ public class CodespaceRange
         return codeLength;
     }
 
-    /** Getter for property end.
-     * @return Value of property end.
-     *
-     */
-    public byte[] getEnd()
-    {
-        return end;
-    }
-
-    /** Setter for property end.
-     * @param endBytes New value of property end.
-     *
-     */
-    void setEnd(byte[] endBytes)
-    {
-        end = endBytes;
-        endInt = toInt(endBytes, endBytes.length);
-    }
-
-    /** Getter for property start.
-     * @return Value of property start.
-     *
-     */
-    public byte[] getStart()
-    {
-        return start;
-    }
-
-    /** Setter for property start.
-     * @param startBytes New value of property start.
-     *
-     */
-    void setStart(byte[] startBytes)
-    {
-        start = startBytes;
-        codeLength = start.length;
-        startInt = toInt(startBytes, startBytes.length);
-    }
-
     /**
      * Returns true if the given code bytes match this codespace range.
      */
@@ -96,20 +72,24 @@ public class CodespaceRange
     }
 
     /**
-     * Returns true if the given code bytes match this codespace range.
+     * Returns true if the given number of code bytes match this codespace range.
      */
     public boolean isFullMatch(byte[] code, int codeLen)
     {
         // code must be the same length as the bounding codes
-        if (codeLen == codeLength)
+        if (codeLength != codeLen)
+        {
+            return false;
+        }
+        for (int i = 0; i < codeLength; i++)
         {
-            int value = toInt(code, codeLen);
-            if (value >= startInt && value <=endInt)
+            int codeAsInt = code[i] & 0xFF;
+            if (codeAsInt < start[i] || codeAsInt > end[i])
             {
-                return true;
+                return false;
             }
         }
-        return false;
+        return true;
     }
-    
+
 }

Added: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cmap/TestCodespaceRange.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cmap/TestCodespaceRange.java?rev=1876362&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cmap/TestCodespaceRange.java (added)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cmap/TestCodespaceRange.java Fri Apr 10 11:45:48 2020
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.cmap;
+
+import junit.framework.TestCase;
+
+/**
+ * This will test the CodeSpaceRange implementation.
+ *
+ */
+public class TestCodespaceRange extends TestCase
+{
+
+    /**
+     * Check whether the code length calculation works.
+     */
+    public void testCodeLength()
+    {
+        byte[] startBytes1 = new byte[] { 0x00 };
+        byte[] endBytes1 = new byte[] { 0x20 };
+        CodespaceRange range1 = new CodespaceRange(startBytes1, endBytes1);
+        assertEquals(1, range1.getCodeLength());
+
+        byte[] startBytes2 = new byte[] { 0x00, 0x00 };
+        byte[] endBytes2 = new byte[] { 0x01, 0x20 };
+        CodespaceRange range2 = new CodespaceRange(startBytes2, endBytes2);
+        assertEquals(2, range2.getCodeLength());
+    }
+
+    /**
+     * Check whether the constructor checks the length of the start and end bytes
+     */
+    public void testConstructor()
+    {
+        byte[] startBytes1 = new byte[] { 0x00 };
+        byte[] endBytes2 = new byte[] { 0x01, 0x20 };
+        try
+        {
+            new CodespaceRange(startBytes1, endBytes2);
+            fail("The constructor should have thrown an IllegalArgumentException exception.");
+        }
+        catch (IllegalArgumentException exception)
+        {
+            // everything is fine as the expected exception is thrown
+        }
+    }
+
+    public void testMatches()
+    {
+        byte[] startBytes1 = new byte[] { 0x00 };
+        byte[] endBytes1 = new byte[] { (byte) 0xA0 };
+        CodespaceRange range1 = new CodespaceRange(startBytes1, endBytes1);
+        // check start and end value
+        assertTrue(range1.matches(new byte[] { 0x00 }));
+        assertTrue(range1.matches(new byte[] { (byte) 0xA0 }));
+        // check any value within range
+        assertTrue(range1.matches(new byte[] { 0x10 }));
+        // check first value out of range
+        assertFalse(range1.matches(new byte[] { (byte) 0xA1 }));
+        // check any value out of range
+        assertFalse(range1.matches(new byte[] { (byte) 0xD0 }));
+        // check any value with a different code length
+        assertFalse(range1.matches(new byte[] { 0x00, 0x10 }));
+
+        byte[] startBytes2 = new byte[] { (byte) 0x81, 0x40 };
+        byte[] endBytes2 = new byte[] { (byte) 0x9F, (byte) 0xFC };
+        CodespaceRange range2 = new CodespaceRange(startBytes2, endBytes2);
+        // check lower start and end value
+        assertTrue(range2.matches(new byte[] { (byte) 0x81, 0x40 }));
+        assertTrue(range2.matches(new byte[] { (byte) 0x81, (byte) 0xFC }));
+        // check higher start and end value
+        assertTrue(range2.matches(new byte[] { (byte) 0x81, 0x40 }));
+        assertTrue(range2.matches(new byte[] { (byte) 0x9F, 0x40 }));
+        // check any value within lower range
+        assertTrue(range2.matches(new byte[] { (byte) 0x81, 0x65 }));
+        // check any value within higher range
+        assertTrue(range2.matches(new byte[] { (byte) 0x90, 0x40 }));
+        // check first value out of lower range
+        assertFalse(range2.matches(new byte[] { (byte) 0x81, (byte) 0xFD }));
+        // check first value out of higher range
+        assertFalse(range2.matches(new byte[] { (byte) 0xA0, 0x40 }));
+        // check any value out of lower range
+        assertFalse(range2.matches(new byte[] { (byte) 0x81, 0x20 }));
+        // check any value out of higher range
+        assertFalse(range2.matches(new byte[] { 0x10, 0x40 }));
+        // check value between start and end but not within the rectangular
+        assertFalse(range2.matches(new byte[] { (byte) 0x82, 0x20 }));
+        // check any value with a different code length
+        assertFalse(range2.matches(new byte[] { 0x00 }));
+    }
+
+}

Propchange: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cmap/TestCodespaceRange.java
------------------------------------------------------------------------------
    svn:eol-style = native