private int readInt(RandomAccessFileOrArray stream) throws IOException {
   if (isBigEndian) {
     return stream.readInt();
   } else {
     return stream.readIntLE();
   }
 }
Beispiel #2
0
 /**
  * Reads the kerning information from the 'kern' table.
  *
  * @throws IOException the font file could not be read
  */
 void readKerning() throws IOException {
   int table_location[];
   table_location = (int[]) positionTables.get("kern");
   if (table_location == null) return;
   rf.seek(table_location[0] + 2);
   int nTables = rf.readUnsignedShort();
   int checkpoint = table_location[0] + 4;
   int length = 0;
   for (int k = 0; k < nTables; ++k) {
     checkpoint += length;
     rf.seek(checkpoint);
     rf.skipBytes(2);
     length = rf.readUnsignedShort();
     int coverage = rf.readUnsignedShort();
     if ((coverage & 0xfff7) == 0x0001) {
       int nPairs = rf.readUnsignedShort();
       rf.skipBytes(6);
       for (int j = 0; j < nPairs; ++j) {
         int pair = rf.readInt();
         int value = ((int) rf.readShort() * 1000) / head.unitsPerEm;
         kerning.put(pair, value);
       }
     }
   }
 }
Beispiel #3
0
 /**
  * Reads the several maps from the table 'cmap'. The maps of interest are 1.0 for symbolic fonts
  * and 3.1 for all others. A symbolic font is defined as having the map 3.0.
  *
  * @throws DocumentException the font is invalid
  * @throws IOException the font file could not be read
  */
 public void readCMaps() throws DocumentException, IOException {
   int table_location[];
   table_location = (int[]) positionTables.get("cmap");
   if (table_location == null)
     throw new DocumentException("Table 'cmap' does not exist in " + fileName + style);
   rf.seek(table_location[0]);
   rf.skipBytes(2);
   int num_tables = rf.readUnsignedShort();
   fontSpecific = false;
   int map10 = 0;
   int map31 = 0;
   int map30 = 0;
   for (int k = 0; k < num_tables; ++k) {
     int platId = rf.readUnsignedShort();
     int platSpecId = rf.readUnsignedShort();
     int offset = rf.readInt();
     if (platId == 3 && platSpecId == 0) {
       fontSpecific = true;
       map30 = offset;
     } else if (platId == 3 && platSpecId == 1) {
       map31 = offset;
     }
     if (platId == 1 && platSpecId == 0) {
       map10 = offset;
     }
   }
   if (map10 > 0) {
     rf.seek(table_location[0] + map10);
     int format = rf.readUnsignedShort();
     switch (format) {
       case 0:
         cmap10 = readFormat0();
         break;
       case 4:
         cmap10 = readFormat4();
         break;
       case 6:
         cmap10 = readFormat6();
         break;
     }
   }
   if (map31 > 0) {
     rf.seek(table_location[0] + map31);
     int format = rf.readUnsignedShort();
     if (format == 4) {
       cmap31 = readFormat4();
     }
   }
   if (map30 > 0) {
     rf.seek(table_location[0] + map30);
     int format = rf.readUnsignedShort();
     if (format == 4) {
       cmap10 = readFormat4();
     }
   }
 }
Beispiel #4
0
 private void processPost() throws DocumentException, IOException {
   int[] tableLocation = getTableLocation("post");
   if (tableLocation == null) {
     italicAngle = -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI;
     return;
   }
   rf.seek(tableLocation[0] + 4);
   short mantissa = rf.readShort();
   int fraction = rf.readUnsignedShort();
   italicAngle = (double) mantissa + (double) fraction / 16384.0;
   underlinePosition = (double) rf.readShort() / head.unitsPerEm;
   underlineThickness = (double) rf.readShort() / head.unitsPerEm;
   isFixedPitch = rf.readInt() != 0;
 }
Beispiel #5
0
 private int[] getGlyphDataPosition(int glyphIndex) throws IOException {
   int[] glyphDataPosition = new int[2];
   int[] tableLocation = (int[]) positionTables.get("loca");
   int offset = tableLocation[0] + head.locaBytesPerEntry * glyphIndex;
   rf.seek(offset);
   if (head.locaBytesPerEntry == 4) {
     glyphDataPosition[0] = rf.readInt();
     glyphDataPosition[1] = rf.readInt() - glyphDataPosition[0];
   } else {
     glyphDataPosition[0] = rf.readUnsignedShort() * 2;
     glyphDataPosition[1] = rf.readUnsignedShort() * 2 - glyphDataPosition[0];
   }
   return glyphDataPosition;
 }
Beispiel #6
0
 private void fillOS() throws DocumentException, IOException {
   int[] tableLocation = getTableLocation("OS/2");
   rf.seek(tableLocation[0]);
   int version = rf.readUnsignedShort();
   os_2.xAvgCharWidth = rf.readShort();
   os_2.usWeightClass = rf.readUnsignedShort();
   os_2.usWidthClass = rf.readUnsignedShort();
   os_2.fsType = rf.readShort();
   os_2.ySubscriptXSize = rf.readShort();
   os_2.ySubscriptYSize = rf.readShort();
   os_2.ySubscriptXOffset = rf.readShort();
   os_2.ySubscriptYOffset = rf.readShort();
   os_2.ySuperscriptXSize = rf.readShort();
   os_2.ySuperscriptYSize = rf.readShort();
   os_2.ySuperscriptXOffset = rf.readShort();
   os_2.ySuperscriptYOffset = rf.readShort();
   os_2.yStrikeoutSize = rf.readShort();
   os_2.yStrikeoutPosition = rf.readShort();
   os_2.sFamilyClass = rf.readShort();
   rf.readFully(os_2.panose);
   rf.skipBytes(16);
   rf.readFully(os_2.achVendID);
   os_2.fsSelection = rf.readUnsignedShort();
   os_2.usFirstCharIndex = rf.readUnsignedShort();
   os_2.usLastCharIndex = rf.readUnsignedShort();
   os_2.sTypoAscender = rf.readShort();
   os_2.sTypoDescender = rf.readShort();
   if (os_2.sTypoDescender > 0) os_2.sTypoDescender = (short) (-os_2.sTypoDescender);
   os_2.sTypoLineGap = rf.readShort();
   os_2.usWinAscent = rf.readUnsignedShort();
   os_2.usWinDescent = rf.readUnsignedShort();
   os_2.ulCodePageRange1 = 0;
   os_2.ulCodePageRange2 = 0;
   if (version > 0) {
     os_2.ulCodePageRange1 = rf.readInt();
     os_2.ulCodePageRange2 = rf.readInt();
   }
   if (version > 1) {
     rf.skipBytes(2);
     os_2.sCapHeight = rf.readShort();
   } else os_2.sCapHeight = (int) (0.7 * head.unitsPerEm);
 }
Beispiel #7
0
 private void readBbox() throws DocumentException, IOException {
   int tableLocation[];
   tableLocation = (int[]) positionTables.get("head");
   if (tableLocation == null)
     throw new DocumentException("Table 'head' does not exist in " + fileName + style);
   rf.seek(tableLocation[0] + HEAD_LOCA_FORMAT_OFFSET);
   boolean locaShortTable = (rf.readUnsignedShort() == 0);
   tableLocation = (int[]) positionTables.get("loca");
   if (tableLocation == null) return;
   rf.seek(tableLocation[0]);
   int locaTable[];
   if (locaShortTable) {
     int entries = tableLocation[1] / 2;
     locaTable = new int[entries];
     for (int k = 0; k < entries; ++k) locaTable[k] = rf.readUnsignedShort() * 2;
   } else {
     int entries = tableLocation[1] / 4;
     locaTable = new int[entries];
     for (int k = 0; k < entries; ++k) locaTable[k] = rf.readInt();
   }
   tableLocation = (int[]) positionTables.get("glyf");
   if (tableLocation == null)
     throw new DocumentException("Table 'glyf' does not exist in " + fileName + style);
   int tableGlyphOffset = tableLocation[0];
   bboxes = new int[locaTable.length - 1][];
   for (int glyph = 0; glyph < locaTable.length - 1; ++glyph) {
     int start = locaTable[glyph];
     if (start != locaTable[glyph + 1]) {
       rf.seek(tableGlyphOffset + start + 2);
       bboxes[glyph] =
           new int[] {
             (rf.readShort() * 1000) / head.unitsPerEm,
             (rf.readShort() * 1000) / head.unitsPerEm,
             (rf.readShort() * 1000) / head.unitsPerEm,
             (rf.readShort() * 1000) / head.unitsPerEm
           };
     }
   }
 }
Beispiel #8
0
  /**
   * Reads the font data.
   *
   * @param ttfAfm the font as a <CODE>byte</CODE> array, possibly <CODE>null</CODE>
   * @throws DocumentException the font is invalid
   * @throws IOException the font file could not be read
   */
  void process() throws DocumentException, IOException {
    positionTables = new HashMap<String, int[]>();
    metadataTables = new HashMap<String, byte[]>();

    try {
      rf = new RandomAccessFileOrArray(fileName);
      if (ttcIndex.length() > 0) {
        int dirIdx = Integer.parseInt(ttcIndex);
        if (dirIdx < 0)
          throw new DocumentException("The font index for " + fileName + " must be positive.");
        String mainTag = readStandardString(4);
        if (!mainTag.equals("ttcf"))
          throw new DocumentException(fileName + " is not a valid TTC file.");
        rf.skipBytes(4);
        int dirCount = rf.readInt();
        if (dirIdx >= dirCount)
          throw new DocumentException(
              "The font index for "
                  + fileName
                  + " must be between 0 and "
                  + (dirCount - 1)
                  + ". It was "
                  + dirIdx
                  + ".");
        rf.skipBytes(dirIdx * 4);
        directoryOffset = rf.readInt();
      }
      rf.seek(directoryOffset);
      rf.readFully(directoryRawData);
      int ttId = Util.getInt(directoryRawData, 0);
      if (ttId != 0x00010000 && ttId != 0x4F54544F)
        throw new DocumentException(fileName + " is not a valid TTF or OTF file.");
      int num_tables = Util.getUnsignedShort(directoryRawData, 4);
      for (int k = 0; k < num_tables; ++k) {
        byte[] rawData = new byte[16];
        rf.readFully(rawData);
        String tag = getStandardString(rawData, 0, 4);
        int table_location[] = new int[2];
        table_location[0] = Util.getInt(rawData, 8);
        table_location[1] = Util.getInt(rawData, 12);
        positionTables.put(tag, table_location);
        metadataTables.put(tag, rawData);
      }
      fontName = getBaseFont();
      fullName = getNames(4); // full name
      familyName = getNames(1); // family name
      notice = getNames(0);
      version = getNames(5);

      if (!justNames) {
        fillTables();
        readGlyphWidths();
        readCMaps();
        readKerning();
        readBbox();
        GlyphWidths = null;
      }
    } finally {
      if (rf != null) {
        rf.close();
        if (!embedded) rf = null;
      }
    }
  }