Example #1
0
 private double readDouble(RandomAccessFileOrArray stream) throws IOException {
   if (isBigEndian) {
     return stream.readDouble();
   } else {
     return stream.readDoubleLE();
   }
 }
Example #2
0
 private long readLong(RandomAccessFileOrArray stream) throws IOException {
   if (isBigEndian) {
     return stream.readLong();
   } else {
     return stream.readLongLE();
   }
 }
Example #3
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);
       }
     }
   }
 }
Example #4
0
 private float readFloat(RandomAccessFileOrArray stream) throws IOException {
   if (isBigEndian) {
     return stream.readFloat();
   } else {
     return stream.readFloatLE();
   }
 }
Example #5
0
 private int readUnsignedShort(RandomAccessFileOrArray stream) throws IOException {
   if (isBigEndian) {
     return stream.readUnsignedShort();
   } else {
     return stream.readUnsignedShortLE();
   }
 }
Example #6
0
 private static long readUnsignedInt(RandomAccessFileOrArray stream, boolean isBigEndian)
     throws IOException {
   if (isBigEndian) {
     return stream.readUnsignedInt();
   } else {
     return stream.readUnsignedIntLE();
   }
 }
Example #7
0
 /**
  * The information in the maps of the table 'cmap' is coded in several formats. Format 0 is the
  * Apple standard character to glyph index mapping table.
  *
  * @return a <CODE>HashMap</CODE> representing this map
  * @throws IOException the font file could not be read
  */
 HashMap<Integer, int[]> readFormat0() throws IOException {
   HashMap<Integer, int[]> h = new HashMap<Integer, int[]>();
   rf.skipBytes(4);
   for (int k = 0; k < 256; ++k) {
     int r[] = new int[2];
     r[0] = rf.readUnsignedByte();
     r[1] = getGlyphWidth(r[0]);
     h.put(k, r);
   }
   return h;
 }
Example #8
0
 /**
  * Reads the glyphs widths. The widths are extracted from the table 'hmtx'. The glyphs are
  * normalized to 1000 units.
  *
  * @throws DocumentException the font is invalid
  * @throws IOException the font file could not be read
  */
 protected void readGlyphWidths() throws DocumentException, IOException {
   int table_location[];
   table_location = (int[]) positionTables.get("hmtx");
   if (table_location == null)
     throw new DocumentException("Table 'hmtx' does not exist in " + fileName + style);
   rf.seek(table_location[0]);
   GlyphWidths = new int[hhea.numberOfHMetrics];
   for (int k = 0; k < hhea.numberOfHMetrics; ++k) {
     GlyphWidths[k] = (rf.readUnsignedShort() * 1000) / head.unitsPerEm;
     rf.readUnsignedShort();
   }
 }
Example #9
0
 public byte[] getGlyphData(int glyph) throws IOException {
   int dataOffsetRelativeToGlyfTable, dataLength;
   int[] glyphDataPosition = getGlyphDataPosition(glyph);
   dataOffsetRelativeToGlyfTable = glyphDataPosition[0];
   dataLength = glyphDataPosition[1];
   int[] glyphLocation = (int[]) positionTables.get("glyf");
   int dataOffset = dataOffsetRelativeToGlyfTable + glyphLocation[0];
   byte[] result = new byte[dataLength];
   rf.seek(dataOffset);
   rf.readFully(result);
   return result;
 }
Example #10
0
 /**
  * The information in the maps of the table 'cmap' is coded in several formats. Format 6 is a
  * trimmed table mapping. It is similar to format 0 but can have less than 256 entries.
  *
  * @return a <CODE>HashMap</CODE> representing this map
  * @throws IOException the font file could not be read
  */
 HashMap<Integer, int[]> readFormat6() throws IOException {
   HashMap<Integer, int[]> h = new HashMap<Integer, int[]>();
   rf.skipBytes(4);
   int start_code = rf.readUnsignedShort();
   int code_count = rf.readUnsignedShort();
   for (int k = 0; k < code_count; ++k) {
     int r[] = new int[2];
     r[0] = rf.readUnsignedShort();
     r[1] = getGlyphWidth(r[0]);
     h.put(k + start_code, r);
   }
   return h;
 }
Example #11
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;
 }
Example #12
0
  public static void populateDescription(String path, BaseFont font, FontDescription descr)
      throws IOException, NoSuchFieldException, IllegalAccessException, DocumentException {
    RandomAccessFileOrArray rf = null;
    try {
      rf = new RandomAccessFileOrArray(getTTCName(path));

      rf = populateDescription0(path, font, descr, rf);
    } finally {
      if (rf != null) {
        try {
          rf.close();
        } catch (IOException e) {
          // ignore
        }
      }
    }
  }
Example #13
0
 /**
  * Reads a Unicode <CODE>String</CODE> from the font file. Each character is represented by two
  * bytes.
  *
  * @param length the length of bytes to read. The <CODE>String</CODE> will have <CODE>length
  *     </CODE>/2 characters
  * @return the <CODE>String</CODE> read
  * @throws IOException the font file could not be read
  */
 protected String readUnicodeString(int length) throws IOException {
   StringBuffer buf = new StringBuffer();
   length /= 2;
   for (int k = 0; k < length; ++k) {
     buf.append(rf.readChar());
   }
   return buf.toString();
 }
Example #14
0
 /**
  * The information in the maps of the table 'cmap' is coded in several formats. Format 4 is the
  * Microsoft standard character to glyph index mapping table.
  *
  * @return a <CODE>HashMap</CODE> representing this map
  * @throws IOException the font file could not be read
  */
 HashMap<Integer, int[]> readFormat4() throws IOException {
   HashMap<Integer, int[]> h = new HashMap<Integer, int[]>();
   int table_lenght = rf.readUnsignedShort();
   rf.skipBytes(2);
   int segCount = rf.readUnsignedShort() / 2;
   rf.skipBytes(6);
   int endCount[] = new int[segCount];
   for (int k = 0; k < segCount; ++k) {
     endCount[k] = rf.readUnsignedShort();
   }
   rf.skipBytes(2);
   int startCount[] = new int[segCount];
   for (int k = 0; k < segCount; ++k) {
     startCount[k] = rf.readUnsignedShort();
   }
   int idDelta[] = new int[segCount];
   for (int k = 0; k < segCount; ++k) {
     idDelta[k] = rf.readUnsignedShort();
   }
   int idRO[] = new int[segCount];
   for (int k = 0; k < segCount; ++k) {
     idRO[k] = rf.readUnsignedShort();
   }
   int glyphId[] = new int[table_lenght / 2 - 8 - segCount * 4];
   for (int k = 0; k < glyphId.length; ++k) {
     glyphId[k] = rf.readUnsignedShort();
   }
   for (int k = 0; k < segCount; ++k) {
     int glyph;
     for (int j = startCount[k]; j <= endCount[k] && j != 0xFFFF; ++j) {
       if (idRO[k] == 0) {
         glyph = (j + idDelta[k]) & 0xFFFF;
       } else {
         int idx = k + idRO[k] / 2 - segCount + j - startCount[k];
         if (idx >= glyphId.length) continue;
         glyph = (glyphId[idx] + idDelta[k]) & 0xFFFF;
       }
       int r[] = new int[2];
       r[0] = glyph;
       r[1] = getGlyphWidth(r[0]);
       h.put((fontSpecific ? ((j & 0xff00) == 0xf000 ? j & 0xff : j) : j), r);
     }
   }
   return h;
 }
Example #15
0
 /**
  * Gets the Postscript font name.
  *
  * @throws DocumentException the font is invalid
  * @throws IOException the font file could not be read
  * @return the Postscript font name
  */
 String getBaseFont() throws DocumentException, IOException {
   int table_location[];
   table_location = (int[]) positionTables.get("name");
   if (table_location == null)
     throw new DocumentException("Table 'name' does not exist in " + fileName + style);
   rf.seek(table_location[0] + 2);
   int numRecords = rf.readUnsignedShort();
   int startOfStorage = rf.readUnsignedShort();
   for (int k = 0; k < numRecords; ++k) {
     int platformID = rf.readUnsignedShort();
     int nameID = rf.readUnsignedShort();
     int length = rf.readUnsignedShort();
     int offset = rf.readUnsignedShort();
     if (nameID == 6) {
       rf.seek(table_location[0] + startOfStorage + offset);
       if (platformID != 0 && platformID != 3) {
         String name = readStandardString(length);
         name = name.replace(' ', '_');
         return name.replace((char) 0, '_');
       }
     }
   }
   File file = new File(fileName);
   return file.getName().replace(' ', '_');
 }
Example #16
0
  public TIFFDirectory(RandomAccessFileOrArray stream, int directory) throws IOException {

    long global_save_offset = stream.getFilePointer();
    long ifd_offset;

    stream.seek(0L);
    int endian = stream.readUnsignedShort();
    if (!isValidEndianTag(endian)) {
      throw new IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
    }
    isBigEndian = (endian == 0x4d4d);

    int magic = readUnsignedShort(stream);
    if (magic != 42) {
      throw new IllegalArgumentException("Bad magic number, should be 42.");
    }

    ifd_offset = readUnsignedInt(stream);

    for (int i = 0; i < directory; i++) {
      if (ifd_offset == 0L) {
        throw new IllegalArgumentException("Directory number too large.");
      }

      stream.seek(ifd_offset);
      int entries = readUnsignedShort(stream);
      stream.skip(12 * entries);

      ifd_offset = readUnsignedInt(stream);
    }

    stream.seek(ifd_offset);
    initialize(stream);
    stream.seek(global_save_offset);
  }
Example #17
0
  public TIFFDirectory(RandomAccessFileOrArray stream, long ifd_offset, int directory)
      throws IOException {

    long global_save_offset = stream.getFilePointer();
    stream.seek(0L);
    int endian = stream.readUnsignedShort();
    if (!isValidEndianTag(endian)) {
      throw new IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
    }
    isBigEndian = (endian == 0x4d4d);

    stream.seek(ifd_offset);

    int dirNum = 0;
    while (dirNum < directory) {

      int numEntries = readUnsignedShort(stream);

      stream.seek(ifd_offset + 12 * numEntries);

      ifd_offset = readUnsignedInt(stream);

      stream.seek(ifd_offset);

      dirNum++;
    }

    initialize(stream);
    stream.seek(global_save_offset);
  }
Example #18
0
  public static int getNumDirectories(RandomAccessFileOrArray stream) throws IOException {
    long pointer = stream.getFilePointer();

    stream.seek(0L);
    int endian = stream.readUnsignedShort();
    if (!isValidEndianTag(endian)) {
      throw new IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
    }
    boolean isBigEndian = (endian == 0x4d4d);
    int magic = readUnsignedShort(stream, isBigEndian);
    if (magic != 42) {
      throw new IllegalArgumentException("Bad magic number, should be 42.");
    }

    stream.seek(4L);
    long offset = readUnsignedInt(stream, isBigEndian);

    int numDirectories = 0;
    while (offset != 0L) {
      ++numDirectories;

      try {
        stream.seek(offset);
        int entries = readUnsignedShort(stream, isBigEndian);
        stream.skip(12 * entries);
        offset = readUnsignedInt(stream, isBigEndian);
      } catch (EOFException eof) {

        break;
      }
    }

    stream.seek(pointer);
    return numDirectories;
  }
Example #19
0
 private List<byte[]> readTable(String name) throws DocumentException, IOException {
   int[] tableLocation = getTableLocation(name);
   if (tableLocation == null) {
     return null;
   }
   rf.seek(tableLocation[0]);
   byte[] data = readData(getEvenLength(tableLocation[1]));
   return split(data);
 }
Example #20
0
 /**
  * Reads a <CODE>String</CODE> from the font file as bytes using the Cp1252 encoding.
  *
  * @param length the length of bytes to read
  * @return the <CODE>String</CODE> read
  * @throws IOException the font file could not be read
  */
 protected String readStandardString(int length) throws IOException {
   byte buf[] = new byte[length];
   rf.readFully(buf);
   try {
     return new String(buf, WINANSI);
   } catch (Exception e) {
     throw new ExceptionConverter(e);
   }
 }
Example #21
0
 private void fillHead() throws DocumentException, IOException {
   int tableLocation[] = getTableLocation("head");
   rf.seek(tableLocation[0] + 16);
   head.flags = rf.readUnsignedShort();
   head.unitsPerEm = rf.readUnsignedShort();
   rf.skipBytes(16);
   head.xMin = rf.readShort();
   head.yMin = rf.readShort();
   head.xMax = rf.readShort();
   head.yMax = rf.readShort();
   head.macStyle = rf.readUnsignedShort();
   rf.skip(4);
   int indexToLocFormat = rf.readUnsignedShort();
   head.locaBytesPerEntry = indexToLocFormat == 0 ? 2 : 4;
 }
  /** @see com.lowagie.toolbox.AbstractTool#execute() */
  public void execute() {
    try {
      if (getValue("odd") == null)
        throw new InstantiationException("You need to choose a sourcefile for the odd pages");
      File odd_file = (File) getValue("odd");
      if (getValue("even") == null)
        throw new InstantiationException("You need to choose a sourcefile for the even pages");
      File even_file = (File) getValue("even");
      if (getValue("destfile") == null)
        throw new InstantiationException("You need to choose a destination file");
      File pdf_file = (File) getValue("destfile");
      RandomAccessFileOrArray odd = new RandomAccessFileOrArray(odd_file.getAbsolutePath());
      RandomAccessFileOrArray even = new RandomAccessFileOrArray(even_file.getAbsolutePath());
      Image img = TiffImage.getTiffImage(odd, 1);
      Document document = new Document(new Rectangle(img.getScaledWidth(), img.getScaledHeight()));
      PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf_file));
      document.open();
      PdfContentByte cb = writer.getDirectContent();
      int count = Math.max(TiffImage.getNumberOfPages(odd), TiffImage.getNumberOfPages(even));
      for (int c = 0; c < count; ++c) {
        try {
          Image imgOdd = TiffImage.getTiffImage(odd, c + 1);
          Image imgEven = TiffImage.getTiffImage(even, count - c);
          document.setPageSize(new Rectangle(imgOdd.getScaledWidth(), imgOdd.getScaledHeight()));
          document.newPage();
          imgOdd.setAbsolutePosition(0, 0);
          cb.addImage(imgOdd);
          document.setPageSize(new Rectangle(imgEven.getScaledWidth(), imgEven.getScaledHeight()));
          document.newPage();
          imgEven.setAbsolutePosition(0, 0);
          cb.addImage(imgEven);

        } catch (Exception e) {
          System.out.println("Exception page " + (c + 1) + " " + e.getMessage());
        }
      }
      odd.close();
      even.close();
      document.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Example #23
0
 protected List<TrueTypeGlyph> getCharactersToOutput(int glyph) throws IOException {
   ArrayList<TrueTypeGlyph> characters = new ArrayList<TrueTypeGlyph>();
   int[] glyphDataPosition = getGlyphDataPosition(glyph);
   int glyphDataOffset = glyphDataPosition[0];
   int glyphDataLength = glyphDataPosition[1];
   if (glyphDataLength == 0) // no contour
   return characters;
   int tableGlyphOffset = ((int[]) positionTables.get("glyf"))[0];
   rf.seek(tableGlyphOffset + glyphDataOffset);
   int numContours = rf.readShort();
   if (numContours >= 0) return characters;
   rf.skipBytes(8);
   for (; ; ) {
     int flags = rf.readUnsignedShort();
     Integer cGlyph = rf.readUnsignedShort();
     TrueTypeGlyph trueTypeGlyph = new TrueTypeGlyph(cGlyph.intValue());
     if (!glyphDefined.contains(trueTypeGlyph)) {
       characters.add(trueTypeGlyph);
     }
     if ((flags & MORE_COMPONENTS) == 0) return characters;
     int skip;
     if ((flags & ARG_1_AND_2_ARE_WORDS) != 0) skip = 4;
     else skip = 2;
     if ((flags & WE_HAVE_A_SCALE) != 0) skip += 2;
     else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0) skip += 4;
     if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0) skip += 8;
     rf.skipBytes(skip);
   }
 }
Example #24
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;
 }
Example #25
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
           };
     }
   }
 }
Example #26
0
  private static RandomAccessFileOrArray populateDescription0(
      String path, BaseFont font, FontDescription descr, RandomAccessFileOrArray rf)
      throws NoSuchFieldException, IllegalAccessException, DocumentException, IOException {
    Map tables = extractTables(font);

    descr.setStyle(guessStyle(font));

    int[] location = (int[]) tables.get("OS/2");
    if (location == null) {
      throw new DocumentException("Table 'OS/2' does not exist in " + path);
    }
    rf.seek(location[0]);
    int want = 4;
    long got = rf.skip(want);
    if (got < want) {
      throw new DocumentException(
          "Skip TT font weight, expect read " + want + " bytes, but only got " + got);
    }
    descr.setWeight(rf.readUnsignedShort());
    want = 20;
    got = rf.skip(want);
    if (got < want) {
      throw new DocumentException(
          "Skip TT font strikeout, expect read " + want + " bytes, but only got " + got);
    }
    descr.setYStrikeoutSize(rf.readShort());
    descr.setYStrikeoutPosition(rf.readShort());

    location = (int[]) tables.get("post");

    if (location != null) {
      rf.seek(location[0]);
      want = 8;
      got = rf.skip(want);
      if (got < want) {
        throw new DocumentException(
            "Skip TT font underline, expect read " + want + " bytes, but only got " + got);
      }
      descr.setUnderlinePosition(rf.readShort());
      descr.setUnderlineThickness(rf.readShort());
    }

    rf.close();
    rf = null;
    return rf;
  }
Example #27
0
 /**
  * Extracts the names of the font in all the languages available.
  *
  * @param id the name id to retrieve
  * @throws DocumentException on error
  * @throws IOException on error
  */
 String[][] getNames(int id) throws DocumentException, IOException {
   int table_location[];
   table_location = (int[]) positionTables.get("name");
   if (table_location == null)
     throw new DocumentException("Table 'name' does not exist in " + fileName + style);
   rf.seek(table_location[0] + 2);
   int numRecords = rf.readUnsignedShort();
   int startOfStorage = rf.readUnsignedShort();
   ArrayList<String[]> names = new ArrayList<String[]>();
   for (int k = 0; k < numRecords; ++k) {
     int platformID = rf.readUnsignedShort();
     int platformEncodingID = rf.readUnsignedShort();
     int languageID = rf.readUnsignedShort();
     int nameID = rf.readUnsignedShort();
     int length = rf.readUnsignedShort();
     int offset = rf.readUnsignedShort();
     if (nameID == id) {
       int pos = rf.getFilePointer();
       rf.seek(table_location[0] + startOfStorage + offset);
       String name;
       if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)) {
         name = readUnicodeString(length);
       } else {
         name = readStandardString(length);
       }
       names.add(
           new String[] {
             String.valueOf(platformID),
             String.valueOf(platformEncodingID),
             String.valueOf(languageID),
             name
           });
       rf.seek(pos);
     }
   }
   String thisName[][] = new String[names.size()][];
   for (int k = 0; k < names.size(); ++k) thisName[k] = (String[]) names.get(k);
   return thisName;
 }
Example #28
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;
      }
    }
  }
Example #29
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();
     }
   }
 }
Example #30
0
  private void initialize(RandomAccessFileOrArray stream) throws IOException {
    long nextTagOffset = 0L;
    long maxOffset = stream.length();
    int i, j;

    IFDOffset = stream.getFilePointer();

    numEntries = readUnsignedShort(stream);
    fields = new TIFFField[numEntries];

    for (i = 0; (i < numEntries) && (nextTagOffset < maxOffset); i++) {
      int tag = readUnsignedShort(stream);
      int type = readUnsignedShort(stream);
      int count = (int) (readUnsignedInt(stream));
      boolean processTag = true;

      nextTagOffset = stream.getFilePointer() + 4;

      try {

        if (count * sizeOfType[type] > 4) {
          long valueOffset = readUnsignedInt(stream);

          if (valueOffset < maxOffset) {
            stream.seek(valueOffset);
          } else {

            processTag = false;
          }
        }
      } catch (ArrayIndexOutOfBoundsException ae) {

        processTag = false;
      }

      if (processTag) {
        fieldIndex.put(new Integer(tag), new Integer(i));
        Object obj = null;

        switch (type) {
          case TIFFField.TIFF_BYTE:
          case TIFFField.TIFF_SBYTE:
          case TIFFField.TIFF_UNDEFINED:
          case TIFFField.TIFF_ASCII:
            byte[] bvalues = new byte[count];
            stream.readFully(bvalues, 0, count);

            if (type == TIFFField.TIFF_ASCII) {

              int index = 0, prevIndex = 0;
              ArrayList v = new ArrayList();

              while (index < count) {

                while ((index < count) && (bvalues[index++] != 0)) ;

                v.add(new String(bvalues, prevIndex, (index - prevIndex)));
                prevIndex = index;
              }

              count = v.size();
              String strings[] = new String[count];
              for (int c = 0; c < count; c++) {
                strings[c] = (String) v.get(c);
              }

              obj = strings;
            } else {
              obj = bvalues;
            }

            break;

          case TIFFField.TIFF_SHORT:
            char[] cvalues = new char[count];
            for (j = 0; j < count; j++) {
              cvalues[j] = (char) (readUnsignedShort(stream));
            }
            obj = cvalues;
            break;

          case TIFFField.TIFF_LONG:
            long[] lvalues = new long[count];
            for (j = 0; j < count; j++) {
              lvalues[j] = readUnsignedInt(stream);
            }
            obj = lvalues;
            break;

          case TIFFField.TIFF_RATIONAL:
            long[][] llvalues = new long[count][2];
            for (j = 0; j < count; j++) {
              llvalues[j][0] = readUnsignedInt(stream);
              llvalues[j][1] = readUnsignedInt(stream);
            }
            obj = llvalues;
            break;

          case TIFFField.TIFF_SSHORT:
            short[] svalues = new short[count];
            for (j = 0; j < count; j++) {
              svalues[j] = readShort(stream);
            }
            obj = svalues;
            break;

          case TIFFField.TIFF_SLONG:
            int[] ivalues = new int[count];
            for (j = 0; j < count; j++) {
              ivalues[j] = readInt(stream);
            }
            obj = ivalues;
            break;

          case TIFFField.TIFF_SRATIONAL:
            int[][] iivalues = new int[count][2];
            for (j = 0; j < count; j++) {
              iivalues[j][0] = readInt(stream);
              iivalues[j][1] = readInt(stream);
            }
            obj = iivalues;
            break;

          case TIFFField.TIFF_FLOAT:
            float[] fvalues = new float[count];
            for (j = 0; j < count; j++) {
              fvalues[j] = readFloat(stream);
            }
            obj = fvalues;
            break;

          case TIFFField.TIFF_DOUBLE:
            double[] dvalues = new double[count];
            for (j = 0; j < count; j++) {
              dvalues[j] = readDouble(stream);
            }
            obj = dvalues;
            break;

          default:
            break;
        }

        fields[i] = new TIFFField(tag, type, count, obj);
      }

      stream.seek(nextTagOffset);
    }

    try {
      nextIFDOffset = readUnsignedInt(stream);
    } catch (Exception e) {

      nextIFDOffset = 0;
    }
  }