private final void readKerning(FontFileReader in) throws IOException {
        // Read kerning
        kerningTab = new java.util.HashMap();
        ansiKerningTab = new java.util.HashMap();
        TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("kern");
        if (dirTab != null) {
            seekTab(in, "kern", 2);
            for (int n = in.readTTFUShort(); n > 0; n--) {
                in.skip(2 * 2);
                int k = in.readTTFUShort();
                if (!((k & 1) != 0) || (k & 2) != 0 || (k & 4) != 0) {
                    return;
                }
                if ((k >> 8) != 0) {
                    continue;
                }

                k = in.readTTFUShort();
                in.skip(3 * 2);
                while (k-- > 0) {
                    int i = in.readTTFUShort();
                    int j = in.readTTFUShort();
                    int kpx = in.readTTFShort();
                    if (kpx != 0) {
                        // CID kerning table entry, using unicode indexes
                        final Integer iObj = glyphToUnicode(i);
                        final Integer u2 = glyphToUnicode(j);
                        if(iObj==null) {
                            // happens for many fonts (Ubuntu font set),
                            // stray entries in the kerning table?? 
                            log.warn("Unicode index (1) not found for glyph " + i);
                        } else if(u2==null) {
                            log.warn("Unicode index (2) not found for glyph " + i);
                        } else {
                            Map adjTab = (Map)kerningTab.get(iObj);
                            if (adjTab == null) {
                                adjTab = new java.util.HashMap();
                            }
                            adjTab.put(u2,new Integer(kpx));
                            kerningTab.put(iObj, adjTab);
                        }
                    }
                }
            }

            // Create winAnsiEncoded kerning table from kerningTab
            // (could probably be simplified, for now we remap back to CID indexes and then to winAnsi)
            Iterator ae = kerningTab.keySet().iterator();
            while (ae.hasNext()) {
                Integer unicodeKey1 = (Integer)ae.next();
                Integer cidKey1 = unicodeToGlyph(unicodeKey1.intValue());
                Map akpx = new java.util.HashMap();
                Map ckpx = (Map)kerningTab.get(unicodeKey1);

                Iterator aee = ckpx.keySet().iterator();
                while (aee.hasNext()) {
                    Integer unicodeKey2 = (Integer)aee.next();
                    Integer cidKey2 = unicodeToGlyph(unicodeKey2.intValue());
                    Integer kern = (Integer)ckpx.get(unicodeKey2);

                    Iterator uniMap = mtxTab[cidKey2.intValue()].getUnicodeIndex().listIterator();
                    while (uniMap.hasNext()) {
                        Integer unicodeKey = (Integer)uniMap.next();
                        Integer[] ansiKeys = unicodeToWinAnsi(unicodeKey.intValue());
                        for (int u = 0; u < ansiKeys.length; u++) {
                            akpx.put(ansiKeys[u], kern);
                        }
                    }
                }

                if (akpx.size() > 0) {
                    Iterator uniMap = mtxTab[cidKey1.intValue()].getUnicodeIndex().listIterator();
                    while (uniMap.hasNext()) {
                        Integer unicodeKey = (Integer)uniMap.next();
                        Integer[] ansiKeys = unicodeToWinAnsi(unicodeKey.intValue());
                        for (int u = 0; u < ansiKeys.length; u++) {
                            ansiKerningTab.put(ansiKeys[u], akpx);
                        }
                    }
                }
            }
        }
    }
private final void readKerning ( FontFileReader in ) throws IOException { kerningTab = new java . util . HashMap ( ) ; ansiKerningTab = new java . util . HashMap ( ) ; TTFDirTabEntry dirTab = ( TTFDirTabEntry ) dirTabs . get ( "kern" ) ; if ( dirTab != null ) { seekTab ( in , "kern" , 2 ) ; for ( int n = in . readTTFUShort ( ) ; n > 0 ; n -- ) { in . skip ( 2 * 2 ) ; int k = in . readTTFUShort ( ) ; if ( ! ( ( k & 1 ) != 0 ) || ( k & 2 ) != 0 || ( k & 4 ) != 0 ) { return ; } if ( ( k > > 8 ) != 0 ) { continue ; } k = in . readTTFUShort ( ) ; in . skip ( 3 * 2 ) ; while ( k -- > 0 ) { int i = in . readTTFUShort ( ) ; int j = in . readTTFUShort ( ) ; int kpx = in . readTTFShort ( ) ; if ( kpx != 0 ) { final Integer iObj = glyphToUnicode ( i ) ; final Integer u2 = glyphToUnicode ( j ) ; if ( iObj == null ) { log . warn ( "Unicode index (1) not found for glyph " + i ) ; } else if ( u2 == null ) { log . warn ( "Unicode index (2) not found for glyph " + i ) ; } else { Map adjTab = ( Map ) kerningTab . get ( iObj ) ; if ( adjTab == null ) { adjTab = new java . util . HashMap ( ) ; } adjTab . put ( u2 , new Integer ( kpx ) ) ; kerningTab . put ( iObj , adjTab ) ; } } } } Iterator ae = kerningTab . keySet ( ) . iterator ( ) ; while ( ae . hasNext ( ) ) { Integer unicodeKey1 = ( Integer ) ae . next ( ) ; Integer cidKey1 = unicodeToGlyph ( unicodeKey1 . intValue ( ) ) ; Map akpx = new java . util . HashMap ( ) ; Map ckpx = ( Map ) kerningTab . get ( unicodeKey1 ) ; Iterator aee = ckpx . keySet ( ) . iterator ( ) ; while ( aee . hasNext ( ) ) { Integer unicodeKey2 = ( Integer ) aee . next ( ) ; Integer cidKey2 = unicodeToGlyph ( unicodeKey2 . intValue ( ) ) ; Integer kern = ( Integer ) ckpx . get ( unicodeKey2 ) ; Iterator uniMap = mtxTab [ cidKey2 . intValue ( ) ] . getUnicodeIndex ( ) . listIterator ( ) ; while ( uniMap . hasNext ( ) ) { Integer unicodeKey = ( Integer ) uniMap . next ( ) ; Integer [ ] ansiKeys = unicodeToWinAnsi ( unicodeKey . intValue ( ) ) ; for ( int u = 0 ; u < ansiKeys . length ; u ++ ) { akpx . put ( ansiKeys [ u ] , kern ) ; } } } if ( akpx . size ( ) > 0 ) { Iterator uniMap = mtxTab [ cidKey1 . intValue ( ) ] . getUnicodeIndex ( ) . listIterator ( ) ; while ( uniMap . hasNext ( ) ) { Integer unicodeKey = ( Integer ) uniMap . next ( ) ; Integer [ ] ansiKeys = unicodeToWinAnsi ( unicodeKey . intValue ( ) ) ; for ( int u = 0 ; u < ansiKeys . length ; u ++ ) { ansiKerningTab . put ( ansiKeys [ u ] , akpx ) ; } } } } } }
Read the kerning table, create a table for both CIDs and
winAnsiEncoding.
@param in FontFileReader to read from
@throws IOException In case of a I/O problem