List of usage examples for com.badlogic.gdx.graphics.g2d PixmapPacker getPageHeight
public int getPageHeight()
From source file:darkyenus.resourcepacker.util.FreeTypePacker.java
License:Apache License
public Array<FileHandle> generate(FreeTypeFontParameter parameter, FileHandle outputFolder) { final Array<FileHandle> resultFiles = new Array<>(FileHandle.class); if (!face.setPixelSizes(0, parameter.size)) throw new GdxRuntimeException("Couldn't set size for font"); // set general font data FreeType.SizeMetrics fontMetrics = face.getSize().getMetrics(); final int descender = FreeType.toInt(fontMetrics.getDescender()); final int lineHeight = FreeType.toInt(fontMetrics.getHeight()); final Array<CharacterData> glyphs = new Array<>(); FreeType.Stroker stroker = null;/*from w ww. j a va2 s.c om*/ if (parameter.borderWidth > 0) { stroker = library.createStroker(); stroker.set((int) (parameter.borderWidth * 64f), parameter.borderStraight ? FreeType.FT_STROKER_LINECAP_BUTT : FreeType.FT_STROKER_LINECAP_ROUND, parameter.borderStraight ? FreeType.FT_STROKER_LINEJOIN_MITER_FIXED : FreeType.FT_STROKER_LINEJOIN_ROUND, 0); } if (parameter.codePoints == null) { for (int codePoint = 0; codePoint < 0x10FFFF; codePoint++) { createGlyph(codePoint, parameter, stroker, glyphs); } } else { parameter.codePoints.add(0); parameter.codePoints.add(' '); for (final IntSet.IntSetIterator it = parameter.codePoints.iterator(); it.hasNext;) { createGlyph(it.next(), parameter, stroker, glyphs); } } glyphs.sort(); // Guess needed texture size final int textureSize; { long totalSize2 = 0; for (CharacterData glyph : glyphs) { totalSize2 += glyph.pixmap.getWidth() * glyph.pixmap.getHeight(); } final double waste = 1.2; int totalSize = (int) Math.ceil(Math.sqrt(totalSize2 * waste)); int size = MathUtils.nextPowerOfTwo(totalSize); if (size > 4096) size = 4096; //System.out.println("Will use size: "+size); textureSize = size; } final PixmapPacker packer = new PixmapPacker(textureSize, textureSize, Pixmap.Format.RGBA8888, 1, false, new PixmapPacker.SkylineStrategy()); if (parameter.borderWidth > 0) { packer.setTransparentColor(parameter.borderColor); packer.getTransparentColor().a = 0; } else { packer.setTransparentColor(parameter.color); packer.getTransparentColor().a = 0; } //System.out.println("Generated "+glyphs.size+" glyphs"); for (CharacterData glyph : glyphs) { if (glyph.pixmap.getHeight() != 0 && glyph.pixmap.getWidth() != 0) { glyph.packed = packer.pack(glyph.pixmap); glyph.page = packer.getPages().size - 1; } } final int topToBaseline = lineHeight + descender; final StringBuilder fnt = new StringBuilder(); fnt.append("info face=\"").append(parameter.fontName).append("\" size=").append(parameter.size).append( " bold=0 italic=0 charset=\"\" unicode=1 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=1,1 outline=0"); fnt.append('\n'); fnt.append("common lineHeight=").append(lineHeight).append(" base=").append(topToBaseline) .append(" scaleW=").append(packer.getPageWidth()).append(" scaleH=").append(packer.getPageHeight()) .append(" pages=").append(packer.getPages().size) .append(" packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4"); fnt.append('\n'); { int pageNo = 0; final boolean addPageNumbers = packer.getPages().size > 1; for (PixmapPacker.Page page : packer.getPages()) { final FileHandle file = outputFolder .child(parameter.fontName + (addPageNumbers ? "_" + pageNo : "") + ".png"); resultFiles.add(file); PixmapIO.writePNG(file, page.getPixmap()); fnt.append("page id=").append(pageNo).append(" file=\"").append(file.name()).append("\""); fnt.append('\n'); pageNo++; } } for (CharacterData glyph : glyphs) { fnt.append("char"); fnt.append(" id=").append(glyph.codePoint); if (glyph.packed == null) { fnt.append(" x=0 y=0 width=0 height=0"); } else { fnt.append(" x=").append(MathUtils.round(glyph.packed.x)); fnt.append(" y=").append(MathUtils.round(glyph.packed.y)); fnt.append(" width=").append(MathUtils.round(glyph.packed.width)); fnt.append(" height=").append(MathUtils.round(glyph.packed.height)); } fnt.append(" xoffset=").append(glyph.offsetX); fnt.append(" yoffset=").append(topToBaseline - glyph.offsetY); fnt.append(" xadvance=").append(glyph.advanceX); fnt.append(" page=").append(glyph.page); fnt.append(" chnl=15"); fnt.append('\n'); } // Generate kerning. if (parameter.kerning) { fnt.append("kernings \n");//No count, not needed if (face.hasKerning()) { final int glyphsSize = glyphs.size; for (int i = 0; i < glyphsSize; i++) { final CharacterData first = glyphs.get(i); for (int ii = i; ii < glyphsSize; ii++) { final CharacterData second = glyphs.get(ii); int kerning = FreeType.toInt(face.getKerning(first.glyphIndex, second.glyphIndex, 0)); if (kerning != 0) { fnt.append("kerning first=").append(first.codePoint).append(" second=") .append(second.codePoint).append(" amount=").append(kerning).append('\n'); } kerning = FreeType.toInt(face.getKerning(second.glyphIndex, first.glyphIndex, 0)); if (kerning != 0) { fnt.append("kerning first=").append(second.codePoint).append(" second=") .append(first.codePoint).append(" amount=").append(kerning).append('\n'); } } } } else { //Try other means //First create mapping glyph -> char final IntIntMap glyphToCodePoint = new IntIntMap(); for (CharacterData glyph : glyphs) { glyphToCodePoint.put(glyph.glyphIndex, glyph.codePoint); } try { Kerning kerning = new Kerning(); kerning.load(fontFile.read(), parameter.size); final int pairCount = kerning.resultAmount.size; final int[] first = kerning.resultFirst.items; final int[] second = kerning.resultSecond.items; final int[] amount = kerning.resultAmount.items; for (int i = 0; i < pairCount; i++) { final int firstChar = glyphToCodePoint.get(first[i], -1); final int secondChar = glyphToCodePoint.get(second[i], -1); if (firstChar == -1 || secondChar == -1) { continue; } fnt.append("kerning first=").append(firstChar).append(" second=").append(secondChar) .append(" amount=").append(amount[i]).append('\n'); } } catch (Exception e) { throw new GdxRuntimeException("Failed to load kerning from advanced format", e); } } } final FileHandle fntFile = outputFolder.child(parameter.fontName + ".fnt"); fntFile.writeString(fnt.toString(), false, "UTF-8"); resultFiles.add(fntFile); if (stroker != null) stroker.dispose(); return resultFiles; }