Пример #1
0
  public void save(File outputBMFontFile) throws IOException, SlickException {
    File outputDir = outputBMFontFile.getParentFile();
    String outputName = outputBMFontFile.getName();
    if (outputName.endsWith(".fnt")) outputName = outputName.substring(0, outputName.length() - 4);

    unicodeFont.loadGlyphs();

    PrintStream out =
        new PrintStream(new FileOutputStream(new File(outputDir, outputName + ".fnt")));
    Font font = unicodeFont.getFont();
    int pageWidth = unicodeFont.getGlyphPageWidth();
    int pageHeight = unicodeFont.getGlyphPageHeight();
    out.println(
        "info face=\""
            + font.getFontName()
            + "\" size="
            + font.getSize()
            + " bold="
            + (font.isBold() ? 1 : 0)
            + " italic="
            + (font.isItalic() ? 1 : 0)
            + " charset=\"\" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1");
    out.println(
        "common lineHeight="
            + unicodeFont.getLineHeight()
            + " base=26 scaleW="
            + pageWidth
            + " scaleH="
            + pageHeight
            + " pages="
            + unicodeFont.getGlyphPages().size()
            + " packed=0");

    int pageIndex = 0, glyphCount = 0;
    for (Iterator pageIter = unicodeFont.getGlyphPages().iterator(); pageIter.hasNext(); ) {
      GlyphPage page = (GlyphPage) pageIter.next();
      String fileName;
      if (pageIndex == 0 && !pageIter.hasNext()) fileName = outputName + ".png";
      else fileName = outputName + (pageIndex + 1) + ".png";
      out.println("page id=" + pageIndex + " file=\"" + fileName + "\"");
      glyphCount += page.getGlyphs().size();
      pageIndex++;
    }

    out.println("chars count=" + glyphCount);

    // Always output space entry (codepoint 32).
    int[] glyphMetrics = getGlyphMetrics(font, 32);
    int xAdvance = glyphMetrics[1];
    out.println(
        "char id=32   x=0     y=0     width=0     height=0     xoffset=0     yoffset="
            + unicodeFont.getAscent()
            + "    xadvance="
            + xAdvance
            + "     page=0  chnl=0 ");

    pageIndex = 0;
    List allGlyphs = new ArrayList(512);
    for (Iterator pageIter = unicodeFont.getGlyphPages().iterator(); pageIter.hasNext(); ) {
      GlyphPage page = (GlyphPage) pageIter.next();
      for (Iterator glyphIter = page.getGlyphs().iterator(); glyphIter.hasNext(); ) {
        Glyph glyph = (Glyph) glyphIter.next();

        glyphMetrics = getGlyphMetrics(font, glyph.getCodePoint());
        int xOffset = glyphMetrics[0];
        xAdvance = glyphMetrics[1];

        out.println(
            "char id="
                + glyph.getCodePoint()
                + "   "
                + "x="
                + (int) (glyph.getImage().getTextureOffsetX() * pageWidth)
                + "     y="
                + (int) (glyph.getImage().getTextureOffsetY() * pageHeight)
                + "     width="
                + glyph.getWidth()
                + "     height="
                + glyph.getHeight()
                + "     xoffset="
                + xOffset
                + "     yoffset="
                + glyph.getYOffset()
                + "    xadvance="
                + xAdvance
                + "     page="
                + pageIndex
                + "  chnl=0 ");
      }
      allGlyphs.addAll(page.getGlyphs());
      pageIndex++;
    }

    String ttfFileRef = unicodeFont.getFontFile();
    if (ttfFileRef == null)
      Log.warn(
          "Kerning information could not be output because a TTF font file was not specified.");
    else {
      Kerning kerning = new Kerning();
      try {
        kerning.load(ResourceLoader.getResourceAsStream(ttfFileRef), font.getSize());
      } catch (IOException ex) {
        Log.warn("Unable to read kerning information from font: " + ttfFileRef);
      }

      Map glyphCodeToCodePoint = new HashMap();
      for (Iterator iter = allGlyphs.iterator(); iter.hasNext(); ) {
        Glyph glyph = (Glyph) iter.next();
        glyphCodeToCodePoint.put(
            new Integer(getGlyphCode(font, glyph.getCodePoint())),
            new Integer(glyph.getCodePoint()));
      }

      List kernings = new ArrayList(256);
      class KerningPair {
        public int firstCodePoint, secondCodePoint, offset;
      }
      for (Iterator iter1 = allGlyphs.iterator(); iter1.hasNext(); ) {
        Glyph firstGlyph = (Glyph) iter1.next();
        int firstGlyphCode = getGlyphCode(font, firstGlyph.getCodePoint());
        int[] values = kerning.getValues(firstGlyphCode);
        if (values == null) continue;
        for (int i = 0; i < values.length; i++) {
          Integer secondCodePoint =
              (Integer) glyphCodeToCodePoint.get(new Integer(values[i] & 0xffff));
          if (secondCodePoint == null) continue; // We may not be outputting the second character.
          int offset = values[i] >> 16;
          KerningPair pair = new KerningPair();
          pair.firstCodePoint = firstGlyph.getCodePoint();
          pair.secondCodePoint = secondCodePoint.intValue();
          pair.offset = offset;
          kernings.add(pair);
        }
      }
      out.println("kernings count=" + kerning.getCount());
      for (Iterator iter = kernings.iterator(); iter.hasNext(); ) {
        KerningPair pair = (KerningPair) iter.next();
        out.println(
            "kerning first="
                + pair.firstCodePoint
                + "  second="
                + pair.secondCodePoint
                + "  amount="
                + pair.offset);
      }
    }
    out.close();

    pageIndex = 0;
    ImageIOWriter imageWriter = new ImageIOWriter();
    for (Iterator pageIter = unicodeFont.getGlyphPages().iterator(); pageIter.hasNext(); ) {
      GlyphPage page = (GlyphPage) pageIter.next();
      String fileName;
      if (pageIndex == 0 && !pageIter.hasNext()) fileName = outputName + ".png";
      else fileName = outputName + (pageIndex + 1) + ".png";
      File imageOutputFile = new File(outputDir, fileName);
      FileOutputStream imageOutput = new FileOutputStream(imageOutputFile);
      try {
        imageWriter.saveImage(page.getImage(), "png", imageOutput, true);
      } finally {
        imageOutput.close();
      }
      // Flip output image.
      Image image = new ImageIcon(imageOutputFile.getAbsolutePath()).getImage();
      BufferedImage bufferedImage =
          new BufferedImage(
              image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
      Graphics g = bufferedImage.getGraphics();
      g.drawImage(image, 0, 0, null);
      AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
      tx.translate(0, -image.getHeight(null));
      AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
      bufferedImage = op.filter(bufferedImage, null);
      ImageIO.write(bufferedImage, "png", imageOutputFile);

      pageIndex++;
    }
  }