use of org.apache.fontbox.ttf.HorizontalMetricsTable in project pdfbox by apache.
the class PDCIDFontType2Embedder method buildVerticalMetrics.
/**
* Builds vertical metrics with a custom CIDToGIDMap (for embedding font subset).
*/
private void buildVerticalMetrics(Map<Integer, Integer> cidToGid) throws IOException {
if (!buildVerticalHeader(cidFont)) {
return;
}
float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
VerticalHeaderTable vhea = ttf.getVerticalHeader();
VerticalMetricsTable vmtx = ttf.getVerticalMetrics();
GlyphTable glyf = ttf.getGlyph();
HorizontalMetricsTable hmtx = ttf.getHorizontalMetrics();
long v_y = Math.round(vhea.getAscender() * scaling);
long w1 = Math.round(-vhea.getAdvanceHeightMax() * scaling);
COSArray heights = new COSArray();
COSArray w2 = new COSArray();
int prev = Integer.MIN_VALUE;
// Use a sorted list to get an optimal width array
Set<Integer> keys = new TreeSet<>(cidToGid.keySet());
for (int cid : keys) {
// Unlike buildWidths, we look up with cid (not gid) here because this is
// the original TTF, not the rebuilt one.
GlyphData glyph = glyf.getGlyph(cid);
if (glyph == null) {
continue;
}
long height = Math.round((glyph.getYMaximum() + vmtx.getTopSideBearing(cid)) * scaling);
long advance = Math.round(-vmtx.getAdvanceHeight(cid) * scaling);
if (height == v_y && advance == w1) {
// skip default metrics
continue;
}
// c [w1_1y v_1x v_1y w1_2y v_2x v_2y ... w1_ny v_nx v_ny]
if (prev != cid - 1) {
w2 = new COSArray();
// c
heights.add(COSInteger.get(cid));
heights.add(w2);
}
// w1_iy
w2.add(COSInteger.get(advance));
long width = Math.round(hmtx.getAdvanceWidth(cid) * scaling);
// v_ix
w2.add(COSInteger.get(width / 2));
// v_iy
w2.add(COSInteger.get(height));
prev = cid;
}
cidFont.setItem(COSName.W2, heights);
}
use of org.apache.fontbox.ttf.HorizontalMetricsTable in project pdfbox by apache.
the class PDTrueTypeFontEmbedder method setWidths.
/**
* Sets the glyph widths in the font dictionary.
*/
private void setWidths(COSDictionary font, GlyphList glyphList) throws IOException {
float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
HorizontalMetricsTable hmtx = ttf.getHorizontalMetrics();
Map<Integer, String> codeToName = getFontEncoding().getCodeToNameMap();
int firstChar = Collections.min(codeToName.keySet());
int lastChar = Collections.max(codeToName.keySet());
List<Integer> widths = new ArrayList<>(lastChar - firstChar + 1);
for (int i = 0; i < lastChar - firstChar + 1; i++) {
widths.add(0);
}
// afterwards, the glyph name is translated to a glyph ID.
for (Map.Entry<Integer, String> entry : codeToName.entrySet()) {
int code = entry.getKey();
String name = entry.getValue();
if (code >= firstChar && code <= lastChar) {
String uni = glyphList.toUnicode(name);
int charCode = uni.codePointAt(0);
int gid = cmapLookup.getGlyphId(charCode);
widths.set(entry.getKey() - firstChar, Math.round(hmtx.getAdvanceWidth(gid) * scaling));
}
}
font.setInt(COSName.FIRST_CHAR, firstChar);
font.setInt(COSName.LAST_CHAR, lastChar);
font.setItem(COSName.WIDTHS, COSArrayList.converterToCOSArray(widths));
}
Aggregations