private COSArray getVerticalMetrics()

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;
    }