Text Get Disorted If I Use GlyphLayout to Draw

Anything libgdx related goes here!

Text Get Disorted If I Use GlyphLayout to Draw

Postby Mr.Noad » Thu May 17, 2018 6:18 am

Hi,

I created a class named ResizableFont which is actually just a wrapper around BitmapFont except it resize itself whenever Libgdx window bounds change.

It is working perfectly when i use draw(batch: Batch, str: CharSequence, x: Float, y: Float) method of BitmapFont but text gets disorted if i use
draw(batch: Batch, layout: GlyphLayout, x: Float, y: Float) method.

Can someone explain why this happens and how can I avoid it?

Thanks.

A working example:

ResizableFont.kt:
Code: Select all
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.*
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator
import com.badlogic.gdx.utils.Array


public class ResizableFont(private val fontFile: FileHandle,
                           private val parameters: FreeTypeFontGenerator.FreeTypeFontParameter,
                           private val designScreenHeight: Int,
                           private val designFontHeight: Int,
                           private var currentScreenHeight: Int = designScreenHeight) : BitmapFont() {

    private var wrappedFont: BitmapFont

    init {
        wrappedFont = reload(currentScreenHeight.toFloat())
    }

    public fun update(currentScreenHeight: Int) {
        if (currentScreenHeight > 0 && this.currentScreenHeight != currentScreenHeight) {
            try {
                wrappedFont.dispose()
            } catch (_: Exception) {
            }
            wrappedFont = reload(currentScreenHeight.toFloat())
            this.currentScreenHeight = currentScreenHeight
        }
    }

    private fun reload(currentScreenHeight: Float): BitmapFont {
        val generator = FreeTypeFontGenerator(fontFile)
        try {
            val size = (Math.max(designFontHeight * currentScreenHeight / designScreenHeight, 5f)).toInt()
            println("$fontFile reloaded with size: $size")
            return generator.generateFont(parameters.apply { this.size = size })
        } finally {
            generator.dispose()
        }
    }

        override fun draw(batch: Batch, str: CharSequence, x: Float, y: Float): GlyphLayout {
        return wrappedFont.draw(batch, str, x, y)
    }

    override fun draw(batch: Batch, str: CharSequence, x: Float, y: Float, targetWidth: Float, halign: Int, wrap: Boolean): GlyphLayout {
        return wrappedFont.draw(batch, str, x, y, targetWidth, halign, wrap)
    }

    override fun draw(batch: Batch, str: CharSequence, x: Float, y: Float, start: Int, end: Int, targetWidth: Float, halign: Int,
                      wrap: Boolean): GlyphLayout {
        return wrappedFont.draw(batch, str, x, y, start, end, targetWidth, halign, wrap)
    }

    override fun draw(batch: Batch, str: CharSequence, x: Float, y: Float, start: Int, end: Int, targetWidth: Float, halign: Int,
                      wrap: Boolean, truncate: String): GlyphLayout {
        return wrappedFont.draw(batch, str, x, y, start, end, targetWidth, halign, wrap, truncate)
    }

    override fun draw(batch: Batch, layout: GlyphLayout, x: Float, y: Float) {
        return wrappedFont.draw(batch, layout, x, y)
    }

    override fun getColor(): Color {
        return wrappedFont.color
    }

    override fun setColor(color: Color) {
        wrappedFont.color = color
    }

    override fun setColor(r: Float, g: Float, b: Float, a: Float) {
        wrappedFont.setColor(r, g, b, a)
    }

    override fun getScaleX(): Float {
        return wrappedFont.scaleX
    }

    override fun getScaleY(): Float {
        return wrappedFont.scaleY
    }

    override fun getRegion(): TextureRegion {
        return wrappedFont.region
    }

    override fun getRegions(): Array<TextureRegion> {
        return wrappedFont.regions
    }

    override fun getRegion(index: Int): TextureRegion {
        return wrappedFont.getRegion(index)
    }

    override fun getLineHeight(): Float {
        return wrappedFont.lineHeight
    }

    override fun getSpaceWidth(): Float {
        return wrappedFont.spaceWidth
    }

    override fun getXHeight(): Float {
        return wrappedFont.xHeight
    }

    override fun getCapHeight(): Float {
        return wrappedFont.capHeight
    }

    override fun getAscent(): Float {
        return wrappedFont.ascent
    }

    override fun getDescent(): Float {
        return wrappedFont.descent
    }

    override fun isFlipped(): Boolean {
        return wrappedFont.isFlipped
    }

    override fun dispose() {
        return wrappedFont.dispose()
    }

    override fun setFixedWidthGlyphs(glyphs: CharSequence) {
        return wrappedFont.setFixedWidthGlyphs(glyphs)
    }

    override fun setUseIntegerPositions(integer: Boolean) {
        return wrappedFont.setUseIntegerPositions(integer)
    }

    override fun usesIntegerPositions(): Boolean {
        return wrappedFont.usesIntegerPositions()
    }

    override fun getCache(): BitmapFontCache {
        return wrappedFont.cache
    }

    override fun getData(): BitmapFontData {
        return wrappedFont.data
    }

    override fun ownsTexture(): Boolean {
        return wrappedFont.ownsTexture()
    }

    override fun setOwnsTexture(ownsTexture: Boolean) {
        return wrappedFont.setOwnsTexture(ownsTexture)
    }

    override fun toString(): String {
        return wrappedFont.toString()
    }
}


Main.kt:
Code: Select all
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Gdx.gl
import com.badlogic.gdx.Gdx.graphics
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.g2d.GlyphLayout
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator
import com.badlogic.gdx.utils.Align
import javax.swing.SwingUtilities


private const val DESIGN_WIDTH = 1920
private const val DESIGN_HEIGHT = 1080
private const val DESIGN_FONT_SIZE = 32

class Main : ApplicationAdapter() {
    private lateinit var batch: SpriteBatch
    private lateinit var camera: OrthographicCamera
    private lateinit var textRenderer: ResizableFont


    init {
        SwingUtilities.invokeLater {
            Lwjgl3Application(this, Lwjgl3ApplicationConfiguration().apply {
                setResizable(true)
                setTitle("Resizable Font Test")
                setWindowedMode(DESIGN_WIDTH, DESIGN_HEIGHT)
                useVsync(OPENGL_VSYNC)
                setBackBufferConfig(8, 8, 8, 8, 16, 0, OPENGL_MSAA_SAMPLES)
            })
        }
    }

    override fun create() {
        camera = OrthographicCamera(DESIGN_WIDTH.toFloat(), DESIGN_HEIGHT.toFloat()).apply {
            setToOrtho(true, DESIGN_WIDTH.toFloat(), DESIGN_HEIGHT.toFloat())
        }
        batch = SpriteBatch().apply { projectionMatrix = camera.combined }

        textRenderer = ResizableFont(Gdx.files.internal("fonts/Bender Bold.ttf"),
                FreeTypeFontGenerator.FreeTypeFontParameter().apply {
                    this.flip = true
                }, DESIGN_HEIGHT, DESIGN_FONT_SIZE)

        gl.glClearColor(0F, 0F, 0F, 0F)
    }


    private fun drawText(color: Color, text: String, x: Float, y: Float) {
        textRenderer.color = color
        textRenderer.draw(batch, text, x, y)
    }

    private fun drawText(layout: GlyphLayout, x: Float, y: Float) {
        textRenderer.draw(batch, layout, x, y)
    }

    override fun render() {
        gl.apply {
            glEnable(GL20.GL_BLEND)
            glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA)
            glClear(GL20.GL_COLOR_BUFFER_BIT)

            textRenderer.update(graphics.height)

            camera.setToOrtho(true, graphics.width.toFloat(), graphics.height.toFloat())
            batch.projectionMatrix = camera.combined

            //draw stuff

            batch.begin()
            val text = "FPS: ${graphics.framesPerSecond}"

            //this draw call works
            drawText(Color.BLUE, text, 0f, 40f)

            //this one doesn't
            val fpsLayout = GlyphLayout()
            fpsLayout.setText(textRenderer, text, 0, text.length, Color.YELLOW, 300f, Align.left, false, null)
            drawText(fpsLayout, graphics.width - 300f, 92f)


            batch.end()

            glDisable(GL20.GL_BLEND)
        }
        fpsLimiter(120)
    }

    override fun dispose() {
        //dispose stuff...
    }
}


fun main(args: Array<String>) {
    Main()
}
Mr.Noad
 
Posts: 1
Joined: Wed May 16, 2018 9:47 pm

Return to Libgdx

Who is online

Users browsing this forum: Google [Bot] and 1 guest