in pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java [547:668]
private COSArray getVerticalMetrics(int[] values) throws IOException
{
if (values.length < 4)
{
throw new IllegalArgumentException("length of values must be at least 4");
}
float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
long lastCid = values[0];
long lastW1Value = Math.round(-values[1] * scaling);
long lastVxValue = Math.round(values[2] * scaling / 2f);
long lastVyValue = Math.round(values[3] * scaling);
COSArray inner = new COSArray();
COSArray outer = new COSArray();
outer.add(COSInteger.get(lastCid));
State state = State.FIRST;
for (int i = 4; i < values.length - 3; i += 4)
{
long cid = values[i];
if (cid == Integer.MIN_VALUE)
{
// no glyph for this cid
continue;
}
long w1Value = Math.round(-values[i + 1] * scaling);
long vxValue = Math.round(values[i + 2] * scaling / 2);
long vyValue = Math.round(values[i + 3] * scaling);
switch (state)
{
case FIRST:
if (cid == lastCid + 1 && w1Value == lastW1Value && vxValue == lastVxValue && vyValue == lastVyValue)
{
state = State.SERIAL;
}
else if (cid == lastCid + 1)
{
state = State.BRACKET;
inner = new COSArray();
inner.add(COSInteger.get(lastW1Value));
inner.add(COSInteger.get(lastVxValue));
inner.add(COSInteger.get(lastVyValue));
}
else
{
inner = new COSArray();
inner.add(COSInteger.get(lastW1Value));
inner.add(COSInteger.get(lastVxValue));
inner.add(COSInteger.get(lastVyValue));
outer.add(inner);
outer.add(COSInteger.get(cid));
}
break;
case BRACKET:
if (cid == lastCid + 1 && w1Value == lastW1Value && vxValue == lastVxValue && vyValue == lastVyValue)
{
state = State.SERIAL;
outer.add(inner);
outer.add(COSInteger.get(lastCid));
}
else if (cid == lastCid + 1)
{
inner.add(COSInteger.get(lastW1Value));
inner.add(COSInteger.get(lastVxValue));
inner.add(COSInteger.get(lastVyValue));
}
else
{
state = State.FIRST;
inner.add(COSInteger.get(lastW1Value));
inner.add(COSInteger.get(lastVxValue));
inner.add(COSInteger.get(lastVyValue));
outer.add(inner);
outer.add(COSInteger.get(cid));
}
break;
case SERIAL:
if (cid != lastCid + 1 || w1Value != lastW1Value || vxValue != lastVxValue || vyValue != lastVyValue)
{
outer.add(COSInteger.get(lastCid));
outer.add(COSInteger.get(lastW1Value));
outer.add(COSInteger.get(lastVxValue));
outer.add(COSInteger.get(lastVyValue));
outer.add(COSInteger.get(cid));
state = State.FIRST;
}
break;
}
lastW1Value = w1Value;
lastVxValue = vxValue;
lastVyValue = vyValue;
lastCid = cid;
}
switch (state)
{
case FIRST:
inner = new COSArray();
inner.add(COSInteger.get(lastW1Value));
inner.add(COSInteger.get(lastVxValue));
inner.add(COSInteger.get(lastVyValue));
outer.add(inner);
break;
case BRACKET:
inner.add(COSInteger.get(lastW1Value));
inner.add(COSInteger.get(lastVxValue));
inner.add(COSInteger.get(lastVyValue));
outer.add(inner);
break;
case SERIAL:
outer.add(COSInteger.get(lastCid));
outer.add(COSInteger.get(lastW1Value));
outer.add(COSInteger.get(lastVxValue));
outer.add(COSInteger.get(lastVyValue));
break;
}
return outer;
}