CMapFormat10(Buffer buffer, int offset) {

      buffer.position(offset + 12);
      startCharCode = buffer.getInt() & INTMASK;
      numChars = buffer.getInt() & INTMASK;
      glyphIdArray = new char[numChars];
      for (int i = 0; i < numChars; i++) {
        glyphIdArray[i] = buffer.getChar();
      }
    }
    CMapFormat12(Buffer buffer, int offset) {

      numGroups = buffer.getInt(offset + 12);
      startCharCode = new long[numGroups];
      endCharCode = new long[numGroups];
      startGlyphID = new int[numGroups];
      buffer.position(offset + 16);
      // REMIND: why slice ?
      // buffer = buffer.slice();
      for (int i = 0; i < numGroups; i++) {
        startCharCode[i] = buffer.getInt() & INTMASK;
        endCharCode[i] = buffer.getInt() & INTMASK;
        startGlyphID[i] = buffer.getInt() & INTMASK;
      }

      /* Finds the high bit by binary searching through the bits */
      int value = numGroups;

      if (value >= 1 << 16) {
        value >>= 16;
        highBit += 16;
      }

      if (value >= 1 << 8) {
        value >>= 8;
        highBit += 8;
      }

      if (value >= 1 << 4) {
        value >>= 4;
        highBit += 4;
      }

      if (value >= 1 << 2) {
        value >>= 2;
        highBit += 2;
      }

      if (value >= 1 << 1) {
        value >>= 1;
        highBit += 1;
      }

      power = 1 << highBit;
      extra = numGroups - power;
    }
  static CMap initialize(PrismFontFile font) {

    CMap cmap = null;

    int offset, platformID, encodingID = -1;

    int three0 = 0, three1 = 0, three10 = 0, zeroStarOffset = 0;
    boolean zeroStar = false, threeStar = false;

    Buffer cmapBuffer = font.readTable(FontConstants.cmapTag);
    short numberSubTables = cmapBuffer.getShort(2);

    /* Locate the offsets of supported 3,* Microsoft platform encodings,
     * and any 0,* Unicode platform encoding. The latter is used by
     * all current OS X fonts that don't have a Microsoft cmap.
     * We will always prefer the Microsoft cmap, for the fonts that
     * provide both. They ought to perform the same mappings. Although
     * I can imagine that a vendor might provide a different looking
     * glyph for some special characters for OS X vs Windows, I'm not
     * actually aware of any such case.
     */
    for (int i = 0; i < numberSubTables; i++) {
      cmapBuffer.position(i * 8 + 4);
      platformID = cmapBuffer.getShort();

      if (platformID == 0) {
        zeroStar = true;
        encodingID = cmapBuffer.getShort();
        zeroStarOffset = cmapBuffer.getInt();
      } else if (platformID == 3) {
        threeStar = true;
        encodingID = cmapBuffer.getShort();
        offset = cmapBuffer.getInt();
        switch (encodingID) {
          case 0:
            three0 = offset;
            break; // MS Symbol encoding
          case 1:
            three1 = offset;
            break; // MS Unicode cmap
          case 10:
            three10 = offset;
            break; // MS Unicode surrogates
        }
      }
    }

    /* This defines the preference order for cmap subtables */
    if (threeStar) {
      if (three10 != 0) {
        cmap = createCMap(cmapBuffer, three10);
      } else if (three0 != 0) {
        cmap = createCMap(cmapBuffer, three0);
      } else if (three1 != 0) {
        cmap = createCMap(cmapBuffer, three1);
      }
    } else if (zeroStar && zeroStarOffset != 0) {
      cmap = createCMap(cmapBuffer, zeroStarOffset);
    } else {
      /* No 0,* or supported 3,* subtable was found.
       * Use whatever is the first table listed.
       * Since these are supposed to be sorted, there's a good chance
       * it will be Mac Roman (1,0). If its not that then its
       * likely a really old font but not one that's found on either
       * Windows or OS X
       * In fact I didn't even find any OS X font that supported
       * only (1,*).
       * So this seems likely to be an untravelled path which is
       * just as well given that its not likely to work properly.
       */
      cmap = createCMap(cmapBuffer, cmapBuffer.getInt(8));
    }
    return cmap;
  }