in fop-core/src/main/java/org/apache/fop/fonts/type1/Type1FontLoader.java [281:428]
private void handleMetrics(AFMFile afm, PFMFile pfm) {
// Basic metrics
if (afm != null) {
if (afm.getCapHeight() != null) {
returnFont.setCapHeight(afm.getCapHeight().intValue());
}
if (afm.getXHeight() != null) {
returnFont.setXHeight(afm.getXHeight().intValue());
}
if (afm.getAscender() != null) {
returnFont.setAscender(afm.getAscender().intValue());
}
if (afm.getDescender() != null) {
returnFont.setDescender(afm.getDescender().intValue());
}
returnFont.setFontBBox(afm.getFontBBoxAsIntArray());
if (afm.getStdVW() != null) {
returnFont.setStemV(afm.getStdVW().intValue());
} else {
returnFont.setStemV(80); // Arbitrary value
}
AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0);
returnFont.setItalicAngle((int) metrics.getItalicAngle());
returnFont.setUnderlinePosition(metrics.getUnderlinePosition().intValue());
returnFont.setUnderlineThickness(metrics.getUnderlineThickness().intValue());
} else {
returnFont.setFontBBox(pfm.getFontBBox());
returnFont.setStemV(pfm.getStemV());
returnFont.setItalicAngle(pfm.getItalicAngle());
}
if (pfm != null) {
// Sometimes the PFM has these metrics while the AFM doesn't (ex. Symbol)
if (returnFont.getCapHeight() == 0) {
returnFont.setCapHeight(pfm.getCapHeight());
}
if (returnFont.getXHeight(1) == 0) {
returnFont.setXHeight(pfm.getXHeight());
}
if (returnFont.getAscender() == 0) {
returnFont.setAscender(pfm.getLowerCaseAscent());
}
if (returnFont.getDescender() == 0) {
returnFont.setDescender(pfm.getLowerCaseDescent());
}
}
// Fallbacks when some crucial font metrics aren't available
// (the following are all optional in AFM, but FontBBox is always available)
if (returnFont.getXHeight(1) == 0) {
int xHeight = 0;
if (afm != null) {
AFMCharMetrics chm = afm.getChar("x");
if (chm != null) {
RectangularShape rect = chm.getBBox();
if (rect != null) {
xHeight = (int) Math.round(rect.getMinX());
}
}
}
if (xHeight == 0) {
xHeight = Math.round(returnFont.getFontBBox()[3] * 0.6f);
}
returnFont.setXHeight(xHeight);
}
if (returnFont.getAscender() == 0) {
int asc = 0;
if (afm != null) {
AFMCharMetrics chm = afm.getChar("d");
if (chm != null) {
RectangularShape rect = chm.getBBox();
if (rect != null) {
asc = (int) Math.round(rect.getMinX());
}
}
}
if (asc == 0) {
asc = Math.round(returnFont.getFontBBox()[3] * 0.9f);
}
returnFont.setAscender(asc);
}
if (returnFont.getDescender() == 0) {
int desc = 0;
if (afm != null) {
AFMCharMetrics chm = afm.getChar("p");
if (chm != null) {
RectangularShape rect = chm.getBBox();
if (rect != null) {
desc = (int) Math.round(rect.getMinX());
}
}
}
if (desc == 0) {
desc = returnFont.getFontBBox()[1];
}
returnFont.setDescender(desc);
}
if (returnFont.getCapHeight() == 0) {
returnFont.setCapHeight(returnFont.getAscender());
}
if (afm != null) {
String charSet = afm.getCharacterSet();
int flags = 0;
if ("Special".equals(charSet)) {
flags |= 4; // bit 3: Symbolic
} else {
if (singleFont.getEncoding().mapChar('A') == 'A') {
// High likelyhood that the font is non-symbolic
flags |= 32; // bit 6: Nonsymbolic
} else {
flags |= 4; // bit 3: Symbolic
}
}
if (afm.getWritingDirectionMetrics(0).isFixedPitch()) {
flags |= 1; // bit 1: FixedPitch
}
if (afm.getWritingDirectionMetrics(0).getItalicAngle() != 0.0) {
flags |= 64; // bit 7: Italic
}
returnFont.setFlags(flags);
returnFont.setFirstChar(afm.getFirstChar());
returnFont.setLastChar(afm.getLastChar());
for (AFMCharMetrics chm : afm.getCharMetrics()) {
if (chm.hasCharCode()) {
singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX()));
singleFont.setBoundingBox(chm.getCharCode(), chm.getBBox());
}
}
if (useKerning) {
returnFont.replaceKerningMap(afm.createXKerningMapEncoded());
}
} else {
returnFont.setFlags(pfm.getFlags());
returnFont.setFirstChar(pfm.getFirstChar());
returnFont.setLastChar(pfm.getLastChar());
for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {
int cw = pfm.getCharWidth(i);
singleFont.setWidth(i, cw);
int[] bbox = pfm.getFontBBox();
singleFont.setBoundingBox(i, new Rectangle(bbox[0], bbox[1], cw, bbox[3]));
}
if (useKerning) {
returnFont.replaceKerningMap(pfm.getKerning());
}
}
}