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 2012/03/30 17:54:13 UTC

svn commit: r1307491 - in /pdfbox/trunk: fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java

Author: leleueri
Date: Fri Mar 30 15:54:12 2012
New Revision: 1307491

URL: http://svn.apache.org/viewvc?rev=1307491&view=rev
Log:
[PDFBOX-1275] The use of ".notdef" glyph character is authorized by the PDF/A-1 specification if the CID is 0. 
 

Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java
    pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java?rev=1307491&r1=1307490&r2=1307491&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java Fri Mar 30 15:54:12 2012
@@ -38,175 +38,175 @@ import org.apache.fontbox.cff.encoding.C
 public class CFFFont
 {
 
-    private String fontname = null;
-    private Map<String, Object> topDict = new LinkedHashMap<String, Object>();
-    private Map<String, Object> privateDict = new LinkedHashMap<String, Object>();
-    private CFFEncoding fontEncoding = null;
-    private CFFCharset fontCharset = null;
-    private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
-    private IndexData globalSubrIndex = null;
-    private IndexData localSubrIndex = null;
-
-    /**
-     * The name of the font.
-     * @return the name of the font
-     */
-    public String getName()
-    {
-        return fontname;
-    }
-
-    /**
-     * Sets the name of the font.
-     * @param name the name of the font
-     */
-    public void setName(String name)
-    {
-        fontname = name;
-    }
-
-    /**
-     * Returns the value for the given name from the dictionary.
-     * @param name the name of the value
-     * @return the value of the name if available
-     */
-    public Object getProperty(String name)
-    {
-        Object topDictValue = topDict.get(name);
-        if (topDictValue != null)
-        {
-            return topDictValue;
-        }
-        Object privateDictValue = privateDict.get(name);
-        if (privateDictValue != null)
-        {
-            return privateDictValue;
-        }
-        return null;
-    }
-
-    /**
-     * Adds the given key/value pair to the top dictionary. 
-     * @param name the given key
-     * @param value the given value
-     */
-    public void addValueToTopDict(String name, Object value)
-    {
-        if (value != null)
-        {
-            topDict.put(name, value);
-        }
-    }
-    /** 
-     * Returns the top dictionary.
-     * @return the dictionary
-     */
-    public Map<String, Object> getTopDict()
-    {
-        return topDict;
-    }
-
-    /**
-     * Adds the given key/value pair to the private dictionary. 
-     * @param name the given key
-     * @param value the given value
-     */
-    public void addValueToPrivateDict(String name, Object value)
-    {
-        if (value != null)
-        {
-            privateDict.put(name, value);
-        }
-    }
-    /** 
-     * Returns the private dictionary.
-     * @return the dictionary
-     */
-    public Map<String, Object> getPrivateDict()
-    {
-        return privateDict;
-    }
-
-    /**
-     * Get the mapping (code/SID/charname/bytes) for this font.
-     * @return mappings for codes < 256 and for codes > = 256
-     */
-    public Collection<Mapping> getMappings()
-    {
-        List<Mapping> mappings = new ArrayList<Mapping>();
-        Set<String> mappedNames = new HashSet<String>();
-        for (CFFEncoding.Entry entry : fontEncoding.getEntries())
-        {
-            String charName = fontCharset.getName(entry.getSID());
-            // Predefined encoding
-            if (charName == null)
-            {
-                continue;
-            }
-            byte[] bytes = charStringsDict.get(charName);
-            if (bytes == null)
-            {
-                continue;
-            }
-            Mapping mapping = new Mapping();
-            mapping.setCode(entry.getCode());
-            mapping.setSID(entry.getSID());
-            mapping.setName(charName);
-            mapping.setBytes(bytes);
-            mappings.add(mapping);
-            mappedNames.add(charName);
-        }
-        if (fontEncoding instanceof CFFParser.EmbeddedEncoding)
-        {
-            CFFParser.EmbeddedEncoding embeddedEncoding = (CFFParser.EmbeddedEncoding)fontEncoding;
-
-            for (CFFParser.EmbeddedEncoding.Supplement supplement : embeddedEncoding.getSupplements())
-            {
-                String charName = fontCharset.getName(supplement.getGlyph());
-                if (charName == null)
-                {
-                    continue;
-                }
-                byte[] bytes = charStringsDict.get(charName);
-                if (bytes == null)
-                {
-                    continue;
-                }
-                Mapping mapping = new Mapping();
-                mapping.setCode(supplement.getCode());
-                mapping.setSID(supplement.getGlyph());
-                mapping.setName(charName);
-                mapping.setBytes(bytes);
-                mappings.add(mapping);
-                mappedNames.add(charName);
-            }
-        }
-        // XXX
-        int code = 256;
-        for (CFFCharset.Entry entry : fontCharset.getEntries())
-        {
-            String name = entry.getName();
-            if (mappedNames.contains(name))
-            {
-                continue;
-            }
-            byte[] bytes = this.charStringsDict.get(name);
-            if (bytes == null)
-            {
-                continue;
-            }
-            Mapping mapping = new Mapping();
-            mapping.setCode(code++);
-            mapping.setSID(entry.getSID());
-            mapping.setName(name);
-            mapping.setBytes(bytes);
-
-            mappings.add(mapping);
-
-            mappedNames.add(name);
-        }
-        return mappings;
-    }
+	private String fontname = null;
+	private Map<String, Object> topDict = new LinkedHashMap<String, Object>();
+	private Map<String, Object> privateDict = new LinkedHashMap<String, Object>();
+	private CFFEncoding fontEncoding = null;
+	private CFFCharset fontCharset = null;
+	private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
+	private IndexData globalSubrIndex = null;
+	private IndexData localSubrIndex = null;
+
+	/**
+	 * The name of the font.
+	 * @return the name of the font
+	 */
+	public String getName()
+	{
+		return fontname;
+	}
+
+	/**
+	 * Sets the name of the font.
+	 * @param name the name of the font
+	 */
+	public void setName(String name)
+	{
+		fontname = name;
+	}
+
+	/**
+	 * Returns the value for the given name from the dictionary.
+	 * @param name the name of the value
+	 * @return the value of the name if available
+	 */
+	public Object getProperty(String name)
+	{
+		Object topDictValue = topDict.get(name);
+		if (topDictValue != null)
+		{
+			return topDictValue;
+		}
+		Object privateDictValue = privateDict.get(name);
+		if (privateDictValue != null)
+		{
+			return privateDictValue;
+		}
+		return null;
+	}
+
+	/**
+	 * Adds the given key/value pair to the top dictionary. 
+	 * @param name the given key
+	 * @param value the given value
+	 */
+	public void addValueToTopDict(String name, Object value)
+	{
+		if (value != null)
+		{
+			topDict.put(name, value);
+		}
+	}
+	/** 
+	 * Returns the top dictionary.
+	 * @return the dictionary
+	 */
+	public Map<String, Object> getTopDict()
+	{
+		return topDict;
+	}
+
+	/**
+	 * Adds the given key/value pair to the private dictionary. 
+	 * @param name the given key
+	 * @param value the given value
+	 */
+	public void addValueToPrivateDict(String name, Object value)
+	{
+		if (value != null)
+		{
+			privateDict.put(name, value);
+		}
+	}
+	/** 
+	 * Returns the private dictionary.
+	 * @return the dictionary
+	 */
+	public Map<String, Object> getPrivateDict()
+	{
+		return privateDict;
+	}
+
+	/**
+	 * Get the mapping (code/SID/charname/bytes) for this font.
+	 * @return mappings for codes < 256 and for codes > = 256
+	 */
+	public Collection<Mapping> getMappings()
+	{
+		List<Mapping> mappings = new ArrayList<Mapping>();
+		Set<String> mappedNames = new HashSet<String>();
+		for (CFFEncoding.Entry entry : fontEncoding.getEntries())
+		{
+			String charName = fontCharset.getName(entry.getSID());
+			// Predefined encoding
+			if (charName == null)
+			{
+				continue;
+			}
+			byte[] bytes = charStringsDict.get(charName);
+			if (bytes == null)
+			{
+				continue;
+			}
+			Mapping mapping = new Mapping();
+			mapping.setCode(entry.getCode());
+			mapping.setSID(entry.getSID());
+			mapping.setName(charName);
+			mapping.setBytes(bytes);
+			mappings.add(mapping);
+			mappedNames.add(charName);
+		}
+		if (fontEncoding instanceof CFFParser.EmbeddedEncoding)
+		{
+			CFFParser.EmbeddedEncoding embeddedEncoding = (CFFParser.EmbeddedEncoding)fontEncoding;
+
+			for (CFFParser.EmbeddedEncoding.Supplement supplement : embeddedEncoding.getSupplements())
+			{
+				String charName = fontCharset.getName(supplement.getGlyph());
+				if (charName == null)
+				{
+					continue;
+				}
+				byte[] bytes = charStringsDict.get(charName);
+				if (bytes == null)
+				{
+					continue;
+				}
+				Mapping mapping = new Mapping();
+				mapping.setCode(supplement.getCode());
+				mapping.setSID(supplement.getGlyph());
+				mapping.setName(charName);
+				mapping.setBytes(bytes);
+				mappings.add(mapping);
+				mappedNames.add(charName);
+			}
+		}
+		// XXX
+		int code = 256;
+		for (CFFCharset.Entry entry : fontCharset.getEntries())
+		{
+			String name = entry.getName();
+			if (mappedNames.contains(name))
+			{
+				continue;
+			}
+			byte[] bytes = this.charStringsDict.get(name);
+			if (bytes == null)
+			{
+				continue;
+			}
+			Mapping mapping = new Mapping();
+			mapping.setCode(code++);
+			mapping.setSID(entry.getSID());
+			mapping.setName(name);
+			mapping.setBytes(bytes);
+
+			mappings.add(mapping);
+
+			mappedNames.add(name);
+		}
+		return mappings;
+	}
 
 	/**
 	 * Return the Width value of the given Glyph identifier
@@ -218,6 +218,7 @@ public class CFFFont
 	public int getWidth(int SID) throws IOException {
 		int nominalWidth = privateDict.containsKey("nominalWidthX") ? ((Number)privateDict.get("nominalWidthX")).intValue() : 0;
 		int defaultWidth = privateDict.containsKey("defaultWidthX") ? ((Number)privateDict.get("defaultWidthX")).intValue() : 1000 ;
+		
 		for (Mapping m : getMappings() ){
 			if (m.getSID() == SID) {
 
@@ -238,207 +239,224 @@ public class CFFFont
 			}
 		}
 
-		// ---- Width not found, return the default width
-		return defaultWidth;
+		// ---- SID Width not found, return the nodef width
+		return getNotDefWidth(defaultWidth, nominalWidth);
+	}
+	
+	protected int getNotDefWidth(int defaultWidth, int nominalWidth) throws IOException {
+		CharStringRenderer csr;
+		byte[] glyphDesc = this.getCharStringsDict().get(".notdef");
+		if (((Number)getProperty("CharstringType")).intValue() == 2 ) {
+			Type2CharStringParser parser = new Type2CharStringParser();
+			List<Object> lSeq = parser.parse(glyphDesc);
+			csr = new CharStringRenderer(false);
+			csr.render(lSeq);
+		} else {
+			Type1CharStringParser parser = new Type1CharStringParser();
+			List<Object> lSeq = parser.parse(glyphDesc);
+			csr = new CharStringRenderer();
+			csr.render(lSeq);
+		}
+		return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+	}
+	
+	/**
+	 * Returns the CFFEncoding of the font.
+	 * @return the encoding
+	 */
+	public CFFEncoding getEncoding()
+	{
+		return fontEncoding;
+	}
+
+	/**
+	 * Sets the CFFEncoding of the font.
+	 * @param encoding the given CFFEncoding
+	 */
+	public void setEncoding(CFFEncoding encoding)
+	{
+		fontEncoding = encoding;
 	}
-    
-    /**
-     * Returns the CFFEncoding of the font.
-     * @return the encoding
-     */
-    public CFFEncoding getEncoding()
-    {
-        return fontEncoding;
-    }
-
-    /**
-     * Sets the CFFEncoding of the font.
-     * @param encoding the given CFFEncoding
-     */
-    public void setEncoding(CFFEncoding encoding)
-    {
-        fontEncoding = encoding;
-    }
-
-    /**
-     * Returns the CFFCharset of the font.
-     * @return the charset
-     */
-    public CFFCharset getCharset()
-    {
-        return fontCharset;
-    }
-
-    /**
-     * Sets the CFFCharset of the font.
-     * @param charset the given CFFCharset
-     */
-    public void setCharset(CFFCharset charset)
-    {
-        fontCharset = charset;
-    }
-
-    /** 
-     * Returns the character strings dictionary.
-     * @return the dictionary
-     */
-    public Map<String, byte[]> getCharStringsDict()
-    {
-        return charStringsDict;
-    }
-
-    /**
-     * Creates a CharStringConverter for this font.
-     * @return the new CharStringConverter
-     */
-    public CharStringConverter createConverter()
-    {
-        Number defaultWidthX = (Number) getProperty("defaultWidthX");
-        Number nominalWidthX = (Number) getProperty("nominalWidthX");
-        return new CharStringConverter(defaultWidthX.intValue(), nominalWidthX
-                .intValue(), getGlobalSubrIndex(), getLocalSubrIndex());
-    }
-
-    /**
-     * Creates a CharStringRenderer for this font.
-     * @return the new CharStringRenderer
-     */
-    public CharStringRenderer createRenderer()
-    {
-        return new CharStringRenderer();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String toString()
-    {
-        return getClass().getName() + "[name=" + fontname + ", topDict=" + topDict
-                + ", privateDict=" + privateDict + ", encoding=" + fontEncoding
-                + ", charset=" + fontCharset + ", charStringsDict="
-                + charStringsDict + "]";
-    }
-
-    
-    /**
-     * Sets the global subroutine index data.
-     * @param globalSubrIndex the IndexData object containing the global subroutines 
-     */
-    public void setGlobalSubrIndex(IndexData globalSubrIndex) {
+
+	/**
+	 * Returns the CFFCharset of the font.
+	 * @return the charset
+	 */
+	public CFFCharset getCharset()
+	{
+		return fontCharset;
+	}
+
+	/**
+	 * Sets the CFFCharset of the font.
+	 * @param charset the given CFFCharset
+	 */
+	public void setCharset(CFFCharset charset)
+	{
+		fontCharset = charset;
+	}
+
+	/** 
+	 * Returns the character strings dictionary.
+	 * @return the dictionary
+	 */
+	public Map<String, byte[]> getCharStringsDict()
+	{
+		return charStringsDict;
+	}
+
+	/**
+	 * Creates a CharStringConverter for this font.
+	 * @return the new CharStringConverter
+	 */
+	public CharStringConverter createConverter()
+	{
+		Number defaultWidthX = (Number) getProperty("defaultWidthX");
+		Number nominalWidthX = (Number) getProperty("nominalWidthX");
+		return new CharStringConverter(defaultWidthX.intValue(), nominalWidthX
+				.intValue(), getGlobalSubrIndex(), getLocalSubrIndex());
+	}
+
+	/**
+	 * Creates a CharStringRenderer for this font.
+	 * @return the new CharStringRenderer
+	 */
+	public CharStringRenderer createRenderer()
+	{
+		return new CharStringRenderer();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String toString()
+	{
+		return getClass().getName() + "[name=" + fontname + ", topDict=" + topDict
+				+ ", privateDict=" + privateDict + ", encoding=" + fontEncoding
+				+ ", charset=" + fontCharset + ", charStringsDict="
+				+ charStringsDict + "]";
+	}
+
+
+	/**
+	 * Sets the global subroutine index data.
+	 * @param globalSubrIndex the IndexData object containing the global subroutines 
+	 */
+	public void setGlobalSubrIndex(IndexData globalSubrIndex) {
 		this.globalSubrIndex = globalSubrIndex;
 	}
 
-    /** 
-     * Returns the global subroutine index data.
-     * @return the dictionary
-     */
+	/** 
+	 * Returns the global subroutine index data.
+	 * @return the dictionary
+	 */
 	public IndexData getGlobalSubrIndex() {
 		return globalSubrIndex;
 	}
-	
-    /** 
-     * Returns the local subroutine index data.
-     * @return the dictionary
-     */
+
+	/** 
+	 * Returns the local subroutine index data.
+	 * @return the dictionary
+	 */
 	public IndexData getLocalSubrIndex() {
 		return localSubrIndex;
 	}
-	
-    /**
-     * Sets the local subroutine index data.
-     * @param localSubrIndex the IndexData object containing the local subroutines 
-     */
+
+	/**
+	 * Sets the local subroutine index data.
+	 * @param localSubrIndex the IndexData object containing the local subroutines 
+	 */
 	public void setLocalSubrIndex(IndexData localSubrIndex) {
 		this.localSubrIndex = localSubrIndex;	
 	}
 
 	/**
-     * This class is used for the font mapping.
-     *
-     */
-    public class Mapping
-    {
-        private int mappedCode;
-        private int mappedSID;
-        private String mappedName;
-        private byte[] mappedBytes;
-
-        /**
-         * Converts the mapping into a Type1-sequence.
-         * @return the Type1-sequence
-         * @throws IOException if an error occurs during reading
-         */
-        public List<Object> toType1Sequence() throws IOException
-        {
-            CharStringConverter converter = createConverter();
-            return converter.convert(toType2Sequence());
-        }
-
-        /**
-         * Converts the mapping into a Type2-sequence.
-         * @return the Type2-sequence
-         * @throws IOException if an error occurs during reading
-         */
-        public List<Object> toType2Sequence() throws IOException
-        {
-            Type2CharStringParser parser = new Type2CharStringParser();
-            return parser.parse(getBytes());
-        }
-
-        /**
-         * Gets the value for the code.
-         * @return the code
-         */
-        public int getCode()
-        {
-            return mappedCode;
-        }
-
-        private void setCode(int code)
-        {
-            mappedCode = code;
-        }
-
-        /**
-         * Gets the value for the SID.
-         * @return the SID
-         */
-        public int getSID()
-        {
-            return mappedSID;
-        }
-
-        private void setSID(int sid)
-        {
-            this.mappedSID = sid;
-        }
-
-        /**
-         * Gets the value for the name.
-         * @return the name
-         */
-        public String getName()
-        {
-            return mappedName;
-        }
-
-        private void setName(String name)
-        {
-            this.mappedName = name;
-        }
-
-        /**
-         * Gets the value for the bytes.
-         * @return the bytes
-         */
-        public byte[] getBytes()
-        {
-            return mappedBytes;
-        }
-
-        private void setBytes(byte[] bytes)
-        {
-            this.mappedBytes = bytes;
-        }
-    }
+	 * This class is used for the font mapping.
+	 *
+	 */
+	public class Mapping
+	{
+		private int mappedCode;
+		private int mappedSID;
+		private String mappedName;
+		private byte[] mappedBytes;
+
+		/**
+		 * Converts the mapping into a Type1-sequence.
+		 * @return the Type1-sequence
+		 * @throws IOException if an error occurs during reading
+		 */
+		public List<Object> toType1Sequence() throws IOException
+		{
+			CharStringConverter converter = createConverter();
+			return converter.convert(toType2Sequence());
+		}
+
+		/**
+		 * Converts the mapping into a Type2-sequence.
+		 * @return the Type2-sequence
+		 * @throws IOException if an error occurs during reading
+		 */
+		public List<Object> toType2Sequence() throws IOException
+		{
+			Type2CharStringParser parser = new Type2CharStringParser();
+			return parser.parse(getBytes());
+		}
+
+		/**
+		 * Gets the value for the code.
+		 * @return the code
+		 */
+		public int getCode()
+		{
+			return mappedCode;
+		}
+
+		private void setCode(int code)
+		{
+			mappedCode = code;
+		}
+
+		/**
+		 * Gets the value for the SID.
+		 * @return the SID
+		 */
+		public int getSID()
+		{
+			return mappedSID;
+		}
+
+		private void setSID(int sid)
+		{
+			this.mappedSID = sid;
+		}
+
+		/**
+		 * Gets the value for the name.
+		 * @return the name
+		 */
+		public String getName()
+		{
+			return mappedName;
+		}
+
+		private void setName(String name)
+		{
+			this.mappedName = name;
+		}
+
+		/**
+		 * Gets the value for the bytes.
+		 * @return the bytes
+		 */
+		public byte[] getBytes()
+		{
+			return mappedBytes;
+		}
+
+		private void setBytes(byte[] bytes)
+		{
+			this.mappedBytes = bytes;
+		}
+	}
 }
\ No newline at end of file

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java?rev=1307491&r1=1307490&r2=1307491&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java Fri Mar 30 15:54:12 2012
@@ -141,21 +141,21 @@ public class CFFFontROS extends CFFFont 
 	/**
 	 * Returns the Width value of the given Glyph identifier
 	 * 
-	 * @param SID
+	 * @param CID
 	 * @return -1 if the SID is missing from the Font.
 	 * @throws IOException
 	 */
-	public int getWidth(int SID) throws IOException {
+	public int getWidth(int CID) throws IOException {
 		// ---- search the right FDArray index in the FDSelect according to the Character identifier
 		// 		this index will be used to access the private dictionary which contains useful values 
 		//		to compute width.
-		int fdArrayIndex = this.fdSelect.getFd(SID);
-		if (fdArrayIndex == -1 && SID == 0 ) { // --- notdef char
-			return super.getWidth(SID);
+		int fdArrayIndex = this.fdSelect.getFd(CID);
+		if (fdArrayIndex == -1 && CID == 0 ) { // --- notdef char
+			return super.getWidth(CID);
 		} else if (fdArrayIndex == -1) {
 			return 1000;
 		}
-
+		
 		Map<String, Object> fontDict = this.fontDictionaries.get(fdArrayIndex);
 		Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
 
@@ -163,7 +163,7 @@ public class CFFFontROS extends CFFFont 
 		int defaultWidth = privDict.containsKey("defaultWidthX") ? ((Number)privDict.get("defaultWidthX")).intValue() : 1000 ;
 
 		for (Mapping m : getMappings() ){
-			if (m.getSID() == SID) {
+			if (m.getSID() == CID) {
 
 				CharStringRenderer csr = null;
 				Number charStringType = (Number)getProperty("CharstringType");
@@ -183,7 +183,7 @@ public class CFFFontROS extends CFFFont 
 			}
 		}
 
-		// ---- Width not found, return the default width
-		return defaultWidth;
+		// ---- CID Width not found, return the notdef width
+		return getNotDefWidth(defaultWidth, nominalWidth);
 	}
 }

Modified: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java?rev=1307491&r1=1307490&r2=1307491&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/font/CFFType0FontContainer.java Fri Mar 30 15:54:12 2012
@@ -63,7 +63,9 @@ public class CFFType0FontContainer exten
 			}
 		}
 
-		if (!cidFound) {
+		if (!cidFound && cid != 0) { 
+			// Cid 0 is commonly used as the NotDef Glyph. this glyph can be used as Space.
+			// IN PDF/A-1 the Notdef glyph can be used as space. Not in PDF/A-2 
 			GlyphException ge = new GlyphException(ValidationConstants.ERROR_FONTS_GLYPH_MISSING, cid, 
 																							"CID " + cid + " is missing from the Composite Font format \"" 
 																							+ this.font.getBaseFont()+"\""	);