public ByteBuffer getData() {
        ByteBuffer buf = ByteBuffer.allocate(getLength());
    
        // write the header
        buf.putShort(getFormat());
        buf.putShort((short) getLength());
        buf.putShort(getLanguage());
        
        // write the various values
        buf.putShort((short) (getSegmentCount() * 2));
        buf.putShort(getSearchRange());
        buf.putShort(getEntrySelector());
        buf.putShort(getRangeShift());
        
        // write the endCodes
        for (Iterator i = segments.keySet().iterator(); i.hasNext();) {
            Segment s = (Segment) i.next();
            buf.putShort((short) s.endCode);
        }
        
        // write the pad
        buf.putShort((short) 0);
        
        // write the startCodes
        for (Iterator i = segments.keySet().iterator(); i.hasNext();) {
            Segment s = (Segment) i.next();
            buf.putShort((short) s.startCode);
        }
        
        // write the idDeltas for segments using deltas
        for (Iterator i = segments.keySet().iterator(); i.hasNext();) {
            Segment s = (Segment) i.next();
            
            if (!s.hasMap) {
                Integer idDelta = (Integer) segments.get(s);
                buf.putShort(idDelta.shortValue());
            } else {
                buf.putShort((short) 0);
            }
        }
        
        // the start of the glyph array
        int glyphArrayOffset = 16 + (8 * getSegmentCount());
        
        // write the idRangeOffsets and maps for segments using maps
        for (Iterator i = segments.keySet().iterator(); i.hasNext();) {
            Segment s = (Segment) i.next();
            
            if (s.hasMap) {
                // first set the offset, which is the number of bytes from the
                // current position to the current offset
                buf.putShort((short) (glyphArrayOffset - buf.position()));
                
                // remember the current position
                buf.mark();
                
                // move the position to the offset
                buf.position(glyphArrayOffset);
                
                // now write the map
                char[] map = (char[]) segments.get(s);
                for (int c = 0; c < map.length; c++) {
                    buf.putChar(map[c]);
                }
                
                // reset the data pointer
                buf.reset();
                
                // update the offset
                glyphArrayOffset += map.length * 2;
            } else {
                buf.putShort((short) 0);
            }
        }

        // make sure we are at the end of the buffer before we flip
        buf.position(glyphArrayOffset);
        
        // reset the data pointer
        buf.flip();
        
        return buf;
    }