Example usage for com.badlogic.gdx.graphics.g2d PixmapPacker getPageWidth

List of usage examples for com.badlogic.gdx.graphics.g2d PixmapPacker getPageWidth

Introduction

In this page you can find the example usage for com.badlogic.gdx.graphics.g2d PixmapPacker getPageWidth.

Prototype

public int getPageWidth() 

Source Link

Usage

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 www  .jav a2 s  .  c o  m*/
    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;
}