# The document/layout model

The Label class demonstrated above presents a simplified interface to pyglet's complete text rendering capabilities. The underlying TextLayout and AbstractDocument classes provide a "model/view" interface to all of pyglet's text features.

# Documents

A document is the "model" part of the architecture, and describes the content and style of the text to be displayed. There are two concrete document classes: UnformattedDocument and FormattedDocument. UnformattedDocument models a document containing text in just one style, whereas FormattedDocument allows the style to change within the text.

An empty, unstyled document can be created by constructing either of the classes directly. Usually you will want to initialise the document with some text, however. The decode_text, decode_attributed and decode_html functions return a document given a source string. For decode_text, this is simply a plain text string, and the return value is an UnformattedDocument:

    document = pyglet.text.decode_text('Hello, world.')

decode_attributed and decode_html are described in detail in the next section.

The text of a document can be modified directly as a property on the object:

    document.text = 'Goodbye, cruel world.'

However, if small changes are being made to the document it can be more efficient (when coupled with an appropriate layout; see below) to use the remove_text and insert_text methods instead.

# Layouts

The actual layout and rendering of a document is performed by the TextLayout classes. This split exists to reduce the complexity of the code, and to allow a single document to be displayed in multiple layouts simultaneously (in other words, many layouts can display one document).

Each of the TextLayout classes perform layout in the same way, but represent a trade-off in efficiency of update against efficiency of drawing and memory usage.

The base TextLayout class uses little memory, and shares its graphics group with other TextLayout instances in the same batch (see Batched rendering). When the text or style of the document is modified, or the layout constraints change (for example, the width of the layout changes), the entire text layout is recalculated. This is a potentially expensive operation, especially for long documents. This makes TextLayout suitable for relatively short or unchanging documents.

ScrollableTextLayout is a small extension to TextLayout that clips the text to a specified view rectangle, and allows text to be scrolled within that rectangle without performing the layout calculuation again. Because of this clipping rectangle the graphics group cannot be shared with other text layouts, so for ideal performance ScrollableTextLayout should be used only if this behaviour is required.

IncrementalTextLayout uses a more sophisticated layout algorithm that performs less work for small changes to documents. For example, if a document is being edited by the user, only the immediately affected lines of text are recalculated when a character is typed or deleted. IncrementalTextLayout also performs view rectangle culling, reducing the amount of layout and rendering required when the document is larger than the view. IncrementalTextLayout should be used for large documents or documents that change rapidly.

All the layout classes can be constructed given a document and display dimensions:

    layout = pyglet.text.layout.TextLayout(document, width, height)

Additional arguments to the constructor allow the specification of a graphics batch and group (recommended if many layouts are to be rendered), and the optional multiline flag. To render more than one line of text (either through word-wrapping or explicit line breaks) multiline must be `True`.

Like labels, layouts are positioned through their x, y, anchor_x and anchor_y properties. Note that unlike AbstractImage, the anchor properties accept a string such as `"bottom"` or `"center"` instead of a numeric displacement.