public Point2D echarAdvance(final char ech) {

        // create a glyph vector for the char
        float advance;
        float advanceY;

        // check cache for existing layout
        String text = String.valueOf(ech);
        Point2D.Float echarAdvance = echarAdvanceCache.get(text);

        // generate metrics is needed
        if (echarAdvance == null) {

            // the glyph vector should be created using any toUnicode value if present, as this is what we
            // are drawing, the method also does a check to apply differences if toUnicode is null.
            char echGlyph = getCMapping(ech);

            GlyphVector glyphVector = awtFont.createGlyphVector(
                    new FontRenderContext(new AffineTransform(), true, true),
                    String.valueOf(echGlyph));

            FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
            TextLayout textLayout = new TextLayout(String.valueOf(echGlyph), awtFont, frc);

            // get bounds, only need to do this once.
            maxCharBounds = awtFont.getMaxCharBounds(frc);
            ascent = textLayout.getAscent();
            descent = textLayout.getDescent();

            GlyphMetrics glyphMetrics = glyphVector.getGlyphMetrics(0);
            advance = glyphMetrics.getAdvanceX();
            advanceY = glyphMetrics.getAdvanceY();

            echarAdvanceCache.put(text,
                    new Point2D.Float(advance, advanceY));
        }
        // returned cashed value
        else {
            advance = echarAdvance.x;
            advanceY = echarAdvance.y;
        }

        // widths uses original cid's, not the converted to unicode value.
        if (widths != null && ech - firstCh >= 0 && ech - firstCh < widths.length) {
            advance = widths[ech - firstCh] * awtFont.getSize2D();
        } else if (cidWidths != null) {
            Float width = cidWidths.get((int) ech);
            if (width != null) {
                advance = cidWidths.get((int) ech) * awtFont.getSize2D();
            }
        }
        // find any widths in the font descriptor
        else if (missingWidth > 0) {
            advance = missingWidth / 1000f;
        }

        return new Point2D.Float(advance, advanceY);
    }