Extensible 3D (X3D)
Part 1: Architecture and base components

15 Text component

--- X3D separator bar ---

cube 15.1 Introduction

15.1.1 Name

The name of this component is "Text". This name shall be used when referring to this component in the COMPONENT statement (see 7.2.5.4 Component statement).

15.1.2 Overview

This clause describes the Text component of this document. The Text component specifies how text strings are rendered in an X3D scene. Table 15.1 provides links to the major topics in this clause.

Table 15.1 — Topics

cube 15.2 Concepts

15.2.1 Text semantics

15.2.1.1 Overview

Text is processed as geometry in X3D. There are special considerations when specifying text as well as when displaying text. This subclause describes the manner in which text values are specified in X3D using the Text node. 15.2.2 Text formatting describes text formatting.

15.2.1.2 Appearance

Textures are applied to text as follows. The texture origin is at the origin of the first string, as determined by the justification. The texture is scaled equally in both S and T dimensions, with the font height representing 1 unit. S increases to the right, and T increases up.

12 Shape component specifies how Appearance, material and textures interact with lighting. 17 Lighting component specifies the X3D lighting equations.

15.2.2 Text formatting

15.2.2.1 Introduction

There is a long history of text layout and formatting. This standard specifies techniques to be used in X3D that provide support for a variety of languages and layout schemes. Additional layout functionality is specified in 36 Layout component.

15.2.2.2 Font family and style

Font attributes are defined with the family and style fields. The X3D browser shall map the specified font attributes to an appropriate available font as described below.

The family field contains a case-sensitive MFString value that specifies a sequence of font family names in preference order. The X3D browser shall search the MFString value for the first font family name matching a supported font family. If none of the string values matches a supported font family, the default font family "SERIF" shall be used. All X3D browsers shall support at least "SERIF" (the default) for a serif font such as Times Roman; "SANS" for a sans-serif font such as Helvetica; and "TYPEWRITER" for a fixed-pitch font such as Courier. An empty family value is identical to ["SERIF"]. The fonts associated with family names "SANS", "SERIF" and "TYPEWRITER" shall not be replaced using fonts introduced by a FontLibrary node. Any other font family may be specified, as shown in the following example that specifies the order of preferred values for selecting of the specification of a font family:

    ["Lucida Sans Typewriter", "Lucida Sans", "Helvetica", "SANS"]

In this example, the X3D browser would first look for the font family "Lucida Sans Typewriter" on the system on which the X3D browser is operating. If that is not available, the X3D browser looks for "Lucida Sans". If that is not available, the browser looks for "Helvetica". If that is not available, the X3D browser looks for any sans-serif font. If there are not sans-serif fonts installed, the X3D browser will use any serif font (the default). It is the responsibility of the author that a suitable list of font families be specified so that the desired appearance is achieved in most operating environments.

NOTE  The author should always be willing to accept that the requested font families may not be available, resulting in the use of "SERIF" font. a X3D browser-selected "SERIF" font being used.

The style field specifies a case-sensitive SFString value that may be "PLAIN" (the default) for default plain type; "BOLD" for boldface type; "ITALIC" for italic type; or "BOLDITALIC" for bold and italic type. An empty style value ("") is identical to "PLAIN". In the case where the requested style is not available, the available style that is closest to the requested style shall be used. For example, some font families specify a Demibold style rather than Bold. In this case, specifying "BOLD" will result in the X3D browser using Demibold as the nearest substitute.

15.2.2.3 Direction and justification

The horizontal, leftToRight, and topToBottom fields indicate the direction of the text. The horizontal field indicates whether the text advances horizontally in its major direction (horizontal = TRUE, the default) or vertically in its major direction (horizontal = FALSE). The leftToRight and topToBottom fields indicate direction of text advance in the major (characters within a single string) and minor (successive strings) axes of layout. Which field is used for the major direction and which is used for the minor direction is determined by the horizontal field. Note that the direction specification overrides any modes inherent in a particular language.

For horizontal text (horizontal = TRUE), characters on each line of text advance in the positive X direction if leftToRight is TRUE or in the negative X direction if leftToRight is FALSE. Characters are advanced according to their natural advance width. Each line of characters is advanced in the negative Y direction if topToBottom is TRUE or in the positive Y direction if topToBottom is FALSE. Lines are advanced by the amount of size ×  spacing.

For vertical text (horizontal = FALSE), characters on each line of text advance in the negative Y direction if topToBottom is TRUE or in the positive Y direction if topToBottom is FALSE. Characters are advanced according to their natural advance height. Each line of characters is advanced in the positive X direction if leftToRight is TRUE or in the negative X direction if leftToRight is FALSE. Lines are advanced by the amount of size ×  spacing.

The justify field determines alignment of the above text layout relative to the origin of the object coordinate system. The justify field is an MFString which can contain 2 values. The first value specifies alignment along the major axis and the second value specifies alignment along the minor axis, as determined by the horizontal field. An empty justify value ("") is equivalent to the default value. If the second string, minor alignment, is not specified, minor alignment defaults to the value "FIRST". Thus, justify values of "", "BEGIN", and ["BEGIN" "FIRST"] are equivalent.

The major alignment is along the X-axis when horizontal is TRUE and along the Y-axis when horizontal is FALSE. The minor alignment is along the Y-axis when horizontal is TRUE and along the X-axis when horizontal is FALSE. The possible values for each enumerant of the justify field are "FIRST", "BEGIN", "MIDDLE", and "END". For major alignment, each line of text is positioned individually according to the major alignment enumerant. For minor alignment, the block of text representing all lines together is positioned according to the minor alignment enumerant. Tables 15.2-15.5 describe the behaviour in terms of which portion of the text is at the origin.

Table 15.2 — Major Alignment, horizontal = TRUE

justifyEnumerant leftToRight= TRUE leftToRight= FALSE
 FIRST  Left edge of each line  Right edge of each line
 BEGIN  Left edge of each line  Right edge of each line
 MIDDLE  Centred about X-axis  Centred about X-axis
 END  Right edge of each line  Left edge of each line

Table 15.3 — Major Alignment, horizontal = FALSE

justifyEnumerant topToBottom= TRUE topToBottom= FALSE
 FIRST  Top edge of each line  Bottom edge of each line
 BEGIN  Top edge of each line  Bottom edge of each line
 MIDDLE  Centred about Y-axis  Centre about Y-axis
 END  Bottom edge of each line  Top edge of each line

Table 15.4 — Minor Alignment, horizontal = TRUE

justifyEnumerant topToBottom= TRUE topToBottom= FALSE
FIRST Baseline of first line Baseline of first line
BEGIN Top edge of first line Bottom edge of first line
MIDDLE Centred about Y-axis Centred about Y-axis
END Bottom edge of last line Top edge of last line

Table 15.5 — Minor Alignment, horizontal = FALSE

justifyEnumerant leftToRight= TRUE leftToRight= FALSE
FIRST Left edge of first line Right edge of first line
BEGIN Left edge of first line Right edge of first line
MIDDLE Centred about X-axis Centred about X-axis
END Right edge of last line Left edge of last line

The default minor alignment is "FIRST ". This is a special case of minor alignment when horizontal is TRUE. Text starts at the baseline at the Y-axis. In all other cases, "FIRST " is identical to "BEGIN ". In Tables 15.6 and 15.7, each colour-coded cross-hair indicates where the X-axis and Y-axis shall be in relation to the text. Figure 15.1 describes the symbols used in Tables 15.6 and Table 15.7.

Key for Tables 14.6 and 14.7

Figure 15.1 — Key for Tables 15.6 and 15.7

Table 15.6 — horizontal = TRUE

horizontal = TRUE

Table 15.7 — horizontal = FALSE

horizontal = FALSE

15.2.2.4 Language

The language field specifies the context of the language for the text string in the form of a language and a country in which that language is used. Both the language and the country are specified using the language tags defined in RFC3066 which may specify only a country (using the three-character codes defined in ISO 3166) or both a language (using the two-character codes specified in ISO 639) and a country (using the three-character codes specified in ISO 3166) utilizing a sub-tag structure as specified in RFC3066). The language tags contain between one and eight characters. Note that the characters used in the language tag are in the Basic Latin alphabet that maps to single-byte characters in the UTF-8 encoding.

See 2 Normative references, for more information on RFC 3066 (RFC3066), ISO/IEC 10646, ISO/IEC 639, and ISO 3166.

cube 15.3 Abstract types

15.3.1 X3DFontStyleNode

X3DFontStyleNode : X3DNode {
  SFNode [in,out] metadata NULL [X3DMetadataObject]
}

This abstract node type is the base node type for all font style nodes.

cube 15.4 Node reference

Feedback is welcome, with detailed discussion occurring on the x3d-public mailing list.

15.4.1 FontLibrary

FontLibrary : X3DNode, X3DUrlObject {
  SFTime   [in,out] autoRefresh          0.0    [0,∞)
  SFTime   [in,out] autoRefreshTimeLimit 3600.0 [0,∞)
  SFString [in,out] description          ""
  SFString [in,out] family               ""     (under consideration)
  SFBool   [in,out] load                 TRUE
  MFString [in,out] url                  []     [URI]
}

The FontLibrary node specifies a collection of one or more font family definitions. A font family may include one or more related font style definitions. FontLibrary provides the ability to selectively load font files for use by FontStyle and ScreenFontStyle nodes.

The visibility of FontLibrary fonts is scoped to the current model, and FontLibrary nodes are typically defined with other root nodes in a scene. Fonts from FontLibrary nodes are also usable when defined within an Inline node, or when defined among the topmost nodes of a Prototype instance contained in a scene.

NOTE  A child scene does not have direct visibility into fonts defined within a parent scene. Meanwhile, if desired, utilizing an X3D Inline model (or external prototype) that contains one or more FontLibrary fonts is a good way for many different X3D scenes to share a consistent set of fonts.

The description field provides a relevant summary of the associated font library.

The family field provides an identifying alias for the font in the associated file, if that file only contains a single font family (possibly with multiple styles). This field provides a reference label for the family field in a corresponding FontStyle or ScreenFontStyle node. If no family field is provided, the X3D browser can look inside the font file to determine the family name of each associated font.
Editors note: this approach for family field is similar to how CSS can identify a font family associated with a font file for corresponding use in an HTML page.

The url field is optional and can refer to a relative or online address for a font library that contains one or more font definitions. An empty url list indicates that the default set of fonts provided by the browser are used. If present, only the first active font library retrieved from the url list shall be used. Individual font library files can be used by multiple FontStyle nodes in a scene. Each font file only needs to be loaded once per session.

X3D browsers shall support WOFF (see W3C WOFF File Format 2.0). Support for the OpenType file format (see OpenType Specification) and TrueType file format (see ISO/IEC 14496-22 Open Font Format) is recommended.

Security, licensing, copyright, and access permissions are handled via the exposure of a font file itself.

More details on the autoRefresh, autoRefreshTimeLimit, description, load, and url fields are contained in 9.3.2 X3DUrlObject.

Editors note: key questions are

  1. Whether global scope is needed for FontLibrary fonts, rather than just within a FontStyle node; we think yes, fonts ought to have scene scope for the current model.
  2. If fonts are visible throughout a given model, then scoping a FontLibrary node within a FontStyle fontLibrary field appears to be superfluous. This avoids much unnecessary complication, especially if an author simply wants to change the value of a FontStyle family field.
  3. Whether a single font file contains more than one font; yes, various specifications indicate that may occur for some font files.
  4. Whether a browser might look inside the font file to check internal metadata and find one of multiple family names; yes that option seems like a good idea if no common matching family field is found for the FontStyle and FontLibrary nodes.

EXAMPLE 1. FontLibrary node defined at the top of a scene with global scope in that model. Font family identification is placed in the family field, or else optionally deduced from internal naming metadata contained within the font file.

    # example adapted with thanks from X3DOM Editor TextHaveFunWithX3D.x3d

    COMPONENT Text : 2
    FontLibrary {
      family "Playwright_CA_Guides"
      url [ "MjQamj1kuP_soQ3o-rysO9Ci_8oJlIUUInI.woff2" 
            "https://fonts.gstatic.com/s/playwritecaguides/v1/MjQamj1kuP_soQ3o-rysO9Ci_8oJlIUUInI.woff2" ]
    }
    Shape {
      # ☺ = ☺ smiley face emoticon, and "" means skip a line
      geometry Text {
        string [ "Have fun" "with X3D!" "" ":)   ☺" ]
        fontStyle FontStyle {
            spacing 1.5
            family [ "Playwright_CA_Guides" "SANS" "TYPEWRITER" ]
            justify [ "MIDDLE" "MIDDLE"  ] 
        }
      }
    }

Editors note: the fontLibrary fields shown in EXAMPLE 2 appear to be an unnecessary complication, since the approach shown in Example 1 can also work for each of these two scene fragments. Subject to mailing list discussion, we expect to delete both fragments in EXAMPLE 2.

EXAMPLE 2. Text and FontStyle node pairs, each containing a FontLibrary node, with font visibility limited to local scope via a fontLibrary field. Font family identification is provided by matching values for corresponding family fields.

    
    # two example Text nodes, adapted with thanks from X_ITE Playground FontLibrary.x3dv

    COMPONENT Text : 2
    DEF Text1 Transform {
      translation 0 1 0
      children Shape {
        geometry Text {
          string "X3D Text (PTSans-Regular)"
          fontStyle FontStyle {
            family [
              "PTSans-Regular",
              "PT Sans",
              "SANS"
            ]
            justify "MIDDLE"
            fontLibrary DEF PTSans-Regular FontLibrary {
              family "PTSans-Regular"
              url [ "PTSans-Regular.ttf" 
                    "https://cdn.jsdelivr.net/npm/x_ite@11.2.2/dist/assets/fonts/PT_Sans/PTSans-Regular.ttf" ]
            }
          }
        }
      }
    }
    
    DEF Text2 Transform {
      translation 0 -1 0
      children Shape {
        geometry Text {
          string "X3D Text (PTSans-Bold)"
          fontStyle FontStyle {
            family [
              "PTSans-Bold",
              "PT Sans",
              "SANS"
            ]
            style "BOLD"
            justify "MIDDLE"
            fontLibrary DEF PTSans-Bold FontLibrary {
              family "PTSans-Bold"
              url [ "PTSans-Bold.ttf" 
                    "https://cdn.jsdelivr.net/npm/x_ite@11.2.2/dist/assets/fonts/PT_Sans/PTSans-Bold.ttf" ]
            }
          }
        }
      }
    }
    

15.4.2 15.4.1 FontStyle

FontStyle : X3DFontStyleNode {
  SFNode   [in,out] fontLibrary NULL      [FontLibrary] 
# Do we really need to add this field? Subject to mailing list discussion, we expect to delete the fontLibrary field
SFNode [in,out] metadata NULL [X3DMetadataObject] MFString [in,out] family ["SERIF"] "SERIF" SFBool [in,out] horizontal TRUE MFString [in,out] justify ["BEGIN"] "BEGIN" ["BEGIN"|"END"|"FIRST"|"MIDDLE"|""],["BEGIN"|"END"|"FIRST"|"MIDDLE"|""] TODO look at square bracket conventions SFString [in,out] language "" SFBool [in,out] leftToRight TRUE SFFloat [in,out] size 1.0 (0,∞) SFFloat [in,out] spacing 1.0 [0,∞) SFString [in,out] style "PLAIN" ["PLAIN"|"BOLD"|"ITALIC"|"BOLDITALIC"|""] SFBool [in,out] topToBottom TRUE }

The FontStyle node defines the size, family, and style fields used for Text nodes (see 15.2.2 Text formatting), also defining and the direction of the text strings and any language-specific rendering techniques used for non-English text. See Text for a description of the Text node.

The fontLibrary field can contain a single FontLibrary node that may provide a font matching a value in the list of allowed family values.
Do we really need to add this field? Subject to mailing list discussion, we expect to delete the fontLibrary field

The size field specifies the nominal height, in the local coordinate system of the Text node, of glyphs rendered and determines the spacing of adjacent lines of text. Values of the size field shall be greater than zero.

The spacing field determines the line spacing between adjacent lines of text. The distance between the baseline of each line of text is (spacing × size) in the appropriate direction (depending on other fields described below). The effects of the size and spacing field are depicted in Figure 15.2 (spacing greater than 1.0). Values of the spacing field shall be non-negative.

Text size and spacing fields

Figure 15.2 — Text size and spacing fields

15.4.3 15.4.2 Text

Text : X3DGeometryNode {
  SFNode   [in,out] fontStyle  NULL  [X3DFontStyleNode]
  MFFloat  [in,out] length     []    [0,∞)
  SFFloat  [in,out] maxExtent  0.0   [0,∞)
  SFNode   [in,out] metadata   NULL  [X3DMetadataObject]
  MFString [in,out] string     []
  MFVec2f  [out]    lineBounds
  SFVec3f  [out]    origin
  SFVec2f  [out]    textBounds
  SFBool   []       solid      FALSE
}

The Text node specifies a two-sided (by default), flat text string object positioned in the Z=0 plane of the local coordinate system based on values defined in the fontStyle field (see 15.4.2 15.4.1 FontStyle). Text nodes may contain multiple text strings specified using the UTF-8 encoding as specified by ISO 10646. The character encoding UTF-16 is also permitted. The text strings are stored in the order in which the text mode characters are to be produced as defined by the parameters in the FontStyle node.

The text strings are contained in the string field. The fontStyle field contains one FontStyle node that specifies the font size, font family and style, direction of the text strings, and any specific language rendering techniques used for the text. If no FontStyle node is specified by the fontStyle field, the default values of the FontStyle node are used.

The maxExtent field limits and compresses all of the text strings if the length of the maximum string is longer than the maximum extent, as measured in the local coordinate system. If the text string with the maximum length is shorter than the maxExtent, then there is no compressing. The maximum extent is measured horizontally for horizontal text (FontStyle node: horizontal=TRUE) and vertically for vertical text (FontStyle node: horizontal=FALSE). The maxExtent field shall be greater than or equal to zero.

The length field contains an MFFloat value that specifies the length of each text string in the local coordinate system. The length of each line of type is measured horizontally for horizontal text (FontStyle node: horizontal=TRUE) and vertically for vertical text (FontStyle node: horizontal=FALSE). The length and maxExtent fields thus refer to local coordinate units along the dimension of type flow (major axis). If the string is too short, it is stretched (either by scaling the text or by adding space between the characters). If the string is too long, it is compressed (either by scaling the text or by subtracting space between the characters). If a length value is missing (for example, if there are four strings but only three length values), the missing values are considered to be 0. The length field shall be greater than or equal to zero.

Specifying a value of 0 for both the maxExtent and length fields indicates that the string may be any length.

When the default values of length and maxExtent are used, the Text node shall generate events called origin, lineBounds and textBounds to provide applications with spatial data regarding the size and position of the rendered string(s) with the font being used. These events are also generated when the default values of length and maxExtent are used and the text is redrawn (e.g., the string field is changed programmatically or the FontStyle node is replaced).

The field origin is a single 3D position that specifies the origin of the text local coordinate system in units of the coordinate system in which the Text node is embedded. The value of the origin field represents the upper left corner of the textBounds. The field lineBounds is a set of 2D vectors where each vector contains the size of the 2D bounding box for each line of rendered text in local text x and y units. The textBounds event is a single 2D vector that contains the size in x and y dimensions of the Text node’s 2D bounding box (all strings) as rendered. An example for each value of the topToBottom of the FontStyle node is depicted in Figure 15.3. Through the origin event, authors can locate relative measures of lineBounds and textBounds regardless of the FontStyle's major or minor axis.

NOTE   In horizontal font styles, the x dimension of the lineBounds and textBounds fields is equivalent to a specified length or maxExtent (the major axis). However, in vertical font styles, the x dimension of the lineBounds and textBounds fields is along the minor axis.

Text Bounds

Figure 15.3 — lineBounds and textBounds measurements

11.2.3 Common geometry fields provides a complete description of the solid field.

cube 15.5 Support levels

The Text component provides 1 level of support as specified in Table 15.8.

Table 15.8 — Text component support levels

Level Prerequisites Nodes/Features Support
1 Core 1
Grouping 1
Shape 1
Rendering 1
X3DFontStyleNode (abstract) n/a
FontStyle All fields fully supported.
(except autoRefresh, autoRefreshTimeLimit, load, and url fields are optional.
Text All fields fully supported.
2 Core 1
Grouping 1
Networking 2
Shape 1
Rendering 1
X3DUrlObject (abstract)
All Level 1 Text component nodes All fields fully supported.
FontLibrary All fields fully supported.

--- X3D separator bar ---