// ---- the Widths value can be a reference to an object
// ---- Access the object using the COSkey
COSArray wArr = COSUtils.getAsArray(this.widths, cDoc);
if (wArr == null) {
this.fontContainer.addError(new ValidationError(
ERROR_FONTS_DICTIONARY_INVALID,
"The Witdhs array is unreachable"));
return false;
}
COSDictionary charProcsDictionary = COSUtils.getAsDictionary(this.charProcs, cDoc);
if (charProcsDictionary == null) {
this.fontContainer.addError(new ValidationError(
ERROR_FONTS_DICTIONARY_INVALID,
"The CharProcs element isn't a dictionary"));
return false;
}
// ---- firstChar and lastChar must be integer.
int fc = ((COSInteger) this.firstChar).intValue();
int lc = ((COSInteger) this.lastChar).intValue();
// ---- wArr length = (lc - fc) +1 and it is an array of int.
// ---- If FirstChar is greater than LastChar, the validation will fail
// because of
// ---- the array will have an expected size <= 0.
int expectedLength = (lc - fc) + 1;
if (wArr.size() != expectedLength) {
this.fontContainer.addError(new ValidationError(
ERROR_FONTS_DICTIONARY_INVALID,
"The length of Witdhs array is invalid. Expected : \""
+ expectedLength + "\" Current : \"" + wArr.size() + "\""));
return false;
}
// ---- Check width consistency
for (int i = 0; i < expectedLength; i++) {
int cid = fc + i;
COSBase arrContent = wArr.get(i);
if (COSUtils.isNumeric(arrContent, cDoc)) {
float width = COSUtils.getAsFloat(arrContent, cDoc);
String charName = null;
try {
charName = this.type3Encoding.getName(cid);
} catch (IOException e) {
// shouldn't occur
throw new ValidationException("Unable to check Widths consistency", e);
}
COSBase item = charProcsDictionary.getItem(COSName.getPDFName(charName));
COSStream charStream = COSUtils.getAsStream(item, cDoc);
if (charStream == null) {
/* There are no character description, we declare the Glyph as Invalid.
* If the character is used in a Stream, the GlyphDetail will throw an exception.
*/
GlyphException glyphEx = new GlyphException(ERROR_FONTS_METRICS, cid,
"The CharProcs \"" + charName
+ "\" doesn't exist, the width defines in the Font Dictionary is " + width);
GlyphDetail glyphDetail = new GlyphDetail(cid, glyphEx);
this.fontContainer.addKnownCidElement(glyphDetail);
} else {
try {
// --- Parse the Glyph description to obtain the Width
PDFAType3StreamParser parser = new PDFAType3StreamParser(
this.handler);
PDResources pRes = null;
if (this.resources != null) {
COSDictionary resAsDict = COSUtils.getAsDictionary(
this.resources, cDoc);
if (resAsDict != null) {
pRes = new PDResources(resAsDict);
}
}
parser.resetEngine();
parser.processSubStream(null, pRes, charStream);
if (width != parser.getWidth()) {
GlyphException glyphEx = new GlyphException(ERROR_FONTS_METRICS, cid,
"The CharProcs \"" + charName
+ "\" should have a width equals to " + width);
GlyphDetail glyphDetail = new GlyphDetail(cid, glyphEx);
this.fontContainer.addKnownCidElement(glyphDetail);
} else {
// Glyph is OK, we keep the CID.
GlyphDetail glyphDetail = new GlyphDetail(cid);
this.fontContainer.addKnownCidElement(glyphDetail);
}
} catch (ContentStreamException e) {
this.fontContainer.addError(new ValidationError(e
.getValidationError()));
return false;
} catch (IOException e) {
this.fontContainer.addError(new ValidationError(
ERROR_FONTS_TYPE3_DAMAGED,
"The CharProcs references an element which can't be read"));
return false;
}
}
} else {
this.fontContainer.addError(new ValidationError(
ERROR_FONTS_DICTIONARY_INVALID,
"The Witdhs array is invalid. (some element aren't integer)"));
return false;
}
}