Class TextLayout

java.lang.Object
edu.cornell.gdiac.graphics.TextLayout
All Implemented Interfaces:
com.badlogic.gdx.utils.Pool.Poolable

public class TextLayout extends Object implements com.badlogic.gdx.utils.Pool.Poolable
This class manages the layout of (potentially) multiple lines of text.

The purpose of this class is to convert text into SpriteMesh objects to decouple text from the from the built-in LibGDX graphics pipeline. The tools for drawing text in LibGDX are quite limited, and this allows us to treat text like any other SpriteBatch object.

In addition, a text layout object has an implicit coordinate system with an origin. This origin is defined by the getAlignment() options. This origin is used to place the text when it is rendered with a sprite batch.

Changing any of the layout attributes will obviously invalidate the text layout. An invalid layout will be recomputed on a call to the method layout. In addition, it is possible to invalidate() the layout at any time, forcing the layout to be recomputed each time the meshes are acquired.

By default, the text layout will only break lines at newline characters in the string. However, you can perform more agressive line breaking with the optional setWidth(float) attribute. When this attribute is positive, the text layout will break lines so that each line does not exceed this width.

Finally, it is possible to constrain the bounding box by calling setBounds(com.badlogic.gdx.math.Rectangle). If this value is set to an non-empty bounding box, then no text outside of this bounding box will be drawn. However, calls to getBounds() will return the true bounds of the text box, which may be smaller than that set.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static enum 
    An enum for categorizing unicode character types.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates an empty text layout
    TextLayout(float width)
    Creates an empty text layout with the given width.
    TextLayout(String text, com.badlogic.gdx.graphics.g2d.BitmapFont font)
    Creates a text layout with the given text and font.
    TextLayout(String text, com.badlogic.gdx.graphics.g2d.BitmapFont font, float width)
    Creates a text layout with the given text, font, and width.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Clears any bounding constraints placed on this text layout.
    int
    Returns the alignment of the text.
    com.badlogic.gdx.math.Rectangle
    Returns the bounds of this text layout
    com.badlogic.gdx.graphics.Color
    Returns the font color to use for the text
    com.badlogic.gdx.graphics.g2d.BitmapFont
    Returns the font associated with this layout.
    com.badlogic.gdx.math.Rectangle
    getGlyphBounds(int index)
    Returns the glyph bounds of the character at the given index
    Returns a (line) mesh of the quad outlines for the text glyphs.
    int
    Stores the quad outlines for the text glyphs in the given mesh.
    int
    getGlyphIndex(float x, float y)
    Returns the index of the character whose glyph is located at (x,y)
    int
    getGlyphIndex(com.badlogic.gdx.math.Vector2 p)
    Returns the index of the character whose glyph is located at p
    getLine(int line)
    Returns the text for the given line.
    int
    Returns the number of lines in this text layout
    com.badlogic.gdx.utils.Array<TexturedMesh>
    Returns an array of textured meshes to render the text layout
    int
    getNearestIndex(float x, float y)
    Returns the index of the character whose glyph is nearest (x,y)
    com.badlogic.gdx.math.Vector2
    Returns the translation offset for the alignment
    com.badlogic.gdx.graphics.g2d.GlyphLayout.GlyphRun
    getRun(int idx)
    Returns the glyph run corresponding to line idx
    Returns the text associated with this layout.
    int
    getTextIndex(int idx)
    Returns the string index of the idxth glyph.
    getUnicodeType(int code)
    Returns the unicode type for the given unicode code point
    float
    Returns the maximum lines width of this layout.
    void
    Invalidates the text layout
    void
    Arranges the text according to the given font and settings
    void
    Resets the text layout for reuse
    void
    setAlignment(int align)
    Sets the alignment of the text.
    void
    setBounds(float x, float y, float width, float height)
    Sets a constraint to place on the text bounds.
    void
    setBounds(com.badlogic.gdx.math.Rectangle rect)
    Sets a constraint to place on the text bounds.
    void
    setColor(com.badlogic.gdx.graphics.Color c)
    Sets the font color to use for the text
    void
    setFont(com.badlogic.gdx.graphics.g2d.BitmapFont font)
    Sets the font associated with this layout.
    void
    Sets the text associated with this layout.
    void
    setWidth(float width)
    Sets the maximum line width of this layout.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • TextLayout

      public TextLayout()
      Creates an empty text layout

      You will need to add both text and a font to properly use this object. Call layout to create the layout once these values are set.

      This layout will have a maximum width of 0, which menas that this method will only break lines at newlines. This guarantees multi-line text support without taking control away from the programmer.

    • TextLayout

      public TextLayout(float width)
      Creates an empty text layout with the given width.

      You will need to add both text and a font to properly use this object. Call layout to create the layout once these values are set.

      A maximum width of 0 will guarantee that breaks only happen at newlines. A postive width will force the layout manager to break up lines so that no individual line exceeds that width.

      Parameters:
      width - The width for each line
    • TextLayout

      public TextLayout(String text, com.badlogic.gdx.graphics.g2d.BitmapFont font)
      Creates a text layout with the given text and font.

      This layout will have a size of 0, which menas that this method will only break lines at newlines. This guarantees multi-line text support without taking control away from the programmer.

      Note that this method does not actually arrange the text. You must call layout to complete the layout. This gives you time to change the alignment before performing the layout.

      Parameters:
      text - The text to layout
      font - The font to arrange the text
    • TextLayout

      public TextLayout(String text, com.badlogic.gdx.graphics.g2d.BitmapFont font, float width)
      Creates a text layout with the given text, font, and width.

      A maximum width of 0 will guarantee that breaks only happen at newlines. A postive width will force the layout manager to break up lines so that no individual line exceeds that width.

      Note that this method does not actually arrange the text. You must call layout to complete the layout. This gives you time to change the alignment before performing the layout.

      Parameters:
      text - The text to layout
      font - The font to arrange the text
      width - The width for each line
  • Method Details

    • reset

      public void reset()
      Resets the text layout for reuse
      Specified by:
      reset in interface com.badlogic.gdx.utils.Pool.Poolable
    • getText

      public String getText()
      Returns the text associated with this layout.

      Changing this value will invalidate() the layout.

      Returns:
      the text associated with this layout.
    • setText

      public void setText(String text)
      Sets the text associated with this layout.

      Changing this value will invalidate() the layout.

      Parameters:
      text - The text associated with this layout.
    • getFont

      public com.badlogic.gdx.graphics.g2d.BitmapFont getFont()
      Returns the font associated with this layout.

      Changing this value will invalidate() the layout.

      Returns:
      the font associated with this layout.
    • setFont

      public void setFont(com.badlogic.gdx.graphics.g2d.BitmapFont font)
      Sets the font associated with this layout.

      Changing this value will invalidate() the layout.

      Parameters:
      font - The font associated with this layout.
    • getWidth

      public float getWidth()
      Returns the maximum lines width of this layout.

      This value will determine how the layout breaks up lines to arrange text. A width of 0 will guarantee that breaks only happen at newlines. A postive width will force the text layout to break up lines so that no individual line exceeds that width.

      Changing this value will invalidate() the layout.

      Returns:
      the maximum line width of this layout.
    • setWidth

      public void setWidth(float width)
      Sets the maximum line width of this layout.

      This value will determine how the layout breaks up lines to arrange text. A width of 0 will guarantee that breaks only happen at newlines. A postive width will force the text layout to break up lines so that no individual line exceeds that width.

      Changing this value will invalidate() the layout.

      Parameters:
      width - The maximum line width of this layout.
    • getAlignment

      public int getAlignment()
      Returns the alignment of the text.

      The integer parameter should be one provided by TextAlign. Note that alignment has two meanings. First, it is the relationship of the relative alignment of multiple lines (e.g. left, right, or center aligned). In addition, it defines the origin of the text layout. The later is relevant even when the text layout is a single line.

      Changing this value will invalidate() the layout.

      Returns:
      the alignment of the text.
    • setAlignment

      public void setAlignment(int align)
      Sets the alignment of the text.

      The integer parameter should be one provided by TextAlign. Note that alignment has two meanings. First, it is the relationship of the relative alignment of multiple lines (e.g. left, right, or center aligned). In addition, it defines the origin of the text layout. The later is relevant even when the text layout is a single line.

      Changing this value will invalidate() the layout.

      Parameters:
      align - The alignment of the text.
    • getColor

      public com.badlogic.gdx.graphics.Color getColor()
      Returns the font color to use for the text

      Changing this value will invalidate() the layout.

      Returns:
      the font color to use for the text
    • setColor

      public void setColor(com.badlogic.gdx.graphics.Color c)
      Sets the font color to use for the text

      Changing this value will invalidate() the layout.

      Parameters:
      c - The font color to use for the text
    • getBounds

      public com.badlogic.gdx.math.Rectangle getBounds()
      Returns the bounds of this text layout

      This rectangle is in the coordinate space whose origin is defined by the alignment. This rectangle has zero size if the layout has been invalidated. It will be set once layout is called. This is true even after a call to setBounds(com.badlogic.gdx.math.Rectangle).

      Returns:
      the bounds of this text layout
    • setBounds

      public void setBounds(com.badlogic.gdx.math.Rectangle rect)
      Sets a constraint to place on the text bounds.

      This method does not actually set the bounds of the text layout. Indeed, calling this method will invalidate() the layout, causing getBounds() to return a zero size rectangle.

      Instead, this method places a constraint on the text box once layout is completed after a call to layout. No text will be drawn outside of these bounds (possibly causing text to be cut-off mid glyph). After text is laid out, the resulting getBounds() is guaranteed to be a subset of these bounds.

      Note that bounds are specified in the coordinate system determined by getAlignment(). So if the alignment is TextAlign.topLeft, a bounding box Rectangle(0,-50,50,50) will limit the text to the top left corner of the box.

      Parameters:
      rect - The bound constraints.
    • setBounds

      public void setBounds(float x, float y, float width, float height)
      Sets a constraint to place on the text bounds.

      This method does not actually set the bounds of the text layout. Indeed, calling this method will invalidate() the layout, causing getBounds() to return a zero size rectangle.

      Instead, this method places a constraint on the text box once layout is completed after a call to layout. No text will be drawn outside of these bounds (possibly causing text to be cut-off mid glyph). After text is laid out, the resulting getBounds() is guaranteed to be a subset of these bounds.

      Note that bounds are specified in the coordinate system determined by getAlignment(). So if the alignment is TextAlign.topLeft, a bounding box Rectangle(0,-50,50,50) will limit the text to the top left corner of the box.

      Parameters:
      x - The left edge of the bound constraints.
      y - The bottom edge of the bound constraints.
      width - The width of the bound constraints.
      height - The height of the bound constraints.
    • clearBounds

      public void clearBounds()
      Clears any bounding constraints placed on this text layout.

      Calling this method will immediately invalidate() the layout. When the text is laid out after a call to layout, the text box will use the full size necessary to layout the text.

    • getRun

      public com.badlogic.gdx.graphics.g2d.GlyphLayout.GlyphRun getRun(int idx)
      Returns the glyph run corresponding to line idx
      Parameters:
      idx - the index of the desired line
      Returns:
      the glyph run corresponding to line idx
    • getOffset

      public com.badlogic.gdx.math.Vector2 getOffset()
      Returns the translation offset for the alignment
      Returns:
      the translation offset for the alignment
    • getTextIndex

      public int getTextIndex(int idx)
      Returns the string index of the idxth glyph.

      Glyphs are 0-indexed. If idx is greater than or equal to the number of glyphs, this returns the string index of the last glyph. If there are no indices or idx < 0, it returns 0.

      Parameters:
      idx - the index of the desired glyph
      Returns:
      the string index of the idxth glyph
    • invalidate

      public void invalidate()
      Invalidates the text layout

      This deletes all rows (so the line count is 0). You will need to call layout to reperform the layout.

    • getLineCount

      public int getLineCount()
      Returns the number of lines in this text layout

      This value will be zero if layout has not been called or if the layout has been invalidated.

      Returns:
      the number of lines in this text layout
    • getLine

      public String getLine(int line)
      Returns the text for the given line.

      Note that line breaking will omit any white space on the ends. Hence adding the text for each line together may not produce the original text. You must call layout before using this method.

      Parameters:
      line - The line number
      Returns:
      the text for the given line.
    • getGlyphBounds

      public com.badlogic.gdx.math.Rectangle getGlyphBounds(int index)
      Returns the glyph bounds of the character at the given index

      The rectangle will be in the coordinate system of this text layout. In addition to the size, it will accurately reflect the position of the character in the layout, including any possible tracking.

      If the index is for an unprintable character, this method will return the empty rectangle. Modifying the rectangle returned has undefined results.

      You must call layout before using this method.

      Parameters:
      index - The position in the layout text
      Returns:
      the glyph bounds of the character at the given index
    • getGlyphIndex

      public int getGlyphIndex(com.badlogic.gdx.math.Vector2 p)
      Returns the index of the character whose glyph is located at p

      If the point p is not on top of a glyph, this method will return the size of the text. Use getNearestIndex(com.badlogic.gdx.math.Vector2) for cases in which the point is out of bounds.

      The point p is assumed to be in the coordinate system of this layout. This method will never return the index of white space "swallowed" at the end of multiline text, even when this point is beyond the edges of the text.

      You must call layout before using this method.

      Parameters:
      p - The position in layout space
      Returns:
      the index of the character whose glyph is located at p
    • getGlyphIndex

      public int getGlyphIndex(float x, float y)
      Returns the index of the character whose glyph is located at (x,y)

      If the point (x,y) is not on top of a glyph, this method will return the size of the text. Use getNearestIndex(com.badlogic.gdx.math.Vector2) for cases in which the point is out of bounds.

      The point (x,y) is assumed to be in the coordinate system of this layout. This method will never return the index of white space "swallowed" at the end of multiline text, even when this point is beyond the edges of the text.

      You must call layout before using this method.

      Parameters:
      x - The x-coordinate in layout space
      y - The y-coordinate in layout space
      Returns:
      the index of the character whose glyph is located at (x,y)
    • getNearestIndex

      public int getNearestIndex(float x, float y)
      Returns the index of the character whose glyph is nearest (x,y)

      The point (x,y) is assumed to be in the coordinate system of this layout. This method will never return the index of white space "swallowed" at the end of multiline text, even when this point is beyond the edges of the text.

      You must call layout before using this method.

      Parameters:
      x - The x-coordinate in layout space
      y - The y-coordinate in layout space
      Returns:
      the index of the character whose glyph is nearest (x,y)
    • getMeshes

      public com.badlogic.gdx.utils.Array<TexturedMesh> getMeshes()
      Returns an array of textured meshes to render the text layout

      Each texture mesh will consist of a sprite mesh and a texture to render the mesh. Rendering all of the meshes together will render the entire string. Generally the quads are non-overlapping, so any blending mode is supported. However, font antialiasing requires transparency, so we recommend alpha blending when rendering a string.

      The origin of each mesh will agree with that of the text layout. Any transforms to the text should be applied uniformly to all meshes in the array.

      Calling this method on an invalidated layout will regenerate the meshes (e.g. this method will invoke layout). Otherwise, the meshes returned will be the same objects as those from the last time they were generated.

      Returns:
      an array of textured meshes to render the text layout
    • getGlyphBoxes

      public SpriteMesh getGlyphBoxes()
      Returns a (line) mesh of the quad outlines for the text glyphs.

      This method is useful for debugging. When this mesh is drawn together with a texture mesh array, it shows the bounding box for each glyph. This includes the bounding boxes for glyphs that are partially cut off due to the bounding constraints from setBounds(com.badlogic.gdx.math.Rectangle).

      The origin of each mesh will agree with that of the text layout. Any transforms to the text should be applied uniformly to all meshes in the array.

      Calling this method on an invalidated layout will invoke layout.

      Returns:
      a (line) mesh of the quad outlines for the text glyphs
    • getGlyphBoxes

      public int getGlyphBoxes(SpriteMesh mesh)
      Stores the quad outlines for the text glyphs in the given mesh.

      This method is useful for debugging. When this mesh is drawn together with a texture mesh array, it shows the bounding box for each glyph. This includes the bounding boxes for glyphs that are partially cut off due to the bounding constraints from setBounds(com.badlogic.gdx.math.Rectangle).

      The origin of each mesh will agree with that of the text layout. Any transforms to the text should be applied uniformly to all meshes in the array.

      Calling this method on an invalidated layout will invoke layout.

      Parameters:
      mesh - The mesh to store the new quads
      Returns:
      the number of quads generated
    • layout

      public void layout()
      Arranges the text according to the given font and settings

      Changing any of the layout attributes will obviously invalidate the text layout. Calling this method will reperform the layout and regenerate the sprite meshes.

    • getUnicodeType

      public static TextLayout.UnicodeType getUnicodeType(int code)
      Returns the unicode type for the given unicode code point

      A unicode code point is the 32-bit representation of a character. It is endian specific and therefore not serializable. A UTF8 representation should be used for serialization.

      Parameters:
      code - The unicode code point
      Returns:
      the unicode type for the given unicode code point