CUGL 2.3
Cornell University Game Library
|
#include <CUTextLayout.h>
Public Member Functions | |
TextLayout () | |
~TextLayout () | |
void | dispose () |
bool | init () |
bool | initWithWidth (float width) |
bool | initWithText (const std::string text, const std::shared_ptr< Font > &font) |
bool | initWithTextWidth (const std::string text, const std::shared_ptr< Font > &font, float width) |
const std::string | getText () const |
void | setText (const std::string text) |
const std::shared_ptr< Font > & | getFont () const |
void | setFont (const std::shared_ptr< Font > &font) |
float | getWidth () const |
void | setWidth (float width) |
float | getSpacing () const |
void | setSpacing (float spacing) |
HorizontalAlign | getHorizontalAlignment () const |
void | setHorizontalAlignment (HorizontalAlign halign) |
VerticalAlign | getVerticalAlignment () const |
void | setVerticalAlignment (VerticalAlign valign) |
void | layout () |
void | invalidate () |
bool | validated () const |
const Rect & | getBounds () const |
const Rect | getTightBounds () const |
const Rect | getTrueBounds () const |
size_t | getLineCount () const |
std::string | getLine (size_t line) const |
Rect | getGlyphBounds (size_t index) const |
size_t | getGlyphIndex (Vec2 p) const |
size_t | getGlyphIndex (float x, float y) const |
size_t | getNearestIndex (Vec2 p) const |
size_t | getNearestIndex (float x, float y) const |
std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > | getGlyphs () const |
std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > | getGlyphs (Rect rect) const |
size_t | getGlyphs (std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > &runs) const |
size_t | getGlyphs (std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > &runs, Rect rect) const |
Mesh< SpriteVertex2 > | getGlyphBoxes () const |
Mesh< SpriteVertex2 > | getGlyphBoxes (Rect rect) const |
size_t | getGlyphBoxes (Mesh< SpriteVertex2 > &mesh) const |
size_t | getGlyphBoxes (Mesh< SpriteVertex2 > &mesh, Rect rect) const |
Static Public Member Functions | |
static std::shared_ptr< TextLayout > | alloc () |
static std::shared_ptr< TextLayout > | allocWithWidth (float width) |
static std::shared_ptr< TextLayout > | allocWithText (const std::string text, const std::shared_ptr< Font > &font) |
static std::shared_ptr< TextLayout > | allocWithTextWidth (const std::string text, const std::shared_ptr< Font > &font, float width) |
Friends | |
class | cugl::scene2::Label |
class | cugl::scene2::TextField |
This class manages the layout of (potentially) multiple lines of text.
The purpose of this class is to decouple text layout from the scene2::Label
scene graph class, so we can draw text directly to a SpriteBatch
. Given a string, it potentially breaks the string up into multiple lines and allows you to control the relative alignment of each line.
In addition, a text layout object has an implicit coordinate system with an origin. This origin is defined by the getHorizontalAlignment
and getVerticalAlignment
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. For performance reasons, we do not automatically recompute the layout in that case. Instead, the user must call layout
to arrange the text.
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 getWidth
attribute. When this attribute is positive, the text layout will break lines so that each line does not exceed this width.
Lines will be broken at the last white space character found before exceeding the width. If there is no such whitespace character, it will break the line before the first character exceeding the width. While this class does not support more sophisticated line breaking like hyphenation, the end result is good enough for most in-game multi-line text support.
When formatting multiline text, whitespace at the beginning and end of each line will be "swallowed", causing it to be ignored for purposes of alignment. The exception is at the beginning and end of a paragraph. Whitespace there will be preserved. A paragraph is defined as any piece of text separated by a newline. So the first part of the string before a newline is a paragraph, and each substring after a newline is also a paragraph.
Finally, it is possible to disable all line breaking in a text layout (including newlines). Simply set the width to a negative value.
cugl::TextLayout::TextLayout | ( | ) |
Creates a degenerate text layout with no data.
NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate an object on the heap, use one of the static constructors instead.
|
inline |
Deletes this text layout, disposing of all resources.
|
inlinestatic |
Returns a newly allocated empty text layout
You will need to add both text and a font, as well as call the method layout
to properly use this object.
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.
|
inlinestatic |
Returns a newly allocated 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 horizontal or vertical alignment before performing the layout.
text | The text to layout |
font | The font to arrange the text |
|
inlinestatic |
Returns a newly allocated text layout with the given text, font, and width.
A width of 0 will guarantee that breaks only happen at newlines, while a negative width means that line breaks never happen at all. 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 horizontal or vertical alignment before performing the layout.
text | The text to layout |
font | The font to arrange the text |
width | The width for each line |
|
inlinestatic |
Returns a newly allocated empty text layout with the given width.
You will need to add both text and a font, as well as call the method layout
to properly use this object.
A width of 0 will guarantee that breaks only happen at newlines, while a negative width means that line breaks never happen at all. A postive width will force the layout manager to break up lines so that no individual line exceeds that width.
width | The width for each line |
void cugl::TextLayout::dispose | ( | ) |
Deletes the layout resources and resets all attributes.
You must reinitialize the text layout to use it.
|
inline |
Returns the bounds of this text layout
This rectangle is in the coordinate space whose origin is defined by the horizontal and vertical alignment. This rectangle has zero size if the layout
method has not been called or if the layout has been invalidated.
|
inline |
Returns the font associated with this layout.
Changing this value will invalidate
the layout.
Rect cugl::TextLayout::getGlyphBounds | ( | size_t | index | ) | const |
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.
The index represents a position in the layout text string. The index must be the first byte of a valid UTF8 character. If it is a successive byte (and hence undecodable as a unicode character), this method will return the empty rectangle.
index | The position in the layout text |
Mesh< SpriteVertex2 > cugl::TextLayout::getGlyphBoxes | ( | ) | const |
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 glyph run sequence, it shows the bounding box for each glyph. However, these bounding boxes are determined by the glyph metrics, and do not take into account atlas padding. So they do not represent potential overlaps when the padding is non-zero.
The origin of the mesh will agree with that of the text layout. This method will do nothing if layout
has not been called or the layout has been invalidated.
size_t cugl::TextLayout::getGlyphBoxes | ( | Mesh< SpriteVertex2 > & | mesh | ) | const |
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 glyph run sequence, it shows the bounding box for each glyph. However, these bounding boxes are determined by the glyph metrics, and do not take into account atlas padding. So they do not represent potential overlaps when the padding is non-zero.
The origin of the mesh will agree with that of the text layout. This method will do nothing if layout
has not been called or the layout has been invalidated.
mesh | The mesh to store the new quads |
size_t cugl::TextLayout::getGlyphBoxes | ( | Mesh< SpriteVertex2 > & | mesh, |
Rect | rect | ||
) | const |
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 glyph run sequence, it shows the bounding box for each glyph. However, these bounding boxes are determined by the glyph metrics, and do not take into account atlas padding. So they do not represent potential overlaps when the padding is non-zero.
The quad sequence is adjusted so that all of the vertices fit in the provided rectangle. The primary use-case for this is to guarantee that glyphs do not spill outside of a window. This may mean that some of the glyphs will be truncrated or even omitted.
The origin of the mesh will agree with that of the text layout. This method will do nothing if layout
has not been called or the layout has been invalidated.
mesh | The mesh to store the new quads |
rect | The bounding box for the quads |
Mesh< SpriteVertex2 > cugl::TextLayout::getGlyphBoxes | ( | Rect | rect | ) | const |
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 glyph run sequence, it shows the bounding box for each glyph. However, these bounding boxes are determined by the glyph metrics, and do not take into account atlas padding. So they do not represent potential overlaps when the padding is non-zero.
The quad sequence is adjusted so that all of the vertices fit in the provided rectangle. The primary use-case for this is to guarantee that glyphs do not spill outside of a window. This may mean that some of the glyphs will be truncrated or even omitted.
The origin of the mesh will agree with that of the text layout. This method will do nothing if layout
has not been called or the layout has been invalidated.
rect | The bounding box for the quads |
size_t cugl::TextLayout::getGlyphIndex | ( | float | x, |
float | y | ||
) | const |
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
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.
x | The x-coordinate in layout space |
y | The y-coordinate in layout space |
|
inline |
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
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.
p | The position in layout space |
std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > cugl::TextLayout::getGlyphs | ( | ) | const |
Returns a set of glyph runs to render the text layout
Each glyph run will consist of a quad mesh and a texture to render those quads. Rendering all of the glyph runs together will render the entire string. Generally the quads are non-overlapping, so any blending mode is supported. However, if the atlas padding is non-zero (to support font blur), the quads will overlap at the padding intervals. Therefore, we recommend alpha blending when you render a string.
The keys for the glyph runs are the Texture#getBuffer
values for the appropriate atlas texture. This, combined with the method Font#getAtlases
allows you to identify the atlas for each run.
The origin of the glyph runs will agree with that of the text layout. This method will return the empty map if layout
has not been called or the layout has been invalidated.
std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > cugl::TextLayout::getGlyphs | ( | Rect | rect | ) | const |
Returns a set of glyph runs to render the text layout
Each glyph run will consist of a quad mesh and a texture to render those quads. Rendering all of the glyph runs together will render the entire string. Generally the quads are non-overlapping, so any blending mode is supported. However, if the atlas padding is non-zero (to support font blur), the quads will overlap at the padding intervals. Therefore, we recommend alpha blending when you render a string.
The keys for the glyph runs are the Texture#getBuffer
values for the appropriate atlas texture. This, combined with the method Font#getAtlases
allows you to identify the atlas for each run.
The quad sequence is adjusted so that all of the vertices fit in the provided rectangle. The primary use-case for this is to guarantee that glyphs do not spill outside of a window. This may mean that some of the glyphs will be truncrated or even omitted.
The origin of the glyph runs will agree with that of the text layout. This method will return the empty map if layout
has not been called or the layout has been invalidated.
rect | The bounding box for the quads |
size_t cugl::TextLayout::getGlyphs | ( | std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > & | runs | ) | const |
Stores the glyph runs to render the text layout in the given map
Each glyph run will consist of a quad mesh and a texture to render those quads. Rendering all of the glyph runs together will render the entire string. Generally the quads are non-overlapping, so any blending mode is supported. However, if the atlas padding is non-zero (to support font blur), the quads will overlap at the padding intervals. Therefore, we recommend alpha blending when you render a string.
The keys for the glyph runs are the Texture#getBuffer
values for the appropriate atlas texture. This, combined with the method Font#getAtlases
allows you to identify the atlas for each run. If the map is non-empty, the glyph run data will be appended to the relevant existing glyph run (if possible).
The origin of the glyph runs will agree with that of the text layout. This method will do nothing if layout
has not been called or the layout has been invalidated.
runs | The map to store the glyph runs |
size_t cugl::TextLayout::getGlyphs | ( | std::unordered_map< GLuint, std::shared_ptr< GlyphRun > > & | runs, |
Rect | rect | ||
) | const |
Stores the glyph runs to render the text layout in the given map
Each glyph run will consist of a quad mesh and a texture to render those quads. Rendering all of the glyph runs together will render the entire string. Generally the quads are non-overlapping, so any blending mode is supported. However, if the atlas padding is non-zero (to support font blur), the quads will overlap at the padding intervals. Therefore, we recommend alpha blending when you render a string.
The keys for the glyph runs are the Texture#getBuffer
values for the appropriate atlas texture. This, combined with the method Font#getAtlases
allows you to identify the atlas for each run. If the map is non-empty, the glyph run data will be appended to the relevant existing glyph run (if possible).
The quad sequence is adjusted so that all of the vertices fit in the provided rectangle. The primary use-case for this is to guarantee that glyphs do not spill outside of a window. This may mean that some of the glyphs will be truncrated or even omitted.
The origin of the glyph runs will agree with that of the text layout. This method will do nothing if layout
has not been called or the layout has been invalidated.
runs | The map to store the glyph runs |
rect | The bounding box for the quads |
|
inline |
Returns the horizontal alignment of the text.
The horizontal alignment has two meanings. First, it is the relationship of the relative alignment of multiple lines. In addition, it defines the x-coordinate 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.
std::string cugl::TextLayout::getLine | ( | size_t | line | ) | const |
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.
line | The line number |
|
inline |
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.
size_t cugl::TextLayout::getNearestIndex | ( | float | x, |
float | y | ||
) | const |
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.
x | The x-coordinate in layout space |
y | The y-coordinate in layout space |
|
inline |
Returns the index of the character whose glyph is nearest p
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.
p | The position in layout space |
|
inline |
Returns the line spacing of this layout.
This value is multiplied by the font size to determine the space between lines in the layout. So a value of 1 is single-spaced text, while a value of 2 is double spaced. The value should be positive.
Changing this value will invalidate
the layout.
|
inline |
Returns the text associated with this layout.
Changing this value will invalidate
the layout.
const Rect cugl::TextLayout::getTightBounds | ( | ) | const |
Returns the tightest bounds of the text layout
This rectangle is in the coordinate space whose origin is defined by the horizontal and vertical alignment. This rectangle has zero size if the layout
method has not been called or if the layout has been invalidated.
Unlike getBounds
, this rectangle sits tight against the text, ignoring any natural spacing such as the ascent or descent. However, it does not include any tracking that the layout may apply.
const Rect cugl::TextLayout::getTrueBounds | ( | ) | const |
Returns the true bounds of the text layout, including tracking
This rectangle is in the coordinate space whose origin is defined by the horizontal and vertical alignment. This rectangle has zero size if the layout
method has not been called or if the layout has been invalidated.
The method is similar to getTightBounds
, except that it also includes any tracking that is applied to the layout.
|
inline |
Returns the vertical alignment of the text.
The vertical alignment defines the y-coordinate origin of this text layout. In the case of multiple lines, the alignment is (often) with respect to the entire block of text, not just the first line.
Changing this value will invalidate
the layout.
|
inline |
Returns the 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, while a negative width means that line breaks never happen at all. 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.
bool cugl::TextLayout::init | ( | ) |
Initializes an empty text layout
You will need to add both text and a font, as well as call the method layout
to properly use this object.
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.
bool cugl::TextLayout::initWithText | ( | const std::string | text, |
const std::shared_ptr< Font > & | font | ||
) |
Initializes 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 horizontal or vertical alignment before performing the layout.
text | The text to layout |
font | The font to arrange the text |
bool cugl::TextLayout::initWithTextWidth | ( | const std::string | text, |
const std::shared_ptr< Font > & | font, | ||
float | width | ||
) |
Initializes a text layout with the given text, font, and width.
A width of 0 will guarantee that breaks only happen at newlines, while a negative width means that line breaks never happen at all. 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 horizontal or vertical alignment before performing the layout.
text | The text to layout |
font | The font to arrange the text |
width | The width for each line |
bool cugl::TextLayout::initWithWidth | ( | float | width | ) |
Initializes an empty text layout with the given width.
You will need to add both text and a font, as well as call the method layout
to properly use this object.
A width of 0 will guarantee that breaks only happen at newlines, while a negative width means that line breaks never happen at all. A postive width will force the layout manager to break up lines so that no individual line exceeds that width.
width | The width for each line |
void cugl::TextLayout::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.
void cugl::TextLayout::layout | ( | ) |
Arranges the text according to the given font and settings
Changing any of the layout attributes will obviously invalidate the text layout. For performance reasons, we do not automatically recompute the layout in that case. Instead, the user must call layout
to arrange the text.
void cugl::TextLayout::setFont | ( | const std::shared_ptr< Font > & | font | ) |
Sets the font associated with this layout.
Changing this value will invalidate
the layout.
font | The font associated with this layout. |
void cugl::TextLayout::setHorizontalAlignment | ( | HorizontalAlign | halign | ) |
Sets the horizontal alignment of the text.
The horizontal alignment has two meanings. First, it is the relationship of the relative alignment of multiple lines. In addition, it defines the x-coordinate 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.
halign | The horizontal alignment of the text. |
void cugl::TextLayout::setSpacing | ( | float | spacing | ) |
Sets the line spacing of this layout.
This value is multiplied by the font size to determine the space between lines in the layout. So a value of 1 is single-spaced text, while a value of 2 is double spaced. The value should be positive.
Changing this value will invalidate
the layout.
spacing | The line spacing of this layout. |
void cugl::TextLayout::setText | ( | const std::string | text | ) |
Sets the text associated with this layout.
Changing this value will invalidate
the layout.
text | The text associated with this layout. |
void cugl::TextLayout::setVerticalAlignment | ( | VerticalAlign | valign | ) |
Sets the vertical alignment of the text.
The vertical alignment defines the y-coordinate origin of this text layout. In the case of multiple lines, the alignment is (often) with respect to the entire block of text, not just the first line.
Changing this value will invalidate
the layout.
valign | The vertical alignment of the text. |
void cugl::TextLayout::setWidth | ( | float | width | ) |
Sets the 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, while a negative width means that line breaks never happen at all. 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.
width | The line width of this layout. |
|
inline |
Returns true if the layout has been successful.
This method will return false unless layout
has been called.
|
friend |
Allow label access for fine-tuned control