Search in sources :

Example 1 with Rectangle

use of com.badlogic.gdx.math.Rectangle in project libgdx by libgdx.

the class FreeTypeFontGenerator method createGlyph.

/** @return null if glyph was not found. */
Glyph createGlyph(char c, FreeTypeBitmapFontData data, FreeTypeFontParameter parameter, Stroker stroker, float baseLine, PixmapPacker packer) {
    boolean missing = face.getCharIndex(c) == 0 && c != 0;
    if (missing)
        return null;
    if (!loadChar(c, getLoadingFlags(parameter)))
        return null;
    GlyphSlot slot = face.getGlyph();
    FreeType.Glyph mainGlyph = slot.getGlyph();
    try {
        mainGlyph.toBitmap(parameter.mono ? FreeType.FT_RENDER_MODE_MONO : FreeType.FT_RENDER_MODE_NORMAL);
    } catch (GdxRuntimeException e) {
        mainGlyph.dispose();
        Gdx.app.log("FreeTypeFontGenerator", "Couldn't render char: " + c);
        return null;
    }
    Bitmap mainBitmap = mainGlyph.getBitmap();
    Pixmap mainPixmap = mainBitmap.getPixmap(Format.RGBA8888, parameter.color, parameter.gamma);
    if (mainBitmap.getWidth() != 0 && mainBitmap.getRows() != 0) {
        int offsetX = 0, offsetY = 0;
        if (parameter.borderWidth > 0) {
            // execute stroker; this generates a glyph "extended" along the outline
            int top = mainGlyph.getTop(), left = mainGlyph.getLeft();
            FreeType.Glyph borderGlyph = slot.getGlyph();
            borderGlyph.strokeBorder(stroker, false);
            borderGlyph.toBitmap(parameter.mono ? FreeType.FT_RENDER_MODE_MONO : FreeType.FT_RENDER_MODE_NORMAL);
            offsetX = left - borderGlyph.getLeft();
            offsetY = -(top - borderGlyph.getTop());
            // Render border (pixmap is bigger than main).
            Bitmap borderBitmap = borderGlyph.getBitmap();
            Pixmap borderPixmap = borderBitmap.getPixmap(Format.RGBA8888, parameter.borderColor, parameter.borderGamma);
            // Draw main glyph on top of border.
            for (int i = 0, n = parameter.renderCount; i < n; i++) borderPixmap.drawPixmap(mainPixmap, offsetX, offsetY);
            mainPixmap.dispose();
            mainGlyph.dispose();
            mainPixmap = borderPixmap;
            mainGlyph = borderGlyph;
        }
        if (parameter.shadowOffsetX != 0 || parameter.shadowOffsetY != 0) {
            int mainW = mainPixmap.getWidth(), mainH = mainPixmap.getHeight();
            int shadowOffsetX = Math.max(parameter.shadowOffsetX, 0), shadowOffsetY = Math.max(parameter.shadowOffsetY, 0);
            int shadowW = mainW + Math.abs(parameter.shadowOffsetX), shadowH = mainH + Math.abs(parameter.shadowOffsetY);
            Pixmap shadowPixmap = new Pixmap(shadowW, shadowH, mainPixmap.getFormat());
            Color shadowColor = parameter.shadowColor;
            float a = shadowColor.a;
            if (a != 0) {
                byte r = (byte) (shadowColor.r * 255), g = (byte) (shadowColor.g * 255), b = (byte) (shadowColor.b * 255);
                ByteBuffer mainPixels = mainPixmap.getPixels();
                ByteBuffer shadowPixels = shadowPixmap.getPixels();
                for (int y = 0; y < mainH; y++) {
                    int shadowRow = shadowW * (y + shadowOffsetY) + shadowOffsetX;
                    for (int x = 0; x < mainW; x++) {
                        int mainPixel = (mainW * y + x) * 4;
                        byte mainA = mainPixels.get(mainPixel + 3);
                        if (mainA == 0)
                            continue;
                        int shadowPixel = (shadowRow + x) * 4;
                        shadowPixels.put(shadowPixel, r);
                        shadowPixels.put(shadowPixel + 1, g);
                        shadowPixels.put(shadowPixel + 2, b);
                        shadowPixels.put(shadowPixel + 3, (byte) ((mainA & 0xff) * a));
                    }
                }
            }
            // Draw main glyph (with any border) on top of shadow.
            for (int i = 0, n = parameter.renderCount; i < n; i++) shadowPixmap.drawPixmap(mainPixmap, Math.max(-parameter.shadowOffsetX, 0), Math.max(-parameter.shadowOffsetY, 0));
            mainPixmap.dispose();
            mainPixmap = shadowPixmap;
        } else if (parameter.borderWidth == 0) {
            // No shadow and no border, draw glyph additional times.
            for (int i = 0, n = parameter.renderCount - 1; i < n; i++) mainPixmap.drawPixmap(mainPixmap, 0, 0);
        }
    }
    GlyphMetrics metrics = slot.getMetrics();
    Glyph glyph = new Glyph();
    glyph.id = c;
    glyph.width = mainPixmap.getWidth();
    glyph.height = mainPixmap.getHeight();
    glyph.xoffset = mainGlyph.getLeft();
    glyph.yoffset = parameter.flip ? -mainGlyph.getTop() + (int) baseLine : -(glyph.height - mainGlyph.getTop()) - (int) baseLine;
    glyph.xadvance = FreeType.toInt(metrics.getHoriAdvance()) + (int) parameter.borderWidth + parameter.spaceX;
    if (bitmapped) {
        mainPixmap.setColor(Color.CLEAR);
        mainPixmap.fill();
        ByteBuffer buf = mainBitmap.getBuffer();
        int whiteIntBits = Color.WHITE.toIntBits();
        int clearIntBits = Color.CLEAR.toIntBits();
        for (int h = 0; h < glyph.height; h++) {
            int idx = h * mainBitmap.getPitch();
            for (int w = 0; w < (glyph.width + glyph.xoffset); w++) {
                int bit = (buf.get(idx + (w / 8)) >>> (7 - (w % 8))) & 1;
                mainPixmap.drawPixel(w, h, ((bit == 1) ? whiteIntBits : clearIntBits));
            }
        }
    }
    Rectangle rect = packer.pack(mainPixmap);
    // Glyph is always packed into the last page for now.
    glyph.page = packer.getPages().size - 1;
    glyph.srcX = (int) rect.x;
    glyph.srcY = (int) rect.y;
    // If a page was added, create a new texture region for the incrementally added glyph.
    if (parameter.incremental && data.regions != null && data.regions.size <= glyph.page)
        packer.updateTextureRegions(data.regions, parameter.minFilter, parameter.magFilter, parameter.genMipMaps);
    mainPixmap.dispose();
    mainGlyph.dispose();
    return glyph;
}
Also used : GlyphSlot(com.badlogic.gdx.graphics.g2d.freetype.FreeType.GlyphSlot) GlyphMetrics(com.badlogic.gdx.graphics.g2d.freetype.FreeType.GlyphMetrics) Color(com.badlogic.gdx.graphics.Color) Rectangle(com.badlogic.gdx.math.Rectangle) ByteBuffer(java.nio.ByteBuffer) GdxRuntimeException(com.badlogic.gdx.utils.GdxRuntimeException) Bitmap(com.badlogic.gdx.graphics.g2d.freetype.FreeType.Bitmap) Glyph(com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph) Pixmap(com.badlogic.gdx.graphics.Pixmap)

Example 2 with Rectangle

use of com.badlogic.gdx.math.Rectangle in project libgdx by libgdx.

the class ParticleEmitter method getBoundingBox.

/** Returns the bounding box for all active particles. z axis will always be zero. */
public BoundingBox getBoundingBox() {
    if (bounds == null)
        bounds = new BoundingBox();
    Particle[] particles = this.particles;
    boolean[] active = this.active;
    BoundingBox bounds = this.bounds;
    bounds.inf();
    for (int i = 0, n = active.length; i < n; i++) if (active[i]) {
        Rectangle r = particles[i].getBoundingRectangle();
        bounds.ext(r.x, r.y, 0);
        bounds.ext(r.x + r.width, r.y + r.height, 0);
    }
    return bounds;
}
Also used : BoundingBox(com.badlogic.gdx.math.collision.BoundingBox) Rectangle(com.badlogic.gdx.math.Rectangle)

Example 3 with Rectangle

use of com.badlogic.gdx.math.Rectangle in project libgdx by libgdx.

the class PixmapPacker method pack.

/** Inserts the pixmap. If name was not null, you can later retrieve the image's position in the output image via
	 * {@link #getRect(String)}.
	 * @param name If null, the image cannot be looked up by name.
	 * @return Rectangle describing the area the pixmap was rendered to.
	 * @throws GdxRuntimeException in case the image did not fit due to the page size being too small or providing a duplicate
	 *            name. */
public synchronized Rectangle pack(String name, Pixmap image) {
    if (disposed)
        return null;
    if (name != null && getRect(name) != null)
        throw new GdxRuntimeException("Pixmap has already been packed with name: " + name);
    Rectangle rect = new Rectangle(0, 0, image.getWidth(), image.getHeight());
    if (rect.getWidth() > pageWidth || rect.getHeight() > pageHeight) {
        if (name == null)
            throw new GdxRuntimeException("Page size too small for pixmap.");
        throw new GdxRuntimeException("Page size too small for pixmap: " + name);
    }
    Page page = packStrategy.pack(this, name, rect);
    if (name != null) {
        page.rects.put(name, rect);
        page.addedRects.add(name);
    }
    int rectX = (int) rect.x, rectY = (int) rect.y, rectWidth = (int) rect.width, rectHeight = (int) rect.height;
    if (packToTexture && !duplicateBorder && page.texture != null && !page.dirty) {
        page.texture.bind();
        Gdx.gl.glTexSubImage2D(page.texture.glTarget, 0, rectX, rectY, rectWidth, rectHeight, image.getGLFormat(), image.getGLType(), image.getPixels());
    } else
        page.dirty = true;
    page.image.setBlending(Blending.None);
    page.image.drawPixmap(image, rectX, rectY);
    if (duplicateBorder) {
        int imageWidth = image.getWidth(), imageHeight = image.getHeight();
        // Copy corner pixels to fill corners of the padding.
        page.image.drawPixmap(image, 0, 0, 1, 1, rectX - 1, rectY - 1, 1, 1);
        page.image.drawPixmap(image, imageWidth - 1, 0, 1, 1, rectX + rectWidth, rectY - 1, 1, 1);
        page.image.drawPixmap(image, 0, imageHeight - 1, 1, 1, rectX - 1, rectY + rectHeight, 1, 1);
        page.image.drawPixmap(image, imageWidth - 1, imageHeight - 1, 1, 1, rectX + rectWidth, rectY + rectHeight, 1, 1);
        // Copy edge pixels into padding.
        page.image.drawPixmap(image, 0, 0, imageWidth, 1, rectX, rectY - 1, rectWidth, 1);
        page.image.drawPixmap(image, 0, imageHeight - 1, imageWidth, 1, rectX, rectY + rectHeight, rectWidth, 1);
        page.image.drawPixmap(image, 0, 0, 1, imageHeight, rectX - 1, rectY, 1, rectHeight);
        page.image.drawPixmap(image, imageWidth - 1, 0, 1, imageHeight, rectX + rectWidth, rectY, 1, rectHeight);
    }
    return rect;
}
Also used : GdxRuntimeException(com.badlogic.gdx.utils.GdxRuntimeException) Rectangle(com.badlogic.gdx.math.Rectangle)

Example 4 with Rectangle

use of com.badlogic.gdx.math.Rectangle in project libgdx by libgdx.

the class PixmapPacker method updateTextureAtlas.

/** Updates the {@link TextureAtlas}, adding any new {@link Pixmap} instances packed since the last call to this method. This
	 * can be used to insert Pixmap instances on a separate thread via {@link #pack(String, Pixmap)} and update the TextureAtlas on
	 * the rendering thread. This method must be called on the rendering thread. After calling this method, disposing the packer
	 * will no longer dispose the page pixmaps. */
public synchronized void updateTextureAtlas(TextureAtlas atlas, TextureFilter minFilter, TextureFilter magFilter, boolean useMipMaps) {
    updatePageTextures(minFilter, magFilter, useMipMaps);
    for (Page page : pages) {
        if (page.addedRects.size > 0) {
            for (String name : page.addedRects) {
                Rectangle rect = page.rects.get(name);
                TextureRegion region = new TextureRegion(page.texture, (int) rect.x, (int) rect.y, (int) rect.width, (int) rect.height);
                atlas.addRegion(name, region);
            }
            page.addedRects.clear();
            atlas.getTextures().add(page.texture);
        }
    }
}
Also used : Rectangle(com.badlogic.gdx.math.Rectangle)

Example 5 with Rectangle

use of com.badlogic.gdx.math.Rectangle in project libgdx by libgdx.

the class PixmapPackerIO method save.

/** Saves the provided PixmapPacker to the provided file. The resulting file will use the standard TextureAtlas file format and
	 * can be loaded by TextureAtlas as if it had been created using TexturePacker.
	 * 
	 * @param file the file to which the atlas descriptor will be written, images will be written as siblings
	 * @param packer the PixmapPacker to be written
	 * @param parameters the SaveParameters specifying how to save the PixmapPacker
	 * @throws IOException if the atlas file can not be written */
public void save(FileHandle file, PixmapPacker packer, SaveParameters parameters) throws IOException {
    Writer writer = file.writer(false);
    int index = 0;
    for (Page page : packer.pages) {
        if (page.rects.size > 0) {
            FileHandle pageFile = file.sibling(file.nameWithoutExtension() + "_" + (++index) + parameters.format.getExtension());
            switch(parameters.format) {
                case CIM:
                    {
                        PixmapIO.writeCIM(pageFile, page.image);
                        break;
                    }
                case PNG:
                    {
                        PixmapIO.writePNG(pageFile, page.image);
                        break;
                    }
            }
            writer.write("\n");
            writer.write(pageFile.name() + "\n");
            writer.write("size: " + page.image.getWidth() + "," + page.image.getHeight() + "\n");
            writer.write("format: " + packer.pageFormat.name() + "\n");
            writer.write("filter: " + parameters.minFilter.name() + "," + parameters.magFilter.name() + "\n");
            writer.write("repeat: none" + "\n");
            for (String name : page.rects.keys()) {
                writer.write(name + "\n");
                Rectangle rect = page.rects.get(name);
                writer.write("rotate: false" + "\n");
                writer.write("xy: " + (int) rect.x + "," + (int) rect.y + "\n");
                writer.write("size: " + (int) rect.width + "," + (int) rect.height + "\n");
                writer.write("orig: " + (int) rect.width + "," + (int) rect.height + "\n");
                writer.write("offset: 0, 0" + "\n");
                writer.write("index: -1" + "\n");
            }
        }
    }
    writer.close();
}
Also used : FileHandle(com.badlogic.gdx.files.FileHandle) Rectangle(com.badlogic.gdx.math.Rectangle) Page(com.badlogic.gdx.graphics.g2d.PixmapPacker.Page) Writer(java.io.Writer)

Aggregations

Rectangle (com.badlogic.gdx.math.Rectangle)35 Test (org.junit.Test)6 TiledMapTileLayer (com.badlogic.gdx.maps.tiled.TiledMapTileLayer)5 MockPointer (com.gemserk.commons.gdx.input.MockPointer)4 Circle (com.badlogic.gdx.math.Circle)3 BitmapFont (com.badlogic.gdx.graphics.g2d.BitmapFont)2 Cell (com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell)2 GdxRuntimeException (com.badlogic.gdx.utils.GdxRuntimeException)2 CoreEntity (com.ilargia.games.entitas.core.CoreEntity)2 View (com.ilargia.games.logicbrick.component.View)2 PlayerSoldier (me.dumfing.multiplayerTools.PlayerSoldier)2 FishColour (ca.hiphiparray.amazingmaze.FishCell.FishColour)1 AssetManager (com.badlogic.gdx.assets.AssetManager)1 FileHandle (com.badlogic.gdx.files.FileHandle)1 Camera (com.badlogic.gdx.graphics.Camera)1 Color (com.badlogic.gdx.graphics.Color)1 Pixmap (com.badlogic.gdx.graphics.Pixmap)1 Batch (com.badlogic.gdx.graphics.g2d.Batch)1 Glyph (com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph)1 TextBounds (com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds)1